From 71f35f94465309e3b3f7ccdb611c4fd390740e16 Mon Sep 17 00:00:00 2001 From: Peter Snyder Date: Fri, 13 Oct 2017 02:32:41 -0500 Subject: [PATCH] update gulp file to build the content_scripts/dist/* code, to make the injected code easier to edit --- .gitignore | 2 + background_scripts/bootstrap.js | 5 +- config/index.html | 6 +- content_scripts/dist/README.md | 2 + content_scripts/{ => src}/defaults.js | 0 content_scripts/{ => src}/init.js | 0 content_scripts/src/instrument.js | 21 +++ .../{injected.js => src/proxyblock.js} | 3 + content_scripts/standards.js | 1 - content_scripts/stub.js | 155 ------------------ gulpfile.js | 49 +++++- manifest.json | 10 +- 12 files changed, 78 insertions(+), 176 deletions(-) create mode 100644 content_scripts/dist/README.md rename content_scripts/{ => src}/defaults.js (100%) rename content_scripts/{ => src}/init.js (100%) create mode 100644 content_scripts/src/instrument.js rename content_scripts/{injected.js => src/proxyblock.js} (96%) delete mode 100644 content_scripts/standards.js delete mode 100644 content_scripts/stub.js diff --git a/.gitignore b/.gitignore index 3216262..5205c64 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ node_modules/ .DS_Store *.swp + +content_scripts/dist/*.js \ No newline at end of file diff --git a/background_scripts/bootstrap.js b/background_scripts/bootstrap.js index 727057d..5b9364d 100644 --- a/background_scripts/bootstrap.js +++ b/background_scripts/bootstrap.js @@ -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); }()); \ No newline at end of file diff --git a/config/index.html b/config/index.html index c2b8fb7..4c8553f 100644 --- a/config/index.html +++ b/config/index.html @@ -24,9 +24,9 @@ - - - + + + diff --git a/content_scripts/dist/README.md b/content_scripts/dist/README.md new file mode 100644 index 0000000..fea22e3 --- /dev/null +++ b/content_scripts/dist/README.md @@ -0,0 +1,2 @@ +This directory contains script files that are build from gulp, and which are +injected into visited frames / pages. \ No newline at end of file diff --git a/content_scripts/defaults.js b/content_scripts/src/defaults.js similarity index 100% rename from content_scripts/defaults.js rename to content_scripts/src/defaults.js diff --git a/content_scripts/init.js b/content_scripts/src/init.js similarity index 100% rename from content_scripts/init.js rename to content_scripts/src/init.js diff --git a/content_scripts/src/instrument.js b/content_scripts/src/instrument.js new file mode 100644 index 0000000..26b905c --- /dev/null +++ b/content_scripts/src/instrument.js @@ -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); +}()); \ No newline at end of file diff --git a/content_scripts/injected.js b/content_scripts/src/proxyblock.js similarity index 96% rename from content_scripts/injected.js rename to content_scripts/src/proxyblock.js index 79cef0c..8f18fe0 100644 --- a/content_scripts/injected.js +++ b/content_scripts/src/proxyblock.js @@ -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"; diff --git a/content_scripts/standards.js b/content_scripts/standards.js deleted file mode 100644 index f80e37e..0000000 --- a/content_scripts/standards.js +++ /dev/null @@ -1 +0,0 @@ -window.WEB_API_MANAGER.standards = {"XMLHttpRequest":{"info":{"name":"XMLHttpRequest","subsection_number":null,"subsection_name":null,"url":"https://xhr.spec.whatwg.org/"},"features":["FormData.prototype.append","FormData.prototype.delete","FormData.prototype.get","FormData.prototype.getAll","FormData.prototype.has","FormData.prototype.set","XMLHttpRequest.prototype.abort","XMLHttpRequest.prototype.getAllResponseHeaders","XMLHttpRequest.prototype.getResponseHeader","XMLHttpRequest.prototype.open","XMLHttpRequest.prototype.overrideMimeType","XMLHttpRequest.prototype.send","XMLHttpRequest.prototype.setRequestHeader"]},"Ambient Light Sensor API":{"info":{"name":"Ambient Light Sensor API","subsection_number":null,"subsection_name":null,"url":"https://w3c.github.io/ambient-light/"},"features":["window.ondevicelight"]},"Battery Status API":{"info":{"name":"Battery Status API","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/battery-status/"},"features":["navigator.battery","Navigator.prototype.getBattery"]},"Beacon":{"info":{"name":"Beacon","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/beacon/"},"features":["Navigator.prototype.sendBeacon"]},"Console API":{"info":{"name":"Console API","subsection_number":null,"subsection_name":null,"url":"https://github.com/DeveloperToolsWG/console-object"},"features":["Console.prototype.assert","Console.prototype.clear","Console.prototype.count","Console.prototype.debug","Console.prototype.dir","Console.prototype.dirxml","Console.prototype.error","Console.prototype.group","Console.prototype.groupCollapsed","Console.prototype.groupEnd","Console.prototype.info","Console.prototype.log","Console.prototype.markTimeline","Console.prototype.profile","Console.prototype.profileEnd","Console.prototype.table","Console.prototype.time","Console.prototype.timeEnd","Console.prototype.timeline","Console.prototype.timelineEnd","Console.prototype.timeStamp","Console.prototype.trace","Console.prototype.warn"]},"CSS Conditional Rules Module Level 3":{"info":{"name":"CSS Conditional Rules Module Level 3","subsection_number":null,"subsection_name":null,"url":"https://drafts.csswg.org/css-conditional-3/"},"features":["CSS.supports"]},"CSS Font Loading Module Level 3":{"info":{"name":"CSS Font Loading Module Level 3","subsection_number":null,"subsection_name":null,"url":"https://drafts.csswg.org/css-font-loading/"},"features":["document.fonts","FontFace.prototype.load","FontFaceSet.prototype.add","FontFaceSet.prototype.check","FontFaceSet.prototype.clear","FontFaceSet.prototype.delete","FontFaceSet.prototype.entries","FontFaceSet.prototype.forEach","FontFaceSet.prototype.has","FontFaceSet.prototype.keys","FontFaceSet.prototype.load","FontFaceSet.prototype.values"]},"CSS Object Model (CSSOM)":{"info":{"name":"CSS Object Model (CSSOM)","subsection_number":null,"subsection_name":null,"url":"https://drafts.csswg.org/cssom/"},"features":["CSS.escape","Document.prototype.caretPositionFromPoint","Document.prototype.elementFromPoint","Element.prototype.getBoundingClientRect","Element.prototype.getClientRects","Element.prototype.scroll","Element.prototype.scrollBy","Element.prototype.scrollIntoView","Element.prototype.scrollTo","MediaList.prototype.appendMedium","MediaList.prototype.deleteMedium","MediaList.prototype.item","MediaQueryList.prototype.addListener","MediaQueryList.prototype.removeListener","StyleSheetList.prototype.item"]},"CSSOM View Module":{"info":{"name":"CSSOM View Module","subsection_number":null,"subsection_name":null,"url":"https://drafts.csswg.org/cssom-view/"},"features":["CaretPosition.prototype.getClientRect","screen.availHeight","screen.availWidth","screen.colorDepth","screen.height","screen.left","screen.pixelDepth","screen.width","window.devicePixelRatio","window.innerHeight","window.innerWidth","window.matchMedia","window.moveBy","window.moveTo","window.outerHeight","window.outerWidth","window.pageXOffset","window.pageYOffset","window.resizeBy","window.resizeTo","window.screen","window.screenX","window.screenY","window.scroll","window.scrollBy","window.scrollTo","window.scrollX","window.scrollY"]},"DeviceOrientation Event Specification":{"info":{"name":"DeviceOrientation Event Specification","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/orientation-event/"},"features":["DeviceMotionEvent.prototype.initDeviceMotionEvent","DeviceOrientationEvent.prototype.initDeviceOrientationEvent"]},"DOM Parsing and Serialization":{"info":{"name":"DOM Parsing and Serialization","subsection_number":null,"subsection_name":null,"url":"https://w3c.github.io/DOM-Parsing/"},"features":["DOMParser.prototype.parseFromString","Element.prototype.insertAdjacentHTML","XMLSerializer.prototype.serializeToString"]},"DOM":{"info":{"name":"DOM","subsection_number":null,"subsection_name":null,"url":"https://dom.spec.whatwg.org/"},"features":["CharacterData.prototype.appendData","CharacterData.prototype.deleteData","CharacterData.prototype.insertData","CharacterData.prototype.remove","CharacterData.prototype.replaceData","CharacterData.prototype.substringData","CustomEvent.prototype.initCustomEvent","document.characterSet","document.childElementCount","document.children","document.close","document.compatMode","document.contentType","document.firstElementChild","document.inputEncoding","document.lastElementChild","Document.prototype.createAttribute","Document.prototype.createElement","Document.prototype.createProcessingInstruction","Document.prototype.getElementsByClassName","document.scripts","DocumentFragment.prototype.getElementById","DocumentType.prototype.remove","DOMImplementation.prototype.createHTMLDocument","DOMTokenList.prototype.add","DOMTokenList.prototype.contains","DOMTokenList.prototype.item","DOMTokenList.prototype.remove","DOMTokenList.prototype.toggle","Element.prototype.closest","Element.prototype.getElementsByClassName","Element.prototype.matches","Element.prototype.mozMatchesSelector","Element.prototype.remove","window.clearInterval","window.clearTimeout"]},"Document Object Model (DOM) Level 1 Specification":{"info":{"name":"Document Object Model (DOM) Level 1 Specification","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/REC-DOM-Level-1/"},"features":["Document.prototype.getElementById","Document.prototype.getElementsByTagName","Element.prototype.getAttribute","Element.prototype.getAttributeNode","Element.prototype.getElementsByTagName","Element.prototype.removeAttribute","Element.prototype.removeAttributeNode","Element.prototype.setAttribute","Element.prototype.setAttributeNode","HTMLCollection.prototype.item","HTMLCollection.prototype.namedItem","HTMLDocument.prototype.close","HTMLDocument.prototype.open","HTMLDocument.prototype.write","HTMLDocument.prototype.writeln","HTMLElement.prototype.click","HTMLElement.prototype.focus","HTMLFormElement.prototype.reset","HTMLFormElement.prototype.submit","HTMLInputElement.prototype.select","HTMLSelectElement.prototype.add","HTMLSelectElement.prototype.item","HTMLSelectElement.prototype.namedItem","HTMLSelectElement.prototype.remove","HTMLTableElement.prototype.createCaption","HTMLTableElement.prototype.createTBody","HTMLTableElement.prototype.createTFoot","HTMLTableElement.prototype.createTHead","HTMLTableElement.prototype.deleteCaption","HTMLTableElement.prototype.deleteRow","HTMLTableElement.prototype.deleteTFoot","HTMLTableElement.prototype.deleteTHead","HTMLTableElement.prototype.insertRow","HTMLTableRowElement.prototype.deleteCell","HTMLTableRowElement.prototype.insertCell","HTMLTableSectionElement.prototype.deleteRow","HTMLTableSectionElement.prototype.insertRow","HTMLTextAreaElement.prototype.select","Node.prototype.appendChild","Node.prototype.cloneNode","Node.prototype.hasChildNodes","Node.prototype.insertBefore","Node.prototype.normalize","Node.prototype.removeChild","Node.prototype.replaceChild","NodeList.prototype.item","Text.prototype.splitText"]},"Document Object Model (DOM) Level 2 Core Specification":{"info":{"name":"Document Object Model (DOM) Level 2 Core Specification","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/DOM-Level-2-Core/"},"features":["document.doctype","document.documentElement","document.domain","document.implementation","Document.prototype.createAttributeNS","Document.prototype.createCDATASection","Document.prototype.createComment","Document.prototype.createDocumentFragment","Document.prototype.createElementNS","Document.prototype.createTextNode","Document.prototype.getElementsByTagNameNS","Document.prototype.importNode","DOMImplementation.prototype.createDocument","DOMImplementation.prototype.createDocumentType","DOMImplementation.prototype.hasFeature","Element.prototype.getAttributeNodeNS","Element.prototype.getAttributeNS","Element.prototype.getElementsByTagNameNS","Element.prototype.hasAttribute","Element.prototype.hasAttributeNS","Element.prototype.hasAttributes","Element.prototype.removeAttributeNS","Element.prototype.setAttributeNodeNS","Element.prototype.setAttributeNS","NamedNodeMap.prototype.getNamedItem","NamedNodeMap.prototype.getNamedItemNS","NamedNodeMap.prototype.item","NamedNodeMap.prototype.removeNamedItem","NamedNodeMap.prototype.removeNamedItemNS","NamedNodeMap.prototype.setNamedItem","NamedNodeMap.prototype.setNamedItemNS"]},"Document Object Model (DOM) Level 2 Events Specification":{"info":{"name":"Document Object Model (DOM) Level 2 Events Specification","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/DOM-Level-2-Events/"},"features":["Document.prototype.createEvent","Event.prototype.initEvent","Event.prototype.preventDefault","Event.prototype.stopPropagation","EventTarget.prototype.addEventListener","EventTarget.prototype.dispatchEvent","EventTarget.prototype.removeEventListener"]},"Document Object Model (DOM) Level 2 HTML Specification":{"info":{"name":"Document Object Model (DOM) Level 2 HTML Specification","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/DOM-Level-2-HTML/"},"features":["document.cookie","document.forms","document.getElementsByName","document.open","document.referrer","document.title","document.URL","document.write","document.writeln","HTMLDocument.prototype.getElementsByName","HTMLElement.prototype.blur"]},"Document Object Model (DOM) Level 2 Style Specification":{"info":{"name":"Document Object Model (DOM) Level 2 Style Specification","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/DOM-Level-2-Style/"},"features":["CSSPrimitiveValue.prototype.getCounterValue","CSSPrimitiveValue.prototype.getFloatValue","CSSPrimitiveValue.prototype.getRectValue","CSSPrimitiveValue.prototype.getRGBColorValue","CSSPrimitiveValue.prototype.getStringValue","CSSPrimitiveValue.prototype.setFloatValue","CSSPrimitiveValue.prototype.setStringValue","CSSRuleList.prototype.item","CSSStyleDeclaration.prototype.getPropertyCSSValue","CSSStyleDeclaration.prototype.getPropertyPriority","CSSStyleDeclaration.prototype.getPropertyValue","CSSStyleDeclaration.prototype.item","CSSStyleDeclaration.prototype.removeProperty","CSSStyleDeclaration.prototype.setProperty","CSSStyleSheet.prototype.deleteRule","CSSStyleSheet.prototype.insertRule","CSSValueList.prototype.item","document.styleSheets","window.getComputedStyle"]},"Document Object Model (DOM) Level 2 Traversal and Range Specification":{"info":{"name":"Document Object Model (DOM) Level 2 Traversal and Range Specification","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/DOM-Level-2-Traversal-Range/"},"features":["Document.prototype.createNodeIterator","Document.prototype.createRange","Document.prototype.createTreeWalker","NodeIterator.prototype.detach","NodeIterator.prototype.nextNode","NodeIterator.prototype.previousNode","Range.prototype.cloneContents","Range.prototype.cloneRange","Range.prototype.collapse","Range.prototype.compareBoundaryPoints","Range.prototype.comparePoint","Range.prototype.createContextualFragment","Range.prototype.deleteContents","Range.prototype.detach","Range.prototype.extractContents","Range.prototype.getBoundingClientRect","Range.prototype.getClientRects","Range.prototype.insertNode","Range.prototype.intersectsNode","Range.prototype.isPointInRange","Range.prototype.selectNode","Range.prototype.selectNodeContents","Range.prototype.setEnd","Range.prototype.setEndAfter","Range.prototype.setEndBefore","Range.prototype.setStart","Range.prototype.setStartAfter","Range.prototype.setStartBefore","Range.prototype.surroundContents","TreeWalker.prototype.firstChild","TreeWalker.prototype.lastChild","TreeWalker.prototype.nextNode","TreeWalker.prototype.nextSibling","TreeWalker.prototype.parentNode","TreeWalker.prototype.previousNode","TreeWalker.prototype.previousSibling"]},"Document Object Model (DOM) Level 3 Core Specification":{"info":{"name":"Document Object Model (DOM) Level 3 Core Specification","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/DOM-Level-3-Core/"},"features":["document.documentURI","Document.prototype.adoptNode","DOMStringList.prototype.contains","DOMStringList.prototype.item","Node.prototype.compareDocumentPosition","Node.prototype.contains","Node.prototype.isDefaultNamespace","Node.prototype.isEqualNode","Node.prototype.lookupNamespaceURI","Node.prototype.lookupPrefix"]},"Document Object Model (DOM) Level 3 XPath Specification":{"info":{"name":"Document Object Model (DOM) Level 3 XPath Specification","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/DOM-Level-3-XPath/"},"features":["Document.prototype.createExpression","Document.prototype.createNSResolver","Document.prototype.evaluate","XPathEvaluator.prototype.createExpression","XPathEvaluator.prototype.createNSResolver","XPathEvaluator.prototype.evaluate","XPathExpression.prototype.evaluate","XPathResult.prototype.iterateNext","XPathResult.prototype.snapshotItem"]},"W3C DOM4":{"info":{"name":"W3C DOM4","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/dom/"},"features":["MutationObserver.prototype.disconnect","MutationObserver.prototype.observe","MutationObserver.prototype.takeRecords"]},"Directory Upload":{"info":{"name":"Directory Upload","subsection_number":null,"subsection_name":null,"url":"https://wicg.github.io/directory-upload/proposal.html"},"features":["Directory.prototype.getFilesAndDirectories"]},"Encoding":{"info":{"name":"Encoding","subsection_number":null,"subsection_name":null,"url":"https://encoding.spec.whatwg.org/"},"features":["TextDecoder.prototype.decode","TextEncoder.prototype.encode"]},"execCommand":{"info":{"name":"execCommand","subsection_number":null,"subsection_name":null,"url":"https://w3c.github.io/editing/execCommand.html"},"features":["document.execCommand","document.queryCommandEnabled","document.queryCommandIndeterm","document.queryCommandState","document.queryCommandSupported","document.queryCommandValue","HTMLDocument.prototype.execCommand","HTMLDocument.prototype.queryCommandEnabled","HTMLDocument.prototype.queryCommandIndeterm","HTMLDocument.prototype.queryCommandState","HTMLDocument.prototype.queryCommandSupported","HTMLDocument.prototype.queryCommandValue"]},"Encrypted Media Extensions":{"info":{"name":"Encrypted Media Extensions","subsection_number":null,"subsection_name":null,"url":"https://w3c.github.io/encrypted-media/"},"features":["MediaKeys.prototype.createSession","MediaKeys.prototype.setServerCertificate","MediaKeySession.prototype.close","MediaKeySession.prototype.generateRequest","MediaKeySession.prototype.load","MediaKeySession.prototype.remove","MediaKeySession.prototype.update","MediaKeyStatusMap.prototype.entries","MediaKeyStatusMap.prototype.keys","MediaKeyStatusMap.prototype.values","MediaKeySystemAccess.prototype.createMediaKeys","MediaKeySystemAccess.prototype.getConfiguration","Navigator.prototype.requestMediaKeySystemAccess"]},"Fetch":{"info":{"name":"Fetch","subsection_number":null,"subsection_name":null,"url":"https://fetch.spec.whatwg.org/"},"features":["Headers.prototype.append","Headers.prototype.delete","Headers.prototype.get","Headers.prototype.getAll","Headers.prototype.has","Headers.prototype.set","Request.prototype.arrayBuffer","Request.prototype.blob","Request.prototype.clone","Request.prototype.formData","Request.prototype.json","Request.prototype.text","Response.error","Response.prototype.arrayBuffer","Response.prototype.blob","Response.prototype.clone","Response.prototype.formData","Response.prototype.json","Response.prototype.text","Response.redirect","window.fetch"]},"File API":{"info":{"name":"File API","subsection_number":null,"subsection_name":null,"url":"https://w3c.github.io/FileAPI/"},"features":["Blob.prototype.slice","FileList.prototype.item","FileReader.prototype.abort","FileReader.prototype.readAsArrayBuffer","FileReader.prototype.readAsBinaryString","FileReader.prototype.readAsDataURL","FileReader.prototype.readAsText","URL.createObjectURL","URL.revokeObjectURL"]},"Fullscreen API":{"info":{"name":"Fullscreen API","subsection_number":null,"subsection_name":null,"url":"https://fullscreen.spec.whatwg.org/"},"features":["document.mozFullScreen","document.mozFullScreenElement","document.mozFullScreenEnabled","document.onmozfullscreenchange","document.onmozfullscreenerror","Document.prototype.mozCancelFullScreen","Element.prototype.mozRequestFullScreen","window.onmozfullscreenchange","window.onmozfullscreenerror"]},"Geolocation API Specification":{"info":{"name":"Geolocation API Specification","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/geolocation-API/"},"features":["navigator.geolocation","navigator.geolocation.getCurrentPosition","navigator.geolocation.watchPosition","navigator.geolocation.clearWatch"]},"Geometry Interfaces Module Level 1":{"info":{"name":"Geometry Interfaces Module Level 1","subsection_number":null,"subsection_name":null,"url":"https://drafts.fxtf.org/geometry/"},"features":["DOMMatrix.prototype.invertSelf","DOMMatrix.prototype.multiplySelf","DOMMatrix.prototype.preMultiplySelf","DOMMatrix.prototype.rotateAxisAngleSelf","DOMMatrix.prototype.rotateFromVectorSelf","DOMMatrix.prototype.rotateSelf","DOMMatrix.prototype.scale3dSelf","DOMMatrix.prototype.scaleNonUniformSelf","DOMMatrix.prototype.scaleSelf","DOMMatrix.prototype.setMatrixValue","DOMMatrix.prototype.skewXSelf","DOMMatrix.prototype.skewYSelf","DOMMatrix.prototype.translateSelf","DOMMatrixReadOnly.prototype.flipX","DOMMatrixReadOnly.prototype.flipY","DOMMatrixReadOnly.prototype.inverse","DOMMatrixReadOnly.prototype.multiply","DOMMatrixReadOnly.prototype.rotate","DOMMatrixReadOnly.prototype.rotateAxisAngle","DOMMatrixReadOnly.prototype.rotateFromVector","DOMMatrixReadOnly.prototype.scale","DOMMatrixReadOnly.prototype.scale3d","DOMMatrixReadOnly.prototype.scaleNonUniform","DOMMatrixReadOnly.prototype.skewX","DOMMatrixReadOnly.prototype.skewY","DOMMatrixReadOnly.prototype.toFloat32Array","DOMMatrixReadOnly.prototype.toFloat64Array","DOMMatrixReadOnly.prototype.transformPoint","DOMMatrixReadOnly.prototype.translate","DOMRectList.prototype.item"]},"Gamepad":{"info":{"name":"Gamepad","subsection_number":null,"subsection_name":null,"url":"https://w3c.github.io/gamepad/"},"features":["Navigator.prototype.getGamepads"]},"HTML":{"info":{"name":"HTML","subsection_number":null,"subsection_name":null,"url":"https://html.spec.whatwg.org"},"features":["DataTransfer.prototype.addElement","DataTransfer.prototype.clearData","DataTransfer.prototype.getData","DataTransfer.prototype.mozClearDataAt","DataTransfer.prototype.mozGetDataAt","DataTransfer.prototype.mozSetDataAt","DataTransfer.prototype.mozTypesAt","DataTransfer.prototype.setData","DataTransfer.prototype.setDragImage","document.activeElement","document.body","document.currentScript","document.designMode","document.dir","document.getItems","document.head","document.images","document.lastModified","document.lastStyleSheetSet","document.links","document.onabort","document.onblur","document.oncanplay","document.oncanplaythrough","document.onchange","document.onclick","document.oncontextmenu","document.oncopy","document.oncut","document.ondblclick","document.ondrag","document.ondragend","document.ondragenter","document.ondragleave","document.ondragover","document.ondragstart","document.ondrop","document.ondurationchange","document.onemptied","document.onended","document.onerror","document.onfocus","document.oninput","document.oninvalid","document.onkeydown","document.onkeypress","document.onkeyup","document.onload","document.onloadeddata","document.onloadedmetadata","document.onloadstart","document.onmousedown","document.onmouseenter","document.onmouseleave","document.onmousemove","document.onmouseout","document.onmouseover","document.onmouseup","document.onpaste","document.onpause","document.onplay","document.onplaying","document.onprogress","document.onratechange","document.onreadystatechange","document.onreset","document.onresize","document.onscroll","document.onseeked","document.onseeking","document.onselect","document.onshow","document.onstalled","document.onsubmit","document.onsuspend","document.ontimeupdate","document.onvolumechange","document.onwaiting","document.onwheel","Document.prototype.enableStyleSheetsForSet","Document.prototype.hasFocus","document.selectedStyleSheetSet","document.styleSheetSets","EventSource.prototype.close","HashChangeEvent.prototype.initHashChangeEvent","HTMLAllCollection.prototype.item","HTMLAllCollection.prototype.namedItem","HTMLDocument.prototype.clear","HTMLDocument.prototype.getItems","navigator.appCodeName","navigator.appName","navigator.appVersion","navigator.cookieEnabled","navigator.onLine","navigator.platform","navigator.product","navigator.productSub","Navigator.prototype.registerContentHandler","Navigator.prototype.registerProtocolHandler","navigator.userAgent","navigator.vendor","navigator.vendorSub","PropertyNodeList.prototype.getValues","TimeRanges.prototype.end","TimeRanges.prototype.start","window.blur","window.close","window.closed","window.console","window.createImageBitmap","window.document","window.focus","window.frameElement","window.frames","window.length","window.location","window.name","window.navigator","window.onabort","window.onafterprint","window.onbeforeprint","window.onbeforeunload","window.onblur","window.oncanplay","window.oncanplaythrough","window.onchange","window.onclick","window.oncontextmenu","window.ondblclick","window.ondrag","window.ondragend","window.ondragenter","window.ondragleave","window.ondragover","window.ondragstart","window.ondurationchange","window.onemptied","window.onended","window.onerror","window.onfocus","window.onhashchange","window.oninput","window.oninvalid","window.onkeydown","window.onkeypress","window.onkeyup","window.onlanguagechange","window.onloadeddata","window.onloadedmetadata","window.onloadstart","window.onmessage","window.onmousedown","window.onmouseenter","window.onmouseleave","window.onmousemove","window.onmouseout","window.onmouseover","window.onmouseup","window.onoffline","window.ononline","window.onpagehide","window.onpageshow","window.onpause","window.onplay","window.onplaying","window.onpopstate","window.onprogress","window.onratechange","window.onreset","window.onresize","window.onscroll","window.onseeked","window.onseeking","window.onselect","window.onshow","window.onstalled","window.onsubmit","window.onsuspend","window.ontimeupdate","window.onunload","window.onvolumechange","window.onwaiting","window.onwheel","window.open","window.opener","window.parent","window.self","window.setInterval","window.setResizable","window.setTimeout","window.showModalDialog","window.stop","window.top","window.window","XMLDocument.prototype.load"]},"High Resolution Time Level 2":{"info":{"name":"High Resolution Time Level 2","subsection_number":null,"subsection_name":null,"url":"https://w3c.github.io/hr-time/"},"features":["Performance.prototype.now"]},"HTML 5":{"info":{"name":"HTML 5","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/html5/"},"features":["document.defaultView","document.location","document.onafterscriptexecute","document.onbeforescriptexecute","document.preferredStyleSheetSet","document.readyState","HTMLButtonElement.prototype.checkValidity","HTMLButtonElement.prototype.setCustomValidity","HTMLFieldSetElement.prototype.checkValidity","HTMLFieldSetElement.prototype.setCustomValidity","HTMLFormControlsCollection.prototype.item","HTMLFormElement.prototype.checkValidity","HTMLInputElement.prototype.checkValidity","HTMLInputElement.prototype.setCustomValidity","HTMLInputElement.prototype.setRangeText","HTMLInputElement.prototype.setSelectionRange","HTMLInputElement.prototype.stepDown","HTMLInputElement.prototype.stepUp","HTMLMediaElement.prototype.addTextTrack","HTMLMediaElement.prototype.canPlayType","HTMLMediaElement.prototype.fastSeek","HTMLMediaElement.prototype.load","HTMLMediaElement.prototype.mozCaptureStream","HTMLMediaElement.prototype.mozCaptureStreamUntilEnded","HTMLMediaElement.prototype.mozGetMetadata","HTMLMediaElement.prototype.pause","HTMLMediaElement.prototype.play","HTMLMediaElement.prototype.setMediaKeys","HTMLObjectElement.prototype.checkValidity","HTMLObjectElement.prototype.setCustomValidity","HTMLOptionsCollection.prototype.add","HTMLOptionsCollection.prototype.remove","HTMLOutputElement.prototype.checkValidity","HTMLOutputElement.prototype.setCustomValidity","HTMLSelectElement.prototype.checkValidity","HTMLSelectElement.prototype.setCustomValidity","HTMLTextAreaElement.prototype.checkValidity","HTMLTextAreaElement.prototype.setCustomValidity","HTMLTextAreaElement.prototype.setRangeText","HTMLTextAreaElement.prototype.setSelectionRange","location.assign","location.reload","location.replace","OfflineResourceList.prototype.mozAdd","OfflineResourceList.prototype.mozHasItem","OfflineResourceList.prototype.mozItem","OfflineResourceList.prototype.mozRemove","OfflineResourceList.prototype.swapCache","OfflineResourceList.prototype.update","TextTrack.prototype.addCue","TextTrack.prototype.removeCue","TextTrackCueList.prototype.getCueById","TextTrackList.prototype.getTrackById","TimeEvent.prototype.initTimeEvent","window.alert","window.applicationCache","window.atob","window.btoa","window.confirm","window.locationbar","window.menubar","window.personalbar","window.print","window.prompt","window.scrollbars","window.status","window.statusbar","window.toolbar","location.href"]},"HTML 5.1":{"info":{"name":"HTML 5.1","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/html51/"},"features":["DragEvent.prototype.initDragEvent","External.prototype.addSearchEngine","External.prototype.AddSearchProvider","External.prototype.IsSearchProviderInstalled","navigator.language","navigator.languages"]},"Indexed Database API":{"info":{"name":"Indexed Database API","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/IndexedDB/"},"features":["IDBCursor.prototype.advance","IDBCursor.prototype.continue","IDBCursor.prototype.delete","IDBCursor.prototype.update","IDBDatabase.prototype.close","IDBDatabase.prototype.createMutableFile","IDBDatabase.prototype.createObjectStore","IDBDatabase.prototype.deleteObjectStore","IDBDatabase.prototype.mozCreateFileHandle","IDBDatabase.prototype.transaction","IDBFactory.prototype.cmp","IDBFactory.prototype.deleteDatabase","IDBFactory.prototype.open","IDBFileHandle.prototype.abort","IDBFileHandle.prototype.append","IDBFileHandle.prototype.flush","IDBFileHandle.prototype.getMetadata","IDBFileHandle.prototype.readAsArrayBuffer","IDBFileHandle.prototype.readAsText","IDBFileHandle.prototype.truncate","IDBFileHandle.prototype.write","IDBIndex.prototype.count","IDBIndex.prototype.get","IDBIndex.prototype.getKey","IDBIndex.prototype.mozGetAll","IDBIndex.prototype.mozGetAllKeys","IDBIndex.prototype.openCursor","IDBIndex.prototype.openKeyCursor","IDBKeyRange.bound","IDBKeyRange.lowerBound","IDBKeyRange.only","IDBKeyRange.upperBound","IDBMutableFile.prototype.getFile","IDBMutableFile.prototype.open","IDBObjectStore.prototype.add","IDBObjectStore.prototype.clear","IDBObjectStore.prototype.count","IDBObjectStore.prototype.createIndex","IDBObjectStore.prototype.delete","IDBObjectStore.prototype.deleteIndex","IDBObjectStore.prototype.get","IDBObjectStore.prototype.index","IDBObjectStore.prototype.mozGetAll","IDBObjectStore.prototype.openCursor","IDBObjectStore.prototype.put","IDBTransaction.prototype.abort","IDBTransaction.prototype.objectStore","window.indexedDB"]},"Media Capture from DOM Elements":{"info":{"name":"Media Capture from DOM Elements","subsection_number":null,"subsection_name":null,"url":"https://w3c.github.io/mediacapture-fromelement/"},"features":["CanvasCaptureMediaStream.prototype.requestFrame","HTMLCanvasElement.prototype.captureStream"]},"Media Capture and Streams":{"info":{"name":"Media Capture and Streams","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/mediacapture-streams/"},"features":["LocalMediaStream.prototype.stop","MediaDevices.prototype.enumerateDevices","MediaDevices.prototype.getUserMedia","navigator.mediaDevices"]},"Media Source Extensions":{"info":{"name":"Media Source Extensions","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/media-source/"},"features":["HTMLVideoElement.prototype.getVideoPlaybackQuality","MediaSource.isTypeSupported","MediaSource.prototype.addSourceBuffer","MediaSource.prototype.endOfStream","MediaSource.prototype.removeSourceBuffer","SourceBuffer.prototype.abort","SourceBuffer.prototype.appendBuffer","SourceBuffer.prototype.remove"]},"MediaStream Recording":{"info":{"name":"MediaStream Recording","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/mediastream-recording/"},"features":["MediaRecorder.prototype.pause","MediaRecorder.prototype.requestData","MediaRecorder.prototype.resume","MediaRecorder.prototype.start","MediaRecorder.prototype.stop","MediaStream.prototype.getAudioTracks","MediaStream.prototype.getTracks","MediaStream.prototype.getVideoTracks","MediaStreamTrack.prototype.applyConstraints","MediaStreamTrack.prototype.stop"]},"Non-Standard":{"info":{"name":"Non-Standard","subsection_number":null,"subsection_name":null,"url":null},"features":["AnonymousContent.prototype.getAttributeForElement","AnonymousContent.prototype.getTextContentForElement","AnonymousContent.prototype.removeAttributeForElement","AnonymousContent.prototype.setAttributeForElement","AnonymousContent.prototype.setTextContentForElement","CommandEvent.prototype.initCommandEvent","document.embeds","Document.prototype.mozSetImageElement","Document.prototype.releaseCapture","DOMCursor.prototype.continue","DOMRequest.prototype.then","Element.prototype.releaseCapture","Element.prototype.setCapture","Event.prototype.getPreventDefault","HTMLDocument.prototype.captureEvents","HTMLDocument.prototype.releaseEvents","HTMLInputElement.prototype.mozIsTextField","HTMLPropertiesCollection.prototype.item","HTMLPropertiesCollection.prototype.namedItem","window.captureEvents","MouseEvent.prototype.initNSMouseEvent","MouseScrollEvent.prototype.initMouseScrollEvent","mozContact.prototype.init","MozPowerManager.prototype.addWakeLockListener","MozPowerManager.prototype.factoryReset","MozPowerManager.prototype.getWakeLockState","MozPowerManager.prototype.powerOff","MozPowerManager.prototype.reboot","MozPowerManager.prototype.removeWakeLockListener","navigator.buildID","navigator.oscpu","Navigator.prototype.javaEnabled","PaintRequestList.prototype.item","screen.availLeft","screen.availTop","screen.top","ScrollAreaEvent.prototype.initScrollAreaEvent","SimpleGestureEvent.prototype.initSimpleGestureEvent","window.content","window.controllers","window.dump","window.external","window.find","window.fullScreen","window.getDefaultComputedStyle","window.mozInnerScreenX","window.mozInnerScreenY","window.mozPaintCount","window.ondrop","window.releaseEvents","window.scrollByLines","window.scrollByPages","window.scrollMaxX","window.scrollMaxY","window.sidebar","window.sizeToContent","window.updateCommands","XSLTProcessor.prototype.clearParameters","XSLTProcessor.prototype.getParameter","XSLTProcessor.prototype.importStylesheet","XSLTProcessor.prototype.removeParameter","XSLTProcessor.prototype.reset","XSLTProcessor.prototype.setParameter","XSLTProcessor.prototype.transformToDocument","XSLTProcessor.prototype.transformToFragment"]},"Navigation Timing":{"info":{"name":"Navigation Timing","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/navigation-timing/"},"features":["performance.navigation","performance.navigation.redirectCount","performance.navigation.type","performance.timing","performance.timing.connectEnd","performance.timing.connectStart","performance.timing.domainLookupEnd","performance.timing.domainLookupStart","performance.timing.domComplete","performance.timing.domContentLoadedEventEnd","performance.timing.domContentLoadedEventStart","performance.timing.domInteractive","performance.timing.domLoading","performance.timing.fetchStart","performance.timing.loadEventEnd","performance.timing.loadEventStart","performance.timing.navigationStart","performance.timing.redirectEnd","performance.timing.redirectStart","performance.timing.requestStart","performance.timing.responseEnd","performance.timing.responseStart","performance.timing.unloadEventEnd","performance.timing.unloadEventStart","window.performance"]},"Proximity Events":{"info":{"name":"Proximity Events","subsection_number":null,"subsection_name":null,"url":"https://w3c.github.io/proximity/"},"features":["window.ondeviceproximity","window.onuserproximity"]},"Pointer Lock":{"info":{"name":"Pointer Lock","subsection_number":null,"subsection_name":null,"url":"https://w3c.github.io/pointerlock/"},"features":["document.mozPointerLockElement","document.onmozpointerlockchange","document.onmozpointerlockerror","Document.prototype.mozExitPointerLock","Element.prototype.mozRequestPointerLock","window.onmozpointerlockchange","window.onmozpointerlockerror"]},"Performance Timeline":{"info":{"name":"Performance Timeline","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/performance-timeline"},"features":["Performance.prototype.getEntriesByName","Performance.prototype.getEntriesByType"]},"Performance Timeline Level 2":{"info":{"name":"Performance Timeline Level 2","subsection_number":null,"subsection_name":null,"url":"https://w3c.github.io/performance-timeline"},"features":["Performance.prototype.getEntries"]},"Page Visibility (Second Edition)":{"info":{"name":"Page Visibility (Second Edition)","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/page-visibility/"},"features":["document.hidden","document.mozHidden","document.mozVisibilityState","document.visibilityState"]},"Resource Timing":{"info":{"name":"Resource Timing","subsection_number":null,"subsection_name":null,"url":"https://w3c.github.io/resource-timing/"},"features":["performance.onresourcetimingbufferfull","Performance.prototype.clearResourceTimings","Performance.prototype.setResourceTimingBufferSize"]},"Shadow DOM":{"info":{"name":"Shadow DOM","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/shadow-dom/"},"features":["HTMLContentElement.prototype.getDistributedNodes"]},"Selection API":{"info":{"name":"Selection API","subsection_number":null,"subsection_name":null,"url":"http://w3c.github.io/selection-api/"},"features":["HTMLDocument.prototype.getSelection","Selection.prototype.addRange","Selection.prototype.collapse","Selection.prototype.collapseToEnd","Selection.prototype.collapseToStart","Selection.prototype.containsNode","Selection.prototype.deleteFromDocument","Selection.prototype.extend","Selection.prototype.getRangeAt","Selection.prototype.modify","Selection.prototype.removeAllRanges","Selection.prototype.removeRange","Selection.prototype.selectAllChildren","window.getSelection"]},"Selectors API Level 1":{"info":{"name":"Selectors API Level 1","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/selectors-api"},"features":["Document.prototype.querySelector","Document.prototype.querySelectorAll","DocumentFragment.prototype.querySelector","DocumentFragment.prototype.querySelectorAll","Element.prototype.querySelector","Element.prototype.querySelectorAll"]},"The Screen Orientation API":{"info":{"name":"The Screen Orientation API","subsection_number":null,"subsection_name":null,"url":"https://w3c.github.io/screen-orientation/"},"features":["screen.mozOrientation","screen.onmozorientationchange","screen.orientation","Screen.prototype.mozLockOrientation","Screen.prototype.mozUnlockOrientation","ScreenOrientation.prototype.lock","ScreenOrientation.prototype.unlock","window.ondevicemotion","window.ondeviceorientation"]},"Scalable Vector Graphics (SVG) 1.1 (Second Edition)":{"info":{"name":"Scalable Vector Graphics (SVG) 1.1 (Second Edition)","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/SVG/"},"features":["HTMLEmbedElement.prototype.getSVGDocument","HTMLIFrameElement.prototype.getSVGDocument","HTMLObjectElement.prototype.getSVGDocument","SVGAngle.prototype.convertToSpecifiedUnits","SVGAngle.prototype.newValueSpecifiedUnits","SVGAnimationElement.prototype.beginElement","SVGAnimationElement.prototype.beginElementAt","SVGAnimationElement.prototype.endElement","SVGAnimationElement.prototype.endElementAt","SVGAnimationElement.prototype.getCurrentTime","SVGAnimationElement.prototype.getSimpleDuration","SVGAnimationElement.prototype.getStartTime","SVGAnimationElement.prototype.hasExtension","SVGFEDropShadowElement.prototype.setStdDeviation","SVGFEGaussianBlurElement.prototype.setStdDeviation","SVGFilterElement.apply","SVGGraphicsElement.prototype.getBBox","SVGGraphicsElement.prototype.getCTM","SVGGraphicsElement.prototype.getScreenCTM","SVGGraphicsElement.prototype.getTransformToElement","SVGGraphicsElement.prototype.hasExtension","SVGLength.prototype.convertToSpecifiedUnits","SVGLength.prototype.newValueSpecifiedUnits","SVGLengthList.prototype.appendItem","SVGLengthList.prototype.clear","SVGLengthList.prototype.getItem","SVGLengthList.prototype.initialize","SVGLengthList.prototype.insertItemBefore","SVGLengthList.prototype.removeItem","SVGLengthList.prototype.replaceItem","SVGMarkerElement.prototype.setOrientToAngle","SVGMarkerElement.prototype.setOrientToAuto","SVGMatrix.prototype.flipX","SVGMatrix.prototype.flipY","SVGMatrix.prototype.inverse","SVGMatrix.prototype.multiply","SVGMatrix.prototype.rotate","SVGMatrix.prototype.rotateFromVector","SVGMatrix.prototype.scale","SVGMatrix.prototype.scaleNonUniform","SVGMatrix.prototype.skewX","SVGMatrix.prototype.skewY","SVGMatrix.prototype.translate","SVGNumberList.prototype.appendItem","SVGNumberList.prototype.clear","SVGNumberList.prototype.getItem","SVGNumberList.prototype.initialize","SVGNumberList.prototype.insertItemBefore","SVGNumberList.prototype.removeItem","SVGNumberList.prototype.replaceItem","SVGPathElement.prototype.createSVGPathSegArcAbs","SVGPathElement.prototype.createSVGPathSegArcRel","SVGPathElement.prototype.createSVGPathSegClosePath","SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs","SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel","SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs","SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel","SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs","SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel","SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs","SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel","SVGPathElement.prototype.createSVGPathSegLinetoAbs","SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs","SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel","SVGPathElement.prototype.createSVGPathSegLinetoRel","SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs","SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel","SVGPathElement.prototype.createSVGPathSegMovetoAbs","SVGPathElement.prototype.createSVGPathSegMovetoRel","SVGPathElement.prototype.getPathSegAtLength","SVGPathElement.prototype.getPointAtLength","SVGPathElement.prototype.getTotalLength","SVGPathSegList.prototype.appendItem","SVGPathSegList.prototype.clear","SVGPathSegList.prototype.getItem","SVGPathSegList.prototype.initialize","SVGPathSegList.prototype.insertItemBefore","SVGPathSegList.prototype.removeItem","SVGPathSegList.prototype.replaceItem","SVGPoint.prototype.matrixTransform","SVGPointList.prototype.appendItem","SVGPointList.prototype.clear","SVGPointList.prototype.getItem","SVGPointList.prototype.initialize","SVGPointList.prototype.insertItemBefore","SVGPointList.prototype.removeItem","SVGPointList.prototype.replaceItem","SVGStringList.prototype.appendItem","SVGStringList.prototype.clear","SVGStringList.prototype.getItem","SVGStringList.prototype.initialize","SVGStringList.prototype.insertItemBefore","SVGStringList.prototype.removeItem","SVGStringList.prototype.replaceItem","SVGSVGElement.prototype.animationsPaused","SVGSVGElement.prototype.createSVGAngle","SVGSVGElement.prototype.createSVGLength","SVGSVGElement.prototype.createSVGMatrix","SVGSVGElement.prototype.createSVGNumber","SVGSVGElement.prototype.createSVGPoint","SVGSVGElement.prototype.createSVGRect","SVGSVGElement.prototype.createSVGTransform","SVGSVGElement.prototype.createSVGTransformFromMatrix","SVGSVGElement.prototype.deselectAll","SVGSVGElement.prototype.forceRedraw","SVGSVGElement.prototype.getCurrentTime","SVGSVGElement.prototype.getElementById","SVGSVGElement.prototype.pauseAnimations","SVGSVGElement.prototype.setCurrentTime","SVGSVGElement.prototype.suspendRedraw","SVGSVGElement.prototype.unpauseAnimations","SVGSVGElement.prototype.unsuspendRedraw","SVGSVGElement.prototype.unsuspendRedrawAll","SVGSymbolElement.prototype.hasExtension","SVGTextContentElement.prototype.getCharNumAtPosition","SVGTextContentElement.prototype.getComputedTextLength","SVGTextContentElement.prototype.getEndPositionOfChar","SVGTextContentElement.prototype.getExtentOfChar","SVGTextContentElement.prototype.getNumberOfChars","SVGTextContentElement.prototype.getRotationOfChar","SVGTextContentElement.prototype.getStartPositionOfChar","SVGTextContentElement.prototype.getSubStringLength","SVGTextContentElement.prototype.selectSubString","SVGTransform.prototype.setMatrix","SVGTransform.prototype.setRotate","SVGTransform.prototype.setScale","SVGTransform.prototype.setSkewX","SVGTransform.prototype.setSkewY","SVGTransform.prototype.setTranslate","SVGTransformList.prototype.appendItem","SVGTransformList.prototype.clear","SVGTransformList.prototype.consolidate","SVGTransformList.prototype.createSVGTransformFromMatrix","SVGTransformList.prototype.getItem","SVGTransformList.prototype.initialize","SVGTransformList.prototype.insertItemBefore","SVGTransformList.prototype.removeItem","SVGTransformList.prototype.replaceItem"]},"Service Workers":{"info":{"name":"Service Workers","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/service-workers/"},"features":["Cache.prototype.add","Cache.prototype.addAll","Cache.prototype.delete","Cache.prototype.keys","Cache.prototype.match","Cache.prototype.matchAll","Cache.prototype.put","CacheStorage.prototype.delete","CacheStorage.prototype.has","CacheStorage.prototype.keys","CacheStorage.prototype.match","CacheStorage.prototype.open","window.caches"]},"Timing control for script-based animations":{"info":{"name":"Timing control for script-based animations","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/animation-timing"},"features":["window.cancelAnimationFrame"]},"Tracking Preference Expression (DNT)":{"info":{"name":"Tracking Preference Expression (DNT)","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/tracking-dnt/"},"features":["navigator.doNotTrack"]},"UI Events Specification":{"info":{"name":"UI Events Specification","subsection_number":null,"subsection_name":null,"url":"https://w3c.github.io/uievents/"},"features":["CompositionEvent.prototype.initCompositionEvent","Event.prototype.stopImmediatePropagation","KeyboardEvent.prototype.getModifierState","KeyboardEvent.prototype.initKeyEvent","MouseEvent.prototype.getModifierState","MouseEvent.prototype.initMouseEvent","MutationEvent.prototype.initMutationEvent","UIEvent.prototype.initUIEvent"]},"URL":{"info":{"name":"URL","subsection_number":null,"subsection_name":null,"url":"https://url.spec.whatwg.org/"},"features":["URLSearchParams.prototype.append","URLSearchParams.prototype.delete","URLSearchParams.prototype.get","URLSearchParams.prototype.getAll","URLSearchParams.prototype.has","URLSearchParams.prototype.set"]},"User Timing Level 2":{"info":{"name":"User Timing Level 2","subsection_number":null,"subsection_name":null,"url":"https://w3c.github.io/user-timing/"},"features":["Performance.prototype.clearMarks","Performance.prototype.clearMeasures","Performance.prototype.mark","Performance.prototype.measure"]},"Vibration API":{"info":{"name":"Vibration API","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/vibration/"},"features":["Navigator.prototype.vibrate"]},"Web Cryptography API":{"info":{"name":"Web Cryptography API","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/WebCryptoAPI/"},"features":["Crypto.prototype.getRandomValues","SubtleCrypto.prototype.decrypt","SubtleCrypto.prototype.deriveBits","SubtleCrypto.prototype.deriveKey","SubtleCrypto.prototype.digest","SubtleCrypto.prototype.encrypt","SubtleCrypto.prototype.exportKey","SubtleCrypto.prototype.generateKey","SubtleCrypto.prototype.importKey","SubtleCrypto.prototype.sign","SubtleCrypto.prototype.unwrapKey","SubtleCrypto.prototype.verify","SubtleCrypto.prototype.wrapKey","window.crypto"]},"Web Audio API":{"info":{"name":"Web Audio API","subsection_number":null,"subsection_name":null,"url":"https://webaudio.github.io/web-audio-api"},"features":["AnalyserNode.prototype.getByteFrequencyData","AnalyserNode.prototype.getByteTimeDomainData","AnalyserNode.prototype.getFloatFrequencyData","AnalyserNode.prototype.getFloatTimeDomainData","AudioBuffer.prototype.copyFromChannel","AudioBuffer.prototype.copyToChannel","AudioBuffer.prototype.getChannelData","AudioBufferSourceNode.prototype.start","AudioBufferSourceNode.prototype.stop","AudioContext.prototype.close","AudioContext.prototype.createAnalyser","AudioContext.prototype.createBiquadFilter","AudioContext.prototype.createBuffer","AudioContext.prototype.createBufferSource","AudioContext.prototype.createChannelMerger","AudioContext.prototype.createChannelSplitter","AudioContext.prototype.createConvolver","AudioContext.prototype.createDelay","AudioContext.prototype.createDynamicsCompressor","AudioContext.prototype.createGain","AudioContext.prototype.createMediaElementSource","AudioContext.prototype.createMediaStreamDestination","AudioContext.prototype.createMediaStreamSource","AudioContext.prototype.createOscillator","AudioContext.prototype.createPanner","AudioContext.prototype.createPeriodicWave","AudioContext.prototype.createScriptProcessor","AudioContext.prototype.createStereoPanner","AudioContext.prototype.createWaveShaper","AudioContext.prototype.decodeAudioData","AudioContext.prototype.resume","AudioContext.prototype.suspend","AudioListener.prototype.setOrientation","AudioListener.prototype.setPosition","AudioListener.prototype.setVelocity","AudioNode.prototype.connect","AudioNode.prototype.disconnect","AudioParam.prototype.cancelScheduledValues","AudioParam.prototype.exponentialRampToValueAtTime","AudioParam.prototype.linearRampToValueAtTime","AudioParam.prototype.setValueAtTime","AudioParam.prototype.setValueCurveAtTime","BiquadFilterNode.prototype.getFrequencyResponse","OfflineAudioContext.prototype.resume","OfflineAudioContext.prototype.startRendering","OfflineAudioContext.prototype.suspend","OscillatorNode.prototype.setPeriodicWave","OscillatorNode.prototype.start","OscillatorNode.prototype.stop","PannerNode.prototype.setOrientation","PannerNode.prototype.setPosition","PannerNode.prototype.setVelocity"]},"WebGL Specification":{"info":{"name":"WebGL Specification","subsection_number":null,"subsection_name":null,"url":"https://www.khronos.org/registry/webgl/specs/latest/1.0/"},"features":["WebGLRenderingContext.prototype.activeTexture","WebGLRenderingContext.prototype.attachShader","WebGLRenderingContext.prototype.bindAttribLocation","WebGLRenderingContext.prototype.bindBuffer","WebGLRenderingContext.prototype.bindFramebuffer","WebGLRenderingContext.prototype.bindRenderbuffer","WebGLRenderingContext.prototype.bindTexture","WebGLRenderingContext.prototype.blendColor","WebGLRenderingContext.prototype.blendEquation","WebGLRenderingContext.prototype.blendEquationSeparate","WebGLRenderingContext.prototype.blendFunc","WebGLRenderingContext.prototype.blendFuncSeparate","WebGLRenderingContext.prototype.bufferData","WebGLRenderingContext.prototype.bufferSubData","WebGLRenderingContext.prototype.checkFramebufferStatus","WebGLRenderingContext.prototype.clear","WebGLRenderingContext.prototype.clearColor","WebGLRenderingContext.prototype.clearDepth","WebGLRenderingContext.prototype.clearStencil","WebGLRenderingContext.prototype.colorMask","WebGLRenderingContext.prototype.compileShader","WebGLRenderingContext.prototype.compressedTexImage2D","WebGLRenderingContext.prototype.compressedTexSubImage2D","WebGLRenderingContext.prototype.copyTexImage2D","WebGLRenderingContext.prototype.copyTexSubImage2D","WebGLRenderingContext.prototype.createBuffer","WebGLRenderingContext.prototype.createFramebuffer","WebGLRenderingContext.prototype.createProgram","WebGLRenderingContext.prototype.createRenderbuffer","WebGLRenderingContext.prototype.createShader","WebGLRenderingContext.prototype.createTexture","WebGLRenderingContext.prototype.cullFace","WebGLRenderingContext.prototype.deleteBuffer","WebGLRenderingContext.prototype.deleteFramebuffer","WebGLRenderingContext.prototype.deleteProgram","WebGLRenderingContext.prototype.deleteRenderbuffer","WebGLRenderingContext.prototype.deleteShader","WebGLRenderingContext.prototype.deleteTexture","WebGLRenderingContext.prototype.depthFunc","WebGLRenderingContext.prototype.depthMask","WebGLRenderingContext.prototype.depthRange","WebGLRenderingContext.prototype.detachShader","WebGLRenderingContext.prototype.disable","WebGLRenderingContext.prototype.disableVertexAttribArray","WebGLRenderingContext.prototype.drawArrays","WebGLRenderingContext.prototype.drawElements","WebGLRenderingContext.prototype.enable","WebGLRenderingContext.prototype.enableVertexAttribArray","WebGLRenderingContext.prototype.finish","WebGLRenderingContext.prototype.flush","WebGLRenderingContext.prototype.framebufferRenderbuffer","WebGLRenderingContext.prototype.framebufferTexture2D","WebGLRenderingContext.prototype.frontFace","WebGLRenderingContext.prototype.generateMipmap","WebGLRenderingContext.prototype.getActiveAttrib","WebGLRenderingContext.prototype.getActiveUniform","WebGLRenderingContext.prototype.getAttachedShaders","WebGLRenderingContext.prototype.getAttribLocation","WebGLRenderingContext.prototype.getBufferParameter","WebGLRenderingContext.prototype.getContextAttributes","WebGLRenderingContext.prototype.getError","WebGLRenderingContext.prototype.getExtension","WebGLRenderingContext.prototype.getFramebufferAttachmentParameter","WebGLRenderingContext.prototype.getParameter","WebGLRenderingContext.prototype.getProgramInfoLog","WebGLRenderingContext.prototype.getProgramParameter","WebGLRenderingContext.prototype.getRenderbufferParameter","WebGLRenderingContext.prototype.getShaderInfoLog","WebGLRenderingContext.prototype.getShaderParameter","WebGLRenderingContext.prototype.getShaderPrecisionFormat","WebGLRenderingContext.prototype.getShaderSource","WebGLRenderingContext.prototype.getSupportedExtensions","WebGLRenderingContext.prototype.getTexParameter","WebGLRenderingContext.prototype.getUniform","WebGLRenderingContext.prototype.getUniformLocation","WebGLRenderingContext.prototype.getVertexAttrib","WebGLRenderingContext.prototype.getVertexAttribOffset","WebGLRenderingContext.prototype.hint","WebGLRenderingContext.prototype.isBuffer","WebGLRenderingContext.prototype.isContextLost","WebGLRenderingContext.prototype.isEnabled","WebGLRenderingContext.prototype.isFramebuffer","WebGLRenderingContext.prototype.isProgram","WebGLRenderingContext.prototype.isRenderbuffer","WebGLRenderingContext.prototype.isShader","WebGLRenderingContext.prototype.isTexture","WebGLRenderingContext.prototype.lineWidth","WebGLRenderingContext.prototype.linkProgram","WebGLRenderingContext.prototype.pixelStorei","WebGLRenderingContext.prototype.polygonOffset","WebGLRenderingContext.prototype.readPixels","WebGLRenderingContext.prototype.renderbufferStorage","WebGLRenderingContext.prototype.sampleCoverage","WebGLRenderingContext.prototype.scissor","WebGLRenderingContext.prototype.shaderSource","WebGLRenderingContext.prototype.stencilFunc","WebGLRenderingContext.prototype.stencilFuncSeparate","WebGLRenderingContext.prototype.stencilMask","WebGLRenderingContext.prototype.stencilMaskSeparate","WebGLRenderingContext.prototype.stencilOp","WebGLRenderingContext.prototype.stencilOpSeparate","WebGLRenderingContext.prototype.texImage2D","WebGLRenderingContext.prototype.texParameterf","WebGLRenderingContext.prototype.texParameteri","WebGLRenderingContext.prototype.texSubImage2D","WebGLRenderingContext.prototype.uniform1f","WebGLRenderingContext.prototype.uniform1fv","WebGLRenderingContext.prototype.uniform1i","WebGLRenderingContext.prototype.uniform1iv","WebGLRenderingContext.prototype.uniform2f","WebGLRenderingContext.prototype.uniform2fv","WebGLRenderingContext.prototype.uniform2i","WebGLRenderingContext.prototype.uniform2iv","WebGLRenderingContext.prototype.uniform3f","WebGLRenderingContext.prototype.uniform3fv","WebGLRenderingContext.prototype.uniform3i","WebGLRenderingContext.prototype.uniform3iv","WebGLRenderingContext.prototype.uniform4f","WebGLRenderingContext.prototype.uniform4fv","WebGLRenderingContext.prototype.uniform4i","WebGLRenderingContext.prototype.uniform4iv","WebGLRenderingContext.prototype.uniformMatrix2fv","WebGLRenderingContext.prototype.uniformMatrix3fv","WebGLRenderingContext.prototype.uniformMatrix4fv","WebGLRenderingContext.prototype.useProgram","WebGLRenderingContext.prototype.validateProgram","WebGLRenderingContext.prototype.vertexAttrib1f","WebGLRenderingContext.prototype.vertexAttrib1fv","WebGLRenderingContext.prototype.vertexAttrib2f","WebGLRenderingContext.prototype.vertexAttrib2fv","WebGLRenderingContext.prototype.vertexAttrib3f","WebGLRenderingContext.prototype.vertexAttrib3fv","WebGLRenderingContext.prototype.vertexAttrib4f","WebGLRenderingContext.prototype.vertexAttrib4fv","WebGLRenderingContext.prototype.vertexAttribPointer","WebGLRenderingContext.prototype.viewport"]},"WebVTT: The Web Video Text Tracks Format":{"info":{"name":"WebVTT: The Web Video Text Tracks Format","subsection_number":null,"subsection_name":null,"url":"https://w3c.github.io/webvtt/"},"features":["VTTCue.prototype.getCueAsHTML"]},"Web Notifications":{"info":{"name":"Web Notifications","subsection_number":null,"subsection_name":null,"url":"https://notifications.spec.whatwg.org/"},"features":["DesktopNotification.prototype.show","DesktopNotificationCenter.prototype.createNotification","Notification.get","Notification.prototype.close","Notification.requestPermission"]},"WebRTC 1.0: Real-time Communication Between Browser":{"info":{"name":"WebRTC 1.0: Real-time Communication Between Browser","subsection_number":null,"subsection_name":null,"url":"https://www.w3.org/TR/webrtc/"},"features":["DataChannel.prototype.close","DataChannel.prototype.send","mozRTCPeerConnection.generateCertificate","mozRTCPeerConnection.prototype.addIceCandidate","mozRTCPeerConnection.prototype.addStream","mozRTCPeerConnection.prototype.addTrack","mozRTCPeerConnection.prototype.close","mozRTCPeerConnection.prototype.createAnswer","mozRTCPeerConnection.prototype.createDataChannel","mozRTCPeerConnection.prototype.createOffer","mozRTCPeerConnection.prototype.getConfiguration","mozRTCPeerConnection.prototype.getIdentityAssertion","mozRTCPeerConnection.prototype.getLocalStreams","mozRTCPeerConnection.prototype.getReceivers","mozRTCPeerConnection.prototype.getRemoteStreams","mozRTCPeerConnection.prototype.getSenders","mozRTCPeerConnection.prototype.getStats","mozRTCPeerConnection.prototype.getStreamById","mozRTCPeerConnection.prototype.removeStream","mozRTCPeerConnection.prototype.removeTrack","mozRTCPeerConnection.prototype.setIdentityProvider","mozRTCPeerConnection.prototype.setLocalDescription","mozRTCPeerConnection.prototype.setRemoteDescription","mozRTCPeerConnection.prototype.updateIce","RTCRtpSender.prototype.replaceTrack","RTCStatsReport.prototype.forEach","RTCStatsReport.prototype.get","RTCStatsReport.prototype.has"]}}; \ No newline at end of file diff --git a/content_scripts/stub.js b/content_scripts/stub.js deleted file mode 100644 index 9877257..0000000 --- a/content_scripts/stub.js +++ /dev/null @@ -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); -}()); \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index 9b6ad1c..c41eacc 100644 --- a/gulpfile.js +++ b/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); + }); }); diff --git a/manifest.json b/manifest.json index b37a81e..61aae36 100644 --- a/manifest.json +++ b/manifest.json @@ -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 } -} +} \ No newline at end of file