Last active
June 1, 2021 18:51
-
-
Save simonzack/d5ac206f0fe661cc0c27 to your computer and use it in GitHub Desktop.
google search filter plus
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Google Search Filter Plus | |
// @description Filters google search results | |
// @namespace smk | |
// @license MPL 1.1; http://www.mozilla.org/MPL/MPL-1.1.html | |
// @include http://www.google.tld/ | |
// @include http://www.google.tld/?* | |
// @include http://www.google.tld/#*&q=* | |
// @include http://www.google.tld/#q=* | |
// @include http://www.google.tld/cse?* | |
// @include http://cse.google.tld/cse?* | |
// @include http://www.google.tld/custom?* | |
// @include http://www.google.tld/search?* | |
// @include https://encrypted.google.com/ | |
// @include https://encrypted.google.com/#*&q=* | |
// @include https://encrypted.google.com/search?* | |
// @include https://www.google.tld/ | |
// @include https://www.google.tld/?* | |
// @include https://www.google.tld/#*&q=* | |
// @include https://www.google.tld/#q=* | |
// @include https://www.google.tld/cse?* | |
// @include https://cse.google.tld/cse?* | |
// @include https://www.google.tld/custom?* | |
// @include https://www.google.tld/search?* | |
// @grant GM_addStyle | |
// @grant GM_getResourceText | |
// @grant GM_getResourceURL | |
// @grant GM_getValue | |
// @grant GM_registerMenuCommand | |
// @grant GM_setValue | |
// @require https://cdn.jsdelivr.net/jquery/2.1.3/jquery.min.js | |
// @require https://cdn.jsdelivr.net/jquery.ui/1.11.3/jquery-ui.min.js | |
// @require https://cdn.jsdelivr.net/jquery.event.drag/2.2/jquery.event.drag.min.js | |
// @require https://rawgit.com/6pac/SlickGrid/2.1.0/slick.core.js | |
// @require https://rawgit.com/6pac/SlickGrid/master/slick.editors.js | |
// @require https://rawgit.com/6pac/SlickGrid/2.1.0/slick.grid.js | |
// @require https://rawgit.com/6pac/SlickGrid/2.1.0/plugins/slick.rowselectionmodel.js | |
// @resource jquery-ui-css https://cdn.jsdelivr.net/jquery.ui/1.11.3/themes/smoothness/jquery-ui.min.css | |
// @resource jquery-ui-css/images/ui-bg_glass_55_fbf9ee_1x400.png https://cdn.jsdelivr.net/jquery.ui/1.11.3/themes/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png | |
// @resource jquery-ui-css/images/ui-bg_glass_65_ffffff_1x400.png https://cdn.jsdelivr.net/jquery.ui/1.11.3/themes/smoothness/images/ui-bg_glass_65_ffffff_1x400.png | |
// @resource jquery-ui-css/images/ui-bg_glass_75_dadada_1x400.png https://cdn.jsdelivr.net/jquery.ui/1.11.3/themes/smoothness/images/ui-bg_glass_75_dadada_1x400.png | |
// @resource jquery-ui-css/images/ui-bg_glass_75_e6e6e6_1x400.png https://cdn.jsdelivr.net/jquery.ui/1.11.3/themes/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png | |
// @resource jquery-ui-css/images/ui-bg_glass_95_fef1ec_1x400.png https://cdn.jsdelivr.net/jquery.ui/1.11.3/themes/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png | |
// @resource jquery-ui-css/images/ui-bg_highlight-soft_75_cccccc_1x100.png https://cdn.jsdelivr.net/jquery.ui/1.11.3/themes/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png | |
// @resource jquery-ui-css/images/ui-icons_222222_256x240.png https://cdn.jsdelivr.net/jquery.ui/1.11.3/themes/smoothness/images/ui-icons_222222_256x240.png | |
// @resource jquery-ui-css/images/ui-icons_2e83ff_256x240.png https://cdn.jsdelivr.net/jquery.ui/1.11.3/themes/smoothness/images/ui-icons_2e83ff_256x240.png | |
// @resource jquery-ui-css/images/ui-icons_454545_256x240.png https://cdn.jsdelivr.net/jquery.ui/1.11.3/themes/smoothness/images/ui-icons_454545_256x240.png | |
// @resource jquery-ui-css/images/ui-icons_888888_256x240.png https://cdn.jsdelivr.net/jquery.ui/1.11.3/themes/smoothness/images/ui-icons_888888_256x240.png | |
// @resource jquery-ui-css/images/ui-icons_cd0a0a_256x240.png https://cdn.jsdelivr.net/jquery.ui/1.11.3/themes/smoothness/images/ui-icons_cd0a0a_256x240.png | |
// @resource slickgrid-css https://rawgit.com/6pac/SlickGrid/2.1.0/slick.grid.css | |
// @resource slickgrid-css/images/sort-asc.gif https://rawgit.com/6pac/SlickGrid/2.1.0/images/sort-asc.gif | |
// @resource slickgrid-css/images/sort-desc.gif https://rawgit.com/6pac/SlickGrid/2.1.0/images/sort-desc.gif | |
// ==/UserScript== | |
/******/ (() => { // webpackBootstrap | |
/******/ var __webpack_modules__ = ({ | |
/***/ "./gfp/lib/filterClasses.js": | |
/*!**********************************!*\ | |
!*** ./gfp/lib/filterClasses.js ***! | |
\**********************************/ | |
/*! default exports */ | |
/*! export ActiveFilter [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! export BlockingFilter [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! export CommentFilter [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! export Filter [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! export InvalidFilter [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! export RegExpFilter [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! export WhitelistFilter [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! other exports [not provided] [no usage info] */ | |
/*! runtime requirements: __webpack_exports__, __webpack_require__ */ | |
/***/ ((__unused_webpack_module, exports, __webpack_require__) => { | |
/* | |
* This file is part of Adblock Plus <https://adblockplus.org/>, | |
* Copyright (C) 2006-2015 Eyeo GmbH | |
* | |
* Adblock Plus is free software: you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License version 3 as | |
* published by the Free Software Foundation. | |
* | |
* Adblock Plus is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* | |
* You should have received a copy of the GNU General Public License | |
* along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | |
*/ | |
/** | |
* @fileOverview Definition of Filter class and its subclasses. | |
*/ | |
const { FilterNotifier } = __webpack_require__(/*! ./filterNotifier */ "./gfp/lib/filterNotifier.js") | |
/** | |
* Abstract base class for filters | |
* | |
* @param {String} text string representation of the filter | |
* @constructor | |
*/ | |
function Filter(text) { | |
this.text = text | |
this.subscriptions = [] | |
} | |
exports.Filter = Filter | |
Filter.prototype = { | |
/** | |
* String representation of the filter | |
* @type String | |
*/ | |
text: null, | |
/** | |
* Filter subscriptions the filter belongs to | |
* @type Array of Subscription | |
*/ | |
subscriptions: null, | |
/** | |
* Serializes the filter to an array of strings for writing out on the disk. | |
* @param {Array<String>} buffer buffer to push the serialization results into | |
*/ | |
serialize: function (buffer) { | |
buffer.push('[Filter]') | |
buffer.push('text=' + this.text) | |
}, | |
toString: function () { | |
return this.text | |
}, | |
} | |
/** | |
* Cache for known filters, maps string representation to filter objects. | |
* @type Object | |
*/ | |
Filter.knownFilters = Object.create(null) | |
/** | |
* Regular expression that element hiding filters should match | |
* @type RegExp | |
*/ | |
Filter.elemhideRegExp = /^([^/*|@"!]*?)#(@)?(?:([\w-]+|\*)((?:\([\w-]+(?:[$^*]?=[^()"]*)?\))*)|#([^{}]+))$/ | |
/** | |
* Regular expression that RegExp filters specified as RegExps should match | |
* @type RegExp | |
*/ | |
Filter.regexpRegExp = /^(@@)?\/.*\/(?:\$~?[\w-]+(?:=[^,\s]+)?(?:,~?[\w-]+(?:=[^,\s]+)?)*)?$/ | |
/** | |
* Regular expression that options on a RegExp filter should match | |
* @type RegExp | |
*/ | |
Filter.optionsRegExp = /\$(~?[\w-]+(?:=[^,\s]+)?(?:,~?[\w-]+(?:=[^,\s]+)?)*)$/ | |
/** | |
* Creates a filter of correct type from its text representation - does the basic parsing and | |
* calls the right constructor then. | |
* | |
* @param {String} text as in Filter() | |
* @return {Filter} | |
*/ | |
Filter.fromText = function (text) { | |
if (text in Filter.knownFilters) return Filter.knownFilters[text] | |
let ret | |
if (text[0] === '!') ret = new CommentFilter(text) | |
else ret = RegExpFilter.fromText(text) | |
Filter.knownFilters[ret.text] = ret | |
return ret | |
} | |
/** | |
* Deserializes a filter | |
* | |
* @param {Object} obj map of serialized properties and their values | |
* @return {Filter} filter or null if the filter couldn't be created | |
*/ | |
Filter.fromObject = function (obj) { | |
const ret = Filter.fromText(obj.text) | |
if (ret instanceof ActiveFilter) { | |
if ('disabled' in obj) ret._disabled = obj.disabled === 'true' | |
if ('hitCount' in obj) ret._hitCount = parseInt(obj.hitCount) || 0 | |
if ('lastHit' in obj) ret._lastHit = parseInt(obj.lastHit) || 0 | |
} | |
return ret | |
} | |
/** | |
* Removes unnecessary whitespaces from filter text, will only return null if | |
* the input parameter is null. | |
*/ | |
Filter.normalize = function (/**String*/ text /**String*/) { | |
if (!text) return text | |
// Remove line breaks and such | |
text = text.replace(/[^\S ]/g, '') | |
if (/^\s*!/.test(text)) { | |
// Don't remove spaces inside comments | |
return text.trim() | |
} else if (Filter.elemhideRegExp.test(text)) { | |
// Special treatment for element hiding filters, right side is allowed to contain spaces | |
const [, domain, separator, selector] = /^(.*?)(#@?#?)(.*)$/.exec(text) | |
return domain.replace(/\s/g, '') + separator + selector.trim() | |
} else return text.replace(/\s/g, '') | |
} | |
/** | |
* Class for invalid filters | |
* @param {String} text see Filter() | |
* @param {String} reason Reason why this filter is invalid | |
* @constructor | |
* @augments Filter | |
*/ | |
function InvalidFilter(text, reason) { | |
Filter.call(this, text) | |
this.reason = reason | |
} | |
exports.InvalidFilter = InvalidFilter | |
InvalidFilter.prototype = { | |
__proto__: Filter.prototype, | |
/** | |
* Reason why this filter is invalid | |
* @type String | |
*/ | |
reason: null, | |
/** | |
* See Filter.serialize() | |
*/ | |
serialize: function (_buffer) {}, | |
} | |
/** | |
* Class for comments | |
* @param {String} text see Filter() | |
* @constructor | |
* @augments Filter | |
*/ | |
function CommentFilter(text) { | |
Filter.call(this, text) | |
} | |
exports.CommentFilter = CommentFilter | |
CommentFilter.prototype = { | |
__proto__: Filter.prototype, | |
/** | |
* See Filter.serialize() | |
*/ | |
serialize: function (_buffer) {}, | |
} | |
/** | |
* Abstract base class for filters that can get hits | |
* @param {String} text see Filter() | |
* @param {String} [domains] Domains that the filter is restricted to separated by domainSeparator e.g. | |
* "foo.com|bar.com|~baz.com" | |
* @constructor | |
* @augments Filter | |
*/ | |
function ActiveFilter(text, domains) { | |
Filter.call(this, text) | |
this.domainSource = domains | |
} | |
exports.ActiveFilter = ActiveFilter | |
ActiveFilter.prototype = { | |
__proto__: Filter.prototype, | |
_disabled: false, | |
_hitCount: 0, | |
_lastHit: 0, | |
/** | |
* Defines whether the filter is disabled | |
* @type Boolean | |
*/ | |
get disabled() { | |
return this._disabled | |
}, | |
set disabled(value) { | |
if (value !== this._disabled) { | |
const oldValue = this._disabled | |
this._disabled = value | |
FilterNotifier.triggerListeners('filter.disabled', this, value, oldValue) | |
} | |
}, | |
/** | |
* Number of hits on the filter since the last reset | |
* @type Number | |
*/ | |
get hitCount() { | |
return this._hitCount | |
}, | |
set hitCount(value) { | |
if (value !== this._hitCount) { | |
const oldValue = this._hitCount | |
this._hitCount = value | |
FilterNotifier.triggerListeners('filter.hitCount', this, value, oldValue) | |
} | |
}, | |
/** | |
* Last time the filter had a hit (in milliseconds since the beginning of the epoch) | |
* @type Number | |
*/ | |
get lastHit() { | |
return this._lastHit | |
}, | |
set lastHit(value) { | |
if (value !== this._lastHit) { | |
const oldValue = this._lastHit | |
this._lastHit = value | |
FilterNotifier.triggerListeners('filter.lastHit', this, value, oldValue) | |
} | |
}, | |
/** | |
* String that the domains property should be generated from | |
* @type String | |
*/ | |
domainSource: null, | |
/** | |
* Separator character used in domainSource property, must be overridden by subclasses | |
* @type String | |
*/ | |
domainSeparator: null, | |
/** | |
* Determines whether the trailing dot in domain names isn't important and | |
* should be ignored, must be overridden by subclasses. | |
* @type Boolean | |
*/ | |
ignoreTrailingDot: true, | |
/** | |
* Determines whether domainSource is already upper-case, | |
* can be overridden by subclasses. | |
* @type Boolean | |
*/ | |
domainSourceIsUpperCase: false, | |
/** | |
* Map containing domains that this filter should match on/not match on or null if the filter should match on all | |
* domains | |
* @type Object | |
*/ | |
/* eslint-disable sonarjs/cognitive-complexity */ | |
get domains() { | |
// Despite this property being cached, the getter is called | |
// several times on Safari, due to WebKit bug 132872 | |
const prop = Object.getOwnPropertyDescriptor(this, 'domains') | |
if (prop) return prop.value | |
let domains = null | |
if (this.domainSource) { | |
let source = this.domainSource | |
if (!this.domainSourceIsUpperCase) { | |
// RegExpFilter already have uppercase domains | |
source = source.toUpperCase() | |
} | |
const list = source.split(this.domainSeparator) | |
if (list.length === 1 && list[0][0] !== '~') { | |
// Fast track for the common one-domain scenario | |
domains = { __proto__: null, '': false } | |
if (this.ignoreTrailingDot) list[0] = list[0].replace(/\.+$/, '') | |
domains[list[0]] = true | |
} else { | |
let hasIncludes = false | |
for (let i = 0; i < list.length; i++) { | |
let domain = list[i] | |
if (this.ignoreTrailingDot) domain = domain.replace(/\.+$/, '') | |
if (domain === '') continue | |
let include | |
if (domain[0] === '~') { | |
include = false | |
domain = domain.substr(1) | |
} else { | |
include = true | |
hasIncludes = true | |
} | |
if (!domains) domains = Object.create(null) | |
domains[domain] = include | |
} | |
domains[''] = !hasIncludes | |
} | |
this.domainSource = null | |
} | |
Object.defineProperty(this, 'domains', { value: domains, enumerable: true }) | |
return this.domains | |
}, | |
/** | |
* Array containing public keys of websites that this filter should apply to | |
* @type Array of String | |
*/ | |
sitekeys: null, | |
/** | |
* Checks whether this filter is active on a domain. | |
* @param {String} docDomain domain name of the document that loads the URL | |
* @param {String} [sitekey] public key provided by the document | |
* @return {Boolean} true in case of the filter being active | |
*/ | |
isActiveOnDomain: function (docDomain, sitekey) { | |
// Sitekeys are case-sensitive so we shouldn't convert them to upper-case to avoid false | |
// positives here. Instead we need to change the way filter options are parsed. | |
if (this.sitekeys && (!sitekey || this.sitekeys.indexOf(sitekey.toUpperCase()) < 0)) return false | |
// If no domains are set the rule matches everywhere | |
if (!this.domains) return true | |
// If the document has no host name, match only if the filter isn't restricted to specific domains | |
if (!docDomain) return this.domains[''] | |
if (this.ignoreTrailingDot) docDomain = docDomain.replace(/\.+$/, '') | |
docDomain = docDomain.toUpperCase() | |
while (true) { | |
if (docDomain in this.domains) return this.domains[docDomain] | |
const nextDot = docDomain.indexOf('.') | |
if (nextDot < 0) break | |
docDomain = docDomain.substr(nextDot + 1) | |
} | |
return this.domains[''] | |
}, | |
/** | |
* Checks whether this filter is active only on a domain and its subdomains. | |
*/ | |
isActiveOnlyOnDomain: function (/**String*/ docDomain /**Boolean*/) { | |
if (!docDomain || !this.domains || this.domains['']) return false | |
if (this.ignoreTrailingDot) docDomain = docDomain.replace(/\.+$/, '') | |
docDomain = docDomain.toUpperCase() | |
for (const domain in this.domains) | |
if ( | |
Object.prototype.hasOwnProperty.call(this.domains, domain) && | |
this.domains[domain] && | |
domain !== docDomain && | |
(domain.length <= docDomain.length || domain.indexOf('.' + docDomain) !== domain.length - docDomain.length - 1) | |
) | |
return false | |
return true | |
}, | |
/** | |
* See Filter.serialize() | |
*/ | |
serialize: function (buffer) { | |
if (this._disabled || this._hitCount || this._lastHit) { | |
Filter.prototype.serialize.call(this, buffer) | |
if (this._disabled) buffer.push('disabled=true') | |
if (this._hitCount) buffer.push('hitCount=' + this._hitCount) | |
if (this._lastHit) buffer.push('lastHit=' + this._lastHit) | |
} | |
}, | |
} | |
/** | |
* Abstract base class for RegExp-based filters | |
* @param {String} text see Filter() | |
* @param {String} regexpSource filter part that the regular expression should be build from | |
* @param {Number} [contentType] Content types the filter applies to, combination of values from RegExpFilter.typeMap | |
* @param {Boolean} [matchCase] Defines whether the filter should distinguish between lower and upper case letters | |
* @param {String} [domains] Domains that the filter is restricted to, e.g. "foo.com|bar.com|~baz.com" | |
* @param {Boolean} [thirdParty] Defines whether the filter should apply to third-party or first-party content only | |
* @param {String} [sitekeys] Public keys of websites that this filter should apply to | |
* @constructor | |
* @augments ActiveFilter | |
*/ | |
function RegExpFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys) { | |
ActiveFilter.call(this, text, domains, sitekeys) | |
if (contentType != null) this.contentType = contentType | |
if (matchCase) this.matchCase = matchCase | |
if (thirdParty != null) this.thirdParty = thirdParty | |
if (sitekeys != null) this.sitekeySource = sitekeys | |
if (regexpSource.length >= 2 && regexpSource[0] === '/' && regexpSource[regexpSource.length - 1] === '/') { | |
// The filter is a regular expression - convert it immediately to catch syntax errors | |
const regexp = new RegExp(regexpSource.substr(1, regexpSource.length - 2), this.matchCase ? '' : 'i') | |
Object.defineProperty(this, 'regexp', { value: regexp }) | |
} else { | |
// No need to convert this filter to regular expression yet, do it on demand | |
this.regexpSource = regexpSource | |
} | |
} | |
exports.RegExpFilter = RegExpFilter | |
RegExpFilter.prototype = { | |
__proto__: ActiveFilter.prototype, | |
/** | |
* @see ActiveFilter.domainSourceIsUpperCase | |
*/ | |
domainSourceIsUpperCase: true, | |
/** | |
* Number of filters contained, will always be 1 (required to optimize Matcher). | |
* @type Integer | |
*/ | |
length: 1, | |
/** | |
* @see ActiveFilter.domainSeparator | |
*/ | |
domainSeparator: '|', | |
/** | |
* Expression from which a regular expression should be generated - for delayed creation of the regexp property | |
* @type String | |
*/ | |
regexpSource: null, | |
/** | |
* Regular expression to be used when testing against this filter | |
* @type RegExp | |
*/ | |
get regexp() { | |
// Despite this property being cached, the getter is called | |
// several times on Safari, due to WebKit bug 132872 | |
const prop = Object.getOwnPropertyDescriptor(this, 'regexp') | |
if (prop) return prop.value | |
// Remove multiple wildcards | |
const source = this.regexpSource | |
.replace(/\*+/g, '*') // remove multiple wildcards | |
.replace(/\^\|$/, '^') // remove anchors following separator placeholder | |
.replace(/\W/g, '\\$&') // escape special symbols | |
.replace(/\\\*/g, '.*') // replace wildcards by .* | |
// process separator placeholders (all ANSI characters but alphanumeric characters and _%.-) | |
.replace(/\\\^/g, '(?:[\\x00-\\x24\\x26-\\x2C\\x2F\\x3A-\\x40\\x5B-\\x5E\\x60\\x7B-\\x7F]|$)') | |
.replace(/^\\\|\\\|/, '^[\\w\\-]+:\\/+(?!\\/)(?:[^\\/]+\\.)?') // process extended anchor at expression start | |
.replace(/^\\\|/, '^') // process anchor at expression start | |
.replace(/\\\|$/, '$') // process anchor at expression end | |
.replace(/^(\.\*)/, '') // remove leading wildcards | |
.replace(/(\.\*)$/, '') // remove trailing wildcards | |
const regexp = new RegExp(source, this.matchCase ? '' : 'i') | |
Object.defineProperty(this, 'regexp', { value: regexp }) | |
return regexp | |
}, | |
/** | |
* Content types the filter applies to, combination of values from RegExpFilter.typeMap | |
* @type Number | |
*/ | |
contentType: 0x7fffffff, | |
/** | |
* Defines whether the filter should distinguish between lower and upper case letters | |
* @type Boolean | |
*/ | |
matchCase: false, | |
/** | |
* Defines whether the filter should apply to third-party or first-party content only. Can be null (apply to all | |
* content). | |
* @type Boolean | |
*/ | |
thirdParty: null, | |
/** | |
* String that the sitekey property should be generated from | |
* @type String | |
*/ | |
sitekeySource: null, | |
/** | |
* Array containing public keys of websites that this filter should apply to | |
* @type Array of String | |
*/ | |
get sitekeys() { | |
// Despite this property being cached, the getter is called | |
// several times on Safari, due to WebKit bug 132872 | |
const prop = Object.getOwnPropertyDescriptor(this, 'sitekeys') | |
if (prop) return prop.value | |
let sitekeys = null | |
if (this.sitekeySource) { | |
sitekeys = this.sitekeySource.split('|') | |
this.sitekeySource = null | |
} | |
Object.defineProperty(this, 'sitekeys', { | |
value: sitekeys, | |
enumerable: true, | |
}) | |
return this.sitekeys | |
}, | |
/** | |
* Tests whether the URL matches this filter | |
* @param {String} location URL to be tested | |
* @param {String} contentType content type identifier of the URL | |
* @param {String} docDomain domain name of the document that loads the URL | |
* @param {Boolean} thirdParty should be true if the URL is a third-party request | |
* @param {String} sitekey public key provided by the document | |
* @return {Boolean} true in case of a match | |
*/ | |
matches: function (location, contentType, docDomain, thirdParty, sitekey) { | |
return ( | |
this.regexp.test(location) && | |
(RegExpFilter.typeMap[contentType] & this.contentType) !== 0 && | |
(this.thirdParty == null || this.thirdParty === thirdParty) && | |
this.isActiveOnDomain(docDomain, sitekey) | |
) | |
}, | |
} | |
// Required to optimize Matcher, see also RegExpFilter.prototype.length | |
Object.defineProperty(RegExpFilter.prototype, '0', { | |
get: function () { | |
return this | |
}, | |
}) | |
/** | |
* Creates a RegExp filter from its text representation | |
* @param {String} text same as in Filter() | |
*/ | |
/* eslint-disable sonarjs/cognitive-complexity */ | |
RegExpFilter.fromText = function (text) { | |
let blocking = true | |
const origText = text | |
if (text.indexOf('@@') === 0) { | |
blocking = false | |
text = text.substr(2) | |
} | |
let contentType = null | |
let matchCase = null | |
let domains = null | |
let sitekeys = null | |
let thirdParty = null | |
let collapse = null | |
let options | |
const match = text.indexOf('$') >= 0 ? Filter.optionsRegExp.exec(text) : null | |
if (match) { | |
options = match[1].toUpperCase().split(',') | |
text = match.input.substr(0, match.index) | |
for (let option of options) { | |
let value = null | |
let separatorIndex = option.indexOf('=') | |
if (separatorIndex >= 0) { | |
value = option.substr(separatorIndex + 1) | |
option = option.substr(0, separatorIndex) | |
} | |
option = option.replace(/-/, '_') | |
if (option in RegExpFilter.typeMap) { | |
if (contentType == null) contentType = 0 | |
contentType |= RegExpFilter.typeMap[option] | |
} else if (option[0] === '~' && option.substr(1) in RegExpFilter.typeMap) { | |
if (contentType == null) contentType = RegExpFilter.prototype.contentType | |
contentType &= ~RegExpFilter.typeMap[option.substr(1)] | |
} else if (option === 'MATCH_CASE') matchCase = true | |
else if (option === '~MATCH_CASE') matchCase = false | |
else if (option === 'DOMAIN' && typeof value != 'undefined') domains = value | |
else if (option === 'THIRD_PARTY') thirdParty = true | |
else if (option === '~THIRD_PARTY') thirdParty = false | |
else if (option === 'COLLAPSE') collapse = true | |
else if (option === '~COLLAPSE') collapse = false | |
else if (option === 'SITEKEY' && typeof value != 'undefined') sitekeys = value | |
else return new InvalidFilter(origText, 'Unknown option ' + option.toLowerCase()) | |
} | |
} | |
if ( | |
!blocking && | |
(contentType == null || contentType & RegExpFilter.typeMap.DOCUMENT) && | |
(!options || options.indexOf('DOCUMENT') < 0) && | |
!/^\|?[\w-]+:/.test(text) | |
) { | |
// Exception filters shouldn't apply to pages by default unless they start with a protocol name | |
if (contentType == null) contentType = RegExpFilter.prototype.contentType | |
contentType &= ~RegExpFilter.typeMap.DOCUMENT | |
} | |
try { | |
if (blocking) | |
return new BlockingFilter(origText, text, contentType, matchCase, domains, thirdParty, sitekeys, collapse) | |
else return new WhitelistFilter(origText, text, contentType, matchCase, domains, thirdParty, sitekeys) | |
} catch (e) { | |
return new InvalidFilter(origText, e) | |
} | |
} | |
/** | |
* Maps type strings like "SCRIPT" or "OBJECT" to bit masks | |
*/ | |
RegExpFilter.typeMap = { | |
OTHER: 1, | |
SCRIPT: 2, | |
IMAGE: 4, | |
STYLESHEET: 8, | |
OBJECT: 16, | |
SUBDOCUMENT: 32, | |
DOCUMENT: 64, | |
XBL: 1, | |
PING: 1, | |
XMLHTTPREQUEST: 2048, | |
OBJECT_SUBREQUEST: 4096, | |
DTD: 1, | |
MEDIA: 16384, | |
FONT: 32768, | |
BACKGROUND: 4, // Backwards compat, same as IMAGE | |
POPUP: 0x10000000, | |
ELEMHIDE: 0x40000000, | |
} | |
// ELEMHIDE, POPUP option shouldn't be there by default | |
RegExpFilter.prototype.contentType &= ~(RegExpFilter.typeMap.ELEMHIDE | RegExpFilter.typeMap.POPUP) | |
/** | |
* Class for blocking filters | |
* @param {String} text see Filter() | |
* @param {String} regexpSource see RegExpFilter() | |
* @param {Number} contentType see RegExpFilter() | |
* @param {Boolean} matchCase see RegExpFilter() | |
* @param {String} domains see RegExpFilter() | |
* @param {Boolean} thirdParty see RegExpFilter() | |
* @param {String} sitekeys see RegExpFilter() | |
* @param {Boolean} collapse defines whether the filter should collapse blocked content, can be null | |
* @constructor | |
* @augments RegExpFilter | |
*/ | |
function BlockingFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys, collapse) { | |
RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys) | |
this.collapse = collapse | |
} | |
exports.BlockingFilter = BlockingFilter | |
BlockingFilter.prototype = { | |
__proto__: RegExpFilter.prototype, | |
/** | |
* Defines whether the filter should collapse blocked content. Can be null (use the global preference). | |
* @type Boolean | |
*/ | |
collapse: null, | |
} | |
/** | |
* Class for whitelist filters | |
* @param {String} text see Filter() | |
* @param {String} regexpSource see RegExpFilter() | |
* @param {Number} contentType see RegExpFilter() | |
* @param {Boolean} matchCase see RegExpFilter() | |
* @param {String} domains see RegExpFilter() | |
* @param {Boolean} thirdParty see RegExpFilter() | |
* @param {String} sitekeys see RegExpFilter() | |
* @constructor | |
* @augments RegExpFilter | |
*/ | |
function WhitelistFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys) { | |
RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys) | |
} | |
exports.WhitelistFilter = WhitelistFilter | |
WhitelistFilter.prototype = { | |
__proto__: RegExpFilter.prototype, | |
} | |
/***/ }), | |
/***/ "./gfp/lib/filterNotifier.js": | |
/*!***********************************!*\ | |
!*** ./gfp/lib/filterNotifier.js ***! | |
\***********************************/ | |
/*! default exports */ | |
/*! export FilterNotifier [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! other exports [not provided] [no usage info] */ | |
/*! runtime requirements: __webpack_exports__ */ | |
/***/ ((__unused_webpack_module, exports) => { | |
/* | |
* This file is part of Adblock Plus <https://adblockplus.org/>, | |
* Copyright (C) 2006-2015 Eyeo GmbH | |
* | |
* Adblock Plus is free software: you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License version 3 as | |
* published by the Free Software Foundation. | |
* | |
* Adblock Plus is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* | |
* You should have received a copy of the GNU General Public License | |
* along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | |
*/ | |
/** | |
* @fileOverview This component manages listeners and calls them to distributes | |
* messages about filter changes. | |
*/ | |
/** | |
* List of registered listeners | |
* @type Array of function(action, item, newValue, oldValue) | |
*/ | |
const listeners = [] | |
/** | |
* This class allows registering and triggering listeners for filter events. | |
* @class | |
*/ | |
const _FilterNotifier = (exports.FilterNotifier = { | |
/** | |
* Adds a listener | |
*/ | |
addListener: function (/**function(action, item, newValue, oldValue)*/ listener) { | |
if (listeners.indexOf(listener) >= 0) return | |
listeners.push(listener) | |
}, | |
/** | |
* Removes a listener that was previosly added via addListener | |
*/ | |
removeListener: function (/**function(action, item, newValue, oldValue)*/ listener) { | |
const index = listeners.indexOf(listener) | |
if (index >= 0) listeners.splice(index, 1) | |
}, | |
/** | |
* Notifies listeners about an event | |
* @param {String} action event code ("load", "save", "elemhideupdate", | |
* "subscription.added", "subscription.removed", | |
* "subscription.disabled", "subscription.title", | |
* "subscription.lastDownload", "subscription.downloadStatus", | |
* "subscription.homepage", "subscription.updated", | |
* "filter.added", "filter.removed", "filter.moved", | |
* "filter.disabled", "filter.hitCount", "filter.lastHit") | |
* @param {Filter} item item that the change applies to | |
*/ | |
triggerListeners: function (action, item, param1, param2, param3) { | |
const list = listeners.slice() | |
for (const listener of list) listener(action, item, param1, param2, param3) | |
}, | |
}) | |
/***/ }), | |
/***/ "./gfp/lib/matcher.js": | |
/*!****************************!*\ | |
!*** ./gfp/lib/matcher.js ***! | |
\****************************/ | |
/*! default exports */ | |
/*! export CombinedMatcher [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! export Matcher [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! export defaultMatcher [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! other exports [not provided] [no usage info] */ | |
/*! runtime requirements: __webpack_exports__, __webpack_require__ */ | |
/***/ ((__unused_webpack_module, exports, __webpack_require__) => { | |
/* | |
* This file is part of Adblock Plus <https://adblockplus.org/>, | |
* Copyright (C) 2006-2015 Eyeo GmbH | |
* | |
* Adblock Plus is free software: you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License version 3 as | |
* published by the Free Software Foundation. | |
* | |
* Adblock Plus is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* | |
* You should have received a copy of the GNU General Public License | |
* along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | |
*/ | |
/** | |
* @fileOverview Matcher class implementing matching addresses against a list of filters. | |
*/ | |
const { Filter, _RegExpFilter, WhitelistFilter } = __webpack_require__(/*! ./filterClasses */ "./gfp/lib/filterClasses.js") | |
/** | |
* Blacklist/whitelist filter matching | |
* @constructor | |
*/ | |
function Matcher() { | |
this.clear() | |
} | |
exports.Matcher = Matcher | |
Matcher.prototype = { | |
/** | |
* Lookup table for filters by their associated keyword | |
* @type Object | |
*/ | |
filterByKeyword: null, | |
/** | |
* Lookup table for keywords by the filter text | |
* @type Object | |
*/ | |
keywordByFilter: null, | |
/** | |
* Removes all known filters | |
*/ | |
clear: function () { | |
this.filterByKeyword = Object.create(null) | |
this.keywordByFilter = Object.create(null) | |
}, | |
/** | |
* Adds a filter to the matcher | |
* @param {RegExpFilter} filter | |
*/ | |
add: function (filter) { | |
if (filter.text in this.keywordByFilter) return | |
// Look for a suitable keyword | |
const keyword = this.findKeyword(filter) | |
const oldEntry = this.filterByKeyword[keyword] | |
if (typeof oldEntry == 'undefined') this.filterByKeyword[keyword] = filter | |
else if (oldEntry.length === 1) this.filterByKeyword[keyword] = [oldEntry, filter] | |
else oldEntry.push(filter) | |
this.keywordByFilter[filter.text] = keyword | |
}, | |
/** | |
* Removes a filter from the matcher | |
* @param {RegExpFilter} filter | |
*/ | |
remove: function (filter) { | |
if (!(filter.text in this.keywordByFilter)) return | |
const keyword = this.keywordByFilter[filter.text] | |
const list = this.filterByKeyword[keyword] | |
if (list.length <= 1) delete this.filterByKeyword[keyword] | |
else { | |
const index = list.indexOf(filter) | |
if (index >= 0) { | |
list.splice(index, 1) | |
if (list.length === 1) this.filterByKeyword[keyword] = list[0] | |
} | |
} | |
delete this.keywordByFilter[filter.text] | |
}, | |
/** | |
* Chooses a keyword to be associated with the filter | |
* @param {String} text text representation of the filter | |
* @return {String} keyword (might be empty string) | |
*/ | |
findKeyword: function (filter) { | |
let result = '' | |
let text = filter.text | |
if (Filter.regexpRegExp.test(text)) return result | |
// Remove options | |
const match = Filter.optionsRegExp.exec(text) | |
if (match) text = match.input.substr(0, match.index) | |
// Remove whitelist marker | |
if (text.substr(0, 2) === '@@') text = text.substr(2) | |
const candidates = text.toLowerCase().match(/[^a-z0-9%*][a-z0-9%]{3,}(?=[^a-z0-9%*])/g) | |
if (!candidates) return result | |
const hash = this.filterByKeyword | |
let resultCount = 0xffffff | |
let resultLength = 0 | |
for (let i = 0, l = candidates.length; i < l; i++) { | |
const candidate = candidates[i].substr(1) | |
const count = candidate in hash ? hash[candidate].length : 0 | |
if (count < resultCount || (count === resultCount && candidate.length > resultLength)) { | |
result = candidate | |
resultCount = count | |
resultLength = candidate.length | |
} | |
} | |
return result | |
}, | |
/** | |
* Checks whether a particular filter is being matched against. | |
*/ | |
hasFilter: function (/**RegExpFilter*/ filter /**Boolean*/) { | |
return filter.text in this.keywordByFilter | |
}, | |
/** | |
* Returns the keyword used for a filter, null for unknown filters. | |
*/ | |
getKeywordForFilter: function (/**RegExpFilter*/ filter /**String*/) { | |
if (filter.text in this.keywordByFilter) return this.keywordByFilter[filter.text] | |
else return null | |
}, | |
/** | |
* Checks whether the entries for a particular keyword match a URL | |
*/ | |
_checkEntryMatch: function (keyword, location, contentType, docDomain, thirdParty, sitekey) { | |
const list = this.filterByKeyword[keyword] | |
for (let i = 0; i < list.length; i++) { | |
const filter = list[i] | |
if (filter.matches(location, contentType, docDomain, thirdParty, sitekey)) return filter | |
} | |
return null | |
}, | |
/** | |
* Tests whether the URL matches any of the known filters | |
* @param {String} location URL to be tested | |
* @param {String} contentType content type identifier of the URL | |
* @param {String} docDomain domain name of the document that loads the URL | |
* @param {Boolean} thirdParty should be true if the URL is a third-party request | |
* @param {String} sitekey public key provided by the document | |
* @return {RegExpFilter} matching filter or null | |
*/ | |
matchesAny: function (location, contentType, docDomain, thirdParty, sitekey) { | |
let candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g) | |
if (candidates === null) candidates = [] | |
candidates.push('') | |
for (let i = 0, l = candidates.length; i < l; i++) { | |
const substr = candidates[i] | |
if (substr in this.filterByKeyword) { | |
const result = this._checkEntryMatch(substr, location, contentType, docDomain, thirdParty, sitekey) | |
if (result) return result | |
} | |
} | |
return null | |
}, | |
} | |
/** | |
* Combines a matcher for blocking and exception rules, automatically sorts | |
* rules into two Matcher instances. | |
* @constructor | |
*/ | |
function CombinedMatcher() { | |
this.blacklist = new Matcher() | |
this.whitelist = new Matcher() | |
this.resultCache = Object.create(null) | |
} | |
exports.CombinedMatcher = CombinedMatcher | |
/** | |
* Maximal number of matching cache entries to be kept | |
* @type Number | |
*/ | |
CombinedMatcher.maxCacheEntries = 1000 | |
CombinedMatcher.prototype = { | |
/** | |
* Matcher for blocking rules. | |
* @type Matcher | |
*/ | |
blacklist: null, | |
/** | |
* Matcher for exception rules. | |
* @type Matcher | |
*/ | |
whitelist: null, | |
/** | |
* Lookup table of previous matchesAny results | |
* @type Object | |
*/ | |
resultCache: null, | |
/** | |
* Number of entries in resultCache | |
* @type Number | |
*/ | |
cacheEntries: 0, | |
/** | |
* @see Matcher#clear | |
*/ | |
clear: function () { | |
this.blacklist.clear() | |
this.whitelist.clear() | |
this.resultCache = Object.create(null) | |
this.cacheEntries = 0 | |
}, | |
/** | |
* @see Matcher#add | |
*/ | |
add: function (filter) { | |
if (filter instanceof WhitelistFilter) this.whitelist.add(filter) | |
else this.blacklist.add(filter) | |
if (this.cacheEntries > 0) { | |
this.resultCache = Object.create(null) | |
this.cacheEntries = 0 | |
} | |
}, | |
/** | |
* @see Matcher#remove | |
*/ | |
remove: function (filter) { | |
if (filter instanceof WhitelistFilter) this.whitelist.remove(filter) | |
else this.blacklist.remove(filter) | |
if (this.cacheEntries > 0) { | |
this.resultCache = Object.create(null) | |
this.cacheEntries = 0 | |
} | |
}, | |
/** | |
* @see Matcher#findKeyword | |
*/ | |
findKeyword: function (filter) { | |
if (filter instanceof WhitelistFilter) return this.whitelist.findKeyword(filter) | |
else return this.blacklist.findKeyword(filter) | |
}, | |
/** | |
* @see Matcher#hasFilter | |
*/ | |
hasFilter: function (filter) { | |
if (filter instanceof WhitelistFilter) return this.whitelist.hasFilter(filter) | |
else return this.blacklist.hasFilter(filter) | |
}, | |
/** | |
* @see Matcher#getKeywordForFilter | |
*/ | |
getKeywordForFilter: function (filter) { | |
if (filter instanceof WhitelistFilter) return this.whitelist.getKeywordForFilter(filter) | |
else return this.blacklist.getKeywordForFilter(filter) | |
}, | |
/** | |
* Checks whether a particular filter is slow | |
*/ | |
isSlowFilter: function (/**RegExpFilter*/ filter /**Boolean*/) { | |
let matcher = filter instanceof WhitelistFilter ? this.whitelist : this.blacklist | |
if (matcher.hasFilter(filter)) return !matcher.getKeywordForFilter(filter) | |
else return !matcher.findKeyword(filter) | |
}, | |
/** | |
* Optimized filter matching testing both whitelist and blacklist matchers | |
* simultaneously. For parameters see Matcher.matchesAny(). | |
* @see Matcher#matchesAny | |
*/ | |
matchesAnyInternal: function (location, contentType, docDomain, thirdParty, sitekey) { | |
let candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g) | |
if (candidates === null) candidates = [] | |
candidates.push('') | |
let blacklistHit = null | |
for (let i = 0, l = candidates.length; i < l; i++) { | |
const substr = candidates[i] | |
if (substr in this.whitelist.filterByKeyword) { | |
const result = this.whitelist._checkEntryMatch(substr, location, contentType, docDomain, thirdParty, sitekey) | |
if (result) return result | |
} | |
if (substr in this.blacklist.filterByKeyword && blacklistHit === null) | |
blacklistHit = this.blacklist._checkEntryMatch(substr, location, contentType, docDomain, thirdParty, sitekey) | |
} | |
return blacklistHit | |
}, | |
/** | |
* @see Matcher#matchesAny | |
*/ | |
matchesAny: function (location, contentType, docDomain, thirdParty, sitekey) { | |
const key = location + ' ' + contentType + ' ' + docDomain + ' ' + thirdParty + ' ' + sitekey | |
if (key in this.resultCache) return this.resultCache[key] | |
const result = this.matchesAnyInternal(location, contentType, docDomain, thirdParty, sitekey) | |
if (this.cacheEntries >= CombinedMatcher.maxCacheEntries) { | |
this.resultCache = Object.create(null) | |
this.cacheEntries = 0 | |
} | |
this.resultCache[key] = result | |
this.cacheEntries++ | |
return result | |
}, | |
} | |
/** | |
* Shared CombinedMatcher instance that should usually be used. | |
* @type CombinedMatcher | |
*/ | |
const _defaultMatcher = (exports.defaultMatcher = new CombinedMatcher()) | |
/***/ }), | |
/***/ "./gfp/plugin sync recursive ^\\.\\/.*$": | |
/*!***********************************!*\ | |
!*** ./gfp/plugin/ sync ^\.\/.*$ ***! | |
\***********************************/ | |
/*! default exports */ | |
/*! exports [not provided] [no usage info] */ | |
/*! runtime requirements: module, __webpack_require__.o, __webpack_require__ */ | |
/***/ ((module, __unused_webpack_exports, __webpack_require__) => { | |
var map = { | |
"./autopagerize": "./gfp/plugin/autopagerize.js", | |
"./autopagerize.js": "./gfp/plugin/autopagerize.js", | |
"./customsearch": "./gfp/plugin/customsearch.js", | |
"./customsearch.js": "./gfp/plugin/customsearch.js", | |
"./google": "./gfp/plugin/google.js", | |
"./google.js": "./gfp/plugin/google.js", | |
"./instant": "./gfp/plugin/instant.js", | |
"./instant.js": "./gfp/plugin/instant.js" | |
}; | |
function webpackContext(req) { | |
var id = webpackContextResolve(req); | |
return __webpack_require__(id); | |
} | |
function webpackContextResolve(req) { | |
if(!__webpack_require__.o(map, req)) { | |
var e = new Error("Cannot find module '" + req + "'"); | |
e.code = 'MODULE_NOT_FOUND'; | |
throw e; | |
} | |
return map[req]; | |
} | |
webpackContext.keys = function webpackContextKeys() { | |
return Object.keys(map); | |
}; | |
webpackContext.resolve = webpackContextResolve; | |
module.exports = webpackContext; | |
webpackContext.id = "./gfp/plugin sync recursive ^\\.\\/.*$"; | |
/***/ }), | |
/***/ "./gfp/bin/main.js": | |
/*!*************************!*\ | |
!*** ./gfp/bin/main.js ***! | |
\*************************/ | |
/*! namespace exports */ | |
/*! exports [not provided] [no usage info] */ | |
/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.* */ | |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { | |
"use strict"; | |
__webpack_require__.r(__webpack_exports__); | |
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../config */ "./gfp/config.js"); | |
/* harmony import */ var _pref__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../pref */ "./gfp/pref.js"); | |
/* harmony import */ var _logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../logger */ "./gfp/logger.js"); | |
function main() { | |
_logger__WEBPACK_IMPORTED_MODULE_2__.LogTime.start(); | |
const config = new _config__WEBPACK_IMPORTED_MODULE_0__.default(); // es5 to allow webpack to parse requires | |
let searchGui = null; | |
for (let i = 0; i < config.plugins.length; i++) { | |
searchGui = __webpack_require__("./gfp/plugin sync recursive ^\\.\\/.*$")("./" + config.plugins[i]).default(searchGui, config); | |
} | |
new _pref__WEBPACK_IMPORTED_MODULE_1__.default(searchGui); | |
_logger__WEBPACK_IMPORTED_MODULE_2__.LogTime.snap('Total init time'); | |
} | |
main(); | |
/***/ }), | |
/***/ "./gfp/config.js": | |
/*!***********************!*\ | |
!*** ./gfp/config.js ***! | |
\***********************/ | |
/*! namespace exports */ | |
/*! export default [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! other exports [not provided] [no usage info] */ | |
/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.d, __webpack_require__.* */ | |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { | |
"use strict"; | |
__webpack_require__.r(__webpack_exports__); | |
/* harmony export */ __webpack_require__.d(__webpack_exports__, { | |
/* harmony export */ "default": () => /* binding */ Config | |
/* harmony export */ }); | |
/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./filter */ "./gfp/filter.js"); | |
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils */ "./gfp/utils.js"); | |
class Filters { | |
constructor(filters) { | |
this._comparer = (x, y) => x['text'] > y['text'] ? 1 : x['text'] < y['text'] ? -1 : 0; | |
this._filters = filters.sort(this._comparer); | |
this._callbacks = []; | |
} | |
get length() { | |
return this._filters.length; | |
} | |
[Symbol.iterator]() { | |
return this._filters[Symbol.iterator](); | |
} | |
_trigger(type, value) { | |
for (const cb of this._callbacks) { | |
cb(type, value); | |
} | |
} | |
add(filter) { | |
this._filters.splice((0,_utils__WEBPACK_IMPORTED_MODULE_1__.bisect)(this._filters, filter, this._comparer), 0, filter); | |
this._trigger('add', filter); | |
} | |
remove(filters) { | |
(0,_utils__WEBPACK_IMPORTED_MODULE_1__.popMany)(this._filters, (0,_utils__WEBPACK_IMPORTED_MODULE_1__.indexOfSorted)(this._filters, filters.sort(this._comparer), this._comparer)); | |
this._trigger('remove', filters); | |
} | |
update(filter) { | |
this._trigger('update', filter); | |
} | |
setValue(filters) { | |
this._filters = filters.sort(this._comparer); | |
this._trigger('setValue', filters); | |
} | |
observe(cb) { | |
this._callbacks.push(cb); | |
} | |
unobserve(cb) { | |
this._callbacks.splice(this._callbacks.indexOf(cb), 1); | |
} | |
} | |
class Config { | |
constructor() { | |
this.plugins = ['google', 'customsearch', 'instant', 'autopagerize']; | |
this.allowHidden = GM_getValue('allowHidden', true); | |
this.filtersObject = JSON.parse(GM_getValue('filters', '{}')); | |
const filters = []; | |
for (const key in this.filtersObject) { | |
if (Object.prototype.hasOwnProperty.call(this.filtersObject, key)) { | |
filters.push(_filter__WEBPACK_IMPORTED_MODULE_0__.Filter.fromObject(key, this.filtersObject[key])); | |
} | |
} | |
this.filters = new Filters(filters); | |
this.filters.observe((type, value) => { | |
switch (type) { | |
case 'add': | |
this.filtersObject[value.text] = value.toObject(); | |
break; | |
case 'remove': | |
for (const filter of value) { | |
delete this.filtersObject[filter.text]; | |
} | |
break; | |
case 'update': | |
this.filtersObject[value.text] = value.toObject(); | |
break; | |
case 'setValue': | |
this.filtersObject = {}; | |
for (const filter of value) { | |
this.filtersObject[filter.text] = filter.toObject(); | |
} | |
break; | |
} | |
}); | |
} | |
flushAllowHidden() { | |
GM_setValue('allowHidden', this.allowHidden); | |
} | |
flushFilters() { | |
GM_setValue('filters', JSON.stringify(this.filtersObject)); | |
} | |
} | |
/***/ }), | |
/***/ "./gfp/filter.js": | |
/*!***********************!*\ | |
!*** ./gfp/filter.js ***! | |
\***********************/ | |
/*! namespace exports */ | |
/*! export BlockingFilter [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! export Filter [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! export MultiRegExpFilter [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! export RegExpFilter [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! export WhitelistFilter [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! other exports [not provided] [no usage info] */ | |
/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.d, __webpack_require__.* */ | |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { | |
"use strict"; | |
__webpack_require__.r(__webpack_exports__); | |
/* harmony export */ __webpack_require__.d(__webpack_exports__, { | |
/* harmony export */ "RegExpFilter": () => /* binding */ RegExpFilter, | |
/* harmony export */ "MultiRegExpFilter": () => /* binding */ MultiRegExpFilter, | |
/* harmony export */ "Filter": () => /* binding */ Filter, | |
/* harmony export */ "BlockingFilter": () => /* binding */ BlockingFilter, | |
/* harmony export */ "WhitelistFilter": () => /* binding */ WhitelistFilter | |
/* harmony export */ }); | |
/* harmony import */ var _lib_filterClasses__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lib/filterClasses */ "./gfp/lib/filterClasses.js"); | |
const RegExpFilter__ = Object.assign(new Function(), _lib_filterClasses__WEBPACK_IMPORTED_MODULE_0__.RegExpFilter, { | |
prototype: _lib_filterClasses__WEBPACK_IMPORTED_MODULE_0__.RegExpFilter.prototype | |
}); | |
class RegExpFilter extends RegExpFilter__ { | |
constructor(regexpSource, matchCase, collapse) { | |
super(); | |
if (matchCase) { | |
this.matchCase = matchCase; | |
} | |
if (collapse) { | |
this.collapse = collapse; | |
} // convert regex filters immediately to catch syntax errors, normal filters on-demand | |
if (regexpSource.length >= 2 && regexpSource.startsWith('/') && regexpSource.endsWith('/')) { | |
const regexp = new RegExp(regexpSource.substr(1, regexpSource.length - 2), this.matchCase ? '' : 'i'); | |
Object.defineProperty(this, 'regexp', { | |
value: regexp | |
}); | |
} else { | |
this.regexpSource = regexpSource; | |
} | |
} | |
matches(data) { | |
return this.regexp.test(data); | |
} | |
static fromParts(text, optionsStr = '') { | |
// text is not stored to save memory | |
let matchCase = false; | |
let collapse = false; | |
const options = optionsStr.toUpperCase().split(','); | |
for (const option of options) { | |
switch (option) { | |
case 'MATCH_CASE': | |
matchCase = true; | |
break; | |
case 'COLLAPSE': | |
collapse = true; | |
break; | |
case '': | |
break; | |
default: | |
return new _lib_filterClasses__WEBPACK_IMPORTED_MODULE_0__.InvalidFilter(`Unknown option: ${option}`); | |
} | |
} | |
return new RegExpFilter(text, matchCase, collapse); | |
} | |
*[Symbol.iterator]() { | |
yield this; | |
} | |
} | |
RegExpFilter.prototype.matchCase = false; | |
RegExpFilter.prototype.collapse = false; // index to all subfilters | |
RegExpFilter.prototype.index = 0; // index to all non-null subfilters | |
RegExpFilter.prototype.dataIndex = 0; | |
const ActiveFilter_ = Object.assign(new Function(), _lib_filterClasses__WEBPACK_IMPORTED_MODULE_0__.ActiveFilter, { | |
prototype: _lib_filterClasses__WEBPACK_IMPORTED_MODULE_0__.RegExpFilter.prototype | |
}); | |
class MultiRegExpFilter extends ActiveFilter_ { | |
constructor(text, filters) { | |
super(); | |
this.text = text; | |
this.filters = filters; | |
for (const filter of filters) { | |
filter.parent = this; | |
} | |
} | |
get collapse() { | |
for (const filter of this.filters) { | |
if (filter.collapse) { | |
return true; | |
} | |
} | |
return false; | |
} | |
static fromText(text) { | |
const origText = text; | |
let filters = []; | |
let blocking = true; | |
if (text.indexOf('@@') === 0) { | |
blocking = false; | |
text = text.substr(2); | |
} | |
const parts = text.split(/\$([\w,]*?)(?:\$|$)/); | |
for (let i = 0; i < parts.length; i += 2) { | |
const [part, options] = [parts[i], parts[i + 1]]; | |
if (!part) { | |
continue; | |
} | |
const filter = RegExpFilter.fromParts(part, options); | |
if (filter instanceof _lib_filterClasses__WEBPACK_IMPORTED_MODULE_0__.InvalidFilter) { | |
return new _lib_filterClasses__WEBPACK_IMPORTED_MODULE_0__.InvalidFilter(text); | |
} | |
if (i > 0) { | |
filter.index = i / 2; | |
} | |
if (filters.length > 0) { | |
filter.dataIndex = filters.length; | |
} | |
filters.push(filter); | |
} | |
if (filters.length === 1) { | |
filters = filters[0]; | |
} | |
return blocking ? new BlockingFilter(origText, filters) : new WhitelistFilter(origText, filters); | |
} | |
} | |
const Filter = _lib_filterClasses__WEBPACK_IMPORTED_MODULE_0__.Filter; | |
Filter.fromObject = function (text, obj) { | |
const res = Filter.fromText(text); | |
if (res instanceof _lib_filterClasses__WEBPACK_IMPORTED_MODULE_0__.ActiveFilter) { | |
if ('disabled' in obj) { | |
res._disabled = obj.disabled === true; | |
} | |
if ('hitCount' in obj) { | |
res._hitCount = parseInt(obj.hitCount) || 0; | |
} | |
if ('lastHit' in obj) { | |
res._lastHit = parseInt(obj.lastHit) || null; | |
} | |
} | |
return res; | |
}; | |
Filter.prototype.toObject = function () { | |
const res = {}; | |
if (this instanceof _lib_filterClasses__WEBPACK_IMPORTED_MODULE_0__.ActiveFilter) { | |
if (this._disabled) { | |
res.disabled = true; | |
} | |
if (this._hitCount) { | |
res.hitCount = this._hitCount; | |
} | |
if (this._lastHit) { | |
res.lastHit = this._lastHit; | |
} | |
} | |
return res; | |
}; | |
Filter.fromText = MultiRegExpFilter.fromText; | |
class BlockingFilter extends MultiRegExpFilter {} | |
class WhitelistFilter extends MultiRegExpFilter {} | |
/***/ }), | |
/***/ "./gfp/gui.js": | |
/*!********************!*\ | |
!*** ./gfp/gui.js ***! | |
\********************/ | |
/*! namespace exports */ | |
/*! export NodeData [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! export SearchGui [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! other exports [not provided] [no usage info] */ | |
/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.d, __webpack_require__.* */ | |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { | |
"use strict"; | |
__webpack_require__.r(__webpack_exports__); | |
/* harmony export */ __webpack_require__.d(__webpack_exports__, { | |
/* harmony export */ "NodeData": () => /* binding */ NodeData, | |
/* harmony export */ "SearchGui": () => /* binding */ SearchGui | |
/* harmony export */ }); | |
/* harmony import */ var _css_gui_sass__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./css/gui.sass */ "./gfp/css/gui.sass"); | |
/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./filter */ "./gfp/filter.js"); | |
/* harmony import */ var _matcher__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./matcher */ "./gfp/matcher.js"); | |
class NodeData { | |
constructor(node) { | |
this.node = node; | |
} | |
act(action, filter) { | |
// action: function which modifies the node | |
if (this.action === action) { | |
this.redo(filter); | |
return true; | |
} else { | |
this.undo(); | |
delete this.redo; | |
delete this.undo; | |
} | |
this.action = action; | |
} | |
*getChildren() {} | |
redo() {} // re-apply action with different arguments | |
undo() {} // undo action | |
} | |
NodeData.attrs = ['url', 'title', 'summary']; | |
NodeData.prototype.linkArea = null; | |
NodeData.prototype.url = null; | |
NodeData.prototype.title = null; | |
NodeData.prototype.summary = null; | |
NodeData.prototype.action = null; | |
class SearchGui { | |
constructor(ResultsData, config) { | |
this.ResultsData = ResultsData; | |
this.config = config; | |
const observer = (type, value) => { | |
switch (type) { | |
case 'add': | |
this.matcher.add(value); | |
break; | |
case 'remove': | |
for (const filter of value) { | |
this.matcher.remove(filter); | |
} | |
break; | |
case 'setValue': | |
this.matcher = new _matcher__WEBPACK_IMPORTED_MODULE_2__.CombinedMultiMatcher(NodeData.attrs.length); | |
for (const filter of value) { | |
this.matcher.add(filter); | |
} | |
break; | |
} | |
}; | |
observer('setValue', this.config.filters); | |
this.config.filters.observe(observer); | |
this.nodeData = new NodeData(); | |
this.nodeData.children = []; | |
this.createNodes(); | |
GM_addStyle(_css_gui_sass__WEBPACK_IMPORTED_MODULE_0__.default.toString()); | |
} | |
createNodes() { | |
/** | |
Create once and clone to improve performance. | |
*/ | |
// add filter link | |
this.addLink = document.createElement('a'); | |
this.addLink.textContent = 'Filter'; | |
this.addLink.setAttribute('href', '#'); | |
this.addLink.classList.add('filter-add'); // hidden result title | |
this.showTitle = document.createElement('span'); | |
this.showTitle.classList.add('show-title'); // hidden result 'show' link | |
this.showLink = document.createElement('a'); | |
this.showLink.textContent = 'show'; | |
this.showLink.setAttribute('href', '#'); | |
this.showLink.classList.add('show-link'); | |
} | |
toggleResult(nodeData, showTitle, showLink, initial = false) { | |
for (const child of nodeData.node.children) { | |
if (child !== showTitle && child !== showLink) { | |
child.classList.toggle('hide'); | |
} | |
} | |
if (initial) { | |
return; | |
} | |
if (showTitle) { | |
showTitle.classList.toggle('hide'); | |
} | |
showLink.classList.toggle('hide'); | |
showLink.textContent = showLink.classList.contains('hide') ? 'hide' : 'show'; | |
} | |
hideResult(nodeData, filter = null) { | |
if (!nodeData.node || nodeData.act(this.hideResult, filter)) { | |
return; | |
} | |
if (this.config.allowHidden && (!filter || filter.collapse)) { | |
nodeData.node.classList.add('hide'); | |
nodeData.undo = () => nodeData.node.classList.remove('hide'); | |
return; | |
} | |
let showTitle = null; | |
if (nodeData.title !== null) { | |
showTitle = this.showTitle.cloneNode(false); | |
showTitle.textContent = nodeData.title; | |
nodeData.node.appendChild(showTitle); | |
} | |
const showLink = this.showLink.cloneNode(true); | |
if (filter) { | |
showLink.title = filter.text; | |
} | |
nodeData.node.appendChild(showLink); | |
this.toggleResult(nodeData, showTitle, showLink, true); | |
showLink.onclick = () => { | |
this.toggleResult(nodeData, showTitle, showLink); | |
return false; | |
}; | |
nodeData.redo = filter => { | |
if (filter) { | |
showLink.title = filter.text; | |
} | |
}; | |
nodeData.undo = () => { | |
if (!showLink.classList.contains('hide')) { | |
this.toggleResult(nodeData, showTitle, showLink); | |
} | |
if (showTitle) { | |
showTitle.remove(); | |
} | |
showLink.remove(); | |
}; | |
} | |
addFilterLink(nodeData, filter = null) { | |
if (!nodeData.node || nodeData.act(this.addFilterLink, filter)) { | |
return; | |
} | |
if (!nodeData.linkArea) { | |
return; | |
} | |
const addLink = this.addLink.cloneNode(true); | |
if (filter) { | |
addLink.title = filter.text; | |
} | |
nodeData.linkArea.appendChild(addLink); | |
addLink.onclick = () => { | |
this.addFromResult(nodeData); | |
return false; | |
}; | |
nodeData.redo = filter => { | |
if (filter) { | |
addLink.title = filter.text; | |
} | |
}; | |
nodeData.undo = () => { | |
addLink.remove(); | |
}; | |
} | |
addFromResult(nodeData) { | |
const domainUrl = '||' + nodeData.url.replace(/^[\w-]+:\/+(?:www\.)?/, ''); | |
const text = prompt('Filter: ', domainUrl); | |
if (text === null) { | |
return; | |
} | |
this.config.filters.add(_filter__WEBPACK_IMPORTED_MODULE_1__.MultiRegExpFilter.fromText(text)); | |
this.filterResults(); | |
} | |
_filterResults(nodeData) { | |
// store all children so we can re-filter | |
if (nodeData.children === undefined) { | |
nodeData.children = Array.from(nodeData.getChildren()); | |
} | |
const filter = this.matcher.matchesAny(nodeData, NodeData.attrs); | |
if (filter) { | |
filter.hitCount++; | |
filter.lastHit = new Date().getTime(); | |
this.config.filters.update(filter); | |
if (filter instanceof _filter__WEBPACK_IMPORTED_MODULE_1__.BlockingFilter) { | |
this.hideResult(nodeData, filter); | |
return true; | |
} else { | |
this.addFilterLink(nodeData, filter); | |
return false; | |
} | |
} | |
let filtered = !!nodeData.children.length; | |
for (const childData of nodeData.children) { | |
if (childData.node.querySelector('a.filter-add')) { | |
continue; | |
} | |
if (!this._filterResults(childData)) { | |
filtered = false; | |
} | |
} | |
if (filtered) { | |
this.hideResult(nodeData); | |
} else if (NodeData.attrs.some(attr => nodeData[attr] !== null)) { | |
this.addFilterLink(nodeData); | |
} | |
return filtered; | |
} | |
filterResults(node = null) { | |
/** | |
args: | |
node: Used when additional search results pop up. | |
*/ | |
let matched = false; | |
const observer = (type, _filter) => { | |
if (type === 'update') { | |
matched = true; | |
} | |
}; | |
this.config.filters.observe(observer); | |
if (node) { | |
// only need to filter the new node | |
const nodeData = new this.ResultsData(node); | |
this.nodeData.children.push(nodeData); | |
this._filterResults(nodeData); | |
} else { | |
this._filterResults(this.nodeData); | |
} | |
if (matched) { | |
this.config.flushFilters(); | |
} | |
this.config.filters.unobserve(observer); | |
} | |
} | |
/***/ }), | |
/***/ "./gfp/logger.js": | |
/*!***********************!*\ | |
!*** ./gfp/logger.js ***! | |
\***********************/ | |
/*! namespace exports */ | |
/*! export LogTime [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! other exports [not provided] [no usage info] */ | |
/*! runtime requirements: __webpack_require__.r, __webpack_exports__, __webpack_require__.d, __webpack_require__.* */ | |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { | |
"use strict"; | |
__webpack_require__.r(__webpack_exports__); | |
/* harmony export */ __webpack_require__.d(__webpack_exports__, { | |
/* harmony export */ "LogTime": () => /* binding */ LogTime | |
/* harmony export */ }); | |
const LogTime = { | |
curTime: null, | |
start() { | |
this.curTime = new Date().getTime(); | |
}, | |
snap(msg) { | |
console.log(`${msg}: ${new Date().getTime() - this.curTime}ms`); | |
} | |
}; | |
/***/ }), | |
/***/ "./gfp/matcher.js": | |
/*!************************!*\ | |
!*** ./gfp/matcher.js ***! | |
\************************/ | |
/*! namespace exports */ | |
/*! export CombinedMultiMatcher [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! export MultiMatcher [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! export SubMatcher [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! other exports [not provided] [no usage info] */ | |
/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.d, __webpack_require__.* */ | |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { | |
"use strict"; | |
__webpack_require__.r(__webpack_exports__); | |
/* harmony export */ __webpack_require__.d(__webpack_exports__, { | |
/* harmony export */ "SubMatcher": () => /* binding */ SubMatcher, | |
/* harmony export */ "MultiMatcher": () => /* binding */ MultiMatcher, | |
/* harmony export */ "CombinedMultiMatcher": () => /* binding */ CombinedMultiMatcher | |
/* harmony export */ }); | |
/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./filter */ "./gfp/filter.js"); | |
/* harmony import */ var _lib_matcher__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./lib/matcher */ "./gfp/lib/matcher.js"); | |
class SubMatcher extends _lib_matcher__WEBPACK_IMPORTED_MODULE_1__.Matcher { | |
static _findCandidates(filter) { | |
if (filter.regexpSource === null) { | |
return null; | |
} | |
return filter.regexpSource.toLowerCase().match(/[^a-z0-9%*][a-z0-9%]{3,}(?=[^a-z0-9%*])/g); | |
} | |
static isSlowFilter(filter) { | |
return !this._findCandidates(filter); | |
} | |
findKeyword(filter) { | |
let res = ''; | |
const candidates = this.constructor._findCandidates(filter); | |
if (candidates === null) { | |
return res; | |
} | |
let resCount = 0xffffff; | |
let resLength = 0; | |
for (let candidate of candidates) { | |
candidate = candidate.substr(1); | |
const count = this.filterByKeyword.has(candidate) ? this.filterByKeyword.get(candidate).length : 0; | |
if (count < resCount || count === resCount && candidate.length > resLength) { | |
res = candidate; | |
resCount = count; | |
resLength = candidate.length; | |
} | |
} | |
return res; | |
} | |
add(filter) { | |
// Duplicates are rare and not checked for efficiency, otherwise we need to store sub filter text maps, and multiple | |
// parents per sub filter. | |
const keyword = this.findKeyword(filter); | |
const prevEntry = this.filterByKeyword.get(keyword); | |
if (prevEntry === undefined) { | |
this.filterByKeyword.set(keyword, filter); | |
} else if (prevEntry.length === 1) { | |
this.filterByKeyword.set(keyword, [prevEntry, filter]); | |
} else { | |
prevEntry.push(filter); | |
} | |
} | |
remove(filter) { | |
// only used by pref, doesn't need to be efficient | |
const candidates = this.constructor._findCandidates(filter) || ['']; | |
for (let candidate of candidates) { | |
candidate = candidate.substr(1); | |
const prevEntry = this.filterByKeyword.get(candidate); | |
if (prevEntry === undefined) { | |
continue; | |
} | |
if (prevEntry.length === 1) { | |
if (prevEntry === filter) { | |
this.filterByKeyword.delete(candidate); | |
break; | |
} | |
continue; | |
} | |
const i = prevEntry.indexOf(filter); | |
if (i === -1) { | |
if (prevEntry.length === 2) { | |
this.filterByKeyword.set(candidate, prevEntry[1 - i]); | |
} else { | |
prevEntry.splice(i, 1); | |
} | |
break; | |
} | |
} | |
} | |
clear() { | |
this.filterByKeyword = new Map(); | |
} | |
hasFilter() { | |
throw 'not implemented'; | |
} | |
getKeywordForFilter() { | |
throw 'not implemented'; | |
} | |
*_iterMatches(filters, data, parents) { | |
for (const filter of filters) { | |
const parent = filter.parent; | |
if ((filter.dataIndex === 0 || parents.has(parent)) && filter.matches(data)) { | |
yield filter; | |
} | |
} | |
} | |
*iterMatches(data, parents) { | |
/** | |
args: | |
parents: All parent filters matched so far, excluding the ones whose subFilters have so far been null. | |
*/ | |
if (data === null) { | |
return; | |
} | |
let candidates = data.toLowerCase().match(/[a-z0-9%]{3,}/g); | |
if (candidates === null) { | |
candidates = []; | |
} | |
candidates.push(''); | |
for (const keyword of candidates) { | |
const filters = this.filterByKeyword.get(keyword); | |
if (filters) { | |
for (const res of this._iterMatches(filters, data, parents)) { | |
yield res; | |
} | |
} | |
} | |
} | |
} | |
class MultiMatcher { | |
constructor(n) { | |
this.n = n; | |
this.matchers = []; | |
for (let i = 0; i < n; i++) { | |
this.matchers.push(new SubMatcher()); | |
} | |
} | |
static isSlowFilter(filter) { | |
for (const subFilter of filter.filters) { | |
if (SubMatcher.isSlowFilter(subFilter)) { | |
return true; | |
} | |
} | |
return false; | |
} | |
add(filter) { | |
if (filter.disabled) { | |
return; | |
} | |
for (const subFilter of filter.filters) { | |
this.matchers[subFilter.index].add(subFilter); | |
} | |
} | |
remove(filter) { | |
for (const subFilter of filter.filters) { | |
this.matchers[subFilter.index].remove(subFilter); | |
} | |
} | |
clear() { | |
for (const matcher of this.matchers) { | |
matcher.clear(); | |
} | |
} | |
matchesAny(data, attrs) { | |
// for each filter, nextNullNum counts how many subfilters there are left until the next non-null subfilter | |
// {filter: nextNullNum} | |
let [prevFilters, curFilters] = [new Map(), new Map()]; | |
for (let i = 0; i < this.n; i++) { | |
for (const subFilter of this.matchers[i].iterMatches(data[attrs[i]], prevFilters)) { | |
if (subFilter.dataIndex === subFilter.parent.filters.length - 1) { | |
return subFilter.parent; | |
} | |
curFilters.set(subFilter.parent, subFilter.parent.filters[subFilter.dataIndex + 1].index - i); | |
} | |
if (i !== this.n - 1) { | |
// include null subFilters whose parents have so far matched | |
for (const [filter, nextNullNum] of prevFilters.entries()) { | |
if (nextNullNum > 0) { | |
curFilters.set(filter, nextNullNum - 1); | |
} | |
} | |
; | |
[prevFilters, curFilters] = [curFilters, new Map()]; | |
} | |
} | |
return null; | |
} | |
} | |
class CombinedMultiMatcher { | |
constructor(n) { | |
// caching is not required since we have one instance per tab, and past filter results are easily accessible | |
this.blacklist = new MultiMatcher(n); | |
this.whitelist = new MultiMatcher(n); | |
} | |
static isSlowFilter(filter) { | |
return MultiMatcher.isSlowFilter(filter); | |
} | |
add(filter) { | |
if (filter instanceof _filter__WEBPACK_IMPORTED_MODULE_0__.WhitelistFilter) { | |
this.whitelist.add(filter); | |
} else { | |
this.blacklist.add(filter); | |
} | |
} | |
remove(filter) { | |
if (filter instanceof _filter__WEBPACK_IMPORTED_MODULE_0__.WhitelistFilter) { | |
this.whitelist.remove(filter); | |
} else { | |
this.blacklist.remove(filter); | |
} | |
} | |
clear() { | |
this.blacklist.clear(); | |
this.whitelist.clear(); | |
} | |
matchesAny(data, attrs) { | |
return this.whitelist.matchesAny(data, attrs) || this.blacklist.matchesAny(data, attrs); | |
} | |
} | |
/***/ }), | |
/***/ "./gfp/plugin/autopagerize.js": | |
/*!************************************!*\ | |
!*** ./gfp/plugin/autopagerize.js ***! | |
\************************************/ | |
/*! namespace exports */ | |
/*! export default [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! other exports [not provided] [no usage info] */ | |
/*! runtime requirements: __webpack_require__.r, __webpack_exports__, __webpack_require__.d, __webpack_require__.* */ | |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { | |
"use strict"; | |
__webpack_require__.r(__webpack_exports__); | |
/* harmony export */ __webpack_require__.d(__webpack_exports__, { | |
/* harmony export */ "default": () => /* export default binding */ __WEBPACK_DEFAULT_EXPORT__ | |
/* harmony export */ }); | |
function mutationObserver(mutations, searchGui) { | |
// all results have finished loading this includes google's own nodes that load later too, such as news items | |
const res = []; | |
for (const mutation of mutations) { | |
for (const addedNode of mutation.addedNodes) { | |
if (addedNode.nodeType !== 3) { | |
res.push(addedNode); | |
} | |
} | |
} | |
if (res.length) { | |
searchGui.filterResults({ | |
querySelectorAll: selector => { | |
// - Can't wrap parent/grandparent's `querySelectorAll`, as it will include elements not in `addedNodes`. | |
// - Can't use node's `querySelectorAll`, as it doesn't include the node itself. | |
// - Can't create a parent element and move the nodes in it, as the nodes don't get added after the | |
// MutationObserver. | |
const matchedNodes = []; | |
for (const node of res) { | |
if (node.matches(selector)) { | |
matchedNodes.push(node); | |
} // call `querySelectorAll` as well, as `node` can be a results container node | |
Array.prototype.push.apply(matchedNodes, node.querySelectorAll(selector)); | |
} | |
return matchedNodes; | |
} | |
}); | |
} | |
} | |
/* harmony default export */ function __WEBPACK_DEFAULT_EXPORT__(searchGui, _config) { | |
const mainNode = document.getElementById('rso'); | |
if (!mainNode || !searchGui) { | |
return searchGui; | |
} | |
new MutationObserver(mutations => mutationObserver(mutations, searchGui)).observe(mainNode, { | |
subtree: true, | |
childList: true | |
}); | |
return searchGui; | |
} | |
/***/ }), | |
/***/ "./gfp/plugin/customsearch.js": | |
/*!************************************!*\ | |
!*** ./gfp/plugin/customsearch.js ***! | |
\************************************/ | |
/*! namespace exports */ | |
/*! export default [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! other exports [not provided] [no usage info] */ | |
/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.d, __webpack_require__.* */ | |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { | |
"use strict"; | |
__webpack_require__.r(__webpack_exports__); | |
/* harmony export */ __webpack_require__.d(__webpack_exports__, { | |
/* harmony export */ "default": () => /* export default binding */ __WEBPACK_DEFAULT_EXPORT__ | |
/* harmony export */ }); | |
/* harmony import */ var _gui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../gui */ "./gfp/gui.js"); | |
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils */ "./gfp/utils.js"); | |
class ResultsData extends _gui__WEBPACK_IMPORTED_MODULE_0__.NodeData { | |
*getChildren() { | |
for (const child of this.node.querySelectorAll('.gsc-table-result')) { | |
yield new TextData(child); | |
} | |
} | |
} | |
class TextData extends _gui__WEBPACK_IMPORTED_MODULE_0__.NodeData { | |
get linkArea() { | |
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.cache)(this, 'linkArea', this.node.querySelector('.gsc-url-bottom')); | |
} | |
get url() { | |
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.cache)(this, 'url', this.node.querySelector('a.gs-title').href); | |
} | |
get title() { | |
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.cache)(this, 'title', this.node.querySelector('a.gs-title').textContent); | |
} | |
get summary() { | |
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.cache)(this, 'summary', this.node.querySelector('.gs-snippet').textContent); | |
} | |
} | |
/* harmony default export */ function __WEBPACK_DEFAULT_EXPORT__(searchGui, config) { | |
if (window.location.href.indexOf('/cse?') === -1 && window.location.href.indexOf('/custom?') === -1) { | |
return searchGui; | |
} | |
const mainNode = document.getElementById('cse'); | |
if (!mainNode) { | |
return searchGui; | |
} | |
searchGui = new _gui__WEBPACK_IMPORTED_MODULE_0__.SearchGui(ResultsData, config); | |
new MutationObserver(mutations => { | |
for (const mutation of mutations) { | |
for (const addedNode of mutation.addedNodes) { | |
if (addedNode.classList && addedNode.classList.contains('gcsc-branding')) { | |
// all results have finished loading | |
searchGui.nodeData.children.length = 0; | |
searchGui.filterResults(document.querySelector('.gsc-results')); | |
} | |
} | |
} | |
}).observe(mainNode, { | |
subtree: true, | |
childList: true | |
}); | |
return searchGui; | |
} | |
/***/ }), | |
/***/ "./gfp/plugin/google.js": | |
/*!******************************!*\ | |
!*** ./gfp/plugin/google.js ***! | |
\******************************/ | |
/*! namespace exports */ | |
/*! export ResultsData [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! export default [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! other exports [not provided] [no usage info] */ | |
/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.d, __webpack_require__.* */ | |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { | |
"use strict"; | |
__webpack_require__.r(__webpack_exports__); | |
/* harmony export */ __webpack_require__.d(__webpack_exports__, { | |
/* harmony export */ "ResultsData": () => /* binding */ ResultsData, | |
/* harmony export */ "default": () => /* export default binding */ __WEBPACK_DEFAULT_EXPORT__ | |
/* harmony export */ }); | |
/* harmony import */ var _gui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../gui */ "./gfp/gui.js"); | |
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils */ "./gfp/utils.js"); | |
class ResultsData extends _gui__WEBPACK_IMPORTED_MODULE_0__.NodeData { | |
*getChildren() { | |
for (const child of this.node.querySelectorAll('.g')) { | |
if (child.classList.contains('obcontainer') || child.classList.contains('kno-kp') || child.classList.contains('g-blk')) {// contains other .g elements, skip so we don't have duplicate links | |
} else if (child.id === 'imagebox_bigimages') { | |
yield new ImageContainerData(child); | |
} else if (child.id === 'lclbox') { | |
yield new MapContainerData(child); | |
} else if (child.firstChild.nodeName === 'G-SECTION-WITH-HEADER') { | |
yield new TweetContainerData(child); | |
} else if (child.previousElementSibling && child.previousElementSibling.classList.contains('mod')) { | |
yield new FeaturedSnippetData(child); | |
} else { | |
yield new TextData(child); | |
} | |
} | |
for (const child of this.node.querySelectorAll('g-inner-card')) { | |
yield new NewsData(child); | |
} | |
for (const child of this.node.querySelectorAll('div[role="heading"] + div > div > div[data-ved]')) { | |
yield new VideoData(child); | |
} | |
} | |
} | |
class CommonData extends _gui__WEBPACK_IMPORTED_MODULE_0__.NodeData { | |
get linkArea() { | |
// query in order of preference | |
let linkArea = this.node.querySelector('a.fl[href^="https://translate."]') || // "Translate this page" | |
this.node.querySelector('.action-menu') || // after the action menu | |
this.node.querySelector('span.b') || // after the bold "PDF" text | |
this.node.querySelector('cite'); // after the title | |
if (linkArea) { | |
linkArea = linkArea.parentNode; | |
} | |
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.cache)(this, 'linkArea', linkArea); | |
} | |
get url() { | |
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.cache)(this, 'url', this.node.querySelector('div[data-ved] > div:first-child > div:first-child > a').href); | |
} | |
get title() { | |
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.cache)(this, 'title', this.node.querySelector('h3').textContent); | |
} | |
} | |
class ImageContainerData extends _gui__WEBPACK_IMPORTED_MODULE_0__.NodeData { | |
*getChildren() { | |
for (const child of this.node.querySelectorAll('.bia')) { | |
yield new ImageData(child); | |
} | |
} | |
} | |
class ImageData extends _gui__WEBPACK_IMPORTED_MODULE_0__.NodeData { | |
get url() { | |
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.cache)(this, 'url', this.node.href); | |
} | |
} | |
class VideoData extends _gui__WEBPACK_IMPORTED_MODULE_0__.NodeData { | |
get linkArea() { | |
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.cache)(this, 'linkArea', this.node.querySelector('span + div > span')); | |
} | |
get url() { | |
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.cache)(this, 'url', this.node.querySelector('a[data-ved]').href); | |
} | |
get title() { | |
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.cache)(this, 'title', this.node.querySelector('div[role="heading"]').textContent); | |
} | |
} | |
class MapContainerData extends _gui__WEBPACK_IMPORTED_MODULE_0__.NodeData { | |
*getChildren() { | |
for (const child of this.node.querySelectorAll('div.g')) { | |
yield new MapData(child); | |
} | |
} | |
} | |
class MapData extends CommonData {} | |
class NewsData extends _gui__WEBPACK_IMPORTED_MODULE_0__.NodeData { | |
get linkArea() { | |
const query = this.node.querySelector('span[tabindex="-1"] + div > p > span'); | |
if (query == null) { | |
// drawing hasn't finished | |
return null; | |
} | |
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.cache)(this, 'linkArea', query.parentNode); | |
} | |
get url() { | |
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.cache)(this, 'url', this.node.querySelector('a').href); | |
} | |
get title() { | |
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.cache)(this, 'title', this.node.querySelector('a').textContent); | |
} | |
} | |
class TweetContainerData extends CommonData { | |
get url() { | |
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.cache)(this, 'url', this.node.querySelector('g-more-link > a').href); | |
} | |
get title() { | |
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.cache)(this, 'title', this.node.querySelector('g-link').textContent); | |
} | |
*getChildren() { | |
for (const child of this.node.querySelectorAll('g-inner-card')) { | |
yield new TweetSubData(child); | |
} | |
} | |
} | |
class TweetSubData extends CommonData { | |
get linkArea() { | |
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.cache)(this, 'linkArea', this.node.querySelector('span.f')); | |
} | |
get title() { | |
return ''; | |
} | |
get url() { | |
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.cache)(this, 'url', this.node.querySelector('a').href); | |
} | |
get summary() { | |
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.cache)(this, 'summary', this.node.querySelector('a').textContent); | |
} | |
} | |
class FeaturedSnippetData extends CommonData { | |
get summary() { | |
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.cache)(this, 'summary', this.node.previousElementSibling.textContent); | |
} | |
} | |
class TextData extends CommonData { | |
get summary() { | |
return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.cache)(this, 'summary', this.node.querySelector('div[data-ved] > div:first-child > div:nth-child(2)').textContent); | |
} | |
} | |
/* harmony default export */ function __WEBPACK_DEFAULT_EXPORT__(searchGui, config) { | |
if (window.location.href.indexOf('/search?') === -1) { | |
return; | |
} | |
searchGui = new _gui__WEBPACK_IMPORTED_MODULE_0__.SearchGui(ResultsData, config); | |
searchGui.filterResults(document.getElementById('search')); | |
return searchGui; | |
} | |
/***/ }), | |
/***/ "./gfp/plugin/instant.js": | |
/*!*******************************!*\ | |
!*** ./gfp/plugin/instant.js ***! | |
\*******************************/ | |
/*! namespace exports */ | |
/*! export default [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! other exports [not provided] [no usage info] */ | |
/*! runtime requirements: __webpack_require__.r, __webpack_exports__, __webpack_require__.d, __webpack_require__.* */ | |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { | |
"use strict"; | |
__webpack_require__.r(__webpack_exports__); | |
/* harmony export */ __webpack_require__.d(__webpack_exports__, { | |
/* harmony export */ "default": () => /* export default binding */ __WEBPACK_DEFAULT_EXPORT__ | |
/* harmony export */ }); | |
/* harmony default export */ function __WEBPACK_DEFAULT_EXPORT__(searchGui, _config) { | |
const mainNode = document.getElementById('main'); | |
if (!mainNode || !searchGui) { | |
return searchGui; | |
} | |
new MutationObserver(mutations => { | |
for (const mutation of mutations) { | |
for (const addedNode of mutation.addedNodes) { | |
const node = addedNode.querySelector && addedNode.querySelector(':scope > #ires'); | |
if (node) { | |
// all results have finished loading | |
searchGui.nodeData.children.length = 0; | |
searchGui.filterResults(node); | |
} | |
} | |
} | |
}).observe(mainNode, { | |
subtree: true, | |
childList: true | |
}); | |
return searchGui; | |
} | |
/***/ }), | |
/***/ "./gfp/pref.js": | |
/*!*********************!*\ | |
!*** ./gfp/pref.js ***! | |
\*********************/ | |
/*! namespace exports */ | |
/*! export default [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! other exports [not provided] [no usage info] */ | |
/*! runtime requirements: __webpack_require__, __webpack_require__.n, __webpack_require__.r, __webpack_exports__, __webpack_require__.d, __webpack_require__.* */ | |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { | |
"use strict"; | |
__webpack_require__.r(__webpack_exports__); | |
/* harmony export */ __webpack_require__.d(__webpack_exports__, { | |
/* harmony export */ "default": () => /* binding */ Pref | |
/* harmony export */ }); | |
/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); | |
/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); | |
/* harmony import */ var slickgrid__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! slickgrid */ "slickgrid"); | |
/* harmony import */ var slickgrid__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(slickgrid__WEBPACK_IMPORTED_MODULE_1__); | |
/* harmony import */ var _html_pref_html__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./html/pref.html */ "./gfp/html/pref.html"); | |
/* harmony import */ var _html_pref_html__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_html_pref_html__WEBPACK_IMPORTED_MODULE_2__); | |
/* harmony import */ var _css_pref_sass__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./css/pref.sass */ "./gfp/css/pref.sass"); | |
/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./filter */ "./gfp/filter.js"); | |
/* harmony import */ var _lib_filterClasses__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./lib/filterClasses */ "./gfp/lib/filterClasses.js"); | |
/* harmony import */ var _matcher__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./matcher */ "./gfp/matcher.js"); | |
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./utils */ "./gfp/utils.js"); | |
class Pref { | |
constructor(searchGui) { | |
this.searchGui = searchGui; | |
this.dialog = null; | |
this.resourcesAdded = false; | |
GM_registerMenuCommand('Google Search Filter +', this.openDialog.bind(this), null); | |
} | |
openDialog() { | |
if (this.dialog) { | |
return; | |
} | |
this.addResources(); | |
this.dialog = new PrefDialog(this.searchGui).dialog.on('dialogclose', () => this.dialog = null); | |
} | |
addResources() { | |
if (this.resourcesAdded) { | |
return; | |
} | |
(0,_utils__WEBPACK_IMPORTED_MODULE_7__.addStyleResolve)('jquery-ui-css'); | |
(0,_utils__WEBPACK_IMPORTED_MODULE_7__.addStyleResolve)('slickgrid-css'); | |
GM_addStyle(_css_pref_sass__WEBPACK_IMPORTED_MODULE_3__.default.toString()); | |
this.resourcesAdded = true; | |
} | |
} | |
class DataView { | |
/** | |
Supports filtering & sorting. | |
config.filters is used as the actual data source. | |
*/ | |
constructor(grid, comparer, filterer, searchGui) { | |
this.grid = grid; | |
this.comparer = comparer; | |
this.filterer = filterer; | |
this.searchGui = searchGui; | |
this.config = searchGui.config; | |
this.filters = []; | |
this._filterObserver = this.filterObserver.bind(this); | |
this.config.filters.observe(this._filterObserver); | |
} | |
destructor() { | |
this.config.filters.unobserve(this._filterObserver); | |
} | |
static filterToitem(filter) { | |
return { | |
text: filter.text, | |
slow: _matcher__WEBPACK_IMPORTED_MODULE_6__.CombinedMultiMatcher.isSlowFilter(filter), | |
enabled: !filter.disabled, | |
hitCount: filter.hitCount, | |
lastHit: filter.lastHit | |
}; | |
} | |
static itemToFilter(item) { | |
return _filter__WEBPACK_IMPORTED_MODULE_4__.Filter.fromObject(item.text, { | |
disabled: !item.enabled, | |
hitCount: item.hitCount, | |
lastHit: item.lastHit | |
}); | |
} | |
_render(resetSelection, resetRows, resetRowCount) { | |
if (resetSelection) { | |
this.grid.resetActiveCell(); | |
this.grid.setSelectedRows([]); | |
} | |
if (resetRows) { | |
this.grid.invalidateAllRows(); | |
} | |
if (resetRowCount) { | |
this.grid.updateRowCount(); | |
} | |
this.grid.render(); | |
} | |
getLength() { | |
return this.filters.length; | |
} | |
_editOp(call, func) { | |
/** | |
args: | |
call: whether the action comes from pref | |
*/ | |
if (this._enterLock) { | |
return; | |
} | |
this._enterLock = true; | |
func(); | |
if (call) { | |
this.config.flushFilters(); | |
this.searchGui.filterResults(); | |
} | |
this._enterLock = false; | |
} | |
add(filter, call = true) { | |
this._editOp(call, () => { | |
if (call) { | |
this.config.filters.add(filter); | |
} else if (!this.filterer(filter)) { | |
return; | |
} | |
const i = (0,_utils__WEBPACK_IMPORTED_MODULE_7__.bisect)(this.filters, filter, this.comparer); | |
this.filters.splice(i, 0, filter); | |
this._render(true, true, true); | |
if (call) { | |
this.grid.scrollRowIntoView(i); | |
} | |
}); | |
} | |
remove(filters, is, call = true) { | |
this._editOp(call, () => { | |
if (call) { | |
this.config.filters.remove(is.map(i => this.filters[i])); | |
} else { | |
// use unique comparer for speed | |
const comparer = (x, y) => x['text'] > y['text'] ? 1 : x['text'] < y['text'] ? -1 : 0; | |
is = (0,_utils__WEBPACK_IMPORTED_MODULE_7__.indexOfSorted)(this.filters.sort(comparer), filters.sort(comparer), comparer); | |
this.filters.sort(this.comparer); | |
} | |
(0,_utils__WEBPACK_IMPORTED_MODULE_7__.popMany)(this.filters, is); | |
this._render(true, true, true); | |
}); | |
} | |
addTemp(i) { | |
this.filters.splice(i, 0, _filter__WEBPACK_IMPORTED_MODULE_4__.Filter.fromText('')); | |
this._render(true, true, true); | |
} | |
removeTemp(i) { | |
this.filters.splice(i, 1); | |
this._render(true, true, true); | |
} | |
update(filter, i, call = true) { | |
this._editOp(call, () => { | |
if (call) { | |
// remove & add since matcher doesn't support updates | |
this.config.filters.remove([this.filters[i]]); | |
this.config.filters.add(filter); | |
} else { | |
i = this.filters.indexOf(filter); | |
if (i === -1) { | |
return; | |
} | |
} | |
this.filters.splice(i, 1); | |
i = (0,_utils__WEBPACK_IMPORTED_MODULE_7__.bisect)(this.filters, filter, this.comparer); | |
this.filters.splice(i, 0, filter); | |
this._render(false, true, false); | |
if (call) { | |
this.grid.scrollRowIntoView(i); | |
} | |
}); | |
} | |
getValue() { | |
return this.config.filters; | |
} | |
setValue(filters = null, call = true) { | |
this._editOp(call, () => { | |
if (filters === null) { | |
filters = Array.from(this.config.filters); | |
} else if (call) { | |
this.config.filters.setValue(filters); | |
} | |
this.filters = filters.filter(this.filterer).sort(this.comparer); | |
this._render(true, true, true); | |
}); | |
} | |
getItem(i) { | |
return this.constructor.filterToitem(this.filters[i]); | |
} | |
sort() { | |
this.filters.sort(this.comparer); | |
this._render(true, true, false); | |
} | |
filter() { | |
this.filters = Array.from(this.config.filters).filter(this.filterer).sort(this.comparer); | |
this._render(true, true, true); | |
} | |
filterObserver(type, value) { | |
switch (type) { | |
case 'add': | |
this.add(value, false); | |
break; | |
case 'remove': | |
this.remove([value], null, false); | |
break; | |
case 'update': | |
this.update(value, null, false); | |
break; | |
case 'setValue': | |
this.setValue(value, false); | |
break; | |
} | |
} | |
} | |
class PrefDialog { | |
constructor(searchGui) { | |
this.searchGui = searchGui; | |
this.dialog = jquery__WEBPACK_IMPORTED_MODULE_0___default()((_html_pref_html__WEBPACK_IMPORTED_MODULE_2___default())).dialog(Object.assign(this.dialogConfig, { | |
title: 'Google Search Filter +', | |
closeOnEscape: false, | |
close: this.destructor.bind(this) | |
})); | |
this.dataView = null; | |
this.addImportExport(); | |
this.addGrid(); | |
} | |
destructor() { | |
this.dataView.destructor(); | |
this.dialog.remove(); | |
} | |
get dialogConfig() { | |
return { | |
width: jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).width() * 0.5, | |
height: jquery__WEBPACK_IMPORTED_MODULE_0___default()(window).height() * 0.5, | |
close() { | |
jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).remove(); | |
} | |
}; | |
} | |
addImportExport() { | |
const self = this; | |
this.dialog.find('.import').click(_e => { | |
jquery__WEBPACK_IMPORTED_MODULE_0___default()('<textarea></textarea>').dialog(Object.assign(this.dialogConfig, { | |
title: 'Import', | |
buttons: [{ | |
text: 'OK', | |
click() { | |
const filtersObject = JSON.parse(jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).val()); | |
const filters = []; | |
for (const key in filtersObject) { | |
if (Object.prototype.hasOwnProperty.call(filtersObject, key)) { | |
filters.push(_filter__WEBPACK_IMPORTED_MODULE_4__.Filter.fromObject(key, filtersObject[key])); | |
} | |
} | |
self.dataView.setValue(filters); | |
jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).dialog('close'); | |
} | |
}, { | |
text: 'Cancel', | |
click() { | |
jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).dialog('close'); | |
} | |
}], | |
create() { | |
setTimeout(() => this.select(), 0); | |
} | |
})); | |
return false; | |
}); | |
this.dialog.find('.export').click(_e => { | |
const filtersObject = {}; | |
for (const filter of this.dataView.getValue()) { | |
filtersObject[filter.text] = filter.toObject(); | |
} | |
jquery__WEBPACK_IMPORTED_MODULE_0___default()('<textarea></textarea>').attr('readonly', 'readonly').val(JSON.stringify(filtersObject, null, 2)).dialog(Object.assign(this.dialogConfig, { | |
title: 'Export', | |
buttons: [{ | |
text: 'Close', | |
click() { | |
jquery__WEBPACK_IMPORTED_MODULE_0___default()(this).dialog('close'); | |
} | |
}], | |
create() { | |
setTimeout(() => { | |
this.focus(); | |
this.setSelectionRange(0, this.value.length, 'backward'); | |
}, 0); | |
} | |
})); | |
return false; | |
}); | |
} | |
addGrid() { | |
const gridDom = this.dialog.find('.grid'); | |
this.dataView = new DataView(null, null, null, this.searchGui); | |
const grid = new (slickgrid__WEBPACK_IMPORTED_MODULE_1___default().Grid)(gridDom, this.dataView, [{ | |
id: 'text', | |
field: 'text', | |
name: 'Filter Rule', | |
width: 300, | |
sortable: true, | |
formatter: (row, cell, value, _columnDef, _dataContext) => `<span class="${value.startsWith('@@') ? 'whitelist' : 'blocking'}-filter">${value}</span>`, | |
editor: (slickgrid__WEBPACK_IMPORTED_MODULE_1___default().Editors.Text), | |
validator: text => { | |
// spaces only don't count as being empty, since they can exist in urls | |
if (!text) return { | |
valid: false, | |
msg: 'Empty filter' | |
}; | |
if (_filter__WEBPACK_IMPORTED_MODULE_4__.Filter.fromText(text) instanceof _lib_filterClasses__WEBPACK_IMPORTED_MODULE_5__.InvalidFilter) return { | |
valid: false, | |
msg: 'Invalid filter' | |
}; | |
if (Array.from(this.dataView.getValue()).some(filter => filter.text === text)) { | |
return { | |
valid: false, | |
msg: 'Duplicate filter' | |
}; | |
} | |
return { | |
valid: true, | |
msg: null | |
}; | |
} | |
}, { | |
// use css for the image since there can be many slow filters | |
id: 'slow', | |
field: 'slow', | |
name: '!', | |
width: 1, | |
sortable: true, | |
cssClass: 'slow-column', | |
formatter: (row, cell, value, _columnDef, _dataContext) => value ? '<img class="slow-image" />' : '' | |
}, { | |
id: 'enabled', | |
field: 'enabled', | |
name: 'Enabled', | |
width: 45, | |
sortable: true, | |
formatter: (row, cell, value, _columnDef, _dataContext) => `<input type="checkbox" name="" value="${value}" checked=${!!value} />` | |
}, { | |
id: 'hitCount', | |
field: 'hitCount', | |
name: 'Hits', | |
width: 1, | |
sortable: true, | |
editor: (slickgrid__WEBPACK_IMPORTED_MODULE_1___default().Editors.Integer), | |
validator: val => val < 0 ? { | |
valid: false, | |
msg: 'Must be >= 0' | |
} : { | |
valid: true, | |
msg: null | |
} | |
}, { | |
id: 'lastHit', | |
field: 'lastHit', | |
name: 'Last Hit', | |
width: 110, | |
sortable: true, | |
formatter: (row, cell, value, columnDef, dataContext) => { | |
if (!value || dataContext.hitCount === 0) { | |
return ''; | |
} | |
const date = new Date(value); | |
return `${date.getFullYear()}-${(0,_utils__WEBPACK_IMPORTED_MODULE_7__.pad)(date.getMonth() + 1, 2)}-${(0,_utils__WEBPACK_IMPORTED_MODULE_7__.pad)(date.getDate(), 2)} ` + `${(0,_utils__WEBPACK_IMPORTED_MODULE_7__.pad)(date.getHours(), 2)}:${(0,_utils__WEBPACK_IMPORTED_MODULE_7__.pad)(date.getMinutes(), 2)}:${(0,_utils__WEBPACK_IMPORTED_MODULE_7__.pad)(date.getSeconds(), 2)}:` + `${(0,_utils__WEBPACK_IMPORTED_MODULE_7__.pad)(date.getMilliseconds(), 3)}`; | |
}, | |
editor: (slickgrid__WEBPACK_IMPORTED_MODULE_1___default().Editors.Integer) | |
}], { | |
autoEdit: false, | |
editable: true, | |
enableCellNavigation: true, | |
enableColumnReorder: false, | |
explicitInitialization: true, | |
forceFitColumns: true, | |
showHeaderRow: true | |
}); | |
/* Find bar */ | |
let filterVals = {}; | |
const binaryFilter = ['FfNn-', 'TtYy+']; | |
window.grid = grid; | |
const dateFormatter = grid.getColumns()[grid.getColumnIndex('lastHit')].formatter; | |
this.dataView.filterer = val => { | |
val = DataView.filterToitem(val); | |
for (const key in filterVals) { | |
switch (key) { | |
case 'text': | |
if (!val[key].includes(filterVals[key])) { | |
return false; | |
} | |
break; | |
case 'slow': | |
case 'enabled': | |
if (!binaryFilter[+val[key]].includes(filterVals[key])) { | |
return false; | |
} | |
break; | |
case 'hitCount': | |
if (!val[key].toString().includes(filterVals[key])) { | |
return false; | |
} | |
break; | |
case 'lastHit': | |
if (!dateFormatter(null, null, val[key], null, val).includes(filterVals[key])) { | |
return false; | |
} | |
break; | |
} | |
} | |
return true; | |
}; | |
const findBar = gridDom.find('.slick-headerrow'); | |
const openFindBar = () => findBar.show().find('input:first').focus(); | |
const closeFindBar = () => { | |
findBar.hide().find('input').val(''); | |
filterVals = {}; | |
this.dataView.filter(); | |
this.dialog.focus(); | |
}; | |
grid.onHeaderRowCellRendered.subscribe((e, args) => { | |
const searchField = jquery__WEBPACK_IMPORTED_MODULE_0___default()('<input/>').keydown(e => { | |
if (e.keyCode === 27) { | |
closeFindBar(); | |
} | |
}).on('input', _e => { | |
filterVals[args.column.field] = searchField.val(); | |
this.dataView.filter(); | |
}); | |
jquery__WEBPACK_IMPORTED_MODULE_0___default()(args.node).empty().append(searchField); | |
}); | |
findBar.hide(); | |
this.dialog.attr('tabindex', 1); | |
this.dialog.keydown(e => { | |
if ((e.ctrlKey || e.metaKey) && e.keyCode === 70) { | |
openFindBar(); | |
e.preventDefault(); | |
} | |
}); | |
/* Sorting */ | |
let [sortField, sortRes] = ['text', 1]; | |
this.dataView.comparer = (x, y) => x[sortField] > y[sortField] ? sortRes : x[sortField] < y[sortField] ? -sortRes : 0; | |
grid.setSortColumn(sortField, !!sortRes); | |
grid.onSort.subscribe((e, args) => { | |
; | |
[sortField, sortRes] = [args.sortCol.field, args.sortAsc ? 1 : -1]; | |
this.dataView.sort(); | |
}); | |
/* Editing */ | |
grid.onClick.subscribe((e, args) => { | |
if (jquery__WEBPACK_IMPORTED_MODULE_0___default()(e.target).is(':checkbox')) { | |
const column = grid.getColumns()[args.cell]; | |
if (column.editable === false || column.autoEdit === false) { | |
return; | |
} | |
const item = this.dataView.getItem(args.row); | |
item[column.field] = !item[column.field]; | |
new grid.onCellChange.notify({ | |
row: args.row, | |
cell: args.cell, | |
item: item | |
}, new (slickgrid__WEBPACK_IMPORTED_MODULE_1___default().EventData)()); | |
} | |
}); | |
grid.onValidationError.subscribe((e, args) => alert(args.validationResults.msg)); | |
grid.onCellChange.subscribe((e, args) => this.dataView.update(DataView.itemToFilter(args.item), args.row)); | |
gridDom.on('blur', 'input.editor-text', () => slickgrid__WEBPACK_IMPORTED_MODULE_1___default().GlobalEditorLock.commitCurrentEdit()); | |
grid.setSelectionModel(new (slickgrid__WEBPACK_IMPORTED_MODULE_1___default().RowSelectionModel)()); | |
/* Add & Remove */ | |
let cancelled = true; | |
let tempI = null; | |
grid.onCellChange.subscribe((_e, _args) => cancelled = false); | |
grid.onBeforeCellEditorDestroy.subscribe((_e, _args) => { | |
if (cancelled && tempI !== null) { | |
setTimeout(() => { | |
this.dataView.removeTemp(tempI); | |
tempI = null; | |
}, 0); | |
} | |
cancelled = true; | |
}); | |
const addFilter = () => { | |
const is = grid.getSelectedRows(); | |
tempI = is[is.length - 1] || 0; | |
this.dataView.addTemp(tempI); | |
grid.gotoCell(tempI, 0, true); | |
}; | |
const removeFilter = () => this.dataView.remove(null, grid.getSelectedRows()); | |
this.dialog.find('.add').click(_e => { | |
addFilter(); | |
return false; | |
}); | |
gridDom.keydown(e => { | |
if (e.target.nodeName === 'INPUT') { | |
return; | |
} | |
switch (e.keyCode) { | |
case 45: | |
addFilter(); | |
break; | |
case 46: | |
removeFilter(); | |
break; | |
case 65: | |
if (e.ctrlKey || e.metaKey) { | |
const rows = []; | |
for (let i = 0; i < grid.getDataLength(); i++) { | |
rows.push(i); | |
} | |
grid.setSelectedRows(rows); | |
e.preventDefault(); | |
} | |
break; | |
} | |
}); | |
/* Initialize grid & dataView */ | |
grid.init(); | |
this.dataView.grid = grid; | |
this.dataView.setValue(); | |
/* Dialog */ | |
const height = gridDom.height(); | |
this.dialog.on('dialogresize', (e, ui) => { | |
gridDom.css('height', `${height + (ui.size.height - ui.originalSize.height)}px`); | |
grid.resizeCanvas(); | |
}); | |
} | |
} | |
/***/ }), | |
/***/ "./gfp/utils.js": | |
/*!**********************!*\ | |
!*** ./gfp/utils.js ***! | |
\**********************/ | |
/*! namespace exports */ | |
/*! export addStyleResolve [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! export bisect [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! export cache [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! export indexOfSorted [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! export pad [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! export popMany [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! other exports [not provided] [no usage info] */ | |
/*! runtime requirements: __webpack_require__.r, __webpack_exports__, __webpack_require__.d, __webpack_require__.* */ | |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { | |
"use strict"; | |
__webpack_require__.r(__webpack_exports__); | |
/* harmony export */ __webpack_require__.d(__webpack_exports__, { | |
/* harmony export */ "addStyleResolve": () => /* binding */ addStyleResolve, | |
/* harmony export */ "pad": () => /* binding */ pad, | |
/* harmony export */ "cache": () => /* binding */ cache, | |
/* harmony export */ "bisect": () => /* binding */ bisect, | |
/* harmony export */ "indexOfSorted": () => /* binding */ indexOfSorted, | |
/* harmony export */ "popMany": () => /* binding */ popMany | |
/* harmony export */ }); | |
function addStyleResolve(name) { | |
GM_addStyle(GM_getResourceText(name).replace(/url\("?([^":]+)"?\)/g, (match, url) => `url("${GM_getResourceURL(`${name}/${url}`)}")`)); | |
} | |
function pad(num, size) { | |
return Array(Math.max(size - num.toString().length + 1, 0)).join(0) + num; | |
} | |
function cache(obj, prop, value) { | |
Object.defineProperty(obj, prop, { | |
value: value | |
}); | |
return value; | |
} | |
function bisect(a, x, comparer, lo = 0, hi = null) { | |
// ported from the python standard library | |
if (lo < 0) { | |
throw 'lo must be non-negative'; | |
} | |
if (hi === null) { | |
hi = a.length; | |
} | |
while (lo < hi) { | |
const mid = lo + hi >> 1; | |
if (comparer(x, a[mid]) < 0) { | |
hi = mid; | |
} else { | |
lo = mid + 1; | |
} | |
} | |
return lo; | |
} | |
function indexOfSorted(xs, ys, comparer) { | |
const res = []; | |
let i = 0; | |
for (const y of ys) { | |
// noinspection JSSuspiciousNameCombination | |
i = bisect(xs, y, comparer, i + 1) - 1; | |
res.push(xs[i] === y ? i : -1); | |
} | |
return res; | |
} | |
function popMany(xs, is) { | |
// O(n) time, mask is not'ed for speed | |
const mask = new Array(xs.length); | |
for (const i of is) { | |
mask[i] = true; | |
} | |
let offset = 0; | |
for (let i = 0; i < xs.length; i++) { | |
if (mask[i] === undefined) { | |
xs[offset] = xs[i]; | |
offset++; | |
} | |
} | |
xs.length = offset; | |
return xs; | |
} | |
/***/ }), | |
/***/ "./node_modules/css-loader/dist/runtime/api.js": | |
/*!*****************************************************!*\ | |
!*** ./node_modules/css-loader/dist/runtime/api.js ***! | |
\*****************************************************/ | |
/*! unknown exports (runtime-defined) */ | |
/*! runtime requirements: module */ | |
/***/ ((module) => { | |
"use strict"; | |
/* | |
MIT License http://www.opensource.org/licenses/mit-license.php | |
Author Tobias Koppers @sokra | |
*/ | |
// css base code, injected by the css-loader | |
// eslint-disable-next-line func-names | |
module.exports = function (cssWithMappingToString) { | |
var list = []; // return the list of modules as css string | |
list.toString = function toString() { | |
return this.map(function (item) { | |
var content = cssWithMappingToString(item); | |
if (item[2]) { | |
return "@media ".concat(item[2], " {").concat(content, "}"); | |
} | |
return content; | |
}).join(''); | |
}; // import a list of modules into the list | |
// eslint-disable-next-line func-names | |
list.i = function (modules, mediaQuery, dedupe) { | |
if (typeof modules === 'string') { | |
// eslint-disable-next-line no-param-reassign | |
modules = [[null, modules, '']]; | |
} | |
var alreadyImportedModules = {}; | |
if (dedupe) { | |
for (var i = 0; i < this.length; i++) { | |
// eslint-disable-next-line prefer-destructuring | |
var id = this[i][0]; | |
if (id != null) { | |
alreadyImportedModules[id] = true; | |
} | |
} | |
} | |
for (var _i = 0; _i < modules.length; _i++) { | |
var item = [].concat(modules[_i]); | |
if (dedupe && alreadyImportedModules[item[0]]) { | |
// eslint-disable-next-line no-continue | |
continue; | |
} | |
if (mediaQuery) { | |
if (!item[2]) { | |
item[2] = mediaQuery; | |
} else { | |
item[2] = "".concat(mediaQuery, " and ").concat(item[2]); | |
} | |
} | |
list.push(item); | |
} | |
}; | |
return list; | |
}; | |
/***/ }), | |
/***/ "./node_modules/css-loader/dist/runtime/getUrl.js": | |
/*!********************************************************!*\ | |
!*** ./node_modules/css-loader/dist/runtime/getUrl.js ***! | |
\********************************************************/ | |
/*! unknown exports (runtime-defined) */ | |
/*! runtime requirements: module */ | |
/***/ ((module) => { | |
"use strict"; | |
module.exports = function (url, options) { | |
if (!options) { | |
// eslint-disable-next-line no-param-reassign | |
options = {}; | |
} // eslint-disable-next-line no-underscore-dangle, no-param-reassign | |
url = url && url.__esModule ? url.default : url; | |
if (typeof url !== 'string') { | |
return url; | |
} // If url is already wrapped in quotes, remove them | |
if (/^['"].*['"]$/.test(url)) { | |
// eslint-disable-next-line no-param-reassign | |
url = url.slice(1, -1); | |
} | |
if (options.hash) { | |
// eslint-disable-next-line no-param-reassign | |
url += options.hash; | |
} // Should url be wrapped? | |
// See https://drafts.csswg.org/css-values-3/#urls | |
if (/["'() \t\n]/.test(url) || options.needQuotes) { | |
return "\"".concat(url.replace(/"/g, '\\"').replace(/\n/g, '\\n'), "\""); | |
} | |
return url; | |
}; | |
/***/ }), | |
/***/ "./node_modules/html-loader/dist/runtime/getUrl.js": | |
/*!*********************************************************!*\ | |
!*** ./node_modules/html-loader/dist/runtime/getUrl.js ***! | |
\*********************************************************/ | |
/*! unknown exports (runtime-defined) */ | |
/*! runtime requirements: module */ | |
/***/ ((module) => { | |
"use strict"; | |
module.exports = function (url, options) { | |
if (!options) { | |
// eslint-disable-next-line no-param-reassign | |
options = {}; | |
} // eslint-disable-next-line no-underscore-dangle, no-param-reassign | |
url = url && url.__esModule ? url.default : url; | |
if (typeof url !== 'string') { | |
return url; | |
} | |
if (options.hash) { | |
// eslint-disable-next-line no-param-reassign | |
url += options.hash; | |
} | |
if (options.maybeNeedQuotes && /[\t\n\f\r "'=<>`]/.test(url)) { | |
return "\"".concat(url, "\""); | |
} | |
return url; | |
}; | |
/***/ }), | |
/***/ "./gfp/css/gui.sass": | |
/*!**************************!*\ | |
!*** ./gfp/css/gui.sass ***! | |
\**************************/ | |
/*! namespace exports */ | |
/*! export default [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! other exports [not provided] [no usage info] */ | |
/*! runtime requirements: __webpack_require__, __webpack_require__.n, __webpack_exports__, __webpack_require__.r, module.id, __webpack_require__.d, __webpack_require__.*, module */ | |
/***/ ((module, __webpack_exports__, __webpack_require__) => { | |
"use strict"; | |
__webpack_require__.r(__webpack_exports__); | |
/* harmony export */ __webpack_require__.d(__webpack_exports__, { | |
/* harmony export */ "default": () => __WEBPACK_DEFAULT_EXPORT__ | |
/* harmony export */ }); | |
/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js"); | |
/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__); | |
// Imports | |
var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default()(function(i){return i[1]}); | |
// Module | |
___CSS_LOADER_EXPORT___.push([module.id, ".hide {\n display: none !important;\n}\n\n.filter-add {\n margin-left: 5px;\n font-size: 14px;\n text-decoration: none;\n}\n.filter-add:hover {\n text-decoration: underline;\n}\n\ncite + .filter-add {\n margin-left: 10px;\n}\n\n.show-title {\n padding-right: 5px;\n color: #999;\n}\n\n.show-link {\n color: #999 !important;\n text-decoration: none;\n}\n.show-link.hide {\n display: inline !important;\n color: #12C !important;\n}\n\n.gs-webResult div.gs-visibleUrl-long {\n display: inline;\n}", ""]); | |
// Exports | |
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); | |
/***/ }), | |
/***/ "./gfp/css/pref.sass": | |
/*!***************************!*\ | |
!*** ./gfp/css/pref.sass ***! | |
\***************************/ | |
/*! namespace exports */ | |
/*! export default [provided] [no usage info] [missing usage info prevents renaming] */ | |
/*! other exports [not provided] [no usage info] */ | |
/*! runtime requirements: __webpack_require__, __webpack_require__.n, __webpack_exports__, __webpack_require__.r, module.id, __webpack_require__.d, __webpack_require__.*, module */ | |
/***/ ((module, __webpack_exports__, __webpack_require__) => { | |
"use strict"; | |
__webpack_require__.r(__webpack_exports__); | |
/* harmony export */ __webpack_require__.d(__webpack_exports__, { | |
/* harmony export */ "default": () => __WEBPACK_DEFAULT_EXPORT__ | |
/* harmony export */ }); | |
/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js"); | |
/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__); | |
/* harmony import */ var _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/getUrl.js */ "./node_modules/css-loader/dist/runtime/getUrl.js"); | |
/* harmony import */ var _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_1__); | |
/* harmony import */ var _img_slow_png__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../img/slow.png */ "./gfp/img/slow.png"); | |
/* harmony import */ var _img_slow_png__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_img_slow_png__WEBPACK_IMPORTED_MODULE_2__); | |
// Imports | |
var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default()(function(i){return i[1]}); | |
var ___CSS_LOADER_URL_REPLACEMENT_0___ = _node_modules_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_1___default()((_img_slow_png__WEBPACK_IMPORTED_MODULE_2___default())); | |
// Module | |
___CSS_LOADER_EXPORT___.push([module.id, ".ui-front {\n z-index: 1000;\n}\n\n.ui-dialog textarea {\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n width: 100% !important;\n resize: none;\n}\n\n.gfp {\n outline: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column;\n}\n.gfp .slick-sort-indicator {\n float: none;\n}\n.gfp a {\n outline: 0;\n}\n.gfp .button-icon {\n height: 16px;\n width: 16px;\n}\n.gfp .row:last-child {\n -webkit-box-flex: 1;\n -ms-flex: 1;\n flex: 1;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n}\n.gfp .slow-column {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n -webkit-box-pack: center;\n -ms-flex-pack: center;\n justify-content: center;\n}\n.gfp .slick-cell:first-child {\n white-space: pre;\n}\n.gfp .slick-cell .whitelist-filter {\n color: #080;\n}\n.gfp .slick-cell .slow-image {\n content: url(" + ___CSS_LOADER_URL_REPLACEMENT_0___ + ");\n}\n.gfp .slick-cell.selected {\n background: #f5f5f5;\n}\n.gfp .slick-header-column:nth-child(2) > .slick-column-name {\n display: table;\n margin: 0 auto;\n}\n.gfp .slick-headerrow-column {\n background: #E6E6E6;\n height: 25px;\n padding: 0;\n border: 0;\n}\n.gfp .slick-cell input, .gfp .slick-headerrow-column input {\n margin: 0;\n padding: 0;\n width: 100%;\n height: 100%;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n}", ""]); | |
// Exports | |
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); | |
/***/ }), | |
/***/ "./gfp/html/pref.html": | |
/*!****************************!*\ | |
!*** ./gfp/html/pref.html ***! | |
\****************************/ | |
/*! unknown exports (runtime-defined) */ | |
/*! runtime requirements: module, __webpack_require__ */ | |
/***/ ((module, __unused_webpack_exports, __webpack_require__) => { | |
// Imports | |
var ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___ = __webpack_require__(/*! ../../node_modules/html-loader/dist/runtime/getUrl.js */ "./node_modules/html-loader/dist/runtime/getUrl.js"); | |
var ___HTML_LOADER_IMPORT_0___ = __webpack_require__(/*! ../img/edit_add.png */ "./gfp/img/edit_add.png"); | |
var ___HTML_LOADER_IMPORT_1___ = __webpack_require__(/*! ../img/import.png */ "./gfp/img/import.png"); | |
var ___HTML_LOADER_IMPORT_2___ = __webpack_require__(/*! ../img/export.png */ "./gfp/img/export.png"); | |
// Module | |
var ___HTML_LOADER_REPLACEMENT_0___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___); | |
var ___HTML_LOADER_REPLACEMENT_1___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_1___); | |
var ___HTML_LOADER_REPLACEMENT_2___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_2___); | |
var code = "<div class=\"gfp\"> <div class=\"row\"> <a href=\"#\" class=\"add\" title=\"Add filter\"><img class=\"button-icon\" src=\"" + ___HTML_LOADER_REPLACEMENT_0___ + "\"/></a> <a href=\"#\" class=\"import\" title=\"Import filters\"><img class=\"button-icon\" src=\"" + ___HTML_LOADER_REPLACEMENT_1___ + "\"/></a> <a href=\"#\" class=\"export\" title=\"Export filters\"><img class=\"button-icon\" src=\"" + ___HTML_LOADER_REPLACEMENT_2___ + "\"/></a> </div> <div class=\"row\"> <div class=\"grid\"></div> </div> </div> "; | |
// Exports | |
module.exports = code; | |
/***/ }), | |
/***/ "./gfp/img/edit_add.png": | |
/*!******************************!*\ | |
!*** ./gfp/img/edit_add.png ***! | |
\******************************/ | |
/*! unknown exports (runtime-defined) */ | |
/*! runtime requirements: module */ | |
/***/ ((module) => { | |
module.exports = "data:img/png;base64,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" | |
/***/ }), | |
/***/ "./gfp/img/export.png": | |
/*!****************************!*\ | |
!*** ./gfp/img/export.png ***! | |
\****************************/ | |
/*! unknown exports (runtime-defined) */ | |
/*! runtime requirements: module */ | |
/***/ ((module) => { | |
module.exports = "data:img/png;base64,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" | |
/***/ }), | |
/***/ "./gfp/img/import.png": | |
/*!****************************!*\ | |
!*** ./gfp/img/import.png ***! | |
\****************************/ | |
/*! unknown exports (runtime-defined) */ | |
/*! runtime requirements: module */ | |
/***/ ((module) => { | |
module.exports = "data:img/png;base64,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" | |
/***/ }), | |
/***/ "./gfp/img/slow.png": | |
/*!**************************!*\ | |
!*** ./gfp/img/slow.png ***! | |
\**************************/ | |
/*! unknown exports (runtime-defined) */ | |
/*! runtime requirements: module */ | |
/***/ ((module) => { | |
module.exports = "data:img/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAQCAMAAAA/D5+aAAABWVBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACheQDX19c8LgCIZgCVlZUaGhoiIiJuUwBYWFh/XwByVgBmTQAuLi6WcQAqKiodHR3Jyck0JwBtUgCLaAAgGAAyJgBUQACCgoK4uLhzVgAaEwB3WgBYQgAqHwAeHh4jIyNkZGR1WABAMAC/v78pHwCEYwBMOQBOOgB5WwCFZACWlpaSbgCDYgATExNHR0cFBQUwJQCGZQCIZwBRPQAMCQCXl5c7LAAWFhaFhYUhISFhYWE2NjZDMwAHBweSkpJ6XABLS0sVFRUKCABISEhrUQBJNwAdFgBOOwCYmJgUFBQA9R6HAAAAKHRSTlMAgpRMfYSBS36Zut28HF0Ua2ppmyWcOpGKPGXCYaHhibauhm11LYAjiwhFZAAAAPxJREFUeF5lzVVTAzEYRuEUaFF3dzlf6oq7u7u76/8XkixDLzgXO/Puk0yUVy6uAjfyMR9yPCmEVDIZgxJnVJmzpU6qWRZXiGZLRagWnJSRkN928Rmqo7y43hEpke2Vzztre+40PiqsVCLyyMvbB0Fj3+Z5H/EBagzlGeLCvTQsslirYFVrAoZ6kOkZsWUQScPgkDbU4N3KEBMZGZWx8Qkmp7Tpi0ZDTYjMEpwjJPMshC0sRWhVpjbWRNY3NrfknR1tC9NuoWM/og8OjxLHJ6dnnGsXncoGl1d2wfWN9rpF/dbFfVxne0gbydYdf4LnKECUV/W/Xn+gz9//Bz+04TZYU20HQAAAAABJRU5ErkJggg==" | |
/***/ }), | |
/***/ "jquery": | |
/*!********************!*\ | |
!*** external "$" ***! | |
\********************/ | |
/*! dynamic exports */ | |
/*! export __esModule [maybe provided (runtime-defined)] [no usage info] [provision prevents renaming (no use info)] */ | |
/*! other exports [maybe provided (runtime-defined)] [no usage info] */ | |
/*! runtime requirements: module */ | |
/***/ ((module) => { | |
"use strict"; | |
module.exports = $; | |
/***/ }), | |
/***/ "slickgrid": | |
/*!************************!*\ | |
!*** external "Slick" ***! | |
\************************/ | |
/*! dynamic exports */ | |
/*! export __esModule [maybe provided (runtime-defined)] [no usage info] [provision prevents renaming (no use info)] */ | |
/*! other exports [maybe provided (runtime-defined)] [no usage info] */ | |
/*! runtime requirements: module */ | |
/***/ ((module) => { | |
"use strict"; | |
module.exports = Slick; | |
/***/ }) | |
/******/ }); | |
/************************************************************************/ | |
/******/ // The module cache | |
/******/ var __webpack_module_cache__ = {}; | |
/******/ | |
/******/ // The require function | |
/******/ function __webpack_require__(moduleId) { | |
/******/ // Check if module is in cache | |
/******/ if(__webpack_module_cache__[moduleId]) { | |
/******/ return __webpack_module_cache__[moduleId].exports; | |
/******/ } | |
/******/ // Create a new module (and put it into the cache) | |
/******/ var module = __webpack_module_cache__[moduleId] = { | |
/******/ id: moduleId, | |
/******/ // no module.loaded needed | |
/******/ exports: {} | |
/******/ }; | |
/******/ | |
/******/ // Execute the module function | |
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); | |
/******/ | |
/******/ // Return the exports of the module | |
/******/ return module.exports; | |
/******/ } | |
/******/ | |
/************************************************************************/ | |
/******/ /* webpack/runtime/compat get default export */ | |
/******/ (() => { | |
/******/ // getDefaultExport function for compatibility with non-harmony modules | |
/******/ __webpack_require__.n = (module) => { | |
/******/ var getter = module && module.__esModule ? | |
/******/ () => module['default'] : | |
/******/ () => module; | |
/******/ __webpack_require__.d(getter, { a: getter }); | |
/******/ return getter; | |
/******/ }; | |
/******/ })(); | |
/******/ | |
/******/ /* webpack/runtime/define property getters */ | |
/******/ (() => { | |
/******/ // define getter functions for harmony exports | |
/******/ __webpack_require__.d = (exports, definition) => { | |
/******/ for(var key in definition) { | |
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { | |
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); | |
/******/ } | |
/******/ } | |
/******/ }; | |
/******/ })(); | |
/******/ | |
/******/ /* webpack/runtime/hasOwnProperty shorthand */ | |
/******/ (() => { | |
/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) | |
/******/ })(); | |
/******/ | |
/******/ /* webpack/runtime/make namespace object */ | |
/******/ (() => { | |
/******/ // define __esModule on exports | |
/******/ __webpack_require__.r = (exports) => { | |
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { | |
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); | |
/******/ } | |
/******/ Object.defineProperty(exports, '__esModule', { value: true }); | |
/******/ }; | |
/******/ })(); | |
/******/ | |
/************************************************************************/ | |
/******/ // startup | |
/******/ // Load entry module | |
/******/ __webpack_require__("./gfp/bin/main.js"); | |
/******/ // This entry module used 'exports' so it can't be inlined | |
/******/ })() | |
; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Only language selection?