update gulp file to build the content_scripts/dist/* code, to make the injected code easier to edit

This commit is contained in:
Peter Snyder 2017-10-13 02:32:41 -05:00
parent 7adf5b0753
commit 71f35f9446
12 changed files with 78 additions and 176 deletions

2
.gitignore vendored
View file

@ -1,3 +1,5 @@
node_modules/
.DS_Store
*.swp
content_scripts/dist/*.js

View file

@ -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);
}());

View file

@ -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
View file

@ -0,0 +1,2 @@
This directory contains script files that are build from gulp, and which are
injected into visited frames / pages.

View 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);
}());

View file

@ -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

View file

@ -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);
}());

View file

@ -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);
});
});

View file

@ -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
}
}
}