|
|
@@ -14,6 +14,18 @@ var _ = {
|
|
|
});
|
|
|
});
|
|
|
},
|
|
|
+
|
|
|
+ includes: function (arr, item) {
|
|
|
+ var length = arr.length;
|
|
|
+ for (var i = 0; i < length; i ++)
|
|
|
+ if (arr[i] === item) return true;
|
|
|
+ return false;
|
|
|
+ },
|
|
|
+ forEach: function (arr, func, context) {
|
|
|
+ var length = arr.length;
|
|
|
+ for (var i = 0; i < length; i ++)
|
|
|
+ if (func.call(context, arr[i], i, arr) === false) break;
|
|
|
+ },
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
@@ -70,6 +82,75 @@ function setBadge(){
|
|
|
}
|
|
|
|
|
|
// Communicator
|
|
|
+function getWrapper() {
|
|
|
+ // http://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects
|
|
|
+ // http://developer.mozilla.org/docs/Web/API/Window
|
|
|
+ var comm = this;
|
|
|
+ var wrapper = {};
|
|
|
+ // Wrap methods
|
|
|
+ comm.forEach([
|
|
|
+ 'eval',
|
|
|
+ // 'uneval',
|
|
|
+ 'isFinite',
|
|
|
+ 'isNaN',
|
|
|
+ 'parseFloat',
|
|
|
+ 'parseInt',
|
|
|
+ 'decodeURI',
|
|
|
+ 'decodeURIComponent',
|
|
|
+ 'encodeURI',
|
|
|
+ 'encodeURIComponent',
|
|
|
+
|
|
|
+ 'addEventListener',
|
|
|
+ 'alert',
|
|
|
+ 'atob',
|
|
|
+ 'blur',
|
|
|
+ 'btoa',
|
|
|
+ 'clearInterval',
|
|
|
+ 'clearTimeout',
|
|
|
+ 'close',
|
|
|
+ 'confirm',
|
|
|
+ 'dispatchEvent',
|
|
|
+ 'find',
|
|
|
+ 'focus',
|
|
|
+ 'getComputedStyle',
|
|
|
+ 'getSelection',
|
|
|
+ 'matchMedia',
|
|
|
+ 'moveBy',
|
|
|
+ 'moveTo',
|
|
|
+ 'open',
|
|
|
+ 'openDialog',
|
|
|
+ 'postMessage',
|
|
|
+ 'print',
|
|
|
+ 'prompt',
|
|
|
+ 'removeEventListener',
|
|
|
+ 'resizeBy',
|
|
|
+ 'resizeTo',
|
|
|
+ 'scroll',
|
|
|
+ 'scrollBy',
|
|
|
+ 'scrollByLines',
|
|
|
+ 'scrollByPages',
|
|
|
+ 'scrollTo',
|
|
|
+ 'setInterval',
|
|
|
+ 'setTimeout',
|
|
|
+ 'stop',
|
|
|
+ ], function (name) {
|
|
|
+ var method = window[name];
|
|
|
+ wrapper[name] = function () {
|
|
|
+ return method.apply(window, arguments);
|
|
|
+ };
|
|
|
+ });
|
|
|
+ // Wrap properties
|
|
|
+ Object.getOwnPropertyNames(window).forEach(function (name) {
|
|
|
+ if (typeof window[name] === 'function') return;
|
|
|
+ Object.defineProperty(wrapper, name, {
|
|
|
+ get: function () {
|
|
|
+ var value = window[name];
|
|
|
+ return value === window ? wrapper : value;
|
|
|
+ },
|
|
|
+ });
|
|
|
+ });
|
|
|
+ return wrapper;
|
|
|
+}
|
|
|
var comm = {
|
|
|
vmid: 'VM_' + _.getUniqId(),
|
|
|
state: 0,
|
|
|
@@ -79,27 +160,9 @@ var comm = {
|
|
|
// Array functions
|
|
|
// to avoid using prototype functions
|
|
|
// since they may be changed by page scripts
|
|
|
- inArray: function(arr, item) {
|
|
|
- for (var i = 0; i < arr.length; i ++)
|
|
|
- if (arr[i] == item) return true;
|
|
|
- return false;
|
|
|
- },
|
|
|
- extendArray: function(arr, arr2) {
|
|
|
- for(var i = 0; i < arr2.length; i ++) arr.push(arr2[i]);
|
|
|
- },
|
|
|
- forEach: function(arr, func, args) {
|
|
|
- for(var i = 0; i < arr.length; i ++) {
|
|
|
- var _args = [arr[i]];
|
|
|
- if(args) this.extendArray(_args, args);
|
|
|
- func.apply(arr, _args);
|
|
|
- }
|
|
|
- },
|
|
|
+ includes: _.includes,
|
|
|
+ forEach: _.forEach,
|
|
|
|
|
|
- prop1: Object.getOwnPropertyNames(window),
|
|
|
- prop2: (function(n,p){
|
|
|
- while(n=Object.getPrototypeOf(n)) p=p.concat(Object.getOwnPropertyNames(n));
|
|
|
- return p;
|
|
|
- })(window,[]),
|
|
|
init: function(srcId, destId) {
|
|
|
var comm = this;
|
|
|
comm.sid = comm.vmid + srcId;
|
|
|
@@ -200,7 +263,7 @@ var comm = {
|
|
|
};
|
|
|
t.id = id;
|
|
|
comm.requests[id] = t;
|
|
|
- if(comm.inArray(['arraybuffer', 'blob'], t.details.responseType))
|
|
|
+ if(comm.includes(['arraybuffer', 'blob'], t.details.responseType))
|
|
|
data.responseType = 'blob';
|
|
|
comm.post({cmd: 'HttpRequest', data: data});
|
|
|
}
|
|
|
@@ -229,55 +292,7 @@ var comm = {
|
|
|
return t.req;
|
|
|
};
|
|
|
},
|
|
|
- initWrapper: function() {
|
|
|
- // wrapper: wrap functions as needed, return and set properties
|
|
|
- function wrapItem(key, thisObj, wrap) {
|
|
|
- var type;
|
|
|
- var value;
|
|
|
- var apply = Function.apply;
|
|
|
- function initProperty() {
|
|
|
- if(!comm.inArray(['function', 'custom'], type)) {
|
|
|
- value = window[key];
|
|
|
- type = typeof value;
|
|
|
- if(wrap && type == 'function') {
|
|
|
- var func = value;
|
|
|
- value = function () {
|
|
|
- var r;
|
|
|
- try {
|
|
|
- r = apply.apply(func, [window, arguments]);
|
|
|
- } catch(e) {
|
|
|
- console.log('[Violentmonkey] Error calling ' + key + ':\n' + e.stack);
|
|
|
- }
|
|
|
- return r === window ? thisObj : r;
|
|
|
- };
|
|
|
- Object.setPrototypeOf(value, func);
|
|
|
- value.prototype = func.prototype;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- try {
|
|
|
- Object.defineProperty(thisObj, key, {
|
|
|
- get: function () {
|
|
|
- initProperty();
|
|
|
- return value === window ? thisObj : value;
|
|
|
- },
|
|
|
- set: function (_value) {
|
|
|
- initProperty();
|
|
|
- value = _value;
|
|
|
- if(type != 'function') window[key] = _value;
|
|
|
- type = 'custom';
|
|
|
- },
|
|
|
- });
|
|
|
- } catch(e) {
|
|
|
- // ignore protected data
|
|
|
- }
|
|
|
- }
|
|
|
- var comm = this;
|
|
|
- comm.Wrapper = function () {
|
|
|
- comm.forEach(comm.prop1, wrapItem, [this]);
|
|
|
- comm.forEach(comm.prop2, wrapItem, [this, true]);
|
|
|
- };
|
|
|
- },
|
|
|
+ getWrapper: getWrapper,
|
|
|
wrapGM: function(script, value, cache) {
|
|
|
// Add GM functions
|
|
|
// Reference: http://wiki.greasespot.net/Greasemonkey_Manual:API
|
|
|
@@ -285,16 +300,15 @@ var comm = {
|
|
|
var gm = {};
|
|
|
var grant = script.meta.grant || [];
|
|
|
var urls = {};
|
|
|
- if (!grant.length || grant.length == 1 && grant[0] == 'none')
|
|
|
+ if (!grant.length || grant.length == 1 && grant[0] == 'none') {
|
|
|
// @grant none
|
|
|
grant.pop();
|
|
|
- else {
|
|
|
- if (!comm.Wrapper) comm.initWrapper();
|
|
|
- gm['window'] = new comm.Wrapper();
|
|
|
+ } else {
|
|
|
+ gm['window'] = comm.getWrapper();
|
|
|
}
|
|
|
value = value || {};
|
|
|
- if(!comm.inArray(grant, 'unsafeWindow')) grant.push('unsafeWindow');
|
|
|
- if(!comm.inArray(grant, 'GM_info')) grant.push('GM_info');
|
|
|
+ if(!comm.includes(grant, 'unsafeWindow')) grant.push('unsafeWindow');
|
|
|
+ if(!comm.includes(grant, 'GM_info')) grant.push('GM_info');
|
|
|
function propertyToString() {
|
|
|
return '[Violentmonkey property]';
|
|
|
}
|
|
|
@@ -529,7 +543,7 @@ var comm = {
|
|
|
}, 0);
|
|
|
};
|
|
|
comm.checkLoad = function() {
|
|
|
- if (!comm.state && comm.inArray(['interactive', 'complete'], document.readyState))
|
|
|
+ if (!comm.state && comm.includes(['interactive', 'complete'], document.readyState))
|
|
|
comm.state = 1;
|
|
|
if (comm.state) comm.load();
|
|
|
};
|