From 684491e8dcd5b117a1bed7f5d7ae3ff29234995e Mon Sep 17 00:00:00 2001 From: Joel Maher Date: Thu, 8 Nov 2012 07:32:58 -0500 Subject: [PATCH 01/39] Bug 809364 - sutagent zeroconf is causing jmdns thread to spike cpu on panda boards. r=wlach DONTBUILD --- build/mobile/sutagent/android/ASMozStub.java | 24 ++++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/build/mobile/sutagent/android/ASMozStub.java b/build/mobile/sutagent/android/ASMozStub.java index 586600cd976..fec2399cb91 100755 --- a/build/mobile/sutagent/android/ASMozStub.java +++ b/build/mobile/sutagent/android/ASMozStub.java @@ -4,12 +4,13 @@ package com.mozilla.SUTAgentAndroid.service; +import java.io.File; +import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.net.InetAddress; import java.net.ServerSocket; import java.util.Timer; -import java.io.IOException; -import java.net.InetAddress; import com.mozilla.SUTAgentAndroid.SUTAgentAndroid; import com.mozilla.SUTAgentAndroid.R; @@ -39,6 +40,7 @@ public class ASMozStub extends android.app.Service { RunDataThread runDataThrd = null; Thread monitor = null; Timer timer = null; + boolean doZeroConfig = false; @SuppressWarnings("unchecked") private static final Class[] mSetForegroundSignature = new Class[] { @@ -178,14 +180,24 @@ public class ASMozStub extends android.app.Service { runDataThrd.start(); doToast(String.format("Data channel port %d ...", DATA_PORT)); - startZeroConf(); + DoCommand tmpdc = new DoCommand(getApplication()); + File dir = getFilesDir(); + File iniFile = new File(dir, "SUTAgent.ini"); + String sIniFile = iniFile.getAbsolutePath(); + String zeroconf = tmpdc.GetIniData("General", "ZeroConfig", sIniFile); + if (zeroconf != "" && Integer.parseInt(zeroconf) == 1) { + this.doZeroConfig = true; + } + + if (this.doZeroConfig) { + startZeroConf(); + } Notification notification = new Notification(); startForegroundCompat(R.string.foreground_service_started, notification); } catch (Exception e) { doToast(e.toString()); -// Toast.makeText(getApplication().getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show(); } return; @@ -195,7 +207,9 @@ public class ASMozStub extends android.app.Service { { super.onDestroy(); - stopZeroConf(); + if (this.doZeroConfig) { + stopZeroConf(); + } if (runCmdThrd.isAlive()) { From f73dae0742902d3fc7d23d46580beb5145dbccd8 Mon Sep 17 00:00:00 2001 From: Joel Maher Date: Thu, 8 Nov 2012 07:33:00 -0500 Subject: [PATCH 02/39] Bug 809366 - watcher has high cpu usage on panda boards in racked environment. r=wlach DONTBUILD --- .../sutagent/android/watcher/WatcherService.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/build/mobile/sutagent/android/watcher/WatcherService.java b/build/mobile/sutagent/android/watcher/WatcherService.java index 5b5971ff9b6..10fbbe70d53 100644 --- a/build/mobile/sutagent/android/watcher/WatcherService.java +++ b/build/mobile/sutagent/android/watcher/WatcherService.java @@ -13,6 +13,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.Date; import java.util.List; import java.util.Timer; import java.util.TimerTask; @@ -53,6 +54,7 @@ public class WatcherService extends Service long lPeriod = 300000; int nMaxStrikes = 0; // maximum number of tries before we consider network unreachable (0 means don't check) boolean bStartSUTAgent = true; + boolean bStartedTimer = false; Process pProc; Context myContext = null; @@ -217,9 +219,13 @@ public class WatcherService extends Service } else if (sCmd.equalsIgnoreCase("start")) { - doToast("WatcherService started"); - myTimer = new Timer(); - myTimer.scheduleAtFixedRate(new MyTime(), lDelay, lPeriod); + if (!this.bStartedTimer) { + doToast("WatcherService started"); + myTimer = new Timer(); + Date startSchedule = new Date(System.currentTimeMillis() + lDelay); + myTimer.schedule(new MyTime(), startSchedule, lPeriod); + this.bStartedTimer = true; + } } else { From 6eeae16283359a67ebf29ad8008cd2274dff88e2 Mon Sep 17 00:00:00 2001 From: Joel Maher Date: Thu, 8 Nov 2012 07:33:03 -0500 Subject: [PATCH 03/39] Bug 809534 - add support to watcher to support version query. r=wlach DONTBUILD --- .../android/watcher/WatcherService.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/build/mobile/sutagent/android/watcher/WatcherService.java b/build/mobile/sutagent/android/watcher/WatcherService.java index 10fbbe70d53..90760c2d20e 100644 --- a/build/mobile/sutagent/android/watcher/WatcherService.java +++ b/build/mobile/sutagent/android/watcher/WatcherService.java @@ -8,9 +8,11 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; +import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.PrintWriter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Date; @@ -47,6 +49,8 @@ import android.os.Environment; public class WatcherService extends Service { + private final String prgVersion = "Watcher Version 1.15"; + String sErrorPrefix = "##Installer Error## "; String currentDir = "/"; String sPingTarget = ""; @@ -236,15 +240,33 @@ public class WatcherService extends Service doToast("WatcherService created"); } + public void writeVersion() { + PrintWriter pw = null; + String appPath = getApplicationContext().getFilesDir().getAbsolutePath(); + String versionPath = appPath + "/version.txt"; + Log.i("Watcher", "writing version string to: " + versionPath); + try { + pw = new PrintWriter(new FileWriter(versionPath, true)); + pw.println(this.prgVersion); + } catch (IOException ioe) { + Log.e("Watcher", "Exception writing version: " + this.prgVersion + " to file: " + versionPath); + } finally { + if (pw != null) { + pw.close(); + } + } + } @Override public void onStart(Intent intent, int startId) { + writeVersion(); handleCommand(intent); return; } @Override public int onStartCommand(Intent intent, int flags, int startId) { + writeVersion(); handleCommand(intent); return START_STICKY; } From 720f71a0d7eb083a45ef776ba1d1c9659d38bdc1 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 25 Sep 2012 15:24:43 +1200 Subject: [PATCH 04/39] Bug 792765. Part 0.5: Fix WebIDL codegen to avoid emitting QueryInterface when there is no interface prototype object. r=bz --HG-- extra : rebase_source : 7e1df198548d8a4f1b2f2a045f637412a5fe8450 --- dom/bindings/Codegen.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 21c09ba3035..ae3170fba13 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -1095,7 +1095,9 @@ class MethodDefiner(PropertyDefiner): "flags": "JSPROP_ENUMERATE", "pref": None }) - if not descriptor.interface.parent and not static and descriptor.nativeOwnership == 'nsisupports': + if (not descriptor.interface.parent and not static and + descriptor.nativeOwnership == 'nsisupports' and + descriptor.interface.hasInterfacePrototypeObject()): self.chrome.append({"name": 'QueryInterface', "methodInfo": False, "length": 1, From 9caa3eeb38b7e3284371fb12f69ac08c7d201cd4 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 7 Nov 2012 17:56:55 -0500 Subject: [PATCH 05/39] Bug 792675. Part 0.6: Handle empty dictionary types in WebIDL bindings. r=bz --HG-- extra : rebase_source : a38a2405d32b76bdef9095398c759346cfc28282 --- dom/bindings/Codegen.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index ae3170fba13..0bf2b398544 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -5807,9 +5807,10 @@ class CGNamespacedEnum(CGThing): class CGDictionary(CGThing): def __init__(self, dictionary, descriptorProvider): - self.dictionary = dictionary; + self.dictionary = dictionary self.descriptorProvider = descriptorProvider self.workers = descriptorProvider.workers + self.needToInitIds = not self.workers and len(dictionary.members) > 0 if all(CGDictionary(d, descriptorProvider).generatable for d in CGDictionary.getDictionaryDependencies(dictionary)): self.generatable = True @@ -5871,7 +5872,7 @@ class CGDictionary(CGThing): " ${selfName}(const ${selfName}&) MOZ_DELETE;\n" + # NOTE: jsids are per-runtime, so don't use them in workers (" static bool InitIds(JSContext* cx);\n" - " static bool initedIds;\n" if not self.workers else "") + + " static bool initedIds;\n" if self.needToInitIds else "") + "\n".join(" static jsid " + self.makeIdName(m.identifier.name) + ";" for m in d.members) + "\n" @@ -5936,7 +5937,7 @@ class CGDictionary(CGThing): " initedIds = true;\n" " return true;\n" "}\n" - "\n" if not self.workers else "") + + "\n" if self.needToInitIds else "") + "bool\n" "${selfName}::Init(JSContext* cx, const JS::Value& val)\n" "{\n" @@ -5946,10 +5947,10 @@ class CGDictionary(CGThing): # NOTE: jsids are per-runtime, so don't use them in workers (" if (cx && !initedIds && !InitIds(cx)) {\n" " return false;\n" - " }\n" if not self.workers else "") + - "${initParent}" - " JSBool found;\n" - " JS::Value temp;\n" + " }\n" if self.needToInitIds else "") + + "${initParent}" + + (" JSBool found;\n" + " JS::Value temp;\n" if len(memberInits) > 0 else "") + " bool isNull = val.isNullOrUndefined();\n" " if (!isNull && !val.isObject()) {\n" " return ThrowErrorMessage(cx, MSG_NOT_OBJECT);\n" @@ -5965,7 +5966,7 @@ class CGDictionary(CGThing): # NOTE: jsids are per-runtime, so don't use them in workers (" if (!initedIds && !InitIds(cx)) {\n" " return false;\n" - " }\n" if not self.workers else "") + + " }\n" if self.needToInitIds else "") + "${toObjectParent}" "${ensureObject}" "\n" From cecf3ae790cdfddf5ce74013b0dcb61f0d1a5b78 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 25 Sep 2012 15:24:43 +1200 Subject: [PATCH 06/39] Bug 792675. Part 1: Make the URL interface use WebIDL. r=bz --HG-- extra : rebase_source : dbb7a3158b71446930400ad523a2896b6306de40 --- dom/base/Makefile.in | 2 + dom/base/URL.cpp | 76 ++++++++++++++ dom/base/URL.h | 30 ++++++ dom/base/nsDOMClassInfo.cpp | 6 -- dom/base/nsDOMClassInfoClasses.h | 1 - dom/base/nsGlobalWindow.cpp | 98 ------------------- dom/base/nsGlobalWindow.h | 6 +- dom/base/nsPIDOMWindow.h | 4 +- dom/bindings/Bindings.conf | 4 + dom/bindings/Codegen.py | 83 ++++++++-------- dom/interfaces/base/nsIDOMWindow.idl | 16 +-- .../mochitest/general/test_interfaces.html | 2 +- dom/webidl/URL.webidl | 23 +++++ dom/webidl/WebIDL.mk | 1 + 14 files changed, 185 insertions(+), 167 deletions(-) create mode 100644 dom/base/URL.cpp create mode 100644 dom/base/URL.h create mode 100644 dom/webidl/URL.webidl diff --git a/dom/base/Makefile.in b/dom/base/Makefile.in index 0cba177f116..c30153bf143 100644 --- a/dom/base/Makefile.in +++ b/dom/base/Makefile.in @@ -84,6 +84,7 @@ EXPORTS_mozilla/dom = \ DOMRequest.h \ StructuredCloneTags.h \ ScreenOrientation.h \ + URL.h \ $(NULL) CPPSRCS = \ @@ -115,6 +116,7 @@ CPPSRCS = \ DOMError.cpp \ DOMRequest.cpp \ Navigator.cpp \ + URL.cpp \ $(NULL) include $(topsrcdir)/dom/dom-config.mk diff --git a/dom/base/URL.cpp b/dom/base/URL.cpp new file mode 100644 index 00000000000..cdeac2d6afd --- /dev/null +++ b/dom/base/URL.cpp @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "URL.h" + +#include "nsGlobalWindow.h" +#include "nsIDOMFile.h" +#include "nsIDocument.h" +#include "nsIPrincipal.h" +#include "nsContentUtils.h" +#include "nsBlobProtocolHandler.h" + +namespace mozilla { +namespace dom { + +void +URL::CreateObjectURL(nsISupports* aGlobal, nsIDOMBlob* aBlob, + const objectURLOptions& aOptions, + nsAString& aResult, + ErrorResult& aError) +{ + nsCOMPtr w = do_QueryInterface(aGlobal); + nsGlobalWindow* window = static_cast(w.get()); + NS_PRECONDITION(!window || window->IsInnerWindow(), + "Should be inner window"); + + if (!window || !window->GetExtantDoc()) { + aError.Throw(NS_ERROR_INVALID_POINTER); + return; + } + + nsIDocument* doc = window->GetExtantDoc(); + + nsresult rv = aBlob->GetInternalUrl(doc->NodePrincipal(), aResult); + if (NS_FAILED(rv)) { + aError.Throw(rv); + return; + } + + doc->RegisterFileDataUri(NS_LossyConvertUTF16toASCII(aResult)); +} + +void +URL::RevokeObjectURL(nsISupports* aGlobal, const nsAString& aURL) +{ + nsCOMPtr w = do_QueryInterface(aGlobal); + nsGlobalWindow* window = static_cast(w.get()); + NS_PRECONDITION(!window || window->IsInnerWindow(), + "Should be inner window"); + if (!window) + return; + + NS_LossyConvertUTF16toASCII asciiurl(aURL); + + nsIPrincipal* winPrincipal = window->GetPrincipal(); + if (!winPrincipal) { + return; + } + + nsIPrincipal* principal = + nsBlobProtocolHandler::GetFileDataEntryPrincipal(asciiurl); + bool subsumes; + if (principal && winPrincipal && + NS_SUCCEEDED(winPrincipal->Subsumes(principal, &subsumes)) && + subsumes) { + if (window->GetExtantDoc()) { + window->GetExtantDoc()->UnregisterFileDataUri(asciiurl); + } + nsBlobProtocolHandler::RemoveFileDataEntry(asciiurl); + } +} + +} +} diff --git a/dom/base/URL.h b/dom/base/URL.h new file mode 100644 index 00000000000..868d6f0ffaf --- /dev/null +++ b/dom/base/URL.h @@ -0,0 +1,30 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef URL_h___ +#define URL_h___ + +#include "nscore.h" +#include "mozilla/dom/URLBinding.h" + +class nsIDOMBlob; + +namespace mozilla { +namespace dom { + +class URL MOZ_FINAL +{ +public: + // WebIDL methods + static void CreateObjectURL(nsISupports* aGlobal, nsIDOMBlob* aBlob, + const objectURLOptions& aOptions, + nsAString& aResult, + ErrorResult& aError); + static void RevokeObjectURL(nsISupports* aGlobal, const nsAString& aURL); +}; + +} +} + +#endif /* URL_h___ */ diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index 47e7cfc3f75..75d5b0e76ed 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -1434,8 +1434,6 @@ static nsDOMClassInfoData sClassInfoData[] = { DOM_DEFAULT_SCRIPTABLE_FLAGS) NS_DEFINE_CLASSINFO_DATA(ArchiveRequest, nsDOMGenericSH, DOM_DEFAULT_SCRIPTABLE_FLAGS) - NS_DEFINE_CLASSINFO_DATA(MozURLProperty, nsDOMGenericSH, - DOM_DEFAULT_SCRIPTABLE_FLAGS) NS_DEFINE_CLASSINFO_DATA(ModalContentWindow, nsWindowSH, DEFAULT_SCRIPTABLE_FLAGS | @@ -4008,10 +4006,6 @@ nsDOMClassInfo::Init() DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMRequest) DOM_CLASSINFO_MAP_END - DOM_CLASSINFO_MAP_BEGIN(MozURLProperty, nsIDOMMozURLProperty) - DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozURLProperty) - DOM_CLASSINFO_MAP_END - DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ModalContentWindow, nsIDOMWindow) DOM_CLASSINFO_WINDOW_MAP_ENTRIES(nsGlobalWindow::HasIndexedDBSupport()) DOM_CLASSINFO_MAP_ENTRY(nsIDOMModalContentWindow) diff --git a/dom/base/nsDOMClassInfoClasses.h b/dom/base/nsDOMClassInfoClasses.h index e5cd73bb57f..992fb4d025a 100644 --- a/dom/base/nsDOMClassInfoClasses.h +++ b/dom/base/nsDOMClassInfoClasses.h @@ -366,7 +366,6 @@ DOMCI_CLASS(File) DOMCI_CLASS(FileReader) DOMCI_CLASS(ArchiveReader) DOMCI_CLASS(ArchiveRequest) -DOMCI_CLASS(MozURLProperty) // DOM modal content window class, almost identical to Window DOMCI_CLASS(ModalContentWindow) diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 1860657cb46..a766d76025f 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -148,7 +148,6 @@ #include "nsAutoPtr.h" #include "nsContentUtils.h" #include "nsCSSProps.h" -#include "nsBlobProtocolHandler.h" #include "nsIDOMFile.h" #include "nsIDOMFileList.h" #include "nsIURIFixup.h" @@ -422,85 +421,6 @@ static const char sPopStatePrefStr[] = "browser.history.allowPopState"; #define NETWORK_UPLOAD_EVENT_NAME NS_LITERAL_STRING("moznetworkupload") #define NETWORK_DOWNLOAD_EVENT_NAME NS_LITERAL_STRING("moznetworkdownload") -/** - * An object implementing the window.URL property. - */ -class nsDOMMozURLProperty MOZ_FINAL : public nsIDOMMozURLProperty -{ -public: - nsDOMMozURLProperty(nsGlobalWindow* aWindow) - : mWindow(aWindow) - { - } - - NS_DECL_ISUPPORTS - NS_DECL_NSIDOMMOZURLPROPERTY - - void ClearWindowReference() { - mWindow = nullptr; - } -private: - nsGlobalWindow* mWindow; -}; - -DOMCI_DATA(MozURLProperty, nsDOMMozURLProperty) -NS_IMPL_ADDREF(nsDOMMozURLProperty) -NS_IMPL_RELEASE(nsDOMMozURLProperty) -NS_INTERFACE_MAP_BEGIN(nsDOMMozURLProperty) - NS_INTERFACE_MAP_ENTRY(nsIDOMMozURLProperty) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMozURLProperty) - NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozURLProperty) -NS_INTERFACE_MAP_END - -NS_IMETHODIMP -nsDOMMozURLProperty::CreateObjectURL(nsIDOMBlob* aBlob, nsAString& aURL) -{ - NS_PRECONDITION(!mWindow || mWindow->IsInnerWindow(), - "Should be inner window"); - - NS_ENSURE_STATE(mWindow && mWindow->mDoc); - NS_ENSURE_ARG_POINTER(aBlob); - - nsIDocument* doc = mWindow->mDoc; - - nsresult rv = aBlob->GetInternalUrl(doc->NodePrincipal(), aURL); - NS_ENSURE_SUCCESS(rv, rv); - - doc->RegisterFileDataUri(NS_LossyConvertUTF16toASCII(aURL)); - - return NS_OK; -} - -NS_IMETHODIMP -nsDOMMozURLProperty::RevokeObjectURL(const nsAString& aURL) -{ - NS_PRECONDITION(!mWindow || mWindow->IsInnerWindow(), - "Should be inner window"); - - NS_ENSURE_STATE(mWindow); - - NS_LossyConvertUTF16toASCII asciiurl(aURL); - - nsIPrincipal* winPrincipal = mWindow->GetPrincipal(); - if (!winPrincipal) { - return NS_OK; - } - - nsIPrincipal* principal = - nsBlobProtocolHandler::GetFileDataEntryPrincipal(asciiurl); - bool subsumes; - if (principal && winPrincipal && - NS_SUCCEEDED(winPrincipal->Subsumes(principal, &subsumes)) && - subsumes) { - if (mWindow->mDoc) { - mWindow->mDoc->UnregisterFileDataUri(asciiurl); - } - nsBlobProtocolHandler::RemoveFileDataEntry(asciiurl); - } - - return NS_OK; -} - /** * An indirect observer object that means we don't have to implement nsIObserver * on nsGlobalWindow, where any script could see it. @@ -928,10 +848,6 @@ nsGlobalWindow::~nsGlobalWindow() nsCycleCollector_DEBUG_wasFreed(static_cast(this)); #endif - if (mURLProperty) { - mURLProperty->ClearWindowReference(); - } - nsCOMPtr ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID); if (ac) ac->RemoveWindowAsListener(this); @@ -10770,20 +10686,6 @@ nsGlobalWindow::DisableDeviceSensor(uint32_t aType) } } -NS_IMETHODIMP -nsGlobalWindow::GetURL(nsIDOMMozURLProperty** aURL) -{ - FORWARD_TO_INNER(GetURL, (aURL), NS_ERROR_UNEXPECTED); - - if (!mURLProperty) { - mURLProperty = new nsDOMMozURLProperty(this); - } - - NS_ADDREF(*aURL = mURLProperty); - - return NS_OK; -} - void nsGlobalWindow::EnableTimeChangeNotifications() { diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index fb7dfa196b9..9b4ddb0f935 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -111,7 +111,6 @@ class PostMessageEvent; class nsRunnable; class nsDOMEventTargetHelper; class nsDOMOfflineResourceList; -class nsDOMMozURLProperty; class nsDOMWindowUtils; class nsIIdleService; @@ -124,6 +123,7 @@ class nsWindowSizes; namespace mozilla { namespace dom { class Navigator; +class URL; } // namespace dom } // namespace mozilla @@ -282,8 +282,6 @@ class nsGlobalWindow : public nsPIDOMWindow, #endif // MOZ_B2G { public: - friend class nsDOMMozURLProperty; - typedef mozilla::TimeStamp TimeStamp; typedef mozilla::TimeDuration TimeDuration; typedef mozilla::dom::Navigator Navigator; @@ -1128,8 +1126,6 @@ protected: // destroying this window). bool mDialogsPermanentlyDisabled; - nsRefPtr mURLProperty; - nsTHashtable > mEventTargetObjects; nsTArray mEnabledSensors; diff --git a/dom/base/nsPIDOMWindow.h b/dom/base/nsPIDOMWindow.h index 06c2320d0ee..c7ceb553a84 100644 --- a/dom/base/nsPIDOMWindow.h +++ b/dom/base/nsPIDOMWindow.h @@ -48,8 +48,8 @@ class nsIArray; class nsPIWindowRoot; #define NS_PIDOMWINDOW_IID \ -{ 0x54fd92bd, 0xda33, 0x4451, \ - { 0x8f, 0xb5, 0x11, 0x20, 0x5c, 0x03, 0xce, 0xaa } } +{ 0x7b18e421, 0x2179, 0x4e24, \ + { 0x96, 0x58, 0x26, 0x75, 0xa4, 0x37, 0xf3, 0x8f } } class nsPIDOMWindow : public nsIDOMWindowInternal { diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index c2e118a0f01..09f6c831cb6 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -365,6 +365,10 @@ DOMInterfaces = { 'implicitJSContext': [ 'encode' ], }, +'URL' : { + 'concrete': False, +}, + 'WebGLActiveInfo': { 'nativeType': 'mozilla::WebGLActiveInfo', 'headerFile': 'WebGLContext.h', diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 0bf2b398544..3db17e980c0 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -5636,50 +5636,53 @@ class CGDescriptor(CGThing): assert not descriptor.concrete or descriptor.interface.hasInterfacePrototypeObject() cgThings = [] - if descriptor.interface.hasInterfacePrototypeObject(): - # These are set to true if at least one non-static - # method/getter/setter exist on the interface. - (hasMethod, hasGetter, hasLenientGetter, - hasSetter, hasLenientSetter) = False, False, False, False, False - for m in descriptor.interface.members: - if (m.isMethod() and - (not m.isIdentifierLess() or m == descriptor.operations['Stringifier'])): - if m.isStatic(): - cgThings.append(CGStaticMethod(descriptor, m)) + # These are set to true if at least one non-static + # method/getter/setter exist on the interface. + (hasMethod, hasGetter, hasLenientGetter, + hasSetter, hasLenientSetter) = False, False, False, False, False + for m in descriptor.interface.members: + if (m.isMethod() and + (not m.isIdentifierLess() or m == descriptor.operations['Stringifier'])): + if m.isStatic(): + assert descriptor.interface.hasInterfaceObject + cgThings.append(CGStaticMethod(descriptor, m)) + elif descriptor.interface.hasInterfacePrototypeObject(): + cgThings.append(CGSpecializedMethod(descriptor, m)) + cgThings.append(CGMemberJITInfo(descriptor, m)) + hasMethod = True + elif m.isAttr(): + if m.isStatic(): + assert descriptor.interface.hasInterfaceObject + cgThings.append(CGStaticGetter(descriptor, m)) + elif descriptor.interface.hasInterfacePrototypeObject(): + cgThings.append(CGSpecializedGetter(descriptor, m)) + if m.hasLenientThis(): + hasLenientGetter = True else: - cgThings.append(CGSpecializedMethod(descriptor, m)) - cgThings.append(CGMemberJITInfo(descriptor, m)) - hasMethod = True - elif m.isAttr(): + hasGetter = True + if not m.readonly: if m.isStatic(): - cgThings.append(CGStaticGetter(descriptor, m)) - else: - cgThings.append(CGSpecializedGetter(descriptor, m)) + assert descriptor.interface.hasInterfaceObject + cgThings.append(CGStaticSetter(descriptor, m)) + elif descriptor.interface.hasInterfacePrototypeObject(): + cgThings.append(CGSpecializedSetter(descriptor, m)) if m.hasLenientThis(): - hasLenientGetter = True + hasLenientSetter = True else: - hasGetter = True - if not m.readonly: - if m.isStatic(): - cgThings.append(CGStaticSetter(descriptor, m)) - else: - cgThings.append(CGSpecializedSetter(descriptor, m)) - if m.hasLenientThis(): - hasLenientSetter = True - else: - hasSetter = True - elif m.getExtendedAttribute("PutForwards"): - cgThings.append(CGSpecializedForwardingSetter(descriptor, m)) - hasSetter = True - if not m.isStatic(): - cgThings.append(CGMemberJITInfo(descriptor, m)) - if hasMethod: cgThings.append(CGGenericMethod(descriptor)) - if hasGetter: cgThings.append(CGGenericGetter(descriptor)) - if hasLenientGetter: cgThings.append(CGGenericGetter(descriptor, - lenientThis=True)) - if hasSetter: cgThings.append(CGGenericSetter(descriptor)) - if hasLenientSetter: cgThings.append(CGGenericSetter(descriptor, - lenientThis=True)) + hasSetter = True + elif m.getExtendedAttribute("PutForwards"): + cgThings.append(CGSpecializedForwardingSetter(descriptor, m)) + hasSetter = True + if (not m.isStatic() and + descriptor.interface.hasInterfacePrototypeObject()): + cgThings.append(CGMemberJITInfo(descriptor, m)) + if hasMethod: cgThings.append(CGGenericMethod(descriptor)) + if hasGetter: cgThings.append(CGGenericGetter(descriptor)) + if hasLenientGetter: cgThings.append(CGGenericGetter(descriptor, + lenientThis=True)) + if hasSetter: cgThings.append(CGGenericSetter(descriptor)) + if hasLenientSetter: cgThings.append(CGGenericSetter(descriptor, + lenientThis=True)) if descriptor.concrete: if descriptor.nativeOwnership == 'owned' or descriptor.nativeOwnership == 'refcounted': diff --git a/dom/interfaces/base/nsIDOMWindow.idl b/dom/interfaces/base/nsIDOMWindow.idl index 26b9b680707..4b4da4eed5b 100644 --- a/dom/interfaces/base/nsIDOMWindow.idl +++ b/dom/interfaces/base/nsIDOMWindow.idl @@ -16,13 +16,6 @@ interface nsIPrompt; interface nsISelection; interface nsIVariant; -[scriptable, uuid(8fc58f56-f769-4368-a098-edd08550cf1a)] -interface nsIDOMMozURLProperty : nsISupports -{ - DOMString createObjectURL(in nsIDOMBlob blob); - void revokeObjectURL(in DOMString URL); -}; - /** * The nsIDOMWindow interface is the primary interface for a DOM * window object. It represents a single window object that may @@ -32,7 +25,7 @@ interface nsIDOMMozURLProperty : nsISupports * @see */ -[scriptable, uuid(1534ecd7-e298-420e-9063-e6c2d1243d49)] +[scriptable, uuid(b9c71e0b-7f81-419a-8253-91f4c8893c4f)] interface nsIDOMWindow : nsISupports { // the current browsing context @@ -461,11 +454,6 @@ interface nsIDOMWindow : nsISupports */ readonly attribute long long mozAnimationStartTime; - /** - * @see - */ - readonly attribute nsIDOMMozURLProperty URL; - /** * HTML5 event attributes that only apply to windows and / */ @@ -525,5 +513,5 @@ interface nsIWindowCrypto : nsISupports * Empty interface for compatibility with older versions. * @deprecated Use nsIDOMWindow instead */ -[scriptable, uuid(8da641ab-906a-456e-97f2-b77df4ca2d95)] +[scriptable, uuid(a5cd0946-bac1-4606-9aaa-9e68dd0a3279)] interface nsIDOMWindowInternal : nsIDOMWindow {}; diff --git a/dom/tests/mochitest/general/test_interfaces.html b/dom/tests/mochitest/general/test_interfaces.html index e21234a5118..9eec189bb11 100644 --- a/dom/tests/mochitest/general/test_interfaces.html +++ b/dom/tests/mochitest/general/test_interfaces.html @@ -342,7 +342,7 @@ var interfaceNamesInGlobalScope = "HTMLSelectElement", "MessageEvent", "SVGFEImageElement", - "MozURLProperty", + "URL", "DeviceStorage", "SVGFEOffsetElement", "DOMImplementation", diff --git a/dom/webidl/URL.webidl b/dom/webidl/URL.webidl new file mode 100644 index 00000000000..9b9908f87a2 --- /dev/null +++ b/dom/webidl/URL.webidl @@ -0,0 +1,23 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * The origins of this IDL file are + * http://dev.w3.org/2006/webapi/FileAPI/#creating-revoking + * http://dev.w3.org/2011/webrtc/editor/getusermedia.html#url + * + * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C + * liability, trademark and document use rules apply. + */ + +interface URL { + [Throws] + static DOMString? createObjectURL(Blob blob, optional objectURLOptions options); + static void revokeObjectURL(DOMString url); +}; + +dictionary objectURLOptions +{ +/* boolean autoRevoke = true; */ /* not supported yet */ +}; diff --git a/dom/webidl/WebIDL.mk b/dom/webidl/WebIDL.mk index 1f90f32ec00..737a878e204 100644 --- a/dom/webidl/WebIDL.mk +++ b/dom/webidl/WebIDL.mk @@ -52,6 +52,7 @@ webidl_files = \ SVGTransformList.webidl \ TextDecoder.webidl \ TextEncoder.webidl \ + URL.webidl \ WebSocket.webidl \ XMLHttpRequest.webidl \ XMLHttpRequestEventTarget.webidl \ From 52979461b74412032ad8405537ac3f3fb9c3eb63 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 25 Sep 2012 15:24:43 +1200 Subject: [PATCH 07/39] Bug 792675. Part 2: Change assertion to warning since Web content can trigger it (trying to create URIs relative to a blob URI). r=sicking --HG-- extra : rebase_source : 256474307aeed04af0aae1445a2e488a5afb8fb0 --- content/base/src/nsBlobProtocolHandler.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/base/src/nsBlobProtocolHandler.cpp b/content/base/src/nsBlobProtocolHandler.cpp index d8b51598e05..856fcdb2aad 100644 --- a/content/base/src/nsBlobProtocolHandler.cpp +++ b/content/base/src/nsBlobProtocolHandler.cpp @@ -69,9 +69,9 @@ nsBlobProtocolHandler::GetFileDataEntryPrincipal(nsACString& aUri) static FileDataInfo* GetFileDataInfo(const nsACString& aUri) { - NS_ASSERTION(StringBeginsWith(aUri, - NS_LITERAL_CSTRING(BLOBURI_SCHEME ":")), - "Bad URI"); + NS_WARN_IF_FALSE(StringBeginsWith(aUri, + NS_LITERAL_CSTRING(BLOBURI_SCHEME ":")), + "Bad URI"); if (!gFileDataTable) { return nullptr; From 7b4c5ebb95de96b39b8c28c1911b270359c56aef Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 25 Sep 2012 15:24:44 +1200 Subject: [PATCH 08/39] Bug 792675. Part 4: Refactor nsBlobURI/nsBlobProtocolHandler to nsHostObjectURI/nsHostObjectProtocolHandler. r=sicking The code to handle MediaStream URIs is almost the same as for Blobs, so share it. nsHostObjectProtocolHandler is modified a bit to simplify method names. Also we make nsHostObjectProtocolHandler::AddDataEntry take responsibility for generating the URI to avoid duplicating that code later. We need separate subclasses for each kind of host object protocol handler, but we don't need separate subclasses for each kind of host object URI. --HG-- rename : content/base/public/nsBlobProtocolHandler.h => content/base/public/nsHostObjectProtocolHandler.h rename : content/base/src/nsBlobProtocolHandler.cpp => content/base/src/nsHostObjectProtocolHandler.cpp rename : content/base/src/nsBlobURI.cpp => content/base/src/nsHostObjectURI.cpp rename : content/base/src/nsBlobURI.h => content/base/src/nsHostObjectURI.h extra : rebase_source : bfb1d7ea2813100a35f9a2054a67584e38f5f330 --- content/base/public/Makefile.in | 2 +- content/base/public/nsBlobProtocolHandler.h | 51 ---- .../base/public/nsHostObjectProtocolHandler.h | 60 +++++ content/base/public/nsIDocument.h | 12 +- content/base/src/Makefile.in | 4 +- content/base/src/nsBlobProtocolHandler.cpp | 217 ---------------- content/base/src/nsDOMFile.cpp | 29 +-- content/base/src/nsDOMFileReader.cpp | 2 +- content/base/src/nsDocument.cpp | 14 +- content/base/src/nsDocument.h | 6 +- .../base/src/nsHostObjectProtocolHandler.cpp | 239 ++++++++++++++++++ .../{nsBlobURI.cpp => nsHostObjectURI.cpp} | 72 +++--- .../src/{nsBlobURI.h => nsHostObjectURI.h} | 25 +- content/media/MediaResource.cpp | 2 +- dom/base/URL.cpp | 26 +- dom/base/URL.h | 7 + layout/build/nsLayoutModule.cpp | 10 +- 17 files changed, 411 insertions(+), 367 deletions(-) delete mode 100644 content/base/public/nsBlobProtocolHandler.h create mode 100644 content/base/public/nsHostObjectProtocolHandler.h delete mode 100644 content/base/src/nsBlobProtocolHandler.cpp create mode 100644 content/base/src/nsHostObjectProtocolHandler.cpp rename content/base/src/{nsBlobURI.cpp => nsHostObjectURI.cpp} (63%) rename content/base/src/{nsBlobURI.h => nsHostObjectURI.h} (69%) diff --git a/content/base/public/Makefile.in b/content/base/public/Makefile.in index 39359091c68..0b9bc4c55ee 100644 --- a/content/base/public/Makefile.in +++ b/content/base/public/Makefile.in @@ -42,7 +42,7 @@ nsReferencedElement.h \ nsTreeSanitizer.h \ nsXMLNameSpaceMap.h \ nsIXFormsUtilityService.h \ -nsBlobProtocolHandler.h \ +nsHostObjectProtocolHandler.h \ $(NULL) EXPORTS_NAMESPACES = mozilla/dom mozilla diff --git a/content/base/public/nsBlobProtocolHandler.h b/content/base/public/nsBlobProtocolHandler.h deleted file mode 100644 index f9560bddda5..00000000000 --- a/content/base/public/nsBlobProtocolHandler.h +++ /dev/null @@ -1,51 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nsBlobProtocolHandler_h -#define nsBlobProtocolHandler_h - -#include "nsIProtocolHandler.h" -#include "nsIURI.h" -#include "nsCOMPtr.h" - -#define BLOBURI_SCHEME "blob" - -class nsIDOMBlob; -class nsIPrincipal; -class nsIInputStream; - -inline bool IsBlobURI(nsIURI* aUri) -{ - bool isBlob; - return NS_SUCCEEDED(aUri->SchemeIs(BLOBURI_SCHEME, &isBlob)) && isBlob; -} - -extern nsresult -NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream); - -class nsBlobProtocolHandler : public nsIProtocolHandler -{ -public: - NS_DECL_ISUPPORTS - - // nsIProtocolHandler methods: - NS_DECL_NSIPROTOCOLHANDLER - - // nsBlobProtocolHandler methods: - nsBlobProtocolHandler() {} - virtual ~nsBlobProtocolHandler() {} - - // Methods for managing uri->file mapping - static void AddFileDataEntry(nsACString& aUri, - nsIDOMBlob* aFile, - nsIPrincipal* aPrincipal); - static void RemoveFileDataEntry(nsACString& aUri); - static nsIPrincipal* GetFileDataEntryPrincipal(nsACString& aUri); -}; - -#define NS_BLOBPROTOCOLHANDLER_CID \ -{ 0xb43964aa, 0xa078, 0x44b2, \ - { 0xb0, 0x6b, 0xfd, 0x4d, 0x1b, 0x17, 0x2e, 0x66 } } - -#endif /* nsBlobProtocolHandler_h */ diff --git a/content/base/public/nsHostObjectProtocolHandler.h b/content/base/public/nsHostObjectProtocolHandler.h new file mode 100644 index 00000000000..98c9782cc9f --- /dev/null +++ b/content/base/public/nsHostObjectProtocolHandler.h @@ -0,0 +1,60 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsHostObjectProtocolHandler_h +#define nsHostObjectProtocolHandler_h + +#include "nsIProtocolHandler.h" +#include "nsIURI.h" +#include "nsCOMPtr.h" + +#define BLOBURI_SCHEME "blob" + +class nsIDOMBlob; +class nsIPrincipal; +class nsIInputStream; + +class nsHostObjectProtocolHandler : public nsIProtocolHandler +{ +public: + NS_DECL_ISUPPORTS + + // nsIProtocolHandler methods, except for GetScheme which is only defined + // in subclasses. + NS_IMETHOD GetDefaultPort(int32_t *aDefaultPort); + NS_IMETHOD GetProtocolFlags(uint32_t *aProtocolFlags); + NS_IMETHOD NewURI(const nsACString & aSpec, const char * aOriginCharset, nsIURI *aBaseURI, nsIURI * *_retval); + NS_IMETHOD NewChannel(nsIURI *aURI, nsIChannel * *_retval); + NS_IMETHOD AllowPort(int32_t port, const char * scheme, bool *_retval); + + // Methods for managing uri->object mapping + // AddDataEntry creates the URI with the given scheme and returns it in aUri + static nsresult AddDataEntry(const nsACString& aScheme, + nsISupports* aObject, + nsIPrincipal* aPrincipal, + nsACString& aUri); + static void RemoveDataEntry(const nsACString& aUri); + static nsIPrincipal* GetDataEntryPrincipal(const nsACString& aUri); +}; + +class nsBlobProtocolHandler : public nsHostObjectProtocolHandler +{ +public: + NS_IMETHOD GetScheme(nsACString &result); +}; + +inline bool IsBlobURI(nsIURI* aUri) +{ + bool isBlob; + return NS_SUCCEEDED(aUri->SchemeIs(BLOBURI_SCHEME, &isBlob)) && isBlob; +} + +extern nsresult +NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream); + +#define NS_BLOBPROTOCOLHANDLER_CID \ +{ 0xb43964aa, 0xa078, 0x44b2, \ + { 0xb0, 0x6b, 0xfd, 0x4d, 0x1b, 0x17, 0x2e, 0x66 } } + +#endif /* nsHostObjectProtocolHandler_h */ diff --git a/content/base/public/nsIDocument.h b/content/base/public/nsIDocument.h index 210a744c901..5afca033585 100644 --- a/content/base/public/nsIDocument.h +++ b/content/base/public/nsIDocument.h @@ -79,8 +79,8 @@ class Element; } // namespace mozilla #define NS_IDOCUMENT_IID \ -{ 0x0e1324c9, 0xc997, 0x447e, \ - { 0xbc, 0xd9, 0xa6, 0x57, 0x80, 0x29, 0x91, 0xe4 } } +{ 0x20d19edb, 0xa74c, 0x4ce4, \ + { 0xb2, 0x7c, 0x5b, 0xdd, 0x6f, 0xbd, 0x2b, 0x66 } } // Flag for AddStyleSheet(). #define NS_STYLESHEET_FROM_CATALOG (1 << 0) @@ -1557,13 +1557,13 @@ public: virtual nsISupports* GetCurrentContentSink() = 0; /** - * Register/Unregister a filedata uri as being "owned" by this document. + * Register/Unregister a hostobject uri as being "owned" by this document. * I.e. that its lifetime is connected with this document. When the document * goes away it should "kill" the uri by calling - * nsBlobProtocolHandler::RemoveFileDataEntry + * nsHostObjectProtocolHandler::RemoveDataEntry */ - virtual void RegisterFileDataUri(const nsACString& aUri) = 0; - virtual void UnregisterFileDataUri(const nsACString& aUri) = 0; + virtual void RegisterHostObjectUri(const nsACString& aUri) = 0; + virtual void UnregisterHostObjectUri(const nsACString& aUri) = 0; virtual void SetScrollToRef(nsIURI *aDocumentURI) = 0; virtual void ScrollToRef() = 0; diff --git a/content/base/src/Makefile.in b/content/base/src/Makefile.in index a1c09fa5b01..3cbf5c23324 100644 --- a/content/base/src/Makefile.in +++ b/content/base/src/Makefile.in @@ -127,8 +127,8 @@ CPPSRCS = \ nsXMLNameSpaceMap.cpp \ FragmentOrElement.cpp \ Link.cpp \ - nsBlobProtocolHandler.cpp \ - nsBlobURI.cpp \ + nsHostObjectProtocolHandler.cpp \ + nsHostObjectURI.cpp \ nsFrameMessageManager.cpp \ nsInProcessTabChildGlobal.cpp \ ThirdPartyUtil.cpp \ diff --git a/content/base/src/nsBlobProtocolHandler.cpp b/content/base/src/nsBlobProtocolHandler.cpp deleted file mode 100644 index 856fcdb2aad..00000000000 --- a/content/base/src/nsBlobProtocolHandler.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsBlobProtocolHandler.h" -#include "nsBlobURI.h" -#include "nsError.h" -#include "nsClassHashtable.h" -#include "nsNetUtil.h" -#include "nsIPrincipal.h" -#include "nsIDOMFile.h" - -// ----------------------------------------------------------------------- -// Hash table -struct FileDataInfo -{ - nsCOMPtr mFile; - nsCOMPtr mPrincipal; -}; - -static nsClassHashtable* gFileDataTable; - -void -nsBlobProtocolHandler::AddFileDataEntry(nsACString& aUri, - nsIDOMBlob* aFile, - nsIPrincipal* aPrincipal) -{ - if (!gFileDataTable) { - gFileDataTable = new nsClassHashtable; - gFileDataTable->Init(); - } - - FileDataInfo* info = new FileDataInfo; - - info->mFile = aFile; - info->mPrincipal = aPrincipal; - - gFileDataTable->Put(aUri, info); -} - -void -nsBlobProtocolHandler::RemoveFileDataEntry(nsACString& aUri) -{ - if (gFileDataTable) { - gFileDataTable->Remove(aUri); - if (gFileDataTable->Count() == 0) { - delete gFileDataTable; - gFileDataTable = nullptr; - } - } -} - -nsIPrincipal* -nsBlobProtocolHandler::GetFileDataEntryPrincipal(nsACString& aUri) -{ - if (!gFileDataTable) { - return nullptr; - } - - FileDataInfo* res; - gFileDataTable->Get(aUri, &res); - if (!res) { - return nullptr; - } - - return res->mPrincipal; -} - -static FileDataInfo* -GetFileDataInfo(const nsACString& aUri) -{ - NS_WARN_IF_FALSE(StringBeginsWith(aUri, - NS_LITERAL_CSTRING(BLOBURI_SCHEME ":")), - "Bad URI"); - - if (!gFileDataTable) { - return nullptr; - } - - FileDataInfo* res; - gFileDataTable->Get(aUri, &res); - return res; -} - -// ----------------------------------------------------------------------- -// Protocol handler - -NS_IMPL_ISUPPORTS1(nsBlobProtocolHandler, nsIProtocolHandler) - -NS_IMETHODIMP -nsBlobProtocolHandler::GetScheme(nsACString &result) -{ - result.AssignLiteral(BLOBURI_SCHEME); - return NS_OK; -} - -NS_IMETHODIMP -nsBlobProtocolHandler::GetDefaultPort(int32_t *result) -{ - *result = -1; - return NS_OK; -} - -NS_IMETHODIMP -nsBlobProtocolHandler::GetProtocolFlags(uint32_t *result) -{ - *result = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_SUBSUMERS | - URI_IS_LOCAL_RESOURCE | URI_NON_PERSISTABLE; - return NS_OK; -} - -NS_IMETHODIMP -nsBlobProtocolHandler::NewURI(const nsACString& aSpec, - const char *aCharset, - nsIURI *aBaseURI, - nsIURI **aResult) -{ - *aResult = nullptr; - nsresult rv; - - FileDataInfo* info = - GetFileDataInfo(aSpec); - - nsRefPtr uri = - new nsBlobURI(info ? info->mPrincipal.get() : nullptr); - - rv = uri->SetSpec(aSpec); - NS_ENSURE_SUCCESS(rv, rv); - - NS_TryToSetImmutable(uri); - uri.forget(aResult); - - return NS_OK; -} - -NS_IMETHODIMP -nsBlobProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result) -{ - *result = nullptr; - - nsCString spec; - uri->GetSpec(spec); - - FileDataInfo* info = - GetFileDataInfo(spec); - - if (!info) { - return NS_ERROR_DOM_BAD_URI; - } - -#ifdef DEBUG - { - nsCOMPtr uriPrinc = do_QueryInterface(uri); - nsCOMPtr principal; - uriPrinc->GetPrincipal(getter_AddRefs(principal)); - NS_ASSERTION(info->mPrincipal == principal, "Wrong principal!"); - } -#endif - - nsCOMPtr stream; - nsresult rv = info->mFile->GetInternalStream(getter_AddRefs(stream)); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr channel; - rv = NS_NewInputStreamChannel(getter_AddRefs(channel), - uri, - stream); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr owner = do_QueryInterface(info->mPrincipal); - - nsAutoString type; - rv = info->mFile->GetType(type); - NS_ENSURE_SUCCESS(rv, rv); - - uint64_t size; - rv = info->mFile->GetSize(&size); - NS_ENSURE_SUCCESS(rv, rv); - - channel->SetOwner(owner); - channel->SetOriginalURI(uri); - channel->SetContentType(NS_ConvertUTF16toUTF8(type)); - channel->SetContentLength(size); - - channel.forget(result); - - return NS_OK; -} - -NS_IMETHODIMP -nsBlobProtocolHandler::AllowPort(int32_t port, const char *scheme, - bool *_retval) -{ - // don't override anything. - *_retval = false; - return NS_OK; -} - -nsresult -NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream) -{ - NS_ASSERTION(IsBlobURI(aURI), "Only call this with blob URIs"); - - *aStream = nullptr; - - nsCString spec; - aURI->GetSpec(spec); - - FileDataInfo* info = - GetFileDataInfo(spec); - - if (!info) { - return NS_ERROR_DOM_BAD_URI; - } - - return info->mFile->GetInternalStream(aStream); -} diff --git a/content/base/src/nsDOMFile.cpp b/content/base/src/nsDOMFile.cpp index 61cba27f6c1..6356909b2c1 100644 --- a/content/base/src/nsDOMFile.cpp +++ b/content/base/src/nsDOMFile.cpp @@ -27,7 +27,7 @@ #include "nsNetCID.h" #include "nsNetUtil.h" #include "nsIUUIDGenerator.h" -#include "nsBlobProtocolHandler.h" +#include "nsHostObjectProtocolHandler.h" #include "nsStringStream.h" #include "nsJSUtils.h" #include "nsPrintfCString.h" @@ -284,26 +284,15 @@ nsDOMFileBase::GetInternalUrl(nsIPrincipal* aPrincipal, nsAString& aURL) { NS_ENSURE_STATE(aPrincipal); - nsresult rv; - nsCOMPtr uuidgen = - do_GetService("@mozilla.org/uuid-generator;1", &rv); - NS_ENSURE_SUCCESS(rv, rv); - - nsID id; - rv = uuidgen->GenerateUUIDInPlace(&id); - NS_ENSURE_SUCCESS(rv, rv); - - char chars[NSID_LENGTH]; - id.ToProvidedString(chars); - - nsCString url = NS_LITERAL_CSTRING(BLOBURI_SCHEME ":") + - Substring(chars + 1, chars + NSID_LENGTH - 2); - - nsBlobProtocolHandler::AddFileDataEntry(url, this, - aPrincipal); + nsCString url; + nsresult rv = nsBlobProtocolHandler::AddDataEntry( + NS_LITERAL_CSTRING(BLOBURI_SCHEME), + static_cast(this), aPrincipal, url); + if (NS_FAILED(rv)) { + return rv; + } CopyASCIItoUTF16(url, aURL); - return NS_OK; } @@ -859,6 +848,6 @@ nsDOMFileInternalUrlHolder::~nsDOMFileInternalUrlHolder() { if (!mUrl.IsEmpty()) { nsAutoCString narrowUrl; CopyUTF16toUTF8(mUrl, narrowUrl); - nsBlobProtocolHandler::RemoveFileDataEntry(narrowUrl); + nsBlobProtocolHandler::RemoveDataEntry(narrowUrl); } } diff --git a/content/base/src/nsDOMFileReader.cpp b/content/base/src/nsDOMFileReader.cpp index 18ddc9befda..4741abfe7bd 100644 --- a/content/base/src/nsDOMFileReader.cpp +++ b/content/base/src/nsDOMFileReader.cpp @@ -38,7 +38,7 @@ #include "nsCycleCollectionParticipant.h" #include "nsLayoutStatics.h" #include "nsIScriptObjectPrincipal.h" -#include "nsBlobProtocolHandler.h" +#include "nsHostObjectProtocolHandler.h" #include "mozilla/Preferences.h" #include "mozilla/dom/EncodingUtils.h" #include "xpcpublic.h" diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index 46ec71f3fb7..04c762ddd4b 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -107,7 +107,7 @@ #include "nsIDOMHTMLFormElement.h" #include "nsIRequest.h" #include "nsILink.h" -#include "nsBlobProtocolHandler.h" +#include "nsHostObjectProtocolHandler.h" #include "nsCharsetAlias.h" #include "nsCharsetSource.h" @@ -1445,8 +1445,8 @@ nsDocument::~nsDocument() mPendingTitleChangeEvent.Revoke(); - for (uint32_t i = 0; i < mFileDataUris.Length(); ++i) { - nsBlobProtocolHandler::RemoveFileDataEntry(mFileDataUris[i]); + for (uint32_t i = 0; i < mHostObjectURIs.Length(); ++i) { + nsHostObjectProtocolHandler::RemoveDataEntry(mHostObjectURIs[i]); } // We don't want to leave residual locks on images. Make sure we're in an @@ -7595,15 +7595,15 @@ nsDocument::GetCurrentContentSink() } void -nsDocument::RegisterFileDataUri(const nsACString& aUri) +nsDocument::RegisterHostObjectUri(const nsACString& aUri) { - mFileDataUris.AppendElement(aUri); + mHostObjectURIs.AppendElement(aUri); } void -nsDocument::UnregisterFileDataUri(const nsACString& aUri) +nsDocument::UnregisterHostObjectUri(const nsACString& aUri) { - mFileDataUris.RemoveElement(aUri); + mHostObjectURIs.RemoveElement(aUri); } void diff --git a/content/base/src/nsDocument.h b/content/base/src/nsDocument.h index a242ee09b39..82cdc610c98 100644 --- a/content/base/src/nsDocument.h +++ b/content/base/src/nsDocument.h @@ -839,7 +839,7 @@ public: virtual NS_HIDDEN_(void) EnumerateExternalResources(nsSubDocEnumFunc aCallback, void* aData); - nsTArray mFileDataUris; + nsTArray mHostObjectURIs; // Returns our (lazily-initialized) animation controller. // If HasAnimationController is true, this is guaranteed to return non-null. @@ -891,8 +891,8 @@ public: virtual nsEventStates GetDocumentState(); - virtual void RegisterFileDataUri(const nsACString& aUri); - virtual void UnregisterFileDataUri(const nsACString& aUri); + virtual void RegisterHostObjectUri(const nsACString& aUri); + virtual void UnregisterHostObjectUri(const nsACString& aUri); // Only BlockOnload should call this! void AsyncBlockOnload(); diff --git a/content/base/src/nsHostObjectProtocolHandler.cpp b/content/base/src/nsHostObjectProtocolHandler.cpp new file mode 100644 index 00000000000..0ada9af32dd --- /dev/null +++ b/content/base/src/nsHostObjectProtocolHandler.cpp @@ -0,0 +1,239 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsHostObjectProtocolHandler.h" +#include "nsHostObjectURI.h" +#include "nsError.h" +#include "nsClassHashtable.h" +#include "nsNetUtil.h" +#include "nsIPrincipal.h" +#include "nsIDOMFile.h" + +// ----------------------------------------------------------------------- +// Hash table +struct DataInfo +{ + // mObject must be an nsIDOMBlob + nsCOMPtr mObject; + nsCOMPtr mPrincipal; +}; + +static nsClassHashtable* gDataTable; + +nsresult +nsHostObjectProtocolHandler::AddDataEntry(const nsACString& aScheme, + nsISupports* aObject, + nsIPrincipal* aPrincipal, + nsACString& aUri) +{ + nsresult rv; + nsCOMPtr uuidgen = + do_GetService("@mozilla.org/uuid-generator;1", &rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsID id; + rv = uuidgen->GenerateUUIDInPlace(&id); + NS_ENSURE_SUCCESS(rv, rv); + + char chars[NSID_LENGTH]; + id.ToProvidedString(chars); + + aUri += aScheme; + aUri += NS_LITERAL_CSTRING(":"); + aUri += Substring(chars + 1, chars + NSID_LENGTH - 2); + + if (!gDataTable) { + gDataTable = new nsClassHashtable; + gDataTable->Init(); + } + + DataInfo* info = new DataInfo; + + info->mObject = aObject; + info->mPrincipal = aPrincipal; + + gDataTable->Put(aUri, info); + return NS_OK; +} + +void +nsHostObjectProtocolHandler::RemoveDataEntry(const nsACString& aUri) +{ + if (gDataTable) { + gDataTable->Remove(aUri); + if (gDataTable->Count() == 0) { + delete gDataTable; + gDataTable = nullptr; + } + } +} + +nsIPrincipal* +nsHostObjectProtocolHandler::GetDataEntryPrincipal(const nsACString& aUri) +{ + if (!gDataTable) { + return nullptr; + } + + DataInfo* res; + gDataTable->Get(aUri, &res); + if (!res) { + return nullptr; + } + + return res->mPrincipal; +} + +static DataInfo* +GetDataInfo(const nsACString& aUri) +{ + if (!gDataTable) { + return nullptr; + } + + DataInfo* res; + gDataTable->Get(aUri, &res); + return res; +} + +static nsISupports* +GetDataObject(nsIURI* aURI) +{ + nsCString spec; + aURI->GetSpec(spec); + + DataInfo* info = GetDataInfo(spec); + return info ? info->mObject : nullptr; +} + +// ----------------------------------------------------------------------- +// Protocol handler + +NS_IMPL_ISUPPORTS1(nsHostObjectProtocolHandler, nsIProtocolHandler) + +NS_IMETHODIMP +nsHostObjectProtocolHandler::GetDefaultPort(int32_t *result) +{ + *result = -1; + return NS_OK; +} + +NS_IMETHODIMP +nsHostObjectProtocolHandler::GetProtocolFlags(uint32_t *result) +{ + *result = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_SUBSUMERS | + URI_IS_LOCAL_RESOURCE | URI_NON_PERSISTABLE; + return NS_OK; +} + +NS_IMETHODIMP +nsHostObjectProtocolHandler::NewURI(const nsACString& aSpec, + const char *aCharset, + nsIURI *aBaseURI, + nsIURI **aResult) +{ + *aResult = nullptr; + nsresult rv; + + DataInfo* info = GetDataInfo(aSpec); + + nsRefPtr uri = + new nsHostObjectURI(info ? info->mPrincipal.get() : nullptr); + + rv = uri->SetSpec(aSpec); + NS_ENSURE_SUCCESS(rv, rv); + + NS_TryToSetImmutable(uri); + uri.forget(aResult); + + return NS_OK; +} + +NS_IMETHODIMP +nsHostObjectProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result) +{ + *result = nullptr; + + nsCString spec; + uri->GetSpec(spec); + + DataInfo* info = GetDataInfo(spec); + + if (!info) { + return NS_ERROR_DOM_BAD_URI; + } + nsCOMPtr blob = do_QueryInterface(info->mObject); + if (!blob) { + return NS_ERROR_DOM_BAD_URI; + } + +#ifdef DEBUG + { + nsCOMPtr uriPrinc = do_QueryInterface(uri); + nsCOMPtr principal; + uriPrinc->GetPrincipal(getter_AddRefs(principal)); + NS_ASSERTION(info->mPrincipal == principal, "Wrong principal!"); + } +#endif + + nsCOMPtr stream; + nsresult rv = blob->GetInternalStream(getter_AddRefs(stream)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr channel; + rv = NS_NewInputStreamChannel(getter_AddRefs(channel), + uri, + stream); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr owner = do_QueryInterface(info->mPrincipal); + + nsAutoString type; + rv = blob->GetType(type); + NS_ENSURE_SUCCESS(rv, rv); + + uint64_t size; + rv = blob->GetSize(&size); + NS_ENSURE_SUCCESS(rv, rv); + + channel->SetOwner(owner); + channel->SetOriginalURI(uri); + channel->SetContentType(NS_ConvertUTF16toUTF8(type)); + channel->SetContentLength(size); + + channel.forget(result); + + return NS_OK; +} + +NS_IMETHODIMP +nsHostObjectProtocolHandler::AllowPort(int32_t port, const char *scheme, + bool *_retval) +{ + // don't override anything. + *_retval = false; + return NS_OK; +} + +NS_IMETHODIMP +nsBlobProtocolHandler::GetScheme(nsACString &result) +{ + result.AssignLiteral(BLOBURI_SCHEME); + return NS_OK; +} + +nsresult +NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream) +{ + NS_ASSERTION(IsBlobURI(aURI), "Only call this with blob URIs"); + + *aStream = nullptr; + + nsCOMPtr blob = do_QueryInterface(GetDataObject(aURI)); + if (!blob) { + return NS_ERROR_DOM_BAD_URI; + } + + return blob->GetInternalStream(aStream); +} diff --git a/content/base/src/nsBlobURI.cpp b/content/base/src/nsHostObjectURI.cpp similarity index 63% rename from content/base/src/nsBlobURI.cpp rename to content/base/src/nsHostObjectURI.cpp index f4f3cabc5a6..aeeb9003f49 100644 --- a/content/base/src/nsBlobURI.cpp +++ b/content/base/src/nsHostObjectURI.cpp @@ -2,24 +2,24 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "nsBlobURI.h" +#include "nsHostObjectURI.h" #include "nsAutoPtr.h" #include "nsIObjectInputStream.h" #include "nsIObjectOutputStream.h" #include "nsIProgrammingLanguage.h" -static NS_DEFINE_CID(kBLOBURICID, NS_BLOBURI_CID); +static NS_DEFINE_CID(kHOSTOBJECTURICID, NS_HOSTOBJECTURI_CID); static NS_DEFINE_CID(kThisSimpleURIImplementationCID, NS_THIS_SIMPLEURI_IMPLEMENTATION_CID); -NS_IMPL_ADDREF_INHERITED(nsBlobURI, nsSimpleURI) -NS_IMPL_RELEASE_INHERITED(nsBlobURI, nsSimpleURI) +NS_IMPL_ADDREF_INHERITED(nsHostObjectURI, nsSimpleURI) +NS_IMPL_RELEASE_INHERITED(nsHostObjectURI, nsSimpleURI) -NS_INTERFACE_MAP_BEGIN(nsBlobURI) +NS_INTERFACE_MAP_BEGIN(nsHostObjectURI) NS_INTERFACE_MAP_ENTRY(nsIURIWithPrincipal) - if (aIID.Equals(kBLOBURICID)) + if (aIID.Equals(kHOSTOBJECTURICID)) foundInterface = static_cast(this); else if (aIID.Equals(kThisSimpleURIImplementationCID)) { // Need to return explicitly here, because if we just set foundInterface @@ -34,7 +34,7 @@ NS_INTERFACE_MAP_END_INHERITING(nsSimpleURI) // nsIURIWithPrincipal methods: NS_IMETHODIMP -nsBlobURI::GetPrincipal(nsIPrincipal** aPrincipal) +nsHostObjectURI::GetPrincipal(nsIPrincipal** aPrincipal) { NS_IF_ADDREF(*aPrincipal = mPrincipal); @@ -42,7 +42,7 @@ nsBlobURI::GetPrincipal(nsIPrincipal** aPrincipal) } NS_IMETHODIMP -nsBlobURI::GetPrincipalUri(nsIURI** aUri) +nsHostObjectURI::GetPrincipalUri(nsIURI** aUri) { if (mPrincipal) { mPrincipal->GetURI(aUri); @@ -57,7 +57,7 @@ nsBlobURI::GetPrincipalUri(nsIURI** aUri) // nsISerializable methods: NS_IMETHODIMP -nsBlobURI::Read(nsIObjectInputStream* aStream) +nsHostObjectURI::Read(nsIObjectInputStream* aStream) { nsresult rv = nsSimpleURI::Read(aStream); NS_ENSURE_SUCCESS(rv, rv); @@ -66,7 +66,7 @@ nsBlobURI::Read(nsIObjectInputStream* aStream) } NS_IMETHODIMP -nsBlobURI::Write(nsIObjectOutputStream* aStream) +nsHostObjectURI::Write(nsIObjectOutputStream* aStream) { nsresult rv = nsSimpleURI::Write(aStream); NS_ENSURE_SUCCESS(rv, rv); @@ -78,8 +78,8 @@ nsBlobURI::Write(nsIObjectOutputStream* aStream) // nsIURI methods: nsresult -nsBlobURI::CloneInternal(nsSimpleURI::RefHandlingEnum aRefHandlingMode, - nsIURI** aClone) +nsHostObjectURI::CloneInternal(nsSimpleURI::RefHandlingEnum aRefHandlingMode, + nsIURI** aClone) { nsCOMPtr simpleClone; nsresult rv = @@ -87,56 +87,56 @@ nsBlobURI::CloneInternal(nsSimpleURI::RefHandlingEnum aRefHandlingMode, NS_ENSURE_SUCCESS(rv, rv); #ifdef DEBUG - nsRefPtr uriCheck; - rv = simpleClone->QueryInterface(kBLOBURICID, getter_AddRefs(uriCheck)); + nsRefPtr uriCheck; + rv = simpleClone->QueryInterface(kHOSTOBJECTURICID, getter_AddRefs(uriCheck)); NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv) && uriCheck, "Unexpected!"); #endif - nsBlobURI* blobURI = static_cast(simpleClone.get()); + nsHostObjectURI* u = static_cast(simpleClone.get()); - blobURI->mPrincipal = mPrincipal; + u->mPrincipal = mPrincipal; simpleClone.forget(aClone); return NS_OK; } /* virtual */ nsresult -nsBlobURI::EqualsInternal(nsIURI* aOther, - nsSimpleURI::RefHandlingEnum aRefHandlingMode, - bool* aResult) +nsHostObjectURI::EqualsInternal(nsIURI* aOther, + nsSimpleURI::RefHandlingEnum aRefHandlingMode, + bool* aResult) { if (!aOther) { *aResult = false; return NS_OK; } - nsRefPtr otherBlobUri; - aOther->QueryInterface(kBLOBURICID, getter_AddRefs(otherBlobUri)); - if (!otherBlobUri) { + nsRefPtr otherUri; + aOther->QueryInterface(kHOSTOBJECTURICID, getter_AddRefs(otherUri)); + if (!otherUri) { *aResult = false; return NS_OK; } // Compare the member data that our base class knows about. - if (!nsSimpleURI::EqualsInternal(otherBlobUri, aRefHandlingMode)) { + if (!nsSimpleURI::EqualsInternal(otherUri, aRefHandlingMode)) { *aResult = false; return NS_OK; - } + } // Compare the piece of additional member data that we add to base class. - if (mPrincipal && otherBlobUri->mPrincipal) { + if (mPrincipal && otherUri->mPrincipal) { // Both of us have mPrincipals. Compare them. - return mPrincipal->Equals(otherBlobUri->mPrincipal, aResult); + return mPrincipal->Equals(otherUri->mPrincipal, aResult); } // else, at least one of us lacks a principal; only equal if *both* lack it. - *aResult = (!mPrincipal && !otherBlobUri->mPrincipal); + *aResult = (!mPrincipal && !otherUri->mPrincipal); return NS_OK; } // nsIClassInfo methods: NS_IMETHODIMP -nsBlobURI::GetInterfaces(uint32_t *count, nsIID * **array) +nsHostObjectURI::GetInterfaces(uint32_t *count, nsIID * **array) { *count = 0; *array = nullptr; @@ -144,14 +144,14 @@ nsBlobURI::GetInterfaces(uint32_t *count, nsIID * **array) } NS_IMETHODIMP -nsBlobURI::GetHelperForLanguage(uint32_t language, nsISupports **_retval) +nsHostObjectURI::GetHelperForLanguage(uint32_t language, nsISupports **_retval) { *_retval = nullptr; return NS_OK; } NS_IMETHODIMP -nsBlobURI::GetContractID(char * *aContractID) +nsHostObjectURI::GetContractID(char * *aContractID) { // Make sure to modify any subclasses as needed if this ever // changes. @@ -160,14 +160,14 @@ nsBlobURI::GetContractID(char * *aContractID) } NS_IMETHODIMP -nsBlobURI::GetClassDescription(char * *aClassDescription) +nsHostObjectURI::GetClassDescription(char * *aClassDescription) { *aClassDescription = nullptr; return NS_OK; } NS_IMETHODIMP -nsBlobURI::GetClassID(nsCID * *aClassID) +nsHostObjectURI::GetClassID(nsCID * *aClassID) { // Make sure to modify any subclasses as needed if this ever // changes to not call the virtual GetClassIDNoAlloc. @@ -178,22 +178,22 @@ nsBlobURI::GetClassID(nsCID * *aClassID) } NS_IMETHODIMP -nsBlobURI::GetImplementationLanguage(uint32_t *aImplementationLanguage) +nsHostObjectURI::GetImplementationLanguage(uint32_t *aImplementationLanguage) { *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; return NS_OK; } NS_IMETHODIMP -nsBlobURI::GetFlags(uint32_t *aFlags) +nsHostObjectURI::GetFlags(uint32_t *aFlags) { *aFlags = nsIClassInfo::MAIN_THREAD_ONLY; return NS_OK; } NS_IMETHODIMP -nsBlobURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) +nsHostObjectURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) { - *aClassIDNoAlloc = kBLOBURICID; + *aClassIDNoAlloc = kHOSTOBJECTURICID; return NS_OK; } diff --git a/content/base/src/nsBlobURI.h b/content/base/src/nsHostObjectURI.h similarity index 69% rename from content/base/src/nsBlobURI.h rename to content/base/src/nsHostObjectURI.h index 71ff8a3b3f9..4b03742e7f0 100644 --- a/content/base/src/nsBlobURI.h +++ b/content/base/src/nsHostObjectURI.h @@ -2,8 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef nsBlobURI_h -#define nsBlobURI_h +#ifndef nsHostObjectURI_h +#define nsHostObjectURI_h #include "nsCOMPtr.h" #include "nsIClassInfo.h" @@ -12,17 +12,20 @@ #include "nsIURIWithPrincipal.h" #include "nsSimpleURI.h" -class nsBlobURI : public nsSimpleURI, - public nsIURIWithPrincipal +/** + * These URIs refer to host objects: Blobs, with scheme "blob". + */ +class nsHostObjectURI : public nsSimpleURI, + public nsIURIWithPrincipal { public: - nsBlobURI(nsIPrincipal* aPrincipal) : + nsHostObjectURI(nsIPrincipal* aPrincipal) : nsSimpleURI(), mPrincipal(aPrincipal) {} - virtual ~nsBlobURI() {} + virtual ~nsHostObjectURI() {} // For use only from deserialization - nsBlobURI() : nsSimpleURI() {} + nsHostObjectURI() : nsSimpleURI() {} NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIURIWITHPRINCIPAL @@ -36,15 +39,15 @@ public: RefHandlingEnum aRefHandlingMode, bool* aResult); - // Override StartClone to hand back a nsBlobURI + // Override StartClone to hand back a nsHostObjectURI virtual nsSimpleURI* StartClone(RefHandlingEnum /* unused */) - { return new nsBlobURI(); } + { return new nsHostObjectURI(); } nsCOMPtr mPrincipal; }; -#define NS_BLOBURI_CID \ +#define NS_HOSTOBJECTURI_CID \ { 0xf5475c51, 0x59a7, 0x4757, \ { 0xb3, 0xd9, 0xe2, 0x11, 0xa9, 0x41, 0x08, 0x72 } } -#endif /* nsBlobURI_h */ +#endif /* nsHostObjectURI_h */ diff --git a/content/media/MediaResource.cpp b/content/media/MediaResource.cpp index acbce98dcf1..f6e2e2dcdd1 100644 --- a/content/media/MediaResource.cpp +++ b/content/media/MediaResource.cpp @@ -28,7 +28,7 @@ #include "nsIAsyncVerifyRedirectCallback.h" #include "mozilla/Util.h" // for DebugOnly #include "nsContentUtils.h" -#include "nsBlobProtocolHandler.h" +#include "nsHostObjectProtocolHandler.h" #ifdef PR_LOGGING PRLogModuleInfo* gMediaResourceLog; diff --git a/dom/base/URL.cpp b/dom/base/URL.cpp index cdeac2d6afd..09a03c575e6 100644 --- a/dom/base/URL.cpp +++ b/dom/base/URL.cpp @@ -10,7 +10,7 @@ #include "nsIDocument.h" #include "nsIPrincipal.h" #include "nsContentUtils.h" -#include "nsBlobProtocolHandler.h" +#include "nsHostObjectProtocolHandler.h" namespace mozilla { namespace dom { @@ -20,6 +20,17 @@ URL::CreateObjectURL(nsISupports* aGlobal, nsIDOMBlob* aBlob, const objectURLOptions& aOptions, nsAString& aResult, ErrorResult& aError) +{ + CreateObjectURLInternal(aGlobal, aBlob, NS_LITERAL_CSTRING(BLOBURI_SCHEME), + aOptions, aResult, aError); +} + +void +URL::CreateObjectURLInternal(nsISupports* aGlobal, nsISupports* aObject, + const nsACString& aScheme, + const mozilla::dom::objectURLOptions& aOptions, + nsAString& aResult, + ErrorResult& aError) { nsCOMPtr w = do_QueryInterface(aGlobal); nsGlobalWindow* window = static_cast(w.get()); @@ -33,13 +44,16 @@ URL::CreateObjectURL(nsISupports* aGlobal, nsIDOMBlob* aBlob, nsIDocument* doc = window->GetExtantDoc(); - nsresult rv = aBlob->GetInternalUrl(doc->NodePrincipal(), aResult); + nsCString url; + nsresult rv = nsHostObjectProtocolHandler::AddDataEntry(aScheme, aObject, + doc->NodePrincipal(), url); if (NS_FAILED(rv)) { aError.Throw(rv); return; } - doc->RegisterFileDataUri(NS_LossyConvertUTF16toASCII(aResult)); + doc->RegisterHostObjectUri(url); + CopyASCIItoUTF16(url, aResult); } void @@ -60,15 +74,15 @@ URL::RevokeObjectURL(nsISupports* aGlobal, const nsAString& aURL) } nsIPrincipal* principal = - nsBlobProtocolHandler::GetFileDataEntryPrincipal(asciiurl); + nsHostObjectProtocolHandler::GetDataEntryPrincipal(asciiurl); bool subsumes; if (principal && winPrincipal && NS_SUCCEEDED(winPrincipal->Subsumes(principal, &subsumes)) && subsumes) { if (window->GetExtantDoc()) { - window->GetExtantDoc()->UnregisterFileDataUri(asciiurl); + window->GetExtantDoc()->UnregisterHostObjectUri(asciiurl); } - nsBlobProtocolHandler::RemoveFileDataEntry(asciiurl); + nsHostObjectProtocolHandler::RemoveDataEntry(asciiurl); } } diff --git a/dom/base/URL.h b/dom/base/URL.h index 868d6f0ffaf..d1a816139b3 100644 --- a/dom/base/URL.h +++ b/dom/base/URL.h @@ -22,6 +22,13 @@ public: nsAString& aResult, ErrorResult& aError); static void RevokeObjectURL(nsISupports* aGlobal, const nsAString& aURL); + +private: + static void CreateObjectURLInternal(nsISupports* aGlobal, nsISupports* aObject, + const nsACString& aScheme, + const mozilla::dom::objectURLOptions& aOptions, + nsAString& aResult, + mozilla::ErrorResult& aError); }; } diff --git a/layout/build/nsLayoutModule.cpp b/layout/build/nsLayoutModule.cpp index ce1a7c06e7c..6bbbfe31b9c 100644 --- a/layout/build/nsLayoutModule.cpp +++ b/layout/build/nsLayoutModule.cpp @@ -80,8 +80,8 @@ #include "ArchiveReader.h" #include "nsFormData.h" -#include "nsBlobProtocolHandler.h" -#include "nsBlobURI.h" +#include "nsHostObjectProtocolHandler.h" +#include "nsHostObjectURI.h" #include "nsGlobalWindowCommands.h" #include "nsIControllerCommandTable.h" #include "nsJSProtocolHandler.h" @@ -278,7 +278,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsDOMFileReader, Init) NS_GENERIC_FACTORY_CONSTRUCTOR(ArchiveReader) NS_GENERIC_FACTORY_CONSTRUCTOR(nsFormData) NS_GENERIC_FACTORY_CONSTRUCTOR(nsBlobProtocolHandler) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsBlobURI) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsHostObjectURI) NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMParser) NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsDOMStorageManager, nsDOMStorageManager::GetInstance) @@ -773,7 +773,7 @@ NS_DEFINE_NAMED_CID(NS_FILEREADER_CID); NS_DEFINE_NAMED_CID(NS_ARCHIVEREADER_CID); NS_DEFINE_NAMED_CID(NS_FORMDATA_CID); NS_DEFINE_NAMED_CID(NS_BLOBPROTOCOLHANDLER_CID); -NS_DEFINE_NAMED_CID(NS_BLOBURI_CID); +NS_DEFINE_NAMED_CID(NS_HOSTOBJECTURI_CID); NS_DEFINE_NAMED_CID(NS_XMLHTTPREQUEST_CID); NS_DEFINE_NAMED_CID(NS_EVENTSOURCE_CID); NS_DEFINE_NAMED_CID(NS_DOMACTIVITY_CID); @@ -1058,7 +1058,7 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = { { &kNS_ARCHIVEREADER_CID, false, NULL, ArchiveReaderConstructor }, { &kNS_FORMDATA_CID, false, NULL, nsFormDataConstructor }, { &kNS_BLOBPROTOCOLHANDLER_CID, false, NULL, nsBlobProtocolHandlerConstructor }, - { &kNS_BLOBURI_CID, false, NULL, nsBlobURIConstructor }, + { &kNS_HOSTOBJECTURI_CID, false, NULL, nsHostObjectURIConstructor }, { &kNS_XMLHTTPREQUEST_CID, false, NULL, nsXMLHttpRequestConstructor }, { &kNS_EVENTSOURCE_CID, false, NULL, nsEventSourceConstructor }, { &kNS_DOMACTIVITY_CID, false, NULL, ActivityConstructor }, From 7de156481a1f6f88bfd2e615fb2670f9af72a3db Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 25 Sep 2012 15:24:44 +1200 Subject: [PATCH 09/39] Bug 792675. Part 5: Extend nsHostObjectProtocolHandler with support for 'mediastream' scheme. r=sicking --HG-- rename : content/base/public/nsBlobProtocolHandler.h => content/base/public/nsHostObjectProtocolHandler.h rename : content/base/src/nsBlobProtocolHandler.cpp => content/base/src/nsHostObjectProtocolHandler.cpp rename : content/base/src/nsBlobURI.h => content/base/src/nsHostObjectURI.h extra : rebase_source : aea1ab3b9eed985ea238d2e9fb74bf3b2f574756 --- .../base/public/nsHostObjectProtocolHandler.h | 21 +++++++++++++++ .../base/src/nsHostObjectProtocolHandler.cpp | 27 ++++++++++++++++++- content/base/src/nsHostObjectURI.h | 3 ++- layout/build/nsLayoutModule.cpp | 4 +++ 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/content/base/public/nsHostObjectProtocolHandler.h b/content/base/public/nsHostObjectProtocolHandler.h index 98c9782cc9f..88cf8c77065 100644 --- a/content/base/public/nsHostObjectProtocolHandler.h +++ b/content/base/public/nsHostObjectProtocolHandler.h @@ -10,8 +10,10 @@ #include "nsCOMPtr.h" #define BLOBURI_SCHEME "blob" +#define MEDIASTREAMURI_SCHEME "mediastream" class nsIDOMBlob; +class nsIDOMMediaStream; class nsIPrincipal; class nsIInputStream; @@ -44,17 +46,36 @@ public: NS_IMETHOD GetScheme(nsACString &result); }; +class nsMediaStreamProtocolHandler : public nsHostObjectProtocolHandler +{ +public: + NS_IMETHOD GetScheme(nsACString &result); +}; + inline bool IsBlobURI(nsIURI* aUri) { bool isBlob; return NS_SUCCEEDED(aUri->SchemeIs(BLOBURI_SCHEME, &isBlob)) && isBlob; } +inline bool IsMediaStreamURI(nsIURI* aUri) +{ + bool isStream; + return NS_SUCCEEDED(aUri->SchemeIs(MEDIASTREAMURI_SCHEME, &isStream)) && isStream; +} + extern nsresult NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream); +extern nsresult +NS_GetStreamForMediaStreamURI(nsIURI* aURI, nsIDOMMediaStream** aStream); + #define NS_BLOBPROTOCOLHANDLER_CID \ { 0xb43964aa, 0xa078, 0x44b2, \ { 0xb0, 0x6b, 0xfd, 0x4d, 0x1b, 0x17, 0x2e, 0x66 } } +#define NS_MEDIASTREAMPROTOCOLHANDLER_CID \ +{ 0x27d1fa24, 0x2b73, 0x4db3, \ + { 0xab, 0x48, 0xb9, 0x83, 0x83, 0x40, 0xe0, 0x81 } } + #endif /* nsHostObjectProtocolHandler_h */ diff --git a/content/base/src/nsHostObjectProtocolHandler.cpp b/content/base/src/nsHostObjectProtocolHandler.cpp index 0ada9af32dd..9c8840290f7 100644 --- a/content/base/src/nsHostObjectProtocolHandler.cpp +++ b/content/base/src/nsHostObjectProtocolHandler.cpp @@ -9,12 +9,13 @@ #include "nsNetUtil.h" #include "nsIPrincipal.h" #include "nsIDOMFile.h" +#include "nsIDOMMediaStream.h" // ----------------------------------------------------------------------- // Hash table struct DataInfo { - // mObject must be an nsIDOMBlob + // mObject must be an nsIDOMBlob or an nsIDOMMediaStream nsCOMPtr mObject; nsCOMPtr mPrincipal; }; @@ -223,6 +224,13 @@ nsBlobProtocolHandler::GetScheme(nsACString &result) return NS_OK; } +NS_IMETHODIMP +nsMediaStreamProtocolHandler::GetScheme(nsACString &result) +{ + result.AssignLiteral(MEDIASTREAMURI_SCHEME); + return NS_OK; +} + nsresult NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream) { @@ -237,3 +245,20 @@ NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream) return blob->GetInternalStream(aStream); } + +nsresult +NS_GetStreamForMediaStreamURI(nsIURI* aURI, nsIDOMMediaStream** aStream) +{ + NS_ASSERTION(IsMediaStreamURI(aURI), "Only call this with mediastream URIs"); + + *aStream = nullptr; + + nsCOMPtr stream = do_QueryInterface(GetDataObject(aURI)); + if (!stream) { + return NS_ERROR_DOM_BAD_URI; + } + + *aStream = stream; + NS_ADDREF(*aStream); + return NS_OK; +} diff --git a/content/base/src/nsHostObjectURI.h b/content/base/src/nsHostObjectURI.h index 4b03742e7f0..0657d5c4154 100644 --- a/content/base/src/nsHostObjectURI.h +++ b/content/base/src/nsHostObjectURI.h @@ -13,7 +13,8 @@ #include "nsSimpleURI.h" /** - * These URIs refer to host objects: Blobs, with scheme "blob". + * These URIs refer to host objects: Blobs, with scheme "blob", and + * MediaStreams, with scheme "mediastream". */ class nsHostObjectURI : public nsSimpleURI, public nsIURIWithPrincipal diff --git a/layout/build/nsLayoutModule.cpp b/layout/build/nsLayoutModule.cpp index 6bbbfe31b9c..c3b4f42d48f 100644 --- a/layout/build/nsLayoutModule.cpp +++ b/layout/build/nsLayoutModule.cpp @@ -278,6 +278,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsDOMFileReader, Init) NS_GENERIC_FACTORY_CONSTRUCTOR(ArchiveReader) NS_GENERIC_FACTORY_CONSTRUCTOR(nsFormData) NS_GENERIC_FACTORY_CONSTRUCTOR(nsBlobProtocolHandler) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsMediaStreamProtocolHandler) NS_GENERIC_FACTORY_CONSTRUCTOR(nsHostObjectURI) NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMParser) NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsDOMStorageManager, @@ -773,6 +774,7 @@ NS_DEFINE_NAMED_CID(NS_FILEREADER_CID); NS_DEFINE_NAMED_CID(NS_ARCHIVEREADER_CID); NS_DEFINE_NAMED_CID(NS_FORMDATA_CID); NS_DEFINE_NAMED_CID(NS_BLOBPROTOCOLHANDLER_CID); +NS_DEFINE_NAMED_CID(NS_MEDIASTREAMPROTOCOLHANDLER_CID); NS_DEFINE_NAMED_CID(NS_HOSTOBJECTURI_CID); NS_DEFINE_NAMED_CID(NS_XMLHTTPREQUEST_CID); NS_DEFINE_NAMED_CID(NS_EVENTSOURCE_CID); @@ -1058,6 +1060,7 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = { { &kNS_ARCHIVEREADER_CID, false, NULL, ArchiveReaderConstructor }, { &kNS_FORMDATA_CID, false, NULL, nsFormDataConstructor }, { &kNS_BLOBPROTOCOLHANDLER_CID, false, NULL, nsBlobProtocolHandlerConstructor }, + { &kNS_MEDIASTREAMPROTOCOLHANDLER_CID, false, NULL, nsMediaStreamProtocolHandlerConstructor }, { &kNS_HOSTOBJECTURI_CID, false, NULL, nsHostObjectURIConstructor }, { &kNS_XMLHTTPREQUEST_CID, false, NULL, nsXMLHttpRequestConstructor }, { &kNS_EVENTSOURCE_CID, false, NULL, nsEventSourceConstructor }, @@ -1206,6 +1209,7 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = { { NS_ARCHIVEREADER_CONTRACTID, &kNS_ARCHIVEREADER_CID }, { NS_FORMDATA_CONTRACTID, &kNS_FORMDATA_CID }, { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX BLOBURI_SCHEME, &kNS_BLOBPROTOCOLHANDLER_CID }, + { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX MEDIASTREAMURI_SCHEME, &kNS_MEDIASTREAMPROTOCOLHANDLER_CID }, { NS_XMLHTTPREQUEST_CONTRACTID, &kNS_XMLHTTPREQUEST_CID }, { NS_EVENTSOURCE_CONTRACTID, &kNS_EVENTSOURCE_CID }, { NS_DOMACTIVITY_CONTRACTID, &kNS_DOMACTIVITY_CID }, From a58b731c33fe59a67066815fb1faa52d8586dfe6 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 25 Sep 2012 15:24:45 +1200 Subject: [PATCH 10/39] Bug 792675. Part 6: Extend createObjectURL to support MediaStreams. r=sicking --HG-- extra : rebase_source : ffec7b146552362b576e88c6dea24d612a5860b9 --- content/media/test/Makefile.in | 1 + dom/base/URL.cpp | 11 +++++++++++ dom/base/URL.h | 5 +++++ dom/webidl/URL.webidl | 4 ++++ 4 files changed, 21 insertions(+) diff --git a/content/media/test/Makefile.in b/content/media/test/Makefile.in index 2fad85bd2d8..1cc056bd982 100644 --- a/content/media/test/Makefile.in +++ b/content/media/test/Makefile.in @@ -138,6 +138,7 @@ ifneq ($(OS_ARCH), WINNT) MOCHITEST_FILES += \ test_streams_element_capture.html \ test_streams_element_capture_reset.html \ + test_streams_element_capture_createObjectURL.html \ test_timeupdate_small_files.html \ $(NULL) else diff --git a/dom/base/URL.cpp b/dom/base/URL.cpp index 09a03c575e6..a6e91432050 100644 --- a/dom/base/URL.cpp +++ b/dom/base/URL.cpp @@ -7,6 +7,7 @@ #include "nsGlobalWindow.h" #include "nsIDOMFile.h" +#include "nsIDOMMediaStream.h" #include "nsIDocument.h" #include "nsIPrincipal.h" #include "nsContentUtils.h" @@ -25,6 +26,16 @@ URL::CreateObjectURL(nsISupports* aGlobal, nsIDOMBlob* aBlob, aOptions, aResult, aError); } +void +URL::CreateObjectURL(nsISupports* aGlobal, nsIDOMMediaStream* aStream, + const mozilla::dom::objectURLOptions& aOptions, + nsAString& aResult, + ErrorResult& aError) +{ + CreateObjectURLInternal(aGlobal, aStream, NS_LITERAL_CSTRING(MEDIASTREAMURI_SCHEME), + aOptions, aResult, aError); +} + void URL::CreateObjectURLInternal(nsISupports* aGlobal, nsISupports* aObject, const nsACString& aScheme, diff --git a/dom/base/URL.h b/dom/base/URL.h index d1a816139b3..0859c5236f1 100644 --- a/dom/base/URL.h +++ b/dom/base/URL.h @@ -9,6 +9,7 @@ #include "mozilla/dom/URLBinding.h" class nsIDOMBlob; +class nsIDOMMediaStream; namespace mozilla { namespace dom { @@ -21,6 +22,10 @@ public: const objectURLOptions& aOptions, nsAString& aResult, ErrorResult& aError); + static void CreateObjectURL(nsISupports* aGlobal, nsIDOMMediaStream* aStream, + const mozilla::dom::objectURLOptions& aOptions, + nsAString& aResult, + mozilla::ErrorResult& aError); static void RevokeObjectURL(nsISupports* aGlobal, const nsAString& aURL); private: diff --git a/dom/webidl/URL.webidl b/dom/webidl/URL.webidl index 9b9908f87a2..f5340a00398 100644 --- a/dom/webidl/URL.webidl +++ b/dom/webidl/URL.webidl @@ -11,9 +11,13 @@ * liability, trademark and document use rules apply. */ +interface MediaStream; + interface URL { [Throws] static DOMString? createObjectURL(Blob blob, optional objectURLOptions options); + [Throws] + static DOMString? createObjectURL(MediaStream stream, optional objectURLOptions options); static void revokeObjectURL(DOMString url); }; From d43a309fc3b2dfab0d0298fc1445d15f03903dae Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 25 Sep 2012 15:25:43 +1200 Subject: [PATCH 11/39] Bug 792675. Part 7: Add support for MediaStream URIs to media elements. r=cpearce --HG-- extra : rebase_source : 1c27fa7038dcdd3ab4e7eac6219b2ed5a6affa4a --- .../html/content/public/nsHTMLMediaElement.h | 4 +- .../html/content/src/nsHTMLMediaElement.cpp | 25 ++++++-- ...reams_element_capture_createObjectURL.html | 62 +++++++++++++++++++ 3 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 content/media/test/test_streams_element_capture_createObjectURL.html diff --git a/content/html/content/public/nsHTMLMediaElement.h b/content/html/content/public/nsHTMLMediaElement.h index 028be6bf1b3..7b721cfe1a0 100644 --- a/content/html/content/public/nsHTMLMediaElement.h +++ b/content/html/content/public/nsHTMLMediaElement.h @@ -429,9 +429,9 @@ protected: void SetPlayedOrSeeked(bool aValue); /** - * Initialize the media element for playback of mSrcAttrStream + * Initialize the media element for playback of aStream */ - void SetupSrcMediaStreamPlayback(); + void SetupSrcMediaStreamPlayback(nsDOMMediaStream* aStream); /** * Stop playback on mSrcStream. */ diff --git a/content/html/content/src/nsHTMLMediaElement.cpp b/content/html/content/src/nsHTMLMediaElement.cpp index a8db13231c8..20a31ad785a 100644 --- a/content/html/content/src/nsHTMLMediaElement.cpp +++ b/content/html/content/src/nsHTMLMediaElement.cpp @@ -64,6 +64,7 @@ #include "MediaStreamGraph.h" #include "nsDOMMediaStream.h" #include "nsIScriptError.h" +#include "nsHostObjectProtocolHandler.h" #include "nsCSSParser.h" #include "nsIMediaList.h" @@ -758,7 +759,7 @@ void nsHTMLMediaElement::SelectResource() // If we have a 'src' attribute, use that exclusively. nsAutoString src; if (mSrcAttrStream) { - SetupSrcMediaStreamPlayback(); + SetupSrcMediaStreamPlayback(mSrcAttrStream); } else if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) { nsCOMPtr uri; nsresult rv = NewURIFromString(src, getter_AddRefs(uri)); @@ -766,6 +767,7 @@ void nsHTMLMediaElement::SelectResource() LOG(PR_LOG_DEBUG, ("%p Trying load from src=%s", this, NS_ConvertUTF16toUTF8(src).get())); NS_ASSERTION(!mIsLoadingFromSourceChildren, "Should think we're not loading from source children by default"); + mLoadingSrc = uri; if (mPreloadAction == nsHTMLMediaElement::PRELOAD_NONE) { // preload:none media, suspend the load here before we make any @@ -1035,7 +1037,7 @@ nsresult nsHTMLMediaElement::LoadResource() mCORSMode = AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin)); nsHTMLMediaElement* other = LookupMediaElementURITable(mLoadingSrc); - if (other) { + if (other && other->mDecoder) { // Clone it. nsresult rv = InitializeDecoderAsClone(other->mDecoder); // Get the mimetype from the element we clone, since we will not get it via @@ -1062,6 +1064,21 @@ nsresult nsHTMLMediaElement::LoadResource() return NS_ERROR_FAILURE; } + if (IsMediaStreamURI(mLoadingSrc)) { + nsCOMPtr stream; + rv = NS_GetStreamForMediaStreamURI(mLoadingSrc, getter_AddRefs(stream)); + if (NS_FAILED(rv)) { + nsCString specUTF8; + mLoadingSrc->GetSpec(specUTF8); + NS_ConvertUTF8toUTF16 spec(specUTF8); + const PRUnichar* params[] = { spec.get() }; + ReportLoadError("MediaLoadInvalidURI", params, ArrayLength(params)); + return rv; + } + SetupSrcMediaStreamPlayback(static_cast(stream.get())); + return NS_OK; + } + nsCOMPtr loadGroup = GetDocumentLoadGroup(); // check for a Content Security Policy to pass down to the channel @@ -2765,11 +2782,11 @@ private: bool mDidHaveCurrentData; }; -void nsHTMLMediaElement::SetupSrcMediaStreamPlayback() +void nsHTMLMediaElement::SetupSrcMediaStreamPlayback(nsDOMMediaStream* aStream) { NS_ASSERTION(!mSrcStream && !mSrcStreamListener, "Should have been ended already"); - mSrcStream = mSrcAttrStream; + mSrcStream = aStream; // XXX if we ever support capturing the output of a media element which is // playing a stream, we'll need to add a CombineWithPrincipal call here. mSrcStreamListener = new StreamListener(this); diff --git a/content/media/test/test_streams_element_capture_createObjectURL.html b/content/media/test/test_streams_element_capture_createObjectURL.html new file mode 100644 index 00000000000..d33a8f080ea --- /dev/null +++ b/content/media/test/test_streams_element_capture_createObjectURL.html @@ -0,0 +1,62 @@ + + + + Test that a MediaStream captured from one element plays back in another + + + + + +
+
+
+ + From 597ac6e30aabbb4a9c9b87e3c1be58f2262165e2 Mon Sep 17 00:00:00 2001 From: Hannes Verschore Date: Thu, 8 Nov 2012 14:35:26 +0100 Subject: [PATCH 12/39] Bug 809472: Add truncate analysis for MMul, r=mjrosenb --- js/src/ion/MIR.cpp | 15 ++++++++++++-- js/src/ion/MIR.h | 28 ++++++++++++++++++++++++-- js/src/ion/RangeAnalysis.cpp | 18 +++++++++++++++++ js/src/ion/RangeAnalysis.h | 2 ++ js/src/jit-test/tests/ion/bug809472.js | 19 +++++++++++++++++ 5 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 js/src/jit-test/tests/ion/bug809472.js diff --git a/js/src/ion/MIR.cpp b/js/src/ion/MIR.cpp index d44f757bb79..b2c3f1014d2 100644 --- a/js/src/ion/MIR.cpp +++ b/js/src/ion/MIR.cpp @@ -958,9 +958,20 @@ MMul::analyzeEdgeCasesBackward() canBeNegativeZero_ = NeedNegativeZeroCheck(this); } -bool -MMul::updateForReplacement(MDefinition *ins) +void +MMul::analyzeTruncateBackward() { + if (!isPossibleTruncated()) + setPossibleTruncated(js::ion::EdgeCaseAnalysis::AllUsesTruncate(this)); +} + +bool +MMul::updateForReplacement(MDefinition *ins_) +{ + JS_ASSERT(ins_->isMul()); + MMul *ins = ins_->toMul(); + if (isPossibleTruncated()) + setPossibleTruncated(ins->isPossibleTruncated()); return true; } diff --git a/js/src/ion/MIR.h b/js/src/ion/MIR.h index f235c2c5039..ec39c856ec3 100644 --- a/js/src/ion/MIR.h +++ b/js/src/ion/MIR.h @@ -2498,11 +2498,24 @@ class MSub : public MBinaryArithInstruction class MMul : public MBinaryArithInstruction { + // Annotation the result could be a negative zero + // and we need to guard this during execution. bool canBeNegativeZero_; + // Annotation the result of this Mul is only used in int32 domain + // and we could possible truncate the result. + bool possibleTruncate_; + + // Annotation the Mul can truncate. This is only set after range analysis, + // because the result could be in the imprecise double range. + // In that case the truncated result isn't correct. + bool implicitTruncate_; + MMul(MDefinition *left, MDefinition *right, MIRType type) : MBinaryArithInstruction(left, right), - canBeNegativeZero_(true) + canBeNegativeZero_(true), + possibleTruncate_(false), + implicitTruncate_(false) { if (type != MIRType_Value) specialization_ = type; @@ -2521,13 +2534,14 @@ class MMul : public MBinaryArithInstruction MDefinition *foldsTo(bool useValueNumbers); void analyzeEdgeCasesForward(); void analyzeEdgeCasesBackward(); + void analyzeTruncateBackward(); double getIdentity() { return 1; } bool canOverflow() { - return !range()->isFinite(); + return !implicitTruncate_ && !range()->isFinite(); } bool canBeNegativeZero() { @@ -2546,8 +2560,18 @@ class MMul : public MBinaryArithInstruction return false; Range *left = getOperand(0)->range(); Range *right = getOperand(1)->range(); + if (isPossibleTruncated()) + implicitTruncate_ = !Range::precisionLossMul(left, right); return range()->update(Range::mul(left, right)); } + + bool isPossibleTruncated() const { + return possibleTruncate_; + } + + void setPossibleTruncated(bool truncate) { + possibleTruncate_ = truncate; + } }; class MDiv : public MBinaryArithInstruction diff --git a/js/src/ion/RangeAnalysis.cpp b/js/src/ion/RangeAnalysis.cpp index 8ac284c5e1b..1edccd6a730 100644 --- a/js/src/ion/RangeAnalysis.cpp +++ b/js/src/ion/RangeAnalysis.cpp @@ -417,6 +417,24 @@ Range::shr(const Range *lhs, int32 c) return ret; } +bool +Range::precisionLossMul(const Range *lhs, const Range *rhs) +{ + int64_t loss = 1LL<<53; // result must be lower than 2^53 + int64_t a = (int64_t)lhs->lower_ * (int64_t)rhs->lower_; + int64_t b = (int64_t)lhs->lower_ * (int64_t)rhs->upper_; + int64_t c = (int64_t)lhs->upper_ * (int64_t)rhs->lower_; + int64_t d = (int64_t)lhs->upper_ * (int64_t)rhs->upper_; + int64_t lower = Min( Min(a, b), Min(c, d) ); + int64_t upper = Max( Max(a, b), Max(c, d) ); + if (lower < 0) + lower = -lower; + if (upper < 0) + upper = -upper; + + return lower > loss || upper > loss; +} + bool Range::update(const Range *other) { diff --git a/js/src/ion/RangeAnalysis.h b/js/src/ion/RangeAnalysis.h index 2d755656466..b60f6857745 100644 --- a/js/src/ion/RangeAnalysis.h +++ b/js/src/ion/RangeAnalysis.h @@ -126,6 +126,8 @@ class Range { static Range shl(const Range *lhs, int32 c); static Range shr(const Range *lhs, int32 c); + static bool precisionLossMul(const Range *lhs, const Range *rhs); + inline void makeLowerInfinite() { lower_infinite_ = true; lower_ = JSVAL_INT_MIN; diff --git a/js/src/jit-test/tests/ion/bug809472.js b/js/src/jit-test/tests/ion/bug809472.js new file mode 100644 index 00000000000..662d6e524ca --- /dev/null +++ b/js/src/jit-test/tests/ion/bug809472.js @@ -0,0 +1,19 @@ +function test1(x) { + return (x*((2<<23)-1))|0 +} +function test2(x) { + return (x*((2<<22)-1))|0 +} +function test3(x) { + return (x*((2<<21)-1))|0 +} +function test4(x) { + var b = x + x + 3 + return (b*b) | 0 +} +//MAX_INT +var x = 0x7ffffffe; +assertEq(test1(x), 2113929216); +assertEq(test2(x), 2130706434); +assertEq(test3(x), 2139095042); +assertEq(test4(x), 0); From 1ecf69a28fa9e06b768f7105ac11f0920fd18072 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Thu, 8 Nov 2012 09:24:46 -0500 Subject: [PATCH 13/39] Bug 809292 - Deal with all source data allocation in one function. r=njn --- js/src/jsscript.cpp | 61 ++++++++++++++++++++++++--------------------- js/src/jsscript.h | 12 ++++++--- 2 files changed, 42 insertions(+), 31 deletions(-) diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index 6ceaad2cc9b..6518248ac33 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -944,8 +944,7 @@ SourceCompressorThread::internalCompress() // Try to keep the maximum memory usage down by only allocating half the // size of the string, first. size_t firstSize = nbytes / 2; - ss->data.compressed = static_cast(js_malloc(firstSize)); - if (!ss->data.compressed) + if (!ss->adjustDataSize(firstSize)) return false; Compressor comp(reinterpret_cast(tok->chars), nbytes); if (!comp.init()) @@ -964,13 +963,8 @@ SourceCompressorThread::internalCompress() // The compressed output is greater than half the size of the // original string. Reallocate to the full size. - void *newmem = js_realloc(ss->data.compressed, nbytes); - if (!newmem) { - js_free(ss->data.compressed); - ss->data.compressed = NULL; + if (!ss->adjustDataSize(nbytes)) return false; - } - ss->data.compressed = static_cast(newmem); comp.setOutput(ss->data.compressed, nbytes); break; } @@ -988,22 +982,12 @@ SourceCompressorThread::internalCompress() } #endif if (compressedLength == 0) { - // Note ss->data.source might be NULL. - jschar *buf = static_cast(js_realloc(ss->data.source, nbytes)); - if (!buf) { - if (ss->data.source) { - js_free(ss->data.source); - ss->data.source = NULL; - } + if (!ss->adjustDataSize(nbytes)) return false; - } - ss->data.source = buf; PodCopy(ss->data.source, tok->chars, ss->length()); } else { // Shrink the buffer to the size of the compressed data. Shouldn't fail. - void *newmem = js_realloc(ss->data.compressed, compressedLength); - JS_ASSERT(newmem); - ss->data.compressed = static_cast(newmem); + JS_ALWAYS_TRUE(ss->adjustDataSize(compressedLength)); } ss->compressedLength_ = compressedLength; return true; @@ -1085,6 +1069,29 @@ SourceCompressorThread::abort(SourceCompressionToken *userTok) } #endif /* JS_THREADSAFE */ +static const unsigned char emptySource[] = ""; + +/* Adjust the amount of memory this script source uses for source data, + reallocating if needed. */ +bool +ScriptSource::adjustDataSize(size_t nbytes) +{ + // Allocating 0 bytes has undefined behavior, so special-case it. + if (nbytes == 0) { + if (data.compressed != emptySource) + js_free(data.compressed); + data.compressed = const_cast(emptySource); + return true; + } + + // |data.compressed| can be NULL. + void *buf = js_realloc(data.compressed, nbytes); + if (!buf && data.compressed != emptySource) + js_free(data.compressed); + data.compressed = static_cast(buf); + return !!data.compressed; +} + void JSScript::setScriptSource(ScriptSource *ss) { @@ -1210,8 +1217,7 @@ ScriptSource::setSourceCopy(JSContext *cx, StableCharPtr src, uint32_t length, } else #endif { - data.source = cx->runtime->pod_malloc(length); - if (!data.source) + if (!adjustDataSize(sizeof(jschar) * length)) return false; PodCopy(data.source, src.get(), length_); } @@ -1257,7 +1263,7 @@ void ScriptSource::destroy(JSRuntime *rt) { JS_ASSERT(ready()); - js_free(data.compressed); + adjustDataSize(0); js_free(sourceMap_); #ifdef DEBUG ready_ = false; @@ -1270,9 +1276,9 @@ ScriptSource::sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) { JS_ASSERT(ready()); - // data is a union, but both members are pointers to allocated memory or - // NULL, so just using compressed will work. - return mallocSizeOf(this) + mallocSizeOf(data.compressed); + // |data| is a union, but both members are pointers to allocated memory, + // |emptySource|, or NULL, so just using |data.compressed| will work. + return mallocSizeOf(this) + ((data.compressed != emptySource) ? mallocSizeOf(data.compressed) : 0); } template @@ -1305,8 +1311,7 @@ ScriptSource::performXDR(XDRState *xdr) size_t byteLen = compressedLength ? compressedLength : (length * sizeof(jschar)); if (mode == XDR_DECODE) { - data.compressed = static_cast(xdr->cx()->malloc_(byteLen)); - if (!data.compressed) + if (!adjustDataSize(byteLen)) return false; } if (!xdr->codeBytes(data.compressed, byteLen)) { diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 21586a9ca82..717d7d11e2f 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -990,9 +990,14 @@ struct ScriptSource friend class SourceCompressorThread; private: union { - // When the script source is ready, compressedLength_ != 0 implies - // compressed holds the compressed data; otherwise, source holds the - // uncompressed source. + // Before setSourceCopy or setSource are successfully called, this union + // has a NULL pointer. When the script source is ready, + // compressedLength_ != 0 implies compressed holds the compressed data; + // otherwise, source holds the uncompressed source. There is a special + // pointer |emptySource| for source code for length 0. + // + // The only function allowed to malloc, realloc, or free the pointers in + // this union is adjustDataSize(). Don't do it elsewhere. jschar *source; unsigned char *compressed; } data; @@ -1068,6 +1073,7 @@ struct ScriptSource size_t computedSizeOfData() const { return compressed() ? compressedLength_ : sizeof(jschar) * length_; } + bool adjustDataSize(size_t nbytes); }; class ScriptSourceHolder From ab8bc55c737c9cdd144fe0052d809024edfac8fc Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Wed, 7 Nov 2012 20:59:14 -0500 Subject: [PATCH 14/39] Bug 809654 - Implement BiquadFilterNode; r=bzbarsky --- content/media/webaudio/AudioContext.cpp | 9 ++ content/media/webaudio/AudioContext.h | 4 + content/media/webaudio/BiquadFilterNode.cpp | 57 ++++++++++++ content/media/webaudio/BiquadFilterNode.h | 92 +++++++++++++++++++ content/media/webaudio/Makefile.in | 2 + content/media/webaudio/test/Makefile.in | 2 + .../media/webaudio/test/test_badConnect.html | 13 +-- .../webaudio/test/test_biquadFilterNode.html | 73 +++++++++++++++ dom/bindings/Bindings.conf | 4 + dom/webidl/AudioContext.webidl | 2 + dom/webidl/BiquadFilterNode.webidl | 37 ++++++++ dom/webidl/WebIDL.mk | 1 + 12 files changed, 284 insertions(+), 12 deletions(-) create mode 100644 content/media/webaudio/BiquadFilterNode.cpp create mode 100644 content/media/webaudio/BiquadFilterNode.h create mode 100644 content/media/webaudio/test/test_biquadFilterNode.html create mode 100644 dom/webidl/BiquadFilterNode.webidl diff --git a/content/media/webaudio/AudioContext.cpp b/content/media/webaudio/AudioContext.cpp index 26d73578655..6fa94758aeb 100644 --- a/content/media/webaudio/AudioContext.cpp +++ b/content/media/webaudio/AudioContext.cpp @@ -17,6 +17,7 @@ #include "PannerNode.h" #include "AudioListener.h" #include "DynamicsCompressorNode.h" +#include "BiquadFilterNode.h" namespace mozilla { namespace dom { @@ -124,6 +125,14 @@ AudioContext::CreateDynamicsCompressor() return compressorNode.forget(); } +already_AddRefed +AudioContext::CreateBiquadFilter() +{ + nsRefPtr filterNode = + new BiquadFilterNode(this); + return filterNode.forget(); +} + AudioListener* AudioContext::Listener() { diff --git a/content/media/webaudio/AudioContext.h b/content/media/webaudio/AudioContext.h index edf5cf6e22a..65e6515e47d 100644 --- a/content/media/webaudio/AudioContext.h +++ b/content/media/webaudio/AudioContext.h @@ -27,6 +27,7 @@ class AudioBuffer; class AudioBufferSourceNode; class AudioDestinationNode; class AudioListener; +class BiquadFilterNode; class DelayNode; class DynamicsCompressorNode; class GainNode; @@ -80,6 +81,9 @@ public: already_AddRefed CreateDynamicsCompressor(); + already_AddRefed + CreateBiquadFilter(); + private: nsCOMPtr mWindow; nsRefPtr mDestination; diff --git a/content/media/webaudio/BiquadFilterNode.cpp b/content/media/webaudio/BiquadFilterNode.cpp new file mode 100644 index 00000000000..5afb15eb306 --- /dev/null +++ b/content/media/webaudio/BiquadFilterNode.cpp @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "BiquadFilterNode.h" +#include "mozilla/dom/BiquadFilterNodeBinding.h" + +namespace mozilla { +namespace dom { + +NS_IMPL_CYCLE_COLLECTION_CLASS(BiquadFilterNode) +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BiquadFilterNode, AudioNode) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFrequency) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mQ) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mGain) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BiquadFilterNode, AudioNode) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mFrequency, AudioParam, "frequency value") + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mQ, AudioParam, "Q value") + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mGain, AudioParam, "gain value") +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BiquadFilterNode) +NS_INTERFACE_MAP_END_INHERITING(AudioNode) + +NS_IMPL_ADDREF_INHERITED(BiquadFilterNode, AudioNode) +NS_IMPL_RELEASE_INHERITED(BiquadFilterNode, AudioNode) + +static float +Nyquist(AudioContext* aContext) +{ + // TODO: Replace the hardcoded 44100 here with AudioContext::SampleRate() + // when we implement that. + return 0.5f * 44100; +} + +BiquadFilterNode::BiquadFilterNode(AudioContext* aContext) + : AudioNode(aContext) + , mType(BiquadTypeEnum::LOWPASS) + , mFrequency(new AudioParam(aContext, 350.f, 10.f, Nyquist(aContext))) + , mQ(new AudioParam(aContext, 1.f, 0.0001f, 1000.f)) + , mGain(new AudioParam(aContext, 0.f, -40.f, 40.f)) +{ +} + +JSObject* +BiquadFilterNode::WrapObject(JSContext* aCx, JSObject* aScope, + bool* aTriedToWrap) +{ + return BiquadFilterNodeBinding::Wrap(aCx, aScope, this, aTriedToWrap); +} + +} +} + diff --git a/content/media/webaudio/BiquadFilterNode.h b/content/media/webaudio/BiquadFilterNode.h new file mode 100644 index 00000000000..83aba4efe15 --- /dev/null +++ b/content/media/webaudio/BiquadFilterNode.h @@ -0,0 +1,92 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BiquadFilterNode_h_ +#define BiquadFilterNode_h_ + +#include "AudioNode.h" +#include "AudioParam.h" +#include "mozilla/Attributes.h" +#include "mozilla/ErrorResult.h" + +namespace mozilla { +namespace dom { + +class AudioContext; + +MOZ_BEGIN_ENUM_CLASS(BiquadTypeEnum, uint16_t) + LOWPASS = 0, + HIGHPASS = 1, + BANDPASS = 2, + LOWSHELF = 3, + HIGHSHELF = 4, + PEAKING = 5, + NOTCH = 6, + ALLPASS = 7, + Max = 7 +MOZ_END_ENUM_CLASS(BiquadTypeEnum) + +class BiquadFilterNode : public AudioNode +{ +public: + explicit BiquadFilterNode(AudioContext* aContext); + + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BiquadFilterNode, AudioNode) + + virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope, + bool* aTriedToWrap); + + virtual uint32_t MaxNumberOfInputs() const MOZ_FINAL MOZ_OVERRIDE + { + return 1; + } + virtual uint32_t MaxNumberOfOutputs() const MOZ_FINAL MOZ_OVERRIDE + { + return 1; + } + + uint16_t Type() const + { + return static_cast (mType); + } + void SetType(uint16_t aType, ErrorResult& aRv) + { + BiquadTypeEnum type = static_cast (aType); + if (type > BiquadTypeEnum::Max) { + aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); + } else { + mType = type; + } + } + + AudioParam* Frequency() const + { + return mFrequency; + } + + AudioParam* Q() const + { + return mQ; + } + + AudioParam* Gain() const + { + return mGain; + } + +private: + BiquadTypeEnum mType; + nsRefPtr mFrequency; + nsRefPtr mQ; + nsRefPtr mGain; +}; + +} +} + +#endif + diff --git a/content/media/webaudio/Makefile.in b/content/media/webaudio/Makefile.in index 1ceaeed3da8..9d55a682b2b 100644 --- a/content/media/webaudio/Makefile.in +++ b/content/media/webaudio/Makefile.in @@ -23,6 +23,7 @@ CPPSRCS := \ AudioNode.cpp \ AudioParam.cpp \ AudioSourceNode.cpp \ + BiquadFilterNode.cpp \ DelayNode.cpp \ DynamicsCompressorNode.cpp \ EnableWebAudioCheck.cpp \ @@ -39,6 +40,7 @@ EXPORTS_mozilla/dom := \ AudioNode.h \ AudioParam.h \ AudioSourceNode.h \ + BiquadFilterNode.h \ DelayNode.h \ DynamicsCompressorNode.h \ GainNode.h \ diff --git a/content/media/webaudio/test/Makefile.in b/content/media/webaudio/test/Makefile.in index 8bb6b6afe34..3e4e05badd2 100644 --- a/content/media/webaudio/test/Makefile.in +++ b/content/media/webaudio/test/Makefile.in @@ -11,11 +11,13 @@ relativesrcdir := @relativesrcdir@ include $(DEPTH)/config/autoconf.mk MOCHITEST_FILES := \ + webaudio.js \ test_bug808374.html \ test_AudioBuffer.html \ test_AudioContext.html \ test_AudioListener.html \ test_badConnect.html \ + test_biquadFilterNode.html \ test_delayNode.html \ test_dynamicsCompressorNode.html \ test_gainNode.html \ diff --git a/content/media/webaudio/test/test_badConnect.html b/content/media/webaudio/test/test_badConnect.html index d3280cd75dc..1f7cd9e9daf 100644 --- a/content/media/webaudio/test/test_badConnect.html +++ b/content/media/webaudio/test/test_badConnect.html @@ -7,20 +7,9 @@
+
 
+  
+
+
+
+
+
+
+ + diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 09f6c831cb6..9bb777fb5fd 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -114,6 +114,10 @@ DOMInterfaces = { 'concrete': False, }, +'BiquadFilterNode': { + 'resultNotAddRefed': [ 'frequency', 'q', 'gain' ], +}, + 'Blob': [ { 'headerFile': 'nsIDOMFile.h', diff --git a/dom/webidl/AudioContext.webidl b/dom/webidl/AudioContext.webidl index 0a44ecf9680..08cff92ea1f 100644 --- a/dom/webidl/AudioContext.webidl +++ b/dom/webidl/AudioContext.webidl @@ -31,6 +31,8 @@ interface mozAudioContext { [Creator] DelayNode createDelay(optional float maxDelayTime = 1); [Creator] + BiquadFilterNode createBiquadFilter(); + [Creator] PannerNode createPanner(); [Creator] diff --git a/dom/webidl/BiquadFilterNode.webidl b/dom/webidl/BiquadFilterNode.webidl new file mode 100644 index 00000000000..370acf4ee89 --- /dev/null +++ b/dom/webidl/BiquadFilterNode.webidl @@ -0,0 +1,37 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * The origin of this IDL file is + * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html + * + * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C + * liability, trademark and document use rules apply. + */ + +[PrefControlled] +interface BiquadFilterNode : AudioNode { + + // Filter type. + const unsigned short LOWPASS = 0; + const unsigned short HIGHPASS = 1; + const unsigned short BANDPASS = 2; + const unsigned short LOWSHELF = 3; + const unsigned short HIGHSHELF = 4; + const unsigned short PEAKING = 5; + const unsigned short NOTCH = 6; + const unsigned short ALLPASS = 7; + + [SetterThrows] + attribute unsigned short type; + readonly attribute AudioParam frequency; // in Hertz + readonly attribute AudioParam Q; // Quality factor + readonly attribute AudioParam gain; // in Decibels + + // void getFrequencyResponse(Float32Array frequencyHz, + // Float32Array magResponse, + // Float32Array phaseResponse); + +}; + diff --git a/dom/webidl/WebIDL.mk b/dom/webidl/WebIDL.mk index 737a878e204..7ee1f08feae 100644 --- a/dom/webidl/WebIDL.mk +++ b/dom/webidl/WebIDL.mk @@ -17,6 +17,7 @@ webidl_files = \ AudioNode.webidl \ AudioParam.webidl \ AudioSourceNode.webidl \ + BiquadFilterNode.webidl \ Blob.webidl \ CanvasRenderingContext2D.webidl \ ClientRectList.webidl \ From aefcb09647b48abffa20e6632ad57e763dc26868 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Thu, 8 Nov 2012 09:33:12 -0500 Subject: [PATCH 15/39] Add the missing file for the test in bug 809654 --- content/media/webaudio/test/webaudio.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 content/media/webaudio/test/webaudio.js diff --git a/content/media/webaudio/test/webaudio.js b/content/media/webaudio/test/webaudio.js new file mode 100644 index 00000000000..4de8715b8b2 --- /dev/null +++ b/content/media/webaudio/test/webaudio.js @@ -0,0 +1,14 @@ +// Helpers for Web Audio tests + +function expectException(func, exceptionCode) { + var threw = false; + try { + func(); + } catch (ex) { + threw = true; + ok(ex instanceof DOMException, "Expect a DOM exception"); + ok(ex.code, exceptionCode, "Expect the correct exception code"); + } + ok(threw, "The exception was thrown"); +} + From 986e3905627808f9cabdc0ee32281cf8bfdb5cc2 Mon Sep 17 00:00:00 2001 From: Benoit Girard Date: Thu, 8 Nov 2012 10:10:51 -0500 Subject: [PATCH 16/39] Bug 809493 - Restore the blend equation state after drawing the underlay. r=joe --- gfx/layers/opengl/LayerManagerOGL.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gfx/layers/opengl/LayerManagerOGL.cpp b/gfx/layers/opengl/LayerManagerOGL.cpp index f6eeff4e407..88864c3d309 100644 --- a/gfx/layers/opengl/LayerManagerOGL.cpp +++ b/gfx/layers/opengl/LayerManagerOGL.cpp @@ -992,6 +992,10 @@ LayerManagerOGL::Render() // Allow widget to render a custom background. mWidget->DrawWindowUnderlay(this, rect); + // Reset some state that might of been clobbered by the underlay. + mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA, + LOCAL_GL_ONE, LOCAL_GL_ONE); + // Render our layers. RootLayer()->RenderLayer(mGLContext->IsDoubleBuffered() ? 0 : mBackBufferFBO, nsIntPoint(0, 0)); From 0b37af40c2de38ed6412625b3749a0cf41308c7d Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Thu, 8 Nov 2012 10:14:04 -0500 Subject: [PATCH 17/39] b=809123; disable broken browser_586068-reload.js test; r=ttaubert --- browser/components/sessionstore/test/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/components/sessionstore/test/Makefile.in b/browser/components/sessionstore/test/Makefile.in index 3e51ca7456c..4d9ac9da252 100644 --- a/browser/components/sessionstore/test/Makefile.in +++ b/browser/components/sessionstore/test/Makefile.in @@ -14,6 +14,7 @@ include $(DEPTH)/config/autoconf.mk # browser_526613.js is disabled because of frequent failures (bug 534489) # browser_589246.js is disabled for leaking browser windows (bug 752467) # browser_580512.js is disabled for leaking browser windows (bug 752467) +# browser_586068-reload.js is disabled due to generally being broken (bug 809123, 797263) MOCHITEST_BROWSER_FILES = \ head.js \ @@ -88,7 +89,6 @@ MOCHITEST_BROWSER_FILES = \ browser_586068-browser_state_interrupted.js \ browser_586068-cascade.js \ browser_586068-multi_window.js \ - browser_586068-reload.js \ browser_586068-select.js \ browser_586068-window_state.js \ browser_586068-window_state_override.js \ From dae0b41b61cf10395af6e282adbbe0d5019547ba Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Wed, 7 Nov 2012 22:40:48 -0800 Subject: [PATCH 18/39] Bug 809547 - Tests. r=bz --- js/xpconnect/tests/mochitest/Makefile.in | 1 + .../tests/mochitest/test_bug809547.html | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 js/xpconnect/tests/mochitest/test_bug809547.html diff --git a/js/xpconnect/tests/mochitest/Makefile.in b/js/xpconnect/tests/mochitest/Makefile.in index c6da75c28f4..686f60ef010 100644 --- a/js/xpconnect/tests/mochitest/Makefile.in +++ b/js/xpconnect/tests/mochitest/Makefile.in @@ -87,6 +87,7 @@ MOCHITEST_FILES = chrome_wrappers_helper.html \ test_bug800864.html \ test_bug802557.html \ file_bug802557.html \ + test_bug809547.html \ $(NULL) ifneq ($(OS_TARGET),Android) diff --git a/js/xpconnect/tests/mochitest/test_bug809547.html b/js/xpconnect/tests/mochitest/test_bug809547.html new file mode 100644 index 00000000000..c2c87623fd9 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug809547.html @@ -0,0 +1,42 @@ + + + + + + Test for Bug 809547 + + + + +Mozilla Bug 809547 +

+ +
+
+
+ + From f6535051b7b3bb8c0e0026438463fcd9f35e8b8b Mon Sep 17 00:00:00 2001 From: Wes Johnston Date: Thu, 8 Nov 2012 07:45:29 -0800 Subject: [PATCH 19/39] Bug 759041 - Bring in Android compatibility libraries. r=blassey --- build/autoconf/android.m4 | 9 +++++++++ build/mobile/robocop/Makefile.in | 2 +- config/android-common.mk | 2 +- js/src/build/autoconf/android.m4 | 9 +++++++++ mobile/android/base/Makefile.in | 2 +- 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/build/autoconf/android.m4 b/build/autoconf/android.m4 index a19690fac2c..b284aeea2e8 100644 --- a/build/autoconf/android.m4 +++ b/build/autoconf/android.m4 @@ -243,8 +243,17 @@ case "$target" in android_platform_tools="$android_sdk"/tools # SDK Tools < r8 fi ANDROID_SDK="${android_sdk}" + if test -e "${android_sdk}/../../extras/android/compatibility/v4/android-support-v4.jar" ; then + ANDROID_COMPAT_LIB="${android_sdk}/../../extras/android/compatibility/v4/android-support-v4.jar" + else + ANDROID_COMPAT_LIB="${android_sdk}/../../extras/android/support/v4/android-support-v4.jar"; + fi ANDROID_PLATFORM_TOOLS="${android_platform_tools}" AC_SUBST(ANDROID_SDK) + AC_SUBST(ANDROID_COMPAT_LIB) + if ! test -e $ANDROID_COMPAT_LIB ; then + AC_MSG_ERROR([You must download the andrioid compatibility library when targeting Android. (found $ANDROID_COMPAT_LIB)]) + fi AC_SUBST(ANDROID_PLATFORM_TOOLS) ;; esac diff --git a/build/mobile/robocop/Makefile.in b/build/mobile/robocop/Makefile.in index 48ec3ef70be..6c9bf815c17 100644 --- a/build/mobile/robocop/Makefile.in +++ b/build/mobile/robocop/Makefile.in @@ -93,7 +93,7 @@ classes.dex: $(_JAVA_HARNESS) classes.dex: $(_JAVA_TESTS) $(NSINSTALL) -D classes $(JAVAC) $(JAVAC_FLAGS) -d classes $(JAVAFILES) $(_JAVA_HARNESS) $(addprefix $(DEPTH)/mobile/android/base/tests/,$(_JAVA_TESTS)) - $(DX) --dex --output=$@ classes $(ROBOTIUM_PATH) + $(DX) --dex --output=$@ classes $(ROBOTIUM_PATH) $(ANDROID_COMPT_LIB) robocop.ap_: AndroidManifest.xml $(TESTPATH)/assets/* $(AAPT) package -f -M AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -I . -S res -A $(TESTPATH)/assets -F $@ -J ./ diff --git a/config/android-common.mk b/config/android-common.mk index fb590a77cca..145a983a639 100644 --- a/config/android-common.mk +++ b/config/android-common.mk @@ -23,7 +23,7 @@ endif # For Android, this defaults to $(ANDROID_SDK)/android.jar ifndef JAVA_BOOTCLASSPATH - JAVA_BOOTCLASSPATH = $(ANDROID_SDK)/android.jar + JAVA_BOOTCLASSPATH = $(ANDROID_SDK)/android.jar:$(ANDROID_COMPAT_LIB) endif # For Android, we default to 1.5 diff --git a/js/src/build/autoconf/android.m4 b/js/src/build/autoconf/android.m4 index a19690fac2c..b284aeea2e8 100644 --- a/js/src/build/autoconf/android.m4 +++ b/js/src/build/autoconf/android.m4 @@ -243,8 +243,17 @@ case "$target" in android_platform_tools="$android_sdk"/tools # SDK Tools < r8 fi ANDROID_SDK="${android_sdk}" + if test -e "${android_sdk}/../../extras/android/compatibility/v4/android-support-v4.jar" ; then + ANDROID_COMPAT_LIB="${android_sdk}/../../extras/android/compatibility/v4/android-support-v4.jar" + else + ANDROID_COMPAT_LIB="${android_sdk}/../../extras/android/support/v4/android-support-v4.jar"; + fi ANDROID_PLATFORM_TOOLS="${android_platform_tools}" AC_SUBST(ANDROID_SDK) + AC_SUBST(ANDROID_COMPAT_LIB) + if ! test -e $ANDROID_COMPAT_LIB ; then + AC_MSG_ERROR([You must download the andrioid compatibility library when targeting Android. (found $ANDROID_COMPAT_LIB)]) + fi AC_SUBST(ANDROID_PLATFORM_TOOLS) ;; esac diff --git a/mobile/android/base/Makefile.in b/mobile/android/base/Makefile.in index 893fbac7d30..e3c6906ae63 100644 --- a/mobile/android/base/Makefile.in +++ b/mobile/android/base/Makefile.in @@ -1043,7 +1043,7 @@ include $(topsrcdir)/config/android-common.mk # indices. classes.dex: jars/gecko-browser.jar @echo "DX classes.dex" - $(DX) --dex --output=classes.dex jars + $(DX) --dex --output=classes.dex jars $(ANDROID_COMPAT_LIB) jars/gecko-browser.jar: jars/gecko-mozglue.jar jars/gecko-util.jar jars/sync-thirdparty.jar $(addprefix $(srcdir)/,$(FENNEC_JAVA_FILES)) $(FENNEC_PP_JAVA_FILES) $(addprefix $(srcdir)/,$(SYNC_JAVA_FILES)) $(SYNC_PP_JAVA_FILES) R.java @echo "JAR gecko-browser.jar" From 94cf35d2ef28209936a33722fbd362bf81bbd2b3 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Thu, 8 Nov 2012 15:54:26 +0000 Subject: [PATCH 20/39] Bug 809567 - Hide ArchiveReader feature behind a pref (disabled by default), r=mounir --- dom/base/nsDOMClassInfo.cpp | 8 ++++++++ dom/file/ArchiveReader.cpp | 12 +++++++++++ dom/file/ArchiveReader.h | 2 ++ dom/file/test/helpers.js | 15 ++++++++++++++ dom/file/test/test_archivereader.html | 20 +++++++++---------- dom/indexedDB/test/helpers.js | 19 ++++++++++++++++-- .../mochitest/general/test_interfaces.html | 2 -- modules/libpref/src/init/all.js | 3 +++ 8 files changed, 67 insertions(+), 14 deletions(-) diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index 75d5b0e76ed..e62343c4f5c 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -6677,6 +6677,14 @@ ConstructorEnabled(const nsGlobalNameStruct *aStruct, nsGlobalWindow *aWin) } } + // Don't expose ArchiveReader unless user has explicitly enabled it + if (aStruct->mDOMClassInfoID == eDOMClassInfo_ArchiveReader_id || + aStruct->mDOMClassInfoID == eDOMClassInfo_ArchiveRequest_id) { + if (!dom::file::ArchiveReader::PrefEnabled()) { + return false; + } + } + return true; } diff --git a/dom/file/ArchiveReader.cpp b/dom/file/ArchiveReader.cpp index bb6b9b375b5..58404491ad1 100644 --- a/dom/file/ArchiveReader.cpp +++ b/dom/file/ArchiveReader.cpp @@ -16,6 +16,8 @@ #include "nsIURI.h" #include "nsNetUtil.h" +#include "mozilla/Preferences.h" + USING_FILE_NAMESPACE ArchiveReader::ArchiveReader() @@ -33,6 +35,12 @@ ArchiveReader::~ArchiveReader() nsLayoutStatics::Release(); } +bool +ArchiveReader::PrefEnabled() +{ + return Preferences::GetBool("dom.archivereader.enabled", true); +} + NS_IMETHODIMP ArchiveReader::Initialize(nsISupports* aOwner, JSContext* aCx, @@ -42,6 +50,10 @@ ArchiveReader::Initialize(nsISupports* aOwner, { NS_ENSURE_TRUE(aArgc == 1 || aArgc == 2, NS_ERROR_INVALID_ARG); + if (!PrefEnabled()) { + return NS_ERROR_UNEXPECTED; + } + // We expect to get a Blob object if (!aArgv[0].isObject()) { return NS_ERROR_INVALID_ARG; // We're not interested diff --git a/dom/file/ArchiveReader.h b/dom/file/ArchiveReader.h index 40b432f2a20..dcc578af091 100644 --- a/dom/file/ArchiveReader.h +++ b/dom/file/ArchiveReader.h @@ -48,6 +48,8 @@ public: nsresult GetInputStream(nsIInputStream** aInputStream); nsresult GetSize(uint64_t* aSize); + static bool PrefEnabled(); + public: // for the ArchiveRequest: nsresult RegisterRequest(ArchiveRequest* aRequest); diff --git a/dom/file/test/helpers.js b/dom/file/test/helpers.js index e3494df2b33..b1c0d690ab0 100644 --- a/dom/file/test/helpers.js +++ b/dom/file/test/helpers.js @@ -13,11 +13,14 @@ var fileStorages = [ var utils = SpecialPowers.getDOMWindowUtils(window); +var archiveReaderEnabled = false; + var testGenerator = testSteps(); function runTest() { allowUnlimitedQuota(); + enableArchiveReader(); SimpleTest.waitForExplicitFinish(); testGenerator.next(); @@ -26,6 +29,7 @@ function runTest() function finishTest() { resetUnlimitedQuota(); + resetArchiveReader(); SimpleTest.executeSoon(function() { testGenerator.close(); @@ -98,6 +102,17 @@ function resetUnlimitedQuota(url) removePermission("indexedDB-unlimited", url); } +function enableArchiveReader() +{ + archiveReaderEnabled = SpecialPowers.getBoolPref("dom.archivereader.enabled"); + SpecialPowers.setBoolPref("dom.archivereader.enabled", true); +} + +function resetArchiveReader() +{ + SpecialPowers.setBoolPref("dom.archivereader.enabled", archiveReaderEnabled); +} + function getFileHandle(fileStorageKey, name) { var requestService = SpecialPowers.getDOMRequestService(); diff --git a/dom/file/test/test_archivereader.html b/dom/file/test/test_archivereader.html index e451f519b39..1a8cbbd5d58 100644 --- a/dom/file/test/test_archivereader.html +++ b/dom/file/test/test_archivereader.html @@ -8,14 +8,8 @@ - - -

- -

- - + + + + +

+ +

diff --git a/dom/indexedDB/test/helpers.js b/dom/indexedDB/test/helpers.js index 73c0f49ab71..034f74264df 100644 --- a/dom/indexedDB/test/helpers.js +++ b/dom/indexedDB/test/helpers.js @@ -4,6 +4,7 @@ */ var testGenerator = testSteps(); +var archiveReaderEnabled = false; // The test js is shared between xpcshell (which has no SpecialPowers object) // and content mochitests (where the |Components| object is accessible only as @@ -68,6 +69,8 @@ if (!window.runTest) { allowUnlimitedQuota(); } + enableArchiveReader(); + clearAllDatabases(function () { testGenerator.next(); }); } } @@ -75,6 +78,7 @@ if (!window.runTest) { function finishTest() { resetUnlimitedQuota(); + resetArchiveReader(); SimpleTest.executeSoon(function() { testGenerator.close(); @@ -163,12 +167,12 @@ function compareKeys(k1, k2) { if (!(k2 instanceof Array) || k1.length != k2.length) return false; - + for (let i = 0; i < k1.length; ++i) { if (!compareKeys(k1[i], k2[i])) return false; } - + return true; } @@ -211,6 +215,17 @@ function resetUnlimitedQuota(url) removePermission("indexedDB-unlimited", url); } +function enableArchiveReader() +{ + archiveReaderEnabled = SpecialPowers.getBoolPref("dom.archivereader.enabled"); + SpecialPowers.setBoolPref("dom.archivereader.enabled", true); +} + +function resetArchiveReader() +{ + SpecialPowers.setBoolPref("dom.archivereader.enabled", archiveReaderEnabled); +} + function gc() { SpecialPowers.forceGC(); diff --git a/dom/tests/mochitest/general/test_interfaces.html b/dom/tests/mochitest/general/test_interfaces.html index 9eec189bb11..b3284b8a911 100644 --- a/dom/tests/mochitest/general/test_interfaces.html +++ b/dom/tests/mochitest/general/test_interfaces.html @@ -207,8 +207,6 @@ var interfaceNamesInGlobalScope = "SVGAltGlyphElement", "Screen", "FileReader", - "ArchiveReader", - "ArchiveRequest", "SVGSwitchElement", "SVGPolylineElement", "SVGPathSegLinetoAbs", diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index f473c40ad4a..ebeb2ebcafe 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -1681,6 +1681,9 @@ pref("editor.positioning.offset", 0); pref("dom.max_chrome_script_run_time", 20); pref("dom.max_script_run_time", 10); +// If true, ArchiveReader will be enabled +pref("dom.archivereader.enabled", false); + // Hang monitor timeout after which we kill the browser, in seconds // (0 is disabled) // Disabled on all platforms per bug 705748 until the found issues are From 36fae3dc883da077901609eb48c903fa3d810bbb Mon Sep 17 00:00:00 2001 From: Eddy Bruel Date: Thu, 8 Nov 2012 16:51:11 +0100 Subject: [PATCH 21/39] Bug 793160 - Add NULL check for proto; r=ejpbruel --- js/src/jit-test/tests/proxy/testBug793160.js | 3 +++ js/src/jsproxy.cpp | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 js/src/jit-test/tests/proxy/testBug793160.js diff --git a/js/src/jit-test/tests/proxy/testBug793160.js b/js/src/jit-test/tests/proxy/testBug793160.js new file mode 100644 index 00000000000..8e15baa2691 --- /dev/null +++ b/js/src/jit-test/tests/proxy/testBug793160.js @@ -0,0 +1,3 @@ +var obj = new Proxy(Object.create(null), {}); +assertEq(typeof obj, 'object'); +assertEq(obj != null, true); diff --git a/js/src/jsproxy.cpp b/js/src/jsproxy.cpp index 5dd9aeff658..1afe8c3e401 100644 --- a/js/src/jsproxy.cpp +++ b/js/src/jsproxy.cpp @@ -3156,9 +3156,12 @@ proxy(JSContext *cx, unsigned argc, jsval *vp) RootedObject proto(cx); if (!JSObject::getProto(cx, target, &proto)) return false; + JSObject *parent = NULL; + if (proto) + parent = proto->getParent(); RootedObject fun(cx, target->isCallable() ? target : (JSObject *) NULL); JSObject *proxy = NewProxyObject(cx, &ScriptedDirectProxyHandler::singleton, - ObjectValue(*target), proto, proto->getParent(), + ObjectValue(*target), proto, parent, fun, fun); if (!proxy) return false; From aac35871dd8a66d1c3467dca7d6eb9765fde976e Mon Sep 17 00:00:00 2001 From: Mounir Lamouri Date: Thu, 8 Nov 2012 15:56:48 +0000 Subject: [PATCH 22/39] Backed out changeset 3566ba4296f7 because of wrong bug number. --HG-- extra : rebase_source : c5d189308a555c7235d6cd405aa44d36c9b7db9a --- dom/base/nsDOMClassInfo.cpp | 8 -------- dom/file/ArchiveReader.cpp | 12 ----------- dom/file/ArchiveReader.h | 2 -- dom/file/test/helpers.js | 15 -------------- dom/file/test/test_archivereader.html | 20 +++++++++---------- dom/indexedDB/test/helpers.js | 19 ++---------------- .../mochitest/general/test_interfaces.html | 2 ++ modules/libpref/src/init/all.js | 3 --- 8 files changed, 14 insertions(+), 67 deletions(-) diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index e62343c4f5c..75d5b0e76ed 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -6677,14 +6677,6 @@ ConstructorEnabled(const nsGlobalNameStruct *aStruct, nsGlobalWindow *aWin) } } - // Don't expose ArchiveReader unless user has explicitly enabled it - if (aStruct->mDOMClassInfoID == eDOMClassInfo_ArchiveReader_id || - aStruct->mDOMClassInfoID == eDOMClassInfo_ArchiveRequest_id) { - if (!dom::file::ArchiveReader::PrefEnabled()) { - return false; - } - } - return true; } diff --git a/dom/file/ArchiveReader.cpp b/dom/file/ArchiveReader.cpp index 58404491ad1..bb6b9b375b5 100644 --- a/dom/file/ArchiveReader.cpp +++ b/dom/file/ArchiveReader.cpp @@ -16,8 +16,6 @@ #include "nsIURI.h" #include "nsNetUtil.h" -#include "mozilla/Preferences.h" - USING_FILE_NAMESPACE ArchiveReader::ArchiveReader() @@ -35,12 +33,6 @@ ArchiveReader::~ArchiveReader() nsLayoutStatics::Release(); } -bool -ArchiveReader::PrefEnabled() -{ - return Preferences::GetBool("dom.archivereader.enabled", true); -} - NS_IMETHODIMP ArchiveReader::Initialize(nsISupports* aOwner, JSContext* aCx, @@ -50,10 +42,6 @@ ArchiveReader::Initialize(nsISupports* aOwner, { NS_ENSURE_TRUE(aArgc == 1 || aArgc == 2, NS_ERROR_INVALID_ARG); - if (!PrefEnabled()) { - return NS_ERROR_UNEXPECTED; - } - // We expect to get a Blob object if (!aArgv[0].isObject()) { return NS_ERROR_INVALID_ARG; // We're not interested diff --git a/dom/file/ArchiveReader.h b/dom/file/ArchiveReader.h index dcc578af091..40b432f2a20 100644 --- a/dom/file/ArchiveReader.h +++ b/dom/file/ArchiveReader.h @@ -48,8 +48,6 @@ public: nsresult GetInputStream(nsIInputStream** aInputStream); nsresult GetSize(uint64_t* aSize); - static bool PrefEnabled(); - public: // for the ArchiveRequest: nsresult RegisterRequest(ArchiveRequest* aRequest); diff --git a/dom/file/test/helpers.js b/dom/file/test/helpers.js index b1c0d690ab0..e3494df2b33 100644 --- a/dom/file/test/helpers.js +++ b/dom/file/test/helpers.js @@ -13,14 +13,11 @@ var fileStorages = [ var utils = SpecialPowers.getDOMWindowUtils(window); -var archiveReaderEnabled = false; - var testGenerator = testSteps(); function runTest() { allowUnlimitedQuota(); - enableArchiveReader(); SimpleTest.waitForExplicitFinish(); testGenerator.next(); @@ -29,7 +26,6 @@ function runTest() function finishTest() { resetUnlimitedQuota(); - resetArchiveReader(); SimpleTest.executeSoon(function() { testGenerator.close(); @@ -102,17 +98,6 @@ function resetUnlimitedQuota(url) removePermission("indexedDB-unlimited", url); } -function enableArchiveReader() -{ - archiveReaderEnabled = SpecialPowers.getBoolPref("dom.archivereader.enabled"); - SpecialPowers.setBoolPref("dom.archivereader.enabled", true); -} - -function resetArchiveReader() -{ - SpecialPowers.setBoolPref("dom.archivereader.enabled", archiveReaderEnabled); -} - function getFileHandle(fileStorageKey, name) { var requestService = SpecialPowers.getDOMRequestService(); diff --git a/dom/file/test/test_archivereader.html b/dom/file/test/test_archivereader.html index 1a8cbbd5d58..e451f519b39 100644 --- a/dom/file/test/test_archivereader.html +++ b/dom/file/test/test_archivereader.html @@ -8,8 +8,14 @@ + - - - - - -

- -

diff --git a/dom/indexedDB/test/helpers.js b/dom/indexedDB/test/helpers.js index 034f74264df..73c0f49ab71 100644 --- a/dom/indexedDB/test/helpers.js +++ b/dom/indexedDB/test/helpers.js @@ -4,7 +4,6 @@ */ var testGenerator = testSteps(); -var archiveReaderEnabled = false; // The test js is shared between xpcshell (which has no SpecialPowers object) // and content mochitests (where the |Components| object is accessible only as @@ -69,8 +68,6 @@ if (!window.runTest) { allowUnlimitedQuota(); } - enableArchiveReader(); - clearAllDatabases(function () { testGenerator.next(); }); } } @@ -78,7 +75,6 @@ if (!window.runTest) { function finishTest() { resetUnlimitedQuota(); - resetArchiveReader(); SimpleTest.executeSoon(function() { testGenerator.close(); @@ -167,12 +163,12 @@ function compareKeys(k1, k2) { if (!(k2 instanceof Array) || k1.length != k2.length) return false; - + for (let i = 0; i < k1.length; ++i) { if (!compareKeys(k1[i], k2[i])) return false; } - + return true; } @@ -215,17 +211,6 @@ function resetUnlimitedQuota(url) removePermission("indexedDB-unlimited", url); } -function enableArchiveReader() -{ - archiveReaderEnabled = SpecialPowers.getBoolPref("dom.archivereader.enabled"); - SpecialPowers.setBoolPref("dom.archivereader.enabled", true); -} - -function resetArchiveReader() -{ - SpecialPowers.setBoolPref("dom.archivereader.enabled", archiveReaderEnabled); -} - function gc() { SpecialPowers.forceGC(); diff --git a/dom/tests/mochitest/general/test_interfaces.html b/dom/tests/mochitest/general/test_interfaces.html index b3284b8a911..9eec189bb11 100644 --- a/dom/tests/mochitest/general/test_interfaces.html +++ b/dom/tests/mochitest/general/test_interfaces.html @@ -207,6 +207,8 @@ var interfaceNamesInGlobalScope = "SVGAltGlyphElement", "Screen", "FileReader", + "ArchiveReader", + "ArchiveRequest", "SVGSwitchElement", "SVGPolylineElement", "SVGPathSegLinetoAbs", diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index ebeb2ebcafe..f473c40ad4a 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -1681,9 +1681,6 @@ pref("editor.positioning.offset", 0); pref("dom.max_chrome_script_run_time", 20); pref("dom.max_script_run_time", 10); -// If true, ArchiveReader will be enabled -pref("dom.archivereader.enabled", false); - // Hang monitor timeout after which we kill the browser, in seconds // (0 is disabled) // Disabled on all platforms per bug 705748 until the found issues are From b7940e94c15cbc79a5986df96f5b061c2d8cf327 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Thu, 8 Nov 2012 15:57:17 +0000 Subject: [PATCH 23/39] Bug 795930 - Hide ArchiveReader feature behind a pref (disabled by default), r=mounir --HG-- extra : rebase_source : fc267035c0eb85bb08b9da91bf79ecbb816da1b3 --- dom/base/nsDOMClassInfo.cpp | 8 ++++++++ dom/file/ArchiveReader.cpp | 12 +++++++++++ dom/file/ArchiveReader.h | 2 ++ dom/file/test/helpers.js | 15 ++++++++++++++ dom/file/test/test_archivereader.html | 20 +++++++++---------- dom/indexedDB/test/helpers.js | 19 ++++++++++++++++-- .../mochitest/general/test_interfaces.html | 2 -- modules/libpref/src/init/all.js | 3 +++ 8 files changed, 67 insertions(+), 14 deletions(-) diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index 75d5b0e76ed..e62343c4f5c 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -6677,6 +6677,14 @@ ConstructorEnabled(const nsGlobalNameStruct *aStruct, nsGlobalWindow *aWin) } } + // Don't expose ArchiveReader unless user has explicitly enabled it + if (aStruct->mDOMClassInfoID == eDOMClassInfo_ArchiveReader_id || + aStruct->mDOMClassInfoID == eDOMClassInfo_ArchiveRequest_id) { + if (!dom::file::ArchiveReader::PrefEnabled()) { + return false; + } + } + return true; } diff --git a/dom/file/ArchiveReader.cpp b/dom/file/ArchiveReader.cpp index bb6b9b375b5..58404491ad1 100644 --- a/dom/file/ArchiveReader.cpp +++ b/dom/file/ArchiveReader.cpp @@ -16,6 +16,8 @@ #include "nsIURI.h" #include "nsNetUtil.h" +#include "mozilla/Preferences.h" + USING_FILE_NAMESPACE ArchiveReader::ArchiveReader() @@ -33,6 +35,12 @@ ArchiveReader::~ArchiveReader() nsLayoutStatics::Release(); } +bool +ArchiveReader::PrefEnabled() +{ + return Preferences::GetBool("dom.archivereader.enabled", true); +} + NS_IMETHODIMP ArchiveReader::Initialize(nsISupports* aOwner, JSContext* aCx, @@ -42,6 +50,10 @@ ArchiveReader::Initialize(nsISupports* aOwner, { NS_ENSURE_TRUE(aArgc == 1 || aArgc == 2, NS_ERROR_INVALID_ARG); + if (!PrefEnabled()) { + return NS_ERROR_UNEXPECTED; + } + // We expect to get a Blob object if (!aArgv[0].isObject()) { return NS_ERROR_INVALID_ARG; // We're not interested diff --git a/dom/file/ArchiveReader.h b/dom/file/ArchiveReader.h index 40b432f2a20..dcc578af091 100644 --- a/dom/file/ArchiveReader.h +++ b/dom/file/ArchiveReader.h @@ -48,6 +48,8 @@ public: nsresult GetInputStream(nsIInputStream** aInputStream); nsresult GetSize(uint64_t* aSize); + static bool PrefEnabled(); + public: // for the ArchiveRequest: nsresult RegisterRequest(ArchiveRequest* aRequest); diff --git a/dom/file/test/helpers.js b/dom/file/test/helpers.js index e3494df2b33..b1c0d690ab0 100644 --- a/dom/file/test/helpers.js +++ b/dom/file/test/helpers.js @@ -13,11 +13,14 @@ var fileStorages = [ var utils = SpecialPowers.getDOMWindowUtils(window); +var archiveReaderEnabled = false; + var testGenerator = testSteps(); function runTest() { allowUnlimitedQuota(); + enableArchiveReader(); SimpleTest.waitForExplicitFinish(); testGenerator.next(); @@ -26,6 +29,7 @@ function runTest() function finishTest() { resetUnlimitedQuota(); + resetArchiveReader(); SimpleTest.executeSoon(function() { testGenerator.close(); @@ -98,6 +102,17 @@ function resetUnlimitedQuota(url) removePermission("indexedDB-unlimited", url); } +function enableArchiveReader() +{ + archiveReaderEnabled = SpecialPowers.getBoolPref("dom.archivereader.enabled"); + SpecialPowers.setBoolPref("dom.archivereader.enabled", true); +} + +function resetArchiveReader() +{ + SpecialPowers.setBoolPref("dom.archivereader.enabled", archiveReaderEnabled); +} + function getFileHandle(fileStorageKey, name) { var requestService = SpecialPowers.getDOMRequestService(); diff --git a/dom/file/test/test_archivereader.html b/dom/file/test/test_archivereader.html index e451f519b39..1a8cbbd5d58 100644 --- a/dom/file/test/test_archivereader.html +++ b/dom/file/test/test_archivereader.html @@ -8,14 +8,8 @@ - - -

- -

- - + + + + +

+ +

diff --git a/dom/indexedDB/test/helpers.js b/dom/indexedDB/test/helpers.js index 73c0f49ab71..034f74264df 100644 --- a/dom/indexedDB/test/helpers.js +++ b/dom/indexedDB/test/helpers.js @@ -4,6 +4,7 @@ */ var testGenerator = testSteps(); +var archiveReaderEnabled = false; // The test js is shared between xpcshell (which has no SpecialPowers object) // and content mochitests (where the |Components| object is accessible only as @@ -68,6 +69,8 @@ if (!window.runTest) { allowUnlimitedQuota(); } + enableArchiveReader(); + clearAllDatabases(function () { testGenerator.next(); }); } } @@ -75,6 +78,7 @@ if (!window.runTest) { function finishTest() { resetUnlimitedQuota(); + resetArchiveReader(); SimpleTest.executeSoon(function() { testGenerator.close(); @@ -163,12 +167,12 @@ function compareKeys(k1, k2) { if (!(k2 instanceof Array) || k1.length != k2.length) return false; - + for (let i = 0; i < k1.length; ++i) { if (!compareKeys(k1[i], k2[i])) return false; } - + return true; } @@ -211,6 +215,17 @@ function resetUnlimitedQuota(url) removePermission("indexedDB-unlimited", url); } +function enableArchiveReader() +{ + archiveReaderEnabled = SpecialPowers.getBoolPref("dom.archivereader.enabled"); + SpecialPowers.setBoolPref("dom.archivereader.enabled", true); +} + +function resetArchiveReader() +{ + SpecialPowers.setBoolPref("dom.archivereader.enabled", archiveReaderEnabled); +} + function gc() { SpecialPowers.forceGC(); diff --git a/dom/tests/mochitest/general/test_interfaces.html b/dom/tests/mochitest/general/test_interfaces.html index 9eec189bb11..b3284b8a911 100644 --- a/dom/tests/mochitest/general/test_interfaces.html +++ b/dom/tests/mochitest/general/test_interfaces.html @@ -207,8 +207,6 @@ var interfaceNamesInGlobalScope = "SVGAltGlyphElement", "Screen", "FileReader", - "ArchiveReader", - "ArchiveRequest", "SVGSwitchElement", "SVGPolylineElement", "SVGPathSegLinetoAbs", diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index f473c40ad4a..ebeb2ebcafe 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -1681,6 +1681,9 @@ pref("editor.positioning.offset", 0); pref("dom.max_chrome_script_run_time", 20); pref("dom.max_script_run_time", 10); +// If true, ArchiveReader will be enabled +pref("dom.archivereader.enabled", false); + // Hang monitor timeout after which we kill the browser, in seconds // (0 is disabled) // Disabled on all platforms per bug 705748 until the found issues are From f1bc1ef2e619215861dc4a6ad639e91cd1295aef Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Wed, 7 Nov 2012 16:20:25 -0500 Subject: [PATCH 24/39] Bug 806618 - followup - remove PR_NewLogModule static initializer in nsNativeComponentLoader.cpp; r=ehsan --- xpcom/components/nsNativeComponentLoader.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/xpcom/components/nsNativeComponentLoader.cpp b/xpcom/components/nsNativeComponentLoader.cpp index 1e19828d04e..d0374412769 100644 --- a/xpcom/components/nsNativeComponentLoader.cpp +++ b/xpcom/components/nsNativeComponentLoader.cpp @@ -52,14 +52,20 @@ using namespace mozilla; -static PRLogModuleInfo *nsNativeModuleLoaderLog = - PR_NewLogModule("nsNativeModuleLoader"); +static PRLogModuleInfo * +GetNativeModuleLoaderLog() +{ + static PRLogModuleInfo *sLog; + if (!sLog) + sLog = PR_NewLogModule("nsNativeModuleLoader"); + return sLog; +} bool gInXPCOMLoadOnMainThread = false; -#define LOG(level, args) PR_LOG(nsNativeModuleLoaderLog, level, args) +#define LOG(level, args) PR_LOG(GetNativeModuleLoaderLog(), level, args) -NS_IMPL_QUERY_INTERFACE1(nsNativeModuleLoader, +NS_IMPL_QUERY_INTERFACE1(nsNativeModuleLoader, mozilla::ModuleLoader) NS_IMPL_ADDREF_USING_AGGREGATOR(nsNativeModuleLoader, @@ -204,7 +210,7 @@ PLDHashOperator nsNativeModuleLoader::UnloaderFunc(nsIHashable* aHashedFile, NativeLoadData& aLoadData, void*) { - if (PR_LOG_TEST(nsNativeModuleLoaderLog, PR_LOG_DEBUG)) { + if (PR_LOG_TEST(GetNativeModuleLoaderLog(), PR_LOG_DEBUG)) { nsCOMPtr file(do_QueryInterface(aHashedFile)); nsAutoCString filePath; From 21603fab23ce111bfbf5bea6c2c2a122b63abc7b Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Thu, 1 Nov 2012 12:27:37 -0400 Subject: [PATCH 25/39] Bug 803665 - part 0 - make nsTimeout properly initialize its fields; r=bz --- dom/base/nsGlobalWindow.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index a766d76025f..b29e25ec94a 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -453,6 +453,14 @@ private: NS_IMPL_ISUPPORTS2(nsGlobalWindowObserver, nsIObserver, nsIInterfaceRequestor) nsTimeout::nsTimeout() + : mCleared(false), + mRunning(false), + mIsInterval(false), + mPublicId(0), + mInterval(0), + mFiringDepth(0), + mNestingLevel(0), + mPopupState(openAllowed) { #ifdef DEBUG_jst { @@ -462,8 +470,6 @@ nsTimeout::nsTimeout() } #endif - memset(this, 0, sizeof(*this)); - MOZ_COUNT_CTOR(nsTimeout); } From dd23c0243af061fc3933857a2b80c01efb4f3049 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Thu, 1 Nov 2012 10:06:22 -0400 Subject: [PATCH 26/39] Bug 803665 - convert nsGlobalWindow's timeout list to use mozilla::LinkedList; r=bz --- dom/base/nsGlobalWindow.cpp | 48 +++++++++++++++++-------------------- dom/base/nsGlobalWindow.h | 21 ++++++---------- 2 files changed, 29 insertions(+), 40 deletions(-) diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index b29e25ec94a..e7dbe01a98e 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -649,9 +649,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow) // Initialize the PRCList (this). PR_INIT_CLIST(this); - // Initialize timeout storage - PR_INIT_CLIST(&mTimeouts); - if (aOuterWindow) { // |this| is an inner window, add this inner window to the outer // window list of inners. @@ -1242,7 +1239,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow) nsEventListenerManager) for (nsTimeout* timeout = tmp->FirstTimeout(); - tmp->IsTimeout(timeout); + timeout; timeout = timeout->Next()) { cb.NoteNativeChild(timeout, NS_CYCLE_COLLECTION_PARTICIPANT(nsTimeout)); } @@ -1348,9 +1345,7 @@ nsGlobalWindow::IsBlackForCC() void nsGlobalWindow::UnmarkGrayTimers() { - for (nsTimeout* timeout = FirstTimeout(); - timeout && IsTimeout(timeout); - timeout = timeout->Next()) { + for (nsTimeout* timeout = FirstTimeout(); timeout; timeout = timeout->Next()) { if (timeout->mScriptHandler) { JSObject* o = timeout->mScriptHandler->GetScriptObject(); xpc_UnmarkGrayObject(o); @@ -2240,8 +2235,7 @@ nsGlobalWindow::DetachFromDocShell() // (mJSObject) so that it can be retrieved later (until it is // finalized by the JS GC). - NS_ASSERTION(PR_CLIST_IS_EMPTY(&mTimeouts), - "Uh, outer window holds timeouts!"); + NS_ASSERTION(mTimeouts.isEmpty(), "Uh, outer window holds timeouts!"); // Call FreeInnerObjects on all inner windows, not just the current // one, since some could be held by WindowStateHolder objects that @@ -9828,7 +9822,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout) // timeout events fire "early", so we need to test the timer as well // as the deadline. last_expired_timeout = nullptr; - for (timeout = FirstTimeout(); IsTimeout(timeout); timeout = timeout->Next()) { + for (timeout = FirstTimeout(); timeout; timeout = timeout->Next()) { if (((timeout == aTimeout) || (timeout->mWhen <= deadline)) && (timeout->mFiringDepth == 0)) { // Mark any timeouts that are on the list to be fired with the @@ -9862,7 +9856,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout) // list for any timeouts inserted as a result of running a timeout. dummy_timeout.mFiringDepth = firingDepth; dummy_timeout.mWhen = now; - PR_INSERT_AFTER(&dummy_timeout, last_expired_timeout); + last_expired_timeout->setNext(&dummy_timeout); // Don't let ClearWindowTimeouts throw away our stack-allocated // dummy timeout. @@ -9945,7 +9939,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout) // we need to reset the pointer to the following timeout. nextTimeout = timeout->Next(); - PR_REMOVE_LINK(timeout); + timeout->remove(); if (needsReinsertion) { // Insert interval timeout onto list sorted in deadline order. @@ -9958,7 +9952,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout) } // Take the dummy timeout off the head of the list - PR_REMOVE_LINK(&dummy_timeout); + dummy_timeout.remove(); mTimeoutInsertionPoint = last_insertion_point; } @@ -9996,9 +9990,7 @@ nsGlobalWindow::ClearTimeoutOrInterval(int32_t aTimerID) uint32_t public_id = (uint32_t)aTimerID; nsTimeout *timeout; - for (timeout = FirstTimeout(); - IsTimeout(timeout); - timeout = timeout->Next()) { + for (timeout = FirstTimeout(); timeout; timeout = timeout->Next()) { if (timeout->mPublicId == public_id) { if (timeout->mRunning) { /* We're running from inside the timeout. Mark this @@ -10008,7 +10000,7 @@ nsGlobalWindow::ClearTimeoutOrInterval(int32_t aTimerID) } else { /* Delete the timeout from the pending timeout list */ - PR_REMOVE_LINK(timeout); + timeout->remove(); if (timeout->mTimer) { timeout->mTimer->Cancel(); @@ -10044,7 +10036,7 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow() // Otherwise, start at the beginning of the list. for (nsTimeout *timeout = mTimeoutInsertionPoint ? mTimeoutInsertionPoint->Next() : FirstTimeout(); - IsTimeout(timeout); ) { + timeout; ) { // It's important that this check be <= so that we guarantee that // taking NS_MAX with |now| won't make a quantity equal to // timeout->mWhen below. @@ -10091,9 +10083,9 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow() // It is safe to remove and re-insert because mWhen is now // strictly smaller than it used to be, so we know we'll insert // |timeout| before nextTimeout. - NS_ASSERTION(!IsTimeout(nextTimeout) || + NS_ASSERTION(!nextTimeout || timeout->mWhen < nextTimeout->mWhen, "How did that happen?"); - PR_REMOVE_LINK(timeout); + timeout->remove(); // InsertTimeoutIntoList will addref |timeout| and reset // mFiringDepth. Make sure to undo that after calling it. uint32_t firingDepth = timeout->mFiringDepth; @@ -10122,7 +10114,7 @@ nsGlobalWindow::ClearAllTimeouts() { nsTimeout *timeout, *nextTimeout; - for (timeout = FirstTimeout(); IsTimeout(timeout); timeout = nextTimeout) { + for (timeout = FirstTimeout(); timeout; timeout = nextTimeout) { /* If RunTimeout() is higher up on the stack for this window, e.g. as a result of document.write from a timeout, then we need to reset the list insertion point for @@ -10151,7 +10143,7 @@ nsGlobalWindow::ClearAllTimeouts() } // Clear out our list - PR_INIT_CLIST(&mTimeouts); + mTimeouts.clear(); } void @@ -10165,7 +10157,7 @@ nsGlobalWindow::InsertTimeoutIntoList(nsTimeout *aTimeout) // insertion at the end. nsTimeout* prevSibling; for (prevSibling = LastTimeout(); - IsTimeout(prevSibling) && prevSibling != mTimeoutInsertionPoint && + prevSibling && prevSibling != mTimeoutInsertionPoint && // This condition needs to match the one in SetTimeoutOrInterval that // determines whether to set mWhen or mTimeRemaining. ((IsFrozen() || mTimeoutsSuspendDepth) ? @@ -10176,7 +10168,11 @@ nsGlobalWindow::InsertTimeoutIntoList(nsTimeout *aTimeout) } // Now link in aTimeout after prevSibling. - PR_INSERT_AFTER(aTimeout, prevSibling); + if (prevSibling) { + prevSibling->setNext(aTimeout); + } else { + mTimeouts.insertFront(aTimeout); + } aTimeout->mFiringDepth = 0; @@ -10468,7 +10464,7 @@ nsGlobalWindow::SuspendTimeouts(uint32_t aIncrease, mozilla::dom::workers::SuspendWorkersForWindow(cx, this); TimeStamp now = TimeStamp::Now(); - for (nsTimeout *t = FirstTimeout(); IsTimeout(t); t = t->Next()) { + for (nsTimeout *t = FirstTimeout(); t; t = t->Next()) { // Set mTimeRemaining to be the time remaining for this timer. if (t->mWhen > now) t->mTimeRemaining = t->mWhen - now; @@ -10556,7 +10552,7 @@ nsGlobalWindow::ResumeTimeouts(bool aThawChildren) bool _seenDummyTimeout = false; #endif - for (nsTimeout *t = FirstTimeout(); IsTimeout(t); t = t->Next()) { + for (nsTimeout *t = FirstTimeout(); t; t = t->Next()) { // There's a chance we're being called with RunTimeout on the stack in which // case we have a dummy timeout in the list that *must not* be resumed. It // can be identified by a null mWindow. diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 9b4ddb0f935..4719b6c4e1f 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -59,6 +59,7 @@ #include "nsIContent.h" #include "nsIIDBFactory.h" #include "nsFrameMessageManager.h" +#include "mozilla/LinkedList.h" #include "mozilla/TimeStamp.h" #include "nsIDOMTouchEvent.h" #include "nsIInlineEventHandlers.h" @@ -138,7 +139,7 @@ NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow, * timeout. Holds a strong reference to an nsIScriptTimeoutHandler, which * abstracts the language specific cruft. */ -struct nsTimeout : PRCList +struct nsTimeout : mozilla::LinkedListElement { nsTimeout(); ~nsTimeout(); @@ -149,13 +150,11 @@ struct nsTimeout : PRCList nsrefcnt AddRef(); nsTimeout* Next() { - // Note: might not actually return an nsTimeout. Use IsTimeout to check. - return static_cast(PR_NEXT_LINK(this)); + return getNext(); } nsTimeout* Prev() { - // Note: might not actually return an nsTimeout. Use IsTimeout to check. - return static_cast(PR_PREV_LINK(this)); + return getPrevious(); } nsresult InitTimer(nsTimerCallbackFunc aFunc, uint64_t delay) { @@ -885,17 +884,11 @@ protected: bool IsInModalState(); nsTimeout* FirstTimeout() { - // Note: might not actually return an nsTimeout. Use IsTimeout to check. - return static_cast(PR_LIST_HEAD(&mTimeouts)); + return mTimeouts.getFirst(); } nsTimeout* LastTimeout() { - // Note: might not actually return an nsTimeout. Use IsTimeout to check. - return static_cast(PR_LIST_TAIL(&mTimeouts)); - } - - bool IsTimeout(PRCList* aList) { - return aList != &mTimeouts; + return mTimeouts.getLast(); } // Convenience functions for the many methods that need to scale @@ -1065,7 +1058,7 @@ protected: // non-null. In that case, the dummy timeout pointed to by // mTimeoutInsertionPoint may have a later mWhen than some of the timeouts // that come after it. - PRCList mTimeouts; + mozilla::LinkedList mTimeouts; // If mTimeoutInsertionPoint is non-null, insertions should happen after it. // This is a dummy timeout at the moment; if that ever changes, the logic in // ResetTimersForNonBackgroundWindow needs to change. From b242110f28fe0171b37851ed1cc17bd2c5adc6f0 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Thu, 1 Nov 2012 10:07:22 -0400 Subject: [PATCH 27/39] Bug 803665 - followup - dispense with nsGlobalWindow::{First,Last}Timeout and nsTimeout::{Next,Previous}; r=bz --- dom/base/nsGlobalWindow.cpp | 38 +++++++++++++++++++------------------ dom/base/nsGlobalWindow.h | 16 ---------------- 2 files changed, 20 insertions(+), 34 deletions(-) diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index e7dbe01a98e..17ad2cde593 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -1238,9 +1238,9 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mListenerManager, nsEventListenerManager) - for (nsTimeout* timeout = tmp->FirstTimeout(); + for (nsTimeout* timeout = tmp->mTimeouts.getFirst(); timeout; - timeout = timeout->Next()) { + timeout = timeout->getNext()) { cb.NoteNativeChild(timeout, NS_CYCLE_COLLECTION_PARTICIPANT(nsTimeout)); } @@ -1345,7 +1345,9 @@ nsGlobalWindow::IsBlackForCC() void nsGlobalWindow::UnmarkGrayTimers() { - for (nsTimeout* timeout = FirstTimeout(); timeout; timeout = timeout->Next()) { + for (nsTimeout* timeout = mTimeouts.getFirst(); + timeout; + timeout = timeout->getNext()) { if (timeout->mScriptHandler) { JSObject* o = timeout->mScriptHandler->GetScriptObject(); xpc_UnmarkGrayObject(o); @@ -9822,7 +9824,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout) // timeout events fire "early", so we need to test the timer as well // as the deadline. last_expired_timeout = nullptr; - for (timeout = FirstTimeout(); timeout; timeout = timeout->Next()) { + for (timeout = mTimeouts.getFirst(); timeout; timeout = timeout->getNext()) { if (((timeout == aTimeout) || (timeout->mWhen <= deadline)) && (timeout->mFiringDepth == 0)) { // Mark any timeouts that are on the list to be fired with the @@ -9870,10 +9872,10 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout) Telemetry::AutoCounter timeoutsRan; - for (timeout = FirstTimeout(); + for (timeout = mTimeouts.getFirst(); timeout != &dummy_timeout && !IsFrozen(); timeout = nextTimeout) { - nextTimeout = timeout->Next(); + nextTimeout = timeout->getNext(); if (timeout->mFiringDepth != firingDepth) { // We skip the timeout since it's on the list to run at another @@ -9937,7 +9939,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout) // Running a timeout can cause another timeout to be deleted, so // we need to reset the pointer to the following timeout. - nextTimeout = timeout->Next(); + nextTimeout = timeout->getNext(); timeout->remove(); @@ -9990,7 +9992,7 @@ nsGlobalWindow::ClearTimeoutOrInterval(int32_t aTimerID) uint32_t public_id = (uint32_t)aTimerID; nsTimeout *timeout; - for (timeout = FirstTimeout(); timeout; timeout = timeout->Next()) { + for (timeout = mTimeouts.getFirst(); timeout; timeout = timeout->getNext()) { if (timeout->mPublicId == public_id) { if (timeout->mRunning) { /* We're running from inside the timeout. Mark this @@ -10035,13 +10037,13 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow() // start at the timer after mTimeoutInsertionPoint, if there is one. // Otherwise, start at the beginning of the list. for (nsTimeout *timeout = mTimeoutInsertionPoint ? - mTimeoutInsertionPoint->Next() : FirstTimeout(); + mTimeoutInsertionPoint->getNext() : mTimeouts.getFirst(); timeout; ) { // It's important that this check be <= so that we guarantee that // taking NS_MAX with |now| won't make a quantity equal to // timeout->mWhen below. if (timeout->mWhen <= now) { - timeout = timeout->Next(); + timeout = timeout->getNext(); continue; } @@ -10078,7 +10080,7 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow() // Get the pointer to the next timeout now, before we move the // current timeout in the list. - nsTimeout* nextTimeout = timeout->Next(); + nsTimeout* nextTimeout = timeout->getNext(); // It is safe to remove and re-insert because mWhen is now // strictly smaller than it used to be, so we know we'll insert @@ -10102,7 +10104,7 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow() timeout = nextTimeout; } else { - timeout = timeout->Next(); + timeout = timeout->getNext(); } } @@ -10114,7 +10116,7 @@ nsGlobalWindow::ClearAllTimeouts() { nsTimeout *timeout, *nextTimeout; - for (timeout = FirstTimeout(); timeout; timeout = nextTimeout) { + for (timeout = mTimeouts.getFirst(); timeout; timeout = nextTimeout) { /* If RunTimeout() is higher up on the stack for this window, e.g. as a result of document.write from a timeout, then we need to reset the list insertion point for @@ -10123,7 +10125,7 @@ nsGlobalWindow::ClearAllTimeouts() if (mRunningTimeout == timeout) mTimeoutInsertionPoint = nullptr; - nextTimeout = timeout->Next(); + nextTimeout = timeout->getNext(); if (timeout->mTimer) { timeout->mTimer->Cancel(); @@ -10156,14 +10158,14 @@ nsGlobalWindow::InsertTimeoutIntoList(nsTimeout *aTimeout) // mTimeoutInsertionPoint, though. This optimizes for the common case of // insertion at the end. nsTimeout* prevSibling; - for (prevSibling = LastTimeout(); + for (prevSibling = mTimeouts.getLast(); prevSibling && prevSibling != mTimeoutInsertionPoint && // This condition needs to match the one in SetTimeoutOrInterval that // determines whether to set mWhen or mTimeRemaining. ((IsFrozen() || mTimeoutsSuspendDepth) ? prevSibling->mTimeRemaining > aTimeout->mTimeRemaining : prevSibling->mWhen > aTimeout->mWhen); - prevSibling = prevSibling->Prev()) { + prevSibling = prevSibling->getPrevious()) { /* Do nothing; just searching */ } @@ -10464,7 +10466,7 @@ nsGlobalWindow::SuspendTimeouts(uint32_t aIncrease, mozilla::dom::workers::SuspendWorkersForWindow(cx, this); TimeStamp now = TimeStamp::Now(); - for (nsTimeout *t = FirstTimeout(); t; t = t->Next()) { + for (nsTimeout *t = mTimeouts.getFirst(); t; t = t->getNext()) { // Set mTimeRemaining to be the time remaining for this timer. if (t->mWhen > now) t->mTimeRemaining = t->mWhen - now; @@ -10552,7 +10554,7 @@ nsGlobalWindow::ResumeTimeouts(bool aThawChildren) bool _seenDummyTimeout = false; #endif - for (nsTimeout *t = FirstTimeout(); t; t = t->Next()) { + for (nsTimeout *t = mTimeouts.getFirst(); t; t = t->getNext()) { // There's a chance we're being called with RunTimeout on the stack in which // case we have a dummy timeout in the list that *must not* be resumed. It // can be identified by a null mWindow. diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 4719b6c4e1f..95b0bfb390b 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -149,14 +149,6 @@ struct nsTimeout : mozilla::LinkedListElement nsrefcnt Release(); nsrefcnt AddRef(); - nsTimeout* Next() { - return getNext(); - } - - nsTimeout* Prev() { - return getPrevious(); - } - nsresult InitTimer(nsTimerCallbackFunc aFunc, uint64_t delay) { return mTimer->InitWithFuncCallback(aFunc, this, delay, nsITimer::TYPE_ONE_SHOT); @@ -883,14 +875,6 @@ protected: bool IsInModalState(); - nsTimeout* FirstTimeout() { - return mTimeouts.getFirst(); - } - - nsTimeout* LastTimeout() { - return mTimeouts.getLast(); - } - // Convenience functions for the many methods that need to scale // from device to CSS pixels or vice versa. Note: if a presentation // context is not available, they will assume a 1:1 ratio. From 589f3dc93b53d3f2cee010fcb97d2be5f27245cb Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Fri, 19 Oct 2012 12:24:12 -0400 Subject: [PATCH 28/39] Bug 803666 - convert nsDocLoader's outstanding status list to use mozilla::LinkedList; r=smaug --- uriloader/base/nsDocLoader.cpp | 84 ++++++++-------------------------- uriloader/base/nsDocLoader.h | 57 +++++++++++++++++++++-- 2 files changed, 73 insertions(+), 68 deletions(-) diff --git a/uriloader/base/nsDocLoader.cpp b/uriloader/base/nsDocLoader.cpp index 9f81cacfb32..4a1f7474127 100644 --- a/uriloader/base/nsDocLoader.cpp +++ b/uriloader/base/nsDocLoader.cpp @@ -62,64 +62,21 @@ void GetURIStringFromRequest(nsIRequest* request, nsACString &name) } #endif /* DEBUG */ -struct nsStatusInfo : public PRCList -{ - nsString mStatusMessage; - nsresult mStatusCode; - // Weak mRequest is ok; we'll be told if it decides to go away. - nsIRequest * const mRequest; - - nsStatusInfo(nsIRequest *aRequest) : - mRequest(aRequest) - { - MOZ_COUNT_CTOR(nsStatusInfo); - PR_INIT_CLIST(this); - } - ~nsStatusInfo() - { - MOZ_COUNT_DTOR(nsStatusInfo); - PR_REMOVE_LINK(this); - } -}; - -struct nsRequestInfo : public PLDHashEntryHdr -{ - nsRequestInfo(const void *key) - : mKey(key), mCurrentProgress(0), mMaxProgress(0), mUploading(false) - , mLastStatus(nullptr) - { - MOZ_COUNT_CTOR(nsRequestInfo); - } - - ~nsRequestInfo() - { - MOZ_COUNT_DTOR(nsRequestInfo); - } - - nsIRequest* Request() { - return static_cast(const_cast(mKey)); - } - - const void* mKey; // Must be first for the pldhash stubs to work - int64_t mCurrentProgress; - int64_t mMaxProgress; - bool mUploading; - - nsAutoPtr mLastStatus; -}; -static bool -RequestInfoHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry, - const void *key) +bool +nsDocLoader::RequestInfoHashInitEntry(PLDHashTable* table, + PLDHashEntryHdr* entry, + const void* key) { // Initialize the entry with placement new new (entry) nsRequestInfo(key); return true; } -static void -RequestInfoHashClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry) +void +nsDocLoader::RequestInfoHashClearEntry(PLDHashTable* table, + PLDHashEntryHdr* entry) { nsRequestInfo* info = static_cast(entry); info->~nsRequestInfo(); @@ -178,8 +135,6 @@ nsDocLoader::nsDocLoader() ClearInternalProgress(); - PR_INIT_CLIST(&mStatusInfoList); - PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, ("DocLoader:%p: created.\n", this)); } @@ -892,9 +847,8 @@ void nsDocLoader::doStopURLLoad(nsIRequest *request, nsresult aStatus) // Fire a status change message for the most recent unfinished // request to make sure that the displayed status is not outdated. - if (!PR_CLIST_IS_EMPTY(&mStatusInfoList)) { - nsStatusInfo* statusInfo = - static_cast(PR_LIST_HEAD(&mStatusInfoList)); + if (!mStatusInfoList.isEmpty()) { + nsStatusInfo* statusInfo = mStatusInfoList.getFirst(); FireOnStatusChange(this, statusInfo->mRequest, statusInfo->mStatusCode, statusInfo->mStatusMessage.get()); @@ -1179,12 +1133,12 @@ NS_IMETHODIMP nsDocLoader::OnStatus(nsIRequest* aRequest, nsISupports* ctxt, } else { // We're going to move it to the front of the list, so remove // it from wherever it is now. - PR_REMOVE_LINK(info->mLastStatus); + info->mLastStatus->remove(); } info->mLastStatus->mStatusMessage = msg; info->mLastStatus->mStatusCode = aStatus; // Put the info at the front of the list - PR_INSERT_LINK(info->mLastStatus, &mStatusInfoList); + mStatusInfoList.insertFront(info->mLastStatus); } FireOnStatusChange(this, aRequest, aStatus, msg); } @@ -1535,10 +1489,10 @@ void nsDocLoader::RemoveRequestInfo(nsIRequest *aRequest) PL_DHashTableOperate(&mRequestInfoHash, aRequest, PL_DHASH_REMOVE); } -nsRequestInfo * nsDocLoader::GetRequestInfo(nsIRequest *aRequest) +nsDocLoader::nsRequestInfo* nsDocLoader::GetRequestInfo(nsIRequest* aRequest) { - nsRequestInfo *info = - static_cast + nsRequestInfo* info = + static_cast (PL_DHashTableOperate(&mRequestInfoHash, aRequest, PL_DHASH_LOOKUP)); @@ -1574,12 +1528,12 @@ void nsDocLoader::ClearRequestInfoHash(void) } // PLDHashTable enumeration callback that calculates the max progress. -static PLDHashOperator -CalcMaxProgressCallback(PLDHashTable *table, PLDHashEntryHdr *hdr, - uint32_t number, void *arg) +PLDHashOperator +nsDocLoader::CalcMaxProgressCallback(PLDHashTable* table, PLDHashEntryHdr* hdr, + uint32_t number, void* arg) { - const nsRequestInfo *info = static_cast(hdr); - int64_t *max = static_cast(arg); + const nsRequestInfo* info = static_cast(hdr); + int64_t* max = static_cast(arg); if (info->mMaxProgress < info->mCurrentProgress) { *max = int64_t(-1); diff --git a/uriloader/base/nsDocLoader.h b/uriloader/base/nsDocLoader.h index be0507540c7..66f9d3d9b85 100644 --- a/uriloader/base/nsDocLoader.h +++ b/uriloader/base/nsDocLoader.h @@ -27,10 +27,10 @@ #include "nsISupportsPriority.h" #include "nsCOMPtr.h" #include "pldhash.h" -#include "prclist.h" #include "nsAutoPtr.h" -struct nsRequestInfo; +#include "mozilla/LinkedList.h" + struct nsListenerInfo; /**************************************************************************** @@ -194,6 +194,54 @@ protected: } protected: + struct nsStatusInfo : public mozilla::LinkedListElement + { + nsString mStatusMessage; + nsresult mStatusCode; + // Weak mRequest is ok; we'll be told if it decides to go away. + nsIRequest * const mRequest; + + nsStatusInfo(nsIRequest* aRequest) : + mRequest(aRequest) + { + MOZ_COUNT_CTOR(nsStatusInfo); + } + ~nsStatusInfo() + { + MOZ_COUNT_DTOR(nsStatusInfo); + } + }; + + struct nsRequestInfo : public PLDHashEntryHdr + { + nsRequestInfo(const void* key) + : mKey(key), mCurrentProgress(0), mMaxProgress(0), mUploading(false) + , mLastStatus(nullptr) + { + MOZ_COUNT_CTOR(nsRequestInfo); + } + + ~nsRequestInfo() + { + MOZ_COUNT_DTOR(nsRequestInfo); + } + + nsIRequest* Request() { + return static_cast(const_cast(mKey)); + } + + const void* mKey; // Must be first for the pldhash stubs to work + int64_t mCurrentProgress; + int64_t mMaxProgress; + bool mUploading; + + nsAutoPtr mLastStatus; + }; + + static bool RequestInfoHashInitEntry(PLDHashTable* table, PLDHashEntryHdr* entry, + const void* key); + static void RequestInfoHashClearEntry(PLDHashTable* table, PLDHashEntryHdr* entry); + // IMPORTANT: The ownership implicit in the following member // variables has been explicitly checked and set using nsCOMPtr // for owning pointers and raw COM interface pointers for weak @@ -223,7 +271,7 @@ protected: PLDHashTable mRequestInfoHash; int64_t mCompletedTotalProgress; - PRCList mStatusInfoList; + mozilla::LinkedList mStatusInfoList; /* * This flag indicates that the loader is loading a document. It is set @@ -268,6 +316,9 @@ private: nsRequestInfo *GetRequestInfo(nsIRequest* aRequest); void ClearRequestInfoHash(); int64_t CalculateMaxProgress(); + static PLDHashOperator CalcMaxProgressCallback(PLDHashTable* table, + PLDHashEntryHdr* hdr, + uint32_t number, void* arg); /// void DumpChannelInfo(void); // used to clear our internal progress state between loads... From dd8473fad8fd5704dc9ebff132e1ef6b1bf4800a Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Thu, 1 Nov 2012 10:03:41 -0400 Subject: [PATCH 29/39] Bug 803668 - convert string bundle caches to use mozilla::LinkedList; r=smontagu --- intl/strres/src/nsStringBundle.cpp | 25 ++++++++----------------- intl/strres/src/nsStringBundleService.h | 5 +++-- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/intl/strres/src/nsStringBundle.cpp b/intl/strres/src/nsStringBundle.cpp index ad83961dab8..53cb270fff1 100644 --- a/intl/strres/src/nsStringBundle.cpp +++ b/intl/strres/src/nsStringBundle.cpp @@ -501,8 +501,7 @@ nsresult nsExtensibleStringBundle::GetSimpleEnumeration(nsISimpleEnumerator ** a #define MAX_CACHED_BUNDLES 16 -struct bundleCacheEntry_t { - PRCList list; +struct bundleCacheEntry_t : public LinkedListElement { nsCStringKey *mHashKey; // do not use a nsCOMPtr - this is a struct not a class! nsIStringBundle* mBundle; @@ -516,7 +515,6 @@ nsStringBundleService::nsStringBundleService() : printf("\n++ nsStringBundleService::nsStringBundleService ++\n"); #endif - PR_INIT_CLIST(&mBundleCache); PL_InitArenaPool(&mCacheEntryPool, "srEntries", sizeof(bundleCacheEntry_t)*MAX_CACHED_BUNDLES, sizeof(bundleCacheEntry_t)); @@ -582,16 +580,10 @@ nsStringBundleService::flushBundleCache() // release all bundles in the cache mBundleMap.Reset(); - PRCList *current = PR_LIST_HEAD(&mBundleCache); - while (current != &mBundleCache) { - bundleCacheEntry_t *cacheEntry = (bundleCacheEntry_t*)current; + while (!mBundleCache.isEmpty()) { + bundleCacheEntry_t *cacheEntry = mBundleCache.popFirst(); recycleEntry(cacheEntry); - PRCList *oldItem = current; - current = PR_NEXT_LINK(current); - - // will be freed in PL_FreeArenaPool - PR_REMOVE_LINK(oldItem); } PL_FreeArenaPool(&mCacheEntryPool); } @@ -616,7 +608,7 @@ nsStringBundleService::getStringBundle(const char *aURLSpec, // cache hit! // remove it from the list, it will later be reinserted // at the head of the list - PR_REMOVE_LINK((PRCList*)cacheEntry); + cacheEntry->remove(); } else { @@ -633,8 +625,7 @@ nsStringBundleService::getStringBundle(const char *aURLSpec, // at this point the cacheEntry should exist in the hashtable, // but is not in the LRU cache. // put the cache entry at the front of the list - - PR_INSERT_LINK((PRCList *)cacheEntry, &mBundleCache); + mBundleCache.insertFront(cacheEntry); // finally, return the value *aResult = cacheEntry->mBundle; @@ -654,12 +645,12 @@ nsStringBundleService::insertIntoCache(nsIStringBundle* aBundle, void *cacheEntryArena; PL_ARENA_ALLOCATE(cacheEntryArena, &mCacheEntryPool, sizeof(bundleCacheEntry_t)); - cacheEntry = (bundleCacheEntry_t*)cacheEntryArena; + cacheEntry = new (cacheEntryArena) bundleCacheEntry_t(); } else { // cache is full // take the last entry in the list, and recycle it. - cacheEntry = (bundleCacheEntry_t*)PR_LIST_TAIL(&mBundleCache); + cacheEntry = mBundleCache.getLast(); // remove it from the hash table and linked list NS_ASSERTION(mBundleMap.Exists(cacheEntry->mHashKey), @@ -670,7 +661,7 @@ nsStringBundleService::insertIntoCache(nsIStringBundle* aBundle, aHashKey->GetString()).get()); #endif mBundleMap.Remove(cacheEntry->mHashKey); - PR_REMOVE_LINK((PRCList*)cacheEntry); + cacheEntry->remove(); // free up excess memory recycleEntry(cacheEntry); diff --git a/intl/strres/src/nsStringBundleService.h b/intl/strres/src/nsStringBundleService.h index c6e6876cd03..c65ca5d4fc9 100644 --- a/intl/strres/src/nsStringBundleService.h +++ b/intl/strres/src/nsStringBundleService.h @@ -6,7 +6,6 @@ #ifndef nsStringBundleService_h__ #define nsStringBundleService_h__ -#include "prclist.h" #include "plarena.h" #include "nsCOMPtr.h" @@ -18,6 +17,8 @@ #include "nsIErrorService.h" #include "nsIStringBundleOverride.h" +#include "mozilla/LinkedList.h" + struct bundleCacheEntry_t; class nsStringBundleService : public nsIStringBundleService, @@ -48,7 +49,7 @@ private: static void recycleEntry(bundleCacheEntry_t*); nsHashtable mBundleMap; - PRCList mBundleCache; + mozilla::LinkedList mBundleCache; PLArenaPool mCacheEntryPool; nsCOMPtr mErrorService; From 1b2d5bc60185881e3419f8b7df3970c1947ac49e Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Thu, 8 Nov 2012 17:09:37 +0100 Subject: [PATCH 30/39] Bug 685012 - Implement page-break-inside:avoid in the style system. r=dbaron --- layout/style/nsCSSPropList.h | 6 ++++-- layout/style/nsComputedDOMStyle.cpp | 11 ++++++++++- layout/style/nsComputedDOMStyle.h | 1 + layout/style/nsRuleNode.cpp | 6 ++++++ layout/style/nsStyleStruct.cpp | 3 +++ layout/style/nsStyleStruct.h | 1 + layout/style/test/property_database.js | 5 ++--- layout/style/ua.css | 1 + 8 files changed, 28 insertions(+), 6 deletions(-) diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index 0cf3742553b..e3dc856bbce 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -2422,14 +2422,16 @@ CSS_PROP_DISPLAY( kPageBreakKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_None) // temp fix for bug 24000 -CSS_PROP_BACKENDONLY( +CSS_PROP_DISPLAY( page-break-inside, page_break_inside, PageBreakInside, CSS_PROPERTY_PARSE_VALUE, "", VARIANT_HK, - kPageBreakInsideKTable) + kPageBreakInsideKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) CSS_PROP_VISIBILITY( pointer-events, pointer_events, diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 9c692638a01..f5c1bc3e2fe 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -3298,6 +3298,15 @@ nsComputedDOMStyle::DoGetPageBreakBefore() return val; } +nsIDOMCSSValue* +nsComputedDOMStyle::DoGetPageBreakInside() +{ + nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue(); + val->SetIdent(nsCSSProps::ValueToKeywordEnum(GetStyleDisplay()->mBreakInside, + nsCSSProps::kPageBreakInsideKTable)); + return val; +} + nsIDOMCSSValue* nsComputedDOMStyle::DoGetHeight() { @@ -4802,7 +4811,7 @@ nsComputedDOMStyle::GetQueryablePropertyMap(uint32_t* aLength) // COMPUTED_STYLE_MAP_ENTRY(page, Page), COMPUTED_STYLE_MAP_ENTRY(page_break_after, PageBreakAfter), COMPUTED_STYLE_MAP_ENTRY(page_break_before, PageBreakBefore), - // COMPUTED_STYLE_MAP_ENTRY(page_break_inside, PageBreakInside), + COMPUTED_STYLE_MAP_ENTRY(page_break_inside, PageBreakInside), COMPUTED_STYLE_MAP_ENTRY(perspective, Perspective), COMPUTED_STYLE_MAP_ENTRY_LAYOUT(perspective_origin, PerspectiveOrigin), COMPUTED_STYLE_MAP_ENTRY(pointer_events, PointerEvents), diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h index b42e1e840db..0d834a75450 100644 --- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -324,6 +324,7 @@ private: nsIDOMCSSValue* DoGetResize(); nsIDOMCSSValue* DoGetPageBreakAfter(); nsIDOMCSSValue* DoGetPageBreakBefore(); + nsIDOMCSSValue* DoGetPageBreakInside(); nsIDOMCSSValue* DoGetTransform(); nsIDOMCSSValue* DoGetTransformOrigin(); nsIDOMCSSValue* DoGetPerspective(); diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 9a3ed51ce69..0a7ffcdb9a8 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -4812,6 +4812,12 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct, } // end temp fix + // page-break-inside: enum, inherit, initial + SetDiscrete(*aRuleData->ValueForPageBreakInside(), + display->mBreakInside, canStoreInRuleTree, + SETDSC_ENUMERATED, parentDisplay->mBreakInside, + NS_STYLE_PAGE_BREAK_AUTO, 0, 0, 0, 0); + // float: enum, inherit, initial SetDiscrete(*aRuleData->ValueForCssFloat(), display->mFloats, canStoreInRuleTree, diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 1811c69798a..5f7fd788859 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -2089,6 +2089,7 @@ nsStyleDisplay::nsStyleDisplay() mFloats = NS_STYLE_FLOAT_NONE; mOriginalFloats = mFloats; mBreakType = NS_STYLE_CLEAR_NONE; + mBreakInside = NS_STYLE_PAGE_BREAK_AUTO; mBreakBefore = false; mBreakAfter = false; mOverflowX = NS_STYLE_OVERFLOW_VISIBLE; @@ -2142,6 +2143,7 @@ nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource) , mFloats(aSource.mFloats) , mOriginalFloats(aSource.mOriginalFloats) , mBreakType(aSource.mBreakType) + , mBreakInside(aSource.mBreakInside) , mBreakBefore(aSource.mBreakBefore) , mBreakAfter(aSource.mBreakAfter) , mOverflowX(aSource.mOverflowX) @@ -2202,6 +2204,7 @@ nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const // XXX the following is conservative, for now: changing float breaking shouldn't // necessarily require a repaint, reflow should suffice. if (mBreakType != aOther.mBreakType + || mBreakInside != aOther.mBreakInside || mBreakBefore != aOther.mBreakBefore || mBreakAfter != aOther.mBreakAfter || mAppearance != aOther.mAppearance diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 4e6d9ea96c2..acf03c37810 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -1595,6 +1595,7 @@ struct nsStyleDisplay { uint8_t mOriginalFloats; // [reset] saved mFloats for position:absolute/fixed; // otherwise equal to mFloats uint8_t mBreakType; // [reset] see nsStyleConsts.h NS_STYLE_CLEAR_* + uint8_t mBreakInside; // [reset] NS_STYLE_PAGE_BREAK_AUTO/AVOID bool mBreakBefore; // [reset] bool mBreakAfter; // [reset] uint8_t mOverflowX; // [reset] see nsStyleConsts.h diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index b6b2756fe5d..d3cae77a7c6 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -2989,12 +2989,11 @@ var gCSSProperties = { }, "page-break-inside": { domProp: "pageBreakInside", - inherited: true, - backend_only: true, + inherited: false, type: CSS_TYPE_LONGHAND, initial_values: [ "auto" ], other_values: [ "avoid" ], - invalid_values: [] + invalid_values: [ "left", "right" ] }, "pointer-events": { domProp: "pointerEvents", diff --git a/layout/style/ua.css b/layout/style/ua.css index 028f1bb5a90..a10b8cc836c 100644 --- a/layout/style/ua.css +++ b/layout/style/ua.css @@ -39,6 +39,7 @@ z-index: inherit; page-break-before: inherit; page-break-after: inherit; + page-break-inside: inherit; vertical-align: inherit; /* needed for inline-table */ line-height: inherit; /* needed for vertical-align on inline-table */ align-self: inherit; /* needed for "align-self" to work on table flex items */ From 78355598f64ff3d176f210cd2cd602c28e99fbdc Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Thu, 8 Nov 2012 17:09:38 +0100 Subject: [PATCH 31/39] Bug 685012 - Implement page-break-inside:avoid in layout. r=fantasai,sr=roc --- layout/generic/nsBlockFrame.cpp | 88 +++++++++++-------- layout/generic/nsBlockFrame.h | 9 +- layout/generic/nsBlockReflowState.cpp | 19 +++- layout/generic/nsFrame.h | 9 ++ ...mn-balancing-break-inside-avoid-2-ref.html | 48 ++++++++++ ...column-balancing-break-inside-avoid-2.html | 49 +++++++++++ layout/reftests/pagination/reftest.list | 3 + layout/reftests/table-overflow/reftest.list | 1 + .../table-row-pagination-ref.html | 24 +++++ .../table-overflow/table-row-pagination.html | 24 +++++ ...css21-block-page-break-inside-avoid-1.html | 20 +++++ ...ss21-block-page-break-inside-avoid-10.html | 19 ++++ ...ss21-block-page-break-inside-avoid-11.html | 20 +++++ ...ss21-block-page-break-inside-avoid-12.html | 21 +++++ ...ss21-block-page-break-inside-avoid-13.html | 22 +++++ ...css21-block-page-break-inside-avoid-2.html | 20 +++++ ...css21-block-page-break-inside-avoid-3.html | 20 +++++ ...css21-block-page-break-inside-avoid-4.html | 20 +++++ ...css21-block-page-break-inside-avoid-5.html | 20 +++++ ...css21-block-page-break-inside-avoid-6.html | 20 +++++ ...css21-block-page-break-inside-avoid-7.html | 21 +++++ ...1-block-page-break-inside-avoid-8-ref.html | 22 +++++ ...css21-block-page-break-inside-avoid-8.html | 22 +++++ ...css21-block-page-break-inside-avoid-9.html | 21 +++++ ...s21-block-page-break-inside-avoid-ref.html | 20 +++++ ...css21-float-page-break-inside-avoid-1.html | 20 +++++ ...1-float-page-break-inside-avoid-2-ref.html | 21 +++++ ...css21-float-page-break-inside-avoid-2.html | 20 +++++ ...css21-float-page-break-inside-avoid-3.html | 20 +++++ ...css21-float-page-break-inside-avoid-4.html | 20 +++++ ...1-float-page-break-inside-avoid-5-ref.html | 34 +++++++ ...css21-float-page-break-inside-avoid-5.html | 34 +++++++ ...1-float-page-break-inside-avoid-6-ref.html | 18 ++++ ...css21-float-page-break-inside-avoid-6.html | 18 ++++ ...1-float-page-break-inside-avoid-7-ref.html | 26 ++++++ ...css21-float-page-break-inside-avoid-7.html | 27 ++++++ ...1-float-page-break-inside-avoid-8-ref.html | 27 ++++++ ...css21-float-page-break-inside-avoid-8.html | 27 ++++++ ...1-float-page-break-inside-avoid-9-ref.html | 31 +++++++ ...css21-float-page-break-inside-avoid-9.html | 32 +++++++ ...-inline-page-break-inside-avoid-1-ref.html | 20 +++++ ...ss21-inline-page-break-inside-avoid-1.html | 20 +++++ ...z-css21-row-page-break-inside-avoid-1.html | 22 +++++ ...z-css21-row-page-break-inside-avoid-2.html | 23 +++++ ...21-rowgroup-page-break-inside-avoid-1.html | 20 +++++ ...21-rowgroup-page-break-inside-avoid-2.html | 20 +++++ ...21-rowgroup-page-break-inside-avoid-3.html | 20 +++++ ...owgroup-page-break-inside-avoid-4-ref.html | 23 +++++ ...21-rowgroup-page-break-inside-avoid-4.html | 23 +++++ ...owgroup-page-break-inside-avoid-5-ref.html | 22 +++++ ...21-rowgroup-page-break-inside-avoid-5.html | 22 +++++ ...21-rowgroup-page-break-inside-avoid-6.html | 23 +++++ ...owgroup-page-break-inside-avoid-7-ref.html | 25 ++++++ ...21-rowgroup-page-break-inside-avoid-7.html | 25 ++++++ ...owgroup-page-break-inside-avoid-8-ref.html | 26 ++++++ ...21-rowgroup-page-break-inside-avoid-8.html | 26 ++++++ ...css21-table-page-break-inside-avoid-1.html | 20 +++++ ...1-table-page-break-inside-avoid-2-ref.html | 28 ++++++ ...css21-table-page-break-inside-avoid-2.html | 28 ++++++ ...1-table-page-break-inside-avoid-3-ref.html | 29 ++++++ ...css21-table-page-break-inside-avoid-3.html | 29 ++++++ ...1-table-page-break-inside-avoid-4-ref.html | 20 +++++ ...css21-table-page-break-inside-avoid-4.html | 21 +++++ ...1-table-page-break-inside-avoid-5-ref.html | 24 +++++ ...css21-table-page-break-inside-avoid-5.html | 24 +++++ ...s21-table-page-break-inside-avoid-ref.html | 20 +++++ .../submitted/css21/pagination/reftest.list | 38 ++++++++ .../w3c-css/submitted/css21/reftest.list | 1 + ...mn-balancing-break-inside-avoid-1-ref.html | 48 ++++++++++ ...column-balancing-break-inside-avoid-1.html | 49 +++++++++++ .../w3c-css/submitted/multicol3/reftest.list | 1 + .../reftests/w3c-css/submitted/reftest.list | 6 +- layout/tables/nsTableFrame.cpp | 22 +++-- layout/tables/nsTableRowFrame.cpp | 5 ++ layout/tables/nsTableRowGroupFrame.cpp | 28 ++++-- layout/tables/nsTableRowGroupFrame.h | 3 +- 76 files changed, 1702 insertions(+), 59 deletions(-) create mode 100644 layout/reftests/pagination/column-balancing-break-inside-avoid-2-ref.html create mode 100644 layout/reftests/pagination/column-balancing-break-inside-avoid-2.html create mode 100644 layout/reftests/table-overflow/table-row-pagination-ref.html create mode 100644 layout/reftests/table-overflow/table-row-pagination.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-1.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-10.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-11.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-12.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-13.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-2.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-3.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-4.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-5.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-6.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-7.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-8-ref.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-8.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-9.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-ref.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-1.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-2-ref.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-2.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-3.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-4.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-5-ref.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-5.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-6-ref.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-6.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-7-ref.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-7.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-8-ref.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-8.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-9-ref.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-9.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-inline-page-break-inside-avoid-1-ref.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-inline-page-break-inside-avoid-1.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-row-page-break-inside-avoid-1.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-row-page-break-inside-avoid-2.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-1.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-2.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-3.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-4-ref.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-4.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-5-ref.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-5.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-6.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-7-ref.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-7.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-8-ref.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-8.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-1.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-2-ref.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-2.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-3-ref.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-3.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-4-ref.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-4.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-5-ref.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-5.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-ref.html create mode 100644 layout/reftests/w3c-css/submitted/css21/pagination/reftest.list create mode 100644 layout/reftests/w3c-css/submitted/css21/reftest.list create mode 100644 layout/reftests/w3c-css/submitted/multicol3/moz-multicol3-column-balancing-break-inside-avoid-1-ref.html create mode 100644 layout/reftests/w3c-css/submitted/multicol3/moz-multicol3-column-balancing-break-inside-avoid-1.html create mode 100644 layout/reftests/w3c-css/submitted/multicol3/reftest.list diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 4afc6eecb92..86eb4720b7a 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -3058,9 +3058,13 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, // constrained height to turn into an unconstrained one. aState.mY = startingY; aState.mPrevBottomMargin = incomingMargin; - PushLines(aState, aLine.prev()); - NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus); *aKeepReflowGoing = false; + if (ShouldAvoidBreakInside(aState.mReflowState)) { + aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE(); + } else { + PushLines(aState, aLine.prev()); + NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus); + } return NS_OK; } @@ -3120,9 +3124,13 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, if (NS_INLINE_IS_BREAK_BEFORE(frameReflowStatus)) { // None of the child block fits. - PushLines(aState, aLine.prev()); *aKeepReflowGoing = false; - NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus); + if (ShouldAvoidBreakInside(aState.mReflowState)) { + aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE(); + } else { + PushLines(aState, aLine.prev()); + NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus); + } } else { // Note: line-break-after a block is a nop @@ -3141,6 +3149,11 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, collapsedBottomMargin, aLine->mBounds, overflowAreas, frameReflowStatus); + if (!NS_FRAME_IS_FULLY_COMPLETE(frameReflowStatus) && + ShouldAvoidBreakInside(aState.mReflowState)) { + *aKeepReflowGoing = false; + } + if (aLine->SetCarriedOutBottomMargin(collapsedBottomMargin)) { line_iterator nextLine = aLine; ++nextLine; @@ -3281,16 +3294,14 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, brc.GetCarriedOutBottomMargin(), collapsedBottomMargin.get(), aState.mPrevBottomMargin); #endif - } - else { - // None of the block fits. Determine the correct reflow status. - if (aLine == mLines.front() && !GetPrevInFlow()) { - // If it's our very first line then we need to be pushed to - // our parents next-in-flow. Therefore, return break-before - // status for our reflow status. + } else { + if ((aLine == mLines.front() && !GetPrevInFlow()) || + ShouldAvoidBreakInside(aState.mReflowState)) { + // If it's our very first line *or* we're not at the top of the page + // and we have page-break-inside:avoid, then we need to be pushed to + // our parent's next-in-flow. aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE(); - } - else { + } else { // Push the line that didn't fit and any lines that follow it // to our next-in-flow. PushLines(aState, aLine.prev()); @@ -3399,12 +3410,10 @@ nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState, void nsBlockFrame::PushTruncatedLine(nsBlockReflowState& aState, line_iterator aLine, - bool& aKeepReflowGoing) + bool* aKeepReflowGoing) { - line_iterator prevLine = aLine; - --prevLine; - PushLines(aState, prevLine); - aKeepReflowGoing = false; + PushLines(aState, aLine.prev()); + *aKeepReflowGoing = false; NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus); } @@ -3625,8 +3634,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState, // it to the next page/column where its contents can fit not // next to a float. lineReflowStatus = LINE_REFLOW_TRUNCATED; - // Push the line that didn't fit - PushTruncatedLine(aState, aLine, *aKeepReflowGoing); + PushTruncatedLine(aState, aLine, aKeepReflowGoing); } } @@ -4191,21 +4199,25 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, newY = aState.mY + dy; } - // See if the line fit. If it doesn't we need to push it. Our first - // line will always fit. + if (!NS_FRAME_IS_FULLY_COMPLETE(aState.mReflowStatus) && + ShouldAvoidBreakInside(aState.mReflowState)) { + aLine->AppendFloats(aState.mCurrentLineFloats); + aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE(); + return true; + } + + // See if the line fit (our first line always does). if (mLines.front() != aLine && newY > aState.mBottomEdge && aState.mBottomEdge != NS_UNCONSTRAINEDSIZE) { - // Push this line and all of its children and anything else that - // follows to our next-in-flow - NS_ASSERTION((aState.mCurrentLine == aLine), "oops"); - PushLines(aState, aLine.prev()); - - // Stop reflow and whack the reflow status if reflow hasn't - // already been stopped. - if (*aKeepReflowGoing) { - NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus); - *aKeepReflowGoing = false; + NS_ASSERTION(aState.mCurrentLine == aLine, "oops"); + if (ShouldAvoidBreakInside(aState.mReflowState)) { + // All our content doesn't fit, start on the next page. + aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE(); + } else { + // Push aLine and all of its children and anything else that + // follows to our next-in-flow. + PushTruncatedLine(aState, aLine, aKeepReflowGoing); } return true; } @@ -5755,11 +5767,15 @@ nsBlockFrame::ReflowFloat(nsBlockReflowState& aState, aReflowStatus, aState); } while (NS_SUCCEEDED(rv) && clearanceFrame); - // An incomplete reflow status means we should split the float - // if the height is constrained (bug 145305). - if (NS_FRAME_IS_NOT_COMPLETE(aReflowStatus) && - (NS_UNCONSTRAINEDSIZE == aAdjustedAvailableSpace.height)) + if (!NS_FRAME_IS_FULLY_COMPLETE(aReflowStatus) && + ShouldAvoidBreakInside(floatRS)) { + aReflowStatus = NS_INLINE_LINE_BREAK_BEFORE(); + } else if (NS_FRAME_IS_NOT_COMPLETE(aReflowStatus) && + (NS_UNCONSTRAINEDSIZE == aAdjustedAvailableSpace.height)) { + // An incomplete reflow status means we should split the float + // if the height is constrained (bug 145305). aReflowStatus = NS_FRAME_COMPLETE; + } if (aReflowStatus & NS_FRAME_REFLOW_NEXTINFLOW) { aState.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW; diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h index 93cb084524f..5d04a48e089 100644 --- a/layout/generic/nsBlockFrame.h +++ b/layout/generic/nsBlockFrame.h @@ -631,11 +631,14 @@ protected: nsIFrame* aFrame, bool& aMadeNewFrame); - // Push aLine, which cannot be placed on this page/column but should - // fit on a future one. Set aKeepReflowGoing to false. + /** + * Push aLine (and any after it), since it cannot be placed on this + * page/column. Set aKeepReflowGoing to false and set + * flag aState.mReflowStatus as incomplete. + */ void PushTruncatedLine(nsBlockReflowState& aState, line_iterator aLine, - bool& aKeepReflowGoing); + bool* aKeepReflowGoing); nsresult SplitLine(nsBlockReflowState& aState, nsLineLayout& aLineLayout, diff --git a/layout/generic/nsBlockReflowState.cpp b/layout/generic/nsBlockReflowState.cpp index 06387223703..ce355ca406c 100644 --- a/layout/generic/nsBlockReflowState.cpp +++ b/layout/generic/nsBlockReflowState.cpp @@ -760,15 +760,28 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat) // (This code is only for DISABLE_FLOAT_BREAKING_IN_COLUMNS .) // // Likewise, if none of the float fit, and it needs to be pushed in - // its entirety to the next page (NS_FRAME_IS_TRUNCATED), we need to - // do the same. + // its entirety to the next page (NS_FRAME_IS_TRUNCATED or + // NS_INLINE_IS_BREAK_BEFORE), we need to do the same. if ((mContentArea.height != NS_UNCONSTRAINEDSIZE && adjustedAvailableSpace.height == NS_UNCONSTRAINEDSIZE && !mustPlaceFloat && aFloat->GetSize().height + floatMargin.TopBottom() > mContentArea.YMost() - floatY) || - NS_FRAME_IS_TRUNCATED(reflowStatus)) { + NS_FRAME_IS_TRUNCATED(reflowStatus) || + NS_INLINE_IS_BREAK_BEFORE(reflowStatus)) { + PushFloatPastBreak(aFloat); + return false; + } + // We can't use aFloat->ShouldAvoidBreakInside(mReflowState) here since + // its mIsTopOfPage may be true even though the float isn't at the + // top when floatY > 0. + if (!mustPlaceFloat && (!mReflowState.mFlags.mIsTopOfPage || floatY > 0) && + NS_STYLE_PAGE_BREAK_AVOID == aFloat->GetStyleDisplay()->mBreakInside && + (!NS_FRAME_IS_FULLY_COMPLETE(reflowStatus) || + aFloat->GetSize().height + floatMargin.TopBottom() > + mContentArea.YMost() - floatY) && + !aFloat->GetPrevInFlow()) { PushFloatPastBreak(aFloat); return false; } diff --git a/layout/generic/nsFrame.h b/layout/generic/nsFrame.h index a81d9e04c4e..a0ecd877387 100644 --- a/layout/generic/nsFrame.h +++ b/layout/generic/nsFrame.h @@ -408,6 +408,15 @@ public: virtual const void* GetStyleDataExternal(nsStyleStructID aSID) const; + /** + * @return true if we should avoid a page/column break in this frame. + */ + bool ShouldAvoidBreakInside(const nsHTMLReflowState& aReflowState) const { + return !aReflowState.mFlags.mIsTopOfPage && + NS_STYLE_PAGE_BREAK_AVOID == GetStyleDisplay()->mBreakInside && + !GetPrevInFlow(); + } + #ifdef DEBUG /** * Tracing method that writes a method enter/exit routine to the diff --git a/layout/reftests/pagination/column-balancing-break-inside-avoid-2-ref.html b/layout/reftests/pagination/column-balancing-break-inside-avoid-2-ref.html new file mode 100644 index 00000000000..a71563c0a47 --- /dev/null +++ b/layout/reftests/pagination/column-balancing-break-inside-avoid-2-ref.html @@ -0,0 +1,48 @@ + + + + + + + Balancing Overflow, page-break-inside:avoid + + + + +
+ diff --git a/layout/reftests/pagination/column-balancing-break-inside-avoid-2.html b/layout/reftests/pagination/column-balancing-break-inside-avoid-2.html new file mode 100644 index 00000000000..3401e0c7f0c --- /dev/null +++ b/layout/reftests/pagination/column-balancing-break-inside-avoid-2.html @@ -0,0 +1,49 @@ + + + + + + + Balancing Overflow, page-break-inside:avoid + + + + +
+ diff --git a/layout/reftests/pagination/reftest.list b/layout/reftests/pagination/reftest.list index ebb5590ced0..52bce0620d1 100644 --- a/layout/reftests/pagination/reftest.list +++ b/layout/reftests/pagination/reftest.list @@ -1,3 +1,5 @@ +# For more pagination tests, see layout/reftests/w3c-css/submitted/css21/pagination/ +# and layout/reftests/w3c-css/submitted/multicol3/ # Pagination tests == abspos-breaking-000.xhtml abspos-breaking-000.ref.xhtml == abspos-breaking-001.xhtml abspos-breaking-000.ref.xhtml @@ -57,3 +59,4 @@ fails == float-continuations-000.html float-continuations-000.ref.html # == table-caption-splitaftercaption-9.html blank.html # bug 672654 # == table-caption-splitaftercaption-10.html blank.html # bug 672654 # == table-caption-splitaftercaption-11.html blank.html # bug 672654 +== column-balancing-break-inside-avoid-2.html column-balancing-break-inside-avoid-2-ref.html diff --git a/layout/reftests/table-overflow/reftest.list b/layout/reftests/table-overflow/reftest.list index eda806e8295..bb2a8a90fce 100644 --- a/layout/reftests/table-overflow/reftest.list +++ b/layout/reftests/table-overflow/reftest.list @@ -1,2 +1,3 @@ == bug785684-x.html bug785684-ref.html == bug785684-y.html bug785684-ref.html +== table-row-pagination.html table-row-pagination-ref.html diff --git a/layout/reftests/table-overflow/table-row-pagination-ref.html b/layout/reftests/table-overflow/table-row-pagination-ref.html new file mode 100644 index 00000000000..2dda93ce322 --- /dev/null +++ b/layout/reftests/table-overflow/table-row-pagination-ref.html @@ -0,0 +1,24 @@ + + + + Testing row split + + + + +
+

+

1

+
+ + + + diff --git a/layout/reftests/table-overflow/table-row-pagination.html b/layout/reftests/table-overflow/table-row-pagination.html new file mode 100644 index 00000000000..113806162da --- /dev/null +++ b/layout/reftests/table-overflow/table-row-pagination.html @@ -0,0 +1,24 @@ + + + + Testing row split + + + + + + + +
1
+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-1.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-1.html new file mode 100644 index 00000000000..027f9457e2d --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-1.html @@ -0,0 +1,20 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-10.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-10.html new file mode 100644 index 00000000000..e9d175bcd8d --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-10.html @@ -0,0 +1,19 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+

2

3

+ + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-11.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-11.html new file mode 100644 index 00000000000..39e92b13e6c --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-11.html @@ -0,0 +1,20 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-12.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-12.html new file mode 100644 index 00000000000..467ce1feb82 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-12.html @@ -0,0 +1,21 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +
+

1

+

2

3

+
+ + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-13.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-13.html new file mode 100644 index 00000000000..842642e0f0a --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-13.html @@ -0,0 +1,22 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +Text +
+

1

+

2

3

+
+ + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-2.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-2.html new file mode 100644 index 00000000000..0adf9e576d8 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-2.html @@ -0,0 +1,20 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-3.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-3.html new file mode 100644 index 00000000000..12fed33de02 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-3.html @@ -0,0 +1,20 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-4.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-4.html new file mode 100644 index 00000000000..472c8e15d54 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-4.html @@ -0,0 +1,20 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-5.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-5.html new file mode 100644 index 00000000000..9ab2a708924 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-5.html @@ -0,0 +1,20 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-6.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-6.html new file mode 100644 index 00000000000..2b445d96edb --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-6.html @@ -0,0 +1,20 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-7.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-7.html new file mode 100644 index 00000000000..ad9befd475d --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-7.html @@ -0,0 +1,21 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +
+

1

+

2

3

+
+ + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-8-ref.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-8-ref.html new file mode 100644 index 00000000000..b572a3b3aac --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-8-ref.html @@ -0,0 +1,22 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +Text +
+

1

+

2

3

+
+ + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-8.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-8.html new file mode 100644 index 00000000000..1c7f4340277 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-8.html @@ -0,0 +1,22 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +Text +
+

1

+

2

3

+
+ + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-9.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-9.html new file mode 100644 index 00000000000..3e9f3ecf4ee --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-9.html @@ -0,0 +1,21 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +
+

1

+

2

3

+
+ + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-ref.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-ref.html new file mode 100644 index 00000000000..8219ff0d470 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-block-page-break-inside-avoid-ref.html @@ -0,0 +1,20 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-1.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-1.html new file mode 100644 index 00000000000..175bd9211a1 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-1.html @@ -0,0 +1,20 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-2-ref.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-2-ref.html new file mode 100644 index 00000000000..b3ebbd48263 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-2-ref.html @@ -0,0 +1,21 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+

2

3

+

4

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-2.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-2.html new file mode 100644 index 00000000000..ca71056c679 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-2.html @@ -0,0 +1,20 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+

2

3

4

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-3.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-3.html new file mode 100644 index 00000000000..21696e3ba03 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-3.html @@ -0,0 +1,20 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-4.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-4.html new file mode 100644 index 00000000000..f910f419103 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-4.html @@ -0,0 +1,20 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-5-ref.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-5-ref.html new file mode 100644 index 00000000000..b76551d3c47 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-5-ref.html @@ -0,0 +1,34 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +
+
+

1

2

3

+

4

5

6

+
+
+

1

2

3

+

4

5

6

+
+
+

1

2

3

+

4

5

6

+
+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-5.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-5.html new file mode 100644 index 00000000000..35d54d955bf --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-5.html @@ -0,0 +1,34 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +
+
+

1

2

3

+

4

5

6

+
+
+

1

2

3

+

4

5

6

+
+
+

1

2

3

+

4

5

6

+
+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-6-ref.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-6-ref.html new file mode 100644 index 00000000000..81dd069c164 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-6-ref.html @@ -0,0 +1,18 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + +

1

2

+ diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-6.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-6.html new file mode 100644 index 00000000000..4b7d6b9df25 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-6.html @@ -0,0 +1,18 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + +

1

2

+ diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-7-ref.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-7-ref.html new file mode 100644 index 00000000000..5bedf75f1d1 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-7-ref.html @@ -0,0 +1,26 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + +
+
1
X +
2
+ + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-7.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-7.html new file mode 100644 index 00000000000..5f45d4a8ec5 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-7.html @@ -0,0 +1,27 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + +
+
1
+
2
X + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-8-ref.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-8-ref.html new file mode 100644 index 00000000000..7d85ee32c30 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-8-ref.html @@ -0,0 +1,27 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + +
+
1
+
X
Y
+
2
+ + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-8.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-8.html new file mode 100644 index 00000000000..36a6dfbf405 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-8.html @@ -0,0 +1,27 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + +
+
1
+
2
X
Y
+ + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-9-ref.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-9-ref.html new file mode 100644 index 00000000000..36404aed38a --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-9-ref.html @@ -0,0 +1,31 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + +
+
1
+
A
2
X
Y
+ + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-9.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-9.html new file mode 100644 index 00000000000..3f91860aa2c --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-9.html @@ -0,0 +1,32 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + +
+
1
+
A
2
X
Y
+ + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-inline-page-break-inside-avoid-1-ref.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-inline-page-break-inside-avoid-1-ref.html new file mode 100644 index 00000000000..8c5474bc083 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-inline-page-break-inside-avoid-1-ref.html @@ -0,0 +1,20 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-inline-page-break-inside-avoid-1.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-inline-page-break-inside-avoid-1.html new file mode 100644 index 00000000000..95dcdfb98c0 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-inline-page-break-inside-avoid-1.html @@ -0,0 +1,20 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-row-page-break-inside-avoid-1.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-row-page-break-inside-avoid-1.html new file mode 100644 index 00000000000..d308ad1b701 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-row-page-break-inside-avoid-1.html @@ -0,0 +1,22 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + + + + +

1

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-row-page-break-inside-avoid-2.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-row-page-break-inside-avoid-2.html new file mode 100644 index 00000000000..7e49b5074e9 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-row-page-break-inside-avoid-2.html @@ -0,0 +1,23 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + + + + + +

1

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-1.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-1.html new file mode 100644 index 00000000000..aa2dcd49142 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-1.html @@ -0,0 +1,20 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-2.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-2.html new file mode 100644 index 00000000000..de2e1aa2189 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-2.html @@ -0,0 +1,20 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-3.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-3.html new file mode 100644 index 00000000000..e766136a430 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-3.html @@ -0,0 +1,20 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-4-ref.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-4-ref.html new file mode 100644 index 00000000000..eeb7c46008a --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-4-ref.html @@ -0,0 +1,23 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + + + + + +

3

1

2

2

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-4.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-4.html new file mode 100644 index 00000000000..c8d6c834277 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-4.html @@ -0,0 +1,23 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + + + + + +

3

1

2

2

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-5-ref.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-5-ref.html new file mode 100644 index 00000000000..b4128b5eaf3 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-5-ref.html @@ -0,0 +1,22 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + + + + +

1

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-5.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-5.html new file mode 100644 index 00000000000..dd828489f8b --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-5.html @@ -0,0 +1,22 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + + + + +

1

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-6.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-6.html new file mode 100644 index 00000000000..c5ab2322ed4 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-6.html @@ -0,0 +1,23 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + + + + +

1

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-7-ref.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-7-ref.html new file mode 100644 index 00000000000..a6849111793 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-7-ref.html @@ -0,0 +1,25 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +1 + + + + + +

2

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-7.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-7.html new file mode 100644 index 00000000000..c638c8745be --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-7.html @@ -0,0 +1,25 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +1 + + + + + +

2

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-8-ref.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-8-ref.html new file mode 100644 index 00000000000..b321d520d50 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-8-ref.html @@ -0,0 +1,26 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +1 + + + + + +

1

2

2

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-8.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-8.html new file mode 100644 index 00000000000..d0b048a08a8 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-rowgroup-page-break-inside-avoid-8.html @@ -0,0 +1,26 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +1 + + + + + +

1

2

2

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-1.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-1.html new file mode 100644 index 00000000000..7d98c2e7051 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-1.html @@ -0,0 +1,20 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-2-ref.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-2-ref.html new file mode 100644 index 00000000000..0a07d2e56aa --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-2-ref.html @@ -0,0 +1,28 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + + + + + +

1

+
+ + + + + +

2

3

+ + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-2.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-2.html new file mode 100644 index 00000000000..16c9c597893 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-2.html @@ -0,0 +1,28 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + + + + + +

1

+
+ + + + + +

2

3

+ + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-3-ref.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-3-ref.html new file mode 100644 index 00000000000..403231b9403 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-3-ref.html @@ -0,0 +1,29 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + + + + + +

1

+
+ + + + + +

2

3

4

+ + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-3.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-3.html new file mode 100644 index 00000000000..4eee96834da --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-3.html @@ -0,0 +1,29 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + + + + + +

1

+
+ + + + + +

2

3

4

+ + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-4-ref.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-4-ref.html new file mode 100644 index 00000000000..ba4461a75a7 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-4-ref.html @@ -0,0 +1,20 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+text

2

3

4

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-4.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-4.html new file mode 100644 index 00000000000..0ca1868877c --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-4.html @@ -0,0 +1,21 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+text

2

3

4

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-5-ref.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-5-ref.html new file mode 100644 index 00000000000..36bcd6c26e0 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-5-ref.html @@ -0,0 +1,24 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+ + + + +
I have page-break-after: always
I have page-break-after: always
I have page-break-after: always
+ + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-5.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-5.html new file mode 100644 index 00000000000..5cdf19a94a8 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-5.html @@ -0,0 +1,24 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+ + + + +
I have page-break-after: always
I have page-break-after: always
I have page-break-after: always
+ + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-ref.html b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-ref.html new file mode 100644 index 00000000000..3d48cf78727 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-table-page-break-inside-avoid-ref.html @@ -0,0 +1,20 @@ + + + + CSS Test: CSS 2.1 page-break-inside:avoid + + + + + + +

1

+

2

3

+ + + + diff --git a/layout/reftests/w3c-css/submitted/css21/pagination/reftest.list b/layout/reftests/w3c-css/submitted/css21/pagination/reftest.list new file mode 100644 index 00000000000..e8ebca0109a --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/pagination/reftest.list @@ -0,0 +1,38 @@ +== moz-css21-block-page-break-inside-avoid-1.html moz-css21-block-page-break-inside-avoid-ref.html +== moz-css21-block-page-break-inside-avoid-2.html moz-css21-block-page-break-inside-avoid-ref.html +== moz-css21-block-page-break-inside-avoid-3.html moz-css21-block-page-break-inside-avoid-ref.html +== moz-css21-block-page-break-inside-avoid-4.html moz-css21-block-page-break-inside-avoid-ref.html +== moz-css21-block-page-break-inside-avoid-5.html moz-css21-block-page-break-inside-avoid-ref.html +== moz-css21-block-page-break-inside-avoid-6.html moz-css21-block-page-break-inside-avoid-ref.html +== moz-css21-block-page-break-inside-avoid-7.html moz-css21-block-page-break-inside-avoid-ref.html +== moz-css21-block-page-break-inside-avoid-8.html moz-css21-block-page-break-inside-avoid-8-ref.html +== moz-css21-block-page-break-inside-avoid-9.html moz-css21-block-page-break-inside-avoid-ref.html +== moz-css21-block-page-break-inside-avoid-10.html moz-css21-block-page-break-inside-avoid-ref.html +== moz-css21-block-page-break-inside-avoid-11.html moz-css21-block-page-break-inside-avoid-ref.html +== moz-css21-block-page-break-inside-avoid-12.html moz-css21-block-page-break-inside-avoid-ref.html +== moz-css21-block-page-break-inside-avoid-13.html moz-css21-block-page-break-inside-avoid-8-ref.html +== moz-css21-table-page-break-inside-avoid-1.html moz-css21-table-page-break-inside-avoid-ref.html +== moz-css21-table-page-break-inside-avoid-2.html moz-css21-table-page-break-inside-avoid-2-ref.html +== moz-css21-table-page-break-inside-avoid-3.html moz-css21-table-page-break-inside-avoid-3-ref.html +== moz-css21-table-page-break-inside-avoid-4.html moz-css21-table-page-break-inside-avoid-4-ref.html +== moz-css21-table-page-break-inside-avoid-5.html moz-css21-table-page-break-inside-avoid-5-ref.html +== moz-css21-float-page-break-inside-avoid-1.html moz-css21-table-page-break-inside-avoid-ref.html +== moz-css21-float-page-break-inside-avoid-2.html moz-css21-float-page-break-inside-avoid-2-ref.html +== moz-css21-float-page-break-inside-avoid-3.html moz-css21-block-page-break-inside-avoid-ref.html +== moz-css21-float-page-break-inside-avoid-4.html moz-css21-block-page-break-inside-avoid-ref.html +== moz-css21-float-page-break-inside-avoid-5.html moz-css21-float-page-break-inside-avoid-5-ref.html +== moz-css21-float-page-break-inside-avoid-6.html moz-css21-float-page-break-inside-avoid-6-ref.html +== moz-css21-float-page-break-inside-avoid-7.html moz-css21-float-page-break-inside-avoid-7-ref.html +== moz-css21-float-page-break-inside-avoid-8.html moz-css21-float-page-break-inside-avoid-8-ref.html +== moz-css21-float-page-break-inside-avoid-9.html moz-css21-float-page-break-inside-avoid-9-ref.html +== moz-css21-rowgroup-page-break-inside-avoid-1.html moz-css21-table-page-break-inside-avoid-ref.html +== moz-css21-rowgroup-page-break-inside-avoid-2.html moz-css21-table-page-break-inside-avoid-ref.html +== moz-css21-rowgroup-page-break-inside-avoid-3.html moz-css21-table-page-break-inside-avoid-ref.html +== moz-css21-rowgroup-page-break-inside-avoid-4.html moz-css21-rowgroup-page-break-inside-avoid-4-ref.html +== moz-css21-rowgroup-page-break-inside-avoid-5.html moz-css21-rowgroup-page-break-inside-avoid-5-ref.html +== moz-css21-rowgroup-page-break-inside-avoid-6.html moz-css21-rowgroup-page-break-inside-avoid-5-ref.html +== moz-css21-rowgroup-page-break-inside-avoid-7.html moz-css21-rowgroup-page-break-inside-avoid-7-ref.html +== moz-css21-rowgroup-page-break-inside-avoid-8.html moz-css21-rowgroup-page-break-inside-avoid-8-ref.html +== moz-css21-row-page-break-inside-avoid-1.html moz-css21-rowgroup-page-break-inside-avoid-5-ref.html +== moz-css21-row-page-break-inside-avoid-2.html moz-css21-rowgroup-page-break-inside-avoid-5-ref.html +== moz-css21-inline-page-break-inside-avoid-1.html moz-css21-inline-page-break-inside-avoid-1-ref.html diff --git a/layout/reftests/w3c-css/submitted/css21/reftest.list b/layout/reftests/w3c-css/submitted/css21/reftest.list new file mode 100644 index 00000000000..75885460ca3 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/css21/reftest.list @@ -0,0 +1 @@ +include pagination/reftest.list diff --git a/layout/reftests/w3c-css/submitted/multicol3/moz-multicol3-column-balancing-break-inside-avoid-1-ref.html b/layout/reftests/w3c-css/submitted/multicol3/moz-multicol3-column-balancing-break-inside-avoid-1-ref.html new file mode 100644 index 00000000000..6fc6f279591 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/multicol3/moz-multicol3-column-balancing-break-inside-avoid-1-ref.html @@ -0,0 +1,48 @@ + + + CSS Test: Balancing Overflow, page-break-inside:avoid + + + + + + + + +
+

one
    

+

two three

+

four five

+
+ +
+

one two three four five

+
+ +
+one two three four five +
+ +
+

one two three four five

+
+ + + diff --git a/layout/reftests/w3c-css/submitted/multicol3/moz-multicol3-column-balancing-break-inside-avoid-1.html b/layout/reftests/w3c-css/submitted/multicol3/moz-multicol3-column-balancing-break-inside-avoid-1.html new file mode 100644 index 00000000000..7e990280a89 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/multicol3/moz-multicol3-column-balancing-break-inside-avoid-1.html @@ -0,0 +1,49 @@ + + + CSS Test: Balancing Overflow, page-break-inside:avoid + + + + + + + + +
+

one

+

two three

+

four five

+
+ +
+

one two three four five

+
+ +
+

one two

+

three four five

+
+ +
+

one two three four five

+
+ + + diff --git a/layout/reftests/w3c-css/submitted/multicol3/reftest.list b/layout/reftests/w3c-css/submitted/multicol3/reftest.list new file mode 100644 index 00000000000..cbbfb418e34 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/multicol3/reftest.list @@ -0,0 +1 @@ +== moz-multicol3-column-balancing-break-inside-avoid-1.html moz-multicol3-column-balancing-break-inside-avoid-1-ref.html diff --git a/layout/reftests/w3c-css/submitted/reftest.list b/layout/reftests/w3c-css/submitted/reftest.list index 3bd7316ce7a..d37319d4da7 100644 --- a/layout/reftests/w3c-css/submitted/reftest.list +++ b/layout/reftests/w3c-css/submitted/reftest.list @@ -8,7 +8,7 @@ ## CSS Snapshot 2007 # CSS2.1 -# include css2.1/reftest.list +include css21/reftest.list # Animations # include animations/reftest.list @@ -28,8 +28,8 @@ skip-if(!prefs.getBoolPref("layout.css.supports-rule.enabled")) include conditio # Media Queries Level 3 # include mediaqueries3/reftest.list -# Multi-column Layout -# include multicol/reftest.list +# Multi-column Layout 3 +include multicol3/reftest.list # Selectors Level 3 # include selectors3/reftest.list diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index fb38ccf04f8..a13bc2bc099 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -2797,10 +2797,9 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState, // If this isn't the first row group, and the previous row group has a // nonzero YMost, then we can't be at the top of the page. - // We ignore the head row group in this check, because a head row group - // may be automatically added at the top of *every* page. This prevents + // We ignore a repeated head row group in this check to avoid causing // infinite loops in some circumstances - see bug 344883. - if (childX > (thead ? 1 : 0) && + if (childX > ((thead && IsRepeatedFrame(thead)) ? 1 : 0) && (rowGroups[childX - 1]->GetRect().YMost() > 0)) { kidReflowState.mFlags.mIsTopOfPage = false; } @@ -2827,11 +2826,22 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState, childX = rowGroups.Length(); } } + if (isPaginated && !NS_FRAME_IS_FULLY_COMPLETE(aStatus) && + ShouldAvoidBreakInside(aReflowState.reflowState)) { + aStatus = NS_INLINE_LINE_BREAK_BEFORE(); + break; + } // see if the rowgroup did not fit on this page might be pushed on // the next page - if (NS_FRAME_IS_COMPLETE(aStatus) && isPaginated && - (NS_UNCONSTRAINEDSIZE != kidReflowState.availableHeight) && - kidReflowState.availableHeight < desiredSize.height) { + if (isPaginated && + (NS_INLINE_IS_BREAK_BEFORE(aStatus) || + (NS_FRAME_IS_COMPLETE(aStatus) && + (NS_UNCONSTRAINEDSIZE != kidReflowState.availableHeight) && + kidReflowState.availableHeight < desiredSize.height))) { + if (ShouldAvoidBreakInside(aReflowState.reflowState)) { + aStatus = NS_INLINE_LINE_BREAK_BEFORE(); + break; + } // if we are on top of the page place with dataloss if (kidReflowState.mFlags.mIsTopOfPage) { if (childX+1 < rowGroups.Length()) { diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp index d1a1fda46c0..4a0b3a84ddd 100644 --- a/layout/tables/nsTableRowFrame.cpp +++ b/layout/tables/nsTableRowFrame.cpp @@ -1020,6 +1020,11 @@ nsTableRowFrame::Reflow(nsPresContext* aPresContext, rv = ReflowChildren(aPresContext, aDesiredSize, aReflowState, *tableFrame, aStatus); + if (aPresContext->IsPaginated() && !NS_FRAME_IS_FULLY_COMPLETE(aStatus) && + ShouldAvoidBreakInside(aReflowState)) { + aStatus = NS_INLINE_LINE_BREAK_BEFORE(); + } + // just set our width to what was available. The table will calculate the width and not use our value. aDesiredSize.width = aReflowState.availableWidth; diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 3c73166c365..ac0780b7a57 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -1017,7 +1017,8 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, nsTableFrame* aTableFrame, - nsReflowStatus& aStatus) + nsReflowStatus& aStatus, + bool aRowForcedPageBreak) { NS_PRECONDITION(aPresContext->IsPaginated(), "SplitRowGroup currently supports only paged media"); @@ -1080,6 +1081,12 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, rowFrame->DidReflow(aPresContext, nullptr, NS_FRAME_REFLOW_FINISHED); rowFrame->DidResize(); + if (!aRowForcedPageBreak && !NS_FRAME_IS_FULLY_COMPLETE(aStatus) && + ShouldAvoidBreakInside(aReflowState)) { + aStatus = NS_INLINE_LINE_BREAK_BEFORE(); + break; + } + nsTableFrame::InvalidateTableFrame(rowFrame, oldRowRect, oldRowVisualOverflow, false); @@ -1110,7 +1117,8 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, // style than its content, or (3) it contains a rowspan >1 cell which hasn't been // reflowed with a constrained height yet (we will find out when SplitSpanningCells is // called below) - if (rowMetrics.height > availSize.height) { + if (rowMetrics.height > availSize.height || + (NS_INLINE_IS_BREAK_BEFORE(aStatus) && !aRowForcedPageBreak)) { // cases (1) and (2) if (isTopOfPage) { // We're on top of the page, so keep the row on this page. There will be data loss. @@ -1140,6 +1148,10 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, nscoord spanningRowBottom = availHeight; if (!rowIsOnPage) { NS_ASSERTION(!contRow, "We should not have created a continuation if none of this row fits"); + if (!aRowForcedPageBreak && ShouldAvoidBreakInside(aReflowState)) { + aStatus = NS_INLINE_LINE_BREAK_BEFORE(); + break; + } if (prevRowFrame) { spanningRowBottom = prevRowFrame->GetRect().YMost(); lastRowThisPage = prevRowFrame; @@ -1292,15 +1304,17 @@ nsTableRowGroupFrame::Reflow(nsPresContext* aPresContext, bool specialReflow = (bool)aReflowState.mFlags.mSpecialHeightReflow; ((nsHTMLReflowState::ReflowStateFlags&)aReflowState.mFlags).mSpecialHeightReflow = false; - SplitRowGroup(aPresContext, aDesiredSize, aReflowState, tableFrame, aStatus); + SplitRowGroup(aPresContext, aDesiredSize, aReflowState, tableFrame, aStatus, + splitDueToPageBreak); ((nsHTMLReflowState::ReflowStateFlags&)aReflowState.mFlags).mSpecialHeightReflow = specialReflow; } - // If we have a next-in-flow, then we're not complete - // XXXldb This used to be done only for the incremental reflow codepath. - if (GetNextInFlow()) { - aStatus = NS_FRAME_NOT_COMPLETE; + // XXXmats The following is just bogus. We leave it here for now because + // ReflowChildren should pull up rows from our next-in-flow before returning + // a Complete status, but doesn't (bug 804888). + if (GetNextInFlow() && GetNextInFlow()->GetFirstPrincipalChild()) { + NS_FRAME_SET_INCOMPLETE(aStatus); } SetHasStyleHeight((NS_UNCONSTRAINEDSIZE != aReflowState.ComputedHeight()) && diff --git a/layout/tables/nsTableRowGroupFrame.h b/layout/tables/nsTableRowGroupFrame.h index 2846120bb04..020052b13b0 100644 --- a/layout/tables/nsTableRowGroupFrame.h +++ b/layout/tables/nsTableRowGroupFrame.h @@ -373,7 +373,8 @@ protected: nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, nsTableFrame* aTableFrame, - nsReflowStatus& aStatus); + nsReflowStatus& aStatus, + bool aRowForcedPageBreak); void SplitSpanningCells(nsPresContext& aPresContext, const nsHTMLReflowState& aReflowState, From cfa16446bfda1c8f1503ed29aa304cc41af13b1a Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Thu, 8 Nov 2012 17:09:38 +0100 Subject: [PATCH 32/39] Bug 798867 - Use the content offset that GetFrameForNodeOffset returns. r=roc --- layout/generic/nsFrame.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 07cb77a5bdd..4c33545f07d 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -2876,11 +2876,10 @@ nsFrame::SelectByTypeAtPoint(nsPresContext* aPresContext, if (!offsets.content) return NS_ERROR_FAILURE; - nsIFrame* theFrame; int32_t offset; const nsFrameSelection* frameSelection = PresContext()->GetPresShell()->ConstFrameSelection(); - theFrame = frameSelection-> + nsIFrame* theFrame = frameSelection-> GetFrameForNodeOffset(offsets.content, offsets.offset, nsFrameSelection::HINT(offsets.associateWithNext), &offset); @@ -2888,8 +2887,8 @@ nsFrame::SelectByTypeAtPoint(nsPresContext* aPresContext, return NS_ERROR_FAILURE; nsFrame* frame = static_cast(theFrame); - return frame->PeekBackwardAndForward(aBeginAmountType, aEndAmountType, - offsets.offset, aPresContext, + return frame->PeekBackwardAndForward(aBeginAmountType, aEndAmountType, + offset, aPresContext, aBeginAmountType != eSelectWord, aSelectFlags); } From 5311e975996341971306b8b4d55bf61d8f33d6f7 Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Thu, 8 Nov 2012 11:13:23 -0500 Subject: [PATCH 33/39] Bug 794752 - Downloads toolbar button changes size the first time it is clicked. r=mak. --- .../downloads/content/indicatorOverlay.xul | 9 ++++-- .../chrome/browser/downloads/downloads.dtd | 5 --- .../gnomestripe/downloads/downloads.css | 32 ++++++++++++++----- .../themes/pinstripe/downloads/downloads.css | 4 --- .../themes/winstripe/downloads/downloads.css | 8 ++--- 5 files changed, 33 insertions(+), 25 deletions(-) diff --git a/browser/components/downloads/content/indicatorOverlay.xul b/browser/components/downloads/content/indicatorOverlay.xul index bb62229e7f9..05defb37fde 100644 --- a/browser/components/downloads/content/indicatorOverlay.xul +++ b/browser/components/downloads/content/indicatorOverlay.xul @@ -9,7 +9,12 @@ - + + %browserDTD; + + %downloadsDTD; +]> - - - diff --git a/browser/themes/gnomestripe/downloads/downloads.css b/browser/themes/gnomestripe/downloads/downloads.css index c7d61a20ddc..22f3c920ae0 100644 --- a/browser/themes/gnomestripe/downloads/downloads.css +++ b/browser/themes/gnomestripe/downloads/downloads.css @@ -160,37 +160,53 @@ richlistitem[type="download"][state="1"]:hover > .downloadButton.downloadShow:ac /*** Status and progress indicator ***/ -#downloads-indicator { - width: 35px; -} - #downloads-indicator-anchor { - min-width: 18px; - min-height: 18px; /* Makes the outermost stack element positioned, so that its contents are rendered over the main browser window in the Z order. This is required by the animated event notification. */ position: relative; } +toolbar[iconsize="small"] #downloads-indicator-anchor { + min-width: 16px; + min-height: 16px; +} + +toolbar[iconsize="large"] #downloads-indicator-anchor { + min-width: 24px; + min-height: 24px; +} + /*** Main indicator icon ***/ -#downloads-indicator-icon { +toolbar[iconsize="small"] #downloads-indicator-icon { background: -moz-image-rect(url("chrome://browser/skin/Toolbar-small.png"), 0, 16, 16, 0) center no-repeat; } +toolbar[iconsize="large"] #downloads-indicator-icon { + background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"), + 0, 24, 24, 0) center no-repeat; +} + #downloads-indicator[attention] > #downloads-indicator-anchor > #downloads-indicator-icon { background: -moz-image-rect(url("chrome://browser/skin/downloads/download-glow.png"), 16, 32, 32, 16) center no-repeat; } -#downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter { +toolbar[iconsize="small"] #downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter { background: -moz-image-rect(url("chrome://browser/skin/Toolbar-small.png"), 0, 16, 16, 0) center no-repeat; background-size: 12px; } +toolbar[iconsize="large"] #downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter { + background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"), + 0, 24, 24, 0) center no-repeat; + background-size: 24px; +} + + #downloads-indicator:not([counter])[attention] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter { background-image: -moz-image-rect(url("chrome://browser/skin/downloads/download-glow.png"), 16, 32, 32, 16); diff --git a/browser/themes/pinstripe/downloads/downloads.css b/browser/themes/pinstripe/downloads/downloads.css index e506857def3..4e5b0d5d1a7 100644 --- a/browser/themes/pinstripe/downloads/downloads.css +++ b/browser/themes/pinstripe/downloads/downloads.css @@ -157,10 +157,6 @@ richlistitem[type="download"][state="1"]:hover > .downloadButton.downloadShow:ac /*** Status and progress indicator ***/ -#downloads-indicator { - width: 35px; -} - #downloads-indicator-anchor { min-width: 20px; min-height: 20px; diff --git a/browser/themes/winstripe/downloads/downloads.css b/browser/themes/winstripe/downloads/downloads.css index c909b914dd5..0e17f10e277 100644 --- a/browser/themes/winstripe/downloads/downloads.css +++ b/browser/themes/winstripe/downloads/downloads.css @@ -159,13 +159,7 @@ richlistitem[type="download"][state="1"]:hover > .downloadButton.downloadShow:ac /*** Status and progress indicator ***/ -#downloads-indicator { - width: 35px; -} - #downloads-indicator-anchor { - min-width: 18px; - min-height: 18px; /* Makes the outermost stack element positioned, so that its contents are rendered over the main browser window in the Z order. This is required by the animated event notification. */ @@ -177,6 +171,8 @@ richlistitem[type="download"][state="1"]:hover > .downloadButton.downloadShow:ac #downloads-indicator-icon { background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"), 0, 108, 18, 90) center no-repeat; + min-width: 18px; + min-height: 18px; } #downloads-indicator-icon:-moz-lwtheme-brighttext { From b34e1892f67922685f3d4154fc982bf8a558d3d6 Mon Sep 17 00:00:00 2001 From: Marty Rosenberg Date: Thu, 8 Nov 2012 11:14:24 -0500 Subject: [PATCH 34/39] Don't attempt to verify that the stack will be aligned, because it may not be. (bug 807156, r=djvj) --- js/src/ion/IonCaches.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/js/src/ion/IonCaches.cpp b/js/src/ion/IonCaches.cpp index f56ba9b21bf..bb459fa4783 100644 --- a/js/src/ion/IonCaches.cpp +++ b/js/src/ion/IonCaches.cpp @@ -471,7 +471,6 @@ struct GetNativePropertyStub // TODO: ensure stack is aligned? DebugOnly initialStack = masm.framePushed(); - masm.checkStackAlignment(); Label success, exception; From b242cbda2f0fddb46597e4320c3b77f7cbd7e908 Mon Sep 17 00:00:00 2001 From: Marty Rosenberg Date: Thu, 8 Nov 2012 11:14:27 -0500 Subject: [PATCH 35/39] Ensure that we are using the same IonCompartment throughout the lifetime of an AFC(bug 792873, r=jandem) --- js/src/ion/Ion.cpp | 8 +++----- js/src/ion/IonSpewer.cpp | 2 ++ js/src/ion/arm/Trampoline-arm.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/js/src/ion/Ion.cpp b/js/src/ion/Ion.cpp index abc74f28eea..e846c25c810 100644 --- a/js/src/ion/Ion.cpp +++ b/js/src/ion/Ion.cpp @@ -1701,9 +1701,9 @@ ion::InvalidateAll(FreeOp *fop, JSCompartment *c) CancelOffThreadIonCompile(c, NULL); FinishAllOffThreadCompilations(c->ionCompartment()); - for (IonActivationIterator iter(fop->runtime()); iter.more(); ++iter) { if (iter.activation()->compartment() == c) { + IonContext ictx(NULL, c, NULL); AutoFlushCache afc ("InvalidateAll", c->ionCompartment()); IonSpew(IonSpew_Invalidate, "Invalidating all frames for GC"); InvalidateActivation(fop, iter.top(), true); @@ -1875,10 +1875,8 @@ AutoFlushCache::AutoFlushCache(const char *nonce, IonCompartment *comp) name_(nonce), used_(false) { - if (comp == NULL) { - if (CurrentIonContext() != NULL) - comp = GetIonContext()->compartment->ionCompartment(); - } + if (CurrentIonContext() != NULL) + comp = GetIonContext()->compartment->ionCompartment(); // If a compartment isn't available, then be a nop, nobody will ever see this flusher if (comp) { if (comp->flusher()) diff --git a/js/src/ion/IonSpewer.cpp b/js/src/ion/IonSpewer.cpp index 31d23e42b66..3a27a2905b0 100644 --- a/js/src/ion/IonSpewer.cpp +++ b/js/src/ion/IonSpewer.cpp @@ -230,6 +230,8 @@ ion::CheckLogging() EnableChannel(IonSpew_Safepoints); if (ContainsFlag(env, "pools")) EnableChannel(IonSpew_Pools); + if (ContainsFlag(env, "cacheflush")) + EnableChannel(IonSpew_CacheFlush); if (ContainsFlag(env, "logs")) EnableIonDebugLogging(); if (ContainsFlag(env, "all")) diff --git a/js/src/ion/arm/Trampoline-arm.cpp b/js/src/ion/arm/Trampoline-arm.cpp index 8288f6ddf5e..86edf179ce1 100644 --- a/js/src/ion/arm/Trampoline-arm.cpp +++ b/js/src/ion/arm/Trampoline-arm.cpp @@ -72,7 +72,6 @@ struct EnterJITStack IonCode * IonCompartment::generateEnterJIT(JSContext *cx) { - AutoFlushCache afc("GenerateEnterJIT", cx->compartment->ionCompartment()); const Register reg_code = r0; const Register reg_argc = r1; @@ -85,6 +84,7 @@ IonCompartment::generateEnterJIT(JSContext *cx) JS_ASSERT(OsrFrameReg == reg_frame); MacroAssembler masm(cx); + AutoFlushCache afc("GenerateEnterJIT", cx->compartment->ionCompartment()); Assembler *aasm = &masm; // Save non-volatile registers. These must be saved by the trampoline, From 2c0fa15194a2284a29e058d8132572b241efbff3 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Thu, 8 Nov 2012 08:26:49 -0800 Subject: [PATCH 36/39] Bug 809290 - Fix nsLocation::CheckURL. r=bz --- dom/base/nsLocation.cpp | 34 +++----------------- dom/tests/mochitest/bugs/test_bug593174.html | 11 +++++-- 2 files changed, 13 insertions(+), 32 deletions(-) diff --git a/dom/base/nsLocation.cpp b/dom/base/nsLocation.cpp index 23d19b3706e..de6871f0d0f 100644 --- a/dom/base/nsLocation.cpp +++ b/dom/base/nsLocation.cpp @@ -108,31 +108,6 @@ nsLocation::GetDocShell() return docshell; } -// Try to get the the document corresponding to the given JSScript. -static already_AddRefed -GetScriptDocument(JSContext *cx, JSScript *script) -{ - if (!cx || !script) - return nullptr; - - JSObject* scope = JS_GetGlobalFromScript(script); - if (!scope) - return nullptr; - - JSAutoCompartment ac(cx, scope); - - nsCOMPtr window = - do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(cx, scope)); - if (!window) - return nullptr; - - // If it's a window, get its document. - nsCOMPtr domDoc; - window->GetDocument(getter_AddRefs(domDoc)); - nsCOMPtr doc = do_QueryInterface(domDoc); - return doc.forget(); -} - nsresult nsLocation::CheckURL(nsIURI* aURI, nsIDocShellLoadInfo** aLoadInfo) { @@ -166,13 +141,12 @@ nsLocation::CheckURL(nsIURI* aURI, nsIDocShellLoadInfo** aLoadInfo) // current URI as the referrer. If they don't match, use the principal's // URI. - JSScript* script = nullptr; nsCOMPtr doc; nsCOMPtr docOriginalURI, docCurrentURI, principalURI; - // NB: A false return value from JS_DescribeScriptedCaller means no caller - // was found. It does not signal that an exception was thrown. - if (JS_DescribeScriptedCaller(cx, &script, nullptr)) { - doc = GetScriptDocument(cx, script); + nsCOMPtr entryPoint = + do_QueryInterface(nsJSUtils::GetDynamicScriptGlobal(cx)); + if (entryPoint) { + doc = entryPoint->GetDoc(); } if (doc) { docOriginalURI = doc->GetOriginalURI(); diff --git a/dom/tests/mochitest/bugs/test_bug593174.html b/dom/tests/mochitest/bugs/test_bug593174.html index c3241c588ee..e7386289b07 100644 --- a/dom/tests/mochitest/bugs/test_bug593174.html +++ b/dom/tests/mochitest/bugs/test_bug593174.html @@ -56,8 +56,15 @@ function iframeLoaded(identifier) { is(iframeCw.getInnerIframeReferrer(), iframeCw.location, 'inner iframe referrer'); // Now do the test again, this time with a popup. - popup = window.open('file_bug593174_1.html'); - popup.onload = iframeLoaded('popup/outer'); + // + // NB: in this situation, we're actually getting called in an event handler from + // the iframe, meaning that it serves as the script entry point. But that's a detail, + // and we want to pretend like this window is doing the call. So let's use setTimeout + // to forget about the iframe. + window.setTimeout(function() { + popup = window.open('file_bug593174_1.html'); + popup.onload = iframeLoaded('popup/outer'); + }, 0); } else if (loadCount == 4) { history.replaceState('', '', Math.random()); From 2b8c345ee200654f4f34e046a625dcf6cf72fa2a Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Thu, 8 Nov 2012 08:26:50 -0800 Subject: [PATCH 37/39] Bug 809290 - Tests. r=bz --- dom/tests/mochitest/bugs/Makefile.in | 5 ++ .../mochitest/bugs/file_bug809290_b1.html | 14 ++++++ .../mochitest/bugs/file_bug809290_b2.html | 14 ++++++ .../mochitest/bugs/file_bug809290_c.html | 10 ++++ dom/tests/mochitest/bugs/file_empty.html | 2 + dom/tests/mochitest/bugs/test_bug809290.html | 48 +++++++++++++++++++ 6 files changed, 93 insertions(+) create mode 100644 dom/tests/mochitest/bugs/file_bug809290_b1.html create mode 100644 dom/tests/mochitest/bugs/file_bug809290_b2.html create mode 100644 dom/tests/mochitest/bugs/file_bug809290_c.html create mode 100644 dom/tests/mochitest/bugs/file_empty.html create mode 100644 dom/tests/mochitest/bugs/test_bug809290.html diff --git a/dom/tests/mochitest/bugs/Makefile.in b/dom/tests/mochitest/bugs/Makefile.in index 570fcbcdd4b..57bcd60bf26 100644 --- a/dom/tests/mochitest/bugs/Makefile.in +++ b/dom/tests/mochitest/bugs/Makefile.in @@ -130,6 +130,11 @@ MOCHITEST_FILES = \ test_bug755320.html \ test_bug777628.html \ test_bug665548.html \ + test_bug809290.html \ + file_bug809290_b1.html \ + file_bug809290_b2.html \ + file_bug809290_c.html \ + file_empty.html \ $(NULL) ifneq (Linux,$(OS_ARCH)) diff --git a/dom/tests/mochitest/bugs/file_bug809290_b1.html b/dom/tests/mochitest/bugs/file_bug809290_b1.html new file mode 100644 index 00000000000..3a3863a61c7 --- /dev/null +++ b/dom/tests/mochitest/bugs/file_bug809290_b1.html @@ -0,0 +1,14 @@ + + + + + + + + + From 2b56bdcbe6004a1a50b4254bb00716b015499a14 Mon Sep 17 00:00:00 2001 From: Jim Chen Date: Thu, 8 Nov 2012 11:45:17 -0500 Subject: [PATCH 38/39] Bug 761287 - Fix NDKr8 build by including Android sigcontext instead of using our own; r=ehsan --- tools/profiler/android-signal-defs.h | 22 +++++++++++----------- tools/profiler/platform-linux.cc | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tools/profiler/android-signal-defs.h b/tools/profiler/android-signal-defs.h index e39482419d9..4cd1c2262eb 100644 --- a/tools/profiler/android-signal-defs.h +++ b/tools/profiler/android-signal-defs.h @@ -6,14 +6,16 @@ // Android runs a fairly new Linux kernel, so signal info is there, // but the C library doesn't have the structs defined. -struct sigcontext { - uint32_t trap_no; - uint32_t error_code; - uint32_t oldmask; - uint32_t gregs[16]; - uint32_t arm_cpsr; - uint32_t fault_address; -}; +// All NDK platform versions have asm/sigcontext.h for ARM +// Only NDK >= 6, platform >= 9 have asm/sigcontext.h for x86 +// Only NDK >= 8, platform >= 9 have asm/sigcontext.h for MIPS +#if defined(__arm__) || defined(__thumb__) || ANDROID_VERSION >= 9 +#include +#else +#error use newer NDK or newer platform version (e.g. --with-android-version=9) +#endif + +#ifndef __BIONIC_HAVE_UCONTEXT_T typedef uint32_t __sigset_t; typedef struct sigcontext mcontext_t; typedef struct ucontext { @@ -23,7 +25,5 @@ typedef struct ucontext { mcontext_t uc_mcontext; __sigset_t uc_sigmask; } ucontext_t; -enum ArmRegisters {R0 = 0, R1 = 1, R2 = 2, R3 = 3, R4 = 4, R5 = 5, - R6 = 6, R7 = 7, R8 = 8, R9 = 9, R10 = 10, - R11 = 11, R12 = 12, R13 = 13, R14 = 14, R15 = 15}; +#endif diff --git a/tools/profiler/platform-linux.cc b/tools/profiler/platform-linux.cc index 593340827bd..5e0919b869d 100644 --- a/tools/profiler/platform-linux.cc +++ b/tools/profiler/platform-linux.cc @@ -54,7 +54,7 @@ pid_t gettid() static Sampler* sActiveSampler = NULL; -#if !defined(__GLIBC__) && (defined(__arm__) || defined(__thumb__)) +#ifdef ANDROID #include "android-signal-defs.h" #endif @@ -93,7 +93,7 @@ static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) { sample->fp = reinterpret_cast
(mcontext.gregs[REG_RBP]); #elif V8_HOST_ARCH_ARM // An undefined macro evaluates to 0, so this applies to Android's Bionic also. -#if (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3)) +#if !defined(ANDROID) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3)) sample->pc = reinterpret_cast
(mcontext.gregs[R15]); sample->sp = reinterpret_cast
(mcontext.gregs[R13]); sample->fp = reinterpret_cast
(mcontext.gregs[R11]); From d88281eec3f82c4dc1b00233d1354fc79763ce1f Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Sat, 27 Oct 2012 12:35:42 -0400 Subject: [PATCH 39/39] Bug 806147 - fix reftests that use setTimeout but not reftest-wait to include reftest-wait; r=dholbert --- layout/reftests/bidi/496006-1.html | 3 ++- layout/reftests/counters/t1204-increment-00-c-o-test.html | 6 ++++-- layout/reftests/counters/t1204-increment-01-c-o-test.html | 6 ++++-- layout/reftests/counters/t1204-increment-02-c-o-test.html | 6 ++++-- layout/reftests/counters/t1204-reset-01-c-o-test.html | 6 ++++-- 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/layout/reftests/bidi/496006-1.html b/layout/reftests/bidi/496006-1.html index 57e75e74d2c..5629fa4ea58 100644 --- a/layout/reftests/bidi/496006-1.html +++ b/layout/reftests/bidi/496006-1.html @@ -1,4 +1,4 @@ - + @@ -13,6 +13,7 @@ var a=document.getElementById('a'); a.style.outline = '1px solid transparent'; document.body.offsetHeight; a.style.outline = ''; +document.documentElement.removeAttribute('class'); } setTimeout(doe, 500); diff --git a/layout/reftests/counters/t1204-increment-00-c-o-test.html b/layout/reftests/counters/t1204-increment-00-c-o-test.html index 01694e1946f..2483f5eab84 100644 --- a/layout/reftests/counters/t1204-increment-00-c-o-test.html +++ b/layout/reftests/counters/t1204-increment-00-c-o-test.html @@ -1,5 +1,5 @@ - + CSS 2.1 Test Suite: dynamic changes to 'counter-increment' @@ -21,11 +21,13 @@ s.setAttribute("class", "increment"); s.appendChild(document.createTextNode("new-")); t.insertBefore(s, t.childNodes.item(1)); + document.documentElement.removeAttribute('class'); } + document.addEventListener("MozReftestInvalidate", run, false); - +
diff --git a/layout/reftests/counters/t1204-increment-01-c-o-test.html b/layout/reftests/counters/t1204-increment-01-c-o-test.html index 1f8864c57e4..891b68fc191 100644 --- a/layout/reftests/counters/t1204-increment-01-c-o-test.html +++ b/layout/reftests/counters/t1204-increment-01-c-o-test.html @@ -1,5 +1,5 @@ - + CSS 2.1 Test Suite: dynamic changes to 'counter-increment' @@ -18,11 +18,13 @@ function run() { var t = document.getElementById("test"); t.removeChild(t.childNodes.item(1)); + document.documentElement.removeAttribute('class'); } + document.addEventListener("MozReftestInvalidate", run, false); - +
FAIL-
diff --git a/layout/reftests/counters/t1204-increment-02-c-o-test.html b/layout/reftests/counters/t1204-increment-02-c-o-test.html index 39e1123a756..a7e72034c37 100644 --- a/layout/reftests/counters/t1204-increment-02-c-o-test.html +++ b/layout/reftests/counters/t1204-increment-02-c-o-test.html @@ -1,5 +1,5 @@ - + CSS 2.1 Test Suite: dynamic changes to 'counter-increment' @@ -20,11 +20,13 @@ document.getElementById("one").removeAttribute("class"); document.getElementById("two").setAttribute("class", "increment"); document.getElementById("three").setAttribute("style", "counter-increment: c"); + document.documentElement.removeAttribute('class'); } + document.addEventListener("MozReftestInvalidate", run, false); - +
diff --git a/layout/reftests/counters/t1204-reset-01-c-o-test.html b/layout/reftests/counters/t1204-reset-01-c-o-test.html index 9c3a7ce82fc..ecd7d18eb8c 100644 --- a/layout/reftests/counters/t1204-reset-01-c-o-test.html +++ b/layout/reftests/counters/t1204-reset-01-c-o-test.html @@ -1,5 +1,5 @@ - + CSS 2.1 Test Suite: dynamic changes to 'counter-increment' @@ -18,11 +18,13 @@ function run() { var t = document.getElementById("test"); t.removeChild(t.childNodes.item(1)); + document.documentElement.removeAttribute('class'); } + document.addEventListener("MozReftestInvalidate", run, false); - +