mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-i to m-c, a=merge
This commit is contained in:
commit
48398662cf
@ -95,7 +95,7 @@ include backend.RecursiveMakeBackend.pp
|
||||
default:: backend.RecursiveMakeBackend
|
||||
|
||||
install_manifests := \
|
||||
$(addprefix dist/,bin idl include public private sdk xpi-stage) \
|
||||
$(addprefix dist/,bin branding idl include public private sdk xpi-stage) \
|
||||
_tests \
|
||||
$(NULL)
|
||||
install_manifest_depends = \
|
||||
|
@ -354,7 +354,7 @@ ia2Accessible::get_states(AccessibleStates* aStates)
|
||||
AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
|
||||
if (acc->IsDefunct()) {
|
||||
*aStates = IA2_STATE_DEFUNCT;
|
||||
return CO_E_OBJNOTCONNECTED;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
uint64_t state;
|
||||
|
@ -610,7 +610,7 @@ pref("mousewheel.with_win.action", 1);
|
||||
pref("browser.xul.error_pages.enabled", true);
|
||||
pref("browser.xul.error_pages.expert_bad_cert", false);
|
||||
|
||||
// Work Offline is best manually managed by the user.
|
||||
// If true, network link events will change the value of navigator.onLine
|
||||
pref("network.manage-offline-status", false);
|
||||
|
||||
// We want to make sure mail URLs are handled externally...
|
||||
|
@ -1,48 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
BRANDING_FILES := \
|
||||
firefox.ico \
|
||||
document.ico \
|
||||
branding.nsi \
|
||||
appname.bmp \
|
||||
bgintro.bmp \
|
||||
clock.bmp \
|
||||
particles.bmp \
|
||||
pencil.bmp \
|
||||
pencil-rtl.bmp \
|
||||
wizHeader.bmp \
|
||||
wizHeaderRTL.bmp \
|
||||
wizWatermark.bmp \
|
||||
newwindow.ico \
|
||||
newtab.ico \
|
||||
pbmode.ico \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
|
||||
BRANDING_FILES := \
|
||||
background.png \
|
||||
firefox.icns \
|
||||
disk.icns \
|
||||
document.icns \
|
||||
dsstore \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifdef MOZ_WIDGET_GTK
|
||||
BRANDING_FILES := \
|
||||
default16.png \
|
||||
default32.png \
|
||||
default48.png \
|
||||
mozicon128.png \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
BRANDING_DEST := $(DIST)/branding
|
||||
BRANDING_TARGET := export
|
||||
INSTALL_TARGETS += BRANDING
|
@ -9,7 +9,4 @@ DIRS += ['content', 'locales']
|
||||
DIST_SUBDIR = 'browser'
|
||||
export('DIST_SUBDIR')
|
||||
|
||||
JS_PREFERENCE_FILES += [
|
||||
'pref/firefox-branding.js',
|
||||
]
|
||||
|
||||
include('../branding-common.mozbuild')
|
||||
|
43
browser/branding/branding-common.mozbuild
Normal file
43
browser/branding/branding-common.mozbuild
Normal file
@ -0,0 +1,43 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
JS_PREFERENCE_FILES += [
|
||||
'pref/firefox-branding.js',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
BRANDING_FILES += [
|
||||
'appname.bmp',
|
||||
'bgintro.bmp',
|
||||
'branding.nsi',
|
||||
'clock.bmp',
|
||||
'document.ico',
|
||||
'firefox.ico',
|
||||
'newtab.ico',
|
||||
'newwindow.ico',
|
||||
'particles.bmp',
|
||||
'pbmode.ico',
|
||||
'pencil-rtl.bmp',
|
||||
'pencil.bmp',
|
||||
'wizHeader.bmp',
|
||||
'wizHeaderRTL.bmp',
|
||||
'wizWatermark.bmp',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
BRANDING_FILES += [
|
||||
'background.png',
|
||||
'disk.icns',
|
||||
'document.icns',
|
||||
'dsstore',
|
||||
'firefox.icns',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_GTK']:
|
||||
BRANDING_FILES += [
|
||||
'default16.png',
|
||||
'default32.png',
|
||||
'default48.png',
|
||||
'mozicon128.png',
|
||||
]
|
@ -1,48 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
BRANDING_FILES := \
|
||||
firefox.ico \
|
||||
document.ico \
|
||||
branding.nsi \
|
||||
appname.bmp \
|
||||
bgintro.bmp \
|
||||
clock.bmp \
|
||||
particles.bmp \
|
||||
pencil.bmp \
|
||||
pencil-rtl.bmp \
|
||||
wizHeader.bmp \
|
||||
wizHeaderRTL.bmp \
|
||||
wizWatermark.bmp \
|
||||
newwindow.ico \
|
||||
newtab.ico \
|
||||
pbmode.ico \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
|
||||
BRANDING_FILES := \
|
||||
background.png \
|
||||
firefox.icns \
|
||||
disk.icns \
|
||||
document.icns \
|
||||
dsstore \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifdef MOZ_WIDGET_GTK
|
||||
BRANDING_FILES := \
|
||||
default16.png \
|
||||
default32.png \
|
||||
default48.png \
|
||||
mozicon128.png \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
BRANDING_DEST := $(DIST)/branding
|
||||
BRANDING_TARGET := export
|
||||
INSTALL_TARGETS += BRANDING
|
@ -9,7 +9,4 @@ DIRS += ['content', 'locales']
|
||||
DIST_SUBDIR = 'browser'
|
||||
export('DIST_SUBDIR')
|
||||
|
||||
JS_PREFERENCE_FILES += [
|
||||
'pref/firefox-branding.js',
|
||||
]
|
||||
|
||||
include('../branding-common.mozbuild')
|
||||
|
@ -1,48 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
BRANDING_FILES := \
|
||||
firefox.ico \
|
||||
document.ico \
|
||||
branding.nsi \
|
||||
appname.bmp \
|
||||
bgintro.bmp \
|
||||
clock.bmp \
|
||||
particles.bmp \
|
||||
pencil.bmp \
|
||||
pencil-rtl.bmp \
|
||||
wizHeader.bmp \
|
||||
wizHeaderRTL.bmp \
|
||||
wizWatermark.bmp \
|
||||
newwindow.ico \
|
||||
newtab.ico \
|
||||
pbmode.ico \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
|
||||
BRANDING_FILES := \
|
||||
background.png \
|
||||
firefox.icns \
|
||||
disk.icns \
|
||||
document.icns \
|
||||
dsstore \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifdef MOZ_WIDGET_GTK
|
||||
BRANDING_FILES := \
|
||||
default16.png \
|
||||
default32.png \
|
||||
default48.png \
|
||||
mozicon128.png \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
BRANDING_DEST := $(DIST)/branding
|
||||
BRANDING_TARGET := export
|
||||
INSTALL_TARGETS += BRANDING
|
@ -9,7 +9,4 @@ DIRS += ['content', 'locales']
|
||||
DIST_SUBDIR = 'browser'
|
||||
export('DIST_SUBDIR')
|
||||
|
||||
JS_PREFERENCE_FILES += [
|
||||
'pref/firefox-branding.js',
|
||||
]
|
||||
|
||||
include('../branding-common.mozbuild')
|
||||
|
@ -1,48 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
BRANDING_FILES := \
|
||||
firefox.ico \
|
||||
document.ico \
|
||||
branding.nsi \
|
||||
appname.bmp \
|
||||
bgintro.bmp \
|
||||
clock.bmp \
|
||||
particles.bmp \
|
||||
pencil.bmp \
|
||||
pencil-rtl.bmp \
|
||||
wizHeader.bmp \
|
||||
wizHeaderRTL.bmp \
|
||||
wizWatermark.bmp \
|
||||
newwindow.ico \
|
||||
newtab.ico \
|
||||
pbmode.ico \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
|
||||
BRANDING_FILES := \
|
||||
background.png \
|
||||
firefox.icns \
|
||||
disk.icns \
|
||||
document.icns \
|
||||
dsstore \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifdef MOZ_WIDGET_GTK
|
||||
BRANDING_FILES := \
|
||||
default16.png \
|
||||
default32.png \
|
||||
default48.png \
|
||||
mozicon128.png \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
BRANDING_DEST := $(DIST)/branding
|
||||
BRANDING_TARGET := export
|
||||
INSTALL_TARGETS += BRANDING
|
@ -9,7 +9,4 @@ DIRS += ['content', 'locales']
|
||||
DIST_SUBDIR = 'browser'
|
||||
export('DIST_SUBDIR')
|
||||
|
||||
JS_PREFERENCE_FILES += [
|
||||
'pref/firefox-branding.js',
|
||||
]
|
||||
|
||||
include('../branding-common.mozbuild')
|
||||
|
@ -36,8 +36,8 @@ netmonitor.security.state.secure=The connection used to fetch this resource was
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.security.state.insecure)
|
||||
# This string is used as an tooltip for request that was performed over insecure
|
||||
# channel i.e. the connection was not encrypted.
|
||||
netmonitor.security.state.insecure=The connection used to fetch this resource was not encrypted.
|
||||
# channel i.e. the connection was not https
|
||||
netmonitor.security.state.insecure=The connection used to fetch this resource was not secure.
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.security.state.broken)
|
||||
# This string is used as an tooltip for request that failed due to security
|
||||
|
@ -80,6 +80,14 @@ class RemoteAutomation(Automation):
|
||||
# Don't override the user's choice here. See bug 1049688.
|
||||
env.setdefault('MOZ_DISABLE_NONLOCAL_CONNECTIONS', '1')
|
||||
|
||||
# Set WebRTC logging in case it is not set yet.
|
||||
# On Android, environment variables cannot contain ',' so the
|
||||
# standard WebRTC setting for NSPR_LOG_MODULES is not available.
|
||||
# env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:5,datachannel:5,jsep:5,MediaPipelineFactory:5')
|
||||
env.setdefault('R_LOG_LEVEL', '6')
|
||||
env.setdefault('R_LOG_DESTINATION', 'stderr')
|
||||
env.setdefault('R_LOG_VERBOSE', '1')
|
||||
|
||||
return env
|
||||
|
||||
def waitForFinish(self, proc, utilityPath, timeout, maxTime, startTime, debuggerInfo, symbolsPath):
|
||||
|
@ -639,6 +639,22 @@ nsContentUtils::InitializeModifierStrings()
|
||||
sModifierSeparator = new nsString(modifierSeparator);
|
||||
}
|
||||
|
||||
// Because of SVG/SMIL we have several atoms mapped to the same
|
||||
// id, but we can rely on ID_TO_EVENT to map id to only one atom.
|
||||
static bool
|
||||
ShouldAddEventToStringEventTable(const EventNameMapping& aMapping)
|
||||
{
|
||||
switch(aMapping.mId) {
|
||||
#define ID_TO_EVENT(name_, id_, type_, struct_) \
|
||||
case id_: return nsGkAtoms::on##name_ == aMapping.mAtom;
|
||||
#include "mozilla/EventNameList.h"
|
||||
#undef ID_TO_EVENT
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
nsContentUtils::InitializeEventTable() {
|
||||
NS_ASSERTION(!sAtomEventTable, "EventTable already initialized!");
|
||||
@ -651,6 +667,7 @@ nsContentUtils::InitializeEventTable() {
|
||||
#define NON_IDL_EVENT EVENT
|
||||
#include "mozilla/EventNameList.h"
|
||||
#undef WINDOW_ONLY_EVENT
|
||||
#undef NON_IDL_EVENT
|
||||
#undef EVENT
|
||||
{ nullptr }
|
||||
};
|
||||
@ -664,8 +681,11 @@ nsContentUtils::InitializeEventTable() {
|
||||
// Subtract one from the length because of the trailing null
|
||||
for (uint32_t i = 0; i < ArrayLength(eventArray) - 1; ++i) {
|
||||
sAtomEventTable->Put(eventArray[i].mAtom, eventArray[i]);
|
||||
sStringEventTable->Put(Substring(nsDependentAtomString(eventArray[i].mAtom), 2),
|
||||
eventArray[i]);
|
||||
if (ShouldAddEventToStringEventTable(eventArray[i])) {
|
||||
sStringEventTable->Put(
|
||||
Substring(nsDependentAtomString(eventArray[i].mAtom), 2),
|
||||
eventArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1636,6 +1636,8 @@ nsIDocument::~nsIDocument()
|
||||
if (mNodeInfoManager) {
|
||||
mNodeInfoManager->DropDocumentReference();
|
||||
}
|
||||
|
||||
UnlinkOriginalDocumentIfStatic();
|
||||
}
|
||||
|
||||
|
||||
@ -2093,13 +2095,14 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
|
||||
}
|
||||
tmp->mFirstChild = nullptr;
|
||||
|
||||
tmp->UnlinkOriginalDocumentIfStatic();
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mXPathEvaluator)
|
||||
tmp->mCachedRootElement = nullptr; // Avoid a dangling pointer
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDisplayDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFirstBaseNodeWithHref)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMImplementation)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mImageMaps)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOriginalDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCachedEncoder)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mUndoManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentTimeline)
|
||||
@ -3925,6 +3928,11 @@ nsIDocument::TakeFrameRequestCallbacks(FrameRequestCallbackList& aCallbacks)
|
||||
bool
|
||||
nsIDocument::ShouldThrottleFrameRequests()
|
||||
{
|
||||
if (mStaticCloneCount > 0) {
|
||||
// Even if we're not visible, a static clone may be, so run at full speed.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mIsShowing) {
|
||||
// We're not showing (probably in a background tab or the bf cache).
|
||||
return true;
|
||||
@ -10280,6 +10288,9 @@ nsIDocument::CreateStaticClone(nsIDocShell* aCloneContainer)
|
||||
} else {
|
||||
clonedDoc->mOriginalDocument = this;
|
||||
}
|
||||
|
||||
clonedDoc->mOriginalDocument->mStaticCloneCount++;
|
||||
|
||||
int32_t sheetsCount = GetNumberOfStyleSheets();
|
||||
for (int32_t i = 0; i < sheetsCount; ++i) {
|
||||
nsRefPtr<CSSStyleSheet> sheet = do_QueryObject(GetStyleSheetAt(i));
|
||||
@ -10317,6 +10328,17 @@ nsIDocument::CreateStaticClone(nsIDocShell* aCloneContainer)
|
||||
return clonedDoc.forget();
|
||||
}
|
||||
|
||||
void
|
||||
nsIDocument::UnlinkOriginalDocumentIfStatic()
|
||||
{
|
||||
if (IsStaticDocument() && mOriginalDocument) {
|
||||
MOZ_ASSERT(mOriginalDocument->mStaticCloneCount > 0);
|
||||
mOriginalDocument->mStaticCloneCount--;
|
||||
mOriginalDocument = nullptr;
|
||||
}
|
||||
MOZ_ASSERT(!mOriginalDocument);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsIDocument::ScheduleFrameRequestCallback(const FrameRequestCallbackHolder& aCallback,
|
||||
int32_t *aHandle)
|
||||
|
@ -1937,6 +1937,12 @@ public:
|
||||
return mOriginalDocument;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this document is a static clone, let the original document know that
|
||||
* we're going away and then release our reference to it.
|
||||
*/
|
||||
void UnlinkOriginalDocumentIfStatic();
|
||||
|
||||
/**
|
||||
* These are called by the parser as it encounters <picture> tags, the end of
|
||||
* said tags, and possible picture <source srcset> sources respectively. These
|
||||
@ -2861,6 +2867,9 @@ protected:
|
||||
*/
|
||||
int32_t mFrameRequestCallbackCounter;
|
||||
|
||||
// Count of live static clones of this document.
|
||||
uint32_t mStaticCloneCount;
|
||||
|
||||
// Array of nodes that have been blocked to prevent user tracking.
|
||||
// They most likely have had their nsIChannel canceled by the URL
|
||||
// classifier. (Safebrowsing)
|
||||
|
@ -22,7 +22,9 @@ class nsICycleCollectorListener;
|
||||
class nsScriptNameSpaceManager;
|
||||
|
||||
namespace JS {
|
||||
class AutoValueVector;
|
||||
template <typename T>
|
||||
class AutoVectorRooter;
|
||||
typedef AutoVectorRooter<Value> AutoValueVector;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -19,18 +19,22 @@
|
||||
return;
|
||||
}
|
||||
|
||||
// Add a little bottom padding to the window so that we don't capture the
|
||||
// rounded corners at the bottom, which our GL drawing code on OS X draws
|
||||
// for regular windows.
|
||||
// (The reftest framework doesn't have this problem because it doesn't use
|
||||
// a regular window with a titlebar, so there are no rounded corners.)
|
||||
const WINDOW_INNER_WIDTH = CANVAS_WIDTH;
|
||||
const WINDOW_INNER_HEIGHT = CANVAS_HEIGHT + 10;
|
||||
|
||||
// Need to open as a toplevel chrome window so that
|
||||
// DRAWWINDOW_USE_WIDGET_LAYERS is honored.
|
||||
sourceWindow = window.open("file_drawWindow_source.html", "",
|
||||
"chrome,width=200,height=100");
|
||||
sourceWindow.addEventListener("load", runTests, false);
|
||||
`chrome,width=${WINDOW_INNER_WIDTH},height=${WINDOW_INNER_HEIGHT}`);
|
||||
SimpleTest.waitForFocus(runTests, sourceWindow);
|
||||
}
|
||||
|
||||
function runTests(event) {
|
||||
if (event.target != sourceWindow.document) {
|
||||
return;
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
var cxInterfaceWrap = SpecialPowers.wrap(CanvasRenderingContext2D);
|
||||
var flags = cxInterfaceWrap.DRAWWINDOW_USE_WIDGET_LAYERS |
|
||||
cxInterfaceWrap.DRAWWINDOW_DRAW_CARET |
|
||||
|
@ -1,6 +1,7 @@
|
||||
const CANVAS_WIDTH = 200;
|
||||
const CANVAS_HEIGHT = 100;
|
||||
|
||||
function runDrawWindowTests(win, drawWindowFlags, transparentBackground) {
|
||||
const CANVAS_WIDTH = 200;
|
||||
const CANVAS_HEIGHT = 100;
|
||||
|
||||
function make_canvas() {
|
||||
var canvas = document.createElement("canvas");
|
||||
|
@ -186,3 +186,5 @@ support-files =
|
||||
bug1096146_embedded.html
|
||||
[test_offsetxy.html]
|
||||
[test_eventhandler_scoping.html]
|
||||
[test_bug1013412.html]
|
||||
skip-if = buildapp == 'b2g' # no wheel events on b2g
|
||||
|
103
dom/events/test/test_bug1013412.html
Normal file
103
dom/events/test/test_bug1013412.html
Normal file
@ -0,0 +1,103 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1013412
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1013412</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<style>
|
||||
#content {
|
||||
height: 800px;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
#scroller {
|
||||
height: 2000px;
|
||||
background: repeating-linear-gradient(#EEE, #EEE 100px, #DDD 100px, #DDD 200px);
|
||||
}
|
||||
|
||||
#scrollbox {
|
||||
margin-top: 200px;
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
border-radius: 250px;
|
||||
box-shadow: inset 0 0 0 60px #555;
|
||||
background: #777;
|
||||
}
|
||||
|
||||
#circle {
|
||||
position: relative;
|
||||
left: 240px;
|
||||
top: 20px;
|
||||
border: 10px solid white;
|
||||
border-radius: 10px;
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
transform-origin: 10px 230px;
|
||||
will-change: transform;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1013412">Mozilla Bug 1013412</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
<p>Scrolling the page should be async, but scrolling over the dark circle should not scroll the page and instead rotate the white ball.</p>
|
||||
<div id="scroller">
|
||||
<div id="scrollbox">
|
||||
<div id="circle"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
/** Test for Bug 1013412 **/
|
||||
|
||||
var rotation = 0;
|
||||
var rotationAdjusted = false;
|
||||
|
||||
var incrementForMode = function (mode) {
|
||||
switch (mode) {
|
||||
case WheelEvent.DOM_DELTA_PIXEL: return 1;
|
||||
case WheelEvent.DOM_DELTA_LINE: return 15;
|
||||
case WheelEvent.DOM_DELTA_PAGE: return 400;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
document.getElementById("scrollbox").addEventListener("wheel", function (e) {
|
||||
rotation += e.deltaY * incrementForMode(e.deltaMode) * 0.2;
|
||||
document.getElementById("circle").style.transform = "rotate(" + rotation + "deg)";
|
||||
rotationAdjusted = true;
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
var iteration = 0;
|
||||
function runTest() {
|
||||
var content = document.getElementById('content');
|
||||
if (iteration < 300) { // enough iterations that we would scroll to the bottom of 'content'
|
||||
iteration++;
|
||||
synthesizeWheel(content, 100, 10,
|
||||
{ deltaMode: WheelEvent.DOM_DELTA_LINE,
|
||||
deltaY: 1.0, lineOrPageDeltaY: 1 });
|
||||
setTimeout(runTest, 0);
|
||||
return;
|
||||
}
|
||||
var scrollbox = document.getElementById('scrollbox');
|
||||
is(content.scrollTop < content.scrollTopMax, true, "We should not have scrolled to the bottom of the scrollframe");
|
||||
is(rotationAdjusted, true, "The rotation should have been adjusted");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(runTest, window);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -9,7 +9,7 @@
|
||||
* A push message received by an `nsIPushNotificationService`, used as the
|
||||
* subject of a `push-notification` observer notification.
|
||||
*/
|
||||
[scriptable, uuid(66a87970-6dc9-46e0-ac61-adb4a13791de)]
|
||||
[scriptable, uuid(56f57607-28b6-44b0-aa56-3d4d3c88be15)]
|
||||
interface nsIPushObserverNotification : nsISupports
|
||||
{
|
||||
/* The URL that receives push messages from an application server. */
|
||||
@ -27,4 +27,14 @@ interface nsIPushObserverNotification : nsISupports
|
||||
* may be discarded.
|
||||
*/
|
||||
attribute string data;
|
||||
|
||||
/**
|
||||
* How many times has a push event occured against this pushEndpoint
|
||||
*/
|
||||
attribute long long pushCount;
|
||||
|
||||
/**
|
||||
* The last time a push occured against this this pushEndpoint
|
||||
*/
|
||||
attribute long long lastPush;
|
||||
};
|
||||
|
@ -806,12 +806,15 @@ ContentChild::InitXPCOM()
|
||||
NS_WARNING("Couldn't register console listener for child process");
|
||||
|
||||
bool isOffline, isLangRTL;
|
||||
bool isConnected;
|
||||
ClipboardCapabilities clipboardCaps;
|
||||
DomainPolicyClone domainPolicy;
|
||||
|
||||
SendGetXPCOMProcessAttributes(&isOffline, &isLangRTL, &mAvailableDictionaries,
|
||||
SendGetXPCOMProcessAttributes(&isOffline, &isConnected,
|
||||
&isLangRTL, &mAvailableDictionaries,
|
||||
&clipboardCaps, &domainPolicy);
|
||||
RecvSetOffline(isOffline);
|
||||
RecvSetConnectivity(isConnected);
|
||||
RecvBidiKeyboardNotify(isLangRTL);
|
||||
|
||||
// Create the CPOW manager as soon as possible.
|
||||
@ -1883,6 +1886,18 @@ ContentChild::RecvSetOffline(const bool& offline)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvSetConnectivity(const bool& connectivity)
|
||||
{
|
||||
nsCOMPtr<nsIIOService> io(do_GetIOService());
|
||||
nsCOMPtr<nsIIOServiceInternal> ioInternal(do_QueryInterface(io));
|
||||
NS_ASSERTION(ioInternal, "IO Service can not be null");
|
||||
|
||||
ioInternal->SetConnectivity(connectivity);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ContentChild::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
|
@ -294,6 +294,7 @@ public:
|
||||
virtual bool DeallocPRemoteSpellcheckEngineChild(PRemoteSpellcheckEngineChild*) override;
|
||||
|
||||
virtual bool RecvSetOffline(const bool& offline) override;
|
||||
virtual bool RecvSetConnectivity(const bool& connectivity) override;
|
||||
|
||||
virtual bool RecvSpeakerManagerNotify() override;
|
||||
|
||||
|
@ -405,6 +405,7 @@ bool ContentParent::sNuwaReady = false;
|
||||
#endif
|
||||
|
||||
#define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
|
||||
#define NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC "ipc:network:set-connectivity"
|
||||
|
||||
class MemoryReportRequestParent : public PMemoryReportRequestParent
|
||||
{
|
||||
@ -643,6 +644,7 @@ static const char* sObserverTopics[] = {
|
||||
"xpcom-shutdown",
|
||||
"profile-before-change",
|
||||
NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC,
|
||||
NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC,
|
||||
"child-memory-reporter-request",
|
||||
"memory-pressure",
|
||||
"child-gc-request",
|
||||
@ -2935,13 +2937,16 @@ ContentParent::RecvAddNewProcess(const uint32_t& aPid,
|
||||
|
||||
// Update offline settings.
|
||||
bool isOffline, isLangRTL;
|
||||
bool isConnected;
|
||||
InfallibleTArray<nsString> unusedDictionaries;
|
||||
ClipboardCapabilities clipboardCaps;
|
||||
DomainPolicyClone domainPolicy;
|
||||
|
||||
RecvGetXPCOMProcessAttributes(&isOffline, &isLangRTL, &unusedDictionaries,
|
||||
RecvGetXPCOMProcessAttributes(&isOffline, &isConnected,
|
||||
&isLangRTL, &unusedDictionaries,
|
||||
&clipboardCaps, &domainPolicy);
|
||||
mozilla::unused << content->SendSetOffline(isOffline);
|
||||
mozilla::unused << content->SendSetConnectivity(isConnected);
|
||||
MOZ_ASSERT(!clipboardCaps.supportsSelectionClipboard() &&
|
||||
!clipboardCaps.supportsFindClipboard(),
|
||||
"Unexpected values");
|
||||
@ -3032,6 +3037,17 @@ ContentParent::Observe(nsISupports* aSubject,
|
||||
}
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC)) {
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (!(IsNuwaReady() && IsNuwaProcess())) {
|
||||
#endif
|
||||
if (!SendSetConnectivity(NS_LITERAL_STRING("true").Equals(aData))) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// listening for alert notifications
|
||||
@ -3282,6 +3298,7 @@ ContentParent::RecvGetProcessAttributes(ContentParentId* aCpId,
|
||||
|
||||
bool
|
||||
ContentParent::RecvGetXPCOMProcessAttributes(bool* aIsOffline,
|
||||
bool* aIsConnected,
|
||||
bool* aIsLangRTL,
|
||||
InfallibleTArray<nsString>* dictionaries,
|
||||
ClipboardCapabilities* clipboardCaps,
|
||||
@ -3292,6 +3309,9 @@ ContentParent::RecvGetXPCOMProcessAttributes(bool* aIsOffline,
|
||||
DebugOnly<nsresult> rv = io->GetOffline(aIsOffline);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed getting offline?");
|
||||
|
||||
rv = io->GetConnectivity(aIsConnected);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed getting connectivity?");
|
||||
|
||||
nsIBidiKeyboard* bidi = nsContentUtils::GetBidiKeyboard();
|
||||
|
||||
*aIsLangRTL = false;
|
||||
|
@ -546,6 +546,7 @@ private:
|
||||
bool* aIsForApp,
|
||||
bool* aIsForBrowser) override;
|
||||
virtual bool RecvGetXPCOMProcessAttributes(bool* aIsOffline,
|
||||
bool* aIsConnected,
|
||||
bool* aIsLangRTL,
|
||||
InfallibleTArray<nsString>* dictionaries,
|
||||
ClipboardCapabilities* clipboardCaps,
|
||||
|
@ -525,6 +525,7 @@ child:
|
||||
RegisterChromeItem(ChromeRegistryItem item);
|
||||
|
||||
async SetOffline(bool offline);
|
||||
async SetConnectivity(bool connectivity);
|
||||
|
||||
async NotifyVisited(URIParams uri);
|
||||
|
||||
@ -669,7 +670,7 @@ parent:
|
||||
sync GetProcessAttributes()
|
||||
returns (ContentParentId cpId, bool isForApp, bool isForBrowser);
|
||||
sync GetXPCOMProcessAttributes()
|
||||
returns (bool isOffline, bool isLangRTL, nsString[] dictionaries,
|
||||
returns (bool isOffline, bool isConnected, bool isLangRTL, nsString[] dictionaries,
|
||||
ClipboardCapabilities clipboardCaps,
|
||||
DomainPolicyClone domainPolicy);
|
||||
|
||||
|
@ -482,10 +482,10 @@ bool
|
||||
Promise::PerformMicroTaskCheckpoint()
|
||||
{
|
||||
CycleCollectedJSRuntime* runtime = CycleCollectedJSRuntime::Get();
|
||||
nsTArray<nsCOMPtr<nsIRunnable>>& microtaskQueue =
|
||||
std::queue<nsCOMPtr<nsIRunnable>>& microtaskQueue =
|
||||
runtime->GetPromiseMicroTaskQueue();
|
||||
|
||||
if (microtaskQueue.IsEmpty()) {
|
||||
if (microtaskQueue.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -495,11 +495,11 @@ Promise::PerformMicroTaskCheckpoint()
|
||||
}
|
||||
|
||||
do {
|
||||
nsCOMPtr<nsIRunnable> runnable = microtaskQueue.ElementAt(0);
|
||||
nsCOMPtr<nsIRunnable> runnable = microtaskQueue.front();
|
||||
MOZ_ASSERT(runnable);
|
||||
|
||||
// This function can re-enter, so we remove the element before calling.
|
||||
microtaskQueue.RemoveElementAt(0);
|
||||
microtaskQueue.pop();
|
||||
nsresult rv = runnable->Run();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
@ -507,7 +507,7 @@ Promise::PerformMicroTaskCheckpoint()
|
||||
if (cx.isSome()) {
|
||||
JS_CheckForInterrupt(cx.ref());
|
||||
}
|
||||
} while (!microtaskQueue.IsEmpty());
|
||||
} while (!microtaskQueue.empty());
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1168,10 +1168,10 @@ Promise::DispatchToMicroTask(nsIRunnable* aRunnable)
|
||||
MOZ_ASSERT(aRunnable);
|
||||
|
||||
CycleCollectedJSRuntime* runtime = CycleCollectedJSRuntime::Get();
|
||||
nsTArray<nsCOMPtr<nsIRunnable>>& microtaskQueue =
|
||||
std::queue<nsCOMPtr<nsIRunnable>>& microtaskQueue =
|
||||
runtime->GetPromiseMicroTaskQueue();
|
||||
|
||||
microtaskQueue.AppendElement(aRunnable);
|
||||
microtaskQueue.push(aRunnable);
|
||||
}
|
||||
|
||||
#if defined(DOM_PROMISE_DEPRECATED_REPORTING)
|
||||
|
@ -262,7 +262,7 @@ Push.prototype = {
|
||||
}.bind(this),
|
||||
|
||||
function() {
|
||||
reject("denied");
|
||||
reject("PermissionDeniedError");
|
||||
}
|
||||
);
|
||||
}.bind(this));
|
||||
@ -286,7 +286,7 @@ Push.prototype = {
|
||||
}.bind(this),
|
||||
|
||||
function() {
|
||||
reject("denied");
|
||||
reject("PermissionDeniedError");
|
||||
}
|
||||
);
|
||||
}.bind(this));
|
||||
|
@ -47,9 +47,9 @@ const prefs = new Preferences("dom.push.");
|
||||
// Set debug first so that all debugging actually works.
|
||||
gDebuggingEnabled = prefs.get("debug");
|
||||
|
||||
const kPUSHDB_DB_NAME = "push";
|
||||
const kPUSHDB_DB_NAME = "pushapi";
|
||||
const kPUSHDB_DB_VERSION = 1; // Change this if the IndexedDB format changes
|
||||
const kPUSHDB_STORE_NAME = "push";
|
||||
const kPUSHDB_STORE_NAME = "pushapi";
|
||||
|
||||
const kUDP_WAKEUP_WS_STATUS_CODE = 4774; // WebSocket Close status code sent
|
||||
// by server to signal that it can
|
||||
@ -1334,6 +1334,8 @@ this.PushService = {
|
||||
aPushRecord.version < aLatestVersion) {
|
||||
debug("Version changed, notifying app and updating DB");
|
||||
aPushRecord.version = aLatestVersion;
|
||||
aPushRecord.pushCount = aPushRecord.pushCount + 1;
|
||||
aPushRecord.lastPush = new Date().getTime();
|
||||
this._notifyApp(aPushRecord);
|
||||
this._updatePushRecord(aPushRecord)
|
||||
.then(
|
||||
@ -1398,6 +1400,9 @@ this.PushService = {
|
||||
notification.pushEndpoint = aPushRecord.pushEndpoint;
|
||||
notification.version = aPushRecord.version;
|
||||
notification.data = "";
|
||||
notification.lastPush = aPushRecord.lastPush;
|
||||
notification.pushCount = aPushRecord.pushCount;
|
||||
|
||||
Services.obs.notifyObservers(
|
||||
notification,
|
||||
"push-notification",
|
||||
@ -1538,6 +1543,8 @@ this.PushService = {
|
||||
pushEndpoint: data.pushEndpoint,
|
||||
pageURL: aPageRecord.pageURL,
|
||||
scope: aPageRecord.scope,
|
||||
pushCount: 0,
|
||||
lastPush: 0,
|
||||
version: null
|
||||
};
|
||||
|
||||
@ -1666,7 +1673,9 @@ this.PushService = {
|
||||
if (pushRecord) {
|
||||
registration = {
|
||||
pushEndpoint: pushRecord.pushEndpoint,
|
||||
version: pushRecord.version
|
||||
version: pushRecord.version,
|
||||
lastPush: pushRecord.lastPush,
|
||||
pushCount: pushRecord.pushCount
|
||||
};
|
||||
}
|
||||
resolve(registration);
|
||||
|
@ -105,5 +105,19 @@ add_task(function* test_notification_incomplete() {
|
||||
let storeRecords = yield promiseDB.getAllChannelIDs();
|
||||
storeRecords.sort(({pushEndpoint: a}, {pushEndpoint: b}) =>
|
||||
compareAscending(a, b));
|
||||
deepEqual(records, storeRecords, 'Should not update malformed records');
|
||||
recordsAreEqual(records, storeRecords);
|
||||
});
|
||||
|
||||
function recordIsEqual(a, b) {
|
||||
strictEqual(a.channelID, b.channelID, 'Wrong channel ID in record');
|
||||
strictEqual(a.pushEndpoint, b.pushEndpoint, 'Wrong push endpoint in record');
|
||||
strictEqual(a.scope, b.scope, 'Wrong scope in record');
|
||||
strictEqual(a.version, b.version, 'Wrong version in record');
|
||||
}
|
||||
|
||||
function recordsAreEqual(a, b) {
|
||||
equal(a.length, b.length, 'Mismatched record count');
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
recordIsEqual(a[i], b[i]);
|
||||
}
|
||||
}
|
||||
|
@ -60,8 +60,10 @@ add_task(function* test_registration_success() {
|
||||
|
||||
let registration = yield PushNotificationService.registration(
|
||||
'https://example.net/a');
|
||||
deepEqual(registration, {
|
||||
pushEndpoint: 'https://example.com/update/same-manifest/1',
|
||||
version: 5
|
||||
}, 'Should include registrations for all pages with this manifest');
|
||||
equal(
|
||||
registration.pushEndpoint,
|
||||
'https://example.com/update/same-manifest/1',
|
||||
'Wrong push endpoint for scope'
|
||||
);
|
||||
equal(registration.version, 5, 'Wrong version for scope');
|
||||
});
|
||||
|
@ -287,6 +287,13 @@ gAnim.addEventListener("beginEvent", handleOnBegin, false);
|
||||
gAnim.addEventListener("repeatEvent", handleOnRepeat, false);
|
||||
gAnim.addEventListener("endEvent", handleOnEnd, false);
|
||||
gCircle.addEventListener("beginEvent", parentHandler, false);
|
||||
|
||||
var expectedEvents =
|
||||
["begin", "beginEvent", "repeat", "repeatEvent", "end", "endEvent", "SVGZoom", "zoom"];
|
||||
|
||||
for (var i = 0; i < expectedEvents.length; ++i) {
|
||||
is((new Event(expectedEvents[i])).type, expectedEvents[i], "Unexpected event type!");
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
</pre>
|
||||
|
@ -923,7 +923,7 @@ var interfaceNamesInGlobalScope =
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"SettingsManager",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "ShadowRoot", pref: "dom.webcomponents.enabled"},
|
||||
"ShadowRoot", // Bogus, but the test harness forces it on. See bug 1159768.
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"SharedWorker",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
@ -1381,7 +1381,6 @@ var interfaceNamesInGlobalScope =
|
||||
// IMPORTANT: Do not change the list above without review from a DOM peer!
|
||||
|
||||
function createInterfaceMap(isXBLScope) {
|
||||
var prefs = SpecialPowers.Services.prefs;
|
||||
var version = SpecialPowers.Cc["@mozilla.org/xre/app-info;1"].getService(SpecialPowers.Ci.nsIXULAppInfo).version;
|
||||
var isNightly = version.endsWith("a1");
|
||||
var isRelease = !version.includes("a");
|
||||
@ -1406,21 +1405,23 @@ function createInterfaceMap(isXBLScope) {
|
||||
for (var entry of interfaces) {
|
||||
if (typeof(entry) === "string") {
|
||||
interfaceMap[entry] = true;
|
||||
} else if ((entry.nightly === !isNightly) ||
|
||||
(entry.xbl === !isXBLScope) ||
|
||||
(entry.desktop === !isDesktop) ||
|
||||
(entry.b2g === !isB2G) ||
|
||||
(entry.windows === !isWindows) ||
|
||||
(entry.mac === !isMac) ||
|
||||
(entry.linux === !isLinux) ||
|
||||
(entry.android === !isAndroid) ||
|
||||
(entry.release === !isRelease) ||
|
||||
(entry.pref && !prefs.getBoolPref(entry.pref)) ||
|
||||
(entry.permission && !hasPermission(entry.permission)) ||
|
||||
entry.disabled) {
|
||||
interfaceMap[entry.name] = false;
|
||||
} else {
|
||||
interfaceMap[entry.name] = true;
|
||||
ok(!("pref" in entry), "Bogus pref annotation for " + entry.name);
|
||||
if ((entry.nightly === !isNightly) ||
|
||||
(entry.xbl === !isXBLScope) ||
|
||||
(entry.desktop === !isDesktop) ||
|
||||
(entry.b2g === !isB2G) ||
|
||||
(entry.windows === !isWindows) ||
|
||||
(entry.mac === !isMac) ||
|
||||
(entry.linux === !isLinux) ||
|
||||
(entry.android === !isAndroid) ||
|
||||
(entry.release === !isRelease) ||
|
||||
(entry.permission && !hasPermission(entry.permission)) ||
|
||||
entry.disabled) {
|
||||
interfaceMap[entry.name] = false;
|
||||
} else {
|
||||
interfaceMap[entry.name] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -581,6 +581,7 @@ public:
|
||||
if (newest && mScriptSpec.Equals(newest->ScriptSpec()) &&
|
||||
mScriptSpec.Equals(mRegistration->mScriptSpec)) {
|
||||
mRegistration->mPendingUninstall = false;
|
||||
swm->StoreRegistration(mPrincipal, mRegistration);
|
||||
Succeed();
|
||||
Done(NS_OK);
|
||||
return;
|
||||
|
@ -31,21 +31,6 @@ function workerTestDone() {
|
||||
client.postMessage({ type: 'finish' });
|
||||
}
|
||||
|
||||
function workerTestGetPrefs(prefs, cb) {
|
||||
addEventListener('message', function workerTestGetPrefsCB(e) {
|
||||
if (e.data.type != 'returnPrefs' ||
|
||||
!workerTestArrayEquals(prefs, e.data.prefs)) {
|
||||
return;
|
||||
}
|
||||
removeEventListener('message', workerTestGetPrefsCB);
|
||||
cb(e.data.result);
|
||||
});
|
||||
client.postMessage({
|
||||
type: 'getPrefs',
|
||||
prefs: prefs
|
||||
});
|
||||
}
|
||||
|
||||
function workerTestGetPermissions(permissions, cb) {
|
||||
addEventListener('message', function workerTestGetPermissionsCB(e) {
|
||||
if (e.data.type != 'returnPermissions' ||
|
||||
|
@ -192,7 +192,7 @@ var interfaceNamesInGlobalScope =
|
||||
];
|
||||
// IMPORTANT: Do not change the list above without review from a DOM peer!
|
||||
|
||||
function createInterfaceMap(prefMap, permissionMap, version, userAgent, isB2G) {
|
||||
function createInterfaceMap(permissionMap, version, userAgent, isB2G) {
|
||||
var isNightly = version.endsWith("a1");
|
||||
var isRelease = !version.includes("a");
|
||||
var isDesktop = !/Mobile|Tablet/.test(userAgent);
|
||||
@ -205,16 +205,18 @@ function createInterfaceMap(prefMap, permissionMap, version, userAgent, isB2G) {
|
||||
for (var entry of interfaces) {
|
||||
if (typeof(entry) === "string") {
|
||||
interfaceMap[entry] = true;
|
||||
} else if ((entry.nightly === !isNightly) ||
|
||||
(entry.desktop === !isDesktop) ||
|
||||
(entry.android === !isAndroid) ||
|
||||
(entry.b2g === !isB2G) ||
|
||||
(entry.release === !isRelease) ||
|
||||
(entry.pref && !prefMap[entry.pref]) ||
|
||||
(entry.permission && !permissionMap[entry.permission])) {
|
||||
interfaceMap[entry.name] = false;
|
||||
} else {
|
||||
interfaceMap[entry.name] = true;
|
||||
ok(!("pref" in entry), "Bogus pref annotation for " + entry.name);
|
||||
if ((entry.nightly === !isNightly) ||
|
||||
(entry.desktop === !isDesktop) ||
|
||||
(entry.android === !isAndroid) ||
|
||||
(entry.b2g === !isB2G) ||
|
||||
(entry.release === !isRelease) ||
|
||||
(entry.permission && !permissionMap[entry.permission])) {
|
||||
interfaceMap[entry.name] = false;
|
||||
} else {
|
||||
interfaceMap[entry.name] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -225,8 +227,8 @@ function createInterfaceMap(prefMap, permissionMap, version, userAgent, isB2G) {
|
||||
return interfaceMap;
|
||||
}
|
||||
|
||||
function runTest(prefMap, permissionMap, version, userAgent, isB2G) {
|
||||
var interfaceMap = createInterfaceMap(prefMap, permissionMap, version, userAgent, isB2G);
|
||||
function runTest(permissionMap, version, userAgent, isB2G) {
|
||||
var interfaceMap = createInterfaceMap(permissionMap, version, userAgent, isB2G);
|
||||
for (var name of Object.getOwnPropertyNames(self)) {
|
||||
// An interface name should start with an upper case character.
|
||||
if (!/^[A-Z]/.test(name)) {
|
||||
@ -249,18 +251,6 @@ function runTest(prefMap, permissionMap, version, userAgent, isB2G) {
|
||||
"The following interface(s) are not enumerated: " + Object.keys(interfaceMap).join(", "));
|
||||
}
|
||||
|
||||
function appendPrefs(prefs, interfaces) {
|
||||
for (var entry of interfaces) {
|
||||
if (entry.pref !== undefined && prefs.indexOf(entry.pref) === -1) {
|
||||
prefs.push(entry.pref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var prefs = [];
|
||||
appendPrefs(prefs, ecmaGlobals);
|
||||
appendPrefs(prefs, interfaceNamesInGlobalScope);
|
||||
|
||||
function appendPermissions(permissions, interfaces) {
|
||||
for (var entry of interfaces) {
|
||||
if (entry.permission !== undefined &&
|
||||
@ -274,14 +264,12 @@ var permissions = [];
|
||||
appendPermissions(permissions, ecmaGlobals);
|
||||
appendPermissions(permissions, interfaceNamesInGlobalScope);
|
||||
|
||||
workerTestGetPrefs(prefs, function(prefMap) {
|
||||
workerTestGetPermissions(permissions, function(permissionMap) {
|
||||
workerTestGetVersion(function(version) {
|
||||
workerTestGetUserAgent(function(userAgent) {
|
||||
workerTestGetIsB2G(function(isB2G) {
|
||||
runTest(prefMap, permissionMap, version, userAgent, isB2G);
|
||||
workerTestDone();
|
||||
});
|
||||
workerTestGetPermissions(permissions, function(permissionMap) {
|
||||
workerTestGetVersion(function(version) {
|
||||
workerTestGetUserAgent(function(userAgent) {
|
||||
workerTestGetIsB2G(function(isB2G) {
|
||||
runTest(permissionMap, version, userAgent, isB2G);
|
||||
workerTestDone();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -180,7 +180,7 @@ var interfaceNamesInGlobalScope =
|
||||
];
|
||||
// IMPORTANT: Do not change the list above without review from a DOM peer!
|
||||
|
||||
function createInterfaceMap(prefMap, permissionMap, version, userAgent, isB2G) {
|
||||
function createInterfaceMap(permissionMap, version, userAgent, isB2G) {
|
||||
var isNightly = version.endsWith("a1");
|
||||
var isRelease = !version.includes("a");
|
||||
var isDesktop = !/Mobile|Tablet/.test(userAgent);
|
||||
@ -193,17 +193,19 @@ function createInterfaceMap(prefMap, permissionMap, version, userAgent, isB2G) {
|
||||
for (var entry of interfaces) {
|
||||
if (typeof(entry) === "string") {
|
||||
interfaceMap[entry] = true;
|
||||
} else if ((entry.nightly === !isNightly) ||
|
||||
(entry.desktop === !isDesktop) ||
|
||||
(entry.android === !isAndroid) ||
|
||||
(entry.b2g === !isB2G) ||
|
||||
(entry.release === !isRelease) ||
|
||||
(entry.pref && !prefMap[entry.pref]) ||
|
||||
(entry.permission && !permissionMap[entry.permission]) ||
|
||||
entry.disabled) {
|
||||
interfaceMap[entry.name] = false;
|
||||
} else {
|
||||
interfaceMap[entry.name] = true;
|
||||
ok(!("pref" in entry), "Bogus pref annotation for " + entry.name);
|
||||
if ((entry.nightly === !isNightly) ||
|
||||
(entry.desktop === !isDesktop) ||
|
||||
(entry.android === !isAndroid) ||
|
||||
(entry.b2g === !isB2G) ||
|
||||
(entry.release === !isRelease) ||
|
||||
(entry.permission && !permissionMap[entry.permission]) ||
|
||||
entry.disabled) {
|
||||
interfaceMap[entry.name] = false;
|
||||
} else {
|
||||
interfaceMap[entry.name] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -214,8 +216,8 @@ function createInterfaceMap(prefMap, permissionMap, version, userAgent, isB2G) {
|
||||
return interfaceMap;
|
||||
}
|
||||
|
||||
function runTest(prefMap, permissionMap, version, userAgent, isB2G) {
|
||||
var interfaceMap = createInterfaceMap(prefMap, permissionMap, version, userAgent, isB2G);
|
||||
function runTest(permissionMap, version, userAgent, isB2G) {
|
||||
var interfaceMap = createInterfaceMap(permissionMap, version, userAgent, isB2G);
|
||||
for (var name of Object.getOwnPropertyNames(self)) {
|
||||
// An interface name should start with an upper case character.
|
||||
if (!/^[A-Z]/.test(name)) {
|
||||
@ -238,18 +240,6 @@ function runTest(prefMap, permissionMap, version, userAgent, isB2G) {
|
||||
"The following interface(s) are not enumerated: " + Object.keys(interfaceMap).join(", "));
|
||||
}
|
||||
|
||||
function appendPrefs(prefs, interfaces) {
|
||||
for (var entry of interfaces) {
|
||||
if (entry.pref !== undefined && prefs.indexOf(entry.pref) === -1) {
|
||||
prefs.push(entry.pref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var prefs = [];
|
||||
appendPrefs(prefs, ecmaGlobals);
|
||||
appendPrefs(prefs, interfaceNamesInGlobalScope);
|
||||
|
||||
function appendPermissions(permissions, interfaces) {
|
||||
for (var entry of interfaces) {
|
||||
if (entry.permission !== undefined &&
|
||||
@ -263,14 +253,12 @@ var permissions = [];
|
||||
appendPermissions(permissions, ecmaGlobals);
|
||||
appendPermissions(permissions, interfaceNamesInGlobalScope);
|
||||
|
||||
workerTestGetPrefs(prefs, function(prefMap) {
|
||||
workerTestGetPermissions(permissions, function(permissionMap) {
|
||||
workerTestGetVersion(function(version) {
|
||||
workerTestGetUserAgent(function(userAgent) {
|
||||
workerTestGetIsB2G(function(isB2G) {
|
||||
runTest(prefMap, permissionMap, version, userAgent, isB2G);
|
||||
workerTestDone();
|
||||
});
|
||||
workerTestGetPermissions(permissions, function(permissionMap) {
|
||||
workerTestGetVersion(function(version) {
|
||||
workerTestGetUserAgent(function(userAgent) {
|
||||
workerTestGetIsB2G(function(isB2G) {
|
||||
runTest(permissionMap, version, userAgent, isB2G);
|
||||
workerTestDone();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -19,7 +19,6 @@
|
||||
// There are also some functions for requesting information that requires
|
||||
// SpecialPowers or other main-thread-only resources:
|
||||
//
|
||||
// workerTestGetPrefs() - request an array of prefs value from the main thread
|
||||
// workerTestGetPermissions() - request an array permissions from the MT
|
||||
// workerTestGetVersion() - request the current version string from the MT
|
||||
// workerTestGetUserAgent() - request the user agent string from the MT
|
||||
@ -37,17 +36,6 @@ function workerTestExec(script) {
|
||||
} else if (event.data.type == 'status') {
|
||||
ok(event.data.status, event.data.msg);
|
||||
|
||||
} else if (event.data.type == 'getPrefs') {
|
||||
var result = {};
|
||||
event.data.prefs.forEach(function(pref) {
|
||||
result[pref] = SpecialPowers.Services.prefs.getBoolPref(pref);
|
||||
});
|
||||
worker.postMessage({
|
||||
type: 'returnPrefs',
|
||||
prefs: event.data.prefs,
|
||||
result: result
|
||||
});
|
||||
|
||||
} else if (event.data.type == 'getPermissions') {
|
||||
var result = {};
|
||||
event.data.permissions.forEach(function(permission) {
|
||||
|
@ -30,21 +30,6 @@ function workerTestDone() {
|
||||
postMessage({ type: 'finish' });
|
||||
}
|
||||
|
||||
function workerTestGetPrefs(prefs, cb) {
|
||||
addEventListener('message', function workerTestGetPrefsCB(e) {
|
||||
if (e.data.type != 'returnPrefs' ||
|
||||
!workerTestArrayEquals(prefs, e.data.prefs)) {
|
||||
return;
|
||||
}
|
||||
removeEventListener('message', workerTestGetPrefsCB);
|
||||
cb(e.data.result);
|
||||
});
|
||||
postMessage({
|
||||
type: 'getPrefs',
|
||||
prefs: prefs
|
||||
});
|
||||
}
|
||||
|
||||
function workerTestGetPermissions(permissions, cb) {
|
||||
addEventListener('message', function workerTestGetPermissionsCB(e) {
|
||||
if (e.data.type != 'returnPermissions' ||
|
||||
|
@ -488,6 +488,8 @@ nsHTMLEditRules::AfterEditInner(EditAction action,
|
||||
|
||||
// also do this for original selection endpoints.
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
NS_ENSURE_STATE(mRangeItem->startNode);
|
||||
NS_ENSURE_STATE(mRangeItem->endNode);
|
||||
nsWSRunObject(mHTMLEditor, mRangeItem->startNode,
|
||||
mRangeItem->startOffset).AdjustWhitespace();
|
||||
// we only need to handle old selection endpoint if it was different from start
|
||||
|
@ -647,8 +647,13 @@ public:
|
||||
: AsyncPanZoomAnimation(TimeDuration::Forever())
|
||||
, mApzc(aApzc)
|
||||
{
|
||||
mApzc.mX.SetVelocity(aVelocity.x);
|
||||
mApzc.mY.SetVelocity(aVelocity.y);
|
||||
mApzc.mX.StartOverscrollAnimation(aVelocity.x);
|
||||
mApzc.mY.StartOverscrollAnimation(aVelocity.y);
|
||||
}
|
||||
~OverscrollAnimation()
|
||||
{
|
||||
mApzc.mX.EndOverscrollAnimation();
|
||||
mApzc.mY.EndOverscrollAnimation();
|
||||
}
|
||||
|
||||
virtual bool DoSample(FrameMetrics& aFrameMetrics,
|
||||
|
@ -140,7 +140,7 @@ bool Axis::AdjustDisplacement(ParentLayerCoord aDisplacement,
|
||||
return false;
|
||||
}
|
||||
|
||||
StopSamplingOverscrollAnimation();
|
||||
ClearOverscrollAnimationState();
|
||||
|
||||
ParentLayerCoord displacement = aDisplacement;
|
||||
|
||||
@ -182,7 +182,7 @@ ParentLayerCoord Axis::ApplyResistance(ParentLayerCoord aRequestedOverscroll) co
|
||||
|
||||
void Axis::OverscrollBy(ParentLayerCoord aOverscroll) {
|
||||
MOZ_ASSERT(CanScroll());
|
||||
StopSamplingOverscrollAnimation();
|
||||
ClearOverscrollAnimationState();
|
||||
aOverscroll = ApplyResistance(aOverscroll);
|
||||
if (aOverscroll > 0) {
|
||||
#ifdef DEBUG
|
||||
@ -224,10 +224,23 @@ ParentLayerCoord Axis::GetOverscroll() const {
|
||||
return result;
|
||||
}
|
||||
|
||||
void Axis::StopSamplingOverscrollAnimation() {
|
||||
ParentLayerCoord overscroll = GetOverscroll();
|
||||
ClearOverscroll();
|
||||
mOverscroll = overscroll;
|
||||
void Axis::StartOverscrollAnimation(float aVelocity) {
|
||||
// Make sure any state from a previous animation has been cleared.
|
||||
MOZ_ASSERT(mFirstOverscrollAnimationSample == 0 &&
|
||||
mLastOverscrollPeak == 0 &&
|
||||
mOverscrollScale == 1);
|
||||
|
||||
SetVelocity(aVelocity);
|
||||
}
|
||||
|
||||
void Axis::EndOverscrollAnimation() {
|
||||
ClearOverscrollAnimationState();
|
||||
}
|
||||
|
||||
void Axis::ClearOverscrollAnimationState() {
|
||||
mFirstOverscrollAnimationSample = 0;
|
||||
mLastOverscrollPeak = 0;
|
||||
mOverscrollScale = 1.0f;
|
||||
}
|
||||
|
||||
void Axis::StepOverscrollAnimation(double aStepDurationMilliseconds) {
|
||||
@ -347,10 +360,8 @@ bool Axis::IsOverscrolled() const {
|
||||
}
|
||||
|
||||
void Axis::ClearOverscroll() {
|
||||
ClearOverscrollAnimationState();
|
||||
mOverscroll = 0;
|
||||
mFirstOverscrollAnimationSample = 0;
|
||||
mLastOverscrollPeak = 0;
|
||||
mOverscrollScale = 1.0f;
|
||||
}
|
||||
|
||||
ParentLayerCoord Axis::PanStart() const {
|
||||
|
@ -105,12 +105,22 @@ public:
|
||||
*/
|
||||
ParentLayerCoord GetOverscroll() const;
|
||||
|
||||
/**
|
||||
* Start an overscroll animation with the given initial velocity.
|
||||
*/
|
||||
void StartOverscrollAnimation(float aVelocity);
|
||||
|
||||
/**
|
||||
* Sample the snap-back animation to relieve overscroll.
|
||||
* |aDelta| is the time since the last sample.
|
||||
*/
|
||||
bool SampleOverscrollAnimation(const TimeDuration& aDelta);
|
||||
|
||||
/**
|
||||
* Stop an overscroll animation.
|
||||
*/
|
||||
void EndOverscrollAnimation();
|
||||
|
||||
/**
|
||||
* Return whether this axis is overscrolled in either direction.
|
||||
*/
|
||||
@ -275,9 +285,8 @@ protected:
|
||||
// actual overscroll amount.
|
||||
ParentLayerCoord ApplyResistance(ParentLayerCoord aOverscroll) const;
|
||||
|
||||
// Helper function to disable overscroll transformations triggered by
|
||||
// SampleOverscrollAnimation().
|
||||
void StopSamplingOverscrollAnimation();
|
||||
// Clear the state associated with an overscroll animation.
|
||||
void ClearOverscrollAnimationState();
|
||||
|
||||
// Helper function for SampleOverscrollAnimation().
|
||||
void StepOverscrollAnimation(double aStepDurationMilliseconds);
|
||||
|
@ -181,6 +181,15 @@ WheelBlockState::WheelBlockState(const nsRefPtr<AsyncPanZoomController>& aTarget
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
WheelBlockState::SetContentResponse(bool aPreventDefault)
|
||||
{
|
||||
if (aPreventDefault) {
|
||||
EndTransaction();
|
||||
}
|
||||
return CancelableBlockState::SetContentResponse(aPreventDefault);
|
||||
}
|
||||
|
||||
bool
|
||||
WheelBlockState::SetConfirmedTargetApzc(const nsRefPtr<AsyncPanZoomController>& aTargetApzc)
|
||||
{
|
||||
|
@ -92,7 +92,7 @@ public:
|
||||
* @return false if this block has already received a response from
|
||||
* web content, true if not.
|
||||
*/
|
||||
bool SetContentResponse(bool aPreventDefault);
|
||||
virtual bool SetContentResponse(bool aPreventDefault);
|
||||
|
||||
/**
|
||||
* Record that content didn't respond in time.
|
||||
@ -161,6 +161,7 @@ public:
|
||||
bool aTargetConfirmed,
|
||||
const ScrollWheelInput& aEvent);
|
||||
|
||||
bool SetContentResponse(bool aPreventDefault) override;
|
||||
bool IsReadyForHandling() const override;
|
||||
bool HasEvents() const override;
|
||||
void DropEvents() override;
|
||||
|
@ -1013,7 +1013,7 @@ CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion,
|
||||
// this is important because resizing our buffers when mimised will fail and
|
||||
// cause a crash when we're restored.
|
||||
NS_ASSERTION(mHwnd, "Couldn't find an HWND when initialising?");
|
||||
if (::IsIconic(mHwnd) || gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) {
|
||||
if (::IsIconic(mHwnd) || mDevice->GetDeviceRemovedReason() != S_OK) {
|
||||
*aRenderBoundsOut = Rect();
|
||||
return;
|
||||
}
|
||||
@ -1086,6 +1086,10 @@ CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion,
|
||||
void
|
||||
CompositorD3D11::EndFrame()
|
||||
{
|
||||
if (!mDefaultRT) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsIntSize oldSize = mSize;
|
||||
EnsureSize();
|
||||
UINT presentInterval = 0;
|
||||
@ -1217,6 +1221,13 @@ CompositorD3D11::UpdateRenderTarget()
|
||||
nsRefPtr<ID3D11Texture2D> backBuf;
|
||||
|
||||
hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)backBuf.StartAssignment());
|
||||
if (hr == DXGI_ERROR_INVALID_CALL) {
|
||||
// This happens on some GPUs/drivers when there's a TDR.
|
||||
if (mDevice->GetDeviceRemovedReason() != S_OK) {
|
||||
gfxCriticalError() << "GetBuffer returned invalid call!";
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (Failed(hr)) {
|
||||
return;
|
||||
}
|
||||
|
@ -257,6 +257,17 @@ protected:
|
||||
apzc->SetFrameMetrics(TestFrameMetrics());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the APZC's scroll range in CSS pixels.
|
||||
*/
|
||||
CSSRect GetScrollRange() const
|
||||
{
|
||||
const FrameMetrics& metrics = apzc->GetFrameMetrics();
|
||||
return CSSRect(
|
||||
metrics.GetScrollableRect().TopLeft(),
|
||||
metrics.GetScrollableRect().Size() - metrics.CalculateCompositedSizeInCssPixels());
|
||||
}
|
||||
|
||||
virtual void TearDown()
|
||||
{
|
||||
apzc->Destroy();
|
||||
@ -277,6 +288,49 @@ protected:
|
||||
apzc->UpdateZoomConstraints(ZoomConstraints(false, false, CSSToParentLayerScale(1.0f), CSSToParentLayerScale(1.0f)));
|
||||
}
|
||||
|
||||
void PanIntoOverscroll(int& aTime);
|
||||
|
||||
/**
|
||||
* Sample animations once, 1 ms later than the last sample.
|
||||
*/
|
||||
void SampleAnimationOnce()
|
||||
{
|
||||
const TimeDuration increment = TimeDuration::FromMilliseconds(1);
|
||||
ParentLayerPoint pointOut;
|
||||
ViewTransform viewTransformOut;
|
||||
testStartTime += increment;
|
||||
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sample animations until we recover from overscroll.
|
||||
* @param aExpectedScrollOffset the expected reported scroll offset
|
||||
* throughout the animation
|
||||
*/
|
||||
void SampleAnimationUntilRecoveredFromOverscroll(const ParentLayerPoint& aExpectedScrollOffset)
|
||||
{
|
||||
const TimeDuration increment = TimeDuration::FromMilliseconds(1);
|
||||
bool recoveredFromOverscroll = false;
|
||||
ParentLayerPoint pointOut;
|
||||
ViewTransform viewTransformOut;
|
||||
while (apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut)) {
|
||||
// The reported scroll offset should be the same throughout.
|
||||
EXPECT_EQ(aExpectedScrollOffset, pointOut);
|
||||
|
||||
// Trigger computation of the overscroll tranform, to make sure
|
||||
// no assetions fire during the calculation.
|
||||
apzc->GetOverscrollTransform();
|
||||
|
||||
if (!apzc->IsOverscrolled()) {
|
||||
recoveredFromOverscroll = true;
|
||||
}
|
||||
|
||||
testStartTime += increment;
|
||||
}
|
||||
EXPECT_TRUE(recoveredFromOverscroll);
|
||||
apzc->AssertStateIsReset();
|
||||
}
|
||||
|
||||
void TestOverscroll();
|
||||
|
||||
AsyncPanZoomController::GestureBehavior mGestureBehavior;
|
||||
@ -1137,36 +1191,23 @@ TEST_F(APZCBasicTester, PanningTransformNotifications) {
|
||||
check.Call("Done");
|
||||
}
|
||||
|
||||
void APZCBasicTester::PanIntoOverscroll(int& aTime)
|
||||
{
|
||||
int touchStart = 500;
|
||||
int touchEnd = 10;
|
||||
Pan(apzc, aTime, touchStart, touchEnd);
|
||||
EXPECT_TRUE(apzc->IsOverscrolled());
|
||||
}
|
||||
|
||||
void APZCBasicTester::TestOverscroll()
|
||||
{
|
||||
// Pan sufficiently to hit overscroll behavior
|
||||
int time = 0;
|
||||
int touchStart = 500;
|
||||
int touchEnd = 10;
|
||||
Pan(apzc, time, touchStart, touchEnd);
|
||||
EXPECT_TRUE(apzc->IsOverscrolled());
|
||||
PanIntoOverscroll(time);
|
||||
|
||||
// Check that we recover from overscroll via an animation.
|
||||
const TimeDuration increment = TimeDuration::FromMilliseconds(1);
|
||||
bool recoveredFromOverscroll = false;
|
||||
ParentLayerPoint pointOut;
|
||||
ViewTransform viewTransformOut;
|
||||
while (apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut)) {
|
||||
// The reported scroll offset should be the same throughout.
|
||||
EXPECT_EQ(ParentLayerPoint(0, 90), pointOut);
|
||||
|
||||
// Trigger computation of the overscroll tranform, to make sure
|
||||
// no assetions fire during the calculation.
|
||||
apzc->GetOverscrollTransform();
|
||||
|
||||
if (!apzc->IsOverscrolled()) {
|
||||
recoveredFromOverscroll = true;
|
||||
}
|
||||
|
||||
testStartTime += increment;
|
||||
}
|
||||
EXPECT_TRUE(recoveredFromOverscroll);
|
||||
apzc->AssertStateIsReset();
|
||||
ParentLayerPoint expectedScrollOffset(0, GetScrollRange().YMost());
|
||||
SampleAnimationUntilRecoveredFromOverscroll(expectedScrollOffset);
|
||||
}
|
||||
|
||||
|
||||
@ -1178,7 +1219,7 @@ TEST_F(APZCBasicTester, OverScrollPanning) {
|
||||
|
||||
// Tests that an overscroll animation doesn't trigger an assertion failure
|
||||
// in the case where a sample has a velocity of zero.
|
||||
TEST_F(APZCBasicTester, OverScroll_Bug1152051) {
|
||||
TEST_F(APZCBasicTester, OverScroll_Bug1152051a) {
|
||||
SCOPED_GFX_PREF(APZOverscrollEnabled, bool, true);
|
||||
|
||||
// Doctor the prefs to make the velocity zero at the end of the first sample.
|
||||
@ -1197,6 +1238,44 @@ TEST_F(APZCBasicTester, OverScroll_Bug1152051) {
|
||||
TestOverscroll();
|
||||
}
|
||||
|
||||
// Tests that ending an overscroll animation doesn't leave around state that
|
||||
// confuses the next overscroll animation.
|
||||
TEST_F(APZCBasicTester, OverScroll_Bug1152051b) {
|
||||
SCOPED_GFX_PREF(APZOverscrollEnabled, bool, true);
|
||||
|
||||
SCOPED_GFX_PREF(APZOverscrollStopDistanceThreshold, float, 0.1f);
|
||||
|
||||
// Pan sufficiently to hit overscroll behavior
|
||||
int time = 0;
|
||||
PanIntoOverscroll(time);
|
||||
|
||||
// Sample animations once, to give the fling animation started on touch-up
|
||||
// a chance to realize it's overscrolled, and schedule a call to
|
||||
// HandleFlingOverscroll().
|
||||
SampleAnimationOnce();
|
||||
|
||||
// Give the call to HandleFlingOverscroll() a chance to occur, creating
|
||||
// an overscroll animation.
|
||||
mcc->RunThroughDelayedTasks();
|
||||
|
||||
// Sample the overscroll animation once, to get it to initialize
|
||||
// the first overscroll sample.
|
||||
SampleAnimationOnce();
|
||||
|
||||
// Do a touch-down to cancel the overscroll animation, and then a touch-up
|
||||
// to schedule a new one since we're still overscrolled. We don't pan because
|
||||
// panning can trigger functions that clear the overscroll animation state
|
||||
// in other ways.
|
||||
TouchDown(apzc, 10, 10, time, nullptr);
|
||||
TouchUp(apzc, 10, 10, time);
|
||||
|
||||
// Sample the second overscroll animation to its end.
|
||||
// If the ending of the first overscroll animation fails to clear state
|
||||
// properly, this will assert.
|
||||
ParentLayerPoint expectedScrollOffset(0, GetScrollRange().YMost());
|
||||
SampleAnimationUntilRecoveredFromOverscroll(expectedScrollOffset);
|
||||
}
|
||||
|
||||
TEST_F(APZCBasicTester, OverScrollAbort) {
|
||||
SCOPED_GFX_PREF(APZOverscrollEnabled, bool, true);
|
||||
|
||||
|
@ -343,7 +343,7 @@ private:
|
||||
DECL_GFX_PREF(Live, "layout.css.scroll-snap.prediction-sensitivity", ScrollSnapPredictionSensitivity, float, 0.750f);
|
||||
DECL_GFX_PREF(Once, "layout.css.touch_action.enabled", TouchActionEnabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "layout.display-list.dump", LayoutDumpDisplayList, bool, false);
|
||||
DECL_GFX_PREF(Live, "layout.event-regions.enabled", LayoutEventRegionsEnabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "layout.event-regions.enabled", LayoutEventRegionsEnabledDoNotUseDirectly, bool, false);
|
||||
DECL_GFX_PREF(Once, "layout.frame_rate", LayoutFrameRate, int32_t, -1);
|
||||
DECL_GFX_PREF(Once, "layout.paint_rects_separately", LayoutPaintRectsSeparately, bool, true);
|
||||
|
||||
|
@ -1725,8 +1725,8 @@ gfxWindowsPlatform::GetDXGIAdapter()
|
||||
|
||||
bool DoesD3D11DeviceWork(ID3D11Device *device)
|
||||
{
|
||||
static bool checked;
|
||||
static bool result;
|
||||
static bool checked = false;
|
||||
static bool result = false;
|
||||
|
||||
if (checked)
|
||||
return result;
|
||||
@ -1764,8 +1764,8 @@ bool DoesD3D11DeviceWork(ID3D11Device *device)
|
||||
// with E_OUTOFMEMORY.
|
||||
bool DoesD3D11TextureSharingWork(ID3D11Device *device)
|
||||
{
|
||||
static bool checked;
|
||||
static bool result;
|
||||
static bool checked = false;
|
||||
static bool result = false;
|
||||
|
||||
if (checked)
|
||||
return result;
|
||||
|
@ -1439,9 +1439,8 @@ imgLoader::PutIntoCache(const ImageCacheKey& aKey, imgCacheEntry* entry)
|
||||
LOG_STATIC_FUNC_WITH_PARAM(GetImgLog(),
|
||||
"imgLoader::PutIntoCache", "uri", aKey.Spec());
|
||||
|
||||
// Check to see if this request already exists in the cache and is being
|
||||
// loaded on a different thread. If so, don't allow this entry to be added to
|
||||
// the cache.
|
||||
// Check to see if this request already exists in the cache. If so, we'll
|
||||
// replace the old version.
|
||||
nsRefPtr<imgCacheEntry> tmpCacheEntry;
|
||||
if (cache.Get(aKey, getter_AddRefs(tmpCacheEntry)) && tmpCacheEntry) {
|
||||
PR_LOG(GetImgLog(), PR_LOG_DEBUG,
|
||||
|
@ -429,7 +429,7 @@ uprv_copyEbcdic(const UDataSwapper *ds,
|
||||
while(count>0) {
|
||||
c=*s++;
|
||||
if(c!=0 && ((c=asciiFromEbcdic[c])==0 || !UCHAR_IS_INVARIANT(c))) {
|
||||
udata_printError(ds, "uprv_copyEbcdic() string[%] contains a variant character in position %d\n",
|
||||
udata_printError(ds, "uprv_copyEbcdic() string[%d] contains a variant character in position %d\n",
|
||||
length, length-count);
|
||||
*pErrorCode=U_INVALID_CHAR_FOUND;
|
||||
return 0;
|
||||
|
@ -1,52 +0,0 @@
|
||||
/* Tests conversion of unrepresented characters that should be transliterated
|
||||
* to spaces (bug 365345), and some others from transliterate.properties while
|
||||
* I'm here
|
||||
*/
|
||||
|
||||
const inSpace = "Hello Space";
|
||||
const inEnSpace = "Hello\u2002EnSpace";
|
||||
const inEmSpace = "Hello\u2003EmSpace";
|
||||
const inEuro = "Hello\u20ACEuro";
|
||||
const inTamil1000 = "Hello\u0BF2Tamil1000";
|
||||
const inMonospace9 = "Hello\ud835\udfffMonospace9";
|
||||
|
||||
const expectedSpace = "Hello Space";
|
||||
const expectedEnSpace = "Hello EnSpace";
|
||||
const expectedEmSpace = "Hello EmSpace";
|
||||
const expectedEuro = "HelloEUREuro";
|
||||
const expectedTamil1000 = "Hello[1000]Tamil1000";
|
||||
const expectedMonospace9 = "Hello9Monospace9";
|
||||
|
||||
const EntityAfterCharsetConv = 512;
|
||||
const transliterate = 8;
|
||||
|
||||
const charset = "ISO-8859-2";
|
||||
|
||||
function run_test() {
|
||||
var SaveAsCharset =
|
||||
Components.Constructor("@mozilla.org/intl/saveascharset;1",
|
||||
"nsISaveAsCharset",
|
||||
"Init");
|
||||
|
||||
var converter = new SaveAsCharset(charset,
|
||||
EntityAfterCharsetConv,
|
||||
transliterate);
|
||||
|
||||
var outSpace = converter.Convert(inSpace);
|
||||
do_check_eq(outSpace, expectedSpace);
|
||||
|
||||
var outEnSpace = converter.Convert(inEnSpace);
|
||||
do_check_eq(outEnSpace, expectedEnSpace);
|
||||
|
||||
var outEmSpace = converter.Convert(inEmSpace);
|
||||
do_check_eq(outEmSpace, expectedEmSpace);
|
||||
|
||||
var outEuro = converter.Convert(inEuro);
|
||||
do_check_eq(outEuro, expectedEuro);
|
||||
|
||||
var outTamil1000 = converter.Convert(inTamil1000);
|
||||
do_check_eq(outTamil1000, expectedTamil1000);
|
||||
|
||||
var outMonospace9 = converter.Convert(inMonospace9);
|
||||
do_check_eq(outMonospace9, expectedMonospace9);
|
||||
}
|
@ -14,7 +14,6 @@ support-files =
|
||||
[test_bug317216.js]
|
||||
[test_bug321379.js]
|
||||
[test_bug340714.js]
|
||||
[test_bug365345.js]
|
||||
[test_bug381412.Big5-HKSCS.js]
|
||||
[test_bug381412.Big5.js]
|
||||
[test_bug381412.euc-kr.js]
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
@ -13,79 +13,56 @@
|
||||
//
|
||||
// implementation methods
|
||||
//
|
||||
nsEntityConverter::nsEntityConverter() :
|
||||
mVersionList(nullptr),
|
||||
mVersionListLength(0)
|
||||
nsEntityConverter::nsEntityConverter() { }
|
||||
|
||||
nsEntityConverter::~nsEntityConverter() { }
|
||||
|
||||
nsIStringBundle*
|
||||
nsEntityConverter:: GetVersionBundleInstance(uint32_t versionNumber)
|
||||
{
|
||||
}
|
||||
|
||||
nsEntityConverter::~nsEntityConverter()
|
||||
{
|
||||
if (mVersionList)
|
||||
delete [] mVersionList;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEntityConverter::LoadVersionPropertyFile()
|
||||
{
|
||||
NS_NAMED_LITERAL_CSTRING(url, "resource://gre/res/entityTables/htmlEntityVersions.properties");
|
||||
|
||||
nsCOMPtr<nsIStringBundleService> bundleService =
|
||||
mozilla::services::GetStringBundleService();
|
||||
if (!bundleService)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIStringBundle> entities;
|
||||
nsresult rv = bundleService->CreateBundle(url.get(), getter_AddRefs(entities));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsresult result;
|
||||
|
||||
nsAutoString key;
|
||||
nsXPIDLString value;
|
||||
rv = entities->GetStringFromName(MOZ_UTF16("length"),
|
||||
getter_Copies(value));
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),"nsEntityConverter: malformed entity table\n");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
mVersionListLength = nsAutoString(value).ToInteger(&result);
|
||||
NS_ASSERTION(32 >= mVersionListLength,"nsEntityConverter: malformed entity table\n");
|
||||
if (32 < mVersionListLength) return NS_ERROR_FAILURE;
|
||||
|
||||
mVersionList = new nsEntityVersionList[mVersionListLength];
|
||||
if (!mVersionList) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
for (uint32_t i = 0; i < mVersionListLength && NS_SUCCEEDED(rv); i++) {
|
||||
key.SetLength(0);
|
||||
key.AppendInt(i+1, 10);
|
||||
rv = entities->GetStringFromName(key.get(), getter_Copies(value));
|
||||
uint32_t len = value.Length();
|
||||
if (kVERSION_STRING_LEN < len) return NS_ERROR_UNEXPECTED;
|
||||
|
||||
memcpy(mVersionList[i].mEntityListName, value.get(), len*sizeof(char16_t));
|
||||
mVersionList[i].mEntityListName[len] = 0;
|
||||
mVersionList[i].mVersion = (1 << i);
|
||||
switch(versionNumber){
|
||||
case nsIEntityConverter::html40Latin1:
|
||||
if (!mHTML40Latin1Bundle) {
|
||||
mHTML40Latin1Bundle = LoadEntityBundle(kHTML40LATIN1);
|
||||
MOZ_ASSERT(mHTML40Latin1Bundle, "LoadEntityBundle failed");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return mHTML40Latin1Bundle;
|
||||
case nsIEntityConverter::html40Symbols:
|
||||
if (!mHTML40SymbolsBundle) {
|
||||
mHTML40SymbolsBundle = LoadEntityBundle(kHTML40SYMBOLS);
|
||||
MOZ_ASSERT(mHTML40SymbolsBundle, "LoadEntityBundle failed");
|
||||
}
|
||||
return mHTML40SymbolsBundle;
|
||||
case nsIEntityConverter::html40Special:
|
||||
if (!mHTML40SpecialBundle) {
|
||||
mHTML40SpecialBundle = LoadEntityBundle(kHTML40SPECIAL);
|
||||
MOZ_ASSERT(mHTML40SpecialBundle, "LoadEntityBundle failed");
|
||||
}
|
||||
return mHTML40SpecialBundle;
|
||||
case nsIEntityConverter::mathml20:
|
||||
if (!mMathML20Bundle) {
|
||||
mMathML20Bundle = LoadEntityBundle(kMATHML20);
|
||||
MOZ_ASSERT(mMathML20Bundle, "LoadEntityBundle failed");
|
||||
}
|
||||
return mMathML20Bundle;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<nsIStringBundle>
|
||||
nsEntityConverter::LoadEntityBundle(uint32_t version)
|
||||
nsEntityConverter:: LoadEntityBundle(const char *fileName)
|
||||
{
|
||||
nsAutoCString url(NS_LITERAL_CSTRING("resource://gre/res/entityTables/"));
|
||||
NS_ENSURE_TRUE(fileName, nullptr);
|
||||
|
||||
nsAutoCString url("resource://gre/res/entityTables/");
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIStringBundleService> bundleService =
|
||||
do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
|
||||
do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
const char16_t *versionName = GetVersionName(version);
|
||||
NS_ENSURE_TRUE(versionName, nullptr);
|
||||
|
||||
// all property file names are ASCII, like "html40Latin1" so this is safe
|
||||
LossyAppendUTF16toASCII(versionName, url);
|
||||
url.AppendLiteral(".properties");
|
||||
url.Append(fileName);
|
||||
|
||||
nsCOMPtr<nsIStringBundle> bundle;
|
||||
rv = bundleService->CreateBundle(url.get(), getter_AddRefs(bundle));
|
||||
@ -94,50 +71,11 @@ nsEntityConverter::LoadEntityBundle(uint32_t version)
|
||||
return bundle.forget();
|
||||
}
|
||||
|
||||
const char16_t*
|
||||
nsEntityConverter:: GetVersionName(uint32_t versionNumber)
|
||||
{
|
||||
for (uint32_t i = 0; i < mVersionListLength; i++) {
|
||||
if (versionNumber == mVersionList[i].mVersion)
|
||||
return mVersionList[i].mEntityListName;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsIStringBundle*
|
||||
nsEntityConverter:: GetVersionBundleInstance(uint32_t versionNumber)
|
||||
{
|
||||
if (!mVersionList) {
|
||||
// load the property file which contains available version names
|
||||
// and generate a list of version/name pair
|
||||
if (NS_FAILED(LoadVersionPropertyFile()))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t i;
|
||||
for (i = 0; i < mVersionListLength; i++) {
|
||||
if (versionNumber == mVersionList[i].mVersion) {
|
||||
if (!mVersionList[i].mEntities)
|
||||
{ // not loaded
|
||||
// load the property file
|
||||
mVersionList[i].mEntities = LoadEntityBundle(versionNumber);
|
||||
NS_ASSERTION(mVersionList[i].mEntities, "LoadEntityBundle failed");
|
||||
}
|
||||
return mVersionList[i].mEntities.get();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// nsISupports methods
|
||||
//
|
||||
NS_IMPL_ISUPPORTS(nsEntityConverter,nsIEntityConverter)
|
||||
|
||||
|
||||
//
|
||||
// nsIEntityConverter
|
||||
//
|
||||
@ -151,18 +89,22 @@ NS_IMETHODIMP
|
||||
nsEntityConverter::ConvertUTF32ToEntity(uint32_t character, uint32_t entityVersion, char **_retval)
|
||||
{
|
||||
NS_ASSERTION(_retval, "null ptr- _retval");
|
||||
if(nullptr == _retval)
|
||||
if (nullptr == _retval) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
*_retval = nullptr;
|
||||
|
||||
for (uint32_t mask = 1, mask2 = 0xFFFFFFFFL; (0!=(entityVersion & mask2)); mask<<=1, mask2<<=1) {
|
||||
if (0 == (entityVersion & mask))
|
||||
if (0 == (entityVersion & mask)) {
|
||||
continue;
|
||||
nsIStringBundle* entities = GetVersionBundleInstance(entityVersion & mask);
|
||||
NS_ASSERTION(entities, "Cannot get the property file");
|
||||
}
|
||||
|
||||
if (!entities)
|
||||
nsIStringBundle* entities = GetVersionBundleInstance(entityVersion & mask);
|
||||
NS_ASSERTION(entities, "Cannot get the entity");
|
||||
|
||||
if (!entities) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsAutoString key(NS_LITERAL_STRING("entity."));
|
||||
key.AppendInt(character,10);
|
||||
@ -171,13 +113,10 @@ nsEntityConverter::ConvertUTF32ToEntity(uint32_t character, uint32_t entityVersi
|
||||
nsresult rv = entities->GetStringFromName(key.get(), getter_Copies(value));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
*_retval = ToNewCString(value);
|
||||
if(nullptr == *_retval)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
else
|
||||
return NS_OK;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -194,13 +133,10 @@ nsEntityConverter::ConvertToEntities(const char16_t *inString, uint32_t entityVe
|
||||
uint32_t len = NS_strlen(inString);
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
nsAutoString key(NS_LITERAL_STRING("entity."));
|
||||
if (NS_IS_HIGH_SURROGATE(inString[i]) &&
|
||||
i + 2 < len &&
|
||||
NS_IS_LOW_SURROGATE(inString[i + 1])) {
|
||||
if (NS_IS_HIGH_SURROGATE(inString[i]) && i + 2 < len && NS_IS_LOW_SURROGATE(inString[i + 1])) {
|
||||
key.AppendInt(SURROGATE_TO_UCS4(inString[i], inString[i+1]), 10);
|
||||
++i;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
key.AppendInt(inString[i],10);
|
||||
}
|
||||
|
||||
@ -208,16 +144,17 @@ nsEntityConverter::ConvertToEntities(const char16_t *inString, uint32_t entityVe
|
||||
const char16_t *entity = nullptr;
|
||||
|
||||
for (uint32_t mask = 1, mask2 = 0xFFFFFFFFL; (0!=(entityVersion & mask2)); mask<<=1, mask2<<=1) {
|
||||
if (0 == (entityVersion & mask))
|
||||
continue;
|
||||
if (0 == (entityVersion & mask)) {
|
||||
continue;
|
||||
}
|
||||
nsIStringBundle* entities = GetVersionBundleInstance(entityVersion & mask);
|
||||
NS_ASSERTION(entities, "Cannot get the property file");
|
||||
|
||||
if (!entities)
|
||||
continue;
|
||||
if (!entities) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsresult rv = entities->GetStringFromName(key.get(),
|
||||
getter_Copies(value));
|
||||
nsresult rv = entities->GetStringFromName(key.get(), getter_Copies(value));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
entity = value.get();
|
||||
break;
|
||||
@ -225,15 +162,12 @@ nsEntityConverter::ConvertToEntities(const char16_t *inString, uint32_t entityVe
|
||||
}
|
||||
if (entity) {
|
||||
outString.Append(entity);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
outString.Append(&inString[i], 1);
|
||||
}
|
||||
}
|
||||
|
||||
*_retval = ToNewUnicode(outString);
|
||||
if (!*_retval)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -10,59 +10,40 @@
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#define kVERSION_STRING_LEN 128
|
||||
|
||||
class nsEntityVersionList
|
||||
{
|
||||
public:
|
||||
nsEntityVersionList() {}
|
||||
|
||||
uint32_t mVersion;
|
||||
char16_t mEntityListName[kVERSION_STRING_LEN+1];
|
||||
nsCOMPtr<nsIStringBundle> mEntities;
|
||||
};
|
||||
|
||||
class nsEntityConverter: public nsIEntityConverter
|
||||
{
|
||||
public:
|
||||
//
|
||||
// implementation methods
|
||||
//
|
||||
nsEntityConverter();
|
||||
|
||||
//
|
||||
// implementation methods
|
||||
//
|
||||
nsEntityConverter();
|
||||
//
|
||||
// nsISupports
|
||||
//
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
//
|
||||
// nsISupports
|
||||
//
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
//
|
||||
// nsIEntityConverter
|
||||
//
|
||||
NS_IMETHOD ConvertUTF32ToEntity(uint32_t character, uint32_t entityVersion, char **_retval) override;
|
||||
NS_IMETHOD ConvertToEntity(char16_t character, uint32_t entityVersion, char **_retval) override;
|
||||
|
||||
NS_IMETHOD ConvertToEntities(const char16_t *inString, uint32_t entityVersion, char16_t **_retval) override;
|
||||
NS_IMETHOD ConvertUTF32ToEntity(uint32_t character, uint32_t entityVersion, char **_retval) override;
|
||||
NS_IMETHOD ConvertToEntity(char16_t character, uint32_t entityVersion, char **_retval) override;
|
||||
NS_IMETHOD ConvertToEntities(const char16_t *inString, uint32_t entityVersion, char16_t **_retval) override;
|
||||
|
||||
protected:
|
||||
// map version number to a string bundle
|
||||
nsIStringBundle* GetVersionBundleInstance(uint32_t versionNumber);
|
||||
|
||||
// load a version property file and generate a version list (number/name pair)
|
||||
NS_IMETHOD LoadVersionPropertyFile();
|
||||
// load a string bundle file
|
||||
already_AddRefed<nsIStringBundle> LoadEntityBundle(const char *fileName);
|
||||
|
||||
// map version number to version string
|
||||
const char16_t* GetVersionName(uint32_t versionNumber);
|
||||
const char* kHTML40LATIN1 = "html40Latin1.properties";
|
||||
const char* kHTML40SYMBOLS = "html40Symbols.properties";
|
||||
const char* kHTML40SPECIAL = "html40Special.properties";
|
||||
const char* kMATHML20 = "mathml20.properties";
|
||||
nsCOMPtr<nsIStringBundle> mHTML40Latin1Bundle;
|
||||
nsCOMPtr<nsIStringBundle> mHTML40SymbolsBundle;
|
||||
nsCOMPtr<nsIStringBundle> mHTML40SpecialBundle;
|
||||
nsCOMPtr<nsIStringBundle> mMathML20Bundle;
|
||||
|
||||
// map version number to a string bundle
|
||||
nsIStringBundle* GetVersionBundleInstance(uint32_t versionNumber);
|
||||
|
||||
// load a string bundle file
|
||||
already_AddRefed<nsIStringBundle> LoadEntityBundle(uint32_t version);
|
||||
|
||||
|
||||
nsEntityVersionList *mVersionList; // array of version number/name pairs
|
||||
uint32_t mVersionListLength; // number of supported versions
|
||||
|
||||
virtual ~nsEntityConverter();
|
||||
virtual ~nsEntityConverter();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -18,7 +18,7 @@ interface nsIEntityConverter : nsISupports
|
||||
const unsigned long html40Latin1 = 1;
|
||||
const unsigned long html40Symbols = 2;
|
||||
const unsigned long html40Special = 4; // excludes ", &, <, >
|
||||
const unsigned long transliterate = 8;
|
||||
const unsigned long transliterate = 8; // Obsolete
|
||||
const unsigned long mathml20 = 16;
|
||||
const unsigned long html32 = html40Latin1;
|
||||
const unsigned long html40 = html40Latin1+html40Symbols+html40Special;
|
||||
|
@ -1,18 +0,0 @@
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
# LOCALIZATION NOTE: FILE
|
||||
# This file associates internal names of entity lists to integers.
|
||||
# Do not translate anything in this file
|
||||
|
||||
# list supported versions number/name pair
|
||||
# length should not be greater than 32
|
||||
length=5
|
||||
1=html40Latin1
|
||||
2=html40Symbols
|
||||
3=html40Special
|
||||
4=transliterate
|
||||
5=mathml20
|
@ -5,12 +5,10 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
RESOURCE_FILES.entityTables = [
|
||||
'htmlEntityVersions.properties',
|
||||
'html40Latin1.properties',
|
||||
'html40Symbols.properties',
|
||||
'html40Special.properties',
|
||||
'mathml20.properties',
|
||||
'transliterate.properties',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
|
||||
|
File diff suppressed because it is too large
Load Diff
2
intl/unicharutil/tests/moz.build
Normal file → Executable file
2
intl/unicharutil/tests/moz.build
Normal file → Executable file
@ -4,8 +4,6 @@
|
||||
# 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/.
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini']
|
||||
|
||||
GeckoSimplePrograms([
|
||||
'NormalizationTest',
|
||||
'UnicharSelfTest',
|
||||
|
@ -1,56 +0,0 @@
|
||||
/* Tests transliteration of new characters in Unicode 5.1, 5.2, and 6.0
|
||||
*/
|
||||
|
||||
const inTeluguFractions = "\u0C78\u0C79\u0C7A\u0C7B\u0C7C\u0C7D\u0C7E";
|
||||
const inMalayalamNumbers = "\u0D70\u0D71\u0D72\u0D73\u0D74\u0D75";
|
||||
|
||||
/* MYANMAR SHAN DIGIT ONE,
|
||||
SUNDANESE DIGIT TWO,
|
||||
LEPCHA DIGIT THREE,
|
||||
OL CHIKI DIGIT FOUR,
|
||||
VAI DIGIT FIVE,
|
||||
SAURASHTRA DIGIT SIX
|
||||
KAYAH LI DIGIT SEVEN
|
||||
CHAM DIGIT EIGHT
|
||||
JAVANESE DIGIT NINE
|
||||
MEETEI MAYEK DIGIT ZERO */
|
||||
const inDigits = "\u1091\u1BB2\u1C43\u1C54\uA625\uA8D6\uA907\uAA58\uA9D9\uABF0";
|
||||
const inRomanNumerals = "\u2185\u2186\u2187\u2188";
|
||||
const inSuperSubscripts = "\u2C7C\u2C7D\u2095\u209C";
|
||||
|
||||
const expectedTeluguFractions = "[0][1][2][3][1][2][3]";
|
||||
const expectedMalayalamNumbers = "[10][100][1000][1/4][1/2][3/4]";
|
||||
const expectedDigits = "1234567890";
|
||||
const expectedRomanNumerals = "[6][50][50000][100000]";
|
||||
const expectedSuperSubscripts = "v(j)^(V)v(h)v(t)";
|
||||
|
||||
const EntityAfterCharsetConv = 512;
|
||||
const transliterate = 8;
|
||||
|
||||
const charset = "ISO-8859-1";
|
||||
|
||||
function run_test() {
|
||||
var SaveAsCharset =
|
||||
Components.Constructor("@mozilla.org/intl/saveascharset;1",
|
||||
"nsISaveAsCharset",
|
||||
"Init");
|
||||
|
||||
var converter = new SaveAsCharset(charset,
|
||||
EntityAfterCharsetConv,
|
||||
transliterate);
|
||||
|
||||
var outTeluguFractions = converter.Convert(inTeluguFractions);
|
||||
do_check_eq(outTeluguFractions, expectedTeluguFractions);
|
||||
|
||||
var outMalayalamNumbers = converter.Convert(inMalayalamNumbers);
|
||||
do_check_eq(outMalayalamNumbers, expectedMalayalamNumbers);
|
||||
|
||||
var outDigits = converter.Convert(inDigits);
|
||||
do_check_eq(outDigits, expectedDigits);
|
||||
|
||||
var outRomanNumerals = converter.Convert(inRomanNumerals);
|
||||
do_check_eq(outRomanNumerals, expectedRomanNumerals);
|
||||
|
||||
var outSuperSubscripts = converter.Convert(inSuperSubscripts);
|
||||
do_check_eq(outSuperSubscripts, expectedSuperSubscripts);
|
||||
}
|
2
intl/unicharutil/tests/unit/xpcshell.ini
Normal file → Executable file
2
intl/unicharutil/tests/unit/xpcshell.ini
Normal file → Executable file
@ -2,5 +2,3 @@
|
||||
head =
|
||||
tail =
|
||||
skip-if = toolkit == 'gonk'
|
||||
|
||||
[test_bug_427350_1.js]
|
||||
|
@ -42,7 +42,9 @@ extern JS_FRIEND_DATA(const js::Class* const) FunctionClassPtr;
|
||||
|
||||
namespace JS {
|
||||
|
||||
class AutoIdVector;
|
||||
template <typename T>
|
||||
class AutoVectorRooter;
|
||||
typedef AutoVectorRooter<jsid> AutoIdVector;
|
||||
|
||||
/*
|
||||
* Per ES6, the [[DefineOwnProperty]] internal method has three different
|
||||
|
@ -28,11 +28,13 @@ class TwoByteCharsZ;
|
||||
class UTF8Chars;
|
||||
class UTF8CharsZ;
|
||||
|
||||
class AutoFunctionVector;
|
||||
class AutoIdVector;
|
||||
class AutoObjectVector;
|
||||
class AutoScriptVector;
|
||||
class AutoValueVector;
|
||||
template <typename T>
|
||||
class AutoVectorRooter;
|
||||
typedef AutoVectorRooter<Value> AutoValueVector;
|
||||
typedef AutoVectorRooter<jsid> AutoIdVector;
|
||||
typedef AutoVectorRooter<JSObject*> AutoObjectVector;
|
||||
typedef AutoVectorRooter<JSFunction*> AutoFunctionVector;
|
||||
typedef AutoVectorRooter<JSScript*> AutoVector;
|
||||
|
||||
class AutoIdArray;
|
||||
|
||||
@ -75,17 +77,17 @@ using JS::TwoByteCharsZ;
|
||||
using JS::UTF8Chars;
|
||||
using JS::UTF8CharsZ;
|
||||
|
||||
using JS::AutoFunctionVector;
|
||||
using JS::AutoIdVector;
|
||||
using JS::AutoObjectVector;
|
||||
using JS::AutoScriptVector;
|
||||
using JS::AutoValueVector;
|
||||
using JS::AutoVectorRooter;
|
||||
typedef AutoVectorRooter<Value> AutoValueVector;
|
||||
typedef AutoVectorRooter<jsid> AutoIdVector;
|
||||
typedef AutoVectorRooter<JSObject*> AutoObjectVector;
|
||||
typedef AutoVectorRooter<JSFunction*> AutoFunctionVector;
|
||||
typedef AutoVectorRooter<JSScript*> AutoScriptVector;
|
||||
|
||||
using JS::AutoIdArray;
|
||||
|
||||
using JS::AutoHashMapRooter;
|
||||
using JS::AutoHashSetRooter;
|
||||
using JS::AutoVectorRooter;
|
||||
using JS::RootedGeneric;
|
||||
|
||||
using JS::CallArgs;
|
||||
|
@ -1060,7 +1060,7 @@ InitClass(JSContext* cx, Handle<GlobalObject*> global, const Class* clasp, JSPro
|
||||
return nullptr;
|
||||
proto->setPrivate(nullptr);
|
||||
|
||||
Rooted<JSFunction*> ctor(cx, global->createConstructor(cx, construct, ClassName(key, cx), 1));
|
||||
Rooted<JSFunction*> ctor(cx, global->createConstructor(cx, construct, ClassName(key, cx), 0));
|
||||
if (!ctor ||
|
||||
!LinkConstructorAndPrototype(cx, ctor, proto) ||
|
||||
!DefinePropertiesAndFunctions(cx, proto, properties, methods) ||
|
||||
|
@ -51,7 +51,7 @@ WeakSetObject::initClass(JSContext* cx, JSObject* obj)
|
||||
return nullptr;
|
||||
proto->setReservedSlot(WEAKSET_MAP_SLOT, UndefinedValue());
|
||||
|
||||
Rooted<JSFunction*> ctor(cx, global->createConstructor(cx, construct, ClassName(JSProto_WeakSet, cx), 1));
|
||||
Rooted<JSFunction*> ctor(cx, global->createConstructor(cx, construct, ClassName(JSProto_WeakSet, cx), 0));
|
||||
if (!ctor ||
|
||||
!LinkConstructorAndPrototype(cx, ctor, proto) ||
|
||||
!DefinePropertiesAndFunctions(cx, proto, properties, methods) ||
|
||||
|
@ -30,12 +30,12 @@ struct IdValuePair
|
||||
{}
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS AutoIdValueVector : public AutoVectorRooter<IdValuePair>
|
||||
class MOZ_STACK_CLASS AutoIdValueVector : public JS::AutoVectorRooterBase<IdValuePair>
|
||||
{
|
||||
public:
|
||||
explicit AutoIdValueVector(ContextFriendFields* cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoVectorRooter<IdValuePair>(cx, IDVALVECTOR)
|
||||
: AutoVectorRooterBase<IdValuePair>(cx, IDVALVECTOR)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
@ -72,7 +72,10 @@ GCRuntime::checkAllocatorState(JSContext* cx, AllocKind kind)
|
||||
|
||||
// For testing out of memory conditions
|
||||
if (js::oom::ShouldFailWithOOM()) {
|
||||
ReportOutOfMemory(cx);
|
||||
// If we are doing a fallible allocation, percolate up the OOM
|
||||
// instead of reporting it.
|
||||
if (allowGC)
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -13,22 +13,10 @@
|
||||
#include "js/Value.h"
|
||||
#include "vm/Symbol.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
struct ReadBarrierFunctor : public VoidDefaultAdaptor<Value> {
|
||||
template <typename T> void operator()(T* t) { T::readBarrier(t); }
|
||||
};
|
||||
|
||||
void
|
||||
ValueReadBarrier(const Value& value)
|
||||
{
|
||||
MOZ_ASSERT(!CurrentThreadIsIonCompiling());
|
||||
DispatchValueTyped(ReadBarrierFunctor(), value);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
bool
|
||||
HeapSlot::preconditionForSet(NativeObject* owner, Kind kind, uint32_t slot)
|
||||
js::HeapSlot::preconditionForSet(NativeObject* owner, Kind kind, uint32_t slot)
|
||||
{
|
||||
return kind == Slot
|
||||
? &owner->getSlotRef(slot) == this
|
||||
@ -36,7 +24,8 @@ HeapSlot::preconditionForSet(NativeObject* owner, Kind kind, uint32_t slot)
|
||||
}
|
||||
|
||||
bool
|
||||
HeapSlot::preconditionForWriteBarrierPost(NativeObject* obj, Kind kind, uint32_t slot, Value target) const
|
||||
js::HeapSlot::preconditionForWriteBarrierPost(NativeObject* obj, Kind kind, uint32_t slot,
|
||||
Value target) const
|
||||
{
|
||||
return kind == Slot
|
||||
? obj->getSlotAddressUnchecked(slot)->get() == target
|
||||
@ -44,29 +33,45 @@ HeapSlot::preconditionForWriteBarrierPost(NativeObject* obj, Kind kind, uint32_t
|
||||
}
|
||||
|
||||
bool
|
||||
RuntimeFromMainThreadIsHeapMajorCollecting(JS::shadow::Zone* shadowZone)
|
||||
js::RuntimeFromMainThreadIsHeapMajorCollecting(JS::shadow::Zone* shadowZone)
|
||||
{
|
||||
return shadowZone->runtimeFromMainThread()->isHeapMajorCollecting();
|
||||
}
|
||||
|
||||
bool
|
||||
CurrentThreadIsIonCompiling()
|
||||
js::CurrentThreadIsIonCompiling()
|
||||
{
|
||||
return TlsPerThreadData.get()->ionCompiling;
|
||||
}
|
||||
|
||||
bool
|
||||
CurrentThreadIsGCSweeping()
|
||||
js::CurrentThreadIsGCSweeping()
|
||||
{
|
||||
return js::TlsPerThreadData.get()->gcSweeping;
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
bool
|
||||
StringIsPermanentAtom(JSString* str)
|
||||
template <typename S>
|
||||
template <typename T>
|
||||
void
|
||||
js::ReadBarrierFunctor<S>::operator()(T* t)
|
||||
{
|
||||
return str->isPermanentAtom();
|
||||
InternalGCMethods<T*>::readBarrier(t);
|
||||
}
|
||||
template void js::ReadBarrierFunctor<JS::Value>::operator()<JS::Symbol>(JS::Symbol*);
|
||||
template void js::ReadBarrierFunctor<JS::Value>::operator()<JSObject>(JSObject*);
|
||||
template void js::ReadBarrierFunctor<JS::Value>::operator()<JSString>(JSString*);
|
||||
|
||||
} // namespace js
|
||||
template <typename S>
|
||||
template <typename T>
|
||||
void
|
||||
js::PreBarrierFunctor<S>::operator()(T* t)
|
||||
{
|
||||
InternalGCMethods<T*>::preBarrier(t);
|
||||
}
|
||||
template void js::PreBarrierFunctor<JS::Value>::operator()<JS::Symbol>(JS::Symbol*);
|
||||
template void js::PreBarrierFunctor<JS::Value>::operator()<JSObject>(JSObject*);
|
||||
template void js::PreBarrierFunctor<JS::Value>::operator()<JSString>(JSString*);
|
||||
template void js::PreBarrierFunctor<jsid>::operator()<JS::Symbol>(JS::Symbol*);
|
||||
template void js::PreBarrierFunctor<jsid>::operator()<JSString>(JSString*);
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "gc/Heap.h"
|
||||
#include "gc/StoreBuffer.h"
|
||||
#include "js/HeapAPI.h"
|
||||
#include "js/Id.h"
|
||||
#include "js/RootingAPI.h"
|
||||
#include "js/Value.h"
|
||||
@ -196,9 +197,6 @@ bool
|
||||
CurrentThreadIsGCSweeping();
|
||||
#endif
|
||||
|
||||
bool
|
||||
StringIsPermanentAtom(JSString* str);
|
||||
|
||||
namespace gc {
|
||||
|
||||
template <typename T> struct MapTypeToTraceKind {};
|
||||
@ -240,55 +238,6 @@ void MarkIdForBarrier(JSTracer* trc, jsid* idp, const char* name);
|
||||
|
||||
} // namespace gc
|
||||
|
||||
// This context is more basal than the GC things being implemented, so C++ does
|
||||
// not know about the inheritance hierarchy yet.
|
||||
static inline const gc::TenuredCell* AsTenuredCell(const JSString* str) {
|
||||
return reinterpret_cast<const gc::TenuredCell*>(str);
|
||||
}
|
||||
static inline const gc::TenuredCell* AsTenuredCell(const JS::Symbol* sym) {
|
||||
return reinterpret_cast<const gc::TenuredCell*>(sym);
|
||||
}
|
||||
|
||||
JS::Zone*
|
||||
ZoneOfObjectFromAnyThread(const JSObject& obj);
|
||||
|
||||
static inline JS::shadow::Zone*
|
||||
ShadowZoneOfObjectFromAnyThread(JSObject* obj)
|
||||
{
|
||||
return JS::shadow::Zone::asShadowZone(ZoneOfObjectFromAnyThread(*obj));
|
||||
}
|
||||
|
||||
static inline JS::shadow::Zone*
|
||||
ShadowZoneOfStringFromAnyThread(JSString* str)
|
||||
{
|
||||
return JS::shadow::Zone::asShadowZone(AsTenuredCell(str)->zoneFromAnyThread());
|
||||
}
|
||||
|
||||
static inline JS::shadow::Zone*
|
||||
ShadowZoneOfSymbolFromAnyThread(JS::Symbol* sym)
|
||||
{
|
||||
return JS::shadow::Zone::asShadowZone(AsTenuredCell(sym)->zoneFromAnyThread());
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE JS::Zone*
|
||||
ZoneOfValueFromAnyThread(const JS::Value& value)
|
||||
{
|
||||
MOZ_ASSERT(value.isMarkable());
|
||||
if (value.isObject())
|
||||
return ZoneOfObjectFromAnyThread(value.toObject());
|
||||
return js::gc::TenuredCell::fromPointer(value.toGCThing())->zoneFromAnyThread();
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE JS::Zone*
|
||||
ZoneOfIdFromAnyThread(const jsid& id)
|
||||
{
|
||||
MOZ_ASSERT(JSID_IS_GCTHING(id));
|
||||
return js::gc::TenuredCell::fromPointer(JSID_TO_GCTHING(id).asCell())->zoneFromAnyThread();
|
||||
}
|
||||
|
||||
void
|
||||
ValueReadBarrier(const Value& value);
|
||||
|
||||
template <typename T>
|
||||
struct InternalGCMethods {};
|
||||
|
||||
@ -306,46 +255,23 @@ struct InternalGCMethods<T*>
|
||||
static void readBarrier(T* v) { T::readBarrier(v); }
|
||||
};
|
||||
|
||||
template <typename S> struct PreBarrierFunctor : VoidDefaultAdaptor<S> {
|
||||
template <typename T> void operator()(T* t);
|
||||
};
|
||||
|
||||
template <typename S> struct ReadBarrierFunctor : public VoidDefaultAdaptor<S> {
|
||||
template <typename T> void operator()(T* t);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct InternalGCMethods<Value>
|
||||
{
|
||||
static JSRuntime* runtimeFromAnyThread(const Value& v) {
|
||||
MOZ_ASSERT(v.isMarkable());
|
||||
return static_cast<js::gc::Cell*>(v.toGCThing())->runtimeFromAnyThread();
|
||||
}
|
||||
static JS::shadow::Runtime* shadowRuntimeFromAnyThread(const Value& v) {
|
||||
return reinterpret_cast<JS::shadow::Runtime*>(runtimeFromAnyThread(v));
|
||||
}
|
||||
static JSRuntime* runtimeFromMainThread(const Value& v) {
|
||||
MOZ_ASSERT(v.isMarkable());
|
||||
return static_cast<js::gc::Cell*>(v.toGCThing())->runtimeFromMainThread();
|
||||
}
|
||||
static JS::shadow::Runtime* shadowRuntimeFromMainThread(const Value& v) {
|
||||
return reinterpret_cast<JS::shadow::Runtime*>(runtimeFromMainThread(v));
|
||||
}
|
||||
|
||||
static bool isMarkable(Value v) { return v.isMarkable(); }
|
||||
|
||||
static void preBarrier(Value v) {
|
||||
MOZ_ASSERT(!CurrentThreadIsIonCompiling());
|
||||
if (v.isString() && StringIsPermanentAtom(v.toString()))
|
||||
return;
|
||||
if (v.isMarkable() && shadowRuntimeFromAnyThread(v)->needsIncrementalBarrier())
|
||||
preBarrierImpl(ZoneOfValueFromAnyThread(v), v);
|
||||
DispatchValueTyped(PreBarrierFunctor<Value>(), v);
|
||||
}
|
||||
|
||||
private:
|
||||
static void preBarrierImpl(Zone* zone, Value v) {
|
||||
JS::shadow::Zone* shadowZone = JS::shadow::Zone::asShadowZone(zone);
|
||||
if (shadowZone->needsIncrementalBarrier()) {
|
||||
MOZ_ASSERT_IF(v.isMarkable(), shadowRuntimeFromMainThread(v)->needsIncrementalBarrier());
|
||||
Value tmp(v);
|
||||
js::gc::MarkValueForBarrier(shadowZone->barrierTracer(), &tmp, "write barrier");
|
||||
MOZ_ASSERT(tmp == v);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
static void postBarrier(Value* vp) {
|
||||
MOZ_ASSERT(!CurrentThreadIsIonCompiling());
|
||||
if (vp->isObject()) {
|
||||
@ -373,7 +299,9 @@ struct InternalGCMethods<Value>
|
||||
shadowRuntime->gcStoreBufferPtr()->removeRelocatableValueFromAnyThread(vp);
|
||||
}
|
||||
|
||||
static void readBarrier(const Value& v) { ValueReadBarrier(v); }
|
||||
static void readBarrier(const Value& v) {
|
||||
DispatchValueTyped(ReadBarrierFunctor<Value>(), v);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
@ -381,32 +309,7 @@ struct InternalGCMethods<jsid>
|
||||
{
|
||||
static bool isMarkable(jsid id) { return JSID_IS_STRING(id) || JSID_IS_SYMBOL(id); }
|
||||
|
||||
static void preBarrier(jsid id) {
|
||||
MOZ_ASSERT(!CurrentThreadIsIonCompiling());
|
||||
if (JSID_IS_STRING(id) && StringIsPermanentAtom(JSID_TO_STRING(id)))
|
||||
return;
|
||||
if (JSID_IS_GCTHING(id) && shadowRuntimeFromAnyThread(id)->needsIncrementalBarrier())
|
||||
preBarrierImpl(ZoneOfIdFromAnyThread(id), id);
|
||||
}
|
||||
|
||||
private:
|
||||
static JSRuntime* runtimeFromAnyThread(jsid id) {
|
||||
MOZ_ASSERT(JSID_IS_GCTHING(id));
|
||||
return JSID_TO_GCTHING(id).asCell()->runtimeFromAnyThread();
|
||||
}
|
||||
static JS::shadow::Runtime* shadowRuntimeFromAnyThread(jsid id) {
|
||||
return reinterpret_cast<JS::shadow::Runtime*>(runtimeFromAnyThread(id));
|
||||
}
|
||||
static void preBarrierImpl(Zone* zone, jsid id) {
|
||||
JS::shadow::Zone* shadowZone = JS::shadow::Zone::asShadowZone(zone);
|
||||
if (shadowZone->needsIncrementalBarrier()) {
|
||||
jsid tmp(id);
|
||||
js::gc::MarkIdForBarrier(shadowZone->barrierTracer(), &tmp, "id write barrier");
|
||||
MOZ_ASSERT(tmp == id);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
static void preBarrier(jsid id) { DispatchIdTyped(PreBarrierFunctor<jsid>(), id); }
|
||||
static void postBarrier(jsid* idp) {}
|
||||
static void postBarrierRelocate(jsid* idp) {}
|
||||
static void postBarrierRemove(jsid* idp) {}
|
||||
|
@ -526,19 +526,6 @@ js::TraceObjectSlots(JSTracer* trc, NativeObject* obj, uint32_t start, uint32_t
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gc::MarkValueForBarrier(JSTracer* trc, Value* valuep, const char* name)
|
||||
{
|
||||
MOZ_ASSERT(!trc->runtime()->isHeapCollecting());
|
||||
TraceManuallyBarrieredEdge(trc, valuep, name);
|
||||
}
|
||||
|
||||
void
|
||||
gc::MarkIdForBarrier(JSTracer* trc, jsid* idp, const char* name)
|
||||
{
|
||||
TraceManuallyBarrieredEdge(trc, idp, name);
|
||||
}
|
||||
|
||||
// A typed functor adaptor for TraceRoot.
|
||||
struct TraceRootFunctor {
|
||||
template <typename T>
|
||||
|
@ -151,13 +151,13 @@ AutoGCRooter::trace(JSTracer* trc)
|
||||
|
||||
case VALVECTOR: {
|
||||
AutoValueVector::VectorImpl& vector = static_cast<AutoValueVector*>(this)->vector;
|
||||
TraceRootRange(trc, vector.length(), vector.begin(), "js::AutoValueVector.vector");
|
||||
TraceRootRange(trc, vector.length(), vector.begin(), "JS::AutoValueVector.vector");
|
||||
return;
|
||||
}
|
||||
|
||||
case IDVECTOR: {
|
||||
AutoIdVector::VectorImpl& vector = static_cast<AutoIdVector*>(this)->vector;
|
||||
TraceRootRange(trc, vector.length(), vector.begin(), "js::AutoIdVector.vector");
|
||||
TraceRootRange(trc, vector.length(), vector.begin(), "JS::AutoIdVector.vector");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -179,13 +179,7 @@ AutoGCRooter::trace(JSTracer* trc)
|
||||
|
||||
case OBJVECTOR: {
|
||||
AutoObjectVector::VectorImpl& vector = static_cast<AutoObjectVector*>(this)->vector;
|
||||
TraceRootRange(trc, vector.length(), vector.begin(), "js::AutoObjectVector.vector");
|
||||
return;
|
||||
}
|
||||
|
||||
case FUNVECTOR: {
|
||||
AutoFunctionVector::VectorImpl& vector = static_cast<AutoFunctionVector*>(this)->vector;
|
||||
TraceRootRange(trc, vector.length(), vector.begin(), "js::AutoFunctionVector.vector");
|
||||
TraceRootRange(trc, vector.length(), vector.begin(), "JS::AutoObjectVector.vector");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -232,12 +232,6 @@ Zone::createJitZone(JSContext* cx)
|
||||
return jitZone_;
|
||||
}
|
||||
|
||||
JS::Zone*
|
||||
js::ZoneOfObjectFromAnyThread(const JSObject& obj)
|
||||
{
|
||||
return obj.zoneFromAnyThread();
|
||||
}
|
||||
|
||||
bool
|
||||
Zone::hasMarkedCompartments()
|
||||
{
|
||||
|
@ -20,10 +20,7 @@ UNIFIED_SOURCES += [
|
||||
'tests/typedef-printers.cpp',
|
||||
]
|
||||
|
||||
# Building against js_static requires that we declare mfbt sybols "exported"
|
||||
# on its behalf.
|
||||
for var in ('EXPORT_JS_API', 'IMPL_MFBT'):
|
||||
DEFINES[var] = True
|
||||
DEFINES['EXPORT_JS_API'] = True
|
||||
|
||||
LOCAL_INCLUDES += ['..']
|
||||
GENERATED_INCLUDES += ['..']
|
||||
|
@ -5,10 +5,10 @@ load(libdir + "asserts.js");
|
||||
var a = ["A", , "B", "C", "D"];
|
||||
var normalArrayElementDesc = Object.getOwnPropertyDescriptor(a, 0);
|
||||
var getterDesc = {
|
||||
configurable: false,
|
||||
enumerable: true,
|
||||
get: function () { return "F"; },
|
||||
set: undefined
|
||||
set: undefined,
|
||||
enumerable: true,
|
||||
configurable: false
|
||||
};
|
||||
Object.defineProperty(a, 1, getterDesc);
|
||||
|
||||
|
@ -9,8 +9,8 @@ function C() {
|
||||
}
|
||||
try { Array.of.call(C, 1); } catch (e) {}
|
||||
assertDeepEq(Object.getOwnPropertyDescriptor(obj, 0), {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
value: "v",
|
||||
writable: false
|
||||
writable: false,
|
||||
enumerable: false,
|
||||
configurable: false
|
||||
});
|
||||
|
@ -9,7 +9,7 @@ assertEq(desc.writable, true);
|
||||
|
||||
assertEq(typeof Map, 'function');
|
||||
assertEq(Object.keys(Map).length, 0);
|
||||
assertEq(Map.length, 1);
|
||||
assertEq(Map.length, 0);
|
||||
assertEq(Map.name, "Map");
|
||||
|
||||
assertEq(Object.getPrototypeOf(Map.prototype), Object.prototype);
|
||||
|
@ -9,7 +9,7 @@ assertEq(desc.writable, true);
|
||||
|
||||
assertEq(typeof Set, 'function');
|
||||
assertEq(Object.keys(Set).length, 0);
|
||||
assertEq(Set.length, 1);
|
||||
assertEq(Set.length, 0);
|
||||
assertEq(Set.name, "Set");
|
||||
|
||||
assertEq(Object.getPrototypeOf(Set.prototype), Object.prototype);
|
||||
|
@ -7,7 +7,7 @@ assertEq(desc.writable, true);
|
||||
|
||||
assertEq(typeof WeakMap, 'function');
|
||||
assertEq(Object.keys(WeakMap).length, 0);
|
||||
assertEq(WeakMap.length, 1);
|
||||
assertEq(WeakMap.length, 0);
|
||||
assertEq(WeakMap.name, "WeakMap");
|
||||
|
||||
assertEq(Object.getPrototypeOf(WeakMap.prototype), Object.prototype);
|
||||
|
@ -7,7 +7,7 @@ assertEq(desc.writable, true);
|
||||
|
||||
assertEq(typeof WeakSet, 'function');
|
||||
assertEq(Object.keys(WeakSet).length, 0);
|
||||
assertEq(WeakSet.length, 1);
|
||||
assertEq(WeakSet.length, 0);
|
||||
assertEq(WeakSet.name, "WeakSet");
|
||||
|
||||
assertEq(Object.getPrototypeOf(WeakSet.prototype), Object.prototype);
|
||||
|
@ -7,8 +7,8 @@ var p = new Proxy({}, {
|
||||
});
|
||||
var desc = Object.getOwnPropertyDescriptor(p, "x");
|
||||
assertDeepEq(desc, {
|
||||
configurable: true,
|
||||
enumerable: false,
|
||||
value: undefined,
|
||||
writable: false
|
||||
writable: false,
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
|
@ -5,8 +5,8 @@ load(libdir + "asserts.js");
|
||||
var p = Proxy.create({ getOwnPropertyDescriptor() { return {}; } });
|
||||
var desc = Object.getOwnPropertyDescriptor(p, "x");
|
||||
assertDeepEq(desc, {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
value: undefined,
|
||||
writable: false
|
||||
writable: false,
|
||||
enumerable: false,
|
||||
configurable: false
|
||||
});
|
||||
|
@ -100,9 +100,6 @@ if CONFIG['ENABLE_ION']:
|
||||
]
|
||||
|
||||
DEFINES['EXPORT_JS_API'] = True
|
||||
# Building against js_static requires that we declare mfbt sybols "exported"
|
||||
# on its behalf.
|
||||
DEFINES['IMPL_MFBT'] = True
|
||||
|
||||
LOCAL_INCLUDES += ['..']
|
||||
GENERATED_INCLUDES += ['..']
|
||||
|
107
js/src/jsapi.h
107
js/src/jsapi.h
@ -94,20 +94,20 @@ class AutoValueArray : public AutoGCRooter
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class AutoVectorRooter : protected AutoGCRooter
|
||||
class AutoVectorRooterBase : protected AutoGCRooter
|
||||
{
|
||||
typedef js::Vector<T, 8> VectorImpl;
|
||||
VectorImpl vector;
|
||||
|
||||
public:
|
||||
explicit AutoVectorRooter(JSContext* cx, ptrdiff_t tag
|
||||
explicit AutoVectorRooterBase(JSContext* cx, ptrdiff_t tag
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoGCRooter(cx, tag), vector(cx)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
explicit AutoVectorRooter(js::ContextFriendFields* cx, ptrdiff_t tag
|
||||
explicit AutoVectorRooterBase(js::ContextFriendFields* cx, ptrdiff_t tag
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoGCRooter(cx, tag), vector(cx)
|
||||
{
|
||||
@ -123,7 +123,7 @@ class AutoVectorRooter : protected AutoGCRooter
|
||||
bool append(const T& v) { return vector.append(v); }
|
||||
bool appendN(const T& v, size_t len) { return vector.appendN(v, len); }
|
||||
bool append(const T* ptr, size_t len) { return vector.append(ptr, len); }
|
||||
bool appendAll(const AutoVectorRooter<T>& other) {
|
||||
bool appendAll(const AutoVectorRooterBase<T>& other) {
|
||||
return vector.appendAll(other.vector);
|
||||
}
|
||||
|
||||
@ -190,6 +190,33 @@ class AutoVectorRooter : protected AutoGCRooter
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class MOZ_STACK_CLASS AutoVectorRooter : public AutoVectorRooterBase<T>
|
||||
{
|
||||
public:
|
||||
explicit AutoVectorRooter(JSContext* cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoVectorRooterBase<T>(cx, this->GetTag(T()))
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
explicit AutoVectorRooter(js::ContextFriendFields* cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoVectorRooterBase<T>(cx, this->GetTag(T()))
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
typedef AutoVectorRooter<Value> AutoValueVector;
|
||||
typedef AutoVectorRooter<jsid> AutoIdVector;
|
||||
typedef AutoVectorRooter<JSObject*> AutoObjectVector;
|
||||
typedef AutoVectorRooter<JSFunction*> AutoFunctionVector;
|
||||
typedef AutoVectorRooter<JSScript*> AutoScriptVector;
|
||||
|
||||
template<class Key, class Value>
|
||||
class AutoHashMapRooter : protected AutoGCRooter
|
||||
{
|
||||
@ -423,78 +450,6 @@ class AutoHashSetRooter : protected AutoGCRooter
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS AutoValueVector : public AutoVectorRooter<Value>
|
||||
{
|
||||
public:
|
||||
explicit AutoValueVector(JSContext* cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoVectorRooter<Value>(cx, VALVECTOR)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
class AutoIdVector : public AutoVectorRooter<jsid>
|
||||
{
|
||||
public:
|
||||
explicit AutoIdVector(JSContext* cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoVectorRooter<jsid>(cx, IDVECTOR)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
class AutoObjectVector : public AutoVectorRooter<JSObject*>
|
||||
{
|
||||
public:
|
||||
explicit AutoObjectVector(JSContext* cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoVectorRooter<JSObject*>(cx, OBJVECTOR)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
class AutoFunctionVector : public AutoVectorRooter<JSFunction*>
|
||||
{
|
||||
public:
|
||||
explicit AutoFunctionVector(JSContext* cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoVectorRooter<JSFunction*>(cx, FUNVECTOR)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
explicit AutoFunctionVector(js::ContextFriendFields* cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoVectorRooter<JSFunction*>(cx, FUNVECTOR)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
class AutoScriptVector : public AutoVectorRooter<JSScript*>
|
||||
{
|
||||
public:
|
||||
explicit AutoScriptVector(JSContext* cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoVectorRooter<JSScript*>(cx, SCRIPTVECTOR)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
/*
|
||||
* Custom rooting behavior for internal and external clients.
|
||||
*/
|
||||
|
@ -659,44 +659,9 @@ CheckForInterrupt(JSContext* cx)
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
class AutoStringVector : public AutoVectorRooter<JSString*>
|
||||
{
|
||||
public:
|
||||
explicit AutoStringVector(JSContext* cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoVectorRooter<JSString*>(cx, STRINGVECTOR)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
class AutoPropertyNameVector : public AutoVectorRooter<PropertyName*>
|
||||
{
|
||||
public:
|
||||
explicit AutoPropertyNameVector(JSContext* cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoVectorRooter<PropertyName*>(cx, STRINGVECTOR)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
class AutoShapeVector : public AutoVectorRooter<Shape*>
|
||||
{
|
||||
public:
|
||||
explicit AutoShapeVector(JSContext* cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoVectorRooter<Shape*>(cx, SHAPEVECTOR)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
typedef JS::AutoVectorRooter<JSString*> AutoStringVector;
|
||||
typedef JS::AutoVectorRooter<PropertyName*> AutoPropertyNameVector;
|
||||
typedef JS::AutoVectorRooter<Shape*> AutoShapeVector;
|
||||
|
||||
class AutoObjectObjectHashMap : public AutoHashMapRooter<JSObject*, JSObject*>
|
||||
{
|
||||
|
@ -101,29 +101,38 @@ JSCompartment::~JSCompartment()
|
||||
}
|
||||
|
||||
bool
|
||||
JSCompartment::init(JSContext* cx)
|
||||
JSCompartment::init(JSContext* maybecx)
|
||||
{
|
||||
/*
|
||||
* maybecx is null when called to create the atoms compartment from
|
||||
* JSRuntime::init().
|
||||
*
|
||||
* As a hack, we clear our timezone cache every time we create a new
|
||||
* compartment. This ensures that the cache is always relatively fresh, but
|
||||
* shouldn't interfere with benchmarks which create tons of date objects
|
||||
* (unless they also create tons of iframes, which seems unlikely).
|
||||
*/
|
||||
if (cx)
|
||||
cx->runtime()->dateTimeInfo.updateTimeZoneAdjustment();
|
||||
if (maybecx)
|
||||
maybecx->runtime()->dateTimeInfo.updateTimeZoneAdjustment();
|
||||
|
||||
if (!crossCompartmentWrappers.init(0))
|
||||
if (!crossCompartmentWrappers.init(0)) {
|
||||
if (maybecx)
|
||||
ReportOutOfMemory(maybecx);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!regExps.init(maybecx))
|
||||
return false;
|
||||
|
||||
if (!regExps.init(cx))
|
||||
return false;
|
||||
|
||||
enumerators = NativeIterator::allocateSentinel(cx);
|
||||
enumerators = NativeIterator::allocateSentinel(maybecx);
|
||||
if (!enumerators)
|
||||
return false;
|
||||
|
||||
if (!savedStacks_.init())
|
||||
if (!savedStacks_.init()) {
|
||||
if (maybecx)
|
||||
ReportOutOfMemory(maybecx);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -377,7 +377,7 @@ struct JSCompartment
|
||||
JSCompartment(JS::Zone* zone, const JS::CompartmentOptions& options);
|
||||
~JSCompartment();
|
||||
|
||||
bool init(JSContext* cx);
|
||||
bool init(JSContext* maybecx);
|
||||
|
||||
/* Mark cross-compartment wrappers. */
|
||||
void markCrossCompartmentWrappers(JSTracer* trc);
|
||||
@ -731,12 +731,12 @@ struct WrapperValue
|
||||
Value value;
|
||||
};
|
||||
|
||||
class AutoWrapperVector : public AutoVectorRooter<WrapperValue>
|
||||
class AutoWrapperVector : public JS::AutoVectorRooterBase<WrapperValue>
|
||||
{
|
||||
public:
|
||||
explicit AutoWrapperVector(JSContext* cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoVectorRooter<WrapperValue>(cx, WRAPVECTOR)
|
||||
: AutoVectorRooterBase<WrapperValue>(cx, WRAPVECTOR)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
@ -574,61 +574,77 @@ date_msecFromDate(double year, double mon, double mday, double hour,
|
||||
return MakeDate(MakeDay(year, mon, mday), MakeTime(hour, min, sec, msec));
|
||||
}
|
||||
|
||||
/* compute the time in msec (unclipped) from the given args */
|
||||
#define MAXARGS 7
|
||||
|
||||
static bool
|
||||
date_msecFromArgs(JSContext* cx, CallArgs args, double* rval)
|
||||
{
|
||||
unsigned loop;
|
||||
double array[MAXARGS];
|
||||
double msec_time;
|
||||
|
||||
for (loop = 0; loop < MAXARGS; loop++) {
|
||||
if (loop < args.length()) {
|
||||
double d;
|
||||
if (!ToNumber(cx, args[loop], &d))
|
||||
return false;
|
||||
/* return NaN if any arg is not finite */
|
||||
if (!IsFinite(d)) {
|
||||
*rval = GenericNaN();
|
||||
return true;
|
||||
}
|
||||
array[loop] = ToInteger(d);
|
||||
} else {
|
||||
if (loop == 2) {
|
||||
array[loop] = 1; /* Default the date argument to 1. */
|
||||
} else {
|
||||
array[loop] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* adjust 2-digit years into the 20th century */
|
||||
if (array[0] >= 0 && array[0] <= 99)
|
||||
array[0] += 1900;
|
||||
|
||||
msec_time = date_msecFromDate(array[0], array[1], array[2],
|
||||
array[3], array[4], array[5], array[6]);
|
||||
*rval = msec_time;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* See ECMA 15.9.4.[3-10];
|
||||
*/
|
||||
/* ES6 20.3.3.4. */
|
||||
static bool
|
||||
date_UTC(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
double msec_time;
|
||||
if (!date_msecFromArgs(cx, args, &msec_time))
|
||||
// Steps 1-2.
|
||||
double y;
|
||||
if (!ToNumber(cx, args.get(0), &y))
|
||||
return false;
|
||||
|
||||
msec_time = TimeClip(msec_time);
|
||||
// Steps 3-4.
|
||||
double m;
|
||||
if (!ToNumber(cx, args.get(1), &m))
|
||||
return false;
|
||||
|
||||
args.rval().setNumber(msec_time);
|
||||
// Steps 5-6.
|
||||
double dt;
|
||||
if (args.length() >= 3) {
|
||||
if (!ToNumber(cx, args[2], &dt))
|
||||
return false;
|
||||
} else {
|
||||
dt = 1;
|
||||
}
|
||||
|
||||
// Steps 7-8.
|
||||
double h;
|
||||
if (args.length() >= 4) {
|
||||
if (!ToNumber(cx, args[3], &h))
|
||||
return false;
|
||||
} else {
|
||||
h = 0;
|
||||
}
|
||||
|
||||
// Steps 9-10.
|
||||
double min;
|
||||
if (args.length() >= 5) {
|
||||
if (!ToNumber(cx, args[4], &min))
|
||||
return false;
|
||||
} else {
|
||||
min = 0;
|
||||
}
|
||||
|
||||
// Steps 11-12.
|
||||
double s;
|
||||
if (args.length() >= 6) {
|
||||
if (!ToNumber(cx, args[5], &s))
|
||||
return false;
|
||||
} else {
|
||||
s = 0;
|
||||
}
|
||||
|
||||
// Steps 13-14.
|
||||
double milli;
|
||||
if (args.length() >= 7) {
|
||||
if (!ToNumber(cx, args[6], &milli))
|
||||
return false;
|
||||
} else {
|
||||
milli = 0;
|
||||
}
|
||||
|
||||
// Step 15.
|
||||
double yr = y;
|
||||
if (!IsNaN(y)) {
|
||||
double yint = ToInteger(y);
|
||||
if (0 <= yint && yint <= 99)
|
||||
yr = 1900 + yint;
|
||||
}
|
||||
|
||||
// Step 16.
|
||||
args.rval().setDouble(TimeClip(MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli))));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2891,7 +2907,7 @@ js::date_valueOf(JSContext* cx, unsigned argc, Value* vp)
|
||||
}
|
||||
|
||||
static const JSFunctionSpec date_static_methods[] = {
|
||||
JS_FN("UTC", date_UTC, MAXARGS,0),
|
||||
JS_FN("UTC", date_UTC, 7,0),
|
||||
JS_FN("parse", date_parse, 1,0),
|
||||
JS_FN("now", date_now, 0,0),
|
||||
JS_FS_END
|
||||
@ -2956,34 +2972,49 @@ static const JSFunctionSpec date_methods[] = {
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
bool
|
||||
js::DateConstructor(JSContext* cx, unsigned argc, Value* vp)
|
||||
static bool
|
||||
NewDateObject(JSContext* cx, const CallArgs& args, double d)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
JSObject* obj = NewDateObjectMsec(cx, d);
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
/* Date called as function. */
|
||||
if (!args.isConstructing())
|
||||
return date_format(cx, NowAsMillis(), FORMATSPEC_FULL, args.rval());
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Date called as constructor. */
|
||||
double d;
|
||||
if (args.length() == 0) {
|
||||
/* ES5 15.9.3.3. */
|
||||
d = NowAsMillis();
|
||||
} else if (args.length() == 1) {
|
||||
/* ES5 15.9.3.2. */
|
||||
static bool
|
||||
ToDateString(JSContext* cx, const CallArgs& args, double d)
|
||||
{
|
||||
return date_format(cx, d, FORMATSPEC_FULL, args.rval());
|
||||
}
|
||||
|
||||
static bool
|
||||
DateNoArguments(JSContext* cx, const CallArgs& args)
|
||||
{
|
||||
MOZ_ASSERT(args.length() == 0);
|
||||
|
||||
double now = NowAsMillis();
|
||||
|
||||
if (args.isConstructing())
|
||||
return NewDateObject(cx, args, now);
|
||||
|
||||
return ToDateString(cx, args, now);
|
||||
}
|
||||
|
||||
static bool
|
||||
DateOneArgument(JSContext* cx, const CallArgs& args)
|
||||
{
|
||||
MOZ_ASSERT(args.length() == 1);
|
||||
|
||||
if (args.isConstructing()) {
|
||||
double d;
|
||||
|
||||
/* Step 1. */
|
||||
if (!ToPrimitive(cx, args[0]))
|
||||
return false;
|
||||
|
||||
if (args[0].isString()) {
|
||||
/* Step 2. */
|
||||
JSString* str = args[0].toString();
|
||||
if (!str)
|
||||
return false;
|
||||
|
||||
JSLinearString* linearStr = str->ensureLinear(cx);
|
||||
JSLinearString* linearStr = args[0].toString()->ensureLinear(cx);
|
||||
if (!linearStr)
|
||||
return false;
|
||||
|
||||
@ -2992,29 +3023,109 @@ js::DateConstructor(JSContext* cx, unsigned argc, Value* vp)
|
||||
else
|
||||
d = TimeClip(d);
|
||||
} else {
|
||||
/* Step 3. */
|
||||
if (!ToNumber(cx, args[0], &d))
|
||||
return false;
|
||||
d = TimeClip(d);
|
||||
}
|
||||
} else {
|
||||
double msec_time;
|
||||
if (!date_msecFromArgs(cx, args, &msec_time))
|
||||
return false;
|
||||
|
||||
if (IsFinite(msec_time)) {
|
||||
msec_time = UTC(msec_time, &cx->runtime()->dateTimeInfo);
|
||||
msec_time = TimeClip(msec_time);
|
||||
}
|
||||
d = msec_time;
|
||||
return NewDateObject(cx, args, d);
|
||||
}
|
||||
|
||||
JSObject* obj = NewDateObjectMsec(cx, d);
|
||||
if (!obj)
|
||||
return false;
|
||||
return ToDateString(cx, args, NowAsMillis());
|
||||
}
|
||||
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
static bool
|
||||
DateMultipleArguments(JSContext* cx, const CallArgs& args)
|
||||
{
|
||||
MOZ_ASSERT(args.length() >= 2);
|
||||
|
||||
// Step 3.
|
||||
if (args.isConstructing()) {
|
||||
// Steps 3a-b.
|
||||
double y;
|
||||
if (!ToNumber(cx, args[0], &y))
|
||||
return false;
|
||||
|
||||
// Steps 3c-d.
|
||||
double m;
|
||||
if (!ToNumber(cx, args[1], &m))
|
||||
return false;
|
||||
|
||||
// Steps 3e-f.
|
||||
double dt;
|
||||
if (args.length() >= 3) {
|
||||
if (!ToNumber(cx, args[2], &dt))
|
||||
return false;
|
||||
} else {
|
||||
dt = 1;
|
||||
}
|
||||
|
||||
// Steps 3g-h.
|
||||
double h;
|
||||
if (args.length() >= 4) {
|
||||
if (!ToNumber(cx, args[3], &h))
|
||||
return false;
|
||||
} else {
|
||||
h = 0;
|
||||
}
|
||||
|
||||
// Steps 3i-j.
|
||||
double min;
|
||||
if (args.length() >= 5) {
|
||||
if (!ToNumber(cx, args[4], &min))
|
||||
return false;
|
||||
} else {
|
||||
min = 0;
|
||||
}
|
||||
|
||||
// Steps 3k-l.
|
||||
double s;
|
||||
if (args.length() >= 6) {
|
||||
if (!ToNumber(cx, args[5], &s))
|
||||
return false;
|
||||
} else {
|
||||
s = 0;
|
||||
}
|
||||
|
||||
// Steps 3m-n.
|
||||
double milli;
|
||||
if (args.length() >= 7) {
|
||||
if (!ToNumber(cx, args[6], &milli))
|
||||
return false;
|
||||
} else {
|
||||
milli = 0;
|
||||
}
|
||||
|
||||
// Step 3o.
|
||||
double yr = y;
|
||||
if (!IsNaN(y)) {
|
||||
double yint = ToInteger(y);
|
||||
if (0 <= yint && yint <= 99)
|
||||
yr = 1900 + yint;
|
||||
}
|
||||
|
||||
// Step 3p.
|
||||
double finalDate = MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli));
|
||||
|
||||
// Steps 3q-t.
|
||||
return NewDateObject(cx, args, TimeClip(UTC(finalDate, &cx->runtime()->dateTimeInfo)));
|
||||
}
|
||||
|
||||
return ToDateString(cx, args, NowAsMillis());
|
||||
}
|
||||
|
||||
bool
|
||||
js::DateConstructor(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
if (args.length() == 0)
|
||||
return DateNoArguments(cx, args);
|
||||
|
||||
if (args.length() == 1)
|
||||
return DateOneArgument(cx, args);
|
||||
|
||||
return DateMultipleArguments(cx, args);
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -3052,7 +3163,7 @@ const Class DateObject::class_ = {
|
||||
nullptr, /* construct */
|
||||
nullptr, /* trace */
|
||||
{
|
||||
GenericCreateConstructor<DateConstructor, MAXARGS, JSFunction::FinalizeKind>,
|
||||
GenericCreateConstructor<DateConstructor, 7, JSFunction::FinalizeKind>,
|
||||
GenericCreatePrototype,
|
||||
date_static_methods,
|
||||
nullptr,
|
||||
|
@ -6456,8 +6456,10 @@ js::NewCompartment(JSContext* cx, Zone* zone, JSPrincipals* principals,
|
||||
|
||||
const JSPrincipals* trusted = rt->trustedPrincipals();
|
||||
bool isSystem = principals && principals == trusted;
|
||||
if (!zone->init(isSystem))
|
||||
if (!zone->init(isSystem)) {
|
||||
ReportOutOfMemory(cx);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ScopedJSDeletePtr<JSCompartment> compartment(cx->new_<JSCompartment>(zone, options));
|
||||
@ -7099,7 +7101,7 @@ JS::IncrementalReferenceBarrier(GCCellPtr thing)
|
||||
if (!thing)
|
||||
return;
|
||||
|
||||
if (thing.isString() && StringIsPermanentAtom(thing.toString()))
|
||||
if (thing.isString() && thing.toString()->isPermanentAtom())
|
||||
return;
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -31,11 +31,15 @@ struct DependentAddPtr
|
||||
{}
|
||||
|
||||
template <class KeyInput, class ValueInput>
|
||||
bool add(const ExclusiveContext* cx, T& table, const KeyInput& key, const ValueInput& value) {
|
||||
bool add(ExclusiveContext* cx, T& table, const KeyInput& key, const ValueInput& value) {
|
||||
bool gcHappened = originalGcNumber != cx->zone()->gcNumber();
|
||||
if (gcHappened)
|
||||
addPtr = table.lookupForAdd(key);
|
||||
return table.relookupOrAdd(addPtr, key, value);
|
||||
if (!table.relookupOrAdd(addPtr, key, value)) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -543,11 +543,14 @@ NativeIterator::allocateIterator(JSContext* cx, uint32_t slength, const AutoIdVe
|
||||
}
|
||||
|
||||
NativeIterator*
|
||||
NativeIterator::allocateSentinel(JSContext* cx)
|
||||
NativeIterator::allocateSentinel(JSContext* maybecx)
|
||||
{
|
||||
NativeIterator* ni = js_pod_malloc<NativeIterator>();
|
||||
if (!ni)
|
||||
if (!ni) {
|
||||
if (maybecx)
|
||||
ReportOutOfMemory(maybecx);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PodZero(ni);
|
||||
|
||||
|
@ -102,7 +102,7 @@ struct NativeIterator
|
||||
prev_ = nullptr;
|
||||
}
|
||||
|
||||
static NativeIterator* allocateSentinel(JSContext* cx);
|
||||
static NativeIterator* allocateSentinel(JSContext* maybecx);
|
||||
static NativeIterator* allocateIterator(JSContext* cx, uint32_t slength,
|
||||
const js::AutoIdVector& props);
|
||||
void init(JSObject* obj, JSObject* iterObj, unsigned flags, uint32_t slength, uint32_t key);
|
||||
|
@ -127,9 +127,11 @@ js::InformalValueTypeName(const Value& v)
|
||||
return "value";
|
||||
}
|
||||
|
||||
// ES6 draft rev37 6.2.4.4 FromPropertyDescriptor
|
||||
bool
|
||||
js::FromPropertyDescriptor(JSContext* cx, Handle<PropertyDescriptor> desc, MutableHandleValue vp)
|
||||
{
|
||||
// Step 1.
|
||||
if (!desc.object()) {
|
||||
vp.setUndefined();
|
||||
return true;
|
||||
@ -142,31 +144,28 @@ bool
|
||||
js::FromPropertyDescriptorToObject(JSContext* cx, Handle<PropertyDescriptor> desc,
|
||||
MutableHandleValue vp)
|
||||
{
|
||||
// Step 2-3.
|
||||
RootedObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
const JSAtomState& names = cx->names();
|
||||
RootedValue v(cx);
|
||||
if (desc.hasConfigurable()) {
|
||||
v.setBoolean(desc.configurable());
|
||||
if (!DefineProperty(cx, obj, names.configurable, v))
|
||||
return false;
|
||||
}
|
||||
if (desc.hasEnumerable()) {
|
||||
v.setBoolean(desc.enumerable());
|
||||
if (!DefineProperty(cx, obj, names.enumerable, v))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 4.
|
||||
if (desc.hasValue()) {
|
||||
if (!DefineProperty(cx, obj, names.value, desc.value()))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 5.
|
||||
RootedValue v(cx);
|
||||
if (desc.hasWritable()) {
|
||||
v.setBoolean(desc.writable());
|
||||
if (!DefineProperty(cx, obj, names.writable, v))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 6.
|
||||
if (desc.hasGetterObject()) {
|
||||
if (JSObject* get = desc.getterObject())
|
||||
v.setObject(*get);
|
||||
@ -175,6 +174,8 @@ js::FromPropertyDescriptorToObject(JSContext* cx, Handle<PropertyDescriptor> des
|
||||
if (!DefineProperty(cx, obj, names.get, v))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 7.
|
||||
if (desc.hasSetterObject()) {
|
||||
if (JSObject* set = desc.setterObject())
|
||||
v.setObject(*set);
|
||||
@ -183,6 +184,21 @@ js::FromPropertyDescriptorToObject(JSContext* cx, Handle<PropertyDescriptor> des
|
||||
if (!DefineProperty(cx, obj, names.set, v))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 8.
|
||||
if (desc.hasEnumerable()) {
|
||||
v.setBoolean(desc.enumerable());
|
||||
if (!DefineProperty(cx, obj, names.enumerable, v))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 9.
|
||||
if (desc.hasConfigurable()) {
|
||||
v.setBoolean(desc.configurable());
|
||||
if (!DefineProperty(cx, obj, names.configurable, v))
|
||||
return false;
|
||||
}
|
||||
|
||||
vp.setObject(*obj);
|
||||
return true;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ struct ClassInfo;
|
||||
|
||||
namespace js {
|
||||
|
||||
class AutoPropertyDescriptorVector;
|
||||
typedef AutoVectorRooter<PropertyDescriptor> AutoPropertyDescriptorVector;
|
||||
class GCMarker;
|
||||
class Nursery;
|
||||
|
||||
|
@ -571,18 +571,7 @@ IsInternalFunctionObject(JSObject* funobj)
|
||||
return fun->isLambda() && fun->isInterpreted() && !fun->environment();
|
||||
}
|
||||
|
||||
class AutoPropertyDescriptorVector : public AutoVectorRooter<PropertyDescriptor>
|
||||
{
|
||||
public:
|
||||
explicit AutoPropertyDescriptorVector(JSContext* cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoVectorRooter(cx, DESCVECTOR)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
typedef AutoVectorRooter<PropertyDescriptor> AutoPropertyDescriptorVector;
|
||||
|
||||
/*
|
||||
* Make an object with the specified prototype. If parent is null, it will
|
||||
|
@ -26,7 +26,9 @@
|
||||
|
||||
namespace JS {
|
||||
|
||||
class AutoIdVector;
|
||||
template <typename T>
|
||||
class AutoVectorRooter;
|
||||
typedef AutoVectorRooter<jsid> AutoIdVector;
|
||||
class CallArgs;
|
||||
|
||||
template <typename T>
|
||||
@ -37,12 +39,14 @@ class JS_FRIEND_API(ReadOnlyCompileOptions);
|
||||
class JS_FRIEND_API(OwningCompileOptions);
|
||||
class JS_PUBLIC_API(CompartmentOptions);
|
||||
|
||||
class Value;
|
||||
struct Zone;
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
namespace js {
|
||||
struct ContextFriendFields;
|
||||
class Shape;
|
||||
} // namespace js
|
||||
|
||||
/*
|
||||
@ -265,10 +269,17 @@ class JS_PUBLIC_API(AutoGCRooter)
|
||||
OBJU32HASHMAP=-23, /* js::AutoObjectUnsigned32HashMap */
|
||||
OBJHASHSET = -24, /* js::AutoObjectHashSet */
|
||||
JSONPARSER = -25, /* js::JSONParser */
|
||||
CUSTOM = -26, /* js::CustomAutoRooter */
|
||||
FUNVECTOR = -27 /* js::AutoFunctionVector */
|
||||
CUSTOM = -26 /* js::CustomAutoRooter */
|
||||
};
|
||||
|
||||
static ptrdiff_t GetTag(const Value& value) { return VALVECTOR; }
|
||||
static ptrdiff_t GetTag(const jsid& id) { return IDVECTOR; }
|
||||
static ptrdiff_t GetTag(JSObject* obj) { return OBJVECTOR; }
|
||||
static ptrdiff_t GetTag(JSScript* script) { return SCRIPTVECTOR; }
|
||||
static ptrdiff_t GetTag(JSString* string) { return STRINGVECTOR; }
|
||||
static ptrdiff_t GetTag(js::Shape* shape) { return SHAPEVECTOR; }
|
||||
static ptrdiff_t GetTag(const JSPropertyDescriptor& pd) { return DESCVECTOR; }
|
||||
|
||||
private:
|
||||
AutoGCRooter ** const stackTop;
|
||||
|
||||
|
@ -1592,8 +1592,10 @@ ScriptSource::chars(JSContext* cx, UncompressedSourceCache::AutoHoldEntry& holde
|
||||
|
||||
const size_t nbytes = sizeof(char16_t) * (length_ + 1);
|
||||
char16_t* decompressed = static_cast<char16_t*>(js_malloc(nbytes));
|
||||
if (!decompressed)
|
||||
if (!decompressed) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!DecompressString((const unsigned char*) compressedData(), compressedBytes(),
|
||||
reinterpret_cast<unsigned char*>(decompressed), nbytes)) {
|
||||
|
@ -646,7 +646,7 @@ InitWeakMapClass(JSContext* cx, HandleObject obj, bool defineMembers)
|
||||
return nullptr;
|
||||
|
||||
RootedFunction ctor(cx, global->createConstructor(cx, WeakMap_construct,
|
||||
cx->names().WeakMap, 1));
|
||||
cx->names().WeakMap, 0));
|
||||
if (!ctor)
|
||||
return nullptr;
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user