home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 November / PCWNOV08.iso / Software / Freeware / NoScript 1.7.7 / noscript-1.7.7-fx+mz+sm.xpi / chrome / noscript.jar / content / noscript / noscriptOptions.js < prev    next >
Encoding:
JavaScript  |  2008-07-14  |  15.9 KB  |  494 lines

  1. /***** BEGIN LICENSE BLOCK *****
  2.  
  3. NoScript - a Firefox extension for whitelist driven safe JavaScript execution
  4. Copyright (C) 2004-2008 Giorgio Maone - g.maone@informaction.com
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  
  20. ***** END LICENSE BLOCK *****/
  21.  
  22.  
  23.  
  24. var nsopt = {
  25.   
  26.   serv: noscriptUtil.service,
  27.   dom2: /^(?:http[s]?|file):\/\/([^\.\?\/#,;:\\\@]+(:?\.[^\.\?\/#,;:\\\@]+$|$))/,
  28.   utils: null,
  29.   init: function() {
  30.     const ns = this.serv; 
  31.     if(ns.uninstalling) { // this should never happen! 
  32.       window.close();
  33.       return;
  34.     }
  35.     
  36.     this.utils = new UIUtils(ns);
  37.     this.utils.resumeTabSelections();
  38.     
  39.     var locked = this.serv.locked;
  40.     for each (widget in ["urlText","urlList", "jsglobal", "addButton", "removeButton", "importButton", "exportButton"]) {
  41.       this[widget] = document.getElementById(widget);
  42.       if(locked) this[widget].disabled = true;
  43.     }
  44.      // forbid <a ping>
  45.     var pingCbx = document.getElementById("mozopt-browser.send_pings");
  46.     if(pingCbx.getAttribute("label").indexOf("Allow ") == 0) { 
  47.       pingCbx.setAttribute("label", noscriptUtil.getString("allowLocal", ["<a ping...>"]));
  48.       document.getElementById("opt-noping")
  49.               .setAttribute("label", noscriptUtil.getString("forbidLocal", ["<a ping...>"]));
  50.     }
  51.     
  52.     this.trustedSites = ns.jsPolicySites.clone();
  53.     this.untrustedSites = ns.untrustedSites.clone();
  54.     this.tempSites = ns.tempSites.clone();
  55.     this.populateUrlList();
  56.     
  57.     this.jsglobal.checked = ns.jsEnabled;
  58.  
  59.     this.utils.visitCheckboxes(function(prefName, inverse, checkbox, mozilla) {
  60.         try {
  61.           var val = mozilla ? ns.prefService.getBoolPref(prefName) : ns.getPref(prefName);
  62.           checkbox.setAttribute("checked", inverse ? !val : val);
  63.           if(ns.prefService.prefIsLocked(mozilla ? prefName : "noscript." + prefName)) {
  64.             checkbox.setAttribute("disabled", true);
  65.           }
  66.         } catch(ex) {}
  67.       }
  68.     );
  69.     
  70.     document.getElementById("opt-showPermanent").setAttribute("label", noscriptUtil.getString("allowLocal", ["[...]"]));
  71.     document.getElementById("opt-showTemp").setAttribute("label", noscriptUtil.getString("allowTemp", ["[...]"]));
  72.     document.getElementById("opt-showDistrust").setAttribute("label", noscriptUtil.getString("distrust", ["[...]"]));
  73.     document.getElementById("opt-showGlobal").setAttribute("label", noscriptUtil.getString("allowGlobal"));
  74.   
  75.     var notifyHideLabels = noscriptUtil.getString("notifyHide").split("%S");
  76.     document.getElementById("opt-notify.hide").setAttribute("label", notifyHideLabels[0]);
  77.     document.getElementById("notifyDelayLabel").setAttribute("value", notifyHideLabels[1]);
  78.     document.getElementById("notifyDelay").value = ns.getPref("notify.hideDelay", 5);
  79.     
  80.     this.soundChooser.setSample(ns.getPref("sound.block"));
  81.     
  82.     this.autoAllowGroup = new ConditionalGroup(ns, "autoAllow", 0);
  83.     this.toggleGroup = new ConditionalGroup(ns, "toolbarToggle", 3);
  84.     
  85.     var shortcut = ns.getPref("keys.toggle");
  86.     if(shortcut) {
  87.       shortcut = shortcut.replace(/VK_([^\.]*).*/g, "$1").replace(/\s+/g, '+').replace(/_/g, ' ');
  88.       var shortcutLabel = document.getElementById("toolbarToggle-shortcut");
  89.       shortcutLabel.value = "(" + shortcut + ")";
  90.       shortcutLabel.removeAttribute("hidden");
  91.     }
  92.     
  93.     this.xssEx = new RegExpController(
  94.         "xssEx", 
  95.         ns.rxParsers.multi,
  96.         ns.getPref("filterXExceptions"));
  97.     this.jarEx = new  RegExpController(
  98.         "jarEx", 
  99.         ns.rxParsers.multi,
  100.         ns.getPref("forbidJarDocumentsExceptions"));
  101.     
  102.     // hide incompatible options
  103.     if(top.opener && top.opener.noscriptOverlay && !top.opener.noscriptOverlay.getNotificationBox()) {
  104.       // Moz/SeaMonkey, no notifications
  105.       document.getElementById("fx-notifications").setAttribute("hidden", "true");
  106.     }
  107.     
  108.     // document.getElementById("policy-tree").view = policyModel;
  109.     window.sizeToContent();
  110.     
  111.     this.addButton.setAttribute("enabled", "false");
  112.     this.removeButton.setAttribute("enabled", "false");
  113.   },
  114.   
  115.   reset: function() {
  116.     
  117.     if(!noscriptUtil.prompter.confirm(window, 
  118.           noscriptUtil.getString("reset.title"),
  119.           noscriptUtil.getString("reset.warning"))
  120.       ) return;
  121.     
  122.     this.serv.resetDefaults();
  123.     this.utils.persistTabSelections();
  124.     var op = top.opener;
  125.     if(op && op.noscriptUtil) {
  126.       op.setTimeout(function() {
  127.           op.noscriptUtil.openOptionsDialog();
  128.       }, 10);
  129.     }
  130.     window.close();
  131.   },
  132.   
  133.   save: function() {
  134.     const ns = this.serv;
  135.     
  136.     this.utils.visitCheckboxes(
  137.       function(prefName, inverse, checkbox, mozilla) {
  138.         if(checkbox.getAttribute("collapsed")!="true") {
  139.           const checked = checkbox.getAttribute("checked") == "true";
  140.           const requestedVal = inverse ? !checked : checked;
  141.           
  142.           if(mozilla) {
  143.             try {
  144.               ns.prefService.setBoolPref(prefName, requestedVal);
  145.             } catch(ex) {}
  146.             return;
  147.           }
  148.           
  149.           const prevVal = ns.getPref(prefName);
  150.           if(requestedVal != prevVal) {
  151.             ns.setPref(prefName, requestedVal);
  152.           }
  153.         }
  154.       }
  155.     );
  156.     
  157.     ns.setPref("notify.hideDelay", parseInt(document.getElementById("notifyDelay").value) || 
  158.               ns.getPref("notify.hideDelay", 5));
  159.  
  160.     ns.setPref("sound.block", this.soundChooser.getSample());
  161.     
  162.     this.autoAllowGroup.persist();
  163.     this.toggleGroup.persist();
  164.     
  165.     var exVal = this.xssEx.getValue();
  166.     if(this.xssEx.validate() || !/\S/.test(exVal)) 
  167.       ns.setPref("filterXExceptions", exVal);
  168.     var exVal = this.jarEx.getValue();
  169.     if(this.jarEx.validate() || !/\S/.test(exVal)) 
  170.       ns.setPref("forbidJarDocumentsExceptions", exVal);
  171.     
  172.     if (this.tempRevoked) {
  173.       ns.resetAllowedObjects();
  174.     }
  175.     
  176.     var global = this.jsglobal.getAttribute("checked") == "true";
  177.     var untrustedSites = this.untrustedSites;
  178.     var trustedSites = this.trustedSites;
  179.     var tempSites = this.tempSites;
  180.     
  181.     ns.safeCapsOp(function() {
  182.       if(ns.untrustedSites.sitesString != untrustedSites.sitesString
  183.           || ns.jsPolicySites.sitesString != trustedSites.sitesString
  184.           || ns.tempSites.sitesString != tempSites.sitesString) {
  185.         ns.untrustedSites.sitesString = untrustedSites.sitesString;
  186.         ns.persistUntrusted();
  187.         ns.setPref("temp", tempSites.sitesString);
  188.         ns.setJSEnabled(trustedSites.sitesList, true, true);
  189.       }
  190.       ns.jsEnabled = global;
  191.     });
  192.   },
  193.  
  194.   urlListChanged: function() {
  195.     const selectedItems = this.urlList.selectedItems;
  196.     var removeDisabled = true;
  197.     for(var j = selectedItems.length; j-- > 0;) {
  198.       if(selectedItems[j].getAttribute("disabled") != "true") {
  199.         removeDisabled = false;
  200.         break;
  201.       }
  202.     }  
  203.     this.removeButton.setAttribute("disabled", removeDisabled);
  204.     document.getElementById("revokeButton")
  205.       .setAttribute("disabled", this.tempRevoked || 
  206.           !(this.tempSites.sitesString || this.serv.objectWhitelistLen));
  207.     this.urlChanged();
  208.   },
  209.   
  210.   urlChanged: function() {
  211.     var url = this.urlText.value;
  212.     if(url.match(/\s/)) url = this.urlText.value = url.replace(/\s/g,'');
  213.     var addEnabled = url.length > 0 && (url = this.serv.getSite(url)) ;
  214.     if(addEnabled) {
  215.       var match = url.match(this.dom2);
  216.       if(match) url = match[1];
  217.       url = this.trustedSites.matches(url);
  218.       if(!(addEnabled = !url)) {
  219.         this.ensureVisible(url);
  220.       }
  221.     }
  222.     this.addButton.setAttribute("disabled", !addEnabled);
  223.   },
  224.   
  225.   notifyHideDelay: {
  226.     onInput: function(txt) {
  227.       if(/\D/.test(txt.value)) txt.value = txt.value.replace(/\D/, "");
  228.     },
  229.     onChange: function(txt) {
  230.       txt.value = parseInt(txt.value) || noscriptUtil.service.getPref("notify.hideDelay", 5);
  231.     }
  232.   },
  233.   
  234.   ensureVisible: function(site) {
  235.     var item;
  236.     const ul = this.urlList;
  237.     for(var j = ul.getRowCount(); j-- > 0;) {
  238.       if((item = ul.getItemAtIndex(j)).getAttribute("value") == site) {
  239.         ul.ensureElementIsVisible(item);
  240.       }
  241.     }
  242.   },
  243.   
  244.   populateUrlList: function() {
  245.     const policy = this.trustedSites;
  246.     const sites = this.trustedSites.sitesList;
  247.     const ul = this.urlList;
  248.     const ns = this.serv;
  249.     for(var j = ul.getRowCount(); j-- > 0; ul.removeItemAt(j));
  250.     const dom2 = this.dom2;
  251.     var site, item;
  252.     var match, k, len;
  253.     var tempMap = this.tempSites.sitesMap;
  254.     for(j = 0, len = sites.length; j < len; j++) {
  255.       site = sites[j];
  256.       // skip protocol + 2nd level domain URLs
  257.       if((match = site.match(dom2)) && policy.matches(item = match[1])) 
  258.         continue;
  259.       
  260.       item = ul.appendItem(site, site);
  261.       if(ns.isPermanent(site)) { 
  262.         item.setAttribute("disabled", "true");
  263.       }
  264.       item.style.fontStyle = (site in tempMap) ? "italic" : "normal";
  265.     }
  266.     this.urlListChanged();
  267.   },
  268.   
  269.   allow: function() {
  270.     const site = this.serv.getSite(this.urlText.value);
  271.     this.trustedSites.add(site);
  272.     this.tempSites.remove(site, true, true); // see noscriptService#eraseTemp()
  273.     this.untrustedSites.remove(site, false, !this.serv.mustCascadeTrust(site, false));
  274.     this.populateUrlList();
  275.     this.ensureVisible(site);
  276.     this.addButton.setAttribute("disabled", "true");
  277.   },
  278.   
  279.   remove: function() {
  280.     const ns = this.serv;
  281.     const ul = this.urlList;
  282.     var visIdx = ul.getIndexOfFirstVisibleRow();
  283.     var lastIdx = visIdx + ul.getNumberOfVisibleRows();
  284.     const selectedItems = ul.selectedItems;
  285.     
  286.     if(selectedItems.length == 1) {
  287.       var site = selectedItems[0].value;
  288.       if(!ns.isPermanent(site)) {
  289.         ul.removeItemAt(ul.getIndexOfItem(selectedItems[0]));
  290.         this.trustedSites.remove(site, true);
  291.       }
  292.       return;
  293.     }
  294.     
  295.     var removed = [];
  296.     for(var j = selectedItems.length; j-- > 0;) {
  297.       if(!ns.isPermanent(site = selectedItems[j].value)) {
  298.         removed.push(site);
  299.       }
  300.     }
  301.     this.trustedSites.remove(removed, true); // keepUp
  302.     // TODO: hide flickering
  303.     this.populateUrlList();
  304.     try {
  305.       var rowCount = ul.getRowCount();
  306.       if(rowCount > lastIdx) {
  307.         ul.scrollToIndex(visIdx);
  308.       } else {
  309.         ul.ensureIndexIsVisible(rowCount - 1);
  310.       } 
  311.     } catch(e) {}
  312.   },
  313.   
  314.   tempRevoked: false,
  315.   revokeTemp: function() {
  316.     const ns = this.serv;
  317.     this.trustedSites.remove(this.tempSites.sitesList, true, true); 
  318.     this.trustedSites.add(ns.permanentSites.sitesList);
  319.     this.tempSites.sitesString = "";
  320.     this.tempRevoked = true;
  321.     this.populateUrlList();
  322.   },
  323.   
  324.   _soundChooser: null,
  325.   get soundChooser() {
  326.     return this._soundChooser || 
  327.       (this._soundChooser = 
  328.         new SoundChooser(
  329.         "sampleURL", 
  330.         this.buttonToTitle("sampleChooseButton"),
  331.         noscriptUtil.service,
  332.         "chrome://noscript/skin/block.wav"
  333.       ));
  334.   },
  335.   
  336.   
  337.   importExport: function(op) {
  338.     const title = this.buttonToTitle(op + "Button");
  339.     try {
  340.       const cc = Components.classes;
  341.       const ci = Components.interfaces;
  342.       const IFP = ci.nsIFilePicker;
  343.       const fp = cc["@mozilla.org/filepicker;1"].createInstance(IFP);
  344.       
  345.       fp.init(window,title, op == "import" ? IFP.modeOpen : IFP.modeSave);
  346.       fp.appendFilters(IFP.filterText);
  347.       fp.appendFilters(IFP.filterAll);
  348.       fp.filterIndex = 0;
  349.       fp.defaultExtension = ".txt";
  350.       const ret = fp.show();
  351.       if(ret == IFP.returnOK || 
  352.           ret == IFP.returnReplace) {
  353.         this[op + "List"](fp.file);
  354.       }
  355.     } catch(ex) {
  356.       noscriptUtil.prompter.alert(window, title, ex.toString());
  357.     }
  358.   },
  359.   
  360.   importList: function(file) {
  361.     var all = this.serv.readFile(file).replace(/\s+/g, "\n");
  362.     var untrustedPos = all.indexOf("[UNTRUSTED]");
  363.     if(untrustedPos < 0) {
  364.       this.trustedSites.sitesString += "\n" + all;
  365.     } else {
  366.       this.trustedSites.sitesString += "\n" + all.substring(0, untrustedPos);
  367.       this.untrustedSites.sitesString += all.substring(all.indexOf("\n", untrustedPos + 2));
  368.     }
  369.     this.untrustedSites.remove(this.trustedSites.sitesList, false, true);
  370.     this.populateUrlList();
  371.     return null;
  372.   },
  373.   
  374.   exportList: function(file) {
  375.     this.serv.writeFile(file, 
  376.       this.trustedSites.sitesList.join("\n") + 
  377.       "\n[UNTRUSTED]\n" +
  378.       this.untrustedSites.sitesList.join("\n")
  379.     );
  380.     return null;
  381.   },
  382.   
  383.   syncNsel: function(cbx) {
  384.     var blockNSWB = document.getElementById("opt-blockNSWB");
  385.     if(cbx.checked) {
  386.       blockNSWB.disabled = true;
  387.       blockNSWB.checked = true;
  388.     } else {
  389.       blockNSWB.disabled = false;
  390.     }
  391.   },
  392.   
  393.   buttonToTitle: function(btid) {
  394.     return "NoScript - " + document.getElementById(btid).getAttribute("label");
  395.   }
  396. }
  397.  
  398. /*
  399. function Site(url, perm, temp, disabled) {
  400.   this.url = url;
  401.   this.perm = perm;
  402.   this.temp = temp;
  403.   this.disabled = disabled;
  404. }
  405.  
  406. Site.prototype = {
  407.   get status() { return this.perm ? "TRUSTED" : "UNTRUSTED" }
  408. }
  409.  
  410. Site.sort = function(array, field, descending) {
  411.   array.sort(function(a,b) {
  412.     var res;
  413.     if(field in a) {
  414.       if(field in b) {
  415.         a = a[field]; b = b[field];
  416.         res =a < b ? -1 : a > b ? 1 : 0;
  417.       } else {
  418.         res = 1;
  419.       }
  420.     } else {
  421.       res=(field in b)? -1 : 0;
  422.     }
  423.     return descending ? -res : res;
  424.   });
  425.   this.currentSorting.field = field;
  426.   this.currentSorting.descending = descending;
  427.   return array;
  428. }
  429.  
  430. Site.currentSorting = { field: 'url', descending: false };
  431.  
  432. var policyModel = {
  433.   data: [],
  434.   get rowCount() { return this.data.length;  },
  435.   
  436.   _getColName: function(col) {
  437.     if(!col) return null;
  438.     const id=(col && col.id)?col.id:col;
  439.     var pos = id.lastIndexOf("-");
  440.     return id.substring(pos + 1);
  441.   },
  442.   getCellText: function(row, col) {
  443.     var colName = this._getColName(col);
  444.     if(!colName) return "";
  445.     return this.data[row][colName];
  446.   },
  447.   //setCellText: function(row, column, text) {},
  448.   setTree: function(treeBox) { this.treeBox = treeBox; },
  449.   isContainer: function(index) { return false; },
  450.   isSeparator: function(index) { return false; }, 
  451.   isSorted: function() {},
  452.   getLevel: function(index) { return 0; },
  453.   getImageSrc: function(row, col) {
  454.    return null;
  455.   },
  456.   getCellProperties: function(row, col, props) {},
  457.   getColumnProperties: function(column, elem, prop) {}, 
  458.   getRowProperties: function(row, props) { },
  459.  
  460.   isContainerOpen: function(index) { },
  461.   isContainerEmpty: function(index) { return false; },
  462.   canDropOn: function(index) { return false; },
  463.   canDropBeforeAfter: function(index, before) { return false; },
  464.   drop: function(row, orientation) { return false; },
  465.   
  466.   getParentIndex: function(index) { return 0; },
  467.   hasNextSibling: function(index, after) { return false; },
  468.   getProgressMode: function(row, column) { },
  469.   getCellValue: function(row, column) { },
  470.   toggleOpenState: function(index) { },
  471.   cycleHeader: function(col, elem) { 
  472.     if(!elem) {
  473.       elem=col.element;
  474.     }
  475.     const colName = this._getColName(col);
  476.     const descending = elem.getAttribute("sortDirection") == "ascending";
  477.     elem.setAttribute("sortDirection", descending ? "descending" : "ascending");
  478.     Sitesort(this.data, colName, descending);
  479.     this.treeBox.invalidate();
  480.   },
  481.   selectionChanged: function() {  
  482.     this._messageSelected(this.data[this.selection.currentIndex]);
  483.   },
  484.   
  485.   cycleCell: function(row, column) { },
  486.   isEditable: function(row, column) { return false; },
  487.   performAction: function(action) { },
  488.   performActionOnRow: function(action, row) { },
  489.   performActionOnCell: function(action, row, column) { }
  490. };
  491. */
  492.  
  493.  
  494.