| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * This Source Code is subject to the terms of the Mozilla Public License | 2  * This Source Code is subject to the terms of the Mozilla Public License | 
| 3  * version 2.0 (the "License"). You can obtain a copy of the License at | 3  * version 2.0 (the "License"). You can obtain a copy of the License at | 
| 4  * http://mozilla.org/MPL/2.0/. | 4  * http://mozilla.org/MPL/2.0/. | 
| 5  */ | 5  */ | 
| 6 | 6 | 
| 7 const Cc = Components.classes; | 7 const Cc = Components.classes; | 
| 8 const Ci = Components.interfaces; | 8 const Ci = Components.interfaces; | 
| 9 const Cr = Components.results; | 9 const Cr = Components.results; | 
| 10 const Cu = Components.utils; | 10 const Cu = Components.utils; | 
| 11 | 11 | 
| 12 Cu.import("resource://gre/modules/Services.jsm"); | 12 Cu.import("resource://gre/modules/Services.jsm"); | 
| 13 | 13 | 
| 14 function abprequire(module) | 14 function abprequire(module) | 
| 15 { | 15 { | 
| 16   let result = {}; | 16   let result = {}; | 
| 17   result.wrappedJSObject = result; | 17   result.wrappedJSObject = result; | 
| 18   Services.obs.notifyObservers(result, "adblockplus-require", module); | 18   Services.obs.notifyObservers(result, "adblockplus-require", module); | 
| 19   return result.exports; | 19   return result.exports; | 
| 20 } | 20 } | 
| 21 | 21 | 
| 22 let {Policy} = abprequire("contentPolicy"); | 22 let {Policy} = abprequire("contentPolicy"); | 
| 23 let {RequestNotifier} = abprequire("requestNotifier"); | 23 let {RequestNotifier} = abprequire("requestNotifier"); | 
| 24 let {Filter} = abprequire("filterClasses"); | 24 let {Filter} = abprequire("filterClasses"); | 
| 25 | 25 | 
| 26 let policyGlobal = Cu.getGlobalForObject(Policy); | 26 let origShouldAllow = Policy.shouldAllow; | 
| 27 let PolicyPrivate = null; | 27 if (!origShouldAllow) | 
| 28 |  | 
| 29 if ("PolicyImplementation" in policyGlobal)  // ABP 2.1+ with scope separation |  | 
| 30   PolicyPrivate = policyGlobal.PolicyImplementation; |  | 
| 31 else if ("require" in policyGlobal)               // ABP 2.1+ without scope sepa
     ration |  | 
| 32   PolicyPrivate = policyGlobal.require.scopes.contentPolicy.PolicyImplementation
     ; |  | 
| 33 else |  | 
| 34   window.close(); | 28   window.close(); | 
| 35 | 29 | 
| 36 let origShouldLoad = PolicyPrivate.shouldLoad; |  | 
| 37 let origProcessNode = Policy.processNode; |  | 
| 38 |  | 
| 39 let currentData = null; | 30 let currentData = null; | 
| 40 let processingQueue = []; | 31 let processingQueue = []; | 
| 41 let notifier = null; | 32 let notifier = null; | 
| 42 | 33 | 
| 43 // Randomize URI to work around bug 719376 | 34 // Randomize URI to work around bug 719376 | 
| 44 let stringBundle = Services.strings.createBundle("chrome://abpwatcher/locale/glo
     bal.properties?" + Math.random()); | 35 let stringBundle = Services.strings.createBundle("chrome://abpwatcher/locale/glo
     bal.properties?" + Math.random()); | 
| 45 | 36 | 
| 46 let clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.
     nsIClipboardHelper); | 37 let clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.
     nsIClipboardHelper); | 
