gecko-dev/browser/extensions/webcompat/lib/custom_functions.js

110 строки
3.2 KiB
JavaScript

/* 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";
/* globals browser, module */
const replaceStringInRequest = (
requestId,
inString,
outString,
inEncoding = "utf-8"
) => {
const filter = browser.webRequest.filterResponseData(requestId);
const decoder = new TextDecoder(inEncoding);
const encoder = new TextEncoder();
const RE = new RegExp(inString, "g");
const carryoverLength = inString.length;
let carryover = "";
filter.ondata = event => {
const replaced = (
carryover + decoder.decode(event.data, { stream: true })
).replace(RE, outString);
filter.write(encoder.encode(replaced.slice(0, -carryoverLength)));
carryover = replaced.slice(-carryoverLength);
};
filter.onstop = () => {
if (carryover.length) {
filter.write(encoder.encode(carryover));
}
filter.close();
};
};
const CUSTOM_FUNCTIONS = {
detectSwipeFix: injection => {
const { urls, types } = injection.data;
const listener = (injection.data.listener = ({ requestId }) => {
replaceStringInRequest(
requestId,
"preventDefault:true",
"preventDefault:false"
);
return {};
});
browser.webRequest.onBeforeRequest.addListener(listener, { urls, types }, [
"blocking",
]);
},
detectSwipeFixDisable: injection => {
const { listener } = injection.data;
browser.webRequest.onBeforeRequest.removeListener(listener);
delete injection.data.listener;
},
noSniffFix: injection => {
const { urls, contentType } = injection.data;
const listener = (injection.data.listener = e => {
e.responseHeaders.push(contentType);
return { responseHeaders: e.responseHeaders };
});
browser.webRequest.onHeadersReceived.addListener(listener, { urls }, [
"blocking",
"responseHeaders",
]);
},
noSniffFixDisable: injection => {
const { listener } = injection.data;
browser.webRequest.onHeadersReceived.removeListener(listener);
delete injection.data.listener;
},
runScriptBeforeRequest: injection => {
const { bug, message, request, script, types } = injection;
const warning = `${message} See https://bugzilla.mozilla.org/show_bug.cgi?id=${bug} for details.`;
const listener = (injection.listener = e => {
const { tabId, frameId } = e;
return browser.tabs
.executeScript(tabId, {
file: script,
frameId,
runAt: "document_start",
})
.then(() => {
browser.tabs.executeScript(tabId, {
code: `console.warn(${JSON.stringify(warning)})`,
runAt: "document_start",
});
})
.catch(_ => {});
});
browser.webRequest.onBeforeRequest.addListener(
listener,
{ urls: request, types: types || ["script"] },
["blocking"]
);
},
runScriptBeforeRequestDisable: injection => {
const { listener } = injection;
browser.webRequest.onBeforeRequest.removeListener(listener);
delete injection.data.listener;
},
};
module.exports = CUSTOM_FUNCTIONS;