зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to autoland
This commit is contained in:
Коммит
1b096c3511
|
@ -14,10 +14,8 @@ using namespace mozilla::a11y;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IMPL_IUNKNOWN_QUERY_HEAD(ChildrenEnumVariant)
|
||||
IMPL_IUNKNOWN_QUERY_IFACE(IEnumVARIANT);
|
||||
IMPL_IUNKNOWN_QUERY_IFACE(IUnknown);
|
||||
IMPL_IUNKNOWN_QUERY_AGGR_COND(mAnchorAcc, !mAnchorAcc->IsDefunct());
|
||||
IMPL_IUNKNOWN_QUERY_TAIL
|
||||
IMPL_IUNKNOWN_QUERY_IFACE(IEnumVARIANT)
|
||||
IMPL_IUNKNOWN_QUERY_TAIL_AGGREGATED(mAnchorAcc)
|
||||
|
||||
STDMETHODIMP
|
||||
ChildrenEnumVariant::Next(ULONG aCount, VARIANT FAR* aItems,
|
||||
|
|
|
@ -65,6 +65,13 @@ PrincipalOriginAttributes::InheritFromNecko(const NeckoOriginAttributes& aAttrs)
|
|||
mFirstPartyDomain = aAttrs.mFirstPartyDomain;
|
||||
}
|
||||
|
||||
void
|
||||
PrincipalOriginAttributes::StripUserContextIdAndFirstPartyDomain()
|
||||
{
|
||||
mUserContextId = nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID;
|
||||
mFirstPartyDomain.Truncate();
|
||||
}
|
||||
|
||||
void
|
||||
DocShellOriginAttributes::InheritFromDocToChildDocShell(const PrincipalOriginAttributes& aAttrs)
|
||||
{
|
||||
|
@ -717,6 +724,23 @@ BasePrincipal::CreateCodebasePrincipal(const nsACString& aOrigin)
|
|||
return BasePrincipal::CreateCodebasePrincipal(uri, attrs);
|
||||
}
|
||||
|
||||
already_AddRefed<BasePrincipal>
|
||||
BasePrincipal::CloneStrippingUserContextIdAndFirstPartyDomain()
|
||||
{
|
||||
PrincipalOriginAttributes attrs = OriginAttributesRef();
|
||||
attrs.StripUserContextIdAndFirstPartyDomain();
|
||||
|
||||
nsAutoCString originNoSuffix;
|
||||
nsresult rv = GetOriginNoSuffix(originNoSuffix);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
return BasePrincipal::CreateCodebasePrincipal(uri, attrs);
|
||||
}
|
||||
|
||||
bool
|
||||
BasePrincipal::AddonAllowsLoad(nsIURI* aURI)
|
||||
{
|
||||
|
|
|
@ -104,6 +104,8 @@ public:
|
|||
|
||||
// Inherit OriginAttributes from Necko.
|
||||
void InheritFromNecko(const NeckoOriginAttributes& aAttrs);
|
||||
|
||||
void StripUserContextIdAndFirstPartyDomain();
|
||||
};
|
||||
|
||||
// For OriginAttributes stored on docshells / loadcontexts / browsing contexts.
|
||||
|
@ -314,6 +316,8 @@ public:
|
|||
|
||||
virtual PrincipalKind Kind() = 0;
|
||||
|
||||
already_AddRefed<BasePrincipal> CloneStrippingUserContextIdAndFirstPartyDomain();
|
||||
|
||||
protected:
|
||||
virtual ~BasePrincipal();
|
||||
|
||||
|
|
|
@ -147,14 +147,15 @@ GetPrincipalDomainOrigin(nsIPrincipal* aPrincipal,
|
|||
return GetOriginFromURI(uri, aOrigin);
|
||||
}
|
||||
|
||||
inline void SetPendingException(JSContext *cx, const char *aMsg)
|
||||
inline void SetPendingExceptionASCII(JSContext *cx, const char *aMsg)
|
||||
{
|
||||
JS_ReportError(cx, "%s", aMsg);
|
||||
JS_ReportErrorASCII(cx, "%s", aMsg);
|
||||
}
|
||||
|
||||
inline void SetPendingException(JSContext *cx, const char16_t *aMsg)
|
||||
{
|
||||
JS_ReportError(cx, "%hs", aMsg);
|
||||
// FIXME: Need to convert to UTF-8 (bug XXX).
|
||||
JS_ReportErrorLatin1(cx, "%hs", aMsg);
|
||||
}
|
||||
|
||||
// Helper class to get stuff from the ClassInfo and not waste extra time with
|
||||
|
@ -596,7 +597,7 @@ nsScriptSecurityManager::CheckLoadURIFromScript(JSContext *cx, nsIURI *aURI)
|
|||
nsAutoCString msg("Access to '");
|
||||
msg.Append(spec);
|
||||
msg.AppendLiteral("' from script denied");
|
||||
SetPendingException(cx, msg.get());
|
||||
SetPendingExceptionASCII(cx, msg.get());
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
|
@ -1305,7 +1306,7 @@ nsScriptSecurityManager::CanCreateInstance(JSContext *cx,
|
|||
char cidStr[NSID_LENGTH];
|
||||
aCID.ToProvidedString(cidStr);
|
||||
errorMsg.Append(cidStr);
|
||||
SetPendingException(cx, errorMsg.get());
|
||||
SetPendingExceptionASCII(cx, errorMsg.get());
|
||||
return NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
|
@ -1322,7 +1323,7 @@ nsScriptSecurityManager::CanGetService(JSContext *cx,
|
|||
char cidStr[NSID_LENGTH];
|
||||
aCID.ToProvidedString(cidStr);
|
||||
errorMsg.Append(cidStr);
|
||||
SetPendingException(cx, errorMsg.get());
|
||||
SetPendingExceptionASCII(cx, errorMsg.get());
|
||||
return NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
LIB_IS_C_ONLY = 1
|
|
@ -13,11 +13,14 @@ var gTab, gPanel, gDebugger;
|
|||
var gPrefs, gOptions;
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: TAB_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
Task.spawn(function* () {
|
||||
let options = {
|
||||
source: TAB_URL,
|
||||
line: 1
|
||||
};
|
||||
|
||||
let [aTab,, aPanel] = yield initDebugger(TAB_URL, options);
|
||||
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
|
@ -28,7 +31,7 @@ function test() {
|
|||
|
||||
gDebugger.DebuggerView.toggleInstrumentsPane({ visible: true, animated: false });
|
||||
|
||||
testInstrumentsPaneCollapse();
|
||||
yield testInstrumentsPaneCollapse();
|
||||
testPanesStartupPref();
|
||||
|
||||
closeDebuggerAndFinish(gPanel);
|
||||
|
@ -50,7 +53,7 @@ function testPanesState() {
|
|||
"The options menu item should not be checked.");
|
||||
}
|
||||
|
||||
function testInstrumentsPaneCollapse() {
|
||||
function* testInstrumentsPaneCollapse () {
|
||||
let instrumentsPane =
|
||||
gDebugger.document.getElementById("instruments-pane");
|
||||
let instrumentsPaneToggleButton =
|
||||
|
@ -69,8 +72,13 @@ function testInstrumentsPaneCollapse() {
|
|||
!instrumentsPaneToggleButton.classList.contains("pane-collapsed"),
|
||||
"The instruments pane should at this point be visible.");
|
||||
|
||||
// Trigger reflow to make sure the UI is in required state.
|
||||
gDebugger.document.documentElement.getBoundingClientRect();
|
||||
|
||||
gDebugger.DebuggerView.toggleInstrumentsPane({ visible: false, animated: true });
|
||||
|
||||
yield once(instrumentsPane, "transitionend");
|
||||
|
||||
is(gPrefs.panesVisibleOnStartup, false,
|
||||
"The debugger view panes should still initially be preffed as hidden.");
|
||||
isnot(gOptions._showPanesOnStartupItem.getAttribute("checked"), "true",
|
||||
|
@ -83,7 +91,8 @@ function testInstrumentsPaneCollapse() {
|
|||
"The instruments pane has an incorrect left margin after collapsing.");
|
||||
is(instrumentsPane.style.marginRight, margin,
|
||||
"The instruments pane has an incorrect right margin after collapsing.");
|
||||
ok(instrumentsPane.hasAttribute("animated"),
|
||||
|
||||
ok(!instrumentsPane.hasAttribute("animated"),
|
||||
"The instruments pane has an incorrect attribute after an animated collapsing.");
|
||||
ok(instrumentsPane.classList.contains("pane-collapsed") &&
|
||||
instrumentsPaneToggleButton.classList.contains("pane-collapsed"),
|
||||
|
|
|
@ -335,6 +335,7 @@ Toolbox.prototype = {
|
|||
get splitConsole() {
|
||||
return this._splitConsole;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the focused state of the split console
|
||||
*/
|
||||
|
@ -1267,6 +1268,16 @@ Toolbox.prototype = {
|
|||
// backward compatibility with existing extensions do a check
|
||||
// for a promise return value.
|
||||
let built = definition.build(iframe.contentWindow, this);
|
||||
|
||||
// Set the dir attribute on the documents of panels using HTML.
|
||||
let docEl = iframe.contentWindow && iframe.contentWindow.document.documentElement;
|
||||
if (docEl && docEl.namespaceURI === HTML_NS) {
|
||||
let top = this.win.top;
|
||||
let topDocEl = top.document.documentElement;
|
||||
let isRtl = top.getComputedStyle(topDocEl).direction === "rtl";
|
||||
docEl.setAttribute("dir", isRtl ? "rtl" : "ltr");
|
||||
}
|
||||
|
||||
if (!(typeof built.then == "function")) {
|
||||
let panel = built;
|
||||
iframe.panel = panel;
|
||||
|
|
|
@ -430,8 +430,6 @@ MarkupView.prototype = {
|
|||
/**
|
||||
* Hide the box model highlighter on a given node front
|
||||
*
|
||||
* @param {NodeFront} nodeFront
|
||||
* The node to hide the highlighter for
|
||||
* @param {Boolean} forceHide
|
||||
* See toolbox-highlighter-utils/unhighlight
|
||||
* @return {Promise} Resolves when the highlighter for this nodeFront is
|
||||
|
|
|
@ -199,6 +199,7 @@ subsuite = clipboard
|
|||
[browser_rules_selector-highlighter_01.js]
|
||||
[browser_rules_selector-highlighter_02.js]
|
||||
[browser_rules_selector-highlighter_03.js]
|
||||
[browser_rules_selector-highlighter_04.js]
|
||||
[browser_rules_selector_highlight.js]
|
||||
[browser_rules_strict-search-filter-computed-list_01.js]
|
||||
[browser_rules_strict-search-filter_01.js]
|
||||
|
|
|
@ -76,9 +76,3 @@ add_task(function* () {
|
|||
is(HighlighterFront.options.selector, "body",
|
||||
"The right selector option is passed to the highlighter (2)");
|
||||
});
|
||||
|
||||
function* clickSelectorIcon(icon, view) {
|
||||
let onToggled = view.once("ruleview-selectorhighlighter-toggled");
|
||||
EventUtils.synthesizeMouseAtCenter(icon, {}, view.styleWindow);
|
||||
yield onToggled;
|
||||
}
|
||||
|
|
|
@ -76,9 +76,3 @@ add_task(function* () {
|
|||
ok(!HighlighterFront.isShown,
|
||||
"The highlighter is hidden now that the same selector was clicked");
|
||||
});
|
||||
|
||||
function* clickSelectorIcon(icon, view) {
|
||||
let onToggled = view.once("ruleview-selectorhighlighter-toggled");
|
||||
EventUtils.synthesizeMouseAtCenter(icon, {}, view.styleWindow);
|
||||
yield onToggled;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that the selector highlighter is shown when clicking on a selector icon
|
||||
// for the 'element {}' rule
|
||||
|
||||
// Note that in this test, we mock the highlighter front, merely testing the
|
||||
// behavior of the style-inspector UI for now
|
||||
|
||||
const TEST_URI = `
|
||||
<p>Testing the selector highlighter for the 'element {}' rule</p>
|
||||
`;
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
let {inspector, view} = yield openRuleView();
|
||||
|
||||
// Mock the highlighter front to get the reference of the NodeFront
|
||||
let HighlighterFront = {
|
||||
isShown: false,
|
||||
nodeFront: null,
|
||||
options: null,
|
||||
show: function (nodeFront, options) {
|
||||
this.nodeFront = nodeFront;
|
||||
this.options = options;
|
||||
this.isShown = true;
|
||||
},
|
||||
hide: function () {
|
||||
this.nodeFront = null;
|
||||
this.options = null;
|
||||
this.isShown = false;
|
||||
}
|
||||
};
|
||||
// Inject the mock highlighter in the rule-view
|
||||
view.selectorHighlighter = HighlighterFront;
|
||||
|
||||
info("Checking that the right NodeFront reference and options are passed");
|
||||
yield selectNode("p", inspector);
|
||||
let icon = getRuleViewSelectorHighlighterIcon(view, "element");
|
||||
|
||||
yield clickSelectorIcon(icon, view);
|
||||
is(HighlighterFront.nodeFront.tagName, "P",
|
||||
"The right NodeFront is passed to the highlighter (1)");
|
||||
is(HighlighterFront.options.selector, "body > p:nth-child(1)",
|
||||
"The right selector option is passed to the highlighter (1)");
|
||||
ok(HighlighterFront.isShown, "The toggle event says the highlighter is visible");
|
||||
|
||||
yield clickSelectorIcon(icon, view);
|
||||
ok(!HighlighterFront.isShown, "The toggle event says the highlighter is not visible");
|
||||
});
|
|
@ -817,6 +817,17 @@ function waitForStyleModification(inspector) {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Click on the selector icon
|
||||
* @param {DOMNode} icon
|
||||
* @param {CSSRuleView} view
|
||||
*/
|
||||
function* clickSelectorIcon(icon, view) {
|
||||
let onToggled = view.once("ruleview-selectorhighlighter-toggled");
|
||||
EventUtils.synthesizeMouseAtCenter(icon, {}, view.styleWindow);
|
||||
yield onToggled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure window is properly focused before sending a key event.
|
||||
* @param {Window} win
|
||||
|
|
|
@ -149,9 +149,10 @@ RuleEditor.prototype = {
|
|||
});
|
||||
}
|
||||
|
||||
if (this.rule.domRule.type !== CSSRule.KEYFRAME_RULE &&
|
||||
this.rule.domRule.selectors) {
|
||||
let selector = this.rule.domRule.selectors.join(", ");
|
||||
if (this.rule.domRule.type !== CSSRule.KEYFRAME_RULE) {
|
||||
let selector = this.rule.domRule.selectors
|
||||
? this.rule.domRule.selectors.join(", ")
|
||||
: this.ruleView.inspector.selectionCssSelector;
|
||||
|
||||
let selectorHighlighter = createChild(header, "span", {
|
||||
class: "ruleview-selectorhighlighter" +
|
||||
|
|
|
@ -4,9 +4,6 @@
|
|||
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"DTD/xhtml1-strict.dtd">
|
||||
%htmlDTD;
|
||||
<!ENTITY % globalDTD
|
||||
SYSTEM "chrome://global/locale/global.dtd">
|
||||
%globalDTD;
|
||||
]>
|
||||
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
|
@ -19,7 +16,7 @@
|
|||
<link rel="stylesheet" href="chrome://devtools/skin/components-frame.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="chrome://devtools/skin/components-h-split-box.css" type="text/css"/>
|
||||
</head>
|
||||
<body class="theme-body" dir="&locale.dir;">
|
||||
<body class="theme-body">
|
||||
<div id="app"></div>
|
||||
|
||||
<script type="application/javascript;version=1.8"
|
||||
|
|
|
@ -34,8 +34,13 @@ add_task(function* () {
|
|||
!detailsPaneToggleButton.classList.contains("pane-collapsed"),
|
||||
"The details pane should at this point be visible.");
|
||||
|
||||
// Trigger reflow to make sure the UI is in required state.
|
||||
document.documentElement.getBoundingClientRect();
|
||||
|
||||
NetMonitorView.toggleDetailsPane({ visible: false, animated: true });
|
||||
|
||||
yield once(detailsPane, "transitionend");
|
||||
|
||||
let margin = -(width + 1) + "px";
|
||||
is(width, Prefs.networkDetailsWidth,
|
||||
"The details pane has an incorrect width after collapsing.");
|
||||
|
@ -43,7 +48,7 @@ add_task(function* () {
|
|||
"The details pane has an incorrect left margin after collapsing.");
|
||||
is(detailsPane.style.marginRight, margin,
|
||||
"The details pane has an incorrect right margin after collapsing.");
|
||||
ok(detailsPane.hasAttribute("animated"),
|
||||
ok(!detailsPane.hasAttribute("animated"),
|
||||
"The details pane has an incorrect attribute after an animated collapsing.");
|
||||
ok(detailsPane.classList.contains("pane-collapsed") &&
|
||||
detailsPaneToggleButton.classList.contains("pane-collapsed"),
|
||||
|
|
|
@ -7,26 +7,26 @@
|
|||
display: block;
|
||||
}
|
||||
|
||||
.sidebar-toggle:-moz-locale-dir(ltr)::before,
|
||||
.sidebar-toggle.pane-collapsed:-moz-locale-dir(rtl)::before {
|
||||
.sidebar-toggle::before,
|
||||
.sidebar-toggle.pane-collapsed:dir(rtl)::before {
|
||||
background-image: var(--theme-pane-collapse-image);
|
||||
}
|
||||
|
||||
.sidebar-toggle.pane-collapsed:-moz-locale-dir(ltr)::before,
|
||||
.sidebar-toggle:-moz-locale-dir(rtl)::before {
|
||||
.sidebar-toggle.pane-collapsed::before,
|
||||
.sidebar-toggle:dir(rtl)::before {
|
||||
background-image: var(--theme-pane-expand-image);
|
||||
}
|
||||
|
||||
/* Rotate button icon 90deg if the toolbox container is
|
||||
in vertical mode (sidebar displayed under the main panel) */
|
||||
@media (max-width: 700px) {
|
||||
.sidebar-toggle:-moz-locale-dir(ltr)::before {
|
||||
.sidebar-toggle::before {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
/* Since RTL swaps the used images, we need to flip them
|
||||
the other way round */
|
||||
.sidebar-toggle:-moz-locale-dir(rtl)::before {
|
||||
.sidebar-toggle:dir(rtl)::before {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ loader.lazyRequireGetter(this, "util", "gcli/util/util");
|
|||
loader.lazyRequireGetter(this, "ConsoleServiceListener", "devtools/server/actors/utils/webconsole-utils", true);
|
||||
loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true);
|
||||
loader.lazyRequireGetter(this, "gDevToolsBrowser", "devtools/client/framework/devtools-browser", true);
|
||||
loader.lazyRequireGetter(this, "nodeConstants", "devtools/shared/dom-node-constants", true);
|
||||
loader.lazyRequireGetter(this, "nodeConstants", "devtools/shared/dom-node-constants");
|
||||
loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
|
||||
|
||||
/**
|
||||
|
|
|
@ -252,6 +252,11 @@ const ViewHelpers = exports.ViewHelpers = {
|
|||
// Add a class to the pane to handle min-widths, margins and animations.
|
||||
pane.classList.add("generic-toggled-pane");
|
||||
|
||||
// Avoid toggles in the middle of animation.
|
||||
if (pane.hasAttribute("animated")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Avoid useless toggles.
|
||||
if (flags.visible == !pane.classList.contains("pane-collapsed")) {
|
||||
if (flags.callback) {
|
||||
|
@ -283,23 +288,36 @@ const ViewHelpers = exports.ViewHelpers = {
|
|||
pane.style.marginLeft = -width + "px";
|
||||
pane.style.marginRight = -width + "px";
|
||||
pane.style.marginBottom = -height + "px";
|
||||
pane.classList.add("pane-collapsed");
|
||||
}
|
||||
|
||||
// Wait for the animation to end before calling afterToggle()
|
||||
if (flags.animated) {
|
||||
pane.addEventListener("transitionend", function onEvent() {
|
||||
pane.removeEventListener("transitionend", onEvent, false);
|
||||
let options = {
|
||||
useCapture: false,
|
||||
once: true
|
||||
};
|
||||
|
||||
pane.addEventListener("transitionend", () => {
|
||||
// Prevent unwanted transitions: if the panel is hidden and the layout
|
||||
// changes margins will be updated and the panel will pop out.
|
||||
pane.removeAttribute("animated");
|
||||
|
||||
if (!flags.visible) {
|
||||
pane.classList.add("pane-collapsed");
|
||||
}
|
||||
if (flags.callback) {
|
||||
flags.callback();
|
||||
}
|
||||
}, false);
|
||||
} else if (flags.callback) {
|
||||
}, options);
|
||||
} else {
|
||||
if (!flags.visible) {
|
||||
pane.classList.add("pane-collapsed");
|
||||
}
|
||||
|
||||
// Invoke the callback immediately since there's no transition.
|
||||
flags.callback();
|
||||
if (flags.callback) {
|
||||
flags.callback();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -325,7 +325,7 @@
|
|||
display: inline-block;
|
||||
}
|
||||
|
||||
.ruleview-expander.theme-twisty:-moz-locale-dir(rtl) {
|
||||
.ruleview-expander.theme-twisty:dir(rtl) {
|
||||
/* for preventing .theme-twisty's wrong direction in rtl; Bug 1296648 */
|
||||
transform: none;
|
||||
}
|
||||
|
|
|
@ -282,23 +282,23 @@
|
|||
/* RTL support: move the images that were on the left to the right,
|
||||
* and move images that were on the right to the left.
|
||||
*/
|
||||
.breadcrumbs-widget-item:-moz-locale-dir(rtl) {
|
||||
.breadcrumbs-widget-item:dir(rtl) {
|
||||
padding: 0 20px 0 8px;
|
||||
}
|
||||
|
||||
.breadcrumbs-widget-item:-moz-locale-dir(rtl),
|
||||
.breadcrumbs-widget-item[checked] + .breadcrumbs-widget-item:-moz-locale-dir(rtl) {
|
||||
.breadcrumbs-widget-item:dir(rtl),
|
||||
.breadcrumbs-widget-item[checked] + .breadcrumbs-widget-item:dir(rtl) {
|
||||
background-position: center right;
|
||||
}
|
||||
|
||||
#breadcrumb-separator-before:-moz-locale-dir(rtl),
|
||||
#breadcrumb-separator-after:-moz-locale-dir(rtl),
|
||||
#breadcrumb-separator-normal:-moz-locale-dir(rtl) {
|
||||
#breadcrumb-separator-before:dir(rtl),
|
||||
#breadcrumb-separator-after:dir(rtl),
|
||||
#breadcrumb-separator-normal:dir(rtl) {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
|
||||
#breadcrumb-separator-before:-moz-locale-dir(rtl):after,
|
||||
#breadcrumb-separator-after:-moz-locale-dir(rtl):after {
|
||||
#breadcrumb-separator-before:dir(rtl):after,
|
||||
#breadcrumb-separator-after:dir(rtl):after {
|
||||
transform: translateX(-5px) rotate(45deg);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ const TEST_CASES = [
|
|||
},
|
||||
{
|
||||
input: '(new DOMParser()).parseFromString("<svg></svg>", "image/svg+xml")',
|
||||
output: "SVGDocument",
|
||||
output: "XMLDocument",
|
||||
inspectable: true,
|
||||
},
|
||||
];
|
||||
|
|
|
@ -626,14 +626,20 @@ let SourceActor = ActorClassWithSpec(sourceSpec, {
|
|||
/**
|
||||
* Handle a request to set a breakpoint.
|
||||
*
|
||||
* @param JSON request
|
||||
* A JSON object representing the request.
|
||||
* @param Number line
|
||||
* Line to break on.
|
||||
* @param Number column
|
||||
* Column to break on.
|
||||
* @param String condition
|
||||
* A condition which must be true for breakpoint to be hit.
|
||||
* @param Boolean noSliding
|
||||
* If true, disables breakpoint sliding.
|
||||
*
|
||||
* @returns Promise
|
||||
* A promise that resolves to a JSON object representing the
|
||||
* response.
|
||||
*/
|
||||
setBreakpoint: function (line, column, condition) {
|
||||
setBreakpoint: function (line, column, condition, noSliding) {
|
||||
if (this.threadActor.state !== "paused") {
|
||||
throw {
|
||||
error: "wrongState",
|
||||
|
@ -644,7 +650,8 @@ let SourceActor = ActorClassWithSpec(sourceSpec, {
|
|||
let location = new OriginalLocation(this, line, column);
|
||||
return this._getOrCreateBreakpointActor(
|
||||
location,
|
||||
condition
|
||||
condition,
|
||||
noSliding
|
||||
).then((actor) => {
|
||||
let response = {
|
||||
actor: actor.actorID,
|
||||
|
@ -671,11 +678,13 @@ let SourceActor = ActorClassWithSpec(sourceSpec, {
|
|||
* @param String condition
|
||||
* A string that is evaluated whenever the breakpoint is hit. If the
|
||||
* string evaluates to false, the breakpoint is ignored.
|
||||
* @param Boolean noSliding
|
||||
* If true, disables breakpoint sliding.
|
||||
*
|
||||
* @returns BreakpointActor
|
||||
* A BreakpointActor representing the breakpoint.
|
||||
*/
|
||||
_getOrCreateBreakpointActor: function (originalLocation, condition) {
|
||||
_getOrCreateBreakpointActor: function (originalLocation, condition, noSliding) {
|
||||
let actor = this.breakpointActorMap.getActor(originalLocation);
|
||||
if (!actor) {
|
||||
actor = new BreakpointActor(this.threadActor, originalLocation);
|
||||
|
@ -685,7 +694,7 @@ let SourceActor = ActorClassWithSpec(sourceSpec, {
|
|||
|
||||
actor.condition = condition;
|
||||
|
||||
return this._setBreakpoint(actor);
|
||||
return this._setBreakpoint(actor, noSliding);
|
||||
},
|
||||
|
||||
/*
|
||||
|
@ -705,18 +714,19 @@ let SourceActor = ActorClassWithSpec(sourceSpec, {
|
|||
*
|
||||
* @param BreakpointActor actor
|
||||
* The BreakpointActor to be set as a breakpoint handler.
|
||||
* @param Boolean noSliding
|
||||
* If true, disables breakpoint sliding.
|
||||
*
|
||||
* @returns A Promise that resolves to the given BreakpointActor.
|
||||
*/
|
||||
_setBreakpoint: function (actor) {
|
||||
_setBreakpoint: function (actor, noSliding) {
|
||||
const { originalLocation } = actor;
|
||||
const { originalLine, originalSourceActor } = originalLocation;
|
||||
|
||||
if (!this.isSourceMapped) {
|
||||
if (!this._setBreakpointAtGeneratedLocation(
|
||||
actor,
|
||||
GeneratedLocation.fromOriginalLocation(originalLocation)
|
||||
)) {
|
||||
const generatedLocation = GeneratedLocation.fromOriginalLocation(originalLocation);
|
||||
if (!this._setBreakpointAtGeneratedLocation(actor, generatedLocation) &&
|
||||
!noSliding) {
|
||||
const query = { line: originalLine };
|
||||
// For most cases, we have a real source to query for. The
|
||||
// only time we don't is for HTML pages. In that case we want
|
||||
|
|
|
@ -36,40 +36,52 @@ function run_test_with_server(aServer, aCallback)
|
|||
});
|
||||
}
|
||||
|
||||
function test_skip_breakpoint()
|
||||
{
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
var test_no_skip_breakpoint = Task.async(function*(source, location) {
|
||||
let [aResponse, bpClient] = yield source.setBreakpoint(
|
||||
Object.assign({}, location, { noSliding: true })
|
||||
);
|
||||
|
||||
do_check_true(!aResponse.actualLocation);
|
||||
do_check_eq(bpClient.location.line, gDebuggee.line0 + 3);
|
||||
yield bpClient.remove();
|
||||
});
|
||||
|
||||
var test_skip_breakpoint = function() {
|
||||
gThreadClient.addOneTimeListener("paused", Task.async(function *(aEvent, aPacket) {
|
||||
let location = { line: gDebuggee.line0 + 3 };
|
||||
let source = gThreadClient.source(aPacket.frame.where.source);
|
||||
|
||||
source.setBreakpoint(location, function (aResponse, bpClient) {
|
||||
// Check that the breakpoint has properly skipped forward one line.
|
||||
do_check_true(!!aResponse.actualLocation);
|
||||
do_check_eq(aResponse.actualLocation.source.actor, source.actor);
|
||||
do_check_eq(aResponse.actualLocation.line, location.line + 1);
|
||||
// First, make sure that we can disable sliding with the
|
||||
// `noSliding` option.
|
||||
yield test_no_skip_breakpoint(source, location);
|
||||
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
// Check the return value.
|
||||
do_check_eq(aPacket.type, "paused");
|
||||
do_check_eq(aPacket.frame.where.source.actor, source.actor);
|
||||
do_check_eq(aPacket.frame.where.line, location.line + 1);
|
||||
do_check_eq(aPacket.why.type, "breakpoint");
|
||||
do_check_eq(aPacket.why.actors[0], bpClient.actor);
|
||||
// Check that the breakpoint worked.
|
||||
do_check_eq(gDebuggee.a, 1);
|
||||
do_check_eq(gDebuggee.b, undefined);
|
||||
// Now make sure that the breakpoint properly slides forward one line.
|
||||
const [aResponse, bpClient] = yield source.setBreakpoint(location);
|
||||
do_check_true(!!aResponse.actualLocation);
|
||||
do_check_eq(aResponse.actualLocation.source.actor, source.actor);
|
||||
do_check_eq(aResponse.actualLocation.line, location.line + 1);
|
||||
|
||||
// Remove the breakpoint.
|
||||
bpClient.remove(function (aResponse) {
|
||||
gThreadClient.resume(function () {
|
||||
gClient.close().then(gCallback);
|
||||
});
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
// Check the return value.
|
||||
do_check_eq(aPacket.type, "paused");
|
||||
do_check_eq(aPacket.frame.where.source.actor, source.actor);
|
||||
do_check_eq(aPacket.frame.where.line, location.line + 1);
|
||||
do_check_eq(aPacket.why.type, "breakpoint");
|
||||
do_check_eq(aPacket.why.actors[0], bpClient.actor);
|
||||
// Check that the breakpoint worked.
|
||||
do_check_eq(gDebuggee.a, 1);
|
||||
do_check_eq(gDebuggee.b, undefined);
|
||||
|
||||
// Remove the breakpoint.
|
||||
bpClient.remove(function (aResponse) {
|
||||
gThreadClient.resume(function () {
|
||||
gClient.close().then(gCallback);
|
||||
});
|
||||
});
|
||||
|
||||
gThreadClient.resume();
|
||||
});
|
||||
});
|
||||
|
||||
gThreadClient.resume();
|
||||
}));
|
||||
|
||||
// Use `evalInSandbox` to make the debugger treat it as normal
|
||||
// globally-scoped code, where breakpoint sliding rules apply.
|
||||
|
|
|
@ -2893,7 +2893,7 @@ SourceClient.prototype = {
|
|||
* @param function aOnResponse
|
||||
* Called with the thread's response.
|
||||
*/
|
||||
setBreakpoint: function ({ line, column, condition }, aOnResponse = noop) {
|
||||
setBreakpoint: function ({ line, column, condition, noSliding }, aOnResponse = noop) {
|
||||
// A helper function that sets the breakpoint.
|
||||
let doSetBreakpoint = aCallback => {
|
||||
let root = this._client.mainRoot;
|
||||
|
@ -2906,7 +2906,8 @@ SourceClient.prototype = {
|
|||
to: this.actor,
|
||||
type: "setBreakpoint",
|
||||
location: location,
|
||||
condition: condition
|
||||
condition: condition,
|
||||
noSliding: noSliding
|
||||
};
|
||||
|
||||
// Backwards compatibility: send the breakpoint request to the
|
||||
|
|
|
@ -29,7 +29,8 @@ const sourceSpec = generateActorSpec({
|
|||
line: Arg(0, "number"),
|
||||
column: Arg(1, "nullable:number")
|
||||
},
|
||||
condition: Arg(2, "nullable:string")
|
||||
condition: Arg(2, "nullable:string"),
|
||||
noSliding: Arg(3, "nullable:boolean")
|
||||
},
|
||||
response: RetVal("json")
|
||||
},
|
||||
|
|
|
@ -118,7 +118,7 @@ test(function(t) {
|
|||
}, 'After cancelling a transition, updating transition properties doesn\'t make'
|
||||
+ ' it live again');
|
||||
|
||||
test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, { style: 'margin-left: 0px' });
|
||||
flushComputedStyle(div);
|
||||
|
||||
|
@ -127,11 +127,39 @@ test(function(t) {
|
|||
flushComputedStyle(div);
|
||||
|
||||
var animation = div.getAnimations()[0];
|
||||
div.style.display = 'none';
|
||||
assert_equals(animation.playState, 'idle');
|
||||
assert_equals(getComputedStyle(div).marginLeft, '1000px');
|
||||
return animation.ready.then(function() {
|
||||
assert_equals(animation.playState, 'running');
|
||||
div.style.display = 'none';
|
||||
return waitForFrame();
|
||||
}).then(function() {
|
||||
assert_equals(animation.playState, 'idle');
|
||||
assert_equals(getComputedStyle(div).marginLeft, '1000px');
|
||||
});
|
||||
}, 'Setting display:none on an element cancels its transitions');
|
||||
|
||||
promise_test(function(t) {
|
||||
var parentDiv = addDiv(t);
|
||||
var childDiv = document.createElement('div');
|
||||
parentDiv.appendChild(childDiv);
|
||||
childDiv.setAttribute('style', 'margin-left: 0px');
|
||||
|
||||
flushComputedStyle(childDiv);
|
||||
|
||||
childDiv.style.transition = 'margin-left 100s';
|
||||
childDiv.style.marginLeft = '1000px';
|
||||
flushComputedStyle(childDiv);
|
||||
|
||||
var animation = childDiv.getAnimations()[0];
|
||||
return animation.ready.then(function() {
|
||||
assert_equals(animation.playState, 'running');
|
||||
parentDiv.style.display = 'none';
|
||||
return waitForFrame();
|
||||
}).then(function() {
|
||||
assert_equals(animation.playState, 'idle');
|
||||
assert_equals(getComputedStyle(childDiv).marginLeft, '1000px');
|
||||
});
|
||||
}, 'Setting display:none cancels transitions on a child element');
|
||||
|
||||
done();
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -12,24 +12,6 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
already_AddRefed<Blob>
|
||||
BlobSet::GetBlobInternal(nsISupports* aParent,
|
||||
const nsACString& aContentType,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsTArray<RefPtr<BlobImpl>> subImpls(GetBlobImpls());
|
||||
RefPtr<BlobImpl> blobImpl =
|
||||
MultipartBlobImpl::Create(Move(subImpls),
|
||||
NS_ConvertASCIItoUTF16(aContentType),
|
||||
aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<Blob> blob = Blob::Create(aParent, blobImpl);
|
||||
return blob.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
BlobSet::AppendVoidPtr(const void* aData, uint32_t aLength)
|
||||
{
|
||||
|
@ -38,13 +20,16 @@ BlobSet::AppendVoidPtr(const void* aData, uint32_t aLength)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
uint64_t offset = mDataLen;
|
||||
|
||||
if (!ExpandBufferSize(aLength)) {
|
||||
void* data = malloc(aLength);
|
||||
if (!data) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
memcpy((char*)mData + offset, aData, aLength);
|
||||
memcpy((char*)data, aData, aLength);
|
||||
|
||||
RefPtr<BlobImpl> blobImpl = new BlobImplMemory(data, aLength, EmptyString());
|
||||
mBlobImpls.AppendElement(blobImpl);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -71,69 +56,9 @@ nsresult
|
|||
BlobSet::AppendBlobImpl(BlobImpl* aBlobImpl)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aBlobImpl);
|
||||
|
||||
Flush();
|
||||
mBlobImpls.AppendElement(aBlobImpl);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
BlobSet::AppendBlobImpls(const nsTArray<RefPtr<BlobImpl>>& aBlobImpls)
|
||||
{
|
||||
Flush();
|
||||
mBlobImpls.AppendElements(aBlobImpls);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
BlobSet::ExpandBufferSize(uint64_t aSize)
|
||||
{
|
||||
if (mDataBufferLen >= mDataLen + aSize) {
|
||||
mDataLen += aSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Start at 1 or we'll loop forever.
|
||||
CheckedUint32 bufferLen =
|
||||
std::max<uint32_t>(static_cast<uint32_t>(mDataBufferLen), 1);
|
||||
while (bufferLen.isValid() && bufferLen.value() < mDataLen + aSize) {
|
||||
bufferLen *= 2;
|
||||
}
|
||||
|
||||
if (!bufferLen.isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void* data = realloc(mData, bufferLen.value());
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mData = data;
|
||||
mDataBufferLen = bufferLen.value();
|
||||
mDataLen += aSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
BlobSet::Flush()
|
||||
{
|
||||
if (mData) {
|
||||
// If we have some data, create a blob for it
|
||||
// and put it on the stack
|
||||
|
||||
RefPtr<BlobImpl> blobImpl =
|
||||
new BlobImplMemory(mData, mDataLen, EmptyString());
|
||||
mBlobImpls.AppendElement(blobImpl);
|
||||
|
||||
mData = nullptr; // The nsDOMMemoryFile takes ownership of the buffer
|
||||
mDataLen = 0;
|
||||
mDataBufferLen = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} // dom namespace
|
||||
} // mozilla namespace
|
||||
|
|
|
@ -12,23 +12,11 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class Blob;
|
||||
class BlobImpl;
|
||||
|
||||
class BlobSet final
|
||||
{
|
||||
public:
|
||||
BlobSet()
|
||||
: mData(nullptr)
|
||||
, mDataLen(0)
|
||||
, mDataBufferLen(0)
|
||||
{}
|
||||
|
||||
~BlobSet()
|
||||
{
|
||||
free(mData);
|
||||
}
|
||||
|
||||
nsresult AppendVoidPtr(const void* aData, uint32_t aLength);
|
||||
|
||||
nsresult AppendString(const nsAString& aString, bool nativeEOL,
|
||||
|
@ -36,23 +24,10 @@ public:
|
|||
|
||||
nsresult AppendBlobImpl(BlobImpl* aBlobImpl);
|
||||
|
||||
nsresult AppendBlobImpls(const nsTArray<RefPtr<BlobImpl>>& aBlobImpls);
|
||||
|
||||
nsTArray<RefPtr<BlobImpl>>& GetBlobImpls() { Flush(); return mBlobImpls; }
|
||||
|
||||
already_AddRefed<Blob> GetBlobInternal(nsISupports* aParent,
|
||||
const nsACString& aContentType,
|
||||
ErrorResult& aRv);
|
||||
nsTArray<RefPtr<BlobImpl>>& GetBlobImpls() { return mBlobImpls; }
|
||||
|
||||
private:
|
||||
bool ExpandBufferSize(uint64_t aSize);
|
||||
|
||||
void Flush();
|
||||
|
||||
nsTArray<RefPtr<BlobImpl>> mBlobImpls;
|
||||
void* mData;
|
||||
uint64_t mDataLen;
|
||||
uint64_t mDataBufferLen;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -910,8 +910,10 @@ Location::GetSourceBaseURL(JSContext* cx, nsIURI** sourceURL)
|
|||
}
|
||||
|
||||
bool
|
||||
Location::CallerSubsumes()
|
||||
Location::CallerSubsumes(nsIPrincipal* aSubjectPrincipal)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal);
|
||||
|
||||
// Get the principal associated with the location object. Note that this is
|
||||
// the principal of the page which will actually be navigated, not the
|
||||
// principal of the Location object itself. This is why we need this check
|
||||
|
@ -923,7 +925,8 @@ Location::CallerSubsumes()
|
|||
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(outer);
|
||||
bool subsumes = false;
|
||||
nsresult rv =
|
||||
nsContentUtils::SubjectPrincipal()->SubsumesConsideringDomain(sop->GetPrincipal(), &subsumes);
|
||||
aSubjectPrincipal->SubsumesConsideringDomain(sop->GetPrincipal(),
|
||||
&subsumes);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
return subsumes;
|
||||
}
|
||||
|
|
|
@ -44,119 +44,180 @@ public:
|
|||
NS_DECL_NSIDOMLOCATION
|
||||
|
||||
#define THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME() { \
|
||||
if (!CallerSubsumes()) { \
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome()); \
|
||||
if (!CallerSubsumes(aSubjectPrincipal.value())) { \
|
||||
aError.Throw(NS_ERROR_DOM_SECURITY_ERR); \
|
||||
return; \
|
||||
} \
|
||||
}
|
||||
|
||||
// WebIDL API:
|
||||
void Assign(const nsAString& aUrl, ErrorResult& aError)
|
||||
void Assign(const nsAString& aUrl,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
aError = Assign(aUrl);
|
||||
}
|
||||
|
||||
void Replace(const nsAString& aUrl, ErrorResult& aError)
|
||||
void Replace(const nsAString& aUrl,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
aError = Replace(aUrl);
|
||||
}
|
||||
|
||||
void Reload(bool aForceget, ErrorResult& aError)
|
||||
void Reload(bool aForceget,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
aError = Reload(aForceget);
|
||||
}
|
||||
void GetHref(nsAString& aHref, ErrorResult& aError)
|
||||
|
||||
void GetHref(nsAString& aHref,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
aError = GetHref(aHref);
|
||||
}
|
||||
void SetHref(const nsAString& aHref, ErrorResult& aError)
|
||||
|
||||
void SetHref(const nsAString& aHref,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
aError = SetHref(aHref);
|
||||
}
|
||||
void GetOrigin(nsAString& aOrigin, ErrorResult& aError)
|
||||
|
||||
void GetOrigin(nsAString& aOrigin,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
aError = GetOrigin(aOrigin);
|
||||
}
|
||||
void GetProtocol(nsAString& aProtocol, ErrorResult& aError)
|
||||
|
||||
void GetProtocol(nsAString& aProtocol,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
aError = GetProtocol(aProtocol);
|
||||
}
|
||||
void SetProtocol(const nsAString& aProtocol, ErrorResult& aError)
|
||||
|
||||
void SetProtocol(const nsAString& aProtocol,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
aError = SetProtocol(aProtocol);
|
||||
}
|
||||
void GetHost(nsAString& aHost, ErrorResult& aError)
|
||||
|
||||
void GetHost(nsAString& aHost,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
aError = GetHost(aHost);
|
||||
}
|
||||
void SetHost(const nsAString& aHost, ErrorResult& aError)
|
||||
|
||||
void SetHost(const nsAString& aHost,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
aError = SetHost(aHost);
|
||||
}
|
||||
void GetHostname(nsAString& aHostname, ErrorResult& aError)
|
||||
|
||||
void GetHostname(nsAString& aHostname,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
aError = GetHostname(aHostname);
|
||||
}
|
||||
void SetHostname(const nsAString& aHostname, ErrorResult& aError)
|
||||
|
||||
void SetHostname(const nsAString& aHostname,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
aError = SetHostname(aHostname);
|
||||
}
|
||||
void GetPort(nsAString& aPort, ErrorResult& aError)
|
||||
|
||||
void GetPort(nsAString& aPort,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
aError = GetPort(aPort);
|
||||
}
|
||||
void SetPort(const nsAString& aPort, ErrorResult& aError)
|
||||
|
||||
void SetPort(const nsAString& aPort,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
aError = SetPort(aPort);
|
||||
}
|
||||
void GetPathname(nsAString& aPathname, ErrorResult& aError)
|
||||
|
||||
void GetPathname(nsAString& aPathname,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
aError = GetPathname(aPathname);
|
||||
}
|
||||
void SetPathname(const nsAString& aPathname, ErrorResult& aError)
|
||||
|
||||
void SetPathname(const nsAString& aPathname,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
aError = SetPathname(aPathname);
|
||||
}
|
||||
void GetSearch(nsAString& aSeach, ErrorResult& aError)
|
||||
|
||||
void GetSearch(nsAString& aSeach,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
aError = GetSearch(aSeach);
|
||||
}
|
||||
void SetSearch(const nsAString& aSeach, ErrorResult& aError)
|
||||
|
||||
void SetSearch(const nsAString& aSeach,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
aError = SetSearch(aSeach);
|
||||
}
|
||||
|
||||
void GetHash(nsAString& aHash, ErrorResult& aError)
|
||||
void GetHash(nsAString& aHash,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
aError = GetHash(aHash);
|
||||
}
|
||||
void SetHash(const nsAString& aHash, ErrorResult& aError)
|
||||
|
||||
void SetHash(const nsAString& aHash,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
aError = SetHash(aHash);
|
||||
}
|
||||
void Stringify(nsAString& aRetval, ErrorResult& aError)
|
||||
|
||||
void Stringify(nsAString& aRetval,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
// GetHref checks CallerSubsumes.
|
||||
GetHref(aRetval, aError);
|
||||
GetHref(aRetval, aSubjectPrincipal, aError);
|
||||
}
|
||||
|
||||
nsPIDOMWindowInner* GetParentObject() const
|
||||
{
|
||||
return mInnerWindow;
|
||||
|
@ -185,7 +246,7 @@ protected:
|
|||
|
||||
nsresult GetSourceBaseURL(JSContext* cx, nsIURI** sourceURL);
|
||||
nsresult CheckURL(nsIURI *url, nsIDocShellLoadInfo** aLoadInfo);
|
||||
bool CallerSubsumes();
|
||||
bool CallerSubsumes(nsIPrincipal* aSubjectPrincipal);
|
||||
|
||||
nsString mCachedHash;
|
||||
nsCOMPtr<nsPIDOMWindowInner> mInnerWindow;
|
||||
|
|
|
@ -0,0 +1,617 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/MutableBlobStorage.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "nsAnonymousTemporaryFile.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "WorkerPrivate.h"
|
||||
|
||||
#define BLOB_MEMORY_TEMPORARY_FILE 1048576
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
namespace {
|
||||
|
||||
// This class uses the callback to inform when the Blob is created or when the
|
||||
// error must be propagated.
|
||||
class BlobCreationDoneRunnable final : public Runnable
|
||||
{
|
||||
public:
|
||||
BlobCreationDoneRunnable(MutableBlobStorage* aBlobStorage,
|
||||
MutableBlobStorageCallback* aCallback,
|
||||
Blob* aBlob,
|
||||
nsresult aRv)
|
||||
: mBlobStorage(aBlobStorage)
|
||||
, mCallback(aCallback)
|
||||
, mBlob(aBlob)
|
||||
, mRv(aRv)
|
||||
{
|
||||
MOZ_ASSERT(aBlobStorage);
|
||||
MOZ_ASSERT(aCallback);
|
||||
MOZ_ASSERT((NS_FAILED(aRv) && !aBlob) ||
|
||||
(NS_SUCCEEDED(aRv) && aBlob));
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mCallback->BlobStoreCompleted(mBlobStorage, mBlob, mRv);
|
||||
mCallback = nullptr;
|
||||
mBlob = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
~BlobCreationDoneRunnable()
|
||||
{
|
||||
// If something when wrong, we still have to release these objects in the
|
||||
// correct thread.
|
||||
NS_ReleaseOnMainThread(mCallback.forget());
|
||||
NS_ReleaseOnMainThread(mBlob.forget());
|
||||
}
|
||||
|
||||
RefPtr<MutableBlobStorage> mBlobStorage;
|
||||
RefPtr<MutableBlobStorageCallback> mCallback;
|
||||
RefPtr<Blob> mBlob;
|
||||
nsresult mRv;
|
||||
};
|
||||
|
||||
// This runnable goes back to the main-thread and informs the BlobStorage about
|
||||
// the temporary file.
|
||||
class FileCreatedRunnable final : public Runnable
|
||||
{
|
||||
public:
|
||||
FileCreatedRunnable(MutableBlobStorage* aBlobStorage, PRFileDesc* aFD)
|
||||
: mBlobStorage(aBlobStorage)
|
||||
, mFD(aFD)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aBlobStorage);
|
||||
MOZ_ASSERT(aFD);
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mBlobStorage->TemporaryFileCreated(mFD);
|
||||
mFD = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
~FileCreatedRunnable()
|
||||
{
|
||||
// If something when wrong, we still have to close the FileDescriptor.
|
||||
if (mFD) {
|
||||
PR_Close(mFD);
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<MutableBlobStorage> mBlobStorage;
|
||||
PRFileDesc* mFD;
|
||||
};
|
||||
|
||||
// This runnable creates the temporary file. When done, FileCreatedRunnable is
|
||||
// dispatched back to the main-thread.
|
||||
class CreateTemporaryFileRunnable final : public Runnable
|
||||
{
|
||||
public:
|
||||
explicit CreateTemporaryFileRunnable(MutableBlobStorage* aBlobStorage)
|
||||
: mBlobStorage(aBlobStorage)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aBlobStorage);
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
PRFileDesc* tempFD = nullptr;
|
||||
nsresult rv = NS_OpenAnonymousTemporaryFile(&tempFD);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
// In sandboxed context we are not allowed to create temporary files, but
|
||||
// this doesn't mean that BlobStorage should fail. We can continue to
|
||||
// store data in memory. We don't change the storageType so that we don't
|
||||
// try to create a temporary file again.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// The ownership of the tempFD is moved to the FileCreatedRunnable.
|
||||
return NS_DispatchToMainThread(new FileCreatedRunnable(mBlobStorage, tempFD));
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<MutableBlobStorage> mBlobStorage;
|
||||
};
|
||||
|
||||
// Simple runnable to propagate the error to the BlobStorage.
|
||||
class ErrorPropagationRunnable final : public Runnable
|
||||
{
|
||||
public:
|
||||
ErrorPropagationRunnable(MutableBlobStorage* aBlobStorage, nsresult aRv)
|
||||
: mBlobStorage(aBlobStorage)
|
||||
, mRv(aRv)
|
||||
{}
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
mBlobStorage->ErrorPropagated(mRv);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<MutableBlobStorage> mBlobStorage;
|
||||
nsresult mRv;
|
||||
};
|
||||
|
||||
// This runnable moves a buffer to the IO thread and there, it writes it into
|
||||
// the temporary file.
|
||||
class WriteRunnable final : public Runnable
|
||||
{
|
||||
public:
|
||||
static WriteRunnable*
|
||||
CopyBuffer(MutableBlobStorage* aBlobStorage, PRFileDesc* aFD,
|
||||
const void* aData, uint32_t aLength)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aBlobStorage);
|
||||
MOZ_ASSERT(aFD);
|
||||
MOZ_ASSERT(aData);
|
||||
|
||||
// We have to take a copy of this buffer.
|
||||
void* data = malloc(aLength);
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
memcpy((char*)data, aData, aLength);
|
||||
return new WriteRunnable(aBlobStorage, aFD, data, aLength);
|
||||
}
|
||||
|
||||
static WriteRunnable*
|
||||
AdoptBuffer(MutableBlobStorage* aBlobStorage, PRFileDesc* aFD,
|
||||
void* aData, uint32_t aLength)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aBlobStorage);
|
||||
MOZ_ASSERT(aFD);
|
||||
MOZ_ASSERT(aData);
|
||||
|
||||
return new WriteRunnable(aBlobStorage, aFD, aData, aLength);
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
int32_t written = PR_Write(mFD, mData, mLength);
|
||||
if (NS_WARN_IF(written < 0 || uint32_t(written) != mLength)) {
|
||||
return NS_DispatchToMainThread(
|
||||
new ErrorPropagationRunnable(mBlobStorage, NS_ERROR_FAILURE));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
WriteRunnable(MutableBlobStorage* aBlobStorage, PRFileDesc* aFD,
|
||||
void* aData, uint32_t aLength)
|
||||
: mBlobStorage(aBlobStorage)
|
||||
, mFD(aFD)
|
||||
, mData(aData)
|
||||
, mLength(aLength)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mBlobStorage);
|
||||
MOZ_ASSERT(aFD);
|
||||
MOZ_ASSERT(aData);
|
||||
}
|
||||
|
||||
~WriteRunnable()
|
||||
{
|
||||
free(mData);
|
||||
}
|
||||
|
||||
RefPtr<MutableBlobStorage> mBlobStorage;
|
||||
PRFileDesc* mFD;
|
||||
void* mData;
|
||||
uint32_t mLength;
|
||||
};
|
||||
|
||||
// This runnable closes the FD in case something goes wrong or the temporary
|
||||
// file is not needed anymore.
|
||||
class CloseFileRunnable final : public Runnable
|
||||
{
|
||||
public:
|
||||
explicit CloseFileRunnable(PRFileDesc* aFD)
|
||||
: mFD(aFD)
|
||||
{}
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
PR_Close(mFD);
|
||||
mFD = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
~CloseFileRunnable()
|
||||
{
|
||||
if (mFD) {
|
||||
PR_Close(mFD);
|
||||
}
|
||||
}
|
||||
|
||||
PRFileDesc* mFD;
|
||||
};
|
||||
|
||||
// This runnable is dispatched to the main-thread from the IO thread and its
|
||||
// task is to create the blob and inform the callback.
|
||||
class CreateBlobRunnable final : public Runnable
|
||||
{
|
||||
public:
|
||||
CreateBlobRunnable(MutableBlobStorage* aBlobStorage,
|
||||
already_AddRefed<nsISupports> aParent,
|
||||
const nsACString& aContentType,
|
||||
already_AddRefed<MutableBlobStorageCallback> aCallback)
|
||||
: mBlobStorage(aBlobStorage)
|
||||
, mParent(aParent)
|
||||
, mContentType(aContentType)
|
||||
, mCallback(aCallback)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mBlobStorage->CreateBlobAndRespond(mParent.forget(), mContentType,
|
||||
mCallback.forget());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
~CreateBlobRunnable()
|
||||
{
|
||||
// If something when wrong, we still have to release data in the correct
|
||||
// thread.
|
||||
NS_ReleaseOnMainThread(mParent.forget());
|
||||
NS_ReleaseOnMainThread(mCallback.forget());
|
||||
}
|
||||
|
||||
RefPtr<MutableBlobStorage> mBlobStorage;
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
nsCString mContentType;
|
||||
RefPtr<MutableBlobStorageCallback> mCallback;
|
||||
};
|
||||
|
||||
// This task is used to know when the writing is completed. From the IO thread
|
||||
// it dispatches a CreateBlobRunnable to the main-thread.
|
||||
class LastRunnable final : public Runnable
|
||||
{
|
||||
public:
|
||||
LastRunnable(MutableBlobStorage* aBlobStorage,
|
||||
nsISupports* aParent,
|
||||
const nsACString& aContentType,
|
||||
MutableBlobStorageCallback* aCallback)
|
||||
: mBlobStorage(aBlobStorage)
|
||||
, mParent(aParent)
|
||||
, mContentType(aContentType)
|
||||
, mCallback(aCallback)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mBlobStorage);
|
||||
MOZ_ASSERT(aParent);
|
||||
MOZ_ASSERT(aCallback);
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
RefPtr<Runnable> runnable =
|
||||
new CreateBlobRunnable(mBlobStorage, mParent.forget(),
|
||||
mContentType, mCallback.forget());
|
||||
return NS_DispatchToMainThread(runnable);
|
||||
}
|
||||
|
||||
private:
|
||||
~LastRunnable()
|
||||
{
|
||||
// If something when wrong, we still have to release data in the correct
|
||||
// thread.
|
||||
NS_ReleaseOnMainThread(mParent.forget());
|
||||
NS_ReleaseOnMainThread(mCallback.forget());
|
||||
}
|
||||
|
||||
RefPtr<MutableBlobStorage> mBlobStorage;
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
nsCString mContentType;
|
||||
RefPtr<MutableBlobStorageCallback> mCallback;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
MutableBlobStorage::MutableBlobStorage(MutableBlobStorageType aType)
|
||||
: mData(nullptr)
|
||||
, mDataLen(0)
|
||||
, mDataBufferLen(0)
|
||||
, mStorageState(aType == eOnlyInMemory ? eKeepInMemory : eInMemory)
|
||||
, mFD(nullptr)
|
||||
, mErrorResult(NS_OK)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
|
||||
MutableBlobStorage::~MutableBlobStorage()
|
||||
{
|
||||
free(mData);
|
||||
|
||||
if (mFD) {
|
||||
DispatchToIOThread(new CloseFileRunnable(mFD));
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t
|
||||
MutableBlobStorage::GetBlobWhenReady(nsISupports* aParent,
|
||||
const nsACString& aContentType,
|
||||
MutableBlobStorageCallback* aCallback)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aParent);
|
||||
MOZ_ASSERT(aCallback);
|
||||
|
||||
// GetBlob can be called just once.
|
||||
MOZ_ASSERT(mStorageState != eClosed);
|
||||
StorageState previousState = mStorageState;
|
||||
mStorageState = eClosed;
|
||||
|
||||
if (previousState == eInTemporaryFile) {
|
||||
MOZ_ASSERT(mFD);
|
||||
|
||||
if (NS_FAILED(mErrorResult)) {
|
||||
NS_DispatchToMainThread(
|
||||
new BlobCreationDoneRunnable(this, aCallback, nullptr, mErrorResult));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We want to wait until all the WriteRunnable are completed. The way we do
|
||||
// this is to go to the I/O thread and then we come back: the runnables are
|
||||
// executed in order and this LastRunnable will be... the last one.
|
||||
nsresult rv = DispatchToIOThread(new LastRunnable(this, aParent,
|
||||
aContentType, aCallback));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
NS_DispatchToMainThread(
|
||||
new BlobCreationDoneRunnable(this, aCallback, nullptr, rv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mDataLen;
|
||||
}
|
||||
|
||||
RefPtr<BlobImpl> blobImpl;
|
||||
|
||||
if (mData) {
|
||||
blobImpl = new BlobImplMemory(mData, mDataLen,
|
||||
NS_ConvertUTF8toUTF16(aContentType));
|
||||
|
||||
mData = nullptr; // The BlobImplMemory takes ownership of the buffer
|
||||
mDataLen = 0;
|
||||
mDataBufferLen = 0;
|
||||
} else {
|
||||
blobImpl = new EmptyBlobImpl(NS_ConvertUTF8toUTF16(aContentType));
|
||||
}
|
||||
|
||||
RefPtr<Blob> blob = Blob::Create(aParent, blobImpl);
|
||||
RefPtr<BlobCreationDoneRunnable> runnable =
|
||||
new BlobCreationDoneRunnable(this, aCallback, blob, NS_OK);
|
||||
|
||||
nsresult error = NS_DispatchToMainThread(runnable);
|
||||
if (NS_WARN_IF(NS_FAILED(error))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mDataLen;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MutableBlobStorage::Append(const void* aData, uint32_t aLength)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mStorageState != eClosed);
|
||||
NS_ENSURE_ARG_POINTER(aData);
|
||||
|
||||
if (!aLength) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If eInMemory is the current Storage state, we could maybe migrate to
|
||||
// a temporary file.
|
||||
if (mStorageState == eInMemory && ShouldBeTemporaryStorage(aLength)) {
|
||||
nsresult rv = MaybeCreateTemporaryFile();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
// If we are already in the temporaryFile mode, we have to dispatch a
|
||||
// runnable.
|
||||
if (mStorageState == eInTemporaryFile) {
|
||||
MOZ_ASSERT(mFD);
|
||||
|
||||
RefPtr<WriteRunnable> runnable =
|
||||
WriteRunnable::CopyBuffer(this, mFD, aData, aLength);
|
||||
if (NS_WARN_IF(!runnable)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsresult rv = DispatchToIOThread(runnable);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mDataLen += aLength;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// By default, we store in memory.
|
||||
|
||||
uint64_t offset = mDataLen;
|
||||
|
||||
if (!ExpandBufferSize(aLength)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
memcpy((char*)mData + offset, aData, aLength);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
MutableBlobStorage::ExpandBufferSize(uint64_t aSize)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mStorageState < eInTemporaryFile);
|
||||
|
||||
if (mDataBufferLen >= mDataLen + aSize) {
|
||||
mDataLen += aSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Start at 1 or we'll loop forever.
|
||||
CheckedUint32 bufferLen =
|
||||
std::max<uint32_t>(static_cast<uint32_t>(mDataBufferLen), 1);
|
||||
while (bufferLen.isValid() && bufferLen.value() < mDataLen + aSize) {
|
||||
bufferLen *= 2;
|
||||
}
|
||||
|
||||
if (!bufferLen.isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void* data = realloc(mData, bufferLen.value());
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mData = data;
|
||||
mDataBufferLen = bufferLen.value();
|
||||
mDataLen += aSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MutableBlobStorage::ShouldBeTemporaryStorage(uint64_t aSize) const
|
||||
{
|
||||
MOZ_ASSERT(mStorageState == eInMemory);
|
||||
|
||||
CheckedUint32 bufferSize = mDataLen;
|
||||
bufferSize += aSize;
|
||||
|
||||
if (!bufferSize.isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return bufferSize.value() >= Preferences::GetUint("dom.blob.memoryToTemporaryFile",
|
||||
BLOB_MEMORY_TEMPORARY_FILE);
|
||||
}
|
||||
|
||||
nsresult
|
||||
MutableBlobStorage::MaybeCreateTemporaryFile()
|
||||
{
|
||||
nsresult rv = DispatchToIOThread(new CreateTemporaryFileRunnable(this));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mStorageState = eWaitingForTemporaryFile;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
MutableBlobStorage::TemporaryFileCreated(PRFileDesc* aFD)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mStorageState == eWaitingForTemporaryFile ||
|
||||
mStorageState == eClosed);
|
||||
|
||||
if (mStorageState == eClosed) {
|
||||
DispatchToIOThread(new CloseFileRunnable(aFD));
|
||||
return;
|
||||
}
|
||||
|
||||
mStorageState = eInTemporaryFile;
|
||||
mFD = aFD;
|
||||
|
||||
RefPtr<WriteRunnable> runnable =
|
||||
WriteRunnable::AdoptBuffer(this, mFD, mData, mDataLen);
|
||||
MOZ_ASSERT(runnable);
|
||||
|
||||
mData = nullptr;
|
||||
|
||||
nsresult rv = DispatchToIOThread(runnable);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
mErrorResult = rv;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MutableBlobStorage::CreateBlobAndRespond(already_AddRefed<nsISupports> aParent,
|
||||
const nsACString& aContentType,
|
||||
already_AddRefed<MutableBlobStorageCallback> aCallback)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mStorageState == eClosed);
|
||||
MOZ_ASSERT(mFD);
|
||||
|
||||
nsCOMPtr<nsISupports> parent(aParent);
|
||||
RefPtr<MutableBlobStorageCallback> callback(aCallback);
|
||||
|
||||
RefPtr<Blob> blob =
|
||||
File::CreateTemporaryBlob(parent, mFD, 0, mDataLen,
|
||||
NS_ConvertUTF8toUTF16(aContentType));
|
||||
callback->BlobStoreCompleted(this, blob, NS_OK);
|
||||
|
||||
// ownership of this FD is moved to the BlobImpl.
|
||||
mFD = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
MutableBlobStorage::ErrorPropagated(nsresult aRv)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mErrorResult = aRv;
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
MutableBlobStorage::DispatchToIOThread(Runnable* aRunnable)
|
||||
{
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
|
||||
nsresult rv = target->Dispatch(aRunnable, NS_DISPATCH_NORMAL);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // dom namespace
|
||||
} // mozilla namespace
|
|
@ -0,0 +1,98 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_MutableBlobStorage_h
|
||||
#define mozilla_dom_MutableBlobStorage_h
|
||||
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "prio.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class Blob;
|
||||
class BlobImpl;
|
||||
class MutableBlobStorage;
|
||||
|
||||
class MutableBlobStorageCallback
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD_(MozExternalRefCountType) AddRef(void) = 0;
|
||||
|
||||
NS_IMETHOD_(MozExternalRefCountType) Release(void) = 0;
|
||||
|
||||
virtual void BlobStoreCompleted(MutableBlobStorage* aBlobStorage,
|
||||
Blob* aBlob,
|
||||
nsresult aRv) = 0;
|
||||
};
|
||||
|
||||
// This class is main-thread only.
|
||||
class MutableBlobStorage final
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MutableBlobStorage);
|
||||
|
||||
enum MutableBlobStorageType
|
||||
{
|
||||
eOnlyInMemory,
|
||||
eCouldBeInTemporaryFile,
|
||||
};
|
||||
|
||||
explicit MutableBlobStorage(MutableBlobStorageType aType);
|
||||
|
||||
nsresult Append(const void* aData, uint32_t aLength);
|
||||
|
||||
// This method can be called just once.
|
||||
// The callback will be called when the Blob is ready.
|
||||
// The return value is the total size of the blob, when created.
|
||||
uint64_t GetBlobWhenReady(nsISupports* aParent,
|
||||
const nsACString& aContentType,
|
||||
MutableBlobStorageCallback* aCallback);
|
||||
|
||||
void TemporaryFileCreated(PRFileDesc* aFD);
|
||||
|
||||
void CreateBlobAndRespond(already_AddRefed<nsISupports> aParent,
|
||||
const nsACString& aContentType,
|
||||
already_AddRefed<MutableBlobStorageCallback> aCallback);
|
||||
|
||||
void ErrorPropagated(nsresult aRv);
|
||||
|
||||
private:
|
||||
~MutableBlobStorage();
|
||||
|
||||
bool ExpandBufferSize(uint64_t aSize);
|
||||
|
||||
bool ShouldBeTemporaryStorage(uint64_t aSize) const;
|
||||
|
||||
nsresult MaybeCreateTemporaryFile();
|
||||
|
||||
static nsresult DispatchToIOThread(Runnable* aRunnable);
|
||||
|
||||
// All these variables are touched on the main thread only.
|
||||
|
||||
void* mData;
|
||||
uint64_t mDataLen;
|
||||
uint64_t mDataBufferLen;
|
||||
|
||||
enum StorageState {
|
||||
eKeepInMemory,
|
||||
eInMemory,
|
||||
eWaitingForTemporaryFile,
|
||||
eInTemporaryFile,
|
||||
eClosed
|
||||
};
|
||||
|
||||
StorageState mStorageState;
|
||||
|
||||
PRFileDesc* mFD;
|
||||
|
||||
nsresult mErrorResult;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_MutableBlobStorage_h
|
|
@ -166,3 +166,16 @@ DOM_MSG_DEF(NS_ERROR_DOM_DOMEXCEPTION, "A DOMException was thrown")
|
|||
DOM4_MSG_DEF(AbortError, "The fetching process for the media resource was aborted by the user agent at the user's request.", NS_ERROR_DOM_MEDIA_ABORT_ERR)
|
||||
DOM4_MSG_DEF(NotAllowedError, "The play method is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.", NS_ERROR_DOM_MEDIA_NOT_ALLOWED_ERR)
|
||||
DOM4_MSG_DEF(NotSupportedError, "The media resource indicated by the src attribute or assigned media provider object was not suitable.", NS_ERROR_DOM_MEDIA_NOT_SUPPORTED_ERR)
|
||||
|
||||
DOM4_MSG_DEF(SyntaxError, "The URI is malformed.", NS_ERROR_DOM_MALFORMED_URI)
|
||||
DOM4_MSG_DEF(SyntaxError, "Invalid header name.", NS_ERROR_DOM_INVALID_HEADER_NAME)
|
||||
|
||||
/* XMLHttpRequest errors. */
|
||||
DOM4_MSG_DEF(InvalidStateError, "XMLHttpRequest has an invalid context.", NS_ERROR_DOM_INVALID_STATE_XHR_HAS_INVALID_CONTEXT)
|
||||
DOM4_MSG_DEF(InvalidStateError, "XMLHttpRequest state must be OPENED.", NS_ERROR_DOM_INVALID_STATE_XHR_MUST_BE_OPENED)
|
||||
DOM4_MSG_DEF(InvalidStateError, "XMLHttpRequest must not be sending.", NS_ERROR_DOM_INVALID_STATE_XHR_MUST_NOT_BE_SENDING)
|
||||
DOM4_MSG_DEF(InvalidStateError, "XMLHttpRequest state must not be LOADING or DONE.", NS_ERROR_DOM_INVALID_STATE_XHR_MUST_NOT_BE_LOADING_OR_DONE)
|
||||
DOM4_MSG_DEF(InvalidStateError, "responseXML is only available if responseType is '' or 'document'.", NS_ERROR_DOM_INVALID_STATE_XHR_HAS_WRONG_RESPONSETYPE_FOR_RESPONSEXML)
|
||||
DOM4_MSG_DEF(InvalidStateError, "responseText is only available if responseType is '', 'document', or 'moz-chunked-text'.", NS_ERROR_DOM_INVALID_STATE_XHR_HAS_WRONG_RESPONSETYPE_FOR_RESPONSETEXT)
|
||||
DOM4_MSG_DEF(InvalidStateError, "synchronous XMLHttpRequests do not support 'moz-chunked-text' or 'moz-chunked-arraybuffer' responseType.", NS_ERROR_DOM_INVALID_STATE_XHR_CHUNKED_RESPONSETYPES_UNSUPPORTED_FOR_SYNC)
|
||||
DOM4_MSG_DEF(InvalidAccessError, "synchronous XMLHttpRequests do not support timeout and responseType.", NS_ERROR_DOM_INVALID_ACCESS_XHR_TIMEOUT_AND_RESPONSETYPE_UNSUPPORTED_FOR_SYNC)
|
||||
|
|
|
@ -186,6 +186,7 @@ EXPORTS.mozilla.dom += [
|
|||
'ImportManager.h',
|
||||
'Link.h',
|
||||
'Location.h',
|
||||
'MutableBlobStorage.h',
|
||||
'NameSpaceConstants.h',
|
||||
'Navigator.h',
|
||||
'NodeInfo.h',
|
||||
|
@ -247,6 +248,7 @@ UNIFIED_SOURCES += [
|
|||
'Link.cpp',
|
||||
'Location.cpp',
|
||||
'MultipartBlobImpl.cpp',
|
||||
'MutableBlobStorage.cpp',
|
||||
'Navigator.cpp',
|
||||
'NodeInfo.cpp',
|
||||
'NodeIterator.cpp',
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "nsJSEnvironment.h"
|
||||
#include "nsInProcessTabChildGlobal.h"
|
||||
#include "nsFrameLoader.h"
|
||||
#include "mozilla/CycleCollectedJSContext.h"
|
||||
#include "mozilla/EventListenerManager.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/ProcessGlobal.h"
|
||||
|
@ -313,6 +314,8 @@ MarkWindowList(nsISimpleEnumerator* aWindowList, bool aCleanupJS,
|
|||
nsCOMPtr<nsIContentFrameMessageManager> mm;
|
||||
tabChild->GetMessageManager(getter_AddRefs(mm));
|
||||
if (mm) {
|
||||
// MarkForCC ends up calling UnmarkGray on message listeners, which
|
||||
// TraceBlackJS can't do yet.
|
||||
mm->MarkForCC();
|
||||
}
|
||||
}
|
||||
|
@ -489,6 +492,13 @@ mozilla::dom::TraceBlackJS(JSTracer* aTrc, uint32_t aGCNumber, bool aIsShutdownG
|
|||
return;
|
||||
}
|
||||
|
||||
if (nsFrameMessageManager::GetChildProcessManager()) {
|
||||
nsIContentProcessMessageManager* pg = ProcessGlobal::Get();
|
||||
if (pg) {
|
||||
mozilla::TraceScriptHolder(pg, aTrc);
|
||||
}
|
||||
}
|
||||
|
||||
// Mark globals of active windows black.
|
||||
nsGlobalWindow::WindowByIdTable* windowsById =
|
||||
nsGlobalWindow::GetWindowsTable();
|
||||
|
@ -502,6 +512,31 @@ mozilla::dom::TraceBlackJS(JSTracer* aTrc, uint32_t aGCNumber, bool aIsShutdownG
|
|||
elm->TraceListeners(aTrc);
|
||||
}
|
||||
|
||||
if (window->IsRootOuterWindow()) {
|
||||
// In child process trace all the TabChildGlobals.
|
||||
// Since there is one root outer window per TabChildGlobal, we need
|
||||
// to look for only those windows, not all.
|
||||
nsIDocShell* ds = window->GetDocShell();
|
||||
if (ds) {
|
||||
nsCOMPtr<nsITabChild> tabChild = ds->GetTabChild();
|
||||
if (tabChild) {
|
||||
nsCOMPtr<nsIContentFrameMessageManager> mm;
|
||||
tabChild->GetMessageManager(getter_AddRefs(mm));
|
||||
nsCOMPtr<EventTarget> et = do_QueryInterface(mm);
|
||||
if (et) {
|
||||
nsCOMPtr<nsISupports> tabChildAsSupports =
|
||||
do_QueryInterface(tabChild);
|
||||
mozilla::TraceScriptHolder(tabChildAsSupports, aTrc);
|
||||
EventListenerManager* elm = et->GetExistingListenerManager();
|
||||
if (elm) {
|
||||
elm->TraceListeners(aTrc);
|
||||
}
|
||||
// As of now there isn't an easy way to trace message listeners.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
nsIDocument* doc = window->GetExtantDoc();
|
||||
if (doc && doc->IsXULDocument()) {
|
||||
|
|
|
@ -33,6 +33,7 @@ DEPRECATED_OPERATION(MozGetAsFile)
|
|||
DEPRECATED_OPERATION(UseOfCaptureEvents)
|
||||
DEPRECATED_OPERATION(UseOfReleaseEvents)
|
||||
DEPRECATED_OPERATION(UseOfDOM3LoadMethod)
|
||||
DEPRECATED_OPERATION(ChromeUseOfDOM3LoadMethod)
|
||||
DEPRECATED_OPERATION(ShowModalDialog)
|
||||
DEPRECATED_OPERATION(Window_Content)
|
||||
DEPRECATED_OPERATION(SyncXMLHttpRequest)
|
||||
|
|
|
@ -252,7 +252,7 @@
|
|||
#include "mozilla/StyleSetHandleInlines.h"
|
||||
#include "mozilla/StyleSheet.h"
|
||||
#include "mozilla/StyleSheetInlines.h"
|
||||
|
||||
#include "mozilla/dom/SVGSVGElement.h"
|
||||
#include "mozilla/DocLoadingTimelineMarker.h"
|
||||
|
||||
#include "nsISpeculativeConnect.h"
|
||||
|
@ -3038,6 +3038,16 @@ nsDocument::GetAnimations(nsTArray<RefPtr<Animation>>& aAnimations)
|
|||
root->GetAnimations(filter, aAnimations);
|
||||
}
|
||||
|
||||
SVGSVGElement*
|
||||
nsIDocument::GetSVGRootElement() const
|
||||
{
|
||||
Element* root = GetRootElement();
|
||||
if (!root || !root->IsSVGElement(nsGkAtoms::svg)) {
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<SVGSVGElement*>(root);
|
||||
}
|
||||
|
||||
/* Return true if the document is in the focused top-level window, and is an
|
||||
* ancestor of the focused DOMWindow. */
|
||||
NS_IMETHODIMP
|
||||
|
@ -5971,30 +5981,6 @@ nsDocument::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::GetAsync(bool *aAsync)
|
||||
{
|
||||
NS_ERROR("nsDocument::GetAsync() should be overriden by subclass!");
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::SetAsync(bool aAsync)
|
||||
{
|
||||
NS_ERROR("nsDocument::SetAsync() should be overriden by subclass!");
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::Load(const nsAString& aUrl, bool *aReturn)
|
||||
{
|
||||
NS_ERROR("nsDocument::Load() should be overriden by subclass!");
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::GetStyleSheets(nsIDOMStyleSheetList** aStyleSheets)
|
||||
{
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "nsWeakReference.h"
|
||||
#include "nsWeakPtr.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsIDOMXMLDocument.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMDocumentXBL.h"
|
||||
#include "nsStubDocumentObserver.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
|
@ -485,16 +485,8 @@ protected:
|
|||
};
|
||||
|
||||
// Base class for our document implementations.
|
||||
//
|
||||
// Note that this class *implements* nsIDOMXMLDocument, but it's not
|
||||
// really an nsIDOMXMLDocument. The reason for implementing
|
||||
// nsIDOMXMLDocument on this class is to avoid having to duplicate all
|
||||
// its inherited methods on document classes that *are*
|
||||
// nsIDOMXMLDocument's. nsDocument's QI should *not* claim to support
|
||||
// nsIDOMXMLDocument unless someone writes a real implementation of
|
||||
// the interface.
|
||||
class nsDocument : public nsIDocument,
|
||||
public nsIDOMXMLDocument, // inherits nsIDOMDocument
|
||||
public nsIDOMDocument,
|
||||
public nsIDOMDocumentXBL,
|
||||
public nsSupportsWeakReference,
|
||||
public nsIScriptObjectPrincipal,
|
||||
|
@ -798,9 +790,6 @@ public:
|
|||
// nsIDOMDocument
|
||||
NS_DECL_NSIDOMDOCUMENT
|
||||
|
||||
// nsIDOMXMLDocument
|
||||
NS_DECL_NSIDOMXMLDOCUMENT
|
||||
|
||||
// nsIDOMDocumentXBL
|
||||
NS_DECL_NSIDOMDOCUMENTXBL
|
||||
|
||||
|
|
|
@ -622,7 +622,7 @@ nsPIDOMWindow<T>::nsPIDOMWindow(nsPIDOMWindowOuter *aOuterWindow)
|
|||
mMediaSuspend(Preferences::GetBool("media.block-autoplay-until-in-foreground", true) ?
|
||||
nsISuspendedTypes::SUSPENDED_BLOCK : nsISuspendedTypes::NONE_SUSPENDED),
|
||||
mAudioMuted(false), mAudioVolume(1.0), mAudioCaptured(false),
|
||||
mDesktopModeViewport(false), mInnerWindow(nullptr),
|
||||
mDesktopModeViewport(false), mIsRootOuterWindow(false), mInnerWindow(nullptr),
|
||||
mOuterWindow(aOuterWindow),
|
||||
// Make sure no actual window ends up with mWindowID == 0
|
||||
mWindowID(NextWindowID()), mHasNotifiedGlobalCreated(false),
|
||||
|
@ -3067,6 +3067,7 @@ nsGlobalWindow::SetDocShell(nsIDocShell* aDocShell)
|
|||
}
|
||||
else {
|
||||
mChromeEventHandler = NS_NewWindowRoot(AsOuter());
|
||||
mIsRootOuterWindow = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -148,6 +148,7 @@ class ProcessingInstruction;
|
|||
class Promise;
|
||||
class StyleSheetList;
|
||||
class SVGDocument;
|
||||
class SVGSVGElement;
|
||||
class Touch;
|
||||
class TouchList;
|
||||
class TreeWalker;
|
||||
|
@ -2328,6 +2329,8 @@ public:
|
|||
virtual void GetAnimations(
|
||||
nsTArray<RefPtr<mozilla::dom::Animation>>& aAnimations) = 0;
|
||||
|
||||
mozilla::dom::SVGSVGElement* GetSVGRootElement() const;
|
||||
|
||||
nsresult ScheduleFrameRequestCallback(mozilla::dom::FrameRequestCallback& aCallback,
|
||||
int32_t *aHandle);
|
||||
void CancelFrameRequestCallback(int32_t aHandle);
|
||||
|
|
|
@ -118,6 +118,12 @@ public:
|
|||
virtual nsPIDOMWindowOuter* GetScriptableParent() = 0;
|
||||
virtual already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() = 0;
|
||||
|
||||
bool IsRootOuterWindow()
|
||||
{
|
||||
MOZ_ASSERT(IsOuterWindow());
|
||||
return mIsRootOuterWindow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Behavies identically to GetScriptableParent extept that it returns null
|
||||
* if GetScriptableParent would return this window.
|
||||
|
@ -666,6 +672,8 @@ protected:
|
|||
// current desktop mode flag.
|
||||
bool mDesktopModeViewport;
|
||||
|
||||
bool mIsRootOuterWindow;
|
||||
|
||||
// And these are the references between inner and outer windows.
|
||||
nsPIDOMWindowInner* MOZ_NON_OWNING_REF mInnerWindow;
|
||||
nsCOMPtr<nsPIDOMWindowOuter> mOuterWindow;
|
||||
|
|
|
@ -217,7 +217,7 @@ var tests =
|
|||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "GET", withUpload: none, testAbort: true, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "progress", optional: true},
|
||||
{target: XHR, type: "abort", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "GET", withUpload: none, testAbort: false, testRedirectError: true, testNetworkError: false,
|
||||
|
@ -236,7 +236,7 @@ var tests =
|
|||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "GET", withUpload: small, testAbort: true, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "progress", optional: true},
|
||||
{target: XHR, type: "abort", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "GET", withUpload: small, testAbort: false, testRedirectError: true, testNetworkError: false,
|
||||
|
@ -255,7 +255,7 @@ var tests =
|
|||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "GET", withUpload: mid, testAbort: true, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "progress", optional: true},
|
||||
{target: XHR, type: "abort", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "GET", withUpload: mid, testAbort: false, testRedirectError: true, testNetworkError: false,
|
||||
|
@ -274,7 +274,7 @@ var tests =
|
|||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "GET", withUpload: large, testAbort: true, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "progress", optional: true},
|
||||
{target: XHR, type: "abort", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "GET", withUpload: large, testAbort: false, testRedirectError: true, testNetworkError: false,
|
||||
|
@ -293,7 +293,7 @@ var tests =
|
|||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "POST", withUpload: none, testAbort: true, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "progress", optional: true},
|
||||
{target: XHR, type: "abort", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "POST", withUpload: none, testAbort: false, testRedirectError: true, testNetworkError: false,
|
||||
|
@ -317,10 +317,10 @@ var tests =
|
|||
{ method: "POST", withUpload: small, testAbort: true, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "progress", optional: false},
|
||||
{target: UPLOAD, type: "progress", optional: true},
|
||||
{target: UPLOAD, type: "abort", optional: false},
|
||||
{target: UPLOAD, type: "loadend", optional: false},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "progress", optional: true},
|
||||
{target: XHR, type: "abort", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "POST", withUpload: small, testAbort: false, testRedirectError: true, testNetworkError: false,
|
||||
|
@ -351,10 +351,10 @@ var tests =
|
|||
{ method: "POST", withUpload: mid, testAbort: true, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "progress", optional: false},
|
||||
{target: UPLOAD, type: "progress", optional: true},
|
||||
{target: UPLOAD, type: "abort", optional: false},
|
||||
{target: UPLOAD, type: "loadend", optional: false},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "progress", optional: true},
|
||||
{target: XHR, type: "abort", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "POST", withUpload: mid, testAbort: false, testRedirectError: true, testNetworkError: false,
|
||||
|
@ -385,10 +385,10 @@ var tests =
|
|||
{ method: "POST", withUpload: large, testAbort: true, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "progress", optional: false},
|
||||
{target: UPLOAD, type: "progress", optional: true},
|
||||
{target: UPLOAD, type: "abort", optional: false},
|
||||
{target: UPLOAD, type: "loadend", optional: false},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "progress", optional: true},
|
||||
{target: XHR, type: "abort", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "POST", withUpload: large, testAbort: false, testRedirectError: true, testNetworkError: false,
|
||||
|
|
|
@ -34,8 +34,6 @@ function testHTMLDocuments(ids, isXHTML) {
|
|||
is(doc1.body, null, "Shouldn't have .body!");
|
||||
ok(doc1 instanceof HTMLDocument,
|
||||
"Document should be an HTML document!");
|
||||
ok(!(doc1 instanceof SVGDocument),
|
||||
"Document shouldn't be an SVG document!");
|
||||
|
||||
var docType2 =
|
||||
document.implementation.createDocumentType(isXHTML ? "html" : "HTML",
|
||||
|
@ -70,11 +68,11 @@ function testSVGDocument() {
|
|||
ok(!doc1.documentElement, "Document shouldn't have document element!");
|
||||
ok(!(doc1 instanceof HTMLDocument),
|
||||
"Document shouldn't be an HTML document!");
|
||||
ok(doc1 instanceof SVGDocument,
|
||||
"Document should be an SVG document!");
|
||||
ok(doc1 instanceof XMLDocument,
|
||||
"Document should be an XML document!");
|
||||
|
||||
// SVG documents have .rootElement.
|
||||
ok("rootElement" in doc1, "No .rootElement in document");
|
||||
// SVG documents have .documentElement.
|
||||
ok("documentElement" in doc1, "No .documentElement in document");
|
||||
|
||||
var docType2 =
|
||||
document.implementation.createDocumentType("svg",
|
||||
|
@ -83,8 +81,7 @@ function testSVGDocument() {
|
|||
var doc2 = document.implementation.createDocument("http://www.w3.org/2000/svg",
|
||||
"svg", docType2);
|
||||
ok(doc2.documentElement, "Document should have document element!");
|
||||
ok(doc2.rootElement, "Should have .rootElement in document");
|
||||
is(doc2.rootElement.localName, "svg", "Wrong .rootElement!");
|
||||
is(doc2.documentElement.localName, "svg", "Wrong .documentElement!");
|
||||
}
|
||||
|
||||
function testFooBarDocument() {
|
||||
|
@ -97,8 +94,6 @@ function testFooBarDocument() {
|
|||
ok(!doc1.documentElement, "Document shouldn't have document element!");
|
||||
ok(!(doc1 instanceof HTMLDocument),
|
||||
"Document shouldn't be an HTML document!");
|
||||
ok(!(doc1 instanceof SVGDocument),
|
||||
"Document shouldn't be an SVG document!");
|
||||
|
||||
var docType2 =
|
||||
document.implementation.createDocumentType("FooBar", "FooBar", null);
|
||||
|
@ -114,8 +109,6 @@ function testNullDocTypeDocument() {
|
|||
ok(!doc1.documentElement, "Document shouldn't have document element!");
|
||||
ok(!(doc1 instanceof HTMLDocument),
|
||||
"Document shouldn't be an HTML document!");
|
||||
ok(!(doc1 instanceof SVGDocument),
|
||||
"Document shouldn't be an SVG document!");
|
||||
|
||||
var doc2 = document.implementation.createDocument("FooBarNS",
|
||||
"FooBar", null);
|
||||
|
|
|
@ -23,16 +23,11 @@ var dp = new DOMParser();
|
|||
var d = dp.parseFromString("<?xml version='1.0'?><svg xmlns='http://www.w3.org/2000/svg'></svg>",
|
||||
"image/svg+xml");
|
||||
|
||||
ok(d instanceof SVGDocument, "Should have created an SVG document.");
|
||||
ok("rootElement" in d, "Should have created an SVG document, which has .rootElement.");
|
||||
ok(d instanceof XMLDocument, "Should have created an XML document.");
|
||||
ok("documentElement" in d, "Should have created an XML document, which has .documentElement.");
|
||||
is(d.documentElement.localName, "svg", "Root element should be svg.");
|
||||
is(d.documentElement.namespaceURI, "http://www.w3.org/2000/svg",
|
||||
"Root element should be in svg namespace.");
|
||||
|
||||
dp = new DOMParser();
|
||||
d = dp.parseFromString("<?xml version='1.0'?><svg xmlns='http://www.w3.org/2000/svg'></svg>",
|
||||
"text/xml");
|
||||
ok(!(d instanceof SVGDocument), "Should not have created an SVG document!");
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
|
|
@ -1117,7 +1117,7 @@ QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp)
|
|||
JS::Rooted<JSObject*> obj(cx, js::CheckedUnwrap(origObj,
|
||||
/* stopAtWindowProxy = */ false));
|
||||
if (!obj) {
|
||||
JS_ReportError(cx, "Permission denied to access object");
|
||||
JS_ReportErrorASCII(cx, "Permission denied to access object");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1855,8 +1855,6 @@ addExternalIface('nsIBrowserDOMWindow', nativeType='nsIBrowserDOMWindow',
|
|||
addExternalIface('nsIControllers', nativeType='nsIControllers')
|
||||
addExternalIface('nsIDOMCrypto', nativeType='nsIDOMCrypto',
|
||||
headerFile='Crypto.h')
|
||||
addExternalIface('nsIInputStreamCallback', nativeType='nsIInputStreamCallback',
|
||||
headerFile='nsIAsyncInputStream.h')
|
||||
addExternalIface('nsIFile', nativeType='nsIFile', notflattened=True)
|
||||
addExternalIface('nsILoadGroup', nativeType='nsILoadGroup',
|
||||
headerFile='nsILoadGroup.h', notflattened=True)
|
||||
|
|
|
@ -6836,6 +6836,9 @@ class CGCallGenerator(CGThing):
|
|||
A class to generate an actual call to a C++ object. Assumes that the C++
|
||||
object is stored in a variable whose name is given by the |object| argument.
|
||||
|
||||
needsSubjectPrincipal is a boolean indicating whether the call should
|
||||
receive the subject nsIPrincipal as argument.
|
||||
|
||||
isFallible is a boolean indicating whether the call should be fallible.
|
||||
|
||||
resultVar: If the returnType is not void, then the result of the call is
|
||||
|
@ -6843,9 +6846,10 @@ class CGCallGenerator(CGThing):
|
|||
declaring the result variable. If the caller doesn't care about the result
|
||||
value, resultVar can be omitted.
|
||||
"""
|
||||
def __init__(self, isFallible, arguments, argsPre, returnType,
|
||||
extendedAttributes, descriptorProvider, nativeMethodName,
|
||||
static, object="self", argsPost=[], resultVar=None):
|
||||
def __init__(self, isFallible, needsSubjectPrincipal, arguments, argsPre,
|
||||
returnType, extendedAttributes, descriptorProvider,
|
||||
nativeMethodName, static, object="self", argsPost=[],
|
||||
resultVar=None):
|
||||
CGThing.__init__(self)
|
||||
|
||||
result, resultOutParam, resultRooter, resultArgs, resultConversion = \
|
||||
|
@ -6902,6 +6906,9 @@ class CGCallGenerator(CGThing):
|
|||
assert resultOutParam == "ptr"
|
||||
args.append(CGGeneric("&" + resultVar))
|
||||
|
||||
if needsSubjectPrincipal:
|
||||
args.append(CGGeneric("subjectPrincipal"))
|
||||
|
||||
if isFallible:
|
||||
args.append(CGGeneric("rv"))
|
||||
args.extend(CGGeneric(arg) for arg in argsPost)
|
||||
|
@ -6940,6 +6947,18 @@ class CGCallGenerator(CGThing):
|
|||
call = CGWrapper(call, post=";\n")
|
||||
self.cgRoot.append(call)
|
||||
|
||||
if needsSubjectPrincipal:
|
||||
self.cgRoot.prepend(CGGeneric(dedent(
|
||||
"""
|
||||
Maybe<nsIPrincipal*> subjectPrincipal;
|
||||
if (NS_IsMainThread()) {
|
||||
JSCompartment* compartment = js::GetContextCompartment(cx);
|
||||
MOZ_ASSERT(compartment);
|
||||
JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
|
||||
subjectPrincipal.emplace(nsJSPrincipals::get(principals));
|
||||
}
|
||||
""")))
|
||||
|
||||
if isFallible:
|
||||
self.cgRoot.prepend(CGGeneric("binding_detail::FastErrorResult rv;\n"))
|
||||
self.cgRoot.append(CGGeneric(dedent(
|
||||
|
@ -7406,6 +7425,7 @@ class CGPerSignatureCall(CGThing):
|
|||
else:
|
||||
cgThings.append(CGCallGenerator(
|
||||
self.isFallible(),
|
||||
idlNode.getExtendedAttribute('NeedsSubjectPrincipal'),
|
||||
self.getArguments(), argsPre, returnType,
|
||||
self.extendedAttributes, descriptor,
|
||||
nativeMethodName,
|
||||
|
@ -13812,6 +13832,9 @@ class CGNativeMember(ClassMethod):
|
|||
elif returnType.isObject() or returnType.isSpiderMonkeyInterface():
|
||||
args.append(Argument("JS::MutableHandle<JSObject*>", "aRetVal"))
|
||||
|
||||
# And the nsIPrincipal
|
||||
if self.member.getExtendedAttribute('NeedsSubjectPrincipal'):
|
||||
args.append(Argument("const Maybe<nsIPrincipal*>&", "aPrincipal"))
|
||||
# And the ErrorResult
|
||||
if 'infallible' not in self.extendedAttrs:
|
||||
# Use aRv so it won't conflict with local vars named "rv"
|
||||
|
@ -15757,7 +15780,7 @@ class CGMaplikeOrSetlikeMethodGenerator(CGThing):
|
|||
// TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
|
||||
// after bug 1023984 is fixed.
|
||||
if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
|
||||
JS_ReportError(cx, "Xray wrapping of iterators not supported.");
|
||||
JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
|
||||
return false;
|
||||
}
|
||||
JS::Rooted<JSObject*> result(cx);
|
||||
|
|
|
@ -4204,6 +4204,7 @@ class IDLAttribute(IDLInterfaceMember):
|
|||
identifier == "Frozen" or
|
||||
identifier == "NewObject" or
|
||||
identifier == "UnsafeInPrerendering" or
|
||||
identifier == "NeedsSubjectPrincipal" or
|
||||
identifier == "BinaryName"):
|
||||
# Known attributes that we don't need to do anything with here
|
||||
pass
|
||||
|
@ -4920,6 +4921,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
|||
identifier == "Func" or
|
||||
identifier == "SecureContext" or
|
||||
identifier == "BinaryName" or
|
||||
identifier == "NeedsSubjectPrincipal" or
|
||||
identifier == "StaticClassOverride"):
|
||||
# Known attributes that we don't need to do anything with here
|
||||
pass
|
||||
|
|
|
@ -773,6 +773,8 @@ interface TestExampleInterface {
|
|||
[Throws] attribute boolean throwingAttr;
|
||||
[GetterThrows] attribute boolean throwingGetterAttr;
|
||||
[SetterThrows] attribute boolean throwingSetterAttr;
|
||||
[NeedsSubjectPrincipal] void needsSubjectPrincipalMethod();
|
||||
[NeedsSubjectPrincipal] attribute boolean needsSubjectPrincipalAttr;
|
||||
legacycaller short(unsigned long arg1, TestInterface arg2);
|
||||
void passArgsWithDefaults(optional long arg1,
|
||||
optional TestInterface? arg2 = null,
|
||||
|
|
|
@ -395,15 +395,16 @@ TexUnpackBytes::TexOrSubImage(bool isSubImage, bool needsRespec, const char* fun
|
|||
|
||||
if (!isSubImage) {
|
||||
// Alloc first to catch OOMs.
|
||||
gl->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
AssertUintParamCorrect(gl, LOCAL_GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
*out_error = DoTexOrSubImage(false, gl, target, level, dui, xOffset, yOffset,
|
||||
zOffset, mWidth, mHeight, mDepth, nullptr);
|
||||
gl->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER,
|
||||
webgl->mBoundPixelUnpackBuffer->mGLName);
|
||||
if (*out_error)
|
||||
return false;
|
||||
}
|
||||
|
||||
const ScopedLazyBind bindPBO(gl, LOCAL_GL_PIXEL_UNPACK_BUFFER,
|
||||
webgl->mBoundPixelUnpackBuffer);
|
||||
|
||||
//////
|
||||
|
||||
// Make our sometimes-implicit values explicit. Also this keeps them constant when we
|
||||
|
|
|
@ -85,6 +85,8 @@ WebGL2Context::CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
|
|||
}
|
||||
|
||||
gl->MakeCurrent();
|
||||
const ScopedLazyBind readBind(gl, readTarget, readBuffer);
|
||||
const ScopedLazyBind writeBind(gl, writeTarget, writeBuffer);
|
||||
gl->fCopyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size);
|
||||
}
|
||||
|
||||
|
@ -143,6 +145,7 @@ WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
|
|||
////
|
||||
|
||||
gl->MakeCurrent();
|
||||
const ScopedLazyBind readBind(gl, target, buffer);
|
||||
|
||||
const auto ptr = gl->fMapBufferRange(target, offset, data.LengthAllowShared(),
|
||||
LOCAL_GL_MAP_READ_BIT);
|
||||
|
|
|
@ -16,6 +16,7 @@ WebGLBuffer::WebGLBuffer(WebGLContext* webgl, GLuint buf)
|
|||
: WebGLContextBoundObject(webgl)
|
||||
, mGLName(buf)
|
||||
, mContent(Kind::Undefined)
|
||||
, mUsage(LOCAL_GL_STATIC_DRAW)
|
||||
, mByteLength(0)
|
||||
, mNumActiveTFOs(0)
|
||||
, mBoundForTF(false)
|
||||
|
@ -114,6 +115,7 @@ WebGLBuffer::BufferData(GLenum target, size_t size, const void* data, GLenum usa
|
|||
|
||||
const auto& gl = mContext->gl;
|
||||
gl->MakeCurrent();
|
||||
const ScopedLazyBind lazyBind(gl, target, this);
|
||||
mContext->InvalidateBufferFetching();
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
|
@ -141,6 +143,7 @@ WebGLBuffer::BufferData(GLenum target, size_t size, const void* data, GLenum usa
|
|||
gl->fBufferData(target, size, data, usage);
|
||||
}
|
||||
|
||||
mUsage = usage;
|
||||
mByteLength = size;
|
||||
|
||||
// Warning: Possibly shared memory. See bug 1225033.
|
||||
|
|
|
@ -45,6 +45,7 @@ public:
|
|||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
|
||||
|
||||
GLenum Usage() const { return mUsage; }
|
||||
size_t ByteLength() const { return mByteLength; }
|
||||
|
||||
bool ElementArrayCacheBufferData(const void* ptr, size_t bufferSizeInBytes);
|
||||
|
@ -74,6 +75,7 @@ protected:
|
|||
~WebGLBuffer();
|
||||
|
||||
Kind mContent;
|
||||
GLenum mUsage;
|
||||
size_t mByteLength;
|
||||
UniquePtr<WebGLElementArrayCache> mCache;
|
||||
size_t mNumActiveTFOs;
|
||||
|
|
|
@ -2159,6 +2159,39 @@ ScopedFBRebinder::UnwrapImpl()
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
static GLenum
|
||||
TargetIfLazy(GLenum target)
|
||||
{
|
||||
switch (target) {
|
||||
case LOCAL_GL_PIXEL_PACK_BUFFER:
|
||||
case LOCAL_GL_PIXEL_UNPACK_BUFFER:
|
||||
return target;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ScopedLazyBind::ScopedLazyBind(gl::GLContext* gl, GLenum target, const WebGLBuffer* buf)
|
||||
: ScopedGLWrapper<ScopedLazyBind>(gl)
|
||||
, mTarget(buf ? TargetIfLazy(target) : 0)
|
||||
, mBuf(buf)
|
||||
{
|
||||
if (mTarget) {
|
||||
mGL->fBindBuffer(mTarget, mBuf->mGLName);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScopedLazyBind::UnwrapImpl()
|
||||
{
|
||||
if (mTarget) {
|
||||
mGL->fBindBuffer(mTarget, 0);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
|
||||
void
|
||||
|
|
|
@ -1834,6 +1834,21 @@ private:
|
|||
void UnwrapImpl();
|
||||
};
|
||||
|
||||
class ScopedLazyBind final
|
||||
: public gl::ScopedGLWrapper<ScopedLazyBind>
|
||||
{
|
||||
friend struct gl::ScopedGLWrapper<ScopedLazyBind>;
|
||||
|
||||
const GLenum mTarget;
|
||||
const WebGLBuffer* const mBuf;
|
||||
|
||||
public:
|
||||
ScopedLazyBind(gl::GLContext* gl, GLenum target, const WebGLBuffer* buf);
|
||||
|
||||
private:
|
||||
void UnwrapImpl();
|
||||
};
|
||||
|
||||
void
|
||||
ComputeLengthAndData(const dom::ArrayBufferViewOrSharedArrayBufferView& view,
|
||||
void** const out_data, size_t* const out_length,
|
||||
|
|
|
@ -137,6 +137,13 @@ WebGLContext::BindBuffer(GLenum target, WebGLBuffer* buffer)
|
|||
if (buffer) {
|
||||
buffer->SetContentAfterBind(target);
|
||||
}
|
||||
|
||||
switch (target) {
|
||||
case LOCAL_GL_PIXEL_PACK_BUFFER:
|
||||
case LOCAL_GL_PIXEL_UNPACK_BUFFER:
|
||||
gl->fBindBuffer(target, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
|
@ -429,6 +436,8 @@ WebGLContext::BufferSubDataT(GLenum target,
|
|||
}
|
||||
|
||||
MakeContextCurrent();
|
||||
const ScopedLazyBind lazyBind(gl, target, buffer);
|
||||
|
||||
// Warning: Possibly shared memory. See bug 1225033.
|
||||
gl->fBufferSubData(target, byteOffset, data.LengthAllowShared(),
|
||||
data.DataAllowShared());
|
||||
|
|
|
@ -630,28 +630,17 @@ WebGLContext::GetBufferParameter(GLenum target, GLenum pname)
|
|||
if (!buffer)
|
||||
return JS::NullValue();
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
switch (pname) {
|
||||
case LOCAL_GL_BUFFER_SIZE:
|
||||
case LOCAL_GL_BUFFER_USAGE:
|
||||
{
|
||||
GLint i = 0;
|
||||
gl->fGetBufferParameteriv(target, pname, &i);
|
||||
if (pname == LOCAL_GL_BUFFER_SIZE) {
|
||||
return JS::Int32Value(i);
|
||||
}
|
||||
case LOCAL_GL_BUFFER_SIZE:
|
||||
return JS::NumberValue(buffer->ByteLength());
|
||||
|
||||
MOZ_ASSERT(pname == LOCAL_GL_BUFFER_USAGE);
|
||||
return JS::NumberValue(uint32_t(i));
|
||||
}
|
||||
break;
|
||||
case LOCAL_GL_BUFFER_USAGE:
|
||||
return JS::NumberValue(buffer->Usage());
|
||||
|
||||
default:
|
||||
ErrorInvalidEnumInfo("getBufferParameter: parameter", pname);
|
||||
default:
|
||||
ErrorInvalidEnumInfo("getBufferParameter: parameter", pname);
|
||||
return JS::NullValue();
|
||||
}
|
||||
|
||||
return JS::NullValue();
|
||||
}
|
||||
|
||||
JS::Value
|
||||
|
@ -1528,6 +1517,9 @@ WebGL2Context::ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenu
|
|||
bytesAfterOffset = checkedBytesAfterOffset.value();
|
||||
}
|
||||
|
||||
gl->MakeCurrent();
|
||||
const ScopedLazyBind lazyBind(gl, LOCAL_GL_PIXEL_PACK_BUFFER, mBoundPixelPackBuffer);
|
||||
|
||||
ReadPixelsImpl(x, y, width, height, format, type, (void*)offset, bytesAfterOffset);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,9 +33,9 @@ private:
|
|||
bool mIsActive;
|
||||
// Not in state tables:
|
||||
WebGLRefPtr<WebGLProgram> mActive_Program;
|
||||
GLenum mActive_PrimMode;
|
||||
size_t mActive_VertPosition;
|
||||
size_t mActive_VertCapacity;
|
||||
MOZ_INIT_OUTSIDE_CTOR GLenum mActive_PrimMode;
|
||||
MOZ_INIT_OUTSIDE_CTOR size_t mActive_VertPosition;
|
||||
MOZ_INIT_OUTSIDE_CTOR size_t mActive_VertCapacity;
|
||||
|
||||
public:
|
||||
WebGLTransformFeedback(WebGLContext* webgl, GLuint tf);
|
||||
|
|
|
@ -449,8 +449,12 @@ DataTransfer::SetData(const nsAString& aFormat, const nsAString& aData,
|
|||
}
|
||||
|
||||
void
|
||||
DataTransfer::ClearData(const Optional<nsAString>& aFormat, ErrorResult& aRv)
|
||||
DataTransfer::ClearData(const Optional<nsAString>& aFormat,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (mReadOnly) {
|
||||
aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
|
||||
return;
|
||||
|
@ -461,9 +465,9 @@ DataTransfer::ClearData(const Optional<nsAString>& aFormat, ErrorResult& aRv)
|
|||
}
|
||||
|
||||
if (aFormat.WasPassed()) {
|
||||
MozClearDataAtHelper(aFormat.Value(), 0, aRv);
|
||||
MozClearDataAtHelper(aFormat.Value(), 0, aSubjectPrincipal, aRv);
|
||||
} else {
|
||||
MozClearDataAtHelper(EmptyString(), 0, aRv);
|
||||
MozClearDataAtHelper(EmptyString(), 0, aSubjectPrincipal, aRv);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -473,7 +477,7 @@ DataTransfer::ClearData(const nsAString& aFormat)
|
|||
Optional<nsAString> format;
|
||||
format = &aFormat;
|
||||
ErrorResult rv;
|
||||
ClearData(format, rv);
|
||||
ClearData(format, Some(nsContentUtils::SubjectPrincipal()), rv);
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
|
@ -743,8 +747,11 @@ DataTransfer::MozSetDataAt(JSContext* aCx, const nsAString& aFormat,
|
|||
|
||||
void
|
||||
DataTransfer::MozClearDataAt(const nsAString& aFormat, uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (mReadOnly) {
|
||||
aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
|
||||
return;
|
||||
|
@ -763,7 +770,7 @@ DataTransfer::MozClearDataAt(const nsAString& aFormat, uint32_t aIndex,
|
|||
return;
|
||||
}
|
||||
|
||||
MozClearDataAtHelper(aFormat, aIndex, aRv);
|
||||
MozClearDataAtHelper(aFormat, aIndex, aSubjectPrincipal, aRv);
|
||||
|
||||
// If we just cleared the 0-th index, and there are still more than 1 indexes
|
||||
// remaining, MozClearDataAt should cause the 1st index to become the 0th
|
||||
|
@ -779,6 +786,7 @@ DataTransfer::MozClearDataAt(const nsAString& aFormat, uint32_t aIndex,
|
|||
|
||||
void
|
||||
DataTransfer::MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(!mReadOnly);
|
||||
|
@ -786,18 +794,19 @@ DataTransfer::MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex,
|
|||
MOZ_ASSERT(aIndex == 0 ||
|
||||
(mEventMessage != eCut && mEventMessage != eCopy &&
|
||||
mEventMessage != ePaste));
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
nsAutoString format;
|
||||
GetRealFormat(aFormat, format);
|
||||
|
||||
mItems->MozRemoveByTypeAt(format, aIndex, aRv);
|
||||
mItems->MozRemoveByTypeAt(format, aIndex, aSubjectPrincipal, aRv);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
DataTransfer::MozClearDataAt(const nsAString& aFormat, uint32_t aIndex)
|
||||
{
|
||||
ErrorResult rv;
|
||||
MozClearDataAt(aFormat, aIndex, rv);
|
||||
MozClearDataAt(aFormat, aIndex, Some(nsContentUtils::SubjectPrincipal()), rv);
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
|
|
|
@ -144,6 +144,7 @@ public:
|
|||
ErrorResult& aRv);
|
||||
|
||||
void ClearData(const mozilla::dom::Optional<nsAString>& aFormat,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<FileList> GetFiles(mozilla::ErrorResult& aRv);
|
||||
|
@ -170,6 +171,7 @@ public:
|
|||
mozilla::ErrorResult& aRv) const;
|
||||
|
||||
void MozClearDataAt(const nsAString& aFormat, uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
void MozSetDataAt(JSContext* aCx, const nsAString& aFormat,
|
||||
|
@ -307,6 +309,7 @@ protected:
|
|||
nsIPrincipal* aPrincipal);
|
||||
|
||||
void MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
|
|
|
@ -238,21 +238,18 @@ DataTransferItem::FillInExternalData()
|
|||
}
|
||||
|
||||
already_AddRefed<File>
|
||||
DataTransferItem::GetAsFile(ErrorResult& aRv)
|
||||
DataTransferItem::GetAsFile(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
return GetAsFileWithPrincipal(nsContentUtils::SubjectPrincipal(), aRv);
|
||||
}
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
already_AddRefed<File>
|
||||
DataTransferItem::GetAsFileWithPrincipal(nsIPrincipal* aPrincipal, ErrorResult& aRv)
|
||||
{
|
||||
if (mKind != KIND_FILE) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// This is done even if we have an mCachedFile, as it performs the necessary
|
||||
// permissions checks to ensure that we are allowed to access this type.
|
||||
nsCOMPtr<nsIVariant> data = Data(aPrincipal, aRv);
|
||||
nsCOMPtr<nsIVariant> data = Data(aSubjectPrincipal.value(), aRv);
|
||||
if (NS_WARN_IF(!data || aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -286,16 +283,12 @@ DataTransferItem::GetAsFileWithPrincipal(nsIPrincipal* aPrincipal, ErrorResult&
|
|||
}
|
||||
|
||||
already_AddRefed<FileSystemEntry>
|
||||
DataTransferItem::GetAsEntry(ErrorResult& aRv)
|
||||
DataTransferItem::GetAsEntry(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
return GetAsEntryWithPrincipal(nsContentUtils::SubjectPrincipal(), aRv);
|
||||
}
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
already_AddRefed<FileSystemEntry>
|
||||
DataTransferItem::GetAsEntryWithPrincipal(nsIPrincipal* aPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<File> file = GetAsFileWithPrincipal(aPrincipal, aRv);
|
||||
RefPtr<File> file = GetAsFile(aSubjectPrincipal, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed()) || !file) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -393,8 +386,11 @@ DataTransferItem::CreateFileFromInputStream(nsIInputStream* aStream)
|
|||
|
||||
void
|
||||
DataTransferItem::GetAsString(FunctionStringCallback* aCallback,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (!aCallback || mKind != KIND_STRING) {
|
||||
return;
|
||||
}
|
||||
|
@ -402,7 +398,7 @@ DataTransferItem::GetAsString(FunctionStringCallback* aCallback,
|
|||
// Theoretically this should be done inside of the runnable, as it might be an
|
||||
// expensive operation on some systems, however we wouldn't get access to the
|
||||
// NS_ERROR_DOM_SECURITY_ERROR messages which may be raised by this method.
|
||||
nsCOMPtr<nsIVariant> data = Data(nsContentUtils::SubjectPrincipal(), aRv);
|
||||
nsCOMPtr<nsIVariant> data = Data(aSubjectPrincipal.value(), aRv);
|
||||
if (NS_WARN_IF(!data || aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -50,7 +50,9 @@ public:
|
|||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
// NOTE: This accesses the subject principal, and should not be called from C++
|
||||
void GetAsString(FunctionStringCallback* aCallback, ErrorResult& aRv);
|
||||
void GetAsString(FunctionStringCallback* aCallback,
|
||||
const Maybe<nsIPrincipal*>& aPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void GetKind(nsAString& aKind) const
|
||||
{
|
||||
|
@ -82,15 +84,11 @@ public:
|
|||
mKind = aKind;
|
||||
}
|
||||
|
||||
// NOTE: This accesses the subject principal, and should not be called from C++
|
||||
already_AddRefed<File> GetAsFile(ErrorResult& aRv);
|
||||
already_AddRefed<File> GetAsFileWithPrincipal(nsIPrincipal* aPrincipal,
|
||||
ErrorResult& aRv);
|
||||
already_AddRefed<File>
|
||||
GetAsFile(const Maybe<nsIPrincipal*>& aSubjectPrincipal, ErrorResult& aRv);
|
||||
|
||||
// NOTE: This accesses the subject principal, and should not be called from C++
|
||||
already_AddRefed<FileSystemEntry> GetAsEntry(ErrorResult& aRv);
|
||||
already_AddRefed<FileSystemEntry> GetAsEntryWithPrincipal(nsIPrincipal* aPrincipal,
|
||||
ErrorResult& aRv);
|
||||
already_AddRefed<FileSystemEntry>
|
||||
GetAsEntry(const Maybe<nsIPrincipal*>& aSubjectPrincipal, ErrorResult& aRv);
|
||||
|
||||
DataTransfer* GetParentObject() const
|
||||
{
|
||||
|
|
|
@ -81,8 +81,12 @@ DataTransferItemList::Clone(DataTransfer* aDataTransfer) const
|
|||
}
|
||||
|
||||
void
|
||||
DataTransferItemList::Remove(uint32_t aIndex, ErrorResult& aRv)
|
||||
DataTransferItemList::Remove(uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (mDataTransfer->IsReadOnly()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
|
@ -93,7 +97,7 @@ DataTransferItemList::Remove(uint32_t aIndex, ErrorResult& aRv)
|
|||
return;
|
||||
}
|
||||
|
||||
ClearDataHelper(mItems[aIndex], aIndex, -1, aRv);
|
||||
ClearDataHelper(mItems[aIndex], aIndex, -1, aSubjectPrincipal, aRv);
|
||||
}
|
||||
|
||||
DataTransferItem*
|
||||
|
@ -122,8 +126,11 @@ DataTransferItemList::MozItemCount() const
|
|||
}
|
||||
|
||||
void
|
||||
DataTransferItemList::Clear(ErrorResult& aRv)
|
||||
DataTransferItemList::Clear(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (NS_WARN_IF(mDataTransfer->IsReadOnly())) {
|
||||
return;
|
||||
}
|
||||
|
@ -132,7 +139,7 @@ DataTransferItemList::Clear(ErrorResult& aRv)
|
|||
for (uint32_t i = 0; i < count; i++) {
|
||||
// We always remove the last item first, to avoid moving items around in
|
||||
// memory as much
|
||||
Remove(Length() - 1, aRv);
|
||||
Remove(Length() - 1, aSubjectPrincipal, aRv);
|
||||
ENSURE_SUCCESS_VOID(aRv);
|
||||
}
|
||||
|
||||
|
@ -142,8 +149,11 @@ DataTransferItemList::Clear(ErrorResult& aRv)
|
|||
DataTransferItem*
|
||||
DataTransferItemList::Add(const nsAString& aData,
|
||||
const nsAString& aType,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (NS_WARN_IF(mDataTransfer->IsReadOnly())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -153,9 +163,8 @@ DataTransferItemList::Add(const nsAString& aData,
|
|||
nsAutoString format;
|
||||
mDataTransfer->GetRealFormat(aType, format);
|
||||
|
||||
nsIPrincipal* subjectPrincipal = nsContentUtils::SubjectPrincipal();
|
||||
|
||||
if (!DataTransfer::PrincipalMaySetData(format, data, subjectPrincipal)) {
|
||||
if (!DataTransfer::PrincipalMaySetData(format, data,
|
||||
aSubjectPrincipal.value())) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -163,7 +172,7 @@ DataTransferItemList::Add(const nsAString& aData,
|
|||
// We add the textual data to index 0. We set aInsertOnly to true, as we don't
|
||||
// want to update an existing entry if it is already present, as per the spec.
|
||||
RefPtr<DataTransferItem> item =
|
||||
SetDataWithPrincipal(format, data, 0, subjectPrincipal,
|
||||
SetDataWithPrincipal(format, data, 0, aSubjectPrincipal.value(),
|
||||
/* aInsertOnly = */ true,
|
||||
/* aHidden = */ false,
|
||||
aRv);
|
||||
|
@ -176,8 +185,12 @@ DataTransferItemList::Add(const nsAString& aData,
|
|||
}
|
||||
|
||||
DataTransferItem*
|
||||
DataTransferItemList::Add(File& aData, ErrorResult& aRv)
|
||||
DataTransferItemList::Add(File& aData,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (mDataTransfer->IsReadOnly()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -189,9 +202,8 @@ DataTransferItemList::Add(File& aData, ErrorResult& aRv)
|
|||
nsAutoString type;
|
||||
aData.GetType(type);
|
||||
|
||||
nsIPrincipal* subjectPrincipal = nsContentUtils::SubjectPrincipal();
|
||||
|
||||
if (!DataTransfer::PrincipalMaySetData(type, data, subjectPrincipal)) {
|
||||
if (!DataTransfer::PrincipalMaySetData(type, data,
|
||||
aSubjectPrincipal.value())) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -201,7 +213,7 @@ DataTransferItemList::Add(File& aData, ErrorResult& aRv)
|
|||
// the internal specced layout.
|
||||
uint32_t index = mIndexedItems.Length();
|
||||
RefPtr<DataTransferItem> item =
|
||||
SetDataWithPrincipal(type, data, index, subjectPrincipal,
|
||||
SetDataWithPrincipal(type, data, index, aSubjectPrincipal.value(),
|
||||
/* aInsertOnly = */ true,
|
||||
/* aHidden = */ false,
|
||||
aRv);
|
||||
|
@ -260,8 +272,11 @@ DataTransferItemList::Files(nsIPrincipal* aPrincipal)
|
|||
void
|
||||
DataTransferItemList::MozRemoveByTypeAt(const nsAString& aType,
|
||||
uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (NS_WARN_IF(mDataTransfer->IsReadOnly() ||
|
||||
aIndex >= mIndexedItems.Length())) {
|
||||
return;
|
||||
|
@ -278,7 +293,7 @@ DataTransferItemList::MozRemoveByTypeAt(const nsAString& aType,
|
|||
uint32_t index = items.Length() - 1;
|
||||
MOZ_ASSERT(index == count - i - 1);
|
||||
|
||||
ClearDataHelper(items[index], -1, index, aRv);
|
||||
ClearDataHelper(items[index], -1, index, aSubjectPrincipal, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
@ -294,7 +309,7 @@ DataTransferItemList::MozRemoveByTypeAt(const nsAString& aType,
|
|||
nsAutoString type;
|
||||
items[i]->GetType(type);
|
||||
if (type == aType) {
|
||||
ClearDataHelper(items[i], -1, i, aRv);
|
||||
ClearDataHelper(items[i], -1, i, aSubjectPrincipal, aRv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -469,6 +484,7 @@ void
|
|||
DataTransferItemList::ClearDataHelper(DataTransferItem* aItem,
|
||||
uint32_t aIndexHint,
|
||||
uint32_t aMozOffsetHint,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aItem);
|
||||
|
@ -476,9 +492,8 @@ DataTransferItemList::ClearDataHelper(DataTransferItem* aItem,
|
|||
return;
|
||||
}
|
||||
|
||||
nsIPrincipal* principal = nsContentUtils::SubjectPrincipal();
|
||||
if (aItem->Principal() && principal &&
|
||||
!principal->Subsumes(aItem->Principal())) {
|
||||
if (aItem->Principal() && aSubjectPrincipal.isSome() &&
|
||||
!aSubjectPrincipal.value()->Subsumes(aItem->Principal())) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
|
@ -557,7 +572,7 @@ DataTransferItemList::GenerateFiles(FileList* aFiles,
|
|||
}
|
||||
|
||||
if (item->Kind() == DataTransferItem::KIND_FILE) {
|
||||
RefPtr<File> file = item->GetAsFileWithPrincipal(aFilesPrincipal, rv);
|
||||
RefPtr<File> file = item->GetAsFile(Some(aFilesPrincipal), rv);
|
||||
if (NS_WARN_IF(rv.Failed() || !file)) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -51,10 +51,15 @@ public:
|
|||
};
|
||||
|
||||
DataTransferItem* Add(const nsAString& aData, const nsAString& aType,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& rv);
|
||||
DataTransferItem* Add(File& aData, ErrorResult& aRv);
|
||||
DataTransferItem* Add(File& aData,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void Remove(uint32_t aIndex, ErrorResult& aRv);
|
||||
void Remove(uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
DataTransferItem* IndexedGetter(uint32_t aIndex, bool& aFound,
|
||||
ErrorResult& aRv) const;
|
||||
|
@ -64,7 +69,7 @@ public:
|
|||
return mDataTransfer;
|
||||
}
|
||||
|
||||
void Clear(ErrorResult& aRv);
|
||||
void Clear(const Maybe<nsIPrincipal*>& aSubjectPrincipal, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<DataTransferItem>
|
||||
SetDataWithPrincipal(const nsAString& aType, nsIVariant* aData,
|
||||
|
@ -75,6 +80,7 @@ public:
|
|||
|
||||
// Moz-style helper methods for interacting with the stored data
|
||||
void MozRemoveByTypeAt(const nsAString& aType, uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
DataTransferItem* MozItemByTypeAt(const nsAString& aType, uint32_t aIndex);
|
||||
const nsTArray<RefPtr<DataTransferItem>>* MozItemsAt(uint32_t aIndex);
|
||||
|
@ -89,7 +95,9 @@ public:
|
|||
|
||||
private:
|
||||
void ClearDataHelper(DataTransferItem* aItem, uint32_t aIndexHint,
|
||||
uint32_t aMozOffsetHint, ErrorResult& aRv);
|
||||
uint32_t aMozOffsetHint,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
DataTransferItem* AppendNewItem(uint32_t aIndex, const nsAString& aType,
|
||||
nsIVariant* aData, nsIPrincipal* aPrincipal,
|
||||
bool aHidden);
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "mozilla/Telemetry.h"
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsISettingsService.h"
|
||||
|
||||
#include "nsGeolocation.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
|
@ -32,7 +31,6 @@
|
|||
#include "mozilla/dom/Event.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "mozilla/dom/PermissionMessageUtils.h"
|
||||
#include "mozilla/dom/SettingChangeNotificationBinding.h"
|
||||
#include "mozilla/dom/WakeLock.h"
|
||||
|
||||
class nsIPrincipal;
|
||||
|
@ -62,9 +60,6 @@ class nsIPrincipal;
|
|||
// that a window can make.
|
||||
#define MAX_GEO_REQUESTS_PER_WINDOW 1500
|
||||
|
||||
// The settings key.
|
||||
#define GEO_SETTINGS_ENABLED "geolocation.enabled"
|
||||
|
||||
using mozilla::Unused; // <snicker>
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -150,53 +145,6 @@ CreatePositionOptionsCopy(const PositionOptions& aOptions)
|
|||
return geoOptions;
|
||||
}
|
||||
|
||||
class GeolocationSettingsCallback : public nsISettingsServiceCallback
|
||||
{
|
||||
virtual ~GeolocationSettingsCallback() {
|
||||
MOZ_COUNT_DTOR(GeolocationSettingsCallback);
|
||||
}
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
GeolocationSettingsCallback() {
|
||||
MOZ_COUNT_CTOR(GeolocationSettingsCallback);
|
||||
}
|
||||
|
||||
NS_IMETHOD Handle(const nsAString& aName, JS::Handle<JS::Value> aResult) override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// The geolocation is enabled by default:
|
||||
bool value = true;
|
||||
if (aResult.isBoolean()) {
|
||||
value = aResult.toBoolean();
|
||||
}
|
||||
|
||||
MozSettingValue(value);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD HandleError(const nsAString& aName) override
|
||||
{
|
||||
NS_WARNING("Unable to get value for '" GEO_SETTINGS_ENABLED "'");
|
||||
|
||||
// Default it's enabled:
|
||||
MozSettingValue(true);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void MozSettingValue(const bool aValue)
|
||||
{
|
||||
RefPtr<nsGeolocationService> gs = nsGeolocationService::GetGeolocationService();
|
||||
if (gs) {
|
||||
gs->HandleMozsettingValue(aValue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(GeolocationSettingsCallback, nsISettingsServiceCallback)
|
||||
|
||||
class RequestPromptEvent : public Runnable
|
||||
{
|
||||
public:
|
||||
|
@ -382,12 +330,14 @@ NS_INTERFACE_MAP_END
|
|||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsGeolocationRequest)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsGeolocationRequest)
|
||||
NS_IMPL_CYCLE_COLLECTION(nsGeolocationRequest, mCallback, mErrorCallback, mLocator)
|
||||
|
||||
void
|
||||
nsGeolocationRequest::Notify()
|
||||
{
|
||||
SetTimeoutTimer();
|
||||
NotifyErrorAndShutdown(nsIDOMGeoPositionError::TIMEOUT);
|
||||
}
|
||||
|
||||
void
|
||||
nsGeolocationRequest::NotifyErrorAndShutdown(uint16_t aErrorCode)
|
||||
{
|
||||
|
@ -559,6 +509,7 @@ nsGeolocationRequest::GetRequester(nsIContentPermissionRequester** aRequester)
|
|||
|
||||
nsCOMPtr<nsIContentPermissionRequester> requester = mRequester;
|
||||
requester.forget(aRequester);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -638,6 +589,7 @@ nsGeolocationRequest::SendLocation(nsIDOMGeoPosition* aPosition)
|
|||
MOZ_ASSERT(mShutdown || mIsWatchPositionRequest,
|
||||
"non-shutdown getCurrentPosition request after callback!");
|
||||
}
|
||||
|
||||
nsIPrincipal*
|
||||
nsGeolocationRequest::GetPrincipal()
|
||||
{
|
||||
|
@ -654,6 +606,7 @@ nsGeolocationRequest::Update(nsIDOMGeoPosition* aPosition)
|
|||
NS_DispatchToMainThread(ev);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGeolocationRequest::NotifyError(uint16_t aErrorCode)
|
||||
{
|
||||
|
@ -695,6 +648,7 @@ nsGeolocationRequest::TimerCallbackHolder::Notify(nsITimer*)
|
|||
RefPtr<nsGeolocationRequest> request(mRequest);
|
||||
request->Notify();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -713,7 +667,6 @@ NS_IMPL_RELEASE(nsGeolocationService)
|
|||
|
||||
|
||||
static bool sGeoEnabled = true;
|
||||
static bool sGeoInitPending = true;
|
||||
static int32_t sProviderTimeout = 6000; // Time, in milliseconds, to wait for the location provider to spin up.
|
||||
|
||||
nsresult nsGeolocationService::Init()
|
||||
|
@ -726,28 +679,9 @@ nsresult nsGeolocationService::Init()
|
|||
}
|
||||
|
||||
if (XRE_IsContentProcess()) {
|
||||
sGeoInitPending = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// check if the geolocation service is enable from settings
|
||||
nsCOMPtr<nsISettingsService> settings =
|
||||
do_GetService("@mozilla.org/settingsService;1");
|
||||
|
||||
if (settings) {
|
||||
nsCOMPtr<nsISettingsServiceLock> settingsLock;
|
||||
nsresult rv = settings->CreateLock(nullptr, getter_AddRefs(settingsLock));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
RefPtr<GeolocationSettingsCallback> callback = new GeolocationSettingsCallback();
|
||||
rv = settingsLock->Get(GEO_SETTINGS_ENABLED, callback);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
// If we cannot obtain the settings service, we continue
|
||||
// assuming that the geolocation is enabled:
|
||||
sGeoInitPending = false;
|
||||
}
|
||||
|
||||
// geolocation service can be enabled -> now register observer
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
if (!obs) {
|
||||
|
@ -755,7 +689,6 @@ nsresult nsGeolocationService::Init()
|
|||
}
|
||||
|
||||
obs->AddObserver(this, "xpcom-shutdown", false);
|
||||
obs->AddObserver(this, "mozsettings-changed", false);
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
mProvider = new AndroidLocationProvider();
|
||||
|
@ -816,47 +749,6 @@ nsGeolocationService::~nsGeolocationService()
|
|||
{
|
||||
}
|
||||
|
||||
void
|
||||
nsGeolocationService::HandleMozsettingChanged(nsISupports* aSubject)
|
||||
{
|
||||
// The string that we're interested in will be a JSON string that looks like:
|
||||
// {"key":"gelocation.enabled","value":true}
|
||||
|
||||
RootedDictionary<SettingChangeNotification> setting(RootingCx());
|
||||
if (!WrappedJSToDictionary(aSubject, setting)) {
|
||||
return;
|
||||
}
|
||||
if (!setting.mKey.EqualsASCII(GEO_SETTINGS_ENABLED)) {
|
||||
return;
|
||||
}
|
||||
if (!setting.mValue.isBoolean()) {
|
||||
return;
|
||||
}
|
||||
|
||||
HandleMozsettingValue(setting.mValue.toBoolean());
|
||||
}
|
||||
|
||||
void
|
||||
nsGeolocationService::HandleMozsettingValue(const bool aValue)
|
||||
{
|
||||
if (!aValue) {
|
||||
// turn things off
|
||||
StopDevice();
|
||||
Update(nullptr);
|
||||
mLastPosition.position = nullptr;
|
||||
sGeoEnabled = false;
|
||||
} else {
|
||||
sGeoEnabled = true;
|
||||
}
|
||||
|
||||
if (sGeoInitPending) {
|
||||
sGeoInitPending = false;
|
||||
for (uint32_t i = 0, length = mGeolocators.Length(); i < length; ++i) {
|
||||
mGeolocators[i]->ServiceReady();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGeolocationService::Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
|
@ -866,7 +758,6 @@ nsGeolocationService::Observe(nsISupports* aSubject,
|
|||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->RemoveObserver(this, "xpcom-shutdown");
|
||||
obs->RemoveObserver(this, "mozsettings-changed");
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i< mGeolocators.Length(); i++) {
|
||||
|
@ -877,11 +768,6 @@ nsGeolocationService::Observe(nsISupports* aSubject,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!strcmp("mozsettings-changed", aTopic)) {
|
||||
HandleMozsettingChanged(aSubject);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!strcmp("timer-callback", aTopic)) {
|
||||
// decide if we can close down the service.
|
||||
for (uint32_t i = 0; i< mGeolocators.Length(); i++)
|
||||
|
@ -905,11 +791,14 @@ nsGeolocationService::Update(nsIDOMGeoPosition *aSomewhere)
|
|||
if (aSomewhere) {
|
||||
SetCachedPosition(aSomewhere);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i< mGeolocators.Length(); i++) {
|
||||
mGeolocators[i]->Update(aSomewhere);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGeolocationService::NotifyError(uint16_t aErrorCode)
|
||||
{
|
||||
|
@ -935,7 +824,7 @@ nsGeolocationService::GetCachedPosition()
|
|||
nsresult
|
||||
nsGeolocationService::StartDevice(nsIPrincipal *aPrincipal)
|
||||
{
|
||||
if (!sGeoEnabled || sGeoInitPending) {
|
||||
if (!sGeoEnabled) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
|
@ -986,7 +875,6 @@ nsGeolocationService::StopDisconnectTimer()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsGeolocationService::SetDisconnectTimer()
|
||||
{
|
||||
|
@ -1009,6 +897,7 @@ nsGeolocationService::HighAccuracyRequested()
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1022,17 +911,11 @@ nsGeolocationService::UpdateAccuracy(bool aForceHigh)
|
|||
if (cpc->IsAlive()) {
|
||||
cpc->SendSetGeolocationHigherAccuracy(highRequired);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mHigherAccuracy && highRequired) {
|
||||
mProvider->SetHighAccuracy(true);
|
||||
}
|
||||
|
||||
if (mHigherAccuracy && !highRequired) {
|
||||
mProvider->SetHighAccuracy(false);
|
||||
}
|
||||
|
||||
mProvider->SetHighAccuracy(!mHigherAccuracy && highRequired);
|
||||
mHigherAccuracy = highRequired;
|
||||
}
|
||||
|
||||
|
@ -1044,6 +927,7 @@ nsGeolocationService::StopDevice()
|
|||
if (XRE_IsContentProcess()) {
|
||||
ContentChild* cpc = ContentChild::GetSingleton();
|
||||
cpc->SendRemoveGeolocationListener();
|
||||
|
||||
return; // bail early
|
||||
}
|
||||
|
||||
|
@ -1072,6 +956,7 @@ nsGeolocationService::GetGeolocationService()
|
|||
RefPtr<nsGeolocationService> result;
|
||||
if (nsGeolocationService::sService) {
|
||||
result = nsGeolocationService::sService;
|
||||
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
|
@ -1079,6 +964,7 @@ nsGeolocationService::GetGeolocationService()
|
|||
if (NS_FAILED(result->Init())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ClearOnShutdown(&nsGeolocationService::sService);
|
||||
nsGeolocationService::sService = result;
|
||||
return result.forget();
|
||||
|
@ -1183,21 +1069,21 @@ Geolocation::Init(nsPIDOMWindowInner* aContentDom)
|
|||
if (mService) {
|
||||
mService->AddLocator(this);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
Geolocation::ContainsRequest(nsGeolocationRequest* aRequest)
|
||||
{
|
||||
if (aRequest->IsWatch()) {
|
||||
if (mWatchingCallbacks.Contains(aRequest)) {
|
||||
if (aRequest->IsWatch() && mWatchingCallbacks.Contains(aRequest)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (mPendingCallbacks.Contains(aRequest)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mPendingCallbacks.Contains(aRequest)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1221,23 +1107,27 @@ Geolocation::HandleEvent(nsIDOMEvent* aEvent)
|
|||
|
||||
MOZ_ASSERT(XRE_IsContentProcess());
|
||||
ContentChild* cpc = ContentChild::GetSingleton();
|
||||
|
||||
if (!info.lockingProcesses().Contains(cpc->GetID())) {
|
||||
cpc->SendRemoveGeolocationListener();
|
||||
mService->StopDisconnectTimer();
|
||||
}
|
||||
} else {
|
||||
mService->SetDisconnectTimer();
|
||||
|
||||
// We will unconditionally allow all the requests in the callbacks
|
||||
// because if a request is put into either of these two callbacks,
|
||||
// it means that it has been allowed before.
|
||||
// That's why when we resume them, we unconditionally allow them again.
|
||||
for (uint32_t i = 0, length = mWatchingCallbacks.Length(); i < length; ++i) {
|
||||
mWatchingCallbacks[i]->Allow(JS::UndefinedHandleValue);
|
||||
}
|
||||
for (uint32_t i = 0, length = mPendingCallbacks.Length(); i < length; ++i) {
|
||||
mPendingCallbacks[i]->Allow(JS::UndefinedHandleValue);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mService->SetDisconnectTimer();
|
||||
|
||||
// We will unconditionally allow all the requests in the callbacks
|
||||
// because if a request is put into either of these two callbacks,
|
||||
// it means that it has been allowed before.
|
||||
// That's why when we resume them, we unconditionally allow them again.
|
||||
for (uint32_t i = 0, length = mWatchingCallbacks.Length(); i < length; ++i) {
|
||||
mWatchingCallbacks[i]->Allow(JS::UndefinedHandleValue);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0, length = mPendingCallbacks.Length(); i < length; ++i) {
|
||||
mPendingCallbacks[i]->Allow(JS::UndefinedHandleValue);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1338,8 +1228,10 @@ Geolocation::Update(nsIDOMGeoPosition *aSomewhere)
|
|||
for (uint32_t i = 0; i < mWatchingCallbacks.Length(); i++) {
|
||||
mWatchingCallbacks[i]->Update(aSomewhere);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Geolocation::NotifyError(uint16_t aErrorCode)
|
||||
{
|
||||
|
@ -1347,6 +1239,7 @@ Geolocation::NotifyError(uint16_t aErrorCode)
|
|||
Shutdown();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mozilla::Telemetry::Accumulate(mozilla::Telemetry::GEOLOCATION_ERROR, true);
|
||||
|
||||
for (uint32_t i = mPendingCallbacks.Length(); i > 0; i--) {
|
||||
|
@ -1370,6 +1263,7 @@ Geolocation::IsAlreadyCleared(nsGeolocationRequest* aRequest)
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1381,6 +1275,7 @@ Geolocation::ClearPendingRequest(nsGeolocationRequest* aRequest)
|
|||
this->ClearWatch(aRequest->WatchId());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1443,11 +1338,6 @@ Geolocation::GetCurrentPosition(GeoPositionCallback callback,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (sGeoInitPending) {
|
||||
mPendingRequests.AppendElement(request);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return GetCurrentPositionReady(request);
|
||||
}
|
||||
|
||||
|
@ -1535,11 +1425,6 @@ Geolocation::WatchPosition(GeoPositionCallback aCallback,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (sGeoInitPending) {
|
||||
mPendingRequests.AppendElement(request);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return WatchPositionReady(request);
|
||||
}
|
||||
|
||||
|
|
|
@ -72,9 +72,6 @@ public:
|
|||
|
||||
nsresult Init();
|
||||
|
||||
void HandleMozsettingChanged(nsISupports* aSubject);
|
||||
void HandleMozsettingValue(const bool aValue);
|
||||
|
||||
// Management of the Geolocation objects
|
||||
void AddLocator(mozilla::dom::Geolocation* locator);
|
||||
void RemoveLocator(mozilla::dom::Geolocation* locator);
|
||||
|
|
|
@ -117,6 +117,7 @@ HTMLImageElement::HTMLImageElement(already_AddRefed<mozilla::dom::NodeInfo>& aNo
|
|||
: nsGenericHTMLElement(aNodeInfo)
|
||||
, mForm(nullptr)
|
||||
, mInDocResponsiveContent(false)
|
||||
, mCurrentDensity(1.0)
|
||||
{
|
||||
// We start out broken
|
||||
AddStatesSilently(NS_EVENT_STATE_BROKEN);
|
||||
|
@ -951,6 +952,19 @@ HTMLImageElement::InResponsiveMode()
|
|||
HaveSrcsetOrInPicture();
|
||||
}
|
||||
|
||||
bool
|
||||
HTMLImageElement::SelectedSourceMatchesLast(nsIURI* aSelectedSource, double aSelectedDensity)
|
||||
{
|
||||
// If there was no selected source previously, we don't want to short-circuit the load.
|
||||
// Similarly for if there is no newly selected source.
|
||||
if (!mLastSelectedSource || !aSelectedSource) {
|
||||
return false;
|
||||
}
|
||||
bool equal = false;
|
||||
return NS_SUCCEEDED(mLastSelectedSource->Equals(aSelectedSource, &equal)) && equal &&
|
||||
aSelectedDensity == mCurrentDensity;
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLImageElement::LoadSelectedImage(bool aForce, bool aNotify, bool aAlwaysLoad)
|
||||
{
|
||||
|
@ -965,8 +979,15 @@ HTMLImageElement::LoadSelectedImage(bool aForce, bool aNotify, bool aAlwaysLoad)
|
|||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> selectedSource;
|
||||
double currentDensity = 1.0; // default to 1.0 for the src attribute case
|
||||
if (mResponsiveSelector) {
|
||||
nsCOMPtr<nsIURI> url = mResponsiveSelector->GetSelectedImageURL();
|
||||
selectedSource = url;
|
||||
currentDensity = mResponsiveSelector->GetSelectedImageDensity();
|
||||
if (!aAlwaysLoad && SelectedSourceMatchesLast(selectedSource, currentDensity)) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (url) {
|
||||
rv = LoadImage(url, aForce, aNotify, eImageLoadType_Imageset);
|
||||
}
|
||||
|
@ -976,6 +997,14 @@ HTMLImageElement::LoadSelectedImage(bool aForce, bool aNotify, bool aAlwaysLoad)
|
|||
CancelImageRequests(aNotify);
|
||||
rv = NS_OK;
|
||||
} else {
|
||||
nsIDocument* doc = GetOurOwnerDoc();
|
||||
if (doc) {
|
||||
StringToURI(src, doc, getter_AddRefs(selectedSource));
|
||||
if (!aAlwaysLoad && SelectedSourceMatchesLast(selectedSource, currentDensity)) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a srcset attribute or are in a <picture> element,
|
||||
// we always use the Imageset load type, even if we parsed no
|
||||
// valid responsive sources from either, per spec.
|
||||
|
@ -984,6 +1013,8 @@ HTMLImageElement::LoadSelectedImage(bool aForce, bool aNotify, bool aAlwaysLoad)
|
|||
: eImageLoadType_Normal);
|
||||
}
|
||||
}
|
||||
mLastSelectedSource = selectedSource;
|
||||
mCurrentDensity = currentDensity;
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
CancelImageRequests(aNotify);
|
||||
|
|
|
@ -292,6 +292,9 @@ protected:
|
|||
// only mode after Bug 1076583
|
||||
bool InResponsiveMode();
|
||||
|
||||
// True if the given URL and density equal the last URL and density that was loaded by this element.
|
||||
bool SelectedSourceMatchesLast(nsIURI* aSelectedSource, double aSelectedDensity);
|
||||
|
||||
// Resolve and load the current mResponsiveSelector (responsive mode) or src
|
||||
// attr image.
|
||||
nsresult LoadSelectedImage(bool aForce, bool aNotify, bool aAlwaysLoad);
|
||||
|
@ -363,6 +366,11 @@ private:
|
|||
|
||||
bool mInDocResponsiveContent;
|
||||
RefPtr<ImageLoadTask> mPendingImageLoadTask;
|
||||
|
||||
// Last URL that was attempted to load by this element.
|
||||
nsCOMPtr<nsIURI> mLastSelectedSource;
|
||||
// Last pixel density that was selected.
|
||||
double mCurrentDensity;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -542,7 +542,7 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
|
|||
}
|
||||
|
||||
bool html = contentType.EqualsLiteral(TEXT_HTML);
|
||||
bool xhtml = !html && contentType.EqualsLiteral(APPLICATION_XHTML_XML);
|
||||
bool xhtml = !html && (contentType.EqualsLiteral(APPLICATION_XHTML_XML) || contentType.EqualsLiteral(APPLICATION_WAPXHTML_XML));
|
||||
bool plainText = !html && !xhtml && nsContentUtils::IsPlainTextType(contentType);
|
||||
if (!(html || xhtml || plainText || viewSource)) {
|
||||
MOZ_ASSERT(false, "Channel with bad content type.");
|
||||
|
|
|
@ -118,7 +118,7 @@ SimpleTest.waitForExplicitFinish();
|
|||
|
||||
function runTest()
|
||||
{
|
||||
SimpleTest.requestLongerTimeout(2);
|
||||
SimpleTest.requestLongerTimeout(4);
|
||||
|
||||
var data = [
|
||||
{
|
||||
|
|
|
@ -79,8 +79,9 @@ protected:
|
|||
nsString mMcc;
|
||||
nsString mMnc;
|
||||
nsString mSpn;
|
||||
bool mIsDisplayNetworkNameRequired;
|
||||
bool mIsDisplaySpnRequired;
|
||||
// The following booleans shall be initialized either in the constructor or in Update
|
||||
MOZ_INIT_OUTSIDE_CTOR bool mIsDisplayNetworkNameRequired;
|
||||
MOZ_INIT_OUTSIDE_CTOR bool mIsDisplaySpnRequired;
|
||||
};
|
||||
|
||||
class GsmIccInfo final : public IccInfo
|
||||
|
@ -140,7 +141,8 @@ private:
|
|||
~CdmaIccInfo() {}
|
||||
|
||||
nsString mPhoneNumber;
|
||||
int32_t mPrlVersion;
|
||||
// The following integer shall be initialized either in the constructor or in Update
|
||||
MOZ_INIT_OUTSIDE_CTOR int32_t mPrlVersion;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -3,24 +3,13 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsIDOMDocument.idl"
|
||||
#include "nsISupports.idl"
|
||||
|
||||
// The only reason this interface still exists is that we have addon and Firefox
|
||||
// code QIing to it and using it for instanceof via Components.interfaces, and
|
||||
// the interface needs to exist in order for the shim stuff in
|
||||
// xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp to work.
|
||||
[uuid(89ab39cb-c568-4d85-bd34-306d5cd5164d)]
|
||||
interface nsIDOMXMLDocument : nsIDOMDocument
|
||||
interface nsIDOMXMLDocument : nsISupports
|
||||
{
|
||||
// DOM Level 3 Load & Save, DocumentLS
|
||||
// http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS
|
||||
/**
|
||||
* Whether to load synchronously or asynchronously.
|
||||
* The default is async==true.
|
||||
*/
|
||||
attribute boolean async;
|
||||
|
||||
/**
|
||||
* Load an XML document.
|
||||
*
|
||||
* @param url URL to an XML document.
|
||||
* @return True if load successfull.
|
||||
*/
|
||||
boolean load(in DOMString url);
|
||||
};
|
||||
|
|
|
@ -199,6 +199,11 @@ public:
|
|||
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
|
||||
}
|
||||
|
||||
if (!jni::IsFennec()) {
|
||||
NS_WARNING("Remote decoding not supported in non-Fennec environment\n");
|
||||
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
|
||||
}
|
||||
|
||||
// Register native methods.
|
||||
JavaCallbacksSupport::Init();
|
||||
|
||||
|
|
|
@ -593,7 +593,7 @@ CamerasChild::ShutdownChild()
|
|||
}
|
||||
|
||||
bool
|
||||
CamerasChild::RecvDeliverFrame(const int& capEngine,
|
||||
CamerasChild::RecvDeliverFrame(const CaptureEngine& capEngine,
|
||||
const int& capId,
|
||||
mozilla::ipc::Shmem&& shmem,
|
||||
const size_t& size,
|
||||
|
@ -602,13 +602,12 @@ CamerasChild::RecvDeliverFrame(const int& capEngine,
|
|||
const int64_t& render_time)
|
||||
{
|
||||
MutexAutoLock lock(mCallbackMutex);
|
||||
CaptureEngine capEng = static_cast<CaptureEngine>(capEngine);
|
||||
if (Callback(capEng, capId)) {
|
||||
if (Callback(capEngine, capId)) {
|
||||
unsigned char* image = shmem.get<unsigned char>();
|
||||
Callback(capEng, capId)->DeliverFrame(image, size,
|
||||
time_stamp,
|
||||
ntp_time, render_time,
|
||||
nullptr);
|
||||
Callback(capEngine, capId)->DeliverFrame(image, size,
|
||||
time_stamp,
|
||||
ntp_time, render_time,
|
||||
nullptr);
|
||||
} else {
|
||||
LOG(("DeliverFrame called with dead callback"));
|
||||
}
|
||||
|
@ -637,15 +636,14 @@ CamerasChild::SetFakeDeviceChangeEvents()
|
|||
}
|
||||
|
||||
bool
|
||||
CamerasChild::RecvFrameSizeChange(const int& capEngine,
|
||||
CamerasChild::RecvFrameSizeChange(const CaptureEngine& capEngine,
|
||||
const int& capId,
|
||||
const int& w, const int& h)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
MutexAutoLock lock(mCallbackMutex);
|
||||
CaptureEngine capEng = static_cast<CaptureEngine>(capEngine);
|
||||
if (Callback(capEng, capId)) {
|
||||
Callback(capEng, capId)->FrameSizeChange(w, h, 0);
|
||||
if (Callback(capEngine, capId)) {
|
||||
Callback(capEngine, capId)->FrameSizeChange(w, h, 0);
|
||||
} else {
|
||||
LOG(("Frame size change with dead callback"));
|
||||
}
|
||||
|
|
|
@ -33,16 +33,6 @@ class BackgroundChildImpl;
|
|||
|
||||
namespace camera {
|
||||
|
||||
enum CaptureEngine : int {
|
||||
InvalidEngine = 0,
|
||||
ScreenEngine,
|
||||
BrowserEngine,
|
||||
WinEngine,
|
||||
AppEngine,
|
||||
CameraEngine,
|
||||
MaxEngine
|
||||
};
|
||||
|
||||
struct CapturerElement {
|
||||
CaptureEngine engine;
|
||||
int id;
|
||||
|
@ -153,10 +143,10 @@ public:
|
|||
|
||||
// IPC messages recevied, received on the PBackground thread
|
||||
// these are the actual callbacks with data
|
||||
virtual bool RecvDeliverFrame(const int&, const int&, mozilla::ipc::Shmem&&,
|
||||
virtual bool RecvDeliverFrame(const CaptureEngine&, const int&, mozilla::ipc::Shmem&&,
|
||||
const size_t&, const uint32_t&, const int64_t&,
|
||||
const int64_t&) override;
|
||||
virtual bool RecvFrameSizeChange(const int&, const int&,
|
||||
virtual bool RecvFrameSizeChange(const CaptureEngine&, const int&,
|
||||
const int& w, const int& h) override;
|
||||
|
||||
virtual bool RecvDeviceChange() override;
|
||||
|
|
|
@ -513,7 +513,7 @@ CamerasParent::EnsureInitialized(int aEngine)
|
|||
// It would be nice to get rid of the code duplication here,
|
||||
// perhaps via Promises.
|
||||
bool
|
||||
CamerasParent::RecvNumberOfCaptureDevices(const int& aCapEngine)
|
||||
CamerasParent::RecvNumberOfCaptureDevices(const CaptureEngine& aCapEngine)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
|
||||
|
@ -547,7 +547,7 @@ CamerasParent::RecvNumberOfCaptureDevices(const int& aCapEngine)
|
|||
}
|
||||
|
||||
bool
|
||||
CamerasParent::RecvNumberOfCapabilities(const int& aCapEngine,
|
||||
CamerasParent::RecvNumberOfCapabilities(const CaptureEngine& aCapEngine,
|
||||
const nsCString& unique_id)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
|
@ -586,7 +586,7 @@ CamerasParent::RecvNumberOfCapabilities(const int& aCapEngine,
|
|||
}
|
||||
|
||||
bool
|
||||
CamerasParent::RecvGetCaptureCapability(const int &aCapEngine,
|
||||
CamerasParent::RecvGetCaptureCapability(const CaptureEngine& aCapEngine,
|
||||
const nsCString& unique_id,
|
||||
const int& num)
|
||||
{
|
||||
|
@ -636,7 +636,7 @@ CamerasParent::RecvGetCaptureCapability(const int &aCapEngine,
|
|||
}
|
||||
|
||||
bool
|
||||
CamerasParent::RecvGetCaptureDevice(const int& aCapEngine,
|
||||
CamerasParent::RecvGetCaptureDevice(const CaptureEngine& aCapEngine,
|
||||
const int& aListNumber)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
|
@ -739,7 +739,7 @@ HasCameraPermission(const nsCString& aOrigin)
|
|||
}
|
||||
|
||||
bool
|
||||
CamerasParent::RecvAllocateCaptureDevice(const int& aCapEngine,
|
||||
CamerasParent::RecvAllocateCaptureDevice(const CaptureEngine& aCapEngine,
|
||||
const nsCString& unique_id,
|
||||
const nsCString& aOrigin)
|
||||
{
|
||||
|
@ -796,7 +796,7 @@ CamerasParent::RecvAllocateCaptureDevice(const int& aCapEngine,
|
|||
}
|
||||
|
||||
int
|
||||
CamerasParent::ReleaseCaptureDevice(const int& aCapEngine,
|
||||
CamerasParent::ReleaseCaptureDevice(const CaptureEngine& aCapEngine,
|
||||
const int& capnum)
|
||||
{
|
||||
int error = -1;
|
||||
|
@ -807,7 +807,7 @@ CamerasParent::ReleaseCaptureDevice(const int& aCapEngine,
|
|||
}
|
||||
|
||||
bool
|
||||
CamerasParent::RecvReleaseCaptureDevice(const int& aCapEngine,
|
||||
CamerasParent::RecvReleaseCaptureDevice(const CaptureEngine& aCapEngine,
|
||||
const int& numdev)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
|
@ -841,7 +841,7 @@ CamerasParent::RecvReleaseCaptureDevice(const int& aCapEngine,
|
|||
}
|
||||
|
||||
bool
|
||||
CamerasParent::RecvStartCapture(const int& aCapEngine,
|
||||
CamerasParent::RecvStartCapture(const CaptureEngine& aCapEngine,
|
||||
const int& capnum,
|
||||
const CaptureCapability& ipcCaps)
|
||||
{
|
||||
|
@ -903,7 +903,7 @@ CamerasParent::RecvStartCapture(const int& aCapEngine,
|
|||
}
|
||||
|
||||
void
|
||||
CamerasParent::StopCapture(const int& aCapEngine,
|
||||
CamerasParent::StopCapture(const CaptureEngine& aCapEngine,
|
||||
const int& capnum)
|
||||
{
|
||||
if (EnsureInitialized(aCapEngine)) {
|
||||
|
@ -924,7 +924,7 @@ CamerasParent::StopCapture(const int& aCapEngine,
|
|||
}
|
||||
|
||||
bool
|
||||
CamerasParent::RecvStopCapture(const int& aCapEngine,
|
||||
CamerasParent::RecvStopCapture(const CaptureEngine& aCapEngine,
|
||||
const int& capnum)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
|
|
|
@ -99,14 +99,19 @@ public:
|
|||
static already_AddRefed<CamerasParent> Create();
|
||||
|
||||
// Messages received form the child. These run on the IPC/PBackground thread.
|
||||
virtual bool RecvAllocateCaptureDevice(const int&, const nsCString&, const nsCString&) override;
|
||||
virtual bool RecvReleaseCaptureDevice(const int&, const int &) override;
|
||||
virtual bool RecvNumberOfCaptureDevices(const int&) override;
|
||||
virtual bool RecvNumberOfCapabilities(const int&, const nsCString&) override;
|
||||
virtual bool RecvGetCaptureCapability(const int&, const nsCString&, const int&) override;
|
||||
virtual bool RecvGetCaptureDevice(const int&, const int&) override;
|
||||
virtual bool RecvStartCapture(const int&, const int&, const CaptureCapability&) override;
|
||||
virtual bool RecvStopCapture(const int&, const int&) override;
|
||||
virtual bool RecvAllocateCaptureDevice(const CaptureEngine&, const nsCString&,
|
||||
const nsCString&) override;
|
||||
virtual bool RecvReleaseCaptureDevice(const CaptureEngine&,
|
||||
const int&) override;
|
||||
virtual bool RecvNumberOfCaptureDevices(const CaptureEngine&) override;
|
||||
virtual bool RecvNumberOfCapabilities(const CaptureEngine&,
|
||||
const nsCString&) override;
|
||||
virtual bool RecvGetCaptureCapability(const CaptureEngine&, const nsCString&,
|
||||
const int&) override;
|
||||
virtual bool RecvGetCaptureDevice(const CaptureEngine&, const int&) override;
|
||||
virtual bool RecvStartCapture(const CaptureEngine&, const int&,
|
||||
const CaptureCapability&) override;
|
||||
virtual bool RecvStopCapture(const CaptureEngine&, const int&) override;
|
||||
virtual bool RecvReleaseFrame(mozilla::ipc::Shmem&&) override;
|
||||
virtual bool RecvAllDone() override;
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
@ -134,8 +139,8 @@ protected:
|
|||
virtual ~CamerasParent();
|
||||
|
||||
// We use these helpers for shutdown and for the respective IPC commands.
|
||||
void StopCapture(const int& aCapEngine, const int& capnum);
|
||||
int ReleaseCaptureDevice(const int& aCapEngine, const int& capnum);
|
||||
void StopCapture(const CaptureEngine& aCapEngine, const int& capnum);
|
||||
int ReleaseCaptureDevice(const CaptureEngine& aCapEngine, const int& capnum);
|
||||
|
||||
bool SetupEngine(CaptureEngine aCapEngine);
|
||||
bool EnsureInitialized(int aEngine);
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et ft=cpp : */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_CamerasTypes_h
|
||||
#define mozilla_CamerasTypes_h
|
||||
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace camera {
|
||||
|
||||
enum CaptureEngine : int {
|
||||
InvalidEngine = 0,
|
||||
ScreenEngine,
|
||||
BrowserEngine,
|
||||
WinEngine,
|
||||
AppEngine,
|
||||
CameraEngine,
|
||||
MaxEngine
|
||||
};
|
||||
|
||||
} // namespace camera
|
||||
} // namespace mozilla
|
||||
|
||||
namespace IPC {
|
||||
template<>
|
||||
struct ParamTraits<mozilla::camera::CaptureEngine> :
|
||||
public ContiguousEnumSerializer<mozilla::camera::CaptureEngine,
|
||||
mozilla::camera::CaptureEngine::InvalidEngine,
|
||||
mozilla::camera::CaptureEngine::MaxEngine>
|
||||
{ };
|
||||
}
|
||||
|
||||
#endif // mozilla_CamerasTypes_h
|
|
@ -5,6 +5,8 @@
|
|||
include protocol PContent;
|
||||
include protocol PBackground;
|
||||
|
||||
using mozilla::camera::CaptureEngine from "CamerasTypes.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace camera {
|
||||
|
||||
|
@ -24,9 +26,9 @@ async protocol PCameras
|
|||
manager PBackground;
|
||||
|
||||
child:
|
||||
async FrameSizeChange(int capEngine, int cap_id, int w, int h);
|
||||
async FrameSizeChange(CaptureEngine capEngine, int cap_id, int w, int h);
|
||||
// transfers ownership of |buffer| from parent to child
|
||||
async DeliverFrame(int capEngine, int cap_id,
|
||||
async DeliverFrame(CaptureEngine capEngine, int cap_id,
|
||||
Shmem buffer, size_t size, uint32_t time_stamp,
|
||||
int64_t ntp_time, int64_t render_time);
|
||||
async DeviceChange();
|
||||
|
@ -40,16 +42,16 @@ child:
|
|||
async __delete__();
|
||||
|
||||
parent:
|
||||
async NumberOfCaptureDevices(int engine);
|
||||
async NumberOfCapabilities(int engine, nsCString deviceUniqueIdUTF8);
|
||||
async NumberOfCaptureDevices(CaptureEngine engine);
|
||||
async NumberOfCapabilities(CaptureEngine engine, nsCString deviceUniqueIdUTF8);
|
||||
|
||||
async GetCaptureCapability(int engine, nsCString unique_idUTF8, int capability_number);
|
||||
async GetCaptureDevice(int engine, int num);
|
||||
async GetCaptureCapability(CaptureEngine engine, nsCString unique_idUTF8, int capability_number);
|
||||
async GetCaptureDevice(CaptureEngine engine, int num);
|
||||
|
||||
async AllocateCaptureDevice(int engine, nsCString unique_idUTF8, nsCString origin);
|
||||
async ReleaseCaptureDevice(int engine, int numdev);
|
||||
async StartCapture(int engine, int numdev, CaptureCapability capability);
|
||||
async StopCapture(int engine, int numdev);
|
||||
async AllocateCaptureDevice(CaptureEngine engine, nsCString unique_idUTF8, nsCString origin);
|
||||
async ReleaseCaptureDevice(CaptureEngine engine, int numdev);
|
||||
async StartCapture(CaptureEngine engine, int numdev, CaptureCapability capability);
|
||||
async StopCapture(CaptureEngine engine, int numdev);
|
||||
// transfers frame back
|
||||
async ReleaseFrame(Shmem s);
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ if CONFIG['MOZ_WEBRTC']:
|
|||
EXPORTS += [
|
||||
'CamerasChild.h',
|
||||
'CamerasParent.h',
|
||||
'CamerasTypes.h',
|
||||
'LoadManager.h',
|
||||
'LoadManagerFactory.h',
|
||||
'LoadMonitor.h',
|
||||
|
|
|
@ -610,7 +610,7 @@ JSValToNPVariant(NPP npp, JSContext *cx, JS::Value val, NPVariant *variant)
|
|||
}
|
||||
|
||||
static void
|
||||
ThrowJSException(JSContext *cx, const char *message)
|
||||
ThrowJSExceptionASCII(JSContext *cx, const char *message)
|
||||
{
|
||||
const char *ex = PeekException();
|
||||
|
||||
|
@ -638,7 +638,7 @@ ThrowJSException(JSContext *cx, const char *message)
|
|||
|
||||
PopException();
|
||||
} else {
|
||||
::JS_ReportError(cx, message);
|
||||
::JS_ReportErrorASCII(cx, message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -651,7 +651,7 @@ ReportExceptionIfPending(JSContext *cx)
|
|||
return true;
|
||||
}
|
||||
|
||||
ThrowJSException(cx, nullptr);
|
||||
ThrowJSExceptionASCII(cx, nullptr);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -736,8 +736,8 @@ nsJSObjWrapper::NP_HasMethod(NPObject *npobj, NPIdentifier id)
|
|||
JSContext *cx = aes.cx();
|
||||
|
||||
if (!npobj) {
|
||||
ThrowJSException(cx,
|
||||
"Null npobj in nsJSObjWrapper::NP_HasMethod!");
|
||||
ThrowJSExceptionASCII(cx,
|
||||
"Null npobj in nsJSObjWrapper::NP_HasMethod!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -772,7 +772,7 @@ doInvoke(NPObject *npobj, NPIdentifier method, const NPVariant *args,
|
|||
JSContext *cx = aes.cx();
|
||||
|
||||
if (!npobj || !result) {
|
||||
ThrowJSException(cx, "Null npobj, or result in doInvoke!");
|
||||
ThrowJSExceptionASCII(cx, "Null npobj, or result in doInvoke!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -864,8 +864,8 @@ nsJSObjWrapper::NP_HasProperty(NPObject *npobj, NPIdentifier npid)
|
|||
JSContext *cx = aes.cx();
|
||||
|
||||
if (!npobj) {
|
||||
ThrowJSException(cx,
|
||||
"Null npobj in nsJSObjWrapper::NP_HasProperty!");
|
||||
ThrowJSExceptionASCII(cx,
|
||||
"Null npobj in nsJSObjWrapper::NP_HasProperty!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -902,8 +902,8 @@ nsJSObjWrapper::NP_GetProperty(NPObject *npobj, NPIdentifier id,
|
|||
JSContext *cx = aes.cx();
|
||||
|
||||
if (!npobj) {
|
||||
ThrowJSException(cx,
|
||||
"Null npobj in nsJSObjWrapper::NP_GetProperty!");
|
||||
ThrowJSExceptionASCII(cx,
|
||||
"Null npobj in nsJSObjWrapper::NP_GetProperty!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -936,8 +936,8 @@ nsJSObjWrapper::NP_SetProperty(NPObject *npobj, NPIdentifier npid,
|
|||
JSContext *cx = aes.cx();
|
||||
|
||||
if (!npobj) {
|
||||
ThrowJSException(cx,
|
||||
"Null npobj in nsJSObjWrapper::NP_SetProperty!");
|
||||
ThrowJSExceptionASCII(cx,
|
||||
"Null npobj in nsJSObjWrapper::NP_SetProperty!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -973,8 +973,8 @@ nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier npid)
|
|||
JSContext *cx = aes.cx();
|
||||
|
||||
if (!npobj) {
|
||||
ThrowJSException(cx,
|
||||
"Null npobj in nsJSObjWrapper::NP_RemoveProperty!");
|
||||
ThrowJSExceptionASCII(cx,
|
||||
"Null npobj in nsJSObjWrapper::NP_RemoveProperty!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1027,8 +1027,8 @@ nsJSObjWrapper::NP_Enumerate(NPObject *npobj, NPIdentifier **idarray,
|
|||
*count = 0;
|
||||
|
||||
if (!npobj) {
|
||||
ThrowJSException(cx,
|
||||
"Null npobj in nsJSObjWrapper::NP_Enumerate!");
|
||||
ThrowJSExceptionASCII(cx,
|
||||
"Null npobj in nsJSObjWrapper::NP_Enumerate!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1047,7 +1047,7 @@ nsJSObjWrapper::NP_Enumerate(NPObject *npobj, NPIdentifier **idarray,
|
|||
*count = ida.length();
|
||||
*idarray = (NPIdentifier *)PR_Malloc(*count * sizeof(NPIdentifier));
|
||||
if (!*idarray) {
|
||||
ThrowJSException(cx, "Memory allocation failed for NPIdentifier!");
|
||||
ThrowJSExceptionASCII(cx, "Memory allocation failed for NPIdentifier!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1216,7 +1216,7 @@ NPObjWrapper_AddProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<js
|
|||
|
||||
if (!npobj || !npobj->_class || !npobj->_class->hasProperty ||
|
||||
!npobj->_class->hasMethod) {
|
||||
ThrowJSException(cx, "Bad NPObject as private data!");
|
||||
ThrowJSExceptionASCII(cx, "Bad NPObject as private data!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1242,7 +1242,7 @@ NPObjWrapper_AddProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<js
|
|||
return false;
|
||||
|
||||
if (!hasMethod) {
|
||||
ThrowJSException(cx, "Trying to add unsupported property on NPObject!");
|
||||
ThrowJSExceptionASCII(cx, "Trying to add unsupported property on NPObject!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1258,7 +1258,7 @@ NPObjWrapper_DelProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<js
|
|||
|
||||
if (!npobj || !npobj->_class || !npobj->_class->hasProperty ||
|
||||
!npobj->_class->removeProperty) {
|
||||
ThrowJSException(cx, "Bad NPObject as private data!");
|
||||
ThrowJSExceptionASCII(cx, "Bad NPObject as private data!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1294,7 +1294,7 @@ NPObjWrapper_SetProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<js
|
|||
|
||||
if (!npobj || !npobj->_class || !npobj->_class->hasProperty ||
|
||||
!npobj->_class->setProperty) {
|
||||
ThrowJSException(cx, "Bad NPObject as private data!");
|
||||
ThrowJSExceptionASCII(cx, "Bad NPObject as private data!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1304,7 +1304,7 @@ NPObjWrapper_SetProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<js
|
|||
NPP npp = LookupNPP(npobj);
|
||||
|
||||
if (!npp) {
|
||||
ThrowJSException(cx, "No NPP found for NPObject!");
|
||||
ThrowJSExceptionASCII(cx, "No NPP found for NPObject!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1319,7 +1319,7 @@ NPObjWrapper_SetProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<js
|
|||
return false;
|
||||
|
||||
if (!hasProperty) {
|
||||
ThrowJSException(cx, "Trying to set unsupported property on NPObject!");
|
||||
ThrowJSExceptionASCII(cx, "Trying to set unsupported property on NPObject!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1327,7 +1327,7 @@ NPObjWrapper_SetProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<js
|
|||
|
||||
NPVariant npv;
|
||||
if (!JSValToNPVariant(npp, cx, vp, &npv)) {
|
||||
ThrowJSException(cx, "Error converting jsval to NPVariant!");
|
||||
ThrowJSExceptionASCII(cx, "Error converting jsval to NPVariant!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1338,7 +1338,7 @@ NPObjWrapper_SetProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<js
|
|||
return false;
|
||||
|
||||
if (!ok) {
|
||||
ThrowJSException(cx, "Error setting property on NPObject!");
|
||||
ThrowJSExceptionASCII(cx, "Error setting property on NPObject!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1353,7 +1353,7 @@ NPObjWrapper_GetProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<js
|
|||
|
||||
if (!npobj || !npobj->_class || !npobj->_class->hasProperty ||
|
||||
!npobj->_class->hasMethod || !npobj->_class->getProperty) {
|
||||
ThrowJSException(cx, "Bad NPObject as private data!");
|
||||
ThrowJSExceptionASCII(cx, "Bad NPObject as private data!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1389,7 +1389,7 @@ NPObjWrapper_GetProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<js
|
|||
// manipulating, and make it own any JSObject wrappers created here.
|
||||
NPP npp = LookupNPP(npobj);
|
||||
if (!npp) {
|
||||
ThrowJSException(cx, "No NPP found for NPObject!");
|
||||
ThrowJSExceptionASCII(cx, "No NPP found for NPObject!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1475,7 +1475,7 @@ CallNPMethodInternal(JSContext *cx, JS::Handle<JSObject*> obj, unsigned argc,
|
|||
NPObject *npobj = GetNPObject(cx, obj);
|
||||
|
||||
if (!npobj || !npobj->_class) {
|
||||
ThrowJSException(cx, "Bad NPObject as private data!");
|
||||
ThrowJSExceptionASCII(cx, "Bad NPObject as private data!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1485,7 +1485,7 @@ CallNPMethodInternal(JSContext *cx, JS::Handle<JSObject*> obj, unsigned argc,
|
|||
NPP npp = LookupNPP(npobj);
|
||||
|
||||
if (!npp) {
|
||||
ThrowJSException(cx, "Error finding NPP for NPObject!");
|
||||
ThrowJSExceptionASCII(cx, "Error finding NPP for NPObject!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1501,7 +1501,7 @@ CallNPMethodInternal(JSContext *cx, JS::Handle<JSObject*> obj, unsigned argc,
|
|||
npargs = (NPVariant *)PR_Malloc(argc * sizeof(NPVariant));
|
||||
|
||||
if (!npargs) {
|
||||
ThrowJSException(cx, "Out of memory!");
|
||||
ThrowJSExceptionASCII(cx, "Out of memory!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1511,7 +1511,7 @@ CallNPMethodInternal(JSContext *cx, JS::Handle<JSObject*> obj, unsigned argc,
|
|||
uint32_t i;
|
||||
for (i = 0; i < argc; ++i) {
|
||||
if (!JSValToNPVariant(npp, cx, argv[i], npargs + i)) {
|
||||
ThrowJSException(cx, "Error converting jsvals to NPVariants!");
|
||||
ThrowJSExceptionASCII(cx, "Error converting jsvals to NPVariants!");
|
||||
|
||||
if (npargs != npargs_buf) {
|
||||
PR_Free(npargs);
|
||||
|
@ -1583,7 +1583,7 @@ CallNPMethodInternal(JSContext *cx, JS::Handle<JSObject*> obj, unsigned argc,
|
|||
// ReportExceptionIfPending returns a return value, which is true
|
||||
// if no exception was thrown. In that case, throw our own.
|
||||
if (ReportExceptionIfPending(cx))
|
||||
ThrowJSException(cx, msg);
|
||||
ThrowJSExceptionASCII(cx, msg);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1613,7 +1613,7 @@ NPObjWrapper_Enumerate(JSContext *cx, JS::Handle<JSObject*> obj,
|
|||
{
|
||||
NPObject *npobj = GetNPObject(cx, obj);
|
||||
if (!npobj || !npobj->_class) {
|
||||
ThrowJSException(cx, "Bad NPObject as private data!");
|
||||
ThrowJSExceptionASCII(cx, "Bad NPObject as private data!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1630,8 +1630,8 @@ NPObjWrapper_Enumerate(JSContext *cx, JS::Handle<JSObject*> obj,
|
|||
if (ReportExceptionIfPending(cx)) {
|
||||
// ReportExceptionIfPending returns a return value, which is true
|
||||
// if no exception was thrown. In that case, throw our own.
|
||||
ThrowJSException(cx, "Error enumerating properties on scriptable "
|
||||
"plugin object");
|
||||
ThrowJSExceptionASCII(cx, "Error enumerating properties on scriptable "
|
||||
"plugin object");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1662,7 +1662,7 @@ NPObjWrapper_Resolve(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid>
|
|||
|
||||
if (!npobj || !npobj->_class || !npobj->_class->hasProperty ||
|
||||
!npobj->_class->hasMethod) {
|
||||
ThrowJSException(cx, "Bad NPObject as private data!");
|
||||
ThrowJSExceptionASCII(cx, "Bad NPObject as private data!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -2060,7 +2060,7 @@ CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject* npobj,
|
|||
{
|
||||
if (!npobj || !npobj->_class || !npobj->_class->getProperty ||
|
||||
!npobj->_class->invoke) {
|
||||
ThrowJSException(cx, "Bad NPObject");
|
||||
ThrowJSExceptionASCII(cx, "Bad NPObject");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -2170,7 +2170,7 @@ NPObjectMember_Call(JSContext *cx, unsigned argc, JS::Value *vp)
|
|||
|
||||
NPObject *npobj = GetNPObject(cx, memberPrivate->npobjWrapper);
|
||||
if (!npobj) {
|
||||
ThrowJSException(cx, "Call on invalid member object");
|
||||
ThrowJSExceptionASCII(cx, "Call on invalid member object");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -2184,7 +2184,7 @@ NPObjectMember_Call(JSContext *cx, unsigned argc, JS::Value *vp)
|
|||
npargs = (NPVariant *)PR_Malloc(args.length() * sizeof(NPVariant));
|
||||
|
||||
if (!npargs) {
|
||||
ThrowJSException(cx, "Out of memory!");
|
||||
ThrowJSExceptionASCII(cx, "Out of memory!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -2193,7 +2193,7 @@ NPObjectMember_Call(JSContext *cx, unsigned argc, JS::Value *vp)
|
|||
// Convert arguments
|
||||
for (uint32_t i = 0; i < args.length(); ++i) {
|
||||
if (!JSValToNPVariant(memberPrivate->npp, cx, args[i], npargs + i)) {
|
||||
ThrowJSException(cx, "Error converting jsvals to NPVariants!");
|
||||
ThrowJSExceptionASCII(cx, "Error converting jsvals to NPVariants!");
|
||||
|
||||
if (npargs != npargs_buf) {
|
||||
PR_Free(npargs);
|
||||
|
@ -2222,7 +2222,7 @@ NPObjectMember_Call(JSContext *cx, unsigned argc, JS::Value *vp)
|
|||
// ReportExceptionIfPending returns a return value, which is true
|
||||
// if no exception was thrown. In that case, throw our own.
|
||||
if (ReportExceptionIfPending(cx))
|
||||
ThrowJSException(cx, "Error calling method on NPObject!");
|
||||
ThrowJSExceptionASCII(cx, "Error calling method on NPObject!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -2299,8 +2299,8 @@ nsJSObjWrapper::HasOwnProperty(NPObject *npobj, NPIdentifier npid)
|
|||
JSContext *cx = aes.cx();
|
||||
|
||||
if (!npobj) {
|
||||
ThrowJSException(cx,
|
||||
"Null npobj in nsJSObjWrapper::NP_HasOwnProperty!");
|
||||
ThrowJSExceptionASCII(cx,
|
||||
"Null npobj in nsJSObjWrapper::NP_HasOwnProperty!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -759,10 +759,8 @@ function runTest() {
|
|||
"wrong responseXML in test for " + test.toSource());
|
||||
is(res.responseText, "",
|
||||
"wrong responseText in test for " + test.toSource());
|
||||
var expectedProgressCount = 0;
|
||||
if (!res.sendThrew) {
|
||||
if (test.username) {
|
||||
expectedProgressCount = 1;
|
||||
is(res.events.join(","),
|
||||
"opening,rs1,sending,loadstart,rs4,error,loadend",
|
||||
"wrong events in test for " + test.toSource());
|
||||
|
@ -772,7 +770,7 @@ function runTest() {
|
|||
"wrong events in test for " + test.toSource());
|
||||
}
|
||||
}
|
||||
is(res.progressEvents, expectedProgressCount,
|
||||
is(res.progressEvents, 0,
|
||||
"wrong events in test for " + test.toSource());
|
||||
if (test.responseHeaders) {
|
||||
for (header in test.responseHeaders) {
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "nsIDOMSVGElement.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsSVGElement.h"
|
||||
#include "mozilla/dom/SVGDocumentBinding.h"
|
||||
#include "mozilla/StyleSheet.h"
|
||||
#include "mozilla/StyleSheetInlines.h"
|
||||
|
||||
|
@ -35,39 +34,6 @@ namespace dom {
|
|||
//----------------------------------------------------------------------
|
||||
// nsISupports methods:
|
||||
|
||||
void
|
||||
SVGDocument::GetDomain(nsAString& aDomain, ErrorResult& aRv)
|
||||
{
|
||||
SetDOMStringToNull(aDomain);
|
||||
|
||||
if (mDocumentURI) {
|
||||
nsAutoCString domain;
|
||||
nsresult rv = mDocumentURI->GetHost(domain);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
return;
|
||||
}
|
||||
if (domain.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
CopyUTF8toUTF16(domain, aDomain);
|
||||
}
|
||||
}
|
||||
|
||||
nsSVGElement*
|
||||
SVGDocument::GetRootElement(ErrorResult& aRv)
|
||||
{
|
||||
Element* root = nsDocument::GetRootElement();
|
||||
if (!root) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!root->IsSVGElement()) {
|
||||
aRv.Throw(NS_NOINTERFACE);
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<nsSVGElement*>(root);
|
||||
}
|
||||
|
||||
nsresult
|
||||
SVGDocument::InsertChildAt(nsIContent* aKid, uint32_t aIndex, bool aNotify)
|
||||
{
|
||||
|
@ -192,12 +158,6 @@ SVGDocument::EnsureNonSVGUserAgentStyleSheetsLoaded()
|
|||
EndUpdate(UPDATE_STYLE);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
SVGDocument::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return SVGDocumentBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -33,10 +33,6 @@ public:
|
|||
bool aNotify) override;
|
||||
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
|
||||
|
||||
// WebIDL API
|
||||
void GetDomain(nsAString& aDomain, ErrorResult& aRv);
|
||||
nsSVGElement* GetRootElement(ErrorResult& aRv);
|
||||
|
||||
virtual SVGDocument* AsSVGDocument() override {
|
||||
return this;
|
||||
}
|
||||
|
@ -44,8 +40,6 @@ public:
|
|||
private:
|
||||
void EnsureNonSVGUserAgentStyleSheetsLoaded();
|
||||
|
||||
virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
bool mHasLoadedNonSVGUserAgentStyleSheets;
|
||||
};
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ function runTests()
|
|||
{
|
||||
var svg = $("svg");
|
||||
var doc = svg.contentWindow.document;
|
||||
var rootElement = doc.rootElement;
|
||||
var rootElement = doc.documentElement;
|
||||
|
||||
var tests = [
|
||||
new Test("unknown", false),
|
||||
|
|
|
@ -29,7 +29,7 @@ var expected = [
|
|||
{ name: "", message: "uncaught exception: [object Object]" },
|
||||
{ name: "", message: "foo", filename: "baz", lineNumber: 123 },
|
||||
{ name: "", message: "uncaught exception: [object Object]" },
|
||||
{ name: "InvalidStateError", message: "An attempt was made to use an object that is not, or is no longer, usable", filename: String(location), lineNumber: 62 },
|
||||
{ name: "InvalidStateError", message: "XMLHttpRequest state must not be LOADING or DONE.", filename: String(location), lineNumber: 62 },
|
||||
{ name: "ReferenceError", message: "xxx is not defined", filename: String(location), lineNumber: 64 },
|
||||
{ name: "ReferenceError", message: "xxx is not defined", filename: String(location), lineNumber: 66 }
|
||||
];
|
||||
|
|
|
@ -1123,8 +1123,6 @@ var interfaceNamesInGlobalScope =
|
|||
"SVGDefsElement",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"SVGDescElement",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"SVGDocument",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"SVGElement",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
[DEFAULT]
|
||||
support-files =
|
||||
geolocation.html
|
||||
geolocation_common.js
|
||||
|
||||
[test_mozsettings.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android'
|
||||
[test_mozsettingsWatch.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android'
|
|
@ -89,15 +89,3 @@ function check_geolocation(location) {
|
|||
// optional ok(location.coords.altitudeAccuracy == 42, "alt acc matches known value");
|
||||
}
|
||||
|
||||
function toggleGeolocationSetting(value, callback) {
|
||||
var mozSettings = window.navigator.mozSettings;
|
||||
var lock = mozSettings.createLock();
|
||||
|
||||
var geoenabled = {"geolocation.enabled": value};
|
||||
|
||||
req = lock.set(geoenabled);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "set done");
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=478911
|
||||
-->
|
||||
<head>
|
||||
<title>Test for getCurrentPosition </title>
|
||||
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="geolocation_common.js"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=777594">Mozilla Bug 777594</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.requestFlakyTimeout("untriaged");
|
||||
|
||||
var timeToWaitMs = 1000;
|
||||
|
||||
resume_geolocationProvider(function() {
|
||||
force_prompt(true, test2);
|
||||
});
|
||||
|
||||
SpecialPowers.importInMainProcess("resource://gre/modules/SettingsRequestManager.jsm");
|
||||
|
||||
function test2() {
|
||||
ok(navigator.geolocation, "get geolocation object");
|
||||
|
||||
toggleGeolocationSetting(false, function() {
|
||||
ok(true, "turned off geolocation via mozSettings");
|
||||
setTimeout(function() {
|
||||
navigator.geolocation.getCurrentPosition(successCallbackAfterMozsettingOff,
|
||||
failureCallbackAfterMozsettingOff);
|
||||
}, timeToWaitMs); // need to wait a bit for all of these async callbacks to finish
|
||||
});
|
||||
}
|
||||
|
||||
function successCallbackAfterMozsettingOff(position) {
|
||||
ok(false, "Success callback should not have been called after setting geolocation.enabled to false.");
|
||||
|
||||
toggleGeolocationSetting(true, function() {
|
||||
ok(true, "turned on geolocation via mozSettings");
|
||||
setTimeout(function() {
|
||||
navigator.geolocation.getCurrentPosition(successCallbackAfterMozsettingOn,
|
||||
failureCallbackAfterMozsettingOn);
|
||||
}, timeToWaitMs); // need to wait a bit for all of these async callbacks to finish
|
||||
});
|
||||
}
|
||||
|
||||
function failureCallbackAfterMozsettingOff(error) {
|
||||
ok(true, "Geolocation didn't work after setting geolocation.enabled to false.");
|
||||
|
||||
toggleGeolocationSetting(true, function() {
|
||||
ok(true, "turned on geolocation via mozSettings");
|
||||
setTimeout(function() {
|
||||
navigator.geolocation.getCurrentPosition(successCallbackAfterMozsettingOn,
|
||||
failureCallbackAfterMozsettingOn);
|
||||
}, timeToWaitMs); // need to wait a bit for all of these async callbacks to finish
|
||||
});
|
||||
}
|
||||
|
||||
function successCallbackAfterMozsettingOn(position) {
|
||||
ok(true, "Geolocation worked after setting geolocation.enabled to true.");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function failureCallbackAfterMozsettingOn(error) {
|
||||
ok(false, "Geolocation didn't work after setting geolocation.enabled to true.");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=478911
|
||||
-->
|
||||
<head>
|
||||
<title>Test for getCurrentPosition </title>
|
||||
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="geolocation_common.js"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=777594">Mozilla Bug 777594</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.requestFlakyTimeout("untriaged");
|
||||
|
||||
resume_geolocationProvider(function() {
|
||||
force_prompt(true, test2);
|
||||
});
|
||||
|
||||
SpecialPowers.importInMainProcess("resource://gre/modules/SettingsRequestManager.jsm");
|
||||
|
||||
var watchId;
|
||||
function test2() {
|
||||
ok(navigator.geolocation, "get geolocation object");
|
||||
|
||||
toggleGeolocationSetting(false, function() {
|
||||
ok(true, "turned off geolocation via mozSettings");
|
||||
setTimeout(function() {
|
||||
watchId = navigator.geolocation.watchPosition(successCallbackAfterMozsettingOff,
|
||||
failureCallbackAfterMozsettingOff);
|
||||
}, 500); // need to wait a bit for all of these async callbacks to finish
|
||||
});
|
||||
}
|
||||
|
||||
function successCallbackAfterMozsettingOff(position) {
|
||||
ok(false, "Success callback should not have been called after setting geolocation.enabled to false.");
|
||||
|
||||
navigator.geolocation.clearWatch(watchId);
|
||||
toggleGeolocationSetting(true, function() {
|
||||
ok(true, "turned on geolocation via mozSettings");
|
||||
setTimeout(function() {
|
||||
watchId = navigator.geolocation.watchPosition(successCallbackAfterMozsettingOn,
|
||||
failureCallbackAfterMozsettingOn);
|
||||
}, 500); // need to wait a bit for all of these async callbacks to finish
|
||||
});
|
||||
}
|
||||
|
||||
function failureCallbackAfterMozsettingOff(error) {
|
||||
ok(true, "Geolocation didn't work after setting geolocation.enabled to false.");
|
||||
|
||||
navigator.geolocation.clearWatch(watchId);
|
||||
toggleGeolocationSetting(true, function() {
|
||||
ok(true, "turned on geolocation via mozSettings");
|
||||
setTimeout(function() {
|
||||
watchId = navigator.geolocation.watchPosition(successCallbackAfterMozsettingOn,
|
||||
failureCallbackAfterMozsettingOn);
|
||||
}, 500); // need to wait a bit for all of these async callbacks to finish
|
||||
});
|
||||
}
|
||||
|
||||
function successCallbackAfterMozsettingOn(position) {
|
||||
ok(true, "Geolocation worked after setting geolocation.enabled to true.");
|
||||
|
||||
navigator.geolocation.clearWatch(watchId);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function failureCallbackAfterMozsettingOn(error) {
|
||||
ok(false, "Geolocation didn't work after setting geolocation.enabled to true.");
|
||||
|
||||
navigator.geolocation.clearWatch(watchId);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -34,7 +34,6 @@ MOCHITEST_CHROME_MANIFESTS += [
|
|||
'mochitest/beacon/chrome.ini',
|
||||
'mochitest/chrome/chrome.ini',
|
||||
'mochitest/general/chrome.ini',
|
||||
'mochitest/geolocation/chrome.ini',
|
||||
'mochitest/localstorage/chrome.ini',
|
||||
'mochitest/notification/chrome.ini',
|
||||
'mochitest/sessionstorage/chrome.ini',
|
||||
|
|
|
@ -18,12 +18,12 @@ enum CSSStyleSheetParsingMode {
|
|||
interface CSSStyleSheet : StyleSheet {
|
||||
[Pure]
|
||||
readonly attribute CSSRule? ownerRule;
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
readonly attribute CSSRuleList cssRules;
|
||||
[ChromeOnly, BinaryName="parsingModeDOM"]
|
||||
readonly attribute CSSStyleSheetParsingMode parsingMode;
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
unsigned long insertRule(DOMString rule, unsigned long index);
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
void deleteRule(unsigned long index);
|
||||
};
|
||||
|
|
|
@ -23,7 +23,7 @@ interface DataTransfer {
|
|||
DOMString getData(DOMString format);
|
||||
[Throws]
|
||||
void setData(DOMString format, DOMString data);
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
void clearData(optional DOMString format);
|
||||
[Throws]
|
||||
readonly attribute FileList? files;
|
||||
|
@ -91,7 +91,7 @@ partial interface DataTransfer {
|
|||
* @throws NS_ERROR_DOM_INDEX_SIZE_ERR if index is greater or equal than itemCount
|
||||
* @throws NO_MODIFICATION_ALLOWED_ERR if the item cannot be modified
|
||||
*/
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
void mozClearDataAt(DOMString format, unsigned long index);
|
||||
|
||||
/*
|
||||
|
|
|
@ -10,15 +10,16 @@
|
|||
interface DataTransferItem {
|
||||
readonly attribute DOMString kind;
|
||||
readonly attribute DOMString type;
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
void getAsString(FunctionStringCallback? _callback);
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
File? getAsFile();
|
||||
};
|
||||
|
||||
callback FunctionStringCallback = void (DOMString data);
|
||||
|
||||
partial interface DataTransferItem {
|
||||
[Pref="dom.webkitBlink.filesystem.enabled", BinaryName="getAsEntry", Throws]
|
||||
[Pref="dom.webkitBlink.filesystem.enabled", BinaryName="getAsEntry", Throws,
|
||||
NeedsSubjectPrincipal]
|
||||
FileSystemEntry? webkitGetAsEntry();
|
||||
};
|
||||
|
|
|
@ -11,12 +11,12 @@ interface DataTransferItemList {
|
|||
readonly attribute unsigned long length;
|
||||
[Throws]
|
||||
getter DataTransferItem (unsigned long index);
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
DataTransferItem? add(DOMString data, DOMString type);
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
DataTransferItem? add(File data);
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
void remove(unsigned long index);
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
void clear();
|
||||
};
|
||||
|
|
|
@ -327,6 +327,12 @@ partial interface Document {
|
|||
sequence<Animation> getAnimations();
|
||||
};
|
||||
|
||||
// https://svgwg.org/svg2-draft/struct.html#InterfaceDocumentExtensions
|
||||
partial interface Document {
|
||||
[BinaryName="SVGRootElement"]
|
||||
readonly attribute SVGSVGElement? rootElement;
|
||||
};
|
||||
|
||||
// Mozilla extensions of various sorts
|
||||
partial interface Document {
|
||||
// nsIDOMDocumentXBL. Wish we could make these [ChromeOnly], but
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
* and create derivative works of this document.
|
||||
*/
|
||||
|
||||
interface nsIInputStreamCallback;
|
||||
interface nsISupports;
|
||||
interface Variant;
|
||||
|
||||
|
|
|
@ -17,36 +17,36 @@ interface Location {
|
|||
// stringifier attribute USVString href;
|
||||
|
||||
// Bug 824857 should remove this.
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
stringifier;
|
||||
|
||||
[Throws, CrossOriginWritable]
|
||||
[Throws, CrossOriginWritable, NeedsSubjectPrincipal]
|
||||
attribute USVString href;
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
readonly attribute USVString origin;
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
attribute USVString protocol;
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
attribute USVString host;
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
attribute USVString hostname;
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
attribute USVString port;
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
attribute USVString pathname;
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
attribute USVString search;
|
||||
[Throws]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
attribute USVString hash;
|
||||
|
||||
[Throws, UnsafeInPrerendering]
|
||||
[Throws, UnsafeInPrerendering, NeedsSubjectPrincipal]
|
||||
void assign(USVString url);
|
||||
|
||||
[Throws, CrossOriginCallable, UnsafeInPrerendering]
|
||||
[Throws, CrossOriginCallable, UnsafeInPrerendering, NeedsSubjectPrincipal]
|
||||
void replace(USVString url);
|
||||
|
||||
// XXXbz there is no forceget argument in the spec! See bug 1037721.
|
||||
[Throws, UnsafeInPrerendering]
|
||||
[Throws, UnsafeInPrerendering, NeedsSubjectPrincipal]
|
||||
void reload(optional boolean forceget = false);
|
||||
|
||||
// Bug 1085214 [SameObject] readonly attribute USVString[] ancestorOrigins;
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче