merge mozilla-inbound to mozilla-central

This commit is contained in:
Carsten "Tomcat" Book 2014-05-21 13:45:46 +02:00
Родитель 6bc448b2f9 93df14c3c1
Коммит 560c22d1e6
273 изменённых файлов: 12502 добавлений и 2388 удалений

Просмотреть файл

@ -918,10 +918,18 @@ var Input = {
},
moveToPoint: function moveToPoint(aRule, aX, aY) {
// XXX: Bug 1013408 - There is no alignment between the chrome window's
// viewport size and the content viewport size in Android. This makes
// sending mouse events beyond its bounds impossible.
if (Utils.MozBuildApp === 'mobile/android') {
let mm = Utils.getMessageManager(Utils.CurrentBrowser);
mm.sendAsyncMessage('AccessFu:MoveToPoint', {rule: aRule,
x: aX, y: aY,
origin: 'top'});
mm.sendAsyncMessage('AccessFu:MoveToPoint',
{rule: aRule, x: aX, y: aY, origin: 'top'});
} else {
let win = Utils.win;
Utils.winUtils.sendMouseEvent('mousemove',
aX - win.mozInnerScreenX, aY - win.mozInnerScreenY, 0, 0, 0);
}
},
moveCursor: function moveCursor(aAction, aRule, aInputType) {
@ -999,9 +1007,7 @@ var Input = {
let page = aDetails.page;
let p = AccessFu.adjustContentBounds(aDetails.bounds, Utils.CurrentBrowser,
true, true).center();
let wu = Utils.win.QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIDOMWindowUtils);
wu.sendWheelEvent(p.x, p.y,
Utils.winUtils.sendWheelEvent(p.x, p.y,
horizontal ? page : 0, horizontal ? 0 : page, 0,
Utils.win.WheelEvent.DOM_DELTA_PAGE, 0, 0, 0, 0);
},

Просмотреть файл

@ -45,6 +45,7 @@ this.ContentControl.prototype = {
for (let message of this.messagesOfInterest) {
cs.addMessageListener(message, this);
}
cs.addEventListener('mousemove', this);
},
stop: function cc_stop() {
@ -52,6 +53,7 @@ this.ContentControl.prototype = {
for (let message of this.messagesOfInterest) {
cs.removeMessageListener(message, this);
}
cs.removeEventListener('mousemove', this);
},
get document() {
@ -124,18 +126,22 @@ this.ContentControl.prototype = {
}
},
handleEvent: function cc_handleEvent(aEvent) {
if (aEvent.type === 'mousemove') {
this.handleMoveToPoint(
{ json: { x: aEvent.screenX, y: aEvent.screenY, rule: 'Simple' } });
}
if (!Utils.getMessageManager(aEvent.target)) {
aEvent.preventDefault();
}
},
handleMoveToPoint: function cc_handleMoveToPoint(aMessage) {
let [x, y] = [aMessage.json.x, aMessage.json.y];
let rule = TraversalRules[aMessage.json.rule];
let vc = this.vc;
let win = this.window;
let dpr = win.devicePixelRatio;
let dpr = this.window.devicePixelRatio;
this.vc.moveToPoint(rule, x * dpr, y * dpr, true);
let delta = Utils.isContentProcess ?
{ x: x - win.mozInnerScreenX, y: y - win.mozInnerScreenY } : {};
this.sendToChild(vc, aMessage, delta);
},
handleClearCursor: function cc_handleClearCursor(aMessage) {

Просмотреть файл

@ -110,36 +110,14 @@ let PointerRelay = { // jshint ignore:line
}
},
_suppressPointerMove: function PointerRelay__suppressPointerMove(aChangedTouches) {
if (!this.lastPointerMove) {
return false;
}
for (let i = 0; i < aChangedTouches.length; ++i) {
let touch = aChangedTouches[i];
let lastTouch;
try {
lastTouch = this.lastPointerMove.identifiedTouch ?
this.lastPointerMove.identifiedTouch(touch.identifier) :
this.lastPointerMove[i];
} catch (x) {
// Sometimes touch object can't be accessed after page navigation.
}
if (!lastTouch || lastTouch.target !== touch.target ||
Math.hypot(touch.screenX - lastTouch.screenX, touch.screenY -
lastTouch.screenY) / Utils.dpi >= GestureSettings.travelThreshold) {
return false;
}
}
return true;
},
handleEvent: function PointerRelay_handleEvent(aEvent) {
// Don't bother with chrome mouse events.
if (Utils.MozBuildApp === 'browser' &&
aEvent.view.top instanceof Ci.nsIDOMChromeWindow) {
return;
}
if (aEvent.mozInputSource === Ci.nsIDOMMouseEvent.MOZ_SOURCE_UNKNOWN) {
if (aEvent.mozInputSource === Ci.nsIDOMMouseEvent.MOZ_SOURCE_UNKNOWN ||
aEvent.isSynthesized) {
// Ignore events that are scripted or clicks from the a11y API.
return;
}
@ -164,13 +142,6 @@ let PointerRelay = { // jshint ignore:line
return;
}
let pointerType = this._eventMap[type];
if (pointerType === 'pointermove') {
if (this._suppressPointerMove(changedTouches)) {
// Do not fire pointermove more than every POINTERMOVE_THROTTLE.
return;
}
this.lastPointerMove = changedTouches;
}
this.onPointerEvent({
type: pointerType,
points: Array.prototype.map.call(changedTouches,

Просмотреть файл

@ -113,6 +113,11 @@ var gSimpleMatchFunc = function gSimpleMatchFunc(aAccessible) {
function isFlatSubtree(acc) {
for (let child = acc.firstChild; child; child = child.nextSibling) {
// text leafs inherit the actionCount of any ancestor that has a click
// listener.
if ([Roles.TEXT_LEAF, Roles.STATICTEXT].indexOf(child.role) >= 0) {
continue;
}
if (child.childCount > 0 || child.actionCount > 0) {
return false;
}

Просмотреть файл

@ -54,6 +54,15 @@ this.Utils = {
return this._win.get();
},
get winUtils() {
let win = this.win;
if (!win) {
return null;
}
return win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(
Ci.nsIDOMWindowUtils);
},
get AccRetrieval() {
if (!this._AccRetrieval) {
this._AccRetrieval = Cc['@mozilla.org/accessibleRetrieval;1'].
@ -181,7 +190,6 @@ this.Utils = {
return aBrowser.QueryInterface(Ci.nsIFrameLoaderOwner).
frameLoader.messageManager;
} catch (x) {
Logger.logException(x);
return null;
}
},
@ -252,8 +260,7 @@ this.Utils = {
*/
get dpi() {
delete this.dpi;
this.dpi = this.win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(
Ci.nsIDOMWindowUtils).displayDPI;
this.dpi = this.winUtils.displayDPI;
return this.dpi;
},

Просмотреть файл

@ -60,7 +60,7 @@
<dd>A esoteric weapon wielded by only the most formidable warriors,
for its unrelenting strict power is unfathomable.</dd>
</dl>
<ul id="list-2">
<ul id="list-2" onclick="alert('hi');">
<li id="listitem-2-1">Lists of Programming Languages</li>
<li id="listitem-2-2">Lisp
<ol id="list-3">

Просмотреть файл

@ -6,8 +6,8 @@
"filename": "setup.sh"
},
{
"size": 165464,
"digest": "ee87db68eb63e417a366333e34a32d9220232bfb9c3e91b9941513acf0551f2603a836537ffef41a240430200970d83fa9271f55b8b5168d6967be595cdb50db",
"size": 165226,
"digest": "79280f7595bc9e1613e05f8b2f0db3798ac739b96191e0f133e8ccd8ad149fedc84a1046e59863574189db28363a01712ae7b368ad1714e30ff88e7ebd5dad23",
"algorithm": "sha512",
"filename": "sccache.tar.bz2"
}

Просмотреть файл

@ -6,8 +6,8 @@
"filename": "setup.sh"
},
{
"size": 165464,
"digest": "ee87db68eb63e417a366333e34a32d9220232bfb9c3e91b9941513acf0551f2603a836537ffef41a240430200970d83fa9271f55b8b5168d6967be595cdb50db",
"size": 165226,
"digest": "79280f7595bc9e1613e05f8b2f0db3798ac739b96191e0f133e8ccd8ad149fedc84a1046e59863574189db28363a01712ae7b368ad1714e30ff88e7ebd5dad23",
"algorithm": "sha512",
"filename": "sccache.tar.bz2"
}

Просмотреть файл

@ -15,8 +15,8 @@
"filename": "clang.tar.bz2"
},
{
"size": 165464,
"digest": "ee87db68eb63e417a366333e34a32d9220232bfb9c3e91b9941513acf0551f2603a836537ffef41a240430200970d83fa9271f55b8b5168d6967be595cdb50db",
"size": 165226,
"digest": "79280f7595bc9e1613e05f8b2f0db3798ac739b96191e0f133e8ccd8ad149fedc84a1046e59863574189db28363a01712ae7b368ad1714e30ff88e7ebd5dad23",
"algorithm": "sha512",
"filename": "sccache.tar.bz2"
}

Просмотреть файл

@ -32,13 +32,14 @@ ul {
max-width: 512px;
}
#errorTitle {
#errorTitleText {
background: url("info.svg") left 0 no-repeat;
-moz-margin-start: -5em;
-moz-padding-start: 5em;
background-size: 1.2em;
-moz-margin-start: -2em;
-moz-padding-start: 2em;
}
#errorTitle:-moz-locale-dir(rtl) {
#errorTitleText:-moz-locale-dir(rtl) {
background-position: right 0;
}

Просмотреть файл

@ -12,8 +12,8 @@
"filename": "gcc.tar.xz"
},
{
"size": 165464,
"digest": "ee87db68eb63e417a366333e34a32d9220232bfb9c3e91b9941513acf0551f2603a836537ffef41a240430200970d83fa9271f55b8b5168d6967be595cdb50db",
"size": 165226,
"digest": "79280f7595bc9e1613e05f8b2f0db3798ac739b96191e0f133e8ccd8ad149fedc84a1046e59863574189db28363a01712ae7b368ad1714e30ff88e7ebd5dad23",
"algorithm": "sha512",
"filename": "sccache.tar.bz2"
}

Просмотреть файл

@ -12,8 +12,8 @@
"filename": "gcc.tar.xz"
},
{
"size": 165464,
"digest": "ee87db68eb63e417a366333e34a32d9220232bfb9c3e91b9941513acf0551f2603a836537ffef41a240430200970d83fa9271f55b8b5168d6967be595cdb50db",
"size": 165226,
"digest": "79280f7595bc9e1613e05f8b2f0db3798ac739b96191e0f133e8ccd8ad149fedc84a1046e59863574189db28363a01712ae7b368ad1714e30ff88e7ebd5dad23",
"algorithm": "sha512",
"filename": "sccache.tar.bz2"
}

Просмотреть файл

@ -15,8 +15,8 @@
"filename": "clang.tar.bz2"
},
{
"size": 165464,
"digest": "ee87db68eb63e417a366333e34a32d9220232bfb9c3e91b9941513acf0551f2603a836537ffef41a240430200970d83fa9271f55b8b5168d6967be595cdb50db",
"size": 165226,
"digest": "79280f7595bc9e1613e05f8b2f0db3798ac739b96191e0f133e8ccd8ad149fedc84a1046e59863574189db28363a01712ae7b368ad1714e30ff88e7ebd5dad23",
"algorithm": "sha512",
"filename": "sccache.tar.bz2"
}

Просмотреть файл

@ -12,8 +12,8 @@
"filename": "setup.sh"
},
{
"size": 165464,
"digest": "ee87db68eb63e417a366333e34a32d9220232bfb9c3e91b9941513acf0551f2603a836537ffef41a240430200970d83fa9271f55b8b5168d6967be595cdb50db",
"size": 165226,
"digest": "79280f7595bc9e1613e05f8b2f0db3798ac739b96191e0f133e8ccd8ad149fedc84a1046e59863574189db28363a01712ae7b368ad1714e30ff88e7ebd5dad23",
"algorithm": "sha512",
"filename": "sccache.tar.bz2"
}

Просмотреть файл

@ -462,6 +462,13 @@ ThreadState.prototype = {
* Update the UI after a thread state change.
*/
_update: function(aEvent) {
// Ignore "interrupted" events, which are generated by the slow script
// dialog and internal events such as setting breakpoints, to avoid UI
// flicker.
if (aEvent == "interrupted") {
return;
}
DebuggerView.Toolbar.toggleResumeButtonState(this.activeThread.state);
if (gTarget && (aEvent == "paused" || aEvent == "resumed")) {
@ -568,6 +575,11 @@ StackFrames.prototype = {
this._currentReturnedValue = aPacket.why.frameFinished.return;
}
break;
// If paused by an explicit interrupt, which are generated by the slow
// script dialog and internal events such as setting breakpoints, ignore
// the event to avoid UI flicker.
case "interrupted":
return;
}
this.activeThread.fillFrames(CALL_STACK_PAGE_SIZE);

Просмотреть файл

@ -78,6 +78,7 @@ support-files =
doc_script-switching-01.html
doc_script-switching-02.html
doc_step-out.html
doc_terminate-on-tab-close.html
doc_tracing-01.html
doc_watch-expressions.html
doc_watch-expression-button.html
@ -237,6 +238,7 @@ skip-if = true # Bug 933950 (leaky test)
[browser_dbg_step-out.js]
[browser_dbg_tabactor-01.js]
[browser_dbg_tabactor-02.js]
[browser_dbg_terminate-on-tab-close.js]
[browser_dbg_tracing-01.js]
[browser_dbg_tracing-02.js]
[browser_dbg_tracing-03.js]

Просмотреть файл

@ -0,0 +1,38 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that debuggee scripts are terminated on tab closure.
*/
const TAB_URL = EXAMPLE_URL + "doc_terminate-on-tab-close.html";
let gTab, gDebuggee, gDebugger, gPanel;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
testTerminate();
});
}
function testTerminate() {
gDebugger.gThreadClient.addOneTimeListener("paused", () => {
resumeDebuggerThenCloseAndFinish(gPanel).then(function () {
ok(true, "should not throw after this point");
});
});
gDebuggee.debuggerThenThrow();
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
});

Просмотреть файл

@ -0,0 +1,20 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>Debugger test page</title>
</head>
<body>
<script type="text/javascript">
function debuggerThenThrow() {
debugger;
throw "unreachable";
}
</script>
</body>
</html>

Просмотреть файл

@ -580,6 +580,79 @@ let gDevToolsBrowser = {
mainKeyset.parentNode.insertBefore(devtoolsKeyset, mainKeyset);
},
/**
* Hook the JS debugger tool to the "Debug Script" button of the slow script
* dialog.
*/
setSlowScriptDebugHandler: function DT_setSlowScriptDebugHandler() {
let debugService = Cc["@mozilla.org/dom/slow-script-debug;1"]
.getService(Ci.nsISlowScriptDebug);
let tm = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager);
debugService.activationHandler = function(aWindow) {
let chromeWindow = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow)
.QueryInterface(Ci.nsIDOMChromeWindow);
let target = devtools.TargetFactory.forTab(chromeWindow.gBrowser.selectedTab);
let setupFinished = false;
gDevTools.showToolbox(target, "jsdebugger").then(toolbox => {
let threadClient = toolbox.getCurrentPanel().panelWin.gThreadClient;
// Break in place, which means resuming the debuggee thread and pausing
// right before the next step happens.
switch (threadClient.state) {
case "paused":
// When the debugger is already paused.
threadClient.breakOnNext();
setupFinished = true;
break;
case "attached":
// When the debugger is already open.
threadClient.interrupt(() => {
threadClient.breakOnNext();
setupFinished = true;
});
break;
case "resuming":
// The debugger is newly opened.
threadClient.addOneTimeListener("resumed", () => {
threadClient.interrupt(() => {
threadClient.breakOnNext();
setupFinished = true;
});
});
break;
default:
throw Error("invalid thread client state in slow script debug handler: " +
threadClient.state);
}
});
// Don't return from the interrupt handler until the debugger is brought
// up; no reason to continue executing the slow script.
let utils = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
utils.enterModalState();
while (!setupFinished) {
tm.currentThread.processNextEvent(true);
}
utils.leaveModalState();
};
},
/**
* Unset the slow script debug handler.
*/
unsetSlowScriptDebugHandler: function DT_unsetSlowScriptDebugHandler() {
let debugService = Cc["@mozilla.org/dom/slow-script-debug;1"]
.getService(Ci.nsISlowScriptDebug);
debugService.activationHandler = undefined;
},
/**
* Detect the presence of a Firebug.
@ -669,6 +742,10 @@ let gDevToolsBrowser = {
}
}
}
if (toolDefinition.id === "jsdebugger") {
gDevToolsBrowser.setSlowScriptDebugHandler();
}
},
/**
@ -844,6 +921,10 @@ let gDevToolsBrowser = {
for (let win of gDevToolsBrowser._trackedBrowserWindows) {
gDevToolsBrowser._removeToolFromMenu(toolId, win.document);
}
if (toolId === "jsdebugger") {
gDevToolsBrowser.unsetSlowScriptDebugHandler();
}
},
/**

Просмотреть файл

@ -531,6 +531,9 @@
@BINPATH@/components/Push.manifest
@BINPATH@/components/PushServiceLauncher.js
@BINPATH@/components/SlowScriptDebug.manifest
@BINPATH@/components/SlowScriptDebug.js
#ifndef RELEASE_BUILD
@BINPATH@/components/InterAppComm.manifest
@BINPATH@/components/InterAppCommService.js

Просмотреть файл

@ -20,3 +20,5 @@ GENERATED_SOURCES += [
DEFINES['ELFHACK_BUILD'] = True
NO_PGO = True
NO_VISIBILITY_FLAGS = True

Просмотреть файл

@ -0,0 +1,11 @@
/* 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/. */
#ifdef __cplusplus
extern "C"
#endif
void *__dso_handle;
/* Begin all files as hidden visibility */
#pragma GCC visibility push(hidden)

Просмотреть файл

@ -407,9 +407,6 @@ DriverServices.h
DriverSynchronization.h
DropInPanel.h
dvidef.h
#ifdef ANDROID
EffectApi.h
#endif
elf.h
endian.h
Entry.h
@ -516,6 +513,8 @@ gtk/gtkprinter.h
gtk/gtkprintjob.h
gtk/gtkprintunixdialog.h
#ifdef ANDROID
gui/BufferQueue.h
gui/ConsumerBase.h
gui/GraphicBufferAlloc.h
gui/IConsumerListener.h
gui/IGraphicBufferAlloc.h
@ -542,14 +541,6 @@ hlink.h
HTTPBase.h
#endif
ia64/sys/inline.h
#ifdef ANDROID
IAudioFlingerClient.h
IAudioFlinger.h
IAudioRecord.h
IAudioTrack.h
IEffect.h
IEffectClient.h
#endif
Icons.h
iconv.h
ieeefp.h
@ -911,6 +902,7 @@ rpc/types.h
sane/sane.h
sane/sanei.h
sane/saneopts.h
sched.h
Scrap.h
Screen.h
Script.h

Просмотреть файл

@ -2550,17 +2550,19 @@ dnl ===============================================================
if test "$GNU_CC" -a "$OS_TARGET" != WINNT; then
AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE)
AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE)
if test -n "$gonkdir"; then
visibility_target=Gonk
else
visibility_target=$OS_TARGET
fi
case "$visibility_target" in
Darwin|Gonk)
case "$OS_TARGET" in
Darwin)
VISIBILITY_FLAGS='-fvisibility=hidden'
;;
*)
case $GCC_VERSION in
4.4*)
VISIBILITY_FLAGS='-I$(DIST)/system_wrappers -include $(topsrcdir)/config/gcc_hidden_dso_handle.h'
;;
*)
VISIBILITY_FLAGS='-I$(DIST)/system_wrappers -include $(topsrcdir)/config/gcc_hidden.h'
;;
esac
WRAP_SYSTEM_INCLUDES=1
;;
esac

Просмотреть файл

