diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /testing/web-platform/tests/mixed-content/generic/common.js | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'testing/web-platform/tests/mixed-content/generic/common.js')
-rw-r--r-- | testing/web-platform/tests/mixed-content/generic/common.js | 398 |
1 files changed, 398 insertions, 0 deletions
diff --git a/testing/web-platform/tests/mixed-content/generic/common.js b/testing/web-platform/tests/mixed-content/generic/common.js new file mode 100644 index 000000000..36427a466 --- /dev/null +++ b/testing/web-platform/tests/mixed-content/generic/common.js @@ -0,0 +1,398 @@ +/** + * @fileoverview Utilities for mixed-content in Web Platform Tests. + * @author burnik@google.com (Kristijan Burnik) + * Disclaimer: Some methods of other authors are annotated in the corresponding + * method's JSDoc. + */ + +/** + * Normalizes the target port for use in a URL. For default ports, this is the + * empty string (omitted port), otherwise it's a colon followed by the port + * number. Ports 80, 443 and an empty string are regarded as default ports. + * @param {number} targetPort The port to use + * @return {string} The port portion for using as part of a URL. + */ +function getNormalizedPort(targetPort) { + return ([80, 443, ""].indexOf(targetPort) >= 0) ? "" : ":" + targetPort; +} + +/** + * Creates a GUID. + * See: https://en.wikipedia.org/wiki/Globally_unique_identifier + * Original author: broofa (http://www.broofa.com/) + * Sourced from: http://stackoverflow.com/a/2117523/4949715 + * @return {string} A pseudo-random GUID. + */ +function guid() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); +} + +/** + * Initiates a new XHR via GET. + * @param {string} url The endpoint URL for the XHR. + * @param {string} responseType Optional - how should the response be parsed. + * Default is "json". + * See: https://xhr.spec.whatwg.org/#dom-xmlhttprequest-responsetype + * @return {Promise} A promise wrapping the success and error events. + */ +function xhrRequest(url, responseType) { + return new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, true); + xhr.responseType = responseType || "json"; + + xhr.addEventListener("error", function() { + reject(Error("Network Error")); + }); + + xhr.addEventListener("load", function() { + if (xhr.status != 200) + return reject(Error(xhr.statusText)); + + resolve(xhr.response); + }); + + xhr.send(); + }); +} + +/** + * Sets attributes on a given DOM element. + * @param {DOMElement} element The element on which to set the attributes. + * @param {object} An object with keys (serving as attribute names) and values. + */ +function setAttributes(el, attrs) { + attrs = attrs || {} + for (var attr in attrs) + el.setAttribute(attr, attrs[attr]); +} + + +/** + * Binds to success and error events of an object wrapping them into a promise + * available through {@code element.eventPromise}. The success event + * resolves and error event rejects. + * @param {object} element An object supporting events on which to bind the + * promise. + * @param {string} resolveEventName [="load"] The event name to bind resolve to. + * @param {string} rejectEventName [="error"] The event name to bind reject to. + */ +function bindEvents(element, resolveEventName, rejectEventName) { + element.eventPromise = new Promise(function(resolve, reject) { + element.addEventListener(resolveEventName || "load", resolve); + element.addEventListener(rejectEventName || "error", + function(e) { e.preventDefault(); reject(); } ); + }); +} + +/** + * Creates a new DOM element. + * @param {string} tagName The type of the DOM element. + * @param {object} attrs A JSON with attributes to apply to the element. + * @param {DOMElement} parent Optional - an existing DOM element to append to + * If not provided, the returned element will remain orphaned. + * @param {boolean} doBindEvents Optional - Whether to bind to load and error + * events and provide the promise wrapping the events via the element's + * {@code eventPromise} property. Default value evaluates to false. + * @return {DOMElement} The newly created DOM element. + */ +function createElement(tagName, attrs, parent, doBindEvents) { + var element = document.createElement(tagName); + + if (doBindEvents) + bindEvents(element); + + // We set the attributes after binding to events to catch any + // event-triggering attribute changes. E.g. form submission. + // + // But be careful with images: unlike other elements they will start the load + // as soon as the attr is set, even if not in the document yet, and sometimes + // complete it synchronously, so the append doesn't have the effect we want. + // So for images, we want to set the attrs after appending, whereas for other + // elements we want to do it before appending. + var isImg = (tagName == "img"); + if (!isImg) + setAttributes(element, attrs); + + if (parent) + parent.appendChild(element); + + if (isImg) + setAttributes(element, attrs); + + return element; +} + +function createRequestViaElement(tagName, attrs, parent) { + return createElement(tagName, attrs, parent, true).eventPromise; +} + +/** + * Creates a new empty iframe and appends it to {@code document.body} . + * @param {string} name The name and ID of the new iframe. + * @param {boolean} doBindEvents Whether to bind load and error events. + * @return {DOMElement} The newly created iframe. + */ +function createHelperIframe(name, doBindEvents) { + return createElement("iframe", + {"name": name, "id": name}, + document.body, + doBindEvents); +} + +/** + * Creates a new iframe, binds load and error events, sets the src attribute and + * appends it to {@code document.body} . + * @param {string} url The src for the iframe. + * @return {Promise} The promise for success/error events. + */ +function requestViaIframe(url) { + return createRequestViaElement("iframe", {"src": url}, document.body); +} + +/** + * Creates a new image, binds load and error events, sets the src attribute and + * appends it to {@code document.body} . + * @param {string} url The src for the image. + * @return {Promise} The promise for success/error events. + */ +function requestViaImage(url) { + return createRequestViaElement("img", {"src": url}, document.body); +} + +/** + * Initiates a new XHR GET request to provided URL. + * @param {string} url The endpoint URL for the XHR. + * @return {Promise} The promise for success/error events. + */ +function requestViaXhr(url) { + return xhrRequest(url); +} + +/** + * Initiates a new GET request to provided URL via the Fetch API. + * @param {string} url The endpoint URL for the Fetch. + * @return {Promise} The promise for success/error events. + */ +function requestViaFetch(url) { + return fetch(url); +} + +/** + * Creates a new Worker, binds message and error events wrapping them into. + * {@code worker.eventPromise} and posts an empty string message to start + * the worker. + * @param {string} url The endpoint URL for the worker script. + * @return {Promise} The promise for success/error events. + */ +function requestViaWorker(url) { + var worker = new Worker(url); + bindEvents(worker, "message", "error"); + worker.postMessage(''); + + return worker.eventPromise; +} + +/** + * Sets the href attribute on a navigable DOM element and performs a navigation + * by clicking it. To avoid navigating away from the current execution + * context, a target attribute is set to point to a new helper iframe. + * @param {DOMElement} navigableElement The navigable DOMElement + * @param {string} url The href for the navigable element. + * @return {Promise} The promise for success/error events. + */ +function requestViaNavigable(navigableElement, url) { + var iframe = createHelperIframe(guid(), true); + setAttributes(navigableElement, + {"href": url, + "target": iframe.name}); + navigableElement.click(); + + return iframe.eventPromise; +} + +/** + * Creates a new anchor element, appends it to {@code document.body} and + * performs the navigation. + * @param {string} url The URL to navigate to. + * @return {Promise} The promise for success/error events. + */ +function requestViaAnchor(url) { + var a = createElement("a", {"innerHTML": "Link to resource"}, document.body); + + return requestViaNavigable(a, url); +} + +/** + * Creates a new area element, appends it to {@code document.body} and performs + * the navigation. + * @param {string} url The URL to navigate to. + * @return {Promise} The promise for success/error events. + */ +function requestViaArea(url) { + var area = createElement("area", {}, document.body); + + return requestViaNavigable(area, url); +} + +/** + * Creates a new script element, sets the src to url, and appends it to + * {@code document.body}. + * @param {string} url The src URL. + * @return {Promise} The promise for success/error events. + */ +function requestViaScript(url) { + return createRequestViaElement("script", {"src": url}, document.body); +} + +/** + * Creates a new form element, sets attributes, appends it to + * {@code document.body} and submits the form. + * @param {string} url The URL to submit to. + * @return {Promise} The promise for success/error events. + */ +function requestViaForm(url) { + var iframe = createHelperIframe(guid()); + var form = createElement("form", + {"action": url, + "method": "POST", + "target": iframe.name}, + document.body); + bindEvents(iframe); + form.submit(); + + return iframe.eventPromise; +} + +/** + * Creates a new link element for a stylesheet, binds load and error events, + * sets the href to url and appends it to {@code document.head}. + * @param {string} url The URL for a stylesheet. + * @return {Promise} The promise for success/error events. + */ +function requestViaLinkStylesheet(url) { + return createRequestViaElement("link", + {"rel": "stylesheet", "href": url}, + document.head); +} + +/** + * Creates a new link element for a prefetch, binds load and error events, sets + * the href to url and appends it to {@code document.head}. + * @param {string} url The URL of a resource to prefetch. + * @return {Promise} The promise for success/error events. + */ +function requestViaLinkPrefetch(url) { + // TODO(kristijanburnik): Check if prefetch should support load and error + // events. For now we assume it's not specified. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Link_prefetching_FAQ + return createRequestViaElement("link", + {"rel": "prefetch", "href": url}, + document.head); +} + +/** + * Creates a new media element with a child source element, binds loadeddata and + * error events, sets attributes and appends to document.body. + * @param {string} type The type of the media element (audio/video/picture). + * @param {object} media_attrs The attributes for the media element. + * @param {object} source_attrs The attributes for the child source element. + * @return {DOMElement} The newly created media element. + */ +function createMediaElement(type, media_attrs, source_attrs) { + var mediaElement = createElement(type, {}); + var sourceElement = createElement("source", {}, mediaElement); + + mediaElement.eventPromise = new Promise(function(resolve, reject) { + mediaElement.addEventListener("loadeddata", resolve); + // Notice that the source element will raise the error. + sourceElement.addEventListener("error", reject); + }); + + setAttributes(mediaElement, media_attrs); + setAttributes(sourceElement, source_attrs); + document.body.appendChild(mediaElement); + + return mediaElement; +} + +/** + * Creates a new video element, binds loadeddata and error events, sets + * attributes and source URL and appends to {@code document.body}. + * @param {string} url The URL of the video. + * @return {Promise} The promise for success/error events. + */ +function requestViaVideo(url) { + return createMediaElement("video", + {}, + {type: "video/mp4", src: url}).eventPromise; +} + +/** + * Creates a new audio element, binds loadeddata and error events, sets + * attributes and source URL and appends to {@code document.body}. + * @param {string} url The URL of the audio. + * @return {Promise} The promise for success/error events. + */ +function requestViaAudio(url) { + return createMediaElement("audio", + {}, + {type: "audio/mpeg", src: url}).eventPromise; +} + +/** + * Creates a new picture element, binds loadeddata and error events, sets + * attributes and source URL and appends to {@code document.body}. Also + * creates new image element appending it to the picture + * @param {string} url The URL of the image for the source and image elements. + * @return {Promise} The promise for success/error events. + */ +function requestViaPicture(url) { + var picture = createMediaElement("picture", {}, {"srcset": url, + "type": "image/png"}); + return createRequestViaElement("img", {"src": url}, picture); +} + +/** + * Creates a new object element, binds load and error events, sets the data to + * url, and appends it to {@code document.body}. + * @param {string} url The data URL. + * @return {Promise} The promise for success/error events. + */ +function requestViaObject(url) { + return createRequestViaElement("object", {"data": url}, document.body); +} + +/** + * Creates a new WebSocket pointing to {@code url} and sends a message string + * "echo". The {@code message} and {@code error} events are triggering the + * returned promise resolve/reject events. + * @param {string} url The URL for WebSocket to connect to. + * @return {Promise} The promise for success/error events. + */ +function requestViaWebSocket(url) { + return new Promise(function(resolve, reject) { + var websocket = new WebSocket(url); + + websocket.addEventListener("message", function(e) { + resolve(JSON.parse(e.data)); + }); + + websocket.addEventListener("open", function(e) { + websocket.send("echo"); + }); + + websocket.addEventListener("error", function(e) { + reject(e) + }); + }); +} + +// SanityChecker does nothing in release mode. See sanity-checker.js for debug +// mode. +function SanityChecker() {} +SanityChecker.prototype.checkScenario = function() {}; +SanityChecker.prototype.setFailTimeout = function(test, timeout) {}; |