Skip to content
This repository has been archived by the owner on Jan 17, 2023. It is now read-only.

Commit

Permalink
Iframe tests (#3134)
Browse files Browse the repository at this point in the history
* Validate iframe URLs
Remove unneeded iframe onload handlers

* Put temporary clipboard TEXTAREA in an iframe
With iframe URL validation
  • Loading branch information
ianb authored and jaredhirsch committed Jul 14, 2017
1 parent efb41d0 commit 5b4609f
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 24 deletions.
12 changes: 12 additions & 0 deletions addon/webextension/assertIsBlankDocumentUrl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/** For use inside an iframe onload function, throws an Error if iframe src is not blank.html
Should be applied *inside* catcher.watchFunction
*/
this.assertIsBlankDocumentUrl = function assertIsBlankDocumentUrl(documentUrl) {
if (documentUrl !== browser.extension.getURL("blank.html")) {
let exc = new Error('iframe URL does not match expected blank.html');
exc.foundURL = documentUrl;
throw exc;
}
}
null;
1 change: 1 addition & 0 deletions addon/webextension/background/selectorLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ this.selectorLoader = (function() {
"log.js",
"catcher.js",
"assertIsTrusted.js",
"assertIsBlankDocumentUrl.js",
"background/selectorLoader.js",
"selector/callBackground.js",
"selector/util.js"
Expand Down
41 changes: 30 additions & 11 deletions addon/webextension/clipboard.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,40 @@
/* globals catcher */
/* globals catcher, assertIsBlankDocumentUrl */

"use strict";

this.clipboard = (function() {
let exports = {};

exports.copy = function(text) {
let el = document.createElement("textarea");
document.body.appendChild(el);
el.value = text;
el.select();
const copied = document.execCommand("copy");
document.body.removeChild(el);
if (!copied) {
catcher.unhandled(new Error("Clipboard copy failed"));
}
return copied;
return new Promise((resolve, reject) => {
let element = document.createElement("iframe");
element.src = browser.extension.getURL("blank.html");
// We can't actually hide the iframe while copying, but we can make
// it close to invisible:
element.style.opacity = "0";
element.style.width = "1px";
element.style.height = "1px";
element.onload = catcher.watchFunction(() => {
try {
element.onload = null;
let doc = element.contentDocument;
assertIsBlankDocumentUrl(doc.URL);
let el = doc.createElement("textarea");
doc.body.appendChild(el);
el.value = text;
el.select();
const copied = doc.execCommand("copy");
if (!copied) {
catcher.unhandled(new Error("Clipboard copy failed"));
}
doc.body.removeChild(el);
resolve(copied);
} finally {
document.body.removeChild(element);
}
});
document.body.appendChild(element);
});
};

return exports;
Expand Down
6 changes: 4 additions & 2 deletions addon/webextension/onboarding/slides.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* globals log, catcher, onboardingHtml, onboardingCss, util, shooter, callBackground, assertIsTrusted */
/* globals log, catcher, onboardingHtml, onboardingCss, util, shooter, callBackground, assertIsTrusted, assertIsBlankDocumentUrl */

"use strict";

Expand Down Expand Up @@ -36,11 +36,13 @@ this.slides = (function() {
return browser.extension.getURL(filename);
});
iframe.onload = catcher.watchFunction(() => {
iframe.onload = null;
doc = iframe.contentDocument;
assertIsBlankDocumentUrl(doc.URL);
let parsedDom = (new DOMParser()).parseFromString(
html,
"text/html"
);
doc = iframe.contentDocument;
doc.replaceChild(
doc.adoptNode(parsedDom.documentElement),
doc.documentElement
Expand Down
5 changes: 3 additions & 2 deletions addon/webextension/selector/shooter.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,9 @@ this.shooter = (function() { // eslint-disable-line no-unused-vars
shotId: shotObject.id,
shot: shotObject.asJson()
}).then((url) => {
const copied = clipboard.copy(url);
return callBackground("openShot", { url, copied });
return clipboard.copy(url).then((copied) => {
return callBackground("openShot", { url, copied });
});
}, (error) => {
if ('popupMessage' in error && (error.popupMessage == "REQUEST_ERROR" || error.popupMessage == 'CONNECTION_ERROR')) {
// The error has been signaled to the user, but unlike other errors (or
Expand Down
16 changes: 10 additions & 6 deletions addon/webextension/selector/ui.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* globals log, util, catcher, inlineSelectionCss, callBackground, assertIsTrusted */
/* globals log, util, catcher, inlineSelectionCss, callBackground, assertIsTrusted, assertIsBlankDocumentUrl */

"use strict";

Expand Down Expand Up @@ -93,7 +93,9 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
this.element.scrolling = "no";
this.updateElementSize();
this.element.onload = watchFunction(() => {
this.element.onload = null;
this.document = this.element.contentDocument;
assertIsBlankDocumentUrl(this.document.URL);
this.document.documentElement.innerHTML = `
<head>
<style>${substitutedCss}</style>
Expand Down Expand Up @@ -163,7 +165,7 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
initSizeWatch() {
this.stopSizeWatch();
this.sizeTracking.timer = setInterval(watchFunction(this.updateElementSize.bind(this)), 2000);
window.addEventListener("resize", this.onResize, true);
window.addEventListener("resize", watchFunction(assertIsTrusted(this.onResize)), true);
},

stopSizeWatch() {
Expand All @@ -176,7 +178,7 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
this.sizeTracking.windowDelayer = null;
}
this.sizeTracking.lastHeight = this.sizeTracking.lastWidth = null;
window.removeEventListener("resize", this.onResize, true);
window.removeEventListener("resize", watchFunction(assertIsTrusted(this.onResize)), true);
},

getElementFromPoint(x, y) {
Expand All @@ -197,7 +199,7 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
}
};

iframeSelection.onResize = watchFunction(onResize.bind(iframeSelection));
iframeSelection.onResize = watchFunction(assertIsTrusted(onResize.bind(iframeSelection)));

let iframePreSelection = exports.iframePreSelection = {
element: null,
Expand All @@ -220,7 +222,9 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
this.element.scrolling = "no";
this.updateElementSize();
this.element.onload = watchFunction(() => {
this.element.onload = null;
this.document = this.element.contentDocument;
assertIsBlankDocumentUrl(this.document.URL)
this.document.documentElement.innerHTML = `
<head>
<style>${substitutedCss}</style>
Expand Down Expand Up @@ -282,7 +286,7 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
},

hide() {
window.removeEventListener("scroll", this.onScroll);
window.removeEventListener("scroll", watchFunction(assertIsTrusted(this.onScroll)));
window.removeEventListener("resize", this.onResize, true);
if (this.element) {
this.element.style.display = "none";
Expand All @@ -291,7 +295,7 @@ this.ui = (function() { // eslint-disable-line no-unused-vars

unhide() {
this.updateElementSize();
window.addEventListener("scroll", this.onScroll);
window.addEventListener("scroll", watchFunction(assertIsTrusted(this.onScroll)));
window.addEventListener("resize", this.onResize, true);
this.element.style.display = "";
this.element.focus();
Expand Down
6 changes: 3 additions & 3 deletions addon/webextension/selector/uicontrol.js
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,7 @@ this.uicontrol = (function() {

function addHandlers() {
["mouseup", "mousedown", "mousemove", "click"].forEach((eventName) => {
let fn = watchFunction((function(eventName, event) {
let fn = watchFunction(assertIsTrusted((function(eventName, event) {
if (typeof event.button == "number" && event.button !== 0) {
// Not a left click
return undefined;
Expand All @@ -884,10 +884,10 @@ this.uicontrol = (function() {
return handler[eventName](event);
}
return undefined;
}).bind(null, eventName));
}).bind(null, eventName)));
primedDocumentHandlers.set(eventName, fn);
});
primedDocumentHandlers.set("keyup", keyupHandler);
primedDocumentHandlers.set("keyup", watchFunction(assertIsTrusted(keyupHandler)));
window.addEventListener('beforeunload', beforeunloadHandler);
}

Expand Down

0 comments on commit 5b4609f

Please sign in to comment.