@ -1334,6 +1334,12 @@ public:
*/
static nsIPrincipal* GetSystemPrincipal();
/**
* Gets the null subject principal singleton. This is only useful for
* assertions.
*/
static nsIPrincipal* GetNullSubjectPrincipal() { return sNullSubjectPrincipal; }
/**
* *aResourcePrincipal is a principal describing who may access the contents
* of a resource. The resource can only be consumed by a principal that
@ -2169,6 +2175,7 @@ private:
static nsIScriptSecurityManager *sSecurityManager;
static nsIPrincipal *sSystemPrincipal;
static nsIPrincipal *sNullSubjectPrincipal;
static nsIParserService *sParserService;

Просмотреть файл

@ -18,6 +18,7 @@
#include "nsIDOMHTMLDocument.h"
#include "nsIDOMHTMLElement.h"
#include "nsIHttpChannel.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIObjectInputStream.h"
#include "nsIObjectOutputStream.h"
@ -26,6 +27,7 @@
#include "nsIPrincipal.h"
#include "nsIPropertyBag2.h"
#include "nsIScriptError.h"
#include "nsIWebNavigation.h"
#include "nsIWritablePropertyBag2.h"
#include "nsString.h"
#include "prlog.h"
@ -45,6 +47,47 @@ GetCspContextLog()
#define CSPCONTEXTLOG(args) PR_LOG(GetCspContextLog(), 4, args)
static const uint32_t CSP_CACHE_URI_CUTOFF_SIZE = 512;
/**
* Creates a key for use in the ShouldLoad cache.
* Looks like: <uri>!<nsIContentPolicy::LOAD_TYPE>
*/
nsresult
CreateCacheKey_Internal(nsIURI* aContentLocation,
nsContentPolicyType aContentType,
nsACString& outCacheKey)
{
if (!aContentLocation) {
return NS_ERROR_FAILURE;
}
bool isDataScheme = false;
nsresult rv = aContentLocation->SchemeIs("data", &isDataScheme);
NS_ENSURE_SUCCESS(rv, rv);
outCacheKey.Truncate();
if (aContentType != nsIContentPolicy::TYPE_SCRIPT && isDataScheme) {
// For non-script data: URI, use ("data:", aContentType) as the cache key.
outCacheKey.Append(NS_LITERAL_CSTRING("data:"));
outCacheKey.AppendInt(aContentType);
return NS_OK;
}
nsAutoCString spec;
rv = aContentLocation->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
// Don't cache for a URI longer than the cutoff size.
if (spec.Length() <= CSP_CACHE_URI_CUTOFF_SIZE) {
outCacheKey.Append(spec);
outCacheKey.Append(NS_LITERAL_CSTRING("!"));
outCacheKey.AppendInt(aContentType);
}
return NS_OK;
}
/* ===== nsIContentSecurityPolicy impl ====== */
NS_IMETHODIMP
@ -74,6 +117,16 @@ nsCSPContext::ShouldLoad(nsContentPolicyType aContentType,
// * Content Type is not whitelisted (CSP Reports, TYPE_DOCUMENT, etc).
// * Fast Path for Apps
nsAutoCString cacheKey;
rv = CreateCacheKey_Internal(aContentLocation, aContentType, cacheKey);
NS_ENSURE_SUCCESS(rv, rv);
bool isCached = mShouldLoadCache.Get(cacheKey, outDecision);
if (isCached && cacheKey.Length() > 0) {
// this is cached, use the cached value.
return NS_OK;
}
// Default decision, CSP can revise it if there's a policy to enforce
*outDecision = nsIContentPolicy::ACCEPT;
@ -137,6 +190,11 @@ nsCSPContext::ShouldLoad(nsContentPolicyType aContentType,
// * Console error reporting, bug 994322
}
}
// Done looping, cache any relevant result
if (cacheKey.Length() > 0 && !isPreload) {
mShouldLoadCache.Put(cacheKey, *outDecision);
}
#ifdef PR_LOGGING
{
nsAutoCString spec;
@ -183,6 +241,7 @@ nsCSPContext::~nsCSPContext()
for (uint32_t i = 0; i < mPolicies.Length(); i++) {
delete mPolicies[i];
}
mShouldLoadCache.Clear();
}
NS_IMETHODIMP
@ -215,6 +274,8 @@ nsCSPContext::RemovePolicy(uint32_t aIndex)
return NS_ERROR_ILLEGAL_VALUE;
}
mPolicies.RemoveElementAt(aIndex);
// reset cache since effective policy changes
mShouldLoadCache.Clear();
return NS_OK;
}
@ -237,6 +298,8 @@ nsCSPContext::AppendPolicy(const nsAString& aPolicyString,
nsCSPPolicy* policy = nsCSPParser::parseContentSecurityPolicy(aPolicyString, mSelfURI, aReportOnly, 0);
if (policy) {
mPolicies.AppendElement(policy);
// reset cache since effective policy changes
mShouldLoadCache.Clear();
}
return NS_OK;
}
@ -378,11 +441,118 @@ nsCSPContext::SetRequestContext(nsIURI* aSelfURI,
return NS_OK;
}
/**
* Based on the given docshell, determines if this CSP context allows the
* ancestry.
*
* In order to determine the URI of the parent document (one causing the load
* of this protected document), this function obtains the docShellTreeItem,
* then walks up the hierarchy until it finds a privileged (chrome) tree item.
* Getting the parent's URI looks like this in pseudocode:
*
* nsIDocShell->QI(nsIInterfaceRequestor)
* ->GI(nsIDocShellTreeItem)
* ->QI(nsIInterfaceRequestor)
* ->GI(nsIWebNavigation)
* ->GetCurrentURI();
*
* aDocShell is the docShell for the protected document.
*/
NS_IMETHODIMP
nsCSPContext::PermitsAncestry(nsIDocShell* aDocShell, bool* outPermitsAncestry)
{
// For now, we allows permitsAncestry, this will be fixed in Bug 994320
nsresult rv;
// Can't check ancestry without a docShell.
if (aDocShell == nullptr) {
return NS_ERROR_FAILURE;
}
*outPermitsAncestry = true;
// extract the ancestry as an array
nsCOMArray<nsIURI> ancestorsArray;
nsCOMPtr<nsIInterfaceRequestor> ir(do_QueryInterface(aDocShell));
nsCOMPtr<nsIDocShellTreeItem> treeItem(do_GetInterface(ir));
nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
nsCOMPtr<nsIWebNavigation> webNav;
nsCOMPtr<nsIURI> currentURI;
nsCOMPtr<nsIURI> uriClone;
// iterate through each docShell parent item
while (NS_SUCCEEDED(treeItem->GetParent(getter_AddRefs(parentTreeItem))) &&
parentTreeItem != nullptr) {
ir = do_QueryInterface(parentTreeItem);
NS_ASSERTION(ir, "Could not QI docShellTreeItem to nsIInterfaceRequestor");
webNav = do_GetInterface(ir);
NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);
rv = webNav->GetCurrentURI(getter_AddRefs(currentURI));
NS_ENSURE_SUCCESS(rv, rv);
if (currentURI) {
// stop when reaching chrome
bool isChrome = false;
rv = currentURI->SchemeIs("chrome", &isChrome);
NS_ENSURE_SUCCESS(rv, rv);
if (isChrome) { break; }
// delete the userpass from the URI.
rv = currentURI->CloneIgnoringRef(getter_AddRefs(uriClone));
NS_ENSURE_SUCCESS(rv, rv);
rv = uriClone->SetUserPass(EmptyCString());
NS_ENSURE_SUCCESS(rv, rv);
#ifdef PR_LOGGING
{
nsAutoCString spec;
uriClone->GetSpec(spec);
CSPCONTEXTLOG(("nsCSPContext::PermitsAncestry, found ancestor: %s", spec.get()));
}
#endif
ancestorsArray.AppendElement(uriClone);
}
// next ancestor
treeItem = parentTreeItem;
}
nsAutoString violatedDirective;
// Now that we've got the ancestry chain in ancestorsArray, time to check
// them against any CSP.
for (uint32_t i = 0; i < mPolicies.Length(); i++) {
for (uint32_t a = 0; a < ancestorsArray.Length(); a++) {
// TODO(sid) the mapping from frame-ancestors context to TYPE_DOCUMENT is
// forced. while this works for now, we will implement something in
// bug 999656.
#ifdef PR_LOGGING
{
nsAutoCString spec;
ancestorsArray[a]->GetSpec(spec);
CSPCONTEXTLOG(("nsCSPContext::PermitsAncestry, checking ancestor: %s", spec.get()));
}
#endif
if (!mPolicies[i]->permits(nsIContentPolicy::TYPE_DOCUMENT,
ancestorsArray[a],
EmptyString(), // no nonce
violatedDirective)) {
// Policy is violated
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
NS_ENSURE_TRUE(observerService, NS_ERROR_NOT_AVAILABLE);
observerService->NotifyObservers(ancestorsArray[a],
CSP_VIOLATION_TOPIC,
violatedDirective.get());
// TODO(sid) generate violation reports and remove NotifyObservers
// call. (in bug 994322)
// TODO(sid) implement logic for report-only (in bug 994322)
*outPermitsAncestry = false;
}
}
}
return NS_OK;
}

Просмотреть файл

@ -7,6 +7,7 @@
#define nsCSPContext_h___
#include "nsCSPUtils.h"
#include "nsDataHashtable.h"
#include "nsIChannel.h"
#include "nsIClassInfo.h"
#include "nsIContentSecurityPolicy.h"
@ -38,6 +39,7 @@ class nsCSPContext : public nsIContentSecurityPolicy
nsTArray<nsCSPPolicy*> mPolicies;
nsCOMPtr<nsIURI> mSelfURI;
nsDataHashtable<nsCStringHashKey, int16_t> mShouldLoadCache;
};
#endif /* nsCSPContext_h___ */

Просмотреть файл

@ -636,6 +636,8 @@ CSP_DirectiveToContentType(enum CSPDirective aDir)
case CSP_MEDIA_SRC: return nsIContentPolicy::TYPE_MEDIA;
case CSP_OBJECT_SRC: return nsIContentPolicy::TYPE_OBJECT;
case CSP_FRAME_SRC: return nsIContentPolicy::TYPE_SUBDOCUMENT;
// TODO(sid): fix this mapping to be more precise (bug 999656)
case CSP_FRAME_ANCESTORS: return nsIContentPolicy::TYPE_DOCUMENT;
// Fall through to error for the following Directives:
case CSP_DEFAULT_SRC:

Просмотреть файл

@ -49,6 +49,7 @@ enum CSPDirective {
CSP_FONT_SRC,
CSP_CONNECT_SRC,
CSP_REPORT_URI,
CSP_FRAME_ANCESTORS,
// CSP_LAST_DIRECTIVE_VALUE always needs to be the last element in the enum
// because we use it to calculate the size for the char* array.
CSP_LAST_DIRECTIVE_VALUE
@ -65,6 +66,7 @@ static const char* CSPStrDirectives[] = {
"font-src", // CSP_FONT_SRC
"connect-src", // CSP_CONNECT_SRC
"report-uri", // CSP_REPORT_URI
"frame-ancestors" // CSP_FRAME_ANCESTORS
};
inline const char* CSP_EnumToDirective(enum CSPDirective aDir)

Просмотреть файл

@ -196,6 +196,7 @@ const char kLoadAsData[] = "loadAsData";
nsIXPConnect *nsContentUtils::sXPConnect;
nsIScriptSecurityManager *nsContentUtils::sSecurityManager;
nsIPrincipal *nsContentUtils::sSystemPrincipal;
nsIPrincipal *nsContentUtils::sNullSubjectPrincipal;
nsIParserService *nsContentUtils::sParserService = nullptr;
nsNameSpaceManager *nsContentUtils::sNameSpaceManager;
nsIIOService *nsContentUtils::sIOService;
@ -379,6 +380,7 @@ nsContentUtils::Init()
sSecurityManager->GetSystemPrincipal(&sSystemPrincipal);
MOZ_ASSERT(sSystemPrincipal);
NS_ADDREF(sNullSubjectPrincipal = new nsNullPrincipal());
nsresult rv = CallGetService(NS_IOSERVICE_CONTRACTID, &sIOService);
if (NS_FAILED(rv)) {
@ -1436,6 +1438,7 @@ nsContentUtils::Shutdown()
sXPConnect = nullptr;
NS_IF_RELEASE(sSecurityManager);
NS_IF_RELEASE(sSystemPrincipal);
NS_IF_RELEASE(sNullSubjectPrincipal);
NS_IF_RELEASE(sParserService);
NS_IF_RELEASE(sIOService);
NS_IF_RELEASE(sLineBreaker);
@ -2322,9 +2325,33 @@ nsContentUtils::SubjectPrincipal()
return GetSystemPrincipal();
}
JSCompartment* compartment = js::GetContextCompartment(cx);
MOZ_ASSERT(compartment);
JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
JSCompartment *compartment = js::GetContextCompartment(cx);
// When an AutoJSAPI is instantiated, we are in a null compartment until the
// first JSAutoCompartment, which is kind of a purgatory as far as permissions
// go. It would be nice to just hard-abort if somebody does a security check
// in this purgatory zone, but that would be too fragile, since it could be
// triggered by random IsCallerChrome() checks 20-levels deep.
//
// So we want to return _something_ here - and definitely not the System
// Principal, since that would make an AutoJSAPI a very dangerous thing to
// instantiate.
//
// The natural thing to return is a null principal. Ideally, we'd return a
// different null principal each time, to avoid any unexpected interactions
// when the principal accidentally gets inherited somewhere. But
// GetSubjectPrincipal doesn't return strong references, so there's no way to
// sanely manage the lifetime of multiple null principals.
//
// So we use a singleton null principal. To avoid it being accidentally
// inherited and becoming a "real" subject or object principal, we do a
// release-mode assert during compartment creation against using this
// principal on an actual global.
if (!compartment) {
return sNullSubjectPrincipal;
}
JSPrincipals *principals = JS_GetCompartmentPrincipals(compartment);
return nsJSPrincipals::get(principals);
}

Просмотреть файл

@ -667,6 +667,28 @@ nsresult TestGoodGeneratedPolicies() {
"script-src http://policy-uri" },
{ "img-src 'self'; ",
"img-src http://www.selfuri.com" },
{ "frame-ancestors foo-bar.com",
"frame-ancestors http://foo-bar.com" },
{ "frame-ancestors http://a.com",
"frame-ancestors http://a.com" },
{ "frame-ancestors 'self'",
"frame-ancestors http://www.selfuri.com" },
{ "frame-ancestors http://self.com:88",
"frame-ancestors http://self.com:88" },
{ "frame-ancestors http://a.b.c.d.e.f.g.h.i.j.k.l.x.com",
"frame-ancestors http://a.b.c.d.e.f.g.h.i.j.k.l.x.com" },
{ "frame-ancestors https://self.com:34",
"frame-ancestors https://self.com:34" },
{ "default-src 'none'; frame-ancestors 'self'",
"default-src 'none'; frame-ancestors http://www.selfuri.com" },
{ "frame-ancestors http://self:80",
"frame-ancestors http://self:80" },
{ "frame-ancestors http://self.com/bar",
"frame-ancestors http://self.com" },
{ "default-src 'self'; frame-ancestors 'self'",
"default-src http://www.selfuri.com; frame-ancestors http://www.selfuri.com" },
{ "frame-ancestors http://bar.com/foo.png",
"frame-ancestors http://bar.com" },
};
uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);

Просмотреть файл

@ -154,15 +154,6 @@ fuzzy(1,65536) random-if(gtk2Widget) fails-if(B2G) fuzzy-if(Android,9,65536) fai
# random-if(B2G) from bug 983650
fuzzy(1,65536) random-if(B2G) fuzzy-if(Android,9,65536) random-if(Android&&AndroidVersion<15) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha&premult wrapper.html?colors-half-alpha.png
# Test over-bright premult:
# random-if(B2G) from bug 983650
# This test assumes that the compositor is able to correctly handle superluminant
# pixels in a WebGL canvas with premultiplied alpha. This is not handled by
# Skia's software blending code. Consequently, this test is random on
# basic-layers when using skia. See bug 1004483.
fuzzy(1,65536) random-if(B2G) fuzzy-if(Android,9,65536) random-if(Android&&AndroidVersion<15) random-if(skiaContent&&!layersGPUAccelerated) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha&premult wrapper.html?colors-half-alpha.png
# Check for hanging framebuffer bindings:
random-if(Android&&AndroidVersion<15) == webgl-hanging-fb-test.html?__&________ wrapper.html?green.png
random-if(Android&&AndroidVersion<15) == webgl-hanging-fb-test.html?aa&________ wrapper.html?green.png

Просмотреть файл

@ -6,43 +6,10 @@
#include "mozilla/dom/HTMLAllCollection.h"
#include "jsapi.h"
#include "mozilla/HoldDropJSObjects.h"
#include "nsContentUtils.h"
#include "nsDOMClassInfo.h"
#include "mozilla/dom/HTMLAllCollectionBinding.h"
#include "mozilla/dom/Nullable.h"
#include "mozilla/dom/UnionTypes.h"
#include "nsHTMLDocument.h"
#include "nsJSUtils.h"
#include "nsWrapperCacheInlines.h"
#include "xpcpublic.h"
using namespace mozilla;
using namespace mozilla::dom;
class nsHTMLDocumentSH
{
public:
static bool DocumentAllGetProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
JS::MutableHandle<JS::Value> vp);
static bool DocumentAllNewResolve(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
JS::MutableHandle<JSObject*> objp);
static void ReleaseDocument(JSFreeOp *fop, JSObject *obj);
static bool CallToGetPropMapper(JSContext *cx, unsigned argc, JS::Value *vp);
};
const JSClass sHTMLDocumentAllClass = {
"HTML document.all class",
JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_NEW_RESOLVE |
JSCLASS_EMULATES_UNDEFINED,
JS_PropertyStub, /* addProperty */
JS_DeletePropertyStub, /* delProperty */
nsHTMLDocumentSH::DocumentAllGetProperty, /* getProperty */
JS_StrictPropertyStub, /* setProperty */
JS_EnumerateStub,
(JSResolveOp)nsHTMLDocumentSH::DocumentAllNewResolve,
JS_ConvertStub,
nsHTMLDocumentSH::ReleaseDocument,
nsHTMLDocumentSH::CallToGetPropMapper
};
namespace mozilla {
namespace dom {
@ -51,37 +18,31 @@ HTMLAllCollection::HTMLAllCollection(nsHTMLDocument* aDocument)
: mDocument(aDocument)
{
MOZ_ASSERT(mDocument);
mozilla::HoldJSObjects(this);
SetIsDOMBinding();
}
HTMLAllCollection::~HTMLAllCollection()
{
mObject = nullptr;
mozilla::DropJSObjects(this);
}
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(HTMLAllCollection, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(HTMLAllCollection, Release)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(HTMLAllCollection,
mDocument,
mCollection,
mNamedMap)
NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLAllCollection)
NS_IMPL_CYCLE_COLLECTING_ADDREF(HTMLAllCollection)
NS_IMPL_CYCLE_COLLECTING_RELEASE(HTMLAllCollection)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(HTMLAllCollection)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCollection)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNamedMap)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(HTMLAllCollection)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(HTMLAllCollection)
tmp->mObject = nullptr;
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCollection)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mNamedMap)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(HTMLAllCollection)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mObject)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
nsINode*
HTMLAllCollection::GetParentObject() const
{
return mDocument;
}
uint32_t
HTMLAllCollection::Length()
@ -95,32 +56,6 @@ HTMLAllCollection::Item(uint32_t aIndex)
return Collection()->Item(aIndex);
}
JSObject*
HTMLAllCollection::GetObject(JSContext* aCx, ErrorResult& aRv)
{
MOZ_ASSERT(aCx);
if (!mObject) {
JS::Rooted<JSObject*> wrapper(aCx, mDocument->GetWrapper());
MOZ_ASSERT(wrapper);
JSAutoCompartment ac(aCx, wrapper);
JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, wrapper));
mObject = JS_NewObject(aCx, &sHTMLDocumentAllClass, JS::NullPtr(), global);
if (!mObject) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
// Make the JSObject hold a reference to the document.
JS_SetPrivate(mObject, ToSupports(mDocument));
NS_ADDREF(mDocument);
}
JS::ExposeObjectToActiveJS(mObject);
return mObject;
}
nsContentList*
HTMLAllCollection::Collection()
{
@ -186,197 +121,43 @@ HTMLAllCollection::GetDocumentAllList(const nsAString& aID)
return docAllList;
}
nsISupports*
HTMLAllCollection::GetNamedItem(const nsAString& aID,
nsWrapperCache** aCache)
void
HTMLAllCollection::NamedGetter(const nsAString& aID,
bool& aFound,
Nullable<OwningNodeOrHTMLCollection>& aResult)
{
nsContentList* docAllList = GetDocumentAllList(aID);
if (!docAllList) {
return nullptr;
aFound = false;
aResult.SetNull();
return;
}
// Check if there are more than 1 entries. Do this by getting the second one
// rather than the length since getting the length always requires walking
// the entire document.
nsIContent* cont = docAllList->Item(1, true);
if (cont) {
*aCache = docAllList;
return static_cast<nsINodeList*>(docAllList);
if (docAllList->Item(1, true)) {
aFound = true;
aResult.SetValue().SetAsHTMLCollection() = docAllList;
return;
}
// There's only 0 or 1 items. Return the first one or null.
*aCache = cont = docAllList->Item(0, true);
return cont;
if (nsIContent* node = docAllList->Item(0, true)) {
aFound = true;
aResult.SetValue().SetAsNode() = node;
return;
}
aFound = false;
aResult.SetNull();
}
JSObject*
HTMLAllCollection::WrapObject(JSContext* aCx)
{
return HTMLAllCollectionBinding::Wrap(aCx, this);
}
} // namespace dom
} // namespace mozilla
static nsHTMLDocument*
GetDocument(JSObject *obj)
{
MOZ_ASSERT(js::GetObjectJSClass(obj) == &sHTMLDocumentAllClass);
return static_cast<nsHTMLDocument*>(
static_cast<nsINode*>(JS_GetPrivate(obj)));
}
bool
nsHTMLDocumentSH::DocumentAllGetProperty(JSContext *cx, JS::Handle<JSObject*> obj_,
JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp)
{
JS::Rooted<JSObject*> obj(cx, obj_);
// document.all.item and .namedItem get their value in the
// newResolve hook, so nothing to do for those properties here. And
// we need to return early to prevent <div id="item"> from shadowing
// document.all.item(), etc.
if (nsDOMClassInfo::sItem_id == id || nsDOMClassInfo::sNamedItem_id == id) {
return true;
}
JS::Rooted<JSObject*> proto(cx);
while (js::GetObjectJSClass(obj) != &sHTMLDocumentAllClass) {
if (!js::GetObjectProto(cx, obj, &proto)) {
return false;
}
if (!proto) {
NS_ERROR("The JS engine lies!");
return true;
}
obj = proto;
}
HTMLAllCollection* allCollection = GetDocument(obj)->All();
nsISupports *result;
nsWrapperCache *cache;
if (JSID_IS_STRING(id)) {
if (nsDOMClassInfo::sLength_id == id) {
// Make sure <div id="length"> doesn't shadow document.all.length.
vp.setNumber(allCollection->Length());
return true;
}
// For all other strings, look for an element by id or name.
nsDependentJSString str(id);
result = allCollection->GetNamedItem(str, &cache);
} else if (JSID_IS_INT(id) && JSID_TO_INT(id) >= 0) {
// Map document.all[n] (where n is a number) to the n:th item in
// the document.all node list.
nsIContent* node = allCollection->Item(SafeCast<uint32_t>(JSID_TO_INT(id)));
result = node;
cache = node;
} else {
result = nullptr;
}
if (result) {
nsresult rv = nsContentUtils::WrapNative(cx, result, cache, vp);
if (NS_FAILED(rv)) {
xpc::Throw(cx, rv);
return false;
}
} else {
vp.setUndefined();
}
return true;
}
bool
nsHTMLDocumentSH::DocumentAllNewResolve(JSContext *cx, JS::Handle<JSObject*> obj,
JS::Handle<jsid> id,
JS::MutableHandle<JSObject*> objp)
{
JS::Rooted<JS::Value> v(cx);
if (nsDOMClassInfo::sItem_id == id || nsDOMClassInfo::sNamedItem_id == id) {
// Define the item() or namedItem() method.
JSFunction *fnc = ::JS_DefineFunctionById(cx, obj, id, CallToGetPropMapper,
0, JSPROP_ENUMERATE);
objp.set(obj);
return fnc != nullptr;
}
if (nsDOMClassInfo::sLength_id == id) {
// document.all.length. Any jsval other than undefined would do
// here, all we need is to get into the code below that defines
// this propery on obj, the rest happens in
// DocumentAllGetProperty().
v = JSVAL_ONE;
} else {
if (!DocumentAllGetProperty(cx, obj, id, &v)) {
return false;
}
}
bool ok = true;
if (v.get() != JSVAL_VOID) {
ok = ::JS_DefinePropertyById(cx, obj, id, v, 0);
objp.set(obj);
}
return ok;
}
void
nsHTMLDocumentSH::ReleaseDocument(JSFreeOp *fop, JSObject *obj)
{
nsIHTMLDocument* doc = GetDocument(obj);
if (doc) {
nsContentUtils::DeferredFinalize(doc);
}
}
bool
nsHTMLDocumentSH::CallToGetPropMapper(JSContext *cx, unsigned argc, jsval *vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
// Handle document.all("foo") style access to document.all.
if (args.length() != 1) {
// XXX: Should throw NS_ERROR_XPC_NOT_ENOUGH_ARGS for argc < 1,
// and create a new NS_ERROR_XPC_TOO_MANY_ARGS for argc > 1? IE
// accepts nothing other than one arg.
xpc::Throw(cx, NS_ERROR_INVALID_ARG);
return false;
}
// Convert all types to string.
JS::Rooted<JSString*> str(cx, JS::ToString(cx, args[0]));
if (!str) {
return false;
}
// If we are called via document.all(id) instead of document.all.item(i) or
// another method, use the document.all callee object as self.
JS::Rooted<JSObject*> self(cx);
if (args.calleev().isObject() &&
JS_GetClass(&args.calleev().toObject()) == &sHTMLDocumentAllClass) {
self = &args.calleev().toObject();
} else {
self = JS_THIS_OBJECT(cx, vp);
if (!self)
return false;
}
size_t length;
JS::Anchor<JSString *> anchor(str);
const jschar *chars = ::JS_GetStringCharsAndLength(cx, str, &length);
if (!chars) {
return false;
}
return ::JS_GetUCProperty(cx, self, chars, length, args.rval());
}

