Merge m-c to autoland, a=merge

MozReview-Commit-ID: 3BrkDVl7521
This commit is contained in:
Wes Kocher 2017-05-08 16:24:51 -07:00
commit 75c2b7a481
325 changed files with 45388 additions and 78510 deletions

View file

@ -9,7 +9,6 @@ obj*/**
# below.
addon-sdk/**
build/**
caps/**
chrome/**
config/**
db/**
@ -78,6 +77,9 @@ browser/extensions/activity-stream/vendor/**
# imported from chromium
browser/extensions/mortar/**
# caps/ exclusions
caps/tests/mochitest/browser_checkloaduri.js
# devtools/ exclusions
devtools/client/canvasdebugger/**
devtools/client/commandline/**

View file

@ -676,6 +676,58 @@
}
}
/**
* Put ARIA owned child back when ARIA owner removed.
*/
function test10_removeARIAOwner()
{
this.eventSeq = [
new invokerChecker(EVENT_HIDE, getAccessible('t10_owner'))
];
this.invoke = () => {
let tree =
{ SECTION: [ // t10_container
{ SECTION: [ // t10_owner
{ ENTRY: [] } // t10_child
] }
] };
testAccessibleTree('t10_container', tree);
getNode('t10_owner').remove();
}
this.getID = () => {
return 'Put aria owned child back when aria owner removed';
}
}
function test10_finishTest()
{
this.eventSeq = [
new invokerChecker(EVENT_REORDER, 't10_container')
];
this.invoke = () => {
// trigger a tree update.
getNode('t10_container').append(document.createElement('p'));
}
this.finalCheck = () => {
let tree =
{ SECTION: [ // t10_container
// { ENTRY: [] }, // t10_child
{ PARAGRAPH: [] }
] };
testAccessibleTree('t10_container', tree);
todo(false, 'Input accessible has be moved back in the tree');
}
this.getID = () => {
return `Put aria owned child back when aria owner removed (finish test)`;
}
}
////////////////////////////////////////////////////////////////////////////
// Test
////////////////////////////////////////////////////////////////////////////
@ -728,6 +780,9 @@
gQueue.push(new test9_setARIAOwns());
gQueue.push(new test9_finish());
gQueue.push(new test10_removeARIAOwner());
gQueue.push(new test10_finishTest());
gQueue.invoke(); // SimpleTest.finish() will be called in the end
}
@ -792,6 +847,11 @@
</div>
<iframe id="t9_container"></iframe>
<div id="t10_container">
<div id="t10_owner" aria-owns="t10_child"></div>
<input id="t10_child">
</div>
</body>
</html>

View file

@ -117,6 +117,10 @@
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="3"/>
</emItem>
<emItem blockID="edad04eb-ea16-42f3-a4a7-20dded33cc37" id="@safesearchscoutee">
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="3"/>
</emItem>
<emItem blockID="i436" id="/(\{7aeae561-714b-45f6-ace3-4a8aed6e227b\})|(\{01e86e69-a2f8-48a0-b068-83869bdba3d0\})|(\{77f5fe49-12e3-4cf5-abb4-d993a0164d9e\})/">
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="1"/>
@ -181,6 +185,10 @@
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="3"/>
</emItem>
<emItem blockID="3fd71895-7fc6-4f3f-aa22-1cbb0c5fd922" id="/^({95E84BD3-3604-4AAC-B2CA-D9AC3E55B64B}|{E3605470-291B-44EB-8648-745EE356599A}|{95E5E0AD-65F9-4FFC-A2A2-0008DCF6ED25}|{FF20459C-DA6E-41A7-80BC-8F4FEFD9C575}|{6E727987-C8EA-44DA-8749-310C0FBE3C3E}|{12E8A6C2-B125-479F-AB3C-13B8757C7F04}|{EB6628CF-0675-4DAE-95CE-EFFA23169743})$/">
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="3"/>
</emItem>
<emItem blockID="i716" id="{cc6cc772-f121-49e0-b1f0-c26583cb0c5e}">
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="3"/>

View file

@ -360,12 +360,6 @@ pref("browser.download.folderList", 1);
pref("browser.download.manager.addToRecentDocs", true);
pref("browser.download.manager.resumeOnWakeDelay", 10000);
#ifdef RELEASE_OR_BETA
pref("browser.download.showPanelDropmarker", false);
#else
pref("browser.download.showPanelDropmarker", true);
#endif
// This allows disabling the animated notifications shown by
// the Downloads Indicator when a download starts or completes.
pref("browser.download.animateNotifications", true);

View file

