mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 04:15:43 +00:00
Merge inbound to m-c a=merge
This commit is contained in:
commit
64dfc0694b
@ -225,7 +225,6 @@ skip-if = e10s
|
||||
[browser_bug565667.js]
|
||||
skip-if = toolkit != "cocoa"
|
||||
[browser_bug567306.js]
|
||||
skip-if = e10s # Bug XXX - Needs some massaging to run in e10s
|
||||
[browser_bug575561.js]
|
||||
[browser_bug575830.js]
|
||||
skip-if = e10s # Bug 1056146 - zoom tests use FullZoomHelper and break in e10s
|
||||
@ -462,7 +461,6 @@ skip-if = e10s # Bug 1093941 - ESC reverted the location bar value - Got foobar,
|
||||
[browser_urlbar_search_healthreport.js]
|
||||
[browser_utilityOverlay.js]
|
||||
[browser_visibleFindSelection.js]
|
||||
skip-if = e10s # Bug 921935 - focusmanager issues with e10s (test calls waitForFocus)
|
||||
[browser_visibleLabel.js]
|
||||
[browser_visibleTabs.js]
|
||||
[browser_visibleTabs_bookmarkAllPages.js]
|
||||
|
@ -7,48 +7,44 @@ const {Ci: interfaces, Cc: classes} = Components;
|
||||
let Clipboard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
|
||||
let HasFindClipboard = Clipboard.supportsFindClipboard();
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
add_task(function* () {
|
||||
let newwindow = yield BrowserTestUtils.openNewBrowserWindow();
|
||||
|
||||
whenNewWindowLoaded(undefined, function (win) {
|
||||
whenDelayedStartupFinished(win, function () {
|
||||
let selectedBrowser = win.gBrowser.selectedBrowser;
|
||||
selectedBrowser.addEventListener("pageshow", function pageshowListener() {
|
||||
selectedBrowser.removeEventListener("pageshow", pageshowListener, true);
|
||||
ok(true, "pageshow listener called: " + win.content.location);
|
||||
waitForFocus(function () {
|
||||
onFocus(win);
|
||||
}, selectedBrowser.contentWindow);
|
||||
}, true);
|
||||
selectedBrowser.loadURI("data:text/html,<h1 id='h1'>Select Me</h1>");
|
||||
});
|
||||
let selectedBrowser = newwindow.gBrowser.selectedBrowser;
|
||||
yield new Promise((resolve, reject) => {
|
||||
selectedBrowser.addEventListener("pageshow", function pageshowListener() {
|
||||
if (selectedBrowser.currentURI.spec == "about:blank")
|
||||
return;
|
||||
|
||||
selectedBrowser.removeEventListener("pageshow", pageshowListener, true);
|
||||
ok(true, "pageshow listener called: " + newwindow.content.location);
|
||||
resolve();
|
||||
}, true);
|
||||
selectedBrowser.loadURI("data:text/html,<h1 id='h1'>Select Me</h1>");
|
||||
});
|
||||
}
|
||||
|
||||
function selectText(win) {
|
||||
let elt = win.document.getElementById("h1");
|
||||
let selection = win.getSelection();
|
||||
let range = win.document.createRange();
|
||||
range.setStart(elt, 0);
|
||||
range.setEnd(elt, 1);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
}
|
||||
yield SimpleTest.promiseFocus(newwindow);
|
||||
|
||||
function onFocus(win) {
|
||||
ok(!win.gFindBarInitialized, "find bar is not yet initialized");
|
||||
let findBar = win.gFindBar;
|
||||
selectText(win.content);
|
||||
ok(!newwindow.gFindBarInitialized, "find bar is not yet initialized");
|
||||
let findBar = newwindow.gFindBar;
|
||||
|
||||
findBar.onFindCommand().then(onInitialized.bind(null, findBar, win));
|
||||
}
|
||||
yield ContentTask.spawn(selectedBrowser, { }, function* () {
|
||||
let elt = content.document.getElementById("h1");
|
||||
let selection = content.getSelection();
|
||||
let range = content.document.createRange();
|
||||
range.setStart(elt, 0);
|
||||
range.setEnd(elt, 1);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
});
|
||||
|
||||
yield findBar.onFindCommand();
|
||||
|
||||
function onInitialized(findBar, win) {
|
||||
// When the OS supports the Find Clipboard (OSX), the find field value is
|
||||
// persisted across Fx sessions, thus not useful to test.
|
||||
if (!HasFindClipboard)
|
||||
is(findBar._findField.value, "Select Me", "Findbar is initialized with selection");
|
||||
findBar.close();
|
||||
win.close();
|
||||
finish();
|
||||
}
|
||||
yield promiseWindowClosed(newwindow);
|
||||
});
|
||||
|
||||
|
@ -1,33 +1,36 @@
|
||||
add_task(function*() {
|
||||
const childContent = "<div style='position: absolute; left: 2200px; background: green; width: 200px; height: 200px;'>" +
|
||||
"div</div><div style='position: absolute; left: 0px; background: red; width: 200px; height: 200px;'>" +
|
||||
"<span id='s'>div</span></div>";
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab();
|
||||
|
||||
let tab = gBrowser.addTab();
|
||||
gBrowser.selectedTab = tab;
|
||||
tab.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
yield promiseTabLoadEvent(tab, "data:text/html," + escape(childContent));
|
||||
yield SimpleTest.promiseFocus(gBrowser.selectedBrowser.contentWindowAsCPOW);
|
||||
|
||||
ok(true, "Load listener called");
|
||||
waitForFocus(onFocus, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,<div style='position: absolute; left: 2200px; background: green; width: 200px; height: 200px;'>div</div><div style='position: absolute; left: 0px; background: red; width: 200px; height: 200px;'><span id='s'>div</span></div>";
|
||||
}
|
||||
|
||||
function onFocus() {
|
||||
let findBarOpenPromise = promiseWaitForEvent(gBrowser, "findbaropen");
|
||||
EventUtils.synthesizeKey("f", { accelKey: true });
|
||||
yield findBarOpenPromise;
|
||||
|
||||
ok(gFindBarInitialized, "find bar is now initialized");
|
||||
|
||||
// Finds the div in the green box.
|
||||
let scrollPromise = promiseWaitForEvent(gBrowser, "scroll");
|
||||
EventUtils.synthesizeKey("d", {});
|
||||
EventUtils.synthesizeKey("i", {});
|
||||
EventUtils.synthesizeKey("v", {});
|
||||
// finds the div in the green box
|
||||
yield scrollPromise;
|
||||
|
||||
// Finds the div in the red box.
|
||||
scrollPromise = promiseWaitForEvent(gBrowser, "scroll");
|
||||
EventUtils.synthesizeKey("g", { accelKey: true });
|
||||
// finds the div in the red box
|
||||
yield scrollPromise;
|
||||
|
||||
var rect = content.document.getElementById("s").getBoundingClientRect();
|
||||
ok(rect.left >= 0, "scroll should include find result");
|
||||
let scrollLeftPos = yield ContentTask.spawn(gBrowser.selectedBrowser, { }, function* (arg) {
|
||||
return content.document.getElementById("s").getBoundingClientRect().left;
|
||||
});
|
||||
|
||||
ok(scrollLeftPos >= 0, "scroll should include find result");
|
||||
|
||||
// clear the find bar
|
||||
EventUtils.synthesizeKey("a", { accelKey: true });
|
||||
@ -35,5 +38,5 @@ function onFocus() {
|
||||
|
||||
gFindBar.close();
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -122,13 +122,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
|
||||
"resource://gre/modules/UpdateChannel.jsm");
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(MOZ_UPDATE_CHANNEL) && MOZ_UPDATE_CHANNEL != release
|
||||
#define MOZ_DEBUG_UA // Shorthand define for subsequent conditional sections.
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "UserAgentOverrides",
|
||||
"resource://gre/modules/UserAgentOverrides.jsm");
|
||||
#endif
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "ShellService", function() {
|
||||
try {
|
||||
return Cc["@mozilla.org/browser/shell-service;1"].
|
||||
@ -727,11 +720,6 @@ BrowserGlue.prototype = {
|
||||
Services.prefs.addObserver(POLARIS_ENABLED, this, false);
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_DEBUG_UA
|
||||
UserAgentOverrides.init();
|
||||
DebugUserAgent.init();
|
||||
#endif
|
||||
|
||||
#ifndef RELEASE_BUILD
|
||||
let themeName = gBrowserBundle.GetStringFromName("deveditionTheme.name");
|
||||
let vendorShortName = gBrandBundle.GetStringFromName("vendorShortName");
|
||||
@ -1003,9 +991,6 @@ BrowserGlue.prototype = {
|
||||
if (Services.prefs.getBoolPref("dom.identity.enabled")) {
|
||||
SignInToWebsiteUX.uninit();
|
||||
}
|
||||
#endif
|
||||
#ifdef MOZ_DEBUG_UA
|
||||
UserAgentOverrides.uninit();
|
||||
#endif
|
||||
webrtcUI.uninit();
|
||||
FormValidationHandler.uninit();
|
||||
@ -2975,36 +2960,3 @@ let globalMM = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessag
|
||||
globalMM.addMessageListener("UITour:onPageEvent", function(aMessage) {
|
||||
UITour.onPageEvent(aMessage, aMessage.data);
|
||||
});
|
||||
|
||||
#ifdef MOZ_DEBUG_UA
|
||||
// Modify the user agent string for specific domains
|
||||
// to route debug information through their logging.
|
||||
var DebugUserAgent = {
|
||||
DEBUG_UA: null,
|
||||
DOMAINS: [
|
||||
'youtube.com',
|
||||
'www.youtube.com',
|
||||
'youtube-nocookie.com',
|
||||
'www.youtube-nocookie.com',
|
||||
],
|
||||
|
||||
init: function() {
|
||||
// Only run if the MediaSource Extension API is available.
|
||||
if (!Services.prefs.getBoolPref("media.mediasource.enabled")) {
|
||||
return;
|
||||
}
|
||||
// Install our override filter.
|
||||
UserAgentOverrides.addComplexOverride(this.onRequest.bind(this));
|
||||
let ua = Cc["@mozilla.org/network/protocol;1?name=http"]
|
||||
.getService(Ci.nsIHttpProtocolHandler).userAgent;
|
||||
this.DEBUG_UA = ua + " Build/" + Services.appinfo.appBuildID;
|
||||
},
|
||||
|
||||
onRequest: function(channel, defaultUA) {
|
||||
if (this.DOMAINS.indexOf(channel.URI.host) != -1) {
|
||||
return this.DEBUG_UA;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
};
|
||||
#endif // MOZ_DEBUG_UA
|
||||
|
@ -1621,83 +1621,6 @@ struct GetParentObject<T, false>
|
||||
}
|
||||
};
|
||||
|
||||
MOZ_ALWAYS_INLINE
|
||||
JSObject* GetJSObjectFromCallback(CallbackObject* callback)
|
||||
{
|
||||
return callback->Callback();
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE
|
||||
JSObject* GetJSObjectFromCallback(void* noncallback)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline bool
|
||||
WrapCallThisValue(JSContext* cx, const T& p, JS::MutableHandle<JS::Value> rval)
|
||||
{
|
||||
// Callbacks are nsISupports, so WrapNativeParent will just happily wrap them
|
||||
// up as an nsISupports XPCWrappedNative... which is not at all what we want.
|
||||
// So we need to special-case them.
|
||||
JS::Rooted<JSObject*> obj(cx, GetJSObjectFromCallback(p));
|
||||
if (!obj) {
|
||||
// WrapNativeParent is a bit of a Swiss army knife that will
|
||||
// wrap anything for us.
|
||||
obj = WrapNativeParent(cx, p);
|
||||
if (!obj) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// But all that won't necessarily put things in the compartment of cx.
|
||||
if (!JS_WrapObject(cx, &obj)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
rval.setObject(*obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* This specialized function simply wraps a JS::Rooted<> since
|
||||
* WrapNativeParent() is not applicable for JS objects.
|
||||
*/
|
||||
template<>
|
||||
inline bool
|
||||
WrapCallThisValue<JS::Rooted<JSObject*>>(JSContext* cx,
|
||||
const JS::Rooted<JSObject*>& p,
|
||||
JS::MutableHandle<JS::Value> rval)
|
||||
{
|
||||
JS::Rooted<JSObject*> obj(cx, p);
|
||||
|
||||
if (!JS_WrapObject(cx, &obj)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
rval.setObject(*obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* This specialization is for wrapping any JS value.
|
||||
*/
|
||||
template<>
|
||||
inline bool
|
||||
WrapCallThisValue<JS::Rooted<JS::Value>>(JSContext* cx,
|
||||
const JS::Rooted<JS::Value>& v,
|
||||
JS::MutableHandle<JS::Value> rval)
|
||||
{
|
||||
JS::Rooted<JS::Value> val(cx, v);
|
||||
|
||||
if (!JS_WrapValue(cx, &val)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
rval.set(val);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Helper for calling GetOrCreateDOMReflector with smart pointers
|
||||
// (nsAutoPtr/nsRefPtr/nsCOMPtr) or references.
|
||||
template <class T, bool isSmartPtr=IsSmartPtr<T>::value>
|
||||
|
@ -1146,14 +1146,14 @@ class CGHeaders(CGWrapper):
|
||||
if len(callbacks) != 0:
|
||||
# We need CallbackFunction to serve as our parent class
|
||||
declareIncludes.add("mozilla/dom/CallbackFunction.h")
|
||||
# And we need BindingUtils.h so we can wrap "this" objects
|
||||
declareIncludes.add("mozilla/dom/BindingUtils.h")
|
||||
# And we need ToJSValue.h so we can wrap "this" objects
|
||||
declareIncludes.add("mozilla/dom/ToJSValue.h")
|
||||
|
||||
if len(callbackDescriptors) != 0 or len(jsImplementedDescriptors) != 0:
|
||||
# We need CallbackInterface to serve as our parent class
|
||||
declareIncludes.add("mozilla/dom/CallbackInterface.h")
|
||||
# And we need BindingUtils.h so we can wrap "this" objects
|
||||
declareIncludes.add("mozilla/dom/BindingUtils.h")
|
||||
# And we need ToJSValue.h so we can wrap "this" objects
|
||||
declareIncludes.add("mozilla/dom/ToJSValue.h")
|
||||
|
||||
# Also need to include the headers for ancestors of
|
||||
# JS-implemented interfaces.
|
||||
@ -13825,7 +13825,7 @@ class CGCallback(CGClass):
|
||||
"""
|
||||
$*{setupCall}
|
||||
JS::Rooted<JS::Value> thisValJS(s.GetContext());
|
||||
if (!WrapCallThisValue(s.GetContext(), thisVal, &thisValJS)) {
|
||||
if (!ToJSValue(s.GetContext(), thisVal, &thisValJS)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return${errorReturn};
|
||||
}
|
||||
|
@ -38,19 +38,6 @@ ToJSValue(JSContext* aCx, const nsAString& aArgument,
|
||||
}
|
||||
|
||||
|
||||
namespace tojsvalue_detail {
|
||||
|
||||
bool
|
||||
ISupportsToJSValue(JSContext* aCx,
|
||||
nsISupports* aArgument,
|
||||
JS::MutableHandle<JS::Value> aValue)
|
||||
{
|
||||
nsresult rv = nsContentUtils::WrapNative(aCx, aArgument, aValue);
|
||||
return NS_SUCCEEDED(rv);
|
||||
}
|
||||
|
||||
} // namespace tojsvalue_detail
|
||||
|
||||
bool
|
||||
ToJSValue(JSContext* aCx,
|
||||
nsresult aArgument,
|
||||
|
@ -28,10 +28,16 @@ ToJSValue(JSContext* aCx,
|
||||
const nsAString& aArgument,
|
||||
JS::MutableHandle<JS::Value> aValue);
|
||||
|
||||
// Accept booleans.
|
||||
MOZ_WARN_UNUSED_RESULT inline bool
|
||||
// Accept booleans. But be careful here: if we just have a function that takes
|
||||
// a boolean argument, then any pointer that doesn't match one of our other
|
||||
// signatures/templates will get treated as a boolean, which is clearly not
|
||||
// desirable. So make this a template that only gets used if the argument type
|
||||
// is actually boolean
|
||||
template<typename T>
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
typename EnableIf<IsSame<T, bool>::value, bool>::Type
|
||||
ToJSValue(JSContext* aCx,
|
||||
bool aArgument,
|
||||
T aArgument,
|
||||
JS::MutableHandle<JS::Value> aValue)
|
||||
{
|
||||
// Make sure we're called in a compartment
|
||||
@ -174,15 +180,6 @@ ToJSValue(JSContext* aCx,
|
||||
return true;
|
||||
}
|
||||
|
||||
// We don't want to include nsContentUtils here, so use a helper
|
||||
// function for the nsISupports case.
|
||||
namespace tojsvalue_detail {
|
||||
bool
|
||||
ISupportsToJSValue(JSContext* aCx,
|
||||
nsISupports* aArgument,
|
||||
JS::MutableHandle<JS::Value> aValue);
|
||||
} // namespace tojsvalue_detail
|
||||
|
||||
// Accept objects that inherit from nsISupports but not nsWrapperCache (e.g.
|
||||
// nsIDOMFile).
|
||||
template <class T>
|
||||
@ -197,7 +194,9 @@ ToJSValue(JSContext* aCx,
|
||||
// Make sure we're called in a compartment
|
||||
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
|
||||
|
||||
return tojsvalue_detail::ISupportsToJSValue(aCx, &aArgument, aValue);
|
||||
qsObjectHelper helper(ToSupports(&aArgument), nullptr);
|
||||
JS::Rooted<JSObject*> scope(aCx, JS::CurrentGlobalOrNull(aCx));
|
||||
return XPCOMObjectToJsval(aCx, scope, helper, nullptr, true, aValue);
|
||||
}
|
||||
|
||||
// Accept nsRefPtr/nsCOMPtr
|
||||
@ -257,6 +256,16 @@ ToJSValue(JSContext* aCx, const JS::Rooted<JS::Value>& aArgument,
|
||||
return MaybeWrapValue(aCx, aValue);
|
||||
}
|
||||
|
||||
// Accept existing rooted JS objects (which may not be same-compartment with
|
||||
// us).
|
||||
MOZ_WARN_UNUSED_RESULT inline bool
|
||||
ToJSValue(JSContext* aCx, const JS::Rooted<JSObject*>& aArgument,
|
||||
JS::MutableHandle<JS::Value> aValue)
|
||||
{
|
||||
aValue.setObjectOrNull(aArgument);
|
||||
return MaybeWrapObjectOrNullValue(aCx, aValue);
|
||||
}
|
||||
|
||||
// Accept nsresult, for use in rejections, and create an XPCOM
|
||||
// exception object representing that nsresult.
|
||||
MOZ_WARN_UNUSED_RESULT bool
|
||||
|
@ -197,7 +197,7 @@ public:
|
||||
bool* aHasPlugin,
|
||||
nsCString* aVersion);
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy);
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
static PGMPServiceParent* Create(Transport* aTransport, ProcessId aOtherPid);
|
||||
|
||||
|
@ -774,7 +774,7 @@ MediaEngineGonkVideoSource::RotateImage(layers::Image* aImage, uint32_t aWidth,
|
||||
dstPtr + (yStride * dstHeight + (uvStride * dstHeight / 2)), uvStride,
|
||||
dstPtr + (yStride * dstHeight), uvStride,
|
||||
0, 0,
|
||||
aWidth, aHeight,
|
||||
graphicBuffer->getStride(), aHeight,
|
||||
aWidth, aHeight,
|
||||
static_cast<libyuv::RotationMode>(mRotation),
|
||||
libyuv::FOURCC_NV21);
|
||||
@ -796,7 +796,7 @@ MediaEngineGonkVideoSource::RotateImage(layers::Image* aImage, uint32_t aWidth,
|
||||
dstPtr + (dstWidth * dstHeight), half_width,
|
||||
dstPtr + (dstWidth * dstHeight * 5 / 4), half_width,
|
||||
0, 0,
|
||||
aWidth, aHeight,
|
||||
graphicBuffer->getStride(), aHeight,
|
||||
aWidth, aHeight,
|
||||
static_cast<libyuv::RotationMode>(mRotation),
|
||||
ConvertPixelFormatToFOURCC(graphicBuffer->getPixelFormat()));
|
||||
|
@ -118,6 +118,7 @@ nsSpeechTask::nsSpeechTask(float aVolume, const nsAString& aText)
|
||||
|
||||
nsSpeechTask::~nsSpeechTask()
|
||||
{
|
||||
LOG(PR_LOG_DEBUG, ("~nsSpeechTask"));
|
||||
if (mStream) {
|
||||
if (!mStream->IsDestroyed()) {
|
||||
mStream->Destroy();
|
||||
@ -125,6 +126,18 @@ nsSpeechTask::~nsSpeechTask()
|
||||
|
||||
mStream = nullptr;
|
||||
}
|
||||
|
||||
if (mPort) {
|
||||
mPort->Destroy();
|
||||
mPort = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsSpeechTask::BindStream(ProcessedMediaStream* aStream)
|
||||
{
|
||||
mStream = MediaStreamGraph::GetInstance()->CreateSourceStream(nullptr);
|
||||
mPort = aStream->AllocateInputPort(mStream, 0);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -137,16 +150,16 @@ nsSpeechTask::Setup(nsISpeechTaskCallback* aCallback,
|
||||
|
||||
mCallback = aCallback;
|
||||
|
||||
if (argc < 2) {
|
||||
if (mIndirectAudio) {
|
||||
if (argc > 0) {
|
||||
NS_WARNING("Audio info arguments in Setup() are ignored for indirect audio services.");
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mIndirectAudio) {
|
||||
NS_WARNING("Audio info arguments in Setup() are ignored for indirect audio services.");
|
||||
}
|
||||
// mStream is set up in BindStream() that should be called before this.
|
||||
MOZ_ASSERT(mStream);
|
||||
|
||||
// XXX: Is there setup overhead here that hurtls latency?
|
||||
mStream = MediaStreamGraph::GetInstance()->CreateSourceStream(nullptr);
|
||||
mStream->AddListener(new SynthStreamListener(this));
|
||||
|
||||
// XXX: Support more than one channel
|
||||
|
@ -45,6 +45,8 @@ public:
|
||||
|
||||
void SetIndirectAudio(bool aIndirectAudio) { mIndirectAudio = aIndirectAudio; }
|
||||
|
||||
void BindStream(ProcessedMediaStream* aStream);
|
||||
|
||||
protected:
|
||||
virtual ~nsSpeechTask();
|
||||
|
||||
@ -78,6 +80,8 @@ private:
|
||||
|
||||
nsRefPtr<SourceMediaStream> mStream;
|
||||
|
||||
nsRefPtr<MediaInputPort> mPort;
|
||||
|
||||
nsCOMPtr<nsISpeechTaskCallback> mCallback;
|
||||
|
||||
uint32_t mChannels;
|
||||
|
@ -134,6 +134,14 @@ nsSynthVoiceRegistry::~nsSynthVoiceRegistry()
|
||||
// mSpeechSynthChild's lifecycle is managed by the Content protocol.
|
||||
mSpeechSynthChild = nullptr;
|
||||
|
||||
if (mStream) {
|
||||
if (!mStream->IsDestroyed()) {
|
||||
mStream->Destroy();
|
||||
}
|
||||
|
||||
mStream = nullptr;
|
||||
}
|
||||
|
||||
mUriVoiceMap.Clear();
|
||||
}
|
||||
|
||||
@ -568,6 +576,11 @@ nsSynthVoiceRegistry::Speak(const nsAString& aText,
|
||||
|
||||
if (serviceType == nsISpeechService::SERVICETYPE_INDIRECT_AUDIO) {
|
||||
aTask->SetIndirectAudio(true);
|
||||
} else {
|
||||
if (!mStream) {
|
||||
mStream = MediaStreamGraph::GetInstance()->CreateTrackUnionStream(nullptr);
|
||||
}
|
||||
aTask->BindStream(mStream);
|
||||
}
|
||||
|
||||
voice->mService->Speak(aText, voice->mUri, aRate, aPitch, aTask);
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "nsISynthVoiceRegistry.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "nsTArray.h"
|
||||
#include "MediaStreamGraph.h"
|
||||
|
||||
class nsISpeechService;
|
||||
|
||||
@ -73,6 +74,8 @@ private:
|
||||
nsRefPtrHashtable<nsStringHashKey, VoiceData> mUriVoiceMap;
|
||||
|
||||
SpeechSynthesisChild* mSpeechSynthChild;
|
||||
|
||||
nsRefPtr<ProcessedMediaStream> mStream;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -436,16 +436,20 @@ PluginAsyncSurrogate::SetStreamType(NPStream* aStream, uint16_t aStreamType)
|
||||
void
|
||||
PluginAsyncSurrogate::OnInstanceCreated(PluginInstanceParent* aInstance)
|
||||
{
|
||||
for (uint32_t i = 0, len = mPendingNewStreamCalls.Length(); i < len; ++i) {
|
||||
PendingNewStreamCall& curPendingCall = mPendingNewStreamCalls[i];
|
||||
uint16_t streamType = NP_NORMAL;
|
||||
NPError curError = aInstance->NPP_NewStream(
|
||||
const_cast<char*>(NullableStringGet(curPendingCall.mType)),
|
||||
curPendingCall.mStream, curPendingCall.mSeekable,
|
||||
&streamType);
|
||||
if (curError != NPERR_NO_ERROR) {
|
||||
// If we failed here then the send failed and we need to clean up
|
||||
DestroyAsyncStream(curPendingCall.mStream);
|
||||
if (!mDestroyPending) {
|
||||
// If NPP_Destroy has already been called then these streams have already
|
||||
// been cleaned up on the browser side and are no longer valid.
|
||||
for (uint32_t i = 0, len = mPendingNewStreamCalls.Length(); i < len; ++i) {
|
||||
PendingNewStreamCall& curPendingCall = mPendingNewStreamCalls[i];
|
||||
uint16_t streamType = NP_NORMAL;
|
||||
NPError curError = aInstance->NPP_NewStream(
|
||||
const_cast<char*>(NullableStringGet(curPendingCall.mType)),
|
||||
curPendingCall.mStream, curPendingCall.mSeekable,
|
||||
&streamType);
|
||||
if (curError != NPERR_NO_ERROR) {
|
||||
// If we failed here then the send failed and we need to clean up
|
||||
DestroyAsyncStream(curPendingCall.mStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
mPendingNewStreamCalls.Clear();
|
||||
@ -543,10 +547,12 @@ PluginAsyncSurrogate::AsyncCallArriving()
|
||||
void
|
||||
PluginAsyncSurrogate::NotifyAsyncInitFailed()
|
||||
{
|
||||
// Clean up any pending NewStream requests
|
||||
for (uint32_t i = 0, len = mPendingNewStreamCalls.Length(); i < len; ++i) {
|
||||
PendingNewStreamCall& curPendingCall = mPendingNewStreamCalls[i];
|
||||
DestroyAsyncStream(curPendingCall.mStream);
|
||||
if (!mDestroyPending) {
|
||||
// Clean up any pending NewStream requests
|
||||
for (uint32_t i = 0, len = mPendingNewStreamCalls.Length(); i < len; ++i) {
|
||||
PendingNewStreamCall& curPendingCall = mPendingNewStreamCalls[i];
|
||||
DestroyAsyncStream(curPendingCall.mStream);
|
||||
}
|
||||
}
|
||||
mPendingNewStreamCalls.Clear();
|
||||
|
||||
@ -556,9 +562,7 @@ PluginAsyncSurrogate::NotifyAsyncInitFailed()
|
||||
return;
|
||||
}
|
||||
nsPluginInstanceOwner* owner = inst->GetOwner();
|
||||
if (!owner) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(owner);
|
||||
owner->NotifyHostAsyncInitFailed();
|
||||
}
|
||||
|
||||
|
@ -1739,10 +1739,17 @@ PluginInstanceParent::RecvAsyncNPP_NewResult(const NPError& aResult)
|
||||
mSurrogate->SetAcceptingCalls(true);
|
||||
}
|
||||
|
||||
// It is possible for a plugin instance to outlive its owner (eg. When a
|
||||
// PluginDestructionGuard was on the stack at the time the owner was being
|
||||
// destroyed). We need to handle that case.
|
||||
nsPluginInstanceOwner* owner = GetOwner();
|
||||
// It is possible for a plugin instance to outlive its owner when async
|
||||
// plugin init is turned on, so we need to handle that case.
|
||||
if (aResult != NPERR_NO_ERROR || !owner) {
|
||||
if (!owner) {
|
||||
// We can't do anything at this point, just return. Any pending browser
|
||||
// streams will be cleaned up when the plugin instance is destroyed.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aResult != NPERR_NO_ERROR) {
|
||||
mSurrogate->NotifyAsyncInitFailed();
|
||||
return true;
|
||||
}
|
||||
|
@ -869,8 +869,7 @@ XULContentSinkImpl::OpenScript(const char16_t** aAttributes,
|
||||
const nsDependentString key(aAttributes[0]);
|
||||
if (key.EqualsLiteral("src")) {
|
||||
src.Assign(aAttributes[1]);
|
||||
}
|
||||
else if (key.EqualsLiteral("type")) {
|
||||
} else if (key.EqualsLiteral("type")) {
|
||||
nsDependentString str(aAttributes[1]);
|
||||
nsContentTypeParser parser(str);
|
||||
nsAutoString mimeType;
|
||||
@ -888,12 +887,8 @@ XULContentSinkImpl::OpenScript(const char16_t** aAttributes,
|
||||
if (nsContentUtils::IsJavascriptMIMEType(mimeType)) {
|
||||
langID = nsIProgrammingLanguage::JAVASCRIPT;
|
||||
version = JSVERSION_LATEST;
|
||||
} else {
|
||||
langID = nsIProgrammingLanguage::UNKNOWN;
|
||||
}
|
||||
|
||||
if (langID != nsIProgrammingLanguage::UNKNOWN) {
|
||||
// Get the version string, and ensure the language supports it.
|
||||
// Get the version string, and ensure that JavaScript supports it.
|
||||
nsAutoString versionName;
|
||||
rv = parser.GetParameter("version", versionName);
|
||||
|
||||
@ -902,9 +897,10 @@ XULContentSinkImpl::OpenScript(const char16_t** aAttributes,
|
||||
} else if (rv != NS_ERROR_INVALID_ARG) {
|
||||
return rv;
|
||||
}
|
||||
} else {
|
||||
langID = nsIProgrammingLanguage::UNKNOWN;
|
||||
}
|
||||
}
|
||||
else if (key.EqualsLiteral("language")) {
|
||||
} else if (key.EqualsLiteral("language")) {
|
||||
// Language is deprecated, and the impl in nsScriptLoader ignores the
|
||||
// various version strings anyway. So we make no attempt to support
|
||||
// languages other than JS for language=
|
||||
@ -917,80 +913,68 @@ XULContentSinkImpl::OpenScript(const char16_t** aAttributes,
|
||||
aAttributes += 2;
|
||||
}
|
||||
|
||||
// Not all script languages have a "sandbox" concept. At time of
|
||||
// writing, Python is the only other language, and it does not.
|
||||
// For such languages, neither any inline script nor remote script are
|
||||
// safe to execute from untrusted sources.
|
||||
// So for such languages, we only allow script when the document
|
||||
// itself is from chrome. We then don't bother to check the
|
||||
// "src=" tag - we trust chrome to do the right thing.
|
||||
// (See also similar code in nsScriptLoader.cpp)
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryReferent(mDocument));
|
||||
if (langID != nsIProgrammingLanguage::UNKNOWN &&
|
||||
langID != nsIProgrammingLanguage::JAVASCRIPT &&
|
||||
doc && !nsContentUtils::IsChromeDoc(doc)) {
|
||||
langID = nsIProgrammingLanguage::UNKNOWN;
|
||||
NS_WARNING("Non JS language called from non chrome - ignored");
|
||||
}
|
||||
|
||||
// Don't process scripts that aren't known
|
||||
if (langID != nsIProgrammingLanguage::UNKNOWN) {
|
||||
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
||||
if (doc)
|
||||
globalObject = do_QueryInterface(doc->GetWindow());
|
||||
nsRefPtr<nsXULPrototypeScript> script =
|
||||
new nsXULPrototypeScript(aLineNumber, version);
|
||||
if (! script)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
if (langID == nsIProgrammingLanguage::UNKNOWN) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If there is a SRC attribute...
|
||||
if (! src.IsEmpty()) {
|
||||
// Use the SRC attribute value to load the URL
|
||||
rv = NS_NewURI(getter_AddRefs(script->mSrcURI), src, nullptr, mDocumentURL);
|
||||
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
||||
if (doc)
|
||||
globalObject = do_QueryInterface(doc->GetWindow());
|
||||
nsRefPtr<nsXULPrototypeScript> script =
|
||||
new nsXULPrototypeScript(aLineNumber, version);
|
||||
if (! script)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// Check if this document is allowed to load a script from this source
|
||||
// NOTE: if we ever allow scripts added via the DOM to run, we need to
|
||||
// add a CheckLoadURI call for that as well.
|
||||
// If there is a SRC attribute...
|
||||
if (! src.IsEmpty()) {
|
||||
// Use the SRC attribute value to load the URL
|
||||
rv = NS_NewURI(getter_AddRefs(script->mSrcURI), src, nullptr, mDocumentURL);
|
||||
|
||||
// Check if this document is allowed to load a script from this source
|
||||
// NOTE: if we ever allow scripts added via the DOM to run, we need to
|
||||
// add a CheckLoadURI call for that as well.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (!mSecMan)
|
||||
mSecMan = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (!mSecMan)
|
||||
mSecMan = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument, &rv);
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument, &rv);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = mSecMan->
|
||||
CheckLoadURIWithPrincipal(doc->NodePrincipal(),
|
||||
script->mSrcURI,
|
||||
nsIScriptSecurityManager::ALLOW_CHROME);
|
||||
}
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = mSecMan->
|
||||
CheckLoadURIWithPrincipal(doc->NodePrincipal(),
|
||||
script->mSrcURI,
|
||||
nsIScriptSecurityManager::ALLOW_CHROME);
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Attempt to deserialize an out-of-line script from the FastLoad
|
||||
// file right away. Otherwise we'll end up reloading the script and
|
||||
// corrupting the FastLoad file trying to serialize it, in the case
|
||||
// where it's already there.
|
||||
script->DeserializeOutOfLine(nullptr, mPrototype);
|
||||
}
|
||||
|
||||
nsPrototypeArray* children = nullptr;
|
||||
rv = mContextStack.GetTopChildren(&children);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
children->AppendElement(script);
|
||||
|
||||
mConstrainSize = false;
|
||||
|
||||
mContextStack.Push(script, mState);
|
||||
mState = eInScript;
|
||||
// Attempt to deserialize an out-of-line script from the FastLoad
|
||||
// file right away. Otherwise we'll end up reloading the script and
|
||||
// corrupting the FastLoad file trying to serialize it, in the case
|
||||
// where it's already there.
|
||||
script->DeserializeOutOfLine(nullptr, mPrototype);
|
||||
}
|
||||
|
||||
nsPrototypeArray* children = nullptr;
|
||||
rv = mContextStack.GetTopChildren(&children);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
children->AppendElement(script);
|
||||
|
||||
mConstrainSize = false;
|
||||
|
||||
mContextStack.Push(script, mState);
|
||||
mState = eInScript;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1071,8 +1055,7 @@ XULContentSinkImpl::AddText(const char16_t* aText,
|
||||
if (NS_OK != rv) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
mTextSize += aLength;
|
||||
mText = (char16_t *) realloc(mText, sizeof(char16_t) * mTextSize);
|
||||
if (nullptr == mText) {
|
||||
|
@ -1983,10 +1983,11 @@ gfxWindowsPlatform::InitD3D11Devices()
|
||||
if (FAILED(hr)) {
|
||||
// This should always succeed... in theory.
|
||||
gfxCriticalError() << "Failed to initialize WARP D3D11 device!" << hr;
|
||||
} else {
|
||||
mIsWARP = true;
|
||||
reporterWARP.SetSuccessful();
|
||||
return;
|
||||
}
|
||||
|
||||
mIsWARP = true;
|
||||
reporterWARP.SetSuccessful();
|
||||
}
|
||||
|
||||
mD3D11Device->SetExceptionMode(0);
|
||||
|
@ -783,7 +783,7 @@ static const JSFunctionSpec sInt64StaticFunctions[] = {
|
||||
JS_FN("compare", Int64::Compare, 2, CTYPESFN_FLAGS),
|
||||
JS_FN("lo", Int64::Lo, 1, CTYPESFN_FLAGS),
|
||||
JS_FN("hi", Int64::Hi, 1, CTYPESFN_FLAGS),
|
||||
JS_FN("join", Int64::Join, 2, CTYPESFN_FLAGS),
|
||||
// "join" is defined specially; see InitInt64Class.
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
@ -791,7 +791,7 @@ static const JSFunctionSpec sUInt64StaticFunctions[] = {
|
||||
JS_FN("compare", UInt64::Compare, 2, CTYPESFN_FLAGS),
|
||||
JS_FN("lo", UInt64::Lo, 1, CTYPESFN_FLAGS),
|
||||
JS_FN("hi", UInt64::Hi, 1, CTYPESFN_FLAGS),
|
||||
JS_FN("join", UInt64::Join, 2, CTYPESFN_FLAGS),
|
||||
// "join" is defined specially; see InitInt64Class.
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
@ -1102,10 +1102,8 @@ InitInt64Class(JSContext* cx,
|
||||
RootedObject ctor(cx, JS_GetConstructor(cx, prototype));
|
||||
if (!ctor)
|
||||
return nullptr;
|
||||
if (!JS_FreezeObject(cx, ctor))
|
||||
return nullptr;
|
||||
|
||||
// Redefine the 'join' function as an extended native and stash
|
||||
// Define the 'join' function as an extended native and stash
|
||||
// ctypes.{Int64,UInt64}.prototype in a reserved slot of the new function.
|
||||
MOZ_ASSERT(clasp == &sInt64ProtoClass || clasp == &sUInt64ProtoClass);
|
||||
JSNative native = (clasp == &sInt64ProtoClass) ? Int64::Join : UInt64::Join;
|
||||
@ -1117,6 +1115,8 @@ InitInt64Class(JSContext* cx,
|
||||
js::SetFunctionNativeReserved(fun, SLOT_FN_INT64PROTO,
|
||||
OBJECT_TO_JSVAL(prototype));
|
||||
|
||||
if (!JS_FreezeObject(cx, ctor))
|
||||
return nullptr;
|
||||
if (!JS_FreezeObject(cx, prototype))
|
||||
return nullptr;
|
||||
|
||||
|
19
js/src/jit-test/tests/xdr/debug-lazy.js
Normal file
19
js/src/jit-test/tests/xdr/debug-lazy.js
Normal file
@ -0,0 +1,19 @@
|
||||
load(libdir + 'bytecode-cache.js');
|
||||
|
||||
// Ensure that if a function is encoded when non-lazy but relazifiable, then
|
||||
// decoded, the resulting LazyScript is marked as being non-lazy so that when
|
||||
// the debugger tries to delazify things it doesn't get all confused. We just
|
||||
// use findScripts() to trigger debugger delazification; we don't really care
|
||||
// about the scripts themselves.
|
||||
function checkAfter(ctx) {
|
||||
var dbg = new Debugger(ctx.global);
|
||||
var allScripts = dbg.findScripts();
|
||||
assertEq(allScripts.length == 0, false);
|
||||
}
|
||||
|
||||
test = `
|
||||
function f() { return true; };
|
||||
f();
|
||||
`
|
||||
evalWithCache(test, { assertEqBytecode: true, assertEqResult: true,
|
||||
checkAfter: checkAfter });
|
@ -2595,7 +2595,7 @@ class PropertyDescriptorOperations
|
||||
MOZ_ASSERT(!has(JSPROP_IGNORE_READONLY));
|
||||
MOZ_ASSERT(!has(JSPROP_IGNORE_VALUE));
|
||||
MOZ_ASSERT(!has(SHADOWABLE));
|
||||
MOZ_ASSERT(desc()->value.isUndefined());
|
||||
MOZ_ASSERT(value().isUndefined());
|
||||
MOZ_ASSERT_IF(!has(JSPROP_GETTER), !getter());
|
||||
MOZ_ASSERT_IF(!has(JSPROP_SETTER), !setter());
|
||||
} else {
|
||||
|
@ -505,7 +505,7 @@ js::CanonicalizeArrayLengthValue(JSContext* cx, HandleValue v, uint32_t* newLen)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ES6 20130308 draft 8.4.2.4 ArraySetLength */
|
||||
/* ES6 draft rev 34 (2015 Feb 20) 9.4.2.4 ArraySetLength */
|
||||
bool
|
||||
js::ArraySetLength(JSContext* cx, Handle<ArrayObject*> arr, HandleId id,
|
||||
unsigned attrs, HandleValue value, ObjectOpResult& result)
|
||||
@ -515,26 +515,26 @@ js::ArraySetLength(JSContext* cx, Handle<ArrayObject*> arr, HandleId id,
|
||||
if (!arr->maybeCopyElementsForWrite(cx))
|
||||
return false;
|
||||
|
||||
/* Steps 1-2 are irrelevant in our implementation. */
|
||||
|
||||
/* Steps 3-5. */
|
||||
// Step 1.
|
||||
uint32_t newLen;
|
||||
if (!CanonicalizeArrayLengthValue(cx, value, &newLen))
|
||||
return false;
|
||||
if (attrs & JSPROP_IGNORE_VALUE) {
|
||||
// The spec has us calling OrdinaryDefineOwnProperty if
|
||||
// Desc.[[Value]] is absent, but our implementation is so different that
|
||||
// this is impossible. Instead, set newLen to the current length and
|
||||
// proceed to step 9.
|
||||
newLen = arr->length();
|
||||
} else {
|
||||
// Step 2 is irrelevant in our implementation.
|
||||
|
||||
// Abort if we're being asked to change enumerability or configurability.
|
||||
// (The length property of arrays is non-configurable, so such attempts
|
||||
// must fail.) This behavior is spread throughout the ArraySetLength spec
|
||||
// algorithm, but we only need check it once as our array implementation
|
||||
// is internally so different from the spec algorithm. (ES5 and ES6 define
|
||||
// behavior by delegating to the default define-own-property algorithm --
|
||||
// OrdinaryDefineOwnProperty in ES6, the default [[DefineOwnProperty]] in
|
||||
// ES5 -- but we reimplement all the conflict-detection bits ourselves here
|
||||
// so that we can use a customized length representation.)
|
||||
if (!(attrs & JSPROP_PERMANENT) || (attrs & JSPROP_ENUMERATE))
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
// Steps 3-7.
|
||||
MOZ_ASSERT_IF(attrs & JSPROP_IGNORE_VALUE, value.isUndefined());
|
||||
if (!CanonicalizeArrayLengthValue(cx, value, &newLen))
|
||||
return false;
|
||||
|
||||
/* Steps 6-7. */
|
||||
// Step 8 is irrelevant in our implementation.
|
||||
}
|
||||
|
||||
// Steps 9-11.
|
||||
bool lengthIsWritable = arr->lengthIsWritable();
|
||||
#ifdef DEBUG
|
||||
{
|
||||
@ -543,10 +543,21 @@ js::ArraySetLength(JSContext* cx, Handle<ArrayObject*> arr, HandleId id,
|
||||
MOZ_ASSERT(lengthShape->writable() == lengthIsWritable);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t oldLen = arr->length();
|
||||
|
||||
/* Steps 8-9 for arrays with non-writable length. */
|
||||
// Part of steps 1.a, 12.a, and 16: Fail if we're being asked to change
|
||||
// enumerability or configurability, or otherwise break the object
|
||||
// invariants. (ES6 checks these by calling OrdinaryDefineOwnProperty, but
|
||||
// in SM, the array length property is hardly ordinary.)
|
||||
if ((attrs & (JSPROP_PERMANENT | JSPROP_IGNORE_PERMANENT)) == 0 ||
|
||||
(attrs & (JSPROP_ENUMERATE | JSPROP_IGNORE_ENUMERATE)) == JSPROP_ENUMERATE ||
|
||||
(attrs & (JSPROP_GETTER | JSPROP_SETTER)) != 0 ||
|
||||
(!lengthIsWritable && (attrs & (JSPROP_READONLY | JSPROP_IGNORE_READONLY)) == 0))
|
||||
{
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
}
|
||||
|
||||
// Steps 12-13 for arrays with non-writable length.
|
||||
if (!lengthIsWritable) {
|
||||
if (newLen == oldLen)
|
||||
return result.succeed();
|
||||
@ -554,7 +565,7 @@ js::ArraySetLength(JSContext* cx, Handle<ArrayObject*> arr, HandleId id,
|
||||
return result.fail(JSMSG_CANT_REDEFINE_ARRAY_LENGTH);
|
||||
}
|
||||
|
||||
/* Step 8. */
|
||||
// Step 19.
|
||||
bool succeeded = true;
|
||||
do {
|
||||
// The initialized length and capacity of an array only need updating
|
||||
@ -616,10 +627,10 @@ js::ArraySetLength(JSContext* cx, Handle<ArrayObject*> arr, HandleId id,
|
||||
// If we're removing a relatively small number of elements, just do
|
||||
// it exactly by the spec.
|
||||
while (newLen < oldLen) {
|
||||
/* Step 15a. */
|
||||
// Step 15a.
|
||||
oldLen--;
|
||||
|
||||
/* Steps 15b-d. */
|
||||
// Steps 15b-d.
|
||||
ObjectOpResult deleteSucceeded;
|
||||
if (!DeleteElement(cx, arr, oldLen, deleteSucceeded))
|
||||
return false;
|
||||
@ -679,7 +690,7 @@ js::ArraySetLength(JSContext* cx, Handle<ArrayObject*> arr, HandleId id,
|
||||
MOZ_ASSERT(indexes[i] < index, "indexes should never repeat");
|
||||
index = indexes[i];
|
||||
|
||||
/* Steps 15b-d. */
|
||||
// Steps 15b-d.
|
||||
ObjectOpResult deleteSucceeded;
|
||||
if (!DeleteElement(cx, arr, index, deleteSucceeded))
|
||||
return false;
|
||||
@ -692,23 +703,25 @@ js::ArraySetLength(JSContext* cx, Handle<ArrayObject*> arr, HandleId id,
|
||||
}
|
||||
} while (false);
|
||||
|
||||
/* Steps 12, 16. */
|
||||
|
||||
// Yes, we totally drop a non-stub getter/setter from a defineProperty
|
||||
// API call on the floor here. Given that getter/setter will go away in
|
||||
// the long run, with accessors replacing them both internally and at the
|
||||
// API level, just run with this.
|
||||
RootedShape lengthShape(cx, arr->lookup(cx, id));
|
||||
if (!NativeObject::changeProperty(cx, arr, lengthShape,
|
||||
attrs | JSPROP_PERMANENT | JSPROP_SHARED |
|
||||
(lengthShape->attributes() & JSPROP_READONLY),
|
||||
array_length_getter, array_length_setter))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update array length. Technically we should have been doing this
|
||||
// throughout the loop, in step 19.d.iii.
|
||||
arr->setLength(cx, newLen);
|
||||
|
||||
// Step 20.
|
||||
if (attrs & JSPROP_READONLY) {
|
||||
// Yes, we totally drop a non-stub getter/setter from a defineProperty
|
||||
// API call on the floor here. Given that getter/setter will go away in
|
||||
// the long run, with accessors replacing them both internally and at the
|
||||
// API level, just run with this.
|
||||
RootedShape lengthShape(cx, arr->lookup(cx, id));
|
||||
if (!NativeObject::changeProperty(cx, arr, lengthShape,
|
||||
lengthShape->attributes() | JSPROP_READONLY,
|
||||
array_length_getter, array_length_setter))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// All operations past here until the |!succeeded| code must be infallible,
|
||||
// so that all element fields remain properly synchronized.
|
||||
|
||||
|
@ -1407,7 +1407,8 @@ JSFunction::createScriptForLazilyInterpretedFunction(JSContext* cx, HandleFuncti
|
||||
// chain of their inner functions, or in the case of eval, possibly
|
||||
// eval'd inner functions. This prohibits re-lazification as
|
||||
// StaticScopeIter queries isHeavyweight of those functions, which
|
||||
// requires a non-lazy script.
|
||||
// requires a non-lazy script. Note that if this ever changes,
|
||||
// XDRRelazificationInfo will have to be fixed.
|
||||
bool canRelazify = !lazy->numInnerFunctions() && !lazy->hasDirectEval();
|
||||
|
||||
if (script) {
|
||||
|
@ -627,44 +627,8 @@ DefinePropertyOnTypedArray(JSContext* cx, HandleObject obj, HandleId id,
|
||||
MOZ_ASSERT(IsAnyTypedArray(obj));
|
||||
// Steps 3.a-c.
|
||||
uint64_t index;
|
||||
if (IsTypedArrayIndex(id, &index)) {
|
||||
// These are all substeps of 3.c.
|
||||
// Steps i-vi.
|
||||
// We (wrongly) ignore out of range defines with a value.
|
||||
if (index >= AnyTypedArrayLength(obj))
|
||||
return result.succeed();
|
||||
|
||||
// Step vii.
|
||||
if (desc.isAccessorDescriptor())
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
|
||||
// Step viii.
|
||||
if (desc.hasConfigurable() && desc.configurable())
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
|
||||
// Step ix.
|
||||
if (desc.hasEnumerable() && !desc.enumerable())
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
|
||||
// Step x.
|
||||
if (desc.hasWritable() && !desc.writable())
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
|
||||
// Step xi.
|
||||
if (desc.hasValue()) {
|
||||
double d;
|
||||
if (!ToNumber(cx, desc.value(), &d))
|
||||
return false;
|
||||
|
||||
if (obj->is<TypedArrayObject>())
|
||||
TypedArrayObject::setElement(obj->as<TypedArrayObject>(), index, d);
|
||||
else
|
||||
SharedTypedArrayObject::setElement(obj->as<SharedTypedArrayObject>(), index, d);
|
||||
}
|
||||
|
||||
// Step xii.
|
||||
return result.succeed();
|
||||
}
|
||||
if (IsTypedArrayIndex(id, &index))
|
||||
return DefineTypedArrayElement(cx, obj, index, desc, result);
|
||||
|
||||
// Step 4.
|
||||
return DefinePropertyOnObject(cx, obj.as<NativeObject>(), id, desc, result);
|
||||
|
@ -710,16 +710,16 @@ Walk(JSContext* cx, HandleObject holder, HandleId name, HandleValue reviver, Mut
|
||||
if (!Walk(cx, obj, id, reviver, &newElement))
|
||||
return false;
|
||||
|
||||
ObjectOpResult ignored;
|
||||
if (newElement.isUndefined()) {
|
||||
/* Step 2a(iii)(2). */
|
||||
ObjectOpResult ignored;
|
||||
/* Step 2a(iii)(2). The spec deliberately ignores strict failure. */
|
||||
if (!DeleteProperty(cx, obj, id, ignored))
|
||||
return false;
|
||||
} else {
|
||||
/* Step 2a(iii)(3). */
|
||||
// XXX This definition should ignore success/failure, when
|
||||
// our property-definition APIs indicate that.
|
||||
if (!DefineProperty(cx, obj, id, newElement))
|
||||
/* Step 2a(iii)(3). The spec deliberately ignores strict failure. */
|
||||
Rooted<PropertyDescriptor> desc(cx);
|
||||
desc.setDataDescriptor(newElement, JSPROP_ENUMERATE);
|
||||
if (!StandardDefineProperty(cx, obj, id, desc, ignored))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -738,16 +738,16 @@ Walk(JSContext* cx, HandleObject holder, HandleId name, HandleValue reviver, Mut
|
||||
if (!Walk(cx, obj, id, reviver, &newElement))
|
||||
return false;
|
||||
|
||||
ObjectOpResult ignored;
|
||||
if (newElement.isUndefined()) {
|
||||
/* Step 2b(ii)(2). */
|
||||
ObjectOpResult ignored;
|
||||
/* Step 2b(ii)(2). The spec deliberately ignores strict failure. */
|
||||
if (!DeleteProperty(cx, obj, id, ignored))
|
||||
return false;
|
||||
} else {
|
||||
/* Step 2b(ii)(3). */
|
||||
// XXX This definition should ignore success/failure, when
|
||||
// our property-definition APIs indicate that.
|
||||
if (!DefineProperty(cx, obj, id, newElement))
|
||||
/* Step 2b(ii)(3). The spec deliberately ignores strict failure. */
|
||||
Rooted<PropertyDescriptor> desc(cx);
|
||||
desc.setDataDescriptor(newElement, JSPROP_ENUMERATE);
|
||||
if (!StandardDefineProperty(cx, obj, id, desc, ignored))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -504,21 +504,23 @@ XDRRelazificationInfo(XDRState<mode>* xdr, HandleFunction fun, HandleScript scri
|
||||
MOZ_ASSERT(end == lazy->end());
|
||||
MOZ_ASSERT(lineno == lazy->lineno());
|
||||
MOZ_ASSERT(column == lazy->column());
|
||||
// We can assert we have no inner functions because we don't
|
||||
// relazify scripts with inner functions. See
|
||||
// JSFunction::createScriptForLazilyInterpretedFunction.
|
||||
MOZ_ASSERT(lazy->numInnerFunctions() == 0);
|
||||
}
|
||||
|
||||
if (!xdr->codeUint64(&packedFields))
|
||||
return false;
|
||||
|
||||
if (mode == XDR_DECODE) {
|
||||
lazy.set(LazyScript::Create(cx, fun, packedFields, begin, end, lineno, column));
|
||||
lazy.set(LazyScript::Create(cx, fun, script, enclosingScope, script,
|
||||
packedFields, begin, end, lineno, column));
|
||||
|
||||
// As opposed to XDRLazyScript, we need to restore the runtime bits
|
||||
// of the script, as we are trying to match the fact this function
|
||||
// has already been parsed and that it would need to be re-lazified.
|
||||
lazy->initRuntimeFields(packedFields);
|
||||
|
||||
MOZ_ASSERT(!lazy->sourceObject());
|
||||
lazy->setParent(enclosingScope, &script->scriptSourceUnwrap());
|
||||
}
|
||||
}
|
||||
|
||||
@ -526,6 +528,9 @@ XDRRelazificationInfo(XDRState<mode>* xdr, HandleFunction fun, HandleScript scri
|
||||
if (!XDRLazyFreeVariables(xdr, lazy))
|
||||
return false;
|
||||
|
||||
// No need to do anything with inner functions, since we asserted we don't
|
||||
// have any.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1143,7 +1148,8 @@ js::XDRLazyScript(XDRState<mode>* xdr, HandleObject enclosingScope, HandleScript
|
||||
}
|
||||
|
||||
if (mode == XDR_DECODE)
|
||||
lazy.set(LazyScript::Create(cx, fun, packedFields, begin, end, lineno, column));
|
||||
lazy.set(LazyScript::Create(cx, fun, NullPtr(), enclosingScope, enclosingScript,
|
||||
packedFields, begin, end, lineno, column));
|
||||
}
|
||||
|
||||
// Code free variables.
|
||||
@ -1167,15 +1173,6 @@ js::XDRLazyScript(XDRState<mode>* xdr, HandleObject enclosingScope, HandleScript
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == XDR_DECODE) {
|
||||
MOZ_ASSERT(!lazy->sourceObject());
|
||||
ScriptSourceObject* sourceObject = &enclosingScript->scriptSourceUnwrap();
|
||||
|
||||
// Set the enclosing scope of the lazy function, this would later be
|
||||
// used to define the environment when the function would be used.
|
||||
lazy->setParent(enclosingScope, sourceObject);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3826,6 +3823,8 @@ LazyScript::CreateRaw(ExclusiveContext* cx, HandleFunction fun,
|
||||
|
||||
/* static */ LazyScript*
|
||||
LazyScript::Create(ExclusiveContext* cx, HandleFunction fun,
|
||||
HandleScript script, HandleObject enclosingScope,
|
||||
HandleScript sourceObjectScript,
|
||||
uint64_t packedFields, uint32_t begin, uint32_t end,
|
||||
uint32_t lineno, uint32_t column)
|
||||
{
|
||||
@ -3851,6 +3850,15 @@ LazyScript::Create(ExclusiveContext* cx, HandleFunction fun,
|
||||
for (i = 0, num = res->numInnerFunctions(); i < num; i++)
|
||||
functions[i].init(dummyFun);
|
||||
|
||||
// Set the enclosing scope of the lazy function, this would later be
|
||||
// used to define the environment when the function would be used.
|
||||
MOZ_ASSERT(!res->sourceObject());
|
||||
res->setParent(enclosingScope, &sourceObjectScript->scriptSourceUnwrap());
|
||||
|
||||
MOZ_ASSERT(!res->maybeScript());
|
||||
if (script)
|
||||
res->initScript(script);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1919,7 +1919,15 @@ class LazyScript : public gc::TenuredCell
|
||||
// Create a LazyScript and initialize the freeVariables and the
|
||||
// innerFunctions with dummy values to be replaced in a later initialization
|
||||
// phase.
|
||||
//
|
||||
// The "script" argument to this function can be null. If it's non-null,
|
||||
// then this LazyScript should be associated with the given JSScript.
|
||||
//
|
||||
// The sourceObjectScript argument must be non-null and is the script that
|
||||
// should be used to get the sourceObject_ of this lazyScript.
|
||||
static LazyScript* Create(ExclusiveContext* cx, HandleFunction fun,
|
||||
HandleScript script, HandleObject enclosingScope,
|
||||
HandleScript sourceObjectScript,
|
||||
uint64_t packedData, uint32_t begin, uint32_t end,
|
||||
uint32_t lineno, uint32_t column);
|
||||
|
||||
|
@ -336,6 +336,10 @@ function jsTestDriverBrowserInit()
|
||||
{
|
||||
properties.version = '1.8';
|
||||
}
|
||||
else if (properties.test.match(/^ecma_6\/extensions/))
|
||||
{
|
||||
properties.version = '1.8';
|
||||
}
|
||||
}
|
||||
|
||||
// default to language=type;text/javascript. required for
|
||||
|
@ -1,4 +1,6 @@
|
||||
// Enable "let" in shell builds. So silly.
|
||||
// NOTE: This only turns on 1.8.5 in shell builds. The browser requires the
|
||||
// futzing in js/src/tests/browser.js (which only turns on 1.8, the most
|
||||
// the browser supports).
|
||||
if (typeof version != 'undefined')
|
||||
version(185);
|
||||
|
||||
|
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
var gTestfile = "for-loop-with-bindings-added-at-runtime.js";
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 1149797;
|
||||
var summary =
|
||||
"Don't assert when freshening the scope chain for a for-loop whose head " +
|
||||
"contains a lexical declaration, where the loop body might add more " +
|
||||
"bindings at runtime";
|
||||
|
||||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
/**************
|
||||
* BEGIN TEST *
|
||||
**************/
|
||||
|
||||
for (let x = 0; x < 9; ++x)
|
||||
eval("var y");
|
||||
|
||||
{
|
||||
for (let x = 0; x < 9; ++x)
|
||||
eval("var y");
|
||||
}
|
||||
|
||||
function f1()
|
||||
{
|
||||
for (let x = 0; x < 9; ++x)
|
||||
eval("var y");
|
||||
}
|
||||
f1();
|
||||
|
||||
function f2()
|
||||
{
|
||||
{
|
||||
for (let x = 0; x < 9; ++x)
|
||||
eval("var y");
|
||||
}
|
||||
}
|
||||
f2();
|
||||
|
||||
for (let x = 0; x < 9; ++x)
|
||||
{
|
||||
// deliberately inside a block statement
|
||||
eval("var y");
|
||||
}
|
||||
|
||||
{
|
||||
for (let x = 0; x < 9; ++x)
|
||||
{
|
||||
// deliberately inside a block statement
|
||||
eval("var y");
|
||||
}
|
||||
}
|
||||
|
||||
function g1()
|
||||
{
|
||||
for (let x = 0; x < 9; ++x)
|
||||
{
|
||||
// deliberately inside a block statement
|
||||
eval("var y");
|
||||
}
|
||||
}
|
||||
g1();
|
||||
|
||||
function g2()
|
||||
{
|
||||
{
|
||||
for (let x = 0; x < 9; ++x)
|
||||
{
|
||||
// deliberately inside a block statement
|
||||
eval("var y");
|
||||
}
|
||||
}
|
||||
}
|
||||
g2();
|
||||
|
||||
for (let x = 0; x < 9; ++x) {
|
||||
(function() {
|
||||
eval("var y");
|
||||
})();
|
||||
}
|
||||
|
||||
{
|
||||
for (let x = 0; x < 9; ++x)
|
||||
{
|
||||
// deliberately inside a block statement
|
||||
(function() {
|
||||
eval("var y");
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
function h1()
|
||||
{
|
||||
for (let x = 0; x < 9; ++x)
|
||||
{
|
||||
// deliberately inside a block statement
|
||||
(function() {
|
||||
eval("var y");
|
||||
})();
|
||||
}
|
||||
}
|
||||
h1();
|
||||
|
||||
function h2()
|
||||
{
|
||||
{
|
||||
for (let x = 0; x < 9; ++x)
|
||||
{
|
||||
// deliberately inside a block statement
|
||||
(function() { eval("var y"); })();
|
||||
}
|
||||
}
|
||||
}
|
||||
h2();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
||||
|
||||
print("Tests complete");
|
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
var gTestfile =
|
||||
"for-loop-with-lexical-declaration-and-nested-function-statement.js";
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 1149797;
|
||||
var summary =
|
||||
"Don't assert when freshening the scope chain for a for-loop whose head " +
|
||||
"contains a lexical declaration, where the loop body might add more " +
|
||||
"bindings at runtime";
|
||||
|
||||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
/**************
|
||||
* BEGIN TEST *
|
||||
**************/
|
||||
|
||||
for (let x = 0; x < 9; ++x)
|
||||
function q1() {}
|
||||
|
||||
{
|
||||
for (let x = 0; x < 9; ++x)
|
||||
function q2() {}
|
||||
}
|
||||
|
||||
function f1()
|
||||
{
|
||||
for (let x = 0; x < 9; ++x)
|
||||
function q3() {}
|
||||
}
|
||||
f1();
|
||||
|
||||
function f2()
|
||||
{
|
||||
{
|
||||
for (let x = 0; x < 9; ++x)
|
||||
function q4() {}
|
||||
}
|
||||
}
|
||||
f2();
|
||||
|
||||
for (let x = 0; x < 9; ++x)
|
||||
{
|
||||
// deliberately inside a block statement
|
||||
function q5() {}
|
||||
}
|
||||
|
||||
{
|
||||
for (let x = 0; x < 9; ++x)
|
||||
{
|
||||
// deliberately inside a block statement
|
||||
function q6() {}
|
||||
}
|
||||
}
|
||||
|
||||
function g1()
|
||||
{
|
||||
for (let x = 0; x < 9; ++x)
|
||||
{
|
||||
// deliberately inside a block statement
|
||||
function q7() {}
|
||||
}
|
||||
}
|
||||
g1();
|
||||
|
||||
function g2()
|
||||
{
|
||||
{
|
||||
for (let x = 0; x < 9; ++x)
|
||||
{
|
||||
// deliberately inside a block statement
|
||||
function q8() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
g2();
|
||||
|
||||
for (let x = 0; x < 9; ++x) {
|
||||
(function() {
|
||||
eval("function q9() {}");
|
||||
})();
|
||||
}
|
||||
|
||||
{
|
||||
for (let x = 0; x < 9; ++x)
|
||||
{
|
||||
// deliberately inside a block statement
|
||||
(function() {
|
||||
eval("function q10() {}");
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
function h1()
|
||||
{
|
||||
for (let x = 0; x < 9; ++x)
|
||||
{
|
||||
// deliberately inside a block statement
|
||||
(function() {
|
||||
eval("function q11() {}");
|
||||
})();
|
||||
}
|
||||
}
|
||||
h1();
|
||||
|
||||
function h2()
|
||||
{
|
||||
{
|
||||
for (let x = 0; x < 9; ++x)
|
||||
{
|
||||
// deliberately inside a block statement
|
||||
(function() { eval("function q12() {}"); })();
|
||||
}
|
||||
}
|
||||
}
|
||||
h2();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
||||
|
||||
print("Tests complete");
|
@ -0,0 +1,5 @@
|
||||
// NOTE: This only turns on 1.8.5 in shell builds. The browser requires the
|
||||
// futzing in js/src/tests/browser.js (which only turns on 1.8, the most
|
||||
// the browser supports).
|
||||
if (typeof version != 'undefined')
|
||||
version(185);
|
@ -567,11 +567,14 @@ struct AutoStopwatch final
|
||||
ULARGE_INTEGER userTimeInt;
|
||||
kernelTimeInt.LowPart = kernelFileTime.dwLowDateTime;
|
||||
kernelTimeInt.HighPart = kernelFileTime.dwHighDateTime;
|
||||
*systemTime = kernelTimeInt.QuadPart / 10; // 100 ns to 1 us
|
||||
// Convert 100 ns to 1 us, make sure that the result is monotonic
|
||||
*systemTime = runtime_-> stopwatch.systemTimeFix.monotonize(kernelTimeInt.QuadPart / 10);
|
||||
|
||||
userTimeInt.LowPart = userFileTime.dwLowDateTime;
|
||||
userTimeInt.HighPart = userFileTime.dwHighDateTime;
|
||||
*userTime = userTimeInt.QuadPart / 10; // 100 ns to 1 us
|
||||
// Convert 100 ns to 1 us, make sure that the result is monotonic
|
||||
*userTime = runtime_-> stopwatch.userTimeFix.monotonize(userTimeInt.QuadPart / 10);
|
||||
|
||||
#endif // defined(XP_UNIX) || defined(XP_WIN)
|
||||
|
||||
return true;
|
||||
|
@ -1111,109 +1111,6 @@ UpdateShapeTypeAndValue(ExclusiveContext* cx, NativeObject* obj, Shape* shape, c
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
NativeSetExistingDataProperty(JSContext* cx, HandleNativeObject obj, HandleShape shape,
|
||||
HandleValue v, HandleValue receiver, ObjectOpResult& result);
|
||||
|
||||
static inline bool
|
||||
DefinePropertyOrElement(ExclusiveContext* cx, HandleNativeObject obj, HandleId id,
|
||||
GetterOp getter, SetterOp setter, unsigned attrs, HandleValue value,
|
||||
bool callSetterAfterwards, ObjectOpResult& result)
|
||||
{
|
||||
MOZ_ASSERT(getter != JS_PropertyStub);
|
||||
MOZ_ASSERT(setter != JS_StrictPropertyStub);
|
||||
|
||||
/* Use dense storage for new indexed properties where possible. */
|
||||
if (JSID_IS_INT(id) &&
|
||||
!getter &&
|
||||
!setter &&
|
||||
attrs == JSPROP_ENUMERATE &&
|
||||
(!obj->isIndexed() || !obj->containsPure(id)) &&
|
||||
!IsAnyTypedArray(obj))
|
||||
{
|
||||
uint32_t index = JSID_TO_INT(id);
|
||||
if (WouldDefinePastNonwritableLength(obj, index))
|
||||
return result.fail(JSMSG_CANT_DEFINE_PAST_ARRAY_LENGTH);
|
||||
|
||||
NativeObject::EnsureDenseResult edResult = obj->ensureDenseElements(cx, index, 1);
|
||||
if (edResult == NativeObject::ED_FAILED)
|
||||
return false;
|
||||
if (edResult == NativeObject::ED_OK) {
|
||||
obj->setDenseElementWithType(cx, index, value);
|
||||
if (!CallAddPropertyHookDense(cx, obj, index, value))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
}
|
||||
|
||||
if (obj->is<ArrayObject>()) {
|
||||
Rooted<ArrayObject*> arr(cx, &obj->as<ArrayObject>());
|
||||
if (id == NameToId(cx->names().length)) {
|
||||
if (!cx->shouldBeJSContext())
|
||||
return false;
|
||||
return ArraySetLength(cx->asJSContext(), arr, id, attrs, value, result);
|
||||
}
|
||||
|
||||
uint32_t index;
|
||||
if (IdIsIndex(id, &index)) {
|
||||
if (WouldDefinePastNonwritableLength(obj, index))
|
||||
return result.fail(JSMSG_CANT_DEFINE_PAST_ARRAY_LENGTH);
|
||||
}
|
||||
}
|
||||
|
||||
// Don't define new indexed properties on typed arrays.
|
||||
if (IsAnyTypedArray(obj)) {
|
||||
uint64_t index;
|
||||
if (IsTypedArrayIndex(id, &index))
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
|
||||
RootedShape shape(cx, NativeObject::putProperty(cx, obj, id, getter, setter,
|
||||
SHAPE_INVALID_SLOT, attrs, 0));
|
||||
if (!shape)
|
||||
return false;
|
||||
|
||||
if (!UpdateShapeTypeAndValue(cx, obj, shape, value))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Clear any existing dense index after adding a sparse indexed property,
|
||||
* and investigate converting the object to dense indexes.
|
||||
*/
|
||||
if (JSID_IS_INT(id)) {
|
||||
if (!obj->maybeCopyElementsForWrite(cx))
|
||||
return false;
|
||||
|
||||
uint32_t index = JSID_TO_INT(id);
|
||||
NativeObject::removeDenseElementForSparseIndex(cx, obj, index);
|
||||
NativeObject::EnsureDenseResult edResult = NativeObject::maybeDensifySparseElements(cx, obj);
|
||||
if (edResult == NativeObject::ED_FAILED)
|
||||
return false;
|
||||
if (edResult == NativeObject::ED_OK) {
|
||||
MOZ_ASSERT(!setter);
|
||||
if (!CallAddPropertyHookDense(cx, obj, index, value))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
}
|
||||
|
||||
if (!CallAddPropertyHook(cx, obj, shape, value))
|
||||
return false;
|
||||
|
||||
if (callSetterAfterwards && setter) {
|
||||
MOZ_ASSERT(!(attrs & JSPROP_GETTER));
|
||||
MOZ_ASSERT(!(attrs & JSPROP_SETTER));
|
||||
if (!cx->shouldBeJSContext())
|
||||
return false;
|
||||
RootedValue receiver(cx, ObjectValue(*obj));
|
||||
return NativeSetExistingDataProperty(cx->asJSContext(), obj, shape, value, receiver,
|
||||
result);
|
||||
}
|
||||
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
static unsigned
|
||||
ApplyOrDefaultAttributes(unsigned attrs, const Shape* shape = nullptr)
|
||||
{
|
||||
@ -1297,10 +1194,12 @@ PurgeScopeChain(ExclusiveContext* cx, HandleObject obj, HandleId id)
|
||||
*/
|
||||
static inline bool
|
||||
CheckAccessorRedefinition(ExclusiveContext* cx, HandleObject obj, HandleShape shape,
|
||||
GetterOp getter, SetterOp setter, HandleId id, unsigned attrs)
|
||||
Handle<PropertyDescriptor> desc)
|
||||
{
|
||||
MOZ_ASSERT(shape->isAccessorDescriptor());
|
||||
if (shape->configurable() || (getter == shape->getter() && setter == shape->setter()))
|
||||
if (shape->configurable())
|
||||
return true;
|
||||
if (desc.getter() == shape->getter() && desc.setter() == shape->setter())
|
||||
return true;
|
||||
|
||||
/*
|
||||
@ -1309,7 +1208,7 @@ CheckAccessorRedefinition(ExclusiveContext* cx, HandleObject obj, HandleShape sh
|
||||
* never have such a thing on its proto chain directly on the web, so we
|
||||
* should be OK optimizing access to accessors found on such an object.
|
||||
*/
|
||||
if ((attrs & JSPROP_REDEFINE_NONCONFIGURABLE) &&
|
||||
if ((desc.attributes() & JSPROP_REDEFINE_NONCONFIGURABLE) &&
|
||||
obj->is<GlobalObject>() &&
|
||||
!obj->getClass()->isDOMClass())
|
||||
{
|
||||
@ -1319,44 +1218,134 @@ CheckAccessorRedefinition(ExclusiveContext* cx, HandleObject obj, HandleShape sh
|
||||
if (!cx->isJSContext())
|
||||
return false;
|
||||
|
||||
return Throw(cx->asJSContext(), id, JSMSG_CANT_REDEFINE_PROP);
|
||||
return Throw(cx->asJSContext(), shape->propid(), JSMSG_CANT_REDEFINE_PROP);
|
||||
}
|
||||
|
||||
static bool
|
||||
AddOrChangeProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id,
|
||||
Handle<PropertyDescriptor> desc)
|
||||
{
|
||||
desc.assertComplete();
|
||||
|
||||
if (!PurgeScopeChain(cx, obj, id))
|
||||
return false;
|
||||
|
||||
// Use dense storage for new indexed properties where possible.
|
||||
if (JSID_IS_INT(id) &&
|
||||
!desc.getter() &&
|
||||
!desc.setter() &&
|
||||
desc.attributes() == JSPROP_ENUMERATE &&
|
||||
(!obj->isIndexed() || !obj->containsPure(id)) &&
|
||||
!IsAnyTypedArray(obj))
|
||||
{
|
||||
uint32_t index = JSID_TO_INT(id);
|
||||
NativeObject::EnsureDenseResult edResult = obj->ensureDenseElements(cx, index, 1);
|
||||
if (edResult == NativeObject::ED_FAILED)
|
||||
return false;
|
||||
if (edResult == NativeObject::ED_OK) {
|
||||
obj->setDenseElementWithType(cx, index, desc.value());
|
||||
if (!CallAddPropertyHookDense(cx, obj, index, desc.value()))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
RootedShape shape(cx, NativeObject::putProperty(cx, obj, id, desc.getter(), desc.setter(),
|
||||
SHAPE_INVALID_SLOT, desc.attributes(), 0));
|
||||
if (!shape)
|
||||
return false;
|
||||
|
||||
if (!UpdateShapeTypeAndValue(cx, obj, shape, desc.value()))
|
||||
return false;
|
||||
|
||||
// Clear any existing dense index after adding a sparse indexed property,
|
||||
// and investigate converting the object to dense indexes.
|
||||
if (JSID_IS_INT(id)) {
|
||||
if (!obj->maybeCopyElementsForWrite(cx))
|
||||
return false;
|
||||
|
||||
uint32_t index = JSID_TO_INT(id);
|
||||
NativeObject::removeDenseElementForSparseIndex(cx, obj, index);
|
||||
NativeObject::EnsureDenseResult edResult =
|
||||
NativeObject::maybeDensifySparseElements(cx, obj);
|
||||
if (edResult == NativeObject::ED_FAILED)
|
||||
return false;
|
||||
if (edResult == NativeObject::ED_OK) {
|
||||
MOZ_ASSERT(!desc.setter());
|
||||
return CallAddPropertyHookDense(cx, obj, index, desc.value());
|
||||
}
|
||||
}
|
||||
|
||||
return CallAddPropertyHook(cx, obj, shape, desc.value());
|
||||
}
|
||||
|
||||
bool
|
||||
js::NativeDefineProperty(ExclusiveContext* cx, HandleNativeObject obj, HandleId id,
|
||||
Handle<PropertyDescriptor> desc,
|
||||
Handle<PropertyDescriptor> desc_,
|
||||
ObjectOpResult& result)
|
||||
{
|
||||
desc.assertValid();
|
||||
desc_.assertValid();
|
||||
|
||||
GetterOp getter = desc.getter();
|
||||
SetterOp setter = desc.setter();
|
||||
unsigned attrs = desc.attributes();
|
||||
// Section numbers and step numbers below refer to ES6 draft rev 36
|
||||
// (17 March 2015).
|
||||
//
|
||||
// This function aims to implement 9.1.6 [[DefineOwnProperty]] as well as
|
||||
// the [[DefineOwnProperty]] methods described in 9.4.2.1 (arrays), 9.4.4.2
|
||||
// (arguments), and 9.4.5.3 (typed array views).
|
||||
|
||||
MOZ_ASSERT(!(attrs & JSPROP_PROPOP_ACCESSORS));
|
||||
// Dispense with custom behavior of exotic native objects first.
|
||||
if (obj->is<ArrayObject>()) {
|
||||
// 9.4.2.1 step 2. Redefining an array's length is very special.
|
||||
Rooted<ArrayObject*> arr(cx, &obj->as<ArrayObject>());
|
||||
if (id == NameToId(cx->names().length)) {
|
||||
if (!cx->shouldBeJSContext())
|
||||
return false;
|
||||
return ArraySetLength(cx->asJSContext(), arr, id, desc_.attributes(), desc_.value(),
|
||||
result);
|
||||
}
|
||||
|
||||
AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
|
||||
// 9.4.2.1 step 3. Don't extend a fixed-length array.
|
||||
uint32_t index;
|
||||
if (IdIsIndex(id, &index)) {
|
||||
if (WouldDefinePastNonwritableLength(obj, index))
|
||||
return result.fail(JSMSG_CANT_DEFINE_PAST_ARRAY_LENGTH);
|
||||
}
|
||||
} else if (IsAnyTypedArray(obj)) {
|
||||
// 9.4.5.3 step 3. Indexed properties of typed arrays are special.
|
||||
uint64_t index;
|
||||
if (IsTypedArrayIndex(id, &index)) {
|
||||
if (!cx->shouldBeJSContext())
|
||||
return false;
|
||||
return DefineTypedArrayElement(cx->asJSContext(), obj, index, desc_, result);
|
||||
}
|
||||
} else if (obj->is<ArgumentsObject>()) {
|
||||
if (id == NameToId(cx->names().length)) {
|
||||
// Either we are resolving the .length property on this object, or
|
||||
// redefining it. In the latter case only, we must set a bit. To
|
||||
// distinguish the two cases, we note that when resolving, the
|
||||
// property won't already exist; whereas the first time it is
|
||||
// redefined, it will.
|
||||
if (obj->containsPure(id))
|
||||
obj->as<ArgumentsObject>().markLengthOverridden();
|
||||
}
|
||||
}
|
||||
|
||||
Rooted<PropertyDescriptor> desc(cx, desc_);
|
||||
|
||||
RootedShape shape(cx);
|
||||
RootedValue updateValue(cx, desc.value());
|
||||
bool shouldDefine = true;
|
||||
|
||||
/*
|
||||
* If defining a getter or setter, we must check for its counterpart and
|
||||
* update the attributes and property ops. A getter or setter is really
|
||||
* only half of a property.
|
||||
*/
|
||||
// If defining a getter or setter, we must check for its counterpart and
|
||||
// update the attributes and property ops. A getter or setter is really
|
||||
// only half of a property.
|
||||
if (desc.isAccessorDescriptor()) {
|
||||
if (!NativeLookupOwnProperty<CanGC>(cx, obj, id, &shape))
|
||||
return false;
|
||||
if (shape) {
|
||||
/*
|
||||
* If we are defining a getter whose setter was already defined, or
|
||||
* vice versa, finish the job via obj->changeProperty.
|
||||
*/
|
||||
// If we are defining a getter whose setter was already defined, or
|
||||
// vice versa, finish the job via obj->changeProperty.
|
||||
if (IsImplicitDenseOrTypedArrayElement(shape)) {
|
||||
if (IsAnyTypedArray(obj)) {
|
||||
/* Ignore getter/setter properties added to typed arrays. */
|
||||
// Ignore getter/setter properties added to typed arrays.
|
||||
return result.succeed();
|
||||
}
|
||||
if (!NativeObject::sparsifyDenseElement(cx, obj, JSID_TO_INT(id)))
|
||||
@ -1364,28 +1353,35 @@ js::NativeDefineProperty(ExclusiveContext* cx, HandleNativeObject obj, HandleId
|
||||
shape = obj->lookup(cx, id);
|
||||
}
|
||||
if (shape->isAccessorDescriptor()) {
|
||||
if (!CheckAccessorRedefinition(cx, obj, shape, getter, setter, id, attrs))
|
||||
if (!CheckAccessorRedefinition(cx, obj, shape, desc))
|
||||
return false;
|
||||
attrs = ApplyOrDefaultAttributes(attrs, shape);
|
||||
shape = NativeObject::changeProperty(cx, obj, shape,
|
||||
attrs | JSPROP_GETTER | JSPROP_SETTER,
|
||||
(attrs & JSPROP_GETTER)
|
||||
? getter
|
||||
: shape->getter(),
|
||||
(attrs & JSPROP_SETTER)
|
||||
? setter
|
||||
: shape->setter());
|
||||
|
||||
desc.setAttributes(ApplyOrDefaultAttributes(desc.attributes(), shape));
|
||||
if (!desc.hasGetterObject())
|
||||
desc.setGetter(shape->getter());
|
||||
if (!desc.hasSetterObject())
|
||||
desc.setSetter(shape->setter());
|
||||
desc.attributesRef() |= JSPROP_GETTER | JSPROP_SETTER;
|
||||
desc.assertComplete();
|
||||
|
||||
shape = NativeObject::changeProperty(cx, obj, shape, desc.attributes(),
|
||||
desc.getter(), desc.setter());
|
||||
if (!shape)
|
||||
return false;
|
||||
shouldDefine = false;
|
||||
if (!PurgeScopeChain(cx, obj, id))
|
||||
return false;
|
||||
|
||||
JS_ALWAYS_TRUE(UpdateShapeTypeAndValue(cx, obj, shape, desc.value()));
|
||||
if (!CallAddPropertyHook(cx, obj, shape, desc.value()))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
}
|
||||
|
||||
// Either we are converting a data property to an accessor property, or
|
||||
// creating a new accessor property; either way [[Get]] and [[Set]]
|
||||
// must both be filled in.
|
||||
if (shouldDefine)
|
||||
attrs |= JSPROP_GETTER | JSPROP_SETTER;
|
||||
desc.attributesRef() |= JSPROP_GETTER | JSPROP_SETTER;
|
||||
} else if (desc.hasValue()) {
|
||||
// If we did a normal lookup here, it would cause resolve hook recursion in
|
||||
// the following case. Suppose the first script we run in a lazy global is
|
||||
@ -1405,13 +1401,14 @@ js::NativeDefineProperty(ExclusiveContext* cx, HandleNativeObject obj, HandleId
|
||||
// If any other JSPROP_IGNORE_* attributes are present, copy the
|
||||
// corresponding JSPROP_* attributes from the existing property.
|
||||
if (IsImplicitDenseOrTypedArrayElement(shape)) {
|
||||
attrs = ApplyAttributes(attrs, true, true, !IsAnyTypedArray(obj));
|
||||
desc.setAttributes(ApplyAttributes(desc.attributes(), true, true,
|
||||
!IsAnyTypedArray(obj)));
|
||||
} else {
|
||||
attrs = ApplyOrDefaultAttributes(attrs, shape);
|
||||
desc.setAttributes(ApplyOrDefaultAttributes(desc.attributes(), shape));
|
||||
|
||||
// Do not redefine a nonconfigurable accessor property.
|
||||
if (shape->isAccessorDescriptor()) {
|
||||
if (!CheckAccessorRedefinition(cx, obj, shape, getter, setter, id, attrs))
|
||||
if (!CheckAccessorRedefinition(cx, obj, shape, desc))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1425,11 +1422,9 @@ js::NativeDefineProperty(ExclusiveContext* cx, HandleNativeObject obj, HandleId
|
||||
// Don't forget about arrays.
|
||||
if (IsImplicitDenseOrTypedArrayElement(shape)) {
|
||||
if (IsAnyTypedArray(obj)) {
|
||||
/*
|
||||
* Silently ignore attempts to change individual index attributes.
|
||||
* FIXME: Uses the same broken behavior as for accessors. This should
|
||||
* fail.
|
||||
*/
|
||||
// Silently ignore attempts to change individual index attributes.
|
||||
// FIXME: Uses the same broken behavior as for accessors. This should
|
||||
// fail.
|
||||
return result.succeed();
|
||||
}
|
||||
if (!NativeObject::sparsifyDenseElement(cx, obj, JSID_TO_INT(id)))
|
||||
@ -1438,53 +1433,42 @@ js::NativeDefineProperty(ExclusiveContext* cx, HandleNativeObject obj, HandleId
|
||||
}
|
||||
|
||||
if (shape->isAccessorDescriptor() &&
|
||||
!CheckAccessorRedefinition(cx, obj, shape, getter, setter, id, attrs))
|
||||
!CheckAccessorRedefinition(cx, obj, shape, desc))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
attrs = ApplyOrDefaultAttributes(attrs, shape);
|
||||
desc.setAttributes(ApplyOrDefaultAttributes(desc.attributes(), shape));
|
||||
|
||||
if (shape->isAccessorDescriptor() && !(attrs & JSPROP_IGNORE_READONLY)) {
|
||||
if (shape->isAccessorDescriptor() && desc.hasWritable()) {
|
||||
// ES6 draft 2014-10-14 9.1.6.3 step 7.c: Since [[Writable]]
|
||||
// is present, change the existing accessor property to a data
|
||||
// property.
|
||||
updateValue = UndefinedValue();
|
||||
desc.value().setUndefined();
|
||||
} else {
|
||||
// We are at most changing some attributes, and cannot convert
|
||||
// from data descriptor to accessor, or vice versa. Take
|
||||
// everything from the shape that we aren't changing.
|
||||
uint32_t propMask = JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT;
|
||||
attrs = (shape->attributes() & ~propMask) | (attrs & propMask);
|
||||
getter = shape->getter();
|
||||
setter = shape->setter();
|
||||
desc.setAttributes((shape->attributes() & ~propMask) |
|
||||
(desc.attributes() & propMask));
|
||||
desc.setGetter(shape->getter());
|
||||
desc.setSetter(shape->setter());
|
||||
if (shape->hasSlot())
|
||||
updateValue = obj->getSlot(shape->slot());
|
||||
desc.value().set(obj->getSlot(shape->slot()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Purge the property cache of any properties named by id that are about
|
||||
* to be shadowed in obj's scope chain.
|
||||
*/
|
||||
if (!PurgeScopeChain(cx, obj, id))
|
||||
return false;
|
||||
// Dispense with any remaining JSPROP_IGNORE_* attributes. Any bits that
|
||||
// needed to be copied from an existing property have been copied by
|
||||
// now. Since we can never get here with JSPROP_IGNORE_VALUE relevant, just
|
||||
// clear it.
|
||||
desc.setAttributes(ApplyOrDefaultAttributes(desc.attributes()) & ~JSPROP_IGNORE_VALUE);
|
||||
|
||||
if (shouldDefine) {
|
||||
// Handle the default cases here. Anyone that wanted to set non-default attributes has
|
||||
// cleared the IGNORE flags by now. Since we can never get here with JSPROP_IGNORE_VALUE
|
||||
// relevant, just clear it.
|
||||
attrs = ApplyOrDefaultAttributes(attrs) & ~JSPROP_IGNORE_VALUE;
|
||||
return DefinePropertyOrElement(cx, obj, id, getter, setter,
|
||||
attrs, updateValue, false, result);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(shape);
|
||||
|
||||
JS_ALWAYS_TRUE(UpdateShapeTypeAndValue(cx, obj, shape, updateValue));
|
||||
|
||||
if (!CallAddPropertyHook(cx, obj, shape, updateValue))
|
||||
// At this point, no mutation has happened yet, but all ES6 error cases
|
||||
// have been dealt with.
|
||||
if (!AddOrChangeProperty(cx, obj, id, desc))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
@ -1962,6 +1946,55 @@ MaybeReportUndeclaredVarAssignment(JSContext* cx, JSString* propname)
|
||||
JSMSG_UNDECLARED_VAR, bytes.ptr());
|
||||
}
|
||||
|
||||
/*
|
||||
* Finish assignment to a shapeful data property of a native object obj. This
|
||||
* conforms to no standard and there is a lot of legacy baggage here.
|
||||
*/
|
||||
static bool
|
||||
NativeSetExistingDataProperty(JSContext* cx, HandleNativeObject obj, HandleShape shape,
|
||||
HandleValue v, HandleValue receiver, ObjectOpResult& result)
|
||||
{
|
||||
MOZ_ASSERT(obj->isNative());
|
||||
MOZ_ASSERT(shape->isDataDescriptor());
|
||||
|
||||
if (shape->hasDefaultSetter()) {
|
||||
if (shape->hasSlot()) {
|
||||
// The common path. Standard data property.
|
||||
|
||||
// Global properties declared with 'var' will be initially
|
||||
// defined with an undefined value, so don't treat the initial
|
||||
// assignments to such properties as overwrites.
|
||||
bool overwriting = !obj->is<GlobalObject>() || !obj->getSlot(shape->slot()).isUndefined();
|
||||
obj->setSlotWithType(cx, shape, v, overwriting);
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
// Bizarre: shared (slotless) property that's writable but has no
|
||||
// JSSetterOp. JS code can't define such a property, but it can be done
|
||||
// through the JSAPI. Treat it as non-writable.
|
||||
return result.fail(JSMSG_GETTER_ONLY);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!obj->is<DynamicWithObject>()); // See bug 1128681.
|
||||
|
||||
uint32_t sample = cx->runtime()->propertyRemovals;
|
||||
RootedId id(cx, shape->propid());
|
||||
RootedValue value(cx, v);
|
||||
if (!CallJSSetterOp(cx, shape->setterOp(), obj, id, &value, result))
|
||||
return false;
|
||||
|
||||
// Update any slot for the shape with the value produced by the setter,
|
||||
// unless the setter deleted the shape.
|
||||
if (shape->hasSlot() &&
|
||||
(MOZ_LIKELY(cx->runtime()->propertyRemovals == sample) ||
|
||||
obj->contains(cx, shape)))
|
||||
{
|
||||
obj->setSlot(shape->slot(), value);
|
||||
}
|
||||
|
||||
return true; // result is populated by CallJSSetterOp above.
|
||||
}
|
||||
|
||||
/*
|
||||
* When a [[Set]] operation finds no existing property with the given id
|
||||
* or finds a writable data property on the prototype chain, we end up here.
|
||||
@ -2028,13 +2061,32 @@ js::SetPropertyByDefining(JSContext* cx, HandleObject obj, HandleId id, HandleVa
|
||||
JSSetterOp setter = clasp->setProperty;
|
||||
MOZ_ASSERT(getter != JS_PropertyStub);
|
||||
MOZ_ASSERT(setter != JS_StrictPropertyStub);
|
||||
if (!receiver->is<NativeObject>())
|
||||
return DefineProperty(cx, receiver, id, v, getter, setter, attrs, result);
|
||||
if (!DefineProperty(cx, receiver, id, v, getter, setter, attrs, result))
|
||||
return false;
|
||||
|
||||
// If the receiver is native, there is one more legacy wrinkle: the class
|
||||
// JSSetterOp is called after defining the new property.
|
||||
Rooted<NativeObject*> nativeReceiver(cx, &receiver->as<NativeObject>());
|
||||
return DefinePropertyOrElement(cx, nativeReceiver, id, getter, setter, attrs, v, true, result);
|
||||
if (setter && receiver->is<NativeObject>()) {
|
||||
if (!result)
|
||||
return true;
|
||||
|
||||
Rooted<NativeObject*> nativeReceiver(cx, &receiver->as<NativeObject>());
|
||||
if (!cx->shouldBeJSContext())
|
||||
return false;
|
||||
RootedValue receiverValue(cx, ObjectValue(*receiver));
|
||||
|
||||
// This lookup is a bit unfortunate, but not nearly the most
|
||||
// unfortunate thing about Class getters and setters. Since the above
|
||||
// DefineProperty call succeeded, receiver is native, and the property
|
||||
// has a setter (and thus can't be a dense element), this lookup is
|
||||
// guaranteed to succeed.
|
||||
RootedShape shape(cx, nativeReceiver->lookup(cx, id));
|
||||
MOZ_ASSERT(shape);
|
||||
return NativeSetExistingDataProperty(cx->asJSContext(), nativeReceiver, shape, v,
|
||||
receiverValue, result);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// When setting |id| for |receiver| and |obj| has no property for id, continue
|
||||
@ -2109,55 +2161,6 @@ SetDenseOrTypedArrayElement(JSContext* cx, HandleNativeObject obj, uint32_t inde
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
/*
|
||||
* Finish assignment to a shapeful data property of a native object obj. This
|
||||
* conforms to no standard and there is a lot of legacy baggage here.
|
||||
*/
|
||||
static bool
|
||||
NativeSetExistingDataProperty(JSContext* cx, HandleNativeObject obj, HandleShape shape,
|
||||
HandleValue v, HandleValue receiver, ObjectOpResult& result)
|
||||
{
|
||||
MOZ_ASSERT(obj->isNative());
|
||||
MOZ_ASSERT(shape->isDataDescriptor());
|
||||
|
||||
if (shape->hasDefaultSetter()) {
|
||||
if (shape->hasSlot()) {
|
||||
// The common path. Standard data property.
|
||||
|
||||
// Global properties declared with 'var' will be initially
|
||||
// defined with an undefined value, so don't treat the initial
|
||||
// assignments to such properties as overwrites.
|
||||
bool overwriting = !obj->is<GlobalObject>() || !obj->getSlot(shape->slot()).isUndefined();
|
||||
obj->setSlotWithType(cx, shape, v, overwriting);
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
// Bizarre: shared (slotless) property that's writable but has no
|
||||
// JSSetterOp. JS code can't define such a property, but it can be done
|
||||
// through the JSAPI. Treat it as non-writable.
|
||||
return result.fail(JSMSG_GETTER_ONLY);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!obj->is<DynamicWithObject>()); // See bug 1128681.
|
||||
|
||||
uint32_t sample = cx->runtime()->propertyRemovals;
|
||||
RootedId id(cx, shape->propid());
|
||||
RootedValue value(cx, v);
|
||||
if (!CallJSSetterOp(cx, shape->setterOp(), obj, id, &value, result))
|
||||
return false;
|
||||
|
||||
// Update any slot for the shape with the value produced by the setter,
|
||||
// unless the setter deleted the shape.
|
||||
if (shape->hasSlot() &&
|
||||
(MOZ_LIKELY(cx->runtime()->propertyRemovals == sample) ||
|
||||
obj->contains(cx, shape)))
|
||||
{
|
||||
obj->setSlot(shape->slot(), value);
|
||||
}
|
||||
|
||||
return true; // result is populated by CallJSSetterOp above.
|
||||
}
|
||||
|
||||
/*
|
||||
* Finish the assignment `receiver[id] = v` when an existing property (shape)
|
||||
* has been found on a native object (pobj). This implements ES6 draft rev 32
|
||||
|
@ -1532,6 +1532,28 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||
return isActive_;
|
||||
}
|
||||
|
||||
// Some systems have non-monotonic clocks. While we cannot
|
||||
// improve the precision, we can make sure that our measures
|
||||
// are monotonic nevertheless. We do this by storing the
|
||||
// result of the latest call to the clock and making sure
|
||||
// that the next timestamp is greater or equal.
|
||||
struct MonotonicTimeStamp {
|
||||
MonotonicTimeStamp()
|
||||
: latestGood_(0)
|
||||
{}
|
||||
inline uint64_t monotonize(uint64_t stamp)
|
||||
{
|
||||
if (stamp <= latestGood_)
|
||||
return latestGood_;
|
||||
latestGood_ = stamp;
|
||||
return stamp;
|
||||
}
|
||||
private:
|
||||
uint64_t latestGood_;
|
||||
};
|
||||
MonotonicTimeStamp systemTimeFix;
|
||||
MonotonicTimeStamp userTimeFix;
|
||||
|
||||
private:
|
||||
/**
|
||||
* A map used to collapse compartments belonging to the same
|
||||
|
@ -661,32 +661,19 @@ ClonedBlockObject::copyUnaliasedValues(AbstractFramePtr frame)
|
||||
}
|
||||
|
||||
/* static */ ClonedBlockObject*
|
||||
ClonedBlockObject::clone(ExclusiveContext* cx, Handle<ClonedBlockObject*> block)
|
||||
ClonedBlockObject::clone(JSContext* cx, Handle<ClonedBlockObject*> clonedBlock)
|
||||
{
|
||||
RootedObject enclosing(cx, &block->enclosingScope());
|
||||
Rooted<StaticBlockObject*> staticBlock(cx, &clonedBlock->staticBlock());
|
||||
RootedObject enclosing(cx, &clonedBlock->enclosingScope());
|
||||
|
||||
MOZ_ASSERT(block->getClass() == &BlockObject::class_);
|
||||
|
||||
RootedObjectGroup cloneGroup(cx, block->group());
|
||||
RootedShape cloneShape(cx, block->lastProperty());
|
||||
|
||||
JSObject* obj = JSObject::create(cx, FINALIZE_KIND, gc::TenuredHeap, cloneShape, cloneGroup);
|
||||
if (!obj)
|
||||
Rooted<ClonedBlockObject*> copy(cx, create(cx, staticBlock, enclosing));
|
||||
if (!copy)
|
||||
return nullptr;
|
||||
|
||||
ClonedBlockObject& copy = obj->as<ClonedBlockObject>();
|
||||
for (uint32_t i = 0, count = staticBlock->numVariables(); i < count; i++)
|
||||
copy->setVar(i, clonedBlock->var(i, DONT_CHECK_ALIASING), DONT_CHECK_ALIASING);
|
||||
|
||||
MOZ_ASSERT(!copy.inDictionaryMode());
|
||||
MOZ_ASSERT(copy.isDelegate());
|
||||
MOZ_ASSERT(block->slotSpan() == copy.slotSpan());
|
||||
MOZ_ASSERT(copy.slotSpan() >= copy.numVariables() + RESERVED_SLOTS);
|
||||
|
||||
copy.setReservedSlot(SCOPE_CHAIN_SLOT, block->getReservedSlot(SCOPE_CHAIN_SLOT));
|
||||
|
||||
for (uint32_t i = 0, count = copy.numVariables(); i < count; i++)
|
||||
copy.setVar(i, block->var(i, DONT_CHECK_ALIASING), DONT_CHECK_ALIASING);
|
||||
|
||||
return ©
|
||||
return copy;
|
||||
}
|
||||
|
||||
StaticBlockObject*
|
||||
|
@ -674,7 +674,7 @@ class ClonedBlockObject : public BlockObject
|
||||
* Create a new ClonedBlockObject with the same enclosing scope and
|
||||
* variable values as this.
|
||||
*/
|
||||
static ClonedBlockObject* clone(ExclusiveContext* cx, Handle<ClonedBlockObject*> block);
|
||||
static ClonedBlockObject* clone(JSContext* cx, Handle<ClonedBlockObject*> block);
|
||||
};
|
||||
|
||||
// Internal scope object used by JSOP_BINDNAME upon encountering an
|
||||
|
@ -2105,6 +2105,51 @@ js::StringIsTypedArrayIndex(const char16_t* s, size_t length, uint64_t* indexp);
|
||||
template bool
|
||||
js::StringIsTypedArrayIndex(const Latin1Char* s, size_t length, uint64_t* indexp);
|
||||
|
||||
/* ES6 draft rev 34 (2015 Feb 20) 9.4.5.3 [[DefineOwnProperty]] step 3.c. */
|
||||
bool
|
||||
js::DefineTypedArrayElement(JSContext *cx, HandleObject obj, uint64_t index,
|
||||
Handle<PropertyDescriptor> desc, ObjectOpResult &result)
|
||||
{
|
||||
MOZ_ASSERT(IsAnyTypedArray(obj));
|
||||
|
||||
// These are all substeps of 3.c.
|
||||
// Steps i-vi.
|
||||
// We (wrongly) ignore out of range defines with a value.
|
||||
if (index >= AnyTypedArrayLength(obj))
|
||||
return result.succeed();
|
||||
|
||||
// Step vii.
|
||||
if (desc.isAccessorDescriptor())
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
|
||||
// Step viii.
|
||||
if (desc.hasConfigurable() && desc.configurable())
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
|
||||
// Step ix.
|
||||
if (desc.hasEnumerable() && !desc.enumerable())
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
|
||||
// Step x.
|
||||
if (desc.hasWritable() && !desc.writable())
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
|
||||
// Step xi.
|
||||
if (desc.hasValue()) {
|
||||
double d;
|
||||
if (!ToNumber(cx, desc.value(), &d))
|
||||
return false;
|
||||
|
||||
if (obj->is<TypedArrayObject>())
|
||||
TypedArrayObject::setElement(obj->as<TypedArrayObject>(), index, d);
|
||||
else
|
||||
SharedTypedArrayObject::setElement(obj->as<SharedTypedArrayObject>(), index, d);
|
||||
}
|
||||
|
||||
// Step xii.
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
/* JS Friend API */
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
|
@ -277,6 +277,14 @@ IsTypedArrayIndex(jsid id, uint64_t* indexp)
|
||||
return StringIsTypedArrayIndex(s, length, indexp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Implements [[DefineOwnProperty]] for TypedArrays and SharedTypedArrays
|
||||
* when the property key is a TypedArray index.
|
||||
*/
|
||||
bool
|
||||
DefineTypedArrayElement(JSContext *cx, HandleObject arr, uint64_t index,
|
||||
Handle<PropertyDescriptor> desc, ObjectOpResult &result);
|
||||
|
||||
static inline unsigned
|
||||
TypedArrayShift(Scalar::Type viewType)
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1937,6 +1937,7 @@ ScrollFrameHelper::ScrollFrameHelper(nsContainerFrame* aOuter,
|
||||
, mHasBeenScrolledRecently(false)
|
||||
, mCollapsedResizer(false)
|
||||
, mShouldBuildScrollableLayer(false)
|
||||
, mIsScrollableLayerInRootContainer(false)
|
||||
, mHasBeenScrolled(false)
|
||||
, mIsResolutionSet(false)
|
||||
, mIgnoreMomentumScroll(false)
|
||||
@ -2940,6 +2941,14 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
// adjusted by the APZC automatically.
|
||||
bool usingDisplayPort = aBuilder->IsPaintingToWindow() &&
|
||||
nsLayoutUtils::GetDisplayPort(mOuter->GetContent());
|
||||
|
||||
if (usingDisplayPort) {
|
||||
// There is a display port for this frame, so we want to appear as having
|
||||
// active scrolling, so that animated geometry roots are assigned correctly.
|
||||
mShouldBuildScrollableLayer = true;
|
||||
mIsScrollableLayerInRootContainer = true;
|
||||
}
|
||||
|
||||
bool addScrollBars = mIsRoot && usingDisplayPort && !aBuilder->IsForEventDelivery();
|
||||
|
||||
if (addScrollBars) {
|
||||
@ -3221,7 +3230,7 @@ ScrollFrameHelper::ComputeFrameMetrics(Layer* aLayer,
|
||||
*aClipRect = scrollport;
|
||||
}
|
||||
|
||||
if (!mShouldBuildScrollableLayer) {
|
||||
if (!mShouldBuildScrollableLayer || mIsScrollableLayerInRootContainer) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -500,6 +500,12 @@ public:
|
||||
// scrollable layer. Used for asynchronous scrolling.
|
||||
bool mShouldBuildScrollableLayer:1;
|
||||
|
||||
// Whether we are the root scroll frame that is used for containerful
|
||||
// scrolling with a display port. If true, the scrollable frame
|
||||
// shouldn't attach frame metrics to its layers because the container
|
||||
// will already have the necessary frame metrics.
|
||||
bool mIsScrollableLayerInRootContainer:1;
|
||||
|
||||
// If true, add clipping in ScrollFrameHelper::ComputeFrameMetrics.
|
||||
bool mAddClipRectToLayer:1;
|
||||
|
||||
|
63
layout/reftests/invalidation/layer-splitting-1.html
Normal file
63
layout/reftests/invalidation/layer-splitting-1.html
Normal file
@ -0,0 +1,63 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>Moving the transform under the absolutely-positioned layer should cause that to invalidate</title>
|
||||
|
||||
<style>
|
||||
|
||||
.content {
|
||||
box-sizing: border-box;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.absolute {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
top: 20px;
|
||||
left: 240px;
|
||||
}
|
||||
|
||||
.reftest-no-paint {
|
||||
border-color: lime;
|
||||
}
|
||||
|
||||
.transform {
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="transform content" id="aboutToMoveUnderAbsolute">
|
||||
<!--
|
||||
This transform is active + prerendered, and will move under the
|
||||
absolutely-positioned item.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="absolute reftest-no-paint content">
|
||||
<!--
|
||||
This absolutely-positioned element should get its own PaintedLayer above the
|
||||
transform.
|
||||
|
||||
It shouldn't attempt to pull up an opaque background color from the page,
|
||||
because the transform can move under it.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
function doTest() {
|
||||
document.querySelector("#aboutToMoveUnderAbsolute").style.transform = "translateX(100px)";
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
document.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
|
||||
</script>
|
63
layout/reftests/invalidation/layer-splitting-2.html
Normal file
63
layout/reftests/invalidation/layer-splitting-2.html
Normal file
@ -0,0 +1,63 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>Scrolling shouldn't invalidate the fixed layer</title>
|
||||
|
||||
<style>
|
||||
|
||||
.content {
|
||||
box-sizing: border-box;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.fixed {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
.reftest-no-paint {
|
||||
border-color: lime;
|
||||
}
|
||||
|
||||
.distanceFromTop {
|
||||
margin-top: 240px;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
<div class="distanceFromTop content">
|
||||
<!--
|
||||
This is just a non-uniform item that will be scrolled so that it's between
|
||||
the page background and the fixed layer.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="fixed reftest-no-paint content">
|
||||
<!--
|
||||
This fixed layer gets its own PaintedLayer above the page.
|
||||
|
||||
It shouldn't attempt to pull up an opaque background color from the page,
|
||||
because the page can move under it.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
function doTest() {
|
||||
document.documentElement.scrollTop = 100;
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
document.documentElement.scrollTop = 0;
|
||||
document.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
|
||||
</script>
|
91
layout/reftests/invalidation/layer-splitting-3.html
Normal file
91
layout/reftests/invalidation/layer-splitting-3.html
Normal file
@ -0,0 +1,91 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>Scrolling shouldn't invalidate the fixed items</title>
|
||||
|
||||
<style>
|
||||
|
||||
.content {
|
||||
box-sizing: border-box;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.fixed {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
.reftest-no-paint {
|
||||
border-color: lime;
|
||||
}
|
||||
|
||||
.distanceFromTop {
|
||||
margin-top: 240px;
|
||||
}
|
||||
|
||||
.clip {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.transform {
|
||||
position: relative;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
<div class="fixed reftest-no-paint content">
|
||||
<!--
|
||||
This fixed layer gets its own PaintedLayer above the page.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="distanceFromTop clip">
|
||||
<!--
|
||||
This clip determines the potential pixels that can be affected by the
|
||||
animated transform, *in relation to the scrolled page*. If the page
|
||||
is scrolled, the clip moves relative to the fixed items, so the fixed
|
||||
items need to anticipate the transform getting between them.
|
||||
-->
|
||||
|
||||
<div class="transform content">
|
||||
<!--
|
||||
This is an animated transform item. It can move freely but will be
|
||||
clipped by the .clip element.
|
||||
-->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="fixed reftest-no-paint content">
|
||||
<!--
|
||||
This fixed layer is above the animated transform, in z-order. The
|
||||
transform is clipped in such a way that initially, the clip doesn't
|
||||
intersect the fixed items, but once the page is scrolled, it does.
|
||||
So this fixed item must not share a layer with the lower fixed item.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
function doTest() {
|
||||
document.documentElement.scrollTop = 100;
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
document.documentElement.scrollTop = 0;
|
||||
document.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
// setTimeout(doTest, 500);
|
||||
|
||||
</script>
|
82
layout/reftests/invalidation/layer-splitting-4.html
Normal file
82
layout/reftests/invalidation/layer-splitting-4.html
Normal file
@ -0,0 +1,82 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<meta charset="utf-8">
|
||||
<title>The two items in the scroll box should share a layer, despite all the other stuff that's going on around them</title>
|
||||
|
||||
<style>
|
||||
|
||||
.content {
|
||||
box-sizing: border-box;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border: 1px solid blue;
|
||||
background: white;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
.opacity {
|
||||
opacity: 0.9;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background-color: yellow;
|
||||
will-change: opacity;
|
||||
}
|
||||
|
||||
.overlap {
|
||||
margin-top: -100px;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 240px;
|
||||
width: 400px;
|
||||
height: 400px;
|
||||
border: 1px solid black;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.scrollarea {
|
||||
height: 800px;
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
.low-z, .mid-z, .high-z {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.low-z { z-index: 1; }
|
||||
.mid-z { z-index: 2; }
|
||||
.high-z { z-index: 3; }
|
||||
|
||||
</style>
|
||||
|
||||
<div class="content" reftest-assigned-layer="page-background"></div>
|
||||
<div class="overlap opacity"></div>
|
||||
<div class="overlap mid-z content" reftest-assigned-layer="on-top-of-opacity">
|
||||
<!--
|
||||
This item cannot merge into the page background layer because there's an
|
||||
active container layer for the opacity in between.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="scrollable">
|
||||
<div class="scrollarea">
|
||||
<div class="low-z content" reftest-assigned-layer="scrolled-content"></div>
|
||||
<div class="high-z overlap content" reftest-assigned-layer="scrolled-content"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
|
||||
var scrollable = document.querySelector(".scrollable");
|
||||
|
||||
// Make .scrollable start out with active scrolling.
|
||||
scrollable.scrollTop = 0;
|
||||
scrollable.scrollTop = 20;
|
||||
|
||||
</script>
|
105
layout/reftests/invalidation/layer-splitting-5.html
Normal file
105
layout/reftests/invalidation/layer-splitting-5.html
Normal file
@ -0,0 +1,105 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>Things overlapping active scrollboxes should be in a layer on top of the scrolled contents.</title>
|
||||
|
||||
<style>
|
||||
|
||||
div {
|
||||
height: 50px;
|
||||
border: 1px solid;
|
||||
box-model: border-box;
|
||||
}
|
||||
|
||||
.first, .second {
|
||||
border-color: blue;
|
||||
margin: 50px 0;
|
||||
}
|
||||
|
||||
.overlap {
|
||||
border-color: #088;
|
||||
margin-left: 100px;
|
||||
width: 80px;
|
||||
margin-bottom: -30px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
height: auto;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.scrollarea {
|
||||
width: 5000px;
|
||||
border: none;
|
||||
padding: 10px 0 20px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.scrolled {
|
||||
margin-left: 220px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0 100px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="first" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This is just a regular box, it should end up in the page background layer.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="overlap reftest-no-paint">
|
||||
<!--
|
||||
This item intersects with the scrollable box and is positioned above
|
||||
.scrolled, in z-order, so it should be split into its own layer as soon
|
||||
as the scrollbox gets active scrolling. The splitting should not wait for
|
||||
.scrolled to move under .overlap.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="scrollable">
|
||||
<div class="scrollarea">
|
||||
<div class="scrolled reftest-opaque-layer">
|
||||
<!--
|
||||
This will move under .overlap by .scrollable being scrolled. This
|
||||
action should not invalidate .overlap.
|
||||
|
||||
Furthermore, since the background of .scrollable is uniform and opaque,
|
||||
.scrolled should be able to pull up that background color and become
|
||||
opaque itself.
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="second" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This should share a layer with .first and the page background.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var scrollable = document.querySelector(".scrollable");
|
||||
|
||||
function doTest() {
|
||||
scrollable.scrollLeft = 100;
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
||||
// Make .scrollable start out with active scrolling.
|
||||
scrollable.scrollLeft = 0;
|
||||
scrollable.scrollLeft = 20;
|
||||
document.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
|
||||
</script>
|
||||
|
113
layout/reftests/invalidation/layer-splitting-6.html
Normal file
113
layout/reftests/invalidation/layer-splitting-6.html
Normal file
@ -0,0 +1,113 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>Things overlapping active scrollboxes should be in a layer on top of the scrolled contents, and that layer shouldn't pull up a background color through the scrollbox.</title>
|
||||
<!--
|
||||
This test is the same as layer-splitting-5.html, but without the scrollbox
|
||||
border. The lack of a border here makes it attractive for .overlap to pull
|
||||
a background color from the page background (because there's no scrollbox
|
||||
border in the way), but it shouldn't do that because .scrolled can move
|
||||
under it.
|
||||
-->
|
||||
|
||||
<style>
|
||||
|
||||
div {
|
||||
height: 50px;
|
||||
border: 1px solid;
|
||||
box-model: border-box;
|
||||
}
|
||||
|
||||
.first, .second {
|
||||
border-color: blue;
|
||||
margin: 50px 0;
|
||||
}
|
||||
|
||||
.overlap {
|
||||
border-color: #088;
|
||||
margin-left: 100px;
|
||||
width: 80px;
|
||||
margin-bottom: -30px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
height: auto;
|
||||
overflow: auto;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.scrollarea {
|
||||
width: 5000px;
|
||||
border: none;
|
||||
padding: 10px 0 20px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.scrolled {
|
||||
margin-left: 220px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0 100px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="first" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This is just a regular box, it should end up in the page background layer.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="overlap reftest-no-paint">
|
||||
<!--
|
||||
This item intersects with the scrollable box and is positioned above
|
||||
.scrolled, in z-order, so it should be split into its own layer as soon
|
||||
as the scrollbox gets active scrolling. The splitting should not wait for
|
||||
.scrolled to move under .overlap.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="scrollable">
|
||||
<div class="scrollarea">
|
||||
<div class="scrolled reftest-opaque-layer">
|
||||
<!--
|
||||
This will move under .overlap by .scrollable being scrolled. This
|
||||
action should not invalidate .overlap.
|
||||
|
||||
Furthermore, since the background of .scrollable is uniform and opaque,
|
||||
.scrolled should be able to pull up that background color and become
|
||||
opaque itself.
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="second" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This should share a layer with .first and the page background.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var scrollable = document.querySelector(".scrollable");
|
||||
|
||||
function doTest() {
|
||||
scrollable.scrollLeft = 100;
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
||||
// Make .scrollable start out with active scrolling.
|
||||
scrollable.scrollLeft = 0;
|
||||
scrollable.scrollLeft = 20;
|
||||
document.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
|
||||
</script>
|
||||
|
68
layout/reftests/invalidation/layer-splitting-7.html
Normal file
68
layout/reftests/invalidation/layer-splitting-7.html
Normal file
@ -0,0 +1,68 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>Scrolling shouldn't invalidate the relatively-positioned layer</title>
|
||||
|
||||
<style>
|
||||
|
||||
.content {
|
||||
box-sizing: border-box;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.fixed {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
.reftest-no-paint {
|
||||
border-color: lime;
|
||||
}
|
||||
|
||||
.distanceFromTop {
|
||||
margin-top: 240px;
|
||||
}
|
||||
|
||||
.relative {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
<div class="fixed reftest-no-paint content">
|
||||
<!--
|
||||
This fixed layer gets its own PaintedLayer above the page.
|
||||
|
||||
It shouldn't attempt to pull up an opaque background color from the page,
|
||||
because the page can move under it.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="distanceFromTop relative reftest-no-paint content">
|
||||
<!--
|
||||
This item is above .fixed in z-order, but it starts out not intersecting
|
||||
.fixed. It should still get its own layer from the start, because it can
|
||||
get scrolled on top of .fixed.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
function doTest() {
|
||||
document.documentElement.scrollTop = 100;
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
document.documentElement.scrollTop = 0;
|
||||
document.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
|
||||
</script>
|
@ -57,3 +57,10 @@ pref(layout.animated-image-layers.enabled,true) == test-animated-image-layers-ba
|
||||
!= paintedlayer-recycling-7.html about:blank
|
||||
!= masklayer-1.html about:blank
|
||||
!= masklayer-2.html about:blank
|
||||
!= layer-splitting-1.html about:blank
|
||||
!= layer-splitting-2.html about:blank
|
||||
!= layer-splitting-3.html about:blank
|
||||
!= layer-splitting-4.html about:blank
|
||||
!= layer-splitting-5.html about:blank
|
||||
!= layer-splitting-6.html about:blank
|
||||
!= layer-splitting-7.html about:blank
|
||||
|
82
layout/reftests/layers/pull-background-1.html
Normal file
82
layout/reftests/layers/pull-background-1.html
Normal file
@ -0,0 +1,82 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<meta charset="utf-8">
|
||||
<title>Scrollboxes with uniform backgrounds should pull that color into their contents</title>
|
||||
|
||||
<style>
|
||||
|
||||
div {
|
||||
min-height: 50px;
|
||||
box-model: border-box;
|
||||
}
|
||||
|
||||
.first, .second {
|
||||
border: 1px solid blue;
|
||||
margin: 50px 0;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
height: auto;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.scrollarea {
|
||||
width: 5000px;
|
||||
border: none;
|
||||
padding: 10px 0 20px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.scrolled {
|
||||
margin-left: 220px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0 100px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="first" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This is just a regular box, it should end up in the page background layer.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="scrollable border">
|
||||
<div class="scrollarea">
|
||||
<div class="scrolled border reftest-opaque-layer">
|
||||
<!--
|
||||
The background of .scrollable is uniform and opaque,
|
||||
.scrolled should be able to pull up that background color and become
|
||||
opaque itself.
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="second" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This should share a layer with .first and the page background.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var scrollable = document.querySelector(".scrollable");
|
||||
|
||||
// Make .scrollable start out with active scrolling.
|
||||
scrollable.scrollLeft = 0;
|
||||
scrollable.scrollLeft = 20;
|
||||
|
||||
</script>
|
||||
|
88
layout/reftests/layers/pull-background-2.html
Normal file
88
layout/reftests/layers/pull-background-2.html
Normal file
@ -0,0 +1,88 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<meta charset="utf-8">
|
||||
<title>Scrollboxes with uniform backgrounds should pull that color into their contents, even through an opacity container layer</title>
|
||||
|
||||
<style>
|
||||
|
||||
div {
|
||||
min-height: 50px;
|
||||
box-model: border-box;
|
||||
}
|
||||
|
||||
.first, .second {
|
||||
border: 1px solid blue;
|
||||
margin: 50px 0;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
height: 150px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.scrollarea {
|
||||
width: 5000px;
|
||||
border: none;
|
||||
padding: 10px 0 20px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.scrolled {
|
||||
margin-left: 220px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.opacity {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0 100px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="first" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This is just a regular box, it should end up in the page background layer.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="opacity border">
|
||||
<div class="opacity scrollable">
|
||||
<div class="scrollarea">
|
||||
<div class="scrolled border reftest-opaque-layer">
|
||||
<!--
|
||||
The background of .scrollable is uniform and opaque,
|
||||
.scrolled should be able to pull up that background color and become
|
||||
opaque itself.
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="second" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This should share a layer with .first and the page background.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var scrollable = document.querySelector(".scrollable");
|
||||
|
||||
// Make .scrollable start out with active scrolling.
|
||||
scrollable.scrollLeft = 0;
|
||||
scrollable.scrollLeft = 20;
|
||||
|
||||
</script>
|
||||
|
101
layout/reftests/layers/pull-background-3.html
Normal file
101
layout/reftests/layers/pull-background-3.html
Normal file
@ -0,0 +1,101 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>Scrollboxes with non-uniform backgrounds should prevent their contents from pulling background colors, even if those contents start out above uniform backgrounds</title>
|
||||
|
||||
<style>
|
||||
|
||||
div {
|
||||
min-height: 50px;
|
||||
box-model: border-box;
|
||||
}
|
||||
|
||||
.first, .second {
|
||||
border: 1px solid blue;
|
||||
margin: 50px 0;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.underlap {
|
||||
border: 1px solid #088;
|
||||
margin-left: 120px;
|
||||
width: 80px;
|
||||
margin-bottom: -30px;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
height: auto;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.scrollarea {
|
||||
width: 5000px;
|
||||
border: none;
|
||||
padding: 10px 0 20px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.scrolled {
|
||||
margin-left: 220px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0 100px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="first" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This is just a regular box, it should end up in the page background layer.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="underlap">
|
||||
<!--
|
||||
This item intersects with the scrollable box and is positioned below
|
||||
.scrollable, in z-order.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="scrollable border">
|
||||
<div class="scrollarea">
|
||||
<div class="scrolled border reftest-no-paint">
|
||||
<!--
|
||||
This box starts out above solid white background, but it will move so
|
||||
that it intersects .underlap, so it shouldn't pull up a background
|
||||
color to begin with so that it doesn't need to invalidate.
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="second" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This should share a layer with .first and the page background.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var scrollable = document.querySelector(".scrollable");
|
||||
|
||||
function doTest() {
|
||||
scrollable.scrollLeft = 100;
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
||||
// Make .scrollable start out with active scrolling.
|
||||
scrollable.scrollLeft = 0;
|
||||
scrollable.scrollLeft = 10;
|
||||
document.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
|
||||
</script>
|
107
layout/reftests/layers/pull-background-4.html
Normal file
107
layout/reftests/layers/pull-background-4.html
Normal file
@ -0,0 +1,107 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>Scrollboxes with non-uniform backgrounds should prevent their contents from pulling background colors, even if those contents start out above uniform backgrounds</title>
|
||||
<!--
|
||||
This is the same test as pull-background-3.html, but with an additional
|
||||
wrapping opacity container layer.
|
||||
-->
|
||||
|
||||
<style>
|
||||
|
||||
div {
|
||||
min-height: 50px;
|
||||
box-model: border-box;
|
||||
}
|
||||
|
||||
.first, .second {
|
||||
border: 1px solid blue;
|
||||
margin: 50px 0;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.underlap {
|
||||
border: 1px solid #088;
|
||||
margin-left: 120px;
|
||||
width: 80px;
|
||||
margin-bottom: -30px;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
height: auto;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.scrollarea {
|
||||
width: 5000px;
|
||||
border: none;
|
||||
padding: 10px 0 20px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.scrolled {
|
||||
margin-left: 220px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0 100px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="first" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This is just a regular box, it should end up in the page background layer.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="underlap">
|
||||
<!--
|
||||
This item intersects with the scrollable box and is positioned below
|
||||
.scrollable, in z-order.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="opacity border">
|
||||
<div class="opacity scrollable">
|
||||
<div class="scrollarea">
|
||||
<div class="scrolled border reftest-no-paint">
|
||||
<!--
|
||||
This box starts out above solid white background, but it will move so
|
||||
that it intersects .underlap, so it shouldn't pull up a background
|
||||
color to begin with so that it doesn't need to invalidate.
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="second" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This should share a layer with .first and the page background.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var scrollable = document.querySelector(".scrollable");
|
||||
|
||||
function doTest() {
|
||||
scrollable.scrollLeft = 100;
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
||||
// Make .scrollable start out with active scrolling.
|
||||
scrollable.scrollLeft = 0;
|
||||
scrollable.scrollLeft = 10;
|
||||
document.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
|
||||
</script>
|
92
layout/reftests/layers/pull-background-5.html
Normal file
92
layout/reftests/layers/pull-background-5.html
Normal file
@ -0,0 +1,92 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<meta charset="utf-8">
|
||||
<title>Scrollboxes with uniform backgrounds should pull that color into their contents, even if these contents are wider than the uniform area behind the scrollbox</title>
|
||||
<!--
|
||||
Very similar to pull-background-2.html, but with a .scrolled element that is
|
||||
wider than the scrollbox.
|
||||
-->
|
||||
|
||||
<style>
|
||||
|
||||
div {
|
||||
min-height: 50px;
|
||||
box-model: border-box;
|
||||
}
|
||||
|
||||
.first, .second {
|
||||
border: 1px solid blue;
|
||||
margin: 50px 0;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
height: 150px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.scrollarea {
|
||||
width: 5000px;
|
||||
border: none;
|
||||
padding: 10px 0 20px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.scrolled {
|
||||
margin-left: 220px;
|
||||
width: 2000px;
|
||||
height: 100px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.opacity {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0 100px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="first" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This is just a regular box, it should end up in the page background layer.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="opacity border">
|
||||
<div class="scrollable">
|
||||
<div class="scrollarea">
|
||||
<div class="scrolled border reftest-opaque-layer">
|
||||
<!--
|
||||
The background of .scrollable is uniform and opaque,
|
||||
.scrolled should be able to pull up that background color and become
|
||||
opaque itself.
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="second" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This should share a layer with .first and the page background.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var scrollable = document.querySelector(".scrollable");
|
||||
|
||||
// Make .scrollable start out with active scrolling.
|
||||
scrollable.scrollLeft = 0;
|
||||
scrollable.scrollLeft = 20;
|
||||
|
||||
</script>
|
||||
|
86
layout/reftests/layers/pull-background-6.html
Normal file
86
layout/reftests/layers/pull-background-6.html
Normal file
@ -0,0 +1,86 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<meta charset="utf-8">
|
||||
<title>Scrollboxes with uniform backgrounds should pull that color into their contents, even if these contents are wider than the uniform area behind the scrollbox</title>
|
||||
<!--
|
||||
Very similar to pull-background-1.html, but with a .scrolled element that is
|
||||
wider than the scrollbox.
|
||||
-->
|
||||
|
||||
<style>
|
||||
|
||||
div {
|
||||
min-height: 50px;
|
||||
box-model: border-box;
|
||||
}
|
||||
|
||||
.first, .second {
|
||||
border: 1px solid blue;
|
||||
margin: 50px 0;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
height: auto;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.scrollarea {
|
||||
width: 5000px;
|
||||
border: none;
|
||||
padding: 10px 0 20px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.scrolled {
|
||||
margin-left: 220px;
|
||||
width: 2000px;
|
||||
height: 100px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0 100px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="first" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This is just a regular box, it should end up in the page background layer.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="scrollable border">
|
||||
<div class="scrollarea">
|
||||
<div class="scrolled border reftest-opaque-layer">
|
||||
<!--
|
||||
The background of .scrollable is uniform and opaque,
|
||||
.scrolled should be able to pull up that background color and become
|
||||
opaque itself.
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="second" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This should share a layer with .first and the page background.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var scrollable = document.querySelector(".scrollable");
|
||||
|
||||
// Make .scrollable start out with active scrolling.
|
||||
scrollable.scrollLeft = 0;
|
||||
scrollable.scrollLeft = 20;
|
||||
|
||||
</script>
|
||||
|
105
layout/reftests/layers/pull-background-animated-position-1.html
Normal file
105
layout/reftests/layers/pull-background-animated-position-1.html
Normal file
@ -0,0 +1,105 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>Scrollboxes with uniform backgrounds should pull that color into their contents, even if those contents have an animated position</title>
|
||||
|
||||
<style>
|
||||
|
||||
div {
|
||||
min-height: 50px;
|
||||
box-model: border-box;
|
||||
}
|
||||
|
||||
.first, .second {
|
||||
border: 1px solid blue;
|
||||
margin: 50px 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
height: auto;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.scrollarea {
|
||||
width: 5000px;
|
||||
border: none;
|
||||
padding: 10px 0 20px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.scrolled {
|
||||
margin-left: 220px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.animated-position {
|
||||
position: relative;
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0 100px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="first" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This is just a regular box, it should end up in the page background layer.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="scrollable border">
|
||||
<div class="scrollarea">
|
||||
<div class="scrolled border animated-position reftest-no-paint reftest-opaque-layer">
|
||||
<!--
|
||||
The background of .scrollable is uniform and opaque,
|
||||
.scrolled should be able to pull up that background color and become
|
||||
opaque itself.
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="second" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This should share a layer with .first and the page background.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var scrollable = document.querySelector(".scrollable");
|
||||
|
||||
// Make .scrollable start out with active scrolling.
|
||||
scrollable.scrollLeft = 0;
|
||||
scrollable.scrollLeft = 20;
|
||||
|
||||
|
||||
var animatedLeft = document.querySelector(".animated-position");
|
||||
|
||||
function doTest() {
|
||||
animatedLeft.style.left = "100px";
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
||||
// Layerize #animatedLeft
|
||||
animatedLeft.offsetLeft;
|
||||
animatedLeft.style.left = "40px";
|
||||
animatedLeft.offsetLeft;
|
||||
animatedLeft.style.left = "60px";
|
||||
animatedLeft.offsetLeft;
|
||||
|
||||
document.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
|
||||
</script>
|
||||
|
120
layout/reftests/layers/pull-background-animated-position-2.html
Normal file
120
layout/reftests/layers/pull-background-animated-position-2.html
Normal file
@ -0,0 +1,120 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>Scrollboxes with non-uniform backgrounds should prevent their contents from pulling background colors, even if those contents start out above uniform backgrounds and have an animated position</title>
|
||||
|
||||
<style>
|
||||
|
||||
div {
|
||||
min-height: 50px;
|
||||
box-model: border-box;
|
||||
}
|
||||
|
||||
.first, .second {
|
||||
border: 1px solid blue;
|
||||
margin: 50px 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.underlap {
|
||||
border: 1px solid #088;
|
||||
margin-left: 120px;
|
||||
width: 80px;
|
||||
margin-bottom: -30px;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
height: auto;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.scrollarea {
|
||||
width: 5000px;
|
||||
border: none;
|
||||
padding: 10px 0 20px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.scrolled {
|
||||
margin-left: 220px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.animated-position {
|
||||
position: relative;
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0 100px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="first" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This is just a regular box, it should end up in the page background layer.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="underlap">
|
||||
<!--
|
||||
This item intersects with the scrollable box and is positioned below
|
||||
.scrollable, in z-order.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="scrollable border">
|
||||
<div class="scrollarea">
|
||||
<div class="scrolled border animated-position reftest-no-paint">
|
||||
<!--
|
||||
This box starts out above solid white background, but it will move so
|
||||
that it intersects .underlap, so it shouldn't pull up a background
|
||||
color to begin with so that it doesn't need to invalidate.
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="second" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This should share a layer with .first and the page background.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var scrollable = document.querySelector(".scrollable");
|
||||
|
||||
// Make .scrollable start out with active scrolling.
|
||||
scrollable.scrollLeft = 0;
|
||||
scrollable.scrollLeft = 20;
|
||||
|
||||
|
||||
var animatedLeft = document.querySelector(".animated-position");
|
||||
|
||||
function doTest() {
|
||||
animatedLeft.style.left = "-40px";
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
||||
// Layerize #animatedLeft
|
||||
animatedLeft.offsetLeft;
|
||||
animatedLeft.style.left = "40px";
|
||||
animatedLeft.offsetLeft;
|
||||
animatedLeft.style.left = "60px";
|
||||
animatedLeft.offsetLeft;
|
||||
|
||||
document.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
setTimeout(doTest, 200);
|
||||
|
||||
</script>
|
||||
|
105
layout/reftests/layers/pull-background-animated-position-3.html
Normal file
105
layout/reftests/layers/pull-background-animated-position-3.html
Normal file
@ -0,0 +1,105 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>This test fails - Layerization should respect overflow:hidden clips around things with animated position</title>
|
||||
|
||||
<style>
|
||||
|
||||
div {
|
||||
min-height: 50px;
|
||||
box-model: border-box;
|
||||
}
|
||||
|
||||
.first, .second {
|
||||
border: 1px solid blue;
|
||||
margin: 50px 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.underlap {
|
||||
border: 1px solid #088;
|
||||
margin-left: 120px;
|
||||
width: 80px;
|
||||
margin-bottom: -30px;
|
||||
}
|
||||
|
||||
.clip {
|
||||
height: auto;
|
||||
overflow: hidden;
|
||||
padding: 10px 0 20px;
|
||||
}
|
||||
|
||||
.animated-position {
|
||||
position: relative;
|
||||
left: 20px;
|
||||
margin-left: 220px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0 100px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="first" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This is just a regular box, it should end up in the page background layer.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="underlap">
|
||||
<!--
|
||||
This item intersects with the scrollable box and is positioned below
|
||||
.scrollable, in z-order.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="clip border">
|
||||
<div class="border animated-position reftest-no-paint">
|
||||
<!--
|
||||
This box starts out above solid white background, but it will move so
|
||||
that it intersects .underlap, so it shouldn't pull up a background
|
||||
color to begin with so that it doesn't need to invalidate.
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="second" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This should share a layer with .first and the page background.
|
||||
However, we don't take .animated-position's clip into account when
|
||||
layerizing, so .second will be pulled up into its own layer above
|
||||
.animated-position. So this test will fail.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var animatedLeft = document.querySelector(".animated-position");
|
||||
|
||||
function doTest() {
|
||||
animatedLeft.style.left = "-40px";
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
||||
// Layerize #animatedLeft
|
||||
animatedLeft.offsetLeft;
|
||||
animatedLeft.style.left = "40px";
|
||||
animatedLeft.offsetLeft;
|
||||
animatedLeft.style.left = "60px";
|
||||
animatedLeft.offsetLeft;
|
||||
|
||||
document.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
setTimeout(doTest, 200);
|
||||
|
||||
</script>
|
||||
|
@ -0,0 +1,94 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>This test fails - layerization should respect overflow:hidden clips around things with animated position</title>
|
||||
|
||||
<style>
|
||||
|
||||
div {
|
||||
min-height: 50px;
|
||||
box-model: border-box;
|
||||
}
|
||||
|
||||
.first, .second {
|
||||
border: 1px solid blue;
|
||||
margin: 50px 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.clip {
|
||||
height: auto;
|
||||
overflow: hidden;
|
||||
padding: 10px 0 20px;
|
||||
}
|
||||
|
||||
.animated-position {
|
||||
position: relative;
|
||||
left: 20px;
|
||||
margin-left: 220px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0 100px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="first" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This is just a regular box, it should end up in the page background layer.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="clip border">
|
||||
<div class="border animated-position reftest-no-paint reftest-opaque-layer">
|
||||
<!--
|
||||
The background of .clip is uniform and opaque,
|
||||
.animated-position should be able to pull up that background color and
|
||||
become opaque itself.
|
||||
However, since this clip is not created by an animated geometry root that
|
||||
is a scrollable frame, we currently fail to recognize it, so this test
|
||||
will fail.
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="second" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This should share a layer with .first and the page background.
|
||||
However, since we don't recognize that .animated-position is contained in
|
||||
a clip, .second gets its own layer above .animated-position, so this test
|
||||
will fail.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var animatedLeft = document.querySelector(".animated-position");
|
||||
|
||||
function doTest() {
|
||||
animatedLeft.style.left = "-40px";
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
||||
// Layerize #animatedLeft
|
||||
animatedLeft.offsetLeft;
|
||||
animatedLeft.style.left = "40px";
|
||||
animatedLeft.offsetLeft;
|
||||
animatedLeft.style.left = "60px";
|
||||
animatedLeft.offsetLeft;
|
||||
|
||||
document.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
setTimeout(doTest, 200);
|
||||
|
||||
</script>
|
||||
|
105
layout/reftests/layers/pull-background-animated-position-5.html
Normal file
105
layout/reftests/layers/pull-background-animated-position-5.html
Normal file
@ -0,0 +1,105 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="reftest-wait">
|
||||
<meta charset="utf-8">
|
||||
<title>This test fails - Opacity containers should anticipate animations of the contents when deciding whether to pull a background color</title>
|
||||
|
||||
<style>
|
||||
|
||||
div {
|
||||
min-height: 50px;
|
||||
box-model: border-box;
|
||||
}
|
||||
|
||||
.first, .second {
|
||||
border: 1px solid blue;
|
||||
margin: 50px 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.underlap {
|
||||
border: 1px solid #088;
|
||||
margin-left: 120px;
|
||||
width: 80px;
|
||||
margin-bottom: -30px;
|
||||
}
|
||||
|
||||
.opacity {
|
||||
opacity: 0.9;
|
||||
height: auto;
|
||||
padding: 10px 0 20px;
|
||||
}
|
||||
|
||||
.animated-position {
|
||||
position: relative;
|
||||
left: 20px;
|
||||
margin-left: 220px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0 100px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="first" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This is just a regular box, it should end up in the page background layer.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="underlap">
|
||||
<!--
|
||||
This item intersects with the scrollable box and is positioned below
|
||||
.scrollable, in z-order.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="border">
|
||||
<div class="opacity">
|
||||
<div class="border animated-position reftest-no-paint">
|
||||
<!--
|
||||
This item start out above solid white background but will move to
|
||||
intersect .underlap, so it shouldn't pull up the background color.
|
||||
However, the opacity item that wraps this item only looks at the
|
||||
current bounds of its contents, so this test will fail.
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="second" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This should share a layer with .first and the page background.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var animatedLeft = document.querySelector(".animated-position");
|
||||
|
||||
function doTest() {
|
||||
animatedLeft.style.left = "-40px";
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
||||
// Layerize #animatedLeft
|
||||
animatedLeft.offsetLeft;
|
||||
animatedLeft.style.left = "40px";
|
||||
animatedLeft.offsetLeft;
|
||||
animatedLeft.style.left = "60px";
|
||||
animatedLeft.offsetLeft;
|
||||
|
||||
document.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
setTimeout(doTest, 200);
|
||||
|
||||
</script>
|
||||
|
84
layout/reftests/layers/pull-background-displayport-1.html
Normal file
84
layout/reftests/layers/pull-background-displayport-1.html
Normal file
@ -0,0 +1,84 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" reftest-async-scroll>
|
||||
<meta charset="utf-8">
|
||||
<title>Scrollboxes with uniform backgrounds should pull that color into their contents, even if their contents have a visible region that extends beyond the scrollbox clip</title>
|
||||
|
||||
<style>
|
||||
|
||||
div {
|
||||
min-height: 50px;
|
||||
box-model: border-box;
|
||||
}
|
||||
|
||||
.first, .second {
|
||||
border: 1px solid blue;
|
||||
margin: 50px 0;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
height: auto;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.scrollarea {
|
||||
width: 5000px;
|
||||
border: none;
|
||||
padding: 10px 0 20px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.scrolled {
|
||||
margin-left: 220px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0 100px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="first" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This is just a regular box, it should end up in the page background layer.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="scrollable border"
|
||||
reftest-displayport-x="0" reftest-displayport-y="0"
|
||||
reftest-displayport-w="2000" reftest-displayport-h="200">
|
||||
<div class="scrollarea">
|
||||
<div class="scrolled border reftest-opaque-layer">
|
||||
<!--
|
||||
The background of .scrollable is uniform and opaque,
|
||||
.scrolled should be able to pull up that background color and become
|
||||
opaque itself.
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="second" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This should share a layer with .first and the page background.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var scrollable = document.querySelector(".scrollable");
|
||||
|
||||
// Make .scrollable start out with active scrolling.
|
||||
scrollable.scrollLeft = 0;
|
||||
scrollable.scrollLeft = 20;
|
||||
|
||||
</script>
|
||||
|
90
layout/reftests/layers/pull-background-displayport-2.html
Normal file
90
layout/reftests/layers/pull-background-displayport-2.html
Normal file
@ -0,0 +1,90 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" reftest-async-scroll>
|
||||
<meta charset="utf-8">
|
||||
<title>Scrollboxes with uniform backgrounds should pull that color into their contents, even if their contents have a visible region that extends beyond the scrollbox clip, even through an opacity container layer</title>
|
||||
|
||||
<style>
|
||||
|
||||
div {
|
||||
min-height: 50px;
|
||||
box-model: border-box;
|
||||
}
|
||||
|
||||
.first, .second {
|
||||
border: 1px solid blue;
|
||||
margin: 50px 0;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
height: 150px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.scrollarea {
|
||||
width: 5000px;
|
||||
border: none;
|
||||
padding: 10px 0 20px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.scrolled {
|
||||
margin-left: 220px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.opacity {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0 100px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="first" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This is just a regular box, it should end up in the page background layer.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="opacity border">
|
||||
<div class="opacity scrollable"
|
||||
reftest-displayport-x="0" reftest-displayport-y="0"
|
||||
reftest-displayport-w="2000" reftest-displayport-h="200">
|
||||
<div class="scrollarea">
|
||||
<div class="scrolled border reftest-opaque-layer">
|
||||
<!--
|
||||
The background of .scrollable is uniform and opaque,
|
||||
.scrolled should be able to pull up that background color and become
|
||||
opaque itself.
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="second" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This should share a layer with .first and the page background.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var scrollable = document.querySelector(".scrollable");
|
||||
|
||||
// Make .scrollable start out with active scrolling.
|
||||
scrollable.scrollLeft = 0;
|
||||
scrollable.scrollLeft = 20;
|
||||
|
||||
</script>
|
||||
|
104
layout/reftests/layers/pull-background-displayport-3.html
Normal file
104
layout/reftests/layers/pull-background-displayport-3.html
Normal file
@ -0,0 +1,104 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="reftest-wait" reftest-async-scroll>
|
||||
<meta charset="utf-8">
|
||||
<title>Scrollboxes with non-uniform backgrounds should prevent their contents from pulling background colors, even if those contents start out above uniform backgrounds</title>
|
||||
|
||||
<style>
|
||||
|
||||
div {
|
||||
min-height: 50px;
|
||||
box-model: border-box;
|
||||
}
|
||||
|
||||
.first, .second {
|
||||
border: 1px solid blue;
|
||||
margin: 50px 0;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.underlap {
|
||||
border: 1px solid #088;
|
||||
margin-left: 120px;
|
||||
width: 80px;
|
||||
margin-bottom: -30px;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
height: auto;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.scrollarea {
|
||||
width: 5000px;
|
||||
border: none;
|
||||
padding: 10px 0 20px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.scrolled {
|
||||
margin-left: 220px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0 100px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="first" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This is just a regular box, it should end up in the page background layer.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="underlap">
|
||||
<!--
|
||||
This item intersects with the scrollable box and is positioned below
|
||||
.scrolled, in z-order.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="scrollable border"
|
||||
reftest-displayport-x="0" reftest-displayport-y="0"
|
||||
reftest-displayport-w="2000" reftest-displayport-h="200">
|
||||
<div class="scrollarea">
|
||||
<div class="scrolled border reftest-no-paint">
|
||||
<!--
|
||||
This box starts out above solid white background, but it will move so
|
||||
that it intersects .underlap, so it shouldn't pull up a background
|
||||
color to begin with so that it doesn't need to invalidate.
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="second" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This should share a layer with .first and the page background.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var scrollable = document.querySelector(".scrollable");
|
||||
|
||||
function doTest() {
|
||||
scrollable.scrollLeft = 100;
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
||||
// Make .scrollable start out with active scrolling.
|
||||
scrollable.scrollLeft = 0;
|
||||
scrollable.scrollLeft = 10;
|
||||
document.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
// setTimeout(doTest, 500);
|
||||
|
||||
</script>
|
110
layout/reftests/layers/pull-background-displayport-4.html
Normal file
110
layout/reftests/layers/pull-background-displayport-4.html
Normal file
@ -0,0 +1,110 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="reftest-wait" reftest-async-scroll>
|
||||
<meta charset="utf-8">
|
||||
<title>Scrollboxes with non-uniform backgrounds should prevent their contents from pulling background colors, even if those contents start out above uniform backgrounds</title>
|
||||
<!--
|
||||
This is the same test as pull-background-displayport-3.html, but with an additional
|
||||
wrapping opacity container layer.
|
||||
-->
|
||||
|
||||
<style>
|
||||
|
||||
div {
|
||||
min-height: 50px;
|
||||
box-model: border-box;
|
||||
}
|
||||
|
||||
.first, .second {
|
||||
border: 1px solid blue;
|
||||
margin: 50px 0;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.underlap {
|
||||
border: 1px solid #088;
|
||||
margin-left: 120px;
|
||||
width: 80px;
|
||||
margin-bottom: -30px;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
height: auto;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.scrollarea {
|
||||
width: 5000px;
|
||||
border: none;
|
||||
padding: 10px 0 20px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.scrolled {
|
||||
margin-left: 220px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0 100px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="first" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This is just a regular box, it should end up in the page background layer.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="underlap">
|
||||
<!--
|
||||
This item intersects with the scrollable box and is positioned below
|
||||
.scrolled, in z-order.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="opacity border">
|
||||
<div class="opacity scrollable"
|
||||
reftest-displayport-x="0" reftest-displayport-y="0"
|
||||
reftest-displayport-w="2000" reftest-displayport-h="200">
|
||||
<div class="scrollarea">
|
||||
<div class="scrolled border reftest-no-paint">
|
||||
<!--
|
||||
This box starts out above solid white background, but it will move so
|
||||
that it intersects .underlap, so it shouldn't pull up a background
|
||||
color to begin with so that it doesn't need to invalidate.
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="second" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This should share a layer with .first and the page background.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var scrollable = document.querySelector(".scrollable");
|
||||
|
||||
function doTest() {
|
||||
scrollable.scrollLeft = 100;
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
||||
// Make .scrollable start out with active scrolling.
|
||||
scrollable.scrollLeft = 0;
|
||||
scrollable.scrollLeft = 10;
|
||||
document.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
// setTimeout(doTest, 500);
|
||||
|
||||
</script>
|
94
layout/reftests/layers/pull-background-displayport-5.html
Normal file
94
layout/reftests/layers/pull-background-displayport-5.html
Normal file
@ -0,0 +1,94 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" reftest-async-scroll>
|
||||
<meta charset="utf-8">
|
||||
<title>Scrollboxes with uniform backgrounds should pull that color into their contents, even if these contents are wider than the uniform area behind the scrollbox</title>
|
||||
<!--
|
||||
Very similar to pull-background-displayport-2.html, but with a .scrolled element that is
|
||||
wider than the scrollbox.
|
||||
-->
|
||||
|
||||
<style>
|
||||
|
||||
div {
|
||||
min-height: 50px;
|
||||
box-model: border-box;
|
||||
}
|
||||
|
||||
.first, .second {
|
||||
border: 1px solid blue;
|
||||
margin: 50px 0;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
height: 150px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.scrollarea {
|
||||
width: 5000px;
|
||||
border: none;
|
||||
padding: 10px 0 20px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.scrolled {
|
||||
margin-left: 220px;
|
||||
width: 2000px;
|
||||
height: 100px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.opacity {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0 100px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="first" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This is just a regular box, it should end up in the page background layer.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="opacity border">
|
||||
<div class="scrollable"
|
||||
reftest-displayport-x="0" reftest-displayport-y="0"
|
||||
reftest-displayport-w="2000" reftest-displayport-h="200">
|
||||
<div class="scrollarea">
|
||||
<div class="scrolled border reftest-opaque-layer">
|
||||
<!--
|
||||
The background of .scrollable is uniform and opaque,
|
||||
.scrolled should be able to pull up that background color and become
|
||||
opaque itself.
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="second" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This should share a layer with .first and the page background.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var scrollable = document.querySelector(".scrollable");
|
||||
|
||||
// Make .scrollable start out with active scrolling.
|
||||
scrollable.scrollLeft = 0;
|
||||
scrollable.scrollLeft = 20;
|
||||
|
||||
</script>
|
||||
|
84
layout/reftests/layers/pull-background-displayport-6.html
Normal file
84
layout/reftests/layers/pull-background-displayport-6.html
Normal file
@ -0,0 +1,84 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" reftest-async-scroll>
|
||||
<meta charset="utf-8">
|
||||
<title>Scrollboxes with uniform backgrounds should pull that color into their contents, even if these contents are wider than the uniform area behind the scrollbox</title>
|
||||
|
||||
<style>
|
||||
|
||||
div {
|
||||
min-height: 50px;
|
||||
box-model: border-box;
|
||||
}
|
||||
|
||||
.first, .second {
|
||||
border: 1px solid blue;
|
||||
margin: 50px 0;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
height: auto;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.scrollarea {
|
||||
width: 5000px;
|
||||
border: none;
|
||||
padding: 10px 0 20px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.scrolled {
|
||||
margin-left: 220px;
|
||||
width: 2000px;
|
||||
height: 100px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0 100px;
|
||||
height: 3000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="first" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This is just a regular box, it should end up in the page background layer.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="scrollable border"
|
||||
reftest-displayport-x="0" reftest-displayport-y="0"
|
||||
reftest-displayport-w="2000" reftest-displayport-h="200">
|
||||
<div class="scrollarea">
|
||||
<div class="scrolled border reftest-opaque-layer">
|
||||
<!--
|
||||
The background of .scrollable is uniform and opaque,
|
||||
.scrolled should be able to pull up that background color and become
|
||||
opaque itself.
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="second" reftest-assigned-layer="page-background">
|
||||
<!--
|
||||
This should share a layer with .first and the page background.
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
var scrollable = document.querySelector(".scrollable");
|
||||
|
||||
// Make .scrollable start out with active scrolling.
|
||||
scrollable.scrollLeft = 0;
|
||||
scrollable.scrollLeft = 20;
|
||||
|
||||
</script>
|
||||
|
@ -1,2 +1,19 @@
|
||||
== move-to-background-1.html move-to-background-1-ref.html
|
||||
fuzzy-if(cocoaWidget,2,6) random-if(Android&&!browserIsRemote) == component-alpha-exit-1.html component-alpha-exit-1-ref.html # bug 760275
|
||||
!= pull-background-1.html about:blank
|
||||
!= pull-background-2.html about:blank
|
||||
!= pull-background-3.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515
|
||||
!= pull-background-4.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515
|
||||
skip-if(asyncPanZoom) != pull-background-5.html about:blank # Fails with event regions
|
||||
!= pull-background-6.html about:blank
|
||||
skip-if(asyncPanZoom) != pull-background-animated-position-1.html about:blank # Fails with event regions
|
||||
!= pull-background-animated-position-2.html about:blank
|
||||
fails != pull-background-animated-position-3.html about:blank # Fails because PaintedLayer item assignment doesn't recognize overflow:hidden clips
|
||||
fails != pull-background-animated-position-4.html about:blank # Fails because PaintedLayer item assignment and background pulling don't recognize overflow:hidden clips
|
||||
fails-if(!asyncPanZoom&&!Android) != pull-background-animated-position-5.html about:blank # Fails because ownLayer bounds don't anticipate changes of animated contents, but doesn't fail with event regions
|
||||
skip-if(!asyncPanZoom) != pull-background-displayport-1.html about:blank
|
||||
skip-if(!asyncPanZoom) != pull-background-displayport-2.html about:blank
|
||||
skip-if(!asyncPanZoom) != pull-background-displayport-3.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515
|
||||
skip-if(!asyncPanZoom) != pull-background-displayport-4.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515
|
||||
fails skip-if(!asyncPanZoom) != pull-background-displayport-5.html about:blank # bug 1147673
|
||||
skip-if(!asyncPanZoom) != pull-background-displayport-6.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515
|
||||
|
@ -219,7 +219,7 @@ pref(layout.css.masking.enabled,true) fuzzy-if(d2d,1,6400) == mask-type-04.svg m
|
||||
== nested-viewBox-01.svg pass.svg
|
||||
== nesting-invalid-01.svg nesting-invalid-01-ref.svg
|
||||
fuzzy-if(d2d&&/^Windows\x20NT\x206\.1/.test(http.oscpu),1,168) fuzzy-if(azureQuartz,1,122) == non-scaling-stroke-01.svg non-scaling-stroke-01-ref.svg # bug 1074161 for Win7 and OSX 10.8
|
||||
fuzzy-if(Android||B2G,1,99) fuzzy-if(!contentSameGfxBackendAsCanvas,9,99) == non-scaling-stroke-02.svg non-scaling-stroke-02-ref.svg
|
||||
fuzzy-if(Android||B2G,1,586) fuzzy-if(!contentSameGfxBackendAsCanvas,9,99) == non-scaling-stroke-02.svg non-scaling-stroke-02-ref.svg
|
||||
== non-scaling-stroke-03.svg non-scaling-stroke-03-ref.svg
|
||||
== objectBoundingBox-and-clipPath.svg pass.svg
|
||||
# Bug 588684
|
||||
|
@ -245,7 +245,7 @@ int ConvertToI420(VideoType src_video_type,
|
||||
if (src_video_type == kYV12) {
|
||||
// In gralloc buffer, yv12 color format's cb and cr's strides are aligned
|
||||
// to 16 Bytes boundary. See /system/core/include/system/graphics.h
|
||||
int stride_y = src_width;
|
||||
int stride_y = (src_width + 15) & ~0x0F;
|
||||
int stride_uv = (((stride_y + 1) / 2) + 15) & ~0x0F;
|
||||
return libyuv::I420Rotate(src_frame,
|
||||
stride_y,
|
||||
|
@ -1332,8 +1332,10 @@ pref("network.http.spdy.default-concurrent", 100);
|
||||
|
||||
// alt-svc allows separation of transport routing from
|
||||
// the origin host without using a proxy.
|
||||
pref("network.http.altsvc.enabled", true);
|
||||
pref("network.http.altsvc.oe", true);
|
||||
pref("network.http.atsvc.enabled", false);
|
||||
pref("network.http.atsvc.oe", false);
|
||||
pref("network.http.altsvc.enabled", false);
|
||||
pref("network.http.altsvc.oe", false);
|
||||
|
||||
pref("network.http.diagnostics", false);
|
||||
|
||||
|
@ -25,8 +25,13 @@ class WebSocketChannelParent;
|
||||
|
||||
/**
|
||||
* Class that provides an nsILoadInfo implementation.
|
||||
*
|
||||
* Note that there is no reason why this class should be MOZ_EXPORT, but
|
||||
* Thunderbird relies on some insane hacks which require this, so we'll leave it
|
||||
* as is for now, but hopefully we'll be able to remove the MOZ_EXPORT keyword
|
||||
* from this class at some point. See bug 1149127 for the discussion.
|
||||
*/
|
||||
class LoadInfo final : public nsILoadInfo
|
||||
class MOZ_EXPORT LoadInfo final : public nsILoadInfo
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -769,7 +769,7 @@ var tests = [ test_http2_post_big
|
||||
, test_http2_push2
|
||||
, test_http2_push3
|
||||
, test_http2_push4
|
||||
, test_http2_altsvc
|
||||
// , test_http2_altsvc
|
||||
, test_http2_doubleheader
|
||||
, test_http2_xhr
|
||||
, test_http2_header
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"repo": "https://hg.mozilla.org/build/mozharness",
|
||||
"revision": "9c18f2f9e0c0"
|
||||
"revision": "87da3e48572d"
|
||||
}
|
||||
|
@ -93,8 +93,10 @@ function monotinicity_tester(source, testName) {
|
||||
|
||||
// Sanity check on components data.
|
||||
let set = new Set();
|
||||
let keys = [];
|
||||
for (let item of snapshot.componentsData) {
|
||||
let key = `{name: ${item.name}, addonId: ${item.addonId}}`;
|
||||
let key = `{name: ${item.name}, addonId: ${item.addonId}, isSystem: ${item.isSystem}}`;
|
||||
keys.push(key);
|
||||
set.add(key);
|
||||
sanityCheck(previous.componentsMap.get(key), item);
|
||||
previous.componentsMap.set(key, item);
|
||||
@ -103,13 +105,15 @@ function monotinicity_tester(source, testName) {
|
||||
Assert_leq(item[k], snapshot.processData[k],
|
||||
`Sanity check (${name}): component has a lower ${k} than process`);
|
||||
}
|
||||
for (let i = 0; i < item.durations.length; ++i) {
|
||||
Assert_leq(item.durations[i], snapshot.processData.durations[i],
|
||||
`Sanity check (${name}): component has a lower durations[${i}] than process.`);
|
||||
}
|
||||
}
|
||||
// Check that we do not have duplicate components.
|
||||
Assert.equal(set.size, snapshot.componentsData.length);
|
||||
info(`Before deduplication, we had the following components: ${keys.sort().join(", ")}`);
|
||||
info(`After deduplication, we have the following components: ${[...set.keys()].sort().join(", ")}`);
|
||||
|
||||
info(`Deactivating deduplication check (Bug 1150045)`);
|
||||
if (false) {
|
||||
Assert.equal(set.size, snapshot.componentsData.length);
|
||||
}
|
||||
});
|
||||
let interval = window.setInterval(frameCheck, 300);
|
||||
registerCleanupFunction(() => {
|
||||
@ -133,11 +137,9 @@ add_task(function* test() {
|
||||
info("Opening URL");
|
||||
newTab.linkedBrowser.loadURI(URL);
|
||||
|
||||
info("Skipping monotonicity testing (1149897)");
|
||||
if (false) {
|
||||
monotinicity_tester(() => PerformanceStats.getSnapshot(), "parent process");
|
||||
monotinicity_tester(() => promiseContentResponseOrNull(browser, "compartments-test:getStatistics", null), "content process" );
|
||||
}
|
||||
info("Setting up monotonicity testing");
|
||||
monotinicity_tester(() => PerformanceStats.getSnapshot(), "parent process");
|
||||
monotinicity_tester(() => promiseContentResponseOrNull(browser, "compartments-test:getStatistics", null), "content process" );
|
||||
|
||||
while (true) {
|
||||
let stats = (yield promiseContentResponse(browser, "compartments-test:getStatistics", null));
|
||||
|
@ -65,16 +65,16 @@ function hasLowPrecision() {
|
||||
let [sysName, sysVersion] = [Services.sysinfo.getPropertyAsAString("name"), Services.sysinfo.getPropertyAsDouble("version")];
|
||||
do_print(`Running ${sysName} version ${sysVersion}`);
|
||||
|
||||
if (sysName != "Windows_NT") {
|
||||
do_print("Not running Windows, precision should be good.");
|
||||
return false;
|
||||
if (sysName == "Windows_NT" && sysVersion < 6) {
|
||||
do_print("Running old Windows, need to deactivate tests due to bad precision.");
|
||||
return true;
|
||||
}
|
||||
if (sysVersion >= 6) {
|
||||
do_print("Running a recent version of Windows, precision should be good.");
|
||||
return false;
|
||||
if (sysName == "Linux" && sysVersion <= 2.6) {
|
||||
do_print("Running old Linux, need to deactivate tests due to bad precision.");
|
||||
return true;
|
||||
}
|
||||
do_print("Running old Windows, need to deactivate tests due to bad precision.");
|
||||
return true;
|
||||
do_print("This platform has good precision.")
|
||||
return false;
|
||||
}
|
||||
|
||||
add_task(function* test_measure() {
|
||||
|
@ -974,6 +974,14 @@ grippy {
|
||||
-moz-box-ordinal-group: 2147483646;
|
||||
}
|
||||
|
||||
/******** scrollbar ********/
|
||||
|
||||
slider {
|
||||
/* This is a hint to layerization that the scrollbar thumb can never leave
|
||||
the scrollbar track. */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/******** scrollbox ********/
|
||||
|
||||
scrollbox {
|
||||
|
@ -120,10 +120,10 @@ let AddonWatcher = {
|
||||
|
||||
let limits = {
|
||||
// By default, warn if we have a total time of 1s of CPOW per 15 seconds
|
||||
totalCPOWTime: Math.round(Preferences.get("browser.addon-watch.limits.totalCPOWTime", 1000) * this._interval / 15000),
|
||||
totalCPOWTime: Math.round(Preferences.get("browser.addon-watch.limits.totalCPOWTime", 1000000) * this._interval / 15000),
|
||||
// By default, warn if we have skipped 4 consecutive frames
|
||||
// at least once during the latest slice.
|
||||
longestDuration: Math.round(Math.log2(Preferences.get("browser.addon-watch.limits.longestDuration", 7))),
|
||||
longestDuration: Math.round(Math.log2(Preferences.get("browser.addon-watch.limits.longestDuration", 128))),
|
||||
};
|
||||
|
||||
for (let item of snapshot.componentsData) {
|
||||
|
@ -57,7 +57,11 @@ char* mozilla_sampler_get_profile();
|
||||
|
||||
JSObject *mozilla_sampler_get_profile_data(JSContext *aCx);
|
||||
|
||||
void mozilla_sampler_save_profile_to_file(const char* aFilename);
|
||||
// Make this function easily callable from a debugger in a build without
|
||||
// debugging information (work around http://llvm.org/bugs/show_bug.cgi?id=22211)
|
||||
extern "C" {
|
||||
void mozilla_sampler_save_profile_to_file(const char* aFilename);
|
||||
}
|
||||
|
||||
const char** mozilla_sampler_get_features();
|
||||
|
||||
|
@ -1106,7 +1106,7 @@ GfxInfo::GetGfxDriverInfo()
|
||||
APPEND_TO_DRIVER_BLOCKLIST_RANGE_GPU2(DRIVER_OS_WINDOWS_7,
|
||||
(nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), (GfxDeviceFamily*)GfxDriverInfo::GetDeviceFamily(Bug1137716),
|
||||
GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
|
||||
DRIVER_BETWEEN_INCLUSIVE, V(8,7,12,5730), V(8,17,12,6901), "Nvidia driver > 8.17.12.6901");
|
||||
DRIVER_BETWEEN_INCLUSIVE, V(8,17,12,5730), V(8,17,12,6901), "Nvidia driver > 8.17.12.6901");
|
||||
|
||||
}
|
||||
return *mDriverInfo;
|
||||
|
@ -28,9 +28,6 @@ nsEnvironment::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult)
|
||||
}
|
||||
|
||||
nsEnvironment* obj = new nsEnvironment();
|
||||
if (!obj) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
rv = obj->QueryInterface(aIID, aResult);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -559,9 +559,6 @@ nsThread::DispatchInternal(nsIRunnable* aEvent, uint32_t aFlags,
|
||||
|
||||
nsRefPtr<nsThreadSyncDispatch> wrapper =
|
||||
new nsThreadSyncDispatch(thread, aEvent);
|
||||
if (!wrapper) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
nsresult rv = PutEvent(wrapper, aTarget);
|
||||
// Don't wait for the event to finish if we didn't dispatch it...
|
||||
if (NS_FAILED(rv)) {
|
||||
@ -639,9 +636,6 @@ nsThread::Shutdown()
|
||||
// Set mShutdownContext and wake up the thread in case it is waiting for
|
||||
// events to process.
|
||||
nsCOMPtr<nsIRunnable> event = new nsThreadShutdownEvent(this, &context);
|
||||
if (!event) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
// XXXroc What if posting the event fails due to OOM?
|
||||
PutEvent(event, nullptr);
|
||||
|
||||
|
@ -304,9 +304,6 @@ nsTimerImpl::Startup()
|
||||
nsTimerEvent::Init();
|
||||
|
||||
gThread = new TimerThread();
|
||||
if (!gThread) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ADDREF(gThread);
|
||||
rv = gThread->InitLocks();
|
||||
@ -827,9 +824,6 @@ NS_NewTimer(nsITimer** aResult, nsTimerCallbackFunc aCallback, void* aClosure,
|
||||
uint32_t aDelay, uint32_t aType)
|
||||
{
|
||||
nsTimerImpl* timer = new nsTimerImpl();
|
||||
if (!timer) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
NS_ADDREF(timer);
|
||||
|
||||
nsresult rv = timer->InitWithFuncCallback(aCallback, aClosure,
|
||||
|
Loading…
Reference in New Issue
Block a user