Просмотреть файл

@ -7,49 +7,84 @@
#ifndef mozilla_dom_HTMLAllCollection_h
#define mozilla_dom_HTMLAllCollection_h
#include "js/RootingAPI.h"
#include "nsAutoPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsISupportsImpl.h"
#include "nsRefPtrHashtable.h"
#include "nsWrapperCache.h"
#include <stdint.h>
class nsContentList;
class nsHTMLDocument;
class nsIContent;
class nsWrapperCache;
class nsINode;
namespace mozilla {
class ErrorResult;
namespace dom {
class HTMLAllCollection
class OwningNodeOrHTMLCollection;
template<typename> class Nullable;
class HTMLAllCollection MOZ_FINAL : public nsISupports
, public nsWrapperCache
{
public:
HTMLAllCollection(nsHTMLDocument* aDocument);
~HTMLAllCollection();
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(HTMLAllCollection)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(HTMLAllCollection)
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(HTMLAllCollection)
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
nsINode* GetParentObject() const;
uint32_t Length();
nsIContent* Item(uint32_t aIndex);
void Item(const nsAString& aName, Nullable<OwningNodeOrHTMLCollection>& aResult)
{
NamedItem(aName, aResult);
}
nsIContent* IndexedGetter(uint32_t aIndex, bool& aFound)
{
nsIContent* result = Item(aIndex);
aFound = !!result;
return result;
}
JSObject* GetObject(JSContext* aCx, ErrorResult& aRv);
nsISupports* GetNamedItem(const nsAString& aID, nsWrapperCache** aCache);
void NamedItem(const nsAString& aName,
Nullable<OwningNodeOrHTMLCollection>& aResult)
{
bool found = false;
NamedGetter(aName, found, aResult);
}
void NamedGetter(const nsAString& aName,
bool& aFound,
Nullable<OwningNodeOrHTMLCollection>& aResult);
void GetSupportedNames(unsigned flags, nsTArray<nsString>& aNames)
{
}
bool NameIsEnumerable(const nsAString& aName)
{
return false;
}
void LegacyCall(JS::Handle<JS::Value>, const nsAString& aName,
Nullable<OwningNodeOrHTMLCollection>& aResult)
{
NamedItem(aName, aResult);
}
private:
nsContentList* Collection();
/**
* Returns the NodeList for document.all[aID], or null if there isn't one.
* Returns the HTMLCollection for document.all[aID], or null if there isn't one.
*/
nsContentList* GetDocumentAllList(const nsAString& aID);
JS::Heap<JSObject*> mObject;
nsRefPtr<nsHTMLDocument> mDocument;
nsRefPtr<nsContentList> mCollection;
nsRefPtrHashtable<nsStringHashKey, nsContentList> mNamedMap;

Просмотреть файл

@ -2564,12 +2564,6 @@ nsHTMLDocument::All()
return mAll;
}
JSObject*
nsHTMLDocument::GetAll(JSContext* aCx, ErrorResult& aRv)
{
return All()->GetObject(aCx, aRv);
}
static void
NotifyEditableStateChange(nsINode *aNode, nsIDocument *aDocument)
{

Просмотреть файл

@ -104,7 +104,6 @@ public:
NS_DECL_NSIDOMHTMLDOCUMENT
mozilla::dom::HTMLAllCollection* All();
JSObject* GetAll(JSContext* aCx, mozilla::ErrorResult& aRv);
nsISupports* ResolveName(const nsAString& aName, nsWrapperCache **aCache);

Просмотреть файл

@ -78,16 +78,17 @@ public:
int64_t aEndTime,
int64_t aCurrentTime) = 0;
// Called to move the reader into idle/active state. When the reader is
// Called to move the reader into idle state. When the reader is
// created it is assumed to be active (i.e. not idle). When the media
// element is paused and we don't need to decode any more data, the state
// machine calls SetIdle() to inform the reader that its decoder won't be
// needed for a while. When we need to decode data again, the state machine
// calls SetActive() to activate the decoder. The reader can use these
// notifications to enter/exit a low power state when the decoder isn't
// needed, if desired. This is most useful on mobile.
// needed for a while. The reader can use these notifications to enter
// a low power state when the decoder isn't needed, if desired.
// This is most useful on mobile.
// Note: DecodeVideoFrame, DecodeAudioData, ReadMetadata and Seek should
// activate the decoder if necessary. The state machine only needs to know
// when to call SetIdle().
virtual void SetIdle() { }
virtual void SetActive() { }
// Tell the reader that the data decoded are not for direct playback, so it
// can accept more files, in particular those which have more channels than

Просмотреть файл

@ -194,7 +194,6 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
mAmpleAudioThresholdUsecs(AMPLE_AUDIO_USECS),
mDispatchedAudioDecodeTask(false),
mDispatchedVideoDecodeTask(false),
mIsReaderIdle(false),
mAudioCaptured(false),
mTransportSeekable(true),
mMediaSeekable(true),
@ -573,7 +572,6 @@ MediaDecoderStateMachine::DecodeVideo()
mDispatchedVideoDecodeTask = false;
return;
}
EnsureActive();
// We don't want to consider skipping to the next keyframe if we've
// only just started up the decode loop, so wait until we've decoded
@ -667,7 +665,6 @@ MediaDecoderStateMachine::DecodeAudio()
mDispatchedAudioDecodeTask = false;
return;
}
EnsureActive();
// We don't want to consider skipping to the next keyframe if we've
// only just started up the decode loop, so wait until we've decoded
@ -1499,21 +1496,6 @@ MediaDecoderStateMachine::EnqueueDecodeMetadataTask()
return NS_OK;
}
void
MediaDecoderStateMachine::EnsureActive()
{
AssertCurrentThreadInMonitor();
MOZ_ASSERT(OnDecodeThread());
if (!mIsReaderIdle) {
return;
}
mIsReaderIdle = false;
{
ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
SetReaderActive();
}
}
void
MediaDecoderStateMachine::SetReaderIdle()
{
@ -1529,14 +1511,6 @@ MediaDecoderStateMachine::SetReaderIdle()
mReader->SetIdle();
}
void
MediaDecoderStateMachine::SetReaderActive()
{
DECODER_LOG(PR_LOG_DEBUG, "SetReaderActive()");
MOZ_ASSERT(OnDecodeThread());
mReader->SetActive();
}
void
MediaDecoderStateMachine::DispatchDecodeTasksIfNeeded()
{
@ -1575,20 +1549,14 @@ MediaDecoderStateMachine::DispatchDecodeTasksIfNeeded()
EnsureVideoDecodeTaskQueued();
}
if (mIsReaderIdle == needIdle) {
return;
}
mIsReaderIdle = needIdle;
RefPtr<nsIRunnable> event;
if (mIsReaderIdle) {
event = NS_NewRunnableMethod(this, &MediaDecoderStateMachine::SetReaderIdle);
} else {
event = NS_NewRunnableMethod(this, &MediaDecoderStateMachine::SetReaderActive);
}
if (NS_FAILED(mDecodeTaskQueue->Dispatch(event.forget())) &&
mState != DECODER_STATE_SHUTDOWN) {
if (needIdle) {
RefPtr<nsIRunnable> event = NS_NewRunnableMethod(
this, &MediaDecoderStateMachine::SetReaderIdle);
nsresult rv = mDecodeTaskQueue->Dispatch(event.forget());
if (NS_FAILED(rv) && mState != DECODER_STATE_SHUTDOWN) {
NS_WARNING("Failed to dispatch event to set decoder idle state");
}
}
}
nsresult
@ -1828,7 +1796,6 @@ nsresult MediaDecoderStateMachine::DecodeMetadata()
if (mState != DECODER_STATE_DECODING_METADATA) {
return NS_ERROR_FAILURE;
}
EnsureActive();
nsresult res;
MediaInfo info;
@ -1930,7 +1897,6 @@ void MediaDecoderStateMachine::DecodeSeek()
if (mState != DECODER_STATE_SEEKING) {
return;
}
EnsureActive();
// During the seek, don't have a lock on the decoder state,
// otherwise long seek operations can block the main thread.

Просмотреть файл

@ -565,11 +565,9 @@ protected:
// The decoder monitor must be held.
nsresult EnqueueDecodeSeekTask();
// Calls the reader's SetIdle(), with aIsIdle as parameter. This is only
// called in a task dispatched to the decode task queue, don't call it
// directly.
// Calls the reader's SetIdle(). This is only called in a task dispatched to
// the decode task queue, don't call it directly.
void SetReaderIdle();
void SetReaderActive();
// Re-evaluates the state and determines whether we need to dispatch
// events to run the decode, or if not whether we should set the reader
@ -577,11 +575,6 @@ protected:
// The decoder monitor must be held.
void DispatchDecodeTasksIfNeeded();
// Called before we do anything on the decode task queue to set the reader
// as not idle if it was idle. This is called before we decode, seek, or
// decode metadata (in case we were dormant or awaiting resources).
void EnsureActive();
// Queries our state to see whether the decode has finished for all streams.
// If so, we move into DECODER_STATE_COMPLETED and schedule the state machine
// to run.
@ -851,12 +844,6 @@ protected:
// the video decode.
bool mDispatchedVideoDecodeTask;
// True when the reader is initialized, but has been ordered "idle" by the
// state machine. This happens when the MediaQueue's of decoded data are
// "full" and playback is paused. The reader may choose to use the idle
// notification to enter a low power state.
bool mIsReaderIdle;
// If the video decode is falling behind the audio, we'll start dropping the
// inter-frames up until the next keyframe which is at or before the current
// playback position. skipToNextKeyframe is true if we're currently

Просмотреть файл

