Remove in-template javascript, add script files
authorThomas Berezansky <tsbere@mvlc.org>
Wed, 24 Aug 2011 15:31:59 +0000 (11:31 -0400)
committerJason Etheridge <jason@esilibrary.com>
Tue, 4 Oct 2011 17:18:42 +0000 (13:18 -0400)
Adds support for a print_custom.js file and an org unit specified file.

If either exists and contains a print_custom function it will be called
before printing to allow for DOM manipulation.

If neither exists the print_win.js file will call all functions it has
defined.

In addition, if any code sets do_print to false the window will close
instead of attempting to print.

The print_custom function will receive the type of template used, if any.
This only applies to "Receipt Template" based print jobs, and the type in
question is the "Type" that shows in the template editor.

Functions defined in print_win.js:

print_init
    Main function, checks for print_custom and does final printing

print_do_sums
    Does summing of values.

print_check_alt
    Does swapping out of template blocks with display:none styling.

print_check_noprint
    Disables printing under certain circumstances.

For more information about usage of the print_do_sums, print_check_alt,
and print_check_noprint functions check the comments in print_win.js.

Signed-off-by: Thomas Berezansky <tsbere@mvlc.org>
Signed-off-by: Jason Etheridge <jason@esilibrary.com>

Open-ILS/src/sql/Pg/950.data.seed-values.sql
Open-ILS/xul/staff_client/chrome/content/util/print.js
Open-ILS/xul/staff_client/chrome/content/util/print_win.js [new file with mode: 0644]

index e605528..1c84e97 100644 (file)
@@ -3734,6 +3734,17 @@ INSERT into config.org_unit_setting_type
         'coust', 'description'),
     'bool', null)
 
