Bug 1593684 - Send additional metadata via postMessage instead of POST from report site issue extension r=twisniewski,miketaylr

Differential Revision: https://phabricator.services.mozilla.com/D52391

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Ksenia Berezina 2019-11-19 17:30:41 +00:00
Родитель a439f13b34
Коммит 16ae1b1a99
6 изменённых файлов: 45 добавлений и 153 удалений

Просмотреть файл

@ -195,23 +195,21 @@ async function openWebCompatTab(compatInfo) {
); );
} }
const tab = await browser.tabs.create({ url: "about:blank" });
const json = stripNonASCIIChars(JSON.stringify(params)); const json = stripNonASCIIChars(JSON.stringify(params));
await browser.tabExtras.loadURIWithPostData( const tab = await browser.tabs.create({ url: url.href });
tab.id,
url.href,
json,
"application/json"
);
await browser.tabs.executeScript(tab.id, { await browser.tabs.executeScript(tab.id, {
runAt: "document_end", runAt: "document_end",
code: `(function() { code: `(function() {
async function sendScreenshot(dataURI) { async function postMessageData(dataURI, metadata) {
const res = await fetch(dataURI); const res = await fetch(dataURI);
const blob = await res.blob(); const blob = await res.blob();
postMessage(blob, "${url.origin}"); const data = {
screenshot: blob,
message: metadata
};
postMessage(data, "${url.origin}");
} }
sendScreenshot("${compatInfo.screenshot}"); postMessageData("${compatInfo.screenshot}", ${json});
})()`, })()`,
}); });
} }

Просмотреть файл

