/** * This macro adds trace statements to all the script in a form. */ /** * emit a message with line breaks fixed for the log window. */ function dbg(msg) { designer.println(msg.replace(/[\n]/gm, "\r\n") + "\r\n"); } /** * Add trace to a JavaScript event */ function addJSTrace(vScript) { var nModified = 0; // Make sure we don't add trace a second time if (vScript.value.search(/scTrace\./m) === -1) { if (vScript.parent.className === "event") { // Prefix the script with the event activity and the object SOM expression var sActivity = vScript.parent.activity; if (sActivity === "ready") { sActivity = vScript.parent.ref + ":" + sActivity; } vScript.value = "scTrace.traceContext(\"" + sActivity + ":\", this);\n" + vScript.value; } else { // Prefix the calculation/validation etc with the SOM expression vScript.value = "scTrace.traceContext(\"" + vScript.parent.className + ":\", this);\n" + vScript.value; } nModified = 1; } return nModified; } /** * Add trace to a FormCalc event */ function addFCTrace(vScript) { var nModified = 0; // Don't add trace a second time if (vScript.value.search(/scTrace\./m) === -1) { // For Formcalc scripts, we populate event properties and execEvent() on a "full" event that // we've also injected if (vScript.parent.className === "event") { var sActivity = vScript.parent.activity; if (sActivity === "ready") { sActivity = vScript.parent.target + ":" + sActivity; } vScript.value = ";scTrace.trace\nxfa.event.fullText = \"" + sActivity + "\"\nxfa.event.newText = $.somExpression\n" + "$form.#subform.execEvent(\"full\")\n" + vScript.value; } else { vScript.value = ";scTrace.trace\nxfa.event.fullText = \"" + vScript.parent.className + "\"\nxfa.event.newText = $.somExpression\n" + "$form.#subform.execEvent(\"full\")\n" + vScript.value; } nModified = 1; } return nModified; } /** * Recursive function to inject trace commands in script */ function addTraceToScripts(vElement) { var nCount = 0; // Found a script. Add trace if (vElement.className === "script") { if (vElement.parent.className === "event" && vElement.parent.activity === "indexChange") { // the runtime doesn't deal well with trace on indexChange events. return nCount; } if (vElement.contentType === "application/x-javascript") { nCount += addJSTrace(vElement); } else { nCount += addFCTrace(vElement); } } // recurse. The script performance improves dramatically if we limit the number of nodes we recurse into var vNodes = vElement.nodes; for (var i = 0; i < vNodes.length; i++) { var vChild = vNodes.item(i); sClassName = vChild.className; if (vChild.isContainer || sClassName === "calculate" || sClassName === "validate" || sClassName === "breakAfter" || sClassName === "breakBefore"|| sClassName === "event" || sClassName === "proto" || sClassName === "script" || sClassName === "traversal" || sClassName === "traverse" && sClassName !== "variables") { nCount += addTraceToScripts(vChild); } } return nCount; } try { // Keep track of the start timestamp so we can measure performance var nStart = (new Date()).getTime(); var vRootSF = xfa.template["#subform"]; // Do the work. // Add full and pre-print events if (vRootSF.nodes.namedItem("DebugEvent") === null) { // The full event is used by formcalc scripts to emit text var vEvent = xfa.template.createNode("event", "DebugEvent"); vEvent.activity = "full"; var vScript = xfa.template.createNode("script"); vScript.contentType = "application/x-javascript"; vScript.value = "scTrace.traceContext(xfa.event.fullText, xfa.resolveNode(xfa.event.newText))\n"; vEvent.nodes.append(vScript); vRootSF.nodes.append(vEvent); // the pre-print event is used to dump output to a text file. vEvent = xfa.template.createNode("event", "DebugDump"); vEvent.activity = "prePrint"; vEvent.ref = "$host"; vScript = xfa.template.createNode("script"); vScript.contentType = "application/x-javascript"; vScript.value = "scTrace.dumpTrace(true);"; vEvent.nodes.append(vScript); vRootSF.nodes.append(vEvent); } // Add a top-level script object for reference by all the trace commands if (vRootSF.resolveNode("scTrace") === null) { var vScript = xfa.template.createNode("script", "scTrace"); vScript.contentType = "application/x-javascript"; vScript.value = "var TRACE_ARRAY = [];\ function traceContext(sDBG, vObject) {\ var sContext = vObject.somExpression;\ sContext = sContext.replace(/xfa\\[0\\]\\.form\\[0\\]\\./, '');\ sContext = sContext.replace(/\\[0\\]/g, '');\ TRACE_ARRAY.push(sDBG + ' ' + sContext);\ }\ function dumpTrace() {\ event.target.createDataObject('DEBUG.txt', TRACE_ARRAY.join('\\r\\n'));\ event.target.exportDataObject('DEBUG.txt');\ event.target.removeDataObject('DEBUG.txt');\ TRACE_ARRAY = [];\ }"; vRootSF.variables.nodes.append(vScript); } // Now modify all the scripts var count = addTraceToScripts(vRootSF); var nEnd = (new Date()).getTime(); // output messages. dbg("Added trace to " + count.toString() + " scripts"); dbg("elapsed: " + (nEnd - nStart).toString()); designer.alert("Added trace to " + count.toString() + " scripts"); } catch (e) { dbg(e.message + "\nat:" + e.line + "\nsource:" + e.source.split("\n")[e.line-1]); }