/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; const Cu = Components.utils; const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}); devtools.lazyImporter(this, "promise", "resource://gre/modules/Promise.jsm", "Promise"); devtools.lazyImporter(this, "Task", "resource://gre/modules/Task.jsm", "Task"); addMessageListener("devtools:test:history", function ({ data }) { content.history[data.direction](); }); addMessageListener("devtools:test:navigate", function ({ data }) { content.location = data.location; }); addMessageListener("devtools:test:reload", function ({ data }) { data = data || {}; content.location.reload(data.forceget); }); addMessageListener("devtools:test:console", function ({ data }) { let method = data.shift(); content.console[method].apply(content.console, data); }); /** * Performs a single XMLHttpRequest and returns a promise that resolves once * the request has loaded. * * @param Object data * { method: the request method (default: "GET"), * url: the url to request (default: content.location.href), * body: the request body to send (default: ""), * nocache: append an unique token to the query string (default: true) * } * * @return Promise A promise that's resolved with object * { status: XMLHttpRequest.status, * response: XMLHttpRequest.response } * */ function promiseXHR(data) { let xhr = new content.XMLHttpRequest(); let method = data.method || "GET"; let url = data.url || content.location.href; let body = data.body || ""; if (data.nocache) { url += "?devtools-cachebust=" + Math.random(); } let deferred = promise.defer(); xhr.addEventListener("loadend", function loadend(event) { xhr.removeEventListener("loadend", loadend); deferred.resolve({ status: xhr.status, response: xhr.response }); }); xhr.open(method, url); xhr.send(body); return deferred.promise; } /** * Performs XMLHttpRequest request(s) in the context of the page. The data * parameter can be either a single object or an array of objects described below. * The requests will be performed one at a time in the order they appear in the data. * * The objects should have following form (any of them can be omitted; defaults * shown below): * { * method: "GET", * url: content.location.href, * body: "", * nocache: true, // Adds a cache busting random token to the URL * } * * The handler will respond with devtools:test:xhr message after all requests * have finished. Following data will be available for each requests * (in the same order as requests): * { * status: XMLHttpRequest.status * response: XMLHttpRequest.response * } */ addMessageListener("devtools:test:xhr", Task.async(function* ({ data }) { let requests = Array.isArray(data) ? data : [data]; let responses = []; for (let request of requests) { let response = yield promiseXHR(request); responses.push(response); } sendAsyncMessage("devtools:test:xhr", responses); })); // To eval in content, look at `evalInDebuggee` in the head.js of canvasdebugger // for an example. addMessageListener("devtools:test:eval", function ({ data }) { sendAsyncMessage("devtools:test:eval:response", { value: content.eval(data.script), id: data.id }); }); addEventListener("load", function() { sendAsyncMessage("devtools:test:load"); }, true);