@ -185,85 +185,9 @@ function getInfoFrameScript(messageName) {
this.tabExtras = class extends ExtensionAPI { this.tabExtras = class extends ExtensionAPI {
getAPI(context) { getAPI(context) {
const { tabManager } = context.extension; const { tabManager } = context.extension;
const {
Management: {
global: { windowTracker },
},
} = ChromeUtils.import("resource://gre/modules/Extension.jsm", null);
const { Services } = ChromeUtils.import(
"resource://gre/modules/Services.jsm"
);
return { return {
tabExtras: { tabExtras: {
async loadURIWithPostData(
tabId,
url,
postDataString,
postDataContentType
) {
const tab = tabManager.get(tabId);
if (!tab || !tab.browser) {
return Promise.reject("Invalid tab");
}
try {
new URL(url);
} catch (_) {
return Promise.reject("Invalid url");
}
if (
typeof postDataString !== "string" &&
!(postDataString instanceof String)
) {
return Promise.reject("postDataString must be a string");
}
const stringStream = Cc[
"@mozilla.org/io/string-input-stream;1"
].createInstance(Ci.nsIStringInputStream);
stringStream.data = postDataString;
const postData = Cc[
"@mozilla.org/network/mime-input-stream;1"
].createInstance(Ci.nsIMIMEInputStream);
postData.addHeader(
"Content-Type",
postDataContentType || "application/x-www-form-urlencoded"
);
postData.setData(stringStream);
return new Promise(resolve => {
const listener = {
onLocationChange(
browser,
webProgress,
request,
locationURI,
flags
) {
if (
webProgress.isTopLevel &&
browser === tab.browser &&
locationURI.spec === url
) {
windowTracker.removeListener("progress", listener);
resolve();
}
},
};
windowTracker.addListener("progress", listener);
let loadURIOptions = {
triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal(
{}
),
postData,
};
tab.browser.webNavigation.loadURI(url, loadURIOptions);
});
},
async getWebcompatInfo(tabId) { async getWebcompatInfo(tabId) {
return new Promise(resolve => { return new Promise(resolve => {
const messageName = "WebExtension:GetWebcompatInfo"; const messageName = "WebExtension:GetWebcompatInfo";

Просмотреть файл

@ -13,26 +13,6 @@
"minimum": 0 "minimum": 0
}], }],
"async": true "async": true
},
{
"name": "loadURIWithPostData",
"type": "function",
"description": "Loads a URI on the given tab using a POST request",
"parameters": [{
"type": "integer",
"name": "tabId",
"minimum": 0
}, {
"type": "string",
"name": "url"
}, {
"type": "string",
"name": "postData"
}, {
"type": "string",
"name": "postDataContentType"
}],
"async": true
} }
] ]
} }

Просмотреть файл

@ -16,27 +16,6 @@ async function clickToReportAndAwaitReportTabLoad() {
document.getElementById(WC_PAGE_ACTION_PANEL_ID).click(); document.getElementById(WC_PAGE_ACTION_PANEL_ID).click();
}); });
// wait for the new tab to switch to its final location
await new Promise(resolve => {
const progressListener = {
onLocationChange(browser) {
// Only interested in location changes on our browser.
if (browser != tab.linkedBrowser) {
return;
}
// Check that new location is the URL we want.
if (browser.currentURI.spec === "about:blank") {
return;
}
gBrowser.removeTabsProgressListener(progressListener);
TestUtils.executeSoon(() => resolve());
},
};
gBrowser.addTabsProgressListener(progressListener);
});
// wait for the new tab to acknowledge that it received a screenshot // wait for the new tab to acknowledge that it received a screenshot
await BrowserTestUtils.waitForContentEvent( await BrowserTestUtils.waitForContentEvent(
gBrowser.selectedBrowser, gBrowser.selectedBrowser,

Просмотреть файл

@ -174,21 +174,6 @@ function unpinFromURLBar() {
} }
async function startIssueServer() { async function startIssueServer() {
const BinaryInputStream = Components.Constructor(
"@mozilla.org/binaryinputstream;1",
"nsIBinaryInputStream",
"setInputStream"
);
function getRequestData(request) {
const body = new BinaryInputStream(request.bodyInputStream);
const bytes = [];
let avail;
while ((avail = body.available()) > 0) {
Array.prototype.push.apply(bytes, body.readByteArray(avail));
}
return String.fromCharCode.apply(null, bytes);
}
const landingTemplate = await new Promise((resolve, reject) => { const landingTemplate = await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
xhr.open("GET", NEW_ISSUE_PAGE); xhr.open("GET", NEW_ISSUE_PAGE);
@ -211,15 +196,7 @@ async function startIssueServer() {
server.registerPathHandler("/new", function(request, response) { server.registerPathHandler("/new", function(request, response) {
response.setHeader("Content-Type", "text/html", false); response.setHeader("Content-Type", "text/html", false);
response.setStatusLine(request.httpVersion, 200, "OK"); response.setStatusLine(request.httpVersion, 200, "OK");
const postData = JSON.parse(getRequestData(request)); response.write(landingTemplate);
const url = postData.url;
const details = JSON.stringify(postData.details);
const label = JSON.stringify(postData.extra_labels);
const output = landingTemplate
.replace("$$URL$$", url)
.replace("$$DETAILS$$", details)
.replace("$$LABEL$$", label);
response.write(output);
}); });
server.start(-1); server.start(-1);

Просмотреть файл

@ -10,6 +10,19 @@
<script> <script>
"use strict"; "use strict";
let preview = document.getElementById("screenshot-preview"); let preview = document.getElementById("screenshot-preview");
const CONFIG = {
url: {
element: document.getElementById("url")
},
details: {
element: document.getElementById("details"),
toStringify: true
},
extra_labels: {
element: document.getElementById("label"),
toStringify: true
},
};
function getBlobAsDataURL(blob) { function getBlobAsDataURL(blob) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -40,12 +53,33 @@ function sendReceivedEvent() {
window.dispatchEvent(new CustomEvent("ScreenshotReceived", {bubbles: true})); window.dispatchEvent(new CustomEvent("ScreenshotReceived", {bubbles: true}));
} }
function prepareContent(toStringify, content) {
if (toStringify) {
return JSON.stringify(content)
}
return content;
}
function appendMessage(message) {
for (const key in CONFIG) {
if (key in message) {
const field = CONFIG[key];
field.element.innerText = prepareContent(field.toStringify, message[key]);
}
}
}
// eslint-disable-next-line mozilla/balanced-listeners // eslint-disable-next-line mozilla/balanced-listeners
window.addEventListener("message", function(event) { window.addEventListener("message", function(event) {
if (event.data instanceof Blob) { if (event.data.screenshot instanceof Blob) {
preview.innerText = "Pass"; preview.innerText = "Pass";
} }
getBlobAsDataURL(event.data).then(setPreviewBG).then(sendReceivedEvent); if (event.data.message) {
appendMessage(event.data.message);
}
getBlobAsDataURL(event.data.screenshot).then(setPreviewBG).then(sendReceivedEvent);
}); });
</script> </script>