@ -71,8 +71,6 @@ XPCOMUtils.defineLazyGetter(this, "DownloadsLogger", () => {
return new ConsoleAPI(consoleOptions);
});
const nsIDM = Ci.nsIDownloadManager;
const kDownloadsStringBundleUrl =
"chrome://browser/locale/downloads/downloads.properties";
@ -124,7 +122,6 @@ var PrefObserver = {
PrefObserver.register({
// prefName: defaultValue
animateNotifications: true,
showPanelDropmarker: true,
});
@ -135,6 +132,19 @@ PrefObserver.register({
* and provides shared methods for all the instances of the user interface.
*/
this.DownloadsCommon = {
// The following legacy constants are still returned by stateOfDownload, but
// individual properties of the Download object should normally be used.
DOWNLOAD_NOTSTARTED: -1,
DOWNLOAD_DOWNLOADING: 0,
DOWNLOAD_FINISHED: 1,
DOWNLOAD_FAILED: 2,
DOWNLOAD_CANCELED: 3,
DOWNLOAD_PAUSED: 4,
DOWNLOAD_BLOCKED_PARENTAL: 6,
DOWNLOAD_DIRTY: 8,
DOWNLOAD_BLOCKED_POLICY: 9,
// The following are the possible values of the "attention" property.
ATTENTION_NONE: "",
ATTENTION_SUCCESS: "success",
ATTENTION_WARNING: "warning",
@ -183,13 +193,6 @@ this.DownloadsCommon = {
return PrefObserver.animateNotifications;
},
/**
* Indicates whether we should show the dropmarker in the Downloads Panel.
*/
get showPanelDropmarker() {
return PrefObserver.showPanelDropmarker;
},
/**
* Get access to one of the DownloadsData or PrivateDownloadsData objects,
* depending on the privacy status of the window in question.
@ -256,27 +259,27 @@ this.DownloadsCommon = {
stateOfDownload(download) {
// Collapse state using the correct priority.
if (!download.stopped) {
return nsIDM.DOWNLOAD_DOWNLOADING;
return DownloadsCommon.DOWNLOAD_DOWNLOADING;
}
if (download.succeeded) {
return nsIDM.DOWNLOAD_FINISHED;
return DownloadsCommon.DOWNLOAD_FINISHED;
}
if (download.error) {
if (download.error.becauseBlockedByParentalControls) {
return nsIDM.DOWNLOAD_BLOCKED_PARENTAL;
return DownloadsCommon.DOWNLOAD_BLOCKED_PARENTAL;
}
if (download.error.becauseBlockedByReputationCheck) {
return nsIDM.DOWNLOAD_DIRTY;
return DownloadsCommon.DOWNLOAD_DIRTY;
}
return nsIDM.DOWNLOAD_FAILED;
return DownloadsCommon.DOWNLOAD_FAILED;
}
if (download.canceled) {
if (download.hasPartialData) {
return nsIDM.DOWNLOAD_PAUSED;
return DownloadsCommon.DOWNLOAD_PAUSED;
}
return nsIDM.DOWNLOAD_CANCELED;
return DownloadsCommon.DOWNLOAD_CANCELED;
}
return nsIDM.DOWNLOAD_NOTSTARTED;
return DownloadsCommon.DOWNLOAD_NOTSTARTED;
},
/**

View file

@ -325,18 +325,18 @@ this.DownloadsViewUI.DownloadElementShell.prototype = {
*/
get currentDefaultCommandName() {
switch (DownloadsCommon.stateOfDownload(this.download)) {
case Ci.nsIDownloadManager.DOWNLOAD_NOTSTARTED:
case DownloadsCommon.DOWNLOAD_NOTSTARTED:
return "downloadsCmd_cancel";
case Ci.nsIDownloadManager.DOWNLOAD_FAILED:
case Ci.nsIDownloadManager.DOWNLOAD_CANCELED:
case DownloadsCommon.DOWNLOAD_FAILED:
case DownloadsCommon.DOWNLOAD_CANCELED:
return "downloadsCmd_retry";
case Ci.nsIDownloadManager.DOWNLOAD_PAUSED:
case DownloadsCommon.DOWNLOAD_PAUSED:
return "downloadsCmd_pauseResume";
case Ci.nsIDownloadManager.DOWNLOAD_FINISHED:
case DownloadsCommon.DOWNLOAD_FINISHED:
return "downloadsCmd_open";
case Ci.nsIDownloadManager.DOWNLOAD_BLOCKED_PARENTAL:
case DownloadsCommon.DOWNLOAD_BLOCKED_PARENTAL:
return "downloadsCmd_openReferrer";
case Ci.nsIDownloadManager.DOWNLOAD_DIRTY:
case DownloadsCommon.DOWNLOAD_DIRTY:
return "downloadsCmd_showBlockedInfo";
}
return "";

View file

@ -30,8 +30,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "Services",
XPCOMUtils.defineLazyModuleGetter(this, "Task",
"resource://gre/modules/Task.jsm");
const nsIDM = Ci.nsIDownloadManager;
const DESTINATION_FILE_URI_ANNO = "downloads/destinationFileURI";
const DOWNLOAD_META_DATA_ANNO = "downloads/metaData";
@ -72,17 +70,17 @@ HistoryDownload.prototype = {
}
if ("state" in metaData) {
this.succeeded = metaData.state == nsIDM.DOWNLOAD_FINISHED;
this.canceled = metaData.state == nsIDM.DOWNLOAD_CANCELED ||
metaData.state == nsIDM.DOWNLOAD_PAUSED;
this.succeeded = metaData.state == DownloadsCommon.DOWNLOAD_FINISHED;
this.canceled = metaData.state == DownloadsCommon.DOWNLOAD_CANCELED ||
metaData.state == DownloadsCommon.DOWNLOAD_PAUSED;
this.endTime = metaData.endTime;
// Recreate partial error information from the state saved in history.
if (metaData.state == nsIDM.DOWNLOAD_FAILED) {
if (metaData.state == DownloadsCommon.DOWNLOAD_FAILED) {
this.error = { message: "History download failed." };
} else if (metaData.state == nsIDM.DOWNLOAD_BLOCKED_PARENTAL) {
} else if (metaData.state == DownloadsCommon.DOWNLOAD_BLOCKED_PARENTAL) {
this.error = { becauseBlockedByParentalControls: true };
} else if (metaData.state == nsIDM.DOWNLOAD_DIRTY) {
} else if (metaData.state == DownloadsCommon.DOWNLOAD_DIRTY) {
this.error = {
becauseBlockedByReputationCheck: true,
reputationCheckVerdict: metaData.reputationCheckVerdict || "",

View file

@ -13,11 +13,6 @@ richlistitem[type="download"]:not([selected]) button {
-moz-user-focus: none;
}
.downloadsHideDropmarker > #downloadsFooterButtonsSplitter,
.downloadsHideDropmarker > #downloadsFooterDropmarker {
display: none;
}
richlistitem[type="download"].download-state[state="1"]:not([exists]) > .downloadButtonArea,
richlistitem[type="download"].download-state[state="1"]:not([exists]) > toolbarseparator {
display: none;
@ -29,9 +24,8 @@ richlistitem[type="download"].download-state[state="1"]:not([exists]) > toolbars
display: none;
}
#downloadsFooter[showingdropdown] > stack > #downloadsSummary,
#downloadsFooter[showingsummary] > stack:hover > #downloadsSummary,
#downloadsFooter[showingsummary]:not([showingdropdown]) > stack:not(:hover) > #downloadsFooterButtons {
#downloadsFooter[showingsummary] > stack:not(:hover) > #downloadsFooterButtons {
/* If we used "visibility: hidden;" then the mouseenter event of
#downloadsHistory wouldn't be triggered immediately, and the hover styling
of the button would not apply until the mouse is moved again.

View file

@ -224,14 +224,6 @@ const DownloadsPanel = {
}
this.initialize(() => {
let downloadsFooterButtons =
document.getElementById("downloadsFooterButtons");
if (DownloadsCommon.showPanelDropmarker) {
downloadsFooterButtons.classList.remove("downloadsHideDropmarker");
} else {
downloadsFooterButtons.classList.add("downloadsHideDropmarker");
}
// Delay displaying the panel because this function will sometimes be
// called while another window is closing (like the window for selecting
// whether to save or open the file), and that would cause the panel to
@ -387,24 +379,6 @@ const DownloadsPanel = {
this._state = this.kStateHidden;
},
onFooterPopupShowing(aEvent) {
let itemClearList = document.getElementById("downloadsDropdownItemClearList");
if (DownloadsCommon.getData(window).canRemoveFinished) {
itemClearList.removeAttribute("hidden");
} else {
itemClearList.setAttribute("hidden", "true");
}
DownloadsViewController.updateCommands();
document.getElementById("downloadsFooter")
.setAttribute("showingdropdown", true);
},
onFooterPopupHidden(aEvent) {
document.getElementById("downloadsFooter")
.removeAttribute("showingdropdown");
},
// Related operations
/**
@ -419,13 +393,6 @@ const DownloadsPanel = {
BrowserDownloadsUI();
},
openDownloadsFolder() {
Downloads.getPreferredDownloadsDirectory().then(downloadsPath => {
DownloadsCommon.showDirectory(new FileUtils.File(downloadsPath));
}).catch(Cu.reportError);
this.hidePanel();
},
// Internal functions
/**

View file

@ -154,23 +154,6 @@
accesskey="&downloadsHistory.accesskey;"
flex="1"
oncommand="DownloadsPanel.showDownloadsHistory();"/>
<toolbarseparator id="downloadsFooterButtonsSplitter"
class="downloadsDropmarkerSplitter"/>
<button id="downloadsFooterDropmarker"
class="downloadsPanelFooterButton downloadsDropmarker"
type="menu">
<menupopup id="downloadSubPanel"
onpopupshowing="DownloadsPanel.onFooterPopupShowing(event);"
onpopuphidden="DownloadsPanel.onFooterPopupHidden(event);"
position="after_end">
<menuitem id="downloadsDropdownItemClearList"
command="downloadsCmd_clearList"
label="&cmd.clearList2.label;"/>
<menuitem id="downloadsDropdownItemOpenDownloadsFolder"
oncommand="DownloadsPanel.openDownloadsFolder();"
label="&openDownloadsFolder.label;"/>
</menupopup>
</button>
</hbox>
</stack>
</vbox>

View file

@ -12,5 +12,4 @@ skip-if = os == "linux" # Bug 952422
[browser_libraryDrop.js]
[browser_downloads_panel_block.js]
skip-if = true # Bug 1352792
[browser_downloads_panel_footer.js]
[browser_downloads_panel_height.js]

View file

@ -14,11 +14,11 @@ registerCleanupFunction(function*() {
add_task(function* test_basic_functionality() {
// Display one of each download state.
const DownloadData = [
{ state: nsIDM.DOWNLOAD_NOTSTARTED },
{ state: nsIDM.DOWNLOAD_PAUSED },
{ state: nsIDM.DOWNLOAD_FINISHED },
{ state: nsIDM.DOWNLOAD_FAILED },
{ state: nsIDM.DOWNLOAD_CANCELED },
{ state: DownloadsCommon.DOWNLOAD_NOTSTARTED },
{ state: DownloadsCommon.DOWNLOAD_PAUSED },
{ state: DownloadsCommon.DOWNLOAD_FINISHED },
{ state: DownloadsCommon.DOWNLOAD_FAILED },
{ state: DownloadsCommon.DOWNLOAD_CANCELED },
];
// Wait for focus first

View file

@ -139,7 +139,7 @@ function promisePanelHidden() {
function makeDownload(verdict) {
return {
state: nsIDM.DOWNLOAD_DIRTY,
state: DownloadsCommon.DOWNLOAD_DIRTY,
hasBlockedData: true,
errorObj: {
result: Components.results.NS_ERROR_FAILURE,

View file

@ -1,95 +0,0 @@
"use strict";
function *task_openDownloadsSubPanel() {
let downloadSubPanel = document.getElementById("downloadSubPanel");
let popupShownPromise = BrowserTestUtils.waitForEvent(downloadSubPanel, "popupshown");
let downloadsDropmarker = document.getElementById("downloadsFooterDropmarker");
EventUtils.synthesizeMouseAtCenter(downloadsDropmarker, {}, window);
yield popupShownPromise;
}
add_task(function* test_openDownloadsFolder() {
yield SpecialPowers.pushPrefEnv({"set": [["browser.download.showPanelDropmarker", true]]});
yield task_openPanel();
yield task_openDownloadsSubPanel();
yield new Promise(resolve => {
sinon.stub(DownloadsCommon, "showDirectory", file => {
resolve(Downloads.getPreferredDownloadsDirectory().then(downloadsPath => {
is(file.path, downloadsPath, "Check the download folder path.");
}));
});
let itemOpenDownloadsFolder =
document.getElementById("downloadsDropdownItemOpenDownloadsFolder");
EventUtils.synthesizeMouseAtCenter(itemOpenDownloadsFolder, {}, window);
});
yield task_resetState();
});
add_task(function* test_clearList() {
const kTestCases = [{
downloads: [
{ state: nsIDM.DOWNLOAD_NOTSTARTED },
{ state: nsIDM.DOWNLOAD_FINISHED },
{ state: nsIDM.DOWNLOAD_FAILED },
{ state: nsIDM.DOWNLOAD_CANCELED },
],
expectClearListShown: true,
expectedItemNumber: 0,
}, {
downloads: [
{ state: nsIDM.DOWNLOAD_NOTSTARTED },
{ state: nsIDM.DOWNLOAD_FINISHED },
{ state: nsIDM.DOWNLOAD_FAILED },
{ state: nsIDM.DOWNLOAD_PAUSED },
{ state: nsIDM.DOWNLOAD_CANCELED },
],
expectClearListShown: true,
expectedItemNumber: 1,
}, {
downloads: [
{ state: nsIDM.DOWNLOAD_PAUSED },
],
expectClearListShown: false,
expectedItemNumber: 1,
}];
for (let testCase of kTestCases) {
yield verify_clearList(testCase);
}
});
function *verify_clearList(testCase) {
let downloads = testCase.downloads;
yield task_addDownloads(downloads);
yield task_openPanel();
is(DownloadsView._downloads.length, downloads.length,
"Expect the number of download items");
yield task_openDownloadsSubPanel();
let itemClearList = document.getElementById("downloadsDropdownItemClearList");
let itemNumberPromise = BrowserTestUtils.waitForCondition(() => {
return DownloadsView._downloads.length === testCase.expectedItemNumber;
});
if (testCase.expectClearListShown) {
isnot("true", itemClearList.getAttribute("hidden"),
"Should show Clear Preview Panel button");
EventUtils.synthesizeMouseAtCenter(itemClearList, {}, window);
} else {
is("true", itemClearList.getAttribute("hidden"),
"Should not show Clear Preview Panel button");
}
yield itemNumberPromise;
is(DownloadsView._downloads.length, testCase.expectedItemNumber,
"Download items remained.");
yield task_resetState();
}

View file

@ -10,7 +10,7 @@
*/
add_task(function* test_height_reduced_after_removal() {
yield task_addDownloads([
{ state: nsIDM.DOWNLOAD_FINISHED },
{ state: DownloadsCommon.DOWNLOAD_FINISHED },
]);
yield task_openPanel();

View file

@ -24,8 +24,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
XPCOMUtils.defineLazyModuleGetter(this, "HttpServer",
"resource://testing-common/httpd.js");
const nsIDM = Ci.nsIDownloadManager;
var gTestTargetFile = FileUtils.getFile("TmpD", ["dm-ui-test.file"]);
gTestTargetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
@ -163,11 +161,12 @@ function* task_addDownloads(aItems) {
target: {
path: gTestTargetFile.path,
},
succeeded: item.state == nsIDM.DOWNLOAD_FINISHED,
canceled: item.state == nsIDM.DOWNLOAD_CANCELED ||
item.state == nsIDM.DOWNLOAD_PAUSED,
error: item.state == nsIDM.DOWNLOAD_FAILED ? new Error("Failed.") : null,
hasPartialData: item.state == nsIDM.DOWNLOAD_PAUSED,
succeeded: item.state == DownloadsCommon.DOWNLOAD_FINISHED,
canceled: item.state == DownloadsCommon.DOWNLOAD_CANCELED ||
item.state == DownloadsCommon.DOWNLOAD_PAUSED,
error: item.state == DownloadsCommon.DOWNLOAD_FAILED ?
new Error("Failed.") : null,
hasPartialData: item.state == DownloadsCommon.DOWNLOAD_PAUSED,
hasBlockedData: item.hasBlockedData || false,
startTime: new Date(startTimeMs++),
};

View file

@ -1,5 +1,5 @@
This is the PDF.js project output, https://github.com/mozilla/pdf.js
Current extension version is: 1.8.314
Current extension version is: 1.8.331
Taken from upstream commit: 3adda80f
Taken from upstream commit: 0dbc68a6

View file

@ -98,7 +98,13 @@ return /******/ (function(modules) { // webpackBootstrap
"use strict";
/* WEBPACK VAR INJECTION */(function(global) {
var compatibility = __w_pdfjs_require__(14);
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.warn = exports.utf8StringToString = exports.stringToUTF8String = exports.stringToPDFString = exports.stringToBytes = exports.string32 = exports.shadow = exports.setVerbosityLevel = exports.removeNullCharacters = exports.readUint32 = exports.readUint16 = exports.readInt8 = exports.log2 = exports.loadJpegStream = exports.isEvalSupported = exports.isLittleEndian = exports.createValidAbsoluteUrl = exports.isSameOrigin = exports.isNodeJS = exports.isSpace = exports.isString = exports.isNum = exports.isInt = exports.isEmptyObj = exports.isBool = exports.isArrayBuffer = exports.isArray = exports.info = exports.globalScope = exports.getVerbosityLevel = exports.getLookupTableFactory = exports.error = exports.deprecated = exports.createObjectURL = exports.createPromiseCapability = exports.createBlob = exports.bytesToString = exports.assert = exports.arraysToBytes = exports.arrayByteLength = exports.XRefParseException = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.TextRenderingMode = exports.StreamType = exports.StatTimer = exports.PasswordResponses = exports.PasswordException = exports.PageViewport = exports.NotImplementedException = exports.MissingPDFException = exports.MissingDataException = exports.MessageHandler = exports.InvalidPDFException = exports.CMapCompressionType = exports.ImageKind = exports.FontType = exports.AnnotationType = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationBorderStyleType = exports.UNSUPPORTED_FEATURES = exports.VERBOSITY_LEVELS = exports.OPS = exports.IDENTITY_MATRIX = exports.FONT_IDENTITY_MATRIX = undefined;
__w_pdfjs_require__(14);
var globalScope = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : undefined;
var FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
var TextRenderingMode = {
@ -3386,8 +3392,8 @@ var _UnsupportedManager = function UnsupportedManagerClosure() {
}();
var version, build;
{
exports.version = version = '1.8.314';
exports.build = build = '3adda80f';
exports.version = version = '1.8.331';
exports.build = build = '0dbc68a6';
}
exports.getDocument = getDocument;
exports.LoopbackPort = LoopbackPort;
@ -4389,8 +4395,8 @@ if (!_util.globalScope.PDFJS) {
}
var PDFJS = _util.globalScope.PDFJS;
{
PDFJS.version = '1.8.314';
PDFJS.build = '3adda80f';
PDFJS.version = '1.8.331';
PDFJS.build = '0dbc68a6';
}
PDFJS.pdfBug = false;
if (PDFJS.verbosity !== undefined) {
@ -6704,8 +6710,8 @@ exports.TilingPattern = TilingPattern;
"use strict";
var pdfjsVersion = '1.8.314';
var pdfjsBuild = '3adda80f';
var pdfjsVersion = '1.8.331';
var pdfjsBuild = '0dbc68a6';
var pdfjsSharedUtil = __w_pdfjs_require__(0);
var pdfjsDisplayGlobal = __w_pdfjs_require__(8);
var pdfjsDisplayAPI = __w_pdfjs_require__(3);
@ -6717,7 +6723,7 @@ exports.PDFJS = pdfjsDisplayGlobal.PDFJS;
exports.build = pdfjsDisplayAPI.build;
exports.version = pdfjsDisplayAPI.version;
exports.getDocument = pdfjsDisplayAPI.getDocument;
exports.LoobpackPort = pdfjsDisplayAPI.LoopbackPort;
exports.LoopbackPort = pdfjsDisplayAPI.LoopbackPort;
exports.PDFDataRangeTransport = pdfjsDisplayAPI.PDFDataRangeTransport;
exports.PDFWorker = pdfjsDisplayAPI.PDFWorker;
exports.renderTextLayer = pdfjsDisplayTextLayer.renderTextLayer;
@ -6748,6 +6754,8 @@ exports.addLinkAttributes = pdfjsDisplayDOMUtils.addLinkAttributes;
"use strict";
;
/***/ })
/******/ ]);
});

View file

@ -98,7 +98,13 @@ return /******/ (function(modules) { // webpackBootstrap
"use strict";
/* WEBPACK VAR INJECTION */(function(global) {
var compatibility = __w_pdfjs_require__(36);
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.warn = exports.utf8StringToString = exports.stringToUTF8String = exports.stringToPDFString = exports.stringToBytes = exports.string32 = exports.shadow = exports.setVerbosityLevel = exports.removeNullCharacters = exports.readUint32 = exports.readUint16 = exports.readInt8 = exports.log2 = exports.loadJpegStream = exports.isEvalSupported = exports.isLittleEndian = exports.createValidAbsoluteUrl = exports.isSameOrigin = exports.isNodeJS = exports.isSpace = exports.isString = exports.isNum = exports.isInt = exports.isEmptyObj = exports.isBool = exports.isArrayBuffer = exports.isArray = exports.info = exports.globalScope = exports.getVerbosityLevel = exports.getLookupTableFactory = exports.error = exports.deprecated = exports.createObjectURL = exports.createPromiseCapability = exports.createBlob = exports.bytesToString = exports.assert = exports.arraysToBytes = exports.arrayByteLength = exports.XRefParseException = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.TextRenderingMode = exports.StreamType = exports.StatTimer = exports.PasswordResponses = exports.PasswordException = exports.PageViewport = exports.NotImplementedException = exports.MissingPDFException = exports.MissingDataException = exports.MessageHandler = exports.InvalidPDFException = exports.CMapCompressionType = exports.ImageKind = exports.FontType = exports.AnnotationType = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationBorderStyleType = exports.UNSUPPORTED_FEATURES = exports.VERBOSITY_LEVELS = exports.OPS = exports.IDENTITY_MATRIX = exports.FONT_IDENTITY_MATRIX = undefined;
__w_pdfjs_require__(36);
var globalScope = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : undefined;
var FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
var TextRenderingMode = {
@ -36626,8 +36632,8 @@ exports.Type1Parser = Type1Parser;
"use strict";
var pdfjsVersion = '1.8.314';
var pdfjsBuild = '3adda80f';
var pdfjsVersion = '1.8.331';
var pdfjsBuild = '0dbc68a6';
var pdfjsCoreWorker = __w_pdfjs_require__(17);
;
exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
@ -36639,6 +36645,8 @@ exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
"use strict";
;
/***/ })
/******/ ]);
});

View file

@ -149,11 +149,11 @@ var FontInspector = (function FontInspectorClosure() {
fonts.appendChild(font);
// Somewhat of a hack, should probably add a hook for when the text layer
// is done rendering.
setTimeout(function() {
setTimeout(() => {
if (this.active) {
resetSelection();
}
}.bind(this), 2000);
}, 2000);
}
};
})();

View file

@ -91,7 +91,7 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.localized = exports.animationStarted = exports.normalizeWheelEventDelta = exports.binarySearchFirstItem = exports.watchScroll = exports.scrollIntoView = exports.getOutputScale = exports.approximateFraction = exports.roundToDivide = exports.getVisibleElements = exports.parseQueryString = exports.noContextMenuHandler = exports.getPDFFileNameFromURL = exports.ProgressBar = exports.EventBus = exports.mozL10n = exports.RendererType = exports.VERTICAL_PADDING = exports.SCROLLBAR_PADDING = exports.MAX_AUTO_SCALE = exports.UNKNOWN_SCALE = exports.MAX_SCALE = exports.MIN_SCALE = exports.DEFAULT_SCALE = exports.DEFAULT_SCALE_VALUE = exports.CSS_UNITS = undefined;
exports.localized = exports.animationStarted = exports.normalizeWheelEventDelta = exports.binarySearchFirstItem = exports.watchScroll = exports.scrollIntoView = exports.getOutputScale = exports.approximateFraction = exports.roundToDivide = exports.getVisibleElements = exports.parseQueryString = exports.noContextMenuHandler = exports.getPDFFileNameFromURL = exports.ProgressBar = exports.EventBus = exports.mozL10n = exports.RendererType = exports.cloneObj = exports.VERTICAL_PADDING = exports.SCROLLBAR_PADDING = exports.MAX_AUTO_SCALE = exports.UNKNOWN_SCALE = exports.MAX_SCALE = exports.MIN_SCALE = exports.DEFAULT_SCALE = exports.DEFAULT_SCALE_VALUE = exports.CSS_UNITS = undefined;
var _pdfjs = __webpack_require__(1);
@ -359,6 +359,15 @@ function normalizeWheelEventDelta(evt) {
}
return delta;
}
function cloneObj(obj) {
var result = {};
for (var i in obj) {
if (Object.prototype.hasOwnProperty.call(obj, i)) {
result[i] = obj[i];
}
}
return result;
}
var animationStarted = new Promise(function (resolve) {
window.requestAnimationFrame(resolve);
});
@ -479,6 +488,7 @@ exports.UNKNOWN_SCALE = UNKNOWN_SCALE;
exports.MAX_AUTO_SCALE = MAX_AUTO_SCALE;
exports.SCROLLBAR_PADDING = SCROLLBAR_PADDING;
exports.VERTICAL_PADDING = VERTICAL_PADDING;
exports.cloneObj = cloneObj;
exports.RendererType = RendererType;
exports.mozL10n = mozL10n;
exports.EventBus = EventBus;
@ -1167,6 +1177,7 @@ var PDFViewerApplication = {
this.pdfThumbnailViewer.setDocument(null);
this.pdfViewer.setDocument(null);
this.pdfLinkService.setDocument(null, null);
this.pdfDocumentProperties.setDocument(null, null);
}
this.store = null;
this.isInitialViewSet = false;
@ -1310,10 +1321,10 @@ var PDFViewerApplication = {
this.disableAutoFetchLoadingBarTimeout = null;
}
this.loadingBar.show();
this.disableAutoFetchLoadingBarTimeout = setTimeout(function () {
this.disableAutoFetchLoadingBarTimeout = setTimeout(() => {
this.loadingBar.hide();
this.disableAutoFetchLoadingBarTimeout = null;
}.bind(this), DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT);
}, DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT);
}
}
},
@ -1321,7 +1332,6 @@ var PDFViewerApplication = {
var self = this;
scale = scale || _ui_utils.UNKNOWN_SCALE;
this.pdfDocument = pdfDocument;
this.pdfDocumentProperties.setDocumentAndUrl(pdfDocument, this.url);
var downloadedPromise = pdfDocument.getDownloadInfo().then(function () {
self.downloadComplete = true;
self.loadingBar.hide();
@ -1333,6 +1343,7 @@ var PDFViewerApplication = {
var baseDocumentUrl;
baseDocumentUrl = this.baseUrl;
this.pdfLinkService.setDocument(pdfDocument, baseDocumentUrl);
this.pdfDocumentProperties.setDocument(pdfDocument, this.url);
var pdfViewer = this.pdfViewer;
pdfViewer.currentScale = scale;
pdfViewer.setDocument(pdfDocument);
@ -2273,8 +2284,8 @@ Object.defineProperty(exports, "__esModule", {
var OverlayManager = {
overlays: {},
active: null,
register: function overlayManagerRegister(name, element, callerCloseMethod, canForceClose) {
return new Promise(function (resolve) {
register(name, element, callerCloseMethod, canForceClose) {
return new Promise(resolve => {
var container;
if (!name || !element || !(container = element.parentNode)) {
throw new Error('Not enough parameters.');
@ -2288,10 +2299,10 @@ var OverlayManager = {
canForceClose: canForceClose || false
};
resolve();
}.bind(this));
});
},
unregister: function overlayManagerUnregister(name) {
return new Promise(function (resolve) {
unregister(name) {
return new Promise(resolve => {
if (!this.overlays[name]) {
throw new Error('The overlay does not exist.');
} else if (this.active === name) {
@ -2299,10 +2310,10 @@ var OverlayManager = {
}
delete this.overlays[name];
resolve();
}.bind(this));
});
},
open: function overlayManagerOpen(name) {
return new Promise(function (resolve) {
open(name) {
return new Promise(resolve => {
if (!this.overlays[name]) {
throw new Error('The overlay does not exist.');
} else if (this.active) {
@ -2319,10 +2330,10 @@ var OverlayManager = {
this.overlays[this.active].container.classList.remove('hidden');
window.addEventListener('keydown', this._keyDown);
resolve();
}.bind(this));
});
},
close: function overlayManagerClose(name) {
return new Promise(function (resolve) {
close(name) {
return new Promise(resolve => {
if (!this.overlays[name]) {
throw new Error('The overlay does not exist.');
} else if (!this.active) {
@ -2335,16 +2346,16 @@ var OverlayManager = {
this.active = null;
window.removeEventListener('keydown', this._keyDown);
resolve();
}.bind(this));
});
},
_keyDown: function overlayManager_keyDown(evt) {
_keyDown(evt) {
var self = OverlayManager;
if (self.active && evt.keyCode === 27) {
self._closeThroughCaller();
evt.preventDefault();
}
},
_closeThroughCaller: function overlayManager_closeThroughCaller() {
_closeThroughCaller() {
if (this.overlays[this.active].callerCloseMethod) {
this.overlays[this.active].callerCloseMethod();
}
@ -2895,7 +2906,7 @@ var PDFFindController = function PDFFindControllerClosure() {
}
this.state = state;
this.updateUIState(FindStates.FIND_PENDING);
this._firstPagePromise.then(function () {
this._firstPagePromise.then(() => {
this.extractText();
clearTimeout(this.findTimeout);
if (cmd === 'find') {
@ -2903,7 +2914,7 @@ var PDFFindController = function PDFFindControllerClosure() {
} else {
this.nextMatch();
}
}.bind(this));
});
},
updatePage: function PDFFindController_updatePage(index) {
if (this.selected.pageIdx === index) {
@ -3212,17 +3223,18 @@ var DownloadManager = function DownloadManagerClosure() {
});
},
download: function DownloadManager_download(blob, url, filename) {
var blobUrl = window.URL.createObjectURL(blob);
FirefoxCom.request('download', {
blobUrl,
originalUrl: url,
filename
}, function response(err) {
let blobUrl = window.URL.createObjectURL(blob);
let onResponse = err => {
if (err && this.onerror) {
this.onerror(err);
}
window.URL.revokeObjectURL(blobUrl);
}.bind(this));
};
FirefoxCom.request('download', {
blobUrl,
originalUrl: url,
filename
}, onResponse);
}
};
return DownloadManager;
@ -3608,16 +3620,16 @@ var HandTool = function HandToolClosure() {
this.handTool.activate();
}
}).catch(function rejected(reason) {});
this.eventBus.on('presentationmodechanged', function (e) {
if (e.switchInProgress) {
this.eventBus.on('presentationmodechanged', evt => {
if (evt.switchInProgress) {
return;
}
if (e.active) {
if (evt.active) {
this.enterPresentationMode();
} else {
this.exitPresentationMode();
}
}.bind(this));
});
}
HandTool.prototype = {
get isActive() {
@ -3800,8 +3812,8 @@ class PDFAttachmentViewer {
}
this._dispatchEvent(attachmentsCount);
}
_appendAttachment(item) {
this._renderedCapability.promise.then(function (id, filename, content) {
_appendAttachment({ id, filename, content }) {
this._renderedCapability.promise.then(() => {
var attachments = this.attachments;
if (!attachments) {
attachments = Object.create(null);
@ -3820,7 +3832,7 @@ class PDFAttachmentViewer {
attachments,
keepRenderedCapability: true
});
}.bind(this, item.id, item.filename, item.content));
});
}
}
exports.PDFAttachmentViewer = PDFAttachmentViewer;
@ -3843,77 +3855,101 @@ var _pdfjs = __webpack_require__(1);
var _overlay_manager = __webpack_require__(5);
const DEFAULT_FIELD_CONTENT = '-';
class PDFDocumentProperties {
constructor(options) {
this.overlayName = options.overlayName;
this.fields = options.fields;
this.container = options.container;
this.rawFileSize = 0;
this.url = null;
this.pdfDocument = null;
if (options.closeButton) {
options.closeButton.addEventListener('click', this.close.bind(this));
constructor({ overlayName, fields, container, closeButton }) {
this.overlayName = overlayName;
this.fields = fields;
this.container = container;
this._reset();
if (closeButton) {
closeButton.addEventListener('click', this.close.bind(this));
}
this._dataAvailableCapability = (0, _pdfjs.createPromiseCapability)();
_overlay_manager.OverlayManager.register(this.overlayName, this.container, this.close.bind(this));
}
open() {
let freezeFieldData = data => {
Object.defineProperty(this, 'fieldData', {
value: Object.freeze(data),
writable: false,
enumerable: true,
configurable: true
});
};
Promise.all([_overlay_manager.OverlayManager.open(this.overlayName), this._dataAvailableCapability.promise]).then(() => {
this._getProperties();
if (this.fieldData) {
this._updateUI();
return;
}
this.pdfDocument.getMetadata().then(({ info, metadata }) => {
freezeFieldData({
'fileName': (0, _ui_utils.getPDFFileNameFromURL)(this.url),
'fileSize': this._parseFileSize(this.maybeFileSize),
'title': info.Title,
'author': info.Author,
'subject': info.Subject,
'keywords': info.Keywords,
'creationDate': this._parseDate(info.CreationDate),
'modificationDate': this._parseDate(info.ModDate),
'creator': info.Creator,
'producer': info.Producer,
'version': info.PDFFormatVersion,
'pageCount': this.pdfDocument.numPages
});
this._updateUI();
return this.pdfDocument.getDownloadInfo();
}).then(({ length }) => {
let data = (0, _ui_utils.cloneObj)(this.fieldData);
data['fileSize'] = this._parseFileSize(length);
freezeFieldData(data);
this._updateUI();
});
});
}
close() {
_overlay_manager.OverlayManager.close(this.overlayName);
}
setFileSize(fileSize) {
if (fileSize > 0) {
this.rawFileSize = fileSize;
setDocument(pdfDocument, url) {
if (this.pdfDocument) {
this._reset();
this._updateUI(true);
}
if (!pdfDocument) {
return;
}
}
setDocumentAndUrl(pdfDocument, url) {
this.pdfDocument = pdfDocument;
this.url = url;
this._dataAvailableCapability.resolve();
}
_getProperties() {
if (!_overlay_manager.OverlayManager.active) {
setFileSize(fileSize) {
if (typeof fileSize === 'number' && fileSize > 0) {
this.maybeFileSize = fileSize;
}
}
_reset() {
this.pdfDocument = null;
this.url = null;
this.maybeFileSize = 0;
delete this.fieldData;
this._dataAvailableCapability = (0, _pdfjs.createPromiseCapability)();
}
_updateUI(reset = false) {
if (reset || !this.fieldData) {
for (let id in this.fields) {
this.fields[id].textContent = DEFAULT_FIELD_CONTENT;
}
return;
}
this.pdfDocument.getDownloadInfo().then(data => {
if (data.length === this.rawFileSize) {
return;
}
this.setFileSize(data.length);
this._updateUI(this.fields['fileSize'], this._parseFileSize());
});
this.pdfDocument.getMetadata().then(data => {
var content = {
'fileName': (0, _ui_utils.getPDFFileNameFromURL)(this.url),
'fileSize': this._parseFileSize(),
'title': data.info.Title,
'author': data.info.Author,
'subject': data.info.Subject,
'keywords': data.info.Keywords,
'creationDate': this._parseDate(data.info.CreationDate),
'modificationDate': this._parseDate(data.info.ModDate),
'creator': data.info.Creator,
'producer': data.info.Producer,
'version': data.info.PDFFormatVersion,
'pageCount': this.pdfDocument.numPages
};
for (var identifier in content) {
this._updateUI(this.fields[identifier], content[identifier]);
}
});
}
_updateUI(field, content) {
if (field && content !== undefined && content !== '') {
field.textContent = content;
if (_overlay_manager.OverlayManager.active !== this.overlayName) {
return;
}
for (let id in this.fields) {
let content = this.fieldData[id];
this.fields[id].textContent = content || content === 0 ? content : DEFAULT_FIELD_CONTENT;
}
}
_parseFileSize() {
var fileSize = this.rawFileSize,
kb = fileSize / 1024;
_parseFileSize(fileSize = 0) {
let kb = fileSize / 1024;
if (!kb) {
return;
} else if (kb < 1024) {
@ -3928,10 +3964,10 @@ class PDFDocumentProperties {
}, '{{size_mb}} MB ({{size_b}} bytes)');
}
_parseDate(inputDate) {
var dateToParse = inputDate;
if (dateToParse === undefined) {
return '';
if (!inputDate) {
return;
}
let dateToParse = inputDate;
if (dateToParse.substring(0, 2) === 'D:') {
dateToParse = dateToParse.substring(2);
}
@ -6020,10 +6056,10 @@ var PDFThumbnailViewer = function PDFThumbnailViewerClosure() {
if (!pdfDocument) {
return Promise.resolve();
}
return pdfDocument.getPage(1).then(function (firstPage) {
return pdfDocument.getPage(1).then(firstPage => {
var pagesCount = pdfDocument.numPages;
var viewport = firstPage.getViewport(1.0);
for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) {
for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) {
var thumbnail = new _pdf_thumbnail_view.PDFThumbnailView({
container: this.container,
id: pageNum,
@ -6034,7 +6070,7 @@ var PDFThumbnailViewer = function PDFThumbnailViewerClosure() {
});
this.thumbnails.push(thumbnail);
}
}.bind(this));
});
},
_cancelRendering: function PDFThumbnailViewer_cancelRendering() {
for (var i = 0, ii = this.thumbnails.length; i < ii; i++) {
@ -6354,8 +6390,8 @@ var PDFViewer = function pdfViewer() {
return;
}
var getPagesLeft = pagesCount;
for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) {
pdfDocument.getPage(pageNum).then(function (pageNum, pdfPage) {
for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) {
pdfDocument.getPage(pageNum).then(pdfPage => {
var pageView = this._pages[pageNum - 1];
if (!pageView.pdfPage) {
pageView.setPdfPage(pdfPage);
@ -6364,7 +6400,7 @@ var PDFViewer = function pdfViewer() {
if (--getPagesLeft === 0) {
pagesCapability.resolve();
}
}.bind(this, pageNum));
});
}
});
this.eventBus.dispatch('pagesinit', { source: this });
@ -6785,6 +6821,10 @@ exports.PDFViewer = PDFViewer;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.BasePreferences = undefined;
var _ui_utils = __webpack_require__(0);
var defaultPreferences = null;
function getDefaultPreferences() {
if (!defaultPreferences) {
@ -6811,15 +6851,6 @@ function getDefaultPreferences() {
}
return defaultPreferences;
}
function cloneObj(obj) {
var result = {};
for (var i in obj) {
if (Object.prototype.hasOwnProperty.call(obj, i)) {
result[i] = obj[i];
}
}
return result;
}
class BasePreferences {
constructor() {
if (this.constructor === BasePreferences) {
@ -6833,7 +6864,7 @@ class BasePreferences {
enumerable: true,
configurable: false
});
this.prefs = cloneObj(defaults);
this.prefs = (0, _ui_utils.cloneObj)(defaults);
return this._readFromStorage(defaults);
}).then(prefObj => {
if (prefObj) {
@ -6849,7 +6880,7 @@ class BasePreferences {
}
reset() {
return this._initializedPromise.then(() => {
this.prefs = cloneObj(this.defaults);
this.prefs = (0, _ui_utils.cloneObj)(this.defaults);
return this._writeToStorage(this.defaults);
});
}
@ -7009,18 +7040,16 @@ var SecondaryToolbar = function SecondaryToolbarClosure() {
},
_bindClickListeners: function SecondaryToolbar_bindClickListeners() {
this.toggleButton.addEventListener('click', this.toggle.bind(this));
for (var button in this.buttons) {
var element = this.buttons[button].element;
var eventName = this.buttons[button].eventName;
var close = this.buttons[button].close;
element.addEventListener('click', function (eventName, close) {
for (let button in this.buttons) {
let { element, eventName, close } = this.buttons[button];
element.addEventListener('click', evt => {
if (eventName !== null) {
this.eventBus.dispatch(eventName, { source: this });
}
if (close) {
this.close();
}
}.bind(this, eventName, close));
});
}
},
_bindHandToolListener: function SecondaryToolbar_bindHandToolListener(toggleHandToolButton) {
@ -7141,11 +7170,11 @@ var TextLayerBuilder = function TextLayerBuilderClosure() {
timeout,
enhanceTextSelection: this.enhanceTextSelection
});
this.textLayerRenderTask.promise.then(function () {
this.textLayerRenderTask.promise.then(() => {
this.textLayerDiv.appendChild(textLayerFrag);
this._finishRendering();
this.updateMatches();
}.bind(this), function (reason) {});
}, function (reason) {});
},
cancel: function TextLayerBuilder_cancel() {
if (this.textLayerRenderTask) {

View file

@ -134,7 +134,11 @@
<!ENTITY downloadsHistory.label "Show All Downloads">
<!ENTITY downloadsHistory.accesskey "S">
<!ENTITY openDownloadsFolder.label "Open Downloads Folder">
<!-- LOCALIZATION NOTE (openDownloadsFolder.label):
This command is not currently available in the user interface, but the
string was preserved by bug 1362207 to be used in a future version.
-->
<!ENTITY openDownloadsFolder.label "Open Downloads Folder">
<!ENTITY clearDownloadsButton.label "Clear Downloads">
<!ENTITY clearDownloadsButton.tooltip "Clears completed, canceled and failed downloads">

View file

@ -97,54 +97,14 @@
padding-inline-end: 10px;
}
#downloadsPanel[hasdownloads] #downloadsFooterButtons:not(.downloadsHideDropmarker) > #downloadsHistory {
padding-inline-start: 68px;
}
toolbarseparator.downloadsDropmarkerSplitter {
margin: 7px 0;
}
@item@ > toolbarseparator {
margin: 10px 0;
}
@item@:hover > toolbarseparator,
#downloadsFooter:hover toolbarseparator.downloadsDropmarkerSplitter,
#downloadsFooter[showingdropdown] toolbarseparator {
@item@:hover > toolbarseparator {
margin: 0;
}
.downloadsDropmarker {
padding: 0 21px;
}
.downloadsDropmarker > .button-box > hbox {
display: none;
}
.downloadsDropmarker > .button-box > .button-menu-dropmarker {
/* This is to override the linux !important */
-moz-appearance: none !important;
display: -moz-box;
padding: 0;
margin: 0;
}
.downloadsDropmarker > .button-box > .button-menu-dropmarker > .dropmarker-icon {
width: 16px;
height: 16px;
list-style-image: url("chrome://global/skin/icons/menubutton-dropmarker.svg");
filter: url("chrome://global/skin/filters.svg#fill");
fill: currentColor;
}
/* Override default icon size which is too small for this dropdown */
.downloadsDropmarker > .button-box > .button-menu-dropmarker {
width: 16px;
height: 16px;
}
#downloadsSummary {
-moz-user-focus: normal;
}

7
caps/.eslintrc.js Normal file
View file

@ -0,0 +1,7 @@
"use strict";
module.exports = {
"extends": [
"plugin:mozilla/recommended"
]
};

View file

@ -0,0 +1,8 @@
"use strict";
module.exports = {
"extends": [
"plugin:mozilla/mochitest-test",
"plugin:mozilla/browser-test"
]
};

View file

@ -22,8 +22,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1180921
SimpleTest.waitForExplicitFinish();
let oldAddonIdCallback = aps.setExtensionURIToAddonIdCallback(uri => uri.host);
SimpleTest.registerCleanupFunction(function() {
aps.setAddonLoadURICallback('addona', null);
aps.setAddonLoadURICallback('addonb', null);
aps.setAddonLoadURICallback("addona", null);
aps.setAddonLoadURICallback("addonb", null);
aps.setExtensionURIToAddonIdCallback(oldAddonIdCallback);
});
@ -41,28 +41,28 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1180921
return p;
}
let addonA = new Cu.Sandbox(ssm.createCodebasePrincipal(Services.io.newURI('moz-extension://addonA/'), {}),
{wantGlobalProperties: ['XMLHttpRequest']});
let addonB = new Cu.Sandbox(ssm.createCodebasePrincipal(Services.io.newURI('moz-extension://addonB/'), {}),
{wantGlobalProperties: ['XMLHttpRequest']});
let addonA = new Cu.Sandbox(ssm.createCodebasePrincipal(Services.io.newURI("moz-extension://addonA/"), {}),
{wantGlobalProperties: ["XMLHttpRequest"]});
let addonB = new Cu.Sandbox(ssm.createCodebasePrincipal(Services.io.newURI("moz-extension://addonB/"), {}),
{wantGlobalProperties: ["XMLHttpRequest"]});
function uriForDomain(d) { return d + '/tests/caps/tests/mochitest/file_data.txt' }
function uriForDomain(d) { return d + "/tests/caps/tests/mochitest/file_data.txt" }
tryLoad(addonA, uriForDomain('http://test1.example.org'))
tryLoad(addonA, uriForDomain("http://test1.example.org"))
.then(function(success) {
ok(!success, "cross-origin load should fail for addon A");
aps.setAddonLoadURICallback('addona', function(uri) { return /test1/.test(uri.host); });
aps.setAddonLoadURICallback('addonb', function(uri) { return /test2/.test(uri.host); });
return tryLoad(addonA, uriForDomain('http://test1.example.org'));
aps.setAddonLoadURICallback("addona", function(uri) { return /test1/.test(uri.host); });
aps.setAddonLoadURICallback("addonb", function(uri) { return /test2/.test(uri.host); });
return tryLoad(addonA, uriForDomain("http://test1.example.org"));
}).then(function(success) {
ok(success, "whitelisted cross-origin load of test1 should succeed for addon A");
return tryLoad(addonB, uriForDomain('http://test1.example.org'));
return tryLoad(addonB, uriForDomain("http://test1.example.org"));
}).then(function(success) {
ok(!success, "non-whitelisted cross-origin load of test1 should fail for addon B");
return tryLoad(addonB, uriForDomain('http://test2.example.org'));
return tryLoad(addonB, uriForDomain("http://test2.example.org"));
}).then(function(success) {
ok(success, "whitelisted cross-origin load of test2 should succeed for addon B");
return tryLoad(addonA, uriForDomain('http://test2.example.org'));
return tryLoad(addonA, uriForDomain("http://test2.example.org"));
}).then(function(success) {
ok(!success, "non-whitelisted cross-origin load of test2 should fail for addon A");
SimpleTest.finish();

View file

@ -21,35 +21,31 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=246699
** Test for Bug 246699
** (should produce stack information for caps errors)
**/
function isError(e)
{
function isError(e) {
return e.constructor.name === "Error" || e.constructor.name === "TypeError";
}
function hasStack(e)
{
function hasStack(e) {
return isError(e) && /inciteCaps/.test(e.stack);
}
function inciteCaps(f)
{
function inciteCaps(f) {
try {
f();
return "operation succeeded";
} catch (e if hasStack(e)) {
return "denied-stack";
} catch (e) {
if (hasStack(e)) {
return "denied-stack";
}
return "unexpected: " + e;
}
}
function tryChromeLoad()
{
function tryChromeLoad() {
window.frames[0].location = "chrome://global/content/mozilla.xhtml";
}
function tryComponentsClasses()
{
function tryComponentsClasses() {
return SpecialPowers.Components.classes["@mozilla.org/dummy;1"];
}

View file

@ -25,6 +25,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=292789
** even for ALLOW_CHROME mechanisms (<script>, <img> etc)
**/
/* import-globals-from ../../../toolkit/content/treeUtils.js */
SimpleTest.waitForExplicitFinish();
/** <script src=""> test **/
@ -75,14 +77,14 @@ function finishTest() {
function fail(event) {
is("fail", event.target.expected,
"content should not be allowed to load "+event.target.src);
"content should not be allowed to load " + event.target.src);
if (event.target.callback)
event.target.callback();
}
function success(event) {
is("success", event.target.expected,
"content should be able to load "+event.target.src);
"content should be able to load " + event.target.src);
if (event.target.callback)
event.target.callback();
}
@ -94,7 +96,7 @@ function loadImage(uri, expect, callback) {
img.expected = expect;
img.callback = callback;
img.src = uri;
//document.getElementById("content").appendChild(img);
// document.getElementById("content").appendChild(img);
}
// Start off the script src test, and have it start the img tests when complete.

View file

@ -21,14 +21,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=423375
** Test for Bug 423375
** (content shouldn't be able to load chrome: or resource:)
**/
function tryLoad(url)
{
function tryLoad(url) {
try {
window.frames[0].location = url;
return "loaded";
} catch (e if /Access.*denied/.test(String(e))) {
return "denied";
} catch (e) {
if (/Access.*denied/.test(String(e))) {
return "denied";
}
return "unexpected: " + e;
}
}

View file

@ -23,8 +23,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1161831
.QueryInterface(SpecialPowers.Ci.nsISubstitutingProtocolHandler);
SimpleTest.registerCleanupFunction(function() {
extensionHandler.setSubstitution('cherise', null);
extensionHandler.setSubstitution('liebchen', null);
extensionHandler.setSubstitution("cherise", null);
extensionHandler.setSubstitution("liebchen", null);
aps.setExtensionURILoadCallback(oldLoadCallback);
aps.setExtensionURIToAddonIdCallback(oldMapCallback);
});
@ -33,16 +33,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1161831
// First, get a file:// URI to something - open to suggestions on how to do
// this more easily.
var resURI = SpecialPowers.Services.io.newURI('resource://testing-common/resource_test_file.html');
var resURI = SpecialPowers.Services.io.newURI("resource://testing-common/resource_test_file.html");
var filePath = resourceHandler.resolveURI(resURI);
ok(filePath.startsWith('file://'), 'resource:// URI resolves where we expect: ' + filePath);
ok(filePath.startsWith("file://"), "resource:// URI resolves where we expect: " + filePath);
var fileURI = SpecialPowers.Services.io.newURI(filePath);
// Register a moz-extension:// URI.
extensionHandler.setSubstitution('cherise', fileURI);
extensionHandler.setSubstitution("cherise", fileURI);
// Alias the above.
extensionHandler.setSubstitution('liebchen', SpecialPowers.Services.io.newURI('moz-extension://cherise'));
extensionHandler.setSubstitution("liebchen", SpecialPowers.Services.io.newURI("moz-extension://cherise"));
//
// Make sure that non-file:// URIs don't work.
@ -50,7 +50,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1161831
// resource://
try {
extensionHandler.setSubstitution('interdit', resURI);
extensionHandler.setSubstitution("interdit", resURI);
ok(false, "Should have thrown for mapping moz-extension to resource");
} catch (e) {
ok(true, "Threw correctly: " + e);
@ -58,15 +58,15 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1161831
// chrome://
try {
var chromeURI = SpecialPowers.Services.io.newURI('chrome://global/content/mozilla.xhtml');
extensionHandler.setSubstitution('verboten', chromeURI);
var chromeURI = SpecialPowers.Services.io.newURI("chrome://global/content/mozilla.xhtml");
extensionHandler.setSubstitution("verboten", chromeURI);
ok(false, "Should have thrown for mapping moz-extension to chrome");
} catch (e) {
ok(true, "Threw correctly: " + e);
}
function navigateWithLocation(ifr, url) { ifr.contentWindow.location = url; }
function navigateWithSrc(ifr, url) { ifr.setAttribute('src', url); }
function navigateWithSrc(ifr, url) { ifr.setAttribute("src", url); }
function navigateFromChromeWithLocation(ifr, url) { SpecialPowers.wrap(ifr).contentWindow.location = url; }
function navigateFromChromeWithWebNav(ifr, url) {
SpecialPowers.wrap(ifr).contentWindow
@ -81,25 +81,25 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1161831
aps.setExtensionURILoadCallback(cb);
}
aps.setExtensionURIToAddonIdCallback(SpecialPowers.wrapCallback(function (uri) { return 'imaginaryaddon-' + uri.host[0]; }));
aps.setExtensionURIToAddonIdCallback(SpecialPowers.wrapCallback(function(uri) { return "imaginaryaddon-" + uri.host[0]; }));
function testLoad(url, navigate, shouldThrow) {
var ifr = document.createElement('iframe');
var ifr = document.createElement("iframe");
var p = new Promise(function(resolve, reject) {
ifr.onload = function() {
ok(true, 'Loaded ' + url);
ok(true, "Loaded " + url);
var prin = SpecialPowers.wrap(ifr.contentWindow).document.nodePrincipal;
function stripTrailingSlash(s) { return s.replace(/\/$/, ''); };
is(stripTrailingSlash(prin.URI.spec), url, 'Principal uri is correct: ' + url);
function stripPath(s) { return s.replace(/(.*\/\/.+)\/.*/, '$1'); };
is(prin.originNoSuffix, stripPath(url), 'Principal origin is correct: ' + prin.originNoSuffix);
is(prin.addonId, 'imaginaryaddon-' + url[url.indexOf('/') + 2], 'addonId is correct');
function stripTrailingSlash(s) { return s.replace(/\/$/, ""); }
is(stripTrailingSlash(prin.URI.spec), url, "Principal uri is correct: " + url);
function stripPath(s) { return s.replace(/(.*\/\/.+)\/.*/, "$1"); }
is(prin.originNoSuffix, stripPath(url), "Principal origin is correct: " + prin.originNoSuffix);
is(prin.addonId, "imaginaryaddon-" + url[url.indexOf("/") + 2], "addonId is correct");
if (/_blank/.test(url)) {
is(SpecialPowers.wrap(ifr.contentWindow).document.documentElement.innerHTML,
'<head></head><body></body>', 'blank document looks right');
"<head></head><body></body>", "blank document looks right");
} else {
is(SpecialPowers.wrap(ifr.contentWindow).document.title, 'resource test file',
'document looks right');
is(SpecialPowers.wrap(ifr.contentWindow).document.title, "resource test file",
"document looks right");
}
ifr.remove();
resolve();
@ -134,20 +134,20 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1161831
//
// Perform some loads and make sure they work correctly.
//
testLoad.bind(null, 'moz-extension://cherise', navigateFromChromeWithLocation)()
.then(testLoad.bind(null, 'moz-extension://cherise', navigateFromChromeWithWebNav))
.then(testLoad.bind(null, 'moz-extension://cherise', navigateWithLocation, /* shouldThrow = */ true))
.then(testXHR.bind(null, 'moz-extension://cherise', /* shouldError = */ true))
testLoad.bind(null, "moz-extension://cherise", navigateFromChromeWithLocation)()
.then(testLoad.bind(null, "moz-extension://cherise", navigateFromChromeWithWebNav))
.then(testLoad.bind(null, "moz-extension://cherise", navigateWithLocation, /* shouldThrow = */ true))
.then(testXHR.bind(null, "moz-extension://cherise", /* shouldError = */ true))
.then(setWhitelistCallback.bind(null, /cherise/))
.then(testLoad.bind(null, 'moz-extension://cherise', navigateWithLocation))
.then(testXHR.bind(null, 'moz-extension://cherise'))
.then(testLoad.bind(null, 'moz-extension://liebchen', navigateWithLocation, /* shouldThrow = */ true))
.then(testXHR.bind(null, 'moz-extension://liebchen', /* shouldError = */ true))
.then(testLoad.bind(null, "moz-extension://cherise", navigateWithLocation))
.then(testXHR.bind(null, "moz-extension://cherise"))
.then(testLoad.bind(null, "moz-extension://liebchen", navigateWithLocation, /* shouldThrow = */ true))
.then(testXHR.bind(null, "moz-extension://liebchen", /* shouldError = */ true))
.then(setWhitelistCallback.bind(null, /cherise|liebchen/))
.then(testLoad.bind(null, 'moz-extension://liebchen', navigateWithLocation))
.then(testLoad.bind(null, 'moz-extension://liebchen', navigateWithSrc))
.then(testLoad.bind(null, 'moz-extension://cherise', navigateWithSrc))
.then(testLoad.bind(null, 'moz-extension://cherise/_blank.html', navigateWithSrc))
.then(testLoad.bind(null, "moz-extension://liebchen", navigateWithLocation))
.then(testLoad.bind(null, "moz-extension://liebchen", navigateWithSrc))
.then(testLoad.bind(null, "moz-extension://cherise", navigateWithSrc))
.then(testLoad.bind(null, "moz-extension://cherise/_blank.html", navigateWithSrc))
.then(SimpleTest.finish.bind(SimpleTest),
function(e) { ok(false, "rejected promise: " + e); SimpleTest.finish() }
);

View file

@ -0,0 +1,7 @@
"use strict";
module.exports = {
"extends": [
"plugin:mozilla/xpcshell-test"
]
};

View file

@ -25,10 +25,10 @@ function checkOriginAttributes(prin, attrs, suffix) {
attrs = attrs || {};
do_check_eq(prin.originAttributes.appId, attrs.appId || 0);
do_check_eq(prin.originAttributes.inIsolatedMozBrowser, attrs.inIsolatedMozBrowser || false);
do_check_eq(prin.originSuffix, suffix || '');
do_check_eq(ChromeUtils.originAttributesToSuffix(attrs), suffix || '');
do_check_eq(prin.originSuffix, suffix || "");
do_check_eq(ChromeUtils.originAttributesToSuffix(attrs), suffix || "");
do_check_true(ChromeUtils.originAttributesMatchPattern(prin.originAttributes, attrs));
if (!prin.isNullPrincipal && !prin.origin.startsWith('[')) {
if (!prin.isNullPrincipal && !prin.origin.startsWith("[")) {
do_check_true(ssm.createCodebasePrincipalFromOrigin(prin.origin).equals(prin));
} else {
checkThrows(() => ssm.createCodebasePrincipalFromOrigin(prin.origin));
@ -55,33 +55,33 @@ function printAttrs(name, attrs) {
function checkValues(attrs, values) {
values = values || {};
//printAttrs("attrs", attrs);
//printAttrs("values", values);
// printAttrs("attrs", attrs);
// printAttrs("values", values);
do_check_eq(attrs.appId, values.appId || 0);
do_check_eq(attrs.userContextId, values.userContextId || 0);
do_check_eq(attrs.inIsolatedMozBrowser, values.inIsolatedMozBrowser || false);
do_check_eq(attrs.privateBrowsingId, values.privateBrowsingId || '');
do_check_eq(attrs.firstPartyDomain, values.firstPartyDomain || '');
do_check_eq(attrs.privateBrowsingId, values.privateBrowsingId || "");
do_check_eq(attrs.firstPartyDomain, values.firstPartyDomain || "");
}
function run_test() {
// Attributeless origins.
do_check_eq(ssm.getSystemPrincipal().origin, '[System Principal]');
do_check_eq(ssm.getSystemPrincipal().origin, "[System Principal]");
checkOriginAttributes(ssm.getSystemPrincipal());
var exampleOrg = ssm.createCodebasePrincipal(makeURI('http://example.org'), {});
do_check_eq(exampleOrg.origin, 'http://example.org');
var exampleOrg = ssm.createCodebasePrincipal(makeURI("http://example.org"), {});
do_check_eq(exampleOrg.origin, "http://example.org");
checkOriginAttributes(exampleOrg);
var exampleCom = ssm.createCodebasePrincipal(makeURI('https://www.example.com:123'), {});
do_check_eq(exampleCom.origin, 'https://www.example.com:123');
var exampleCom = ssm.createCodebasePrincipal(makeURI("https://www.example.com:123"), {});
do_check_eq(exampleCom.origin, "https://www.example.com:123");
checkOriginAttributes(exampleCom);
var nullPrin = Cu.getObjectPrincipal(new Cu.Sandbox(null));
do_check_true(/^moz-nullprincipal:\{([0-9]|[a-z]|\-){36}\}$/.test(nullPrin.origin));
checkOriginAttributes(nullPrin);
var ipv6Prin = ssm.createCodebasePrincipal(makeURI('https://[2001:db8::ff00:42:8329]:123'), {});
do_check_eq(ipv6Prin.origin, 'https://[2001:db8::ff00:42:8329]:123');
var ipv6Prin = ssm.createCodebasePrincipal(makeURI("https://[2001:db8::ff00:42:8329]:123"), {});
do_check_eq(ipv6Prin.origin, "https://[2001:db8::ff00:42:8329]:123");
checkOriginAttributes(ipv6Prin);
var ipv6NPPrin = ssm.createCodebasePrincipal(makeURI('https://[2001:db8::ff00:42:8329]'), {});
do_check_eq(ipv6NPPrin.origin, 'https://[2001:db8::ff00:42:8329]');
var ipv6NPPrin = ssm.createCodebasePrincipal(makeURI("https://[2001:db8::ff00:42:8329]"), {});
do_check_eq(ipv6NPPrin.origin, "https://[2001:db8::ff00:42:8329]");
checkOriginAttributes(ipv6NPPrin);
var ep = Cu.getObjectPrincipal(Cu.Sandbox([exampleCom, nullPrin, exampleOrg]));
checkOriginAttributes(ep);
@ -92,42 +92,42 @@ function run_test() {
do_check_eq(ep.origin, `[Expanded Principal [${exampleOrg.origin}, ${exampleCom.origin}, ${nullPrin.origin}]]`);
// Make sure createCodebasePrincipal does what the rest of gecko does.
do_check_true(exampleOrg.equals(Cu.getObjectPrincipal(new Cu.Sandbox('http://example.org'))));
do_check_true(exampleOrg.equals(Cu.getObjectPrincipal(new Cu.Sandbox("http://example.org"))));
//
// Test origin attributes.
//
// Just app.
var exampleOrg_app = ssm.createCodebasePrincipal(makeURI('http://example.org'), {appId: 42});
var exampleOrg_app = ssm.createCodebasePrincipal(makeURI("http://example.org"), {appId: 42});
var nullPrin_app = ssm.createNullPrincipal({appId: 42});
checkOriginAttributes(exampleOrg_app, {appId: 42}, '^appId=42');
checkOriginAttributes(nullPrin_app, {appId: 42}, '^appId=42');
do_check_eq(exampleOrg_app.origin, 'http://example.org^appId=42');
checkOriginAttributes(exampleOrg_app, {appId: 42}, "^appId=42");
checkOriginAttributes(nullPrin_app, {appId: 42}, "^appId=42");
do_check_eq(exampleOrg_app.origin, "http://example.org^appId=42");
// Just browser.
var exampleOrg_browser = ssm.createCodebasePrincipal(makeURI('http://example.org'), {inIsolatedMozBrowser: true});
var exampleOrg_browser = ssm.createCodebasePrincipal(makeURI("http://example.org"), {inIsolatedMozBrowser: true});
var nullPrin_browser = ssm.createNullPrincipal({inIsolatedMozBrowser: true});
checkOriginAttributes(exampleOrg_browser, {inIsolatedMozBrowser: true}, '^inBrowser=1');
checkOriginAttributes(nullPrin_browser, {inIsolatedMozBrowser: true}, '^inBrowser=1');
do_check_eq(exampleOrg_browser.origin, 'http://example.org^inBrowser=1');
checkOriginAttributes(exampleOrg_browser, {inIsolatedMozBrowser: true}, "^inBrowser=1");
checkOriginAttributes(nullPrin_browser, {inIsolatedMozBrowser: true}, "^inBrowser=1");
do_check_eq(exampleOrg_browser.origin, "http://example.org^inBrowser=1");
// App and browser.
var exampleOrg_appBrowser = ssm.createCodebasePrincipal(makeURI('http://example.org'), {inIsolatedMozBrowser: true, appId: 42});
var exampleOrg_appBrowser = ssm.createCodebasePrincipal(makeURI("http://example.org"), {inIsolatedMozBrowser: true, appId: 42});
var nullPrin_appBrowser = ssm.createNullPrincipal({inIsolatedMozBrowser: true, appId: 42});
checkOriginAttributes(exampleOrg_appBrowser, {appId: 42, inIsolatedMozBrowser: true}, '^appId=42&inBrowser=1');
checkOriginAttributes(nullPrin_appBrowser, {appId: 42, inIsolatedMozBrowser: true}, '^appId=42&inBrowser=1');
do_check_eq(exampleOrg_appBrowser.origin, 'http://example.org^appId=42&inBrowser=1');
checkOriginAttributes(exampleOrg_appBrowser, {appId: 42, inIsolatedMozBrowser: true}, "^appId=42&inBrowser=1");
checkOriginAttributes(nullPrin_appBrowser, {appId: 42, inIsolatedMozBrowser: true}, "^appId=42&inBrowser=1");
do_check_eq(exampleOrg_appBrowser.origin, "http://example.org^appId=42&inBrowser=1");
// App and browser, different domain.
var exampleCom_appBrowser = ssm.createCodebasePrincipal(makeURI('https://www.example.com:123'), {appId: 42, inIsolatedMozBrowser: true});
checkOriginAttributes(exampleCom_appBrowser, {appId: 42, inIsolatedMozBrowser: true}, '^appId=42&inBrowser=1');
do_check_eq(exampleCom_appBrowser.origin, 'https://www.example.com:123^appId=42&inBrowser=1');
var exampleCom_appBrowser = ssm.createCodebasePrincipal(makeURI("https://www.example.com:123"), {appId: 42, inIsolatedMozBrowser: true});
checkOriginAttributes(exampleCom_appBrowser, {appId: 42, inIsolatedMozBrowser: true}, "^appId=42&inBrowser=1");
do_check_eq(exampleCom_appBrowser.origin, "https://www.example.com:123^appId=42&inBrowser=1");
// First party Uri
var exampleOrg_firstPartyDomain = ssm.createCodebasePrincipal(makeURI('http://example.org'), {firstPartyDomain: 'example.org'});
checkOriginAttributes(exampleOrg_firstPartyDomain, { firstPartyDomain: "example.org" }, '^firstPartyDomain=example.org');
do_check_eq(exampleOrg_firstPartyDomain.origin, 'http://example.org^firstPartyDomain=example.org');
var exampleOrg_firstPartyDomain = ssm.createCodebasePrincipal(makeURI("http://example.org"), {firstPartyDomain: "example.org"});
checkOriginAttributes(exampleOrg_firstPartyDomain, { firstPartyDomain: "example.org" }, "^firstPartyDomain=example.org");
do_check_eq(exampleOrg_firstPartyDomain.origin, "http://example.org^firstPartyDomain=example.org");
// Make sure we don't crash when serializing principals with UNKNOWN_APP_ID.
try {
@ -136,7 +136,7 @@ function run_test() {
let pipe = Cc["@mozilla.org/pipe;1"].createInstance(Ci.nsIPipe);
pipe.init(false, false, 0, 0xffffffff, null);
binaryStream.setOutputStream(pipe.outputStream);
binaryStream.writeCompoundObject(simplePrin, Ci.nsISupports, true);
binaryStream.writeCompoundObject(simplePrin, Ci.nsISupports, true); // eslint-disable-line no-undef
binaryStream.close();
} catch (e) {
do_check_true(true);
@ -144,24 +144,24 @@ function run_test() {
// Just userContext.
var exampleOrg_userContext = ssm.createCodebasePrincipal(makeURI('http://example.org'), {userContextId: 42});
checkOriginAttributes(exampleOrg_userContext, { userContextId: 42 }, '^userContextId=42');
do_check_eq(exampleOrg_userContext.origin, 'http://example.org^userContextId=42');
var exampleOrg_userContext = ssm.createCodebasePrincipal(makeURI("http://example.org"), {userContextId: 42});
checkOriginAttributes(exampleOrg_userContext, { userContextId: 42 }, "^userContextId=42");
do_check_eq(exampleOrg_userContext.origin, "http://example.org^userContextId=42");
// UserContext and App.
var exampleOrg_userContextApp = ssm.createCodebasePrincipal(makeURI('http://example.org'), {appId: 24, userContextId: 42});
var exampleOrg_userContextApp = ssm.createCodebasePrincipal(makeURI("http://example.org"), {appId: 24, userContextId: 42});
var nullPrin_userContextApp = ssm.createNullPrincipal({appId: 24, userContextId: 42});
checkOriginAttributes(exampleOrg_userContextApp, {appId: 24, userContextId: 42}, '^appId=24&userContextId=42');
checkOriginAttributes(nullPrin_userContextApp, {appId: 24, userContextId: 42}, '^appId=24&userContextId=42');
do_check_eq(exampleOrg_userContextApp.origin, 'http://example.org^appId=24&userContextId=42');
checkOriginAttributes(exampleOrg_userContextApp, {appId: 24, userContextId: 42}, "^appId=24&userContextId=42");
checkOriginAttributes(nullPrin_userContextApp, {appId: 24, userContextId: 42}, "^appId=24&userContextId=42");
do_check_eq(exampleOrg_userContextApp.origin, "http://example.org^appId=24&userContextId=42");
checkSandboxOriginAttributes(null, {});
checkSandboxOriginAttributes('http://example.org', {});
checkSandboxOriginAttributes('http://example.org', {}, {originAttributes: {}});
checkSandboxOriginAttributes('http://example.org', {appId: 42}, {originAttributes: {appId: 42}});
checkSandboxOriginAttributes(['http://example.org'], {});
checkSandboxOriginAttributes(['http://example.org'], {}, {originAttributes: {}});
checkSandboxOriginAttributes(['http://example.org'], {appId: 42}, {originAttributes: {appId: 42}});
checkSandboxOriginAttributes("http://example.org", {});
checkSandboxOriginAttributes("http://example.org", {}, {originAttributes: {}});
checkSandboxOriginAttributes("http://example.org", {appId: 42}, {originAttributes: {appId: 42}});
checkSandboxOriginAttributes(["http://example.org"], {});
checkSandboxOriginAttributes(["http://example.org"], {}, {originAttributes: {}});
checkSandboxOriginAttributes(["http://example.org"], {appId: 42}, {originAttributes: {appId: 42}});
// Check that all of the above are cross-origin.
checkCrossOrigin(exampleOrg_app, exampleOrg);
@ -177,15 +177,15 @@ function run_test() {
// Check Principal kinds.
function checkKind(prin, kind) {
do_check_eq(prin.isNullPrincipal, kind == 'nullPrincipal');
do_check_eq(prin.isCodebasePrincipal, kind == 'codebasePrincipal');
do_check_eq(prin.isExpandedPrincipal, kind == 'expandedPrincipal');
do_check_eq(prin.isSystemPrincipal, kind == 'systemPrincipal');
do_check_eq(prin.isNullPrincipal, kind == "nullPrincipal");
do_check_eq(prin.isCodebasePrincipal, kind == "codebasePrincipal");
do_check_eq(prin.isExpandedPrincipal, kind == "expandedPrincipal");
do_check_eq(prin.isSystemPrincipal, kind == "systemPrincipal");
}
checkKind(ssm.createNullPrincipal({}), 'nullPrincipal');
checkKind(ssm.createCodebasePrincipal(makeURI('http://www.example.com'), {}), 'codebasePrincipal');
checkKind(Cu.getObjectPrincipal(Cu.Sandbox([ssm.createCodebasePrincipal(makeURI('http://www.example.com'), {})])), 'expandedPrincipal');
checkKind(ssm.getSystemPrincipal(), 'systemPrincipal');
checkKind(ssm.createNullPrincipal({}), "nullPrincipal");
checkKind(ssm.createCodebasePrincipal(makeURI("http://www.example.com"), {}), "codebasePrincipal");
checkKind(Cu.getObjectPrincipal(Cu.Sandbox([ssm.createCodebasePrincipal(makeURI("http://www.example.com"), {})])), "expandedPrincipal");
checkKind(ssm.getSystemPrincipal(), "systemPrincipal");
//
// Test Origin Attribute Manipulation
@ -260,7 +260,7 @@ function run_test() {
let orig = ChromeUtils.createOriginAttributesFromOrigin(uri + t[0]);
checkValues(orig, t[1]);
let mod = orig;
mod['userContextId'] = 0;
mod["userContextId"] = 0;
checkValues(mod, t[2]);
do_check_eq(ChromeUtils.originAttributesToSuffix(mod), t[3]);
});
@ -281,12 +281,12 @@ function run_test() {
let orig = ChromeUtils.createOriginAttributesFromOrigin(uri + t[0]);
checkValues(orig, t[1]);
let mod = orig;
mod['firstPartyDomain'] = "";
mod["firstPartyDomain"] = "";
checkValues(mod, t[2]);
do_check_eq(ChromeUtils.originAttributesToSuffix(mod), t[3]);
});
var fileURI = makeURI('file:///foo/bar').QueryInterface(Ci.nsIFileURL);
var fileURI = makeURI("file:///foo/bar").QueryInterface(Ci.nsIFileURL);
var fileTests = [
[true, fileURI.spec],
[false, "file://UNIVERSAL_FILE_URI_ORIGIN"],
@ -298,7 +298,7 @@ function run_test() {
});
Services.prefs.clearUserPref("security.fileuri.strict_origin_policy");
var aboutBlankURI = makeURI('about:blank');
var aboutBlankURI = makeURI("about:blank");
var aboutBlankPrin = ssm.createCodebasePrincipal(aboutBlankURI, {});
do_check_true(/^moz-nullprincipal:\{([0-9]|[a-z]|\-){36}\}$/.test(aboutBlankPrin.origin));
}

View file

@ -19,7 +19,6 @@
#include "nsIConsoleService.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIDOMLocation.h"
#include "nsIDOMWindowCollection.h"
#include "nsIDOMWindow.h"
#include "nsIObserverService.h"
@ -31,6 +30,7 @@
#include "mozilla/Printf.h"
#include "mozilla/StyleSheet.h"
#include "mozilla/StyleSheetInlines.h"
#include "mozilla/dom/Location.h"
#ifdef ENABLE_INTL_API
#include "unicode/uloc.h"
@ -42,6 +42,7 @@ nsChromeRegistry* nsChromeRegistry::gChromeRegistry;
// mozilla::TextRange and a TextRange in OSX headers.
using mozilla::StyleSheet;
using mozilla::dom::IsChromeURI;
using mozilla::dom::Location;
////////////////////////////////////////////////////////////////////////////////
@ -508,7 +509,7 @@ nsChromeRegistry::ReloadChrome()
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsPIDOMWindowOuter> domWindow = do_QueryInterface(protoWindow);
if (domWindow) {
nsIDOMLocation* location = domWindow->GetLocation();
Location* location = domWindow->Location();
if (location) {
rv = location->Reload(false);
if (NS_FAILED(rv)) return rv;

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -17,7 +17,7 @@
</head>
<body>
<div id="mount"></div>
<script type="application/javascript;version=1.8"
<script type="application/javascript"
src="chrome://devtools/content/shared/theme-switching.js"></script>
<script type="text/javascript">
const { BrowserLoader } = Components.utils.import("resource://devtools/client/shared/browser-loader.js", {});

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -65,14 +65,16 @@ return /******/ (function(modules) { // webpackBootstrap
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = assert;
function assert(condition, message) {
if (!condition) {
throw new Error(`Assertion failure: ${message}`);
}
}
module.exports = assert;
/***/ },
/***/ 802:
@ -94,7 +96,7 @@ return /******/ (function(modules) { // webpackBootstrap
} else {
root.prettyFast = factory();
}
}(this, () => {
}(this, function () {
"use strict";
var acorn = this.acorn || __webpack_require__(803);
@ -952,7 +954,7 @@ return /******/ (function(modules) { // webpackBootstrap
return result.toStringWithSourceMap({ file: options.url });
};
}));
}.bind(this)));
/***/ },
@ -5855,8 +5857,15 @@ return /******/ (function(modules) { // webpackBootstrap
"use strict";
var prettyFast = __webpack_require__(802);
var assert = __webpack_require__(223);
var _prettyFast = __webpack_require__(802);
var _prettyFast2 = _interopRequireDefault(_prettyFast);
var _assert = __webpack_require__(223);
var _assert2 = _interopRequireDefault(_assert);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function prettyPrint(_ref) {
var url = _ref.url,
@ -5864,7 +5873,7 @@ return /******/ (function(modules) { // webpackBootstrap
source = _ref.source;
try {
var prettified = prettyFast(source, {
var prettified = (0, _prettyFast2.default)(source, {
url: url,
indent: " ".repeat(indent)
});
@ -5903,7 +5912,7 @@ return /******/ (function(modules) { // webpackBootstrap
id = _msg$data.id,
args = _msg$data.args;
assert(msg.data.method === "prettyPrint", "Method must be `prettyPrint`");
(0, _assert2.default)(msg.data.method === "prettyPrint", "Method must be `prettyPrint`");
try {
var _prettyPrint = prettyPrint(args[0]),

View file

@ -11,7 +11,9 @@ support-files =
examples/sourcemaps2/main.min.js
examples/sourcemaps2/main.js
examples/sourcemaps2/main.js.map
examples/doc-asm.html
examples/doc-scripts.html
examples/doc-script-mutate.html
examples/doc-script-switching.html
examples/doc-exceptions.html
examples/doc-iframes.html
@ -22,6 +24,8 @@ support-files =
examples/doc-sourcemaps2.html
examples/doc-sourcemap-bogus.html
examples/doc-sources.html
examples/doc-return-values.html
examples/asm.js
examples/bogus-map.js
examples/entry.js
examples/exceptions.js
@ -33,6 +37,7 @@ support-files =
examples/simple1.js
examples/simple2.js
examples/frames.js
examples/script-mutate.js
examples/script-switching-02.js
examples/script-switching-01.js
examples/times2.js
@ -58,6 +63,7 @@ support-files =
[browser_dbg-navigation.js]
[browser_dbg-pretty-print.js]
[browser_dbg-pretty-print-paused.js]
[browser_dbg-scopes-mutations.js]
[browser_dbg-searching.js]
skip-if = true
[browser_dbg-sourcemaps.js]

View file

@ -8,19 +8,19 @@ function findBreakpoint(dbg, url, line) {
}
function setConditionalBreakpoint(dbg, index, condition) {
return Task.spawn(function* () {
return Task.spawn(function*() {
rightClickElement(dbg, "gutter", index);
selectMenuItem(dbg, 2);
yield waitForElement(dbg, ".conditional-breakpoint-panel input");
findElementWithSelector(dbg, ".conditional-breakpoint-panel input").focus();
// Position cursor reliably at the end of the text.
pressKey(dbg, "End")
pressKey(dbg, "End");
type(dbg, condition);
pressKey(dbg, "Enter");
});
}
add_task(function* () {
add_task(function*() {
const dbg = yield initDebugger("doc-scripts.html");
yield selectSource(dbg, "simple2");
@ -49,4 +49,3 @@ add_task(function* () {
bp = findBreakpoint(dbg, "simple2", 5);
is(bp.condition, "1", "breakpoint is created with the condition");
});

View file

@ -33,7 +33,7 @@ async function editExpression(dbg, input) {
info("updating the expression");
dblClickElement(dbg, "expressionNode", 1);
// Position cursor reliably at the end of the text.
pressKey(dbg, "End")
pressKey(dbg, "End");
type(dbg, input);
pressKey(dbg, "Enter");
await waitForDispatch(dbg, "EVALUATE_EXPRESSION");

View file

@ -0,0 +1,120 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
function getScopeNodeLabel(dbg, index) {
return findElement(dbg, "scopeNode", index).innerText;
}
function getScopeNodeValue(dbg, index) {
return findElement(dbg, "scopeValue", index).innerText;
}
function expandNode(dbg, index) {
let onLoadProperties = onLoadObjectProperties(dbg);
clickElement(dbg, "scopeNode", index);
return onLoadProperties;
}
function toggleScopes(dbg) {
return findElement(dbg, "scopesHeader").click();
}
function onLoadObjectProperties(dbg) {
return waitForDispatch(dbg, "LOAD_OBJECT_PROPERTIES");
}
add_task(async function() {
const dbg = await initDebugger("doc-script-mutate.html");
toggleScopes(dbg);
let onPaused = waitForPaused(dbg);
invokeInTab("mutate");
await onPaused;
is(
getScopeNodeLabel(dbg, 2),
"<this>",
'The second element in the scope panel is "<this>"'
);
is(
getScopeNodeLabel(dbg, 3),
"phonebook",
'The third element in the scope panel is "phonebook"'
);
// Expand `phonebook`
await expandNode(dbg, 3);
is(
getScopeNodeLabel(dbg, 4),
"S",
'The fourth element in the scope panel is "S"'
);
// Expand `S`
await expandNode(dbg, 4);
is(
getScopeNodeLabel(dbg, 5),
"sarah",
'The fifth element in the scope panel is "sarah"'
);
is(
getScopeNodeLabel(dbg, 6),
"serena",
'The sixth element in the scope panel is "serena"'
);
// Expand `sarah`
await expandNode(dbg, 5);
is(
getScopeNodeLabel(dbg, 6),
"lastName",
'The sixth element in the scope panel is now "lastName"'
);
is(
getScopeNodeValue(dbg, 6),
'"Doe"',
'The "lastName" element has the expected "Doe" value'
);
info("Resuming");
onPaused = waitForPaused(dbg);
await resume(dbg);
await onPaused;
is(
getScopeNodeLabel(dbg, 6),
"lastName",
'The sixth element in the scope panel is still "lastName"'
);
is(
getScopeNodeValue(dbg, 6),
'"Doe"',
'The "lastName" property is still "Doe", but it should be "Pierce"' +
"since it was changed in the script."
);
onPaused = waitForPaused(dbg);
await resume(dbg);
await onPaused;
is(
getScopeNodeLabel(dbg, 6),
"lastName",
'The sixth element in the scope panel is still "lastName"'
);
is(
getScopeNodeLabel(dbg, 7),
"__proto__",
'The seventh element in the scope panel is still "__proto__", ' +
'but it should be now "timezone", since it was added to the "sarah" object ' +
"in the script"
);
is(
getScopeNodeValue(dbg, 7),
"Object",
'The seventh element in the scope panel has the value "Object", ' +
'but it should be "PST"'
);
await resume(dbg);
});

View file

@ -1,11 +1,10 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
var asmjs = (function () {
var asmjs = (function() {
"use asm";
function f() {
return 1|0;
return 1 | 0;
}
return {f: f};
})()
return { f: f };
})();

View file

@ -22,6 +22,26 @@
}
}
</script>
<h3>Returns</h3>
<button onclick="return_something(2)">return(2)</button>
<button onclick="return_something(new Error('blah'))">return(error)</button>
<button onclick="return_something(undefined)">return(undefined)</button>
<button onclick="return_something(false)">return(false)</button>
<button onclick="return_something(null)">return(null)</button>
<button onclick="return_something(0)">return(0)</button>
<button onclick="return_something('yay')">return('yay')</button>
<h3>Throws</h3>
<button onclick="throw_something(2)">throw(2)</button>
<button onclick="throw_something(new Error('blah'))">throw(error)</button>
<button onclick="throw_something(undefined)">throw(undefined)</button>
<button onclick="throw_something(false)">throw(false)</button>
<button onclick="throw_something(0)">throw(0)</button>
<button onclick="throw_something(null)">throw(null)</button>
<button onclick="throw_something('yay')">throw('yay')</button>
</body>
</html>

View file

@ -0,0 +1,17 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>Debugger test page - Mutate object</title>
</head>
<body>
<button onclick="mutate()">Click me!</button>
<script type="text/javascript" src="script-mutate.js"></script>
</body>
</html>

View file

@ -6,16 +6,17 @@
<meta charset="utf-8"/>
<title>Debugger test page</title>
</head>
<body>
<script src="simple1.js"></script>
<script src="simple2.js"></script>
<script src="long.js"></script>
<script>
// This inline script allows this HTML page to show up as a
// source. It also needs to introduce a new global variable so
// it's not immediately garbage collected.
function inline_script() { var x = 5; }
function loadScript() {
const script = document.createElement("script");
script.src = "math.min.js";
document.body.appendChild(script);
}
</script>
<script src="nested/nested-source.js"></script>
<script src="nested/deeper/deeper-source.js"></script>

View file

@ -0,0 +1,20 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function mutate() {
const phonebook = {
S: {
sarah: {
lastName: "Doe"
},
serena: {
lastName: "Williams"
}
}
};
debugger;
phonebook.S.sarah.lastName = "Pierce";
debugger;
phonebook.S.sarah.timezone = "PST";
debugger;
}

View file

@ -38,7 +38,8 @@ Services.scriptloader.loadSubScript(
this
);
var { Toolbox } = require("devtools/client/framework/toolbox");
const EXAMPLE_URL = "http://example.com/browser/devtools/client/debugger/new/test/mochitest/examples/";
const EXAMPLE_URL =
"http://example.com/browser/devtools/client/debugger/new/test/mochitest/examples/";
Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", true);
@ -336,7 +337,7 @@ window.resumeTest = undefined;
*/
function pauseTest() {
info("Test paused. Invoke resumeTest to continue.");
return new Promise(resolve => resumeTest = resolve);
return new Promise(resolve => (resumeTest = resolve));
}
// Actions
@ -563,12 +564,12 @@ const cmdOrCtrl = isLinux ? { ctrlKey: true } : { metaKey: true };
// On Mac, going to beginning/end only works with meta+left/right. On
// Windows, it only works with home/end. On Linux, apparently, either
// ctrl+left/right or home/end work.
const endKey = isMac ?
{ code: "VK_RIGHT", modifiers: cmdOrCtrl } :
{ code: "VK_END" };
const startKey = isMac ?
{ code: "VK_LEFT", modifiers: cmdOrCtrl } :
{ code: "VK_HOME" };
const endKey = isMac
? { code: "VK_RIGHT", modifiers: cmdOrCtrl }
: { code: "VK_END" };
const startKey = isMac
? { code: "VK_LEFT", modifiers: cmdOrCtrl }
: { code: "VK_HOME" };
const keyMappings = {
sourceSearch: { code: "p", modifiers: cmdOrCtrl },
fileSearch: { code: "f", modifiers: cmdOrCtrl },
@ -622,16 +623,14 @@ function isVisibleWithin(outerEl, innerEl) {
const selectors = {
callStackHeader: ".call-stack-pane ._header",
callStackBody: ".call-stack-pane .pane",
expressionNode: i =>
`.expressions-list .tree-node:nth-child(${i}) .object-label`,
expressionValue: i =>
`.expressions-list .tree-node:nth-child(${i}) .object-value`,
expressionClose: i =>
`.expressions-list .expression-container:nth-child(${i}) .close`,
expressionNode: i => `.expressions-list .tree-node:nth-child(${i}) .object-label`,
expressionValue: i => `.expressions-list .tree-node:nth-child(${i}) .object-value`,
expressionClose: i => `.expressions-list .expression-container:nth-child(${i}) .close`,
expressionNodes: ".expressions-list .tree-node",
scopesHeader: ".scopes-pane ._header",
breakpointItem: i => `.breakpoints-list .breakpoint:nth-child(${i})`,
scopeNode: i => `.scopes-list .tree-node:nth-child(${i}) .object-label`,
scopeValue: i => `.scopes-list .tree-node:nth-child(${i}) .object-value`,
frame: i => `.frames ul li:nth-child(${i})`,
frames: ".frames ul li",
gutter: i => `.CodeMirror-code *:nth-child(${i}) .CodeMirror-linenumber`,

View file

@ -2408,14 +2408,17 @@ Toolbox.prototype = {
.then(() => {
this._removeHostListeners();
// `location` may already be null if the toolbox document is already
// in process of destruction. Otherwise if it is still around, ensure
// releasing toolbox document and triggering cleanup thanks to unload
// event. We do that precisely here, before nullifying the target as
// various cleanup code depends on the target attribute to be still
// `location` may already be 'invalid' if the toolbox document is
// already in process of destruction. Otherwise if it is still
// around, ensure releasing toolbox document and triggering cleanup
// thanks to unload event. We do that precisely here, before
// nullifying the target as various cleanup code depends on the
// target attribute to be still
// defined.
if (win.location) {
try {
win.location.replace("about:blank");
} catch (e) {
// Do nothing;
}
// Targets need to be notified that the toolbox is being torn down.

View file

@ -22,6 +22,14 @@ copySourceUrl=Copy Source Url
# the context menu.
copySourceUrl.accesskey=u
# LOCALIZATION NOTE (copyStackTrace): This is the text that appears in the
# context menu to copy the stack trace methods, file names and row number.
copyStackTrace=Copy Stack Trace
# LOCALIZATION NOTE (copyStackTrace.accesskey): Access key to copy the stack trace data from
# the context menu.
copyStackTrace.accesskey=c
# LOCALIZATION NOTE (expandPanes): This is the tooltip for the button
# that expands the left and right panes in the debugger UI.
expandPanes=Expand panes
@ -128,10 +136,6 @@ sources.search.key=P
# does not have any sources.
sources.noSourcesAvailable=This page has no sources
# LOCALIZATION NOTE (sources.searchAlt.key): Alternate key shortcut to open
# the search for searching all the source files the debugger has seen.
sources.searchAlt.key=O
# LOCALIZATION NOTE (sourceSearch.search.key): Key shortcut to open the search
# for searching within a the currently opened files in the editor
sourceSearch.search.key=F
@ -246,6 +250,14 @@ editor.singleResult=1 result
# for when no results found.
editor.noResults=no results
# LOCALIZATION NOTE (editor.searchResults.nextResult): Editor Search bar
# tooltip for traversing to the Next Result
editor.searchResults.nextResult=Next Result
# LOCALIZATION NOTE (editor.searchResults.prevResult): Editor Search bar
# tooltip for traversing to the Previous Result
editor.searchResults.prevResult=Previous Result
# LOCALIZATION NOTE (editor.searchTypeToggleTitle): Search bar title for
# toggling search type buttons(function search, variable search)
editor.searchTypeToggleTitle=Search for:

View file

@ -6,6 +6,7 @@
#include "ImportManager.h"
#include "mozilla/dom/ScriptLoader.h"
#include "mozilla/EventListenerManager.h"
#include "HTMLLinkElement.h"
#include "nsContentPolicyUtils.h"
@ -18,7 +19,6 @@
#include "nsIDOMEvent.h"
#include "nsIPrincipal.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsScriptLoader.h"
#include "nsNetUtil.h"
//-----------------------------------------------------------------------------
@ -156,7 +156,7 @@ ImportLoader::Updater::UpdateMainReferrer(uint32_t aNewIdx)
// Our nearest predecessor has changed. So let's add the ScriptLoader to the
// new one if there is any. And remove it from the old one.
RefPtr<ImportManager> manager = mLoader->Manager();
nsScriptLoader* loader = mLoader->mDocument->ScriptLoader();
ScriptLoader* loader = mLoader->mDocument->ScriptLoader();
ImportLoader*& pred = mLoader->mBlockingPredecessor;
ImportLoader* newPred = manager->GetNearestPredecessor(newMainReferrer);
if (pred) {
@ -339,7 +339,7 @@ ImportLoader::DispatchEventIfFinished(nsINode* aNode)
}
void
ImportLoader::AddBlockedScriptLoader(nsScriptLoader* aScriptLoader)
ImportLoader::AddBlockedScriptLoader(ScriptLoader* aScriptLoader)
{
if (mBlockedScriptLoaders.Contains(aScriptLoader)) {
return;
@ -352,7 +352,7 @@ ImportLoader::AddBlockedScriptLoader(nsScriptLoader* aScriptLoader)
}
bool
ImportLoader::RemoveBlockedScriptLoader(nsScriptLoader* aScriptLoader)
ImportLoader::RemoveBlockedScriptLoader(ScriptLoader* aScriptLoader)
{
aScriptLoader->RemoveParserBlockingScriptExecutionBlocker();
return mBlockedScriptLoaders.RemoveElement(aScriptLoader);

View file

@ -45,8 +45,8 @@
#include "nsIStreamListener.h"
#include "nsIWeakReferenceUtils.h"
#include "nsRefPtrHashtable.h"
#include "nsScriptLoader.h"
#include "nsURIHashKey.h"
#include "mozilla/dom/ScriptLoader.h"
class nsIDocument;
class nsIPrincipal;
@ -184,8 +184,8 @@ public:
// and wait for that to run its scripts. We keep track of all the
// ScriptRunners that are waiting for this import. NOTE: updating
// the main referrer might change this list.
void AddBlockedScriptLoader(nsScriptLoader* aScriptLoader);
bool RemoveBlockedScriptLoader(nsScriptLoader* aScriptLoader);
void AddBlockedScriptLoader(ScriptLoader* aScriptLoader);
bool RemoveBlockedScriptLoader(ScriptLoader* aScriptLoader);
void SetBlockingPredecessor(ImportLoader* aLoader);
private:
@ -230,7 +230,7 @@ private:
// List of pending ScriptLoaders that are waiting for this import
// to finish.
nsTArray<RefPtr<nsScriptLoader>> mBlockedScriptLoaders;
nsTArray<RefPtr<ScriptLoader>> mBlockedScriptLoaders;
// There is always exactly one referrer link that is flagged as
// the main referrer the primary link. This is the one that is

View file

@ -32,9 +32,9 @@
#include "mozilla/Likely.h"
#include "nsCycleCollectionParticipant.h"
#include "NullPrincipal.h"
#include "ScriptSettings.h"
#include "mozilla/Unused.h"
#include "mozilla/dom/LocationBinding.h"
#include "mozilla/dom/ScriptSettings.h"
namespace mozilla {
namespace dom {
@ -87,19 +87,6 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(Location)
NS_IMPL_CYCLE_COLLECTING_ADDREF(Location)
NS_IMPL_CYCLE_COLLECTING_RELEASE(Location)
void
Location::SetDocShell(nsIDocShell *aDocShell)
{
mDocShell = do_GetWeakReference(aDocShell);
}
nsIDocShell *
Location::GetDocShell()
{
nsCOMPtr<nsIDocShell> docshell(do_QueryReferent(mDocShell));
return docshell;
}
nsresult
Location::CheckURL(nsIURI* aURI, nsIDocShellLoadInfo** aLoadInfo)
{
@ -210,8 +197,12 @@ Location::GetURI(nsIURI** aURI, bool aGetInnermostURI)
{
*aURI = nullptr;
nsresult rv;
nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocShell));
if (!mDocShell) {
return NS_OK;
}
nsresult rv;
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(docShell, &rv));
if (NS_FAILED(rv)) {
return rv;
@ -896,9 +887,10 @@ Location::GetSourceBaseURL(JSContext* cx, nsIURI** sourceURL)
// this happens, try falling back on the current document associated with the
// docshell. If that fails, just return null and hope that the caller passed
// an absolute URI.
if (!doc && GetDocShell()) {
nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocShell));
if (!doc && docShell) {
nsCOMPtr<nsPIDOMWindowOuter> docShellWin =
do_QueryInterface(GetDocShell()->GetScriptGlobalObject());
do_QueryInterface(docShell->GetScriptGlobalObject());
if (docShellWin) {
doc = docShellWin->GetDoc();
}

View file

@ -37,9 +37,6 @@ public:
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(Location,
nsIDOMLocation)
void SetDocShell(nsIDocShell *aDocShell);
nsIDocShell *GetDocShell();
// nsIDOMLocation
NS_DECL_NSIDOMLOCATION
@ -233,7 +230,11 @@ protected:
// In the case of jar: uris, we sometimes want the place the jar was
// fetched from as the URI instead of the jar: uri itself. Pass in
// true for aGetInnermostURI when that's the case.
// Note, this method can return NS_OK with a null value for aURL. This happens
// if the docShell is null.
nsresult GetURI(nsIURI** aURL, bool aGetInnermostURI = false);
// Note, this method can return NS_OK with a null value for aURL. This happens
// if the docShell is null.
nsresult GetWritableURI(nsIURI** aURL,
// If not null, give it the new ref
const nsACString* aNewRef = nullptr);

View file

@ -27,7 +27,6 @@ XPIDL_SOURCES += [
'nsIObjectLoadingContent.idl',
'nsIRemoteWindowContext.idl',
'nsIScriptChannel.idl',
'nsIScriptLoaderObserver.idl',
'nsISelection.idl',
'nsISelectionController.idl',
'nsISelectionDisplay.idl',
@ -92,7 +91,6 @@ EXPORTS += [
'nsINode.h',
'nsINodeList.h',
'nsIScriptContext.h',
'nsIScriptElement.h',
'nsIScriptGlobalObject.h',
'nsIScriptNameSpaceManager.h',
'nsIScriptObjectPrincipal.h',
@ -113,7 +111,6 @@ EXPORTS += [
'nsRange.h',
'nsReferencedElement.h',
'nsSandboxFlags.h',
'nsScriptLoader.h',
'nsStructuredCloneContainer.h',
'nsStubAnimationObserver.h',
'nsStubDocumentObserver.h',
@ -198,7 +195,6 @@ EXPORTS.mozilla.dom += [
'ResponsiveImageSelector.h',
'SameProcessMessageQueue.h',
'ScreenOrientation.h',
'ScriptSettings.h',
'ShadowRoot.h',
'StructuredCloneHolder.h',
'StructuredCloneTags.h',
@ -315,8 +311,6 @@ UNIFIED_SOURCES += [
'nsRange.cpp',
'nsReferencedElement.cpp',
'nsScreen.cpp',
'nsScriptElement.cpp',
'nsScriptLoader.cpp',
'nsScriptNameSpaceManager.cpp',
'nsStructuredCloneContainer.cpp',
'nsStubAnimationObserver.cpp',
@ -343,7 +337,6 @@ UNIFIED_SOURCES += [
'ResponsiveImageSelector.cpp',
'SameProcessMessageQueue.cpp',
'ScreenOrientation.cpp',
'ScriptSettings.cpp',
'ShadowRoot.cpp',
'StructuredCloneHolder.cpp',
'StyleSheetList.cpp',

View file

@ -29,6 +29,7 @@
#include "nsInProcessTabChildGlobal.h"
#include "nsFrameLoader.h"
#include "mozilla/CycleCollectedJSContext.h"
#include "mozilla/CycleCollectedJSRuntime.h"
#include "mozilla/EventListenerManager.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ProcessGlobal.h"

View file

@ -32,7 +32,6 @@
#include "nsIDocument.h"
#include "nsIDOMEvent.h"
#include "nsWeakPtr.h"
#include "ScriptSettings.h"
using mozilla::Unused; // <snicker>
using namespace mozilla::dom;

View file

@ -125,8 +125,7 @@ nsContentPolicy::CheckPolicy(CPMethod policyMethod,
* their permissions.
*/
nsresult rv;
nsCOMArray<nsIContentPolicy> entries;
mPolicies.GetEntries(entries);
const nsCOMArray<nsIContentPolicy>& entries = mPolicies.GetCachedEntries();
nsCOMPtr<nsPIDOMWindowOuter> window;
if (nsCOMPtr<nsINode> node = do_QueryInterface(requestingContext)) {
@ -187,8 +186,8 @@ nsContentPolicy::CheckPolicy(CPMethod policyMethod,
}
}
nsCOMArray<nsISimpleContentPolicy> simpleEntries;
mSimplePolicies.GetEntries(simpleEntries);
const nsCOMArray<nsISimpleContentPolicy>& simpleEntries =
mSimplePolicies.GetCachedEntries();
count = simpleEntries.Count();
for (int32_t i = 0; i < count; i++) {
/* check the appropriate policy */

View file

@ -10,7 +10,6 @@
*/
#include "nsContentSink.h"
#include "nsScriptLoader.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "mozilla/css/Loader.h"
@ -49,6 +48,7 @@
#include "nsHTMLDNSPrefetch.h"
#include "nsIObserverService.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/ScriptLoader.h"
#include "nsParserConstants.h"
#include "nsSandboxFlags.h"

View file

@ -36,13 +36,16 @@ class nsIAtom;
class nsIChannel;
class nsIContent;
class nsNodeInfoManager;
class nsScriptLoader;
class nsIApplicationCache;
namespace mozilla {
namespace css {
class Loader;
} // namespace css
namespace dom {
class ScriptLoader;
} // namespace dom
} // namespace mozilla
#ifdef DEBUG
@ -276,7 +279,7 @@ protected:
nsCOMPtr<nsIDocShell> mDocShell;
RefPtr<mozilla::css::Loader> mCSSLoader;
RefPtr<nsNodeInfoManager> mNodeInfoManager;
RefPtr<nsScriptLoader> mScriptLoader;
RefPtr<mozilla::dom::ScriptLoader> mScriptLoader;
// back off timer notification after count
int32_t mBackoffCount;

View file

@ -2026,7 +2026,7 @@ nsDocument::Init()
mScopeObject = do_GetWeakReference(global);
MOZ_ASSERT(mScopeObject);
mScriptLoader = new nsScriptLoader(this);
mScriptLoader = new dom::ScriptLoader(this);
mozilla::HoldJSObjects(this);
@ -5011,7 +5011,7 @@ nsDocument::GetWindowInternal() const
return win;
}
nsScriptLoader*
ScriptLoader*
nsDocument::ScriptLoader()
{
return mScriptLoader;
@ -6877,9 +6877,7 @@ nsIDocument::GetLocation() const
}
nsGlobalWindow* window = nsGlobalWindow::Cast(w);
ErrorResult dummy;
RefPtr<Location> loc = window->GetLocation(dummy);
dummy.SuppressException();
RefPtr<Location> loc = window->Location();
return loc.forget();
}

View file

@ -31,7 +31,6 @@
#include "nsJSThingHashtable.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsIURI.h"
#include "nsScriptLoader.h"
#include "nsIRadioGroupContainer.h"
#include "nsILayoutHistoryState.h"
#include "nsIRequest.h"
@ -60,6 +59,7 @@
#include "mozilla/MemoryReporting.h"
#include "mozilla/PendingAnimationTracker.h"
#include "mozilla/dom/DOMImplementation.h"
#include "mozilla/dom/ScriptLoader.h"
#include "mozilla/dom/StyleSheetList.h"
#include "nsDataHashtable.h"
#include "mozilla/TimeStamp.h"
@ -742,7 +742,7 @@ public:
/**
* Get the script loader for this document
*/
virtual nsScriptLoader* ScriptLoader() override;
virtual mozilla::dom::ScriptLoader* ScriptLoader() override;
/**
* Add/Remove an element to the document's id and name hashes
@ -1492,7 +1492,7 @@ public:
RefPtr<mozilla::EventListenerManager> mListenerManager;
RefPtr<mozilla::dom::StyleSheetList> mDOMStyleSheets;
RefPtr<nsDOMStyleSheetSetList> mStyleSheetSetList;
RefPtr<nsScriptLoader> mScriptLoader;
RefPtr<mozilla::dom::ScriptLoader> mScriptLoader;
nsDocHeaderData* mHeaderData;
/* mIdentifierMap works as follows for IDs:
* 1) Attribute changes affect the table immediately (removing and adding

View file

@ -18,7 +18,7 @@
#include "nsJSUtils.h"
#include "nsJSPrincipals.h"
#include "nsNetUtil.h"
#include "nsScriptLoader.h"
#include "mozilla/dom/ScriptLoader.h"
#include "nsFrameLoader.h"
#include "nsIInputStream.h"
#include "nsIXULRuntime.h"
@ -256,17 +256,13 @@ nsFrameMessageManager::AddMessageListener(const nsAString& aMessage,
nsIMessageListener* aListener,
bool aListenWhenClosed)
{
nsAutoTObserverArray<nsMessageListenerInfo, 1>* listeners =
mListeners.Get(aMessage);
if (!listeners) {
listeners = new nsAutoTObserverArray<nsMessageListenerInfo, 1>();
mListeners.Put(aMessage, listeners);
} else {
uint32_t len = listeners->Length();
for (uint32_t i = 0; i < len; ++i) {
if (listeners->ElementAt(i).mStrongListener == aListener) {
return NS_OK;
}
auto listeners = mListeners.LookupForAdd(aMessage).OrInsert([]() {
return new nsAutoTObserverArray<nsMessageListenerInfo, 1>();
});
uint32_t len = listeners->Length();
for (uint32_t i = 0; i < len; ++i) {
if (listeners->ElementAt(i).mStrongListener == aListener) {
return NS_OK;
}
}
@ -323,17 +319,13 @@ nsFrameMessageManager::AddWeakMessageListener(const nsAString& aMessage,
}
#endif
nsAutoTObserverArray<nsMessageListenerInfo, 1>* listeners =
mListeners.Get(aMessage);
if (!listeners) {
listeners = new nsAutoTObserverArray<nsMessageListenerInfo, 1>();
mListeners.Put(aMessage, listeners);
} else {
uint32_t len = listeners->Length();
for (uint32_t i = 0; i < len; ++i) {
if (listeners->ElementAt(i).mWeakListener == weak) {
return NS_OK;
}
auto listeners = mListeners.LookupForAdd(aMessage).OrInsert([]() {
return new nsAutoTObserverArray<nsMessageListenerInfo, 1>();
});
uint32_t len = listeners->Length();
for (uint32_t i = 0; i < len; ++i) {
if (listeners->ElementAt(i).mWeakListener == weak) {
return NS_OK;
}
}
@ -1640,9 +1632,9 @@ nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript(
if (NS_FAILED(NS_ReadInputStreamToString(input, buffer, avail))) {
return;
}
nsScriptLoader::ConvertToUTF16(channel, (uint8_t*)buffer.get(), avail,
EmptyString(), nullptr,
dataStringBuf, dataStringLength);
ScriptLoader::ConvertToUTF16(channel, (uint8_t*)buffer.get(), avail,
EmptyString(), nullptr,
dataStringBuf, dataStringLength);
}
JS::SourceBufferHolder srcBuf(dataStringBuf, dataStringLength,

View file

@ -64,7 +64,7 @@
#include "nsReadableUtils.h"
#include "nsDOMClassInfo.h"
#include "nsJSEnvironment.h"
#include "ScriptSettings.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/Preferences.h"
#include "mozilla/Likely.h"
#include "mozilla/Sprintf.h"
@ -1933,7 +1933,6 @@ nsGlobalWindow::CleanUp()
mPersonalbar = nullptr;
mStatusbar = nullptr;
mScrollbars = nullptr;
mLocation = nullptr;
mHistory = nullptr;
mCustomElements = nullptr;
mFrames = nullptr;
@ -2096,7 +2095,6 @@ nsGlobalWindow::FreeInnerObjects()
mListenerManager = nullptr;
}
mLocation = nullptr;
mHistory = nullptr;
mCustomElements = nullptr;
@ -10440,28 +10438,17 @@ nsGlobalWindow::GetPrivateRoot()
}
Location*
nsGlobalWindow::GetLocation(ErrorResult& aError)
nsGlobalWindow::Location()
{
MOZ_RELEASE_ASSERT(IsInnerWindow());
nsIDocShell *docShell = GetDocShell();
if (!mLocation && docShell) {
mLocation = new Location(AsInner(), docShell);
if (!mLocation) {
mLocation = new dom::Location(AsInner(), GetDocShell());
}
return mLocation;
}
nsIDOMLocation*
nsGlobalWindow::GetLocation()
{
FORWARD_TO_INNER(GetLocation, (), nullptr);
ErrorResult dummy;
nsIDOMLocation* location = GetLocation(dummy);
dummy.SuppressException();
return location;
}
void
nsGlobalWindow::ActivateOrDeactivate(bool aActivate)
{

View file

@ -855,8 +855,7 @@ public:
void GetName(nsAString& aName, mozilla::ErrorResult& aError);
void SetNameOuter(const nsAString& aName, mozilla::ErrorResult& aError);
void SetName(const nsAString& aName, mozilla::ErrorResult& aError);
mozilla::dom::Location* GetLocation(mozilla::ErrorResult& aError);
nsIDOMLocation* GetLocation() override;
mozilla::dom::Location* Location() override;
nsHistory* GetHistory(mozilla::ErrorResult& aError);
mozilla::dom::CustomElementRegistry* CustomElements() override;
mozilla::dom::BarProp* GetLocationbar(mozilla::ErrorResult& aError);

View file

@ -92,7 +92,6 @@ class nsIVariant;
class nsViewManager;
class nsPresContext;
class nsRange;
class nsScriptLoader;
class nsSMILAnimationController;
class nsSVGElement;
class nsTextNode;
@ -154,6 +153,7 @@ class NodeIterator;
enum class OrientationType : uint8_t;
class ProcessingInstruction;
class Promise;
class ScriptLoader;
class StyleSheetList;
class SVGDocument;
class SVGSVGElement;
@ -1368,7 +1368,7 @@ public:
/**
* Get the script loader for this document
*/
virtual nsScriptLoader* ScriptLoader() = 0;
virtual mozilla::dom::ScriptLoader* ScriptLoader() = 0;
/**
* Add/Remove an element to the document's id and name hashes

View file

@ -11,13 +11,13 @@
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsComponentManagerUtils.h"
#include "nsScriptLoader.h"
#include "nsFrameLoader.h"
#include "xpcpublic.h"
#include "nsIMozBrowserFrame.h"
#include "nsDOMClassInfoID.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/dom/SameProcessMessageQueue.h"
#include "mozilla/dom/ScriptLoader.h"
using namespace mozilla;
using namespace mozilla::dom;

View file

@ -37,7 +37,6 @@
#include "nsXPCOMCIDInternal.h"
#include "nsIXULRuntime.h"
#include "nsTextFormatter.h"
#include "ScriptSettings.h"
#ifdef XP_WIN
#include <process.h>
#define getpid _getpid
@ -60,6 +59,7 @@
#include "mozilla/dom/DOMException.h"
#include "mozilla/dom/DOMExceptionBinding.h"
#include "mozilla/dom/ErrorEvent.h"
#include "mozilla/dom/ScriptSettings.h"
#include "nsAXPCNativeCallContext.h"
#include "mozilla/CycleCollectedJSRuntime.h"
#include "mozilla/SystemGroup.h"

View file

@ -91,6 +91,9 @@ enum class FullscreenReason
namespace mozilla {
namespace dom {
class Location;
// The states in this enum represent the different possible outcomes which the
// window could be experiencing of loading a document with the
// Large-Allocation header. The NONE case represents the case where no
@ -570,7 +573,7 @@ public:
virtual nsIDOMScreen* GetScreen() = 0;
virtual nsIDOMNavigator* GetNavigator() = 0;
virtual nsIDOMLocation* GetLocation() = 0;
virtual mozilla::dom::Location* Location() = 0;
virtual nsresult GetPrompter(nsIPrompt** aPrompt) = 0;
virtual nsresult GetControllers(nsIControllers** aControllers) = 0;
virtual already_AddRefed<nsISelection> GetSelection() = 0;

View file

@ -16,6 +16,7 @@
#include "mozilla/Attributes.h"
#include "nsCOMPtr.h"
#include "nsIAtom.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIContentSerializer.h"
#include "nsIDocumentEncoder.h"
#include "nsILineBreaker.h"

View file

@ -2,7 +2,7 @@
<html>
<!-- https://bugzilla.mozilla.org/show_bug.cgi?id=900784 -->
<!-- The JS bytecode cache is not supposed to be observable. To make it
observable, the nsScriptLoader is instrumented to trigger events on the
observable, the ScriptLoader is instrumented to trigger events on the
script tag. These events are followed to reconstruct the code path taken by
the script loader and associate a simple name which is checked in these
test cases.
@ -14,7 +14,7 @@
<script src="/resources/testharnessreport.js"></script>
<script type="application/javascript">
// This is the state machine of the trace events produced by the
// nsScriptLoader. This state machine is used to give a name to each
// ScriptLoader. This state machine is used to give a name to each
// code path, such that we can assert each code path with a single word.
var scriptLoaderStateMachine = {
"scriptloader_load_source": {
@ -112,7 +112,7 @@
promise_test(async function() {
// Setting dom.expose_test_interfaces pref causes the
// nsScriptLoadRequest to fire event on script tags, with information
// about its internal state. The nsScriptLoader source send events to
// about its internal state. The ScriptLoader source send events to
// trace these and resolve a promise with the path taken by the
// script loader.
//

View file

@ -211,12 +211,9 @@ nsControllerCommandGroup::AddCommandToGroup(const char* aCommand,
const char* aGroup)
{
nsDependentCString groupKey(aGroup);
nsTArray<nsCString>* commandList = mGroupsHash.Get(groupKey);
if (!commandList) {
// make this list
commandList = new AutoTArray<nsCString, 8>;
mGroupsHash.Put(groupKey, commandList);
}
auto commandList = mGroupsHash.LookupForAdd(groupKey).OrInsert([]() {
return new AutoTArray<nsCString, 8>();
});
#ifdef DEBUG
nsCString* appended =

View file

@ -12,6 +12,7 @@
#include "mozilla/dom/File.h"
#include "mozilla/dom/FunctionBinding.h"
#include "mozilla/dom/Performance.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/StructuredCloneHolder.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/WorkletGlobalScope.h"
@ -22,7 +23,6 @@
#include "nsGlobalWindow.h"
#include "nsJSUtils.h"
#include "nsNetUtil.h"
#include "ScriptSettings.h"
#include "WorkerPrivate.h"
#include "WorkerRunnable.h"
#include "WorkerScope.h"

View file

@ -8,7 +8,7 @@
#include "nsIDocument.h"
#include "mozilla/Sprintf.h"
#include "nsGlobalWindow.h"
#include "ScriptSettings.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/EventListenerManager.h"

View file

@ -38,7 +38,7 @@ HTMLScriptElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
HTMLScriptElement::HTMLScriptElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
FromParser aFromParser)
: nsGenericHTMLElement(aNodeInfo)
, nsScriptElement(aFromParser)
, ScriptElement(aFromParser)
{
AddMutationObserver(this);
}

View file

@ -8,16 +8,16 @@
#define mozilla_dom_HTMLScriptElement_h
#include "nsIDOMHTMLScriptElement.h"
#include "nsScriptElement.h"
#include "nsGenericHTMLElement.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/ScriptElement.h"
namespace mozilla {
namespace dom {
class HTMLScriptElement final : public nsGenericHTMLElement,
public nsIDOMHTMLScriptElement,
public nsScriptElement
public ScriptElement
{
public:
using Element::GetText;
@ -97,7 +97,8 @@ protected:
virtual ~HTMLScriptElement();
virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
// nsScriptElement
// ScriptElement
virtual bool HasScriptContent() override;
};

View file

@ -49,7 +49,6 @@
#include "nsIDocShell.h"
#include "nsNameSpaceManager.h"
#include "nsError.h"
#include "nsScriptLoader.h"
#include "nsIPrincipal.h"
#include "nsContainerFrame.h"
#include "nsStyleUtil.h"
@ -91,6 +90,7 @@
#include "mozilla/dom/FromParser.h"
#include "mozilla/dom/Link.h"
#include "mozilla/BloomFilter.h"
#include "mozilla/dom/ScriptLoader.h"
#include "nsVariant.h"
#include "nsDOMTokenList.h"

View file

@ -19,10 +19,10 @@
#include "nsIHTMLContentSink.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsScriptLoader.h"
#include "nsIURI.h"
#include "nsIContentViewer.h"
#include "mozilla/dom/NodeInfo.h"
#include "mozilla/dom/ScriptLoader.h"
#include "nsToken.h"
#include "nsIAppShell.h"
#include "nsCRT.h"

View file

@ -7,7 +7,6 @@
interface nsIControllers;
interface nsIDOMBlob;
interface nsIDOMLocation;
interface nsIDOMOfflineResourceList;
interface nsIPrompt;
interface nsISelection;

View file

@ -8,7 +8,6 @@
#include "nsIDOMDocument.h" // for nsIDOMDocument
#include "nsIDOMEvent.h" // for nsIDOMEvent
#include "nsIDOMLocation.h" // for nsIDOMLocation
#include "nsIURI.h" // for nsIURI
#include "TabChild.h" // for TabChildGlobal, TabChildBase
#include "mozilla/Telemetry.h" // for mozilla::Telemetry

View file

@ -16,6 +16,7 @@
#include "mozilla/dom/MessagePortBinding.h"
#include "mozilla/dom/MessagePortChild.h"
#include "mozilla/dom/PMessagePort.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/StructuredCloneTags.h"
#include "mozilla/dom/WorkerPrivate.h"
#include "mozilla/dom/WorkerScope.h"
@ -28,7 +29,6 @@
#include "nsContentUtils.h"
#include "nsGlobalWindow.h"
#include "nsPresContext.h"
#include "ScriptSettings.h"
#include "SharedMessagePortMessage.h"
#include "nsIBFCacheEntry.h"

View file

@ -104,6 +104,7 @@ DIRS += [
'webbrowserpersist',
'xhr',
'worklet',
'script',
]
if CONFIG['OS_ARCH'] == 'WINNT':

View file

@ -0,0 +1,103 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#include "ModuleLoadRequest.h"
#include "ModuleScript.h"
#include "ScriptLoader.h"
namespace mozilla {
namespace dom {
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ModuleLoadRequest)
NS_INTERFACE_MAP_END_INHERITING(ScriptLoadRequest)
NS_IMPL_CYCLE_COLLECTION_INHERITED(ModuleLoadRequest, ScriptLoadRequest,
mBaseURL,
mLoader,
mParent,
mModuleScript,
mImports)
NS_IMPL_ADDREF_INHERITED(ModuleLoadRequest, ScriptLoadRequest)
NS_IMPL_RELEASE_INHERITED(ModuleLoadRequest, ScriptLoadRequest)
ModuleLoadRequest::ModuleLoadRequest(nsIScriptElement* aElement,
uint32_t aVersion,
CORSMode aCORSMode,
const SRIMetadata& aIntegrity,
ScriptLoader* aLoader)
: ScriptLoadRequest(ScriptKind::Module,
aElement,
aVersion,
aCORSMode,
aIntegrity),
mIsTopLevel(true),
mLoader(aLoader)
{}
void
ModuleLoadRequest::Cancel()
{
ScriptLoadRequest::Cancel();
mModuleScript = nullptr;
mProgress = ScriptLoadRequest::Progress::Ready;
for (size_t i = 0; i < mImports.Length(); i++) {
mImports[i]->Cancel();
}
mReady.RejectIfExists(NS_ERROR_FAILURE, __func__);
}
void
ModuleLoadRequest::SetReady()
{
#ifdef DEBUG
for (size_t i = 0; i < mImports.Length(); i++) {
MOZ_ASSERT(mImports[i]->IsReadyToRun());
}
#endif
ScriptLoadRequest::SetReady();
mReady.ResolveIfExists(true, __func__);
}
void
ModuleLoadRequest::ModuleLoaded()
{
// A module that was found to be marked as fetching in the module map has now
// been loaded.
mModuleScript = mLoader->GetFetchedModule(mURI);
mLoader->StartFetchingModuleDependencies(this);
}
void
ModuleLoadRequest::DependenciesLoaded()
{
// The module and all of its dependencies have been successfully fetched and
// compiled.
if (!mLoader->InstantiateModuleTree(this)) {
LoadFailed();
return;
}
SetReady();
mLoader->ProcessLoadedModuleTree(this);
mLoader = nullptr;
mParent = nullptr;
}
void
ModuleLoadRequest::LoadFailed()
{
Cancel();
mLoader->ProcessLoadedModuleTree(this);
mLoader = nullptr;
mParent = nullptr;
}
} // dom namespace
} // mozilla namespace

View file

@ -0,0 +1,82 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_dom_ModuleLoadRequest_h
#define mozilla_dom_ModuleLoadRequest_h
#include "ScriptLoadRequest.h"
#include "mozilla/MozPromise.h"
namespace mozilla {
namespace dom {
class ModuleScript;
class ScriptLoader;
// A load request for a module, created for every top level module script and
// every module import. Load request can share an ModuleScript if there are
// multiple imports of the same module.
class ModuleLoadRequest final : public ScriptLoadRequest
{
~ModuleLoadRequest() = default;
ModuleLoadRequest(const ModuleLoadRequest& aOther) = delete;
ModuleLoadRequest(ModuleLoadRequest&& aOther) = delete;
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ModuleLoadRequest, ScriptLoadRequest)
ModuleLoadRequest(nsIScriptElement* aElement,
uint32_t aVersion,
CORSMode aCORSMode,
const SRIMetadata& aIntegrity,
ScriptLoader* aLoader);
bool IsTopLevel() const
{
return mIsTopLevel;
}
void SetReady() override;
void Cancel() override;
void ModuleLoaded();
void DependenciesLoaded();
void LoadFailed();
// Is this a request for a top level module script or an import?
bool mIsTopLevel;
// The base URL used for resolving relative module imports.
nsCOMPtr<nsIURI> mBaseURL;
// Pointer to the script loader, used to trigger actions when the module load
// finishes.
RefPtr<ScriptLoader> mLoader;
// The importing module, or nullptr for top level module scripts. Used to
// implement the ancestor list checked when fetching module dependencies.
RefPtr<ModuleLoadRequest> mParent;
// Set to a module script object after a successful load or nullptr on
// failure.
RefPtr<ModuleScript> mModuleScript;
// A promise that is completed on successful load of this module and all of
// its dependencies, indicating that the module is ready for instantiation and
// evaluation.
MozPromiseHolder<GenericPromise> mReady;
// Array of imported modules.
nsTArray<RefPtr<ModuleLoadRequest>> mImports;
};
} // dom namespace
} // mozilla namespace
#endif // mozilla_dom_ModuleLoadRequest_h

View file

@ -0,0 +1,96 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#include "ModuleScript.h"
#include "mozilla/HoldDropJSObjects.h"
#include "ScriptLoader.h"
namespace mozilla {
namespace dom {
// A single module script. May be used to satisfy multiple load requests.
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ModuleScript)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_CLASS(ModuleScript)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ModuleScript)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoader)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBaseURL)
tmp->UnlinkModuleRecord();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ModuleScript)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoader)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ModuleScript)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mModuleRecord)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mException)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(ModuleScript)
NS_IMPL_CYCLE_COLLECTING_RELEASE(ModuleScript)
ModuleScript::ModuleScript(ScriptLoader* aLoader, nsIURI* aBaseURL,
JS::Handle<JSObject*> aModuleRecord)
: mLoader(aLoader),
mBaseURL(aBaseURL),
mModuleRecord(aModuleRecord),
mInstantiationState(Uninstantiated)
{
MOZ_ASSERT(mLoader);
MOZ_ASSERT(mBaseURL);
MOZ_ASSERT(mModuleRecord);
MOZ_ASSERT(mException.isUndefined());
// Make module's host defined field point to this module script object.
// This is cleared in the UnlinkModuleRecord().
JS::SetModuleHostDefinedField(mModuleRecord, JS::PrivateValue(this));
HoldJSObjects(this);
}
void
ModuleScript::UnlinkModuleRecord()
{
// Remove module's back reference to this object request if present.
if (mModuleRecord) {
MOZ_ASSERT(JS::GetModuleHostDefinedField(mModuleRecord).toPrivate() ==
this);
JS::SetModuleHostDefinedField(mModuleRecord, JS::UndefinedValue());
}
mModuleRecord = nullptr;
mException.setUndefined();
}
ModuleScript::~ModuleScript()
{
if (mModuleRecord) {
// The object may be destroyed without being unlinked first.
UnlinkModuleRecord();
}
DropJSObjects(this);
}
void
ModuleScript::SetInstantiationResult(JS::Handle<JS::Value> aMaybeException)
{
MOZ_ASSERT(mInstantiationState == Uninstantiated);
MOZ_ASSERT(mModuleRecord);
MOZ_ASSERT(mException.isUndefined());
if (aMaybeException.isUndefined()) {
mInstantiationState = Instantiated;
} else {
mModuleRecord = nullptr;
mException = aMaybeException;
mInstantiationState = Errored;
}
}
} // dom namespace
} // mozilla namespace

73
dom/script/ModuleScript.h Normal file
View file

@ -0,0 +1,73 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_dom_ModuleScript_h
#define mozilla_dom_ModuleScript_h
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "jsapi.h"
class nsIURI;
namespace mozilla {
namespace dom {
class ScriptLoader;
class ModuleScript final : public nsISupports
{
enum InstantiationState {
Uninstantiated,
Instantiated,
Errored
};
RefPtr<ScriptLoader> mLoader;
nsCOMPtr<nsIURI> mBaseURL;
JS::Heap<JSObject*> mModuleRecord;
JS::Heap<JS::Value> mException;
InstantiationState mInstantiationState;
~ModuleScript();
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ModuleScript)
ModuleScript(ScriptLoader* aLoader,
nsIURI* aBaseURL,
JS::Handle<JSObject*> aModuleRecord);
ScriptLoader* Loader() const { return mLoader; }
JSObject* ModuleRecord() const { return mModuleRecord; }
JS::Value Exception() const { return mException; }
nsIURI* BaseURL() const { return mBaseURL; }
void SetInstantiationResult(JS::Handle<JS::Value> aMaybeException);
bool IsUninstantiated() const
{
return mInstantiationState == Uninstantiated;
}
bool IsInstantiated() const
{
return mInstantiationState == Instantiated;
}
bool InstantiationFailed() const
{
return mInstantiationState == Errored;
}
void UnlinkModuleRecord();
};
} // dom namespace
} // mozilla namespace
#endif // mozilla_dom_ModuleScript_h

View file

@ -4,13 +4,13 @@
* 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/. */
#include "nsScriptElement.h"
#include "ScriptElement.h"
#include "ScriptLoader.h"
#include "mozilla/BasicEvents.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/dom/Element.h"
#include "nsContentUtils.h"
#include "nsPresContext.h"
#include "nsScriptLoader.h"
#include "nsIParser.h"
#include "nsGkAtoms.h"
#include "nsContentSink.h"
@ -19,11 +19,11 @@ using namespace mozilla;
using namespace mozilla::dom;
NS_IMETHODIMP
nsScriptElement::ScriptAvailable(nsresult aResult,
nsIScriptElement *aElement,
bool aIsInline,
nsIURI *aURI,
int32_t aLineNo)
ScriptElement::ScriptAvailable(nsresult aResult,
nsIScriptElement* aElement,
bool aIsInline,
nsIURI* aURI,
int32_t aLineNo)
{
if (!aIsInline && NS_FAILED(aResult)) {
nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser);
@ -40,7 +40,7 @@ nsScriptElement::ScriptAvailable(nsresult aResult,
}
/* virtual */ nsresult
nsScriptElement::FireErrorEvent()
ScriptElement::FireErrorEvent()
{
nsCOMPtr<nsIContent> cont =
do_QueryInterface((nsIScriptElement*) this);
@ -53,9 +53,9 @@ nsScriptElement::FireErrorEvent()
}
NS_IMETHODIMP
nsScriptElement::ScriptEvaluated(nsresult aResult,
nsIScriptElement *aElement,
bool aIsInline)
ScriptElement::ScriptEvaluated(nsresult aResult,
nsIScriptElement* aElement,
bool aIsInline)
{
nsresult rv = NS_OK;
if (!aIsInline) {
@ -78,44 +78,44 @@ nsScriptElement::ScriptEvaluated(nsresult aResult,
}
void
nsScriptElement::CharacterDataChanged(nsIDocument *aDocument,
nsIContent* aContent,
CharacterDataChangeInfo* aInfo)
ScriptElement::CharacterDataChanged(nsIDocument* aDocument,
nsIContent* aContent,
CharacterDataChangeInfo* aInfo)
{
MaybeProcessScript();
}
void
nsScriptElement::AttributeChanged(nsIDocument* aDocument,
Element* aElement,
int32_t aNameSpaceID,
nsIAtom* aAttribute,
int32_t aModType,
const nsAttrValue* aOldValue)
ScriptElement::AttributeChanged(nsIDocument* aDocument,
Element* aElement,
int32_t aNameSpaceID,
nsIAtom* aAttribute,
int32_t aModType,
const nsAttrValue* aOldValue)
{
MaybeProcessScript();
}
void
nsScriptElement::ContentAppended(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aFirstNewContent,
int32_t aNewIndexInContainer)
ScriptElement::ContentAppended(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aFirstNewContent,
int32_t aNewIndexInContainer)
{
MaybeProcessScript();
}
void
nsScriptElement::ContentInserted(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
int32_t aIndexInContainer)
ScriptElement::ContentInserted(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
int32_t aIndexInContainer)
{
MaybeProcessScript();
}
bool
nsScriptElement::MaybeProcessScript()
ScriptElement::MaybeProcessScript()
{
nsCOMPtr<nsIContent> cont =
do_QueryInterface((nsIScriptElement*) this);
@ -145,6 +145,6 @@ nsScriptElement::MaybeProcessScript()
}
}
RefPtr<nsScriptLoader> loader = ownerDoc->ScriptLoader();
RefPtr<ScriptLoader> loader = ownerDoc->ScriptLoader();
return loader->ProcessScriptElement(this);
}

View file

@ -4,22 +4,25 @@
* 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/. */
#ifndef nsScriptElement_h
#define nsScriptElement_h
#ifndef mozilla_dom_ScriptElement_h
#define mozilla_dom_ScriptElement_h
#include "mozilla/Attributes.h"
#include "nsIScriptLoaderObserver.h"
#include "nsIScriptElement.h"
#include "nsStubMutationObserver.h"
namespace mozilla {
namespace dom {
/**
* Baseclass useful for script elements (such as <xhtml:script> and
* <svg:script>). Currently the class assumes that only the 'src'
* attribute and the children of the class affect what script to execute.
*/
class nsScriptElement : public nsIScriptElement,
public nsStubMutationObserver
class ScriptElement : public nsIScriptElement,
public nsStubMutationObserver
{
public:
// nsIScriptLoaderObserver
@ -31,7 +34,7 @@ public:
NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
explicit nsScriptElement(mozilla::dom::FromParser aFromParser)
explicit ScriptElement(FromParser aFromParser)
: nsIScriptElement(aFromParser)
{
}
@ -49,4 +52,7 @@ protected:
virtual bool MaybeProcessScript() override;
};
#endif // nsScriptElement_h
} // dom namespace
} // mozilla namespace
#endif // mozilla_dom_ScriptElement_h

View file

@ -0,0 +1,388 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#include "ScriptLoadHandler.h"
#include "ScriptLoader.h"
#include "ScriptTrace.h"
#include "mozilla/dom/EncodingUtils.h"
#include "mozilla/Telemetry.h"
namespace mozilla {
namespace dom {
#undef LOG
#define LOG(args) \
MOZ_LOG(ScriptLoader::gScriptLoaderLog, mozilla::LogLevel::Debug, args)
#define LOG_ENABLED() \
MOZ_LOG_TEST(ScriptLoader::gScriptLoaderLog, mozilla::LogLevel::Debug)
ScriptLoadHandler::ScriptLoadHandler(ScriptLoader* aScriptLoader,
ScriptLoadRequest* aRequest,
SRICheckDataVerifier* aSRIDataVerifier)
: mScriptLoader(aScriptLoader),
mRequest(aRequest),
mSRIDataVerifier(aSRIDataVerifier),
mSRIStatus(NS_OK),
mDecoder()
{
MOZ_ASSERT(mRequest->IsUnknownDataType());
MOZ_ASSERT(mRequest->IsLoading());
}
ScriptLoadHandler::~ScriptLoadHandler()
{}
NS_IMPL_ISUPPORTS(ScriptLoadHandler, nsIIncrementalStreamLoaderObserver)
NS_IMETHODIMP
ScriptLoadHandler::OnIncrementalData(nsIIncrementalStreamLoader* aLoader,
nsISupports* aContext,
uint32_t aDataLength,
const uint8_t* aData,
uint32_t* aConsumedLength)
{
if (mRequest->IsCanceled()) {
// If request cancelled, ignore any incoming data.
*aConsumedLength = aDataLength;
return NS_OK;
}
nsresult rv = NS_OK;
if (mRequest->IsUnknownDataType()) {
rv = EnsureKnownDataType(aLoader);
NS_ENSURE_SUCCESS(rv, rv);
}
if (mRequest->IsSource()) {
if (!EnsureDecoder(aLoader, aData, aDataLength,
/* aEndOfStream = */ false)) {
return NS_OK;
}
// Below we will/shall consume entire data chunk.
*aConsumedLength = aDataLength;
// Decoder has already been initialized. -- trying to decode all loaded bytes.
rv = DecodeRawData(aData, aDataLength, /* aEndOfStream = */ false);
NS_ENSURE_SUCCESS(rv, rv);
// If SRI is required for this load, appending new bytes to the hash.
if (mSRIDataVerifier && NS_SUCCEEDED(mSRIStatus)) {
mSRIStatus = mSRIDataVerifier->Update(aDataLength, aData);
}
} else {
MOZ_ASSERT(mRequest->IsBytecode());
if (!mRequest->mScriptBytecode.append(aData, aDataLength)) {
return NS_ERROR_OUT_OF_MEMORY;
}
*aConsumedLength = aDataLength;
rv = MaybeDecodeSRI();
if (NS_FAILED(rv)) {
nsCOMPtr<nsIRequest> channelRequest;
aLoader->GetRequest(getter_AddRefs(channelRequest));
return channelRequest->Cancel(mScriptLoader->RestartLoad(mRequest));
}
}
return rv;
}
nsresult
ScriptLoadHandler::DecodeRawData(const uint8_t* aData,
uint32_t aDataLength,
bool aEndOfStream)
{
int32_t srcLen = aDataLength;
const char* src = reinterpret_cast<const char*>(aData);
int32_t dstLen;
nsresult rv =
mDecoder->GetMaxLength(src, srcLen, &dstLen);
NS_ENSURE_SUCCESS(rv, rv);
uint32_t haveRead = mRequest->mScriptText.length();
CheckedInt<uint32_t> capacity = haveRead;
capacity += dstLen;
if (!capacity.isValid() || !mRequest->mScriptText.reserve(capacity.value())) {
return NS_ERROR_OUT_OF_MEMORY;
}
rv = mDecoder->Convert(src,
&srcLen,
mRequest->mScriptText.begin() + haveRead,
&dstLen);
NS_ENSURE_SUCCESS(rv, rv);
haveRead += dstLen;
MOZ_ASSERT(haveRead <= capacity.value(), "mDecoder produced more data than expected");
MOZ_ALWAYS_TRUE(mRequest->mScriptText.resizeUninitialized(haveRead));
return NS_OK;
}
bool
ScriptLoadHandler::EnsureDecoder(nsIIncrementalStreamLoader* aLoader,
const uint8_t* aData,
uint32_t aDataLength,
bool aEndOfStream)
{
// Check if decoder has already been created.
if (mDecoder) {
return true;
}
nsAutoCString charset;
if (!EnsureDecoder(aLoader, aData, aDataLength, aEndOfStream, charset)) {
return false;
}
if (charset.Length() == 0) {
charset = "?";
}
mozilla::Telemetry::Accumulate(mozilla::Telemetry::DOM_SCRIPT_SRC_ENCODING,
charset);
return true;
}
bool
ScriptLoadHandler::EnsureDecoder(nsIIncrementalStreamLoader* aLoader,
const uint8_t* aData,
uint32_t aDataLength,
bool aEndOfStream,
nsCString& oCharset)
{
// JavaScript modules are always UTF-8.
if (mRequest->IsModuleRequest()) {
oCharset = "UTF-8";
mDecoder = EncodingUtils::DecoderForEncoding(oCharset);
return true;
}
// Determine if BOM check should be done. This occurs either
// if end-of-stream has been reached, or at least 3 bytes have
// been read from input.
if (!aEndOfStream && (aDataLength < 3)) {
return false;
}
// Do BOM detection.
if (nsContentUtils::CheckForBOM(aData, aDataLength, oCharset)) {
mDecoder = EncodingUtils::DecoderForEncoding(oCharset);
return true;
}
// BOM detection failed, check content stream for charset.
nsCOMPtr<nsIRequest> req;
nsresult rv = aLoader->GetRequest(getter_AddRefs(req));
NS_ASSERTION(req, "StreamLoader's request went away prematurely");
NS_ENSURE_SUCCESS(rv, false);
nsCOMPtr<nsIChannel> channel = do_QueryInterface(req);
if (channel &&
NS_SUCCEEDED(channel->GetContentCharset(oCharset)) &&
EncodingUtils::FindEncodingForLabel(oCharset, oCharset)) {
mDecoder = EncodingUtils::DecoderForEncoding(oCharset);
return true;
}
// Check the hint charset from the script element or preload
// request.
nsAutoString hintCharset;
if (!mRequest->IsPreload()) {
mRequest->mElement->GetScriptCharset(hintCharset);
} else {
nsTArray<ScriptLoader::PreloadInfo>::index_type i =
mScriptLoader->mPreloads.IndexOf(mRequest, 0,
ScriptLoader::PreloadRequestComparator());
NS_ASSERTION(i != mScriptLoader->mPreloads.NoIndex,
"Incorrect preload bookkeeping");
hintCharset = mScriptLoader->mPreloads[i].mCharset;
}
if (EncodingUtils::FindEncodingForLabel(hintCharset, oCharset)) {
mDecoder = EncodingUtils::DecoderForEncoding(oCharset);
return true;
}
// Get the charset from the charset of the document.
if (mScriptLoader->mDocument) {
oCharset = mScriptLoader->mDocument->GetDocumentCharacterSet();
mDecoder = EncodingUtils::DecoderForEncoding(oCharset);
return true;
}
// Curiously, there are various callers that don't pass aDocument. The
// fallback in the old code was ISO-8859-1, which behaved like
// windows-1252. Saying windows-1252 for clarity and for compliance
// with the Encoding Standard.
oCharset = "windows-1252";
mDecoder = EncodingUtils::DecoderForEncoding(oCharset);
return true;
}
nsresult
ScriptLoadHandler::MaybeDecodeSRI()
{
if (!mSRIDataVerifier || mSRIDataVerifier->IsComplete() || NS_FAILED(mSRIStatus)) {
return NS_OK;
}
// Skip until the content is large enough to be decoded.
if (mRequest->mScriptBytecode.length() <= mSRIDataVerifier->DataSummaryLength()) {
return NS_OK;
}
mSRIStatus = mSRIDataVerifier->ImportDataSummary(
mRequest->mScriptBytecode.length(), mRequest->mScriptBytecode.begin());
if (NS_FAILED(mSRIStatus)) {
// We are unable to decode the hash contained in the alternate data which
// contains the bytecode, or it does not use the same algorithm.
LOG(("ScriptLoadHandler::MaybeDecodeSRI, failed to decode SRI, restart request"));
return mSRIStatus;
}
mRequest->mBytecodeOffset = mSRIDataVerifier->DataSummaryLength();
return NS_OK;
}
nsresult
ScriptLoadHandler::EnsureKnownDataType(nsIIncrementalStreamLoader* aLoader)
{
MOZ_ASSERT(mRequest->IsUnknownDataType());
MOZ_ASSERT(mRequest->IsLoading());
if (mRequest->IsLoadingSource()) {
mRequest->mDataType = ScriptLoadRequest::DataType::Source;
TRACE_FOR_TEST(mRequest->mElement, "scriptloader_load_source");
return NS_OK;
}
nsCOMPtr<nsIRequest> req;
nsresult rv = aLoader->GetRequest(getter_AddRefs(req));
MOZ_ASSERT(req, "StreamLoader's request went away prematurely");
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsICacheInfoChannel> cic(do_QueryInterface(req));
if (cic) {
nsAutoCString altDataType;
cic->GetAlternativeDataType(altDataType);
if (altDataType.EqualsLiteral("javascript/moz-bytecode-" NS_STRINGIFY(MOZ_BUILDID))) {
mRequest->mDataType = ScriptLoadRequest::DataType::Bytecode;
TRACE_FOR_TEST(mRequest->mElement, "scriptloader_load_bytecode");
} else {
mRequest->mDataType = ScriptLoadRequest::DataType::Source;
TRACE_FOR_TEST(mRequest->mElement, "scriptloader_load_source");
}
} else {
mRequest->mDataType = ScriptLoadRequest::DataType::Source;
TRACE_FOR_TEST(mRequest->mElement, "scriptloader_load_source");
}
MOZ_ASSERT(!mRequest->IsUnknownDataType());
MOZ_ASSERT(mRequest->IsLoading());
return NS_OK;
}
NS_IMETHODIMP
ScriptLoadHandler::OnStreamComplete(nsIIncrementalStreamLoader* aLoader,
nsISupports* aContext,
nsresult aStatus,
uint32_t aDataLength,
const uint8_t* aData)
{
nsresult rv = NS_OK;
if (LOG_ENABLED()) {
nsAutoCString url;
mRequest->mURI->GetAsciiSpec(url);
LOG(("ScriptLoadRequest (%p): Stream complete (url = %s)",
mRequest.get(), url.get()));
}
nsCOMPtr<nsIRequest> channelRequest;
aLoader->GetRequest(getter_AddRefs(channelRequest));
if (!mRequest->IsCanceled()) {
if (mRequest->IsUnknownDataType()) {
rv = EnsureKnownDataType(aLoader);
NS_ENSURE_SUCCESS(rv, rv);
}
if (mRequest->IsSource()) {
DebugOnly<bool> encoderSet =
EnsureDecoder(aLoader, aData, aDataLength, /* aEndOfStream = */ true);
MOZ_ASSERT(encoderSet);
rv = DecodeRawData(aData, aDataLength, /* aEndOfStream = */ true);
NS_ENSURE_SUCCESS(rv, rv);
LOG(("ScriptLoadRequest (%p): Source length = %u",
mRequest.get(), unsigned(mRequest->mScriptText.length())));
// If SRI is required for this load, appending new bytes to the hash.
if (mSRIDataVerifier && NS_SUCCEEDED(mSRIStatus)) {
mSRIStatus = mSRIDataVerifier->Update(aDataLength, aData);
}
} else {
MOZ_ASSERT(mRequest->IsBytecode());
if (!mRequest->mScriptBytecode.append(aData, aDataLength)) {
return NS_ERROR_OUT_OF_MEMORY;
}
LOG(("ScriptLoadRequest (%p): Bytecode length = %u",
mRequest.get(), unsigned(mRequest->mScriptBytecode.length())));
// If we abort while decoding the SRI, we fallback on explictly requesting
// the source. Thus, we should not continue in
// ScriptLoader::OnStreamComplete, which removes the request from the
// waiting lists.
rv = MaybeDecodeSRI();
if (NS_FAILED(rv)) {
return channelRequest->Cancel(mScriptLoader->RestartLoad(mRequest));
}
// The bytecode cache always starts with the SRI hash, thus even if there
// is no SRI data verifier instance, we still want to skip the hash.
rv = SRICheckDataVerifier::DataSummaryLength(mRequest->mScriptBytecode.length(),
mRequest->mScriptBytecode.begin(),
&mRequest->mBytecodeOffset);
if (NS_FAILED(rv)) {
return channelRequest->Cancel(mScriptLoader->RestartLoad(mRequest));
}
}
}
// Everything went well, keep the CacheInfoChannel alive such that we can
// later save the bytecode on the cache entry.
if (NS_SUCCEEDED(rv) && mRequest->IsSource() &&
ScriptLoader::IsBytecodeCacheEnabled()) {
mRequest->mCacheInfo = do_QueryInterface(channelRequest);
LOG(("ScriptLoadRequest (%p): nsICacheInfoChannel = %p",
mRequest.get(), mRequest->mCacheInfo.get()));
}
// we have to mediate and use mRequest.
rv = mScriptLoader->OnStreamComplete(aLoader, mRequest, aStatus, mSRIStatus,
mSRIDataVerifier);
// In case of failure, clear the mCacheInfoChannel to avoid keeping it alive.
if (NS_FAILED(rv)) {
mRequest->mCacheInfo = nullptr;
}
return rv;
}
#undef LOG_ENABLED
#undef LOG
} // dom namespace
} // mozilla namespace

View file

@ -0,0 +1,83 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
/*
* A class that handles loading and evaluation of <script> elements.
*/
#ifndef mozilla_dom_ScriptLoadHandler_h
#define mozilla_dom_ScriptLoadHandler_h
#include "nsIIncrementalStreamLoader.h"
namespace mozilla {
namespace dom {
class ScriptLoadRequest;
class ScriptLoader;
class SRICheckDataVerifier;
class ScriptLoadHandler final : public nsIIncrementalStreamLoaderObserver
{
public:
explicit ScriptLoadHandler(ScriptLoader* aScriptLoader,
ScriptLoadRequest* aRequest,
SRICheckDataVerifier* aSRIDataVerifier);
NS_DECL_ISUPPORTS
NS_DECL_NSIINCREMENTALSTREAMLOADEROBSERVER
private:
virtual ~ScriptLoadHandler();
/*
* Once the charset is found by the EnsureDecoder function, we can
* incrementally convert the charset to the one expected by the JS Parser.
*/
nsresult DecodeRawData(const uint8_t* aData, uint32_t aDataLength,
bool aEndOfStream);
/*
* Discover the charset by looking at the stream data, the script
* tag, and other indicators. Returns true if charset has been
* discovered.
*/
bool EnsureDecoder(nsIIncrementalStreamLoader* aLoader,
const uint8_t* aData, uint32_t aDataLength,
bool aEndOfStream);
bool EnsureDecoder(nsIIncrementalStreamLoader* aLoader,
const uint8_t* aData, uint32_t aDataLength,
bool aEndOfStream, nsCString& oCharset);
/*
* When streaming bytecode, we have the opportunity to fallback early if SRI
* does not match the expectation of the document.
*/
nsresult MaybeDecodeSRI();
// Query the channel to find the data type associated with the input stream.
nsresult EnsureKnownDataType(nsIIncrementalStreamLoader* aLoader);
// ScriptLoader which will handle the parsed script.
RefPtr<ScriptLoader> mScriptLoader;
// The ScriptLoadRequest for this load. Decoded data are accumulated on it.
RefPtr<ScriptLoadRequest> mRequest;
// SRI data verifier.
nsAutoPtr<SRICheckDataVerifier> mSRIDataVerifier;
// Status of SRI data operations.
nsresult mSRIStatus;
// Unicode decoder for charset.
nsCOMPtr<nsIUnicodeDecoder> mDecoder;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ScriptLoadHandler_h

View file

@ -0,0 +1,193 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#include "ModuleLoadRequest.h"
#include "mozilla/HoldDropJSObjects.h"
#include "nsICacheInfoChannel.h"
#include "ScriptLoadRequest.h"
#include "ScriptSettings.h"
namespace mozilla {
namespace dom {
//////////////////////////////////////////////////////////////
// ScriptLoadRequest
//////////////////////////////////////////////////////////////
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ScriptLoadRequest)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(ScriptLoadRequest)
NS_IMPL_CYCLE_COLLECTING_RELEASE(ScriptLoadRequest)
NS_IMPL_CYCLE_COLLECTION_CLASS(ScriptLoadRequest)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ScriptLoadRequest)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCacheInfo)
tmp->DropBytecodeCacheReferences();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ScriptLoadRequest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCacheInfo)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ScriptLoadRequest)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mScript)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
ScriptLoadRequest::ScriptLoadRequest(ScriptKind aKind,
nsIScriptElement* aElement,
uint32_t aVersion,
mozilla::CORSMode aCORSMode,
const mozilla::dom::SRIMetadata& aIntegrity)
: mKind(aKind)
, mElement(aElement)
, mScriptFromHead(false)
, mProgress(Progress::Loading)
, mDataType(DataType::Unknown)
, mIsInline(true)
, mHasSourceMapURL(false)
, mIsDefer(false)
, mIsAsync(false)
, mIsNonAsyncScriptInserted(false)
, mIsXSLT(false)
, mIsCanceled(false)
, mWasCompiledOMT(false)
, mIsTracking(false)
, mOffThreadToken(nullptr)
, mScriptText()
, mScriptBytecode()
, mBytecodeOffset(0)
, mJSVersion(aVersion)
, mLineNo(1)
, mCORSMode(aCORSMode)
, mIntegrity(aIntegrity)
, mReferrerPolicy(mozilla::net::RP_Unset)
{
}
ScriptLoadRequest::~ScriptLoadRequest()
{
// We should always clean up any off-thread script parsing resources.
MOZ_ASSERT(!mOffThreadToken);
// But play it safe in release builds and try to clean them up here
// as a fail safe.
MaybeCancelOffThreadScript();
if (mScript) {
DropBytecodeCacheReferences();
}
}
void
ScriptLoadRequest::SetReady()
{
MOZ_ASSERT(mProgress != Progress::Ready);
mProgress = Progress::Ready;
}
void
ScriptLoadRequest::Cancel()
{
MaybeCancelOffThreadScript();
mIsCanceled = true;
}
void
ScriptLoadRequest::MaybeCancelOffThreadScript()
{
MOZ_ASSERT(NS_IsMainThread());
if (!mOffThreadToken) {
return;
}
JSContext* cx = danger::GetJSContext();
// Follow the same conditions as ScriptLoader::AttemptAsyncScriptCompile
if (IsModuleRequest()) {
JS::CancelOffThreadModule(cx, mOffThreadToken);
} else if (IsSource()) {
JS::CancelOffThreadScript(cx, mOffThreadToken);
} else {
MOZ_ASSERT(IsBytecode());
JS::CancelOffThreadScriptDecoder(cx, mOffThreadToken);
}
mOffThreadToken = nullptr;
}
void
ScriptLoadRequest::DropBytecodeCacheReferences()
{
mCacheInfo = nullptr;
mScript = nullptr;
DropJSObjects(this);
}
inline ModuleLoadRequest*
ScriptLoadRequest::AsModuleRequest()
{
MOZ_ASSERT(IsModuleRequest());
return static_cast<ModuleLoadRequest*>(this);
}
//////////////////////////////////////////////////////////////
// ScriptLoadRequestList
//////////////////////////////////////////////////////////////
ScriptLoadRequestList::~ScriptLoadRequestList()
{
Clear();
}
void
ScriptLoadRequestList::Clear()
{
while (!isEmpty()) {
RefPtr<ScriptLoadRequest> first = StealFirst();
first->Cancel();
// And just let it go out of scope and die.
}
}
#ifdef DEBUG
bool
ScriptLoadRequestList::Contains(ScriptLoadRequest* aElem) const
{
for (const ScriptLoadRequest* req = getFirst();
req; req = req->getNext()) {
if (req == aElem) {
return true;
}
}
return false;
}
#endif // DEBUG
inline void
ImplCycleCollectionUnlink(ScriptLoadRequestList& aField)
{
while (!aField.isEmpty()) {
RefPtr<ScriptLoadRequest> first = aField.StealFirst();
}
}
inline void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
ScriptLoadRequestList& aField,
const char* aName,
uint32_t aFlags)
{
for (ScriptLoadRequest* request = aField.getFirst();
request; request = request->getNext())
{
CycleCollectionNoteChild(aCallback, request, aName, aFlags);
}
}
} // dom namespace
} // mozilla namespace

View file

@ -0,0 +1,249 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_dom_ScriptLoadRequest_h
#define mozilla_dom_ScriptLoadRequest_h
#include "mozilla/CORSMode.h"
#include "mozilla/dom/SRIMetadata.h"
#include "mozilla/LinkedList.h"
#include "mozilla/net/ReferrerPolicy.h"
#include "mozilla/Vector.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIScriptElement.h"
class nsICacheInfoChannel;
namespace mozilla {
namespace dom {
class ModuleLoadRequest;
class ScriptLoadRequestList;
enum class ScriptKind {
Classic,
Module
};
/*
* A class that handles loading and evaluation of <script> elements.
*/
class ScriptLoadRequest : public nsISupports,
private mozilla::LinkedListElement<ScriptLoadRequest>
{
typedef LinkedListElement<ScriptLoadRequest> super;
// Allow LinkedListElement<ScriptLoadRequest> to cast us to itself as needed.
friend class mozilla::LinkedListElement<ScriptLoadRequest>;
friend class ScriptLoadRequestList;
protected:
virtual ~ScriptLoadRequest();
public:
ScriptLoadRequest(ScriptKind aKind,
nsIScriptElement* aElement,
uint32_t aVersion,
mozilla::CORSMode aCORSMode,
const mozilla::dom::SRIMetadata &aIntegrity);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ScriptLoadRequest)
bool IsModuleRequest() const
{
return mKind == ScriptKind::Module;
}
ModuleLoadRequest* AsModuleRequest();
void FireScriptAvailable(nsresult aResult)
{
mElement->ScriptAvailable(aResult, mElement, mIsInline, mURI, mLineNo);
}
void FireScriptEvaluated(nsresult aResult)
{
mElement->ScriptEvaluated(aResult, mElement, mIsInline);
}
bool IsPreload()
{
return mElement == nullptr;
}
virtual void Cancel();
bool IsCanceled() const
{
return mIsCanceled;
}
virtual void SetReady();
void** OffThreadTokenPtr()
{
return mOffThreadToken ? &mOffThreadToken : nullptr;
}
bool IsTracking() const
{
return mIsTracking;
}
void SetIsTracking()
{
MOZ_ASSERT(!mIsTracking);
mIsTracking = true;
}
enum class Progress : uint8_t {
Loading, // Request either source or bytecode
Loading_Source, // Explicitly Request source stream
Compiling,
FetchingImports,
Ready
};
bool IsReadyToRun() const {
return mProgress == Progress::Ready;
}
bool IsLoading() const {
return mProgress == Progress::Loading ||
mProgress == Progress::Loading_Source;
}
bool IsLoadingSource() const {
return mProgress == Progress::Loading_Source;
}
bool InCompilingStage() const {
return mProgress == Progress::Compiling ||
(IsReadyToRun() && mWasCompiledOMT);
}
// Type of data provided by the nsChannel.
enum class DataType : uint8_t {
Unknown,
Source,
Bytecode
};
bool IsUnknownDataType() const {
return mDataType == DataType::Unknown;
}
bool IsSource() const {
return mDataType == DataType::Source;
}
bool IsBytecode() const {
return mDataType == DataType::Bytecode;
}
void MaybeCancelOffThreadScript();
void DropBytecodeCacheReferences();
using super::getNext;
using super::isInList;
const ScriptKind mKind;
nsCOMPtr<nsIScriptElement> mElement;
bool mScriptFromHead; // Synchronous head script block loading of other non js/css content.
Progress mProgress; // Are we still waiting for a load to complete?
DataType mDataType; // Does this contain Source or Bytecode?
bool mIsInline; // Is the script inline or loaded?
bool mHasSourceMapURL; // Does the HTTP header have a source map url?
bool mIsDefer; // True if we live in mDeferRequests.
bool mIsAsync; // True if we live in mLoadingAsyncRequests or mLoadedAsyncRequests.
bool mIsNonAsyncScriptInserted; // True if we live in mNonAsyncExternalScriptInsertedRequests
bool mIsXSLT; // True if we live in mXSLTRequests.
bool mIsCanceled; // True if we have been explicitly canceled.
bool mWasCompiledOMT; // True if the script has been compiled off main thread.
bool mIsTracking; // True if the script comes from a source on our tracking protection list.
void* mOffThreadToken; // Off-thread parsing token.
nsString mSourceMapURL; // Holds source map url for loaded scripts
// Holds the top-level JSScript that corresponds to the current source, once
// it is parsed, and planned to be saved in the bytecode cache.
JS::Heap<JSScript*> mScript;
// Holds script text for non-inline scripts. Don't use nsString so we can give
// ownership to jsapi.
mozilla::Vector<char16_t> mScriptText;
// Holds the SRI serialized hash and the script bytecode for non-inline
// scripts.
mozilla::Vector<uint8_t> mScriptBytecode;
uint32_t mBytecodeOffset; // Offset of the bytecode in mScriptBytecode
uint32_t mJSVersion;
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIPrincipal> mOriginPrincipal;
nsAutoCString mURL; // Keep the URI's filename alive during off thread parsing.
int32_t mLineNo;
const mozilla::CORSMode mCORSMode;
const mozilla::dom::SRIMetadata mIntegrity;
mozilla::net::ReferrerPolicy mReferrerPolicy;
// Holds the Cache information, which is used to register the bytecode
// on the cache entry, such that we can load it the next time.
nsCOMPtr<nsICacheInfoChannel> mCacheInfo;
};
class ScriptLoadRequestList : private mozilla::LinkedList<ScriptLoadRequest>
{
typedef mozilla::LinkedList<ScriptLoadRequest> super;
public:
~ScriptLoadRequestList();
void Clear();
#ifdef DEBUG
bool Contains(ScriptLoadRequest* aElem) const;
#endif // DEBUG
using super::getFirst;
using super::isEmpty;
void AppendElement(ScriptLoadRequest* aElem)
{
MOZ_ASSERT(!aElem->isInList());
NS_ADDREF(aElem);
insertBack(aElem);
}
MOZ_MUST_USE
already_AddRefed<ScriptLoadRequest> Steal(ScriptLoadRequest* aElem)
{
aElem->removeFrom(*this);
return dont_AddRef(aElem);
}
MOZ_MUST_USE
already_AddRefed<ScriptLoadRequest> StealFirst()
{
MOZ_ASSERT(!isEmpty());
return Steal(getFirst());
}
void Remove(ScriptLoadRequest* aElem)
{
aElem->removeFrom(*this);
NS_RELEASE(aElem);
}
};
void
ImplCycleCollectionUnlink(ScriptLoadRequestList& aField);
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
ScriptLoadRequestList& aField,
const char* aName,
uint32_t aFlags);
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ScriptLoadRequest_h

File diff suppressed because it is too large Load diff

View file

@ -4,12 +4,8 @@
* 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/. */
/*
* A class that handles loading and evaluation of <script> elements.
*/
#ifndef __nsScriptLoader_h__
#define __nsScriptLoader_h__
#ifndef mozilla_dom_ScriptLoader_h
#define mozilla_dom_ScriptLoader_h
#include "nsCOMPtr.h"
#include "nsRefPtrHashtable.h"
@ -24,16 +20,13 @@
#include "nsIIncrementalStreamLoader.h"
#include "nsURIHashKey.h"
#include "mozilla/CORSMode.h"
#include "mozilla/dom/ScriptLoadRequest.h"
#include "mozilla/dom/SRIMetadata.h"
#include "mozilla/dom/SRICheck.h"
#include "mozilla/LinkedList.h"
#include "mozilla/MozPromise.h"
#include "mozilla/net/ReferrerPolicy.h"
#include "mozilla/Vector.h"
class nsModuleLoadRequest;
class nsModuleScript;
class nsScriptLoadRequestList;
class nsIURI;
namespace JS {
@ -42,280 +35,50 @@ namespace JS {
namespace mozilla {
namespace dom {
class AutoJSAPI;
} // namespace dom
} // namespace mozilla
//////////////////////////////////////////////////////////////
// Per-request data structure
//////////////////////////////////////////////////////////////
enum class nsScriptKind {
Classic,
Module
};
class nsScriptLoadRequest : public nsISupports,
private mozilla::LinkedListElement<nsScriptLoadRequest>
{
typedef LinkedListElement<nsScriptLoadRequest> super;
// Allow LinkedListElement<nsScriptLoadRequest> to cast us to itself as needed.
friend class mozilla::LinkedListElement<nsScriptLoadRequest>;
friend class nsScriptLoadRequestList;
protected:
virtual ~nsScriptLoadRequest();
public:
nsScriptLoadRequest(nsScriptKind aKind,
nsIScriptElement* aElement,
uint32_t aVersion,
mozilla::CORSMode aCORSMode,
const mozilla::dom::SRIMetadata &aIntegrity)
: mKind(aKind),
mElement(aElement),
mScriptFromHead(false),
mProgress(Progress::Loading),
mDataType(DataType::Unknown),
mIsInline(true),
mHasSourceMapURL(false),
mIsDefer(false),
mIsAsync(false),
mIsNonAsyncScriptInserted(false),
mIsXSLT(false),
mIsCanceled(false),
mWasCompiledOMT(false),
mIsTracking(false),
mOffThreadToken(nullptr),
mScriptText(),
mScriptBytecode(),
mBytecodeOffset(0),
mJSVersion(aVersion),
mLineNo(1),
mCORSMode(aCORSMode),
mIntegrity(aIntegrity),
mReferrerPolicy(mozilla::net::RP_Unset)
{
}
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsScriptLoadRequest)
bool IsModuleRequest() const
{
return mKind == nsScriptKind::Module;
}
nsModuleLoadRequest* AsModuleRequest();
void FireScriptAvailable(nsresult aResult)
{
mElement->ScriptAvailable(aResult, mElement, mIsInline, mURI, mLineNo);
}
void FireScriptEvaluated(nsresult aResult)
{
mElement->ScriptEvaluated(aResult, mElement, mIsInline);
}
bool IsPreload()
{
return mElement == nullptr;
}
virtual void Cancel();
bool IsCanceled() const
{
return mIsCanceled;
}
virtual void SetReady();
void** OffThreadTokenPtr()
{
return mOffThreadToken ? &mOffThreadToken : nullptr;
}
bool IsTracking() const
{
return mIsTracking;
}
void SetIsTracking()
{
MOZ_ASSERT(!mIsTracking);
mIsTracking = true;
}
enum class Progress : uint8_t {
Loading, // Request either source or bytecode
Loading_Source, // Explicitly Request source stream
Compiling,
FetchingImports,
Ready
};
bool IsReadyToRun() const {
return mProgress == Progress::Ready;
}
bool IsLoading() const {
return mProgress == Progress::Loading ||
mProgress == Progress::Loading_Source;
}
bool IsLoadingSource() const {
return mProgress == Progress::Loading_Source;
}
bool InCompilingStage() const {
return mProgress == Progress::Compiling ||
(IsReadyToRun() && mWasCompiledOMT);
}
// Type of data provided by the nsChannel.
enum class DataType : uint8_t {
Unknown,
Source,
Bytecode
};
bool IsUnknownDataType() const {
return mDataType == DataType::Unknown;
}
bool IsSource() const {
return mDataType == DataType::Source;
}
bool IsBytecode() const {
return mDataType == DataType::Bytecode;
}
void MaybeCancelOffThreadScript();
void DropBytecodeCacheReferences();
using super::getNext;
using super::isInList;
const nsScriptKind mKind;
nsCOMPtr<nsIScriptElement> mElement;
bool mScriptFromHead; // Synchronous head script block loading of other non js/css content.
Progress mProgress; // Are we still waiting for a load to complete?
DataType mDataType; // Does this contain Source or Bytecode?
bool mIsInline; // Is the script inline or loaded?
bool mHasSourceMapURL; // Does the HTTP header have a source map url?
bool mIsDefer; // True if we live in mDeferRequests.
bool mIsAsync; // True if we live in mLoadingAsyncRequests or mLoadedAsyncRequests.
bool mIsNonAsyncScriptInserted; // True if we live in mNonAsyncExternalScriptInsertedRequests
bool mIsXSLT; // True if we live in mXSLTRequests.
bool mIsCanceled; // True if we have been explicitly canceled.
bool mWasCompiledOMT; // True if the script has been compiled off main thread.
bool mIsTracking; // True if the script comes from a source on our tracking protection list.
void* mOffThreadToken; // Off-thread parsing token.
nsString mSourceMapURL; // Holds source map url for loaded scripts
// Holds the top-level JSScript that corresponds to the current source, once
// it is parsed, and planned to be saved in the bytecode cache.
JS::Heap<JSScript*> mScript;
// Holds script text for non-inline scripts. Don't use nsString so we can give
// ownership to jsapi.
mozilla::Vector<char16_t> mScriptText;
// Holds the SRI serialized hash and the script bytecode for non-inline
// scripts.
mozilla::Vector<uint8_t> mScriptBytecode;
uint32_t mBytecodeOffset; // Offset of the bytecode in mScriptBytecode
uint32_t mJSVersion;
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIPrincipal> mOriginPrincipal;
nsAutoCString mURL; // Keep the URI's filename alive during off thread parsing.
int32_t mLineNo;
const mozilla::CORSMode mCORSMode;
const mozilla::dom::SRIMetadata mIntegrity;
mozilla::net::ReferrerPolicy mReferrerPolicy;
// Holds the Cache information, which is used to register the bytecode
// on the cache entry, such that we can load it the next time.
nsCOMPtr<nsICacheInfoChannel> mCacheInfo;
};
class nsScriptLoadRequestList : private mozilla::LinkedList<nsScriptLoadRequest>
{
typedef mozilla::LinkedList<nsScriptLoadRequest> super;
public:
~nsScriptLoadRequestList();
void Clear();
#ifdef DEBUG
bool Contains(nsScriptLoadRequest* aElem) const;
#endif // DEBUG
using super::getFirst;
using super::isEmpty;
void AppendElement(nsScriptLoadRequest* aElem)
{
MOZ_ASSERT(!aElem->isInList());
NS_ADDREF(aElem);
insertBack(aElem);
}
MOZ_MUST_USE
already_AddRefed<nsScriptLoadRequest> Steal(nsScriptLoadRequest* aElem)
{
aElem->removeFrom(*this);
return dont_AddRef(aElem);
}
MOZ_MUST_USE
already_AddRefed<nsScriptLoadRequest> StealFirst()
{
MOZ_ASSERT(!isEmpty());
return Steal(getFirst());
}
void Remove(nsScriptLoadRequest* aElem)
{
aElem->removeFrom(*this);
NS_RELEASE(aElem);
}
};
class ModuleLoadRequest;
class ModuleScript;
class ScriptLoadHandler;
class ScriptRequestProcessor;
//////////////////////////////////////////////////////////////
// Script loader implementation
//////////////////////////////////////////////////////////////
class nsScriptLoader final : public nsISupports
class ScriptLoader final : public nsISupports
{
class MOZ_STACK_CLASS AutoCurrentScriptUpdater
{
public:
AutoCurrentScriptUpdater(nsScriptLoader* aScriptLoader,
AutoCurrentScriptUpdater(ScriptLoader* aScriptLoader,
nsIScriptElement* aCurrentScript)
: mOldScript(aScriptLoader->mCurrentScript)
, mScriptLoader(aScriptLoader)
{
mScriptLoader->mCurrentScript = aCurrentScript;
}
~AutoCurrentScriptUpdater()
{
mScriptLoader->mCurrentScript.swap(mOldScript);
}
private:
nsCOMPtr<nsIScriptElement> mOldScript;
nsScriptLoader* mScriptLoader;
ScriptLoader* mScriptLoader;
};
friend class nsModuleLoadRequest;
friend class nsScriptRequestProcessor;
friend class nsScriptLoadHandler;
friend class ModuleLoadRequest;
friend class ScriptRequestProcessor;
friend class ScriptLoadHandler;
friend class AutoCurrentScriptUpdater;
public:
explicit nsScriptLoader(nsIDocument* aDocument);
explicit ScriptLoader(nsIDocument* aDocument);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(nsScriptLoader)
NS_DECL_CYCLE_COLLECTION_CLASS(ScriptLoader)
/**
* The loader maintains a weak reference to the document with
@ -390,6 +153,7 @@ public:
{
return mEnabled;
}
void SetEnabled(bool aEnabled)
{
if (!mEnabled && aEnabled) {
@ -407,6 +171,7 @@ public:
{
++mParserBlockingBlockerCount;
}
void RemoveParserBlockingScriptExecutionBlocker()
{
if (!--mParserBlockingBlockerCount && ReadyToExecuteScripts()) {
@ -422,6 +187,7 @@ public:
{
++mBlockerCount;
}
void RemoveExecuteBlocker()
{
MOZ_ASSERT(mBlockerCount);
@ -458,8 +224,8 @@ public:
JS::UniqueTwoByteChars& aBufOut, size_t& aLengthOut)
{
char16_t* bufOut;
nsresult rv = ConvertToUTF16(aChannel, aData, aLength, aHintCharset, aDocument,
bufOut, aLengthOut);
nsresult rv = ConvertToUTF16(aChannel, aData, aLength, aHintCharset,
aDocument, bufOut, aLengthOut);
if (NS_SUCCEEDED(rv)) {
aBufOut.reset(bufOut);
}
@ -468,12 +234,12 @@ public:
/**
* Handle the completion of a stream. This is called by the
* nsScriptLoadHandler object which observes the IncrementalStreamLoader
* ScriptLoadHandler object which observes the IncrementalStreamLoader
* loading the script. The streamed content is expected to be stored on the
* aRequest argument.
*/
nsresult OnStreamComplete(nsIIncrementalStreamLoader* aLoader,
nsScriptLoadRequest* aRequest,
ScriptLoadRequest* aRequest,
nsresult aChannelStatus,
nsresult aSRIStatus,
mozilla::dom::SRICheckDataVerifier* aSRIDataVerifier);
@ -530,9 +296,9 @@ public:
* @param aIntegrity The expect hash url, if avail, of the request
* @param aScriptFromHead Whether or not the script was a child of head
*/
virtual void PreloadURI(nsIURI *aURI, const nsAString &aCharset,
const nsAString &aType,
const nsAString &aCrossOrigin,
virtual void PreloadURI(nsIURI* aURI, const nsAString& aCharset,
const nsAString& aType,
const nsAString& aCrossOrigin,
const nsAString& aIntegrity,
bool aScriptFromHead,
const mozilla::net::ReferrerPolicy aReferrerPolicy);
@ -541,9 +307,10 @@ public:
* Process a request that was deferred so that the script could be compiled
* off thread.
*/
nsresult ProcessOffThreadRequest(nsScriptLoadRequest *aRequest);
nsresult ProcessOffThreadRequest(ScriptLoadRequest* aRequest);
bool AddPendingChildLoader(nsScriptLoader* aChild) {
bool AddPendingChildLoader(ScriptLoader* aChild)
{
return mPendingChildLoaders.AppendElement(aChild) != nullptr;
}
@ -560,46 +327,45 @@ public:
void LoadEventFired();
private:
virtual ~nsScriptLoader();
virtual ~ScriptLoader();
nsScriptLoadRequest* CreateLoadRequest(
nsScriptKind aKind,
nsIScriptElement* aElement,
uint32_t aVersion,
mozilla::CORSMode aCORSMode,
const mozilla::dom::SRIMetadata &aIntegrity);
ScriptLoadRequest* CreateLoadRequest(ScriptKind aKind,
nsIScriptElement* aElement,
uint32_t aVersion,
mozilla::CORSMode aCORSMode,
const mozilla::dom::SRIMetadata& aIntegrity);
/**
* Unblocks the creator parser of the parser-blocking scripts.
*/
void UnblockParser(nsScriptLoadRequest* aParserBlockingRequest);
void UnblockParser(ScriptLoadRequest* aParserBlockingRequest);
/**
* Asynchronously resumes the creator parser of the parser-blocking scripts.
*/
void ContinueParserAsync(nsScriptLoadRequest* aParserBlockingRequest);
void ContinueParserAsync(ScriptLoadRequest* aParserBlockingRequest);
/**
* Helper function to check the content policy for a given request.
*/
static nsresult CheckContentPolicy(nsIDocument* aDocument,
nsISupports *aContext,
nsIURI *aURI,
const nsAString &aType,
nsISupports* aContext,
nsIURI* aURI,
const nsAString& aType,
bool aIsPreLoad);
/**
* Start a load for aRequest's URI.
*/
nsresult StartLoad(nsScriptLoadRequest *aRequest);
nsresult StartLoad(ScriptLoadRequest* aRequest);
/**
* Abort the current stream, and re-start with a new load request from scratch
* without requesting any alternate data. Returns NS_BINDING_RETARGETED on
* success, as this error code is used to abort the input stream.
*/
nsresult RestartLoad(nsScriptLoadRequest *aRequest);
nsresult RestartLoad(ScriptLoadRequest* aRequest);
/**
* Process any pending requests asynchronously (i.e. off an event) if there
@ -635,14 +401,14 @@ private:
return mEnabled && !mBlockerCount;
}
nsresult AttemptAsyncScriptCompile(nsScriptLoadRequest* aRequest);
nsresult ProcessRequest(nsScriptLoadRequest* aRequest);
nsresult CompileOffThreadOrProcessRequest(nsScriptLoadRequest* aRequest);
nsresult AttemptAsyncScriptCompile(ScriptLoadRequest* aRequest);
nsresult ProcessRequest(ScriptLoadRequest* aRequest);
nsresult CompileOffThreadOrProcessRequest(ScriptLoadRequest* aRequest);
void FireScriptAvailable(nsresult aResult,
nsScriptLoadRequest* aRequest);
ScriptLoadRequest* aRequest);
void FireScriptEvaluated(nsresult aResult,
nsScriptLoadRequest* aRequest);
nsresult EvaluateScript(nsScriptLoadRequest* aRequest);
ScriptLoadRequest* aRequest);
nsresult EvaluateScript(ScriptLoadRequest* aRequest);
/**
* Queue the current script load request to be saved, when the page
@ -650,7 +416,7 @@ private:
* time when the load event got received, and when no more scripts are waiting
* to be executed.
*/
void RegisterForBytecodeEncoding(nsScriptLoadRequest* aRequest);
void RegisterForBytecodeEncoding(ScriptLoadRequest* aRequest);
/**
* Check if all conditions are met, i-e that the onLoad event fired and that
@ -664,94 +430,101 @@ private:
* functions on the cache provided by the channel.
*/
void EncodeBytecode();
void EncodeRequestBytecode(JSContext* aCx, nsScriptLoadRequest* aRequest);
void EncodeRequestBytecode(JSContext* aCx, ScriptLoadRequest* aRequest);
void GiveUpBytecodeEncoding();
already_AddRefed<nsIScriptGlobalObject> GetScriptGlobalObject();
nsresult FillCompileOptionsForRequest(const mozilla::dom::AutoJSAPI& jsapi,
nsScriptLoadRequest* aRequest,
ScriptLoadRequest* aRequest,
JS::Handle<JSObject*> aScopeChain,
JS::CompileOptions* aOptions);
uint32_t NumberOfProcessors();
nsresult PrepareLoadedRequest(nsScriptLoadRequest* aRequest,
nsresult PrepareLoadedRequest(ScriptLoadRequest* aRequest,
nsIIncrementalStreamLoader* aLoader,
nsresult aStatus);
void AddDeferRequest(nsScriptLoadRequest* aRequest);
void AddDeferRequest(ScriptLoadRequest* aRequest);
bool MaybeRemovedDeferRequests();
void MaybeMoveToLoadedList(nsScriptLoadRequest* aRequest);
void MaybeMoveToLoadedList(ScriptLoadRequest* aRequest);
JS::SourceBufferHolder GetScriptSource(nsScriptLoadRequest* aRequest,
JS::SourceBufferHolder GetScriptSource(ScriptLoadRequest* aRequest,
nsAutoString& inlineData);
bool ModuleScriptsEnabled();
void SetModuleFetchStarted(nsModuleLoadRequest *aRequest);
void SetModuleFetchFinishedAndResumeWaitingRequests(nsModuleLoadRequest *aRequest,
void SetModuleFetchStarted(ModuleLoadRequest *aRequest);
void SetModuleFetchFinishedAndResumeWaitingRequests(ModuleLoadRequest* aRequest,
nsresult aResult);
bool IsFetchingModule(nsModuleLoadRequest *aRequest) const;
bool IsFetchingModule(ModuleLoadRequest* aRequest) const;
bool ModuleMapContainsModule(nsModuleLoadRequest *aRequest) const;
RefPtr<mozilla::GenericPromise> WaitForModuleFetch(nsModuleLoadRequest *aRequest);
nsModuleScript* GetFetchedModule(nsIURI* aURL) const;
bool ModuleMapContainsModule(ModuleLoadRequest* aRequest) const;
RefPtr<mozilla::GenericPromise> WaitForModuleFetch(ModuleLoadRequest* aRequest);
ModuleScript* GetFetchedModule(nsIURI* aURL) const;
friend bool
HostResolveImportedModule(JSContext* aCx, unsigned argc, JS::Value* vp);
nsresult CreateModuleScript(nsModuleLoadRequest* aRequest);
nsresult ProcessFetchedModuleSource(nsModuleLoadRequest* aRequest);
void ProcessLoadedModuleTree(nsModuleLoadRequest* aRequest);
bool InstantiateModuleTree(nsModuleLoadRequest* aRequest);
void StartFetchingModuleDependencies(nsModuleLoadRequest* aRequest);
static bool
IsBytecodeCacheEnabled();
nsresult CreateModuleScript(ModuleLoadRequest* aRequest);
nsresult ProcessFetchedModuleSource(ModuleLoadRequest* aRequest);
void ProcessLoadedModuleTree(ModuleLoadRequest* aRequest);
bool InstantiateModuleTree(ModuleLoadRequest* aRequest);
void StartFetchingModuleDependencies(ModuleLoadRequest* aRequest);
RefPtr<mozilla::GenericPromise>
StartFetchingModuleAndDependencies(nsModuleLoadRequest* aRequest, nsIURI* aURI);
StartFetchingModuleAndDependencies(ModuleLoadRequest* aRequest, nsIURI* aURI);
nsIDocument* mDocument; // [WEAK]
nsCOMArray<nsIScriptLoaderObserver> mObservers;
nsScriptLoadRequestList mNonAsyncExternalScriptInsertedRequests;
ScriptLoadRequestList mNonAsyncExternalScriptInsertedRequests;
// mLoadingAsyncRequests holds async requests while they're loading; when they
// have been loaded they are moved to mLoadedAsyncRequests.
nsScriptLoadRequestList mLoadingAsyncRequests;
nsScriptLoadRequestList mLoadedAsyncRequests;
nsScriptLoadRequestList mDeferRequests;
nsScriptLoadRequestList mXSLTRequests;
RefPtr<nsScriptLoadRequest> mParserBlockingRequest;
ScriptLoadRequestList mLoadingAsyncRequests;
ScriptLoadRequestList mLoadedAsyncRequests;
ScriptLoadRequestList mDeferRequests;
ScriptLoadRequestList mXSLTRequests;
RefPtr<ScriptLoadRequest> mParserBlockingRequest;
// List of script load request that are holding a buffer which has to be saved
// on the cache.
nsScriptLoadRequestList mBytecodeEncodingQueue;
ScriptLoadRequestList mBytecodeEncodingQueue;
// In mRequests, the additional information here is stored by the element.
struct PreloadInfo {
RefPtr<nsScriptLoadRequest> mRequest;
struct PreloadInfo
{
RefPtr<ScriptLoadRequest> mRequest;
nsString mCharset;
};
friend void ImplCycleCollectionUnlink(nsScriptLoader::PreloadInfo& aField);
friend void ImplCycleCollectionUnlink(ScriptLoader::PreloadInfo& aField);
friend void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
nsScriptLoader::PreloadInfo& aField,
ScriptLoader::PreloadInfo& aField,
const char* aName, uint32_t aFlags);
struct PreloadRequestComparator {
bool Equals(const PreloadInfo &aPi, nsScriptLoadRequest * const &aRequest)
const
struct PreloadRequestComparator
{
bool Equals(const PreloadInfo& aPi, ScriptLoadRequest* const& aRequest) const
{
return aRequest == aPi.mRequest;
}
};
struct PreloadURIComparator {
bool Equals(const PreloadInfo &aPi, nsIURI * const &aURI) const;
struct PreloadURIComparator
{
bool Equals(const PreloadInfo& aPi, nsIURI* const &aURI) const;
};
nsTArray<PreloadInfo> mPreloads;
nsCOMPtr<nsIScriptElement> mCurrentScript;
nsCOMPtr<nsIScriptElement> mCurrentParserInsertedScript;
nsTArray< RefPtr<nsScriptLoader> > mPendingChildLoaders;
nsTArray< RefPtr<ScriptLoader> > mPendingChildLoaders;
uint32_t mParserBlockingBlockerCount;
uint32_t mBlockerCount;
uint32_t mNumberOfProcessors;
@ -763,66 +536,13 @@ private:
// Module map
nsRefPtrHashtable<nsURIHashKey, mozilla::GenericPromise::Private> mFetchingModules;
nsRefPtrHashtable<nsURIHashKey, nsModuleScript> mFetchedModules;
nsRefPtrHashtable<nsURIHashKey, ModuleScript> mFetchedModules;
nsCOMPtr<nsIConsoleReportCollector> mReporter;
};
class nsScriptLoadHandler final : public nsIIncrementalStreamLoaderObserver
{
public:
explicit nsScriptLoadHandler(nsScriptLoader* aScriptLoader,
nsScriptLoadRequest *aRequest,
mozilla::dom::SRICheckDataVerifier *aSRIDataVerifier);
NS_DECL_ISUPPORTS
NS_DECL_NSIINCREMENTALSTREAMLOADEROBSERVER
private:
virtual ~nsScriptLoadHandler();
/*
* Once the charset is found by the EnsureDecoder function, we can
* incrementally convert the charset to the one expected by the JS Parser.
*/
nsresult DecodeRawData(const uint8_t* aData, uint32_t aDataLength,
bool aEndOfStream);
/*
* Discover the charset by looking at the stream data, the script
* tag, and other indicators. Returns true if charset has been
* discovered.
*/
bool EnsureDecoder(nsIIncrementalStreamLoader *aLoader,
const uint8_t* aData, uint32_t aDataLength,
bool aEndOfStream);
bool EnsureDecoder(nsIIncrementalStreamLoader *aLoader,
const uint8_t* aData, uint32_t aDataLength,
bool aEndOfStream, nsCString& oCharset);
/*
* When streaming bytecode, we have the opportunity to fallback early if SRI
* does not match the expectation of the document.
*/
nsresult MaybeDecodeSRI();
// Query the channel to find the data type associated with the input stream.
nsresult EnsureKnownDataType(nsIIncrementalStreamLoader *aLoader);
// ScriptLoader which will handle the parsed script.
RefPtr<nsScriptLoader> mScriptLoader;
// The nsScriptLoadRequest for this load. Decoded data are accumulated on it.
RefPtr<nsScriptLoadRequest> mRequest;
// SRI data verifier.
nsAutoPtr<mozilla::dom::SRICheckDataVerifier> mSRIDataVerifier;
// Status of SRI data operations.
nsresult mSRIStatus;
// Unicode decoder for charset.
nsCOMPtr<nsIUnicodeDecoder> mDecoder;
// Logging
static LazyLogModule gCspPRLog;
static LazyLogModule gScriptLoaderLog;
};
class nsAutoScriptLoaderDisabler
@ -845,7 +565,10 @@ public:
}
bool mWasEnabled;
RefPtr<nsScriptLoader> mLoader;
RefPtr<ScriptLoader> mLoader;
};
#endif //__nsScriptLoader_h__
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ScriptLoader_h

View file

@ -29,13 +29,15 @@ namespace dom {
static MOZ_THREAD_LOCAL(ScriptSettingsStackEntry*) sScriptSettingsTLS;
static bool sScriptSettingsTLSInitialized;
class ScriptSettingsStack {
class ScriptSettingsStack
{
public:
static ScriptSettingsStackEntry* Top() {
return sScriptSettingsTLS.get();
}
static void Push(ScriptSettingsStackEntry *aEntry) {
static void Push(ScriptSettingsStackEntry* aEntry)
{
MOZ_ASSERT(!aEntry->mOlder);
// Whenever JSAPI use is disabled, the next stack entry pushed must
// not be an AutoIncumbentScript.
@ -50,13 +52,15 @@ public:
sScriptSettingsTLS.set(aEntry);
}
static void Pop(ScriptSettingsStackEntry *aEntry) {
static void Pop(ScriptSettingsStackEntry* aEntry)
{
MOZ_ASSERT(aEntry == Top());
sScriptSettingsTLS.set(aEntry->mOlder);
}
static nsIGlobalObject* IncumbentGlobal() {
ScriptSettingsStackEntry *entry = Top();
static nsIGlobalObject* IncumbentGlobal()
{
ScriptSettingsStackEntry* entry = Top();
while (entry) {
if (entry->IsIncumbentCandidate()) {
return entry->mGlobalObject;
@ -66,8 +70,9 @@ public:
return nullptr;
}
static ScriptSettingsStackEntry* EntryPoint() {
ScriptSettingsStackEntry *entry = Top();
static ScriptSettingsStackEntry* EntryPoint()
{
ScriptSettingsStackEntry* entry = Top();
while (entry) {
if (entry->IsEntryCandidate()) {
return entry;
@ -77,8 +82,9 @@ public:
return nullptr;
}
static nsIGlobalObject* EntryGlobal() {
ScriptSettingsStackEntry *entry = EntryPoint();
static nsIGlobalObject* EntryGlobal()
{
ScriptSettingsStackEntry* entry = EntryPoint();
if (!entry) {
return nullptr;
}
@ -86,8 +92,9 @@ public:
}
#ifdef DEBUG
static ScriptSettingsStackEntry* TopNonIncumbentScript() {
ScriptSettingsStackEntry *entry = Top();
static ScriptSettingsStackEntry* TopNonIncumbentScript()
{
ScriptSettingsStackEntry* entry = Top();
while (entry) {
if (!entry->IsIncumbentScript()) {
return entry;
@ -141,7 +148,7 @@ ScriptSettingsInitialized()
return sScriptSettingsTLSInitialized;
}
ScriptSettingsStackEntry::ScriptSettingsStackEntry(nsIGlobalObject *aGlobal,
ScriptSettingsStackEntry::ScriptSettingsStackEntry(nsIGlobalObject* aGlobal,
Type aType)
: mGlobalObject(aGlobal)
, mType(aType)
@ -227,7 +234,7 @@ GetIncumbentGlobal()
// manipulated the stack. If it's null, that means that there
// must be no entry global on the stack, and therefore no incumbent
// global either.
JSContext *cx = nsContentUtils::GetCurrentJSContextForThread();
JSContext* cx = nsContentUtils::GetCurrentJSContextForThread();
if (!cx) {
MOZ_ASSERT(ScriptSettingsStack::EntryGlobal() == nullptr);
return nullptr;
@ -237,7 +244,7 @@ GetIncumbentGlobal()
// override in place, the JS engine will lie to us and pretend that
// there's nothing on the JS stack, which will cause us to check the
// incumbent script stack below.
if (JSObject *global = JS::GetScriptedCallerGlobal(cx)) {
if (JSObject* global = JS::GetScriptedCallerGlobal(cx)) {
return ClampToSubject(xpc::NativeGlobal(global));
}
@ -249,12 +256,12 @@ GetIncumbentGlobal()
nsIGlobalObject*
GetCurrentGlobal()
{
JSContext *cx = nsContentUtils::GetCurrentJSContextForThread();
JSContext* cx = nsContentUtils::GetCurrentJSContextForThread();
if (!cx) {
return nullptr;
}
JSObject *global = JS::CurrentGlobalOrNull(cx);
JSObject* global = JS::CurrentGlobalOrNull(cx);
if (!global) {
return nullptr;
}
@ -266,7 +273,7 @@ nsIPrincipal*
GetWebIDLCallerPrincipal()
{
MOZ_ASSERT(NS_IsMainThread());
ScriptSettingsStackEntry *entry = ScriptSettingsStack::EntryPoint();
ScriptSettingsStackEntry* entry = ScriptSettingsStack::EntryPoint();
// If we have an entry point that is not NoJSAPI, we know it must be an
// AutoEntryScript.
@ -658,7 +665,7 @@ AutoJSAPI::IsStackTop() const
#endif // DEBUG
AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
const char *aReason,
const char* aReason,
bool aIsMainThread)
: AutoJSAPI(aGlobalObject, aIsMainThread, eEntryScript)
, mWebIDLCallerPrincipal(nullptr)
@ -674,7 +681,7 @@ AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
}
AutoEntryScript::AutoEntryScript(JSObject* aObject,
const char *aReason,
const char* aReason,
bool aIsMainThread)
: AutoEntryScript(xpc::NativeGlobal(aObject), aReason, aIsMainThread)
{

View file

@ -0,0 +1,41 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#include "ScriptTrace.h"
namespace mozilla {
namespace dom {
namespace script {
static nsresult
TestingDispatchEvent(nsIScriptElement* aScriptElement,
const nsAString& aEventType)
{
static bool sExposeTestInterfaceEnabled = false;
static bool sExposeTestInterfacePrefCached = false;
if (!sExposeTestInterfacePrefCached) {
sExposeTestInterfacePrefCached = true;
Preferences::AddBoolVarCache(&sExposeTestInterfaceEnabled,
"dom.expose_test_interfaces",
false);
}
if (!sExposeTestInterfaceEnabled) {
return NS_OK;
}
nsCOMPtr<nsINode> target(do_QueryInterface(aScriptElement));
if (!target) {
return NS_OK;
}
RefPtr<AsyncEventDispatcher> dispatcher =
new AsyncEventDispatcher(target, aEventType, true, false);
return dispatcher->PostDOMEvent();
}
} // script namespace
} // dom namespace
} // mozilla namespace

46
dom/script/ScriptTrace.h Normal file
View file

@ -0,0 +1,46 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_dom_ScriptTrace_h
#define mozilla_dom_ScriptTrace_h
#include "ScriptLoader.h"
namespace mozilla {
namespace dom {
namespace script {
// This macro is used to wrap a tracing mechanism which is scheduling events
// which are then used by the JavaScript code of test cases to track the code
// path to verify the optimizations are working as expected.
#define TRACE_FOR_TEST(elem, str) \
PR_BEGIN_MACRO \
nsresult rv = NS_OK; \
rv = script::TestingDispatchEvent(elem, NS_LITERAL_STRING(str)); \
NS_ENSURE_SUCCESS(rv, rv); \
PR_END_MACRO
#define TRACE_FOR_TEST_BOOL(elem, str) \
PR_BEGIN_MACRO \
nsresult rv = NS_OK; \
rv = script::TestingDispatchEvent(elem, NS_LITERAL_STRING(str)); \
NS_ENSURE_SUCCESS(rv, false); \
PR_END_MACRO
#define TRACE_FOR_TEST_NONE(elem, str) \
PR_BEGIN_MACRO \
script::TestingDispatchEvent(elem, NS_LITERAL_STRING(str)); \
PR_END_MACRO
static nsresult
TestingDispatchEvent(nsIScriptElement* aScriptElement,
const nsAString& aEventType);
} // script namespace
} // dom namespace
} // mozilla namespace
#endif // mozilla_dom_ScriptTrace_h

45
dom/script/moz.build Normal file
View file

@ -0,0 +1,45 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
with Files("**"):
BUG_COMPONENT = ("Core", "DOM")
XPIDL_SOURCES += [
'nsIScriptLoaderObserver.idl',
]
XPIDL_MODULE = 'dom'
EXPORTS += [
'nsIScriptElement.h',
]
EXPORTS.mozilla.dom += [
'ScriptElement.h',
'ScriptLoader.h',
'ScriptLoadRequest.h',
'ScriptSettings.h',
]
UNIFIED_SOURCES += [
'ModuleLoadRequest.cpp',
'ModuleScript.cpp',
'ScriptElement.cpp',
'ScriptLoader.cpp',
'ScriptLoadHandler.cpp',
'ScriptLoadRequest.cpp',
'ScriptSettings.cpp',
'ScriptTrace.cpp',
]
LOCAL_INCLUDES += [
'/dom/base',
'/dom/workers',
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'

Some files were not shown because too many files have changed in this diff Show more