+,( 'print.custom_js_file', 'circ',
+    oils_i18n_gettext('print.custom_js_file',
+        'Printing: Custom Javascript File',
+        'coust', 'label'),
+    oils_i18n_gettext('print.custom_js_file',
+        'Full URL path to a Javascript File to be loaded when printing. Should'
+        || ' implement a print_custom function for DOM manipulation. Can change'
+        || ' the value of the do_print variable to false to cancel printing.',
+        'coust', 'description'),
+    'string', null)
+
 ,( 'serial.prev_issuance_copy_location', 'serial',
     oils_i18n_gettext('serial.prev_issuance_copy_location',
         'Previous Issuance Copy Location',
index a4222fa..320152c 100644 (file)
@@ -155,10 +155,25 @@ util.print.prototype = {
 
             switch(content_type) {
                 case 'text/html' :
-                    var jsrc = 'data:text/javascript,' + window.escape('var params = window.arguments[0]; window.go_print = window.arguments[1];');
-                    var print_url = 'data:text/html,'
-                        + '<html id="top"><head><script src="/xul/server/main/JSAN.js"></script><script src="' + window.escape(jsrc) + '"></script></head>'
-                        + '<body onload="try{go_print();}catch(E){alert(E);}">' + window.escape(msg) + '</body></html>';
+                    if(!params.type) {
+                        params.type = '';
+                    }
+                    var my_prefix = '/xul/server/';
+                    if(window.location.protocol == "chrome:") {
+                        // Likely in offline interface
+                        my_prefix = 'chrome://open_ils_staff_client/content/';
+                    } else {
+                        if(xulG && xulG.url_prefix) {
+                            my_prefix = xulG.url_prefix(my_prefix);
+                        }
+                    }
+                    var print_url = 'data:text/html,<html id="top"><head>'
+                        + '<script src="' + my_prefix + 'util/print_win.js"></script>'
+                        + '<script src="' + my_prefix + 'util/print_custom.js"></script>';
+                    if(this.data.hash.aous['print.custom_js_file']) {
+                        print_url += '<script src="' + this.data.hash.aous['print.custom_js_file'] + '"></script>';
+                    }
+                    print_url += '</head><body onload="try{print_init(\'' + params.type + '\');}catch(E){alert(E);}">' + window.escape(msg.replace(/<script[^>]*>.*?<\/script>/gi,'')) + '</body></html>';
                     w = obj.win.openDialog(print_url,'receipt_temp','chrome,resizable,minimizable', null, { "data" : params.data, "list" : params.list}, function() { 
                         try {
                             obj.NSPrint(w, silent, params);
@@ -265,6 +280,12 @@ util.print.prototype = {
         }
         if (params.footer) s += this.template_sub( params.footer, cols, params );
 
+        // Sanity check, no javascript in templates
+        // Note: [\s\S] is a workaround for . not including newlines.
+        s=s.replace(/<script[^>]*>[\s\S]*?<\/script[^>]*>/gi,'')
+        s=s.replace(/onload\s*=\s*"[^"]*"/gi,'');
+        s=s.replace(/onload\s*=\s*'[^']*'/gi,'');
+
         if (params.sample_frame) {
             var jsrc = 'data:text/javascript,' + window.escape('var params = { "data" : ' + js2JSON(params.data) + ', "list" : ' + js2JSON(params.list) + '};');
             params.sample_frame.setAttribute('src','data:text/html,<html id="top"><head><script src="' + window.escape(jsrc) + '"></script></head><body>' + window.escape(s) + '</body></html>');
diff --git a/Open-ILS/xul/staff_client/chrome/content/util/print_win.js b/Open-ILS/xul/staff_client/chrome/content/util/print_win.js
new file mode 100644 (file)
index 0000000..136b3bf
--- /dev/null
@@ -0,0 +1,165 @@
+// Print Window Functions
+// Loaded when print.js creates a window for printing
+
+var params = window.arguments[0];
+window.go_print = window.arguments[1];
+var do_print = true;
+
+function print_init(type) {
+    if (typeof print_custom == "function") {
+        print_custom(type);
+    } else {
+        print_do_sums();
+        print_check_alt();
+        print_check_noprint();
+    }
+    if (do_print) {
+        go_print();
+    } else {
+        window.close();
+    }
+}
+
+/* Example "swap slip" code
+ * Use example:
+ * <div altgroup="print1" altid="main">
+ * <span altcheck="print1">%some_replace%</span>
+ * <!-- Other slip stuff -->
+ * </div>
+ * <div altgroup="print1" altid="alt1" style="display: none">
+ * <!-- Alt slip stuff -->
+ * </div>
+ * <div altgroup="print1" altid="alt2" style="display: none">
+ * <!-- Second alt slip stuff -->
+ * </div>
+ * <div style="display: none">
+ * <span alt="print1" altshow="alt1">Code1</span>
+ * <span alt="print1" altshow="alt2">Code2</span>
+ * </div>
+ */
+function print_check_alt() {
+    var spans = document.getElementsByTagName('span');
+    if(!spans) return;
+    var groups_check = {};
+    var foundgroups = false;
+    for (var i = 0; i < spans.length; i++) {
+        var group = spans[i].getAttribute('altcheck');
+        if(group) {
+            groups_check[group] = spans[i].textContent;
+            foundgroups = true;
+        }
+    }
+    if(!foundgroups) return;
+    foundgroups = false;
+    var groups_show = {};
+    for (var i = 0; i < spans.length; i++) {
+        var group = spans[i].getAttribute('alt');
+        if(group && groups_check[group] && spans[i].textContent == groups_check[group]) {
+            groups_show[group] = spans[i].getAttribute('altshow');
+            foundgroups = true;
+        }
+    }
+    if(!foundgroups) return;
+    for (var i = 0; i < spans.length; i++) {
+        var group = spans[i].getAttribute('altgroup');
+        if(group && groups_check[group]) {
+            spans[i].style.display = (groups_show[group] == spans[i].getAttribute('altid') ? '' : 'none');
+        }
+    }
+    var divs = document.getElementsByTagName('div');
+    if (!divs) return;
+    for (var i = 0; i < divs.length; i++) {
+        var group = divs[i].getAttribute('altgroup');
+        if(group && groups_check[group]) {
+            divs[i].style.display = (groups_show[group] == divs[i].getAttribute('altid') ? '' : 'none');
+        }
+    }
+}
+
+/* Example "don't print" code
+ * Use example:
+ * <!-- blah blah -->
+ * <span noprintcheck="noprint1">%some_replace%</span>
+ * <span noprintcheck="noprint2">%some_other_replace%</span>
+ * <!-- blah blah -->
+ * <div style="display: none">
+ * <span noprint="noprint1">Code1</span>
+ * <span noprint="noprint2">Code2</span>
+ * </div>
+ */
+function print_check_noprint() {
+    var spans = document.getElementsByTagName('span');
+    if(!spans) return;
+    var noprints = {};
+    var foundnoprints = false;
+    for (var i = 0; i < spans.length; i++) {
+        var noprint = spans[i].getAttribute('noprintcheck');
+        if(noprint) {
+            noprints[noprint] = spans[i].textContent;
+            foundnoprints = true;
+        }
+    }
+    if(!foundnoprints) return;
+    for (var i = 0; i < spans.length; i++) {
+        var noprint = spans[i].getAttribute('noprint');
+        if(noprint) {
+            if(noprints[noprint] == spans[i].textContent) {
+                do_print = false;
+            }
+        }
+    }
+}
+
+/* Example "sum up" code
+ * Use example:
+ * <!-- blah blah -->
+ * <!-- Probably as line_item entries: -->
+ * <span sum="sum1">$5.00</span>
+ * <span sum="sum1">$15.00</span>
+ * <span sum="sum1">$25.00</span>
+ * <!-- blah blah -->
+ * $<span sumout="sum1" fixed="2"></span>
+ */
+function print_do_sums() {
+    var spans = document.getElementsByTagName('span');
+    if(!spans) return;
+    var sums = {};
+    var foundsums = false;
+    for (var i = 0; i < spans.length; i++) {
+        var sumset = spans[i].getAttribute("sum");
+        if(sumset) {
+            if(typeof sums[sumset] == 'undefined') {
+                sums[sumset] = 0.0;
+                foundsums = true;
+            }
+            var newVal = spans[i].textContent;
+            // strip off a single non-digit character
+            // Don't want to assume dollar sign
+            // But don't strip a -
+            newVal = newVal.replace(/^[^-0-9]/,'');
+            newVal = parseFloat(newVal);
+            if(!isNaN(newVal)) {
+                sums[sumset] += newVal;
+            }
+        }
+    }
+    if(!foundsums) return;
+    for (var i = 0; i < spans.length; i++) {
+        var sumset = spans[i].getAttribute("sumout");
+        if(sumset) {
+            if(typeof sums[sumset] == 'undefined') {
+                sums[sumset] = 0;
+            }
+            var fixed = spans[i].getAttribute("fixed");
+            if(fixed) {
+                fixed = parseInt(fixed);
+                if(isNaN(fixed)) {
+                    fixed = 0;
+                }
+                spans[i].textContent=sums[sumset].toFixed(fixed);
+            } else {
+                spans[i].textContent = sums[sumset];
+            }
+        }
+    }
+}