Академический Документы
Профессиональный Документы
Культура Документы
History
Several years ago we recognized the pattern where customers were developing forms with too much JavaScript, too much complexity On analysis we recognized that we needed to take two approaches
1. 2.
Product improvements to reduce the need for JavaScript Better user education on form design patterns
Outline
1. 2. 3.
Forms, Applications and Monsters Steps to Sanity Form Design Review (Library of Congress)
Tens of thousands of lines of script Several megabytes in size Slow open time Sluggish performance Big memory footprint High maintenance costs Susceptible to changes in new versions of Reader These are our "monster forms"
Nobody sets out to create a monster They start small and the requirements start to creep Form complexity grows incrementally After several revisions of the form you have a large investment in JavaScript
You wrote a modest amount of code Not the most elegant code but it works
You wrote a modest amount of code Not the most elegant code but it works You have a manageable, small monster
You wrote a modest amount of code Not the most elegant code but it works You have a manageable, small monster
You wrote a modest amount of code Not the most elegant code but it works You have a manageable, small monster
Your initial form is a great success! You copy the code and design patterns to 200 new forms in your department
You wrote a modest amount of code Not the most elegant code but it works You have a manageable, small monster
Your initial form is a great success! You copy the code and design patterns to 200 new forms in your department You discover a flaw in your design pattern affecting all 200 forms
Inefficient code is excusable in small forms -- does not factor into overall processing costs Small inefficiencies in small forms become big inefficiencies in big forms Design flaws repeated over many small forms become a maintenance nightmare
many person-years of development invested Critical to business processes Fragile to update, hard to test Susceptible to changes in Reader
Collectively, many person-years invested Used in many parts of the business Common code not shared: maintenance is very expensive Re-testing is a big job
14
It is perfectly valid to develop forms with lots of script If the script is well-written the form(s) can be:
BUT Adopt a new mindset: You are no longer developing forms You are developing applications Are you ready for application development?
Do your form developers have programming skills? Do you have coding standards? Do you perform code reviews? Do you have a source control system? Do you insist on documentation? Do you aggressively modularize common code patterns? Are you prepared to take a step backward and re-factor when needed? Do you have a quality assurance methodology? Do you have a form deployment methodology?
Youve been asked to add an enhancement or diagnose a problem -- but dont know the intricacies of the form How do I tame the monster? Welcome to my world
Outline
1. 2. 3.
Forms, Applications and Monsters Steps to Sanity Form Design Review (Library of Congress)
Steps to sanity
1. 2. 3. 4. 5. 6.
Be an expert Bring your forms to version 9.1 Share code Think Accessibility First Get to know the available tools Common problems, common solutions
Steps to sanity
1.
Be a JavaScript Expert
JavaScript has some very powerful constructs that (if used correctly) can greatly improve your code
Can you write a recursive function? Do you use try/catch? Do you use arrays and object literals? Do you understand JavaScript closure? Do you use regular expressions?
Be a JavaScript Expert
There are different implementations of JavaScript Acrobat/Reader uses Mozilla JavaScript (Spidermonkey) Includes E4X for manipulating XML Check out this web page: http://code.google.com/p/jslibs/wiki/JavascriptTips Server products use ExtendScript highly compatible
Steps to sanity
1.
Be an XML Expert
Can you create an XML document in notepad? Have you ever written an XSL script? Can you decipher an XML Schema? Do you know how XLIFF is used? Do you understand XHTML? You need to be familiar with the basics of each
Steps to sanity
1.
Be an XFA Expert
XFA Schema XFA Scripting Object Model SOM expressions XFA Events
Be an XFA Expert
XFA Schema XFA Scripting Object Model SOM expressions XFA Events
city.border.fill.color.value = "100,100,100";
city.fillColor = "100,100,100";
DOM hierarchy:
all, index, classAll, classIndex, className, somExpression, instanceIndex, isContainer, model, parent, parentSubform, nodes
Shortcuts:
Dropdown lists:
Field values:
Miscellaneous:
Be an XFA Expert
XFA Schema XFA Scripting Object Model SOM expressions XFA Events
SOM Expressions
Used in data binding Used as the parameter to resolveNode() and resolveNodes() Used for FormCalc expressions
Similar, but not the same. E.g. Is evaluated differently from: Can return a different result, but usually does not SOM has extra capabilities that object expressions do not have
A.B.rawValue
this.resolveNode("A.B").rawValue;
33
SOM Expressions
item[-1] po.*
item.#field[*]
// previous item // all children of po // all field children of item // predicate in FormCalc:
Be an XFA Expert
XFA Schema XFA Scripting Object Model SOM expressions XFA Events
Convert input to input uppercase Prevent users from formatting telephone numbers (demo)
Use xfa.event.cancelAction inside preSubmit / preSign / prePrint to cancel if conditions arent right Use initialize to change properties that designer doesnt expose Use propagating events (details later)
Use execEvent() minimally. It is not intended as a method for sharing code Put shared code in script objects:
Steps to sanity
1. 2. 3. 4. 5. 6.
Be an expert Bring your forms to version 9.1 Share code Think Accessibility First Get to know the available tools Common problems, common solutions
Acrobat 9.1
Enhancements in the 9.1 release specifically addressed the issue of excessive code in forms
Historical Reader behavior was to issue one error message per validation failure Form authors wrote their own validation frameworks in order to avoid the message boxes
Encapsulation
Keep the code that defines field behaviour inside the field Validations, calculations should be defined in field calculation, validation scripts Messages that are specific to a field defined within the field
Encapsulated validation
External validation
encapsulation.validate::click - (JavaScript, client) var field = A.B.C.D; var bValid = field.isNull || (field.rawValue > 0); if (bValid) { field.borderColor = "0,0,0"; field.assist.toolTip.value = ""; } else { field.borderColor = "255,0,0"; field.assist.toolTip.value = "The value of D must be greater than zero"; }
(demo) Better (immediate) user validation feedback No need for a separate action to trigger validation Form processor will prevent submit if there are validation failures External validation is replicating functionality found in the XFA processor External validation requires writing code for mandatory processing encapsulated version is handled declaratively Less code, simpler code
If any subforms are renamed/moved/unwrapped, the field SOM expression changes Changed SOM expression causes the external validation script to break:
var field = A.B.C.D; var bValid = field.isNull || (field.rawValue > 0); if (bValid) { ...
In the encapsulated version, there are no references to field or subform names, only this object.
Not Encapsulated:
External validation logic not automatically included in the fragment External logic needs to be knit into the validation logic of the host form
When the same event logic appears on many fields, we can define the event once and propagate Use cases:
Field highlighting on enter or mouseEnter Change field appearance on validationState Change row color on indexChange
ES2 designer does not allow you to define propagating field events on a subform A10 designer removes the propagating UI To use them you need to edit XML source or use a macro demo: uniqueValues.pdf
Inactive presence
object.presence = "visible | invisible | hidden | inactive"; visible: object is rendered; events fire invisible: object is not rendered; participates in layout; events fire hidden: object is not rendered; excluded from layout; events fire inactive: objects is not rendered; excluded from layout; events do not fire
(demo)
49
Payment sample
if (this.rawValue === "Credit Card") { CreditCardDetails.presence = "visible"; } else { CreditCardDetails.presence = "inactive"; } // this isn't really a validation // just a place to trigger on changes to this field true;
50
Bug fixes can change the behaviour of forms We use a processing instruction to ensure compatibility between Reader releases Compatibility PI ensures you continue to get the same set of behaviours (and same set of bugs) in new releases To get the latest, from XML Source view, remove:
<?originalXFAVersion http://www.xfa.org/schema/xfa-template/2.5/?>
It is possible to build a framework that uses encapsulation and avoids the message boxes Samples on the formfeed blog
Steps to sanity
1. 2. 3. 4. 5. 6.
Be an expert Bring your forms to version 9.1 Share code Think Accessibility First Get to know the available tools Common problems, common solutions
Share Code
Code sharing is one of the disciplines of good programming Benefits of code sharing:
Less code Faster development Lower maintenance costs Consistent behaviours within a form and between forms Simplify complex operations for use by novice form designers
55
Share Code
BUT to get the benefits of code sharing you need to make an investment:
Recognize repeated patterns Generalize the repeated operation Isolate the variable parts of the operation into parameters The generalized version of functionality has higher up-front development costs Once the initial investment has been made in shared code, the ROI will more than compensate
56
Share Code
Functions within a script event Functions within a script object Script objects stored as fragments Propagating events
57
Task: Copy all field data from one subform to another. Brute force code looks like:
S2.F1.rawValue = S1.F1.rawValue; S2.F2.rawValue = S1.F2.rawValue; S2.F3.rawValue = S1.F3.rawValue; S2.F4.rawValue = S1.F4.rawValue; S2.F5.rawValue = S1.F5.rawValue;
(demo)
58
Before:
S2.F1.rawValue = S1.F1.rawValue; S2.F2.rawValue = S1.F2.rawValue; S2.F3.rawValue = S1.F3.rawValue; S2.F4.rawValue = S1.F4.rawValue; S2.F5.rawValue = S1.F5.rawValue;
After:
utilities.subformCopy(S2, S1);
59
60
Steps to sanity
1. 2. 3. 4. 5. 6.
Be an expert Bring your forms to version 9.1 Share code Think Accessibility First Get to know the available tools Common problems, common solutions
Even if Accessibility is not currently a requirement, make sure you know what an accessible form looks like The up-front development costs for Accessible forms are much lower than retrofitting accessibility
Use captions. Do not use separate text objects Make sure your tables have rows designated as a header Carefully define tab order Dont rely on color to convey invalid fields
Steps to sanity
1. 2. 3. 4. 5. 6.
Be an expert Bring your forms to version 9.1 Share code Think Accessibility First Get to know the available tools Common problems, common solutions
Use the JavaScript console Form Summary Tool Dump the data DOM XFA Debugger JSLint Accessibility Checker XLIFF translator Develop your own Designer Macros
JavaScript errors show up in the console At the end of a form session, make sure there are no errors in the console Use console.println() to trace code Better yet, leave conditional trace statements in your code permanently
Use the JavaScript console Form Summary Tool Dump the data DOM XFA Debugger JSLint Accessibility Checker Develop your own Designer Macros
Effective way to get an overview of form content Understanding the details of a form report can help identify problems (demo)
Use the JavaScript console Form Summary Tool Dump the data DOM XFA Debugger JSLint Accessibility Checker Develop your own Designer Macros
Many form design challenges require a good understanding of what the data looks like Easiest way to understand the data is to dump a snapshot (demo)
Use the JavaScript console Form Summary Tool Dump the data DOM XFA Debugger JSLint Accessibility Checker Develop your own Designer Macros
XFA Debugger
For advanced form design it helps to have an understanding of the form processing stages Opening a form:
1. 2. 3. 4.
Create several DOMs Merge data and template Perform calculations and validations Perform layout (pagination)
XFA Debugger gives insight into the final DOMs and resulting layout
XFA Debugger
How it is implemented:
Acroform PDF with a button that loads and opens an XFA-PDF Once open, uses the XFA scripting object model to extract the state of the form Passes the state to an embedded flash widget Flash widget decodes state and displays it graphically
(demo)
Use the JavaScript console Form Summary Tool Dump the data DOM XFA Debugger JSLint Accessibility Checker Develop your own Designer Macros
JS Lint
Thank you Douglas Crockford http://www.jslint.com/ (demo)
Accessibility Checker
Accessibility experience is only as good as the effort made by the form author Accessibility Checker is a Designer Macro that reports on a few basic properties throughout your form Does not check everything e.g. low contrast colors
(demo)
XLIFF Translator
Set up designer to embed xliff ids in your form template XLIFF translator sample is a form whose data schema is the XLIFF schema Translator sample updates the visible form when translating text
77
The scripting object model is the same as the model used by the runtime Several samples available to get started Lots of possibilities
Enforce your own design checks Apply bulk updates Generate reports ...
Steps to sanity
1. 2. 3. 4. 5. 6.
Be an expert Bring your forms to version 9.1 Share code Think Accessibility First Get to know the available tools Common problems, common solutions
Large PDF size Slow open time Sluggish performance Big memory footprint Layout issues (blank pages)
Embedded fonts
Use as few fonts as possible More control over font embedding on server:
Specify which fonts are embedded and which are not Specify thresholds for font subsetting
Fonts used by interactive form fields may not be subset Dont need to embed fonts installed by Adobe Reader
Embedded Images
Embedded Image
The image is *always* embedded in the PDF "Embedded" refers to whether it is embedded in the form design Whether the image is embedded in the template or not has a big impact on how it is stored in the PDF and how it is processed
Linked image
Embedded Image
<field name="ImageField1"> <value> <image contentType="image/jpg">
/9j/4S5+RXhpZgAASUkqAAgAAAAHAA8BAgAGAAAAYgAAABABAgAOAAAAaAAAABoBBQABAAAAdgAA ABsBBQABAAAAfgAAACgBAwABAAAAAgAAADIBAgAUAAAAhgAAAGmHBAABAAAAmgAAAKoCAABDYW5v bgBDYW5vbiBFT1MgNjBEAPAAAAABAAAA8AAAAAEAAAAyMDExOjAyOjA5IDIyOjA2OjIwAB0AmoIF AAEAAAD8AQAAnYIFAAEAAAAEAgAAIogDAAEAAAABAAAAJ4gDAAEAAACQAQAAMIgDAAEAAAACAAAA MogEAAEAAACQAQAAAJAHAAQAAAAwMjMwA5ACABQAAAAMAgAABJACABQAAAAgAgAAAZIKAAEAAAA0 AgAAApIFAAEAAAA8AgAABJIKAAEAAABEAgAABZIFAAEAAABMAgAAB5IDAAEAAAAFAAAACZIDAAEA AAAJAAAACpIFAAEAAABUAgAAkZICAAMAAAA1MgAAkpICAAMAAAA1MgAADqIFAAEAAABcAgAAD6IF AAEAAABkAgAAEKIDAAEAAAACAAAAAaQDAAEAAAAAAAAAAqQDAAEAAAABAAAAA6QDAAEAAAAAAAAA BqQDAAEAAAAAAAAAMaQCAAsAAABsAgAAMqQFAAQAAAB4AgAANKQCAAYAAACYAgAANaQCAAsAAACe AgAAAAAAAAEAAACgAAAAIwAAAAoAAAAyMDExOjAyOjA5IDIxOjU1OjU3ADIwMTE6MDI6MDkgMjE6 NTU6NTcASLlvAEBCDwD/gwUAoIYBAAAAAAABAAAAAwAAAAEAAABpAAAAAQAAAAAaTwCJAwAAALw0 AFMCAAAwNTcwMzA5MTI0AABpAAAAAQAAAGkAAAABAAAAAAAAAAAAAAAAAAAAAAAAADEwNW1tADAw MDAwMDAwMDAAAAYAAwEDAAEAAAAGAAAAGgEFAAEAAAD4AgAAGwEFAAEAAAAAAwAAKAEDAAEAAAAC AAAAAQIEAAEAAAAIAwAAAgIEAAEAAABuKwAAAAAAAEgAAAABAAAASAAAAAEAAAD/2P/uAA5BZG9i ZQBkAAAAAAH/2wCEAAYEBAQFBAYFBQYJBgUGCQsIBgYICwwKCgsKCgwQDAwMDAwMEAwMDAwMDAwM DAwMDAwMDAwMDAwMDAwMDAwMDAwBBwcHDQwNGBAQGBQODg4UFA4ODg4UEQwMDAwMEREMDAwMDAwR DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDP/AABEIAKsBAAMBEQACEQEDEQH/3QAEACD/xAGi AAAABwEBAQEBAAAAAAAAAAAEBQMCBgEABwgJCgsBAAICAwEBAQEBAAAAAAAAAAEAAgMEBQYHCAkK CxAAAgEDAwIEAgYHAwQCBgJzAQIDEQQABSESMUFRBhNhInGBFDKRoQcVsUIjwVLR4TMWYvAkcoLx
...
2011 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.
Embedded Image
Images embedded in the template are stored in base64 format Causes very large templates: base64 is 4/3 bigger than binary Forces Designer and Reader to keep the image in DOM memory Slower open times, higher memory footprint, slower performance in Reader and Designer Same image used <n> times is stored <n> times
Linked images are stored in a PDF names tree Linked images are all resolved to a single copy of the image
XDP (Template)
XDP (Template)
Names Tree
<image> <image>
Binary Image
Text labels instead of captions Unnecessary wrapper subforms Spacing objects Rectangles instead of borders Rich text instead of plain text Duplicated subform instead of repeated subform
(Rights enabling uses encryption) Large form open time degrades more quickly with decryption
Too many pages!? Tortured tables complex row/cell definitions Fix your binding warnings
Sluggish Performance
Form too large Too much script Circular script references Forced re-layout or re-merge
Use strict scoping Use strict scoping Use strict scoping Dont use Acroforms XMLData object (use E4X instead)
Layout issues
Many layout bug fixes in 9.0 and 9.1 Even if you know you cant use 9.1, you at least will know if it is a bug or a user error
Outline
1. 2. 3.
Forms, Applications and Monsters Steps to Sanity Form Design Review (Library of Congress)
Form Review
Review Step 1
Form Report:
Bring form version to 9.1 Turn on strict scoping Start size: 1.66MB New size after moving to 9.1: 938KB
Conversion to strict scoping and moving to a newer version can expose script errors Test the form and watch the script console With the LOC form, we needed to fix 3 scripting issues
100
Review Step 2
1 instance of "Times New Roman" 9 instances of "Georgia" 15 instances of "Verdana" 366 instances of "Myriad Pro"
(demo)
Two embedded images are 136KB and 26KB Replace with links
259 countries in each list 1813 total <text> elements for drop down lists (15% of form definition)
Many objects marked as growable that do not need to be growable Growable objects are more expensive than fixed size objects for layout Not a critical problem for this form, but on a large scale could become noticeable Likely an artefact of early version of Designer
105
data type according to field value always returns string always returns string
Validation on exit
ACRegistration.details.Author_Information.f2gpseu::exit - (JavaScript, client) if(pseudo_2g.rawValue=="Yes" && this.rawValue==null || pseudo_2g.rawValue=="Yes" && this.rawValue=="") { xfa.host.messageBox("You must enter a Pseudonym"); xfa.host.setFocus(this); }
(demo 2g) Exit event is not a good place to perform validations (save/close/reopen sequence will leave the field invalid but not detected) Exit validation traps the user in the mandatory field Validation logic is repeated in global script Should use presence="inactive" and mandatory setting
Alternative:
ACR.Author.pseudo_2g::change - (JavaScript, client) if(this.rawValue=="Yes") { f2gpseu.presence = "visible"; TextField2.presence = "visible"; anon_2g.rawValue = ""; } else { f2gpseu.presence = "invisible inactive"; f2gpseu.rawValue = ""; TextField2.presence = "invisible"; }
110
Validate numeric
ACR.Cert.f8dacc::exit - (JavaScript, client) formTools.isNumeric(this); isNumeric() if not all digits, message box error and resets focus back in the field Alternative is to prevent alpha input via the change event
112
113
114
resolveNode() vs resolveNodes()
Both functions accept a SOM expression argument and search from the context of the node where the call originates resolveNode() expects to return a single node and returns either a node or null resolveNodes() expects to return multiple nodes and returns a nodelist SOM expressions that include either "[*]" notation or a predicate expression will return a list Calling resolveNode() with an expression that returns a list will cause a runtime error
115
116
prePrint validation
if(Work_Being_Registered_Type.f1a.rawValue=="" || Work_Being_Registered_Type.f1a.rawValue==null) { vRequiredFieldsNotFilledFlag = true; errorMessages+="\r1a. - You must select the Type of Work..."; formTools.markFieldRequired(Work_Being_Registered_Type.f1a); } else { formTools.markFieldNotRequired(Work_Being_Registered_Type.f1a); }
Many blocks of code similar to this can be wholly eliminated if using mandatory field processing
117
prePrint validation
Need to push the validations out to the individual fields for encapsulated design
118
Form currently has over 1200 total lines of script In 9.1 the same functionality can be implemented in less than half the amount of script and with a better user experience
119
Questions?