mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
commit
fd4709f9c1
@ -403,9 +403,10 @@ DocAccessibleParent::RecvShutdown()
|
||||
{
|
||||
Destroy();
|
||||
|
||||
if (!static_cast<dom::TabParent*>(Manager())->IsDestroyed()) {
|
||||
auto mgr = static_cast<dom::TabParent*>(Manager());
|
||||
if (!mgr->IsDestroyed()) {
|
||||
if (!PDocAccessibleParent::Send__delete__(this)) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
return IPC_FAIL_NO_REASON(mgr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -317,62 +317,7 @@ Target.prototype = {
|
||||
},
|
||||
|
||||
_logHistogram(metric) {
|
||||
if (!developerHUD._telemetry || metric.skipTelemetry) {
|
||||
return;
|
||||
}
|
||||
|
||||
metric.appName = this.appName;
|
||||
if (!metric.appName) {
|
||||
return;
|
||||
}
|
||||
|
||||
let metricName = metric.name.toUpperCase();
|
||||
let metricAppName = metric.appName.toUpperCase();
|
||||
if (!metric.custom) {
|
||||
let keyedMetricName = 'DEVTOOLS_HUD_' + metricName;
|
||||
try {
|
||||
let keyed = Services.telemetry.getKeyedHistogramById(keyedMetricName);
|
||||
if (keyed) {
|
||||
keyed.add(metric.appName, parseInt(metric.value, 10));
|
||||
developerHUD._histograms.add(keyedMetricName);
|
||||
telemetryDebug(keyedMetricName, metric.value, metric.appName);
|
||||
}
|
||||
} catch(err) {
|
||||
console.error('Histogram error is metricname added to histograms.json:'
|
||||
+ keyedMetricName);
|
||||
}
|
||||
} else {
|
||||
let histogramName = CUSTOM_HISTOGRAM_PREFIX + metricAppName + '_'
|
||||
+ metricName;
|
||||
// This is a call to add a value to an existing histogram.
|
||||
if (typeof metric.value !== 'undefined') {
|
||||
Services.telemetry.getAddonHistogram(metricAppName,
|
||||
CUSTOM_HISTOGRAM_PREFIX + metricName).add(parseInt(metric.value, 10));
|
||||
telemetryDebug(histogramName, metric.value);
|
||||
return;
|
||||
}
|
||||
|
||||
// The histogram already exists and are not adding data to it.
|
||||
if (developerHUD._customHistograms.has(histogramName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This is a call to create a new histogram.
|
||||
try {
|
||||
let metricType = parseInt(metric.type, 10);
|
||||
if (metricType === Services.telemetry.HISTOGRAM_COUNT) {
|
||||
Services.telemetry.registerAddonHistogram(metricAppName,
|
||||
CUSTOM_HISTOGRAM_PREFIX + metricName, metricType);
|
||||
} else {
|
||||
Services.telemetry.registerAddonHistogram(metricAppName,
|
||||
CUSTOM_HISTOGRAM_PREFIX + metricName, metricType, metric.min,
|
||||
metric.max, metric.buckets);
|
||||
}
|
||||
developerHUD._customHistograms.add(histogramName);
|
||||
} catch (err) {
|
||||
console.error('Histogram error: ' + err);
|
||||
}
|
||||
}
|
||||
//method left as no-op as histograms are not in use anymore.
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1147,7 +1147,7 @@ var gBrowserInit = {
|
||||
// we are swapping in.
|
||||
gBrowser.updateBrowserRemoteness(gBrowser.selectedBrowser,
|
||||
tabToOpen.linkedBrowser.isRemoteBrowser,
|
||||
tabToOpen.linkedBrowser.remoteType);
|
||||
{ remoteType: tabToOpen.linkedBrowser.remoteType });
|
||||
gBrowser.swapBrowsersAndCloseOther(gBrowser.selectedTab, tabToOpen);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
@ -4254,13 +4254,13 @@ var XULBrowserWindow = {
|
||||
forceInitialBrowserRemote: function(aRemoteType) {
|
||||
let initBrowser =
|
||||
document.getAnonymousElementByAttribute(gBrowser, "anonid", "initialBrowser");
|
||||
gBrowser.updateBrowserRemoteness(initBrowser, true, aRemoteType, null);
|
||||
gBrowser.updateBrowserRemoteness(initBrowser, true, { remoteType: aRemoteType });
|
||||
},
|
||||
|
||||
forceInitialBrowserNonRemote: function(aOpener) {
|
||||
let initBrowser =
|
||||
document.getAnonymousElementByAttribute(gBrowser, "anonid", "initialBrowser");
|
||||
gBrowser.updateBrowserRemoteness(initBrowser, false, E10SUtils.NOT_REMOTE, aOpener);
|
||||
gBrowser.updateBrowserRemoteness(initBrowser, false, { opener: aOpener });
|
||||
},
|
||||
|
||||
setDefaultStatus: function(status) {
|
||||
@ -4669,6 +4669,17 @@ var XULBrowserWindow = {
|
||||
if (loadingDone)
|
||||
return;
|
||||
this.onStatusChange(gBrowser.webProgress, null, 0, aMessage);
|
||||
},
|
||||
|
||||
navigateAndRestoreByIndex: function XWB_navigateAndRestoreByIndex(aBrowser, aIndex) {
|
||||
let tab = gBrowser.getTabForBrowser(aBrowser);
|
||||
if (tab) {
|
||||
SessionStore.navigateAndRestore(tab, {}, aIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Error("Trying to navigateAndRestore a browser which was " +
|
||||
"not attached to this tabbrowser is unsupported");
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1669,38 +1669,37 @@
|
||||
<method name="updateBrowserRemoteness">
|
||||
<parameter name="aBrowser"/>
|
||||
<parameter name="aShouldBeRemote"/>
|
||||
<parameter name="aNewRemoteType"/>
|
||||
<parameter name="aOpener"/>
|
||||
<parameter name="aFreshProcess"/>
|
||||
<parameter name="aOptions"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
aOptions = aOptions || {};
|
||||
let isRemote = aBrowser.getAttribute("remote") == "true";
|
||||
|
||||
if (!gMultiProcessBrowser && aShouldBeRemote) {
|
||||
throw new Error("Cannot switch to remote browser in a window " +
|
||||
"without the remote tabs load context.");
|
||||
}
|
||||
|
||||
let isRemote = aBrowser.getAttribute("remote") == "true";
|
||||
|
||||
// If going remote and no aNewRemoteType then use default.
|
||||
if (aShouldBeRemote && !aNewRemoteType) {
|
||||
aNewRemoteType = E10SUtils.DEFAULT_REMOTE_TYPE;
|
||||
// Default values for remoteType
|
||||
if (!aOptions.remoteType) {
|
||||
aOptions.remoteType = aShouldBeRemote ? E10SUtils.DEFAULT_REMOTE_TYPE : E10SUtils.NOT_REMOTE;
|
||||
}
|
||||
|
||||
// If we are passed an opener, we must be making the browser non-remote, and
|
||||
// if the browser is _currently_ non-remote, we need the openers to match,
|
||||
// because it is already too late to change it.
|
||||
if (aOpener) {
|
||||
if (aOptions.opener) {
|
||||
if (aShouldBeRemote) {
|
||||
throw new Error("Cannot set an opener on a browser which should be remote!");
|
||||
}
|
||||
if (!isRemote && aBrowser.contentWindow.opener != aOpener) {
|
||||
if (!isRemote && aBrowser.contentWindow.opener != aOptions.opener) {
|
||||
throw new Error("Cannot change opener on an already non-remote browser!");
|
||||
}
|
||||
}
|
||||
|
||||
// Abort if we're not going to change anything
|
||||
if (isRemote == aShouldBeRemote && !aFreshProcess &&
|
||||
(!isRemote || aBrowser.getAttribute("remoteType") == aNewRemoteType)) {
|
||||
if (isRemote == aShouldBeRemote && !aOptions.newFrameloader && !aOptions.freshProcess &&
|
||||
(!isRemote || aBrowser.getAttribute("remoteType") == aOptions.remoteType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1739,7 +1738,7 @@
|
||||
parent.removeChild(aBrowser);
|
||||
if (aShouldBeRemote) {
|
||||
aBrowser.setAttribute("remote", "true");
|
||||
aBrowser.setAttribute("remoteType", aNewRemoteType);
|
||||
aBrowser.setAttribute("remoteType", aOptions.remoteType);
|
||||
} else {
|
||||
aBrowser.setAttribute("remote", "false");
|
||||
aBrowser.removeAttribute("remoteType");
|
||||
@ -1749,13 +1748,15 @@
|
||||
// turns this normal property into a field.
|
||||
aBrowser.relatedBrowser = relatedBrowser;
|
||||
|
||||
// Set the opener window on the browser, such that when the frame
|
||||
// loader is created the opener is set correctly.
|
||||
aBrowser.presetOpenerWindow(aOpener);
|
||||
if (aOptions.opener) {
|
||||
// Set the opener window on the browser, such that when the frame
|
||||
// loader is created the opener is set correctly.
|
||||
aBrowser.presetOpenerWindow(aOptions.opener);
|
||||
}
|
||||
|
||||
// Set the freshProcess attribute so that the frameloader knows to
|
||||
// create a new process
|
||||
if (aFreshProcess) {
|
||||
if (aOptions.freshProcess) {
|
||||
aBrowser.setAttribute("freshProcess", "true");
|
||||
}
|
||||
|
||||
@ -1830,24 +1831,24 @@
|
||||
<method name="updateBrowserRemotenessByURL">
|
||||
<parameter name="aBrowser"/>
|
||||
<parameter name="aURL"/>
|
||||
<parameter name="aFreshProcess"/>
|
||||
<parameter name="aOptions"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
aOptions = aOptions || {};
|
||||
|
||||
if (!gMultiProcessBrowser)
|
||||
return this.updateBrowserRemoteness(aBrowser, false);
|
||||
|
||||
// If this URL can't load in the current browser then flip it to the
|
||||
// correct type.
|
||||
let currentRemoteType = aBrowser.remoteType;
|
||||
let requiredRemoteType =
|
||||
aOptions.remoteType =
|
||||
E10SUtils.getRemoteTypeForURI(aURL, gMultiProcessBrowser,
|
||||
currentRemoteType);
|
||||
if (currentRemoteType != requiredRemoteType || aFreshProcess) {
|
||||
return this.updateBrowserRemoteness(aBrowser,
|
||||
!!requiredRemoteType,
|
||||
requiredRemoteType,
|
||||
/* aOpener */ null,
|
||||
aFreshProcess);
|
||||
if (currentRemoteType != aOptions.remoteType ||
|
||||
aOptions.freshProcess || aOptions.newFrameloader) {
|
||||
let remote = aOptions.remoteType != E10SUtils.NOT_REMOTE;
|
||||
return this.updateBrowserRemoteness(aBrowser, remote, aOptions);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -2525,6 +2526,13 @@
|
||||
|
||||
var browser = this.getBrowserForTab(aTab);
|
||||
|
||||
// Start closing the FrameLoaderOwners which are inactive, so that
|
||||
// they are cleaned up as well.
|
||||
let frameLoader = browser.frameLoader;
|
||||
if (frameLoader && frameLoader.groupedSessionHistory) {
|
||||
frameLoader.groupedSessionHistory.closeInactiveFrameLoaderOwners();
|
||||
}
|
||||
|
||||
if (!aTab._pendingPermitUnload && !aAdoptedByTab && !aSkipPermitUnload) {
|
||||
// We need to block while calling permitUnload() because it
|
||||
// processes the event queue and may lead to another removeTab()
|
||||
@ -2916,11 +2924,29 @@
|
||||
|
||||
<method name="swapBrowsers">
|
||||
<parameter name="aOurTab"/>
|
||||
<parameter name="aOtherBrowser"/>
|
||||
<parameter name="aOtherTab"/>
|
||||
<parameter name="aFlags"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
this._swapBrowserDocShells(aOurTab, aOtherBrowser, aFlags);
|
||||
let otherBrowser = aOtherTab.linkedBrowser;
|
||||
let otherTabBrowser = otherBrowser.getTabBrowser();
|
||||
|
||||
// We aren't closing the other tab so, we also need to swap its tablisteners.
|
||||
let filter = otherTabBrowser._tabFilters.get(aOtherTab);
|
||||
let tabListener = otherTabBrowser._tabListeners.get(aOtherTab);
|
||||
otherBrowser.webProgress.removeProgressListener(filter);
|
||||
filter.removeProgressListener(tabListener);
|
||||
|
||||
// Perform the docshell swap through the common mechanism.
|
||||
this._swapBrowserDocShells(aOurTab, otherBrowser, aFlags);
|
||||
|
||||
// Restore the listeners for the swapped in tab.
|
||||
tabListener = otherTabBrowser.mTabProgressListener(aOtherTab, otherBrowser, false, false);
|
||||
otherTabBrowser._tabListeners.set(aOtherTab, tabListener);
|
||||
|
||||
const notifyAll = Ci.nsIWebProgress.NOTIFY_ALL;
|
||||
filter.addProgressListener(tabListener, notifyAll);
|
||||
otherBrowser.webProgress.addProgressListener(filter, notifyAll);
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
@ -492,3 +492,5 @@ tags = mcb
|
||||
[browser_newwindow_focus.js]
|
||||
skip-if = (os == "linux" && !e10s) # Bug 1263254 - Perma fails on Linux without e10s for some reason.
|
||||
[browser_bug1299667.js]
|
||||
[browser_close_dependent_tabs.js]
|
||||
skip-if = !e10s # GroupedSHistory is e10s-only
|
||||
|
@ -0,0 +1,51 @@
|
||||
add_task(function* () {
|
||||
yield SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.groupedhistory.enabled", true]]
|
||||
});
|
||||
|
||||
// Wait for a process change and then fulfil the promise.
|
||||
function awaitProcessChange(browser) {
|
||||
return new Promise(resolve => {
|
||||
browser.addEventListener("BrowserChangedProcess", function bcp(e) {
|
||||
browser.removeEventListener("BrowserChangedProcess", bcp);
|
||||
ok(true, "The browser changed process!");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
let tab2;
|
||||
|
||||
// Test 1: Create prerendered browser, and don't switch to it, then close the tab
|
||||
yield BrowserTestUtils.withNewTab({ gBrowser, url: "data:text/html,a" }, function* (browser1) {
|
||||
// Set up the grouped SHEntry setup
|
||||
tab2 = gBrowser.loadOneTab("data:text/html,b", {
|
||||
referrerPolicy: Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT,
|
||||
allowThirdPartyFixup: true,
|
||||
relatedToCurrent: true,
|
||||
isPrerendered: true,
|
||||
});
|
||||
});
|
||||
|
||||
// At this point tab2 should be closed
|
||||
todo(!tab2.linkedBrowser, "The new tab should be closed");
|
||||
yield BrowserTestUtils.removeTab(tab2); // XXX: Shouldn't be needed once the todo is fixed
|
||||
|
||||
// Test 2: Create prerendered browser, switch to it, then close the tab
|
||||
yield BrowserTestUtils.withNewTab({ gBrowser, url: "data:text/html,a" }, function* (browser1) {
|
||||
// Set up the grouped SHEntry setup
|
||||
tab2 = gBrowser.loadOneTab("data:text/html,b", {
|
||||
referrerPolicy: Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT,
|
||||
allowThirdPartyFixup: true,
|
||||
relatedToCurrent: true,
|
||||
isPrerendered: true,
|
||||
});
|
||||
yield BrowserTestUtils.browserLoaded(tab2.linkedBrowser);
|
||||
browser1.frameLoader.appendPartialSessionHistoryAndSwap(
|
||||
tab2.linkedBrowser.frameLoader);
|
||||
yield awaitProcessChange(browser1);
|
||||
});
|
||||
|
||||
// At this point tab2 should be closed
|
||||
ok(!tab2.linkedBrowser, "The new tab should be closed");
|
||||
});
|
@ -3611,8 +3611,17 @@ var SessionStoreInternal = {
|
||||
// flip the remoteness of any browser that is not being displayed.
|
||||
this.markTabAsRestoring(aTab);
|
||||
|
||||
// We need a new frameloader either if we are reloading into a fresh
|
||||
// process, or we have a browser with a grouped session history (as we don't
|
||||
// support restoring into browsers with grouped session histories directly).
|
||||
let newFrameloader =
|
||||
aReloadInFreshProcess || !!browser.frameLoader.groupedSessionHistory;
|
||||
let isRemotenessUpdate =
|
||||
tabbrowser.updateBrowserRemotenessByURL(browser, uri, aReloadInFreshProcess);
|
||||
tabbrowser.updateBrowserRemotenessByURL(browser, uri, {
|
||||
freshProcess: aReloadInFreshProcess,
|
||||
newFrameloader: newFrameloader,
|
||||
});
|
||||
|
||||
if (isRemotenessUpdate) {
|
||||
// We updated the remoteness, so we need to send the history down again.
|
||||
//
|
||||
|
@ -32,8 +32,8 @@
|
||||
},
|
||||
{
|
||||
"version": "clang 4.0pre/r286542",
|
||||
"size": 206088429,
|
||||
"digest": "a6de709a5097d98084b6111e340f53cd8397736f783aa6f76c9d45bcb694d3983ab3b7aea7f96756fcc4ee44f7b0e57df5ebabbd59242cd51942742fe1769d9a",
|
||||
"size": 222604502,
|
||||
"digest": "cea6119131adb66e0b7ec5030b00922ac95e4e97249fcab9561a848ea60b7f80536c9171a07136afcb79decbcdb20099a5e7ee493013710b8ba5ae072ad40851",
|
||||
"algorithm": "sha512",
|
||||
"filename": "clang.tar.bz2",
|
||||
"unpack": true
|
||||
|
@ -33,8 +33,8 @@
|
||||
},
|
||||
{
|
||||
"version": "clang 4.0pre/r286542",
|
||||
"size": 210049255,
|
||||
"digest": "8da8c653ea1948c13aa152cf0b1b0fa94e9619c49006ec80cc625d33cbf2dafa3533764f38fc0213e469cc786a738e5099f0e39d52e30f9a711718e8a3124311",
|
||||
"size": 226755339,
|
||||
"digest": "3c598607c36e70788ca7dbdf0d835f9e44fbcaa7b1ed77ef9971d743a5a230bebc0ccd2bcdf97f63ed4546d1b83f4c3556f35c30589c755aaaefbd674f750e22",
|
||||
"algorithm": "sha512",
|
||||
"filename": "clang.tar.bz2",
|
||||
"unpack": true
|
||||
|
@ -137,6 +137,11 @@ def install_libgcc(gcc_dir, clang_dir):
|
||||
copy_dir_contents(include_dir, clang_include_dir)
|
||||
|
||||
|
||||
def install_import_library(build_dir, clang_dir):
|
||||
shutil.copy2(os.path.join(build_dir, "lib", "clang.lib"),
|
||||
os.path.join(clang_dir, "lib"))
|
||||
|
||||
|
||||
def svn_co(source_dir, url, directory, revision):
|
||||
run_in(source_dir, ["svn", "co", "-q", "-r", revision, url, directory])
|
||||
|
||||
@ -211,7 +216,10 @@ def build_one_stage(cc, cxx, src_dir, stage_dir, build_libcxx,
|
||||
|
||||
if is_linux():
|
||||
install_libgcc(gcc_dir, inst_dir)
|
||||
|
||||
# For some reasons the import library clang.lib of clang.exe is not
|
||||
# installed, so we copy it by ourselves.
|
||||
if is_windows():
|
||||
install_import_library(build_dir, inst_dir)
|
||||
|
||||
def get_compiler(config, key):
|
||||
if key not in config:
|
||||
|
@ -39,9 +39,19 @@ interface nsIGroupedSHistory : nsISupports
|
||||
* corresponding to the given global index. Note it doesn't swap frameloaders,
|
||||
* but rather return the target loader for the caller to swap.
|
||||
*
|
||||
* @param aGlobalIndex The global index to navigate to.
|
||||
* @param aTargetLoaderToSwap The owner frameloader of the to-be-navigate
|
||||
* partial session history.
|
||||
* This function may throw NS_ERROR_NOT_AVAILABLE if the frameloader to swap
|
||||
* to is dead.
|
||||
*
|
||||
* @param aGlobalIndex
|
||||
* The global index to navigate to.
|
||||
* @return The frameloader which needs to be swapped in, or null if no
|
||||
* frameloader needs to be swapped.
|
||||
*/
|
||||
void gotoIndex(in unsigned long aGlobalIndex, out nsIFrameLoader aTargetLoaderToSwap);
|
||||
nsIFrameLoader gotoIndex(in unsigned long aGlobalIndex);
|
||||
|
||||
/**
|
||||
* Close the FrameLoaderOwners of the inactive PartialSHistories in this GlobalSHistory.
|
||||
* This does not remove the PartialSHistories from the GroupedSHistory.
|
||||
*/
|
||||
void closeInactiveFrameLoaderOwners();
|
||||
};
|
||||
|
@ -91,3 +91,5 @@ skip-if = true # Bug 1220415
|
||||
[browser_timelineMarkers-04.js]
|
||||
[browser_timelineMarkers-05.js]
|
||||
[browser_ua_emulation.js]
|
||||
[browser_grouped_shistory_dead_navigate.js]
|
||||
skip-if = !e10s
|
||||
|
@ -0,0 +1,44 @@
|
||||
add_task(function* () {
|
||||
yield SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.groupedhistory.enabled", true]]
|
||||
});
|
||||
|
||||
// Wait for a process change and then fulfil the promise.
|
||||
function awaitProcessChange(browser) {
|
||||
return new Promise(resolve => {
|
||||
browser.addEventListener("BrowserChangedProcess", function bcp(e) {
|
||||
browser.removeEventListener("BrowserChangedProcess", bcp);
|
||||
ok(true, "The browser changed process!");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
yield BrowserTestUtils.withNewTab({ gBrowser, url: "data:text/html,a" }, function* (browser1) {
|
||||
// Set up the grouped SHEntry setup
|
||||
let tab2 = gBrowser.loadOneTab("data:text/html,b", {
|
||||
referrerPolicy: Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT,
|
||||
allowThirdPartyFixup: true,
|
||||
relatedToCurrent: true,
|
||||
isPrerendered: true,
|
||||
});
|
||||
yield BrowserTestUtils.browserLoaded(tab2.linkedBrowser);
|
||||
browser1.frameLoader.appendPartialSessionHistoryAndSwap(
|
||||
tab2.linkedBrowser.frameLoader);
|
||||
yield awaitProcessChange(browser1);
|
||||
|
||||
// Close tab2 such that the back frameloader is dead
|
||||
yield BrowserTestUtils.removeTab(tab2);
|
||||
browser1.goBack();
|
||||
yield BrowserTestUtils.browserLoaded(browser1);
|
||||
yield ContentTask.spawn(browser1, null, function() {
|
||||
is(content.window.location + "", "data:text/html,a");
|
||||
let webNav = content.window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation);
|
||||
is(webNav.canGoForward, true, "canGoForward is correct");
|
||||
is(webNav.canGoBack, false, "canGoBack is correct");
|
||||
});
|
||||
is(browser1.frameLoader.groupedSessionHistory, null,
|
||||
"browser1's session history is now complete");
|
||||
});
|
||||
});
|
@ -75,11 +75,6 @@ const gMozillaSpecificProperties = {
|
||||
from: "ignore",
|
||||
to: "stretch-to-fit"
|
||||
},
|
||||
"-moz-tab-size": {
|
||||
// https://drafts.csswg.org/css-text-3/#propdef-tab-size
|
||||
from: "1",
|
||||
to: "5"
|
||||
},
|
||||
"-moz-text-size-adjust": {
|
||||
// https://drafts.csswg.org/css-size-adjust/#propdef-text-size-adjust
|
||||
from: "none",
|
||||
|
@ -99,6 +99,9 @@ NS_IMETHODIMP
|
||||
GroupedSHistory::GotoIndex(uint32_t aGlobalIndex,
|
||||
nsIFrameLoader** aTargetLoaderToSwap)
|
||||
{
|
||||
MOZ_ASSERT(aTargetLoaderToSwap);
|
||||
*aTargetLoaderToSwap = nullptr;
|
||||
|
||||
nsCOMPtr<nsIPartialSHistory> currentPartialHistory =
|
||||
mPartialHistories[mIndexOfActivePartialHistory];
|
||||
if (!currentPartialHistory) {
|
||||
@ -118,7 +121,15 @@ GroupedSHistory::GotoIndex(uint32_t aGlobalIndex,
|
||||
uint32_t count = partialHistory->GetCount();
|
||||
if (offset <= aGlobalIndex && (offset + count) > aGlobalIndex) {
|
||||
uint32_t targetIndex = aGlobalIndex - offset;
|
||||
partialHistory->GetOwnerFrameLoader(aTargetLoaderToSwap);
|
||||
|
||||
// Check if we are trying to swap to a dead frameloader, and return
|
||||
// NS_ERROR_NOT_AVAILABLE if we are.
|
||||
nsCOMPtr<nsIFrameLoader> frameLoader;
|
||||
partialHistory->GetOwnerFrameLoader(getter_AddRefs(frameLoader));
|
||||
if (!frameLoader || frameLoader->GetIsDead()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if ((size_t)mIndexOfActivePartialHistory == i) {
|
||||
return NS_OK;
|
||||
}
|
||||
@ -127,6 +138,9 @@ GroupedSHistory::GotoIndex(uint32_t aGlobalIndex,
|
||||
NS_FAILED(partialHistory->OnActive(mCount, targetIndex))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Return the target frameloader to the caller.
|
||||
frameLoader.forget(aTargetLoaderToSwap);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
@ -168,5 +182,18 @@ GroupedSHistory::GroupedHistoryEnabled() {
|
||||
return Preferences::GetBool("browser.groupedhistory.enabled", false);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GroupedSHistory::CloseInactiveFrameLoaderOwners()
|
||||
{
|
||||
for (int32_t i = 0; i < mPartialHistories.Count(); ++i) {
|
||||
if (i != mIndexOfActivePartialHistory) {
|
||||
nsCOMPtr<nsIFrameLoader> loader;
|
||||
mPartialHistories[i]->GetOwnerFrameLoader(getter_AddRefs(loader));
|
||||
loader->RequestFrameLoaderClose();
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -76,7 +76,6 @@ CalculateNewBackPressureDelayMS(uint32_t aBacklogDepth)
|
||||
|
||||
TimeoutManager::TimeoutManager(nsGlobalWindow& aWindow)
|
||||
: mWindow(aWindow),
|
||||
mTimeoutInsertionPoint(nullptr),
|
||||
mTimeoutIdCounter(1),
|
||||
mTimeoutFiringDepth(0),
|
||||
mRunningTimeout(nullptr),
|
||||
@ -226,7 +225,7 @@ TimeoutManager::ClearTimeout(int32_t aTimerId, Timeout::Reason aReason)
|
||||
uint32_t timerId = (uint32_t)aTimerId;
|
||||
Timeout* timeout;
|
||||
|
||||
for (timeout = mTimeouts.getFirst(); timeout; timeout = timeout->getNext()) {
|
||||
for (timeout = mTimeouts.GetFirst(); timeout; timeout = timeout->getNext()) {
|
||||
if (timeout->mTimeoutId == timerId && timeout->mReason == aReason) {
|
||||
if (timeout->mRunning) {
|
||||
/* We're running from inside the timeout. Mark this
|
||||
@ -296,7 +295,7 @@ TimeoutManager::RunTimeout(Timeout* aTimeout)
|
||||
// whose mWhen is greater than deadline, since once that happens we know
|
||||
// nothing past that point is expired.
|
||||
last_expired_timeout = nullptr;
|
||||
for (Timeout* timeout = mTimeouts.getFirst();
|
||||
for (Timeout* timeout = mTimeouts.GetFirst();
|
||||
timeout && timeout->mWhen <= deadline;
|
||||
timeout = timeout->getNext()) {
|
||||
if (timeout->mFiringDepth == 0) {
|
||||
@ -339,12 +338,12 @@ TimeoutManager::RunTimeout(Timeout* aTimeout)
|
||||
last_expired_timeout->setNext(dummy_timeout);
|
||||
RefPtr<Timeout> timeoutExtraRef(dummy_timeout);
|
||||
|
||||
last_insertion_point = mTimeoutInsertionPoint;
|
||||
// If we ever start setting mTimeoutInsertionPoint to a non-dummy timeout,
|
||||
// the logic in ResetTimersForThrottleReduction will need to change.
|
||||
mTimeoutInsertionPoint = dummy_timeout;
|
||||
last_insertion_point = mTimeouts.InsertionPoint();
|
||||
// If we ever start setting insertion point to a non-dummy timeout, the logic
|
||||
// in ResetTimersForThrottleReduction will need to change.
|
||||
mTimeouts.SetInsertionPoint(dummy_timeout);
|
||||
|
||||
for (Timeout* timeout = mTimeouts.getFirst();
|
||||
for (Timeout* timeout = mTimeouts.GetFirst();
|
||||
timeout != dummy_timeout && !mWindow.IsFrozen();
|
||||
timeout = nextTimeout) {
|
||||
nextTimeout = timeout->getNext();
|
||||
@ -387,7 +386,7 @@ TimeoutManager::RunTimeout(Timeout* aTimeout)
|
||||
MOZ_ASSERT(dummy_timeout->HasRefCntOne(), "dummy_timeout may leak");
|
||||
Unused << timeoutExtraRef.forget().take();
|
||||
|
||||
mTimeoutInsertionPoint = last_insertion_point;
|
||||
mTimeouts.SetInsertionPoint(last_insertion_point);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -417,7 +416,7 @@ TimeoutManager::RunTimeout(Timeout* aTimeout)
|
||||
timeoutExtraRef = nullptr;
|
||||
MOZ_ASSERT(dummy_timeout->HasRefCntOne(), "dummy_timeout may leak");
|
||||
|
||||
mTimeoutInsertionPoint = last_insertion_point;
|
||||
mTimeouts.SetInsertionPoint(last_insertion_point);
|
||||
|
||||
MaybeApplyBackPressure();
|
||||
}
|
||||
@ -598,15 +597,15 @@ TimeoutManager::ResetTimersForThrottleReduction(int32_t aPreviousThrottleDelayMS
|
||||
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
|
||||
// If mTimeoutInsertionPoint is non-null, we're in the middle of firing
|
||||
// timers and the timers we're planning to fire all come before
|
||||
// mTimeoutInsertionPoint; mTimeoutInsertionPoint itself is a dummy timeout
|
||||
// with an mWhen that may be semi-bogus. In that case, we don't need to do
|
||||
// anything with mTimeoutInsertionPoint or anything before it, so should
|
||||
// start at the timer after mTimeoutInsertionPoint, if there is one.
|
||||
// If insertion point is non-null, we're in the middle of firing timers and
|
||||
// the timers we're planning to fire all come before insertion point;
|
||||
// insertion point itself is a dummy timeout with an mWhen that may be
|
||||
// semi-bogus. In that case, we don't need to do anything with insertion
|
||||
// point or anything before it, so should start at the timer after insertion
|
||||
// point, if there is one.
|
||||
// Otherwise, start at the beginning of the list.
|
||||
for (Timeout* timeout = mTimeoutInsertionPoint ?
|
||||
mTimeoutInsertionPoint->getNext() : mTimeouts.getFirst();
|
||||
for (Timeout* timeout = mTimeouts.InsertionPoint() ?
|
||||
mTimeouts.InsertionPoint()->getNext() : mTimeouts.GetFirst();
|
||||
timeout; ) {
|
||||
// It's important that this check be <= so that we guarantee that
|
||||
// taking std::max with |now| won't make a quantity equal to
|
||||
@ -687,14 +686,15 @@ TimeoutManager::ClearAllTimeouts()
|
||||
Timeout* timeout;
|
||||
Timeout* nextTimeout;
|
||||
|
||||
for (timeout = mTimeouts.getFirst(); timeout; timeout = nextTimeout) {
|
||||
for (timeout = mTimeouts.GetFirst(); timeout; timeout = nextTimeout) {
|
||||
/* If RunTimeout() is higher up on the stack for this
|
||||
window, e.g. as a result of document.write from a timeout,
|
||||
then we need to reset the list insertion point for
|
||||
newly-created timeouts in case the user adds a timeout,
|
||||
before we pop the stack back to RunTimeout. */
|
||||
if (mRunningTimeout == timeout)
|
||||
mTimeoutInsertionPoint = nullptr;
|
||||
if (mRunningTimeout == timeout) {
|
||||
mTimeouts.SetInsertionPoint(nullptr);
|
||||
}
|
||||
|
||||
nextTimeout = timeout->getNext();
|
||||
|
||||
@ -716,18 +716,17 @@ TimeoutManager::ClearAllTimeouts()
|
||||
}
|
||||
|
||||
// Clear out our list
|
||||
mTimeouts.clear();
|
||||
mTimeouts.Clear();
|
||||
}
|
||||
|
||||
void
|
||||
TimeoutManager::InsertTimeoutIntoList(Timeout* aTimeout)
|
||||
{
|
||||
// Start at mLastTimeout and go backwards. Don't go further than
|
||||
// mTimeoutInsertionPoint, though. This optimizes for the common case of
|
||||
// insertion at the end.
|
||||
// Start at mLastTimeout and go backwards. Don't go further than insertion
|
||||
// point, though. This optimizes for the common case of insertion at the end.
|
||||
Timeout* prevSibling;
|
||||
for (prevSibling = mTimeouts.getLast();
|
||||
prevSibling && prevSibling != mTimeoutInsertionPoint &&
|
||||
for (prevSibling = mTimeouts.GetLast();
|
||||
prevSibling && prevSibling != mTimeouts.InsertionPoint() &&
|
||||
// This condition needs to match the one in SetTimeoutOrInterval that
|
||||
// determines whether to set mWhen or mTimeRemaining.
|
||||
(mWindow.IsFrozen() ?
|
||||
@ -741,7 +740,7 @@ TimeoutManager::InsertTimeoutIntoList(Timeout* aTimeout)
|
||||
if (prevSibling) {
|
||||
prevSibling->setNext(aTimeout);
|
||||
} else {
|
||||
mTimeouts.insertFront(aTimeout);
|
||||
mTimeouts.InsertFront(aTimeout);
|
||||
}
|
||||
|
||||
aTimeout->mFiringDepth = 0;
|
||||
@ -775,7 +774,7 @@ TimeoutManager::EndRunningTimeout(Timeout* aTimeout)
|
||||
void
|
||||
TimeoutManager::UnmarkGrayTimers()
|
||||
{
|
||||
for (Timeout* timeout = mTimeouts.getFirst();
|
||||
for (Timeout* timeout = mTimeouts.GetFirst();
|
||||
timeout;
|
||||
timeout = timeout->getNext()) {
|
||||
if (timeout->mScriptHandler) {
|
||||
@ -787,7 +786,7 @@ TimeoutManager::UnmarkGrayTimers()
|
||||
void
|
||||
TimeoutManager::Suspend()
|
||||
{
|
||||
for (Timeout* t = mTimeouts.getFirst(); t; t = t->getNext()) {
|
||||
for (Timeout* t = mTimeouts.GetFirst(); t; t = t->getNext()) {
|
||||
// Leave the timers with the current time remaining. This will
|
||||
// cause the timers to potentially fire when the window is
|
||||
// Resume()'d. Time effectively passes while suspended.
|
||||
@ -810,7 +809,7 @@ TimeoutManager::Resume()
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
DebugOnly<bool> _seenDummyTimeout = false;
|
||||
|
||||
for (Timeout* t = mTimeouts.getFirst(); t; t = t->getNext()) {
|
||||
for (Timeout* t = mTimeouts.GetFirst(); t; t = t->getNext()) {
|
||||
// There's a chance we're being called with RunTimeout on the stack in which
|
||||
// case we have a dummy timeout in the list that *must not* be resumed. It
|
||||
// can be identified by a null mWindow.
|
||||
@ -856,7 +855,7 @@ void
|
||||
TimeoutManager::Freeze()
|
||||
{
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
for (Timeout *t = mTimeouts.getFirst(); t; t = t->getNext()) {
|
||||
for (Timeout *t = mTimeouts.GetFirst(); t; t = t->getNext()) {
|
||||
// Save the current remaining time for this timeout. We will
|
||||
// re-apply it when the window is Thaw()'d. This effectively
|
||||
// shifts timers to the right as if time does not pass while
|
||||
@ -879,7 +878,7 @@ TimeoutManager::Thaw()
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
DebugOnly<bool> _seenDummyTimeout = false;
|
||||
|
||||
for (Timeout *t = mTimeouts.getFirst(); t; t = t->getNext()) {
|
||||
for (Timeout *t = mTimeouts.GetFirst(); t; t = t->getNext()) {
|
||||
// There's a chance we're being called with RunTimeout on the stack in which
|
||||
// case we have a dummy timeout in the list that *must not* be resumed. It
|
||||
// can be identified by a null mWindow.
|
||||
|
@ -28,7 +28,7 @@ public:
|
||||
static uint32_t GetNestingLevel() { return sNestingLevel; }
|
||||
static void SetNestingLevel(uint32_t aLevel) { sNestingLevel = aLevel; }
|
||||
|
||||
bool HasTimeouts() const { return !mTimeouts.isEmpty(); }
|
||||
bool HasTimeouts() const { return !mTimeouts.IsEmpty(); }
|
||||
|
||||
nsresult SetTimeout(nsITimeoutHandler* aHandler,
|
||||
int32_t interval, bool aIsInterval,
|
||||
@ -87,7 +87,7 @@ public:
|
||||
template <class Callable>
|
||||
void ForEachTimeout(Callable c)
|
||||
{
|
||||
for (Timeout* timeout = mTimeouts.getFirst();
|
||||
for (Timeout* timeout = mTimeouts.GetFirst();
|
||||
timeout;
|
||||
timeout = timeout->getNext()) {
|
||||
c(timeout);
|
||||
@ -98,18 +98,46 @@ private:
|
||||
nsresult ResetTimersForThrottleReduction(int32_t aPreviousThrottleDelayMS);
|
||||
|
||||
private:
|
||||
typedef mozilla::LinkedList<mozilla::dom::Timeout> TimeoutList;
|
||||
struct Timeouts {
|
||||
Timeouts()
|
||||
: mTimeoutInsertionPoint(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
const Timeout* GetFirst() const { return mTimeoutList.getFirst(); }
|
||||
Timeout* GetFirst() { return mTimeoutList.getFirst(); }
|
||||
const Timeout* GetLast() const { return mTimeoutList.getLast(); }
|
||||
Timeout* GetLast() { return mTimeoutList.getLast(); }
|
||||
bool IsEmpty() const { return mTimeoutList.isEmpty(); }
|
||||
void InsertFront(Timeout* aTimeout) { mTimeoutList.insertFront(aTimeout); }
|
||||
void Clear() { mTimeoutList.clear(); }
|
||||
|
||||
void SetInsertionPoint(Timeout* aTimeout)
|
||||
{
|
||||
mTimeoutInsertionPoint = aTimeout;
|
||||
}
|
||||
Timeout* InsertionPoint()
|
||||
{
|
||||
return mTimeoutInsertionPoint;
|
||||
}
|
||||
|
||||
private:
|
||||
// mTimeoutList is generally sorted by mWhen, unless mTimeoutInsertionPoint is
|
||||
// non-null. In that case, the dummy timeout pointed to by
|
||||
// mTimeoutInsertionPoint may have a later mWhen than some of the timeouts
|
||||
// that come after it.
|
||||
TimeoutList mTimeoutList;
|
||||
// If mTimeoutInsertionPoint is non-null, insertions should happen after it.
|
||||
// This is a dummy timeout at the moment; if that ever changes, the logic in
|
||||
// ResetTimersForThrottleReduction needs to change.
|
||||
mozilla::dom::Timeout* mTimeoutInsertionPoint;
|
||||
};
|
||||
|
||||
// Each nsGlobalWindow object has a TimeoutManager member. This reference
|
||||
// points to that holder object.
|
||||
nsGlobalWindow& mWindow;
|
||||
// mTimeouts is generally sorted by mWhen, unless mTimeoutInsertionPoint is
|
||||
// non-null. In that case, the dummy timeout pointed to by
|
||||
// mTimeoutInsertionPoint may have a later mWhen than some of the timeouts
|
||||
// that come after it.
|
||||
mozilla::LinkedList<mozilla::dom::Timeout> mTimeouts;
|
||||
// If mTimeoutInsertionPoint is non-null, insertions should happen after it.
|
||||
// This is a dummy timeout at the moment; if that ever changes, the logic in
|
||||
// ResetTimersForThrottleReduction needs to change.
|
||||
mozilla::dom::Timeout* mTimeoutInsertionPoint;
|
||||
Timeouts mTimeouts;
|
||||
uint32_t mTimeoutIdCounter;
|
||||
uint32_t mTimeoutFiringDepth;
|
||||
mozilla::dom::Timeout* mRunningTimeout;
|
||||
|
@ -515,17 +515,70 @@ public:
|
||||
void
|
||||
ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override
|
||||
{
|
||||
if (NS_WARN_IF(!mThis->mOwnerContent)) {
|
||||
mPromise->MaybeRejectWithUndefined();
|
||||
return;
|
||||
}
|
||||
|
||||
// Navigate the loader to the new index
|
||||
nsCOMPtr<nsIFrameLoader> otherLoader;
|
||||
nsresult rv = mThis->mGroupedSessionHistory->
|
||||
GotoIndex(mGlobalIndex, getter_AddRefs(otherLoader));
|
||||
if (NS_WARN_IF(!otherLoader || NS_FAILED(rv))) {
|
||||
|
||||
// Check if the gotoIndex failed because the target frameloader is dead. We
|
||||
// need to perform a navigateAndRestoreByIndex and then return to recover.
|
||||
if (rv == NS_ERROR_NOT_AVAILABLE) {
|
||||
// Get the nsIXULBrowserWindow so that we can call NavigateAndRestoreByIndex on it.
|
||||
nsCOMPtr<nsIDocShell> docShell = mThis->mOwnerContent->OwnerDoc()->GetDocShell();
|
||||
if (NS_WARN_IF(!docShell)) {
|
||||
mPromise->MaybeRejectWithUndefined();
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
||||
docShell->GetTreeOwner(getter_AddRefs(treeOwner));
|
||||
if (NS_WARN_IF(!treeOwner)) {
|
||||
mPromise->MaybeRejectWithUndefined();
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXULWindow> window = do_GetInterface(treeOwner);
|
||||
if (NS_WARN_IF(!window)) {
|
||||
mPromise->MaybeRejectWithUndefined();
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXULBrowserWindow> xbw;
|
||||
window->GetXULBrowserWindow(getter_AddRefs(xbw));
|
||||
if (NS_WARN_IF(!xbw)) {
|
||||
mPromise->MaybeRejectWithUndefined();
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIBrowser> ourBrowser = do_QueryInterface(mThis->mOwnerContent);
|
||||
if (NS_WARN_IF(!ourBrowser)) {
|
||||
mPromise->MaybeRejectWithUndefined();
|
||||
return;
|
||||
}
|
||||
|
||||
rv = xbw->NavigateAndRestoreByIndex(ourBrowser, mGlobalIndex);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
mPromise->MaybeRejectWithUndefined();
|
||||
return;
|
||||
}
|
||||
mPromise->MaybeResolveWithUndefined();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for any other type of failure
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
mPromise->MaybeRejectWithUndefined();
|
||||
return;
|
||||
}
|
||||
nsFrameLoader* other = static_cast<nsFrameLoader*>(otherLoader.get());
|
||||
|
||||
if (other == mThis) {
|
||||
// Perform the swap.
|
||||
nsFrameLoader* other = static_cast<nsFrameLoader*>(otherLoader.get());
|
||||
if (!other || other == mThis) {
|
||||
mPromise->MaybeRejectWithUndefined();
|
||||
return;
|
||||
}
|
||||
@ -3575,6 +3628,13 @@ nsFrameLoader::PopulateUserContextIdFromAttribute(DocShellOriginAttributes& aAtt
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameLoader::GetIsDead(bool* aIsDead)
|
||||
{
|
||||
*aIsDead = mDestroyCalled;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIMessageSender*
|
||||
nsFrameLoader::GetProcessMessageManager() const
|
||||
{
|
||||
|
@ -258,6 +258,11 @@ interface nsIFrameLoader : nsISupports
|
||||
* across root docshells.
|
||||
*/
|
||||
readonly attribute nsIGroupedSHistory groupedSessionHistory;
|
||||
|
||||
/**
|
||||
* Is `true` if the frameloader is dead (destroy has been called on it)
|
||||
*/
|
||||
[infallible] readonly attribute boolean isDead;
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "mozilla/dom/PBackgroundFileHandleParent.h"
|
||||
#include "mozilla/dom/PBackgroundFileRequestParent.h"
|
||||
#include "mozilla/dom/indexedDB/ActorsParent.h"
|
||||
#include "mozilla/dom/indexedDB/PBackgroundIDBDatabaseParent.h"
|
||||
#include "mozilla/dom/ipc/BlobParent.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
@ -1518,8 +1519,9 @@ BackgroundMutableFileParentBase::RecvDeleteMe()
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(!mActorDestroyed);
|
||||
|
||||
IProtocol* mgr = Manager();
|
||||
if (!PBackgroundMutableFileParent::Send__delete__(this)) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
return IPC_FAIL_NO_REASON(mgr);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
@ -1843,8 +1845,9 @@ FileHandle::RecvDeleteMe()
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(!IsActorDestroyed());
|
||||
|
||||
IProtocol* mgr = Manager();
|
||||
if (!PBackgroundFileHandleParent::Send__delete__(this)) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
return IPC_FAIL_NO_REASON(mgr);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -59,6 +59,7 @@
|
||||
#include "mozilla/ipc/InputStreamParams.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "mozilla/ipc/PBackground.h"
|
||||
#include "mozilla/ipc/PBackgroundParent.h"
|
||||
#include "mozilla/Scoped.h"
|
||||
#include "mozilla/storage/Variant.h"
|
||||
#include "nsAutoPtr.h"
|
||||
@ -13727,8 +13728,9 @@ Factory::RecvDeleteMe()
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(!mActorDestroyed);
|
||||
|
||||
IProtocol* mgr = Manager();
|
||||
if (!PBackgroundIDBFactoryParent::Send__delete__(this)) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
return IPC_FAIL_NO_REASON(mgr);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
@ -14666,8 +14668,9 @@ Database::RecvDeleteMe()
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(!mActorDestroyed);
|
||||
|
||||
IProtocol* mgr = Manager();
|
||||
if (!PBackgroundIDBDatabaseParent::Send__delete__(this)) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
return IPC_FAIL_NO_REASON(mgr);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
@ -15791,8 +15794,9 @@ NormalTransaction::RecvDeleteMe()
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(!IsActorDestroyed());
|
||||
|
||||
IProtocol* mgr = Manager();
|
||||
if (!PBackgroundIDBTransactionParent::Send__delete__(this)) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
return IPC_FAIL_NO_REASON(mgr);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
@ -16097,8 +16101,9 @@ VersionChangeTransaction::RecvDeleteMe()
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(!IsActorDestroyed());
|
||||
|
||||
IProtocol* mgr = Manager();
|
||||
if (!PBackgroundIDBVersionChangeTransactionParent::Send__delete__(this)) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
return IPC_FAIL_NO_REASON(mgr);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
@ -16892,8 +16897,9 @@ Cursor::RecvDeleteMe()
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
|
||||
IProtocol* mgr = Manager();
|
||||
if (!PBackgroundIDBCursorParent::Send__delete__(this)) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
return IPC_FAIL_NO_REASON(mgr);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
@ -28927,8 +28933,9 @@ Utils::RecvDeleteMe()
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(!mActorDestroyed);
|
||||
|
||||
IProtocol* mgr = Manager();
|
||||
if (!PBackgroundIndexedDBUtilsParent::Send__delete__(this)) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
return IPC_FAIL_NO_REASON(mgr);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "mozilla/ipc/PBackgroundParent.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsThreadUtils.h"
|
||||
@ -1013,8 +1014,9 @@ CamerasParent::RecvAllDone()
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
// Don't try to send anything to the child now
|
||||
mChildIsAlive = false;
|
||||
IProtocol* mgr = Manager();
|
||||
if (!Send__delete__(this)) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
return IPC_FAIL_NO_REASON(mgr);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/layers/PImageBridgeParent.h"
|
||||
|
||||
#include "MediaSystemResourceManagerParent.h"
|
||||
|
||||
@ -58,8 +59,9 @@ MediaSystemResourceManagerParent::RecvRelease(const uint32_t& aId)
|
||||
mozilla::ipc::IPCResult
|
||||
MediaSystemResourceManagerParent::RecvRemoveResourceManager()
|
||||
{
|
||||
IProtocol* mgr = Manager();
|
||||
if (!PMediaSystemResourceManagerParent::Send__delete__(this)) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
return IPC_FAIL_NO_REASON(mgr);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -167,8 +167,9 @@ BrowserStreamParent::RecvStreamDestroyed()
|
||||
mStreamPeer = nullptr;
|
||||
|
||||
mState = DELETING;
|
||||
IProtocol* mgr = Manager();
|
||||
if (!Send__delete__(this)) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
return IPC_FAIL_NO_REASON(mgr);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ xhr.onloadend = function(e) {
|
||||
xhr.onprogress = function(e) {
|
||||
if (e.loaded > 0) {
|
||||
progressFired = true;
|
||||
xhr.abort();
|
||||
}
|
||||
xhr.abort();
|
||||
};
|
||||
|
||||
onmessage = function(e) {
|
||||
|
@ -107,6 +107,7 @@ support-files =
|
||||
script_createFile.js
|
||||
worker_suspended.js
|
||||
window_suspended.html
|
||||
!/dom/base/test/file_bug945152.jar
|
||||
!/dom/base/test/file_websocket_basic_wsh.py
|
||||
!/dom/base/test/file_websocket_hello_wsh.py
|
||||
!/dom/base/test/file_websocket_http_resource.txt
|
||||
|
@ -673,7 +673,7 @@ XMLHttpRequestMainThread::CreatePartialBlob(ErrorResult& aRv)
|
||||
// Use progress info to determine whether load is complete, but use
|
||||
// mDataAvailable to ensure a slice is created based on the uncompressed
|
||||
// data count.
|
||||
if (mLoadTotal == mLoadTransferred) {
|
||||
if (mState == State::done) {
|
||||
mResponseBlob = mDOMBlob;
|
||||
} else {
|
||||
mResponseBlob = mDOMBlob->CreateSlice(0, mDataAvailable,
|
||||
@ -688,7 +688,7 @@ XMLHttpRequestMainThread::CreatePartialBlob(ErrorResult& aRv)
|
||||
}
|
||||
|
||||
nsAutoCString contentType;
|
||||
if (mLoadTotal == mLoadTransferred) {
|
||||
if (mState == State::done) {
|
||||
mChannel->GetContentType(contentType);
|
||||
}
|
||||
|
||||
@ -1790,7 +1790,15 @@ XMLHttpRequestMainThread::OnDataAvailable(nsIRequest *request,
|
||||
|
||||
mDataAvailable += totalRead;
|
||||
|
||||
ChangeState(State::loading);
|
||||
// Fire the first progress event/loading state change
|
||||
if (mState != State::loading) {
|
||||
ChangeState(State::loading);
|
||||
if (!mFlagSynchronous) {
|
||||
DispatchProgressEvent(this, ProgressEventType::progress,
|
||||
mLoadTransferred, mLoadTotal);
|
||||
}
|
||||
mProgressSinceLastProgressEvent = false;
|
||||
}
|
||||
|
||||
if (!mFlagSynchronous && !mProgressTimerIsActive) {
|
||||
StartProgressEventTimer();
|
||||
@ -2098,10 +2106,6 @@ XMLHttpRequestMainThread::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
|
||||
bool waitingForBlobCreation = false;
|
||||
|
||||
if (NS_SUCCEEDED(status) &&
|
||||
(mResponseType == XMLHttpRequestResponseType::_empty ||
|
||||
mResponseType == XMLHttpRequestResponseType::Text)) {
|
||||
mLoadTotal = mResponseBody.Length();
|
||||
} else if (NS_SUCCEEDED(status) &&
|
||||
(mResponseType == XMLHttpRequestResponseType::Blob ||
|
||||
mResponseType == XMLHttpRequestResponseType::Moz_blob)) {
|
||||
ErrorResult rv;
|
||||
@ -2111,11 +2115,6 @@ XMLHttpRequestMainThread::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
|
||||
if (mDOMBlob) {
|
||||
mResponseBlob = mDOMBlob;
|
||||
mDOMBlob = nullptr;
|
||||
|
||||
mLoadTotal = mResponseBlob->GetSize(rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
status = rv.StealNSResult();
|
||||
}
|
||||
} else {
|
||||
// Smaller files may be written in cache map instead of separate files.
|
||||
// Also, no-store response cannot be written in persistent cache.
|
||||
@ -2126,8 +2125,7 @@ XMLHttpRequestMainThread::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
|
||||
// mBlobStorage can be null if the channel is non-file non-cacheable
|
||||
// and if the response length is zero.
|
||||
MaybeCreateBlobStorage();
|
||||
mLoadTotal =
|
||||
mBlobStorage->GetBlobWhenReady(GetOwner(), contentType, this);
|
||||
mBlobStorage->GetBlobWhenReady(GetOwner(), contentType, this);
|
||||
waitingForBlobCreation = true;
|
||||
} else {
|
||||
// mBlobSet can be null if the channel is non-file non-cacheable
|
||||
@ -2148,10 +2146,6 @@ XMLHttpRequestMainThread::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
|
||||
}
|
||||
|
||||
mResponseBlob = Blob::Create(GetOwner(), blobImpl);
|
||||
mLoadTotal = mResponseBlob->GetSize(rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
status = rv.StealNSResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2163,8 +2157,7 @@ XMLHttpRequestMainThread::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
|
||||
mResponseType == XMLHttpRequestResponseType::Moz_chunked_arraybuffer)) {
|
||||
// set the capacity down to the actual length, to realloc back
|
||||
// down to the actual size
|
||||
mLoadTotal = mArrayBufferBuilder.length();
|
||||
if (!mArrayBufferBuilder.setCapacity(mLoadTotal)) {
|
||||
if (!mArrayBufferBuilder.setCapacity(mArrayBufferBuilder.length())) {
|
||||
// this should never happen!
|
||||
status = NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
@ -2268,12 +2261,6 @@ XMLHttpRequestMainThread::ChangeStateToDone()
|
||||
mTimeoutTimer->Cancel();
|
||||
}
|
||||
|
||||
if (mLoadTransferred) {
|
||||
mLoadTotal = mLoadTransferred;
|
||||
} else {
|
||||
mLoadTotal = -1;
|
||||
}
|
||||
|
||||
// Per spec, fire the last download progress event, if any,
|
||||
// before readystatechange=4/done. (Note that 0-sized responses
|
||||
// will have not sent a progress event yet, so one must be sent here).
|
||||
@ -3412,9 +3399,8 @@ XMLHttpRequestMainThread::OnProgress(nsIRequest *aRequest, nsISupports *aContext
|
||||
StartProgressEventTimer();
|
||||
}
|
||||
} else {
|
||||
mLoadTotal = lengthComputable ? aProgressMax : -1;
|
||||
mLoadTotal = aProgressMax;
|
||||
mLoadTransferred = aProgress;
|
||||
|
||||
// OnDataAvailable() handles mProgressSinceLastProgressEvent
|
||||
// for the download phase.
|
||||
}
|
||||
@ -3631,6 +3617,7 @@ XMLHttpRequestMainThread::HandleProgressTimerCallback()
|
||||
mUploadTransferred, mUploadTotal);
|
||||
}
|
||||
} else {
|
||||
FireReadystatechangeEvent();
|
||||
DispatchProgressEvent(this, ProgressEventType::progress,
|
||||
mLoadTransferred, mLoadTotal);
|
||||
}
|
||||
@ -3809,12 +3796,6 @@ XMLHttpRequestMainThread::BlobStoreCompleted(MutableBlobStorage* aBlobStorage,
|
||||
mResponseBlob = aBlob;
|
||||
mBlobStorage = nullptr;
|
||||
|
||||
ErrorResult rv;
|
||||
mLoadTotal = mResponseBlob->GetSize(rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
rv.SuppressException();
|
||||
}
|
||||
|
||||
ChangeStateToDone();
|
||||
}
|
||||
|
||||
|
@ -319,6 +319,15 @@ bool
|
||||
CSSEditUtils::IsCSSEditableProperty(nsINode* aNode,
|
||||
nsIAtom* aProperty,
|
||||
const nsAString* aAttribute)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
|
||||
return IsCSSEditableProperty(aNode, aProperty, attribute);
|
||||
}
|
||||
|
||||
bool
|
||||
CSSEditUtils::IsCSSEditableProperty(nsINode* aNode,
|
||||
nsIAtom* aProperty,
|
||||
nsIAtom* aAttribute)
|
||||
{
|
||||
MOZ_ASSERT(aNode);
|
||||
|
||||
@ -336,13 +345,12 @@ CSSEditUtils::IsCSSEditableProperty(nsINode* aNode,
|
||||
nsGkAtoms::u == aProperty ||
|
||||
nsGkAtoms::strike == aProperty ||
|
||||
(nsGkAtoms::font == aProperty && aAttribute &&
|
||||
(aAttribute->EqualsLiteral("color") ||
|
||||
aAttribute->EqualsLiteral("face")))) {
|
||||
(aAttribute == nsGkAtoms::color || aAttribute == nsGkAtoms::face))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// ALIGN attribute on elements supporting it
|
||||
if (aAttribute && (aAttribute->EqualsLiteral("align")) &&
|
||||
if (aAttribute == nsGkAtoms::align &&
|
||||
node->IsAnyOfHTMLElements(nsGkAtoms::div,
|
||||
nsGkAtoms::p,
|
||||
nsGkAtoms::h1,
|
||||
@ -365,7 +373,7 @@ CSSEditUtils::IsCSSEditableProperty(nsINode* aNode,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aAttribute && (aAttribute->EqualsLiteral("valign")) &&
|
||||
if (aAttribute == nsGkAtoms::valign &&
|
||||
node->IsAnyOfHTMLElements(nsGkAtoms::col,
|
||||
nsGkAtoms::colgroup,
|
||||
nsGkAtoms::tbody,
|
||||
@ -378,59 +386,52 @@ CSSEditUtils::IsCSSEditableProperty(nsINode* aNode,
|
||||
}
|
||||
|
||||
// attributes TEXT, BACKGROUND and BGCOLOR on BODY
|
||||
if (aAttribute && node->IsHTMLElement(nsGkAtoms::body) &&
|
||||
(aAttribute->EqualsLiteral("text")
|
||||
|| aAttribute->EqualsLiteral("background")
|
||||
|| aAttribute->EqualsLiteral("bgcolor"))) {
|
||||
if (node->IsHTMLElement(nsGkAtoms::body) &&
|
||||
(aAttribute == nsGkAtoms::text || aAttribute == nsGkAtoms::background ||
|
||||
aAttribute == nsGkAtoms::bgcolor)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// attribute BGCOLOR on other elements
|
||||
if (aAttribute && aAttribute->EqualsLiteral("bgcolor")) {
|
||||
if (aAttribute == nsGkAtoms::bgcolor) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// attributes HEIGHT, WIDTH and NOWRAP on TD and TH
|
||||
if (aAttribute &&
|
||||
node->IsAnyOfHTMLElements(nsGkAtoms::td, nsGkAtoms::th) &&
|
||||
(aAttribute->EqualsLiteral("height")
|
||||
|| aAttribute->EqualsLiteral("width")
|
||||
|| aAttribute->EqualsLiteral("nowrap"))) {
|
||||
if (node->IsAnyOfHTMLElements(nsGkAtoms::td, nsGkAtoms::th) &&
|
||||
(aAttribute == nsGkAtoms::height || aAttribute == nsGkAtoms::width ||
|
||||
aAttribute == nsGkAtoms::nowrap)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// attributes HEIGHT and WIDTH on TABLE
|
||||
if (aAttribute && node->IsHTMLElement(nsGkAtoms::table) &&
|
||||
(aAttribute->EqualsLiteral("height")
|
||||
|| aAttribute->EqualsLiteral("width"))) {
|
||||
if (node->IsHTMLElement(nsGkAtoms::table) &&
|
||||
(aAttribute == nsGkAtoms::height || aAttribute == nsGkAtoms::width)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// attributes SIZE and WIDTH on HR
|
||||
if (aAttribute && node->IsHTMLElement(nsGkAtoms::hr) &&
|
||||
(aAttribute->EqualsLiteral("size")
|
||||
|| aAttribute->EqualsLiteral("width"))) {
|
||||
if (node->IsHTMLElement(nsGkAtoms::hr) &&
|
||||
(aAttribute == nsGkAtoms::size || aAttribute == nsGkAtoms::width)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// attribute TYPE on OL UL LI
|
||||
if (aAttribute &&
|
||||
node->IsAnyOfHTMLElements(nsGkAtoms::ol, nsGkAtoms::ul,
|
||||
if (node->IsAnyOfHTMLElements(nsGkAtoms::ol, nsGkAtoms::ul,
|
||||
nsGkAtoms::li) &&
|
||||
aAttribute->EqualsLiteral("type")) {
|
||||
aAttribute == nsGkAtoms::type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aAttribute && node->IsHTMLElement(nsGkAtoms::img) &&
|
||||
(aAttribute->EqualsLiteral("border")
|
||||
|| aAttribute->EqualsLiteral("width")
|
||||
|| aAttribute->EqualsLiteral("height"))) {
|
||||
if (node->IsHTMLElement(nsGkAtoms::img) &&
|
||||
(aAttribute == nsGkAtoms::border || aAttribute == nsGkAtoms::width ||
|
||||
aAttribute == nsGkAtoms::height)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// other elements that we can align using CSS even if they
|
||||
// can't carry the html ALIGN attribute
|
||||
if (aAttribute && aAttribute->EqualsLiteral("align") &&
|
||||
if (aAttribute == nsGkAtoms::align &&
|
||||
node->IsAnyOfHTMLElements(nsGkAtoms::ul,
|
||||
nsGkAtoms::ol,
|
||||
nsGkAtoms::dl,
|
||||
@ -818,7 +819,7 @@ void
|
||||
CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle(
|
||||
Element* aElement,
|
||||
nsIAtom* aHTMLProperty,
|
||||
const nsAString* aAttribute,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString* aValue,
|
||||
nsTArray<nsIAtom*>& cssPropertyArray,
|
||||
nsTArray<nsString>& cssValueArray,
|
||||
@ -838,21 +839,20 @@ CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle(
|
||||
} else if (nsGkAtoms::tt == aHTMLProperty) {
|
||||
equivTable = ttEquivTable;
|
||||
} else if (aAttribute) {
|
||||
if (nsGkAtoms::font == aHTMLProperty &&
|
||||
aAttribute->EqualsLiteral("color")) {
|
||||
if (nsGkAtoms::font == aHTMLProperty && aAttribute == nsGkAtoms::color) {
|
||||
equivTable = fontColorEquivTable;
|
||||
} else if (nsGkAtoms::font == aHTMLProperty &&
|
||||
aAttribute->EqualsLiteral("face")) {
|
||||
aAttribute == nsGkAtoms::face) {
|
||||
equivTable = fontFaceEquivTable;
|
||||
} else if (aAttribute->EqualsLiteral("bgcolor")) {
|
||||
} else if (aAttribute == nsGkAtoms::bgcolor) {
|
||||
equivTable = bgcolorEquivTable;
|
||||
} else if (aAttribute->EqualsLiteral("background")) {
|
||||
} else if (aAttribute == nsGkAtoms::background) {
|
||||
equivTable = backgroundImageEquivTable;
|
||||
} else if (aAttribute->EqualsLiteral("text")) {
|
||||
} else if (aAttribute == nsGkAtoms::text) {
|
||||
equivTable = textColorEquivTable;
|
||||
} else if (aAttribute->EqualsLiteral("border")) {
|
||||
} else if (aAttribute == nsGkAtoms::border) {
|
||||
equivTable = borderEquivTable;
|
||||
} else if (aAttribute->EqualsLiteral("align")) {
|
||||
} else if (aAttribute == nsGkAtoms::align) {
|
||||
if (aElement->IsHTMLElement(nsGkAtoms::table)) {
|
||||
equivTable = tableAlignEquivTable;
|
||||
} else if (aElement->IsHTMLElement(nsGkAtoms::hr)) {
|
||||
@ -863,17 +863,17 @@ CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle(
|
||||
} else {
|
||||
equivTable = textAlignEquivTable;
|
||||
}
|
||||
} else if (aAttribute->EqualsLiteral("valign")) {
|
||||
} else if (aAttribute == nsGkAtoms::valign) {
|
||||
equivTable = verticalAlignEquivTable;
|
||||
} else if (aAttribute->EqualsLiteral("nowrap")) {
|
||||
} else if (aAttribute == nsGkAtoms::nowrap) {
|
||||
equivTable = nowrapEquivTable;
|
||||
} else if (aAttribute->EqualsLiteral("width")) {
|
||||
} else if (aAttribute == nsGkAtoms::width) {
|
||||
equivTable = widthEquivTable;
|
||||
} else if (aAttribute->EqualsLiteral("height") ||
|
||||
} else if (aAttribute == nsGkAtoms::height ||
|
||||
(aElement->IsHTMLElement(nsGkAtoms::hr) &&
|
||||
aAttribute->EqualsLiteral("size"))) {
|
||||
aAttribute == nsGkAtoms::size)) {
|
||||
equivTable = heightEquivTable;
|
||||
} else if (aAttribute->EqualsLiteral("type") &&
|
||||
} else if (aAttribute == nsGkAtoms::type &&
|
||||
aElement->IsAnyOfHTMLElements(nsGkAtoms::ol,
|
||||
nsGkAtoms::ul,
|
||||
nsGkAtoms::li)) {
|
||||
@ -890,40 +890,46 @@ CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle(
|
||||
// aValue for the node, and return in aCount the number of CSS properties set
|
||||
// by the call. The Element version returns aCount instead.
|
||||
int32_t
|
||||
CSSEditUtils::SetCSSEquivalentToHTMLStyle(Element* aElement,
|
||||
CSSEditUtils::SetCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
|
||||
nsIAtom* aProperty,
|
||||
const nsAString* aAttribute,
|
||||
const nsAString* aValue,
|
||||
bool aSuppressTransaction)
|
||||
{
|
||||
MOZ_ASSERT(aElement && aProperty);
|
||||
MOZ_ASSERT_IF(aAttribute, aValue);
|
||||
int32_t count;
|
||||
// This can only fail if SetCSSProperty fails, which should only happen if
|
||||
// something is pretty badly wrong. In this case we assert so that hopefully
|
||||
// someone will notice, but there's nothing more sensible to do than just
|
||||
// return the count and carry on.
|
||||
nsresult rv = SetCSSEquivalentToHTMLStyle(aElement->AsDOMNode(),
|
||||
aProperty, aAttribute,
|
||||
aValue, &count,
|
||||
aSuppressTransaction);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "SetCSSEquivalentToHTMLStyle failed");
|
||||
NS_ENSURE_SUCCESS(rv, count);
|
||||
return count;
|
||||
nsCOMPtr<Element> element = do_QueryInterface(aNode);
|
||||
return SetCSSEquivalentToHTMLStyle(element,
|
||||
aProperty, aAttribute,
|
||||
aValue, aSuppressTransaction);
|
||||
}
|
||||
|
||||
nsresult
|
||||
CSSEditUtils::SetCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
|
||||
int32_t
|
||||
CSSEditUtils::SetCSSEquivalentToHTMLStyle(Element* aElement,
|
||||
nsIAtom* aHTMLProperty,
|
||||
const nsAString* aAttribute,
|
||||
const nsAString* aValue,
|
||||
int32_t* aCount,
|
||||
bool aSuppressTransaction)
|
||||
{
|
||||
nsCOMPtr<Element> element = do_QueryInterface(aNode);
|
||||
*aCount = 0;
|
||||
if (!element || !IsCSSEditableProperty(element, aHTMLProperty, aAttribute)) {
|
||||
return NS_OK;
|
||||
nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
|
||||
return SetCSSEquivalentToHTMLStyle(aElement, aHTMLProperty, attribute,
|
||||
aValue, aSuppressTransaction);
|
||||
}
|
||||
|
||||
int32_t
|
||||
CSSEditUtils::SetCSSEquivalentToHTMLStyle(Element* aElement,
|
||||
nsIAtom* aHTMLProperty,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString* aValue,
|
||||
bool aSuppressTransaction)
|
||||
{
|
||||
MOZ_ASSERT(aElement);
|
||||
|
||||
if (!IsCSSEditableProperty(aElement, aHTMLProperty, aAttribute)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// we can apply the styles only if the node is an element and if we have
|
||||
@ -932,18 +938,20 @@ CSSEditUtils::SetCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
|
||||
// Find the CSS equivalence to the HTML style
|
||||
nsTArray<nsIAtom*> cssPropertyArray;
|
||||
nsTArray<nsString> cssValueArray;
|
||||
GenerateCSSDeclarationsFromHTMLStyle(element, aHTMLProperty, aAttribute,
|
||||
GenerateCSSDeclarationsFromHTMLStyle(aElement, aHTMLProperty, aAttribute,
|
||||
aValue, cssPropertyArray, cssValueArray,
|
||||
false);
|
||||
|
||||
// set the individual CSS inline styles
|
||||
*aCount = cssPropertyArray.Length();
|
||||
for (int32_t index = 0; index < *aCount; index++) {
|
||||
nsresult rv = SetCSSProperty(*element, *cssPropertyArray[index],
|
||||
size_t count = cssPropertyArray.Length();
|
||||
for (size_t index = 0; index < count; index++) {
|
||||
nsresult rv = SetCSSProperty(*aElement, *cssPropertyArray[index],
|
||||
cssValueArray[index], aSuppressTransaction);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
return count;
|
||||
}
|
||||
|
||||
// Remove from aNode the CSS inline style equivalent to HTMLProperty/aAttribute/aValue for the node
|
||||
@ -955,20 +963,22 @@ CSSEditUtils::RemoveCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
|
||||
bool aSuppressTransaction)
|
||||
{
|
||||
nsCOMPtr<Element> element = do_QueryInterface(aNode);
|
||||
NS_ENSURE_TRUE(element, NS_OK);
|
||||
nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
|
||||
|
||||
return RemoveCSSEquivalentToHTMLStyle(element, aHTMLProperty, aAttribute,
|
||||
return RemoveCSSEquivalentToHTMLStyle(element, aHTMLProperty, attribute,
|
||||
aValue, aSuppressTransaction);
|
||||
}
|
||||
|
||||
nsresult
|
||||
CSSEditUtils::RemoveCSSEquivalentToHTMLStyle(Element* aElement,
|
||||
nsIAtom* aHTMLProperty,
|
||||
const nsAString* aAttribute,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString* aValue,
|
||||
bool aSuppressTransaction)
|
||||
{
|
||||
MOZ_ASSERT(aElement);
|
||||
if (NS_WARN_IF(!aElement)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!IsCSSEditableProperty(aElement, aHTMLProperty, aAttribute)) {
|
||||
return NS_OK;
|
||||
@ -1003,7 +1013,7 @@ CSSEditUtils::RemoveCSSEquivalentToHTMLStyle(Element* aElement,
|
||||
nsresult
|
||||
CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
|
||||
nsIAtom* aHTMLProperty,
|
||||
const nsAString* aAttribute,
|
||||
nsIAtom* aAttribute,
|
||||
nsAString& aValueString,
|
||||
StyleType aStyleType)
|
||||
{
|
||||
@ -1020,7 +1030,8 @@ CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
|
||||
nsTArray<nsString> cssValueArray;
|
||||
// get the CSS equivalence with last param true indicating we want only the
|
||||
// "gettable" properties
|
||||
GenerateCSSDeclarationsFromHTMLStyle(theElement, aHTMLProperty, aAttribute, nullptr,
|
||||
GenerateCSSDeclarationsFromHTMLStyle(theElement, aHTMLProperty, aAttribute,
|
||||
nullptr,
|
||||
cssPropertyArray, cssValueArray, true);
|
||||
int32_t count = cssPropertyArray.Length();
|
||||
for (int32_t index = 0; index < count; index++) {
|
||||
@ -1066,48 +1077,58 @@ CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
|
||||
StyleType aStyleType)
|
||||
{
|
||||
MOZ_ASSERT(aNode && aProperty);
|
||||
bool isSet;
|
||||
nsresult rv = IsCSSEquivalentToHTMLInlineStyleSet(aNode->AsDOMNode(),
|
||||
aProperty, aAttribute,
|
||||
isSet, aValue, aStyleType);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
return isSet;
|
||||
nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
|
||||
return IsCSSEquivalentToHTMLInlineStyleSet(aNode,
|
||||
aProperty, attribute,
|
||||
aValue, aStyleType);
|
||||
}
|
||||
|
||||
nsresult
|
||||
bool
|
||||
CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsIDOMNode* aNode,
|
||||
nsIAtom* aProperty,
|
||||
const nsAString* aAttribute,
|
||||
nsAString& aValue,
|
||||
StyleType aStyleType)
|
||||
{
|
||||
MOZ_ASSERT(aNode && aProperty);
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
|
||||
nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
|
||||
return IsCSSEquivalentToHTMLInlineStyleSet(node, aProperty, attribute,
|
||||
aValue, aStyleType);
|
||||
}
|
||||
|
||||
bool
|
||||
CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
|
||||
nsIDOMNode* aNode,
|
||||
nsINode* aNode,
|
||||
nsIAtom* aHTMLProperty,
|
||||
const nsAString* aHTMLAttribute,
|
||||
bool& aIsSet,
|
||||
nsIAtom* aHTMLAttribute,
|
||||
nsAString& valueString,
|
||||
StyleType aStyleType)
|
||||
{
|
||||
NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
|
||||
NS_ENSURE_TRUE(aNode, false);
|
||||
|
||||
nsAutoString htmlValueString(valueString);
|
||||
aIsSet = false;
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
|
||||
bool isSet = false;
|
||||
do {
|
||||
valueString.Assign(htmlValueString);
|
||||
// get the value of the CSS equivalent styles
|
||||
nsresult rv =
|
||||
GetCSSEquivalentToHTMLInlineStyleSet(node, aHTMLProperty, aHTMLAttribute,
|
||||
GetCSSEquivalentToHTMLInlineStyleSet(aNode, aHTMLProperty, aHTMLAttribute,
|
||||
valueString, aStyleType);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
// early way out if we can
|
||||
if (valueString.IsEmpty()) {
|
||||
return NS_OK;
|
||||
return isSet;
|
||||
}
|
||||
|
||||
if (nsGkAtoms::b == aHTMLProperty) {
|
||||
if (valueString.EqualsLiteral("bold")) {
|
||||
aIsSet = true;
|
||||
isSet = true;
|
||||
} else if (valueString.EqualsLiteral("normal")) {
|
||||
aIsSet = false;
|
||||
isSet = false;
|
||||
} else if (valueString.EqualsLiteral("bolder")) {
|
||||
aIsSet = true;
|
||||
isSet = true;
|
||||
valueString.AssignLiteral("bold");
|
||||
} else {
|
||||
int32_t weight = 0;
|
||||
@ -1115,32 +1136,31 @@ CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
|
||||
nsAutoString value(valueString);
|
||||
weight = value.ToInteger(&errorCode);
|
||||
if (400 < weight) {
|
||||
aIsSet = true;
|
||||
isSet = true;
|
||||
valueString.AssignLiteral("bold");
|
||||
} else {
|
||||
aIsSet = false;
|
||||
isSet = false;
|
||||
valueString.AssignLiteral("normal");
|
||||
}
|
||||
}
|
||||
} else if (nsGkAtoms::i == aHTMLProperty) {
|
||||
if (valueString.EqualsLiteral("italic") ||
|
||||
valueString.EqualsLiteral("oblique")) {
|
||||
aIsSet = true;
|
||||
isSet = true;
|
||||
}
|
||||
} else if (nsGkAtoms::u == aHTMLProperty) {
|
||||
nsAutoString val;
|
||||
val.AssignLiteral("underline");
|
||||
aIsSet = ChangeStyleTransaction::ValueIncludes(valueString, val);
|
||||
isSet = ChangeStyleTransaction::ValueIncludes(valueString, val);
|
||||
} else if (nsGkAtoms::strike == aHTMLProperty) {
|
||||
nsAutoString val;
|
||||
val.AssignLiteral("line-through");
|
||||
aIsSet = ChangeStyleTransaction::ValueIncludes(valueString, val);
|
||||
} else if (aHTMLAttribute &&
|
||||
((nsGkAtoms::font == aHTMLProperty &&
|
||||
aHTMLAttribute->EqualsLiteral("color")) ||
|
||||
aHTMLAttribute->EqualsLiteral("bgcolor"))) {
|
||||
isSet = ChangeStyleTransaction::ValueIncludes(valueString, val);
|
||||
} else if ((nsGkAtoms::font == aHTMLProperty &&
|
||||
aHTMLAttribute == nsGkAtoms::color) ||
|
||||
aHTMLAttribute == nsGkAtoms::bgcolor) {
|
||||
if (htmlValueString.IsEmpty()) {
|
||||
aIsSet = true;
|
||||
isSet = true;
|
||||
} else {
|
||||
nscolor rgba;
|
||||
nsAutoString subStr;
|
||||
@ -1174,54 +1194,53 @@ CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
|
||||
htmlColor.Append(char16_t(')'));
|
||||
}
|
||||
|
||||
aIsSet = htmlColor.Equals(valueString,
|
||||
nsCaseInsensitiveStringComparator());
|
||||
isSet = htmlColor.Equals(valueString,
|
||||
nsCaseInsensitiveStringComparator());
|
||||
} else {
|
||||
aIsSet = htmlValueString.Equals(valueString,
|
||||
nsCaseInsensitiveStringComparator());
|
||||
isSet = htmlValueString.Equals(valueString,
|
||||
nsCaseInsensitiveStringComparator());
|
||||
}
|
||||
}
|
||||
} else if (nsGkAtoms::tt == aHTMLProperty) {
|
||||
aIsSet = StringBeginsWith(valueString, NS_LITERAL_STRING("monospace"));
|
||||
isSet = StringBeginsWith(valueString, NS_LITERAL_STRING("monospace"));
|
||||
} else if (nsGkAtoms::font == aHTMLProperty && aHTMLAttribute &&
|
||||
aHTMLAttribute->EqualsLiteral("face")) {
|
||||
aHTMLAttribute == nsGkAtoms::face) {
|
||||
if (!htmlValueString.IsEmpty()) {
|
||||
const char16_t commaSpace[] = { char16_t(','), char16_t(' '), 0 };
|
||||
const char16_t comma[] = { char16_t(','), 0 };
|
||||
htmlValueString.ReplaceSubstring(commaSpace, comma);
|
||||
nsAutoString valueStringNorm(valueString);
|
||||
valueStringNorm.ReplaceSubstring(commaSpace, comma);
|
||||
aIsSet = htmlValueString.Equals(valueStringNorm,
|
||||
nsCaseInsensitiveStringComparator());
|
||||
isSet = htmlValueString.Equals(valueStringNorm,
|
||||
nsCaseInsensitiveStringComparator());
|
||||
} else {
|
||||
aIsSet = true;
|
||||
isSet = true;
|
||||
}
|
||||
return NS_OK;
|
||||
} else if (aHTMLAttribute && aHTMLAttribute->EqualsLiteral("align")) {
|
||||
aIsSet = true;
|
||||
return isSet;
|
||||
} else if (aHTMLAttribute == nsGkAtoms::align) {
|
||||
isSet = true;
|
||||
} else {
|
||||
aIsSet = false;
|
||||
return NS_OK;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!htmlValueString.IsEmpty() &&
|
||||
htmlValueString.Equals(valueString,
|
||||
nsCaseInsensitiveStringComparator())) {
|
||||
aIsSet = true;
|
||||
isSet = true;
|
||||
}
|
||||
|
||||
if (htmlValueString.EqualsLiteral("-moz-editor-invert-value")) {
|
||||
aIsSet = !aIsSet;
|
||||
isSet = !isSet;
|
||||
}
|
||||
|
||||
if (nsGkAtoms::u == aHTMLProperty || nsGkAtoms::strike == aHTMLProperty) {
|
||||
// unfortunately, the value of the text-decoration property is not inherited.
|
||||
// that means that we have to look at ancestors of node to see if they are underlined
|
||||
node = node->GetParentElement(); // set to null if it's not a dom element
|
||||
aNode = aNode->GetParentElement(); // set to null if it's not a dom element
|
||||
}
|
||||
} while ((nsGkAtoms::u == aHTMLProperty ||
|
||||
nsGkAtoms::strike == aHTMLProperty) && !aIsSet && node);
|
||||
return NS_OK;
|
||||
nsGkAtoms::strike == aHTMLProperty) && !isSet && aNode);
|
||||
return isSet;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -90,6 +90,8 @@ public:
|
||||
*/
|
||||
bool IsCSSEditableProperty(nsINode* aNode, nsIAtom* aProperty,
|
||||
const nsAString* aAttribute);
|
||||
bool IsCSSEditableProperty(nsINode* aNode, nsIAtom* aProperty,
|
||||
nsIAtom* aAttribute);
|
||||
|
||||
/**
|
||||
* Adds/remove a CSS declaration to the STYLE atrribute carried by a given
|
||||
@ -188,14 +190,14 @@ public:
|
||||
*
|
||||
* @param aNode [IN] A DOM node.
|
||||
* @param aHTMLProperty [IN] An atom containing an HTML property.
|
||||
* @param aAttribute [IN] A pointer to an attribute name or nullptr if
|
||||
* @param aAttribute [IN] An atom of attribute name or nullptr if
|
||||
* irrelevant.
|
||||
* @param aValueString [OUT] The list of CSS values.
|
||||
* @param aStyleType [IN] eSpecified or eComputed.
|
||||
*/
|
||||
nsresult GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
|
||||
nsIAtom* aHTMLProperty,
|
||||
const nsAString* aAttribute,
|
||||
nsIAtom* aAttribute,
|
||||
nsAString& aValueString,
|
||||
StyleType aStyleType);
|
||||
|
||||
@ -205,16 +207,20 @@ public:
|
||||
*
|
||||
* @param aNode [IN] A DOM node.
|
||||
* @param aHTMLProperty [IN] An atom containing an HTML property.
|
||||
* @param aAttribute [IN] A pointer to an attribute name or nullptr if
|
||||
* irrelevant.
|
||||
* @param aIsSet [OUT] A boolean being true if the css properties are
|
||||
* set.
|
||||
* @param aAttribute [IN] A pointer/atom to an attribute name or nullptr
|
||||
* if irrelevant.
|
||||
* @param aValueString [IN/OUT] The attribute value (in) the list of CSS
|
||||
* values (out).
|
||||
* @param aStyleType [IN] eSpecified or eComputed.
|
||||
*
|
||||
* The nsIContent variant returns aIsSet instead of using an out parameter.
|
||||
* @return A boolean being true if the css properties are
|
||||
* set.
|
||||
*/
|
||||
bool IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aContent,
|
||||
nsIAtom* aProperty,
|
||||
nsIAtom* aAttribute,
|
||||
nsAString& aValue,
|
||||
StyleType aStyleType);
|
||||
|
||||
bool IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aContent,
|
||||
nsIAtom* aProperty,
|
||||
const nsAString* aAttribute,
|
||||
@ -227,12 +233,11 @@ public:
|
||||
nsAString& aValue,
|
||||
StyleType aStyleType);
|
||||
|
||||
nsresult IsCSSEquivalentToHTMLInlineStyleSet(nsIDOMNode* aNode,
|
||||
nsIAtom* aHTMLProperty,
|
||||
const nsAString* aAttribute,
|
||||
bool& aIsSet,
|
||||
nsAString& aValueString,
|
||||
StyleType aStyleType);
|
||||
bool IsCSSEquivalentToHTMLInlineStyleSet(nsIDOMNode* aNode,
|
||||
nsIAtom* aProperty,
|
||||
const nsAString* aAttribute,
|
||||
nsAString& aValue,
|
||||
StyleType aStyleType);
|
||||
|
||||
/**
|
||||
* Adds to the node the CSS inline styles equivalent to the HTML style
|
||||
@ -240,27 +245,29 @@ public:
|
||||
*
|
||||
* @param aNode [IN] A DOM node.
|
||||
* @param aHTMLProperty [IN] An atom containing an HTML property.
|
||||
* @param aAttribute [IN] A pointer to an attribute name or nullptr if
|
||||
* irrelevant.
|
||||
* @param aAttribute [IN] A pointer/atom to an attribute name or nullptr
|
||||
* if irrelevant.
|
||||
* @param aValue [IN] The attribute value.
|
||||
* @param aCount [OUT] The number of CSS properties set by the call.
|
||||
* @param aSuppressTransaction [IN] A boolean indicating, when true,
|
||||
* that no transaction should be recorded.
|
||||
*
|
||||
* aCount is returned by the dom::Element variant instead of being an out
|
||||
* parameter.
|
||||
* @return The number of CSS properties set by the call.
|
||||
*/
|
||||
int32_t SetCSSEquivalentToHTMLStyle(dom::Element* aElement,
|
||||
nsIAtom* aProperty,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString* aValue,
|
||||
bool aSuppressTransaction);
|
||||
int32_t SetCSSEquivalentToHTMLStyle(dom::Element* aElement,
|
||||
nsIAtom* aProperty,
|
||||
const nsAString* aAttribute,
|
||||
const nsAString* aValue,
|
||||
bool aSuppressTransaction);
|
||||
nsresult SetCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
|
||||
nsIAtom* aHTMLProperty,
|
||||
const nsAString* aAttribute,
|
||||
const nsAString* aValue,
|
||||
int32_t* aCount,
|
||||
bool aSuppressTransaction);
|
||||
int32_t SetCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
|
||||
nsIAtom* aHTMLProperty,
|
||||
const nsAString* aAttribute,
|
||||
const nsAString* aValue,
|
||||
bool aSuppressTransaction);
|
||||
|
||||
/**
|
||||
* Removes from the node the CSS inline styles equivalent to the HTML style.
|
||||
@ -284,7 +291,7 @@ public:
|
||||
*
|
||||
* @param aElement [IN] A DOM Element (must not be null).
|
||||
* @param aHTMLProperty [IN] An atom containing an HTML property.
|
||||
* @param aAttribute [IN] A pointer to an attribute name or nullptr if
|
||||
* @param aAttribute [IN] An atom to an attribute name or nullptr if
|
||||
* irrelevant.
|
||||
* @param aValue [IN] The attribute value.
|
||||
* @param aSuppressTransaction [IN] A boolean indicating, when true,
|
||||
@ -292,7 +299,7 @@ public:
|
||||
*/
|
||||
nsresult RemoveCSSEquivalentToHTMLStyle(dom::Element* aElement,
|
||||
nsIAtom* aHTMLProperty,
|
||||
const nsAString* aAttribute,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString* aValue,
|
||||
bool aSuppressTransaction);
|
||||
|
||||
@ -409,7 +416,7 @@ private:
|
||||
*
|
||||
* @param aNode [IN] The DOM node.
|
||||
* @param aHTMLProperty [IN] An atom containing an HTML property.
|
||||
* @param aAttribute [IN] A pointer to an attribute name or nullptr
|
||||
* @param aAttribute [IN] An atom to an attribute name or nullptr
|
||||
* if irrelevant
|
||||
* @param aValue [IN] The attribute value.
|
||||
* @param aPropertyArray [OUT] The array of CSS properties.
|
||||
@ -422,7 +429,7 @@ private:
|
||||
*/
|
||||
void GenerateCSSDeclarationsFromHTMLStyle(dom::Element* aNode,
|
||||
nsIAtom* aHTMLProperty,
|
||||
const nsAString* aAttribute,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString* aValue,
|
||||
nsTArray<nsIAtom*>& aPropertyArray,
|
||||
nsTArray<nsString>& aValueArray,
|
||||
|
@ -838,19 +838,18 @@ HTMLEditRules::GetAlignment(bool* aMixed,
|
||||
|
||||
NS_ENSURE_TRUE(nodeToExamine, NS_ERROR_NULL_POINTER);
|
||||
|
||||
NS_NAMED_LITERAL_STRING(typeAttrName, "align");
|
||||
nsCOMPtr<Element> blockParent = htmlEditor->GetBlock(*nodeToExamine);
|
||||
|
||||
NS_ENSURE_TRUE(blockParent, NS_ERROR_FAILURE);
|
||||
|
||||
if (htmlEditor->IsCSSEnabled() &&
|
||||
htmlEditor->mCSSEditUtils->IsCSSEditableProperty(blockParent, nullptr,
|
||||
&typeAttrName)) {
|
||||
nsGkAtoms::align)) {
|
||||
// We are in CSS mode and we know how to align this element with CSS
|
||||
nsAutoString value;
|
||||
// Let's get the value(s) of text-align or margin-left/margin-right
|
||||
htmlEditor->mCSSEditUtils->GetCSSEquivalentToHTMLInlineStyleSet(
|
||||
blockParent, nullptr, &typeAttrName, value, CSSEditUtils::eComputed);
|
||||
blockParent, nullptr, nsGkAtoms::align, value, CSSEditUtils::eComputed);
|
||||
if (value.EqualsLiteral("center") ||
|
||||
value.EqualsLiteral("-moz-center") ||
|
||||
value.EqualsLiteral("auto auto")) {
|
||||
@ -4727,7 +4726,7 @@ HTMLEditRules::WillAlign(Selection& aSelection,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (useCSS) {
|
||||
htmlEditor->mCSSEditUtils->SetCSSEquivalentToHTMLStyle(
|
||||
curNode->AsElement(), nullptr, &NS_LITERAL_STRING("align"),
|
||||
curNode->AsElement(), nullptr, nsGkAtoms::align,
|
||||
&aAlignType, false);
|
||||
curDiv = nullptr;
|
||||
continue;
|
||||
@ -7093,9 +7092,9 @@ HTMLEditRules::CacheInlineStyles(nsIDOMNode* aNode)
|
||||
isSet, &outValue);
|
||||
} else {
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
mHTMLEditor->mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(aNode,
|
||||
mCachedStyles[j].tag, &(mCachedStyles[j].attr), isSet, outValue,
|
||||
CSSEditUtils::eComputed);
|
||||
isSet = mHTMLEditor->mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(
|
||||
aNode, mCachedStyles[j].tag, &(mCachedStyles[j].attr), outValue,
|
||||
CSSEditUtils::eComputed);
|
||||
}
|
||||
if (isSet) {
|
||||
mCachedStyles[j].mPresent = true;
|
||||
|
@ -4455,30 +4455,35 @@ HTMLEditor::SetAttributeOrEquivalent(nsIDOMElement* aElement,
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
|
||||
if (IsCSSEnabled() && mCSSEditUtils) {
|
||||
int32_t count;
|
||||
nsresult rv =
|
||||
mCSSEditUtils->SetCSSEquivalentToHTMLStyle(aElement, nullptr,
|
||||
&aAttribute, &aValue,
|
||||
&count,
|
||||
nsCOMPtr<dom::Element> element = do_QueryInterface(aElement);
|
||||
MOZ_ASSERT(element);
|
||||
|
||||
nsCOMPtr<nsIAtom> attribute = NS_Atomize(aAttribute);
|
||||
MOZ_ASSERT(attribute);
|
||||
|
||||
int32_t count =
|
||||
mCSSEditUtils->SetCSSEquivalentToHTMLStyle(element, nullptr,
|
||||
attribute, &aValue,
|
||||
aSuppressTransaction);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (count) {
|
||||
// we found an equivalence ; let's remove the HTML attribute itself if it is set
|
||||
nsAutoString existingValue;
|
||||
bool wasSet = false;
|
||||
rv = GetAttributeValue(aElement, aAttribute, existingValue, &wasSet);
|
||||
nsresult rv =
|
||||
GetAttributeValue(aElement, aAttribute, existingValue, &wasSet);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!wasSet) {
|
||||
return NS_OK;
|
||||
}
|
||||
return aSuppressTransaction ? aElement->RemoveAttribute(aAttribute) :
|
||||
RemoveAttribute(aElement, aAttribute);
|
||||
return aSuppressTransaction ?
|
||||
element->UnsetAttr(kNameSpaceID_None, attribute, true) :
|
||||
RemoveAttribute(aElement, aAttribute);
|
||||
}
|
||||
|
||||
// count is an integer that represents the number of CSS declarations applied to the
|
||||
// element. If it is zero, we found no equivalence in this implementation for the
|
||||
// attribute
|
||||
if (aAttribute.EqualsLiteral("style")) {
|
||||
if (attribute == nsGkAtoms::style) {
|
||||
// if it is the style attribute, just add the new value to the existing style
|
||||
// attribute's value
|
||||
nsAutoString existingValue;
|
||||
@ -4489,14 +4494,15 @@ HTMLEditor::SetAttributeOrEquivalent(nsIDOMElement* aElement,
|
||||
existingValue.Append(' ');
|
||||
existingValue.Append(aValue);
|
||||
return aSuppressTransaction ?
|
||||
aElement->SetAttribute(aAttribute, existingValue) :
|
||||
element->SetAttr(kNameSpaceID_None, attribute, existingValue, true) :
|
||||
SetAttribute(aElement, aAttribute, existingValue);
|
||||
}
|
||||
|
||||
// we have no CSS equivalence for this attribute and it is not the style
|
||||
// attribute; let's set it the good'n'old HTML way
|
||||
return aSuppressTransaction ? aElement->SetAttribute(aAttribute, aValue) :
|
||||
SetAttribute(aElement, aAttribute, aValue);
|
||||
return aSuppressTransaction ?
|
||||
element->SetAttr(kNameSpaceID_None, attribute, aValue, true) :
|
||||
SetAttribute(aElement, aAttribute, aValue);
|
||||
}
|
||||
|
||||
// we are not in an HTML+CSS editor; let's set the attribute the HTML way
|
||||
@ -4518,7 +4524,7 @@ HTMLEditor::RemoveAttributeOrEquivalent(nsIDOMElement* aElement,
|
||||
if (IsCSSEnabled() && mCSSEditUtils) {
|
||||
nsresult rv =
|
||||
mCSSEditUtils->RemoveCSSEquivalentToHTMLStyle(
|
||||
element, nullptr, &aAttribute, nullptr, aSuppressTransaction);
|
||||
element, nullptr, attribute, nullptr, aSuppressTransaction);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
@ -4580,7 +4586,6 @@ HTMLEditor::SetCSSBackgroundColor(const nsAString& aColor)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!cancel && !handled) {
|
||||
// Loop through the ranges in the selection
|
||||
NS_NAMED_LITERAL_STRING(bgcolor, "bgcolor");
|
||||
for (uint32_t i = 0; i < selection->RangeCount(); i++) {
|
||||
RefPtr<nsRange> range = selection->GetRangeAt(i);
|
||||
NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
|
||||
@ -4599,13 +4604,15 @@ HTMLEditor::SetCSSBackgroundColor(const nsAString& aColor)
|
||||
if (blockParent && cachedBlockParent != blockParent) {
|
||||
cachedBlockParent = blockParent;
|
||||
mCSSEditUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
|
||||
&bgcolor, &aColor, false);
|
||||
nsGkAtoms::bgcolor,
|
||||
&aColor, false);
|
||||
}
|
||||
} else if (startNode == endNode &&
|
||||
startNode->IsHTMLElement(nsGkAtoms::body) && isCollapsed) {
|
||||
// No block in the document, let's apply the background to the body
|
||||
mCSSEditUtils->SetCSSEquivalentToHTMLStyle(startNode->AsElement(),
|
||||
nullptr, &bgcolor, &aColor,
|
||||
nullptr, nsGkAtoms::bgcolor,
|
||||
&aColor,
|
||||
false);
|
||||
} else if (startNode == endNode && (endOffset - startOffset == 1 ||
|
||||
(!startOffset && !endOffset))) {
|
||||
@ -4616,7 +4623,8 @@ HTMLEditor::SetCSSBackgroundColor(const nsAString& aColor)
|
||||
if (blockParent && cachedBlockParent != blockParent) {
|
||||
cachedBlockParent = blockParent;
|
||||
mCSSEditUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
|
||||
&bgcolor, &aColor, false);
|
||||
nsGkAtoms::bgcolor,
|
||||
&aColor, false);
|
||||
}
|
||||
} else {
|
||||
// Not the easy case. Range not contained in single text node. There
|
||||
@ -4659,7 +4667,8 @@ HTMLEditor::SetCSSBackgroundColor(const nsAString& aColor)
|
||||
if (blockParent && cachedBlockParent != blockParent) {
|
||||
cachedBlockParent = blockParent;
|
||||
mCSSEditUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
|
||||
&bgcolor, &aColor,
|
||||
nsGkAtoms::bgcolor,
|
||||
&aColor,
|
||||
false);
|
||||
}
|
||||
}
|
||||
@ -4670,7 +4679,8 @@ HTMLEditor::SetCSSBackgroundColor(const nsAString& aColor)
|
||||
if (blockParent && cachedBlockParent != blockParent) {
|
||||
cachedBlockParent = blockParent;
|
||||
mCSSEditUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
|
||||
&bgcolor, &aColor,
|
||||
nsGkAtoms::bgcolor,
|
||||
&aColor,
|
||||
false);
|
||||
}
|
||||
}
|
||||
@ -4684,7 +4694,8 @@ HTMLEditor::SetCSSBackgroundColor(const nsAString& aColor)
|
||||
if (blockParent && cachedBlockParent != blockParent) {
|
||||
cachedBlockParent = blockParent;
|
||||
mCSSEditUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
|
||||
&bgcolor, &aColor,
|
||||
nsGkAtoms::bgcolor,
|
||||
&aColor,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
@ -427,7 +427,7 @@ HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode,
|
||||
mCSSEditUtils->IsCSSEditableProperty(&aNode, &aProperty,
|
||||
aAttribute)) ||
|
||||
// bgcolor is always done using CSS
|
||||
aAttribute->EqualsLiteral("bgcolor");
|
||||
attrAtom == nsGkAtoms::bgcolor;
|
||||
|
||||
if (useCSS) {
|
||||
nsCOMPtr<dom::Element> tmp;
|
||||
@ -442,12 +442,9 @@ HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode,
|
||||
}
|
||||
|
||||
// Add the CSS styles corresponding to the HTML style request
|
||||
int32_t count;
|
||||
nsresult rv =
|
||||
mCSSEditUtils->SetCSSEquivalentToHTMLStyle(tmp->AsDOMNode(),
|
||||
&aProperty, aAttribute,
|
||||
&aValue, &count, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mCSSEditUtils->SetCSSEquivalentToHTMLStyle(tmp,
|
||||
&aProperty, attrAtom,
|
||||
&aValue, false);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -572,8 +569,9 @@ HTMLEditor::SplitStyleAbovePoint(nsCOMPtr<nsINode>* aNode,
|
||||
// in this implementation for the node; let's check if it carries those
|
||||
// CSS styles
|
||||
nsAutoString firstValue;
|
||||
mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(GetAsDOMNode(node),
|
||||
aProperty, aAttribute, isSet, firstValue, CSSEditUtils::eSpecified);
|
||||
isSet = mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(
|
||||
node, aProperty, aAttribute, firstValue,
|
||||
CSSEditUtils::eSpecified);
|
||||
}
|
||||
if (// node is the correct inline prop
|
||||
(aProperty && node->IsHTMLElement(aProperty)) ||
|
||||
@ -784,15 +782,17 @@ HTMLEditor::RemoveStyleInside(nsIContent& aNode,
|
||||
// the HTML style defined by aProperty/aAttribute has a CSS equivalence in
|
||||
// this implementation for the node aNode; let's check if it carries those
|
||||
// css styles
|
||||
nsCOMPtr<nsIAtom> attribute =
|
||||
aAttribute ? NS_Atomize(*aAttribute) : nullptr;
|
||||
nsAutoString propertyValue;
|
||||
bool isSet = mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(&aNode,
|
||||
aProperty, aAttribute, propertyValue, CSSEditUtils::eSpecified);
|
||||
aProperty, attribute, propertyValue, CSSEditUtils::eSpecified);
|
||||
if (isSet && aNode.IsElement()) {
|
||||
// yes, tmp has the corresponding css declarations in its style attribute
|
||||
// let's remove them
|
||||
mCSSEditUtils->RemoveCSSEquivalentToHTMLStyle(aNode.AsElement(),
|
||||
aProperty,
|
||||
aAttribute,
|
||||
attribute,
|
||||
&propertyValue,
|
||||
false);
|
||||
// remove the node if it is a span or font, if its style attribute is
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "WebBrowserPersistDocumentParent.h"
|
||||
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "mozilla/dom/PContentParent.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "WebBrowserPersistResourcesParent.h"
|
||||
@ -84,8 +85,9 @@ WebBrowserPersistDocumentParent::RecvInitFailure(const nsresult& aFailure)
|
||||
mOnReady->OnError(aFailure);
|
||||
mOnReady = nullptr;
|
||||
// Warning: Send__delete__ deallocates this object.
|
||||
IProtocol* mgr = Manager();
|
||||
if (!Send__delete__(this)) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
return IPC_FAIL_NO_REASON(mgr);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -163,8 +163,9 @@ mozilla::ipc::IPCResult
|
||||
LayerTransactionParent::RecvShutdown()
|
||||
{
|
||||
Destroy();
|
||||
IProtocol* mgr = Manager();
|
||||
if (!Send__delete__(this)) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
return IPC_FAIL_NO_REASON(mgr);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -139,9 +139,13 @@ gfxFontUtils::ReadCMAPTableFormat10(const uint8_t *aBuf, uint32_t aLength,
|
||||
}
|
||||
|
||||
nsresult
|
||||
gfxFontUtils::ReadCMAPTableFormat12(const uint8_t *aBuf, uint32_t aLength,
|
||||
gfxSparseBitSet& aCharacterMap)
|
||||
gfxFontUtils::ReadCMAPTableFormat12or13(const uint8_t *aBuf, uint32_t aLength,
|
||||
gfxSparseBitSet& aCharacterMap)
|
||||
{
|
||||
// Format 13 has the same structure as format 12, the only difference is
|
||||
// the interpretation of the glyphID field. So we can share the code here
|
||||
// that reads the table and just records character coverage.
|
||||
|
||||
// Ensure table is large enough that we can safely read the header
|
||||
NS_ENSURE_TRUE(aLength >= sizeof(Format12CmapHeader),
|
||||
NS_ERROR_GFX_CMAP_MALFORMED);
|
||||
@ -149,9 +153,10 @@ gfxFontUtils::ReadCMAPTableFormat12(const uint8_t *aBuf, uint32_t aLength,
|
||||
// Sanity-check header fields
|
||||
const Format12CmapHeader *cmap12 =
|
||||
reinterpret_cast<const Format12CmapHeader*>(aBuf);
|
||||
NS_ENSURE_TRUE(uint16_t(cmap12->format) == 12,
|
||||
NS_ENSURE_TRUE(uint16_t(cmap12->format) == 12 ||
|
||||
uint16_t(cmap12->format) == 13,
|
||||
NS_ERROR_GFX_CMAP_MALFORMED);
|
||||
NS_ENSURE_TRUE(uint16_t(cmap12->reserved) == 0,
|
||||
NS_ENSURE_TRUE(uint16_t(cmap12->reserved) == 0,
|
||||
NS_ERROR_GFX_CMAP_MALFORMED);
|
||||
|
||||
uint32_t tablelen = cmap12->length;
|
||||
@ -472,7 +477,7 @@ gfxFontUtils::FindPreferredSubtable(const uint8_t *aBuf, uint32_t aBufLength,
|
||||
keepFormat = format;
|
||||
*aTableOffset = offset;
|
||||
*aSymbolEncoding = false;
|
||||
} else if ((format == 10 || format == 12) &&
|
||||
} else if ((format == 10 || format == 12 || format == 13) &&
|
||||
acceptableUCS4Encoding(platformID, encodingID, keepFormat)) {
|
||||
keepFormat = format;
|
||||
*aTableOffset = offset;
|
||||
@ -521,10 +526,11 @@ gfxFontUtils::ReadCMAP(const uint8_t *aBuf, uint32_t aBufLength,
|
||||
aCharacterMap);
|
||||
|
||||
case 12:
|
||||
case 13:
|
||||
aUnicodeFont = true;
|
||||
aSymbolFont = false;
|
||||
return ReadCMAPTableFormat12(aBuf + offset, aBufLength - offset,
|
||||
aCharacterMap);
|
||||
return ReadCMAPTableFormat12or13(aBuf + offset, aBufLength - offset,
|
||||
aCharacterMap);
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -651,13 +657,17 @@ gfxFontUtils::MapCharToGlyphFormat10(const uint8_t *aBuf, uint32_t aCh)
|
||||
}
|
||||
|
||||
uint32_t
|
||||
gfxFontUtils::MapCharToGlyphFormat12(const uint8_t *aBuf, uint32_t aCh)
|
||||
gfxFontUtils::MapCharToGlyphFormat12or13(const uint8_t *aBuf, uint32_t aCh)
|
||||
{
|
||||
// The only difference between formats 12 and 13 is the interpretation of
|
||||
// the glyphId field. So the code here uses the same "Format12" structures,
|
||||
// etc., to handle both subtable formats.
|
||||
|
||||
const Format12CmapHeader *cmap12 =
|
||||
reinterpret_cast<const Format12CmapHeader*>(aBuf);
|
||||
|
||||
// We know that numGroups is within range for the subtable size
|
||||
// because it was checked by ReadCMAPTableFormat12.
|
||||
// because it was checked by ReadCMAPTableFormat12or13.
|
||||
uint32_t numGroups = cmap12->numGroups;
|
||||
|
||||
// The array of groups immediately follows the subtable header.
|
||||
@ -688,10 +698,13 @@ gfxFontUtils::MapCharToGlyphFormat12(const uint8_t *aBuf, uint32_t aCh)
|
||||
}
|
||||
|
||||
// Check if the character is actually present in the range and return
|
||||
// the corresponding glyph ID
|
||||
// the corresponding glyph ID. Here is where formats 12 and 13 interpret
|
||||
// the startGlyphId (12) or glyphId (13) field differently
|
||||
startCharCode = groups[range].startCharCode;
|
||||
if (startCharCode <= aCh && groups[range].endCharCode >= aCh) {
|
||||
return groups[range].startGlyphId + aCh - startCharCode;
|
||||
return uint16_t(cmap12->format) == 12
|
||||
? uint16_t(groups[range].startGlyphId) + aCh - startCharCode
|
||||
: uint16_t(groups[range].startGlyphId);
|
||||
}
|
||||
|
||||
// Else it's not present, so return the .notdef glyph
|
||||
@ -767,7 +780,8 @@ gfxFontUtils::MapCharToGlyph(const uint8_t *aCmapBuf, uint32_t aBufLength,
|
||||
gid = MapCharToGlyphFormat10(aCmapBuf + offset, aUnicode);
|
||||
break;
|
||||
case 12:
|
||||
gid = MapCharToGlyphFormat12(aCmapBuf + offset, aUnicode);
|
||||
case 13:
|
||||
gid = MapCharToGlyphFormat12or13(aCmapBuf + offset, aUnicode);
|
||||
break;
|
||||
default:
|
||||
NS_WARNING("unsupported cmap format, glyphs will be missing");
|
||||
@ -793,8 +807,9 @@ gfxFontUtils::MapCharToGlyph(const uint8_t *aCmapBuf, uint32_t aBufLength,
|
||||
aUnicode);
|
||||
break;
|
||||
case 12:
|
||||
varGID = MapCharToGlyphFormat12(aCmapBuf + offset,
|
||||
aUnicode);
|
||||
case 13:
|
||||
varGID = MapCharToGlyphFormat12or13(aCmapBuf + offset,
|
||||
aUnicode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -781,8 +781,8 @@ public:
|
||||
gfxSparseBitSet& aCharacterMap);
|
||||
|
||||
static nsresult
|
||||
ReadCMAPTableFormat12(const uint8_t *aBuf, uint32_t aLength,
|
||||
gfxSparseBitSet& aCharacterMap);
|
||||
ReadCMAPTableFormat12or13(const uint8_t *aBuf, uint32_t aLength,
|
||||
gfxSparseBitSet& aCharacterMap);
|
||||
|
||||
static nsresult
|
||||
ReadCMAPTableFormat4(const uint8_t *aBuf, uint32_t aLength,
|
||||
@ -810,7 +810,7 @@ public:
|
||||
MapCharToGlyphFormat10(const uint8_t *aBuf, uint32_t aCh);
|
||||
|
||||
static uint32_t
|
||||
MapCharToGlyphFormat12(const uint8_t *aBuf, uint32_t aCh);
|
||||
MapCharToGlyphFormat12or13(const uint8_t *aBuf, uint32_t aCh);
|
||||
|
||||
static uint16_t
|
||||
MapUVSToGlyphFormat14(const uint8_t *aBuf, uint32_t aCh, uint32_t aVS);
|
||||
|
@ -131,8 +131,10 @@ gfxHarfBuzzShaper::GetNominalGlyph(hb_codepoint_t unicode) const
|
||||
unicode);
|
||||
break;
|
||||
case 12:
|
||||
gid = gfxFontUtils::MapCharToGlyphFormat12(data + mSubtableOffset,
|
||||
unicode);
|
||||
case 13:
|
||||
gid =
|
||||
gfxFontUtils::MapCharToGlyphFormat12or13(data + mSubtableOffset,
|
||||
unicode);
|
||||
break;
|
||||
default:
|
||||
NS_WARNING("unsupported cmap format, glyphs will be missing");
|
||||
@ -190,8 +192,10 @@ gfxHarfBuzzShaper::GetVariationGlyph(hb_codepoint_t unicode,
|
||||
compat);
|
||||
break;
|
||||
case 12:
|
||||
return gfxFontUtils::MapCharToGlyphFormat12(data + mSubtableOffset,
|
||||
compat);
|
||||
case 13:
|
||||
return
|
||||
gfxFontUtils::MapCharToGlyphFormat12or13(data + mSubtableOffset,
|
||||
compat);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4084,15 +4084,12 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
||||
|
||||
msgvar, stmts = self.makeMessage(md, errfnSendDtor, actorvar)
|
||||
sendok, sendstmts = self.sendAsync(md, msgvar, actorvar)
|
||||
failif = StmtIf(ExprNot(sendok))
|
||||
failif.addifstmt(StmtReturn.FALSE)
|
||||
|
||||
method.addstmts(
|
||||
stmts
|
||||
+ self.genVerifyMessage(md.decl.type.verify, md.params,
|
||||
errfnSendDtor, ExprVar('msg__'))
|
||||
+ sendstmts
|
||||
+ [ failif, Whitespace.NL ]
|
||||
+ [ Whitespace.NL ]
|
||||
+ self.dtorEpilogue(md, actor.var())
|
||||
+ [ StmtReturn(sendok) ])
|
||||
|
||||
|
@ -1341,21 +1341,6 @@ js::ReportIsNotFunction(JSContext* cx, HandleValue v)
|
||||
return ReportIsNotFunction(cx, v, -1);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::ReportASCIIErrorWithId(JSContext* cx, const char* msg, HandleId id)
|
||||
{
|
||||
RootedValue idv(cx);
|
||||
if (!JS_IdToValue(cx, id, &idv))
|
||||
return;
|
||||
RootedString idstr(cx, JS::ToString(cx, idv));
|
||||
if (!idstr)
|
||||
return;
|
||||
JSAutoByteString bytes;
|
||||
if (!bytes.encodeUtf8(cx, idstr))
|
||||
return;
|
||||
JS_ReportErrorUTF8(cx, msg, bytes.ptr());
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
bool
|
||||
js::HasObjectMovedOp(JSObject* obj) {
|
||||
|
@ -2773,9 +2773,6 @@ SetPropertyIgnoringNamedGetter(JSContext* cx, JS::HandleObject obj, JS::HandleId
|
||||
JS::Handle<JS::PropertyDescriptor> ownDesc,
|
||||
JS::ObjectOpResult& result);
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
ReportASCIIErrorWithId(JSContext* cx, const char* msg, JS::HandleId id);
|
||||
|
||||
// This function is for one specific use case, please don't use this for anything else!
|
||||
extern JS_FRIEND_API(bool)
|
||||
ExecuteInGlobalAndReturnScope(JSContext* cx, JS::HandleObject obj, JS::HandleScript script,
|
||||
|
@ -3270,7 +3270,8 @@ GCHelperState::startBackgroundThread(State newState, const AutoLockGC& lock,
|
||||
void
|
||||
GCHelperState::waitForBackgroundThread(js::AutoLockGC& lock)
|
||||
{
|
||||
done.wait(lock.guard());
|
||||
while (isBackgroundSweeping())
|
||||
done.wait(lock.guard());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -23,6 +23,21 @@ using namespace JS;
|
||||
|
||||
namespace xpc {
|
||||
|
||||
static inline void
|
||||
ReportASCIIErrorWithId(JSContext* cx, const char* msg, HandleId id)
|
||||
{
|
||||
RootedValue idv(cx);
|
||||
if (!JS_IdToValue(cx, id, &idv))
|
||||
return;
|
||||
RootedString idstr(cx, JS::ToString(cx, idv));
|
||||
if (!idstr)
|
||||
return;
|
||||
JSAutoByteString bytes;
|
||||
if (!bytes.encodeUtf8(cx, idstr))
|
||||
return;
|
||||
JS_ReportErrorUTF8(cx, msg, bytes.ptr());
|
||||
}
|
||||
|
||||
bool
|
||||
InterposeProperty(JSContext* cx, HandleObject target, const nsIID* iid, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> descriptor)
|
||||
@ -231,7 +246,7 @@ AddonWrapper<Base>::defineProperty(JSContext* cx, HandleObject wrapper, HandleId
|
||||
if (!interpDesc.object())
|
||||
return Base::defineProperty(cx, wrapper, id, desc, result);
|
||||
|
||||
js::ReportASCIIErrorWithId(cx, "unable to modify interposed property %s", id);
|
||||
ReportASCIIErrorWithId(cx, "unable to modify interposed property %s", id);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -247,7 +262,7 @@ AddonWrapper<Base>::delete_(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
if (!desc.object())
|
||||
return Base::delete_(cx, wrapper, id, result);
|
||||
|
||||
js::ReportASCIIErrorWithId(cx, "unable to delete interposed property %s", id);
|
||||
ReportASCIIErrorWithId(cx, "unable to delete interposed property %s", id);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
12
layout/reftests/text/1320665-cmap-format-13-ref.html
Normal file
12
layout/reftests/text/1320665-cmap-format-13-ref.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset=utf-8>
|
||||
<style>
|
||||
body {
|
||||
font-family: monospace;
|
||||
font-size: 48px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
PASS
|
22
layout/reftests/text/1320665-cmap-format-13.html
Normal file
22
layout/reftests/text/1320665-cmap-format-13.html
Normal file
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset=utf-8>
|
||||
<style>
|
||||
/* Adobe Blank 2 font from https://github.com/adobe-fonts/adobe-blank-2/blob/master/adobe-blank-2.css,
|
||||
licensed under the SIL Open Font License, Version 1.1. http://scripts.sil.org/OFL */
|
||||
@font-face {
|
||||
font-family: AdobeBlank2;
|
||||
src: url("data:font/opentype;base64,T1RUTwAKAIAAAwAgQ0ZGIN6nWacAAAfMAAABMURTSUcAAAABAAAJCAAAAAhPUy8yAF+xmwAAARAAAABgY21hcAE0tLwAAAasAAABAGhlYWQIOsNZAAAArAAAADZoaGVhB1oD7wAAAOQAAAAkaG10eAPoAHwAAAkAAAAACG1heHAAAlAAAAABCAAAAAZuYW1lc0mXUAAAAXAAAAU6cG9zdP+4ADIAAAesAAAAIAABAAAAAgBB1Q6SE18PPPUAAwPoAAAAANKdP6AAAAAA0p0/oAB8/4gDbANwAAAAAwACAAAAAAAAAAEAAANw/4gAAAPoAHwAfANsAAEAAAAAAAAAAAAAAAAAAAACAABQAAACAAAAAwPoAZAABQAAAooCWAAAAEsCigJYAAABXgAyANwAAAAAAAAAAAAAAAD3/67/+9///w/gAD8AAAAAQURCTwBAAAD//wNw/4gAAANwAHhgLwH/AAAAAAAAAAAAAAAgAAAAAAALAIoAAwABBAkAAACUAAAAAwABBAkAAQAaAJQAAwABBAkAAgAOAK4AAwABBAkAAwA4ALwAAwABBAkABAAaAJQAAwABBAkABQB0APQAAwABBAkABgAWAWgAAwABBAkACAA0AX4AAwABBAkACwA0AbIAAwABBAkADQKWAeYAAwABBAkADgA0BHwAQwBvAHAAeQByAGkAZwBoAHQAIACpACAAMgAwADEAMwAsACAAMgAwADEANQAgAEEAZABvAGIAZQAgAFMAeQBzAHQAZQBtAHMAIABJAG4AYwBvAHIAcABvAHIAYQB0AGUAZAAgACgAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGEAZABvAGIAZQAuAGMAbwBtAC8AKQAuAEEAZABvAGIAZQAgAEIAbABhAG4AawAgADIAUgBlAGcAdQBsAGEAcgAyAC4AMAAwADEAOwBBAEQAQgBPADsAQQBkAG8AYgBlAEIAbABhAG4AawAyADsAQQBEAE8AQgBFAFYAZQByAHMAaQBvAG4AIAAyAC4AMAAwADEAOwBQAFMAIAAyAC4AMAAwADEAOwBoAG8AdABjAG8AbgB2ACAAMQAuADAALgA4ADgAOwBtAGEAawBlAG8AdABmAC4AbABpAGIAMgAuADUALgA2ADUAMAAxADIAQQBkAG8AYgBlAEIAbABhAG4AawAyAEEAZABvAGIAZQAgAFMAeQBzAHQAZQBtAHMAIABJAG4AYwBvAHIAcABvAHIAYQB0AGUAZABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBkAG8AYgBlAC4AYwBvAG0ALwB0AHkAcABlAC8AVABoAGkAcwAgAEYAbwBuAHQAIABTAG8AZgB0AHcAYQByAGUAIABpAHMAIABsAGkAYwBlAG4AcwBlAGQAIAB1AG4AZABlAHIAIAB0AGgAZQAgAFMASQBMACAATwBwAGUAbgAgAEYAbwBuAHQAIABMAGkAYwBlAG4AcwBlACwAIABWAGUAcgBzAGkAbwBuACAAMQAuADEALgAgAFQAaABpAHMAIABGAG8AbgB0ACAAUwBvAGYAdAB3AGEAcgBlACAAaQBzACAAZABpAHMAdAByAGkAYgB1AHQAZQBkACAAbwBuACAAYQBuACAAIgBBAFMAIABJAFMAIgAgAEIAQQBTAEkAUwAsACAAVwBJAFQASABPAFUAVAAgAFcAQQBSAFIAQQBOAFQASQBFAFMAIABPAFIAIABDAE8ATgBEAEkAVABJAE8ATgBTACAATwBGACAAQQBOAFkAIABLAEkATgBEACwAIABlAGkAdABoAGUAcgAgAGUAeABwAHIAZQBzAHMAIABvAHIAIABpAG0AcABsAGkAZQBkAC4AIABTAGUAZQAgAHQAaABlACAAUwBJAEwAIABPAHAAZQBuACAARgBvAG4AdAAgAEwAaQBjAGUAbgBzAGUAIABmAG8AcgAgAHQAaABlACAAcwBwAGUAYwBpAGYAaQBjACAAbABhAG4AZwB1AGEAZwBlACwAIABwAGUAcgBtAGkAcwBzAGkAbwBuAHMAIABhAG4AZAAgAGwAaQBtAGkAdABhAHQAaQBvAG4AcwAgAGcAbwB2AGUAcgBuAGkAbgBnACAAeQBvAHUAcgAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEYAbwBuAHQAIABTAG8AZgB0AHcAYQByAGUALgBoAHQAdABwADoALwAvAHMAYwByAGkAcAB0AHMALgBzAGkAbAAuAG8AcgBnAC8ATwBGAEwAAAAAAAEAAwAKAAAADAANAAAAAAD0AAAAAAAAABMAAAAAAADX/wAAAAEAAOAAAAD9zwAAAAEAAP3wAAD//QAAAAEAAQAAAAH//QAAAAEAAgAAAAL//QAAAAEAAwAAAAP//QAAAAEABAAAAAT//QAAAAEABQAAAAX//QAAAAEABgAAAAb//QAAAAEABwAAAAf//QAAAAEACAAAAAj//QAAAAEACQAAAAn//QAAAAEACgAAAAr//QAAAAEACwAAAAv//QAAAAEADAAAAAz//QAAAAEADQAAAA3//QAAAAEADgAAAA7//QAAAAEADwAAAA///QAAAAEAEAAAABD//QAAAAEAAwAAAAAAAP+1ADIAAAAAAAAAAAAAAAAAAAAAAAAAAAEABAIAAQEBDEFkb2JlQmxhbmsyAAEBAS34G/gciwwe+B0B+B4Ci/sM+gD6BAUeKgAfDB+NDCL3Uw/3WRH3Vgwl96wMJAAFAQEGDlZjcEFkb2JlSWRlbnRpdHlDb3B5cmlnaHQgMjAxMywgMjAxNSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCAoaHR0cDovL3d3dy5hZG9iZS5jb20vKS5BZG9iZSBCbGFuayAyQWRvYmVCbGFuazItMgAAAAABAAAAAAIBAUxO+nz7DLf6JLcB9xC3+Sy3A/cQ+gQV/nz5hPp8B/1Y/icV+dIH98X8MwWmsBX7xfg3Bfj2BqZiFf3SB/vF+DMFcGYV98X8NwX89gYOiw4AAQEBCfgfDCaX97kS+46LHAVGiwa9Cr0LAAAAA+gAfAAAAAAAAAABAAAAAA==");
|
||||
}
|
||||
body {
|
||||
font-family: monospace;
|
||||
font-size: 48px;
|
||||
}
|
||||
span {
|
||||
font-family: AdobeBlank2;
|
||||
font-size: 24px; /* smaller size to avoid risk of disrupting line height */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
P<span> (fail) </span>A<span>ሴ顶ꯍ</span>S<span>𐐀🌳</span>S
|
@ -185,6 +185,7 @@ HTTP(..) != fallback-mark-stacking-1.html fallback-mark-stacking-1-notref.html
|
||||
== 745555-2.html 745555-2-ref.html
|
||||
== 820255.html 820255-ref.html
|
||||
HTTP(..) != 1170688.html 1170688-ref.html
|
||||
fails-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 1320665-cmap-format-13.html 1320665-cmap-format-13-ref.html # see bug 1320665 comments 8-9
|
||||
|
||||
# ensure emoji chars don't render blank (bug 715798, bug 779042);
|
||||
# should at least render hexboxes if there's no font support
|
||||
|
@ -3878,7 +3878,7 @@ CSS_PROP_TEXT(
|
||||
VARIANT_INHERIT | VARIANT_LNCALC,
|
||||
nullptr,
|
||||
offsetof(nsStyleText, mTabSize),
|
||||
eStyleAnimType_Discrete)
|
||||
eStyleAnimType_Coord)
|
||||
CSS_PROP_TABLE(
|
||||
table-layout,
|
||||
table_layout,
|
||||
|
@ -248,6 +248,8 @@ var supported_properties = {
|
||||
// test_length_percent_calc_transition.
|
||||
"stroke-width": [ test_length_transition_svg, test_percent_transition,
|
||||
test_length_clamped_svg, test_percent_clamped ],
|
||||
"-moz-tab-size": [ test_float_zeroToOne_transition,
|
||||
test_float_aboveOne_transition, test_length_clamped ],
|
||||
"text-decoration": [ test_color_shorthand_transition,
|
||||
test_true_currentcolor_shorthand_transition ],
|
||||
"text-decoration-color": [ test_color_transition,
|
||||
|
@ -49,8 +49,9 @@ WebSocketChannelParent::RecvDeleteSelf()
|
||||
LOG(("WebSocketChannelParent::RecvDeleteSelf() %p\n", this));
|
||||
mChannel = nullptr;
|
||||
mAuthProvider = nullptr;
|
||||
IProtocol* mgr = Manager();
|
||||
if (mIPCOpen && !Send__delete__(this)) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
return IPC_FAIL_NO_REASON(mgr);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
[firing-events-http-no-content-length.html]
|
||||
type: testharness
|
||||
[ProgressEvent: firing events for HTTP with no Content-Length]
|
||||
expected: FAIL
|
||||
|
@ -22,53 +22,56 @@
|
||||
}
|
||||
|
||||
function getNextEvent(arr) {
|
||||
var eventStr = arr.shift();
|
||||
var event = { str: arr.shift() };
|
||||
|
||||
// we can only handle strings, numbers (readystates) and undefined
|
||||
if (eventStr === undefined) {
|
||||
if (event.str === undefined) {
|
||||
return event;
|
||||
}
|
||||
if (typeof eventStr !== "string") {
|
||||
if (Number.isInteger(eventStr)) {
|
||||
eventStr = "readystatechange(" + eventStr + ")";
|
||||
|
||||
if (typeof event.str !== "string") {
|
||||
if (Number.isInteger(event.str)) {
|
||||
event.state = event.str;
|
||||
event.str = "readystatechange(" + event.str + ")";
|
||||
} else {
|
||||
throw "Test error: unexpected event type " + eventStr;
|
||||
throw "Test error: unexpected event type " + event.str;
|
||||
}
|
||||
}
|
||||
|
||||
// parse out the general type, loaded and total values
|
||||
var type = eventStr.type = eventStr.split("(")[0].split(".").pop();
|
||||
eventStr.mayFollowOptionalProgressEvents = type == "progress" ||
|
||||
type == "load" || type == "abort" || type == "error";
|
||||
var loadedAndTotal = eventStr.match(/\((\d)+,(\d)+/);
|
||||
var type = event.type = event.str.split("(")[0].split(".").pop();
|
||||
var loadedAndTotal = event.str.match(/.*\((\d+),(\d+),(true|false)\)/);
|
||||
if (loadedAndTotal) {
|
||||
eventStr.loaded = parseInt(loadedAndTotal[0]);
|
||||
eventStr.total = parseInt(loadedAndTotal[1]);
|
||||
event.loaded = parseInt(loadedAndTotal[1]);
|
||||
event.total = parseInt(loadedAndTotal[2]);
|
||||
event.lengthComputable = loadedAndTotal[3] == "true";
|
||||
}
|
||||
|
||||
return eventStr;
|
||||
return event;
|
||||
}
|
||||
|
||||
global.assert_xhr_event_order_matches = function(expected) {
|
||||
var recorded = recorded_xhr_events;
|
||||
var lastRecordedLoaded = -1;
|
||||
|
||||
while(expected.length && recorded.length) {
|
||||
var currentExpected = getNextEvent(expected),
|
||||
currentRecorded = getNextEvent(recorded);
|
||||
|
||||
// skip to the last progress event if we've hit one
|
||||
while (recorded.length && currentRecorded.type == "progress") {
|
||||
assert_greater(currentRecorded.loaded, lastRecordedLoaded,
|
||||
"progress event 'loaded' values must only increase");
|
||||
// skip to the last progress event if we've hit one (note the next
|
||||
// event after a progress event should be a LOADING readystatechange,
|
||||
// if there are multiple progress events in a row).
|
||||
while (recorded.length && currentRecorded.type == "progress" &&
|
||||
parseInt(recorded) === 3) {
|
||||
assert_greater_than(currentRecorded.loaded, lastRecordedLoaded,
|
||||
"progress event 'loaded' values must only increase");
|
||||
lastRecordedLoaded = currentRecorded.loaded;
|
||||
currentRecorded = getNextEvent(recorded);
|
||||
}
|
||||
if (currentRecorded.type == "loadstart") {
|
||||
if (currentRecorded.type == "loadend") {
|
||||
recordedProgressCount = 0;
|
||||
lastRecordedLoaded = -1;
|
||||
}
|
||||
|
||||
assert_equals(currentRecorded, currentExpected);
|
||||
assert_equals(currentRecorded.str, currentExpected.str);
|
||||
}
|
||||
if (recorded.length) {
|
||||
throw "\nUnexpected extra events: " + recorded.join(", ");
|
||||
|
@ -9623,196 +9623,6 @@
|
||||
"releaseChannelCollection": "opt-out",
|
||||
"description": "Reports whether the graphics sanity test passed an OS snapshot test. 0=Pass, 1=Fail, 2=Error, 3=Timed out."
|
||||
},
|
||||
"DEVTOOLS_HUD_JANK": {
|
||||
"alert_emails": ["rnicoletti@mozilla.com","thills@mozilla.com"],
|
||||
"expires_in_version": "52",
|
||||
"kind": "exponential",
|
||||
"keyed": true,
|
||||
"description": "The duration which a thread is blocked in ms, keyed by appName.",
|
||||
"high": 5000,
|
||||
"n_buckets": 10
|
||||
},
|
||||
"DEVTOOLS_HUD_REFLOW_DURATION": {
|
||||
"alert_emails": ["rnicoletti@mozilla.com","thills@mozilla.com"],
|
||||
"expires_in_version": "52",
|
||||
"kind": "exponential",
|
||||
"keyed": true,
|
||||
"description": "The duration a reflow takes in ms, keyed by appName.",
|
||||
"high": 1000,
|
||||
"n_buckets": 10
|
||||
},
|
||||
"DEVTOOLS_HUD_REFLOWS": {
|
||||
"alert_emails": ["rnicoletti@mozilla.com","thills@mozilla.com"],
|
||||
"expires_in_version": "52",
|
||||
"kind": "count",
|
||||
"keyed": true,
|
||||
"description": "A count of the number of reflows, keyed by appName."
|
||||
},
|
||||
"DEVTOOLS_HUD_SECURITY_CATEGORY": {
|
||||
"alert_emails": ["rnicoletti@mozilla.com","thills@mozilla.com"],
|
||||
"expires_in_version": "52",
|
||||
"kind": "enumerated",
|
||||
"keyed": true,
|
||||
"description": "The security error enums, keyed by appName.",
|
||||
"n_values": 8
|
||||
},
|
||||
"DEVTOOLS_HUD_ERRORS": {
|
||||
"alert_emails": ["rnicoletti@mozilla.com","thills@mozilla.com"],
|
||||
"expires_in_version": "52",
|
||||
"kind": "count",
|
||||
"keyed": true,
|
||||
"description": "Number of errors, keyed by appName."
|
||||
},
|
||||
"DEVTOOLS_HUD_WARNINGS": {
|
||||
"alert_emails": ["rnicoletti@mozilla.com","thills@mozilla.com"],
|
||||
"expires_in_version": "52",
|
||||
"kind": "count",
|
||||
"keyed": true,
|
||||
"description": "Number of warnings, keyed by appName."
|
||||
},
|
||||
"DEVTOOLS_HUD_USS": {
|
||||
"alert_emails": ["rnicoletti@mozilla.com","thills@mozilla.com"],
|
||||
"expires_in_version": "52",
|
||||
"kind": "linear",
|
||||
"keyed": true,
|
||||
"low": 20000000,
|
||||
"high": 100000000,
|
||||
"n_buckets": 52,
|
||||
"description": "The USS memory consumed by an application, keyed by appName."
|
||||
},
|
||||
"DEVTOOLS_HUD_APP_STARTUP_TIME_CONTENTINTERACTIVE": {
|
||||
"alert_emails": ["rnicoletti@mozilla.com","thills@mozilla.com"],
|
||||
"expires_in_version": "52",
|
||||
"kind": "linear",
|
||||
"keyed": true,
|
||||
"description": "The duration in ms between application launch and the 'contentInteractive' performance mark, keyed by appName.",
|
||||
"high": 2000,
|
||||
"n_buckets": 10
|
||||
},
|
||||
"DEVTOOLS_HUD_APP_STARTUP_TIME_NAVIGATIONINTERACTIVE": {
|
||||
"alert_emails": ["rnicoletti@mozilla.com","thills@mozilla.com"],
|
||||
"expires_in_version": "52",
|
||||
"kind": "linear",
|
||||
"keyed": true,
|
||||
"description": "The duration in ms between application launch and the 'navigationInteractive' performance mark, keyed by appName.",
|
||||
"high": 3000,
|
||||
"n_buckets": 10
|
||||
},
|
||||
"DEVTOOLS_HUD_APP_STARTUP_TIME_NAVIGATIONLOADED": {
|
||||
"alert_emails": ["rnicoletti@mozilla.com","thills@mozilla.com"],
|
||||
"expires_in_version": "52",
|
||||
"kind": "linear",
|
||||
"keyed": true,
|
||||
"description": "The duration in ms between application launch and the 'navigationLoaded' performance mark, keyed by appName.",
|
||||
"high": 4000,
|
||||
"n_buckets": 10
|
||||
},
|
||||
"DEVTOOLS_HUD_APP_STARTUP_TIME_VISUALLYLOADED": {
|
||||
"alert_emails": ["rnicoletti@mozilla.com","thills@mozilla.com"],
|
||||
"expires_in_version": "52",
|
||||
"kind": "linear",
|
||||
"keyed": true,
|
||||
"description": "The duration in ms between application launch and the 'visuallyLoaded' performance mark, keyed by appName.",
|
||||
"high": 5000,
|
||||
"n_buckets": 10
|
||||
},
|
||||
"DEVTOOLS_HUD_APP_STARTUP_TIME_MEDIAENUMERATED": {
|
||||
"alert_emails": ["rnicoletti@mozilla.com","thills@mozilla.com"],
|
||||
"expires_in_version": "52",
|
||||
"kind": "linear",
|
||||
"keyed": true,
|
||||
"description": "The duration in ms between application launch and the 'mediaEnumerated' performance mark, keyed by appName.",
|
||||
"high": 5000,
|
||||
"n_buckets": 10
|
||||
},
|
||||
"DEVTOOLS_HUD_APP_STARTUP_TIME_FULLYLOADED": {
|
||||
"alert_emails": ["rnicoletti@mozilla.com","thills@mozilla.com"],
|
||||
"expires_in_version": "52",
|
||||
"kind": "linear",
|
||||
"keyed": true,
|
||||
"description": "The duration in ms between application launch and the 'fullyLoaded' performance mark, keyed by appName.",
|
||||
"high": 30000,
|
||||
"n_buckets": 30
|
||||
},
|
||||
"DEVTOOLS_HUD_APP_STARTUP_TIME_SCANEND": {
|
||||
"alert_emails": ["rnicoletti@mozilla.com","thills@mozilla.com"],
|
||||
"expires_in_version": "52",
|
||||
"kind": "linear",
|
||||
"keyed": true,
|
||||
"description": "The duration in ms between application launch and the 'scanEnd' performance mark, keyed by appName.",
|
||||
"high": 30000,
|
||||
"n_buckets": 30
|
||||
},
|
||||
"DEVTOOLS_HUD_APP_MEMORY_CONTENTINTERACTIVE_V2": {
|
||||
"alert_emails": ["rnicoletti@mozilla.com","thills@mozilla.com"],
|
||||
"expires_in_version": "52",
|
||||
"kind": "linear",
|
||||
"keyed": true,
|
||||
"description": "The USS memory consumed by an application at the time of the 'contentInteractive' performance mark, keyed by appName.",
|
||||
"low": 20000000,
|
||||
"high": 30000000,
|
||||
"n_buckets": 10
|
||||
},
|
||||
"DEVTOOLS_HUD_APP_MEMORY_NAVIGATIONINTERACTIVE_V2": {
|
||||
"alert_emails": ["rnicoletti@mozilla.com","thills@mozilla.com"],
|
||||
"expires_in_version": "52",
|
||||
"kind": "linear",
|
||||
"keyed": true,
|
||||
"description": "The USS memory consumed by an application at the time of the 'navigationInteractive' performance mark, keyed by appName.",
|
||||
"low": 20000000,
|
||||
"high": 30000000,
|
||||
"n_buckets": 10
|
||||
},
|
||||
"DEVTOOLS_HUD_APP_MEMORY_NAVIGATIONLOADED_V2": {
|
||||
"alert_emails": ["rnicoletti@mozilla.com","thills@mozilla.com"],
|
||||
"expires_in_version": "52",
|
||||
"kind": "linear",
|
||||
"keyed": true,
|
||||
"description": "The USS memory consumed by an application at the time of the 'navigationLoaded' performance mark, keyed by appName.",
|
||||
"low": 20000000,
|
||||
"high": 30000000,
|
||||
"n_buckets": 10
|
||||
},
|
||||
"DEVTOOLS_HUD_APP_MEMORY_VISUALLYLOADED_V2": {
|
||||
"alert_emails": ["rnicoletti@mozilla.com","thills@mozilla.com"],
|
||||
"expires_in_version": "52",
|
||||
"kind": "linear",
|
||||
"keyed": true,
|
||||
"description": "The USS memory consumed by an application at the time of the 'visuallyLoaded' performance mark, keyed by appName.",
|
||||
"low": 20000000,
|
||||
"high": 30000000,
|
||||
"n_buckets": 10
|
||||
},
|
||||
"DEVTOOLS_HUD_APP_MEMORY_MEDIAENUMERATED_V2": {
|
||||
"alert_emails": ["rnicoletti@mozilla.com","thills@mozilla.com"],
|
||||
"expires_in_version": "52",
|
||||
"kind": "linear",
|
||||
"keyed": true,
|
||||
"description": "The USS memory consumed by an application at the time of the 'mediaEnumerated' performance mark, keyed by appName.",
|
||||
"low": 20000000,
|
||||
"high": 40000000,
|
||||
"n_buckets": 10
|
||||
},
|
||||
"DEVTOOLS_HUD_APP_MEMORY_FULLYLOADED_V2": {
|
||||
"alert_emails": ["rnicoletti@mozilla.com","thills@mozilla.com"],
|
||||
"expires_in_version": "52",
|
||||
"kind": "linear",
|
||||
"keyed": true,
|
||||
"description": "The USS memory consumed by an application at the time of the 'fullyLoaded' performance mark, keyed by appName.",
|
||||
"low": 20000000,
|
||||
"high": 40000000,
|
||||
"n_buckets": 20
|
||||
},
|
||||
"DEVTOOLS_HUD_APP_MEMORY_SCANEND_V2": {
|
||||
"alert_emails": ["rnicoletti@mozilla.com","thills@mozilla.com"],
|
||||
"expires_in_version": "52",
|
||||
"kind": "linear",
|
||||
"keyed": true,
|
||||
"description": "The USS memory consumed by an application at the time of the 'scanEnd' performance mark, keyed by appName.",
|
||||
"low": 20000000,
|
||||
"high": 40000000,
|
||||
"n_buckets": 20
|
||||
},
|
||||
"DEVTOOLS_MEMORY_TAKE_SNAPSHOT_COUNT": {
|
||||
"expires_in_version": "56",
|
||||
"kind": "count",
|
||||
|
@ -893,27 +893,6 @@
|
||||
"DEVTOOLS_FONTINSPECTOR_TIME_ACTIVE_SECONDS",
|
||||
"DEVTOOLS_HEAP_SNAPSHOT_EDGE_COUNT",
|
||||
"DEVTOOLS_HEAP_SNAPSHOT_NODE_COUNT",
|
||||
"DEVTOOLS_HUD_APP_MEMORY_CONTENTINTERACTIVE_V2",
|
||||
"DEVTOOLS_HUD_APP_MEMORY_FULLYLOADED_V2",
|
||||
"DEVTOOLS_HUD_APP_MEMORY_MEDIAENUMERATED_V2",
|
||||
"DEVTOOLS_HUD_APP_MEMORY_NAVIGATIONINTERACTIVE_V2",
|
||||
"DEVTOOLS_HUD_APP_MEMORY_NAVIGATIONLOADED_V2",
|
||||
"DEVTOOLS_HUD_APP_MEMORY_SCANEND_V2",
|
||||
"DEVTOOLS_HUD_APP_MEMORY_VISUALLYLOADED_V2",
|
||||
"DEVTOOLS_HUD_APP_STARTUP_TIME_CONTENTINTERACTIVE",
|
||||
"DEVTOOLS_HUD_APP_STARTUP_TIME_FULLYLOADED",
|
||||
"DEVTOOLS_HUD_APP_STARTUP_TIME_MEDIAENUMERATED",
|
||||
"DEVTOOLS_HUD_APP_STARTUP_TIME_NAVIGATIONINTERACTIVE",
|
||||
"DEVTOOLS_HUD_APP_STARTUP_TIME_NAVIGATIONLOADED",
|
||||
"DEVTOOLS_HUD_APP_STARTUP_TIME_SCANEND",
|
||||
"DEVTOOLS_HUD_APP_STARTUP_TIME_VISUALLYLOADED",
|
||||
"DEVTOOLS_HUD_ERRORS",
|
||||
"DEVTOOLS_HUD_JANK",
|
||||
"DEVTOOLS_HUD_REFLOWS",
|
||||
"DEVTOOLS_HUD_REFLOW_DURATION",
|
||||
"DEVTOOLS_HUD_SECURITY_CATEGORY",
|
||||
"DEVTOOLS_HUD_USS",
|
||||
"DEVTOOLS_HUD_WARNINGS",
|
||||
"DEVTOOLS_INSPECTOR_TIME_ACTIVE_SECONDS",
|
||||
"DEVTOOLS_JSBROWSERDEBUGGER_TIME_ACTIVE_SECONDS",
|
||||
"DEVTOOLS_JSDEBUGGER_TIME_ACTIVE_SECONDS",
|
||||
|
@ -1281,16 +1281,16 @@
|
||||
// The request comes from a XPCOM component, we'd want to redirect
|
||||
// the request to tabbrowser so tabbrowser will be setup correctly,
|
||||
// and it will eventually call swapDocShells.
|
||||
let tabbrowser = this.getTabBrowser();
|
||||
if (tabbrowser) {
|
||||
let tab = tabbrowser.getTabForBrowser(this);
|
||||
if (tab) {
|
||||
tabbrowser.swapBrowsers(tab, aOtherBrowser, aFlags);
|
||||
return;
|
||||
}
|
||||
let ourTabBrowser = this.getTabBrowser();
|
||||
let otherTabBrowser = aOtherBrowser.getTabBrowser();
|
||||
if (ourTabBrowser && otherTabBrowser) {
|
||||
let ourTab = ourTabBrowser.getTabForBrowser(this);
|
||||
let otherTab = otherTabBrowser.getTabForBrowser(aOtherBrowser);
|
||||
ourTabBrowser.swapBrowsers(ourTab, otherTab, aFlags);
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're not attached to a tabbrowser, just swap.
|
||||
// One of us is not connected to a tabbrowser, so just swap.
|
||||
this.swapDocShells(aOtherBrowser);
|
||||
]]>
|
||||
</body>
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "nsIURI.idl"
|
||||
#include "nsIDOMNode.idl"
|
||||
|
||||
interface nsIBrowser;
|
||||
interface nsIRequest;
|
||||
interface nsIDOMElement;
|
||||
interface nsIInputStream;
|
||||
@ -73,5 +74,14 @@ interface nsIXULBrowserWindow : nsISupports
|
||||
* Return the number of tabs in this window.
|
||||
*/
|
||||
uint32_t getTabCount();
|
||||
|
||||
/**
|
||||
* Navigate the browser to the given history index after restoring the full history
|
||||
* from SessionStore. If the browser is currently in GroupedSHistory mode, it will
|
||||
* be reverted to a non-grouped history mode. If a process change is required to
|
||||
* perform the load, this will also occur.
|
||||
*/
|
||||
void navigateAndRestoreByIndex(in nsIBrowser aBrowser, in long aIndex);
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user