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/
|
||||
.DS_Store
|
||||
*.swp
|
||||
|
||||
content_scripts/dist/*.js
|
5
background_scripts/bootstrap.js
vendored
5
background_scripts/bootstrap.js
vendored
|
@ -2,9 +2,8 @@
|
|||
/*global chrome*/
|
||||
(function () {
|
||||
"use strict";
|
||||
let onMsgHandler;
|
||||
|
||||
onMsgHandler = function (request, ignore, sendResponse) {
|
||||
const onMsgHandler = function (request, ignore, sendResponse) {
|
||||
|
||||
let requestingDoman = request.domain;
|
||||
|
||||
|
@ -19,7 +18,5 @@
|
|||
return false;
|
||||
};
|
||||
|
||||
chrome.runtime.peteStuff = "P";
|
||||
|
||||
chrome.runtime.onMessage.addListener(onMsgHandler);
|
||||
}());
|
|
@ -24,9 +24,9 @@
|
|||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<script src="../content_scripts/init.js"></script>
|
||||
<script src="../content_scripts/defaults.js"></script>
|
||||
<script src="../content_scripts/standards.js"></script>
|
||||
<script src="../content_scripts/dist/init.js"></script>
|
||||
<script src="../content_scripts/dist/defaults.js"></script>
|
||||
<script src="../content_scripts/dist/standards.js"></script>
|
||||
<script src="js/storage.js"></script>
|
||||
<script src="js/lib/vue.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*/
|
||||
/*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 () {
|
||||
"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');
|
||||
let fs = require('fs');
|
||||
const gulp = require('gulp');
|
||||
const fs = require('fs');
|
||||
|
||||
gulp.task('default', function () {
|
||||
|
||||
let standardsDefDir = "data/standards";
|
||||
const standardsDefDir = "data/standards";
|
||||
|
||||
// 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) {
|
||||
|
||||
if (next.indexOf(".json") === -1) {
|
||||
return prev;
|
||||
}
|
||||
|
||||
let fileContents = fs.readFileSync(standardsDefDir + "/" + next, {encoding: "utf8"});
|
||||
let standardContents = JSON.parse(fileContents);
|
||||
const fileContents = fs.readFileSync(standardsDefDir + "/" + next, {encoding: "utf8"});
|
||||
const standardContents = JSON.parse(fileContents);
|
||||
prev[standardContents.info.name] = standardContents;
|
||||
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": ["*://*/*"],
|
||||
"js": [
|
||||
"content_scripts/init.js",
|
||||
"content_scripts/standards.js",
|
||||
"content_scripts/defaults.js",
|
||||
"content_scripts/stub.js"
|
||||
"content_scripts/dist/init.js",
|
||||
"content_scripts/dist/standards.js",
|
||||
"content_scripts/dist/defaults.js",
|
||||
"content_scripts/dist/instrument.js"
|
||||
],
|
||||
"all_frames": true,
|
||||
"run_at": "document_start"
|
||||
|
@ -29,4 +29,4 @@
|
|||
"page": "config/index.html",
|
||||
"chrome_style": true
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue