mirror of
https://github.com/wassname/RubberGlove.git
synced 2026-06-27 16:59:06 +08:00
settings support (no UI yet), more BOM overload corner case handling, improved bomViewer
This commit is contained in:
+42
-16
@@ -1,28 +1,54 @@
|
|||||||
$(function() {
|
$(function() {
|
||||||
$("#bomTree").fancytree({
|
$("#bomTree").fancytree({
|
||||||
source: [
|
source: [
|
||||||
{title: "window", key: "window", folder: true, lazy: true, data: { obj: window }}
|
{title: "<b>window</b>", key: "window", folder: true, lazy: true, data: { obj: window }, icon: "images/ClassIcon.png"}
|
||||||
],
|
],
|
||||||
checkbox: false,
|
checkbox: false,
|
||||||
lazyLoad: function(event, data) {
|
lazyLoad: function(event, data) {
|
||||||
var node = data.node;
|
var node = data.node;
|
||||||
var object = node.data.obj;
|
var object = node.data.obj;
|
||||||
var result = [];
|
var result = [];
|
||||||
for(property in object) {
|
if(object != null) {
|
||||||
var propertyType = typeof object[property];
|
|
||||||
switch(propertyType) {
|
if(typeof object.constructor != 'undefined' && object.constructor !== object) {
|
||||||
case "object":
|
var func = "constructor: " + object.constructor.toString();
|
||||||
result.push({title: property, key: node.key + "." + property, folder: true, lazy: true, data: { obj : object[property]}});
|
result.push({title: func, key: node.key + ".constructor", folder: true, lazy: true, data: {obj: object.constructor}, icon: "images/Function_8941.png"});
|
||||||
break;
|
}
|
||||||
case "function":
|
|
||||||
var func = object[property].toString();
|
var propertyNames = Object.getOwnPropertyNames(object);
|
||||||
if(func.indexOf("function (") == 0)
|
for(var propertyIndex = 0; propertyIndex < propertyNames.length; propertyIndex++) {
|
||||||
func = func.substring(0, 9) + property + func.substring(9);
|
var propertyName = propertyNames[propertyIndex];
|
||||||
result.push({title: func, key: node.key + "." + property, folder: false, lazy: false});
|
if(propertyName == "constructor") continue;
|
||||||
break;
|
var propertyType = typeof object[propertyName];
|
||||||
default:
|
var propertyDescriptor = Object.getOwnPropertyDescriptor(object, propertyName);
|
||||||
result.push({title: property + " = '" + object[property] + "'", key: node.key + "." + property, folder: false, lazy: false});
|
var enumerable = (typeof propertyDescriptor.enumerable != 'undefined' && propertyDescriptor.enumerable == true);
|
||||||
break;
|
var child = {
|
||||||
|
title: enumerable ? "<b>" + propertyName + "</b>" : "<b style=\"color: lightgray;\">" + propertyName + "</b>",
|
||||||
|
key: node.key + "." + propertyName,
|
||||||
|
data: {obj: object[propertyName]},
|
||||||
|
}
|
||||||
|
switch(propertyType) {
|
||||||
|
case "object":
|
||||||
|
child.title += ": " + object[propertyName];
|
||||||
|
child.icon = "images/ClassIcon.png";
|
||||||
|
child.folder = object[propertyName] != null;
|
||||||
|
child.lazy = object[propertyName] != null;
|
||||||
|
break;
|
||||||
|
case "function":
|
||||||
|
child.title += ": " + object[propertyName].toString();
|
||||||
|
child.folder = true;
|
||||||
|
child.lazy = true;
|
||||||
|
child.icon = "images/Function_8941.png";
|
||||||
|
break;
|
||||||
|
case "string":
|
||||||
|
child.title += ": '" + object[propertyName] + "'";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
child.title += ": " + object[propertyName];
|
||||||
|
child.icon = "images/PropertyIcon.png";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result.push(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log("Adding " + result.length + " children to " + node.key);
|
console.log("Adding " + result.length + " children to " + node.key);
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 210 B |
Binary file not shown.
|
After Width: | Height: | Size: 412 B |
Binary file not shown.
|
After Width: | Height: | Size: 264 B |
@@ -1,3 +1,7 @@
|
|||||||
|
console.log("RubberGlove: Persisting settings");
|
||||||
|
persistConfig("persistedSettings.js", {local:{enabled:true, verbose:true}});
|
||||||
|
console.log("RubberGlove: Settings stored at " + getWebStorageUri("persistedSettings.js"));
|
||||||
|
|
||||||
function resetBadgeCounter(tabId) {
|
function resetBadgeCounter(tabId) {
|
||||||
localStorage['RubberGlove_BlockCount_' + tabId] = 0;
|
localStorage['RubberGlove_BlockCount_' + tabId] = 0;
|
||||||
chrome.browserAction.setBadgeBackgroundColor({ color: [255, 0, 0, 255] });
|
chrome.browserAction.setBadgeBackgroundColor({ color: [255, 0, 0, 255] });
|
||||||
|
|||||||
+244
-151
@@ -1,165 +1,258 @@
|
|||||||
var bomOverloadFunction = function() {
|
function bomOverload() {
|
||||||
|
if(config.local.verbose) console.log("RubberGlove: Creating PluginArray");
|
||||||
|
function PluginArray() { // native(PluginArray)
|
||||||
|
if(window.navigator.plugins.constructor === PluginArray)
|
||||||
|
throw new TypeError("Illegal constructor");
|
||||||
|
|
||||||
|
if(config.local.verbose) console.log("RubberGlove: Creating PluginArray instance");
|
||||||
|
|
||||||
|
Object.defineProperty(this, 'length', {
|
||||||
|
enumerable: true,
|
||||||
|
get: (function(eventNode) {
|
||||||
|
return function() {
|
||||||
|
// native()
|
||||||
|
console.error('RubberGlove: Iteration of window.navigator.plugins blocked for ' + window.location.href + ' (Informational, not an error.)');
|
||||||
|
window.postMessage({
|
||||||
|
type: 'RubberGlove',
|
||||||
|
text: 'window.navigator.plugins',
|
||||||
|
url: window.location.href
|
||||||
|
}, '*');
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
})(document.currentScript.parentNode)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add hidden named plugins
|
||||||
|
var plugins = window.navigator.plugins;
|
||||||
|
for(var i = 0; i < plugins.length; i++) {
|
||||||
|
var plugin = plugins[i];
|
||||||
|
if(typeof plugin != 'undefined' && typeof plugin.name != 'undefined' && plugin.name != null) {
|
||||||
|
Object.defineProperty(this, plugin.name, {
|
||||||
|
configurable: true,
|
||||||
|
value: plugin
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Don't ask me why the real function has this... It's not even a prototype.
|
||||||
|
PluginArray.toString = function toString() { // native(toString)
|
||||||
|
return Function.prototype.toString.apply(this, Array.prototype.slice.apply(arguments));
|
||||||
|
};
|
||||||
|
if(config.local.verbose) console.log("RubberGlove: Creating PluginArray.prototype.item()");
|
||||||
|
PluginArray.prototype.item = function item() { // native(item)
|
||||||
|
return this[arguments[0]];
|
||||||
|
};
|
||||||
|
if(config.local.verbose) console.log("RubberGlove: Creating PluginArray.prototype.namedItem()");
|
||||||
|
PluginArray.prototype.namedItem = function namedItem() { // native(namedItem)
|
||||||
|
return this[arguments[0]];
|
||||||
|
};
|
||||||
|
if(config.local.verbose) console.log("RubberGlove: Creating PluginArray.prototype.refresh()");
|
||||||
|
PluginArray.prototype.refresh = (function(plugins) {
|
||||||
|
if(config.local.verbose) console.log("RubberGlove: Returning our custom PluginArray.refresh()");
|
||||||
|
return function refresh() { // native(refresh)
|
||||||
|
// Refresh the real plugins list
|
||||||
|
plugins.refresh.apply(plugins, Array.prototype.slice.apply(arguments));
|
||||||
|
|
||||||
|
// Delete our existing set of plugins
|
||||||
|
var propertyNames = Object.getOwnPropertyNames(this);
|
||||||
|
for(var i = 0; i < propertyNames.length; i++) {
|
||||||
|
var property = propertyNames[i];
|
||||||
|
if(property != 'length') delete this[property];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add hidden named plugins
|
||||||
|
for(var i = 0; i < plugins.length; i++) {
|
||||||
|
var plugin = plugins[i];
|
||||||
|
if(typeof plugin.name != 'undefined' && plugin.name != null) {
|
||||||
|
Object.defineProperty(this, plugin.name, {
|
||||||
|
configurable: true,
|
||||||
|
value: plugin
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})(window.navigator.plugins);
|
||||||
|
if(config.local.verbose) console.log("RubberGlove: Replacing window.PluginArray");
|
||||||
|
Object.defineProperty(window, 'PluginArray', {
|
||||||
|
enumerable: false,
|
||||||
|
configurable: false,
|
||||||
|
writable: true,
|
||||||
|
value: PluginArray
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO: This should refresh as well when PluginArray.refresh() is called.
|
||||||
|
if(config.local.verbose) console.log("RubberGlove: Creating MimeTypeArray");
|
||||||
|
function MimeTypeArray() { // native(MimeTypeArray)
|
||||||
|
if(window.navigator.mimeTypes.constructor === MimeTypeArray)
|
||||||
|
throw new TypeError("Illegal constructor");
|
||||||
|
|
||||||
|
if(config.local.verbose) console.log("RubberGlove: Creating MimeTypeArray instance");
|
||||||
|
|
||||||
|
Object.defineProperty(this, 'length', {
|
||||||
|
enumerable: true,
|
||||||
|
get: (function(eventNode) {
|
||||||
|
return function() {
|
||||||
|
// native()
|
||||||
|
console.error('RubberGlove: Iteration of window.navigator.mimeTypes blocked for ' + window.location.href + ' (Informational, not an error.)');
|
||||||
|
window.postMessage({
|
||||||
|
type: 'RubberGlove',
|
||||||
|
text: 'window.navigator.mimeTypes',
|
||||||
|
url: window.location.href
|
||||||
|
}, '*');
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
})(document.currentScript.parentNode)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add hidden named mimeTypes
|
||||||
|
var mimeTypes = window.navigator.mimeTypes;
|
||||||
|
for(var i = 0; i < mimeTypes.length; i++) {
|
||||||
|
var mimeType = mimeTypes[i];
|
||||||
|
if(typeof mimeType != 'undefined' && typeof mimeType.type != 'undefined' && mimeType.type != null) {
|
||||||
|
Object.defineProperty(this, mimeType.type, {
|
||||||
|
configurable: true,
|
||||||
|
value: mimeType
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Don't ask me why the real function has this... It's not even a prototype.
|
||||||
|
MimeTypeArray.toString = function toString() { // native(toString)
|
||||||
|
return Function.prototype.toString.apply(this, Array.prototype.slice.apply(arguments));
|
||||||
|
};
|
||||||
|
// Yes, these duplicate the ones for PluginArray. No, they should
|
||||||
|
// not use the same functions as they shouldn't test as equal.
|
||||||
|
if(config.local.verbose) console.log("RubberGlove: Creating MimeTypeArray.prototype.item()");
|
||||||
|
MimeTypeArray.prototype.item = function item(index) { // native(item)
|
||||||
|
return this[arguments[0]];
|
||||||
|
};
|
||||||
|
if(config.local.verbose) console.log("RubberGlove: Creating MimeTypeArray.prototype.namedItem()");
|
||||||
|
MimeTypeArray.prototype.namedItem = function namedItem(name) { // native(namedItem)
|
||||||
|
return this[arguments[0]];
|
||||||
|
};
|
||||||
|
if(config.local.verbose) console.log("RubberGlove: Replacing window.MimeTypeArray");
|
||||||
|
Object.defineProperty(window, 'MimeTypeArray', {
|
||||||
|
enumerable: false,
|
||||||
|
configurable: false,
|
||||||
|
writable: true,
|
||||||
|
value: MimeTypeArray
|
||||||
|
});
|
||||||
|
|
||||||
|
if(config.local.verbose) console.log("RubberGlove: Creating Navigator");
|
||||||
|
function Navigator() { // native(Navigator)
|
||||||
|
if(window.navigator.constructor === Navigator)
|
||||||
|
throw new TypeError("Illegal constructor");
|
||||||
|
|
||||||
|
if(config.local.verbose) console.log("RubberGlove: Creating Navigator instance");
|
||||||
|
|
||||||
|
var propertyNames = Object.getOwnPropertyNames(window.navigator);
|
||||||
|
for(var propertyIndex = 0; propertyIndex < propertyNames.length; propertyIndex++) {
|
||||||
|
var propertyName = propertyNames[propertyIndex];
|
||||||
|
var descriptor = Object.getOwnPropertyDescriptor(window.navigator, propertyName);
|
||||||
|
var writable = descriptor.writable == true || typeof descriptor.set == 'function';
|
||||||
|
|
||||||
|
delete descriptor.value;
|
||||||
|
delete descriptor.get;
|
||||||
|
delete descriptor.set;
|
||||||
|
delete descriptor.writable;
|
||||||
|
|
||||||
|
switch(propertyName) {
|
||||||
|
case 'plugins':
|
||||||
|
console.log('RubberGlove: Cloaking plugins for ' + window.location.href);
|
||||||
|
descriptor.value = new PluginArray();
|
||||||
|
break;
|
||||||
|
case 'mimeTypes':
|
||||||
|
console.log('RubberGlove: Cloaking mimeTypes for ' + window.location.href);
|
||||||
|
descriptor.value = new MimeTypeArray();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//console.log("RubberGlove: wrapping " + propertyName);
|
||||||
|
descriptor.get = (function(propertyName, navigator) {
|
||||||
|
return function() { /* native() */ return navigator[propertyName] };
|
||||||
|
})(propertyName, window.navigator);
|
||||||
|
if(writable) {
|
||||||
|
descriptor.set = (function(propertyName, navigator) {
|
||||||
|
return function(value) { /* native(item) */ navigator[propertyName] = value; };
|
||||||
|
})(propertyName, window.navigator);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Object.defineProperty(this, propertyName, descriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Don't ask me why the real function has this... It's not even a prototype.
|
||||||
|
Navigator.toString = function toString() { // native(toString)
|
||||||
|
return Function.prototype.toString.apply(this, Array.prototype.slice.apply(arguments));
|
||||||
|
};
|
||||||
|
if(config.local.verbose) console.log("RubberGlove: Replacing Navigator.prototype");
|
||||||
|
for(var property in window.Navigator.prototype) {
|
||||||
|
Navigator.prototype[property] = window.Navigator.prototype[property];
|
||||||
|
}
|
||||||
|
if(config.local.verbose) console.log("RubberGlove: Replacing window.Navigator");
|
||||||
|
Object.defineProperty(window, 'Navigator', {
|
||||||
|
enumerable: false,
|
||||||
|
configurable: false,
|
||||||
|
writable: true,
|
||||||
|
value: Navigator
|
||||||
|
});
|
||||||
|
|
||||||
|
if(config.local.verbose) console.log("RubberGlove: Constructing Navigator");
|
||||||
|
var navigatorProxy = new Navigator();
|
||||||
|
if(config.local.verbose) console.log("RubberGlove: Replacing window.navigator");
|
||||||
|
Object.defineProperty(window, 'navigator', {
|
||||||
|
enumerable: true,
|
||||||
|
configurable: false,
|
||||||
|
writable: true,
|
||||||
|
value: navigatorProxy
|
||||||
|
});
|
||||||
|
if(config.local.verbose) console.log("RubberGlove: Replacing window.clientInformation");
|
||||||
|
Object.defineProperty(window, 'clientInformation', {
|
||||||
|
enumerable: true,
|
||||||
|
configurable: false,
|
||||||
|
writable: true,
|
||||||
|
value: navigatorProxy
|
||||||
|
});
|
||||||
|
|
||||||
// Hides source code when it contains "// native(functionName)" or
|
// Hides source code when it contains "// native(functionName)" or
|
||||||
// "/* native(functionName)" at the beginning of the function body.
|
// "/* native(functionName)" at the beginning of the function body.
|
||||||
Function.prototype.toString = (function() {
|
if(config.local.verbose) console.log("RubberGlove: Replacing Function.prototype.toString()");
|
||||||
var toString = Function.prototype.toString;
|
Function.prototype.toString = (function(oldToString) {
|
||||||
return function(thisArg, argsArray) {
|
return function toString() { // native(toString) <-- yes, it handles itself
|
||||||
// native(toString) <-- yes, it handles itself
|
var result = oldToString.apply(this, Array.prototype.slice.apply(arguments));
|
||||||
var result = toString.apply(this, Array.prototype.slice.apply(arguments));
|
|
||||||
var match = result.match(/^\s*?function.*?\(.*?\)\s*?{\s*?\/[\*\/]\s*?native\((.*?)\)/);
|
var match = result.match(/^\s*?function.*?\(.*?\)\s*?{\s*?\/[\*\/]\s*?native\((.*?)\)/);
|
||||||
if(match != null && match.length > 1)
|
if(match != null && match.length > 1)
|
||||||
return 'function ' + match[1] + '() { [native code] }';
|
return 'function ' + match[1] + '() { [native code] }';
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
})();
|
})(Function.prototype.toString);
|
||||||
|
|
||||||
var navWrapper = (function() {
|
// Hides named plugins and mimeTypes
|
||||||
var oldNavigator = navigator;
|
if(config.local.verbose) console.log("RubberGlove: Replacing Object.getOwnPropertyNames()");
|
||||||
var altNav = {};
|
Object.getOwnPropertyNames = (function(oldGetOwnPropertyNames) {
|
||||||
var propertyNames = Object.getOwnPropertyNames(oldNavigator);
|
return function getOwnPropertyNames() { // native(getOwnPropertyNames)
|
||||||
for(var propertyIndex = 0; propertyIndex < propertyNames.length; propertyIndex++) {
|
var propertyNames = oldGetOwnPropertyNames.apply(this, Array.prototype.slice.apply(arguments));
|
||||||
propertyName = propertyNames[propertyIndex];
|
if(arguments[0] === window.navigator.plugins || arguments[0] === window.navigator.mimeTypes) {
|
||||||
|
var filteredNames = [];
|
||||||
// Get the Property Descriptor
|
for(var i=0; i < propertyNames.length; i++) {
|
||||||
var descriptor = Object.getOwnPropertyDescriptor(navigator, propertyName);
|
var propertyName = propertyNames[i];
|
||||||
|
if(propertyName == 'item' || propertyName == 'namedItem' || propertyName == 'length') {
|
||||||
// Delete any values we'll be replacing
|
filteredNames.push(propertyName);
|
||||||
if(typeof descriptor.value != 'undefined') delete descriptor['value'];
|
|
||||||
if(typeof descriptor.get != 'undefined') delete descriptor['get'];
|
|
||||||
var writable = false;
|
|
||||||
if(typeof descriptor.set != 'undefined') {
|
|
||||||
delete descriptor['set'];
|
|
||||||
writable = true;
|
|
||||||
}
|
|
||||||
if(typeof descriptor.writable != 'undefined') {
|
|
||||||
if(descriptor.writable == 'true') writable = true;
|
|
||||||
delete descriptor['writable'];
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(propertyName) {
|
|
||||||
|
|
||||||
// Wrap the navigator.plugins object
|
|
||||||
case 'plugins':
|
|
||||||
console.log('RubberGlove: Cloaking plugins for ' + window.location.href);
|
|
||||||
var plugins = { };
|
|
||||||
Object.defineProperty(plugins, 'length', { 'get': (function() {
|
|
||||||
var eventNode = document.currentScript.parentNode;
|
|
||||||
return function() {
|
|
||||||
// native()
|
|
||||||
console.error('RubberGlove: Iteration of navigator.plugins blocked for ' + window.location.href + ' (Informational, not an error.)');
|
|
||||||
window.postMessage({ type: 'RubberGlove', text: 'navigator.plugins', url: window.location.href }, '*');
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
})(), enumerable: true});
|
|
||||||
plugins.item = (function() {
|
|
||||||
var fakePlugins = plugins;
|
|
||||||
return function(index) { /* native(item) */ return fakePlugins[index]; };
|
|
||||||
})();
|
|
||||||
plugins.namedItem = (function() {
|
|
||||||
var fakePlugins = plugins;
|
|
||||||
return function(name) { /* native(namedItem) */ return fakePlugins[name]; };
|
|
||||||
})();
|
|
||||||
plugins.refresh = (function() {
|
|
||||||
var fakePlugins = plugins;
|
|
||||||
var realPlugins = oldNavigator.plugins;
|
|
||||||
return function() {
|
|
||||||
// native(refresh)
|
|
||||||
// Refresh the real plugins list
|
|
||||||
// TODO: We probably shouldn't call this the first time if possible
|
|
||||||
realPlugins.refresh();
|
|
||||||
// Remove any plugins we already have
|
|
||||||
var propNames = Object.getOwnPropertyNames(oldNavigator);
|
|
||||||
for(var i = 0; i < propNames.length; i++) {
|
|
||||||
var property = propNames[propertyIndex];
|
|
||||||
if(property != 'length') delete fakePlugins[property];
|
|
||||||
}
|
|
||||||
// Add plugins so they are accessible by key but not index
|
|
||||||
for(var n = 0; n < realPlugins.length; n++) {
|
|
||||||
var plugin = realPlugins[n];
|
|
||||||
//console.log('RubberGlove: Cloaking \'' + plugin.name + '\'');
|
|
||||||
if(typeof plugin.name != 'undefined' && plugin.name != null && plugin.name != '')
|
|
||||||
Object.defineProperty(fakePlugins, plugin.name, { 'value': plugin, configurable: true });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
// Refresh to initially populate the plugins
|
|
||||||
plugins.refresh();
|
|
||||||
descriptor.value = plugins;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Wrap the navigator.mimeTypes object
|
|
||||||
case 'mimeTypes':
|
|
||||||
console.log('RubberGlove: Cloaking mimeTypes for ' + window.location.href);
|
|
||||||
var mimeTypes = { };
|
|
||||||
Object.defineProperty(mimeTypes, 'length', { 'get': (function() {
|
|
||||||
var eventNode = document.currentScript.parentNode;
|
|
||||||
return function() {
|
|
||||||
// native()
|
|
||||||
console.error('RubberGlove: Iteration of navigator.mimeTypes blocked for ' + window.location.href + ' (Informational, not an error.)');
|
|
||||||
window.postMessage({ type: 'RubberGlove', text: 'navigator.mimeTypes', url: window.location.href }, '*');
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
})(), enumerable: true});
|
|
||||||
mimeTypes.item = (function() {
|
|
||||||
var fakeMimeTypes = mimeTypes;
|
|
||||||
return function(index) { /* native(item) */ return fakeMimeTypes[index]; };
|
|
||||||
})();
|
|
||||||
// Add mimeTypes so they are accessible by key but not index
|
|
||||||
for(var n = 0; n < oldNavigator.mimeTypes.length; n++) {
|
|
||||||
var mimeType = oldNavigator.mimeTypes[n];
|
|
||||||
//console.log('RubberGlove: Cloaking \'' + mimeType.type + '\'');
|
|
||||||
if(typeof mimeType.type != 'undefined' && mimeType.type != null && mimeType.type != '')
|
|
||||||
Object.defineProperty(mimeTypes, mimeType.type, { 'value': mimeType, configurable: true });
|
|
||||||
}
|
}
|
||||||
descriptor.value = mimeTypes;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// wrap any other properties of navigator
|
|
||||||
default:
|
|
||||||
//console.log("RubberGlove: wrapping " + propertyName);
|
|
||||||
descriptor.get = (function() {
|
|
||||||
var prop = propertyName;
|
|
||||||
var nav = oldNavigator;
|
|
||||||
return function() { /* native() */ return nav[prop] };
|
|
||||||
})();
|
|
||||||
if(writable) {
|
|
||||||
descriptor.set = (function(value) {
|
|
||||||
var prop = propertyName;
|
|
||||||
var nav = oldNavigator;
|
|
||||||
return function() { /* native(item) */ nav[prop] = value; };
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Object.defineProperty(altNav, propertyName, descriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add or wrap any functions
|
|
||||||
for(propertyName in oldNavigator) {
|
|
||||||
if(typeof(oldNavigator[propertyName]) == "function") {
|
|
||||||
switch(propertyName) {
|
|
||||||
default:
|
|
||||||
//console.log("RubberGlove: Adding function " + propertyName + "()");
|
|
||||||
altNav[propertyName] = oldNavigator[propertyName];
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
return filteredNames;
|
||||||
}
|
}
|
||||||
|
return propertyNames;
|
||||||
}
|
}
|
||||||
|
})(Object.getOwnPropertyNames);
|
||||||
|
|
||||||
return altNav;
|
// Makes our objects look like first class objects
|
||||||
})();
|
if(config.local.verbose) console.log("RubberGlove: Replacing Object.prototype.toString()");
|
||||||
|
Object.prototype.toString = (function(oldToString) {
|
||||||
Object.defineProperty(window, 'navigator', {
|
return function toString() { // native(toString)
|
||||||
enumerable: true,
|
if(this === window.navigator) return "[object Navigator]";
|
||||||
configurable: false,
|
if(this === window.navigator.plugins) return "[object PluginArray]";
|
||||||
writable: true,
|
if(this === window.navigator.mimeTypes) return "[object MimeTypeArray]";
|
||||||
value: navWrapper
|
return oldToString.apply(this, Array.prototype.slice.apply(arguments));
|
||||||
});
|
};
|
||||||
|
})(Object.prototype.toString);
|
||||||
Object.defineProperty(window, 'clientInformation', {
|
|
||||||
enumerable: true,
|
|
||||||
configurable: false,
|
|
||||||
writable: true,
|
|
||||||
value: navWrapper
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|||||||
+50
-34
@@ -1,38 +1,54 @@
|
|||||||
//console.log("RubberGlove: Content Script for " + window.location.href);
|
//console.log("RubberGlove: Content Script for " + window.location.href);
|
||||||
|
function getConfig(filename) {
|
||||||
// Create the script to be injected
|
var xhr = new XMLHttpRequest();
|
||||||
var pageScript = document.createElement('script');
|
xhr.open('GET', 'filesystem:' + chrome.extension.getURL('temporary/' + filename), false);
|
||||||
pageScript.type = 'text/javascript';
|
xhr.send(null);
|
||||||
pageScript.async = false;
|
if(xhr.status == 200) return xhr.responseText;
|
||||||
pageScript.text = "(" + bomOverloadFunction.toString() + ")();"
|
return;
|
||||||
+ "(" + scriptCleanupFunction.toString() + ")();";
|
|
||||||
|
|
||||||
// Locate the <head> or create a new one if there isn't one or it isn't at
|
|
||||||
// the top of the page.
|
|
||||||
var html = document.documentElement
|
|
||||||
var headTags = document.getElementsByTagName("head");
|
|
||||||
var head = headTags.length > 0 ? head = headTags[0] : null;
|
|
||||||
if(!head || head !== html.firstChild) {
|
|
||||||
head = document.createElement('head');
|
|
||||||
html.insertBefore(head, html.firstChild);
|
|
||||||
pageScript.id = "_RubberGlove_removeHead";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listen for callbacks from the page script
|
var configText = getConfig("persistedSettings.js");
|
||||||
window.addEventListener("message", function(event) {
|
console.log("RubberGlove: config = " + configText);
|
||||||
if(event.source != window) return;
|
var config = JSON.parse(configText);
|
||||||
if(event.data.type && event.data.type == "RubberGlove") {
|
|
||||||
// Tell background.js to increment the badge counter
|
|
||||||
chrome.runtime.sendMessage({
|
|
||||||
type: "increment-counter",
|
|
||||||
url: window.location.href,
|
|
||||||
message: event.data.text
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Insert our script into the page. Note: This absolutely cannot under
|
if(config.local.enabled) {
|
||||||
// any circumstances happen in an async callback otherwise scripts on the
|
// Create the script to be injected
|
||||||
// page may run first and have access to the unwrapped objects.
|
var pageScript = document.createElement('script');
|
||||||
// Synchronous XHR requests before this seem to work fine, however.
|
pageScript.type = 'text/javascript';
|
||||||
head.insertBefore(pageScript, head.firstChild);
|
pageScript.async = false;
|
||||||
|
pageScript.text = "(function() {\n" +
|
||||||
|
"var config = " + configText + ";\n" +
|
||||||
|
"(" + bomOverload.toString() + ")();\n" +
|
||||||
|
"(" + scriptCleanupFunction.toString() + ")();\n" +
|
||||||
|
"})();";
|
||||||
|
|
||||||
|
// Locate the <head> or create a new one if there isn't one or it isn't at
|
||||||
|
// the top of the page.
|
||||||
|
var html = document.documentElement
|
||||||
|
var headTags = document.getElementsByTagName("head");
|
||||||
|
var head = headTags.length > 0 ? head = headTags[0] : null;
|
||||||
|
if(!head || head !== html.firstChild) {
|
||||||
|
head = document.createElement('head');
|
||||||
|
html.insertBefore(head, html.firstChild);
|
||||||
|
pageScript.id = "_RubberGlove_removeHead";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen for callbacks from the page script
|
||||||
|
window.addEventListener("message", function(event) {
|
||||||
|
if(event.source != window) return;
|
||||||
|
if(event.data.type && event.data.type == "RubberGlove") {
|
||||||
|
// Tell background.js to increment the badge counter
|
||||||
|
chrome.runtime.sendMessage({
|
||||||
|
type: "increment-counter",
|
||||||
|
url: window.location.href,
|
||||||
|
message: event.data.text
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Insert our script into the page. Note: This absolutely cannot under
|
||||||
|
// any circumstances happen in an async callback otherwise scripts on the
|
||||||
|
// page may run first and have access to the unwrapped objects.
|
||||||
|
// Synchronous XHR requests before this seem to work fine, however.
|
||||||
|
head.insertBefore(pageScript, head.firstChild);
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
function persistConfig(fileName, data, callback) {
|
||||||
|
console.log("RubberGlove: Requesting quota");
|
||||||
|
navigator.webkitTemporaryStorage.requestQuota(1024*1024, function(grantedBytes) {
|
||||||
|
console.log("RubberGlove: Granted quota of " + grantedBytes);
|
||||||
|
window.webkitRequestFileSystem(TEMPORARY, grantedBytes, function(fs) {
|
||||||
|
console.log("RubberGlove: Got FileSystem");
|
||||||
|
fs.root.getFile(fileName, {create: true}, function(fileEntry) {
|
||||||
|
console.log("RubberGlove: Got file " + fileEntry.name);
|
||||||
|
fileEntry.createWriter(function(fileWriter) {
|
||||||
|
console.log("RubberGlove: Got writer");
|
||||||
|
fileWriter.onwriteend=function(e) {
|
||||||
|
console.log("RubberGlove: onWriteEnd");
|
||||||
|
fileWriter.onwriteend=null;
|
||||||
|
var blob = new Blob([JSON.stringify(data)], {type: 'application/json'});
|
||||||
|
fileWriter.write(blob);
|
||||||
|
}
|
||||||
|
fileWriter.truncate(0);
|
||||||
|
});
|
||||||
|
}, fsErrorHandler);
|
||||||
|
}, fsErrorHandler);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function fsErrorHandler(e) {
|
||||||
|
console.error(e.name + ": " + e.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getConfigAsync(fileName, callback) {
|
||||||
|
window.webkitStorageInfo.requestQuota(PERSISTENT, 1024*1024, function(grantedBytes) {
|
||||||
|
window.webkitRequestFileSystem(PERSISTENT, grantedBytes, function(fs) {
|
||||||
|
fs.root.getFile(fileName, {create: false}, function(fileEntry) {
|
||||||
|
// TODO: Finish writing this!
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
function sanitizeVersions(version) {
|
||||||
|
return version.replace(/(\b(?:[0-9]+\.?)+\b)/g, function(match) {
|
||||||
|
var version = match.split('.');
|
||||||
|
var foundMajor = false;
|
||||||
|
for(var i=0; i < version.length; i++) {
|
||||||
|
var number = parseInt(version[i]);
|
||||||
|
if(number > 0) {
|
||||||
|
if(foundMajor) version[i] = 0;
|
||||||
|
else foundMajor = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return version.join(".");
|
||||||
|
});
|
||||||
|
}
|
||||||
+4
-1
@@ -31,7 +31,10 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"background": {
|
"background": {
|
||||||
"scripts": ["js/background.js"],
|
"scripts": [
|
||||||
|
"js/settings.js",
|
||||||
|
"js/background.js"
|
||||||
|
],
|
||||||
"persistent": true
|
"persistent": true
|
||||||
},
|
},
|
||||||
"browser_action": {
|
"browser_action": {
|
||||||
|
|||||||
Reference in New Issue
Block a user