diff --git a/.jshintrc b/.jshintrc index 618c34f76..df4628b92 100644 --- a/.jshintrc +++ b/.jshintrc @@ -7,7 +7,6 @@ "unused": true, "nonew": false, "sub": true, - "boss": true, "laxbreak": true, "validthis": true, "newcap": false, @@ -19,4 +18,4 @@ "safari": false, "Components": false // global variable in Firefox } -} \ No newline at end of file +} diff --git a/platform/firefox/frameModule.js b/platform/firefox/frameModule.js index b7c765d1c..ac2b4ed07 100644 --- a/platform/firefox/frameModule.js +++ b/platform/firefox/frameModule.js @@ -159,7 +159,8 @@ const contentObserver = { if ( type === this.MAIN_FRAME ) { context = context.contentWindow || context; if ( - context.opener && + typeof context.opener === 'object' && + context.opener !== null && context.opener !== context && this.ignoredPopups.has(context) === false ) { @@ -334,9 +335,8 @@ const contentObserver = { return; } - let win = doc.defaultView; - - if ( !win ) { + let win = doc.defaultView || null; + if ( win === null ) { return; } diff --git a/platform/firefox/frameScript.js b/platform/firefox/frameScript.js index 45d5e1aed..fdee50c59 100644 --- a/platform/firefox/frameScript.js +++ b/platform/firefox/frameScript.js @@ -19,6 +19,8 @@ Home: https://github.com/gorhill/uBlock */ +/* global addMessageListener, removeMessageListener, docShell */ + /******************************************************************************/ var locationChangeListener; // Keep alive while frameScript is alive diff --git a/platform/firefox/vapi-background.js b/platform/firefox/vapi-background.js index aece135dc..deb789038 100644 --- a/platform/firefox/vapi-background.js +++ b/platform/firefox/vapi-background.js @@ -2707,14 +2707,22 @@ vAPI.contextMenu.displayMenuItem = function({target}) { var ctxMap = vAPI.contextMenu.contextMap; for ( var context of ctx ) { - if ( context === 'page' && !gContextMenu.onLink && !gContextMenu.onImage - && !gContextMenu.onEditableArea && !gContextMenu.inFrame - && !gContextMenu.onVideo && !gContextMenu.onAudio ) { + if ( + context === 'page' && + !gContextMenu.onLink && + !gContextMenu.onImage && + !gContextMenu.onEditableArea && + !gContextMenu.inFrame && + !gContextMenu.onVideo && + !gContextMenu.onAudio + ) { menuitem.hidden = false; return; } - - if ( gContextMenu[ctxMap[context]] ) { + if ( + ctxMap.hasOwnProperty(context) && + gContextMenu[ctxMap[context]] + ) { menuitem.hidden = false; return; } diff --git a/platform/firefox/vapi-client.js b/platform/firefox/vapi-client.js index 31c3f67d8..bd6facd29 100644 --- a/platform/firefox/vapi-client.js +++ b/platform/firefox/vapi-client.js @@ -54,7 +54,7 @@ vAPI.shutdown = (function() { var exec = function() { //console.debug('Shutting down...'); var job; - while ( job = jobs.pop() ) { + while ( (job = jobs.pop()) ) { job(); } }; @@ -199,7 +199,7 @@ var messagingConnector = function(details) { var channel; // Sent to all channels - if ( details.broadcast === true && !details.channelName ) { + if ( details.broadcast && !details.channelName ) { for ( channel in channels ) { if ( channels[channel] instanceof MessagingChannel === false ) { continue; diff --git a/src/js/assets.js b/src/js/assets.js index 58e741473..51ba53f01 100644 --- a/src/js/assets.js +++ b/src/js/assets.js @@ -448,14 +448,14 @@ var getRepoMetadata = function(callback) { }; var onLocalChecksumsLoaded = function(details) { - if ( localChecksums = validateChecksums(details) ) { + if ( (localChecksums = validateChecksums(details)) ) { parseChecksums(localChecksums, 'local'); } checksumsReceived(); }; var onRepoChecksumsLoaded = function(details) { - if ( repoChecksums = validateChecksums(details) ) { + if ( (repoChecksums = validateChecksums(details)) ) { parseChecksums(repoChecksums, 'repo'); } checksumsReceived(); diff --git a/src/js/contentscript-end.js b/src/js/contentscript-end.js index e6047f022..a3134fc76 100644 --- a/src/js/contentscript-end.js +++ b/src/js/contentscript-end.js @@ -81,7 +81,7 @@ vAPI.shutdown.add(function() { (function() { // Were there specific cosmetic filters? - if ( vAPI.specificHideStyle instanceof HTMLStyleElement === false ) { + if ( typeof vAPI.specificHideStyle !== 'object' ) { return; } // Is our style tag still in the DOM? (the guess is whatever parent there @@ -171,7 +171,7 @@ var uBlockCollapser = (function() { // https://github.com/chrisaljoudi/uBlock/issues/1048 // Use attribute to construct CSS rule - if ( value = target.getAttribute(entry.attr) ) { + if ( (value = target.getAttribute(entry.attr)) ) { selectors.push(entry.tagName + '[' + entry.attr + '="' + value + '"]'); } } @@ -534,7 +534,7 @@ var uBlockCollapser = (function() { var attrs = ['title', 'alt']; var attr, attrValue, nodeList, iNode, node; var selector; - while ( attr = attrs.pop() ) { + while ( (attr = attrs.pop()) ) { nodeList = selectNodes('[' + attr + ']'); iNode = nodeList.length; while ( iNode-- ) { @@ -738,7 +738,7 @@ var uBlockCollapser = (function() { var treeMutationObservedHandler = function() { var nodeList, iNode, node; - while ( nodeList = addedNodeLists.pop() ) { + while ( (nodeList = addedNodeLists.pop()) ) { iNode = nodeList.length; while ( iNode-- ) { node = nodeList[iNode]; diff --git a/src/js/cosmetic-filtering.js b/src/js/cosmetic-filtering.js index e48849b3f..f0eeed1fe 100644 --- a/src/js/cosmetic-filtering.js +++ b/src/js/cosmetic-filtering.js @@ -1141,7 +1141,7 @@ FilterContainer.prototype.retrieveGenericSelectors = function(request) { continue; } hash = makeHash(0, selector, hashMask); - if ( bucket = this.lowGenericHide[hash] ) { + if ( (bucket = this.lowGenericHide[hash]) ) { bucket.retrieve(selector, hideSelectors); } } @@ -1187,29 +1187,29 @@ FilterContainer.prototype.retrieveDomainSelectors = function(request) { var hash, bucket; hash = makeHash(0, domain, this.domainHashMask); - if ( bucket = this.hostnameFilters[hash] ) { + if ( (bucket = this.hostnameFilters[hash]) ) { bucket.retrieve(hostname, r.cosmeticHide); } // https://github.com/chrisaljoudi/uBlock/issues/188 // Special bucket for those filters without a valid domain name as per PSL - if ( bucket = this.hostnameFilters[this.type0NoDomainHash] ) { + if ( (bucket = this.hostnameFilters[this.type0NoDomainHash]) ) { bucket.retrieve(hostname, r.cosmeticHide); } // entity filter buckets are always plain js array - if ( bucket = this.entityFilters[r.entity] ) { + if ( (bucket = this.entityFilters[r.entity]) ) { r.cosmeticHide = r.cosmeticHide.concat(bucket); } // No entity exceptions as of now hash = makeHash(1, domain, this.domainHashMask); - if ( bucket = this.hostnameFilters[hash] ) { + if ( (bucket = this.hostnameFilters[hash]) ) { bucket.retrieve(hostname, r.cosmeticDonthide); } // https://github.com/chrisaljoudi/uBlock/issues/188 // Special bucket for those filters without a valid domain name as per PSL - if ( bucket = this.hostnameFilters[this.type1NoDomainHash] ) { + if ( (bucket = this.hostnameFilters[this.type1NoDomainHash]) ) { bucket.retrieve(hostname, r.cosmeticDonthide); } diff --git a/src/js/dynamic-net-filtering.js b/src/js/dynamic-net-filtering.js index 319e19134..9a1fe3539 100644 --- a/src/js/dynamic-net-filtering.js +++ b/src/js/dynamic-net-filtering.js @@ -206,11 +206,11 @@ Matrix.prototype.hasSameRules = function(other, srcHostname, desHostnames) { // Specific types ruleKey = '* *'; - if ( thisRules[ruleKey] !== otherRules[ruleKey] ) { + if ( (thisRules[ruleKey] || 0) !== (otherRules[ruleKey] || 0) ) { return false; } ruleKey = srcHostname + ' *'; - if ( thisRules[ruleKey] !== otherRules[ruleKey] ) { + if ( (thisRules[ruleKey] || 0) !== (otherRules[ruleKey] || 0) ) { return false; } @@ -220,11 +220,11 @@ Matrix.prototype.hasSameRules = function(other, srcHostname, desHostnames) { continue; } ruleKey = '* ' + desHostname; - if ( thisRules[ruleKey] !== otherRules[ruleKey] ) { + if ( (thisRules[ruleKey] || 0) !== (otherRules[ruleKey] || 0) ) { return false; } ruleKey = srcHostname + ' ' + desHostname ; - if ( thisRules[ruleKey] !== otherRules[ruleKey] ) { + if ( (thisRules[ruleKey] || 0) !== (otherRules[ruleKey] || 0) ) { return false; } } diff --git a/src/js/logger-ui.js b/src/js/logger-ui.js index 3c2c8faa4..d532cce85 100644 --- a/src/js/logger-ui.js +++ b/src/js/logger-ui.js @@ -19,7 +19,6 @@ Home: https://github.com/gorhill/uBlock */ -/* jshint boss: true */ /* global vAPI, uDom */ /******************************************************************************/ @@ -400,7 +399,7 @@ var createRow = function(layout) { td.setAttribute('colspan', span); } index += 1; - while ( td = tr.cells[index] ) { + while ( (td = tr.cells[index]) ) { tdJunkyard.push(tr.removeChild(td)); } return tr; diff --git a/src/js/messaging.js b/src/js/messaging.js index 2c747792a..47886d5e3 100644 --- a/src/js/messaging.js +++ b/src/js/messaging.js @@ -231,7 +231,9 @@ var getHostnameDict = function(hostnameToCountMap) { r[hostname] = { domain: domain, blockCount: blockCount, - allowCount: allowCount + allowCount: allowCount, + totalBlockCount: 0, + totalAllowCount: 0 }; } return r; diff --git a/src/js/mirrors.js b/src/js/mirrors.js index d574b1751..53d90824d 100644 --- a/src/js/mirrors.js +++ b/src/js/mirrors.js @@ -298,7 +298,7 @@ var pruneToSize = function(toSize) { delete h2cMap[hash]; toRemove.push(storageKeyFromHash(hash)); exports.bytesInUse -= ctEntry.dataURL.length; - while ( urlKey = prEntry.urlKeys.pop() ) { + while ( (urlKey = prEntry.urlKeys.pop()) ) { delete k2hMap[urlKey]; } if ( exports.bytesInUse < toSize ) { diff --git a/src/js/pagestore.js b/src/js/pagestore.js index ab21efa4a..40975c357 100644 --- a/src/js/pagestore.js +++ b/src/js/pagestore.js @@ -212,7 +212,7 @@ NetFilteringResultCache.prototype.pruneAsyncCallback = function() { /******************************************************************************/ NetFilteringResultCache.prototype.lookup = function(context) { - return this.urls[context.requestType + ' ' + context.requestURL]; + return this.urls[context.requestType + ' ' + context.requestURL] || undefined; }; /******************************************************************************/ @@ -445,10 +445,7 @@ PageStore.prototype.createContextFromFrameHostname = function(frameHostname) { PageStore.prototype.getNetFilteringSwitch = function() { var tabContext = µb.tabContextManager.lookup(this.tabId); - if ( - this.netFilteringReadTime > µb.netWhitelistModifyTime && - this.netFilteringReadTime > tabContext.modifyTime - ) { + if ( this.netFilteringReadTime > µb.netWhitelistModifyTime ) { return this.netFiltering; } diff --git a/src/js/popup.js b/src/js/popup.js index 346e616da..cddc69cb0 100644 --- a/src/js/popup.js +++ b/src/js/popup.js @@ -40,10 +40,15 @@ var dfPaneVisibleStored = vAPI.localStorage.getItem('popupFirewallPane') === 'tr // dictate the height of the popup. The right pane dictates the height // of the popup, and the left pane will have a scrollbar if ever its // height is more than what is available. -document.querySelector('#panes > div:nth-of-type(2)').style.setProperty( - 'height', - document.querySelector('#panes > div:nth-of-type(1)').offsetHeight + 'px' -); +(function() { + var rpane = document.querySelector('#panes > div:nth-of-type(1)'); + if ( typeof rpane.offsetHeight === 'number' ) { + document.querySelector('#panes > div:nth-of-type(2)').style.setProperty( + 'height', + rpane.offsetHeight + 'px' + ); + } +})(); // The padlock/eraser must be manually positioned: // - Its vertical position depends on the height of the popup title bar diff --git a/src/js/scriptlets/cosmetic-on.js b/src/js/scriptlets/cosmetic-on.js index bedb95358..e53397f07 100644 --- a/src/js/scriptlets/cosmetic-on.js +++ b/src/js/scriptlets/cosmetic-on.js @@ -78,7 +78,7 @@ try { } catch (e) { } -var elem, shadow, selector = '#' + sessionId; +var elem, shadow; i = elems.length; while ( i-- ) { elem = elems[i]; diff --git a/src/js/scriptlets/dom-inspector.js b/src/js/scriptlets/dom-inspector.js index 2ea07cbca..203ba0ddb 100644 --- a/src/js/scriptlets/dom-inspector.js +++ b/src/js/scriptlets/dom-inspector.js @@ -618,7 +618,7 @@ var cosmeticFilterFromNode = function(elem) { default: break; } - while ( attr = attributes.pop() ) { + while ( (attr = attributes.pop()) ) { if ( attr.v.length === 0 ) { continue; } diff --git a/src/js/scriptlets/element-picker.js b/src/js/scriptlets/element-picker.js index 24e878c0c..2a980afa3 100644 --- a/src/js/scriptlets/element-picker.js +++ b/src/js/scriptlets/element-picker.js @@ -419,7 +419,7 @@ var cosmeticFilterFromElement = function(elem, out) { default: break; } - while ( attr = attributes.pop() ) { + while ( (attr = attributes.pop()) ) { if ( attr.v.length === 0 ) { continue; } @@ -890,8 +890,8 @@ var startPicker = function(details) { pickerRoot.contentWindow.focus(); // Restore net filter union data if it originate from the same URL. - var eprom = details.eprom || {}; - if ( eprom.lastNetFilterSession === lastNetFilterSession ) { + var eprom = details.eprom || null; + if ( eprom !== null && eprom.lastNetFilterSession === lastNetFilterSession ) { lastNetFilterHostname = eprom.lastNetFilterHostname || ''; lastNetFilterUnion = eprom.lastNetFilterUnion || ''; } diff --git a/src/js/static-net-filtering.js b/src/js/static-net-filtering.js index f9654d87b..6aa4190ed 100644 --- a/src/js/static-net-filtering.js +++ b/src/js/static-net-filtering.js @@ -19,7 +19,7 @@ Home: https://github.com/gorhill/uBlock */ -/* jshint bitwise: false, esnext: true, boss: true */ +/* jshint bitwise: false, esnext: true */ /* global punycode, µBlock */ /******************************************************************************/ @@ -1198,7 +1198,7 @@ var trimChar = function(s, c) { pos += 1; } s = s.slice(pos); - if ( pos = s.length ) { + if ( (pos = s.length) ) { while ( s.charAt(pos-1) === c ) { pos -= 1; } @@ -1497,7 +1497,7 @@ var badTokens = { var findFirstGoodToken = function(s) { reGoodToken.lastIndex = 0; var matches; - while ( matches = reGoodToken.exec(s) ) { + while ( (matches = reGoodToken.exec(s)) ) { if ( s.charAt(reGoodToken.lastIndex) === '*' ) { continue; } @@ -1508,7 +1508,7 @@ var findFirstGoodToken = function(s) { } // No good token found, try again without minding "bad" tokens reGoodToken.lastIndex = 0; - while ( matches = reGoodToken.exec(s) ) { + while ( (matches = reGoodToken.exec(s)) ) { if ( s.charAt(reGoodToken.lastIndex) === '*' ) { continue; } @@ -2154,7 +2154,7 @@ FilterContainer.prototype.tokenize = function(url) { var matches, tokenEntry; re.lastIndex = 0; var i = 0; - while ( matches = re.exec(url) ) { + while ( (matches = re.exec(url)) ) { tokenEntry = tokens[i]; if ( tokenEntry === undefined ) { tokenEntry = tokens[i] = new TokenEntry(); @@ -2251,14 +2251,14 @@ FilterContainer.prototype.matchStringExactType = function(context, requestURL, r // https://github.com/chrisaljoudi/uBlock/issues/139 // Test against important block filters key = BlockAnyParty | Important | type; - if ( bucket = categories[toHex(key)] ) { + if ( (bucket = categories[toHex(key)]) ) { if ( this.matchTokens(bucket, url) ) { this.keyRegister = key; return true; } } key = BlockAction | Important | type | party; - if ( bucket = categories[toHex(key)] ) { + if ( (bucket = categories[toHex(key)]) ) { if ( this.matchTokens(bucket, url) ) { this.keyRegister = key; return true; @@ -2267,14 +2267,14 @@ FilterContainer.prototype.matchStringExactType = function(context, requestURL, r // Test against block filters key = BlockAnyParty | type; - if ( bucket = categories[toHex(key)] ) { + if ( (bucket = categories[toHex(key)]) ) { if ( this.matchTokens(bucket, url) ) { this.keyRegister = key; } } if ( this.fRegister === null ) { key = BlockAction | type | party; - if ( bucket = categories[toHex(key)] ) { + if ( (bucket = categories[toHex(key)]) ) { if ( this.matchTokens(bucket, url) ) { this.keyRegister = key; } @@ -2288,14 +2288,14 @@ FilterContainer.prototype.matchStringExactType = function(context, requestURL, r // Test against allow filters key = AllowAnyParty | type; - if ( bucket = categories[toHex(key)] ) { + if ( (bucket = categories[toHex(key)]) ) { if ( this.matchTokens(bucket, url) ) { this.keyRegister = key; return false; } } key = AllowAction | type | party; - if ( bucket = categories[toHex(key)] ) { + if ( (bucket = categories[toHex(key)]) ) { if ( this.matchTokens(bucket, url) ) { this.keyRegister = key; return false; @@ -2363,28 +2363,28 @@ FilterContainer.prototype.matchString = function(context) { // evaluation. Normally, it is "evaluate block then evaluate allow", with // the `important` property it is "evaluate allow then evaluate block". key = BlockAnyTypeAnyParty | Important; - if ( bucket = categories[toHex(key)] ) { + if ( (bucket = categories[toHex(key)]) ) { if ( this.matchTokens(bucket, url) ) { this.keyRegister = key; return true; } } key = BlockAnyType | Important | party; - if ( bucket = categories[toHex(key)] ) { + if ( (bucket = categories[toHex(key)]) ) { if ( this.matchTokens(bucket, url) ) { this.keyRegister = key; return true; } } key = BlockAnyParty | Important | type; - if ( bucket = categories[toHex(key)] ) { + if ( (bucket = categories[toHex(key)]) ) { if ( this.matchTokens(bucket, url) ) { this.keyRegister = key; return true; } } key = BlockAction | Important | type | party; - if ( bucket = categories[toHex(key)] ) { + if ( (bucket = categories[toHex(key)]) ) { if ( this.matchTokens(bucket, url) ) { this.keyRegister = key; return true; @@ -2393,28 +2393,28 @@ FilterContainer.prototype.matchString = function(context) { // Test against block filters key = BlockAnyTypeAnyParty; - if ( bucket = categories[toHex(key)] ) { + if ( (bucket = categories[toHex(key)]) ) { if ( this.matchTokens(bucket, url) ) { this.keyRegister = key; } } if ( this.fRegister === null ) { key = BlockAnyType | party; - if ( bucket = categories[toHex(key)] ) { + if ( (bucket = categories[toHex(key)]) ) { if ( this.matchTokens(bucket, url) ) { this.keyRegister = key; } } if ( this.fRegister === null ) { key = BlockAnyParty | type; - if ( bucket = categories[toHex(key)] ) { + if ( (bucket = categories[toHex(key)]) ) { if ( this.matchTokens(bucket, url) ) { this.keyRegister = key; } } if ( this.fRegister === null ) { key = BlockAction | type | party; - if ( bucket = categories[toHex(key)] ) { + if ( (bucket = categories[toHex(key)]) ) { if ( this.matchTokens(bucket, url) ) { this.keyRegister = key; } @@ -2430,28 +2430,28 @@ FilterContainer.prototype.matchString = function(context) { // Test against allow filters key = AllowAnyTypeAnyParty; - if ( bucket = categories[toHex(key)] ) { + if ( (bucket = categories[toHex(key)]) ) { if ( this.matchTokens(bucket, url) ) { this.keyRegister = key; return false; } } key = AllowAnyType | party; - if ( bucket = categories[toHex(key)] ) { + if ( (bucket = categories[toHex(key)]) ) { if ( this.matchTokens(bucket, url) ) { this.keyRegister = key; return false; } } key = AllowAnyParty | type; - if ( bucket = categories[toHex(key)] ) { + if ( (bucket = categories[toHex(key)]) ) { if ( this.matchTokens(bucket, url) ) { this.keyRegister = key; return false; } } key = AllowAction | type | party; - if ( bucket = categories[toHex(key)] ) { + if ( (bucket = categories[toHex(key)]) ) { if ( this.matchTokens(bucket, url) ) { this.keyRegister = key; return false; diff --git a/src/js/storage.js b/src/js/storage.js index f1a1e20f9..173c11de7 100644 --- a/src/js/storage.js +++ b/src/js/storage.js @@ -225,7 +225,7 @@ var location, availableEntry, storedEntry; var off; - while ( location = locations.pop() ) { + while ( (location = locations.pop()) ) { storedEntry = lists[location]; off = storedEntry.off === true; // New location? @@ -242,7 +242,9 @@ continue; } availableEntry.off = off; - µb.assets.setHomeURL(location, availableEntry.homeURL); + if ( typeof availableEntry.homeURL === 'string' ) { + µb.assets.setHomeURL(location, availableEntry.homeURL); + } if ( storedEntry.entryCount !== undefined ) { availableEntry.entryCount = storedEntry.entryCount; } diff --git a/src/js/tab.js b/src/js/tab.js index a3b1d4a2d..6625bff26 100644 --- a/src/js/tab.js +++ b/src/js/tab.js @@ -597,7 +597,7 @@ vAPI.tabs.registerListeners(); if ( !pageStore ) { this.updateTitle(tabId); this.pageStoresToken = Date.now(); - return this.pageStores[tabId] = this.PageStore.factory(tabId); + return (this.pageStores[tabId] = this.PageStore.factory(tabId)); } // https://github.com/chrisaljoudi/uBlock/issues/516 diff --git a/src/js/udom.js b/src/js/udom.js index 87c05d07e..0f4420e28 100644 --- a/src/js/udom.js +++ b/src/js/udom.js @@ -336,7 +336,7 @@ DOMList.prototype.remove = function() { var i = this.nodes.length; while ( i-- ) { cn = this.nodes[i]; - if ( p = cn.parentNode ) { + if ( (p = cn.parentNode) ) { p.removeChild(cn); } } @@ -713,7 +713,7 @@ DOMList.prototype.trigger = function(etype) { var onBeforeUnload = function() { var entry; - while ( entry = listenerEntries.pop() ) { + while ( (entry = listenerEntries.pop()) ) { entry.dispose(); } window.removeEventListener('beforeunload', onBeforeUnload); diff --git a/src/js/url-net-filtering.js b/src/js/url-net-filtering.js index 2fdb66232..4525786d3 100644 --- a/src/js/url-net-filtering.js +++ b/src/js/url-net-filtering.js @@ -252,7 +252,7 @@ URLNetFiltering.prototype.evaluateZ = function(context, target, type) { for (;;) { this.context = context; keyShard = context + ' ' + urlKey; - if ( urls = this.rules[keyShard + ' ' + type] ) { + if ( (urls = this.rules[keyShard + ' ' + type]) ) { i = indexOfMatch(urls, target); if ( i !== -1 ) { entry = urls[i]; @@ -262,7 +262,7 @@ URLNetFiltering.prototype.evaluateZ = function(context, target, type) { return this; } } - if ( urls = this.rules[keyShard + ' *'] ) { + if ( (urls = this.rules[keyShard + ' *']) ) { i = indexOfMatch(urls, target); if ( i !== -1 ) { entry = urls[i];