Update aak-cont-master-es6.js

This commit is contained in:
Giwayume 2017-05-28 17:03:00 +00:00
parent 9bfb8b2499
commit f59cf46931

View File

@ -87,6 +87,45 @@ var a = (function(window) {
this.on("load", func, capture);
},
/**
* String content matching across an array of strings. Returns true if any string in the args array is matched.
* @method applyMatch
* @param args {Array} The strings to match against.
* @param method {Number} The method to match with. Defined in the enum (aak.matchMethod).
* @param filter {String|RegExp} The matching criteria.
* @return {Boolen} True if any string match, false otherwise.
*/
applyMatch(args, method, filter) {
switch (method) {
case this.matchMethod.string:
for (let i=0; i<args.length; i++) {
if (String(args[i]).includes(filter)) {
return true;
}
}
break;
case this.matchMethod.stringExact:
for (let i=0; i<args.length; i++) {
if (filter === String(args[i])) {
return true;
}
}
break;
case this.matchMethod.RegExp:
for (let i=0; i<args.length; i++) {
if (filter.test(String(args[i]))) {
return true;
}
}
break;
case this.matchMethod.callback:
return filter(args);
default:
return true;
}
return false;
},
/**
* Adds an HTML element to the page for scripts checking an element's existence.
* @method bait
@ -94,7 +133,7 @@ var a = (function(window) {
* @param identifier {String} CSS selector for adding an ID or class to the element.
*/
bait(type, identifier) {
let elem = a.$(`<${type}>`);
let elem = this.$(`<${type}>`);
if (identifier.startsWith("#") {
elem.attr("id", identifier.substr(1));
} else if (identifier.startsWith(".")) {
@ -105,36 +144,16 @@ var a = (function(window) {
/**
* Configuration for this script.
* @property config
* @method config
* @type Object
*/
config: {
aggressiveAdflySkipper: true,
allowExperimental: true,
allowGeneric: true,
debugMode: false,
domExcluded: null,
init() {
this.debugMode = GM_getValue("config_debugMode", this.debugMode);
this.allowExperimental = GM_getValue("config_allowExperimental", this.allowExperimental);
this.aggressiveAdflySkipper = GM_getValue("config_aggressiveAdflySkiper", this.aggressiveAdflySkipper);
aak.mods.Facebook_JumpToTop = GM_getValue("mods_Facebook_JumpToTop", aak.mods.Facebook_JumpToTop);
aak.mods.Blogspot_AutoNCR = GM_getValue("mods_Blogspot_AutoNCR", aak.mods.Blogspot_AutoNCR);
aak.mods.NoAutoplay = GM_getValue("mods_NoAutoplay", aak.mods.NoAutoplay);
},
update(id, val) {
const names = [
"config_debugMode",
"config_allowExperimental",
"config_aggressiveAdflySkiper",
"mods_Facebook_JumpToTop",
"mods_Blogspot_AutoNCR",
"mods_NoAutoplay"
];
if (names.includes(id)) {
GM_setValue(id, Boolean(val));
}
}
config() {
this.config.debugMode = GM_getValue("config_debugMode", this.config.debugMode);
this.config.allowExperimental = GM_getValue("config_allowExperimental", this.config.allowExperimental);
this.config.aggressiveAdflySkipper = GM_getValue("config_aggressiveAdflySkiper", this.config.aggressiveAdflySkipper);
this.mods.Facebook_JumpToTop = GM_getValue("mods_Facebook_JumpToTop", this.mods.Facebook_JumpToTop);
this.mods.Blogspot_AutoNCR = GM_getValue("mods_Blogspot_AutoNCR", this.mods.Blogspot_AutoNCR);
this.mods.NoAutoplay = GM_getValue("mods_NoAutoplay", this.mods.NoAutoplay);
},
/**
@ -148,7 +167,7 @@ var a = (function(window) {
*/
cookie(key, val, time, path) {
if (typeof val === "undefined") {
const value = "; " + a.doc.cookie;
const value = "; " + this.doc.cookie;
let parts = value.split("; " + key + "=");
if (parts.length == 2) {
return parts.pop().split(";").shift();
@ -162,6 +181,17 @@ var a = (function(window) {
}
},
/**
* Removes an inline script on the page, using the sample string.
* @method crashScript
* @param sample {String} Sample function string.
*/
crashScript(sample) {
this.patchHTML((html) => {
return html.replace(sample, "])} \"'` ])} \n\r \r\n */ ])}");
});
},
/**
* Adds CSS styles to the page.
* @method css
@ -229,6 +259,7 @@ var a = (function(window) {
/**
* Displays a console error.
* @method err
* @param name {String} Descriptive type of error.
*/
err(name) {
@ -240,22 +271,144 @@ var a = (function(window) {
this.out.error(`Uncaught AdBlock Error: ${name}AdBlocker detectors are not allowed on this device! `);
},
/**
* Replaces a global function with a version that can stop or modify its execution based on the arguments passed.
* @method filter
* @param func {String} The name of the function (or dot separate path to the function) to be replaced. Starts at the global context.
* @param method {Number} The method to match function arguments with. Defined in the enum (aak.matchMethod).
* @param filter {String|RegExp} This string or regex criteria that determines a match. If this matches, the original function is not executed.
* @param onMatch {Function} Callback when the "filter" argument matches. The return value of this function is used instead of the original function's return value.
* @param onAfter {Function} Callback that fires every time original function is called. The first argument is whether or not the flter matched. The second argument is the args passed into the original function.
* @return {Boolean} True if errors did not occur.
*/
filter(func, method, filter, onMatch, onAfter) {
let original = this.win;
let parent;
const newFunc = (...args) => {
if (this.config.debugMode) {
this.out.warn(func + "is called with these arguments: ");
for (let i=0; i<args.length; i++) {
this.out.warn(String(args[i]));
}
}
if (!method || this.applyMatch(args, method, filter)) {
this.config.debugMode && this.err();
let ret = undefined;
if (onMatch) {
ret = onMatch(args);
}
onAfter && onAfter(true, args);
return ret;
}
this.config.debugMode && this.out.info("Tests passed.");
onAfter && onAfter(false, args);
return original.apply(parent, args);
};
try {
let stack = func.split(".");
let current;
while (current = stack.shift()) {
parent = original;
original = parent[current];
if (!stack.length) {
parent[current] = newFunc;
}
}
if (this.protectFunc.enabled) {
this.protectFunc.pointers.push(newFunc);
this.protectFunc.masks.push(String(original));
}
this.config.debugMode && this.out.warn("Filter activated on " + func);
} catch(err) {
this.config.debugMode && this.out.error("AAK failed to activate fitler on " + func + "!");
return false;
}
return true;
},
generic: undefined, // TODO
/**
* Match enum for the "applyMatch" method.
* @property matchMethod
* @type Object
*/
matchMethod: {
matchAll: 0, // Match all, this is default.
string: 1, // Substring match
stringExact: 2, // Exact string match, will result in match if one or more arguments matches the filter
RegExp: 3, // Regular expression
callback: 4 // Callback, arguments list will be supplied as an array. Retrun true for match, false for no match.
},
nativePlayer() {
},
generic: undefined,
noAccess() {
/**
* Blocks scripts from accessing a global property.
* @method noAccess
* @param name {String} The name of the property to deny access to. Using "." will traverse an object's properties. Starts at the global context.
*/
noAccess(name) {
const errMsg = "AdBlock Error: This property may not be accessed!";
try {
let property = this.win;
let parent;
let stack = name.split(".");
let current;
while (current = stack.shift()) {
parent = property;
property = parent[current];
if (!stack.length) {
this.win.Object.defineProperty(parent, current {
configurable: false,
set: function() {
throw errMsg;
},
get: function() {
throw errMsg;
}
});
}
}
} catch(err) {
this.config.debugMode && this.out.error("AAK failed to define non-accessible property " + name + "!");
return false;
}
return true;
},
observe() {
/**
* Shorthand function for observing and reacting to DOM mutations.
* @method observe
* @param type {String} The type of mutation to observe, "insert" or "remove".
* @param callback {Function} The callback function that fires when the mutation occurs.
*/
observe(type, callback) {
if (!this.observe.init.done) {
this.observe.init.done = true;
this.observe.init();
}
switch(type) {
case "insert":
this.observe.insertCallbacks.push(callback);
break;
case "remove":
this.observe.removeCallbacks.push(callback);
break;
}
},
on() {
/**
* Shorthand function for unsafeWindow.attachEventListener.
* @method on
* @param event {String} The event to listen to.
* @param func {Function} The callback that fires when the event occurs.
* @param capture {Boolean} "useCapture".
*/
on(event, func, capture) {
this.win.addEventListener(event, func, capture);
},
/**
@ -264,23 +417,155 @@ var a = (function(window) {
*/
out: unsafeWindow.console,
patchHTML() {
/**
* Modify the HTML of the entire page before it loads.
* @method patchHTML
* @param patcher {Function} Function that is passed the HTML of the page, and returns the replacement.
*/
patchHTML(patcher) {
this.win.stop();
GM_xmlhttpRequest({
method: "GET",
url: this.doc.location.href,
headers: {
"Referer": this.doc.referer
},
onload: (result) => {
this.doc.write(patcher(result.responseText));
}
});
},
/**
* Stops websites from detecting function modifications by utilizing the toString method of the function. Used in conjunction with "filter".
* @method protectFunc
*/
protectFunc() {
this.protectFunc.enabled = true;
const original = this.win.Function.prototype.toString;
const newFunc = () => {
const index = this.protectFunc.pointers.indexOf(this);
if (index === -1) {
return original.apply(this);
} else {
return this.protectFunc.masks[index];
}
};
try {
this.win.Function.prototype.toString = newFunc;
this.protectFunc.pointers.push(newFunc);
this.protectFunc.masks.push(String(original));
this.config.debugMode && this.out.warn("Functions protected.");
} catch(err) {
this.config.debugMode && this.out.error("AAK failed to protect functions!");
return false;
}
return true;
},
/**
* Makes it so a global property is not modifiable by further scripts.
* @method noAccess
* @param name {String} The name of the property to make read-only. Using "." will traverse an object's properties. Starts at the global context.
* @param val {Any} The desired value of the read-only property.
*/
readOnly(name, val) {
try {
let property = this.win;
let parent;
let stack = name.split(".");
let current;
while (current = stack.shift()) {
parent = property;
property = parent[current];
if (!stack.length) {
this.win.Object.defineProperty(parent, current {
configurable: false,
set: function() {},
get: function() {
return val;
}
});
}
}
} catch(err) {
this.config.debugMode && this.out.error("AAK failed to define read-only property " + name + "!");
return false;
}
return true;
},
/**
* Fires when the DOM is ready for modification.
* @method ready
* @param func {Function} Callback to fire when DOM is ready.
* @param capture {Boolean} Whether or not the callback should fire before event target.
*/
ready(func, capture) {
this.on("DOMContentLoaded", func, capture);
},
/**
* The unsafe window's setTimeout.
* @property setTimeout
*/
setTimeout: unsafeWindow.setTimeout,
/**
* The unsafe window's setInterval.
* @property setInterval
*/
setInterval: unsafeWindow.setInterval,
sha256() {
},
readOnly() {
/**
* Similar to "filter", except all arguments are multiplied by a "ratio" for detection on the next call. Usually used on "setInterval".
* @method timewarp
*/
timewarp(func, method, filter, onMatch, onAfter, ratio) {
ratio = ratio || 0.02;
const original = this.win[func];
const newFunc = (...args) => {
if (this.config.debugMode) {
this.out.warn("Timewarpped " + func + " is called with these arguments: ");
for (let i = 0; i < args.length; i++) {
this.out.warn(String(args[i]));
}
}
if (!method || this.applyMatch(args, method, filter)) {
this.config.debugMode && this.out.warn("Timewarpped. ");
onMatch && onMatch(args);
onAfter && onAfter(true, args);
args[1] = args[1] * ratio;
return original.apply(this.win, args);
} else {
this.config.debugMode && this.out.info("Not timewarpped. ");
onAfter && onAfter(false, args);
return original.apply(this.win, args);
}
};
try {
this.win[func] = newFunc;
if (this.protectFunc.enabled) {
this.protectFunc.pointers.push(newFunc);
this.protectFunc.masks.push(String(original));
}
this.config.debugMode && this.out.warn("Timewarp activated on " + func);
} catch (err) {
this.config.debugMode && this.out.error("uBlock Protector failed to apply timewarp on " + func + "! ");
return false;
}
return true;
},
uid() {
},
ready() {
},
timewarp() {
videoJS() {
},
@ -292,6 +577,60 @@ var a = (function(window) {
};
// Defaults for config
aak.config.aggressiveAdflySkipper = true;
aak.config.allowExperimental = true;
aak.config.allowGeneric = true;
aak.config.debugMode = false;
aak.config.domExcluded = null;
aak.config.update = (id, val) => {
const names = [
"config_debugMode",
"config_allowExperimental",
"config_aggressiveAdflySkiper",
"mods_Facebook_JumpToTop",
"mods_Blogspot_AutoNCR",
"mods_NoAutoplay"
];
if (names.includes(id)) {
GM_setValue(id, Boolean(val));
}
};
// Defaults for observe
aak.observe.init = () => {
const observer = new this.win.MutationObserver(function(mutations) {
for (let i=0; i<mutations.length; i++) {
if (mutations[i].addedNodes.length) {
for (let ii=0; ii<this.observe.insertCallbacks.length; ii++) {
for (let iii=0; iii<mutations[i].addedNodes.length; iii++) {
this.observe.insertCallbacks[ii](mutations[i].addedNodes[iii]);
}
}
}
if (mutations[i].removedNodes.length) {
for (let ii = 0; ii < this.observe.removeCallbacks.length; ii++) {
for (let iii = 0; iii < mutations[i].removedNodes.length; iii++) {
this.observe.removeCallbacks[ii](mutations[i].removedNodes[iii]);
}
}
}
}
});
observer.observe(this.doc, {
childList: true,
subtree: true
});
};
aak.observe.init.done = false;
aak.observe.insertCallbacks = [];
aak.observe.removeCallbacks = [];
// Defaults for protectFunc
aak.protectFunc.enabled = false;
aak.protectFunc.pointers = [];
aak.protectFunc.masks = [];
return aak;
})(window);