| 47 | 38 | 
| 48 function init() | 39 function init() | 
| 49 { | 40 { | 
| 50   let list = document.getElementById("list"); | 41   let list = document.getElementById("list"); | 
| 51   list.view = treeView; | 42   list.view = treeView; | 
| 52   list.focus(); | 43   list.focus(); | 
| 53 | 44 | 
| 54   treeView.addObserver(updateProcessingTime); | 45   treeView.addObserver(updateProcessingTime); | 
| 55   updateProcessingTime(treeView, "refresh"); | 46   updateProcessingTime(treeView, "refresh"); | 
| 56 | 47 | 
| 57   // Make sure the tree view has correct filters | 48   // Make sure the tree view has correct filters | 
| 58   document.getElementById("ignore-early").doCommand(); |  | 
| 59   document.getElementById("filterText").doCommand(); | 49   document.getElementById("filterText").doCommand(); | 
| 60 | 50 | 
| 61   notifier = new RequestNotifier(null, handleFilterHit); | 51   notifier = new RequestNotifier(null, handleFilterHit); | 
| 62 | 52 | 
| 63   PolicyPrivate.shouldLoad = replacementShouldLoad; | 53   Policy.shouldAllow = replacementShouldAllow; | 
| 64   Policy.processNode = replacementProcessNode; |  | 
| 65   setInterval(processQueue, 200); | 54   setInterval(processQueue, 200); | 
| 66 } | 55 } | 
| 67 | 56 | 
| 68 function E(id) | 57 function E(id) | 
| 69 { | 58 { | 
| 70   return document.getElementById(id); | 59   return document.getElementById(id); | 
| 71 } | 60 } | 
| 72 | 61 | 
| 73 function replacementShouldLoad(contentType, contentLocation, requestOrigin, node
     , mimeTypeGuess, extra) | 62 function replacementShouldAllow({contentType, location, frames, isPrivate}) | 