@ -147,7 +147,6 @@ private:
mActiveVideoDecoder = i;
MSE_DEBUG("%p MSR::DecodeVF switching to %d", this, mActiveVideoDecoder);
GetVideoReader()->SetActive();
return true;
}
}
@ -326,7 +325,6 @@ MediaSourceReader::CallDecoderInitialization()
MediaDecoderReader* reader = decoder->GetReader();
MSE_DEBUG("%p: Initializating subdecoder %p reader %p", this, decoder.get(), reader);
reader->SetActive();
MediaInfo mi;
nsAutoPtr<MetadataTags> tags; // TODO: Handle metadata.
nsresult rv;
@ -456,8 +454,6 @@ MediaSourceReader::ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags)
for (uint32_t i = 0; i < mDecoders.Length(); ++i) {
MediaDecoderReader* reader = mDecoders[i]->GetReader();
reader->SetActive(); // XXX check where this should be called
MediaInfo mi = reader->GetMediaInfo();
if (mi.HasVideo() && !mInfo.HasVideo()) {

Просмотреть файл

@ -47,9 +47,6 @@ MediaOmxReader::MediaOmxReader(AbstractMediaDecoder *aDecoder)
, mVideoSeekTimeUs(-1)
, mAudioSeekTimeUs(-1)
, mSkipCount(0)
#ifdef DEBUG
, mIsActive(true)
#endif
{
#ifdef PR_LOGGING
if (!gMediaDecoderLog) {
@ -135,7 +132,7 @@ nsresult MediaOmxReader::ReadMetadata(MediaInfo* aInfo,
MetadataTags** aTags)
{
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
MOZ_ASSERT(mIsActive);
EnsureActive();
*aTags = nullptr;
@ -211,7 +208,8 @@ nsresult MediaOmxReader::ReadMetadata(MediaInfo* aInfo,
bool MediaOmxReader::DecodeVideoFrame(bool &aKeyframeSkip,
int64_t aTimeThreshold)
{
MOZ_ASSERT(mIsActive);
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
EnsureActive();
// Record number of frames decoded and parsed. Automatically update the
// stats counters using the AutoNotifyDecoded stack-based class.
@ -341,7 +339,7 @@ void MediaOmxReader::NotifyDataArrived(const char* aBuffer, uint32_t aLength, in
bool MediaOmxReader::DecodeAudioData()
{
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
MOZ_ASSERT(mIsActive);
EnsureActive();
// This is the approximate byte position in the stream.
int64_t pos = mDecoder->GetResource()->Tell();
@ -375,7 +373,7 @@ bool MediaOmxReader::DecodeAudioData()
nsresult MediaOmxReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime)
{
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
MOZ_ASSERT(mIsActive);
EnsureActive();
ResetDecode();
VideoFrameContainer* container = mDecoder->GetVideoFrameContainer();
@ -410,19 +408,13 @@ static uint64_t BytesToTime(int64_t offset, uint64_t length, uint64_t durationUs
}
void MediaOmxReader::SetIdle() {
#ifdef DEBUG
mIsActive = false;
#endif
if (!mOmxDecoder.get()) {
return;
}
mOmxDecoder->Pause();
}
void MediaOmxReader::SetActive() {
#ifdef DEBUG
mIsActive = true;
#endif
void MediaOmxReader::EnsureActive() {
if (!mOmxDecoder.get()) {
return;
}

Просмотреть файл

@ -49,6 +49,10 @@ protected:
// information used for creating OMX decoder such as video/audio codec.
virtual nsresult InitOmxDecoder();
// Called inside DecodeVideoFrame, DecodeAudioData, ReadMetadata and Seek
// to activate the decoder automatically.
virtual void EnsureActive();
public:
MediaOmxReader(AbstractMediaDecoder* aDecoder);
~MediaOmxReader();
@ -83,7 +87,6 @@ public:
virtual nsresult Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime);
virtual void SetIdle() MOZ_OVERRIDE;
virtual void SetActive() MOZ_OVERRIDE;
void SetAudioChannel(dom::AudioChannel aAudioChannel) {
mAudioChannel = aAudioChannel;
@ -99,12 +102,6 @@ public:
// ANDROID_VERSION < 19
void CheckAudioOffload();
#endif
private:
// This flag is true when SetActive() has been called without a matching
// SetIdle(). This is used to sanity check the SetIdle/SetActive calls, to
// ensure SetActive has been called before a decode call.
DebugOnly<bool> mIsActive;
};
} // namespace mozilla

Просмотреть файл

@ -299,18 +299,6 @@ nsresult RtspOmxReader::Seek(int64_t aTime, int64_t aStartTime,
return MediaOmxReader::Seek(aTime, aStartTime, aEndTime, aCurrentTime);
}
nsresult
RtspOmxReader::ReadMetadata(MediaInfo* aInfo,
MetadataTags** aTags)
{
SetActive();
nsresult rv = MediaOmxReader::ReadMetadata(aInfo, aTags);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
void RtspOmxReader::SetIdle() {
// Call parent class to set OMXCodec idle.
MediaOmxReader::SetIdle();
@ -326,7 +314,7 @@ void RtspOmxReader::SetIdle() {
}
}
void RtspOmxReader::SetActive() {
void RtspOmxReader::EnsureActive() {
// Need to start RTSP streaming OMXCodec decoding.
if (mRtspResource) {
nsIStreamingProtocolController* controller =
@ -338,7 +326,7 @@ void RtspOmxReader::SetActive() {
}
// Call parent class to set OMXCodec active.
MediaOmxReader::SetActive();
MediaOmxReader::EnsureActive();
}
} // namespace mozilla

Просмотреть файл

@ -28,6 +28,7 @@ class RtspOmxReader : public MediaOmxReader
protected:
// Provide a Rtsp extractor.
nsresult InitOmxDecoder() MOZ_FINAL MOZ_OVERRIDE;
virtual void EnsureActive() MOZ_OVERRIDE;
public:
RtspOmxReader(AbstractMediaDecoder* aDecoder)
@ -44,9 +45,6 @@ public:
MOZ_COUNT_DTOR(RtspOmxReader);
}
virtual nsresult ReadMetadata(MediaInfo* aInfo,
MetadataTags** aTags) MOZ_OVERRIDE;
// Implement a time-based seek instead of byte-based..
virtual nsresult Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
int64_t aCurrentTime) MOZ_FINAL MOZ_OVERRIDE;
@ -66,7 +64,6 @@ public:
}
virtual void SetIdle() MOZ_OVERRIDE;
virtual void SetActive() MOZ_OVERRIDE;
private:
// A pointer to RtspMediaResource for calling the Rtsp specific function.

Просмотреть файл

@ -5,6 +5,7 @@
#include "gfx2DGlue.h"
#include "mozilla/dom/SVGAnimatedTransformList.h"
#include "mozilla/dom/SVGGraphicsElementBinding.h"
#include "mozilla/dom/SVGTransformableElement.h"
#include "mozilla/dom/SVGMatrix.h"
#include "mozilla/dom/SVGSVGElement.h"
@ -182,7 +183,8 @@ SVGTransformableElement::GetFarthestViewportElement()
}
already_AddRefed<SVGIRect>
SVGTransformableElement::GetBBox(ErrorResult& rv)
SVGTransformableElement::GetBBox(const SVGBoundingBoxOptions& aOptions,
ErrorResult& rv)
{
nsIFrame* frame = GetPrimaryFrame(Flush_Layout);
@ -190,14 +192,37 @@ SVGTransformableElement::GetBBox(ErrorResult& rv)
rv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsISVGChildFrame* svgframe = do_QueryFrame(frame);
if (!svgframe) {
rv.Throw(NS_ERROR_NOT_IMPLEMENTED); // XXX: outer svg
return nullptr;
}
if (!NS_SVGNewGetBBoxEnabled()) {
return NS_NewSVGRect(this, ToRect(nsSVGUtils::GetBBox(frame)));
} else {
uint32_t aFlags = 0;
if (aOptions.mFill) {
aFlags |= nsSVGUtils::eBBoxIncludeFill;
}
if (aOptions.mStroke) {
aFlags |= nsSVGUtils::eBBoxIncludeStroke;
}
if (aOptions.mMarkers) {
aFlags |= nsSVGUtils::eBBoxIncludeMarkers;
}
if (aOptions.mClipped) {
aFlags |= nsSVGUtils::eBBoxIncludeClipped;
}
if (aFlags == 0) {
return NS_NewSVGRect(this,0,0,0,0);
}
if (aFlags == nsSVGUtils::eBBoxIncludeMarkers ||
aFlags == nsSVGUtils::eBBoxIncludeClipped) {
aFlags |= nsSVGUtils::eBBoxIncludeFill;
}
return NS_NewSVGRect(this, ToRect(nsSVGUtils::GetBBox(frame, aFlags)));
}
}
already_AddRefed<SVGMatrix>

Просмотреть файл

@ -19,6 +19,7 @@ class SVGAnimatedTransformList;
class SVGGraphicsElement;
class SVGMatrix;
class SVGIRect;
class SVGBoundingBoxOptions;
class SVGTransformableElement : public nsSVGElement
{
@ -33,7 +34,8 @@ public:
already_AddRefed<SVGAnimatedTransformList> Transform();
nsSVGElement* GetNearestViewportElement();
nsSVGElement* GetFarthestViewportElement();
already_AddRefed<SVGIRect> GetBBox(ErrorResult& rv);
already_AddRefed<SVGIRect> GetBBox(const SVGBoundingBoxOptions& aOptions,
ErrorResult& rv);
already_AddRefed<SVGMatrix> GetCTM();
already_AddRefed<SVGMatrix> GetScreenCTM();
already_AddRefed<SVGMatrix> GetTransformToElement(SVGGraphicsElement& aElement,

Просмотреть файл

@ -0,0 +1,299 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 500 500" width="500px" height="500px">
<defs>
<clipPath id="rect01" clip-rule="evenodd" clipPathUnits="objectBoundingBox">
<rect x="0" y="0" width="0.5" height="1.0"/>
</clipPath>
<clipPath id="rect02" clip-rule="evenodd" clipPathUnits="objectBoundingBox">
<rect x="0.5" y="0" width="0.5" height="1.0"/>
</clipPath>
<clipPath id="rect03" clip-rule="evenodd" clipPathUnits="objectBoundingBox">
<rect x="0.5" y="0" width="0.5" height="1.0"/>
</clipPath>
<clipPath id="rect04" clip-rule="evenodd" clipPathUnits="objectBoundingBox">
<rect x="0" y="0" width="0.5" height="1.0"/>
</clipPath>
<clipPath id="rect05" clip-rule="evenodd">
<rect x="0" y="60" width="10px" height="23px"/>
</clipPath>
<clipPath id="rect06" clip-rule="evenodd">
<rect x="10" y="60" width="10px" height="23px"/>
</clipPath>
<clipPath id="rect4" clip-rule="evenodd">
<rect x="200" y="200" width="200" height="200"/>
</clipPath>
<clipPath id="rect-none" clip-rule="evenodd">
</clipPath>
<clipPath id="rect5" clip-rule="evenodd">
<rect x="0" y="0" width="100" height="100"/>
</clipPath>
<clipPath id="rect6" clip-rule="evenodd">
<rect x="150" y="0" width="100" height="100"/>
</clipPath>
<clipPath id="rect7" clip-rule="evenodd">
<rect x="0" y="100" width="100" height="100"/>
</clipPath>
<clipPath id="rect8" clip-rule="evenodd">
<rect x="10" y="10" width="180" height="180"/>
</clipPath>
<clipPath id="rect9" clip-rule="evenodd">
<rect x="100" y="100" width="200" height="200"/>
</clipPath>
<clipPath id="circle1" clip-rule="evenodd">
<circle cx="203" cy="203" r="150"/>
</clipPath>
<clipPath id="circle2" clip-rule="evenodd" clipPathUnits="objectBoundingBox">
<circle cx="0.5" cy="0.5" r="0.25"/>
</clipPath>
<clipPath id="circle3" clip-rule="evenodd">
<circle cx="100" cy="100" r="50"/>
<circle cx="300" cy="300" r="50"/>
</clipPath>
<clipPath id="circle4" clip-rule="evenodd">
<circle cx="50" cy="50" r="50"/>
</clipPath>
<clipPath id="circle5" clip-rule="evenodd">
<circle cx="150" cy="50" r="50"/>
</clipPath>
<clipPath id="circle6" clip-rule="evenodd">
<circle cx="50" cy="200" r="50"/>
</clipPath>
<clipPath id="circle7" clip-rule="evenodd" clipPathUnits="objectBoundingBox">
<circle cx="0.5" cy="0.5" r="0.5"/>
</clipPath>
<clipPath id="circle8" clip-rule="evenodd" clipPathUnits="userSpaceOnUse">
<circle cx="110" cy="20" r="90"/>
</clipPath>
<clipPath id="circle9" clip-rule="evenodd" clipPathUnits="userSpaceOnUse">
<circle cx="290" cy="20" r="90"/>
</clipPath>
<clipPath id="circle10" clip-rule="evenodd" clipPathUnits="userSpaceOnUse">
<circle cx="110" cy="200" r="90"/>
</clipPath>
<clipPath id="circle11" clip-rule="evenodd">
<circle cx="0" cy="0" r="150"/>
</clipPath>
<clipPath id="star" clip-rule="evenodd">
<path d="M400,25 L619,703 43,283 757,283 181,703 z" />
</clipPath>
<marker id="m_atr" markerUnits="strokeWidth" markerWidth="3" markerHeight="3" viewBox="0 0 10 10" refX="5" refY="5">
<polygon points="0,0 5,5 0,10 10,5" fill="red"/>
</marker>
<switch>
<rect id="rect-10" x="20" y="20" width="180" height="180" fill="blue" stroke="cyan" stroke-width="8"/>
<rect id="rect-11" x="200" y="20" width="180" height="180" fill="lightgreen" stroke="none" />
<rect id="rect-12" x="20" y="200" width="180" height="180" fill="darkcyan" stroke="none" />
</switch>
<clipPath id="clipCircle1">
<circle id="c1" cx="100" cy="100" r="50"/>
</clipPath>
<clipPath id="clipCircle2">
<circle id="c2" cx="150" cy="150" r="50"/>
</clipPath>
<clipPath id="clipPath1">
<path id="p1" d="M10 10l100 0 0 100 -100 0ZM50 50l40 0 0 40 -40 0Z" clip-rule="evenodd"/>
</clipPath>
<!-- "If a valid 'clip-path' reference is placed on one of the children of a 'clipPath' element,
then the given child element is clipped by the referenced clipping path before OR'ing the
silhouette of the child element with the silhouettes of the other child elements." -->
<clipPath id="clipRects1">
<rect x="50" y="30" width="25" height="100"/>
<rect x="25" y="50" width="10" height="10" clip-path="url(#clipTwoCircles)"/>
</clipPath>
<!-- Test use in a clipPath -->
<clipPath id="clipTwoCircles">
<use xlink:href="#c1"/>
<use xlink:href="#c2"/>
</clipPath>
<clipPath id="clipInClip1">
<use xlink:href="#c2" clip-path="url(#clipCircle1)"/>
<use xlink:href="#p1"/>
</clipPath>
<clipPath id="clipOnClip1" clip-path="url(#clipCircle1)">
<use xlink:href="#c2"/>
<use xlink:href="#p1"/>
</clipPath>
</defs>
<!-- text -->
<text id="text1" font-size="20px" font-familiy="monospace" fill="red" x="0" y="50" clip-path="url('#rect01')">99</text>
<text id="text2" font-size="20px" font-familiy="monospace" fill="blue" x="100" y="120" clip-path="url('#rect02')">99</text>
<text id="text3" font-size="20px" font-familiy="monospace" clip-path="url('#rect03')" x="0" y="120">
<tspan x="0" y="50" fill="red">99</tspan>
</text>
<text id="text4" font-size="20px" font-familiy="monospace" clip-path="url('#rect04')" x="0" y="120">
<tspan x="100" y="120" fill="blue">99</tspan>
</text>
<text id="text5" font-size="20px" font-familiy="monospace" fill="red" x="0" y="80" clip-path="url('#rect05')">99</text>
<text id="text6" font-size="20px" font-familiy="monospace" fill="blue" x="0" y="80" clip-path="url('#rect06')">99</text>
<!-- image -->
<image id="image1" x="150" y="150" width="200" height="200" preserveApectRatio="none" clip="rect(200,300,300,200)"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAKXRFWHRDcmVhdGlvbiBUaW1lAJCFIDMwIDQgMjAxNCAwOToyODo0MyArMDkwMH73aTcAAAAHdElNRQfeBB4AHhEfV06+AAAACXBIWXMAAB7BAAAewQHDaVRTAAAABGdBTUEAALGPC/xhBQAAABlJREFUeNpjZPj/n4EUwESS6lENoxqGlAYASU8CHux7qQ4AAAAASUVORK5CYII="/>
<image id="image2" x="2" y="2" width="200" height="200" clip-path="url('#circle1')" preserveApectRatio="none"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAKXRFWHRDcmVhdGlvbiBUaW1lAJCFIDMwIDQgMjAxNCAwOToyODo0MyArMDkwMH73aTcAAAAHdElNRQfeBB4AHhEfV06+AAAACXBIWXMAAB7BAAAewQHDaVRTAAAABGdBTUEAALGPC/xhBQAAABlJREFUeNpjZPj/n4EUwESS6lENoxqGlAYASU8CHux7qQ4AAAAASUVORK5CYII="/>
<image id="image3" x="205" y="2" width="200" height="200" clip-path="url('#circle1')" preserveApectRatio="none"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAKXRFWHRDcmVhdGlvbiBUaW1lAJCFIDMwIDQgMjAxNCAwOToyODo0MyArMDkwMH73aTcAAAAHdElNRQfeBB4AHhEfV06+AAAACXBIWXMAAB7BAAAewQHDaVRTAAAABGdBTUEAALGPC/xhBQAAABlJREFUeNpjZPj/n4EUwESS6lENoxqGlAYASU8CHux7qQ4AAAAASUVORK5CYII="/>
<image id="image4" x="2" y="205" width="200" height="200" clip-path="url('#circle1')" preserveApectRatio="none"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAKXRFWHRDcmVhdGlvbiBUaW1lAJCFIDMwIDQgMjAxNCAwOToyODo0MyArMDkwMH73aTcAAAAHdElNRQfeBB4AHhEfV06+AAAACXBIWXMAAB7BAAAewQHDaVRTAAAABGdBTUEAALGPC/xhBQAAABlJREFUeNpjZPj/n4EUwESS6lENoxqGlAYASU8CHux7qQ4AAAAASUVORK5CYII="/>
<image id="image5" x="205" y="205" width="200" height="200" clip-path="url('#circle1')" preserveApectRatio="none"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAKXRFWHRDcmVhdGlvbiBUaW1lAJCFIDMwIDQgMjAxNCAwOToyODo0MyArMDkwMH73aTcAAAAHdElNRQfeBB4AHhEfV06+AAAACXBIWXMAAB7BAAAewQHDaVRTAAAABGdBTUEAALGPC/xhBQAAABlJREFUeNpjZPj/n4EUwESS6lENoxqGlAYASU8CHux7qQ4AAAAASUVORK5CYII="/>
<image id="image6" x="2" y="2" width="200" height="200" clip-path="url('#circle2')" preserveApectRatio="none"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAKXRFWHRDcmVhdGlvbiBUaW1lAJCFIDMwIDQgMjAxNCAwOToyODo0MyArMDkwMH73aTcAAAAHdElNRQfeBB4AHhEfV06+AAAACXBIWXMAAB7BAAAewQHDaVRTAAAABGdBTUEAALGPC/xhBQAAABlJREFUeNpjZPj/n4EUwESS6lENoxqGlAYASU8CHux7qQ4AAAAASUVORK5CYII="/>
<image id="image7" x="205" y="2" width="200" height="200" clip-path="url('#circle2')" preserveApectRatio="none"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAKXRFWHRDcmVhdGlvbiBUaW1lAJCFIDMwIDQgMjAxNCAwOToyODo0MyArMDkwMH73aTcAAAAHdElNRQfeBB4AHhEfV06+AAAACXBIWXMAAB7BAAAewQHDaVRTAAAABGdBTUEAALGPC/xhBQAAABlJREFUeNpjZPj/n4EUwESS6lENoxqGlAYASU8CHux7qQ4AAAAASUVORK5CYII="/>
<image id="image8" x="2" y="205" width="200" height="200" clip-path="url('#circle2')" preserveApectRatio="none"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAKXRFWHRDcmVhdGlvbiBUaW1lAJCFIDMwIDQgMjAxNCAwOToyODo0MyArMDkwMH73aTcAAAAHdElNRQfeBB4AHhEfV06+AAAACXBIWXMAAB7BAAAewQHDaVRTAAAABGdBTUEAALGPC/xhBQAAABlJREFUeNpjZPj/n4EUwESS6lENoxqGlAYASU8CHux7qQ4AAAAASUVORK5CYII="/>
<image id="image9" x="205" y="205" width="200" height="200" clip-path="url('#circle2')" preserveApectRatio="none"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAKXRFWHRDcmVhdGlvbiBUaW1lAJCFIDMwIDQgMjAxNCAwOToyODo0MyArMDkwMH73aTcAAAAHdElNRQfeBB4AHhEfV06+AAAACXBIWXMAAB7BAAAewQHDaVRTAAAABGdBTUEAALGPC/xhBQAAABlJREFUeNpjZPj/n4EUwESS6lENoxqGlAYASU8CHux7qQ4AAAAASUVORK5CYII="/>
<image id="image10" x="0" y="0" width="400" height="400" clip-path="url('#rect4')"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAKXRFWHRDcmVhdGlvbiBUaW1lAJCFIDMwIDQgMjAxNCAwOToyODo0MyArMDkwMH73aTcAAAAHdElNRQfeBB4AHhEfV06+AAAACXBIWXMAAB7BAAAewQHDaVRTAAAABGdBTUEAALGPC/xhBQAAABlJREFUeNpjZPj/n4EUwESS6lENoxqGlAYASU8CHux7qQ4AAAAASUVORK5CYII="/>
<image id="image11" x="0" y="0" width="400" height="400" clip-path="url('#rect-none')"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAKXRFWHRDcmVhdGlvbiBUaW1lAJCFIDMwIDQgMjAxNCAwOToyODo0MyArMDkwMH73aTcAAAAHdElNRQfeBB4AHhEfV06+AAAACXBIWXMAAB7BAAAewQHDaVRTAAAABGdBTUEAALGPC/xhBQAAABlJREFUeNpjZPj/n4EUwESS6lENoxqGlAYASU8CHux7qQ4AAAAASUVORK5CYII="/>
<image id="image12" x="25" y="43" width="768" height="768" clip-path="url('#star')" preserveApectRatio="none"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAKXRFWHRDcmVhdGlvbiBUaW1lAJCFIDMwIDQgMjAxNCAwOToyODo0MyArMDkwMH73aTcAAAAHdElNRQfeBB4AHhEfV06+AAAACXBIWXMAAB7BAAAewQHDaVRTAAAABGdBTUEAALGPC/xhBQAAABlJREFUeNpjZPj/n4EUwESS6lENoxqGlAYASU8CHux7qQ4AAAAASUVORK5CYII="/>
<image id="image13" x="0" y="0" width="400" height="400" clip-path="url('#circle3')"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAKXRFWHRDcmVhdGlvbiBUaW1lAJCFIDMwIDQgMjAxNCAwOToyODo0MyArMDkwMH73aTcAAAAHdElNRQfeBB4AHhEfV06+AAAACXBIWXMAAB7BAAAewQHDaVRTAAAABGdBTUEAALGPC/xhBQAAABlJREFUeNpjZPj/n4EUwESS6lENoxqGlAYASU8CHux7qQ4AAAAASUVORK5CYII="/>
<image id="image14" x="0" y="0" width="400" height="400" clip-path="url('#m_atr')"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAKXRFWHRDcmVhdGlvbiBUaW1lAJCFIDMwIDQgMjAxNCAwOToyODo0MyArMDkwMH73aTcAAAAHdElNRQfeBB4AHhEfV06+AAAACXBIWXMAAB7BAAAewQHDaVRTAAAABGdBTUEAALGPC/xhBQAAABlJREFUeNpjZPj/n4EUwESS6lENoxqGlAYASU8CHux7qQ4AAAAASUVORK5CYII="/>
<!-- path -->
<path id="path1" d="M10,50 L25,100 H110 V50 Q60,0 10,50" stroke="black" stroke-width="8" stroke-miterlimit="1" stroke-linejoin="miter" fill="lightcyan" marker-mid="url(#m_atr)"/>
<path id="path2" d="M160,50 L175,100 H260 V50 Q210,0 160,50" stroke="black" stroke-width="8" stroke-linejoin="bevel" fill="lightcyan" marker-mid="url(#m_atr)"/>
<path id="path3" d="M10,150 L25,200 H110 V150 Q60,100 10,150" stroke="black" stroke-width="8" stroke-linejoin="round" fill="lightcyan" marker-mid="url(#m_atr)"/>
<path id="path4" d="M10,50 L25,100 H110 V50 Q60,0 10,50" stroke="black" stroke-width="8" stroke-miterlimit="1" stroke-linejoin="miter" fill="lightcyan"
marker-mid="url(#m_atr)" clip-path="url(#circle4)"/>
<path id="path5" d="M160,50 L175,100 H260 V50 Q210,0 160,50" stroke="black" stroke-width="8" stroke-linejoin="bevel" fill="lightcyan"
marker-mid="url(#m_atr)" clip-path="url(#circle5)"/>
<path id="path6" d="M10,150 L25,200 H110 V150 Q60,100 10,150" stroke="black" stroke-width="8" stroke-linejoin="round" fill="lightcyan"
marker-mid="url(#m_atr)" clip-path="url(#circle6)"/>
<path id="path7" d="M10,50 L25,100 H110 V50 Q60,0 10,50"
stroke="black" stroke-width="8" stroke-miterlimit="1" stroke-linejoin="miter" fill="lightcyan"
clip-path="url('#rect5')" marker-mid="url(#m_atr)"/>
<path id="path8" d="M160,50 L175,100 H260 V50 Q210,0 160,50"
stroke="black" stroke-width="8" stroke-linejoin="bevel" fill="lightcyan"
clip-path="url('#rect6')" marker-mid="url(#m_atr)"/>
<path id="path9" d="M10,150 L25,200 H110 V150 Q60,100 10,150"
stroke="black" stroke-width="8" stroke-linejoin="round" fill="lightcyan"
clip-path="url('#rect7')" marker-mid="url(#m_atr)"/>
<path id="path10" d="M10,50 L25,100 H110 V50 Q60,0 10,50"
stroke="black" stroke-width="8" stroke-miterlimit="1" stroke-linejoin="miter" fill="lightcyan"
clip-path="url('#circle7')" marker-mid="url(#m_atr)"/>
<path id="path11" d="M160,50 L175,100 H260 V50 Q210,0 160,50"
stroke="black" stroke-width="8" stroke-linejoin="bevel" fill="lightcyan"
clip-path="url('#circle7')" marker-mid="url(#m_atr)"/>
<path id="path12" d="M10,150 L25,200 H110 V150 Q60,100 10,150"
stroke="black" stroke-width="8" stroke-linejoin="round" fill="lightcyan"
clip-path="url('#circle7')" marker-mid="url(#m_atr)"/>
<!-- use -->
<use id="use1" xlink:href="#rect-10" x="50" y="50" clip-path="url('#circle8')"/>
<use id="use2" xlink:href="#rect-11" x="50" y="50" clip-path="url('#circle9')"/>
<use id="use3" xlink:href="#rect-12" x="50" y="50" clip-path="url('#circle10')"/>
<use id="use4" xlink:href="#rect-10" x="2" y="2" width="200" height="200" clip-path="url('#circle11')"/>
<use id="use5" xlink:href="#rect-10" x="205" y="2" width="200" height="200" clip-path="url('#circle11')"/>
<use id="use6" xlink:href="#rect-10" x="2" y="205" width="200" height="200" clip-path="url('#circle11')"/>
<use id="use7" xlink:href="#rect-10" x="205" y="205" width="200" height="200" clip-path="url('#circle11')"/>
<use id="use8" xlink:href="#rect-10" x="50" y="50" clip-path="url('#m_atr')"/>
<!-- foreignObject -->
<foreignObject id="fo1" x="2" y="2" width="200" height="200" clip-path="url('#circle1')" clip="rect(2,102,102,2)">
<div xmlns="http://www.w3.org/1999/xhtml" style="background-color:pink;width:100%;height:100%;">
There are issues of dynamic loading required for tiling. Accroding to 'postpone' attribute of Resource Priorities, the dynamic loading is controlled by positional relation with bounding box of embedded contents and container's viewport. However, each bounding boxes of embedded contents should be whole earth basically when this method is used. (green part on Example) Tiling is impossible unless this situation is changed.
</div>
</foreignObject>
<foreignObject id="fo2" x="205" y="2" width="200" height="200" clip-path="url('#circle1')" >
<div xmlns="http://www.w3.org/1999/xhtml" style="background-color:pink;width:100%;height:100%;">
There are issues of dynamic loading required for tiling. Accroding to 'postpone' attribute of Resource Priorities, the dynamic loading is controlled by positional relation with bounding box of embedded contents and container's viewport. However, each bounding boxes of embedded contents should be whole earth basically when this method is used. (green part on Example) Tiling is impossible unless this situation is changed.
</div>
</foreignObject>
<foreignObject id="fo3" x="2" y="205" width="200" height="200" clip-path="url('#circle1')" >
<div xmlns="http://www.w3.org/1999/xhtml" style="background-color:pink;width:100%;height:100%;">
There are issues of dynamic loading required for tiling. Accroding to 'postpone' attribute of Resource Priorities, the dynamic loading is controlled by positional relation with bounding box of embedded contents and container's viewport. However, each bounding boxes of embedded contents should be whole earth basically when this method is used. (green part on Example) Tiling is impossible unless this situation is changed.
</div>
</foreignObject>
<foreignObject id="fo4" x="205" y="205" width="200" height="200" clip-path="url('#circle1')" clip="rect(2,102,102,2)">
<div xmlns="http://www.w3.org/1999/xhtml" style="background-color:pink;width:100%;height:100%;">
There are issues of dynamic loading required for tiling. Accroding to 'postpone' attribute of Resource Priorities, the dynamic loading is controlled by positional relation with bounding box of embedded contents and container's viewport. However, each bounding boxes of embedded contents should be whole earth basically when this method is used. (green part on Example) Tiling is impossible unless this situation is changed.
</div>
</foreignObject>
<foreignObject id="fo5" x="250" y="250" width="200" height="200" clip-path="url('#rect8')">
<div xmlns="http://www.w3.org/1999/xhtml" style="background-color:pink;width:100%;height:100%;">
There are issues of dynamic loading required for tiling. Accroding to 'postpone' attribute of Resource Priorities, the dynamic loading is controlled by positional relation with bounding box of embedded contents and container's viewport. However, each bounding boxes of embedded contents should be whole earth basically when this method is used. (green part on Example) Tiling is impossible unless this situation is changed.
</div>
</foreignObject>
<foreignObject id="fo6" x="0" y="0" width="200" height="200" clip-path="url('#rect9')">
<div xmlns="http://www.w3.org/1999/xhtml" style="background-color:pink;width:100%;height:100%;">
There are issues of dynamic loading required for tiling. Accroding to 'postpone' attribute of Resource Priorities, the dynamic loading is controlled by positional relation with bounding box of embedded contents and container's viewport. However, each bounding boxes of embedded contents should be whole earth basically when this method is used. (green part on Example) Tiling is impossible unless this situation is changed.
</div>
</foreignObject>
<foreignObject id="fo7" x="0" y="0" width="200" height="200" clip-path="url('#rect8')">
<div xmlns="http://www.w3.org/1999/xhtml" style="background-color:pink;width:100%;height:100%;">
There are issues of dynamic loading required for tiling. Accroding to 'postpone' attribute of Resource Priorities, the dynamic loading is controlled by positional relation with bounding box of embedded contents and container's viewport. However, each bounding boxes of embedded contents should be whole earth basically when this method is used. (green part on Example) Tiling is impossible unless this situation is changed.
</div>
</foreignObject>
<foreignObject id="fo8" x="0" y="0" width="200" height="200" clip-path="url('#m_atr')">
<div xmlns="http://www.w3.org/1999/xhtml" style="background-color:pink;width:100%;height:100%;">
There are issues of dynamic loading required for tiling. Accroding to 'postpone' attribute of Resource Priorities, the dynamic loading is controlled by positional relation with bounding box of embedded contents and container's viewport. However, each bounding boxes of embedded contents should be whole earth basically when this method is used. (green part on Example) Tiling is impossible unless this situation is changed.
</div>
</foreignObject>
<!-- -->
<rect id="rect-1" width="200" height="200" fill="blue" clip-path="url(#clipInClip1)"/>
<rect id="rect-2" width="200" height="200" fill="blue" clip-path="url(#clipRects1)"/>
<rect id="rect-3" width="300" height="300" fill="blue" clip-path="url(#clipOnClip1)"/>
<g clip-path="url(#clipCircle1)" id="g1">
<use xlink:href="#c2" fill="red"/>
<use xlink:href="#p1" fill="red" fill-rule="evenodd"/>
</g>
</svg>

После

Ширина:  |  Высота:  |  Размер: 20 KiB

Просмотреть файл

@ -9,6 +9,7 @@ support-files =
animated-svg-image-helper.svg
bbox-helper.svg
bounds-helper.svg
getBBox-method-helper.svg
dataTypes-helper.svg
fragments-helper.svg
getCTM-helper.svg
@ -34,6 +35,7 @@ support-files =
[test_bbox.xhtml]
[test_bounds.html]
[test_bug872812.html]
[test_getBBox-method.html]
[test_dataTypes.html]
[test_dataTypesModEvents.html]
[test_fragments.html]

Просмотреть файл

@ -0,0 +1,249 @@
<!DOCTYPE HTML>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=999964
-->
<head>
<meta charset="utf-8"/>
<title>Test case for Bug 999964</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=999964">Mozilla Bug 999964</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<iframe id="svg" src="getBBox-method-helper.svg"></iframe>
<pre id="test">
<script class="testbody" type="application/javascript">
/** Test case for Bug 999964 **/
SimpleTest.waitForExplicitFinish();
function run()
{
var flag = SpecialPowers.getBoolPref("svg.new-getBBox.enabled");
if (!flag) {
ok(!flag, "skip test for bug999964.");
SimpleTest.finish();
return;
}
var doc = $("svg").contentDocument;
function isFuzzy(a, b, error, name)
{
ok(!(Math.abs(a - b) > error), name, "got " + a + ", expected " + b + " (within " + error + ")");
}
function getBBox(id, opt) {
return doc.getElementById(id).getBBox(opt);
}
function checkBBox(id, opt, x, y, width, height, error) {
var bbox = getBBox(id, opt);
isFuzzy(bbox.x, x, error, id + ".getBBox().x");
isFuzzy(bbox.y, y, error, id + ".getBBox().y");
isFuzzy(bbox.width, width, error, id + ".getBBox().width");
isFuzzy(bbox.height, height, error, id + ".getBBox().height");
}
function compareBBox1(id1, id2) {
var bbox1 = getBBox(id1);
var bbox2 = getBBox(id2);
is(bbox1.x, bbox2.x, id1 + ".getBBox().x");
is(bbox1.y, bbox2.y, id1 + ".getBBox().y");
isFuzzy(bbox1.width, bbox2.width, 0.0002, id1 + ".getBBox().width");
isFuzzy(bbox1.height, bbox2.height, 0.0001, id1 + ".getBBox().height");
}
function compareBBox2(id1, id2) {
// without 'x'
var bbox1 = getBBox(id1);
var bbox2 = getBBox(id2);
is(bbox1.y, bbox2.y, id1 + ".getBBox().y");
isFuzzy(bbox1.width, bbox2.width, 0.0002, id1 + ".getBBox().width");
isFuzzy(bbox1.height, bbox2.height, 0.0001, id1 + ".getBBox().height");
}
var opt = { fill: true, stroke: true, markers: true, clipped: true };
// <text>
// fill
opt = { fill: true, stroke: false, markers: false, clipped: false };
compareBBox1("text1","text3");
compareBBox1("text2","text4");
compareBBox1("text5","text6");
// all
opt = { fill: true, stroke: true, markers: true, clipped: true };
compareBBox2("text1","text3");
compareBBox2("text2","text4");
compareBBox2("text5","text6");
// clipped
opt = { fill: false, stroke: false, markers: false, clipped: true };
compareBBox2("text1","text3");
compareBBox2("text2","text4");
compareBBox2("text5","text6");
// <image>
opt = { fill: true, stroke: true, markers: true, clipped: true };
checkBBox("image1", opt, 250, 250, 100, 100);
checkBBox("image2", opt, 53, 53, 149, 149);
checkBBox("image3", opt, 205, 53, 148, 149);
checkBBox("image4", opt, 53, 205, 149, 148);
checkBBox("image5", opt, 205, 205, 148, 148);
checkBBox("image6", opt, 52, 52, 100, 100);
checkBBox("image7", opt, 255, 52, 100, 100);
checkBBox("image8", opt, 52, 255, 100, 100);
checkBBox("image9", opt, 255, 255, 100, 100);
checkBBox("image10", opt, 200, 200, 200, 200);
checkBBox("image11", opt, 0, 0, 0, 0);
checkBBox("image12", opt, 43, 43, 714, 660);
checkBBox("image13", opt, 50, 50, 300, 300);
checkBBox("image14", opt, 0, 0, 0, 0);
opt = { fill: true, stroke: false, markers: false, clipped: false };
checkBBox("image1", opt, 150,150,200,200, 0);
checkBBox("image2", opt, 2,2,200,200, 0);
checkBBox("image3", opt, 205,2,200,200, 0);
checkBBox("image4", opt, 2,205,200,200, 0);
checkBBox("image5", opt, 205,205,200,200, 0);
checkBBox("image6", opt, 2,2,200,200, 0);
checkBBox("image7", opt, 205,2,200,200, 0);
checkBBox("image8", opt, 2,205,200,200, 0);
checkBBox("image9", opt, 205,205,200,200, 0);
checkBBox("image10", opt, 0,0,400,400, 0);
checkBBox("image11", opt, 0,0,400,400, 0);
checkBBox("image12", opt, 25,43,768,768, 0);
checkBBox("image13", opt, 0,0,400,400, 0);
// <path>
opt = { fill: true, stroke: true, markers: true, clipped: true };
checkBBox("path1", opt, 2,17,120,95, 0);
checkBBox("path2", opt, 156,21,116,91, 0);
checkBBox("path3", opt, 6,121,116,91, 0);
checkBBox("path4", opt, 2,17,98,83, 0);
checkBBox("path5", opt, 156,21,44,79, 0);
checkBBox("path6", opt, 6,150,94,62, 0);
checkBBox("path7", opt, 2,17,98,83, 0);
checkBBox("path8", opt, 156,21,94,79, 0);
checkBBox("path9", opt, 6,121,94,79, 0);
checkBBox("path10", opt, 10,25,100,75, 0);
checkBBox("path11", opt, 160,25,100,75, 0);
checkBBox("path12", opt, 10,125,100,75, 0);
opt = { fill: true, stroke: false, markers: false, clipped: true };
checkBBox("path1", opt, 10,25,100,75, 0);
checkBBox("path2", opt, 160,25,100,75, 0);
checkBBox("path3", opt, 10,125,100,75, 0);
checkBBox("path4", opt, 10,25,90,75, 0);
checkBBox("path5", opt, 160,25,40,75, 0);
checkBBox("path6", opt, 10,150,90,50, 0);
checkBBox("path7", opt, 10,25,90,75, 0);
checkBBox("path8", opt, 160,25,90,75, 0);
checkBBox("path9", opt, 10,125,90,75, 0);
checkBBox("path10", opt, 10,25,100,75, 0);
checkBBox("path11", opt, 160,25,100,75, 0);
checkBBox("path12", opt, 10,125,100,75, 0);
opt = { fill: true, stroke: false, markers: false, clipped: false };
checkBBox("path1", opt, 10,25,100,75, 0);
checkBBox("path2", opt, 160,25,100,75, 0);
checkBBox("path3", opt, 10,125,100,75, 0);
checkBBox("path4", opt, 10,25,100,75, 0);
checkBBox("path5", opt, 160,25,100,75, 0);
checkBBox("path6", opt, 10,125,100,75, 0);
checkBBox("path7", opt, 10,25,100,75, 0);
checkBBox("path8", opt, 160,25,100,75, 0);
checkBBox("path9", opt, 10,125,100,75, 0);
checkBBox("path10", opt, 10,25,100,75, 0);
checkBBox("path11", opt, 160,25,100,75, 0);
checkBBox("path12", opt, 10,125,100,75, 0);
opt = { fill: false, stroke: true, markers: false, clipped: false };
checkBBox("path1", opt, 2,17,116,91, 0);
checkBBox("path2", opt, 156,21,108,83, 0);
checkBBox("path3", opt, 6,121,108,83, 0);
checkBBox("path4", opt, 2,17,116,91, 0);
checkBBox("path5", opt, 156,21,108,83, 0);
checkBBox("path6", opt, 6,121,108,83, 0);
checkBBox("path7", opt, 2,17,116,91, 0);
checkBBox("path8", opt, 156,21,108,83, 0);
checkBBox("path9", opt, 6,121,108,83, 0);
checkBBox("path10", opt, 2,17,116,91, 0);
checkBBox("path11", opt, 156,21,108,83, 0);
checkBBox("path12", opt, 6,121,108,83, 0);
opt = { fill: false, stroke: false, markers: true, clipped: false };
checkBBox("path1", opt, 10,25,112,87, 0);
checkBBox("path2", opt, 160,25,112,87, 0);
checkBBox("path3", opt, 10,125,112,87, 0);
checkBBox("path4", opt, 10,25,112,87, 0);
checkBBox("path5", opt, 160,25,112,87, 0);
checkBBox("path6", opt, 10,125,112,87, 0);
checkBBox("path7", opt, 10,25,112,87, 0);
checkBBox("path8", opt, 160,25,112,87, 0);
checkBBox("path9", opt, 10,125,112,87, 0);
checkBBox("path10", opt, 10,25,112,87, 0);
checkBBox("path11", opt, 160,25,112,87, 0);
checkBBox("path12", opt, 10,125,112,87, 0);
// <use>
opt = { fill: true, stroke: false, markers: false, clipped: false };
checkBBox("use1", opt, 70,70,180,180, 0);
checkBBox("use2", opt, 250,70,180,180, 0);
checkBBox("use3", opt, 70,250,180,180, 0);
checkBBox("use4", opt, 22,22,180,180, 0);
checkBBox("use5", opt, 225,22,180,180, 0);
checkBBox("use6", opt, 22,225,180,180, 0);
checkBBox("use7", opt, 225,225,180,180, 0);
opt = { fill: true, stroke: true, markers: true, clipped: true };
checkBBox("use1", opt, 70,66,180,94, 0);
checkBBox("use2", opt, 250,70,180,90, 0);
checkBBox("use3", opt, 70,250,180,90, 0);
checkBBox("use4", opt, 18,18,134,134, 0);
checkBBox("use5", opt, 221,18,134,134, 0);
checkBBox("use6", opt, 18,221,134,134, 0);
checkBBox("use7", opt, 221,221,134,134, 0);
checkBBox("use8", opt, 0,0,0,0, 0);
// <foreignObject>
opt = { fill: true, stroke: false, markers: false, clipped: false };
checkBBox("fo1", opt, 2,2,200,200, 0);
checkBBox("fo2", opt, 205,2,200,200, 0);
checkBBox("fo3", opt, 2,205,200,200, 0);
checkBBox("fo4", opt, 205,205,200,200, 0);
checkBBox("fo5", opt, 250,250,200,200, 0);
checkBBox("fo6", opt, 0,0,200,200, 0);
checkBBox("fo7", opt, 0,0,200,200, 0);
opt = { fill: true, stroke: true, markers: true, clipped: true };
checkBBox("fo1", opt, 53,53,51,51, 0);
checkBBox("fo2", opt, 205,53,148,149, 0);
checkBBox("fo3", opt, 53,205,149,148, 0);
checkBBox("fo4", opt, 207,207,100,100, 0);
checkBBox("fo5", opt, 0,0,0,0, 0);
checkBBox("fo6", opt, 100,100,100,100, 0);
checkBBox("fo7", opt, 10,10,180,180, 0);
checkBBox("fo8", opt, 0,0,0,0, 0);
// from http://www.w3.org/Graphics/SVG/Test/20110816/harness/htmlObjectApproved/masking-path-07-b.html
opt = { fill: true, stroke: true, markers: true, clipped: true };
checkBBox("rect-1", opt, 10,10,140,140, 0);
checkBBox("rect-2", opt, 50,30,25,100, 0);
checkBBox("rect-3", opt, 50,50,100,100, 0);
checkBBox("g1", opt, 50,50,100,100, 0);
SimpleTest.finish();
}
window.addEventListener("load", run, false);
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -98,6 +98,11 @@
#include "WorkerPrivate.h"
#include "WorkerRunnable.h"
#if defined(XP_LINUX)
#include "mozilla/Hal.h"
#endif
#include "mozilla/dom/ContentChild.h"
namespace mozilla {
namespace dom {
@ -1483,41 +1488,27 @@ Navigator::GetFeature(const nsAString& aName)
#if defined(XP_LINUX)
if (aName.EqualsLiteral("hardware.memory")) {
static int memLevel = 1;
if (memLevel == 1) {
FILE* f = fopen("/proc/meminfo", "r");
if (!f) {
p->MaybeReject(NS_LITERAL_STRING("CannotOpenMeminfo"));
return p.forget();
}
int memTotal;
int n = fscanf(f, "MemTotal: %d kB\n", &memTotal);
fclose(f);
if (memTotal == 0 || n != 1) {
// with seccomp enabled, fopen() should be in a non-sandboxed process
if (XRE_GetProcessType() == GeckoProcessType_Default) {
uint32_t memLevel = mozilla::hal::GetTotalSystemMemoryLevel();
if (memLevel == 0) {
p->MaybeReject(NS_LITERAL_STRING("Abnormal"));
return p.forget();
}
// From KB to MB
memTotal /= 1024;
// round the value up to the next power of two
while (memLevel <= memTotal) {
memLevel *= 2;
p->MaybeResolve((int)memLevel);
} else {
mozilla::dom::ContentChild* cc =
mozilla::dom::ContentChild::GetSingleton();
nsRefPtr<Promise> ipcRef(p);
cc->SendGetSystemMemory(reinterpret_cast<uint64_t>(ipcRef.forget().take()));
}
}
p->MaybeResolve(memLevel);
return p.forget();
} // hardware.memory
else
#endif
{
// resolve with <undefined> because the feature name is not supported
p->MaybeResolve(JS::UndefinedHandleValue);
}
return p.forget();
}

Просмотреть файл

@ -0,0 +1,21 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
function SlowScriptDebug() { }
SlowScriptDebug.prototype = {
classID: Components.ID("{e740ddb4-18b4-4aac-8ae1-9b0f4320769d}"),
classDescription: "Slow script debug handler",
contractID: "@mozilla.org/dom/slow-script-debug;1",
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISlowScriptDebug]),
get activationHandler() { return this._activationHandler; },
set activationHandler(cb) { return this._activationHandler = cb; },
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SlowScriptDebug]);

Просмотреть файл

@ -0,0 +1,2 @@
component {e740ddb4-18b4-4aac-8ae1-9b0f4320769d} SlowScriptDebug.js
contract @mozilla.org/dom/slow-script-debug;1 {e740ddb4-18b4-4aac-8ae1-9b0f4320769d}

Просмотреть файл

@ -13,6 +13,7 @@ XPIDL_SOURCES += [
'nsIEntropyCollector.idl',
'nsIScriptChannel.idl',
'nsISiteSpecificUserAgent.idl',
'nsISlowScriptDebug.idl',
]
XPIDL_MODULE = 'dom'
@ -128,6 +129,8 @@ EXTRA_COMPONENTS += [
'ConsoleAPIStorage.js',
'SiteSpecificUserAgent.js',
'SiteSpecificUserAgent.manifest',
'SlowScriptDebug.js',
'SlowScriptDebug.manifest',
]
EXTRA_JS_MODULES += [

Просмотреть файл

@ -485,10 +485,6 @@ bool nsDOMClassInfo::sIsInitialized = false;
jsid nsDOMClassInfo::sLocation_id = JSID_VOID;
jsid nsDOMClassInfo::sConstructor_id = JSID_VOID;
jsid nsDOMClassInfo::sLength_id = JSID_VOID;
jsid nsDOMClassInfo::sItem_id = JSID_VOID;
jsid nsDOMClassInfo::sNamedItem_id = JSID_VOID;
jsid nsDOMClassInfo::sEnumerate_id = JSID_VOID;
jsid nsDOMClassInfo::sTop_id = JSID_VOID;
jsid nsDOMClassInfo::sDocument_id = JSID_VOID;
jsid nsDOMClassInfo::sWrappedJSObject_id = JSID_VOID;
@ -595,10 +591,6 @@ nsDOMClassInfo::DefineStaticJSVals(JSContext *cx)
SET_JSID_TO_STRING(sLocation_id, cx, "location");
SET_JSID_TO_STRING(sConstructor_id, cx, "constructor");
SET_JSID_TO_STRING(sLength_id, cx, "length");
SET_JSID_TO_STRING(sItem_id, cx, "item");
SET_JSID_TO_STRING(sNamedItem_id, cx, "namedItem");
SET_JSID_TO_STRING(sEnumerate_id, cx, "enumerateProperties");
SET_JSID_TO_STRING(sTop_id, cx, "top");
SET_JSID_TO_STRING(sDocument_id, cx, "document");
SET_JSID_TO_STRING(sWrappedJSObject_id, cx, "wrappedJSObject");
@ -1717,9 +1709,6 @@ nsDOMClassInfo::ShutDown()
sLocation_id = JSID_VOID;
sConstructor_id = JSID_VOID;
sLength_id = JSID_VOID;
sItem_id = JSID_VOID;
sEnumerate_id = JSID_VOID;
sTop_id = JSID_VOID;
sDocument_id = JSID_VOID;
sWrappedJSObject_id = JSID_VOID;

Просмотреть файл

@ -166,10 +166,6 @@ protected:
public:
static jsid sLocation_id;
static jsid sConstructor_id;
static jsid sLength_id;
static jsid sItem_id;
static jsid sNamedItem_id;
static jsid sEnumerate_id;
static jsid sTop_id;
static jsid sDocument_id;
static jsid sWrappedJSObject_id;

Просмотреть файл

@ -35,6 +35,7 @@
#include "nsIScriptTimeoutHandler.h"
#include "nsIController.h"
#include "nsScriptNameSpaceManager.h"
#include "nsISlowScriptDebug.h"
#include "nsWindowMemoryReporter.h"
#include "WindowNamedPropertiesHandler.h"
@ -1344,12 +1345,14 @@ nsGlobalWindow::~nsGlobalWindow()
void
nsGlobalWindow::AddEventTargetObject(DOMEventTargetHelper* aObject)
{
MOZ_ASSERT(IsInnerWindow());
mEventTargetObjects.PutEntry(aObject);
}
void
nsGlobalWindow::RemoveEventTargetObject(DOMEventTargetHelper* aObject)
{
MOZ_ASSERT(IsInnerWindow());
mEventTargetObjects.RemoveEntry(aObject);
}
@ -1986,8 +1989,10 @@ nsGlobalWindow::OuterObject(JSContext* aCx, JS::Handle<JSObject*> aObj)
}
bool
nsGlobalWindow::WouldReuseInnerWindow(nsIDocument *aNewDocument)
nsGlobalWindow::WouldReuseInnerWindow(nsIDocument* aNewDocument)
{
MOZ_ASSERT(IsOuterWindow());
// We reuse the inner window when:
// a. We are currently at our original document.
// b. At least one of the following conditions are true:
@ -2027,7 +2032,7 @@ nsGlobalWindow::WouldReuseInnerWindow(nsIDocument *aNewDocument)
void
nsGlobalWindow::SetInitialPrincipalToSubject()
{
FORWARD_TO_OUTER_VOID(SetInitialPrincipalToSubject, ());
MOZ_ASSERT(IsOuterWindow());
// First, grab the subject principal.
nsCOMPtr<nsIPrincipal> newWindowPrincipal = nsContentUtils::SubjectPrincipal();
@ -2296,11 +2301,6 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
nsCOMPtr<nsIDocument> oldDoc = mDoc;
nsIScriptContext *scx = GetContextInternal();
NS_ENSURE_TRUE(scx, NS_ERROR_NOT_INITIALIZED);
JSContext *cx = scx->GetNativeContext();
#ifndef MOZ_DISABLE_CRYPTOLEGACY
// clear smartcard events, our document has gone away.
if (mCrypto && XRE_GetProcessType() != GeckoProcessType_Content) {
@ -2309,6 +2309,9 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
}
#endif
AutoJSAPI jsapi;
JSContext *cx = jsapi.cx();
if (!mDoc) {
// First document load.
@ -2365,9 +2368,6 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
bool thisChrome = IsChromeWindow();
nsCxPusher cxPusher;
cxPusher.Push(cx);
// Check if we're near the stack limit before we get anywhere near the
// transplanting code.
JS_CHECK_RECURSION(cx, return NS_ERROR_FAILURE);
@ -2660,8 +2660,11 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
// We wait to fire the debugger hook until the window is all set up and hooked
// up with the outer. See bug 969156.
if (createdInnerWindow) {
JS::Rooted<JSObject*> global(cx, newInnerWindow->GetWrapper());
JS_FireOnNewGlobalObject(cx, global);
// AutoEntryScript required to invoke debugger hook, which is a
// Gecko-specific concept at present.
AutoEntryScript aes(newInnerWindow);
JS::Rooted<JSObject*> global(aes.cx(), newInnerWindow->GetWrapper());
JS_FireOnNewGlobalObject(aes.cx(), global);
}
if (newInnerWindow && !newInnerWindow->mHasNotifiedGlobalCreated && mDoc) {
@ -2686,6 +2689,8 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
void
nsGlobalWindow::PreloadLocalStorage()
{
MOZ_ASSERT(IsOuterWindow());
if (!Preferences::GetBool(kStorageEnabled)) {
return;
}
@ -2713,6 +2718,8 @@ nsGlobalWindow::PreloadLocalStorage()
void
nsGlobalWindow::DispatchDOMWindowCreated()
{
MOZ_ASSERT(IsOuterWindow());
if (!mDoc) {
return;
}
@ -3063,6 +3070,8 @@ nsGlobalWindow::ShouldPromptToBlockDialogs()
bool
nsGlobalWindow::AreDialogsEnabled()
{
MOZ_ASSERT(IsOuterWindow());
nsGlobalWindow *topWindow = GetScriptableTop();
if (!topWindow) {
NS_ERROR("AreDialogsEnabled() called without a top window?");
@ -6263,6 +6272,12 @@ nsGlobalWindow::AlertOrConfirm(bool aAlert,
return result;
}
void
nsGlobalWindow::Alert(mozilla::ErrorResult& aError)
{
Alert(EmptyString(), aError);
}
void
nsGlobalWindow::Alert(const nsAString& aMessage, mozilla::ErrorResult& aError)
{
@ -8216,8 +8231,11 @@ public:
bool
nsGlobalWindow::CanClose()
{
if (!mDocShell)
MOZ_ASSERT(IsOuterWindow());
if (!mDocShell) {
return true;
}
// Ask the content viewer whether the toplevel window can close.
// If the content viewer returns false, it is responsible for calling
@ -8311,7 +8329,7 @@ nsGlobalWindow::Close(ErrorResult& aError)
return;
}
aError = FinalClose();
FinalClose();
}
NS_IMETHODIMP
@ -8323,32 +8341,35 @@ nsGlobalWindow::Close()
return rv.ErrorCode();
}
nsresult
void
nsGlobalWindow::ForceClose()
{
MOZ_ASSERT(IsOuterWindow());
if (IsFrame() || !mDocShell) {
// This may be a frame in a frameset, or a window that's already closed.
// Ignore such calls.
return NS_OK;
return;
}
if (mHavePendingClose) {
// We're going to be closed anyway; do nothing since we don't want
// to double-close
return NS_OK;
return;
}
mInClose = true;
DispatchCustomEvent("DOMWindowClose");
return FinalClose();
FinalClose();
}
nsresult
void
nsGlobalWindow::FinalClose()
{
MOZ_ASSERT(IsOuterWindow());
// Flag that we were closed.
mIsClosed = true;
@ -8372,8 +8393,6 @@ nsGlobalWindow::FinalClose()
} else {
mHavePendingClose = true;
}
return NS_OK;
}
@ -10749,10 +10768,22 @@ nsGlobalWindow::ShowSlowScriptDialog()
unsigned lineno;
bool hasFrame = JS::DescribeScriptedCaller(cx, &filename, &lineno);
bool debugPossible = hasFrame && js::CanCallContextDebugHandler(cx);
// Prioritize the SlowScriptDebug interface over JSD1.
nsCOMPtr<nsISlowScriptDebugCallback> debugCallback;
bool oldDebugPossible = false;
if (hasFrame) {
const char *debugCID = "@mozilla.org/dom/slow-script-debug;1";
nsCOMPtr<nsISlowScriptDebug> debugService = do_GetService(debugCID, &rv);
if (NS_SUCCEEDED(rv)) {
debugService->GetActivationHandler(getter_AddRefs(debugCallback));
}
if (!debugCallback) {
oldDebugPossible = js::CanCallContextDebugHandler(cx);
#ifdef MOZ_JSDEBUGGER
// Get the debugger service if necessary.
if (debugPossible) {
if (oldDebugPossible) {
bool jsds_IsOn = false;
const char jsdServiceCtrID[] = "@mozilla.org/js/jsd/debugger-service;1";
nsCOMPtr<jsdIExecutionHook> jsdHook;
@ -10767,9 +10798,13 @@ nsGlobalWindow::ShowSlowScriptDialog()
// If there is a debug handler registered for this runtime AND
// ((jsd is on AND has a hook) OR (jsd isn't on (something else debugs)))
// then something useful will be done with our request to debug.
debugPossible = ((jsds_IsOn && (jsdHook != nullptr)) || !jsds_IsOn);
oldDebugPossible = ((jsds_IsOn && (jsdHook != nullptr)) || !jsds_IsOn);
}
#endif
}
}
bool showDebugButton = debugCallback || oldDebugPossible;
// Get localizable strings
nsXPIDLString title, msg, stopButton, waitButton, debugButton, neverShowDlg;
@ -10800,7 +10835,7 @@ nsGlobalWindow::ShowSlowScriptDialog()
}
if (debugPossible) {
if (showDebugButton) {
tmp = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
"DebugScriptButton",
debugButton);
@ -10826,7 +10861,7 @@ nsGlobalWindow::ShowSlowScriptDialog()
// GetStringFromName can return NS_OK and still give nullptr string
if (NS_FAILED(rv) || !title || !msg || !stopButton || !waitButton ||
(!debugButton && debugPossible) || !neverShowDlg) {
(!debugButton && showDebugButton) || !neverShowDlg) {
NS_ERROR("Failed to get localized strings.");
return ContinueSlowScript;
}
@ -10856,7 +10891,7 @@ nsGlobalWindow::ShowSlowScriptDialog()
(nsIPrompt::BUTTON_POS_0 + nsIPrompt::BUTTON_POS_1));
// Add a third button if necessary.
if (debugPossible)
if (showDebugButton)
buttonFlags += nsIPrompt::BUTTON_TITLE_IS_STRING * nsIPrompt::BUTTON_POS_2;
// Null out the operation callback while we're re-entering JS here.
@ -10873,9 +10908,16 @@ nsGlobalWindow::ShowSlowScriptDialog()
if (NS_SUCCEEDED(rv) && (buttonPressed == 0)) {
return neverShowDlgChk ? AlwaysContinueSlowScript : ContinueSlowScript;
}
if ((buttonPressed == 2) && debugPossible) {
if (buttonPressed == 2) {
if (debugCallback) {
rv = debugCallback->HandleSlowScriptDebug(this);
return NS_SUCCEEDED(rv) ? ContinueSlowScript : KillSlowScript;
}
if (oldDebugPossible) {
return js_CallContextDebugHandler(cx) ? ContinueSlowScript : KillSlowScript;
}
}
JS_ClearPendingException(cx);
return KillSlowScript;
}

Просмотреть файл

@ -434,6 +434,7 @@ public:
virtual NS_HIDDEN_(void) SetIsBackground(bool aIsBackground);
virtual NS_HIDDEN_(void) SetChromeEventHandler(mozilla::dom::EventTarget* aChromeEventHandler);
// Outer windows only.
virtual NS_HIDDEN_(void) SetInitialPrincipalToSubject();
virtual NS_HIDDEN_(PopupControlState) PushPopupControlState(PopupControlState state, bool aForce) const;
@ -453,14 +454,18 @@ public:
}
virtual NS_HIDDEN_(bool) IsRunningTimeout() { return mTimeoutFiringDepth > 0; }
virtual NS_HIDDEN_(bool) WouldReuseInnerWindow(nsIDocument *aNewDocument);
// Outer windows only.
virtual NS_HIDDEN_(bool) WouldReuseInnerWindow(nsIDocument* aNewDocument);
virtual NS_HIDDEN_(void) SetDocShell(nsIDocShell* aDocShell);
virtual void DetachFromDocShell();
virtual NS_HIDDEN_(nsresult) SetNewDocument(nsIDocument *aDocument,
nsISupports *aState,
bool aForceReuseInnerWindow);
// Outer windows only.
void DispatchDOMWindowCreated();
virtual NS_HIDDEN_(void) SetOpenerWindow(nsIDOMWindow* aOpener,
bool aOriginalOpener);
@ -470,8 +475,9 @@ public:
virtual NS_HIDDEN_(void) EnterModalState();
virtual NS_HIDDEN_(void) LeaveModalState();
// Outer windows only.
virtual NS_HIDDEN_(bool) CanClose();
virtual NS_HIDDEN_(nsresult) ForceClose();
virtual NS_HIDDEN_(void) ForceClose();
virtual NS_HIDDEN_(void) MaybeUpdateTouchState();
virtual NS_HIDDEN_(void) UpdateTouchState();
@ -557,6 +563,7 @@ public:
// (alert, prompt, confirm) are currently allowed in this window.
void EnableDialogs();
void DisableDialogs();
// Outer windows only.
bool AreDialogsEnabled();
nsIScriptContext *GetContextInternal()
@ -696,6 +703,7 @@ public:
void UnmarkGrayTimers();
// Inner windows only.
void AddEventTargetObject(mozilla::DOMEventTargetHelper* aObject);
void RemoveEventTargetObject(mozilla::DOMEventTargetHelper* aObject);
@ -848,6 +856,7 @@ protected:
mozilla::ErrorResult& aError);
public:
void Alert(mozilla::ErrorResult& aError);
void Alert(const nsAString& aMessage, mozilla::ErrorResult& aError);
bool Confirm(const nsAString& aMessage, mozilla::ErrorResult& aError);
void Prompt(const nsAString& aMessage, const nsAString& aInitial,
@ -1044,7 +1053,8 @@ protected:
void DropOuterWindowDocs();
void CleanUp();
void ClearControllers();
nsresult FinalClose();
// Outer windows only.
void FinalClose();
inline void MaybeClearInnerWindow(nsGlobalWindow* aExpectedInner)
{
@ -1343,6 +1353,7 @@ protected:
bool aDefaultStylesOnly,
nsIDOMCSSStyleDeclaration** aReturn);
// Outer windows only.
void PreloadLocalStorage();
// Returns device pixels. Outer windows only.

Просмотреть файл

@ -0,0 +1,19 @@
/* 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 "nsISupports.idl"
interface nsIDOMWindow;
[scriptable, function, uuid(f7dbb80c-5d1e-4fd9-b55c-a9ffda4a75b1)]
interface nsISlowScriptDebugCallback : nsISupports
{
void handleSlowScriptDebug(in nsIDOMWindow aWindow);
};
[scriptable, uuid(f75d4164-3aa7-4395-ba44-a5f95b2e8427)]
interface nsISlowScriptDebug : nsISupports
{
attribute nsISlowScriptDebugCallback activationHandler;
};

Просмотреть файл

@ -277,13 +277,11 @@ nsJSEnvironmentObserver::Observe(nsISupports* aSubject, const char* aTopic,
}
nsJSContext::GarbageCollectNow(JS::gcreason::MEM_PRESSURE,
nsJSContext::NonIncrementalGC,
nsJSContext::NonCompartmentGC,
nsJSContext::ShrinkingGC);
nsJSContext::CycleCollectNow();
if (NeedsGCAfterCC()) {
nsJSContext::GarbageCollectNow(JS::gcreason::MEM_PRESSURE,
nsJSContext::NonIncrementalGC,
nsJSContext::NonCompartmentGC,
nsJSContext::ShrinkingGC);
}
} else if (!nsCRT::strcmp(aTopic, "quit-application")) {
@ -388,10 +386,8 @@ AsyncErrorReporter::AsyncErrorReporter(JSRuntime* aRuntime,
NS_LITERAL_CSTRING("content javascript");
mInnerWindowID = 0;
if (aWindow && aWindow->IsOuterWindow()) {
aWindow = aWindow->GetCurrentInnerWindow();
}
if (aWindow) {
MOZ_ASSERT(aWindow->IsInnerWindow());
mInnerWindowID = aWindow->WindowID();
}
}
@ -429,8 +425,7 @@ AsyncErrorReporter::ReportError()
class ScriptErrorEvent : public AsyncErrorReporter
{
public:
ScriptErrorEvent(nsIScriptGlobalObject* aScriptGlobal,
JSRuntime* aRuntime,
ScriptErrorEvent(JSRuntime* aRuntime,
JSErrorReport* aErrorReport,
const char* aFallbackMessage,
nsIPrincipal* aScriptOriginPrincipal,
@ -442,20 +437,21 @@ public:
: AsyncErrorReporter(aRuntime, aErrorReport, aFallbackMessage,
nsContentUtils::IsSystemPrincipal(aGlobalPrincipal),
aWindow)
, mScriptGlobal(aScriptGlobal)
, mOriginPrincipal(aScriptOriginPrincipal)
, mDispatchEvent(aDispatchEvent)
, mError(aRuntime, aError)
, mWindow(aWindow)
{
MOZ_ASSERT_IF(mWindow, mWindow->IsInnerWindow());
}
NS_IMETHOD Run()
{
nsEventStatus status = nsEventStatus_eIgnore;
// First, notify the DOM that we have a script error.
if (mDispatchEvent) {
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(mScriptGlobal));
nsIDocShell* docShell = win ? win->GetDocShell() : nullptr;
// First, notify the DOM that we have a script error, but only if
// our window is still the current inner, if we're associated with a window.
if (mDispatchEvent && (!mWindow || mWindow->IsCurrentInnerWindow())) {
nsIDocShell* docShell = mWindow ? mWindow->GetDocShell() : nullptr;
if (docShell &&
!JSREPORT_IS_WARNING(mFlags) &&
!sHandlingScriptError) {
@ -471,7 +467,7 @@ public:
init.mFilename = mFileName;
init.mBubbles = true;
nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(win));
nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(mWindow));
NS_ENSURE_STATE(sop);
nsIPrincipal* p = sop->GetPrincipal();
NS_ENSURE_STATE(p);
@ -497,11 +493,11 @@ public:
}
nsRefPtr<ErrorEvent> event =
ErrorEvent::Constructor(static_cast<nsGlobalWindow*>(win.get()),
ErrorEvent::Constructor(static_cast<nsGlobalWindow*>(mWindow.get()),
NS_LITERAL_STRING("error"), init);
event->SetTrusted(true);
EventDispatcher::DispatchDOMEvent(win, nullptr, event, presContext,
EventDispatcher::DispatchDOMEvent(mWindow, nullptr, event, presContext,
&status);
}
}
@ -514,10 +510,10 @@ public:
}
private:
nsCOMPtr<nsIScriptGlobalObject> mScriptGlobal;
nsCOMPtr<nsIPrincipal> mOriginPrincipal;
bool mDispatchEvent;
JS::PersistentRootedValue mError;
nsCOMPtr<nsPIDOMWindow> mWindow;
static bool sHandlingScriptError;
};
@ -575,13 +571,15 @@ NS_ScriptErrorReporter(JSContext *cx,
if (globalObject) {
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(globalObject);
if (win) {
win = win->GetCurrentInnerWindow();
}
nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal =
do_QueryInterface(globalObject);
NS_ASSERTION(scriptPrincipal, "Global objects must implement "
"nsIScriptObjectPrincipal");
nsContentUtils::AddScriptRunner(
new ScriptErrorEvent(globalObject,
JS_GetRuntime(cx),
new ScriptErrorEvent(JS_GetRuntime(cx),
report,
message,
nsJSPrincipals::get(report->originPrincipals),
@ -1708,7 +1706,6 @@ FullGCTimerFired(nsITimer* aTimer, void* aClosure)
void
nsJSContext::GarbageCollectNow(JS::gcreason::Reason aReason,
IsIncremental aIncremental,
IsCompartment aCompartment,
IsShrinking aShrinking,
int64_t aSliceMillis)
{
@ -2201,7 +2198,6 @@ InterSliceGCTimerFired(nsITimer *aTimer, void *aClosure)
nsJSContext::KillInterSliceGCTimer();
nsJSContext::GarbageCollectNow(JS::gcreason::INTER_SLICE_GC,
nsJSContext::IncrementalGC,
nsJSContext::CompartmentGC,
nsJSContext::NonShrinkingGC,
NS_INTERSLICE_GC_BUDGET);
}
@ -2213,8 +2209,7 @@ GCTimerFired(nsITimer *aTimer, void *aClosure)
nsJSContext::KillGCTimer();
uintptr_t reason = reinterpret_cast<uintptr_t>(aClosure);
nsJSContext::GarbageCollectNow(static_cast<JS::gcreason::Reason>(reason),
nsJSContext::IncrementalGC,
nsJSContext::CompartmentGC);
nsJSContext::IncrementalGC);
}
void

Просмотреть файл

@ -68,11 +68,6 @@ public:
static void LoadStart();
static void LoadEnd();
enum IsCompartment {
CompartmentGC,
NonCompartmentGC
};
enum IsShrinking {
ShrinkingGC,
NonShrinkingGC
@ -88,7 +83,6 @@ public:
static void GarbageCollectNow(JS::gcreason::Reason reason,
IsIncremental aIncremental = NonIncrementalGC,
IsCompartment aCompartment = NonCompartmentGC,
IsShrinking aShrinking = NonShrinkingGC,
int64_t aSliceMillis = 0);
static void ShrinkGCBuffersNow();

Просмотреть файл

@ -278,6 +278,7 @@ public:
// Set the window up with an about:blank document with the current subject
// principal.
// Outer windows only.
virtual void SetInitialPrincipalToSubject() = 0;
virtual PopupControlState PushPopupControlState(PopupControlState aState,
@ -364,7 +365,8 @@ public:
return !IsInnerWindow();
}
virtual bool WouldReuseInnerWindow(nsIDocument *aNewDocument) = 0;
// Outer windows only.
virtual bool WouldReuseInnerWindow(nsIDocument* aNewDocument) = 0;
/**
* Get the docshell in this window.
@ -424,8 +426,9 @@ public:
virtual void EnterModalState() = 0;
virtual void LeaveModalState() = 0;
// Outer windows only.
virtual bool CanClose() = 0;
virtual nsresult ForceClose() = 0;
virtual void ForceClose() = 0;
bool IsModalContentWindow() const
{

Просмотреть файл

@ -48,12 +48,9 @@ support-files =
[test_named_frames.html]
[test_navigator_resolve_identity.html]
[test_navigator_language.html]
[test_nondomexception.html]
[test_openDialogChromeOnly.html]
[test_open_null_features.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Fails on b2g-desktop, tracked in bug 1011874
[test_postMessage_solidus.html]
[test_screen_orientation.html]
[test_settimeout_extra_arguments.html]

Просмотреть файл

@ -1,28 +0,0 @@
<!-- intentionally omiting doctype because this test requires document.all -->
<html>
<head>
<title>Test for non-DOM module exceptions</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="application/javascript;version=1.7">
"use strict";
try {
document.all();
} catch (e) {
is(typeof e, "object");
is(e.filename, location);
is(e.lineNumber, 18);
}
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -91,7 +91,7 @@ DOMEventTargetHelper::~DOMEventTargetHelper()
void
DOMEventTargetHelper::BindToOwner(nsPIDOMWindow* aOwner)
{
MOZ_ASSERT(!aOwner || aOwner->IsInnerWindow());
MOZ_ASSERT_IF(aOwner, aOwner->IsInnerWindow());
nsCOMPtr<nsIGlobalObject> glob = do_QueryInterface(aOwner);
BindToOwner(glob);
}
@ -112,6 +112,7 @@ DOMEventTargetHelper::BindToOwner(nsIGlobalObject* aOwner)
// Let's cache the result of this QI for fast access and off main thread usage
mOwnerWindow = nsCOMPtr<nsPIDOMWindow>(do_QueryInterface(aOwner)).get();
if (mOwnerWindow) {
MOZ_ASSERT(mOwnerWindow->IsInnerWindow());
mHasOrHasHadOwnerWindow = true;
static_cast<nsGlobalWindow*>(mOwnerWindow)->AddEventTargetObject(this);
}
@ -134,6 +135,7 @@ DOMEventTargetHelper::BindToOwner(DOMEventTargetHelper* aOther)
// Let's cache the result of this QI for fast access and off main thread usage
mOwnerWindow = nsCOMPtr<nsPIDOMWindow>(do_QueryInterface(mParentObject)).get();
if (mOwnerWindow) {
MOZ_ASSERT(mOwnerWindow->IsInnerWindow());
mHasOrHasHadOwnerWindow = true;
static_cast<nsGlobalWindow*>(mOwnerWindow)->AddEventTargetObject(this);
}

Просмотреть файл

@ -120,13 +120,9 @@ public:
nsresult CheckInnerWindowCorrectness()
{
NS_ENSURE_STATE(!mHasOrHasHadOwnerWindow || mOwnerWindow);
if (mOwnerWindow) {
NS_ASSERTION(mOwnerWindow->IsInnerWindow(), "Should have inner window here!\n");
nsPIDOMWindow* outer = mOwnerWindow->GetOuterWindow();
if (!outer || outer->GetCurrentInnerWindow() != mOwnerWindow) {
if (mOwnerWindow && !mOwnerWindow->IsCurrentInnerWindow()) {
return NS_ERROR_FAILURE;
}
}
return NS_OK;
}
@ -159,7 +155,7 @@ protected:
private:
// Inner window or sandbox.
nsIGlobalObject* mParentObject;
// mParentObject pre QI-ed and cached
// mParentObject pre QI-ed and cached (inner window)
// (it is needed for off main thread access)
nsPIDOMWindow* mOwnerWindow;
bool mHasOrHasHadOwnerWindow;

Просмотреть файл

@ -660,15 +660,10 @@ IDBTransaction::GetMode(ErrorResult& aRv) const
}
DOMError*
IDBTransaction::GetError(ErrorResult& aRv)
IDBTransaction::GetError() const
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
if (IsOpen()) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
return mError;
}

Просмотреть файл

@ -242,7 +242,7 @@ public:
}
DOMError*
GetError(ErrorResult& aRv);
GetError() const;
already_AddRefed<IDBObjectStore>
ObjectStore(const nsAString& aName, ErrorResult& aRv);

Просмотреть файл

@ -58,6 +58,7 @@ tail =
[test_success_events_after_abort.js]
[test_traffic_jam.js]
[test_transaction_abort.js]
[test_transaction_error.js]
[test_transaction_lifetimes.js]
[test_transaction_lifetimes_nested.js]
[test_transaction_ordering.js]

Просмотреть файл

@ -192,6 +192,8 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_transaction_abort_hang.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_transaction_error.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_transaction_lifetimes.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_transaction_lifetimes_nested.html]

Просмотреть файл

@ -0,0 +1,18 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>Indexed Database Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7" src="unit/test_transaction_error.js"></script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

Просмотреть файл

@ -64,6 +64,7 @@
[test_traffic_jam.js]
[test_transaction_abort.js]
[test_transaction_abort_hang.js]
[test_transaction_error.js]
[test_transaction_lifetimes.js]
[test_transaction_lifetimes_nested.js]
[test_transaction_ordering.js]

Просмотреть файл

@ -34,13 +34,7 @@ function testSteps()
transaction = event.target.transaction;
try {
let error = transaction.error;
ok(false, "Expect an exception");
} catch(e) {
ok(true, "Got an exception.");
is(e.name, "InvalidStateError", "Got the right exception");
}
is(transaction.error, null, "Expect a null error");
objectStore = db.createObjectStore("foo", { autoIncrement: true });
index = objectStore.createIndex("fooindex", "indexKey", { unique: true });

Просмотреть файл

@ -0,0 +1,116 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
let testGenerator = testSteps();
function testSteps() {
const dbName = this.window ?
window.location.pathname :
"test_transaction_error";
const dbVersion = 1;
const objectStoreName = "foo";
const data = { };
const dataKey = 1;
const expectedError = "ConstraintError";
let request = indexedDB.open(dbName, dbVersion);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
let event = yield undefined;
info("Creating database");
let db = event.target.result;
let objectStore = db.createObjectStore(objectStoreName);
objectStore.add(data, dataKey);
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
db = event.target.result;
let transaction = db.transaction(objectStoreName, "readwrite");
transaction.onerror = grabEventAndContinueHandler;
transaction.oncomplete = grabEventAndContinueHandler;
objectStore = transaction.objectStore(objectStoreName);
info("Adding duplicate entry with preventDefault()");
let request = objectStore.add(data, dataKey);
request.onsuccess = unexpectedSuccessHandler;
request.onerror = grabEventAndContinueHandler;
event = yield undefined;
is(event.type, "error", "Got an error event");
is(event.target, request, "Error event targeted request");
is(event.currentTarget, request, "Got request error first");
is(event.currentTarget.error.name, expectedError,
"Request has correct error");
event.preventDefault();
event = yield undefined;
is(event.type, "error", "Got an error event");
is(event.target, request, "Error event targeted request");
is(event.currentTarget, transaction, "Got transaction error second");
is(event.currentTarget.error, null, "Transaction has null error");
event = yield undefined;
is(event.type, "complete", "Got a complete event");
is(event.target, transaction, "Complete event targeted transaction");
is(event.currentTarget, transaction,
"Complete event only targeted transaction");
is(event.currentTarget.error, null, "Transaction has null error");
// Try again without preventDefault().
transaction = db.transaction(objectStoreName, "readwrite");
transaction.onerror = grabEventAndContinueHandler;
transaction.onabort = grabEventAndContinueHandler;
objectStore = transaction.objectStore(objectStoreName);
info("Adding duplicate entry without preventDefault()");
if ("SimpleTest" in this) {
SimpleTest.expectUncaughtException();
}
request = objectStore.add(data, dataKey);
request.onsuccess = unexpectedSuccessHandler;
request.onerror = grabEventAndContinueHandler;
event = yield undefined;
is(event.type, "error", "Got an error event");
is(event.target, request, "Error event targeted request");
is(event.currentTarget, request, "Got request error first");
is(event.currentTarget.error.name, expectedError,
"Request has correct error");
event = yield undefined;
is(event.type, "error", "Got an error event");
is(event.target, request, "Error event targeted request");
is(event.currentTarget, transaction, "Got transaction error second");
is(event.currentTarget.error, null, "Transaction has null error");
event = yield undefined;
is(event.type, "abort", "Got an abort event");
is(event.target, transaction, "Abort event targeted transaction");
is(event.currentTarget, transaction,
"Abort event only targeted transaction");
is(event.currentTarget.error.name, expectedError,
"Transaction has correct error");
finishTest();
yield undefined;
}

Просмотреть файл

@ -79,6 +79,7 @@ skip-if = os == "android" && processor == "x86"
[test_traffic_jam.js]
[test_transaction_abort.js]
[test_transaction_abort_hang.js]
[test_transaction_error.js]
[test_transaction_lifetimes.js]
[test_transaction_lifetimes_nested.js]
[test_transaction_ordering.js]

Просмотреть файл

@ -23,6 +23,7 @@
#include "mozilla/dom/ExternalHelperAppChild.h"
#include "mozilla/dom/PCrashReporterChild.h"
#include "mozilla/dom/DOMStorageIPC.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/hal_sandbox/PHalChild.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/FileDescriptorUtils.h"
@ -1437,6 +1438,22 @@ ContentChild::AddRemoteAlertObserver(const nsString& aData,
return NS_OK;
}
bool
ContentChild::RecvSystemMemoryAvailable(const uint64_t& aGetterId,
const uint32_t& aMemoryAvailable)
{
nsRefPtr<Promise> p = dont_AddRef(reinterpret_cast<Promise*>(aGetterId));
if (!aMemoryAvailable) {
p->MaybeReject(NS_LITERAL_STRING("Abnormal"));
return true;
}
p->MaybeResolve((int)aMemoryAvailable);
return true;
}
bool
ContentChild::RecvPreferenceUpdate(const PrefSetting& aPref)
{

Просмотреть файл

@ -218,6 +218,9 @@ public:
// auto remove when alertfinished is received.
nsresult AddRemoteAlertObserver(const nsString& aData, nsIObserver* aObserver);
virtual bool RecvSystemMemoryAvailable(const uint64_t& aGetterId,
const uint32_t& aMemoryAvailable) MOZ_OVERRIDE;
virtual bool RecvPreferenceUpdate(const PrefSetting& aPref) MOZ_OVERRIDE;
virtual bool RecvNotifyAlertsObserver(const nsCString& aType,

Просмотреть файл

@ -119,6 +119,10 @@
#include "nsSystemInfo.h"
#endif
#if defined(XP_LINUX)
#include "mozilla/Hal.h"
#endif
#ifdef ANDROID
# include "gfxAndroidPlatform.h"
#endif
@ -3056,6 +3060,21 @@ ContentParent::RecvGetRandomValues(const uint32_t& length,
return true;
}
bool
ContentParent::RecvGetSystemMemory(const uint64_t& aGetterId)
{
uint32_t memoryTotal = 0;
#if defined(XP_LINUX)
memoryTotal = mozilla::hal::GetTotalSystemMemoryLevel();
#endif
unused << SendSystemMemoryAvailable(aGetterId, memoryTotal);
return true;
}
bool
ContentParent::RecvLoadURIExternal(const URIParams& uri)
{

Просмотреть файл

@ -523,7 +523,7 @@ private:
virtual bool RecvAudioChannelChangeDefVolChannel(const int32_t& aChannel,
const bool& aHidden) MOZ_OVERRIDE;
virtual bool RecvGetSystemMemory(const uint64_t& getterId) MOZ_OVERRIDE;
virtual bool RecvBroadcastVolume(const nsString& aVolumeName) MOZ_OVERRIDE;
virtual bool RecvSpeakerManagerGetSpeakerStatus(bool* aValue) MOZ_OVERRIDE;

Просмотреть файл

@ -357,6 +357,8 @@ child:
async NotifyVisited(URIParams uri);
async SystemMemoryAvailable(uint64_t getterId, uint32_t memoryAvailable);
PreferenceUpdate(PrefSetting pref);
NotifyAlertsObserver(nsCString topic, nsString data);
@ -436,6 +438,8 @@ parent:
sync GetRandomValues(uint32_t length)
returns (uint8_t[] randomValues);
async GetSystemMemory(uint64_t getterId);
PHal();
PIndexedDB();

Просмотреть файл

@ -168,6 +168,209 @@ public:
}
};
enum {
SLOT_PROMISE = 0,
SLOT_DATA
};
/*
* Utilities for thenable callbacks.
*
* A thenable is a { then: function(resolve, reject) { } }.
* `then` is called with a resolve and reject callback pair.
* Since only one of these should be called at most once (first call wins), the
* two keep a reference to each other in SLOT_DATA. When either of them is
* called, the references are cleared. Further calls are ignored.
*/
namespace {
void
LinkThenableCallables(JSContext* aCx, JS::Handle<JSObject*> aResolveFunc,
JS::Handle<JSObject*> aRejectFunc)
{
js::SetFunctionNativeReserved(aResolveFunc, SLOT_DATA,
JS::ObjectValue(*aRejectFunc));
js::SetFunctionNativeReserved(aRejectFunc, SLOT_DATA,
JS::ObjectValue(*aResolveFunc));
}
/*
* Returns false if callback was already called before, otherwise breaks the
* links and returns true.
*/
bool
MarkAsCalledIfNotCalledBefore(JSContext* aCx, JS::Handle<JSObject*> aFunc)
{
JS::Value otherFuncVal = js::GetFunctionNativeReserved(aFunc, SLOT_DATA);
if (!otherFuncVal.isObject()) {
return false;
}
JSObject* otherFuncObj = &otherFuncVal.toObject();
MOZ_ASSERT(js::GetFunctionNativeReserved(otherFuncObj, SLOT_DATA).isObject());
// Break both references.
js::SetFunctionNativeReserved(aFunc, SLOT_DATA, JS::UndefinedValue());
js::SetFunctionNativeReserved(otherFuncObj, SLOT_DATA, JS::UndefinedValue());
return true;
}
Promise*
GetPromise(JSContext* aCx, JS::Handle<JSObject*> aFunc)
{
JS::Value promiseVal = js::GetFunctionNativeReserved(aFunc, SLOT_PROMISE);
MOZ_ASSERT(promiseVal.isObject());
Promise* promise;
UNWRAP_OBJECT(Promise, &promiseVal.toObject(), promise);
return promise;
}
};
// Equivalent to the specification's ResolvePromiseViaThenableTask.
class ThenableResolverMixin
{
public:
ThenableResolverMixin(Promise* aPromise,
JS::Handle<JSObject*> aThenable,
PromiseInit* aThen)
: mPromise(aPromise)
, mThenable(CycleCollectedJSRuntime::Get()->Runtime(), aThenable)
, mThen(aThen)
{
MOZ_ASSERT(aPromise);
MOZ_COUNT_CTOR(ThenableResolverMixin);
}
virtual ~ThenableResolverMixin()
{
NS_ASSERT_OWNINGTHREAD(ThenableResolverMixin);
MOZ_COUNT_DTOR(ThenableResolverMixin);
}
protected:
void
RunInternal()
{
NS_ASSERT_OWNINGTHREAD(ThenableResolverMixin);
ThreadsafeAutoJSContext cx;
JS::Rooted<JSObject*> wrapper(cx, mPromise->GetOrCreateWrapper(cx));
if (!wrapper) {
return;
}
JSAutoCompartment ac(cx, wrapper);
JS::Rooted<JSObject*> resolveFunc(cx,
mPromise->CreateThenableFunction(cx, mPromise, PromiseCallback::Resolve));
if (!resolveFunc) {
mPromise->HandleException(cx);
return;
}
JS::Rooted<JSObject*> rejectFunc(cx,
mPromise->CreateThenableFunction(cx, mPromise, PromiseCallback::Reject));
if (!rejectFunc) {
mPromise->HandleException(cx);
return;
}
LinkThenableCallables(cx, resolveFunc, rejectFunc);
ErrorResult rv;
JS::Rooted<JSObject*> rootedThenable(cx, mThenable);
mThen->Call(rootedThenable, resolveFunc, rejectFunc, rv,
CallbackObject::eRethrowExceptions);
rv.WouldReportJSException();
if (rv.IsJSException()) {
JS::Rooted<JS::Value> exn(cx);
rv.StealJSException(cx, &exn);
bool couldMarkAsCalled = MarkAsCalledIfNotCalledBefore(cx, resolveFunc);
// If we could mark as called, neither of the callbacks had been called
// when the exception was thrown. So we can reject the Promise.
if (couldMarkAsCalled) {
bool ok = JS_WrapValue(cx, &exn);
MOZ_ASSERT(ok);
if (!ok) {
NS_WARNING("Failed to wrap value into the right compartment.");
}
mPromise->RejectInternal(cx, exn, Promise::SyncTask);
}
// At least one of resolveFunc or rejectFunc have been called, so ignore
// the exception. FIXME(nsm): This should be reported to the error
// console though, for debugging.
}
}
private:
nsRefPtr<Promise> mPromise;
JS::PersistentRooted<JSObject*> mThenable;
nsRefPtr<PromiseInit> mThen;
NS_DECL_OWNINGTHREAD;
};
// Main thread runnable to resolve thenables.
class ThenableResolverTask MOZ_FINAL : public nsRunnable,
public ThenableResolverMixin
{
public:
ThenableResolverTask(Promise* aPromise,
JS::Handle<JSObject*> aThenable,
PromiseInit* aThen)
: ThenableResolverMixin(aPromise, aThenable, aThen)
{
MOZ_ASSERT(NS_IsMainThread());
}
~ThenableResolverTask()
{
MOZ_ASSERT(NS_IsMainThread());
}
NS_IMETHOD Run()
{
MOZ_ASSERT(NS_IsMainThread());
RunInternal();
return NS_OK;
}
};
// Worker thread runnable to resolve thenables.
class WorkerThenableResolverTask MOZ_FINAL : public WorkerSameThreadRunnable,
public ThenableResolverMixin
{
public:
WorkerThenableResolverTask(WorkerPrivate* aWorkerPrivate,
Promise* aPromise,
JS::Handle<JSObject*> aThenable,
PromiseInit* aThen)
: WorkerSameThreadRunnable(aWorkerPrivate),
ThenableResolverMixin(aPromise, aThenable, aThen)
{
MOZ_ASSERT(aWorkerPrivate);
aWorkerPrivate->AssertIsOnWorkerThread();
}
~WorkerThenableResolverTask()
{}
bool
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
{
aWorkerPrivate->AssertIsOnWorkerThread();
RunInternal();
return true;
}
};
// Promise
NS_IMPL_CYCLE_COLLECTION_CLASS(Promise)
@ -267,11 +470,6 @@ Promise::MaybeReject(JSContext* aCx,
MaybeRejectInternal(aCx, aValue);
}
enum {
SLOT_PROMISE = 0,
SLOT_DATA
};
/* static */ bool
Promise::JSCallback(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
{
@ -299,62 +497,6 @@ Promise::JSCallback(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
return true;
}
/*
* Utilities for thenable callbacks.
*
* A thenable is a { then: function(resolve, reject) { } }.
* `then` is called with a resolve and reject callback pair.
* Since only one of these should be called at most once (first call wins), the
* two keep a reference to each other in SLOT_DATA. When either of them is
* called, the references are cleared. Further calls are ignored.
*/
namespace {
void
LinkThenableCallables(JSContext* aCx, JS::Handle<JSObject*> aResolveFunc,
JS::Handle<JSObject*> aRejectFunc)
{
js::SetFunctionNativeReserved(aResolveFunc, SLOT_DATA,
JS::ObjectValue(*aRejectFunc));
js::SetFunctionNativeReserved(aRejectFunc, SLOT_DATA,
JS::ObjectValue(*aResolveFunc));
}
/*
* Returns false if callback was already called before, otherwise breaks the
* links and returns true.
*/
bool
MarkAsCalledIfNotCalledBefore(JSContext* aCx, JS::Handle<JSObject*> aFunc)
{
JS::Value otherFuncVal = js::GetFunctionNativeReserved(aFunc, SLOT_DATA);
if (!otherFuncVal.isObject()) {
return false;
}
JSObject* otherFuncObj = &otherFuncVal.toObject();
MOZ_ASSERT(js::GetFunctionNativeReserved(otherFuncObj, SLOT_DATA).isObject());
// Break both references.
js::SetFunctionNativeReserved(aFunc, SLOT_DATA, JS::UndefinedValue());
js::SetFunctionNativeReserved(otherFuncObj, SLOT_DATA, JS::UndefinedValue());
return true;
}
Promise*
GetPromise(JSContext* aCx, JS::Handle<JSObject*> aFunc)
{
JS::Value promiseVal = js::GetFunctionNativeReserved(aFunc, SLOT_PROMISE);
MOZ_ASSERT(promiseVal.isObject());
Promise* promise;
UNWRAP_OBJECT(Promise, &promiseVal.toObject(), promise);
return promise;
}
};
/*
* Common bits of (JSCallbackThenableResolver/JSCallbackThenableRejecter).
* Resolves/rejects the Promise if it is ok to do so, based on whether either of
@ -375,9 +517,9 @@ Promise::ThenableResolverCommon(JSContext* aCx, uint32_t aTask,
MOZ_ASSERT(promise);
if (aTask == PromiseCallback::Resolve) {
promise->ResolveInternal(aCx, args.get(0), SyncTask);
promise->ResolveInternal(aCx, args.get(0));
} else {
promise->RejectInternal(aCx, args.get(0), SyncTask);
promise->RejectInternal(aCx, args.get(0));
}
return true;
}
@ -982,52 +1124,20 @@ Promise::ResolveInternal(JSContext* aCx,
}
if (then.isObject() && JS_ObjectIsCallable(aCx, &then.toObject())) {
JS::Rooted<JSObject*> resolveFunc(aCx,
CreateThenableFunction(aCx, this, PromiseCallback::Resolve));
if (!resolveFunc) {
HandleException(aCx);
return;
}
JS::Rooted<JSObject*> rejectFunc(aCx,
CreateThenableFunction(aCx, this, PromiseCallback::Reject));
if (!rejectFunc) {
HandleException(aCx);
return;
}
LinkThenableCallables(aCx, resolveFunc, rejectFunc);
// This is the then() function of the thenable aValueObj.
JS::Rooted<JSObject*> thenObj(aCx, &then.toObject());
nsRefPtr<PromiseInit> thenCallback =
new PromiseInit(thenObj, mozilla::dom::GetIncumbentGlobal());
ErrorResult rv;
thenCallback->Call(valueObj, resolveFunc, rejectFunc,
rv, CallbackObject::eRethrowExceptions);
rv.WouldReportJSException();
if (rv.IsJSException()) {
JS::Rooted<JS::Value> exn(aCx);
rv.StealJSException(aCx, &exn);
bool couldMarkAsCalled = MarkAsCalledIfNotCalledBefore(aCx, resolveFunc);
// If we could mark as called, neither of the callbacks had been called
// when the exception was thrown. So we can reject the Promise.
if (couldMarkAsCalled) {
bool ok = JS_WrapValue(aCx, &exn);
MOZ_ASSERT(ok);
if (!ok) {
NS_WARNING("Failed to wrap value into the right compartment.");
}
RejectInternal(aCx, exn, Promise::SyncTask);
}
// At least one of resolveFunc or rejectFunc have been called, so ignore
// the exception. FIXME(nsm): This should be reported to the error
// console though, for debugging.
if (NS_IsMainThread()) {
nsRefPtr<ThenableResolverTask> task =
new ThenableResolverTask(this, valueObj, thenCallback);
NS_DispatchToCurrentThread(task);
} else {
WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(worker);
nsRefPtr<WorkerThenableResolverTask> task =
new WorkerThenableResolverTask(worker, this, valueObj, thenCallback);
task->Dispatch(worker->GetJSContext());
}
return;

Просмотреть файл

@ -59,6 +59,7 @@ class Promise MOZ_FINAL : public nsISupports,
friend class PromiseWorkerProxyRunnable;
friend class RejectPromiseCallback;
friend class ResolvePromiseCallback;
friend class ThenableResolverMixin;
friend class WorkerPromiseResolverTask;
friend class WorkerPromiseTask;
friend class WrapperPromiseCallback;

Просмотреть файл

@ -618,6 +618,59 @@ function promiseResolvePromise() {
});
}
// Bug 1009569.
// Ensure that thenables are run on a clean stack asynchronously.
// Test case adopted from
// https://gist.github.com/getify/d64bb01751b50ed6b281#file-bug1-js.
function promiseResolveThenableCleanStack() {
function immed(s) { x++; s(); }
function incX(){ x++; }
var x = 0;
var thenable = { then: immed };
var results = [];
Promise.resolve(thenable).then(incX);
results.push(x);
// check what happens after all "next cycle" steps
// have had a chance to complete
setTimeout(function(){
results.push(x);
// Result should be [0, 2] since `thenable` will be called async.
is(results[0], 0, "Expected thenable to be called asynchronously");
is(results[1], 2, "Expected thenable to be called asynchronously");
runTest();
},1000);
}
// Bug 1008467 - Promise fails with "too much recursion".
// The bug was that the callbacks passed to a thenable would resolve the
// promise synchronously when the fulfill handler returned a non-thenable.
//
// For example:
// var p = new Promise(function(resolve) {
// resolve(5);
// });
// var m = Promise.resolve(p);
//
// At this point `m` is a Promise that is resolved with a thenable `p`, so it
// calls `p.then()` with two callbacks, both of which would synchronously resolve
// `m` when `p` invoked them (on account of itself being resolved, possibly
// synchronously. A chain of these 'Promise resolved by a Promise' would lead to
// stack overflow.
function promiseTestAsyncThenableResolution()
{
var k = 3000;
Promise.resolve().then(function next() {
k--;
if (k > 0) return Promise.resolve().then(next);
}).then(function () {
ok(true, "Resolution of a chain of thenables should not be synchronous.");
runTest();
});
}
var tests = [ promiseResolve, promiseReject,
promiseException, promiseGC, promiseAsync,
promiseDoubleThen, promiseThenException,
@ -648,6 +701,8 @@ var tests = [ promiseResolve, promiseReject,
promiseResolveArray,
promiseResolveThenable,
promiseResolvePromise,
promiseResolveThenableCleanStack,
promiseTestAsyncThenableResolution,
];
function runTest() {

Просмотреть файл

@ -17,6 +17,8 @@
#ifndef ANDROID_AUDIOSYSTEM_H_
#define ANDROID_AUDIOSYSTEM_H_
#pragma GCC visibility push(default)
#include <utils/RefBase.h>
#include <utils/threads.h>
#include "IAudioFlinger.h"
@ -961,4 +963,6 @@ private:
}; // namespace android
#pragma GCC visibility pop
#endif /*ANDROID_AUDIOSYSTEM_H_*/

Просмотреть файл

@ -381,6 +381,8 @@ var interfaceNamesInGlobalScope =
"HashChangeEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
"History",
// IMPORTANT: Do not change this list without review from a DOM peer!
"HTMLAllCollection",
// IMPORTANT: Do not change this list without review from a DOM peer!
"HTMLAnchorElement",
// IMPORTANT: Do not change this list without review from a DOM peer!

Просмотреть файл

@ -0,0 +1,13 @@
/* 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/. */
/* Emulates undefined through Codegen.py. */
interface HTMLAllCollection {
readonly attribute unsigned long length;
getter Node? (unsigned long index);
Node? item(unsigned long index);
(Node or HTMLCollection)? item(DOMString name);
legacycaller (Node or HTMLCollection)? (DOMString name);
getter (Node or HTMLCollection)? namedItem(DOMString name);
};

Просмотреть файл

@ -72,8 +72,7 @@ interface HTMLDocument : Document {
void clear();
[Throws]
readonly attribute object all;
readonly attribute HTMLAllCollection all;
// https://dvcs.w3.org/hg/editing/raw-file/tip/editing.html#selections
[Throws]

Просмотреть файл

@ -19,7 +19,6 @@ interface IDBTransaction : EventTarget {
readonly attribute IDBTransactionMode mode;
readonly attribute IDBDatabase db;
[Throws]
readonly attribute DOMError? error;
[Throws]

Просмотреть файл

@ -10,6 +10,13 @@
* liability, trademark and document use rules apply.
*/
dictionary SVGBoundingBoxOptions {
boolean fill = true;
boolean stroke = false;
boolean markers = false;
boolean clipped = false;
};
interface SVGGraphicsElement : SVGElement {
readonly attribute SVGAnimatedTransformList transform;
@ -17,7 +24,7 @@ interface SVGGraphicsElement : SVGElement {
readonly attribute SVGElement? farthestViewportElement;
[NewObject, Throws]
SVGRect getBBox();
SVGRect getBBox(optional SVGBoundingBoxOptions aOptions);
// Not implemented
// SVGRect getStrokeBBox();
SVGMatrix? getCTM();

Просмотреть файл

@ -72,7 +72,8 @@ typedef any Transferable;
[Throws] readonly attribute ApplicationCache applicationCache;
// user prompts
[Throws] void alert(optional DOMString message = "");
[Throws] void alert();
[Throws] void alert(DOMString message);
[Throws] boolean confirm(optional DOMString message = "");
[Throws] DOMString? prompt(optional DOMString message = "", optional DOMString default = "");
[Throws] void print();
@ -294,9 +295,9 @@ partial interface Window {
[Throws] attribute boolean fullScreen;
[Throws] void back();
[Throws] void forward();
[Throws] void home();
[Throws, ChromeOnly] void back();
[Throws, ChromeOnly] void forward();
[Throws, ChromeOnly] void home();
// XXX Should this be in nsIDOMChromeWindow?
void updateCommands(DOMString action);

Просмотреть файл

@ -124,6 +124,7 @@ WEBIDL_FILES = [
'GeometryUtils.webidl',
'GetUserMediaRequest.webidl',
'History.webidl',
'HTMLAllCollection.webidl',
'HTMLAnchorElement.webidl',
'HTMLAppletElement.webidl',
'HTMLAreaElement.webidl',

Просмотреть файл

@ -654,6 +654,32 @@ function promiseResolvePromise() {
});
}
// Bug 1009569.
// Ensure that thenables are run on a clean stack asynchronously.
// Test case adopted from
// https://gist.github.com/getify/d64bb01751b50ed6b281#file-bug1-js.
function promiseResolveThenableCleanStack() {
function immed(s) { x++; s(); }
function incX(){ x++; }
var x = 0;
var thenable = { then: immed };
var results = [];
Promise.resolve(thenable).then(incX);
results.push(x);
// check what happens after all "next cycle" steps
// have had a chance to complete
setTimeout(function(){
results.push(x);
// Result should be [0, 2] since `thenable` will be called async.
is(results[0], 0, "Expected thenable to be called asynchronously");
is(results[1], 2, "Expected thenable to be called asynchronously");
runTest();
},1000);
}
var tests = [
promiseResolve,
promiseReject,
@ -698,6 +724,8 @@ var tests = [
promiseResolveArray,
promiseResolveThenable,
promiseResolvePromise,
promiseResolveThenableCleanStack,
];
function runTest() {

Просмотреть файл

@ -63,7 +63,9 @@ txExecutionState::~txExecutionState()
delete mResultHandler;
delete mLocalVariables;
if (mEvalContext != mInitialEvalContext) {
delete mEvalContext;
}
txStackIterator varsIter(&mLocalVarsStack);
while (varsIter.hasNext()) {
@ -87,6 +89,8 @@ txExecutionState::~txExecutionState()
while (paramIter.hasNext()) {
delete (txVariableMap*)paramIter.next();
}
delete mInitialEvalContext;
}
nsresult

Просмотреть файл

@ -546,9 +546,6 @@ const knownFailures = {
"S-Proposed-SM:e.b.lb_P.P.P-1_SIR-2-dM": true,
"S-Proposed-SM:e.b.lb_P.P.P-1_SIR-2-body": true,
"S-Proposed-SM:e.b.lb_P.P.P-1_SIR-2-div": true,
"S-Proposed-SM:e.f.l_BR.BR-2_SI-1-dM": true,
"S-Proposed-SM:e.f.l_BR.BR-2_SI-1-body": true,
"S-Proposed-SM:e.f.l_BR.BR-2_SI-1-div": true,
"A-Proposed-B_TEXT-1_SI-dM": true,
"A-Proposed-B_TEXT-1_SI-body": true,
"A-Proposed-B_TEXT-1_SI-div": true,

Просмотреть файл

@ -9103,557 +9103,564 @@
< anecdotal
---
> anecdotal/Y
11804c17614
11750a17561,17562
> anonymization/SM
> anonymize/DSG
11804c17616
< anthropomorphizing
---
> anthropomorphize/DSG
11983c17793
11983c17795
< app/S
---
> app/MS
12137a17948
12137a17950
> archaeology/M
12152c17963
12152c17965
< archeological
---
> archeological/Y
12432c18243
12432c18245
< assignees
---
> assignee/MS
12685c18496
12685c18498
< auteur
---
> auteur/MS
12713a18525
12713a18527
> autocomplete/S
12754a18567
12754a18569
> avant-garde
12827d18639
12827d18641
< awol
12829a18642
12829a18644
> axe/M
13864a19678
13864a19680
> biodiesel/M
14210d20023
14210d20025
< blueing's
14434a20248
14434a20250
> bookselling
14841c20655
14841c20657
< broadcast/AMGS
---
> broadcast/AMGSD
15039,15040c20853
15039,15040c20855
< bullshitter's
< bullshitter/S!
---
> bullshitter/SM!
15230d21042
15230d21044
< byelaw/SM
15383d21194
15383d21196
< callisthenics/M
15460a21272,21274
15460a21274,21276
> cancelled/U
> canceller/M
> cancelling
15559a21374
15559a21376
> capita
15629,15630d21443
15629,15630d21445
< carburetter/SM
< carburettor/SM
15701a21515
15701a21517
> carnitas
15788d21601
15788d21603
< cashpoint/S
15797d21609
15797d21611
< cassino/M
15832a21645
15832a21647
> catalyses
15940d21752
15940d21754
< caviare/M
16372c22184
16372c22186
< chickenshit/S!
---
> chickenshit/SM!
16404c22216
16404c22218
< children
---
> children/M
16488d22299
16488d22301
< chlorophyl/M
16629,16630c22440
16629,16630c22442
< cider's
< cider/S
---
> cider/MS
16652a22463
16652a22465
> ciphertext/S
17072d22882
17072d22884
< cocain/M
17102,17103c22912
17102,17103c22914
< cocksucker's
< cocksucker/S!
---
> cocksucker/SM!
17755c23564
17755c23566
< confer/S
---
> confer/SB
17800a23610
17800a23612
> conformant
18151d23960
18151d23962
< convenor/S
18206c24015
18206c24017
< cookie/M
---
> cookie/SM
18375a24185,24186
18375a24187,24188
> corrigibility/IM
> corrigible/I
18389a24201
18389a24203
> corruptibly/I
18467a24280
18467a24282
> could've
18999a24813
18999a24815
> cryptologist/MS
19000a24815
19000a24817
> cryptosystem/S
19035a24851
19035a24853
> cul-de-sac
19246c25062
19246c25064
< cysteine
---
> cysteine/M
19935a25752
19935a25754
> dequeue/DSG
20196,20197c26013,26014
20196,20197c26015,26016
< dialog/SM
< dialogue/SM
---
> dialog/SMGD
> dialogue/SMRGD
20220a26038
20220a26040
> diatomaceous
20481a26300
20481a26302
> disclose/DSG
20633a26453
20633a26455
> dissentious
20830c26650
20830c26652
< dogie/M
---
> dogie/SM
20895a26716
20895a26718
> donator/MS
21820a27642
21820a27644
> elicitor/MS
22071a27894
22071a27896
> encyclopaedia
22196a28020
22196a28022
> enqueue/DSG
22556a28381
22556a28383
> estoppel
22638c28463
22638c28465
< euthanize
---
> euthanize/DSG
22719a28545
22719a28547
> exabyte/MS
22947a28774
22947a28776
> experimentalism
23207,23208d29033
23207,23208d29035
< faecal
< faeces/M
23215c29040
23215c29042
< faggoting's
---
> faggot/SMG
23701a29527
23701a29529
> filesystem/MS
24155c29981
24155c29983
< fluidized
---
> fluidize/DSG
24216a30043
24216a30045
> foci
24736d30562
24736d30564
< frier/M
24855,24856c30681,30682
24855,24856c30683,30684
< fucker/M!
< fuckhead/S!
---
> fucker/SM!
> fuckhead/SM!
24953d30778
24953d30780
< furore/MS
25125c30950
25125c30952
< gaolbird/S
---
> gaolbirds
25180d31004
25180d31006
< gasolene/M
25190a31015
25190a31017
> gastroenterologist/M
25262c31087
25262c31089
< geezer/M
---
> geezer/MS
25327c31152
25327c31154
< genomic
---
> genomic/S
25462a31288
25462a31290
> gigabit/MS
25464a31291,31293
25464a31293,31295
> gigajoule/MS
> gigapixel/MS
> gigawatt/MS
25560d31388
25560d31390
< glamourize/DSG
25674c31502
25674c31504
< glycerine's
---
> glycerine/M
25905c31733
25905c31735
< gram/MS
---
> gram/KMS
25909d31736
25909d31738
< gramme/SM
26063c31890,31891
26063c31892,31893
< greybeard
---
> grey/MDRTGSP
> greybeard/SM
26066c31894
26066c31896
< greyness
---
> greyness/M
26246,26247d32073
26246,26247d32075
< guerilla's
< guerillas
26432,26436d32257
26432,26436d32259
< haemoglobin's
< haemophilia/M
< haemorrhage/DSMG
< haemorrhoid/S
< haemorrhoids/M
27167c32988
27167c32990
< hexane
---
> hexane/SM
27273a33095
27273a33097
> hippopotami
27875d33696
27875d33698
< hyaena/SM
28017c33838
28017c33840
< iPod/M
---
> iPod/MS
28105a33927
28105a33929
> idolator/SM
28513c34335
28227c34051
< immerse/XDSGN
---
> immerse/XDSGNV
28513c34337
< inbound
---
> inbound/s
28590,28591c34412
28590,28591c34414
< incorrigibility/M
< incorrigible
---
> incorrigibleness
28593d34413
28593d34415
< incorruptibly
28650a34471
28650a34473
> indices
28812d34632
28812d34634
< inflexion/SM
29216a35037
29216a35039
> intern/GDL
29266a35088
29266a35090
> interruptible/U
29272a35095,35098
29272a35097,35100
> intersex
> intersexual/MS
> intersexualism
> intersexuality
29724c35550
29724c35552
< jewellery's
---
> jewellery/M
29870a35697
29870a35699
> judgement/MS
30066c35893
30066c35895
< kiddie/M
---
> kiddie/SM
30262,30263c36089
30262,30263c36091
< kraut's
< kraut/S!
---
> kraut/MS!
30665a36492
30665a36494
> lector/MS
31031c36858
31031c36860
< linguini's
---
> linguini/M
31034c36861
31034c36863
< linguistically
---
> linguistical/Y
31151,31152c36978
31151,31152c36980
< liver's
< liver/S
---
> liver/MS
32230c38056
32230c38058
< meanie/M
---
> meanie/MS
32317,32318c38143
32317,32318c38145
< megadeath/M
< megadeaths
---
> megadeath/SM
32320c38145
32320c38147
< megajoules
---
> megajoule/SM
32329c38154
32329c38156
< megapixel/S
---
> megapixel/MS
32708a38534
32708a38536
> might've
32717a38544
32717a38546
> migrator/SM
32760a38588
32760a38590
> millennia
32777d38604
32777d38606
< millionnaire/M
32934a38762
32934a38764
> miscommunication/S
32991a38820
32991a38822
> misjudgement/MS
33784a39614
33784a39616
> must've
33963c39793
33963c39795
< native/MS
---
> native/MSY
34169,34171c39999,40000
34169,34171c40001,40002
< neurone/S
< neurophysiology
< neuroscience
---
> neurophysiology/M
> neuroscience/MS
34275c40104
34275c40106
< nightie/M
---
> nightie/SM
35104a40934
35104a40936
> octopi
35219d41048
35219d41050
< oleomargarin/M
35226a41056
35226a41058
> oligo
35913c41743
35913c41745
< oversize/D
---
> oversize
36056,36059d41885
36056,36059d41887
< paederast/S
< paediatrician's
< paediatricians
< paediatrics/M
36291a42118
36291a42120
> paralyses
36403d42229
36403d42231
< parrakeet/MS
36449d42274
36449d42276
< partizan/SM
37093a42919
37093a42921
> petabyte/MS
37102c42928
37102c42930
< petitioner/M
---
> petitioner/MS
37264a43091
37264a43093
> phosphorylate/DSGN
37316d43142
37316d43144
< phrenetic
37630a43457
37630a43459
> plaintext
37796a43624
37796a43626
> plugin/MS
37987c43815
37987c43817
< polypeptide/S
---
> polypeptide/MS
38291d44118
38291d44120
< practise's
38451a44279
38451a44281
> prejudgement/MS
38805a44634
38805a44636
> profiler/SM
38835a44665
38835a44667
> programmatically
38891a44722,44723
38891a44724,44725
> pronate/DSGN
> pronator/MS
38951c44783
38951c44785
< proprietorship/M
---
> proprietorship/MS
39039a44872
39039a44874
> provender/M
39095a44929
39095a44931
> pseudorandom/Y
39564a45399
39564a45401
> quinoa
39873a45709,45710
39873a45711,45712
> rasterization/M
> rasterize/SGDR
40036a45874
40036a45876
> recency
40140a45979
40140a45981
> recurse/DGSV
40141a45981
40141a45983
> recuse/DGS
40208a46049
40208a46051
> refactor/SMDG
40244d46084
40244d46086
< reflexion/SM
40659d46498
40659d46500
< resizing
40829c46668
40829c46670
< reverie/M
---
> reverie/MS
41415a47255
41415a47257
> sabre/MS
41914c47754
41914c47756
< schnaps's
---
> schnaps/M
41949c47789
41949c47791
< schrod's
---
> schrod/SM
41998a47839
41998a47841
> scot-free
42883,42885c48724
42883,42885c48726
< shit's
< shit/S!
< shite/S!
---
> shit/MS!
42887,42888c48726,48727
42887,42888c48728,48729
< shithead/S!
< shitload/!
---
> shithead/MS!
> shitload/MS!
42891c48730
42891c48732
< shitty/RT!
---
> shitty/TR!
42976a48816
42976a48818
> should've
43008c48848
43008c48850
< showtime
---
> showtime/MS
43328c49168
43328c49170
< size/MGBDRS
---
> size/AMGBDRS
43724,43726c49564
43724,43726c49566
< smoulder's
< smouldered
< smoulders
---
> smoulder/GSMD
43766a49605,49606
43766a49607,49608
> snarkily
> snarky/TR
44062c49902
44062c49904
< sonofabitch
---
> sonofabitch/!
44346a50187
44346a50189
> spelled
44348a50190
44348a50192
> spelt
44371a50214
44371a50216
> spick/S!
44383c50226
44383c50228
< spik/S
---
> spik/S!
46106a51950
46106a51952
> syllabi
46160c52004
46160c52006
< synch/GMD
---
> synch/GMDS
46167d52010
46167d52012
< synchs
46203,46204c52046,52047
46203,46204c52048,52049
< sysadmin/S
< sysop/S
---
> sysadmin/MS
> sysop/MS
46752a52596
46752a52598
> terabit/MS
46753a52598,52599
46753a52600,52601
> terahertz/M
> terapixel/MS
46817a52664
46817a52666
> testcase/MS
46831a52679
46831a52681
> testsuite/MS
46845a52694
46845a52696
> textbox/SM
46925a52775
46925a52777
> theremin/MS
47455c53305
47455c53307
< toolbar
---
> toolbar/MS
47755a53606
47755a53608
> transfect/DSMG
47774a53626,53627
47774a53628,53629
> transgenderism
> transgene/MS
47951c53804
47951c53806
< triage/M
---
> triage/MG
48869a54723
48869a54725
> unlikeable
49211c55065
49211c55067
< vagina/M
---
> vagina/MS
49368,49369c55222
49368,49369c55224
< velour's
< velours's
---
> velour/MS
49478a55332
49478a55334
> vertices
50148a56003
50148a56005
> weaponize/DSG
50260,50261d56114
50260,50261d56116
< werwolf/M
< werwolves
50728c56581
50728c56583
< women
---
> women/M
50794c56647
50794c56649
< wop/S!
---
> wop/MS!

Просмотреть файл

@ -1,4 +1,4 @@
57469
57471
0/nm
0th/pt
1/n1
@ -17802,6 +17802,8 @@ anomalous/Y
anomaly/SM
anon/S
anonymity/M
anonymization/SM
anonymize/DSG
anonymous/Y
anopheles/M
anorak/MS
@ -34336,7 +34338,7 @@ immediateness/M
immemorial/Y
immense/RYTP
immensity/SM
immerse/XDSGN
immerse/XDSGNV
immersible
immersion/M
immigrant/SM

Просмотреть файл

@ -1253,6 +1253,7 @@ DrawTargetCG::CopySurface(SourceSurface *aSurface,
CGContextDrawImage(mCg, flippedRect, image);
CGContextRestoreGState(mCg);
CGImageRelease(image);
}
}

Просмотреть файл

@ -1232,6 +1232,11 @@ GetTotalSystemMemory()
return hal_impl::GetTotalSystemMemory();
}
uint32_t
GetTotalSystemMemoryLevel()
{
return hal_impl::GetTotalSystemMemoryLevel();
}
} // namespace hal
} // namespace mozilla

Просмотреть файл

@ -616,6 +616,14 @@ void StopDiskSpaceWatcher();
*/
uint32_t GetTotalSystemMemory();
/**
* Get the level of total system memory on device in MiB.
* (round the value up to the next power of two)
*
* Returns 0 if we are unable to determine this information from /proc/meminfo.
*/
uint32_t GetTotalSystemMemoryLevel();
} // namespace MOZ_HAL_NAMESPACE
} // namespace mozilla

Просмотреть файл

@ -16,5 +16,11 @@ GetTotalSystemMemory()
return 0;
}
uint32_t
GetTotalSystemMemoryLevel()
{
return 0;
}
} // namespace hal_impl
} // namespace mozilla

Просмотреть файл

@ -35,5 +35,37 @@ GetTotalSystemMemory()
return sTotalMemory * 1024;
}
uint32_t
GetTotalSystemMemoryLevel()
{
static uint32_t sTotalMemoryLevel = 1;
uint32_t sTotalMemory;
static bool sTotalMemoryObtained = false;
if (!sTotalMemoryObtained) {
sTotalMemoryObtained = true;
FILE* fd = fopen("/proc/meminfo", "r");
if (!fd) {
return 0;
}
int rv = fscanf(fd, "MemTotal: %i kB", &sTotalMemory);
if (fclose(fd) || rv != 1) {
return 0;
}
// From KB to MiB
sTotalMemory /= 1024;
while (sTotalMemoryLevel <= sTotalMemory) {
sTotalMemoryLevel *= 2;
}
}
return sTotalMemoryLevel;
}
} // namespace hal_impl
} // namespace mozilla

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше