update gulp file to build the content_scripts/dist/* code, to make the injected code easier to edit
This commit is contained in:
parent
7adf5b0753
commit
71f35f9446
12 changed files with 78 additions and 176 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,3 +1,5 @@
|
||||||
node_modules/
|
node_modules/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*.swp
|
*.swp
|
||||||
|
|
||||||
|
content_scripts/dist/*.js
|
5
background_scripts/bootstrap.js
vendored
5
background_scripts/bootstrap.js
vendored
|
@ -2,9 +2,8 @@
|
||||||
/*global chrome*/
|
/*global chrome*/
|
||||||
(function () {
|
(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
let onMsgHandler;
|
|
||||||
|
|
||||||
onMsgHandler = function (request, ignore, sendResponse) {
|
const onMsgHandler = function (request, ignore, sendResponse) {
|
||||||
|
|
||||||
let requestingDoman = request.domain;
|
let requestingDoman = request.domain;
|
||||||
|
|
||||||
|
@ -19,7 +18,5 @@
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
chrome.runtime.peteStuff = "P";
|
|
||||||
|
|
||||||
chrome.runtime.onMessage.addListener(onMsgHandler);
|
chrome.runtime.onMessage.addListener(onMsgHandler);
|
||||||
}());
|
}());
|
|
@ -24,9 +24,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<script src="../content_scripts/init.js"></script>
|
<script src="../content_scripts/dist/init.js"></script>
|
||||||
<script src="../content_scripts/defaults.js"></script>
|
<script src="../content_scripts/dist/defaults.js"></script>
|
||||||
<script src="../content_scripts/standards.js"></script>
|
<script src="../content_scripts/dist/standards.js"></script>
|
||||||
<script src="js/storage.js"></script>
|
<script src="js/storage.js"></script>
|
||||||
<script src="js/lib/vue.js"></script>
|
<script src="js/lib/vue.js"></script>
|
||||||
<script src="js/state.js"></script>
|
<script src="js/state.js"></script>
|
||||||
|
|
2
content_scripts/dist/README.md
vendored
Normal file
2
content_scripts/dist/README.md
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
This directory contains script files that are build from gulp, and which are
|
||||||
|
injected into visited frames / pages.
|
21
content_scripts/src/instrument.js
Normal file
21
content_scripts/src/instrument.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/*jslint es6: true, browser: true*/
|
||||||
|
/*global chrome, window*/
|
||||||
|
// This script file runs in the context of the extension, and mainly
|
||||||
|
// exists to inject the proxy blocking code into content frames.
|
||||||
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
let script = document.createElement('script');
|
||||||
|
let rootElm = document.head || document.documentElement;
|
||||||
|
let code = `
|
||||||
|
window.WEB_API_MANAGER_PAGE = {
|
||||||
|
standards: ${JSON.stringify(window.WEB_API_MANAGER.standards)},
|
||||||
|
toBlock: ${JSON.stringify(window.WEB_API_MANAGER.defaults)},
|
||||||
|
shouldLog: true
|
||||||
|
};
|
||||||
|
###-INJECTED-PROXY-BLOCKING-CODE-###
|
||||||
|
`;
|
||||||
|
|
||||||
|
script.appendChild(document.createTextNode(code));
|
||||||
|
rootElm.appendChild(script);
|
||||||
|
}());
|
|
@ -1,5 +1,8 @@
|
||||||
/*jslint es6: true, browser: true*/
|
/*jslint es6: true, browser: true*/
|
||||||
/*global window*/
|
/*global window*/
|
||||||
|
// The contents of this file are programatically injected into all frames.
|
||||||
|
// It is compiled into the src/instrument.js file to create the
|
||||||
|
// dist/instrument.js script/
|
||||||
(function () {
|
(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,155 +0,0 @@
|
||||||
/*jslint es6: true, browser: true*/
|
|
||||||
/*global chrome, window*/
|
|
||||||
(function () {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
let script = document.createElement('script');
|
|
||||||
let rootElm = document.head || document.documentElement;
|
|
||||||
let code = `
|
|
||||||
window.WEB_API_MANAGER_PAGE = {
|
|
||||||
standards: ${JSON.stringify(window.WEB_API_MANAGER.standards)},
|
|
||||||
toBlock: ${JSON.stringify(window.WEB_API_MANAGER.defaults)},
|
|
||||||
shouldLog: true
|
|
||||||
};
|
|
||||||
/*jslint es6: true, browser: true*/
|
|
||||||
/*global window*/
|
|
||||||
(function () {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const settings = window.WEB_API_MANAGER_PAGE;
|
|
||||||
const shouldLog = settings.shouldLog;
|
|
||||||
const standardsToBlock = settings.toBlock;
|
|
||||||
const standardDefinitions = settings.standards;
|
|
||||||
|
|
||||||
const defaultFunction = function () {};
|
|
||||||
const funcPropNames = Object.getOwnPropertyNames(defaultFunction);
|
|
||||||
const unconfigurablePropNames = funcPropNames.filter(function (propName) {
|
|
||||||
const possiblePropDesc = Object.getOwnPropertyDescriptor(defaultFunction, propName);
|
|
||||||
return (possiblePropDesc && !possiblePropDesc.configurable);
|
|
||||||
});
|
|
||||||
|
|
||||||
const featuresToBlock = standardsToBlock.reduce(function (prev, cur) {
|
|
||||||
return prev.concat(standardDefinitions[cur].features);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const toPrimitiveFunc = function (hint) {
|
|
||||||
if (hint === "number" || hint === "default") {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (hint === "string") {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
const keyPathToRefPath = function (keyPath) {
|
|
||||||
const keyParts = keyPath.split(".");
|
|
||||||
return keyParts.reduce(function (prev, cur) {
|
|
||||||
|
|
||||||
if (prev === undefined) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const numNodes = prev.length;
|
|
||||||
const currentLeaf = (numNodes === 0)
|
|
||||||
? window
|
|
||||||
: prev[numNodes - 1];
|
|
||||||
const nextLeaf = currentLeaf[cur];
|
|
||||||
|
|
||||||
if (nextLeaf === undefined) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return prev.concat([nextLeaf]);
|
|
||||||
}, []);
|
|
||||||
};
|
|
||||||
|
|
||||||
const createBlockingProxy = function (keyPath) {
|
|
||||||
|
|
||||||
let hasBeenLogged = false;
|
|
||||||
|
|
||||||
const logKeyPath = function () {
|
|
||||||
if (keyPath !== undefined && hasBeenLogged === false) {
|
|
||||||
hasBeenLogged = true;
|
|
||||||
console.info(keyPath);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let blockingProxy;
|
|
||||||
blockingProxy = new Proxy(defaultFunction, {
|
|
||||||
get: function (ignore, property) {
|
|
||||||
logKeyPath();
|
|
||||||
|
|
||||||
if (property === Symbol.toPrimitive) {
|
|
||||||
return toPrimitiveFunc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (property === "valueOf") {
|
|
||||||
return toPrimitiveFunc;
|
|
||||||
}
|
|
||||||
|
|
||||||
return blockingProxy;
|
|
||||||
},
|
|
||||||
set: function () {
|
|
||||||
logKeyPath();
|
|
||||||
return blockingProxy;
|
|
||||||
},
|
|
||||||
apply: function () {
|
|
||||||
logKeyPath();
|
|
||||||
return blockingProxy;
|
|
||||||
},
|
|
||||||
ownKeys: function (ignore) {
|
|
||||||
return unconfigurablePropNames;
|
|
||||||
},
|
|
||||||
has: function (ignore, property) {
|
|
||||||
return (unconfigurablePropNames.indexOf(property) > -1);
|
|
||||||
},
|
|
||||||
getOwnPropertyDescriptor: function (ignore, property) {
|
|
||||||
if (unconfigurablePropNames.indexOf(property) === -1) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
return Object.getOwnPropertyDescriptor(defaultFunction, property);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return blockingProxy;
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultBlockingProxy = createBlockingProxy();
|
|
||||||
|
|
||||||
const blockFeatureAtKeyPath = function (keyPath) {
|
|
||||||
const propertyRefs = keyPathToRefPath(keyPath);
|
|
||||||
|
|
||||||
// If we weren't able to turn the key path into an array of references,
|
|
||||||
// then it means that the property doesn't exist in this DOM /
|
|
||||||
// environment, so there is nothing to block.
|
|
||||||
if (propertyRefs === undefined) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const keyPathSegments = keyPath.split(".");
|
|
||||||
const lastPropertyName = keyPathSegments[keyPathSegments.length - 1];
|
|
||||||
const leafRef = propertyRefs[propertyRefs.length - 1];
|
|
||||||
const parentRef = propertyRefs[propertyRefs.length - 2];
|
|
||||||
|
|
||||||
// At least for now, only interpose on methods.
|
|
||||||
if (typeof leafRef !== "function") {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldLog === true) {
|
|
||||||
parentRef[lastPropertyName] = createBlockingProxy(keyPath);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
parentRef[lastPropertyName] = defaultBlockingProxy;
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
featuresToBlock.forEach(blockFeatureAtKeyPath);
|
|
||||||
}());
|
|
||||||
`;
|
|
||||||
|
|
||||||
script.appendChild(document.createTextNode(code));
|
|
||||||
rootElm.appendChild(script);
|
|
||||||
}());
|
|
49
gulpfile.js
49
gulpfile.js
|
@ -1,25 +1,58 @@
|
||||||
let gulp = require('gulp');
|
const gulp = require('gulp');
|
||||||
let fs = require('fs');
|
const fs = require('fs');
|
||||||
|
|
||||||
gulp.task('default', function () {
|
gulp.task('default', function () {
|
||||||
|
|
||||||
let standardsDefDir = "data/standards";
|
const standardsDefDir = "data/standards";
|
||||||
|
|
||||||
// Build all the standards listings into a single features.js file.
|
// Build all the standards listings into a single features.js file.
|
||||||
let combinedStandards = fs.readdirSync(standardsDefDir)
|
const combinedStandards = fs.readdirSync(standardsDefDir)
|
||||||
.reduce(function (prev, next) {
|
.reduce(function (prev, next) {
|
||||||
|
|
||||||
if (next.indexOf(".json") === -1) {
|
if (next.indexOf(".json") === -1) {
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
let fileContents = fs.readFileSync(standardsDefDir + "/" + next, {encoding: "utf8"});
|
const fileContents = fs.readFileSync(standardsDefDir + "/" + next, {encoding: "utf8"});
|
||||||
let standardContents = JSON.parse(fileContents);
|
const standardContents = JSON.parse(fileContents);
|
||||||
prev[standardContents.info.name] = standardContents;
|
prev[standardContents.info.name] = standardContents;
|
||||||
return prev;
|
return prev;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
let renderedStandardsModule = "window.WEB_API_MANAGER.standards = " + JSON.stringify(combinedStandards) + ";";
|
let renderedStandardsModule = "/** This file is automatically generated by gulp. **/\n";
|
||||||
|
renderedStandardsModule += `window.WEB_API_MANAGER.standards = ${JSON.stringify(combinedStandards)};`;
|
||||||
|
|
||||||
fs.writeFileSync("content_scripts/standards.js", renderedStandardsModule);
|
fs.writeFileSync("content_scripts/dist/standards.js", renderedStandardsModule);
|
||||||
|
|
||||||
|
const proxyBlockSrc = fs.readFileSync("content_scripts/src/proxyblock.js", "utf8");
|
||||||
|
const instrumentSrc = fs.readFileSync("content_scripts/src/instrument.js", "utf8");
|
||||||
|
|
||||||
|
const stripCommentsFromSource = function (source) {
|
||||||
|
const fileLines = source.split("\n");
|
||||||
|
const linesWithoutComments = fileLines.filter(function (aLine) {
|
||||||
|
const lineStartsWithComment = (
|
||||||
|
aLine.indexOf("// ") === 0 ||
|
||||||
|
aLine.indexOf("/*") === 0 ||
|
||||||
|
aLine.indexOf(" * ") === 0
|
||||||
|
);
|
||||||
|
return !lineStartsWithComment;
|
||||||
|
});
|
||||||
|
return linesWithoutComments.join("\n");
|
||||||
|
};
|
||||||
|
|
||||||
|
const proxyBlockSrcWOComments = stripCommentsFromSource(proxyBlockSrc);
|
||||||
|
const instrumentSrcWOComments = stripCommentsFromSource(instrumentSrc);
|
||||||
|
const instrumentSrcWithProxyInjected = instrumentSrcWOComments.replace(
|
||||||
|
"###-INJECTED-PROXY-BLOCKING-CODE-###",
|
||||||
|
proxyBlockSrcWOComments
|
||||||
|
);
|
||||||
|
|
||||||
|
fs.writeFileSync("content_scripts/dist/instrument.js", instrumentSrcWithProxyInjected);
|
||||||
|
|
||||||
|
// Last, several content script files are just copied over, unmodified,
|
||||||
|
// as script files to be injected.
|
||||||
|
const srcFilesToCopy = ["defaults.js", "init.js"];
|
||||||
|
srcFilesToCopy.forEach(function (aSrcPath) {
|
||||||
|
fs.copyFileSync("content_scripts/src/" + aSrcPath, "content_scripts/dist/" + aSrcPath);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,10 +11,10 @@
|
||||||
{
|
{
|
||||||
"matches": ["*://*/*"],
|
"matches": ["*://*/*"],
|
||||||
"js": [
|
"js": [
|
||||||
"content_scripts/init.js",
|
"content_scripts/dist/init.js",
|
||||||
"content_scripts/standards.js",
|
"content_scripts/dist/standards.js",
|
||||||
"content_scripts/defaults.js",
|
"content_scripts/dist/defaults.js",
|
||||||
"content_scripts/stub.js"
|
"content_scripts/dist/instrument.js"
|
||||||
],
|
],
|
||||||
"all_frames": true,
|
"all_frames": true,
|
||||||
"run_at": "document_start"
|
"run_at": "document_start"
|
||||||
|
|
Loading…
Reference in a new issue