mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Merge inbound to central, a=merge CLOSED TREE
MozReview-Commit-ID: 4j8ngmg8FAD
This commit is contained in:
commit
f8412cddff
@ -656,8 +656,10 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
nsIContent* containerElm = containerNode->IsElement() ?
|
||||
containerNode->AsElement() : nullptr;
|
||||
#endif
|
||||
|
||||
nsIFrame::RenderedText text = textFrame->GetRenderedText(0,
|
||||
UINT32_MAX, nsIFrame::TextOffsetType::OFFSETS_IN_CONTENT_TEXT,
|
||||
|
@ -51,12 +51,14 @@
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.tab-label-container[textoverflow][dir=ltr]:not([pinned]) {
|
||||
.tab-label-container[textoverflow][dir=ltr]:not([pinned]),
|
||||
.tab-label-container[textoverflow]:not([dir]):not([pinned]):-moz-locale-dir(ltr) {
|
||||
direction: ltr;
|
||||
mask-image: linear-gradient(to left, transparent, black 2em);
|
||||
}
|
||||
|
||||
.tab-label-container[textoverflow][dir=rtl]:not([pinned]) {
|
||||
.tab-label-container[textoverflow][dir=rtl]:not([pinned]),
|
||||
.tab-label-container[textoverflow]:not([dir]):not([pinned]):-moz-locale-dir(rtl) {
|
||||
direction: rtl;
|
||||
mask-image: linear-gradient(to right, transparent, black 2em);
|
||||
}
|
||||
|
@ -1445,12 +1445,41 @@
|
||||
<parameter name="aTitle"/>
|
||||
<parameter name="aOptions"/>
|
||||
<body><![CDATA[
|
||||
if (aTitle) {
|
||||
// If we don't have the content title yet, aTitle is a URI. Set its hostname
|
||||
// as the label so that the tab isn't empty while the content is loading.
|
||||
const label = aOptions && aOptions.isContentTitle
|
||||
? aTitle
|
||||
: getHostnameWithoutWWW(aTitle, this.mURIFixup);
|
||||
|
||||
if (label) {
|
||||
// Don't replace the set label with the empty tab label or the URL
|
||||
// while the tab is loading.
|
||||
aTab._suppressTransientPlaceholderLabel = true;
|
||||
|
||||
this._setTabLabel(aTab, aTitle, aOptions);
|
||||
this._setTabLabel(aTab, label, aOptions);
|
||||
}
|
||||
|
||||
function getHostnameWithoutWWW(uri, URIFixup) {
|
||||
// about: pages don't have hostnames, so we can bail early here.
|
||||
if (uri.startsWith("about:")) {
|
||||
return uri;
|
||||
}
|
||||
|
||||
// Some tests pass in values that are not valid URLs, such as
|
||||
// "example.com" with no scheme. Just show whatever was passed in
|
||||
// until we know the page's actual title.
|
||||
let hostname;
|
||||
try {
|
||||
const fixedURI = URIFixup.createFixupURI(uri, URIFixup.FIXUP_FLAG_NONE);
|
||||
hostname = fixedURI.host;
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
if (!hostname) {
|
||||
return uri;
|
||||
}
|
||||
|
||||
return hostname.startsWith("www.") ? hostname.slice(4) : hostname;
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
@ -14,8 +14,8 @@
|
||||
!define URLInfoAbout "https://www.mozilla.org"
|
||||
!define HelpLink "https://support.mozilla.org"
|
||||
|
||||
!define URLStubDownload32 "http://download.mozilla.org/?os=win&lang=${AB_CD}&product=devedition-latest"
|
||||
!define URLStubDownload64 "http://download.mozilla.org/?os=win64&lang=${AB_CD}&product=devedition-latest"
|
||||
!define URLStubDownload32 "http://download.mozilla.org/?os=win&lang=${AB_CD}&product=firefox-devedition-latest"
|
||||
!define URLStubDownload64 "http://download.mozilla.org/?os=win64&lang=${AB_CD}&product=firefox-devedition-latest"
|
||||
!define URLManualDownload "https://www.mozilla.org/${AB_CD}/firefox/installer-help/?channel=aurora&installer_lang=${AB_CD}"
|
||||
!define URLSystemRequirements "https://www.mozilla.org/firefox/system-requirements/"
|
||||
!define Channel "aurora"
|
||||
|
@ -237,7 +237,7 @@ class TabTracker extends TabTrackerBase {
|
||||
// Copy the ID from the old tab to the new.
|
||||
this.setId(nativeTab, this.getId(adoptedTab));
|
||||
|
||||
adoptedTab.linkedBrowser.messageManager.sendAsyncMessage("Extension:SetTabAndWindowId", {
|
||||
adoptedTab.linkedBrowser.messageManager.sendAsyncMessage("Extension:SetFrameData", {
|
||||
windowId: windowTracker.getId(nativeTab.ownerGlobal),
|
||||
});
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Test that we don't do unnecessary tab label changes while restoring a tab.
|
||||
*/
|
||||
@ -12,8 +14,11 @@ add_task(async function() {
|
||||
["browser.sessionstore.restore_tabs_lazily", true],
|
||||
]
|
||||
});
|
||||
|
||||
const BACKUP_STATE = SessionStore.getBrowserState();
|
||||
const TEST_URL = "http://example.com/";
|
||||
const TEST_URL = "http://www.example.com/";
|
||||
const ABOUT_ROBOTS_URI = "about:robots";
|
||||
const ABOUT_ROBOTS_TITLE = "Gort! Klaatu barada nikto!";
|
||||
|
||||
function observeLabelChanges(tab) {
|
||||
info("observing tab label changes. initial label: " + tab.label);
|
||||
@ -37,11 +42,12 @@ add_task(async function() {
|
||||
windows: [{
|
||||
tabs: [
|
||||
{ entries: [{ url: TEST_URL }] },
|
||||
{ entries: [{ url: ABOUT_ROBOTS_URI }] },
|
||||
{ entries: [{ url: TEST_URL }] },
|
||||
]
|
||||
}]
|
||||
});
|
||||
let [firstTab, secondTab] = gBrowser.tabs;
|
||||
let [firstTab, secondTab, thirdTab] = gBrowser.tabs;
|
||||
is(gBrowser.selectedTab, firstTab, "first tab is selected");
|
||||
|
||||
await browserLoadedPromise;
|
||||
@ -53,26 +59,46 @@ add_task(async function() {
|
||||
is(firstTab.label, CONTENT_TITLE, "first tab displays content title");
|
||||
ok(document.title.startsWith(CONTENT_TITLE), "title bar displays content title");
|
||||
ok(secondTab.hasAttribute("pending"), "second tab is pending");
|
||||
is(secondTab.label, TEST_URL, "second tab displays URL as its title");
|
||||
// The fix for bug 1364127 caused about: pages' initial tab titles to show
|
||||
// their about: URIs until their actual page titles are known, e.g.
|
||||
// "about:addons" -> "Add-ons Manager". This is bug 1371896. Previously,
|
||||
// about: pages' initial tab titles were blank until the page title was known.
|
||||
is(secondTab.label, ABOUT_ROBOTS_URI, "second tab displays URI as its initial title");
|
||||
ok(thirdTab.hasAttribute("pending"), "third tab is pending");
|
||||
is(thirdTab.label, "example.com", "third tab displays hostname without www as its initial title");
|
||||
|
||||
info("selecting the second tab");
|
||||
let checkLabelChangeCount = observeLabelChanges(secondTab);
|
||||
browserLoadedPromise = BrowserTestUtils.browserLoaded(secondTab.linkedBrowser, false, TEST_URL);
|
||||
browserLoadedPromise = BrowserTestUtils.browserLoaded(secondTab.linkedBrowser, false, ABOUT_ROBOTS_URI);
|
||||
gBrowser.selectedTab = secondTab;
|
||||
await browserLoadedPromise;
|
||||
ok(!secondTab.hasAttribute("pending"), "second tab isn't pending anymore");
|
||||
is(secondTab.label, CONTENT_TITLE, "second tab displays content title");
|
||||
is(secondTab.label, ABOUT_ROBOTS_TITLE, "second tab displays content title");
|
||||
ok(document.title.startsWith(ABOUT_ROBOTS_TITLE), "title bar displays content title");
|
||||
checkLabelChangeCount(1); // ABOUT_ROBOTS_URI -> ABOUT_ROBOTS_TITLE
|
||||
|
||||
info("selecting the third tab");
|
||||
checkLabelChangeCount = observeLabelChanges(thirdTab);
|
||||
browserLoadedPromise = BrowserTestUtils.browserLoaded(thirdTab.linkedBrowser, false, TEST_URL);
|
||||
gBrowser.selectedTab = thirdTab;
|
||||
await browserLoadedPromise;
|
||||
ok(!thirdTab.hasAttribute("pending"), "third tab isn't pending anymore");
|
||||
is(thirdTab.label, CONTENT_TITLE, "third tab displays content title");
|
||||
ok(document.title.startsWith(CONTENT_TITLE), "title bar displays content title");
|
||||
checkLabelChangeCount(1);
|
||||
checkLabelChangeCount(1); // TEST_URL -> CONTENT_TITLE
|
||||
|
||||
info("restoring the modified browser state");
|
||||
await TabStateFlusher.flushWindow(window);
|
||||
await promiseBrowserState(SessionStore.getBrowserState());
|
||||
[firstTab, secondTab] = gBrowser.tabs;
|
||||
is(secondTab, gBrowser.selectedTab, "second tab is selected after restoring");
|
||||
[firstTab, secondTab, thirdTab] = gBrowser.tabs;
|
||||
is(thirdTab, gBrowser.selectedTab, "third tab is selected after restoring");
|
||||
ok(document.title.startsWith(CONTENT_TITLE), "title bar displays content title");
|
||||
ok(firstTab.hasAttribute("pending"), "first tab is pending after restoring");
|
||||
is(firstTab.label, CONTENT_TITLE, "first tab displays content title in pending state");
|
||||
ok(secondTab.hasAttribute("pending"), "second tab is pending after restoring");
|
||||
is(secondTab.label, ABOUT_ROBOTS_TITLE, "second tab displays content title");
|
||||
ok(!thirdTab.hasAttribute("pending"), "third tab is not pending after restoring");
|
||||
is(thirdTab.label, CONTENT_TITLE, "third tab displays content title in pending state");
|
||||
|
||||
info("selecting the first tab");
|
||||
checkLabelChangeCount = observeLabelChanges(firstTab);
|
||||
@ -86,4 +112,3 @@ add_task(async function() {
|
||||
|
||||
await promiseBrowserState(BACKUP_STATE);
|
||||
});
|
||||
|
||||
|
@ -77,14 +77,16 @@ function defineCohort() {
|
||||
// If it's either test/control, the cohort might have changed
|
||||
// if the desired sampling has been changed.
|
||||
let testThreshold = TEST_THRESHOLD[updateChannel];
|
||||
let testGroup = (getUserSample(false) < testThreshold);
|
||||
let userSample = getUserSample();
|
||||
|
||||
if (testGroup) {
|
||||
if (userSample < testThreshold) {
|
||||
cohort = "test";
|
||||
let defaultPrefs = new Preferences({defaultBranch: true});
|
||||
defaultPrefs.set(PREF_FLASH_STATE, Ci.nsIPluginTag.STATE_CLICKTOPLAY);
|
||||
} else {
|
||||
} else if (userSample >= 1.0 - testThreshold) {
|
||||
cohort = "control";
|
||||
} else {
|
||||
cohort = "excluded";
|
||||
}
|
||||
|
||||
setCohort(cohort);
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>clicktoplay-rollout@mozilla.org</em:id>
|
||||
<em:version>1.0</em:version>
|
||||
<em:version>1.1</em:version>
|
||||
<em:type>2</em:type>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
<em:multiprocessCompatible>true</em:multiprocessCompatible>
|
||||
|
@ -92,12 +92,6 @@ const gCachedGridPattern = new Map();
|
||||
// Using a fixed value should also solve bug 1348293.
|
||||
const CANVAS_SIZE = 4096;
|
||||
|
||||
// This constant is used as value to draw infinite lines on canvas; since we cannot use
|
||||
// the canvas boundaries as coordinates to draw the lines, and then applying
|
||||
// transformations on top of them (the resulting coordinates might ending before reaching
|
||||
// the viewport's edges, therefore the lines won't looks as "infinite").
|
||||
const CANVAS_INFINITY = CANVAS_SIZE << 8;
|
||||
|
||||
/**
|
||||
* Returns an array containing the four coordinates of a rectangle, given its diagonal
|
||||
* as input; optionally applying a matrix, and a function to each of the coordinates'
|
||||
@ -182,15 +176,38 @@ function getPathDescriptionFromPoints(points) {
|
||||
* The x-axis of the coordinate for the end of the line.
|
||||
* @param {Number} y2
|
||||
* The y-axis of the coordinate for the end of the line.
|
||||
* @param {Array} [matrix=identity()]
|
||||
* @param {Object} [options]
|
||||
* The options object.
|
||||
* @param {Array} [options.matrix=identity()]
|
||||
* The transformation matrix to apply.
|
||||
* @param {Array} [options.extendToBoundaries]
|
||||
* If set, the line will be extended to reach the boundaries specified.
|
||||
*/
|
||||
function drawLine(ctx, x1, y1, x2, y2, matrix = identity()) {
|
||||
let fromPoint = apply(matrix, [x1, y1]);
|
||||
let toPoint = apply(matrix, [x2, y2]);
|
||||
function drawLine(ctx, x1, y1, x2, y2, options) {
|
||||
let matrix = options.matrix || identity();
|
||||
|
||||
ctx.moveTo(Math.round(fromPoint[0]), Math.round(fromPoint[1]));
|
||||
ctx.lineTo(Math.round(toPoint[0]), Math.round(toPoint[1]));
|
||||
let p1 = apply(matrix, [x1, y1]);
|
||||
let p2 = apply(matrix, [x2, y2]);
|
||||
|
||||
x1 = p1[0];
|
||||
y1 = p1[1];
|
||||
x2 = p2[0];
|
||||
y2 = p2[1];
|
||||
|
||||
if (options.extendToBoundaries) {
|
||||
if (p1[1] === p2[1]) {
|
||||
x1 = options.extendToBoundaries[0];
|
||||
x2 = options.extendToBoundaries[2];
|
||||
} else {
|
||||
y1 = options.extendToBoundaries[1];
|
||||
x1 = (p2[0] - p1[0]) * (y1 - p1[1]) / (p2[1] - p1[1]) + p1[0];
|
||||
y2 = options.extendToBoundaries[3];
|
||||
x2 = (p2[0] - p1[0]) * (y2 - p1[1]) / (p2[1] - p1[1]) + p1[0];
|
||||
}
|
||||
}
|
||||
|
||||
ctx.moveTo(Math.round(x1), Math.round(y1));
|
||||
ctx.lineTo(Math.round(x2), Math.round(y2));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1019,8 +1036,7 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
|
||||
* clears the drawing context.
|
||||
*/
|
||||
updateCanvasElement() {
|
||||
let ratio = parseFloat((this.win.devicePixelRatio || 1).toFixed(2));
|
||||
let size = CANVAS_SIZE / ratio;
|
||||
let size = CANVAS_SIZE / this.win.devicePixelRatio;
|
||||
let { x, y } = this._canvasPosition;
|
||||
|
||||
// Resize the canvas taking the dpr into account so as to have crisp lines, and
|
||||
@ -1280,11 +1296,6 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
|
||||
let lineStartPos = startPos;
|
||||
let lineEndPos = endPos;
|
||||
|
||||
if (this.options.showInfiniteLines) {
|
||||
lineStartPos = 0;
|
||||
lineEndPos = Infinity;
|
||||
}
|
||||
|
||||
let lastEdgeLineIndex = this.getLastEdgeLineIndex(gridDimension.tracks);
|
||||
|
||||
for (let i = 0; i < gridDimension.lines.length; i++) {
|
||||
@ -1351,28 +1362,25 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
|
||||
|
||||
linePos = Math.round(linePos);
|
||||
startPos = Math.round(startPos);
|
||||
endPos = Math.round(endPos);
|
||||
|
||||
this.ctx.save();
|
||||
this.ctx.setLineDash(GRID_LINES_PROPERTIES[lineType].lineDash);
|
||||
this.ctx.beginPath();
|
||||
this.ctx.translate(offset - x, offset - y);
|
||||
|
||||
let lineOptions = {
|
||||
matrix: this.currentMatrix
|
||||
};
|
||||
|
||||
if (this.options.showInfiniteLines) {
|
||||
lineOptions.extendToBoundaries = [x, y, x + CANVAS_SIZE, y + CANVAS_SIZE];
|
||||
}
|
||||
|
||||
if (dimensionType === COLUMNS) {
|
||||
if (isFinite(endPos)) {
|
||||
endPos = Math.round(endPos);
|
||||
} else {
|
||||
endPos = CANVAS_INFINITY;
|
||||
startPos = -endPos;
|
||||
}
|
||||
drawLine(this.ctx, linePos, startPos, linePos, endPos, this.currentMatrix);
|
||||
drawLine(this.ctx, linePos, startPos, linePos, endPos, lineOptions);
|
||||
} else {
|
||||
if (isFinite(endPos)) {
|
||||
endPos = Math.round(endPos);
|
||||
} else {
|
||||
endPos = CANVAS_INFINITY;
|
||||
startPos = -endPos;
|
||||
}
|
||||
drawLine(this.ctx, startPos, linePos, endPos, linePos, this.currentMatrix);
|
||||
drawLine(this.ctx, startPos, linePos, endPos, linePos, lineOptions);
|
||||
}
|
||||
|
||||
this.ctx.strokeStyle = this.color;
|
||||
|
@ -1,748 +0,0 @@
|
||||
/* -*- 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 "ImportManager.h"
|
||||
|
||||
#include "mozilla/dom/ScriptLoader.h"
|
||||
#include "mozilla/EventListenerManager.h"
|
||||
#include "HTMLLinkElement.h"
|
||||
#include "nsContentPolicyUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIScriptObjectPrincipal.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// AutoError
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class AutoError {
|
||||
public:
|
||||
explicit AutoError(mozilla::dom::ImportLoader* loader, bool scriptsBlocked = true)
|
||||
: mLoader(loader)
|
||||
, mPassed(false)
|
||||
, mScriptsBlocked(scriptsBlocked)
|
||||
{}
|
||||
|
||||
~AutoError()
|
||||
{
|
||||
if (!mPassed) {
|
||||
mLoader->Error(mScriptsBlocked);
|
||||
}
|
||||
}
|
||||
|
||||
void Pass() { mPassed = true; }
|
||||
|
||||
private:
|
||||
mozilla::dom::ImportLoader* mLoader;
|
||||
bool mPassed;
|
||||
bool mScriptsBlocked;
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ImportLoader::Updater
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
ImportLoader::Updater::GetReferrerChain(nsINode* aNode,
|
||||
nsTArray<nsINode*>& aResult)
|
||||
{
|
||||
// We fill up the array backward. First the last link: aNode.
|
||||
MOZ_ASSERT(mLoader->mLinks.Contains(aNode));
|
||||
|
||||
aResult.AppendElement(aNode);
|
||||
nsINode* node = aNode;
|
||||
RefPtr<ImportManager> manager = mLoader->Manager();
|
||||
for (ImportLoader* referrersLoader = manager->Find(node->OwnerDoc());
|
||||
referrersLoader;
|
||||
referrersLoader = manager->Find(node->OwnerDoc()))
|
||||
{
|
||||
// Then walking up the main referrer chain and append each link
|
||||
// to the array.
|
||||
node = referrersLoader->GetMainReferrer();
|
||||
MOZ_ASSERT(node);
|
||||
aResult.AppendElement(node);
|
||||
}
|
||||
|
||||
// The reversed order is more useful for consumers.
|
||||
// XXX: This should probably go to nsTArray or some generic utility
|
||||
// lib for our containers that we don't have... I would really like to
|
||||
// get rid of this part...
|
||||
uint32_t l = aResult.Length();
|
||||
for (uint32_t i = 0; i < l / 2; i++) {
|
||||
Swap(aResult[i], aResult[l - i - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ImportLoader::Updater::ShouldUpdate(nsTArray<nsINode*>& aNewPath)
|
||||
{
|
||||
if (mLoader->Manager()->GetNearestPredecessor(mLoader->GetMainReferrer()) !=
|
||||
mLoader->mBlockingPredecessor) {
|
||||
return true;
|
||||
}
|
||||
// Let's walk down on the main referrer chains of both the current main and
|
||||
// the new link, and find the last pair of links that are from the same
|
||||
// document. This is the junction point between the two referrer chain. Their
|
||||
// order in the subimport list of that document will determine if we have to
|
||||
// update the spanning tree or this new edge changes nothing in the script
|
||||
// execution order.
|
||||
nsTArray<nsINode*> oldPath;
|
||||
GetReferrerChain(mLoader->mLinks[mLoader->mMainReferrer], oldPath);
|
||||
uint32_t max = std::min(oldPath.Length(), aNewPath.Length());
|
||||
MOZ_ASSERT(max > 0);
|
||||
uint32_t lastCommonImportAncestor = 0;
|
||||
|
||||
for (uint32_t i = 0;
|
||||
i < max && oldPath[i]->OwnerDoc() == aNewPath[i]->OwnerDoc();
|
||||
i++)
|
||||
{
|
||||
lastCommonImportAncestor = i;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(lastCommonImportAncestor < max);
|
||||
nsINode* oldLink = oldPath[lastCommonImportAncestor];
|
||||
nsINode* newLink = aNewPath[lastCommonImportAncestor];
|
||||
|
||||
if ((lastCommonImportAncestor == max - 1) &&
|
||||
newLink == oldLink ) {
|
||||
// If one chain contains the other entirely, then this is a simple cycle,
|
||||
// nothing to be done here.
|
||||
MOZ_ASSERT(oldPath.Length() != aNewPath.Length(),
|
||||
"This would mean that new link == main referrer link");
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aNewPath != oldPath,
|
||||
"How could this happen?");
|
||||
nsIDocument* doc = oldLink->OwnerDoc();
|
||||
MOZ_ASSERT(doc->HasSubImportLink(newLink));
|
||||
MOZ_ASSERT(doc->HasSubImportLink(oldLink));
|
||||
|
||||
return doc->IndexOfSubImportLink(newLink) < doc->IndexOfSubImportLink(oldLink);
|
||||
}
|
||||
|
||||
void
|
||||
ImportLoader::Updater::UpdateMainReferrer(uint32_t aNewIdx)
|
||||
{
|
||||
MOZ_ASSERT(aNewIdx < mLoader->mLinks.Length());
|
||||
nsINode* newMainReferrer = mLoader->mLinks[aNewIdx];
|
||||
|
||||
// This new link means we have to execute our scripts sooner...
|
||||
// Let's make sure that unblocking a loader does not trigger a script execution.
|
||||
// So we start with placing the new blockers and only then will we remove any
|
||||
// blockers.
|
||||
if (mLoader->IsBlocking()) {
|
||||
// Our import parent is changed, let's block the new one and later unblock
|
||||
// the old one.
|
||||
newMainReferrer->OwnerDoc()->
|
||||
ScriptLoader()->AddParserBlockingScriptExecutionBlocker();
|
||||
newMainReferrer->OwnerDoc()->BlockDOMContentLoaded();
|
||||
}
|
||||
|
||||
if (mLoader->mDocument) {
|
||||
// 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();
|
||||
ScriptLoader* loader = mLoader->mDocument->ScriptLoader();
|
||||
ImportLoader*& pred = mLoader->mBlockingPredecessor;
|
||||
ImportLoader* newPred = manager->GetNearestPredecessor(newMainReferrer);
|
||||
if (pred) {
|
||||
if (newPred) {
|
||||
newPred->AddBlockedScriptLoader(loader);
|
||||
}
|
||||
pred->RemoveBlockedScriptLoader(loader);
|
||||
}
|
||||
}
|
||||
|
||||
if (mLoader->IsBlocking()) {
|
||||
mLoader->mImportParent->
|
||||
ScriptLoader()->RemoveParserBlockingScriptExecutionBlocker();
|
||||
mLoader->mImportParent->UnblockDOMContentLoaded();
|
||||
}
|
||||
|
||||
// Finally update mMainReferrer to point to the newly added link.
|
||||
mLoader->mMainReferrer = aNewIdx;
|
||||
mLoader->mImportParent = newMainReferrer->OwnerDoc();
|
||||
}
|
||||
|
||||
nsINode*
|
||||
ImportLoader::Updater::NextDependant(nsINode* aCurrentLink,
|
||||
nsTArray<nsINode*>& aPath,
|
||||
NodeTable& aVisitedNodes, bool aSkipChildren)
|
||||
{
|
||||
// Depth first graph traversal.
|
||||
if (!aSkipChildren) {
|
||||
// "first child"
|
||||
ImportLoader* loader = mLoader->Manager()->Find(aCurrentLink);
|
||||
if (loader && loader->GetDocument()) {
|
||||
nsINode* firstSubImport = loader->GetDocument()->GetSubImportLink(0);
|
||||
if (firstSubImport && !aVisitedNodes.Contains(firstSubImport)) {
|
||||
aPath.AppendElement(aCurrentLink);
|
||||
aVisitedNodes.PutEntry(firstSubImport);
|
||||
return firstSubImport;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aPath.AppendElement(aCurrentLink);
|
||||
// "(parent's) next sibling"
|
||||
while(aPath.Length() > 1) {
|
||||
aCurrentLink = aPath[aPath.Length() - 1];
|
||||
aPath.RemoveElementAt(aPath.Length() - 1);
|
||||
|
||||
// Let's find the next "sibling"
|
||||
ImportLoader* loader = mLoader->Manager()->Find(aCurrentLink->OwnerDoc());
|
||||
MOZ_ASSERT(loader && loader->GetDocument(), "How can this happend?");
|
||||
nsIDocument* doc = loader->GetDocument();
|
||||
MOZ_ASSERT(doc->HasSubImportLink(aCurrentLink));
|
||||
uint32_t idx = doc->IndexOfSubImportLink(aCurrentLink);
|
||||
nsINode* next = doc->GetSubImportLink(idx + 1);
|
||||
if (next) {
|
||||
// Note: If we found an already visited link that means the parent links has
|
||||
// closed the circle it's always the "first child" section that should find
|
||||
// the first already visited node. Let's just assert that.
|
||||
MOZ_ASSERT(!aVisitedNodes.Contains(next));
|
||||
aVisitedNodes.PutEntry(next);
|
||||
return next;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
ImportLoader::Updater::UpdateDependants(nsINode* aNode,
|
||||
nsTArray<nsINode*>& aPath)
|
||||
{
|
||||
NodeTable visitedNodes;
|
||||
nsINode* current = aNode;
|
||||
uint32_t initialLength = aPath.Length();
|
||||
bool neededUpdate = true;
|
||||
while ((current = NextDependant(current, aPath, visitedNodes, !neededUpdate))) {
|
||||
if (!current || aPath.Length() <= initialLength) {
|
||||
break;
|
||||
}
|
||||
ImportLoader* loader = mLoader->Manager()->Find(current);
|
||||
if (!loader) {
|
||||
continue;
|
||||
}
|
||||
Updater& updater = loader->mUpdater;
|
||||
neededUpdate = updater.ShouldUpdate(aPath);
|
||||
if (neededUpdate) {
|
||||
updater.UpdateMainReferrer(loader->mLinks.IndexOf(current));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ImportLoader::Updater::UpdateSpanningTree(nsINode* aNode)
|
||||
{
|
||||
if (mLoader->mReady || mLoader->mStopped) {
|
||||
// Scripts already executed, nothing to be done here.
|
||||
return;
|
||||
}
|
||||
|
||||
if (mLoader->mLinks.Length() == 1) {
|
||||
// If this is the first referrer, let's mark it.
|
||||
mLoader->mMainReferrer = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
nsTArray<nsINode*> newReferrerChain;
|
||||
GetReferrerChain(aNode, newReferrerChain);
|
||||
if (ShouldUpdate(newReferrerChain)) {
|
||||
UpdateMainReferrer(mLoader->mLinks.Length() - 1);
|
||||
UpdateDependants(aNode, newReferrerChain);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ImportLoader
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(ImportLoader)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
|
||||
NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(ImportLoader)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(ImportLoader)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(ImportLoader)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION(ImportLoader,
|
||||
mDocument,
|
||||
mImportParent,
|
||||
mLinks)
|
||||
|
||||
ImportLoader::ImportLoader(nsIURI* aURI, nsIDocument* aImportParent)
|
||||
: mURI(aURI)
|
||||
, mImportParent(aImportParent)
|
||||
, mBlockingPredecessor(nullptr)
|
||||
, mReady(false)
|
||||
, mStopped(false)
|
||||
, mBlockingScripts(false)
|
||||
, mUpdater(this)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ImportLoader::BlockScripts()
|
||||
{
|
||||
MOZ_ASSERT(!mBlockingScripts);
|
||||
mImportParent->ScriptLoader()->AddParserBlockingScriptExecutionBlocker();
|
||||
mImportParent->BlockDOMContentLoaded();
|
||||
mBlockingScripts = true;
|
||||
}
|
||||
|
||||
void
|
||||
ImportLoader::UnblockScripts()
|
||||
{
|
||||
MOZ_ASSERT(mBlockingScripts);
|
||||
mImportParent->ScriptLoader()->RemoveParserBlockingScriptExecutionBlocker();
|
||||
mImportParent->UnblockDOMContentLoaded();
|
||||
for (uint32_t i = 0; i < mBlockedScriptLoaders.Length(); i++) {
|
||||
mBlockedScriptLoaders[i]->RemoveParserBlockingScriptExecutionBlocker();
|
||||
}
|
||||
mBlockedScriptLoaders.Clear();
|
||||
mBlockingScripts = false;
|
||||
}
|
||||
|
||||
void
|
||||
ImportLoader::SetBlockingPredecessor(ImportLoader* aLoader)
|
||||
{
|
||||
mBlockingPredecessor = aLoader;
|
||||
}
|
||||
|
||||
void
|
||||
ImportLoader::DispatchEventIfFinished(nsINode* aNode)
|
||||
{
|
||||
MOZ_ASSERT(!(mReady && mStopped));
|
||||
if (mReady) {
|
||||
DispatchLoadEvent(aNode);
|
||||
}
|
||||
if (mStopped) {
|
||||
DispatchErrorEvent(aNode);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ImportLoader::AddBlockedScriptLoader(ScriptLoader* aScriptLoader)
|
||||
{
|
||||
if (mBlockedScriptLoaders.Contains(aScriptLoader)) {
|
||||
return;
|
||||
}
|
||||
|
||||
aScriptLoader->AddParserBlockingScriptExecutionBlocker();
|
||||
|
||||
// Let's keep track of the pending script loaders.
|
||||
mBlockedScriptLoaders.AppendElement(aScriptLoader);
|
||||
}
|
||||
|
||||
bool
|
||||
ImportLoader::RemoveBlockedScriptLoader(ScriptLoader* aScriptLoader)
|
||||
{
|
||||
aScriptLoader->RemoveParserBlockingScriptExecutionBlocker();
|
||||
return mBlockedScriptLoaders.RemoveElement(aScriptLoader);
|
||||
}
|
||||
|
||||
void
|
||||
ImportLoader::AddLinkElement(nsINode* aNode)
|
||||
{
|
||||
// If a new link element is added to the import tree that
|
||||
// refers to an import that is already finished loading or
|
||||
// stopped trying, we need to fire the corresponding event
|
||||
// on it.
|
||||
mLinks.AppendElement(aNode);
|
||||
mUpdater.UpdateSpanningTree(aNode);
|
||||
DispatchEventIfFinished(aNode);
|
||||
}
|
||||
|
||||
void
|
||||
ImportLoader::RemoveLinkElement(nsINode* aNode)
|
||||
{
|
||||
mLinks.RemoveElement(aNode);
|
||||
}
|
||||
|
||||
// Events has to be fired with a script runner, so mImport can
|
||||
// be set on the link element before the load event is fired even
|
||||
// if ImportLoader::Get returns an already loaded import and we
|
||||
// fire the load event immediately on the new referring link element.
|
||||
class AsyncEvent : public Runnable {
|
||||
public:
|
||||
AsyncEvent(nsINode* aNode, bool aSuccess)
|
||||
: mNode(aNode)
|
||||
, mSuccess(aSuccess)
|
||||
{
|
||||
MOZ_ASSERT(mNode);
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() override {
|
||||
return nsContentUtils::DispatchTrustedEvent(mNode->OwnerDoc(),
|
||||
mNode,
|
||||
mSuccess ? NS_LITERAL_STRING("load")
|
||||
: NS_LITERAL_STRING("error"),
|
||||
/* aCanBubble = */ false,
|
||||
/* aCancelable = */ false);
|
||||
}
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsINode> mNode;
|
||||
bool mSuccess;
|
||||
};
|
||||
|
||||
void
|
||||
ImportLoader::DispatchErrorEvent(nsINode* aNode)
|
||||
{
|
||||
nsContentUtils::AddScriptRunner(new AsyncEvent(aNode, /* aSuccess = */ false));
|
||||
}
|
||||
|
||||
void
|
||||
ImportLoader::DispatchLoadEvent(nsINode* aNode)
|
||||
{
|
||||
nsContentUtils::AddScriptRunner(new AsyncEvent(aNode, /* aSuccess = */ true));
|
||||
}
|
||||
|
||||
void
|
||||
ImportLoader::Done()
|
||||
{
|
||||
mReady = true;
|
||||
uint32_t l = mLinks.Length();
|
||||
for (uint32_t i = 0; i < l; i++) {
|
||||
DispatchLoadEvent(mLinks[i]);
|
||||
}
|
||||
UnblockScripts();
|
||||
ReleaseResources();
|
||||
}
|
||||
|
||||
void
|
||||
ImportLoader::Error(bool aUnblockScripts)
|
||||
{
|
||||
mDocument = nullptr;
|
||||
mStopped = true;
|
||||
uint32_t l = mLinks.Length();
|
||||
for (uint32_t i = 0; i < l; i++) {
|
||||
DispatchErrorEvent(mLinks[i]);
|
||||
}
|
||||
if (aUnblockScripts) {
|
||||
UnblockScripts();
|
||||
}
|
||||
ReleaseResources();
|
||||
}
|
||||
|
||||
// Release all the resources we don't need after there is no more
|
||||
// data available on the channel, and the parser is done.
|
||||
void ImportLoader::ReleaseResources()
|
||||
{
|
||||
mParserStreamListener = nullptr;
|
||||
mImportParent = nullptr;
|
||||
}
|
||||
|
||||
nsIPrincipal*
|
||||
ImportLoader::Principal()
|
||||
{
|
||||
MOZ_ASSERT(mImportParent);
|
||||
nsCOMPtr<nsIDocument> master = mImportParent->MasterDocument();
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(master);
|
||||
MOZ_ASSERT(sop);
|
||||
return sop->GetPrincipal();
|
||||
}
|
||||
|
||||
void
|
||||
ImportLoader::Open()
|
||||
{
|
||||
AutoError ae(this, false);
|
||||
|
||||
nsCOMPtr<nsILoadGroup> loadGroup =
|
||||
mImportParent->MasterDocument()->GetDocumentLoadGroup();
|
||||
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
nsresult rv = NS_NewChannel(getter_AddRefs(channel),
|
||||
mURI,
|
||||
mImportParent,
|
||||
nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS,
|
||||
nsIContentPolicy::TYPE_SUBDOCUMENT,
|
||||
loadGroup,
|
||||
nullptr, // aCallbacks
|
||||
nsIRequest::LOAD_BACKGROUND);
|
||||
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
rv = channel->AsyncOpen2(this);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
BlockScripts();
|
||||
ae.Pass();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImportLoader::OnDataAvailable(nsIRequest* aRequest,
|
||||
nsISupports* aContext,
|
||||
nsIInputStream* aStream,
|
||||
uint64_t aOffset,
|
||||
uint32_t aCount)
|
||||
{
|
||||
MOZ_ASSERT(mParserStreamListener);
|
||||
|
||||
AutoError ae(this);
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mParserStreamListener->OnDataAvailable(channel, aContext,
|
||||
aStream, aOffset,
|
||||
aCount);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
ae.Pass();
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImportLoader::HandleEvent(nsIDOMEvent *aEvent)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
nsAutoString type;
|
||||
aEvent->GetType(type);
|
||||
MOZ_ASSERT(type.EqualsLiteral("DOMContentLoaded"));
|
||||
#endif
|
||||
Done();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImportLoader::OnStopRequest(nsIRequest* aRequest,
|
||||
nsISupports* aContext,
|
||||
nsresult aStatus)
|
||||
{
|
||||
// OnStartRequest throws a special error code to let us know that we
|
||||
// shouldn't do anything else.
|
||||
if (aStatus == NS_ERROR_DOM_ABORT_ERR) {
|
||||
// We failed in OnStartRequest, nothing more to do (we've already
|
||||
// dispatched an error event) just return here.
|
||||
MOZ_ASSERT(mStopped);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mParserStreamListener) {
|
||||
mParserStreamListener->OnStopRequest(aRequest, aContext, aStatus);
|
||||
}
|
||||
|
||||
if (!mDocument) {
|
||||
// If at this point we don't have a document, then the error was
|
||||
// already reported.
|
||||
return NS_ERROR_DOM_ABORT_ERR;
|
||||
}
|
||||
|
||||
nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(mDocument);
|
||||
EventListenerManager* manager = eventTarget->GetOrCreateListenerManager();
|
||||
manager->AddEventListenerByType(this,
|
||||
NS_LITERAL_STRING("DOMContentLoaded"),
|
||||
TrustedEventsAtSystemGroupBubble());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImportLoader::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
|
||||
{
|
||||
AutoError ae(this);
|
||||
nsIPrincipal* principal = Principal();
|
||||
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
||||
if (!channel) {
|
||||
return NS_ERROR_DOM_ABORT_ERR;
|
||||
}
|
||||
|
||||
if (nsContentUtils::IsSystemPrincipal(principal)) {
|
||||
// We should never import non-system documents and run their scripts with system principal!
|
||||
nsCOMPtr<nsIPrincipal> channelPrincipal;
|
||||
nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(channel,
|
||||
getter_AddRefs(channelPrincipal));
|
||||
if (!nsContentUtils::IsSystemPrincipal(channelPrincipal)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
channel->SetOwner(principal);
|
||||
|
||||
nsAutoCString type;
|
||||
channel->GetContentType(type);
|
||||
if (!type.EqualsLiteral("text/html")) {
|
||||
NS_WARNING("ImportLoader wrong content type");
|
||||
return NS_ERROR_DOM_ABORT_ERR;
|
||||
}
|
||||
|
||||
// The scope object is same for all the imports in an import tree,
|
||||
// let's get it form the import parent.
|
||||
nsCOMPtr<nsIGlobalObject> global = mImportParent->GetScopeObject();
|
||||
nsCOMPtr<nsIDOMDocument> importDoc;
|
||||
nsCOMPtr<nsIURI> baseURI = mImportParent->GetBaseURI();
|
||||
const nsAString& emptyStr = EmptyString();
|
||||
nsresult rv = NS_NewDOMDocument(getter_AddRefs(importDoc),
|
||||
emptyStr, emptyStr, nullptr, mURI,
|
||||
baseURI, principal, false, global,
|
||||
DocumentFlavorHTML);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_ABORT_ERR);
|
||||
|
||||
// The imported document must know which master document it belongs to.
|
||||
mDocument = do_QueryInterface(importDoc);
|
||||
nsCOMPtr<nsIDocument> master = mImportParent->MasterDocument();
|
||||
mDocument->SetMasterDocument(master);
|
||||
|
||||
// We want to inherit the sandbox flags and fullscreen enabled flag
|
||||
// from the master document.
|
||||
mDocument->SetSandboxFlags(master->GetSandboxFlags());
|
||||
|
||||
// We have to connect the blank document we created with the channel we opened,
|
||||
// and create its own LoadGroup for it.
|
||||
nsCOMPtr<nsIStreamListener> listener;
|
||||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
channel->GetLoadGroup(getter_AddRefs(loadGroup));
|
||||
nsCOMPtr<nsILoadGroup> newLoadGroup = do_CreateInstance(NS_LOADGROUP_CONTRACTID);
|
||||
NS_ENSURE_TRUE(newLoadGroup, NS_ERROR_OUT_OF_MEMORY);
|
||||
newLoadGroup->SetLoadGroup(loadGroup);
|
||||
rv = mDocument->StartDocumentLoad("import", channel, newLoadGroup,
|
||||
nullptr, getter_AddRefs(listener),
|
||||
true);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_ABORT_ERR);
|
||||
|
||||
nsCOMPtr<nsIURI> originalURI;
|
||||
rv = channel->GetOriginalURI(getter_AddRefs(originalURI));
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_ABORT_ERR);
|
||||
|
||||
nsCOMPtr<nsIURI> URI;
|
||||
rv = channel->GetURI(getter_AddRefs(URI));
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_ABORT_ERR);
|
||||
MOZ_ASSERT(URI, "URI of a channel should never be null");
|
||||
|
||||
bool equals;
|
||||
rv = URI->Equals(originalURI, &equals);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_ABORT_ERR);
|
||||
|
||||
if (!equals) {
|
||||
// In case of a redirection we must add the new URI to the import map.
|
||||
Manager()->AddLoaderWithNewURI(this, URI);
|
||||
}
|
||||
|
||||
// Let's start the parser.
|
||||
mParserStreamListener = listener;
|
||||
rv = listener->OnStartRequest(aRequest, aContext);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_ABORT_ERR);
|
||||
|
||||
ae.Pass();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ImportManager
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION(ImportManager,
|
||||
mImports)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(ImportManager)
|
||||
NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(ImportManager)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(ImportManager)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(ImportManager)
|
||||
|
||||
already_AddRefed<ImportLoader>
|
||||
ImportManager::Get(nsIURI* aURI, nsINode* aNode, nsIDocument* aOrigDocument)
|
||||
{
|
||||
// Check if we have a loader for that URI, if not create one,
|
||||
// and start it up.
|
||||
RefPtr<ImportLoader> loader;
|
||||
mImports.Get(aURI, getter_AddRefs(loader));
|
||||
bool needToStart = false;
|
||||
if (!loader) {
|
||||
loader = new ImportLoader(aURI, aOrigDocument);
|
||||
mImports.Put(aURI, loader);
|
||||
needToStart = true;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(loader);
|
||||
// Let's keep track of the sub imports links in each document. It will
|
||||
// be used later for scrip execution order calculation. (see UpdateSpanningTree)
|
||||
// NOTE: removing and adding back the link to the tree somewhere else will
|
||||
// NOT have an effect on script execution order.
|
||||
if (!aOrigDocument->HasSubImportLink(aNode)) {
|
||||
aOrigDocument->AddSubImportLink(aNode);
|
||||
}
|
||||
|
||||
loader->AddLinkElement(aNode);
|
||||
|
||||
if (needToStart) {
|
||||
loader->Open();
|
||||
}
|
||||
|
||||
return loader.forget();
|
||||
}
|
||||
|
||||
ImportLoader*
|
||||
ImportManager::Find(nsIDocument* aImport)
|
||||
{
|
||||
return mImports.GetWeak(aImport->GetDocumentURIObject());
|
||||
}
|
||||
|
||||
ImportLoader*
|
||||
ImportManager::Find(nsINode* aLink)
|
||||
{
|
||||
HTMLLinkElement* linkElement = static_cast<HTMLLinkElement*>(aLink);
|
||||
nsCOMPtr<nsIURI> uri = linkElement->GetHrefURI();
|
||||
return mImports.GetWeak(uri);
|
||||
}
|
||||
|
||||
void
|
||||
ImportManager::AddLoaderWithNewURI(ImportLoader* aLoader, nsIURI* aNewURI)
|
||||
{
|
||||
mImports.Put(aNewURI, aLoader);
|
||||
}
|
||||
|
||||
ImportLoader* ImportManager::GetNearestPredecessor(nsINode* aNode)
|
||||
{
|
||||
// Return the previous link if there is any in the same document.
|
||||
nsIDocument* doc = aNode->OwnerDoc();
|
||||
int32_t idx = doc->IndexOfSubImportLink(aNode);
|
||||
MOZ_ASSERT(idx != -1, "aNode must be a sub import link of its owner document");
|
||||
|
||||
for (; idx > 0; idx--) {
|
||||
HTMLLinkElement* link =
|
||||
static_cast<HTMLLinkElement*>(doc->GetSubImportLink(idx - 1));
|
||||
nsCOMPtr<nsIURI> uri = link->GetHrefURI();
|
||||
RefPtr<ImportLoader> ret;
|
||||
mImports.Get(uri, getter_AddRefs(ret));
|
||||
// Only main referrer links are interesting.
|
||||
if (ret->GetMainReferrer() == link) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (idx == 0) {
|
||||
if (doc->IsMasterDocument()) {
|
||||
// If there is no previous one, and it was the master document, then
|
||||
// there is no predecessor.
|
||||
return nullptr;
|
||||
}
|
||||
// Else we find the main referrer of the import parent of the link's document.
|
||||
// And do a recursion.
|
||||
ImportLoader* owner = Find(doc);
|
||||
MOZ_ASSERT(owner);
|
||||
nsCOMPtr<nsINode> mainReferrer = owner->GetMainReferrer();
|
||||
return GetNearestPredecessor(mainReferrer);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
@ -1,283 +0,0 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
/*
|
||||
*
|
||||
* For each import tree there is one master document (the root) and one
|
||||
* import manager. The import manager is a map of URI ImportLoader pairs.
|
||||
* An ImportLoader is responsible for loading an import document from a
|
||||
* given location, and sending out load or error events to all the link
|
||||
* nodes that refer to it when it's done. For loading it opens up a
|
||||
* channel, using the same CSP as the master document. It then creates a
|
||||
* blank document, and starts parsing the data from the channel. When
|
||||
* there is no more data on the channel we wait for the DOMContentLoaded
|
||||
* event from the parsed document. For the duration of the loading
|
||||
* process the scripts on the parent documents are blocked. When an error
|
||||
* occurs, or the DOMContentLoaded event is received, the scripts on the
|
||||
* parent document are unblocked and we emit the corresponding event on
|
||||
* all the referrer link nodes. If a new link node is added to one of the
|
||||
* DOM trees in the import tree that refers to an import that was already
|
||||
* loaded, the already existing ImportLoader is being used (without
|
||||
* loading the referred import document twice) and if necessary the
|
||||
* load/error is emitted on it immediately.
|
||||
*
|
||||
* Ownership model:
|
||||
*
|
||||
* ImportDocument ----------------------------
|
||||
* ^ |
|
||||
* | v
|
||||
* MasterDocument <- ImportManager <-ImportLoader
|
||||
* ^ ^
|
||||
* | |
|
||||
* LinkElement <-----------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef mozilla_dom_ImportManager_h__
|
||||
#define mozilla_dom_ImportManager_h__
|
||||
|
||||
#include "nsTArray.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIWeakReferenceUtils.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "nsURIHashKey.h"
|
||||
#include "mozilla/dom/ScriptLoader.h"
|
||||
|
||||
class nsIDocument;
|
||||
class nsIPrincipal;
|
||||
class nsINode;
|
||||
class AutoError;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class ImportManager;
|
||||
|
||||
typedef nsTHashtable<nsPtrHashKey<nsINode>> NodeTable;
|
||||
|
||||
class ImportLoader final : public nsIStreamListener
|
||||
, public nsIDOMEventListener
|
||||
{
|
||||
|
||||
// A helper inner class to decouple the logic of updating the import graph
|
||||
// after a new import link has been found by one of the parsers.
|
||||
class Updater {
|
||||
|
||||
public:
|
||||
explicit Updater(ImportLoader* aLoader) : mLoader(aLoader)
|
||||
{}
|
||||
|
||||
// After a new link is added that refers to this import, we
|
||||
// have to update the spanning tree, since given this new link the
|
||||
// priority of this import might be higher in the scripts
|
||||
// execution order than before. It updates mMainReferrer, mImportParent,
|
||||
// the corresponding pending ScriptRunners, etc.
|
||||
// It also handles updating additional dependant loaders via the
|
||||
// UpdateDependants calls.
|
||||
// (NOTE: See GetMainReferrer about spanning tree.)
|
||||
void UpdateSpanningTree(nsINode* aNode);
|
||||
|
||||
private:
|
||||
// Returns an array of links that forms a referring chain from
|
||||
// the master document to this import. Each link in the array
|
||||
// is marked as main referrer in the list.
|
||||
void GetReferrerChain(nsINode* aNode, nsTArray<nsINode*>& aResult);
|
||||
|
||||
// Once we find a new referrer path to our import, we have to see if
|
||||
// it changes the load order hence we have to do an update on the graph.
|
||||
bool ShouldUpdate(nsTArray<nsINode*>& aNewPath);
|
||||
void UpdateMainReferrer(uint32_t newIdx);
|
||||
|
||||
// It's a depth first graph traversal algorithm, for UpdateDependants. The
|
||||
// nodes in the graph are the import link elements, and there is a directed
|
||||
// edge from link1 to link2 if link2 is a subimport in the import document
|
||||
// of link1.
|
||||
// If the ImportLoader that aCurrentLink points to didn't need to be updated
|
||||
// the algorithm skips its "children" (subimports). Note, that this graph can
|
||||
// also contain cycles, aVisistedLinks is used to track the already visited
|
||||
// links to avoid an infinite loop.
|
||||
// aPath - (in/out) the referrer link chain of aCurrentLink when called, and
|
||||
// of the next link when the function returns
|
||||
// aVisitedLinks - (in/out) list of links that the traversal already visited
|
||||
// (to handle cycles in the graph)
|
||||
// aSkipChildren - when aCurrentLink points to an import that did not need
|
||||
// to be updated, we can skip its sub-imports ('children')
|
||||
nsINode* NextDependant(nsINode* aCurrentLink,
|
||||
nsTArray<nsINode*>& aPath,
|
||||
NodeTable& aVisitedLinks, bool aSkipChildren);
|
||||
|
||||
// When we find a new link that changes the load order of the known imports,
|
||||
// we also have to check all the subimports of it, to see if they need an
|
||||
// update too. (see test_imports_nested_2.html)
|
||||
void UpdateDependants(nsINode* aNode, nsTArray<nsINode*>& aPath);
|
||||
|
||||
ImportLoader* mLoader;
|
||||
};
|
||||
|
||||
friend class ::AutoError;
|
||||
friend class ImportManager;
|
||||
friend class Updater;
|
||||
|
||||
public:
|
||||
ImportLoader(nsIURI* aURI, nsIDocument* aOriginDocument);
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(ImportLoader, nsIStreamListener)
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
|
||||
// We need to listen to DOMContentLoaded event to know when the document
|
||||
// is fully leaded.
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent *aEvent) override;
|
||||
|
||||
// Validation then opening and starting up the channel.
|
||||
void Open();
|
||||
void AddLinkElement(nsINode* aNode);
|
||||
void RemoveLinkElement(nsINode* aNode);
|
||||
bool IsReady() { return mReady; }
|
||||
bool IsStopped() { return mStopped; }
|
||||
bool IsBlocking() { return mBlockingScripts; }
|
||||
|
||||
ImportManager* Manager() {
|
||||
MOZ_ASSERT(mDocument || mImportParent, "One of them should be always set");
|
||||
return (mDocument ? mDocument : mImportParent)->ImportManager();
|
||||
}
|
||||
|
||||
// Simply getter for the import document. Can return a partially parsed
|
||||
// document if called too early.
|
||||
nsIDocument* GetDocument()
|
||||
{
|
||||
return mDocument;
|
||||
}
|
||||
|
||||
// Getter for the import document that is used in the spec. Returns
|
||||
// nullptr if the import is not yet ready.
|
||||
nsIDocument* GetImport()
|
||||
{
|
||||
if (!mReady) {
|
||||
return nullptr;
|
||||
}
|
||||
return mDocument;
|
||||
}
|
||||
|
||||
// There is only one referring link that is marked as primary link per
|
||||
// imports. This is the one that has to be taken into account when
|
||||
// scrip execution order is determined. Links marked as primary link form
|
||||
// a spanning tree in the import graph. (Eliminating the cycles and
|
||||
// multiple parents.) This spanning tree is recalculated every time
|
||||
// a new import link is added to the manager.
|
||||
nsINode* GetMainReferrer()
|
||||
{
|
||||
if (mLinks.IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
return mLinks[mMainReferrer];
|
||||
}
|
||||
|
||||
// An import is not only blocked by its import children, but also
|
||||
// by its predecessors. It's enough to find the closest predecessor
|
||||
// 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(ScriptLoader* aScriptLoader);
|
||||
bool RemoveBlockedScriptLoader(ScriptLoader* aScriptLoader);
|
||||
void SetBlockingPredecessor(ImportLoader* aLoader);
|
||||
|
||||
private:
|
||||
~ImportLoader() {}
|
||||
|
||||
// If a new referrer LinkElement was added, let's
|
||||
// see if we are already finished and if so fire
|
||||
// the right event.
|
||||
void DispatchEventIfFinished(nsINode* aNode);
|
||||
|
||||
// Dispatch event for a single referrer LinkElement.
|
||||
void DispatchErrorEvent(nsINode* aNode);
|
||||
void DispatchLoadEvent(nsINode* aNode);
|
||||
|
||||
// Must be called when an error has occured during load.
|
||||
void Error(bool aUnblockScripts);
|
||||
|
||||
// Must be called when the import document has been loaded successfully.
|
||||
void Done();
|
||||
|
||||
// When the reading from the channel and the parsing
|
||||
// of the document is done, we can release the resources
|
||||
// that we don't need any longer to hold on.
|
||||
void ReleaseResources();
|
||||
|
||||
// While the document is being loaded we must block scripts
|
||||
// on the import parent document.
|
||||
void BlockScripts();
|
||||
void UnblockScripts();
|
||||
|
||||
nsIPrincipal* Principal();
|
||||
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIStreamListener> mParserStreamListener;
|
||||
nsCOMPtr<nsIDocument> mImportParent;
|
||||
ImportLoader* mBlockingPredecessor;
|
||||
|
||||
// List of the LinkElements that are referring to this import
|
||||
// we need to keep track of them so we can fire event on them.
|
||||
nsTArray<nsCOMPtr<nsINode>> mLinks;
|
||||
|
||||
// List of pending ScriptLoaders that are waiting for this import
|
||||
// to finish.
|
||||
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
|
||||
// used in the script execution order calculation.
|
||||
// ("Branch" according to the spec.)
|
||||
uint32_t mMainReferrer;
|
||||
bool mReady;
|
||||
bool mStopped;
|
||||
bool mBlockingScripts;
|
||||
Updater mUpdater;
|
||||
};
|
||||
|
||||
class ImportManager final : public nsISupports
|
||||
{
|
||||
typedef nsRefPtrHashtable<nsURIHashKey, ImportLoader> ImportMap;
|
||||
|
||||
~ImportManager() {}
|
||||
|
||||
public:
|
||||
ImportManager() {}
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(ImportManager)
|
||||
|
||||
// Finds the ImportLoader that belongs to aImport in the map.
|
||||
ImportLoader* Find(nsIDocument* aImport);
|
||||
|
||||
// Find the ImportLoader aLink refers to.
|
||||
ImportLoader* Find(nsINode* aLink);
|
||||
|
||||
void AddLoaderWithNewURI(ImportLoader* aLoader, nsIURI* aNewURI);
|
||||
|
||||
// When a new import link is added, this getter either creates
|
||||
// a new ImportLoader for it, or returns an existing one if
|
||||
// it was already created and in the import map.
|
||||
already_AddRefed<ImportLoader> Get(nsIURI* aURI, nsINode* aNode,
|
||||
nsIDocument* aOriginDocument);
|
||||
|
||||
// It finds the predecessor for an import link node that runs its
|
||||
// scripts the latest among its predecessors.
|
||||
ImportLoader* GetNearestPredecessor(nsINode* aNode);
|
||||
|
||||
private:
|
||||
ImportMap mImports;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_ImportManager_h__
|
@ -110,8 +110,7 @@ Link::TryDNSPrefetchPreconnectOrPrefetchOrPrerender()
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(rel,
|
||||
mElement->NodePrincipal());
|
||||
uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(rel);
|
||||
|
||||
if ((linkTypes & nsStyleLinkElement::ePREFETCH) ||
|
||||
(linkTypes & nsStyleLinkElement::eNEXT)){
|
||||
|
@ -27,8 +27,8 @@ StructuredCloneBlob::StructuredCloneBlob()
|
||||
|
||||
/* static */ already_AddRefed<StructuredCloneBlob>
|
||||
StructuredCloneBlob::Constructor(GlobalObject& aGlobal, JS::HandleValue aValue,
|
||||
JS::HandleObject aTargetGlobal,
|
||||
ErrorResult& aRv)
|
||||
JS::HandleObject aTargetGlobal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
JSContext* cx = aGlobal.Context();
|
||||
|
||||
@ -38,7 +38,14 @@ StructuredCloneBlob::Constructor(GlobalObject& aGlobal, JS::HandleValue aValue,
|
||||
JS::RootedValue value(cx, aValue);
|
||||
|
||||
if (aTargetGlobal) {
|
||||
ac.emplace(cx, aTargetGlobal);
|
||||
JS::RootedObject targetGlobal(cx, js::CheckedUnwrap(aTargetGlobal));
|
||||
if (!targetGlobal) {
|
||||
js::ReportAccessDenied(cx);
|
||||
aRv.NoteJSContextException(cx);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ac.emplace(cx, targetGlobal);
|
||||
|
||||
if (!JS_WrapValue(cx, &value)) {
|
||||
aRv.NoteJSContextException(cx);
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "mozilla/net/WebSocketChannel.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
@ -2484,7 +2485,14 @@ WebSocket::Send(nsIInputStream* aMsgStream,
|
||||
}
|
||||
|
||||
// Always increment outgoing buffer len, even if closed
|
||||
mOutgoingBufferedAmount += aMsgLength;
|
||||
CheckedUint32 size = mOutgoingBufferedAmount;
|
||||
size += aMsgLength;
|
||||
if (!size.isValid()) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
mOutgoingBufferedAmount = size.value();
|
||||
|
||||
if (readyState == CLOSING ||
|
||||
readyState == CLOSED) {
|
||||
|
@ -181,7 +181,6 @@ EXPORTS.mozilla.dom += [
|
||||
'IdleRequest.h',
|
||||
'ImageEncoder.h',
|
||||
'ImageTracker.h',
|
||||
'ImportManager.h',
|
||||
'Link.h',
|
||||
'Location.h',
|
||||
'NameSpaceConstants.h',
|
||||
@ -254,7 +253,6 @@ UNIFIED_SOURCES += [
|
||||
'IdleRequest.cpp',
|
||||
'ImageEncoder.cpp',
|
||||
'ImageTracker.cpp',
|
||||
'ImportManager.cpp',
|
||||
'Link.cpp',
|
||||
'Location.cpp',
|
||||
'Navigator.cpp',
|
||||
|
@ -697,7 +697,7 @@ nsContentSink::ProcessLink(const nsSubstring& aAnchor, const nsSubstring& aHref,
|
||||
const nsSubstring& aCrossOrigin)
|
||||
{
|
||||
uint32_t linkTypes =
|
||||
nsStyleLinkElement::ParseLinkTypes(aRel, mDocument->NodePrincipal());
|
||||
nsStyleLinkElement::ParseLinkTypes(aRel);
|
||||
|
||||
// The link relation may apply to a different resource, specified
|
||||
// in the anchor parameter. For the link relations supported so far,
|
||||
|
@ -9978,15 +9978,12 @@ nsContentUtils::LookupCustomElementDefinition(nsIDocument* aDoc,
|
||||
{
|
||||
MOZ_ASSERT(aDoc);
|
||||
|
||||
// To support imported document.
|
||||
nsCOMPtr<nsIDocument> doc = aDoc->MasterDocument();
|
||||
|
||||
if (aNameSpaceID != kNameSpaceID_XHTML ||
|
||||
!doc->GetDocShell()) {
|
||||
!aDoc->GetDocShell()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> window(doc->GetInnerWindow());
|
||||
nsCOMPtr<nsPIDOMWindowInner> window(aDoc->GetInnerWindow());
|
||||
if (!window) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -10011,9 +10008,6 @@ nsContentUtils::SetupCustomElement(Element* aElement,
|
||||
return;
|
||||
}
|
||||
|
||||
// To support imported document.
|
||||
doc = doc->MasterDocument();
|
||||
|
||||
if (aElement->GetNameSpaceID() != kNameSpaceID_XHTML ||
|
||||
!doc->GetDocShell()) {
|
||||
return;
|
||||
@ -10041,14 +10035,11 @@ nsContentUtils::EnqueueLifecycleCallback(nsIDocument* aDoc,
|
||||
{
|
||||
MOZ_ASSERT(aDoc);
|
||||
|
||||
// To support imported document.
|
||||
nsCOMPtr<nsIDocument> doc = aDoc->MasterDocument();
|
||||
|
||||
if (!doc->GetDocShell()) {
|
||||
if (!aDoc->GetDocShell()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> window(doc->GetInnerWindow());
|
||||
nsCOMPtr<nsPIDOMWindowInner> window(aDoc->GetInnerWindow());
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
@ -10069,15 +10060,12 @@ nsContentUtils::GetCustomPrototype(nsIDocument* aDoc,
|
||||
{
|
||||
MOZ_ASSERT(aDoc);
|
||||
|
||||
// To support imported document.
|
||||
nsCOMPtr<nsIDocument> doc = aDoc->MasterDocument();
|
||||
|
||||
if (aNamespaceID != kNameSpaceID_XHTML ||
|
||||
!doc->GetDocShell()) {
|
||||
!aDoc->GetDocShell()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> window(doc->GetInnerWindow());
|
||||
nsCOMPtr<nsPIDOMWindowInner> window(aDoc->GetInnerWindow());
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
@ -1776,8 +1776,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMStyleSheets)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheetSetList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScriptLoader)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMasterDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImportManager)
|
||||
|
||||
for (auto iter = tmp->mRadioGroups.Iter(); !iter.Done(); iter.Next()) {
|
||||
nsRadioGroupStruct* radioGroup = iter.UserData();
|
||||
@ -1825,8 +1823,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOnDemandBuiltInUASheets)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPreloadingImages)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSubImportLinks)
|
||||
|
||||
for (uint32_t i = 0; i < tmp->mFrameRequestCallbacks.Length(); ++i) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mFrameRequestCallbacks[i]");
|
||||
cb.NoteXPCOMChild(tmp->mFrameRequestCallbacks[i].mCallback);
|
||||
@ -1911,10 +1907,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPendingAnimationTracker)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTemplateContentsOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChildrenCollection)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMasterDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOrientationPendingPromise)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mImportManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSubImportLinks)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFontFaceSet)
|
||||
|
||||
tmp->mParentDocument = nullptr;
|
||||
@ -3679,10 +3672,6 @@ nsDocument::SetDocumentCharacterSet(const nsACString& aCharSetID)
|
||||
// but before we figure out what to do about non-Encoding Standard
|
||||
// encodings in the charset menu and in mailnews, assertions are futile.
|
||||
if (!mCharacterSet.Equals(aCharSetID)) {
|
||||
if (mMasterDocument && !aCharSetID.EqualsLiteral("UTF-8")) {
|
||||
// Imports are always UTF-8
|
||||
return;
|
||||
}
|
||||
mCharacterSet = aCharSetID;
|
||||
|
||||
int32_t n = mCharSetObservers.Length();
|
||||
@ -8178,9 +8167,6 @@ nsDocument::IsScriptEnabled()
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> globalObject = do_QueryInterface(GetInnerWindow());
|
||||
if (!globalObject && mMasterDocument) {
|
||||
globalObject = do_QueryInterface(mMasterDocument->GetInnerWindow());
|
||||
}
|
||||
if (!globalObject || !globalObject->GetGlobalJSObject()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -66,7 +66,6 @@
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsIDOMXPathEvaluator.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "ImportManager.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "CustomElementRegistry.h"
|
||||
#include "mozilla/dom/Performance.h"
|
||||
@ -1217,63 +1216,6 @@ public:
|
||||
const mozilla::dom::ElementCreationOptionsOrString& aOptions,
|
||||
mozilla::ErrorResult& rv) override;
|
||||
|
||||
virtual nsIDocument* MasterDocument() override
|
||||
{
|
||||
return mMasterDocument ? mMasterDocument.get()
|
||||
: this;
|
||||
}
|
||||
|
||||
virtual void SetMasterDocument(nsIDocument* master) override
|
||||
{
|
||||
MOZ_ASSERT(master);
|
||||
mMasterDocument = master;
|
||||
}
|
||||
|
||||
virtual bool IsMasterDocument() override
|
||||
{
|
||||
return !mMasterDocument;
|
||||
}
|
||||
|
||||
virtual mozilla::dom::ImportManager* ImportManager() override
|
||||
{
|
||||
if (mImportManager) {
|
||||
MOZ_ASSERT(!mMasterDocument, "Only the master document has ImportManager set");
|
||||
return mImportManager.get();
|
||||
}
|
||||
|
||||
if (mMasterDocument) {
|
||||
return mMasterDocument->ImportManager();
|
||||
}
|
||||
|
||||
// ImportManager is created lazily.
|
||||
// If the manager is not yet set it has to be the
|
||||
// master document and this is the first import in it.
|
||||
// Let's create a new manager.
|
||||
mImportManager = new mozilla::dom::ImportManager();
|
||||
return mImportManager.get();
|
||||
}
|
||||
|
||||
virtual bool HasSubImportLink(nsINode* aLink) override
|
||||
{
|
||||
return mSubImportLinks.Contains(aLink);
|
||||
}
|
||||
|
||||
virtual uint32_t IndexOfSubImportLink(nsINode* aLink) override
|
||||
{
|
||||
return mSubImportLinks.IndexOf(aLink);
|
||||
}
|
||||
|
||||
virtual void AddSubImportLink(nsINode* aLink) override
|
||||
{
|
||||
mSubImportLinks.AppendElement(aLink);
|
||||
}
|
||||
|
||||
virtual nsINode* GetSubImportLink(uint32_t aIdx) override
|
||||
{
|
||||
return aIdx < mSubImportLinks.Length() ? mSubImportLinks[aIdx].get()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
virtual void UnblockDOMContentLoaded() override;
|
||||
|
||||
protected:
|
||||
@ -1681,10 +1623,6 @@ private:
|
||||
nsrefcnt mStackRefCnt;
|
||||
bool mNeedsReleaseAfterStackRefCntRelease;
|
||||
|
||||
nsCOMPtr<nsIDocument> mMasterDocument;
|
||||
RefPtr<mozilla::dom::ImportManager> mImportManager;
|
||||
nsTArray<nsCOMPtr<nsINode> > mSubImportLinks;
|
||||
|
||||
// Set to true when the document is possibly controlled by the ServiceWorker.
|
||||
// Used to prevent multiple requests to ServiceWorkerManager.
|
||||
bool mMaybeServiceWorkerControlled;
|
||||
|
@ -141,7 +141,6 @@ class FontFaceSet;
|
||||
class FrameRequestCallback;
|
||||
struct FullscreenRequest;
|
||||
class ImageTracker;
|
||||
class ImportManager;
|
||||
class HTMLBodyElement;
|
||||
struct LifecycleCallbackArgs;
|
||||
class Link;
|
||||
@ -2844,18 +2843,6 @@ public:
|
||||
virtual nsHTMLDocument* AsHTMLDocument() { return nullptr; }
|
||||
virtual mozilla::dom::SVGDocument* AsSVGDocument() { return nullptr; }
|
||||
|
||||
// The root document of the import tree. If this document is not an import
|
||||
// this will return the document itself.
|
||||
virtual nsIDocument* MasterDocument() = 0;
|
||||
virtual void SetMasterDocument(nsIDocument* master) = 0;
|
||||
virtual bool IsMasterDocument() = 0;
|
||||
virtual mozilla::dom::ImportManager* ImportManager() = 0;
|
||||
// We keep track of the order of sub imports were added to the document.
|
||||
virtual bool HasSubImportLink(nsINode* aLink) = 0;
|
||||
virtual uint32_t IndexOfSubImportLink(nsINode* aLink) = 0;
|
||||
virtual void AddSubImportLink(nsINode* aLink) = 0;
|
||||
virtual nsINode* GetSubImportLink(uint32_t aIdx) = 0;
|
||||
|
||||
/*
|
||||
* Given a node, get a weak reference to it and append that reference to
|
||||
* mBlockedTrackingNodes. Can be used later on to look up a node in it.
|
||||
|
@ -128,23 +128,7 @@ nsStyleLinkElement::GetLineNumber()
|
||||
return mLineNumber;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
nsStyleLinkElement::IsImportEnabled()
|
||||
{
|
||||
static bool sAdded = false;
|
||||
static bool sImportsEnabled;
|
||||
if (!sAdded) {
|
||||
// This part runs only once because of the static flag.
|
||||
Preferences::AddBoolVarCache(&sImportsEnabled,
|
||||
"dom.htmlimports.enabled",
|
||||
false);
|
||||
sAdded = true;
|
||||
}
|
||||
|
||||
return sImportsEnabled;
|
||||
}
|
||||
|
||||
static uint32_t ToLinkMask(const nsAString& aLink, nsIPrincipal* aPrincipal)
|
||||
static uint32_t ToLinkMask(const nsAString& aLink)
|
||||
{
|
||||
// Keep this in sync with sRelValues in HTMLLinkElement.cpp
|
||||
if (aLink.EqualsLiteral("prefetch"))
|
||||
@ -157,9 +141,6 @@ static uint32_t ToLinkMask(const nsAString& aLink, nsIPrincipal* aPrincipal)
|
||||
return nsStyleLinkElement::eNEXT;
|
||||
else if (aLink.EqualsLiteral("alternate"))
|
||||
return nsStyleLinkElement::eALTERNATE;
|
||||
else if (aLink.EqualsLiteral("import") &&
|
||||
nsStyleLinkElement::IsImportEnabled())
|
||||
return nsStyleLinkElement::eHTMLIMPORT;
|
||||
else if (aLink.EqualsLiteral("preconnect"))
|
||||
return nsStyleLinkElement::ePRECONNECT;
|
||||
else if (aLink.EqualsLiteral("prerender"))
|
||||
@ -168,7 +149,7 @@ static uint32_t ToLinkMask(const nsAString& aLink, nsIPrincipal* aPrincipal)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes, nsIPrincipal* aPrincipal)
|
||||
uint32_t nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes)
|
||||
{
|
||||
uint32_t linkMask = 0;
|
||||
nsAString::const_iterator start, done;
|
||||
@ -180,12 +161,12 @@ uint32_t nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes, nsIPrincipa
|
||||
nsAString::const_iterator current(start);
|
||||
bool inString = !nsContentUtils::IsHTMLWhitespace(*current);
|
||||
nsAutoString subString;
|
||||
|
||||
|
||||
while (current != done) {
|
||||
if (nsContentUtils::IsHTMLWhitespace(*current)) {
|
||||
if (inString) {
|
||||
nsContentUtils::ASCIIToLower(Substring(start, current), subString);
|
||||
linkMask |= ToLinkMask(subString, aPrincipal);
|
||||
linkMask |= ToLinkMask(subString);
|
||||
inString = false;
|
||||
}
|
||||
}
|
||||
@ -199,7 +180,7 @@ uint32_t nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes, nsIPrincipa
|
||||
}
|
||||
if (inString) {
|
||||
nsContentUtils::ASCIIToLower(Substring(start, current), subString);
|
||||
linkMask |= ToLinkMask(subString, aPrincipal);
|
||||
linkMask |= ToLinkMask(subString);
|
||||
}
|
||||
return linkMask;
|
||||
}
|
||||
|
@ -62,19 +62,13 @@ public:
|
||||
eSTYLESHEET = 0x00000004,
|
||||
eNEXT = 0x00000008,
|
||||
eALTERNATE = 0x00000010,
|
||||
eHTMLIMPORT = 0x00000020,
|
||||
ePRECONNECT = 0x00000040,
|
||||
ePRERENDER = 0x00000080
|
||||
ePRECONNECT = 0x00000020,
|
||||
ePRERENDER = 0x00000040
|
||||
};
|
||||
|
||||
// The return value is a bitwise or of 0 or more RelValues.
|
||||
// aPrincipal is used to check if HTML imports is enabled for the
|
||||
// provided principal.
|
||||
static uint32_t ParseLinkTypes(const nsAString& aTypes,
|
||||
nsIPrincipal* aPrincipal);
|
||||
static uint32_t ParseLinkTypes(const nsAString& aTypes);
|
||||
|
||||
static bool IsImportEnabled();
|
||||
|
||||
void UpdateStyleSheetInternal()
|
||||
{
|
||||
UpdateStyleSheetInternal(nullptr, nullptr);
|
||||
|
@ -67,14 +67,12 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLLinkElement,
|
||||
nsGenericHTMLElement)
|
||||
tmp->nsStyleLinkElement::Traverse(cb);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRelList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImportLoader)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLLinkElement,
|
||||
nsGenericHTMLElement)
|
||||
tmp->nsStyleLinkElement::Unlink();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRelList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mImportLoader)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(HTMLLinkElement, Element)
|
||||
@ -175,9 +173,6 @@ HTMLLinkElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
void (HTMLLinkElement::*update)() = &HTMLLinkElement::UpdateStyleSheetInternal;
|
||||
nsContentUtils::AddScriptRunner(NewRunnableMethod(this, update));
|
||||
|
||||
void (HTMLLinkElement::*updateImport)() = &HTMLLinkElement::UpdateImport;
|
||||
nsContentUtils::AddScriptRunner(NewRunnableMethod(this, updateImport));
|
||||
|
||||
CreateAndDispatchEvent(aDocument, NS_LITERAL_STRING("DOMLinkAdded"));
|
||||
|
||||
return rv;
|
||||
@ -222,7 +217,6 @@ HTMLLinkElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
|
||||
UpdateStyleSheetInternal(oldDoc, oldShadowRoot);
|
||||
UpdateImport();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -281,54 +275,6 @@ HTMLLinkElement::CreateAndDispatchEvent(nsIDocument* aDoc,
|
||||
asyncDispatcher->PostDOMEvent();
|
||||
}
|
||||
|
||||
void
|
||||
HTMLLinkElement::UpdateImport()
|
||||
{
|
||||
// 1. link node should be attached to the document.
|
||||
nsCOMPtr<nsIDocument> doc = GetUncomposedDoc();
|
||||
if (!doc) {
|
||||
// We might have been just removed from the document, so
|
||||
// let's remove ourself from the list of link nodes of
|
||||
// the import and reset mImportLoader.
|
||||
if (mImportLoader) {
|
||||
mImportLoader->RemoveLinkElement(this);
|
||||
mImportLoader = nullptr;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. rel type should be import.
|
||||
nsAutoString rel;
|
||||
GetAttr(kNameSpaceID_None, nsGkAtoms::rel, rel);
|
||||
uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(rel, NodePrincipal());
|
||||
if (!(linkTypes & eHTMLIMPORT)) {
|
||||
mImportLoader = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri = GetHrefURI();
|
||||
if (!uri) {
|
||||
mImportLoader = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!nsStyleLinkElement::IsImportEnabled()) {
|
||||
// For now imports are hidden behind a pref...
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<ImportManager> manager = doc->ImportManager();
|
||||
MOZ_ASSERT(manager, "ImportManager should be created lazily when needed");
|
||||
|
||||
{
|
||||
// The load even might fire sooner than we could set mImportLoader so
|
||||
// we must use async event and a scriptBlocker here.
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
// CORS check will happen at the start of the load.
|
||||
mImportLoader = manager->Get(uri, this, doc);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLLinkElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
const nsAttrValueOrString* aValue, bool aNotify)
|
||||
@ -373,19 +319,12 @@ HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
if (aName == nsGkAtoms::rel) {
|
||||
nsAutoString value;
|
||||
aValue->ToString(value);
|
||||
uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(value,
|
||||
NodePrincipal());
|
||||
uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(value);
|
||||
if (GetSheet()) {
|
||||
dropSheet = !(linkTypes & nsStyleLinkElement::eSTYLESHEET);
|
||||
} else if (linkTypes & eHTMLIMPORT) {
|
||||
UpdateImport();
|
||||
}
|
||||
}
|
||||
|
||||
if (aName == nsGkAtoms::href) {
|
||||
UpdateImport();
|
||||
}
|
||||
|
||||
if ((aName == nsGkAtoms::rel || aName == nsGkAtoms::href) &&
|
||||
IsInComposedDoc()) {
|
||||
TryDNSPrefetchPreconnectOrPrefetchOrPrerender();
|
||||
@ -408,10 +347,6 @@ HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
aName == nsGkAtoms::type) {
|
||||
UpdateStyleSheetInternal(nullptr, nullptr, true);
|
||||
}
|
||||
if (aName == nsGkAtoms::href ||
|
||||
aName == nsGkAtoms::rel) {
|
||||
UpdateImport();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -449,7 +384,6 @@ HTMLLinkElement::GetLinkTarget(nsAString& aTarget)
|
||||
static const DOMTokenListSupportedToken sSupportedRelValues[] = {
|
||||
// Keep this in sync with ToLinkMask in nsStyleLinkElement.cpp.
|
||||
// "import" must come first because it's conditional.
|
||||
"import",
|
||||
"prefetch",
|
||||
"dns-prefetch",
|
||||
"stylesheet",
|
||||
@ -465,11 +399,7 @@ nsDOMTokenList*
|
||||
HTMLLinkElement::RelList()
|
||||
{
|
||||
if (!mRelList) {
|
||||
const DOMTokenListSupportedTokenArray relValues =
|
||||
nsStyleLinkElement::IsImportEnabled() ?
|
||||
sSupportedRelValues : &sSupportedRelValues[1];
|
||||
|
||||
mRelList = new nsDOMTokenList(this, nsGkAtoms::rel, relValues);
|
||||
mRelList = new nsDOMTokenList(this, nsGkAtoms::rel, sSupportedRelValues);
|
||||
}
|
||||
return mRelList;
|
||||
}
|
||||
@ -508,7 +438,7 @@ HTMLLinkElement::GetStyleSheetInfo(nsAString& aTitle,
|
||||
|
||||
nsAutoString rel;
|
||||
GetAttr(kNameSpaceID_None, nsGkAtoms::rel, rel);
|
||||
uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(rel, NodePrincipal());
|
||||
uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(rel);
|
||||
// Is it a stylesheet link?
|
||||
if (!(linkTypes & nsStyleLinkElement::eSTYLESHEET)) {
|
||||
return;
|
||||
@ -573,11 +503,5 @@ HTMLLinkElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
return HTMLLinkElementBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDocument>
|
||||
HTMLLinkElement::GetImport()
|
||||
{
|
||||
return mImportLoader ? RefPtr<nsIDocument>(mImportLoader->GetImport()).forget() : nullptr;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/Link.h"
|
||||
#include "ImportManager.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsIDOMHTMLLinkElement.h"
|
||||
#include "nsStyleLinkElement.h"
|
||||
@ -43,8 +42,6 @@ public:
|
||||
void LinkAdded();
|
||||
void LinkRemoved();
|
||||
|
||||
void UpdateImport();
|
||||
|
||||
// nsIDOMEventTarget
|
||||
virtual nsresult GetEventTargetParent(
|
||||
EventChainPreVisitor& aVisitor) override;
|
||||
@ -166,12 +163,6 @@ public:
|
||||
return GetReferrerPolicyAsEnum();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDocument> GetImport();
|
||||
already_AddRefed<ImportLoader> GetImportLoader()
|
||||
{
|
||||
return RefPtr<ImportLoader>(mImportLoader).forget();
|
||||
}
|
||||
|
||||
virtual CORSMode GetCORSMode() const override;
|
||||
|
||||
virtual void NodeInfoChanged(nsIDocument* aOldDoc) final override
|
||||
@ -192,9 +183,6 @@ protected:
|
||||
bool* aIsAlternate) override;
|
||||
protected:
|
||||
RefPtr<nsDOMTokenList> mRelList;
|
||||
|
||||
private:
|
||||
RefPtr<ImportLoader> mImportLoader;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -11,7 +11,6 @@ DIRS += ['input']
|
||||
|
||||
MOCHITEST_MANIFESTS += [
|
||||
'test/forms/mochitest.ini',
|
||||
'test/imports/mochitest.ini',
|
||||
'test/mochitest.ini',
|
||||
]
|
||||
|
||||
|
@ -531,8 +531,7 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
|
||||
!strcmp(aCommand, "external-resource");
|
||||
bool viewSource = !strcmp(aCommand, "view-source");
|
||||
bool asData = !strcmp(aCommand, kLoadAsData);
|
||||
bool import = !strcmp(aCommand, "import");
|
||||
if (!(view || viewSource || asData || import)) {
|
||||
if (!(view || viewSource || asData)) {
|
||||
MOZ_ASSERT(false, "Bad parser command");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
@ -1476,7 +1475,7 @@ nsHTMLDocument::Open(JSContext* cx,
|
||||
|
||||
NS_ASSERTION(nsContentUtils::CanCallerAccess(static_cast<nsIDOMHTMLDocument*>(this)),
|
||||
"XOW should have caught this!");
|
||||
if (!IsHTMLDocument() || mDisableDocWrite || !IsMasterDocument()) {
|
||||
if (!IsHTMLDocument() || mDisableDocWrite) {
|
||||
// No calling document.open() on XHTML
|
||||
rv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return nullptr;
|
||||
@ -1894,7 +1893,7 @@ nsHTMLDocument::WriteCommon(JSContext *cx,
|
||||
(mWriteLevel > NS_MAX_DOCUMENT_WRITE_DEPTH || mTooDeepWriteRecursion);
|
||||
NS_ENSURE_STATE(!mTooDeepWriteRecursion);
|
||||
|
||||
if (!IsHTMLDocument() || mDisableDocWrite || !IsMasterDocument()) {
|
||||
if (!IsHTMLDocument() || mDisableDocWrite) {
|
||||
// No calling document.write*() on XHTML!
|
||||
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
|
@ -1,22 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div id="foo">bar</div>
|
||||
<script>
|
||||
counter++;
|
||||
var importDone = true;
|
||||
is(document.currentScript.ownerDocument.getElementById("foo").textContent, "bar",
|
||||
"currentScript.ownerDocument works in imported document,");
|
||||
try{
|
||||
document.currentScript.ownerDocument.open();
|
||||
document.currentScript.ownerDocument.write("<h1>This should not show up!</h1>");
|
||||
document.currentScript.ownerDocument.close();
|
||||
ok(false, "document.write should have thrown (import)")
|
||||
} catch (e) {
|
||||
ok(true, "document.write has thrown (import)")
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,5 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -1,2 +0,0 @@
|
||||
HTTP 301 Moved Permanently
|
||||
Location: http://mochi.test:8888/tests/dom/html/test/file_imports_redirected.html
|
@ -1,6 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<script> var redirected = true; </script>
|
||||
</body>
|
||||
</html>
|
@ -1,7 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<link rel="import" href="file_CSP_sandbox_import.html" id="import"></link>
|
||||
</body>
|
||||
|
@ -1,9 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
var scriptExecuted = true;
|
||||
</script>
|
||||
</body>
|
||||
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<script>
|
||||
order.push("AS0");
|
||||
</script>
|
||||
<link rel="import" href="file_blocking_DOMContentLoaded_B.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<script>
|
||||
order.push("BS0");
|
||||
</script>
|
||||
<link rel="import" href="file_blocking_DOMContentLoaded_C.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<script>
|
||||
order.push("CS0");
|
||||
</script>
|
||||
<link rel="import" href="file_blocking_DOMContentLoaded_D.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -1,10 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<script>
|
||||
order.push("DS0");
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_cycle_1_B.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("A");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,12 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_cycle_1_C.html" onload="loaded()" onerror="failed()"></link>
|
||||
<link rel="import" href="file_cycle_1_A.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("B");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,12 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_cycle_1_B.html" onload="loaded()" onerror="failed()"></link>
|
||||
<link rel="import" href="file_cycle_1_A.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("C");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_cycle_2_B.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("A");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,13 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_cycle_2_A.html" onload="loaded()" onerror="failed()"></link>
|
||||
<link rel="import" href="file_cycle_2_C.html" onload="loaded()" onerror="failed()"></link>
|
||||
<link rel="import" href="file_cycle_2_D.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("B");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,10 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("C");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,10 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("D");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_cycle_3_C.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("A");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_cycle_3_C.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("B");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,12 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_cycle_3_A.html" onload="loaded()" onerror="failed()"></link>
|
||||
<link rel="import" href="file_cycle_3_B.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("C");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_cycle_4_B.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("A");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_cycle_4_C.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("B");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_cycle_4_D.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("C");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,12 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_cycle_4_B.html" onload="loaded()" onerror="failed()"></link>
|
||||
<link rel="import" href="file_cycle_4_E.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("D");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_cycle_4_C.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("E");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,15 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<x-foo></x-foo>
|
||||
<script>
|
||||
var prototype = Object.create(HTMLElement.prototype);
|
||||
prototype.createdCallback = function() {
|
||||
createdCallbackCalled = true;
|
||||
}
|
||||
document.registerElement('x-foo', {prototype: prototype});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,5 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset="EUC-KR">
|
||||
</head>
|
||||
<body>Ignore my encoding</body>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_importA2.html" id="A2" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("A1");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,10 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("A2");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_importB2.html" id="B2" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("B1");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,10 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("B2");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_importC2.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("C1");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_importE.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("C10");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_importC3.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("C2");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_importC4.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("C3");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_importC5.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("C4");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_importC6.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("C5");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_importC7.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("C6");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_importC8.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("C7");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_importC9.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("C8");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_importC10.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("C9");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,8 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<body>
|
||||
<script>
|
||||
order.push("D");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="import" href="file_importD.html" onload="loaded()" onerror="failed()"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
order.push("E");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,4 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
</head>
|
||||
<body>Simple import</body>
|
@ -1,52 +0,0 @@
|
||||
[DEFAULT]
|
||||
support-files =
|
||||
file_importA1.html
|
||||
file_importA2.html
|
||||
file_importB1.html
|
||||
file_importB2.html
|
||||
file_importC1.html
|
||||
file_importC2.html
|
||||
file_importC3.html
|
||||
file_importC4.html
|
||||
file_importC5.html
|
||||
file_importC6.html
|
||||
file_importC7.html
|
||||
file_importC8.html
|
||||
file_importC9.html
|
||||
file_importC10.html
|
||||
file_importD.html
|
||||
file_importE.html
|
||||
file_cycle_1_A.html
|
||||
file_cycle_1_B.html
|
||||
file_cycle_1_C.html
|
||||
file_cycle_2_A.html
|
||||
file_cycle_2_B.html
|
||||
file_cycle_2_C.html
|
||||
file_cycle_2_D.html
|
||||
file_cycle_3_A.html
|
||||
file_cycle_3_B.html
|
||||
file_cycle_3_C.html
|
||||
file_cycle_4_A.html
|
||||
file_cycle_4_B.html
|
||||
file_cycle_4_C.html
|
||||
file_cycle_4_D.html
|
||||
file_cycle_4_E.html
|
||||
file_encoding.html
|
||||
file_simple_import.html
|
||||
file_blocking_DOMContentLoaded_A.html
|
||||
file_blocking_DOMContentLoaded_B.html
|
||||
file_blocking_DOMContentLoaded_C.html
|
||||
file_blocking_DOMContentLoaded_D.html
|
||||
file_element_upgrade.html
|
||||
file_CSP_sandbox.html
|
||||
file_CSP_sandbox_import.html
|
||||
|
||||
[test_cycle_1.html]
|
||||
[test_cycle_2.html]
|
||||
[test_cycle_3.html]
|
||||
[test_cycle_4.html]
|
||||
[test_blocking_DOMContentLoaded.html]
|
||||
[test_encoding.html]
|
||||
[test_defaultView.html]
|
||||
[test_element_upgrade.html]
|
||||
[test_CSP_sandbox.html]
|
@ -1,26 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1106713
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1106713</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1106713">Mozilla Bug 1106713</a>
|
||||
<script type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
function go() {
|
||||
var ifr = document.getElementById('iframe1').contentWindow;
|
||||
ok(!ifr.scriptExecuted, "script is not allowed to run");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
<iframe src='file_CSP_sandbox.html' sandbox="allow-same-origin" onload="go()" id="iframe1"></iframe>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,36 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1093028
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1093028</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1093028">Mozilla Bug 1093028</a>
|
||||
<script type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var counter = 0;
|
||||
var fcounter = 0;
|
||||
var order = [];
|
||||
function loaded() {
|
||||
counter++;
|
||||
}
|
||||
function failed() {
|
||||
fcounter++;
|
||||
}
|
||||
</script>
|
||||
<link rel="import" href="file_blocking_DOMContentLoaded_A.html" onload="loaded()" onerror="failed()"></link>
|
||||
<script type="text/javascript">
|
||||
is(counter, 4, "Imports are loaded");
|
||||
is(fcounter, 0, "No error in imports");
|
||||
var expected = ["AS0","BS0","CS0","DS0"];
|
||||
for (i in expected)
|
||||
is(order[i], expected[i], "import " + i + " should be " + expected[i]);
|
||||
SimpleTest.finish();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,36 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1061469
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1061469</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1061469">Mozilla Bug 1061469</a>
|
||||
<script type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var counter = 0;
|
||||
var fcounter = 0;
|
||||
var order = [];
|
||||
function loaded() {
|
||||
counter++;
|
||||
}
|
||||
function failed() {
|
||||
fcounter++;
|
||||
}
|
||||
</script>
|
||||
<link rel="import" href="file_cycle_1_A.html" onload="loaded()" onerror="failed()"></link>
|
||||
<script type="text/javascript">
|
||||
is(counter, 6, "Imports are loaded");
|
||||
is(fcounter, 0, "No error in imports");
|
||||
var expected = ["C","B","A"];
|
||||
for (i in expected)
|
||||
is(order[i], expected[i], "import " + i + " should be " + expected[i]);
|
||||
SimpleTest.finish();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,36 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1061469
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1061469</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1061469">Mozilla Bug 1061469</a>
|
||||
<script type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var counter = 0;
|
||||
var fcounter = 0;
|
||||
var order = [];
|
||||
function loaded() {
|
||||
counter++;
|
||||
}
|
||||
function failed() {
|
||||
fcounter++;
|
||||
}
|
||||
</script>
|
||||
<link rel="import" href="file_cycle_2_A.html" onload="loaded()" onerror="failed()"></link>
|
||||
<script type="text/javascript">
|
||||
is(counter, 5, "Imports are loaded");
|
||||
is(fcounter, 0, "No error in imports");
|
||||
var expected = ["C","D","B","A"];
|
||||
for (i in expected)
|
||||
is(order[i], expected[i], "import " + i + " should be " + expected[i]);
|
||||
SimpleTest.finish();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,37 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1061469
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1061469</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1061469">Mozilla Bug 1061469</a>
|
||||
<script type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var counter = 0;
|
||||
var fcounter = 0;
|
||||
var order = [];
|
||||
function loaded() {
|
||||
counter++;
|
||||
}
|
||||
function failed() {
|
||||
fcounter++;
|
||||
}
|
||||
</script>
|
||||
<link rel="import" href="file_cycle_3_A.html" onload="loaded()" onerror="failed()"></link>
|
||||
<link rel="import" href="file_cycle_3_B.html" onload="loaded()" onerror="failed()"></link>
|
||||
<script type="text/javascript">
|
||||
is(counter, 6, "Imports are loaded");
|
||||
is(fcounter, 0, "No error in imports");
|
||||
var expected = ["B","C","A"];
|
||||
for (i in expected)
|
||||
is(order[i], expected[i], "import " + i + " should be " + expected[i]);
|
||||
SimpleTest.finish();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,37 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1061469
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1061469</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1061469">Mozilla Bug 1061469</a>
|
||||
<script type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var counter = 0;
|
||||
var fcounter = 0;
|
||||
var order = [];
|
||||
function loaded() {
|
||||
counter++;
|
||||
}
|
||||
function failed() {
|
||||
fcounter++;
|
||||
}
|
||||
</script>
|
||||
<link rel="import" href="file_cycle_4_A.html" onload="loaded()" onerror="failed()"></link>
|
||||
<link rel="import" href="file_cycle_4_D.html" onload="loaded()" onerror="failed()"></link>
|
||||
<script type="text/javascript">
|
||||
is(counter, 8, "Imports are loaded");
|
||||
is(fcounter, 0, "No error in imports");
|
||||
var expected = ["E","D","C","B","A"];
|
||||
for (i in expected)
|
||||
is(order[i], expected[i], "import " + i + " should be " + expected[i]);
|
||||
SimpleTest.finish();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,31 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1061469
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1061469</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1061469">Mozilla Bug 1061469</a>
|
||||
<script type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var success = false;
|
||||
function loaded() {
|
||||
success = true;
|
||||
}
|
||||
function failed() {
|
||||
ok(false, "Import loading failed");
|
||||
}
|
||||
</script>
|
||||
<link rel="import" href="file_simple_import.html" id="import" onload="loaded()" onerror="failed()"></link>
|
||||
<script type="text/javascript">
|
||||
document.defaultView;
|
||||
is(document.getElementById("import").import.defaultView, null, "defaultView is always null for imports");
|
||||
SimpleTest.finish();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,34 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1081107
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1081107</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1081107">Mozilla Bug 1081107</a>
|
||||
<script type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var counter = 0;
|
||||
var fcounter = 0;
|
||||
var createdCallbackCalled = false;
|
||||
function loaded() {
|
||||
counter++;
|
||||
}
|
||||
function failed() {
|
||||
fcounter++;
|
||||
}
|
||||
</script>
|
||||
<link rel="import" href="file_element_upgrade.html" onload="loaded()" onerror="failed()"></link>
|
||||
<script type="text/javascript">
|
||||
is(counter, 1, "Imports are loaded");
|
||||
is(fcounter, 0, "No error in imports");
|
||||
ok(createdCallbackCalled, "custom element in import has been upgraded");
|
||||
SimpleTest.finish();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,30 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1061469
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1061469</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1061469">Mozilla Bug 1061469</a>
|
||||
<script type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var success = false;
|
||||
function loaded() {
|
||||
success = true;
|
||||
}
|
||||
function failed() {
|
||||
ok(false, "Import loading failed");
|
||||
}
|
||||
</script>
|
||||
<link rel="import" href="file_encoding.html" id="import" onload="loaded()" onerror="failed()"></link>
|
||||
<script type="text/javascript">
|
||||
is(document.getElementById("import").import.characterSet, "UTF-8", "characterSet should be UTF-8 for imports");
|
||||
SimpleTest.finish();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -165,10 +165,6 @@ support-files =
|
||||
file_iframe_sandbox_window_top_navigation_pass.html
|
||||
file_iframe_sandbox_window_top_navigation_fail.html
|
||||
file_iframe_sandbox_worker.js
|
||||
file_imports_basics.html
|
||||
file_imports_redirect.html
|
||||
file_imports_redirect.html^headers^
|
||||
file_imports_redirected.html
|
||||
file_srcdoc-2.html
|
||||
file_srcdoc.html
|
||||
file_window_open_close_outer.html
|
||||
@ -499,11 +495,6 @@ skip-if = toolkit == 'android' # bug 939642
|
||||
[test_iframe_sandbox_workers.html]
|
||||
[test_img_attributes_reflection.html]
|
||||
[test_imageSrcSet.html]
|
||||
[test_imports_basics.html]
|
||||
[test_imports_redirect.html]
|
||||
[test_imports_nonhttp.html]
|
||||
[test_imports_nested.html]
|
||||
[test_imports_nested_2.html]
|
||||
[test_li_attributes_reflection.html]
|
||||
[test_link_attributes_reflection.html]
|
||||
[test_link_sizes.html]
|
||||
|
@ -1,68 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=877072
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 877072</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=877072">Mozilla Bug 877072</a>
|
||||
|
||||
<script type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var loadEventFired = false;
|
||||
var errorEventFired = false;
|
||||
var counter = 0;
|
||||
function loaded() {
|
||||
loadEventFired = true;
|
||||
}
|
||||
function failed() {
|
||||
errorEventFired = true;
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel="import" href="file_imports_basics.html" id="import1" onload="loaded()" onerror="failed()"></link>
|
||||
|
||||
<script type="text/javascript">
|
||||
ok(importDone, "Script of the imported document runned before this script");
|
||||
ok(loadEventFired, "Load eventhandler works");
|
||||
ok(!errorEventFired, "There were no error event fired");
|
||||
|
||||
var import1 = document.getElementById("import1").import;
|
||||
is(import1.getElementById("foo").textContent, "bar",
|
||||
"import property of link import works");
|
||||
|
||||
try{
|
||||
import1.open();
|
||||
import1.write("<h1>This should not show up!</h1>");
|
||||
import1.close();
|
||||
} catch (e) {
|
||||
ok(true, "import.open/write should throw");
|
||||
}
|
||||
|
||||
// Let's add dynamically a new link import with the same URI
|
||||
var link = document.createElement("link");
|
||||
link.setAttribute("id", "inserted");
|
||||
link.setAttribute("rel", "import");
|
||||
link.setAttribute("href", "file_imports_basics.html");
|
||||
function loaded2() {
|
||||
ok(true, "Load event is fired for link import that refers to an already loaded import");
|
||||
is(counter, 1, "Adding another link referring to the same import, does not load it twice");
|
||||
is(document.getElementById("inserted").import.getElementById("foo").textContent, "bar",
|
||||
"import property of dynamic link import works");
|
||||
SimpleTest.finish();
|
||||
};
|
||||
link.setAttribute("onload", "loaded2()");
|
||||
function failed2() {
|
||||
ok(false, "You should not reach this code");
|
||||
SimpleTest.finish();
|
||||
};
|
||||
link.setAttribute("onerror", "failed2()");
|
||||
document.body.appendChild(link);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,41 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=877072
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 877072</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=877072">Mozilla Bug 877072</a>
|
||||
|
||||
<script type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var counter = 0;
|
||||
var fcounter = 0;
|
||||
var order = [];
|
||||
function loaded() {
|
||||
counter++;
|
||||
}
|
||||
function failed() {
|
||||
fcounter++;
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel="import" href="imports/file_importA1.html" id="A1" onload="loaded()" onerror="failed()"></link>
|
||||
<link rel="import" href="imports/file_importB1.html" id="B1" onload="loaded()" onerror="failed()"></link>
|
||||
<link rel="import" href="imports/file_importB2.html" id="B2_2" onload="loaded()" onerror="failed()"></link>
|
||||
|
||||
<script type="text/javascript">
|
||||
is(counter, 5, "Imports are loaded");
|
||||
is(fcounter, 0, "No error in imports");
|
||||
var expected = ["A2", "A1", "B2", "B1"];
|
||||
for (i in expected)
|
||||
is(order[i], expected[i], "import " + i + " should be " + expected[i]);
|
||||
SimpleTest.finish();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,56 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=877072
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 877072</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=877072">Mozilla Bug 877072</a>
|
||||
|
||||
<script type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var counter = 0;
|
||||
var fcounter = 0;
|
||||
var order = [];
|
||||
function loaded() {
|
||||
counter++;
|
||||
}
|
||||
function failed() {
|
||||
fcounter++;
|
||||
}
|
||||
</script>
|
||||
|
||||
<!--
|
||||
|
||||
Master -> c1 -> ... -> C10
|
||||
| | |
|
||||
| - - -> D |
|
||||
| ^ |
|
||||
| | |
|
||||
- - - -> E < - - - - - -
|
||||
|
||||
This test is for testing ImportLoader::UpdateDependants.Because of the long
|
||||
chain to C10, it's very likely that C10->E will be the last edge the ImportLoaders
|
||||
find. At that point it won't only have to update E but also its subimport D.
|
||||
|
||||
-->
|
||||
|
||||
<link rel="import" href="imports/file_importC1.html" onload="loaded()" onerror="failed()"></link>
|
||||
<link rel="import" href="imports/file_importD.html" onload="loaded()" onerror="failed()"></link>
|
||||
<link rel="import" href="imports/file_importE.html" onload="loaded()" onerror="failed()"></link>
|
||||
|
||||
<script type="text/javascript">
|
||||
is(counter, 14, "Imports are loaded"); // 12 imports but 14 link imports...
|
||||
is(fcounter, 0, "No error in imports");
|
||||
var expected = ["D", "E", "C10", "C9", "C8", "C7", "C6", "C5", "C4", "C3", "C2", "C1"];
|
||||
for (i in expected)
|
||||
is(order[i], expected[i], "import " + i + " should be " + expected[i]);
|
||||
SimpleTest.finish();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,56 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1016875
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1016875</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1016875">Mozilla Bug 1016875</a>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var counter = 0;
|
||||
function loaded() {
|
||||
if ( counter++ == 1 ) {
|
||||
ok(document.getElementById("import1").import.getElementById("div1"),
|
||||
"import document was loaded");
|
||||
ok(document.getElementById("import2").import.getElementById("div1"),
|
||||
"import document was loaded");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
function failed() {
|
||||
ok(false, "Import should not have failed")
|
||||
SimpleTest.finish();
|
||||
}
|
||||
var link = document.createElement("link");
|
||||
link.setAttribute("id", "import1");
|
||||
link.setAttribute("rel", "import");
|
||||
var stringDoc = "<!DOCTYPE html><html><body><div id='div1'></div></body></html>";
|
||||
var encoded = btoa(stringDoc);
|
||||
var dataurl = "data:text/html;base64," + encoded;
|
||||
link.setAttribute("href", dataurl);
|
||||
link.onload = loaded;
|
||||
link.onerror = failed;
|
||||
document.body.appendChild(link);
|
||||
|
||||
var link = document.createElement("link");
|
||||
link.setAttribute("id", "import2");
|
||||
link.setAttribute("rel", "import");
|
||||
var blob = new Blob([stringDoc], {type : 'text/html'});
|
||||
var objectURL = URL.createObjectURL(blob);
|
||||
link.setAttribute("href", objectURL);
|
||||
link.onload = loaded;
|
||||
link.onerror = failed;
|
||||
document.body.appendChild(link);
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,39 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1016875
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1016875</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1016875">Mozilla Bug 1016875</a>
|
||||
|
||||
<script type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var loadEventFired = false;
|
||||
var errorEventFired = false;
|
||||
var counter = 0;
|
||||
function loaded() {
|
||||
loadEventFired = true;
|
||||
}
|
||||
function failed() {
|
||||
errorEventFired = true;
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel="import" href="http://mochi.test:8888/tests/dom/html/test/file_imports_redirect.html" id="import" onload="loaded()" onerror="failed()"></link>
|
||||
|
||||
<script type="text/javascript">
|
||||
ok(loadEventFired, "Load event was fired");
|
||||
ok(!errorEventFired, "Error event was not fired, redirection worked");
|
||||
ok(redirected, "Script of the target of redirection was executed");
|
||||
|
||||
SimpleTest.finish();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -64,7 +64,12 @@ TCPServerSocket::Init()
|
||||
}
|
||||
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
mServerBridgeChild = new TCPServerSocketChild(this, mPort, mBacklog, mUseArrayBuffers);
|
||||
nsCOMPtr<nsIEventTarget> target;
|
||||
if (nsCOMPtr<nsIGlobalObject> global = GetOwnerGlobal()) {
|
||||
target = global->EventTargetFor(TaskCategory::Other);
|
||||
}
|
||||
mServerBridgeChild =
|
||||
new TCPServerSocketChild(this, mPort, mBacklog, mUseArrayBuffers, target);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -46,9 +46,13 @@ NS_IMETHODIMP_(MozExternalRefCountType) TCPServerSocketChild::Release(void)
|
||||
}
|
||||
|
||||
TCPServerSocketChild::TCPServerSocketChild(TCPServerSocket* aServerSocket, uint16_t aLocalPort,
|
||||
uint16_t aBacklog, bool aUseArrayBuffers)
|
||||
uint16_t aBacklog, bool aUseArrayBuffers,
|
||||
nsIEventTarget* aIPCEventTarget)
|
||||
{
|
||||
mServerSocket = aServerSocket;
|
||||
if (aIPCEventTarget) {
|
||||
gNeckoChild->SetEventTargetForActor(this, aIPCEventTarget);
|
||||
}
|
||||
AddIPDLReference();
|
||||
gNeckoChild->SendPTCPServerSocketConstructor(this, aLocalPort, aBacklog, aUseArrayBuffers);
|
||||
}
|
||||
|
@ -44,7 +44,8 @@ public:
|
||||
NS_IMETHOD_(MozExternalRefCountType) Release() override;
|
||||
|
||||
TCPServerSocketChild(TCPServerSocket* aServerSocket, uint16_t aLocalPort,
|
||||
uint16_t aBacklog, bool aUseArrayBuffers);
|
||||
uint16_t aBacklog, bool aUseArrayBuffers,
|
||||
nsIEventTarget* aIPCEventTarget);
|
||||
~TCPServerSocketChild();
|
||||
|
||||
void Close();
|
||||
|
@ -270,7 +270,12 @@ TCPSocket::Init()
|
||||
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
mReadyState = TCPReadyState::Connecting;
|
||||
mSocketBridgeChild = new TCPSocketChild(mHost, mPort);
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target;
|
||||
if (nsCOMPtr<nsIGlobalObject> global = GetOwnerGlobal()) {
|
||||
target = global->EventTargetFor(TaskCategory::Other);
|
||||
}
|
||||
mSocketBridgeChild = new TCPSocketChild(mHost, mPort, target);
|
||||
mSocketBridgeChild->SendOpen(this, mSsl, mUseArrayBuffers);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -88,9 +88,12 @@ NS_IMETHODIMP_(MozExternalRefCountType) TCPSocketChild::Release(void)
|
||||
return refcnt;
|
||||
}
|
||||
|
||||
TCPSocketChild::TCPSocketChild(const nsAString& aHost, const uint16_t& aPort)
|
||||
TCPSocketChild::TCPSocketChild(const nsAString& aHost,
|
||||
const uint16_t& aPort,
|
||||
nsIEventTarget* aTarget)
|
||||
: mHost(aHost)
|
||||
, mPort(aPort)
|
||||
, mIPCEventTarget(aTarget)
|
||||
{
|
||||
}
|
||||
|
||||
@ -99,6 +102,10 @@ TCPSocketChild::SendOpen(nsITCPSocketCallback* aSocket, bool aUseSSL, bool aUseA
|
||||
{
|
||||
mSocket = aSocket;
|
||||
|
||||
if (mIPCEventTarget) {
|
||||
gNeckoChild->SetEventTargetForActor(this, mIPCEventTarget);
|
||||
}
|
||||
|
||||
AddIPDLReference();
|
||||
gNeckoChild->SendPTCPSocketConstructor(this, mHost, mPort);
|
||||
MOZ_ASSERT(mFilterName.IsEmpty()); // Currently nobody should use this
|
||||
@ -112,6 +119,11 @@ TCPSocketChild::SendWindowlessOpenBind(nsITCPSocketCallback* aSocket,
|
||||
bool aUseSSL, bool aReuseAddrPort)
|
||||
{
|
||||
mSocket = aSocket;
|
||||
|
||||
if (mIPCEventTarget) {
|
||||
gNeckoChild->SetEventTargetForActor(this, mIPCEventTarget);
|
||||
}
|
||||
|
||||
AddIPDLReference();
|
||||
gNeckoChild->SendPTCPSocketConstructor(this,
|
||||
NS_ConvertUTF8toUTF16(aRemoteHost),
|
||||
|
@ -49,7 +49,9 @@ class TCPSocketChild : public mozilla::net::PTCPSocketChild
|
||||
public:
|
||||
NS_IMETHOD_(MozExternalRefCountType) Release() override;
|
||||
|
||||
TCPSocketChild(const nsAString& aHost, const uint16_t& aPort);
|
||||
TCPSocketChild(const nsAString& aHost,
|
||||
const uint16_t& aPort,
|
||||
nsIEventTarget* aTarget);
|
||||
~TCPSocketChild();
|
||||
|
||||
void SendOpen(nsITCPSocketCallback* aSocket, bool aUseSSL, bool aUseArrayBuffers);
|
||||
@ -82,6 +84,7 @@ private:
|
||||
nsString mHost;
|
||||
uint16_t mPort;
|
||||
nsCString mFilterName;
|
||||
nsCOMPtr<nsIEventTarget> mIPCEventTarget;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -498,6 +498,11 @@ UDPSocket::InitRemote(const nsAString& aLocalAddress,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target;
|
||||
if (nsCOMPtr<nsIGlobalObject> global = GetOwnerGlobal()) {
|
||||
target = global->EventTargetFor(TaskCategory::Other);
|
||||
}
|
||||
|
||||
rv = sock->Bind(mListenerProxy,
|
||||
principal,
|
||||
NS_ConvertUTF16toUTF8(aLocalAddress),
|
||||
@ -505,7 +510,8 @@ UDPSocket::InitRemote(const nsAString& aLocalAddress,
|
||||
mAddressReuse,
|
||||
mLoopback,
|
||||
0,
|
||||
0);
|
||||
0,
|
||||
target);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
|
@ -165,7 +165,8 @@ UDPSocketChild::Bind(nsIUDPSocketInternal* aSocket,
|
||||
bool aAddressReuse,
|
||||
bool aLoopback,
|
||||
uint32_t recvBufferSize,
|
||||
uint32_t sendBufferSize)
|
||||
uint32_t sendBufferSize,
|
||||
nsIEventTarget* aMainThreadEventTarget)
|
||||
{
|
||||
UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, PromiseFlatCString(aHost).get(), aPort));
|
||||
|
||||
@ -180,6 +181,9 @@ UDPSocketChild::Bind(nsIUDPSocketInternal* aSocket,
|
||||
MOZ_ASSERT(!aPrincipal);
|
||||
mBackgroundManager->SendPUDPSocketConstructor(this, void_t(), mFilterName);
|
||||
} else {
|
||||
if (aMainThreadEventTarget) {
|
||||
gNeckoChild->SetEventTargetForActor(this, aMainThreadEventTarget);
|
||||
}
|
||||
gNeckoChild->SendPUDPSocketConstructor(this, IPC::Principal(aPrincipal),
|
||||
mFilterName);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
interface nsIUDPSocketInternal;
|
||||
interface nsIInputStream;
|
||||
interface nsIPrincipal;
|
||||
interface nsIEventTarget;
|
||||
|
||||
%{ C++
|
||||
namespace mozilla {
|
||||
@ -33,7 +34,8 @@ interface nsIUDPSocketChild : nsISupports
|
||||
void bind(in nsIUDPSocketInternal socket, in nsIPrincipal principal,
|
||||
in AUTF8String host, in unsigned short port,
|
||||
in bool addressReuse, in bool loopback, in uint32_t recvBufferSize,
|
||||
in uint32_t sendBufferSize);
|
||||
in uint32_t sendBufferSize,
|
||||
[optional] in nsIEventTarget mainThreadTarget);
|
||||
|
||||
// Tell the chrome process to connect the UDP socket to a given remote host and port
|
||||
void connect(in nsIUDPSocketInternal socket, in AUTF8String host, in unsigned short port);
|
||||
|
@ -54,7 +54,6 @@
|
||||
#include "nsSandboxFlags.h"
|
||||
#include "nsContentTypeParser.h"
|
||||
#include "nsINetworkPredictor.h"
|
||||
#include "ImportManager.h"
|
||||
#include "mozilla/dom/EncodingUtils.h"
|
||||
#include "mozilla/ConsoleReportCollector.h"
|
||||
|
||||
@ -402,12 +401,6 @@ ScriptLoader::CreateModuleScript(ModuleLoadRequest* aRequest)
|
||||
{
|
||||
// Update our current script.
|
||||
AutoCurrentScriptUpdater scriptUpdater(this, aRequest->mElement);
|
||||
Maybe<AutoCurrentScriptUpdater> masterScriptUpdater;
|
||||
nsCOMPtr<nsIDocument> master = mDocument->MasterDocument();
|
||||
if (master != mDocument) {
|
||||
masterScriptUpdater.emplace(master->ScriptLoader(),
|
||||
aRequest->mElement);
|
||||
}
|
||||
|
||||
JSContext* cx = aes.cx();
|
||||
JS::Rooted<JSObject*> module(cx);
|
||||
@ -864,7 +857,7 @@ ScriptLoader::StartLoad(ScriptLoadRequest* aRequest)
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILoadGroup> loadGroup = mDocument->GetDocumentLoadGroup();
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = mDocument->MasterDocument()->GetWindow();
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = mDocument->GetWindow();
|
||||
NS_ENSURE_TRUE(window, NS_ERROR_NULL_POINTER);
|
||||
nsIDocShell* docshell = window->GetDocShell();
|
||||
nsCOMPtr<nsIInterfaceRequestor> prompter(do_QueryInterface(docshell));
|
||||
@ -1696,13 +1689,13 @@ ScriptLoader::ProcessRequest(ScriptLoadRequest* aRequest)
|
||||
|
||||
// The window may have gone away by this point, in which case there's no point
|
||||
// in trying to run the script.
|
||||
nsCOMPtr<nsIDocument> master = mDocument->MasterDocument();
|
||||
|
||||
{
|
||||
// Try to perform a microtask checkpoint
|
||||
nsAutoMicroTask mt;
|
||||
}
|
||||
|
||||
nsPIDOMWindowInner* pwin = master->GetInnerWindow();
|
||||
nsPIDOMWindowInner* pwin = mDocument->GetInnerWindow();
|
||||
bool runScript = !!pwin;
|
||||
if (runScript) {
|
||||
nsContentUtils::DispatchTrustedEvent(scriptElem->OwnerDoc(),
|
||||
@ -1712,7 +1705,7 @@ ScriptLoader::ProcessRequest(ScriptLoadRequest* aRequest)
|
||||
}
|
||||
|
||||
// Inner window could have gone away after firing beforescriptexecute
|
||||
pwin = master->GetInnerWindow();
|
||||
pwin = mDocument->GetInnerWindow();
|
||||
if (!pwin) {
|
||||
runScript = false;
|
||||
}
|
||||
@ -1787,8 +1780,7 @@ ScriptLoader::FireScriptEvaluated(nsresult aResult,
|
||||
already_AddRefed<nsIScriptGlobalObject>
|
||||
ScriptLoader::GetScriptGlobalObject()
|
||||
{
|
||||
nsCOMPtr<nsIDocument> master = mDocument->MasterDocument();
|
||||
nsPIDOMWindowInner* pwin = master->GetInnerWindow();
|
||||
nsPIDOMWindowInner* pwin = mDocument->GetInnerWindow();
|
||||
if (!pwin) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -2056,17 +2048,6 @@ ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest)
|
||||
{
|
||||
// Update our current script.
|
||||
AutoCurrentScriptUpdater scriptUpdater(this, aRequest->mElement);
|
||||
Maybe<AutoCurrentScriptUpdater> masterScriptUpdater;
|
||||
nsCOMPtr<nsIDocument> master = mDocument->MasterDocument();
|
||||
if (master != mDocument) {
|
||||
// If this script belongs to an import document, it will be
|
||||
// executed in the context of the master document. During the
|
||||
// execution currentScript of the master should refer to this
|
||||
// script. So let's update the mCurrentScript of the ScriptLoader
|
||||
// of the master document too.
|
||||
masterScriptUpdater.emplace(master->ScriptLoader(),
|
||||
aRequest->mElement);
|
||||
}
|
||||
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
// When a module is already loaded, it is not feched a second time and the
|
||||
@ -2446,42 +2427,6 @@ ScriptLoader::ReadyToExecuteParserBlockingScripts()
|
||||
}
|
||||
}
|
||||
|
||||
if (mDocument && !mDocument->IsMasterDocument()) {
|
||||
RefPtr<ImportManager> im = mDocument->ImportManager();
|
||||
RefPtr<ImportLoader> loader = im->Find(mDocument);
|
||||
MOZ_ASSERT(loader, "How can we have an import document without a loader?");
|
||||
|
||||
// The referring link that counts in the execution order calculation
|
||||
// (in spec: flagged as branch)
|
||||
nsCOMPtr<nsINode> referrer = loader->GetMainReferrer();
|
||||
MOZ_ASSERT(referrer, "There has to be a main referring link for each imports");
|
||||
|
||||
// Import documents are blocked by their import predecessors. We need to
|
||||
// wait with script execution until all the predecessors are done.
|
||||
// Technically it means we have to wait for the last one to finish,
|
||||
// which is the neares one to us in the order.
|
||||
RefPtr<ImportLoader> lastPred = im->GetNearestPredecessor(referrer);
|
||||
if (!lastPred) {
|
||||
// If there is no predecessor we can run.
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = lastPred->GetDocument();
|
||||
if (lastPred->IsBlocking() || !doc ||
|
||||
!doc->ScriptLoader()->SelfReadyToExecuteParserBlockingScripts()) {
|
||||
// Document has not been created yet or it was created but not ready.
|
||||
// Either case we are blocked by it. The ImportLoader will take care
|
||||
// of blocking us, and adding the pending child loader to the blocking
|
||||
// ScriptLoader when it's possible (at this point the blocking loader
|
||||
// might not have created the document/ScriptLoader)
|
||||
lastPred->AddBlockedScriptLoader(this);
|
||||
// As more imports are parsed, this can change, let's cache what we
|
||||
// blocked, so it can be later updated if needed (see: ImportLoader::Updater).
|
||||
loader->SetBlockingPredecessor(lastPred);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,9 @@ nsresult
|
||||
GenerateOriginKey(nsIPrincipal* aPrincipal, nsACString& aOriginAttrSuffix,
|
||||
nsACString& aOriginKey)
|
||||
{
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
if (NS_WARN_IF(!aPrincipal)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
aPrincipal->OriginAttributesRef().CreateSuffix(aOriginAttrSuffix);
|
||||
|
||||
|
@ -46,12 +46,6 @@ partial interface HTMLLinkElement {
|
||||
attribute DOMString target;
|
||||
};
|
||||
|
||||
// http://w3c.github.io/webcomponents/spec/imports/#interface-import
|
||||
partial interface HTMLLinkElement {
|
||||
[Func="nsDocument::IsWebComponentsEnabled"]
|
||||
readonly attribute Document? import;
|
||||
};
|
||||
|
||||
// https://w3c.github.io/webappsec/specs/subresourceintegrity/#htmllinkelement-1
|
||||
partial interface HTMLLinkElement {
|
||||
[SetterThrows]
|
||||
|
@ -114,13 +114,13 @@ gfxCallbackDrawable::gfxCallbackDrawable(gfxDrawingCallback* aCallback,
|
||||
}
|
||||
|
||||
already_AddRefed<gfxSurfaceDrawable>
|
||||
gfxCallbackDrawable::MakeSurfaceDrawable(const SamplingFilter aSamplingFilter)
|
||||
gfxCallbackDrawable::MakeSurfaceDrawable(gfxContext *aContext, const SamplingFilter aSamplingFilter)
|
||||
{
|
||||
SurfaceFormat format =
|
||||
gfxPlatform::GetPlatform()->Optimal2DFormatForContent(gfxContentType::COLOR_ALPHA);
|
||||
RefPtr<DrawTarget> dt =
|
||||
gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(mSize,
|
||||
format);
|
||||
aContext->GetDrawTarget()->CreateSimilarDrawTarget(mSize, format);
|
||||
|
||||
if (!dt || !dt->IsValid())
|
||||
return nullptr;
|
||||
|
||||
@ -160,7 +160,7 @@ gfxCallbackDrawable::Draw(gfxContext* aContext,
|
||||
{
|
||||
if ((IsRepeatingExtendMode(aExtendMode) || aOpacity != 1.0 || aContext->CurrentOp() != CompositionOp::OP_OVER) &&
|
||||
!mSurfaceDrawable) {
|
||||
mSurfaceDrawable = MakeSurfaceDrawable(aSamplingFilter);
|
||||
mSurfaceDrawable = MakeSurfaceDrawable(aContext, aSamplingFilter);
|
||||
}
|
||||
|
||||
if (mSurfaceDrawable)
|
||||
|
@ -148,8 +148,9 @@ public:
|
||||
|
||||
protected:
|
||||
already_AddRefed<gfxSurfaceDrawable>
|
||||
MakeSurfaceDrawable(mozilla::gfx::SamplingFilter aSamplingFilter =
|
||||
mozilla::gfx::SamplingFilter::LINEAR);
|
||||
MakeSurfaceDrawable(gfxContext* aContext,
|
||||
mozilla::gfx::SamplingFilter aSamplingFilter =
|
||||
mozilla::gfx::SamplingFilter::LINEAR);
|
||||
|
||||
RefPtr<gfxDrawingCallback> mCallback;
|
||||
RefPtr<gfxSurfaceDrawable> mSurfaceDrawable;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user