| 74 { | 63 { | 
| 75   let startTime = null; | 64   let startTime = null; | 
| 76   try | 65   try | 
| 77   { | 66   { | 
| 78     currentData = {internal: false, earlyReturn: true, filters: []}; | 67     currentData = { | 
|  | 68       filters: [], | 
|  | 69       type: contentType, | 
|  | 70       location: location, | 
|  | 71       frames: frames, | 
|  | 72       isPrivate: isPrivate | 
|  | 73     }; | 
| 79     startTime = Date.now(); | 74     startTime = Date.now(); | 
| 80 |  | 
| 81     if (contentLocation) |  | 
| 82       currentData.location = contentLocation.spec; |  | 
| 83     if (requestOrigin) |  | 
| 84       currentData.origin = requestOrigin.spec; |  | 
| 85 |  | 
| 86     currentData.type = contentType; |  | 
| 87   } catch(e) {} |  | 
| 88 |  | 
| 89   let ret; |  | 
| 90   try |  | 
| 91   { |  | 
| 92     ret = origShouldLoad.apply(this, arguments); |  | 
| 93     return ret; |  | 
| 94   } |  | 
| 95   finally |  | 
| 96   { |  | 
| 97     if (startTime !== null) |  | 
| 98       currentData.processingTime = (Date.now() - startTime); |  | 
| 99     currentData.result = (ret == Ci.nsIContentPolicy.ACCEPT); |  | 
| 100 |  | 
| 101     processingQueue.push(currentData); |  | 
| 102     currentData = null; |  | 
| 103   } |  | 
| 104 } |  | 
| 105 |  | 
| 106 function replacementProcessNode(wnd, node, contentType, location, collapse) |  | 
| 107 { |  | 
| 108   let startTime = null; |  | 
| 109   try |  | 
| 110   { |  | 
| 111     if (currentData && !("context" in currentData)) |  | 
| 112     { |  | 
| 113       currentData.earlyReturn = false; |  | 
| 114       currentData.context = node; |  | 
| 115       currentData.window = wnd; |  | 
| 116       currentData.internalType = contentType; |  | 
| 117       if (location) |  | 
| 118           currentData.internalLocation = location.spec; |  | 
| 119     } |  | 
| 120     else |  | 
| 121     { |  | 
| 122       // shouldLoad wasn't called - this isn't being called by content policy |  | 
| 123       let locationString = (location instanceof Filter ? location.text : locatio
     n.spec); |  | 
| 124 |  | 
| 125       currentData = { |  | 
| 126         internal: true, |  | 
| 127         earlyReturn: false, |  | 
| 128         filters: [], |  | 
| 129         location: locationString, |  | 
| 130         internalLocation: locationString, |  | 
| 131         context: node, |  | 
| 132         window: wnd, |  | 
| 133         type: contentType, |  | 
| 134         internalType: contentType |  | 
| 135       }; |  | 
| 136       startTime = Date.now(); |  | 
| 137     } |  | 
| 138   } | 75   } | 
| 139   catch(e) | 76   catch(e) | 
| 140   { | 77   { | 
| 141     Cu.reportError(e); | 78     Cu.reportError(e); | 
| 142   } | 79   } | 
| 143 | 80 | 
| 144   let ret; | 81   let ret; | 
| 145   try | 82   try | 
| 146   { | 83   { | 
| 147     ret = origProcessNode.apply(this, arguments); | 84     ret = origShouldAllow.apply(this, arguments); | 
| 148     return ret; | 85     return ret; | 
| 149   } | 86   } | 
| 150   finally | 87   finally | 
| 151   { | 88   { | 
| 152     if (startTime !== null) | 89     if (startTime !== null) | 
| 153     { | 90     { | 
| 154       currentData.processingTime = (Date.now() - startTime); | 91       currentData.processingTime = (Date.now() - startTime); | 
| 155       currentData.result = (ret == true); | 92       currentData.result = ret; | 
| 156 | 93 | 
| 157       processingQueue.push(currentData); | 94       processingQueue.push(currentData); | 
| 158       currentData = null; | 95       currentData = null; | 
| 159     } | 96     } | 
| 160   } | 97   } | 
| 161 } | 98 } | 
| 162 | 99 | 
| 163 function destroy() | 100 function destroy() | 
| 164 { | 101 { | 
| 165   if (notifier) | 102   if (notifier) | 
| 166     notifier.shutdown(); | 103     notifier.shutdown(); | 
| 167   if (origShouldLoad) | 104   if (origShouldAllow) | 
| 168     PolicyPrivate.shouldLoad = origShouldLoad; | 105     Policy.shouldAllow = origShouldAllow; | 
| 169   if (origProcessNode) |  | 
| 170     Policy.processNode = origProcessNode; |  | 
| 171 } | 106 } | 
| 172 | 107 | 
| 173 function handleFilterHit(wnd, node, data) | 108 function handleFilterHit(data) | 
| 174 { | 109 { | 
| 175   if (data.filter && currentData) | 110   if (data.filter && currentData) | 
| 176     currentData.filters.push(data.filter.text); | 111     currentData.filters.push(data.filter); | 
| 177 } | 112 } | 
| 178 | 113 | 
| 179 function processQueue() | 114 function processQueue() | 
| 180 { | 115 { | 
| 181   if (!processingQueue.length) | 116   if (!processingQueue.length) | 
| 182     return; | 117     return; | 
| 183 | 118 | 
|  | 119   function stringify(value) | 
|  | 120   { | 
|  | 121     if (typeof value == "undefined" || value == null) | 
|  | 122       return ""; | 
|  | 123     else | 
|  | 124       return String(value); | 
|  | 125   } | 
|  | 126 | 
| 184   for each (let entry in processingQueue) | 127   for each (let entry in processingQueue) | 
| 185   { | 128   { | 
| 186     entry.cols = {}; | 129     entry.cols = { | 
| 187     if (typeof entry.location != "undefined") | 130       address: stringify(entry.location), | 
| 188       entry.cols.address = String(entry.location); | 131       type: stringify(entry.type), | 
| 189     if (typeof entry.type != "undefined") | 132       result: stringBundle.GetStringFromName(entry.result && entry.result.allow 
     ? "decision.allow" : "decision.block"), | 
| 190     { | 133       origin: stringify(entry.frames && entry.frames[0] && entry.frames[0].locat
     ion), | 
| 191       entry.cols.type = String(entry.type); | 134       filters: stringify(entry.filters && entry.filters.join(", ")), | 
| 192       try { | 135       time: stringify(entry.processingTime) | 
| 193         // Nasty hack: try to get type name from ABP | 136     }; | 
| 194         if (entry.type in Policy.localizedDescr) |  | 
| 195           entry.cols.type = String(Policy.localizedDescr[entry.type]); |  | 
| 196       } catch(e) {} |  | 
| 197     } |  | 
| 198     entry.cols.result = stringBundle.GetStringFromName(entry.result ? "decision.
     allow" : "decision.block"); |  | 
| 199     if (typeof entry.context != "undefined") |  | 
| 200       entry.cols.context = (entry.context ? getNodeLabel(entry.context) : String
     (entry.context)); |  | 
| 201     if (typeof entry.window != "undefined") |  | 
| 202       entry.cols.document = (entry.window ? getNodeLabel(entry.window) : String(
     entry.window)); |  | 
| 203     if (typeof entry.origin != "undefined") |  | 
| 204       entry.cols.origin = String(entry.origin); |  | 
| 205     if (entry.filters.length) |  | 
| 206       entry.cols.filter = entry.filters.join(", "); |  | 
| 207     if (typeof entry.processingTime != "undefined") |  | 
| 208       entry.cols.time = String(entry.processingTime); |  | 
| 209 |  | 
| 210     let additional = []; |  | 
| 211     if (entry.internal) |  | 
| 212       additional.push(stringBundle.GetStringFromName("additional.internalInvocat
     ion")); |  | 
| 213     if (typeof entry.internalType != "undefined" && entry.type != entry.internal
     Type) |  | 
| 214     { |  | 
| 215       let internalType = String(entry.internalType); |  | 
| 216       try { |  | 
| 217         // Nasty hack: try to get type name from ABP |  | 
| 218         if (entry.internalType in Policy.localizedDescr) |  | 
| 219           internalType = String(Policy.localizedDescr[entry.internalType]); |  | 
| 220       } catch(e) {} |  | 
| 221       additional.push(stringBundle.formatStringFromName("additional.typeChanged"
     , [internalType], 1)); |  | 
| 222     } |  | 
| 223     if (typeof entry.internalLocation != "undefined" && entry.location != entry.
     internalLocation) |  | 
| 224       additional.push(stringBundle.formatStringFromName("additional.locationChan
     ged", [String(entry.internalLocation)], 1)); |  | 
| 225 |  | 
| 226     if (additional.length > 0) |  | 
| 227       entry.cols.additional = additional.join(", "); |  | 
| 228 |  | 
| 229     treeView.add(entry); | 137     treeView.add(entry); | 
| 230   } | 138   } | 
| 231 | 139 | 
| 232   processingQueue = []; | 140   processingQueue = []; | 
| 233 } | 141 } | 
| 234 | 142 | 
| 235 function getNodeLabel(node) |  | 
| 236 { |  | 
| 237   try |  | 
| 238   { |  | 
| 239     if (node instanceof Ci.nsIDOMWindow) |  | 
| 240       return stringBundle.formatStringFromName("NodeLabel.window", [node.locatio
     n.href], 1); |  | 
| 241     if (node instanceof Ci.nsIDOMDocument) |  | 
| 242       return stringBundle.formatStringFromName("NodeLabel.document", [node.URL],
      1); |  | 
| 243     else if (node instanceof Ci.nsIDOMXULElement) |  | 
| 244       return stringBundle.formatStringFromName("NodeLabel.xulElement", [node.tag
     Name], 1); |  | 
| 245     else if (node instanceof Ci.nsIDOMHTMLElement) |  | 
| 246       return stringBundle.formatStringFromName("NodeLabel.htmlElement", [node.ta
     gName], 1); |  | 
| 247     else if (node instanceof Ci.nsIDOMSVGElement) |  | 
| 248       return stringBundle.formatStringFromName("NodeLabel.svgElement", [node.tag
     Name], 1); |  | 
| 249     else if (node instanceof Ci.nsIDOMElement) |  | 
| 250       return stringBundle.formatStringFromName("NodeLabel.element", [node.tagNam
     e], 1); |  | 
| 251     else |  | 
| 252       return stringBundle.formatStringFromName("NodeLabel.unknown", [String(node
     )], 1); |  | 
| 253   } |  | 
| 254   catch (e) |  | 
| 255   { |  | 
| 256     Cu.reportError(e); |  | 
| 257     return stringBundle.formatStringFromName("NodeLabel.unknown", [""], 1); |  | 
| 258   } |  | 
| 259 } |  | 
| 260 |  | 
| 261 function fillInTooltip(event) | 143 function fillInTooltip(event) | 
| 262 { | 144 { | 
| 263   let entry = treeView.getEntryAt(event.clientX, event.clientY); | 145   let entry = treeView.getEntryAt(event.clientX, event.clientY); | 
| 264   if (!entry) | 146   if (!entry) | 
| 265     return false; | 147     return false; | 
| 266 | 148 | 
| 267   let rows = document.getElementById("tooltip-rows"); | 149   let rows = document.getElementById("tooltip-rows"); | 
| 268   while (rows.firstChild) | 150   while (rows.firstChild) | 
| 269     rows.removeChild(rows.firstChild); | 151     rows.removeChild(rows.firstChild); | 
| 270 | 152 | 
| 271   let cols = document.getElementById("list").getElementsByTagName("treecol"); | 153   let cols = document.getElementById("list").getElementsByTagName("treecol"); | 
| 272   for (let i = 0; i < cols.length; i++) | 154   for (let i = 0; i < cols.length; i++) | 
| 273   { | 155   { | 
| 274     let col = cols[i].id; | 156     let col = cols[i].id; | 
| 275     if (col && col in entry.cols) | 157     if (col && col in entry.cols) | 
| 276     { | 158     { | 
| 277       let row = document.createElement("row"); | 159       let row = document.createElement("row"); | 
| 278 | 160 | 
| 279       let label = document.createElement("description"); | 161       let label = document.createElement("description"); | 
| 280       label.setAttribute("class", "tooltip-label"); | 162       label.setAttribute("class", "tooltip-label"); | 
| 281       label.setAttribute("value", cols[i].getAttribute("label")); | 163       label.setAttribute("value", cols[i].getAttribute("label")); | 
| 282       row.appendChild(label); | 164       row.appendChild(label); | 
| 283 | 165 | 
| 284       let value = document.createElement("vbox"); | 166       let value = document.createElement("vbox"); | 
| 285       setMultilineContent(value, entry.cols[col]); | 167       let data = entry.cols[col]; | 
|  | 168       if (col == "origin") | 
|  | 169         data = entry.frames.map(f => f.location).join("\n"); | 
|  | 170       setMultilineContent(value, data); | 
| 286       row.appendChild(value); | 171       row.appendChild(value); | 
| 287 | 172 | 
| 288       rows.appendChild(row); | 173       rows.appendChild(row); | 
| 289     } | 174     } | 
| 290   } | 175   } | 
| 291 | 176 | 
| 292   return true; | 177   return true; | 
| 293 } | 178 } | 
| 294 | 179 | 
| 295 function updateContextMenu(event) | 180 function updateContextMenu(event) | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 310     clipboardHelper.copyString(String(entry.location)); | 195     clipboardHelper.copyString(String(entry.location)); | 
| 311 } | 196 } | 
| 312 | 197 | 
| 313 function copyFilters() | 198 function copyFilters() | 
| 314 { | 199 { | 
| 315   let entry = treeView.getCurrentEntry(); | 200   let entry = treeView.getCurrentEntry(); | 
| 316   if (entry && entry.filters.length) | 201   if (entry && entry.filters.length) | 
| 317     clipboardHelper.copyString(entry.filters.join("\n")); | 202     clipboardHelper.copyString(entry.filters.join("\n")); | 
| 318 } | 203 } | 
| 319 | 204 | 
| 320 function setMultilineContent(box, text) { | 205 function setMultilineContent(box, text) | 
| 321   // The following is sufficient in Gecko 1.9 but Gecko 1.8 fails on multiline | 206 { | 
| 322   // text fields in tooltips | 207   let lines = text.split(/\n+/); | 
| 323   // box.textContent = text.replace(/\S{80}(?=\S)/g, "$& "); | 208   for (let line of lines) | 
| 324 | 209   { | 
| 325   for (let i = 0; i < text.length; i += 80) { |  | 
| 326     let description = document.createElement("description"); | 210     let description = document.createElement("description"); | 
| 327     description.setAttribute("value", text.substr(i, 80)); | 211     description.textContent = line.replace(/\S{80}(?=\S)/g, "$& "); | 
| 328     box.appendChild(description); | 212     box.appendChild(description); | 
| 329   } | 213   } | 
| 330 } | 214 } | 
| 331 | 215 | 
| 332 var totalProcessingTime = 0; | 216 var totalProcessingTime = 0; | 
| 333 function updateProcessingTime(view, operation, entry) | 217 function updateProcessingTime(view, operation, entry) | 
| 334 { | 218 { | 
| 335   if (operation == "add") | 219   if (operation == "add") | 
| 336     totalProcessingTime += entry.processingTime; | 220     totalProcessingTime += entry.processingTime; | 
| 337   else { | 221   else { | 
| 338     totalProcessingTime = 0; | 222     totalProcessingTime = 0; | 
| 339     for each (let entry in view.displayedItems) | 223     for each (let entry in view.displayedItems) | 
| 340       totalProcessingTime += entry.processingTime; | 224       totalProcessingTime += entry.processingTime; | 
| 341   } | 225   } | 
| 342 | 226 | 
| 343   let numItems = view.displayedItems.length; | 227   let numItems = view.displayedItems.length; | 
| 344 | 228 | 
| 345   let summary = document.getElementById("summary"); | 229   let summary = document.getElementById("summary"); | 
| 346   let template = summary.getAttribute("_template"); | 230   let template = summary.getAttribute("_template"); | 
| 347   summary.textContent = template.replace(/\*NUMITEMS\*/g, numItems).replace(/\*T
     IME\*/, (totalProcessingTime / 1000).toFixed(3)); | 231   summary.textContent = template.replace(/\*NUMITEMS\*/g, numItems).replace(/\*T
     IME\*/, (totalProcessingTime / 1000).toFixed(3)); | 
| 348 } | 232 } | 
| 349 | 233 | 
| 350 var treeView = { | 234 var treeView = { | 
| 351   currentItems: [], | 235   currentItems: [], | 
| 352   displayedItems: [], | 236   displayedItems: [], | 
| 353   _ignoreEarlyReturns: false, |  | 
| 354   _filterString: "", | 237   _filterString: "", | 
| 355   _sortColumn: null, | 238   _sortColumn: null, | 
| 356   _sortDirection: null, | 239   _sortDirection: null, | 
| 357   boxObject: null, | 240   boxObject: null, | 
| 358   atoms: {}, | 241   atoms: {}, | 
| 359   observers: [], | 242   observers: [], | 
| 360 | 243 | 
| 361   // | 244   // | 
| 362   // nsISupports implementation | 245   // nsISupports implementation | 
| 363   // | 246   // | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 379   selection: null, | 262   selection: null, | 
| 380 | 263 | 
| 381   setTree: function(boxObject) | 264   setTree: function(boxObject) | 
| 382   { | 265   { | 
| 383     if (!boxObject) | 266     if (!boxObject) | 
| 384       return; | 267       return; | 
| 385 | 268 | 
| 386     this.boxObject = boxObject; | 269     this.boxObject = boxObject; | 
| 387 | 270 | 
| 388     let atomService = Cc["@mozilla.org/atom-service;1"].getService(Ci.nsIAtomSer
     vice); | 271     let atomService = Cc["@mozilla.org/atom-service;1"].getService(Ci.nsIAtomSer
     vice); | 
| 389     for each (let col in ["address", "type", "result", "context", "document", "o
     rigin", "additional", "filter", "time"]) | 272     for each (let col in ["address", "type", "result", "origin", "filter", "time
     "]) | 
| 390     { | 273     { | 
| 391       let atomStr = "col-" + col; | 274       let atomStr = "col-" + col; | 
| 392       this.atoms[atomStr] = atomService.getAtom(atomStr); | 275       this.atoms[atomStr] = atomService.getAtom(atomStr); | 
| 393     } | 276     } | 
| 394     for each (let flag in ["selected", "blocked"]) | 277     for each (let flag in ["selected", "blocked"]) | 
| 395     { | 278     { | 
| 396       let atomStr = flag + "-true"; | 279       let atomStr = flag + "-true"; | 
| 397       this.atoms[atomStr] = atomService.getAtom(atomStr); | 280       this.atoms[atomStr] = atomService.getAtom(atomStr); | 
| 398 | 281 | 
| 399       atomStr = flag + "-false"; | 282       atomStr = flag + "-false"; | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 454   }, | 337   }, | 
| 455 | 338 | 
| 456   getRowProperties: function(row, properties) | 339   getRowProperties: function(row, properties) | 
| 457   { | 340   { | 
| 458     if (row < 0 || row >= this.displayedItems.length) | 341     if (row < 0 || row >= this.displayedItems.length) | 
| 459       return ""; | 342       return ""; | 
| 460 | 343 | 
| 461     let entry = this.displayedItems[row]; | 344     let entry = this.displayedItems[row]; | 
| 462     return this.generateProperties([ | 345     return this.generateProperties([ | 
| 463         "selected-" + this.selection.isSelected(row), | 346         "selected-" + this.selection.isSelected(row), | 
| 464         "blocked-" + !entry.result | 347         "blocked-" + !(entry.result && entry.result.allow) | 
| 465       ], properties); | 348       ], properties); | 
| 466   }, | 349   }, | 
| 467 | 350 | 
| 468   getCellProperties: function(row, col, properties) | 351   getCellProperties: function(row, col, properties) | 
| 469   { | 352   { | 
| 470     return this.getRowProperties(row, properties) + " " + this.getColumnProperti
     es(col, properties); | 353     return this.getRowProperties(row, properties) + " " + this.getColumnProperti
     es(col, properties); | 
| 471   }, | 354   }, | 
| 472 | 355 | 
| 473   cycleHeader: function(col) | 356   cycleHeader: function(col) | 
| 474   { | 357   { | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 524   cycleCell: function() {}, | 407   cycleCell: function() {}, | 
| 525   performAction: function() {}, | 408   performAction: function() {}, | 
| 526   performActionOnRow: function() {}, | 409   performActionOnRow: function() {}, | 
| 527   performActionOnCell: function() {}, | 410   performActionOnCell: function() {}, | 
| 528   selectionChanged: function() {}, | 411   selectionChanged: function() {}, | 
| 529 | 412 | 
| 530   // | 413   // | 
| 531   // Custom methods | 414   // Custom methods | 
| 532   // | 415   // | 
| 533 | 416 | 
| 534   get ignoreEarlyReturns() |  | 
| 535   { |  | 
| 536     return this._ignoreEarlyReturns; |  | 
| 537   }, |  | 
| 538   set ignoreEarlyReturns(value) |  | 
| 539   { |  | 
| 540     this._ignoreEarlyReturns = value; |  | 
| 541     this.refilter(); |  | 
| 542   }, |  | 
| 543 |  | 
| 544   get filterString() | 417   get filterString() | 
| 545   { | 418   { | 
| 546     return this._filterString; | 419     return this._filterString; | 
| 547   }, | 420   }, | 
| 548   set filterString(value) | 421   set filterString(value) | 
| 549   { | 422   { | 
| 550     this._filterString = value.toLowerCase(); | 423     this._filterString = value.toLowerCase(); | 
| 551     this.refilter(); | 424     this.refilter(); | 
| 552   }, | 425   }, | 
| 553 | 426 | 
| 554   filter: function(entry) | 427   filter: function(entry) | 
| 555   { | 428   { | 
| 556     if (this._ignoreEarlyReturns && entry.earlyReturn) |  | 
| 557       return false; |  | 
| 558 |  | 
| 559     if (this._filterString) | 429     if (this._filterString) | 
| 560     { | 430     { | 
| 561       let foundMatch = false; | 431       let foundMatch = false; | 
| 562       for each (let label in entry.cols) | 432       for each (let label in entry.cols) | 
| 563         if (label.toLowerCase().indexOf(this._filterString) >= 0) | 433         if (label.toLowerCase().indexOf(this._filterString) >= 0) | 
| 564           foundMatch = true; | 434           foundMatch = true; | 
| 565 | 435 | 
| 566       if (!foundMatch) | 436       if (!foundMatch) | 
| 567         return false; | 437         return false; | 
| 568     } | 438     } | 
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 678     for (let i = 0; i < this.observers.length; i++) | 548     for (let i = 0; i < this.observers.length; i++) | 
| 679       if (this.observers[i] == observer) | 549       if (this.observers[i] == observer) | 
| 680         this.observers.splice(i--, 1); | 550         this.observers.splice(i--, 1); | 
| 681   }, | 551   }, | 
| 682   notifyObservers: function(operation, entry) | 552   notifyObservers: function(operation, entry) | 
| 683   { | 553   { | 
| 684     for each (let observer in this.observers) | 554     for each (let observer in this.observers) | 
| 685       observer(this, operation, entry); | 555       observer(this, operation, entry); | 
| 686   } | 556   } | 
| 687 }; | 557 }; | 
| OLD | NEW | 
|---|