From d6d77cb689a30e08cb358658c55b6f1471943c8b Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Tue, 20 Nov 2012 14:08:59 +0100 Subject: [PATCH 01/75] Bug 772830 - Add some regalloc asserts. r=dvander --- js/src/ion/LinearScan.cpp | 40 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/js/src/ion/LinearScan.cpp b/js/src/ion/LinearScan.cpp index 3b0fe12933d3..14b431536716 100644 --- a/js/src/ion/LinearScan.cpp +++ b/js/src/ion/LinearScan.cpp @@ -470,6 +470,29 @@ NextInstructionHasFixedUses(LBlock *block, LInstruction *ins) } return false; } + +// Returns true iff ins has a def/temp reusing the input allocation. +static bool +IsInputReused(LInstruction *ins, LUse *use) +{ + for (size_t i = 0; i < ins->numDefs(); i++) { + if (ins->getDef(i)->policy() == LDefinition::MUST_REUSE_INPUT && + ins->getOperand(ins->getDef(i)->getReusedInput())->toUse() == use) + { + return true; + } + } + + for (size_t i = 0; i < ins->numTemps(); i++) { + if (ins->getTemp(i)->policy() == LDefinition::MUST_REUSE_INPUT && + ins->getOperand(ins->getTemp(i)->getReusedInput())->toUse() == use) + { + return true; + } + } + + return false; +} #endif /* @@ -618,6 +641,9 @@ LinearScanAllocator::buildLivenessInfo() } } + DebugOnly hasUseRegister = false; + DebugOnly hasUseRegisterAtStart = false; + for (LInstruction::InputIterator alloc(**ins); alloc.more(); alloc.next()) { if (alloc->isUse()) { LUse *use = alloc->toUse(); @@ -637,6 +663,20 @@ LinearScanAllocator::buildLivenessInfo() for (size_t i = 0; i < ins->numTemps(); i++) JS_ASSERT(vregs[ins->getTemp(i)].isDouble() != vregs[use].isDouble()); } + + // If there are both useRegisterAtStart(x) and useRegister(y) + // uses, we may assign the same register to both operands due to + // interval splitting (bug 772830). Don't allow this for now. + if (use->policy() == LUse::REGISTER) { + if (use->usedAtStart()) { + if (!IsInputReused(*ins, use)) + hasUseRegisterAtStart = true; + } else { + hasUseRegister = true; + } + } + + JS_ASSERT(!(hasUseRegister && hasUseRegisterAtStart)); #endif CodePosition to; From 6164b4865fababb8db0935f6af0ceb330418ac58 Mon Sep 17 00:00:00 2001 From: Paul Adenot Date: Tue, 20 Nov 2012 14:36:29 +0100 Subject: [PATCH 02/75] Bug 810458 - Make mozRTCSessionDescriptor respect the spec. r=jesup --- dom/media/PeerConnection.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dom/media/PeerConnection.js b/dom/media/PeerConnection.js index 234be094b5c9..9789d2f903a5 100644 --- a/dom/media/PeerConnection.js +++ b/dom/media/PeerConnection.js @@ -144,13 +144,14 @@ SessionDescription.prototype = { Ci.nsIDOMRTCSessionDescription, Ci.nsIDOMGlobalObjectConstructor ]), - constructor: function(win, type, sdp) { + constructor: function(win, descriptionInitDict) { if (this._win) { throw new Error("Constructor already called"); } this._win = win; - this.type = type; - this.sdp = sdp; + if (descriptionInitDict === undefined) { + this.type = this.sdp = null; + } }, toString: function() { From eaaabd00eb69fbad773bdb0722752f366abf90a4 Mon Sep 17 00:00:00 2001 From: Paul Adenot Date: Tue, 20 Nov 2012 14:53:46 +0100 Subject: [PATCH 03/75] Backed out changeset d66d35f64802 because it is wrong. --- dom/media/PeerConnection.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dom/media/PeerConnection.js b/dom/media/PeerConnection.js index 9789d2f903a5..234be094b5c9 100644 --- a/dom/media/PeerConnection.js +++ b/dom/media/PeerConnection.js @@ -144,14 +144,13 @@ SessionDescription.prototype = { Ci.nsIDOMRTCSessionDescription, Ci.nsIDOMGlobalObjectConstructor ]), - constructor: function(win, descriptionInitDict) { + constructor: function(win, type, sdp) { if (this._win) { throw new Error("Constructor already called"); } this._win = win; - if (descriptionInitDict === undefined) { - this.type = this.sdp = null; - } + this.type = type; + this.sdp = sdp; }, toString: function() { From b3b82bec158aeb2f9191f4ec5347b369c5d21707 Mon Sep 17 00:00:00 2001 From: Alexander Surkov Date: Tue, 20 Nov 2012 23:15:32 +0900 Subject: [PATCH 04/75] Bug 812844 - densify nsAccDocManager, r=tbsaunde --HG-- rename : accessible/src/base/nsAccDocManager.cpp => accessible/src/base/DocManager.cpp rename : accessible/src/base/nsAccDocManager.h => accessible/src/base/DocManager.h --- .../{nsAccDocManager.cpp => DocManager.cpp} | 92 +++++++++---------- .../base/{nsAccDocManager.h => DocManager.h} | 29 +++--- accessible/src/base/Makefile.in | 4 +- .../src/base/nsAccessibilityService.cpp | 10 +- accessible/src/base/nsAccessibilityService.h | 8 +- accessible/src/generic/DocAccessible.cpp | 2 +- accessible/src/generic/DocAccessible.h | 4 +- accessible/src/generic/OuterDocAccessible.cpp | 6 +- 8 files changed, 77 insertions(+), 78 deletions(-) rename accessible/src/base/{nsAccDocManager.cpp => DocManager.cpp} (83%) rename accessible/src/base/{nsAccDocManager.h => DocManager.h} (87%) diff --git a/accessible/src/base/nsAccDocManager.cpp b/accessible/src/base/DocManager.cpp similarity index 83% rename from accessible/src/base/nsAccDocManager.cpp rename to accessible/src/base/DocManager.cpp index 0317bfdbe0fc..67bcaca2f5d7 100644 --- a/accessible/src/base/nsAccDocManager.cpp +++ b/accessible/src/base/DocManager.cpp @@ -3,7 +3,7 @@ * 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 "nsAccDocManager.h" +#include "DocManager.h" #include "Accessible-inl.h" #include "ApplicationAccessible.h" @@ -33,14 +33,14 @@ using namespace mozilla::a11y; //////////////////////////////////////////////////////////////////////////////// -// nsAccDocManager +// DocManager //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// -// nsAccDocManager public +// DocManager public DocAccessible* -nsAccDocManager::GetDocAccessible(nsIDocument *aDocument) +DocManager::GetDocAccessible(nsIDocument* aDocument) { if (!aDocument) return nullptr; @@ -56,7 +56,7 @@ nsAccDocManager::GetDocAccessible(nsIDocument *aDocument) } Accessible* -nsAccDocManager::FindAccessibleInCache(nsINode* aNode) const +DocManager::FindAccessibleInCache(nsINode* aNode) const { nsSearchAccessibleInCacheArg arg; arg.mNode = aNode; @@ -69,7 +69,7 @@ nsAccDocManager::FindAccessibleInCache(nsINode* aNode) const #ifdef DEBUG bool -nsAccDocManager::IsProcessingRefreshDriverNotification() const +DocManager::IsProcessingRefreshDriverNotification() const { bool isDocRefreshing = false; mDocAccessibleCache.EnumerateRead(SearchIfDocIsRefreshing, @@ -81,10 +81,10 @@ nsAccDocManager::IsProcessingRefreshDriverNotification() const //////////////////////////////////////////////////////////////////////////////// -// nsAccDocManager protected +// DocManager protected bool -nsAccDocManager::Init() +DocManager::Init() { mDocAccessibleCache.Init(4); @@ -101,7 +101,7 @@ nsAccDocManager::Init() } void -nsAccDocManager::Shutdown() +DocManager::Shutdown() { nsCOMPtr progress = do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID); @@ -115,7 +115,7 @@ nsAccDocManager::Shutdown() //////////////////////////////////////////////////////////////////////////////// // nsISupports -NS_IMPL_THREADSAFE_ISUPPORTS3(nsAccDocManager, +NS_IMPL_THREADSAFE_ISUPPORTS3(DocManager, nsIWebProgressListener, nsIDOMEventListener, nsISupportsWeakReference) @@ -124,9 +124,9 @@ NS_IMPL_THREADSAFE_ISUPPORTS3(nsAccDocManager, // nsIWebProgressListener NS_IMETHODIMP -nsAccDocManager::OnStateChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, uint32_t aStateFlags, - nsresult aStatus) +DocManager::OnStateChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, uint32_t aStateFlags, + nsresult aStatus) { NS_ASSERTION(aStateFlags & STATE_IS_DOCUMENT, "Other notifications excluded"); @@ -203,39 +203,39 @@ nsAccDocManager::OnStateChange(nsIWebProgress *aWebProgress, } NS_IMETHODIMP -nsAccDocManager::OnProgressChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, - int32_t aCurSelfProgress, - int32_t aMaxSelfProgress, - int32_t aCurTotalProgress, - int32_t aMaxTotalProgress) +DocManager::OnProgressChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + int32_t aCurSelfProgress, + int32_t aMaxSelfProgress, + int32_t aCurTotalProgress, + int32_t aMaxTotalProgress) { NS_NOTREACHED("notification excluded in AddProgressListener(...)"); return NS_OK; } NS_IMETHODIMP -nsAccDocManager::OnLocationChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, nsIURI *aLocation, - uint32_t aFlags) +DocManager::OnLocationChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, nsIURI* aLocation, + uint32_t aFlags) { NS_NOTREACHED("notification excluded in AddProgressListener(...)"); return NS_OK; } NS_IMETHODIMP -nsAccDocManager::OnStatusChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, nsresult aStatus, - const PRUnichar *aMessage) +DocManager::OnStatusChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, nsresult aStatus, + const PRUnichar* aMessage) { NS_NOTREACHED("notification excluded in AddProgressListener(...)"); return NS_OK; } NS_IMETHODIMP -nsAccDocManager::OnSecurityChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, - uint32_t aState) +DocManager::OnSecurityChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + uint32_t aState) { NS_NOTREACHED("notification excluded in AddProgressListener(...)"); return NS_OK; @@ -245,7 +245,7 @@ nsAccDocManager::OnSecurityChange(nsIWebProgress *aWebProgress, // nsIDOMEventListener NS_IMETHODIMP -nsAccDocManager::HandleEvent(nsIDOMEvent *aEvent) +DocManager::HandleEvent(nsIDOMEvent* aEvent) { nsAutoString type; aEvent->GetType(type); @@ -303,11 +303,11 @@ nsAccDocManager::HandleEvent(nsIDOMEvent *aEvent) } //////////////////////////////////////////////////////////////////////////////// -// nsAccDocManager private +// DocManager private void -nsAccDocManager::HandleDOMDocumentLoad(nsIDocument *aDocument, - uint32_t aLoadEventType) +DocManager::HandleDOMDocumentLoad(nsIDocument* aDocument, + uint32_t aLoadEventType) { // Document accessible can be created before we were notified the DOM document // was loaded completely. However if it's not created yet then create it. @@ -322,8 +322,8 @@ nsAccDocManager::HandleDOMDocumentLoad(nsIDocument *aDocument, } void -nsAccDocManager::AddListeners(nsIDocument *aDocument, - bool aAddDOMContentLoadedListener) +DocManager::AddListeners(nsIDocument* aDocument, + bool aAddDOMContentLoadedListener) { nsPIDOMWindow *window = aDocument->GetWindow(); nsIDOMEventTarget *target = window->GetChromeEventHandler(); @@ -347,7 +347,7 @@ nsAccDocManager::AddListeners(nsIDocument *aDocument, } DocAccessible* -nsAccDocManager::CreateDocOrRootAccessible(nsIDocument* aDocument) +DocManager::CreateDocOrRootAccessible(nsIDocument* aDocument) { // Ignore temporary, hiding, resource documents and documents without // docshell. @@ -419,12 +419,12 @@ nsAccDocManager::CreateDocOrRootAccessible(nsIDocument* aDocument) } //////////////////////////////////////////////////////////////////////////////// -// nsAccDocManager static +// DocManager static PLDHashOperator -nsAccDocManager::GetFirstEntryInDocCache(const nsIDocument* aKey, - DocAccessible* aDocAccessible, - void* aUserArg) +DocManager::GetFirstEntryInDocCache(const nsIDocument* aKey, + DocAccessible* aDocAccessible, + void* aUserArg) { NS_ASSERTION(aDocAccessible, "No doc accessible for the object in doc accessible cache!"); @@ -434,7 +434,7 @@ nsAccDocManager::GetFirstEntryInDocCache(const nsIDocument* aKey, } void -nsAccDocManager::ClearDocCache() +DocManager::ClearDocCache() { DocAccessible* docAcc = nullptr; while (mDocAccessibleCache.EnumerateRead(GetFirstEntryInDocCache, static_cast(&docAcc))) { @@ -444,9 +444,9 @@ nsAccDocManager::ClearDocCache() } PLDHashOperator -nsAccDocManager::SearchAccessibleInDocCache(const nsIDocument* aKey, - DocAccessible* aDocAccessible, - void* aUserArg) +DocManager::SearchAccessibleInDocCache(const nsIDocument* aKey, + DocAccessible* aDocAccessible, + void* aUserArg) { NS_ASSERTION(aDocAccessible, "No doc accessible for the object in doc accessible cache!"); @@ -464,9 +464,9 @@ nsAccDocManager::SearchAccessibleInDocCache(const nsIDocument* aKey, #ifdef DEBUG PLDHashOperator -nsAccDocManager::SearchIfDocIsRefreshing(const nsIDocument* aKey, - DocAccessible* aDocAccessible, - void* aUserArg) +DocManager::SearchIfDocIsRefreshing(const nsIDocument* aKey, + DocAccessible* aDocAccessible, + void* aUserArg) { NS_ASSERTION(aDocAccessible, "No doc accessible for the object in doc accessible cache!"); diff --git a/accessible/src/base/nsAccDocManager.h b/accessible/src/base/DocManager.h similarity index 87% rename from accessible/src/base/nsAccDocManager.h rename to accessible/src/base/DocManager.h index c60b3ef95843..2cdb5207447d 100644 --- a/accessible/src/base/nsAccDocManager.h +++ b/accessible/src/base/DocManager.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 nsAccDocManager_h_ -#define nsAccDocManager_h_ +#ifndef mozilla_a11_DocManager_h_ +#define mozilla_a11_DocManager_h_ #include "nsIDocument.h" #include "nsIDOMEventListener.h" @@ -19,21 +19,15 @@ namespace a11y { class Accessible; class DocAccessible; -} // namespace a11y -} // namespace mozilla - /** * Manage the document accessible life cycle. */ -class nsAccDocManager : public nsIWebProgressListener, - public nsIDOMEventListener, - public nsSupportsWeakReference +class DocManager : public nsIWebProgressListener, + public nsIDOMEventListener, + public nsSupportsWeakReference { public: - typedef mozilla::a11y::Accessible Accessible; - typedef mozilla::a11y::DocAccessible DocAccessible; - - virtual ~nsAccDocManager() { } + virtual ~DocManager() { } NS_DECL_ISUPPORTS NS_DECL_NSIWEBPROGRESSLISTENER @@ -86,7 +80,7 @@ public: #endif protected: - nsAccDocManager() { } + DocManager() { } /** * Initialize the manager. @@ -99,8 +93,8 @@ protected: void Shutdown(); private: - nsAccDocManager(const nsAccDocManager&); - nsAccDocManager& operator =(const nsAccDocManager&); + DocManager(const DocManager&); + DocManager& operator =(const DocManager&); private: /** @@ -160,4 +154,7 @@ private: DocAccessibleHashtable mDocAccessibleCache; }; -#endif // nsAccDocManager_h_ +} // namespace a11y +} // namespace mozilla + +#endif // mozilla_a11_DocManager_h_ diff --git a/accessible/src/base/Makefile.in b/accessible/src/base/Makefile.in index b29b53fcf241..1d65fcca5c13 100644 --- a/accessible/src/base/Makefile.in +++ b/accessible/src/base/Makefile.in @@ -21,9 +21,9 @@ CPPSRCS = \ AccIterator.cpp \ Filters.cpp \ ARIAStateMap.cpp \ + DocManager.cpp \ FocusManager.cpp \ NotificationController.cpp \ - nsAccDocManager.cpp \ nsAccessNode.cpp \ nsARIAMap.cpp \ nsCoreUtils.cpp \ @@ -48,7 +48,6 @@ endif EXPORTS = \ AccEvent.h \ - nsAccDocManager.h \ nsAccessibilityService.h \ nsAccessNode.h \ $(NULL) @@ -56,6 +55,7 @@ EXPORTS = \ EXPORTS_NAMESPACES = mozilla/a11y EXPORTS_mozilla/a11y = \ + DocManager.h \ FocusManager.h \ AccTypes.h \ States.h \ diff --git a/accessible/src/base/nsAccessibilityService.cpp b/accessible/src/base/nsAccessibilityService.cpp index 5a562217a34f..6c8914a4cc48 100644 --- a/accessible/src/base/nsAccessibilityService.cpp +++ b/accessible/src/base/nsAccessibilityService.cpp @@ -125,7 +125,7 @@ ApplicationAccessible* nsAccessibilityService::gApplicationAccessible = nullptr; bool nsAccessibilityService::gIsShutdown = true; nsAccessibilityService::nsAccessibilityService() : - nsAccDocManager(), FocusManager() + DocManager(), FocusManager() { } @@ -139,7 +139,7 @@ nsAccessibilityService::~nsAccessibilityService() // nsISupports NS_IMPL_ISUPPORTS_INHERITED3(nsAccessibilityService, - nsAccDocManager, + DocManager, nsIAccessibilityService, nsIAccessibleRetrieval, nsIObserver) @@ -621,7 +621,7 @@ nsAccessibilityService::GetAccessibleFromCache(nsIDOMNode* aNode, // caches. If we don't find it, and the given node is itself a document, check // our cache of document accessibles (document cache). Note usually shutdown // document accessibles are not stored in the document cache, however an - // "unofficially" shutdown document (i.e. not from nsAccDocManager) can still + // "unofficially" shutdown document (i.e. not from DocManager) can still // exist in the document cache. Accessible* accessible = FindAccessibleInCache(node); if (!accessible) { @@ -975,7 +975,7 @@ bool nsAccessibilityService::Init() { // Initialize accessible document manager. - if (!nsAccDocManager::Init()) + if (!DocManager::Init()) return false; // Add observers. @@ -1026,7 +1026,7 @@ nsAccessibilityService::Shutdown() } // Stop accessible document loader. - nsAccDocManager::Shutdown(); + DocManager::Shutdown(); // Application is going to be closed, shutdown accessibility and mark // accessibility service as shutdown to prevent calls of its methods. diff --git a/accessible/src/base/nsAccessibilityService.h b/accessible/src/base/nsAccessibilityService.h index 3d6cb2cf8207..061f1151d2d9 100644 --- a/accessible/src/base/nsAccessibilityService.h +++ b/accessible/src/base/nsAccessibilityService.h @@ -8,8 +8,7 @@ #include "nsIAccessibilityService.h" -#include "nsAccDocManager.h" - +#include "mozilla/a11y/DocManager.h" #include "mozilla/a11y/FocusManager.h" #include "nsIObserver.h" @@ -64,12 +63,15 @@ bool ShouldA11yBeEnabled(); } // namespace a11y } // namespace mozilla -class nsAccessibilityService : public nsAccDocManager, +class nsAccessibilityService : public mozilla::a11y::DocManager, public mozilla::a11y::FocusManager, public nsIAccessibilityService, public nsIObserver { public: + typedef mozilla::a11y::Accessible Accessible; + typedef mozilla::a11y::DocAccessible DocAccessible; + virtual ~nsAccessibilityService(); NS_DECL_ISUPPORTS_INHERITED diff --git a/accessible/src/generic/DocAccessible.cpp b/accessible/src/generic/DocAccessible.cpp index 4b4b4c1dc782..634b3675cc97 100644 --- a/accessible/src/generic/DocAccessible.cpp +++ b/accessible/src/generic/DocAccessible.cpp @@ -96,7 +96,7 @@ DocAccessible:: if (!mDocument) return; - // nsAccDocManager creates document accessible when scrollable frame is + // DocManager creates document accessible when scrollable frame is // available already, it should be safe time to add scroll listener. AddScrollListener(); diff --git a/accessible/src/generic/DocAccessible.h b/accessible/src/generic/DocAccessible.h index 8b8fbf9dd85f..6d60c787ef86 100644 --- a/accessible/src/generic/DocAccessible.h +++ b/accessible/src/generic/DocAccessible.h @@ -24,7 +24,6 @@ #include "nsIWeakReference.h" #include "nsIDocShellTreeNode.h" -class nsAccDocManager; class nsAccessiblePivot; class nsIScrollableView; @@ -34,6 +33,7 @@ const uint32_t kDefaultCacheSize = 256; namespace mozilla { namespace a11y { +class DocManager; class NotificationController; class RelatedAccIterator; template @@ -319,7 +319,7 @@ protected: void NotifyOfLoad(uint32_t aLoadEventType); void NotifyOfLoading(bool aIsReloading); - friend class ::nsAccDocManager; + friend class DocManager; /** * Perform initial update (create accessible tree). diff --git a/accessible/src/generic/OuterDocAccessible.cpp b/accessible/src/generic/OuterDocAccessible.cpp index eda45e6c9670..d10496f0ec49 100644 --- a/accessible/src/generic/OuterDocAccessible.cpp +++ b/accessible/src/generic/OuterDocAccessible.cpp @@ -135,13 +135,13 @@ OuterDocAccessible::Shutdown() void OuterDocAccessible::InvalidateChildren() { - // Do not invalidate children because nsAccDocManager is responsible for + // Do not invalidate children because DocManager is responsible for // document accessible lifetime when DOM document is created or destroyed. If // DOM document isn't destroyed but its presshell is destroyed (for example, // when DOM node of outerdoc accessible is hidden), then outerdoc accessible - // notifies nsAccDocManager about this. If presshell is created for existing + // notifies DocManager about this. If presshell is created for existing // DOM document (for example when DOM node of outerdoc accessible is shown) - // then allow nsAccDocManager to handle this case since the document + // then allow DocManager to handle this case since the document // accessible is created and appended as a child when it's requested. SetChildrenFlag(eChildrenUninitialized); From 2c79e554a20ce6c2250f04cc4c4ba74cdbf1710f Mon Sep 17 00:00:00 2001 From: Simon Montagu Date: Tue, 20 Nov 2012 06:21:13 -0800 Subject: [PATCH 05/75] Add EnumerateEntries to nsCheapSet. Bug 809446, r=bsmedberg --- xpcom/ds/nsCheapSets.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/xpcom/ds/nsCheapSets.h b/xpcom/ds/nsCheapSets.h index 5e39c88a5d22..4912ae7d81f9 100644 --- a/xpcom/ds/nsCheapSets.h +++ b/xpcom/ds/nsCheapSets.h @@ -18,6 +18,7 @@ class nsCheapSet { public: typedef typename EntryType::KeyType KeyType; + typedef PLDHashOperator (* Enumerator)(EntryType* aEntry, void* userArg); nsCheapSet() : mState(ZERO) { @@ -58,6 +59,25 @@ public: } } + uint32_t EnumerateEntries(Enumerator enumFunc, void* userArg) + { + switch (mState) { + case ZERO: + return 0; + case ONE: + if (enumFunc(GetSingleEntry(), userArg) == PL_DHASH_REMOVE) { + GetSingleEntry()->~EntryType(); + mState = ZERO; + } + return 1; + case MANY: + return mUnion.table->EnumerateEntries(enumFunc, userArg); + default: + NS_NOTREACHED("bogus state"); + return 0; + } + } + private: EntryType* GetSingleEntry() { From 1b752132f25fb9d31d999124a104b75a6fa8f568 Mon Sep 17 00:00:00 2001 From: Simon Montagu Date: Tue, 20 Nov 2012 06:21:13 -0800 Subject: [PATCH 06/75] Changes to existing tests caused by bug 548206 --- content/html/content/test/test_bug660663.html | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/content/html/content/test/test_bug660663.html b/content/html/content/test/test_bug660663.html index 1e79740dfa35..2ce3f9ac694a 100644 --- a/content/html/content/test/test_bug660663.html +++ b/content/html/content/test/test_bug660663.html @@ -21,9 +21,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=660663 reflectLimitedEnumerated({ element: document.createElement("div"), attribute: "dir", - validValues: ["ltr", "rtl"], - invalidValues: ["cheesecake", ""], - unsupportedValues: ["auto"] + validValues: ["ltr", "rtl", "auto"], + invalidValues: ["cheesecake", ""] }); From 94e8b8852a96f5265b676021ca5880f789984c19 Mon Sep 17 00:00:00 2001 From: Matitiahu Allouche Date: Tue, 20 Nov 2012 06:21:14 -0800 Subject: [PATCH 07/75] Tests for dir=auto (Bug 548206) from w3c HTML5 test suite, r=smontagu --- .../bidi/dirAuto/dir_auto-EN-L-ref.html | 58 +++++++++++ .../reftests/bidi/dirAuto/dir_auto-EN-L.html | 58 +++++++++++ .../bidi/dirAuto/dir_auto-EN-R-ref.html | 58 +++++++++++ .../reftests/bidi/dirAuto/dir_auto-EN-R.html | 58 +++++++++++ .../reftests/bidi/dirAuto/dir_auto-L-ref.html | 58 +++++++++++ layout/reftests/bidi/dirAuto/dir_auto-L.html | 58 +++++++++++ .../bidi/dirAuto/dir_auto-N-EN-L-ref.html | 58 +++++++++++ .../bidi/dirAuto/dir_auto-N-EN-L.html | 58 +++++++++++ .../bidi/dirAuto/dir_auto-N-EN-R-ref.html | 58 +++++++++++ .../bidi/dirAuto/dir_auto-N-EN-R.html | 58 +++++++++++ .../bidi/dirAuto/dir_auto-N-EN-ref.html | 51 ++++++++++ .../reftests/bidi/dirAuto/dir_auto-N-EN.html | 51 ++++++++++ .../bidi/dirAuto/dir_auto-N-L-ref.html | 58 +++++++++++ .../reftests/bidi/dirAuto/dir_auto-N-L.html | 58 +++++++++++ .../bidi/dirAuto/dir_auto-N-R-ref.html | 58 +++++++++++ .../reftests/bidi/dirAuto/dir_auto-N-R.html | 58 +++++++++++ .../reftests/bidi/dirAuto/dir_auto-R-ref.html | 59 +++++++++++ layout/reftests/bidi/dirAuto/dir_auto-R.html | 58 +++++++++++ .../dirAuto/dir_auto-contained-L-ref.html | 62 ++++++++++++ .../bidi/dirAuto/dir_auto-contained-L.html | 62 ++++++++++++ .../dirAuto/dir_auto-contained-R-ref.html | 58 +++++++++++ .../bidi/dirAuto/dir_auto-contained-R.html | 58 +++++++++++ .../dirAuto/dir_auto-contained-bdi-L-ref.html | 64 ++++++++++++ .../dirAuto/dir_auto-contained-bdi-L.html | 64 ++++++++++++ .../dirAuto/dir_auto-contained-bdi-R-ref.html | 61 ++++++++++++ .../dirAuto/dir_auto-contained-bdi-R.html | 61 ++++++++++++ .../dirAuto/dir_auto-contained-dir-L-ref.html | 61 ++++++++++++ .../dirAuto/dir_auto-contained-dir-L.html | 61 ++++++++++++ .../dirAuto/dir_auto-contained-dir-R-ref.html | 58 +++++++++++ .../dirAuto/dir_auto-contained-dir-R.html | 58 +++++++++++ .../dir_auto-contained-dir_auto-L-ref.html | 61 ++++++++++++ .../dir_auto-contained-dir_auto-L.html | 61 ++++++++++++ .../dir_auto-contained-dir_auto-R-ref.html | 58 +++++++++++ .../dir_auto-contained-dir_auto-R.html | 58 +++++++++++ .../dir_auto-contained-script-L-ref.html | 58 +++++++++++ .../dirAuto/dir_auto-contained-script-L.html | 58 +++++++++++ .../dir_auto-contained-script-R-ref.html | 58 +++++++++++ .../dirAuto/dir_auto-contained-script-R.html | 58 +++++++++++ .../dir_auto-contained-style-L-ref.html | 70 +++++++++++++ .../dirAuto/dir_auto-contained-style-L.html | 70 +++++++++++++ .../dir_auto-contained-style-R-ref.html | 70 +++++++++++++ .../dirAuto/dir_auto-contained-style-R.html | 70 +++++++++++++ .../dir_auto-contained-textarea-L-ref.html | 61 ++++++++++++ .../dir_auto-contained-textarea-L.html | 61 ++++++++++++ .../dir_auto-contained-textarea-R-ref.html | 58 +++++++++++ .../dir_auto-contained-textarea-R.html | 58 +++++++++++ .../bidi/dirAuto/dir_auto-input-EN-L-ref.html | 59 +++++++++++ .../bidi/dirAuto/dir_auto-input-EN-L.html | 59 +++++++++++ .../bidi/dirAuto/dir_auto-input-EN-R-ref.html | 59 +++++++++++ .../bidi/dirAuto/dir_auto-input-EN-R.html | 59 +++++++++++ .../bidi/dirAuto/dir_auto-input-L-ref.html | 59 +++++++++++ .../bidi/dirAuto/dir_auto-input-L.html | 59 +++++++++++ .../dirAuto/dir_auto-input-N-EN-L-ref.html | 59 +++++++++++ .../bidi/dirAuto/dir_auto-input-N-EN-L.html | 59 +++++++++++ .../dirAuto/dir_auto-input-N-EN-R-ref.html | 59 +++++++++++ .../bidi/dirAuto/dir_auto-input-N-EN-R.html | 59 +++++++++++ .../bidi/dirAuto/dir_auto-input-N-EN-ref.html | 54 ++++++++++ .../bidi/dirAuto/dir_auto-input-N-EN.html | 54 ++++++++++ .../bidi/dirAuto/dir_auto-input-N-L-ref.html | 59 +++++++++++ .../bidi/dirAuto/dir_auto-input-N-L.html | 59 +++++++++++ .../bidi/dirAuto/dir_auto-input-N-R-ref.html | 59 +++++++++++ .../bidi/dirAuto/dir_auto-input-N-R.html | 59 +++++++++++ .../bidi/dirAuto/dir_auto-input-R-ref.html | 59 +++++++++++ .../bidi/dirAuto/dir_auto-input-R.html | 59 +++++++++++ .../dir_auto-input-script-EN-L-ref.html | 59 +++++++++++ .../dirAuto/dir_auto-input-script-EN-L.html | 68 +++++++++++++ .../dir_auto-input-script-EN-R-ref.html | 59 +++++++++++ .../dirAuto/dir_auto-input-script-EN-R.html | 68 +++++++++++++ .../dirAuto/dir_auto-input-script-L-ref.html | 59 +++++++++++ .../bidi/dirAuto/dir_auto-input-script-L.html | 68 +++++++++++++ .../dir_auto-input-script-N-EN-L-ref.html | 59 +++++++++++ .../dirAuto/dir_auto-input-script-N-EN-L.html | 68 +++++++++++++ .../dir_auto-input-script-N-EN-R-ref.html | 59 +++++++++++ .../dirAuto/dir_auto-input-script-N-EN-R.html | 68 +++++++++++++ .../dir_auto-input-script-N-EN-ref.html | 54 ++++++++++ .../dirAuto/dir_auto-input-script-N-EN.html | 63 ++++++++++++ .../dir_auto-input-script-N-L-ref.html | 59 +++++++++++ .../dirAuto/dir_auto-input-script-N-L.html | 68 +++++++++++++ .../dir_auto-input-script-N-R-ref.html | 59 +++++++++++ .../dirAuto/dir_auto-input-script-N-R.html | 68 +++++++++++++ .../dirAuto/dir_auto-input-script-R-ref.html | 59 +++++++++++ .../bidi/dirAuto/dir_auto-input-script-R.html | 68 +++++++++++++ .../bidi/dirAuto/dir_auto-isolate-ref.html | 56 +++++++++++ .../bidi/dirAuto/dir_auto-isolate.html | 58 +++++++++++ .../bidi/dirAuto/dir_auto-pre-N-EN-ref.html | 49 ++++++++++ .../bidi/dirAuto/dir_auto-pre-N-EN.html | 66 +++++++++++++ .../dir_auto-pre-N-between-Rs-ref.html | 61 ++++++++++++ .../dirAuto/dir_auto-pre-N-between-Rs.html | 76 ++++++++++++++ .../bidi/dirAuto/dir_auto-pre-mixed-ref.html | 61 ++++++++++++ .../bidi/dirAuto/dir_auto-pre-mixed.html | 77 +++++++++++++++ .../dirAuto/dir_auto-textarea-N-EN-ref.html | 49 ++++++++++ .../bidi/dirAuto/dir_auto-textarea-N-EN.html | 66 +++++++++++++ .../dir_auto-textarea-N-between-Rs-ref.html | 65 ++++++++++++ .../dir_auto-textarea-N-between-Rs.html | 79 +++++++++++++++ .../dirAuto/dir_auto-textarea-mixed-ref.html | 64 ++++++++++++ .../bidi/dirAuto/dir_auto-textarea-mixed.html | 80 +++++++++++++++ .../dir_auto-textarea-script-N-EN-ref.html | 49 ++++++++++ .../dir_auto-textarea-script-N-EN.html | 75 ++++++++++++++ ...auto-textarea-script-N-between-Rs-ref.html | 65 ++++++++++++ ...dir_auto-textarea-script-N-between-Rs.html | 84 ++++++++++++++++ .../dir_auto-textarea-script-mixed-ref.html | 64 ++++++++++++ .../dir_auto-textarea-script-mixed.html | 98 +++++++++++++++++++ layout/reftests/bidi/dirAuto/reftest.list | 51 ++++++++++ layout/reftests/bidi/reftest.list | 1 + 104 files changed, 6326 insertions(+) create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-EN-L-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-EN-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-EN-R-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-EN-R.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-L-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-N-EN-L-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-N-EN-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-N-EN-R-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-N-EN-R.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-N-EN-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-N-EN.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-N-L-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-N-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-N-R-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-N-R.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-R-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-R.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-L-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-R-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-R.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-L-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-R-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-R.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-dir-L-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-dir-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-dir-R-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-dir-R.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-L-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-R-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-R.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-script-L-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-script-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-script-R-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-script-R.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-style-L-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-style-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-style-R-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-style-R.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-L-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-R-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-R.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-EN-L-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-EN-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-EN-R-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-EN-R.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-L-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-L-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-R-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-R.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-N-EN.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-N-L-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-N-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-N-R-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-N-R.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-R-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-R.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-L-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-R-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-R.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-L-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-L-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-R-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-R.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-N-L-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-N-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-N-R-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-N-R.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-R-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-R.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-isolate-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-isolate.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-pre-N-EN-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-pre-N-EN.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-pre-N-between-Rs-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-pre-N-between-Rs.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-pre-mixed-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-pre-mixed.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-N-EN-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-N-EN.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-N-between-Rs-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-N-between-Rs.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-mixed-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-mixed.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-EN-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-EN.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-between-Rs-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-between-Rs.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-script-mixed-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-script-mixed.html create mode 100644 layout/reftests/bidi/dirAuto/reftest.list diff --git a/layout/reftests/bidi/dirAuto/dir_auto-EN-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-EN-L-ref.html new file mode 100644 index 000000000000..b53ed1fb795f --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-EN-L-ref.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with EN, then L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

123ABCאבג.

+
+
+

123ABCאבג.

+
+
+
+
+

123ABCאבג.

+
+
+

123ABCאבג.

+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-EN-L.html b/layout/reftests/bidi/dirAuto/dir_auto-EN-L.html new file mode 100644 index 000000000000..57f074a2bc1f --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-EN-L.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with EN, then L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

123ABCאבג.

+
+
+

123ABCאבג.

+
+
+
+
+

123ABCאבג.

+
+
+

123ABCאבג.

+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-EN-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-EN-R-ref.html new file mode 100644 index 000000000000..d695e5ab570a --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-EN-R-ref.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with EN, then R + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

123אבגABC.

+
+
+

123אבגABC.

+
+
+
+
+

123אבגABC.

+
+
+

123אבגABC.

+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-EN-R.html b/layout/reftests/bidi/dirAuto/dir_auto-EN-R.html new file mode 100644 index 000000000000..1ab3112440f0 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-EN-R.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with EN, then R + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

123אבגABC.

+
+
+

123אבגABC.

+
+
+
+
+

123אבגABC.

+
+
+

123אבגABC.

+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-L-ref.html new file mode 100644 index 000000000000..64b178d7b594 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-L-ref.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

ABCאבג.

+
+
+

ABCאבג.

+
+
+
+
+

ABCאבג.

+
+
+

ABCאבג.

+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-L.html b/layout/reftests/bidi/dirAuto/dir_auto-L.html new file mode 100644 index 000000000000..1da642cc19b7 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-L.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

ABCאבג.

+
+
+

ABCאבג.

+
+
+
+
+

ABCאבג.

+
+
+

ABCאבג.

+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-N-EN-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-N-EN-L-ref.html new file mode 100644 index 000000000000..71da52633ea6 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-N-EN-L-ref.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with N, then EN, then L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

.-=123ABCאבג.

+
+
+

.-=123ABCאבג.

+
+
+
+
+

.-=123ABCאבג.

+
+
+

.-=123ABCאבג.

+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-N-EN-L.html b/layout/reftests/bidi/dirAuto/dir_auto-N-EN-L.html new file mode 100644 index 000000000000..9372a42628da --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-N-EN-L.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with N, then EN, then L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

.-=123ABCאבג.

+
+
+

.-=123ABCאבג.

+
+
+
+
+

.-=123ABCאבג.

+
+
+

.-=123ABCאבג.

+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-N-EN-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-N-EN-R-ref.html new file mode 100644 index 000000000000..856a6ee3e2ef --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-N-EN-R-ref.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with N, then EN, then R + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

.-=123אבגABC.

+
+
+

.-=123אבגABC.

+
+
+
+
+

.-=123אבגABC.

+
+
+

.-=123אבגABC.

+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-N-EN-R.html b/layout/reftests/bidi/dirAuto/dir_auto-N-EN-R.html new file mode 100644 index 000000000000..4f0126b1a48b --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-N-EN-R.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with N, then EN, then R + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

.-=123אבגABC.

+
+
+

.-=123אבגABC.

+
+
+
+
+

.-=123אבגABC.

+
+
+

.-=123אבגABC.

+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-N-EN-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-N-EN-ref.html new file mode 100644 index 000000000000..df0339f1342e --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-N-EN-ref.html @@ -0,0 +1,51 @@ + + + + + HTML Test: dir=auto, start with N, then EN, then L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+
+

@123!

+
+
+

@123!

+
+
+
+
+

@123!

+
+
+

@123!

+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-N-EN.html b/layout/reftests/bidi/dirAuto/dir_auto-N-EN.html new file mode 100644 index 000000000000..a7c6db6d6a79 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-N-EN.html @@ -0,0 +1,51 @@ + + + + + HTML Test: dir=auto, start with N, then EN, then L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+
+

@123!

+
+
+

@123!

+
+
+
+
+

@123!

+
+
+

@123!

+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-N-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-N-L-ref.html new file mode 100644 index 000000000000..818b9c0e6746 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-N-L-ref.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with N, then L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

.-=ABCאבג.

+
+
+

.-=ABCאבג.

+
+
+
+
+

.-=ABCאבג.

+
+
+

.-=ABCאבג.

+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-N-L.html b/layout/reftests/bidi/dirAuto/dir_auto-N-L.html new file mode 100644 index 000000000000..eab63560c7be --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-N-L.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with N, then L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

.-=ABCאבג.

+
+
+

.-=ABCאבג.

+
+
+
+
+

.-=ABCאבג.

+
+
+

.-=ABCאבג.

+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-N-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-N-R-ref.html new file mode 100644 index 000000000000..a2c82541a557 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-N-R-ref.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with N, then R + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

.-=אבגABC.

+
+
+

.-=אבגABC.

+
+
+
+
+

.-=אבגABC.

+
+
+

.-=אבגABC.

+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-N-R.html b/layout/reftests/bidi/dirAuto/dir_auto-N-R.html new file mode 100644 index 000000000000..352b8f80a7d4 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-N-R.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with N, then R + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

.-=אבגABC.

+
+
+

.-=אבגABC.

+
+
+
+
+

.-=אבגABC.

+
+
+

.-=אבגABC.

+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-R-ref.html new file mode 100644 index 000000000000..61ff12f2f8f8 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-R-ref.html @@ -0,0 +1,59 @@ + + + + + HTML Test: dir=auto, start with R + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+ +
+
+

אבגABC.

+
+
+

אבגABC.

+
+
+
+
+

אבגABC.

+
+
+

אבגABC.

+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-R.html b/layout/reftests/bidi/dirAuto/dir_auto-R.html new file mode 100644 index 000000000000..52677931cabf --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-R.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with R + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

אבגABC.

+
+
+

אבגABC.

+
+
+
+
+

אבגABC.

+
+
+

אבגABC.

+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-L-ref.html new file mode 100644 index 000000000000..9048362d0a75 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-L-ref.html @@ -0,0 +1,62 @@ + + + + + HTML Test: dir=auto, start with L within contained element + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). + ד - The Hebrew letter Dalet (strongly RTL). + ה - The Hebrew letter He (strongly RTL). + ו - The Hebrew letter Vav (strongly RTL). + ז - The Hebrew letter Zayin (strongly RTL). +
+
+
+
ABCאבג.
דה
ו
+
+
+
ABCאבג.
דה
ו
+
+
+
+
+
ABCאבג.
דה
ו
+
+
+
ABCאבג.
דה
ו
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-L.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-L.html new file mode 100644 index 000000000000..994bfbe78452 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-L.html @@ -0,0 +1,62 @@ + + + + + HTML Test: dir=auto, start with L within contained element + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). + ד - The Hebrew letter Dalet (strongly RTL). + ה - The Hebrew letter He (strongly RTL). + ו - The Hebrew letter Vav (strongly RTL). + ז - The Hebrew letter Zayin (strongly RTL). +
+
+
+
ABCאבג.
דה
ו
+
+
+
ABCאבג.
דה
ו
+
+
+
+
+
ABCאבג.
דה
ו
+
+
+
ABCאבג.
דה
ו
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-R-ref.html new file mode 100644 index 000000000000..0cee718c43de --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-R-ref.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with R within contained element + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+
אבגABC.
XY
Z
+
+
+
אבגABC.
XY
Z
+
+
+
+
+
אבגABC.
XY
Z
+
+
+
אבגABC.
XY
Z
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-R.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-R.html new file mode 100644 index 000000000000..113eb073ccaf --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-R.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with R within contained element + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+
אבגABC.
XY
Z
+
+
+
אבגABC.
XY
Z
+
+
+
+
+
אבגABC.
XY
Z
+
+
+
אבגABC.
XY
Z
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-L-ref.html new file mode 100644 index 000000000000..745eea114eb2 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-L-ref.html @@ -0,0 +1,64 @@ + + + + + HTML Test: dir=auto, start with bdi, then L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). + ד - The Hebrew letter Dalet (strongly RTL). + ה - The Hebrew letter He (strongly RTL). + ו - The Hebrew letter Vav (strongly RTL). +
+
+
+
123דהוABCאבג.
+
+
+
123דהוABCאבג.
+
+
+
+
+
123דהוABCאבג.
+
+
+
123דהוABCאבג.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-L.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-L.html new file mode 100644 index 000000000000..cd0292c5cf4f --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-L.html @@ -0,0 +1,64 @@ + + + + + HTML Test: dir=auto, start with bdi, then L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). + ד - The Hebrew letter Dalet (strongly RTL). + ה - The Hebrew letter He (strongly RTL). + ו - The Hebrew letter Vav (strongly RTL). +
+
+
+
123דהוABCאבג.
+
+
+
123דהוABCאבג.
+
+
+
+
+
123דהוABCאבג.
+
+
+
123דהוABCאבג.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-R-ref.html new file mode 100644 index 000000000000..43405ea6e799 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-R-ref.html @@ -0,0 +1,61 @@ + + + + + HTML Test: dir=auto, start with bdi, then R + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+
123DEFאבגABC.
+
+
+
123DEFאבגABC.
+
+
+
+
+
123DEFאבגABC.
+
+
+
123DEFאבגABC.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-R.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-R.html new file mode 100644 index 000000000000..cce36bddf2a1 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-R.html @@ -0,0 +1,61 @@ + + + + + HTML Test: dir=auto, start with bdi, then R + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+
123DEFאבגABC.
+
+
+
123DEFאבגABC.
+
+
+
+
+
123DEFאבגABC.
+
+
+
123DEFאבגABC.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-L-ref.html new file mode 100644 index 000000000000..d5935d83f612 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-L-ref.html @@ -0,0 +1,61 @@ + + + + + HTML Test: dir=auto, start with dir, then L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). + ד - The Hebrew letter Dalet (strongly RTL). + ה - The Hebrew letter He (strongly RTL). + ו - The Hebrew letter Vav (strongly RTL). +
+
+
+

דהו

ABCאבג.
+
+
+

דהו

ABCאבג.
+
+
+
+
+

דהו

ABCאבג.
+
+
+

דהו

ABCאבג.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-L.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-L.html new file mode 100644 index 000000000000..292c753fdd1a --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-L.html @@ -0,0 +1,61 @@ + + + + + HTML Test: dir=auto, start with dir, then L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). + ד - The Hebrew letter Dalet (strongly RTL). + ה - The Hebrew letter He (strongly RTL). + ו - The Hebrew letter Vav (strongly RTL). +
+
+
+

דהו

ABCאבג.
+
+
+

דהו

ABCאבג.
+
+
+
+
+

דהו

ABCאבג.
+
+
+

דהו

ABCאבג.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-R-ref.html new file mode 100644 index 000000000000..5ae48d897043 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-R-ref.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with dir, then R + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

DEF

אבגABC.
+
+
+

DEF

אבגABC.
+
+
+
+
+

DEF

אבגABC.
+
+
+

DEF

אבגABC.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-R.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-R.html new file mode 100644 index 000000000000..cc625553f828 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-R.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with dir, then R + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

DEF

אבגABC.
+
+
+

DEF

אבגABC.
+
+
+
+
+

DEF

אבגABC.
+
+
+

DEF

אבגABC.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-L-ref.html new file mode 100644 index 000000000000..ac1f178799ae --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-L-ref.html @@ -0,0 +1,61 @@ + + + + + HTML Test: dir=auto, start with dir=auto, then L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). + ד - The Hebrew letter Dalet (strongly RTL). + ה - The Hebrew letter He (strongly RTL). + ו - The Hebrew letter Vav (strongly RTL). +
+
+
+

דהו

ABCאבג.
+
+
+

דהו

ABCאבג.
+
+
+
+
+

דהו

ABCאבג.
+
+
+

דהו

ABCאבג.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-L.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-L.html new file mode 100644 index 000000000000..892894e8e990 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-L.html @@ -0,0 +1,61 @@ + + + + + HTML Test: dir=auto, start with dir=auto, then L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). + ד - The Hebrew letter Dalet (strongly RTL). + ה - The Hebrew letter He (strongly RTL). + ו - The Hebrew letter Vav (strongly RTL). +
+
+
+

דהו

ABCאבג.
+
+
+

דהו

ABCאבג.
+
+
+
+
+

דהו

ABCאבג.
+
+
+

דהו

ABCאבג.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-R-ref.html new file mode 100644 index 000000000000..d7157de5c89b --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-R-ref.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with dir=auto, then R + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

DEF

.-=123אבגABC.
+
+
+

DEF

.-=123אבגABC.
+
+
+
+
+

DEF

.-=123אבגABC.
+
+
+

DEF

.-=123אבגABC.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-R.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-R.html new file mode 100644 index 000000000000..328104cb8783 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-R.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with dir=auto, then R + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

DEF

.-=123אבגABC.
+
+
+

DEF

.-=123אבגABC.
+
+
+
+
+

DEF

.-=123אבגABC.
+
+
+

DEF

.-=123אבגABC.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-script-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-script-L-ref.html new file mode 100644 index 000000000000..ad844fd1da23 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-script-L-ref.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with script, then L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+
ABCאבג.
+
+
+
ABCאבג.
+
+
+
+
+
ABCאבג.
+
+
+
ABCאבג.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-script-L.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-script-L.html new file mode 100644 index 000000000000..d5e685ee0eb6 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-script-L.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with script, then L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+
ABCאבג.
+
+
+
ABCאבג.
+
+
+
+
+
ABCאבג.
+
+
+
ABCאבג.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-script-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-script-R-ref.html new file mode 100644 index 000000000000..8225443c86a1 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-script-R-ref.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with script, then R + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+
אבגABC.
+
+
+
אבגABC.
+
+
+
+
+
אבגABC.
+
+
+
אבגABC.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-script-R.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-script-R.html new file mode 100644 index 000000000000..4d131a2d480d --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-script-R.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with script, then R + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+
אבגABC.
+
+
+
אבגABC.
+
+
+
+
+
אבגABC.
+
+
+
אבגABC.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-style-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-style-L-ref.html new file mode 100644 index 000000000000..46e713774051 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-style-L-ref.html @@ -0,0 +1,70 @@ + + + + + HTML Test: dir=auto, start with style, then L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+
ABCאבג.
+
+
+
ABCאבג.
+
+
+
+
+
ABCאבג.
+
+
+
ABCאבג.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-style-L.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-style-L.html new file mode 100644 index 000000000000..5ad03180f2ec --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-style-L.html @@ -0,0 +1,70 @@ + + + + + HTML Test: dir=auto, start with style, then L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+
ABCאבג.
+
+
+
ABCאבג.
+
+
+
+
+
ABCאבג.
+
+
+
ABCאבג.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-style-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-style-R-ref.html new file mode 100644 index 000000000000..6cf5e1d24b2d --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-style-R-ref.html @@ -0,0 +1,70 @@ + + + + + HTML Test: dir=auto, start with style, then R + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+
אבגABC.
+
+
+
אבגABC.
+
+
+
+
+
אבגABC.
+
+
+
אבגABC.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-style-R.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-style-R.html new file mode 100644 index 000000000000..133ce1be0510 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-style-R.html @@ -0,0 +1,70 @@ + + + + + HTML Test: dir=auto, start with style, then R + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+
אבגABC.
+
+
+
אבגABC.
+
+
+
+
+
אבגABC.
+
+
+
אבגABC.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-L-ref.html new file mode 100644 index 000000000000..d13f702557a1 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-L-ref.html @@ -0,0 +1,61 @@ + + + + + HTML Test: dir=auto, start with textarea, then L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). + ד - The Hebrew letter Dalet (strongly RTL). + ה - The Hebrew letter He (strongly RTL). + ו - The Hebrew letter Vav (strongly RTL). +
+
+
+
ABCאבג.
+
+
+
ABCאבג.
+
+
+
+
+
ABCאבג.
+
+
+
ABCאבג.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-L.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-L.html new file mode 100644 index 000000000000..51468ce17c82 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-L.html @@ -0,0 +1,61 @@ + + + + + HTML Test: dir=auto, start with textarea, then L + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). + ד - The Hebrew letter Dalet (strongly RTL). + ה - The Hebrew letter He (strongly RTL). + ו - The Hebrew letter Vav (strongly RTL). +
+
+
+
ABCאבג.
+
+
+
ABCאבג.
+
+
+
+
+
ABCאבג.
+
+
+
ABCאבג.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-R-ref.html new file mode 100644 index 000000000000..ffa5ba5c92c3 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-R-ref.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with textarea, then R + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+
אבגABC.
+
+
+
אבגABC.
+
+
+
+
+
אבגABC.
+
+
+
אבגABC.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-R.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-R.html new file mode 100644 index 000000000000..83875ef58a41 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-R.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, start with textarea, then R + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+
אבגABC.
+
+
+
אבגABC.
+
+
+
+
+
אבגABC.
+
+
+
אבגABC.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-EN-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-EN-L-ref.html new file mode 100644 index 000000000000..cedc14acf026 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-EN-L-ref.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, start with EN+L + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-EN-L.html b/layout/reftests/bidi/dirAuto/dir_auto-input-EN-L.html new file mode 100644 index 000000000000..9d32b7a59084 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-EN-L.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, start with EN+L + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-EN-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-EN-R-ref.html new file mode 100644 index 000000000000..91c1bf568692 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-EN-R-ref.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, start with EN+R + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-EN-R.html b/layout/reftests/bidi/dirAuto/dir_auto-input-EN-R.html new file mode 100644 index 000000000000..7ac8b11f6c04 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-EN-R.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, start with EN+R + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-L-ref.html new file mode 100644 index 000000000000..a16ecdbd12d1 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-L-ref.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, start with L + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-L.html b/layout/reftests/bidi/dirAuto/dir_auto-input-L.html new file mode 100644 index 000000000000..adefc3b80298 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-L.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, start with L + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-L-ref.html new file mode 100644 index 000000000000..1e68258423b8 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-L-ref.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, start with N+EN+L + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-L.html b/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-L.html new file mode 100644 index 000000000000..5ad1d24a14dc --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-L.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, start with N+EN+L + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-R-ref.html new file mode 100644 index 000000000000..fe2ba0b3f715 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-R-ref.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, start with N+EN+R + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-R.html b/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-R.html new file mode 100644 index 000000000000..fba3dda45499 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-R.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, start with N+EN+R + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-ref.html new file mode 100644 index 000000000000..6a9db60ab10b --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-ref.html @@ -0,0 +1,54 @@ + + + + + HTML Test: input with dir=auto, all N+EN + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN.html b/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN.html new file mode 100644 index 000000000000..649beca1a6e8 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN.html @@ -0,0 +1,54 @@ + + + + + HTML Test: input with dir=auto, all N+EN + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-N-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-N-L-ref.html new file mode 100644 index 000000000000..03b396d4bff8 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-N-L-ref.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, start with N+L + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-N-L.html b/layout/reftests/bidi/dirAuto/dir_auto-input-N-L.html new file mode 100644 index 000000000000..14bd05fb270c --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-N-L.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, start with N+L + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-N-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-N-R-ref.html new file mode 100644 index 000000000000..474b5c7e7623 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-N-R-ref.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, start with N+R + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-N-R.html b/layout/reftests/bidi/dirAuto/dir_auto-input-N-R.html new file mode 100644 index 000000000000..f78f28981800 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-N-R.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, start with N+R + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-R-ref.html new file mode 100644 index 000000000000..6942d3ffb8a4 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-R-ref.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, start with R + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-R.html b/layout/reftests/bidi/dirAuto/dir_auto-input-R.html new file mode 100644 index 000000000000..70163671dcfe --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-R.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, start with R + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-L-ref.html new file mode 100644 index 000000000000..a58f6c166696 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-L-ref.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, script assigns to start with EN+L + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-L.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-L.html new file mode 100644 index 000000000000..03850c990ded --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-L.html @@ -0,0 +1,68 @@ + + + + + HTML Test: input with dir=auto, script assigns to start with EN+L + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+ +
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-R-ref.html new file mode 100644 index 000000000000..33061e92917f --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-R-ref.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, script assigns to start with EN+R + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-R.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-R.html new file mode 100644 index 000000000000..207652d2505c --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-R.html @@ -0,0 +1,68 @@ + + + + + HTML Test: input with dir=auto, script assigns to start with EN+R + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+ +
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-L-ref.html new file mode 100644 index 000000000000..b14ec45e6745 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-script-L-ref.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, script assigns to start with L + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-L.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-L.html new file mode 100644 index 000000000000..6ee4ee471ef1 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-script-L.html @@ -0,0 +1,68 @@ + + + + + HTML Test: input with dir=auto, script assigns to start with L + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+ +
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-L-ref.html new file mode 100644 index 000000000000..eda0b659dea4 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-L-ref.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, script assigns to start with N+EN+L + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-L.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-L.html new file mode 100644 index 000000000000..50222dd07f05 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-L.html @@ -0,0 +1,68 @@ + + + + + HTML Test: input with dir=auto, script assigns to start with N+EN+L + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+ +
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-R-ref.html new file mode 100644 index 000000000000..f78ef0bbc9a0 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-R-ref.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, script assigns to start with N+EN+R + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-R.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-R.html new file mode 100644 index 000000000000..e87f8f13bb8c --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-R.html @@ -0,0 +1,68 @@ + + + + + HTML Test: input with dir=auto, script assigns to start with N+EN+R + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+ +
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-ref.html new file mode 100644 index 000000000000..b61f677dc71c --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-ref.html @@ -0,0 +1,54 @@ + + + + + HTML Test: input with dir=auto, script assigns to all N+EN + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN.html new file mode 100644 index 000000000000..088036a25516 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN.html @@ -0,0 +1,63 @@ + + + + + HTML Test: input with dir=auto, script assigns to all N+EN + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ +
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-L-ref.html new file mode 100644 index 000000000000..55ff0d53c438 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-L-ref.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, script assigns to start with N+L + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-L.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-L.html new file mode 100644 index 000000000000..1f3486c0ed14 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-L.html @@ -0,0 +1,68 @@ + + + + + HTML Test: input with dir=auto, script assigns to start with N+L + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+ +
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-R-ref.html new file mode 100644 index 000000000000..f06f47738ed9 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-R-ref.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, script assigns to start with N+R + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-R.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-R.html new file mode 100644 index 000000000000..941b55143543 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-R.html @@ -0,0 +1,68 @@ + + + + + HTML Test: input with dir=auto, script assigns to start with N+R + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+ +
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-R-ref.html new file mode 100644 index 000000000000..2b9ea5d73362 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-script-R-ref.html @@ -0,0 +1,59 @@ + + + + + HTML Test: input with dir=auto, script assigns to start with R + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-R.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-R.html new file mode 100644 index 000000000000..304189e189b0 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-input-script-R.html @@ -0,0 +1,68 @@ + + + + + HTML Test: input with dir=auto, script assigns to start with R + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+ +
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-isolate-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-isolate-ref.html new file mode 100644 index 000000000000..4583ac2c7a64 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-isolate-ref.html @@ -0,0 +1,56 @@ + + + + + HTML Test: dir=auto, isolated in LTR text + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). +
+
+
+ ‭1 a! א‬ +
+
+ ‭a !א 1‬ +
+
+
+
+ ‭1 a! א‬ +
+
+ ‭a !א 1‬ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-isolate.html b/layout/reftests/bidi/dirAuto/dir_auto-isolate.html new file mode 100644 index 000000000000..71f929204ed9 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-isolate.html @@ -0,0 +1,58 @@ + + + + + HTML Test: dir=auto, isolated in LTR text + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ‭ - The LRO (left-to-right-override) formatting character. + ‬ - The PDF (pop directional formatting) formatting character; closes LRO. +
+
+
+ א a! 1 +
+
+ a א! 1 +
+
+
+
+ ‭1 a! א‬ +
+
+ ‭a !א 1‬ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-pre-N-EN-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-pre-N-EN-ref.html new file mode 100644 index 000000000000..c951c30b2023 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-pre-N-EN-ref.html @@ -0,0 +1,49 @@ + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+
+
+@123!
+        
+
+
+
+@123!
+        
+
+
+
+
+
+@123!
+        
+
+
+
+@123!
+        
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-pre-N-EN.html b/layout/reftests/bidi/dirAuto/dir_auto-pre-N-EN.html new file mode 100644 index 000000000000..ed923a908d99 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-pre-N-EN.html @@ -0,0 +1,66 @@ + + + + + HTML Test: pre with dir=auto, all N+EN + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + ‎ - LRM, the invisible left-to-right mark (strongly LTR). + ‏ - RLM, the invisible right-to-left mark (strongly RTL). + We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext + specification states whether text-align:start and text-align:end should obey the paragraph + direction or the direction property in a unicode-bidi:plaintext element. +
+
+
+
+@123!
+        
+
+
+
+@123!
+        
+
+
+
+
+
+@123!
+        
+
+
+
+@123!
+        
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-pre-N-between-Rs-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-pre-N-between-Rs-ref.html new file mode 100644 index 000000000000..2d9caf062d24 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-pre-N-between-Rs-ref.html @@ -0,0 +1,61 @@ + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). +
+
+
+
+א
+!...
+א
+        
+
+
+
+א
+!...
+א
+        
+
+
+
+
+
+א
+!...
+א
+        
+
+
+
+א
+!...
+א
+        
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-pre-N-between-Rs.html b/layout/reftests/bidi/dirAuto/dir_auto-pre-N-between-Rs.html new file mode 100644 index 000000000000..00115a401003 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-pre-N-between-Rs.html @@ -0,0 +1,76 @@ + + + + + HTML Test: pre with dir=auto, all-N between all-Rs + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext + specification states whether text-align:start and text-align:end should obey the paragraph + direction or the direction property in a unicode-bidi:plaintext element. + The ...! paragraph, being neutral, is supposed to be displayed LTR (i.e. as ...!, not as !...) + despite both the paragraph before it and the paragraph after it being all-RTL, which makes the + element as a whole RTL. +
+
+
+
+א
+...!
+א
+        
+
+
+
+א
+...!
+א
+        
+
+
+
+
+
+א
+!...
+א
+        
+
+
+
+א
+!...
+א
+        
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-pre-mixed-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-pre-mixed-ref.html new file mode 100644 index 000000000000..10bd02433b45 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-pre-mixed-ref.html @@ -0,0 +1,61 @@ + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+
+
+@123!
+@123!
+@123!
+@123!
+        
+
+
+
+@123!
+@123!
+@123!
+@123!
+        
+
+
+
+
+
+@123!
+@123!
+@123!
+@123!
+        
+
+
+
+@123!
+@123!
+@123!
+@123!
+        
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-pre-mixed.html b/layout/reftests/bidi/dirAuto/dir_auto-pre-mixed.html new file mode 100644 index 000000000000..46eac9551d4b --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-pre-mixed.html @@ -0,0 +1,77 @@ + + + + + HTML Test: pre with dir=auto, mixed L and R paragraphs + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + ‎ - LRM, the invisible left-to-right mark (strongly LTR). + ‏ - RLM, the invisible right-to-left mark (strongly RTL). + We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext + specification states whether text-align:start and text-align:end should obey the paragraph + direction or the direction property in a unicode-bidi:plaintext element. +
+
+
+
+@‎123‏!
+!‏123‎@
+@123‎‏!
+!123‏‎@
+        
+
+
+
+@‎123‏!
+!‏123‎@
+@123‎‏!
+!123‏‎@
+        
+
+
+
+
+
+@123!
+@123!
+@123!
+@123!
+        
+
+
+
+@123!
+@123!
+@123!
+@123!
+        
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-EN-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-EN-ref.html new file mode 100644 index 000000000000..253b84459eef --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-EN-ref.html @@ -0,0 +1,49 @@ + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-EN.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-EN.html new file mode 100644 index 000000000000..fd05e30dec6b --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-EN.html @@ -0,0 +1,66 @@ + + + + + HTML Test: textarea with dir=auto, all N+EN + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + ‎ - LRM, the invisible left-to-right mark (strongly LTR). + ‏ - RLM, the invisible right-to-left mark (strongly RTL). + We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext + specification states whether text-align:start and text-align:end should obey the paragraph + direction or the direction property in a unicode-bidi:plaintext element. +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-between-Rs-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-between-Rs-ref.html new file mode 100644 index 000000000000..558e27171bc8 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-between-Rs-ref.html @@ -0,0 +1,65 @@ + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-between-Rs.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-between-Rs.html new file mode 100644 index 000000000000..d48a6141d874 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-between-Rs.html @@ -0,0 +1,79 @@ + + + + + HTML Test: textarea with dir=auto, all-N between all-Rs + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext + specification states whether text-align:start and text-align:end should obey the paragraph + direction or the direction property in a unicode-bidi:plaintext element. + The ...! paragraph, being neutral, is supposed to be displayed LTR (i.e. as ...!, not as !...) + despite both the paragraph before it and the paragraph after it being all-RTL, which makes the + element as a whole RTL. +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-mixed-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-mixed-ref.html new file mode 100644 index 000000000000..a5a84480f6f4 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-textarea-mixed-ref.html @@ -0,0 +1,64 @@ + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-mixed.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-mixed.html new file mode 100644 index 000000000000..db53d8ff43f1 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-textarea-mixed.html @@ -0,0 +1,80 @@ + + + + + HTML Test: textarea with dir=auto, mixed L and R paragraphs + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + ‎ - LRM, the invisible left-to-right mark (strongly LTR). + ‏ - RLM, the invisible right-to-left mark (strongly RTL). + We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext + specification states whether text-align:start and text-align:end should obey the paragraph + direction or the direction property in a unicode-bidi:plaintext element. +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-EN-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-EN-ref.html new file mode 100644 index 000000000000..253b84459eef --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-EN-ref.html @@ -0,0 +1,49 @@ + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-EN.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-EN.html new file mode 100644 index 000000000000..a622db584b53 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-EN.html @@ -0,0 +1,75 @@ + + + + + HTML Test: textarea with dir=auto, script assigns to all N+EN + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + ‎ - LRM, the invisible left-to-right mark (strongly LTR). + ‏ - RLM, the invisible right-to-left mark (strongly RTL). + We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext + specification states whether text-align:start and text-align:end should obey the paragraph + direction or the direction property in a unicode-bidi:plaintext element. +
+
+ +
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-between-Rs-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-between-Rs-ref.html new file mode 100644 index 000000000000..558e27171bc8 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-between-Rs-ref.html @@ -0,0 +1,65 @@ + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-between-Rs.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-between-Rs.html new file mode 100644 index 000000000000..407e3414fb3f --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-between-Rs.html @@ -0,0 +1,84 @@ + + + + + HTML Test: textarea with dir=auto, script assigns to all-N between all-Rs + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext + specification states whether text-align:start and text-align:end should obey the paragraph + direction or the direction property in a unicode-bidi:plaintext element. + The ...! paragraph, being neutral, is supposed to be displayed LTR (i.e. as ...!, not as !...) + despite both the paragraph before it and the paragraph after it being all-RTL, which makes the + element as a whole RTL. +
+
+ +
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-mixed-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-mixed-ref.html new file mode 100644 index 000000000000..a5a84480f6f4 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-mixed-ref.html @@ -0,0 +1,64 @@ + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-mixed.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-mixed.html new file mode 100644 index 000000000000..f5a5ece56f28 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-mixed.html @@ -0,0 +1,98 @@ + + + + + HTML Test: textarea with dir=auto, script assigns to mixed L and R paragraphs + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + ‎ - LRM, the invisible left-to-right mark (strongly LTR). + ‏ - RLM, the invisible right-to-left mark (strongly RTL). + We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext + specification states whether text-align:start and text-align:end should obey the paragraph + direction or the direction property in a unicode-bidi:plaintext element. +
+
+ +
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + diff --git a/layout/reftests/bidi/dirAuto/reftest.list b/layout/reftests/bidi/dirAuto/reftest.list new file mode 100644 index 000000000000..fc032cd353d7 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/reftest.list @@ -0,0 +1,51 @@ +== dir_auto-contained-bdi-L.html dir_auto-contained-bdi-L-ref.html +== dir_auto-contained-bdi-R.html dir_auto-contained-bdi-R-ref.html +== dir_auto-contained-dir-L.html dir_auto-contained-dir-L-ref.html +== dir_auto-contained-dir-R.html dir_auto-contained-dir-R-ref.html +== dir_auto-contained-dir_auto-L.html dir_auto-contained-dir_auto-L-ref.html +== dir_auto-contained-dir_auto-R.html dir_auto-contained-dir_auto-R-ref.html +== dir_auto-contained-L.html dir_auto-contained-L-ref.html +== dir_auto-contained-R.html dir_auto-contained-R-ref.html +== dir_auto-contained-script-L.html dir_auto-contained-script-L-ref.html +== dir_auto-contained-script-R.html dir_auto-contained-script-R-ref.html +== dir_auto-contained-style-L.html dir_auto-contained-style-L-ref.html +== dir_auto-contained-style-R.html dir_auto-contained-style-R-ref.html +== dir_auto-contained-textarea-L.html dir_auto-contained-textarea-L-ref.html +== dir_auto-contained-textarea-R.html dir_auto-contained-textarea-R-ref.html +== dir_auto-EN-L.html dir_auto-EN-L-ref.html +== dir_auto-EN-R.html dir_auto-EN-R-ref.html +== dir_auto-input-EN-L.html dir_auto-input-EN-L-ref.html +== dir_auto-input-EN-R.html dir_auto-input-EN-R-ref.html +== dir_auto-input-L.html dir_auto-input-L-ref.html +== dir_auto-input-N-EN-L.html dir_auto-input-N-EN-L-ref.html +== dir_auto-input-N-EN-R.html dir_auto-input-N-EN-R-ref.html +== dir_auto-input-N-EN.html dir_auto-input-N-EN-ref.html +== dir_auto-input-N-L.html dir_auto-input-N-L-ref.html +== dir_auto-input-N-R.html dir_auto-input-N-R-ref.html +== dir_auto-input-R.html dir_auto-input-R-ref.html +== dir_auto-input-script-EN-L.html dir_auto-input-script-EN-L-ref.html +== dir_auto-input-script-EN-R.html dir_auto-input-script-EN-R-ref.html +== dir_auto-input-script-L.html dir_auto-input-script-L-ref.html +== dir_auto-input-script-N-EN-L.html dir_auto-input-script-N-EN-L-ref.html +== dir_auto-input-script-N-EN-R.html dir_auto-input-script-N-EN-R-ref.html +== dir_auto-input-script-N-EN.html dir_auto-input-script-N-EN-ref.html +== dir_auto-input-script-N-L.html dir_auto-input-script-N-L-ref.html +== dir_auto-input-script-N-R.html dir_auto-input-script-N-R-ref.html +== dir_auto-input-script-R.html dir_auto-input-script-R-ref.html +== dir_auto-isolate.html dir_auto-isolate-ref.html +== dir_auto-L.html dir_auto-L-ref.html +== dir_auto-N-EN-L.html dir_auto-N-EN-L-ref.html +== dir_auto-N-EN-R.html dir_auto-N-EN-R-ref.html +== dir_auto-N-EN.html dir_auto-N-EN-ref.html +== dir_auto-N-L.html dir_auto-N-L-ref.html +== dir_auto-N-R.html dir_auto-N-R-ref.html +== dir_auto-pre-mixed.html dir_auto-pre-mixed-ref.html +== dir_auto-pre-N-between-Rs.html dir_auto-pre-N-between-Rs-ref.html +== dir_auto-pre-N-EN.html dir_auto-pre-N-EN-ref.html +== dir_auto-R.html dir_auto-R-ref.html +== dir_auto-textarea-mixed.html dir_auto-textarea-mixed-ref.html +== dir_auto-textarea-N-between-Rs.html dir_auto-textarea-N-between-Rs-ref.html +== dir_auto-textarea-N-EN.html dir_auto-textarea-N-EN-ref.html +== dir_auto-textarea-script-mixed.html dir_auto-textarea-script-mixed-ref.html +== dir_auto-textarea-script-N-between-Rs.html dir_auto-textarea-script-N-between-Rs-ref.html +== dir_auto-textarea-script-N-EN.html dir_auto-textarea-script-N-EN-ref.html diff --git a/layout/reftests/bidi/reftest.list b/layout/reftests/bidi/reftest.list index f0347219da9a..bf2191c7dd46 100644 --- a/layout/reftests/bidi/reftest.list +++ b/layout/reftests/bidi/reftest.list @@ -1,3 +1,4 @@ +include dirAuto/reftest.list == bdi-element.html bdi-element-ref.html == bidi-000.html bidi-000-ref.html == bidi-001.html bidi-001-ref.html From 9d55ac57c7aa945f8f526c6640f6d3e63bc9b60e Mon Sep 17 00:00:00 2001 From: Simon Montagu Date: Tue, 20 Nov 2012 06:21:15 -0800 Subject: [PATCH 08/75] Dynamic tests for bug 548206, r=ehsan --- .../dirAuto/dir_auto-set-contained-dir-L.html | 74 ++++++++++++++++ .../dirAuto/dir_auto-set-contained-dir-R.html | 71 ++++++++++++++++ .../dir_auto-set-contained-invalid-dir-L.html | 75 +++++++++++++++++ .../dir_auto-set-contained-invalid-dir-R.html | 72 ++++++++++++++++ .../dir_auto-unset-contained-dir-L-ref.html | 61 ++++++++++++++ .../dir_auto-unset-contained-dir-L.html | 71 ++++++++++++++++ .../dir_auto-unset-contained-dir-R-ref.html | 64 ++++++++++++++ .../dir_auto-unset-contained-dir-R.html | 74 ++++++++++++++++ .../dirAuto/dynamicDirAuto-addLTR-Auto.html | 14 ++++ .../dirAuto/dynamicDirAuto-addRTL-Auto.html | 14 ++++ .../dirAuto/dynamicDirAuto-refLTR-LTR.html | 17 ++++ .../dirAuto/dynamicDirAuto-refLTR-RTL.html | 17 ++++ .../dirAuto/dynamicDirAuto-refRTL-LTR.html | 17 ++++ .../dirAuto/dynamicDirAuto-refRTL-NoDir.html | 20 +++++ .../dirAuto/dynamicDirAuto-refRTL-RTL.html | 17 ++++ .../dirAuto/dynamicDirAuto-setLTR-Auto1.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-Auto2.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-Auto3.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-Auto4.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-Auto5.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-Auto6.html | 18 ++++ .../dynamicDirAuto-setLTR-InvalidDir1.html | 18 ++++ .../dynamicDirAuto-setLTR-InvalidDir2.html | 18 ++++ .../dynamicDirAuto-setLTR-InvalidDir3.html | 18 ++++ .../dynamicDirAuto-setLTR-InvalidDir4.html | 18 ++++ .../dynamicDirAuto-setLTR-InvalidDir5.html | 18 ++++ .../dynamicDirAuto-setLTR-InvalidDir6.html | 18 ++++ .../dynamicDirAuto-setLTR-InvalidDir7.html | 18 ++++ .../dynamicDirAuto-setLTR-InvalidDir8.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-LTR1.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-LTR2.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-LTR3.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-LTR4.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-LTR5.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-LTR6.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-LTR7.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-LTR8.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-NoDir1.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-NoDir2.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-NoDir3.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-NoDir4.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-NoDir5.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-NoDir6.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-NoDir7.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-NoDir8.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-RTL1.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-RTL2.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-RTL3.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-RTL4.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-RTL5.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-RTL6.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-RTL7.html | 18 ++++ .../dirAuto/dynamicDirAuto-setLTR-RTL8.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-Auto1.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-Auto2.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-Auto3.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-Auto4.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-Auto5.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-Auto6.html | 18 ++++ .../dynamicDirAuto-setRTL-InvalidDir1.html | 18 ++++ .../dynamicDirAuto-setRTL-InvalidDir2.html | 18 ++++ .../dynamicDirAuto-setRTL-InvalidDir3.html | 18 ++++ .../dynamicDirAuto-setRTL-InvalidDir4.html | 18 ++++ .../dynamicDirAuto-setRTL-InvalidDir5.html | 18 ++++ .../dynamicDirAuto-setRTL-InvalidDir6.html | 18 ++++ .../dynamicDirAuto-setRTL-InvalidDir7.html | 18 ++++ .../dynamicDirAuto-setRTL-InvalidDir8.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-LTR1.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-LTR2.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-LTR3.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-LTR4.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-LTR5.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-LTR6.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-LTR7.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-LTR8.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-NoDir1.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-NoDir2.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-NoDir3.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-NoDir4.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-NoDir5.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-NoDir6.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-NoDir7.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-NoDir8.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-RTL1.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-RTL2.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-RTL3.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-RTL4.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-RTL5.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-RTL6.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-RTL7.html | 18 ++++ .../dirAuto/dynamicDirAuto-setRTL-RTL8.html | 18 ++++ layout/reftests/bidi/dirAuto/reftest.list | 84 +++++++++++++++++++ layout/reftests/bidi/dirAuto/setDir.js | 61 ++++++++++++++ 93 files changed, 2191 insertions(+) create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-set-contained-dir-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-set-contained-dir-R.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-set-contained-invalid-dir-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-set-contained-invalid-dir-R.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-L-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-L.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-R-ref.html create mode 100644 layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-R.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-addLTR-Auto.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-addRTL-Auto.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-refLTR-LTR.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-refLTR-RTL.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-LTR.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-NoDir.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-RTL.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto1.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto2.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto3.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto4.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto5.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto6.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir1.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir2.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir3.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir4.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir5.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir6.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir7.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir8.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR1.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR2.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR3.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR4.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR5.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR6.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR7.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR8.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir1.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir2.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir3.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir4.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir5.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir6.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir7.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir8.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL1.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL2.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL3.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL4.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL5.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL6.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL7.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL8.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto1.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto2.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto3.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto4.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto5.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto6.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir1.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir2.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir3.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir4.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir5.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir6.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir7.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir8.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR1.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR2.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR3.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR4.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR5.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR6.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR7.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR8.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir1.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir2.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir3.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir4.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir5.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir6.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir7.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir8.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL1.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL2.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL3.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL4.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL5.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL6.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL7.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL8.html create mode 100644 layout/reftests/bidi/dirAuto/setDir.js diff --git a/layout/reftests/bidi/dirAuto/dir_auto-set-contained-dir-L.html b/layout/reftests/bidi/dirAuto/dir_auto-set-contained-dir-L.html new file mode 100644 index 000000000000..41bf37180e9f --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-set-contained-dir-L.html @@ -0,0 +1,74 @@ + + + + + HTML Test: dir=auto, start with dir, then L + + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). + ד - The Hebrew letter Dalet (strongly RTL). + ה - The Hebrew letter He (strongly RTL). + ו - The Hebrew letter Vav (strongly RTL). +
+
+
+

דהו

ABCאבג.
+
+
+

דהו

ABCאבג.
+
+
+
+
+

דהו

ABCאבג.
+
+
+

דהו

ABCאבג.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-set-contained-dir-R.html b/layout/reftests/bidi/dirAuto/dir_auto-set-contained-dir-R.html new file mode 100644 index 000000000000..0c74b3f3b4d0 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-set-contained-dir-R.html @@ -0,0 +1,71 @@ + + + + + HTML Test: dir=auto, start with dir, then R + + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

DEF

אבגABC.
+
+
+

DEF

אבגABC.
+
+
+
+
+

DEF

אבגABC.
+
+
+

DEF

אבגABC.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-set-contained-invalid-dir-L.html b/layout/reftests/bidi/dirAuto/dir_auto-set-contained-invalid-dir-L.html new file mode 100644 index 000000000000..10a75a4cee85 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-set-contained-invalid-dir-L.html @@ -0,0 +1,75 @@ + + + + + HTML Test: dir=auto, start with dir, then L + + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). + ד - The Hebrew letter Dalet (strongly RTL). + ה - The Hebrew letter He (strongly RTL). + ו - The Hebrew letter Vav (strongly RTL). +
+
+
+

דהו

ABCאבג.
+
+
+

דהו

ABCאבג.
+
+
+
+
+

דהו

ABCאבג.
+
+
+

דהו

ABCאבג.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-set-contained-invalid-dir-R.html b/layout/reftests/bidi/dirAuto/dir_auto-set-contained-invalid-dir-R.html new file mode 100644 index 000000000000..0ff92cb55d9c --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-set-contained-invalid-dir-R.html @@ -0,0 +1,72 @@ + + + + + HTML Test: dir=auto, start with dir, then R + + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

DEF

אבגABC.
+
+
+

DEF

אבגABC.
+
+
+
+
+

DEF

אבגABC.
+
+
+

DEF

אבגABC.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-L-ref.html new file mode 100644 index 000000000000..a786430499bd --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-L-ref.html @@ -0,0 +1,61 @@ + + + + + HTML Test: dir=auto, start with dir, then R + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

DEF

אבגABC.
+
+
+

DEF

אבגABC.
+
+
+
+
+

DEF

אבגABC.
+
+
+

DEF

אבגABC.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-L.html b/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-L.html new file mode 100644 index 000000000000..c2cbdc2415ed --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-L.html @@ -0,0 +1,71 @@ + + + + + HTML Test: dir=auto, start with dir, then R + + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). +
+
+
+

DEF

אבגABC.
+
+
+

DEF

אבגABC.
+
+
+
+
+

DEF

אבגABC.
+
+
+

DEF

אבגABC.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-R-ref.html new file mode 100644 index 000000000000..f383652215c9 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-R-ref.html @@ -0,0 +1,64 @@ + + + + + HTML Test: dir=auto, start with dir, then L + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). + ד - The Hebrew letter Dalet (strongly RTL). + ה - The Hebrew letter He (strongly RTL). + ו - The Hebrew letter Vav (strongly RTL). +
+
+
+

דהו

ABCאבג.
+
+
+

דהו

ABCאבג.
+
+
+
+
+

דהו

ABCאבג.
+
+
+

דהו

ABCאבג.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-R.html b/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-R.html new file mode 100644 index 000000000000..a63f718ce1a0 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-R.html @@ -0,0 +1,74 @@ + + + + + HTML Test: dir=auto, start with dir, then L + + + + + + + + + + + +

Test passes if the two boxes below look exactly the same.

+
+ Key to entities used below: + א - The Hebrew letter Alef (strongly RTL). + ב - The Hebrew letter Bet (strongly RTL). + ג - The Hebrew letter Gimel (strongly RTL). + ד - The Hebrew letter Dalet (strongly RTL). + ה - The Hebrew letter He (strongly RTL). + ו - The Hebrew letter Vav (strongly RTL). +
+
+
+

דהו

ABCאבג.
+
+
+

דהו

ABCאבג.
+
+
+
+
+

דהו

ABCאבג.
+
+
+

דהו

ABCאבג.
+
+
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-addLTR-Auto.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-addLTR-Auto.html new file mode 100644 index 000000000000..16dc62b5b936 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-addLTR-Auto.html @@ -0,0 +1,14 @@ + + + + + Set and unset dir="auto" + + + + +
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-addRTL-Auto.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-addRTL-Auto.html new file mode 100644 index 000000000000..52c0949c91f1 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-addRTL-Auto.html @@ -0,0 +1,14 @@ + + + + + Set and unset dir="auto" + + + + +
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-refLTR-LTR.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-refLTR-LTR.html new file mode 100644 index 000000000000..62a74bf334d8 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-refLTR-LTR.html @@ -0,0 +1,17 @@ + + + + + Set and unset dir="auto" + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-refLTR-RTL.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-refLTR-RTL.html new file mode 100644 index 000000000000..60619730a8cd --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-refLTR-RTL.html @@ -0,0 +1,17 @@ + + + + + Set and unset dir="auto" + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-LTR.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-LTR.html new file mode 100644 index 000000000000..4ea471a8d1cf --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-LTR.html @@ -0,0 +1,17 @@ + + + + + Set and unset dir="auto" + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-NoDir.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-NoDir.html new file mode 100644 index 000000000000..b2f56c1ac115 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-NoDir.html @@ -0,0 +1,20 @@ + + + + + Set and unset dir="auto" + + + +
+
אבג ABC
+
+
+ +
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-RTL.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-RTL.html new file mode 100644 index 000000000000..71c42ea3e426 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-RTL.html @@ -0,0 +1,17 @@ + + + + + Set and unset dir="auto" + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto1.html new file mode 100644 index 000000000000..2c1c525f97b8 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto1.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto2.html new file mode 100644 index 000000000000..f0400e0d0050 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto2.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto3.html new file mode 100644 index 000000000000..2cbf52716ccb --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto3.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto4.html new file mode 100644 index 000000000000..5bcec0648d48 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto4.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto5.html new file mode 100644 index 000000000000..a0423c2468cc --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto5.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto6.html new file mode 100644 index 000000000000..2574c867fa38 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto6.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir1.html new file mode 100644 index 000000000000..1913335b8b9c --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir1.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir2.html new file mode 100644 index 000000000000..596f1143af99 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir2.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir3.html new file mode 100644 index 000000000000..f22dd147d1ba --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir3.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir4.html new file mode 100644 index 000000000000..f876484e4beb --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir4.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="foopy" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir5.html new file mode 100644 index 000000000000..6da8dff2f35c --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir5.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir6.html new file mode 100644 index 000000000000..b63c0dd0d24f --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir6.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir7.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir7.html new file mode 100644 index 000000000000..e1b9d82c1cdb --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir7.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir8.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir8.html new file mode 100644 index 000000000000..9b80f42d0b02 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir8.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="foopy" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR1.html new file mode 100644 index 000000000000..e89fc792119e --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR1.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR2.html new file mode 100644 index 000000000000..5a8e4f122161 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR2.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR3.html new file mode 100644 index 000000000000..bbc5f8090044 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR3.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR4.html new file mode 100644 index 000000000000..08b21e09a458 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR4.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="foopy" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR5.html new file mode 100644 index 000000000000..cffe2556b84f --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR5.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR6.html new file mode 100644 index 000000000000..b54417b6f4e2 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR6.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR7.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR7.html new file mode 100644 index 000000000000..0baeb9fc6d32 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR7.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR8.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR8.html new file mode 100644 index 000000000000..ec1de35425e1 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR8.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="foopy" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir1.html new file mode 100644 index 000000000000..2040663c3590 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir1.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir2.html new file mode 100644 index 000000000000..f8c2e99a744a --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir2.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir3.html new file mode 100644 index 000000000000..c295012dba84 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir3.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir4.html new file mode 100644 index 000000000000..13e0e5fc8ff7 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir4.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="foopy" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir5.html new file mode 100644 index 000000000000..6dce96a6065c --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir5.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir6.html new file mode 100644 index 000000000000..2d9973fa1d33 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir6.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir7.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir7.html new file mode 100644 index 000000000000..dd1964e01ff6 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir7.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir8.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir8.html new file mode 100644 index 000000000000..b25d70232366 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir8.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="foopy" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL1.html new file mode 100644 index 000000000000..c5a9bf42df7d --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL1.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL2.html new file mode 100644 index 000000000000..b8ed6cda812a --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL2.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL3.html new file mode 100644 index 000000000000..528ffde04e6a --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL3.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL4.html new file mode 100644 index 000000000000..884c8fa852e2 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL4.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="foopy" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL5.html new file mode 100644 index 000000000000..5cf486c905bc --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL5.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL6.html new file mode 100644 index 000000000000..61c7331bd3b2 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL6.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL7.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL7.html new file mode 100644 index 000000000000..c4cc154cbe88 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL7.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL8.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL8.html new file mode 100644 index 000000000000..18e333978c8e --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL8.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="foopy" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto1.html new file mode 100644 index 000000000000..483d79fd518f --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto1.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto2.html new file mode 100644 index 000000000000..b0773e6f6c4d --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto2.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto3.html new file mode 100644 index 000000000000..77ce26cb3b1a --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto3.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto4.html new file mode 100644 index 000000000000..f8cabec1ee8f --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto4.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto5.html new file mode 100644 index 000000000000..20621a5a756e --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto5.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto6.html new file mode 100644 index 000000000000..c9e1b560f77f --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto6.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir1.html new file mode 100644 index 000000000000..a2ddd5292f54 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir1.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir2.html new file mode 100644 index 000000000000..87eb1181902a --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir2.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir3.html new file mode 100644 index 000000000000..17ec5b453b5d --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir3.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir4.html new file mode 100644 index 000000000000..b4c5ebc09194 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir4.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="foopy" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir5.html new file mode 100644 index 000000000000..1859e89bc6f3 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir5.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir6.html new file mode 100644 index 000000000000..06c3d71703ec --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir6.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir7.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir7.html new file mode 100644 index 000000000000..03239e88b701 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir7.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir8.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir8.html new file mode 100644 index 000000000000..fc353ac22f7c --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir8.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="foopy" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR1.html new file mode 100644 index 000000000000..52fcf96b37a1 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR1.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR2.html new file mode 100644 index 000000000000..074eeab1042b --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR2.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR3.html new file mode 100644 index 000000000000..2bb5ad2de54e --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR3.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR4.html new file mode 100644 index 000000000000..79372c6ed3f6 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR4.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="foopy" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR5.html new file mode 100644 index 000000000000..21201701535d --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR5.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR6.html new file mode 100644 index 000000000000..272d5f9fcea0 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR6.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR7.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR7.html new file mode 100644 index 000000000000..d1d1185d2d67 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR7.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR8.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR8.html new file mode 100644 index 000000000000..a6f9fa09a271 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR8.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="foopy" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir1.html new file mode 100644 index 000000000000..ba2bd8bab5db --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir1.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir2.html new file mode 100644 index 000000000000..5833b2e4adff --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir2.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir3.html new file mode 100644 index 000000000000..1a031d043819 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir3.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir4.html new file mode 100644 index 000000000000..53074850d35f --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir4.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="foopy" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir5.html new file mode 100644 index 000000000000..63fc1a746588 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir5.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir6.html new file mode 100644 index 000000000000..31af1459d2ea --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir6.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir7.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir7.html new file mode 100644 index 000000000000..5fd61d42e618 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir7.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir8.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir8.html new file mode 100644 index 000000000000..d388d5377fdc --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir8.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="foopy" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL1.html new file mode 100644 index 000000000000..45ee5c571375 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL1.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL2.html new file mode 100644 index 000000000000..0df2fc8de199 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL2.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL3.html new file mode 100644 index 000000000000..0dee370b6b37 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL3.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL4.html new file mode 100644 index 000000000000..dbfbe2125adb --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL4.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="foopy" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL5.html new file mode 100644 index 000000000000..1b401367c12a --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL5.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL6.html new file mode 100644 index 000000000000..d2c70793c25f --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL6.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL7.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL7.html new file mode 100644 index 000000000000..ca0153cc2f53 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL7.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL8.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL8.html new file mode 100644 index 000000000000..15b323976eed --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL8.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="foopy" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/reftest.list b/layout/reftests/bidi/dirAuto/reftest.list index fc032cd353d7..74aa0636fc68 100644 --- a/layout/reftests/bidi/dirAuto/reftest.list +++ b/layout/reftests/bidi/dirAuto/reftest.list @@ -2,6 +2,12 @@ == dir_auto-contained-bdi-R.html dir_auto-contained-bdi-R-ref.html == dir_auto-contained-dir-L.html dir_auto-contained-dir-L-ref.html == dir_auto-contained-dir-R.html dir_auto-contained-dir-R-ref.html +== dir_auto-set-contained-dir-L.html dir_auto-contained-dir-L-ref.html +== dir_auto-set-contained-dir-R.html dir_auto-contained-dir-R-ref.html +== dir_auto-set-contained-invalid-dir-L.html dir_auto-contained-dir-L-ref.html +== dir_auto-set-contained-invalid-dir-R.html dir_auto-contained-dir-R-ref.html +== dir_auto-unset-contained-dir-L.html dir_auto-unset-contained-dir-L-ref.html +== dir_auto-unset-contained-dir-R.html dir_auto-unset-contained-dir-R-ref.html == dir_auto-contained-dir_auto-L.html dir_auto-contained-dir_auto-L-ref.html == dir_auto-contained-dir_auto-R.html dir_auto-contained-dir_auto-R-ref.html == dir_auto-contained-L.html dir_auto-contained-L-ref.html @@ -49,3 +55,81 @@ == dir_auto-textarea-script-mixed.html dir_auto-textarea-script-mixed-ref.html == dir_auto-textarea-script-N-between-Rs.html dir_auto-textarea-script-N-between-Rs-ref.html == dir_auto-textarea-script-N-EN.html dir_auto-textarea-script-N-EN-ref.html +== dynamicDirAuto-setLTR-Auto1.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-Auto2.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-Auto3.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-Auto4.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-Auto5.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-Auto6.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-LTR1.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-LTR2.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-LTR3.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-LTR4.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-LTR5.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-LTR6.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-LTR7.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-LTR8.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-RTL1.html dynamicDirAuto-refLTR-RTL.html +== dynamicDirAuto-setLTR-RTL2.html dynamicDirAuto-refLTR-RTL.html +== dynamicDirAuto-setLTR-RTL3.html dynamicDirAuto-refLTR-RTL.html +== dynamicDirAuto-setLTR-RTL4.html dynamicDirAuto-refLTR-RTL.html +== dynamicDirAuto-setLTR-RTL5.html dynamicDirAuto-refLTR-RTL.html +== dynamicDirAuto-setLTR-RTL6.html dynamicDirAuto-refLTR-RTL.html +== dynamicDirAuto-setLTR-RTL7.html dynamicDirAuto-refLTR-RTL.html +== dynamicDirAuto-setLTR-RTL8.html dynamicDirAuto-refLTR-RTL.html +== dynamicDirAuto-setLTR-NoDir1.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-NoDir2.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-NoDir3.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-NoDir4.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-NoDir5.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-NoDir6.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-NoDir7.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-NoDir8.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-InvalidDir1.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-InvalidDir2.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-InvalidDir3.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-InvalidDir4.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-InvalidDir5.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-InvalidDir6.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-InvalidDir7.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setLTR-InvalidDir7.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-setRTL-Auto1.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-setRTL-Auto2.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-setRTL-Auto3.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-setRTL-Auto4.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-setRTL-Auto5.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-setRTL-Auto6.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-setRTL-LTR1.html dynamicDirAuto-refRTL-LTR.html +== dynamicDirAuto-setRTL-LTR2.html dynamicDirAuto-refRTL-LTR.html +== dynamicDirAuto-setRTL-LTR3.html dynamicDirAuto-refRTL-LTR.html +== dynamicDirAuto-setRTL-LTR4.html dynamicDirAuto-refRTL-LTR.html +== dynamicDirAuto-setRTL-LTR5.html dynamicDirAuto-refRTL-LTR.html +== dynamicDirAuto-setRTL-LTR6.html dynamicDirAuto-refRTL-LTR.html +== dynamicDirAuto-setRTL-LTR7.html dynamicDirAuto-refRTL-LTR.html +== dynamicDirAuto-setRTL-LTR8.html dynamicDirAuto-refRTL-LTR.html +== dynamicDirAuto-setRTL-RTL1.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-setRTL-RTL2.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-setRTL-RTL3.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-setRTL-RTL4.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-setRTL-RTL5.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-setRTL-RTL6.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-setRTL-RTL7.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-setRTL-RTL8.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-setRTL-NoDir1.html dynamicDirAuto-refRTL-NoDir.html +== dynamicDirAuto-setRTL-NoDir2.html dynamicDirAuto-refRTL-NoDir.html +== dynamicDirAuto-setRTL-NoDir3.html dynamicDirAuto-refRTL-NoDir.html +== dynamicDirAuto-setRTL-NoDir4.html dynamicDirAuto-refRTL-NoDir.html +== dynamicDirAuto-setRTL-NoDir5.html dynamicDirAuto-refRTL-NoDir.html +== dynamicDirAuto-setRTL-NoDir6.html dynamicDirAuto-refRTL-NoDir.html +== dynamicDirAuto-setRTL-NoDir7.html dynamicDirAuto-refRTL-NoDir.html +== dynamicDirAuto-setRTL-NoDir8.html dynamicDirAuto-refRTL-NoDir.html +== dynamicDirAuto-setRTL-InvalidDir1.html dynamicDirAuto-refRTL-NoDir.html +== dynamicDirAuto-setRTL-InvalidDir2.html dynamicDirAuto-refRTL-NoDir.html +== dynamicDirAuto-setRTL-InvalidDir3.html dynamicDirAuto-refRTL-NoDir.html +== dynamicDirAuto-setRTL-InvalidDir4.html dynamicDirAuto-refRTL-NoDir.html +== dynamicDirAuto-setRTL-InvalidDir5.html dynamicDirAuto-refRTL-NoDir.html +== dynamicDirAuto-setRTL-InvalidDir6.html dynamicDirAuto-refRTL-NoDir.html +== dynamicDirAuto-setRTL-InvalidDir7.html dynamicDirAuto-refRTL-NoDir.html +== dynamicDirAuto-setRTL-InvalidDir8.html dynamicDirAuto-refRTL-NoDir.html +== dynamicDirAuto-addLTR-Auto.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-addRTL-Auto.html dynamicDirAuto-refRTL-RTL.html diff --git a/layout/reftests/bidi/dirAuto/setDir.js b/layout/reftests/bidi/dirAuto/setDir.js new file mode 100644 index 000000000000..f96dcfc097a1 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/setDir.js @@ -0,0 +1,61 @@ +function setAllDir(value) +{ + for (var i = 0; ; ++i) { + try { + theElement = document.getElementById("set" + i); + theElement.dir = value; + } catch(e) { + break; + } + } +} + +function setAllDirAttribute(value) +{ + for (var i = 0; ; ++i) { + try { + theElement = document.getElementById("set" + i); + theElement.setAttribute("dir", value); + } catch(e) { + break; + } + } +} + +function removeAllDirAttribute() +{ + for (var i = 0; ; ++i) { + try { + theElement = document.getElementById("set" + i); + theElement.removeAttribute("dir"); + } catch(e) { + break; + } + } +} + +function addOneElement(innerHTML) +{ + var container = document.getElementById("container"); + var elem = document.createElement("div"); + elem.innerHTML = innerHTML; + container.appendChild(elem); +} + +function addLTRAutoElements() +{ + addOneElement(''); + addOneElement('ABC אבג'); + addOneElement(''); + addOneElement(''); + addOneElement('ABC אבג'); +} + +function addRTLAutoElements() +{ + addOneElement(''); + addOneElement('אבג ABC'); + addOneElement(''); + addOneElement(''); + addOneElement('אבג ABC'); +} From 4688933342909f7f23814ddb2534f27153a71468 Mon Sep 17 00:00:00 2001 From: Simon Montagu Date: Tue, 20 Nov 2012 06:21:15 -0800 Subject: [PATCH 09/75] More tests for bug 548206, r=ehsan --- .../dynamicDirAuto-ChangeText-LTR1.html | 18 +++ .../dynamicDirAuto-ChangeText-LTR10.html | 18 +++ .../dynamicDirAuto-ChangeText-LTR2.html | 18 +++ .../dynamicDirAuto-ChangeText-LTR3.html | 18 +++ .../dynamicDirAuto-ChangeText-LTR4.html | 18 +++ .../dynamicDirAuto-ChangeText-LTR5.html | 18 +++ .../dynamicDirAuto-ChangeText-LTR6.html | 18 +++ .../dynamicDirAuto-ChangeText-LTR7.html | 18 +++ .../dynamicDirAuto-ChangeText-LTR8.html | 18 +++ .../dynamicDirAuto-ChangeText-LTR9.html | 18 +++ .../dynamicDirAuto-ChangeText-RTL1.html | 18 +++ .../dynamicDirAuto-ChangeText-RTL10.html | 18 +++ .../dynamicDirAuto-ChangeText-RTL2.html | 18 +++ .../dynamicDirAuto-ChangeText-RTL3.html | 18 +++ .../dynamicDirAuto-ChangeText-RTL4.html | 18 +++ .../dynamicDirAuto-ChangeText-RTL5.html | 18 +++ .../dynamicDirAuto-ChangeText-RTL6.html | 18 +++ .../dynamicDirAuto-ChangeText-RTL7.html | 18 +++ .../dynamicDirAuto-ChangeText-RTL8.html | 18 +++ .../dynamicDirAuto-ChangeText-RTL9.html | 18 +++ .../dynamicDirAuto-DeleteText-LTR1.html | 18 +++ .../dynamicDirAuto-DeleteText-LTR2.html | 18 +++ .../dynamicDirAuto-DeleteText-LTR3.html | 18 +++ .../dynamicDirAuto-DeleteText-RTL1.html | 18 +++ .../dynamicDirAuto-DeleteText-RTL2.html | 18 +++ .../dynamicDirAuto-DeleteText-RTL3.html | 18 +++ layout/reftests/bidi/dirAuto/reftest.list | 26 ++++ layout/reftests/bidi/dirAuto/setDir.js | 138 ++++++++++++++++++ 28 files changed, 632 insertions(+) create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR1.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR10.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR2.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR3.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR4.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR5.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR6.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR7.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR8.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR9.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL1.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL10.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL2.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL3.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL4.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL5.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL6.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL7.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL8.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL9.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR1.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR2.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR3.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL1.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL2.html create mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL3.html diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR1.html new file mode 100644 index 000000000000..223aa56e6dbf --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR1.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR10.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR10.html new file mode 100644 index 000000000000..bd3dad92a84b --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR10.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
...
+
+
+
...
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR2.html new file mode 100644 index 000000000000..f9af6b961fdb --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR2.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
...
+
+
+
...
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR3.html new file mode 100644 index 000000000000..2d07131d57b9 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR3.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
­
+
+
+
­
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR4.html new file mode 100644 index 000000000000..38801d2a47c7 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR4.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
­
+
+
+
­
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR5.html new file mode 100644 index 000000000000..7cd5db77c461 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR5.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
­
+
+
+
­
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR6.html new file mode 100644 index 000000000000..b66f5e30612b --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR6.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
­
+
+
+
­
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR7.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR7.html new file mode 100644 index 000000000000..461118996689 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR7.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR8.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR8.html new file mode 100644 index 000000000000..2fb2148f994e --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR8.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
...
+
+
+
...
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR9.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR9.html new file mode 100644 index 000000000000..087d5104fc98 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR9.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
אבג ABC
+
+
+
אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL1.html new file mode 100644 index 000000000000..361fcd1e725b --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL1.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL10.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL10.html new file mode 100644 index 000000000000..01e6f6bcba64 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL10.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
...
+
+
+
...
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL2.html new file mode 100644 index 000000000000..f243dec4fa3a --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL2.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
...
+
+
+
...
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL3.html new file mode 100644 index 000000000000..0aaedfe4a1b1 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL3.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
­
+
+
+
­
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL4.html new file mode 100644 index 000000000000..60df2980c6fe --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL4.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
­
+
+
+
­
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL5.html new file mode 100644 index 000000000000..36d2940e585b --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL5.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
­
+
+
+
­
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL6.html new file mode 100644 index 000000000000..440945bb5875 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL6.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
­
+
+
+
­
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL7.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL7.html new file mode 100644 index 000000000000..032c2f4eb11c --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL7.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL8.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL8.html new file mode 100644 index 000000000000..9c1da6b0fc7a --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL8.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
...
+
+
+
...
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL9.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL9.html new file mode 100644 index 000000000000..b7c4c36533cf --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL9.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
ABC אבג
+
+
+
ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR1.html new file mode 100644 index 000000000000..4ba7a037f638 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR1.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
DEF ABC אבג
+
+
+
DEF ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR2.html new file mode 100644 index 000000000000..4bea44d83be8 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR2.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
גדה ABC אבג
+
+
+
גדה ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR3.html new file mode 100644 index 000000000000..2c16829530ff --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR3.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
... ABC אבג
+
+
+
... ABC אבג
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL1.html new file mode 100644 index 000000000000..ab08388b8206 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL1.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
DEF אבג ABC
+
+
+
DEF אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL2.html new file mode 100644 index 000000000000..477e155a0bde --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL2.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
גדה אבג ABC
+
+
+
גדה אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL3.html new file mode 100644 index 000000000000..cf4069567e05 --- /dev/null +++ b/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL3.html @@ -0,0 +1,18 @@ + + + + + Set and unset dir="auto" + + + + +
+
... אבג ABC
+
+
+
... אבג ABC
+ + diff --git a/layout/reftests/bidi/dirAuto/reftest.list b/layout/reftests/bidi/dirAuto/reftest.list index 74aa0636fc68..a280551522b1 100644 --- a/layout/reftests/bidi/dirAuto/reftest.list +++ b/layout/reftests/bidi/dirAuto/reftest.list @@ -133,3 +133,29 @@ == dynamicDirAuto-setRTL-InvalidDir8.html dynamicDirAuto-refRTL-NoDir.html == dynamicDirAuto-addLTR-Auto.html dynamicDirAuto-refLTR-LTR.html == dynamicDirAuto-addRTL-Auto.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-ChangeText-LTR1.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-ChangeText-LTR2.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-ChangeText-LTR3.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-ChangeText-LTR4.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-ChangeText-LTR5.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-ChangeText-LTR6.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-ChangeText-LTR7.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-ChangeText-LTR8.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-ChangeText-LTR9.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-ChangeText-LTR10.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-ChangeText-RTL1.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-ChangeText-RTL2.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-ChangeText-RTL3.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-ChangeText-RTL4.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-ChangeText-RTL5.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-ChangeText-RTL6.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-ChangeText-RTL7.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-ChangeText-RTL8.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-ChangeText-RTL9.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-ChangeText-RTL10.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-DeleteText-LTR1.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-DeleteText-LTR2.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-DeleteText-LTR3.html dynamicDirAuto-refLTR-LTR.html +== dynamicDirAuto-DeleteText-RTL1.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-DeleteText-RTL2.html dynamicDirAuto-refRTL-RTL.html +== dynamicDirAuto-DeleteText-RTL3.html dynamicDirAuto-refRTL-RTL.html diff --git a/layout/reftests/bidi/dirAuto/setDir.js b/layout/reftests/bidi/dirAuto/setDir.js index f96dcfc097a1..19a9fb66953b 100644 --- a/layout/reftests/bidi/dirAuto/setDir.js +++ b/layout/reftests/bidi/dirAuto/setDir.js @@ -59,3 +59,141 @@ function addRTLAutoElements() addOneElement(''); addOneElement('אבג ABC'); } + +function setAllTextValuesTo(newText) +{ + for (var i = 0; ; ++i) { + theElement = document.getElementById("set" + i); + if (!theElement) { + break; + } + if (theElement.tagName == "INPUT" || + theElement.tagName == "TEXTAREA") { + theElement.value = newText; + } else { + theElement.firstChild.textContent = newText; + } + } +} + +function setAllTextDefaultValuesTo(newText) +{ + for (var i = 0; ; ++i) { + theElement = document.getElementById("set" + i); + if (!theElement) { + break; + } + if (theElement.tagName == "INPUT" || + theElement.tagName == "TEXTAREA") { + theElement.defaultValue = newText; + } else { + theElement.firstChild.textContent = newText; + } + } +} + +function setAllTextChildrenTo(newText) +{ + for (var i = 0; ; ++i) { + theElement = document.getElementById("set" + i); + if (!theElement) { + break; + } + if (theElement.tagName == "INPUT") { + theElement.value = newText; + } else { + theElement.firstChild.textContent = newText; + } + } +} + +function appendTextFromArray(textArray) +{ + for (var i = 0; ; ++i) { + theElement = document.getElementById("set" + i); + if (!theElement) { + break; + } + for (var j = 0; j < textArray.length; ++j) { + if (theElement.tagName == "INPUT") { + theElement.value += textArray[j]; + } else { + var textNode = document.createTextNode(textArray[j]); + theElement.appendChild(textNode); + } + } + } +} + +function appendSpansFromArray(textArray) +{ + for (var i = 0; ; ++i) { + theElement = document.getElementById("set" + i); + if (!theElement) { + break; + } + for (var j = 0; j < textArray.length; ++j) { + // fake the result for elements that can't have markup content + if (theElement.tagName == "INPUT") { + theElement.value += textArray[j]; + } else if (theElement.tagName == "TEXTAREA") { + theElement.innerHTML += textArray[j]; + } else { + var span = document.createElement("span"); + span.innerHTML = textArray[j]; + theElement.appendChild(span); + } + } + } +} + +function prependTextFromArray(textArray) +{ + for (var i = 0; ; ++i) { + theElement = document.getElementById("set" + i); + if (!theElement) { + break; + } + for (var j = 0; j < textArray.length; ++j) { + if (theElement.tagName == "INPUT") { + theElement.value = textArray[j] + theElement.value; + } else { + var textNode = document.createTextNode(textArray[j]); + theElement.insertBefore(textNode, theElement.firstChild); + } + } + } +} + +function prependSpansFromArray(textArray) +{ + for (var i = 0; ; ++i) { + theElement = document.getElementById("set" + i); + if (!theElement) { + break; + } + for (var j = 0; j < textArray.length; ++j) { + // fake the result for elements that can't have markup content + if (theElement.tagName == "INPUT") { + theElement.value = textArray[j] + theElement.value; + } else if (theElement.tagName == "TEXTAREA") { + theElement.innerHTML = textArray[j] + theElement.innerHTML; + } else { + var span = document.createElement("span"); + span.innerHTML = textArray[j]; + theElement.insertBefore(span, theElement.firstChild); + } + } + } +} + +function removeElements() +{ + for (var i = 0; ; ++i) { + theElement = document.getElementById("set" + i); + if (!theElement) { + break; + } + theElement.parentNode.removeChild(theElement); + } +} From ef21364c12fb6da8e3affc62eb8470f469e6f8b3 Mon Sep 17 00:00:00 2001 From: Simon Montagu Date: Tue, 20 Nov 2012 06:21:15 -0800 Subject: [PATCH 10/75] Implementation of HTML5 dir=auto. Bug 548206, r=ehsan, peterv --- content/base/public/DirectionalityUtils.h | 92 +- content/base/public/Element.h | 24 +- content/base/public/nsIDocument.h | 4 +- content/base/public/nsINode.h | 61 +- content/base/src/DirectionalityUtils.cpp | 810 +++++++++++++++++- content/base/src/Element.cpp | 39 +- content/base/src/nsDocument.cpp | 1 - content/base/src/nsDocument.h | 2 +- content/base/src/nsGenericDOMDataNode.cpp | 5 + content/base/src/nsGkAtomList.h | 2 + content/base/src/nsTextNode.cpp | 23 + content/base/src/nsTextNode.h | 6 + .../html/content/src/nsGenericHTMLElement.cpp | 50 +- .../html/content/src/nsGenericHTMLElement.h | 4 + .../html/content/src/nsHTMLInputElement.cpp | 30 + content/html/content/src/nsHTMLInputElement.h | 2 + .../html/content/src/nsHTMLUnknownElement.h | 3 + layout/style/html.css | 3 + 18 files changed, 1120 insertions(+), 41 deletions(-) diff --git a/content/base/public/DirectionalityUtils.h b/content/base/public/DirectionalityUtils.h index 195f7009de2f..9d4a4000dbff 100644 --- a/content/base/public/DirectionalityUtils.h +++ b/content/base/public/DirectionalityUtils.h @@ -7,9 +7,15 @@ #ifndef DirectionalityUtils_h___ #define DirectionalityUtils_h___ +#include "prtypes.h" +#include "mozilla/StandardInteger.h" + class nsIContent; class nsIDocument; class nsINode; +class nsAString; +class nsAttrValue; +class nsTextNode; namespace mozilla { namespace dom { @@ -19,12 +25,11 @@ class Element; namespace mozilla { -namespace directionality { - enum Directionality { - eDir_NotSet = 0, - eDir_RTL = 1, - eDir_LTR = 2 + eDir_NotSet, + eDir_RTL, + eDir_LTR, + eDir_Auto }; /** @@ -44,11 +49,84 @@ Directionality RecomputeDirectionality(mozilla::dom::Element* aElement, * of setting the dir attribute, rather than walking up the ancestor tree in * the much more common case of getting the element's directionality. */ -void SetDirectionalityOnDescendants(mozilla::dom::Element* aElement, +void SetDirectionalityOnDescendants(mozilla::dom::Element* aElement, Directionality aDir, bool aNotify = true); -} // end namespace directionality +/** + * Walk the descendants of a node in tree order and, for any text node + * descendant that determines the directionality of some element and is not a + * descendant of another descendant of the original node with dir=auto, + * redetermine that element's directionality + */ +void WalkDescendantsResetAutoDirection(mozilla::dom::Element* aElement); + +/** + * After setting dir=auto on an element, walk its descendants in tree order. + * If the node doesn't have the NODE_ANCESTOR_HAS_DIR_AUTO flag, set the + * NODE_ANCESTOR_HAS_DIR_AUTO flag on all of its descendants. + * Resolve the directionality of the element by the "downward propagation + * algorithm" (defined in section 3 in the comments at the beginning of + * DirectionalityUtils.cpp) + */ +void WalkDescendantsSetDirAuto(mozilla::dom::Element* aElement, + bool aNotify = true); + +/** + * After unsetting dir=auto on an element, walk its descendants in tree order, + * skipping any that have dir=auto themselves, and unset the + * NODE_ANCESTOR_HAS_DIR_AUTO flag + */ +void WalkDescendantsClearAncestorDirAuto(mozilla::dom::Element* aElement); + +/** + * Walk the parent chain of a text node whose dir attribute has been removed and + * reset the direction of any of its ancestors which have dir=auto and whose + * directionality is determined by a text node descendant. + */ +void WalkAncestorsResetAutoDirection(mozilla::dom::Element* aElement, + bool aNotify = true); + +/** + * When the contents of a text node have changed, deal with any elements whose + * directionality needs to change + */ +void SetDirectionFromChangedTextNode(nsIContent* aTextNode, uint32_t aOffset, + const PRUnichar* aBuffer, uint32_t aLength, + bool aNotify); + +/** + * When a text node is appended to an element, find any ancestors with dir=auto + * whose directionality will be determined by the text node + */ +void SetDirectionFromNewTextNode(nsTextNode* aTextNode); + +/** + * When a text node is removed from a document, find any ancestors whose + * directionality it determined and redetermine their directionality + */ +void ResetDirectionSetByTextNode(nsTextNode* aTextNode); + +/** + * Set the directionality of an element according to the directionality of the + * text in aValue + */ +void SetDirectionalityFromValue(mozilla::dom::Element* aElement, + const nsAString& aValue, + bool aNotify); + +/** + * Called when setting the dir attribute on an element, immediately after + * AfterSetAttr. This is instead of using BeforeSetAttr or AfterSetAttr, because + * in AfterSetAttr we don't know the old value, so we can't identify all cases + * where we need to walk up or down the document tree and reset the direction; + * and in BeforeSetAttr we can't do the walk because this element hasn't had the + * value set yet so the results will be wrong. + */ +void OnSetDirAttr(mozilla::dom::Element* aElement, + const nsAttrValue* aNewValue, + bool hadValidDir, + bool aNotify); } // end namespace mozilla diff --git a/content/base/public/Element.h b/content/base/public/Element.h index b4800755ce9d..8ab3e2557e8e 100644 --- a/content/base/public/Element.h +++ b/content/base/public/Element.h @@ -282,34 +282,33 @@ public: */ virtual nsIAtom *GetClassAttributeName() const; - inline directionality::Directionality GetDirectionality() const { + inline Directionality GetDirectionality() const { if (HasFlag(NODE_HAS_DIRECTION_RTL)) { - return directionality::eDir_RTL; + return eDir_RTL; } if (HasFlag(NODE_HAS_DIRECTION_LTR)) { - return directionality::eDir_LTR; + return eDir_LTR; } - return directionality::eDir_NotSet; + return eDir_NotSet; } - inline void SetDirectionality(directionality::Directionality aDir, - bool aNotify) { + inline void SetDirectionality(Directionality aDir, bool aNotify) { UnsetFlags(NODE_ALL_DIRECTION_FLAGS); if (!aNotify) { RemoveStatesSilently(DIRECTION_STATES); } switch (aDir) { - case (directionality::eDir_RTL): + case (eDir_RTL): SetFlags(NODE_HAS_DIRECTION_RTL); if (!aNotify) { AddStatesSilently(NS_EVENT_STATE_RTL); } break; - case(directionality::eDir_LTR): + case(eDir_LTR): SetFlags(NODE_HAS_DIRECTION_LTR); if (!aNotify) { AddStatesSilently(NS_EVENT_STATE_LTR); @@ -332,6 +331,15 @@ public: bool GetBindingURL(nsIDocument *aDocument, css::URLValue **aResult); + // The bdi element defaults to dir=auto if it has no dir attribute set. + // Other elements will only have dir=auto if they have an explicit dir=auto, + // which will mean that HasValidDir() returns true but HasFixedDir() returns + // false + inline bool HasDirAuto() const { + return (!HasFixedDir() && + (HasValidDir() || NodeInfo()->Equals(nsGkAtoms::bdi))); + } + protected: /** * Method to get the _intrinsic_ content state of this element. This is the diff --git a/content/base/public/nsIDocument.h b/content/base/public/nsIDocument.h index d37b1b5de01c..3fc21aeed2f2 100644 --- a/content/base/public/nsIDocument.h +++ b/content/base/public/nsIDocument.h @@ -419,7 +419,7 @@ public: mSandboxFlags = sandboxFlags; } - inline mozilla::directionality::Directionality GetDocumentDirectionality() { + inline mozilla::Directionality GetDocumentDirectionality() { return mDirectionality; } @@ -1916,7 +1916,7 @@ protected: uint32_t mSandboxFlags; // The root directionality of this document. - mozilla::directionality::Directionality mDirectionality; + mozilla::Directionality mDirectionality; nsCString mContentLanguage; private: diff --git a/content/base/public/nsINode.h b/content/base/public/nsINode.h index 5bbab1d1950d..2775c08a1c10 100644 --- a/content/base/public/nsINode.h +++ b/content/base/public/nsINode.h @@ -1295,8 +1295,21 @@ private: NodeIsContent, // Set if the node has animations or transitions ElementHasAnimations, - // Set if node has a dir attribute with a valid value (ltr or rtl) + // Set if node has a dir attribute with a valid value (ltr, rtl, or auto) NodeHasValidDirAttribute, + // Set if node has a dir attribute with a fixed value (ltr or rtl, NOT auto) + NodeHasFixedDir, + // Set if the node has dir=auto and has a property pointing to the text + // node that determines its direction + NodeHasDirAutoSet, + // Set if the node is a text node descendant of a node with dir=auto + // and has a TextNodeDirectionalityMap property listing the elements whose + // direction it determines. + NodeHasTextNodeDirectionalityMap, + // Set if the node has dir=auto. + NodeHasDirAuto, + // Set if a node in the node's parent chain has dir=auto. + NodeAncestorHasDirAuto, // Guard value BooleanFlagCount }; @@ -1367,6 +1380,52 @@ public: void SetHasValidDir() { SetBoolFlag(NodeHasValidDirAttribute); } void ClearHasValidDir() { ClearBoolFlag(NodeHasValidDirAttribute); } bool HasValidDir() const { return GetBoolFlag(NodeHasValidDirAttribute); } + void SetHasFixedDir() { + MOZ_ASSERT(NodeType() != nsIDOMNode::TEXT_NODE, + "SetHasFixedDir on text node"); + SetBoolFlag(NodeHasFixedDir); + } + void ClearHasFixedDir() { + MOZ_ASSERT(NodeType() != nsIDOMNode::TEXT_NODE, + "ClearHasFixedDir on text node"); + ClearBoolFlag(NodeHasFixedDir); + } + bool HasFixedDir() const { return GetBoolFlag(NodeHasFixedDir); } + void SetHasDirAutoSet() { + MOZ_ASSERT(NodeType() != nsIDOMNode::TEXT_NODE, + "SetHasDirAutoSet on text node"); + SetBoolFlag(NodeHasDirAutoSet); + } + void ClearHasDirAutoSet() { + MOZ_ASSERT(NodeType() != nsIDOMNode::TEXT_NODE, + "ClearHasDirAutoSet on text node"); + ClearBoolFlag(NodeHasDirAutoSet); + } + bool HasDirAutoSet() const + { return GetBoolFlag(NodeHasDirAutoSet); } + void SetHasTextNodeDirectionalityMap() { + MOZ_ASSERT(NodeType() == nsIDOMNode::TEXT_NODE, + "SetHasTextNodeDirectionalityMap on non-text node"); + SetBoolFlag(NodeHasTextNodeDirectionalityMap); + } + void ClearHasTextNodeDirectionalityMap() { + MOZ_ASSERT(NodeType() == nsIDOMNode::TEXT_NODE, + "ClearHasTextNodeDirectionalityMap on non-text node"); + ClearBoolFlag(NodeHasTextNodeDirectionalityMap); + } + bool HasTextNodeDirectionalityMap() const + { return GetBoolFlag(NodeHasTextNodeDirectionalityMap); } + + void SetHasDirAuto() { SetBoolFlag(NodeHasDirAuto); } + void ClearHasDirAuto() { ClearBoolFlag(NodeHasDirAuto); } + bool HasDirAuto() const { return GetBoolFlag(NodeHasDirAuto); } + + void SetAncestorHasDirAuto() { SetBoolFlag(NodeAncestorHasDirAuto); } + void ClearAncestorHasDirAuto() { ClearBoolFlag(NodeAncestorHasDirAuto); } + bool AncestorHasDirAuto() const { return GetBoolFlag(NodeAncestorHasDirAuto); } + + bool NodeOrAncestorHasDirAuto() const + { return HasDirAuto() || AncestorHasDirAuto(); } protected: void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); } void SetInDocument() { SetBoolFlag(IsInDocument); } diff --git a/content/base/src/DirectionalityUtils.cpp b/content/base/src/DirectionalityUtils.cpp index 8523e25a333a..59a565cdb780 100644 --- a/content/base/src/DirectionalityUtils.cpp +++ b/content/base/src/DirectionalityUtils.cpp @@ -4,25 +4,554 @@ * 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/. */ +/* + Implementation description from https://etherpad.mozilla.org/dir-auto + + Static case + =========== + When we see a new content node with @dir=auto from the parser, we set the + NodeHasDirAuto flag on the node. We won't have enough information to + decide the directionality of the node at this point. + + When we bind a new content node to the document, if its parent has either of + the NodeAncestorHasDirAuto or NodeHasDirAuto flags, we set the + NodeAncestorHasDirAuto flag on the node. + + When a new input with @type=text/search/tel/url/email and @dir=auto is added + from the parser, we resolve the directionality based on its @value. + + When a new text node with non-neutral content is appended to a textarea + element with NodeHasDirAuto, if the directionality of the textarea element + is still unresolved, it is resolved based on the value of the text node. + Elements with unresolved directionality behave as LTR. + + When a new text node with non-neutral content is appended to an element that + is not a textarea but has either of the NodeAncestorHasDirAuto or + NodeHasDirAuto flags, we walk up the parent chain while the + NodeAncestorHasDirAuto flag is present, and when we reach an element with + NodeHasDirAuto and no resolved directionality, we resolve the directionality + based on the contents of the text node and cease walking the parent chain. + Note that we should ignore elements with NodeHasDirAuto with resolved + directionality, so that the second text node in this example tree doesn't + affect the directionality of the div: + +
+ foo + بار +
+ + The parent chain walk will be aborted if we hit a script or style element, or + if we hit an element with @dir=ltr or @dir=rtl. + + I will call this algorithm "upward propagation". + + Each text node should maintain a list of elements which have their + directionality determined by the first strong character of that text node. + This is useful to make dynamic changes more efficient. One way to implement + this is to have a per-document hash table mapping a text node to a set of + elements. I'll call this data structure TextNodeDirectionalityMap. The + algorithm for appending a new text node above needs to update this data + structure. + + *IMPLEMENTATION NOTE* + In practice, the implementation uses two per-node properties: + + dirAutoSetBy, which is set on a node with auto-directionality, and points to + the textnode that contains the strong character which determines the + directionality of the node. + + textNodeDirectionalityMap, which is set on a text node and points to a hash + table listing the nodes whose directionality is determined by the text node. + + Handling dynamic changes + ======================== + + We need to handle the following cases: + + 1. When the value of an input element with @type=text/search/tel/url/email is + changed, if it has NodeHasDirAuto, we update the resolved directionality. + + 2. When the dir attribute is changed from something else (including the case + where it doesn't exist) to auto on a textarea or an input element with + @type=text/search/tel/url/email, we set the NodeHasDirAuto flag and resolve + the directionality based on the value of the element. + + 3. When the dir attribute is changed from something else (including the case + where it doesn't exist) to auto on any element except case 1 above and the bdi + element, we run the following algorithm: + * We set the NodeHasDirAuto flag. + * If the element doesn't have the NodeAncestorHasDirAuto flag, we set the + NodeAncestorHasDirAuto flag on all of its child nodes. (Note that if the + element does have NodeAncestorHasDirAuto, all of its children should + already have this flag too. We can assert this in debug builds.) + * To resolve the directionality of the element, we run the algorithm explained + in http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#the-dir-attribute + (I'll call this the "downward propagation algorithm".) by walking the child + subtree in tree order. Note that an element with @dir=auto should not affect + other elements in its document with @dir=auto. So there is no need to walk up + the parent chain in this case. TextNodeDirectionalityMap needs to be updated + as appropriate. + + 3a. When the dir attribute is set to any valid value on an element that didn't + have a valid dir attribute before, this means that any descendant of that + element will not affect the directionality of any of its ancestors. So we need + to check whether any text node descendants of the element are listed in + TextNodeDirectionalityMap, and whether the elements whose direction they set + are ancestors of the element. If so, we need to rerun the downward propagation + algorithm for those ancestors. + + 4. When the dir attribute is changed from auto to something else (including + the case where it gets removed) on a textarea or an input element with + @type=text/search/tel/url/email, we unset the NodeHasDirAuto flag and + resolve the directionality based on the directionality of the value of the @dir + attribute on element itself or its parent element. + + 5. When the dir attribute is changed from auto to something else (including the + case where it gets removed) on any element except case 4 above and the bdi + element, we run the following algorithm: + * We unset the NodeHasDirAuto flag. + * If the element does not have the NodeAncestorHasDirAuto flag, we unset + the NodeAncestorHasDirAuto flag on all of its child nodes, except those + who are a descendant of another element with NodeHasDirAuto. (Note that if + the element has the NodeAncestorHasDirAuto flag, all of its child nodes + should still retain the same flag.) + * We resolve the directionality of the element based on the value of the @dir + attribute on the element itself or its parent element. + TextNodeDirectionalityMap needs to be updated as appropriate. + + 5a. When the dir attribute is removed or set to an invalid value on any + element (except a bdi element) with the NodeAncestorHasDirAuto flag which + previously had a valid dir attribute, it might have a text node descendant that + did not previously affect the directionality of any of its ancestors but should + now begin to affect them. + We run the following algorithm: + * Walk up the parent chain from the element. + * For any element that appears in the TextNodeDirectionalityMap, remove the + element from the map and rerun the downward propagation algorithm + (see section 3). + * If we reach an element without either of the NodeHasDirAuto or + NodeAncestorHasDirAuto flags, abort the parent chain walk. + + 6. When an element with @dir=auto is added to the document, we should handle it + similar to the case 2/3 above. + + 7. When an element with NodeHasDirAuto or NodeAncestorHasDirAuto is + removed from the document, we should handle it similar to the case 4/5 above, + except that we don't need to handle anything in the child subtree. We should + also remove all of the occurrences of that node and its descendants from + TextNodeDirectionalityMap. (This is the conceptual description of what needs to + happen but in the implementation UnbindFromTree is going to be called on all of + the descendants so we don't need to descend into the child subtree). + + 8. When the contents of a text node is changed either from script or by the + user, we need to run the following algorithm: + * If the change has happened after the first character with strong + directionality in the text node, do nothing. + * If the text node is a child of a bdi, script or style element, do nothing. + * If the text node belongs to a textarea with NodeHasDirAuto, we need to + update the directionality of the textarea. + * Grab a list of elements affected by this text node from + TextNodeDirectionalityMap and re-resolve the directionality of each one of them + based on the new contents of the text node. + * If the text node does not exist in TextNodeDirectionalityMap, and it has the + NodeAncestorHasDirAuto flag set, this could potentially be a text node + which is going to start affecting the directionality of its parent @dir=auto + elements. In this case, we need to fall back to the (potentially expensive) + "upward propagation algorithm". The TextNodeDirectionalityMap data structure + needs to be update during this algorithm. + * If the new contents of the text node do not have any strong characters, and + the old contents used to, and the text node used to exist in + TextNodeDirectionalityMap and it has the NodeAncestorHasDirAuto flag set, + the elements associated with this text node inside TextNodeDirectionalityMap + will now get their directionality from another text node. In this case, for + each element in the list retrieved from TextNodeDirectionalityMap, run the + downward propagation algorithm (section 3), and remove the text node from + TextNodeDirectionalityMap. + + 9. When a new text node is injected into a document, we need to run the + following algorithm: + * If the contents of the text node do not have any characters with strong + direction, do nothing. + * If the text node is a child of a bdi, script or style element, do nothing. + * If the text node is appended to a textarea element with NodeHasDirAuto, we + need to update the directionality of the textarea. + * If the text node has NodeAncestorHasDirAuto, we need to run the "upward + propagation algorithm". The TextNodeDirectionalityMap data structure needs to + be update during this algorithm. + + 10. When a text node is removed from a document, we need to run the following + algorithm: + * If the contents of the text node do not have any characters with strong + direction, do nothing. + * If the text node is a child of a bdi, script or style element, do nothing. + * If the text node is removed from a textarea element with NodeHasDirAuto, + set the directionality to "ltr". (This is what the spec currently says, but I'm + filing a spec bug to get it fixed -- the directionality should depend on the + parent element here.) + * If the text node has NodeAncestorHasDirAuto, we need to look at the list + of elements being affected by this text node from TextNodeDirectionalityMap, + run the "downward propagation algorithm" (section 3) for each one of them, + while updating TextNodeDirectionalityMap along the way. + + 11. If the value of the @dir attribute on a bdi element is changed to an + invalid value (or if it's removed), determine the new directionality similar + to the case 3 above. + + == Implemention Notes == + When a new node gets bound to the tree, the BindToTree function gets called. + The reverse case is UnbindFromTree. + When the contents of a text node change, nsGenericDOMDataNode::SetTextInternal + gets called. + */ + #include "mozilla/dom/DirectionalityUtils.h" #include "nsINode.h" #include "nsIContent.h" #include "nsIDocument.h" #include "mozilla/dom/Element.h" -#include "nsIDOMNodeFilter.h" -#include "nsTreeWalker.h" #include "nsIDOMHTMLDocument.h" - +#include "nsUnicodeProperties.h" +#include "nsTextFragment.h" +#include "nsAttrValue.h" +#include "nsContentUtils.h" +#include "nsTextNode.h" +#include "nsCheapSets.h" namespace mozilla { -namespace directionality { - typedef mozilla::dom::Element Element; +/** + * Returns true if aNode is one of the elements whose text content should not + * affect its own direction, nor the direction of ancestors with dir=auto. + * + * Note that this does not include , whose content does affect its own + * direction when it has dir=auto (which it has by default), so one needs to + * test for it separately. + * It *does* include textarea, because even if a textarea has dir=auto, it has + * unicode-bidi: plaintext and is handled automatically in bidi resolution. + */ +static bool +DoesNotParticipateInAutoDirection(const Element* aElement) +{ + nsINodeInfo* nodeInfo = aElement->NodeInfo(); + return (aElement->IsHTML() && + (nodeInfo->Equals(nsGkAtoms::script) || + nodeInfo->Equals(nsGkAtoms::style) || + nodeInfo->Equals(nsGkAtoms::textarea))); +} + +/** + * Returns the directionality of a Unicode character + */ +static Directionality +GetDirectionFromChar(uint32_t ch) +{ + switch(mozilla::unicode::GetBidiCat(ch)) { + case eCharType_RightToLeft: + case eCharType_RightToLeftArabic: + return eDir_RTL; + + case eCharType_LeftToRight: + return eDir_LTR; + + default: + return eDir_NotSet; + } +} + +inline static bool NodeAffectsDirAutoAncestor(nsINode* aTextNode) +{ + Element* parent = aTextNode->GetElementParent(); + return (parent && + !DoesNotParticipateInAutoDirection(parent) && + parent->NodeOrAncestorHasDirAuto()); +} + +/** + * Various methods for returning the directionality of a string using the + * first-strong algorithm defined in http://unicode.org/reports/tr9/#P2 + * + * @param[out] aFirstStrong the offset to the first character in the string with + * strong directionality, or PR_UINT32_MAX if there is none (return + value is eDir_NotSet). + * @return the directionality of the string + */ +static Directionality +GetDirectionFromText(const PRUnichar* aText, const uint32_t aLength, + uint32_t* aFirstStrong = nullptr) +{ + const PRUnichar* start = aText; + const PRUnichar* end = aText + aLength; + + while (start < end) { + uint32_t current = start - aText; + uint32_t ch = *start++; + + if (NS_IS_HIGH_SURROGATE(ch) && + start < end && + NS_IS_LOW_SURROGATE(*start)) { + ch = SURROGATE_TO_UCS4(ch, *start++); + } + + Directionality dir = GetDirectionFromChar(ch); + if (dir != eDir_NotSet) { + if (aFirstStrong) { + *aFirstStrong = current; + } + return dir; + } + } + + if (aFirstStrong) { + *aFirstStrong = PR_UINT32_MAX; + } + return eDir_NotSet; +} + +static Directionality +GetDirectionFromText(const char* aText, const uint32_t aLength, + uint32_t* aFirstStrong = nullptr) +{ + const char* start = aText; + const char* end = aText + aLength; + + while (start < end) { + uint32_t current = start - aText; + unsigned char ch = (unsigned char)*start++; + + Directionality dir = GetDirectionFromChar(ch); + if (dir != eDir_NotSet) { + if (aFirstStrong) { + *aFirstStrong = current; + } + return dir; + } + } + + if (aFirstStrong) { + *aFirstStrong = PR_UINT32_MAX; + } + return eDir_NotSet; +} + +static Directionality +GetDirectionFromText(const nsTextFragment* aFrag, + uint32_t* aFirstStrong = nullptr) +{ + if (aFrag->Is2b()) { + return GetDirectionFromText(aFrag->Get2b(), aFrag->GetLength(), + aFirstStrong); + } + + return GetDirectionFromText(aFrag->Get1b(), aFrag->GetLength(), + aFirstStrong); +} + +/** + * Set the directionality of a node with dir=auto as defined in + * http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#the-directionality + * + * @param[in] aStartAfterNode as an optimization, a caller may pass in a node + * from which to begin walking the descendants of aElement, if it is + * known that all text nodes before this node do not contain any + * strong directional characters + * @return the text node containing the character that determined the direction + */ +static nsINode* +WalkDescendantsSetDirectionFromText(Element* aElement, bool aNotify = true, + nsINode* aStartAfterNode = nullptr) +{ + MOZ_ASSERT(aElement, "aElement is null"); + + nsIContent* child; + if (aStartAfterNode && + nsContentUtils::ContentIsDescendantOf(aStartAfterNode, aElement)) { +#ifdef DEBUG + child = aElement->GetFirstChild(); + while (child && child != aStartAfterNode) { + if (child->NodeType() == nsIDOMNode::TEXT_NODE) { + MOZ_ASSERT(GetDirectionFromText(child->GetText()) == eDir_NotSet, + "Strong directional characters before aStartAfterNode"); + } + child = child->GetNextNode(aElement); + } +#endif + child = aStartAfterNode->GetNextNode(aElement); + } else { + child = aElement->GetFirstChild(); + } + + while (child) { + if (child->IsElement() && + (DoesNotParticipateInAutoDirection(child->AsElement()) || + child->NodeInfo()->Equals(nsGkAtoms::bdi) || + child->HasFixedDir())) { + child = child->GetNextNonChildNode(aElement); + continue; + } + + if (child->NodeType() == nsIDOMNode::TEXT_NODE) { + Directionality textNodeDir = GetDirectionFromText(child->GetText()); + if (textNodeDir != eDir_NotSet) { + // We found a descendant text node with strong directional characters. + // Set the directionality of aElement to the corresponding value. + aElement->SetDirectionality(textNodeDir, aNotify); + return child; + } + } + child = child->GetNextNode(aElement); + } + + // We walked all the descendants without finding a text node with strong + // directional characters. Set the directionality to LTR + aElement->SetDirectionality(eDir_LTR, aNotify); + return nullptr; +} + +class nsTextNodeDirectionalityMap +{ + static void + nsTextNodeDirectionalityMapDtor(void *aObject, nsIAtom* aPropertyName, + void *aPropertyValue, void* aData) + { + nsTextNodeDirectionalityMap* map = + reinterpret_cast(aPropertyValue); + delete map; + } + +public: + nsTextNodeDirectionalityMap(nsINode* aTextNode) + { + MOZ_ASSERT(aTextNode, "Null text node"); + MOZ_COUNT_CTOR(nsTextNodeDirectionalityMap); + aTextNode->SetProperty(nsGkAtoms::textNodeDirectionalityMap, this, + nsTextNodeDirectionalityMapDtor); + aTextNode->SetHasTextNodeDirectionalityMap(); + } + + ~nsTextNodeDirectionalityMap() + { + MOZ_COUNT_DTOR(nsTextNodeDirectionalityMap); + } + + void AddEntry(nsINode* aTextNode, Element* aElement) + { + if (!mElements.Contains(aElement)) { + mElements.Put(aElement); + aElement->SetProperty(nsGkAtoms::dirAutoSetBy, aTextNode); + aElement->SetHasDirAutoSet(); + } + } + + void RemoveEntry(nsINode* aTextNode, Element* aElement) + { + if (mElements.Contains(aElement)) { + mElements.Remove(aElement); + + aElement->ClearHasDirAutoSet(); + aElement->UnsetProperty(nsGkAtoms::dirAutoSetBy); + } + } + +private: + nsCheapSet > mElements; + + static nsTextNodeDirectionalityMap* GetDirectionalityMap(nsINode* aTextNode) + { + MOZ_ASSERT(aTextNode->NodeType() == nsIDOMNode::TEXT_NODE, + "Must be a text node"); + nsTextNodeDirectionalityMap* map = nullptr; + + if (aTextNode->HasTextNodeDirectionalityMap()) { + map = static_cast + (aTextNode->GetProperty(nsGkAtoms::textNodeDirectionalityMap)); + } + + return map; + } + + static PLDHashOperator SetNodeDirection(nsPtrHashKey* aEntry, void* aDir) + { + MOZ_ASSERT(aEntry->GetKey()->IsElement(), "Must be an Element"); + aEntry->GetKey()->SetDirectionality(*reinterpret_cast(aDir), + true); + return PL_DHASH_NEXT; + } + + static PLDHashOperator ResetNodeDirection(nsPtrHashKey* aEntry, void* aData) + { + MOZ_ASSERT(aEntry->GetKey()->IsElement(), "Must be an Element"); + // run the downward propagation algorithm + // and remove the text node from the map + nsINode* startAfterNode = static_cast(aData); + Element* rootNode = aEntry->GetKey(); + nsINode* textNode = WalkDescendantsSetDirectionFromText(rootNode, true, + startAfterNode); + if (textNode) { + nsTextNodeDirectionalityMap::AddEntryToMap(textNode, rootNode); + } + return PL_DHASH_REMOVE; + } + +public: + void UpdateAutoDirection(Directionality aDir) + { + mElements.EnumerateEntries(SetNodeDirection, &aDir); + } + + void ResetAutoDirection(nsINode* aTextNode, nsINode* aStartAfterNode) + { + mElements.EnumerateEntries(ResetNodeDirection, aStartAfterNode); + } + + static void RemoveElementFromMap(nsINode* aTextNode, Element* aElement) + { + if (aTextNode->HasTextNodeDirectionalityMap()) { + GetDirectionalityMap(aTextNode)->RemoveEntry(aTextNode, aElement); + } + } + + static void AddEntryToMap(nsINode* aTextNode, Element* aElement) + { + nsTextNodeDirectionalityMap* map = GetDirectionalityMap(aTextNode); + if (!map) { + map = new nsTextNodeDirectionalityMap(aTextNode); + } + + map->AddEntry(aTextNode, aElement); + } + + static void UpdateTextNodeDirection(nsINode* aTextNode, Directionality aDir) + { + MOZ_ASSERT(aTextNode->HasTextNodeDirectionalityMap(), + "Map missing in UpdateTextNodeDirection"); + GetDirectionalityMap(aTextNode)->UpdateAutoDirection(aDir); + } + + static void ResetTextNodeDirection(nsINode* aTextNode, + nsINode* aStartAfterNode = nullptr) + { + MOZ_ASSERT(aTextNode->HasTextNodeDirectionalityMap(), + "Map missing in ResetTextNodeDirection"); + GetDirectionalityMap(aTextNode)->ResetAutoDirection(aTextNode, + aStartAfterNode); + } +}; + Directionality RecomputeDirectionality(Element* aElement, bool aNotify) { + MOZ_ASSERT(!aElement->HasDirAuto(), + "RecomputeDirectionality called with dir=auto"); + if (aElement->HasDirAutoSet()) { + nsINode* setByNode = + static_cast(aElement->GetProperty(nsGkAtoms::dirAutoSetBy)); + if (setByNode) { + nsTextNodeDirectionalityMap::RemoveElementFromMap(setByNode, aElement); + } + } + Directionality dir = eDir_LTR; if (aElement->HasValidDir()) { @@ -46,7 +575,7 @@ RecomputeDirectionality(Element* aElement, bool aNotify) dir = documentDir; } } - + aElement->SetDirectionality(dir, aNotify); } return dir; @@ -63,7 +592,7 @@ SetDirectionalityOnDescendants(Element* aElement, Directionality aDir, } Element* element = child->AsElement(); - if (element->HasValidDir()) { + if (element->HasValidDir() || element->HasDirAuto()) { child = child->GetNextNonChildNode(aElement); continue; } @@ -72,7 +601,272 @@ SetDirectionalityOnDescendants(Element* aElement, Directionality aDir, } } -} // end namespace directionality +void +WalkAncestorsResetAutoDirection(Element* aElement, bool aNotify) +{ + nsINode* setByNode; + Element* parent = aElement->GetElementParent(); + + while (parent && parent->NodeOrAncestorHasDirAuto()) { + if (parent->HasDirAutoSet()) { + // If the parent has the DirAutoSet flag, its direction is determined by + // some text node descendant. + // Remove it from the map and reset its direction by the downward + // propagation algorithm + setByNode = + static_cast(parent->GetProperty(nsGkAtoms::dirAutoSetBy)); + if (setByNode) { + nsTextNodeDirectionalityMap::RemoveElementFromMap(setByNode, parent); + } + } + if (parent->HasDirAuto()) { + setByNode = WalkDescendantsSetDirectionFromText(parent, aNotify); + if (setByNode) { + nsTextNodeDirectionalityMap::AddEntryToMap(setByNode, parent); + } + break; + } + parent = parent->GetElementParent(); + } +} + +void +WalkDescendantsResetAutoDirection(Element* aElement) +{ + nsIContent* child = aElement->GetFirstChild(); + while (child) { + if (child->HasDirAuto()) { + child = child->GetNextNonChildNode(aElement); + continue; + } + + if (child->HasTextNodeDirectionalityMap()) { + nsTextNodeDirectionalityMap::ResetTextNodeDirection(child, child); + } + child = child->GetNextNode(aElement); + } +} + +void +WalkDescendantsSetDirAuto(Element* aElement, bool aNotify) +{ + bool setAncestorDirAutoFlag = +#ifdef DEBUG + true; +#else + !aElement->AncestorHasDirAuto(); +#endif + + if (setAncestorDirAutoFlag) { + nsIContent* child = aElement->GetFirstChild(); + while (child) { + MOZ_ASSERT(!aElement->AncestorHasDirAuto() || + child->AncestorHasDirAuto(), + "AncestorHasDirAuto set on node but not its children"); + child->SetHasDirAuto(); + child = child->GetNextNode(aElement); + } + } + + nsINode* textNode = WalkDescendantsSetDirectionFromText(aElement, aNotify); + if (textNode) { + nsTextNodeDirectionalityMap::AddEntryToMap(textNode, aElement); + } +} + +void +WalkDescendantsClearAncestorDirAuto(Element* aElement) +{ + nsIContent* child = aElement->GetFirstChild(); + while (child) { + if (child->HasDirAuto()) { + child = child->GetNextNonChildNode(aElement); + continue; + } + + child->ClearAncestorHasDirAuto(); + child = child->GetNextNode(aElement); + } +} + +void SetAncestorDirectionIfAuto(nsINode* aTextNode, Directionality aDir, + bool aNotify = true) +{ + MOZ_ASSERT(aTextNode->NodeType() == nsIDOMNode::TEXT_NODE, + "Must be a text node"); + + Element* parent = aTextNode->GetElementParent(); + while (parent && parent->NodeOrAncestorHasDirAuto()) { + if (DoesNotParticipateInAutoDirection(parent) || parent->HasFixedDir()) { + break; + } + + if (parent->HasDirAuto()) { + bool resetDirection = false; + + if (!parent->HasDirAutoSet()) { + // Fast path if parent's direction is not yet set by any descendant + resetDirection = true; + } else { + // If parent's direction is already set, we need to know if + // aTextNode is before or after the text node that had set it. + // We will walk parent's descendants in tree order starting from + // aTextNode to optimize for the most common case where text nodes are + // being appended to tree. + nsINode* directionWasSetByTextNode = + static_cast(parent->GetProperty(nsGkAtoms::dirAutoSetBy)); + if (!directionWasSetByTextNode) { + resetDirection = true; + } else if (directionWasSetByTextNode != aTextNode) { + nsIContent* child = aTextNode->GetNextNode(parent); + while (child) { + if (child->IsElement() && + (DoesNotParticipateInAutoDirection(child->AsElement()) || + child->NodeInfo()->Equals(nsGkAtoms::bdi) || + child->HasFixedDir())) { + child = child->GetNextNonChildNode(parent); + continue; + } + + if (child == directionWasSetByTextNode) { + // we found the node that set the element's direction after our + // text node, so we need to reset the direction + resetDirection = true; + break; + } + + child = child->GetNextNode(parent); + } + } + } + + if (resetDirection) { + parent->SetDirectionality(aDir, aNotify); + nsTextNodeDirectionalityMap::AddEntryToMap(aTextNode, parent); + SetDirectionalityOnDescendants(parent, aDir, aNotify); + } + + // Since we found an element with dir=auto, we can stop walking the + // parent chain: none of its ancestors will have their direction set by + // any of its descendants. + return; + } + parent = parent->GetElementParent(); + } +} + +void +SetDirectionFromChangedTextNode(nsIContent* aTextNode, uint32_t aOffset, + const PRUnichar* aBuffer, uint32_t aLength, + bool aNotify) +{ + if (!NodeAffectsDirAutoAncestor(aTextNode)) { + return; + } + + uint32_t firstStrong; + Directionality oldDir = GetDirectionFromText(aTextNode->GetText(), + &firstStrong); + if (aOffset > firstStrong) { + return; + } + + Directionality newDir = GetDirectionFromText(aBuffer, aLength); + if (newDir == eDir_NotSet) { + if (oldDir != eDir_NotSet && aTextNode->HasTextNodeDirectionalityMap()) { + // This node used to have a strong directional character but no + // longer does. ResetTextNodeDirection() will re-resolve the + // directionality of any elements whose directionality was + // determined by this node. + nsTextNodeDirectionalityMap::ResetTextNodeDirection(aTextNode); + } + } else { + // This node has a strong directional character. If it has a + // TextNodeDirectionalityMap property, it already determines the + // directionality of some element(s), so call UpdateTextNodeDirection to + // reresolve their directionality. Otherwise call + // SetAncestorDirectionIfAuto to find ancestor elements which should + // have their directionality determined by this node. + if (aTextNode->HasTextNodeDirectionalityMap()) { + nsTextNodeDirectionalityMap::UpdateTextNodeDirection(aTextNode, newDir); + } else { + SetAncestorDirectionIfAuto(aTextNode, newDir, aNotify); + } + } +} + +void +SetDirectionFromNewTextNode(nsTextNode* aTextNode) +{ + if (!NodeAffectsDirAutoAncestor(aTextNode)) { + return; + } + + Directionality dir = GetDirectionFromText(aTextNode->GetText()); + if (dir != eDir_NotSet) { + SetAncestorDirectionIfAuto(aTextNode, dir); + } +} + +void +ResetDirectionSetByTextNode(nsTextNode* aTextNode) +{ + if (!NodeAffectsDirAutoAncestor(aTextNode)) { + return; + } + + Directionality dir = GetDirectionFromText(aTextNode->GetText()); + if (dir != eDir_NotSet && aTextNode->HasTextNodeDirectionalityMap()) { + nsTextNodeDirectionalityMap::ResetTextNodeDirection(aTextNode); + } +} + +void +SetDirectionalityFromValue(Element* aElement, const nsAString& value, + bool aNotify) +{ + Directionality dir = GetDirectionFromText(PromiseFlatString(value).get(), + value.Length()); + if (dir == eDir_NotSet) { + dir = eDir_LTR; + } + + aElement->SetDirectionality(dir, aNotify); +} + +void +OnSetDirAttr(Element* aElement, const nsAttrValue* aNewValue, + bool hadValidDir, bool aNotify) +{ + if (aElement->IsHTML() && aElement->NodeInfo()->Equals(nsGkAtoms::input)) { + return; + } + + if (aElement->AncestorHasDirAuto()) { + if (!hadValidDir) { + // The element is a descendant of an element with dir = auto, is + // having its dir attribute set, and previously didn't have a valid dir + // attribute. + // Check whether any of its text node descendants determine the + // direction of any of its ancestors, and redetermine their direction + WalkDescendantsResetAutoDirection(aElement); + } else if (!aElement->HasValidDir()) { + // The element is a descendant of an element with dir = auto and is + // having its dir attribute removed or set to an invalid value. + // Reset the direction of any of its ancestors whose direction is + // determined by a text node descendant + WalkAncestorsResetAutoDirection(aElement, aNotify); + } + } + + if (aElement->HasDirAuto()) { + WalkDescendantsSetDirAuto(aElement, aNotify); + } else { + SetDirectionalityOnDescendants(aElement, + RecomputeDirectionality(aElement, aNotify), + aNotify); + } +} } // end namespace mozilla diff --git a/content/base/src/Element.cpp b/content/base/src/Element.cpp index b77f7c957b85..06f5f912a00d 100644 --- a/content/base/src/Element.cpp +++ b/content/base/src/Element.cpp @@ -130,7 +130,6 @@ using namespace mozilla; using namespace mozilla::dom; -using namespace mozilla::directionality; nsEventStates Element::IntrinsicState() const @@ -1163,7 +1162,21 @@ Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent, // because it has to happen after updating the parent pointer, but before // recursively binding the kids. if (IsHTML()) { - RecomputeDirectionality(this, false); + if (aParent && aParent->NodeOrAncestorHasDirAuto()) { + SetAncestorHasDirAuto(); + // if we are binding an element to the tree that already has descendants, + // and the parent has NodeHasDirAuto or NodeAncestorHasDirAuto, we may + // need to reset the direction of an ancestor with dir=auto + if (GetFirstChild()) { + WalkAncestorsResetAutoDirection(this); + } + } + + if (!HasDirAuto()) { + // if the element doesn't have dir=auto, set its directionality from + // the dir attribute or by inheriting from its ancestors. + RecomputeDirectionality(this, false); + } } // If NODE_FORCE_XBL_BINDINGS was set we might have anonymous children @@ -1354,7 +1367,7 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent) // This has to be here, rather than in nsGenericHTMLElement::UnbindFromTree, // because it has to happen after unsetting the parent pointer, but before // recursively unbinding the kids. - if (IsHTML()) { + if (IsHTML() && !HasDirAuto()) { RecomputeDirectionality(this, false); } @@ -1827,7 +1840,13 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, aValueForAfterSetAttr.SetTo(aParsedValue); } + bool hadValidDir = false; + if (aNamespaceID == kNameSpaceID_None) { + if (aName == nsGkAtoms::dir) { + hadValidDir = HasValidDir() || NodeInfo()->Equals(nsGkAtoms::bdi); + } + // XXXbz Perhaps we should push up the attribute mapping function // stuff to Element? if (!IsAttributeMapped(aName) || @@ -1863,6 +1882,10 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, if (aCallAfterSetAttr) { rv = AfterSetAttr(aNamespaceID, aName, &aValueForAfterSetAttr, aNotify); NS_ENSURE_SUCCESS(rv, rv); + + if (aNamespaceID == kNameSpaceID_None && aName == nsGkAtoms::dir) { + OnSetDirAttr(this, &aValueForAfterSetAttr, hadValidDir, aNotify); + } } if (aFireMutation) { @@ -2065,6 +2088,12 @@ Element::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName, // react to unexpected attribute changes. nsMutationGuard::DidMutate(); + bool hadValidDir = false; + + if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::dir) { + hadValidDir = HasValidDir() || NodeInfo()->Equals(nsGkAtoms::bdi); + } + nsAttrValue oldValue; rv = mAttrsAndChildren.RemoveAttrAt(index, oldValue); NS_ENSURE_SUCCESS(rv, rv); @@ -2087,6 +2116,10 @@ Element::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName, rv = AfterSetAttr(aNameSpaceID, aName, nullptr, aNotify); NS_ENSURE_SUCCESS(rv, rv); + if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::dir) { + OnSetDirAttr(this, nullptr, hadValidDir, aNotify); + } + if (hasMutationListeners) { nsCOMPtr node = do_QueryObject(this); nsMutationEvent mutation(true, NS_MUTATION_ATTRMODIFIED); diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index e2bc9b7e32c0..bd11aed738e4 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -177,7 +177,6 @@ using namespace mozilla; using namespace mozilla::dom; -using namespace mozilla::directionality; typedef nsTArray LinkArray; diff --git a/content/base/src/nsDocument.h b/content/base/src/nsDocument.h index 0235edad50dc..297a95029b53 100644 --- a/content/base/src/nsDocument.h +++ b/content/base/src/nsDocument.h @@ -1053,7 +1053,7 @@ protected: nsresult SetFirstBaseNodeWithHref(nsIContent *node); inline void - SetDocumentDirectionality(mozilla::directionality::Directionality aDir) + SetDocumentDirectionality(mozilla::Directionality aDir) { mDirectionality = aDir; } diff --git a/content/base/src/nsGenericDOMDataNode.cpp b/content/base/src/nsGenericDOMDataNode.cpp index 3889998b8814..34e5b285201a 100644 --- a/content/base/src/nsGenericDOMDataNode.cpp +++ b/content/base/src/nsGenericDOMDataNode.cpp @@ -26,6 +26,7 @@ #include "nsEventDispatcher.h" #include "nsCOMArray.h" #include "nsNodeUtils.h" +#include "mozilla/dom/DirectionalityUtils.h" #include "nsBindingManager.h" #include "nsCCUncollectableMarker.h" #include "mozAutoDocUpdate.h" @@ -279,6 +280,10 @@ nsGenericDOMDataNode::SetTextInternal(uint32_t aOffset, uint32_t aCount, nsNodeUtils::CharacterDataWillChange(this, &info); } + if (NodeType() == nsIDOMNode::TEXT_NODE) { + SetDirectionFromChangedTextNode(this, aOffset, aBuffer, aLength, aNotify); + } + if (aOffset == 0 && endOffset == textLength) { // Replacing whole text or old text was empty. Don't bother to check for // bidi in this string if the document already has bidi enabled. diff --git a/content/base/src/nsGkAtomList.h b/content/base/src/nsGkAtomList.h index 98ebc34b8e50..9a4301fbe839 100644 --- a/content/base/src/nsGkAtomList.h +++ b/content/base/src/nsGkAtomList.h @@ -276,6 +276,7 @@ GK_ATOM(dialog, "dialog") GK_ATOM(difference, "difference") GK_ATOM(digit, "digit") GK_ATOM(dir, "dir") +GK_ATOM(dirAutoSetBy, "dirAutoSetBy") GK_ATOM(directionality, "directionality") GK_ATOM(disableOutputEscaping, "disable-output-escaping") GK_ATOM(disabled, "disabled") @@ -1033,6 +1034,7 @@ GK_ATOM(text, "text") GK_ATOM(textarea, "textarea") GK_ATOM(textbox, "textbox") GK_ATOM(textnode, "textnode") +GK_ATOM(textNodeDirectionalityMap, "textNodeDirectionalityMap") GK_ATOM(tfoot, "tfoot") GK_ATOM(th, "th") GK_ATOM(thead, "thead") diff --git a/content/base/src/nsTextNode.cpp b/content/base/src/nsTextNode.cpp index db2ffb24e683..09fd9df926b4 100644 --- a/content/base/src/nsTextNode.cpp +++ b/content/base/src/nsTextNode.cpp @@ -9,6 +9,7 @@ #include "nsTextNode.h" #include "nsContentUtils.h" +#include "mozilla/dom/DirectionalityUtils.h" #include "nsIDOMEventListener.h" #include "nsIDOMMutationEvent.h" #include "nsIDocument.h" @@ -18,6 +19,7 @@ #include "nsRange.h" #endif +using namespace mozilla; using namespace mozilla::dom; /** @@ -162,6 +164,27 @@ nsTextNode::AppendTextForNormalize(const PRUnichar* aBuffer, uint32_t aLength, return SetTextInternal(mText.GetLength(), 0, aBuffer, aLength, aNotify, &details); } +nsresult +nsTextNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent, + nsIContent* aBindingParent, bool aCompileEventHandlers) +{ + nsresult rv = nsGenericDOMDataNode::BindToTree(aDocument, aParent, + aBindingParent, + aCompileEventHandlers); + NS_ENSURE_SUCCESS(rv, rv); + + SetDirectionFromNewTextNode(this); + + return NS_OK; +} + +void nsTextNode::UnbindFromTree(bool aDeep, bool aNullParent) +{ + ResetDirectionSetByTextNode(this); + + nsGenericDOMDataNode::UnbindFromTree(aDeep, aNullParent); +} + #ifdef DEBUG void nsTextNode::List(FILE* out, int32_t aIndent) const diff --git a/content/base/src/nsTextNode.h b/content/base/src/nsTextNode.h index b10a27c6d30d..506d7106ca5b 100644 --- a/content/base/src/nsTextNode.h +++ b/content/base/src/nsTextNode.h @@ -40,6 +40,12 @@ public: virtual nsXPCClassInfo* GetClassInfo(); + virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, + nsIContent* aBindingParent, + bool aCompileEventHandlers); + virtual void UnbindFromTree(bool aDeep = true, + bool aNullParent = true); + nsresult AppendTextForNormalize(const PRUnichar* aBuffer, uint32_t aLength, bool aNotify, nsIContent* aNextSibling); diff --git a/content/html/content/src/nsGenericHTMLElement.cpp b/content/html/content/src/nsGenericHTMLElement.cpp index 682a78c73b64..cc4e95614850 100644 --- a/content/html/content/src/nsGenericHTMLElement.cpp +++ b/content/html/content/src/nsGenericHTMLElement.cpp @@ -68,6 +68,7 @@ #include "nsIDOMHTMLFormElement.h" #include "nsHTMLFormElement.h" #include "nsFocusManager.h" +#include "nsAttrValueOrString.h" #include "nsMutationEvent.h" @@ -102,7 +103,6 @@ using namespace mozilla; using namespace mozilla::dom; -using namespace mozilla::directionality; class nsINodeInfo; class nsIDOMNodeList; @@ -347,8 +347,9 @@ nsGenericHTMLElement::ClearDataset() } static const nsAttrValue::EnumTable kDirTable[] = { - { "ltr", NS_STYLE_DIRECTION_LTR }, - { "rtl", NS_STYLE_DIRECTION_RTL }, + { "ltr", eDir_LTR }, + { "rtl", eDir_RTL }, + { "auto", eDir_Auto }, { 0 } }; @@ -1698,6 +1699,23 @@ nsGenericHTMLElement::GetHrefURIForAnchors() const return uri.forget(); } +nsresult +nsGenericHTMLElement::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName, + const nsAttrValueOrString* aValue, + bool aNotify) +{ + if (aNamespaceID == kNameSpaceID_None && + aName == nsGkAtoms::dir && + HasDirAuto()) { + // setting dir on an element that currently has dir=auto + WalkDescendantsClearAncestorDirAuto(this); + SetHasDirAuto(); + } + + return nsGenericHTMLElementBase::BeforeSetAttr(aNamespaceID, aName, + aValue, aNotify); +} + nsresult nsGenericHTMLElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName, const nsAttrValue* aValue, bool aNotify) @@ -1719,16 +1737,28 @@ nsGenericHTMLElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName, SyncEditorsOnSubtree(this); } else if (aName == nsGkAtoms::dir) { - Directionality dir; - if (aValue && - (aValue->Equals(nsGkAtoms::ltr, eIgnoreCase) || - aValue->Equals(nsGkAtoms::rtl, eIgnoreCase))) { + Directionality dir = eDir_LTR; + if (aValue && aValue->Type() == nsAttrValue::eEnum) { SetHasValidDir(); - dir = aValue->Equals(nsGkAtoms::rtl, eIgnoreCase) ? eDir_RTL : eDir_LTR; - SetDirectionality(dir, aNotify); + Directionality dirValue = (Directionality)aValue->GetEnumValue(); + if (dirValue == eDir_Auto) { + SetHasDirAuto(); + ClearHasFixedDir(); + } else { + dir = dirValue; + SetDirectionality(dir, aNotify); + ClearHasDirAuto(); + ClearHasDirAutoSet(); + SetHasFixedDir(); + } } else { ClearHasValidDir(); - dir = RecomputeDirectionality(this, aNotify); + ClearHasFixedDir(); + if (NodeInfo()->Equals(nsGkAtoms::bdi)) { + SetHasDirAuto(); + } else { + dir = RecomputeDirectionality(this, aNotify); + } } SetDirectionalityOnDescendants(this, dir, aNotify); } diff --git a/content/html/content/src/nsGenericHTMLElement.h b/content/html/content/src/nsGenericHTMLElement.h index a1a92c33e834..b701145cb32e 100644 --- a/content/html/content/src/nsGenericHTMLElement.h +++ b/content/html/content/src/nsGenericHTMLElement.h @@ -777,6 +777,10 @@ protected: */ bool IsEventName(nsIAtom* aName); + virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName, + const nsAttrValueOrString* aValue, + bool aNotify); + virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName, const nsAttrValue* aValue, bool aNotify); diff --git a/content/html/content/src/nsHTMLInputElement.cpp b/content/html/content/src/nsHTMLInputElement.cpp index 6b49672e5521..5fa870ffd92a 100644 --- a/content/html/content/src/nsHTMLInputElement.cpp +++ b/content/html/content/src/nsHTMLInputElement.cpp @@ -81,6 +81,7 @@ #include "mozAutoDocUpdate.h" #include "nsContentCreatorFunctions.h" #include "nsContentUtils.h" +#include "mozilla/dom/DirectionalityUtils.h" #include "nsRadioVisitor.h" #include "mozilla/LookAndFeel.h" @@ -760,6 +761,10 @@ nsHTMLInputElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, } } else if (aNotify && aName == nsGkAtoms::disabled) { mDisabledChanged = true; + } else if (aName == nsGkAtoms::dir && + AttrValueIs(kNameSpaceID_None, nsGkAtoms::dir, + nsGkAtoms::_auto, eIgnoreCase)) { + SetDirectionIfAuto(false, aNotify); } } @@ -866,6 +871,9 @@ nsHTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, UpdateStepMismatchValidityState(); } else if (aName == nsGkAtoms::step) { UpdateStepMismatchValidityState(); + } else if (aName == nsGkAtoms::dir && + aValue && aValue->Equals(nsGkAtoms::_auto, eIgnoreCase)) { + SetDirectionIfAuto(true, aNotify); } UpdateState(aNotify); @@ -2582,6 +2590,9 @@ nsHTMLInputElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent, AddedToRadioGroup(); } + // Set direction based on value if dir=auto + SetDirectionIfAuto(HasDirAuto(), false); + // An element can't suffer from value missing if it is not in a document. // We have to check if we suffer from that as we are now in a document. UpdateValueMissingValidityState(); @@ -3197,6 +3208,21 @@ nsHTMLInputElement::SetDefaultValueAsValue() return SetValueInternal(resetVal, false, false); } +void +nsHTMLInputElement::SetDirectionIfAuto(bool aAuto, bool aNotify) +{ + if (aAuto) { + SetHasDirAuto(); + if (IsSingleLineTextControl(true)) { + nsAutoString value; + GetValue(value); + SetDirectionalityFromValue(this, value, aNotify); + } + } else { + ClearHasDirAuto(); + } +} + NS_IMETHODIMP nsHTMLInputElement::Reset() { @@ -4606,6 +4632,10 @@ NS_IMETHODIMP_(void) nsHTMLInputElement::OnValueChanged(bool aNotify) { UpdateAllValidityStates(aNotify); + + if (HasDirAuto()) { + SetDirectionIfAuto(true, aNotify); + } } NS_IMETHODIMP_(bool) diff --git a/content/html/content/src/nsHTMLInputElement.h b/content/html/content/src/nsHTMLInputElement.h index 35f4c58a390a..5dc742c02f0d 100644 --- a/content/html/content/src/nsHTMLInputElement.h +++ b/content/html/content/src/nsHTMLInputElement.h @@ -511,6 +511,8 @@ protected: */ nsresult SetDefaultValueAsValue(); + virtual void SetDirectionIfAuto(bool aAuto, bool aNotify); + /** * Return if an element should have a specific validity UI * (with :-moz-ui-invalid and :-moz-ui-valid pseudo-classes). diff --git a/content/html/content/src/nsHTMLUnknownElement.h b/content/html/content/src/nsHTMLUnknownElement.h index bf450106d03a..2b6d70c69123 100644 --- a/content/html/content/src/nsHTMLUnknownElement.h +++ b/content/html/content/src/nsHTMLUnknownElement.h @@ -15,6 +15,9 @@ public: nsHTMLUnknownElement(already_AddRefed aNodeInfo) : nsGenericHTMLElement(aNodeInfo) { + if (NodeInfo()->Equals(nsGkAtoms::bdi)) { + SetHasDirAuto(); + } } // nsISupports diff --git a/layout/style/html.css b/layout/style/html.css index 42bd05def8a3..a988d6896b59 100644 --- a/layout/style/html.css +++ b/layout/style/html.css @@ -16,6 +16,9 @@ unicode-bidi: embed; } +bdi:-moz-dir(ltr), [dir="auto"]:-moz-dir(ltr) { direction: ltr; } +bdi:-moz-dir(rtl), [dir="auto"]:-moz-dir(rtl) { direction: rtl; } + /* To ensure http://www.w3.org/TR/REC-html40/struct/dirlang.html#style-bidi: * * "When a block element that does not have a dir attribute is transformed to From 968fb57de65993d69b12b78199d3f9aa3113ae92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20=C3=81vila=20de=20Esp=C3=ADndola?= Date: Tue, 20 Nov 2012 09:45:14 -0500 Subject: [PATCH 11/75] Bug 808699 - Change the wire format for hang reports. r=vladan. --- toolkit/components/telemetry/ProcessedStack.h | 11 +- toolkit/components/telemetry/Telemetry.cpp | 224 +++++++++--------- toolkit/content/aboutTelemetry.js | 32 ++- xpcom/build/mozPoisonWriteMac.cpp | 2 +- xpcom/threads/HangMonitor.cpp | 2 +- 5 files changed, 133 insertions(+), 138 deletions(-) diff --git a/toolkit/components/telemetry/ProcessedStack.h b/toolkit/components/telemetry/ProcessedStack.h index c83cfa825cac..1baf431ba765 100644 --- a/toolkit/components/telemetry/ProcessedStack.h +++ b/toolkit/components/telemetry/ProcessedStack.h @@ -35,13 +35,6 @@ public: // The file name, /foo/bar/libxul.so for example. std::string mName; - // The address it was loaded to. - // FIXME: remove this once chrome hang has switched to using offsets. - uintptr_t mStart; - - // The size of this mapping. May or may not be the entire file. - // FIXME: remove this. It was only used as a sanity check. - size_t mMappingSize; // Windows specific fields. On other platforms they are 0/empty. int mPdbAge; std::string mPdbSignature; @@ -65,10 +58,8 @@ private: // Get the current list of loaded modules, filter and pair it to the provided // stack. We let the caller collect the stack since different callers have // different needs (current thread X main thread, stopping the thread, etc). -// FIXME: remove the aRelative option once chrome hang has switched to using -// offsets. ProcessedStack -GetStackAndModules(const std::vector &aPCs, bool aRelative); +GetStackAndModules(const std::vector &aPCs); } // namespace Telemetry } // namespace mozilla diff --git a/toolkit/components/telemetry/Telemetry.cpp b/toolkit/components/telemetry/Telemetry.cpp index 8c5dc25c9892..6f609360090b 100644 --- a/toolkit/components/telemetry/Telemetry.cpp +++ b/toolkit/components/telemetry/Telemetry.cpp @@ -1221,137 +1221,135 @@ NS_IMETHODIMP TelemetryImpl::GetChromeHangs(JSContext *cx, jsval *ret) { MutexAutoLock hangReportMutex(mHangReportsMutex); + + JSObject *fullReportObj = JS_NewObject(cx, nullptr, nullptr, nullptr); + if (!fullReportObj) { + return NS_ERROR_FAILURE; + } + + *ret = OBJECT_TO_JSVAL(fullReportObj); + + JSObject *moduleArray = JS_NewArrayObject(cx, 0, nullptr); + if (!moduleArray) { + return NS_ERROR_FAILURE; + } + JSBool ok = JS_DefineProperty(cx, fullReportObj, "memoryMap", + OBJECT_TO_JSVAL(moduleArray), + NULL, NULL, JSPROP_ENUMERATE); + if (!ok) { + return NS_ERROR_FAILURE; + } + + const uint32_t moduleCount = mHangReports.GetModuleCount(); + for (size_t moduleIndex = 0; moduleIndex < moduleCount; ++moduleIndex) { + // Current module + const Telemetry::ProcessedStack::Module& module = + mHangReports.GetModule(moduleIndex); + + JSObject *moduleInfoArray = JS_NewArrayObject(cx, 0, nullptr); + if (!moduleInfoArray) { + return NS_ERROR_FAILURE; + } + jsval val = OBJECT_TO_JSVAL(moduleInfoArray); + if (!JS_SetElement(cx, moduleArray, moduleIndex, &val)) { + return NS_ERROR_FAILURE; + } + + unsigned index = 0; + + // Module name + JSString *str = JS_NewStringCopyZ(cx, module.mName.c_str()); + if (!str) { + return NS_ERROR_FAILURE; + } + val = STRING_TO_JSVAL(str); + if (!JS_SetElement(cx, moduleInfoArray, index++, &val)) { + return NS_ERROR_FAILURE; + } + + // "PDB Age" identifier + val = INT_TO_JSVAL(module.mPdbAge); + if (!JS_SetElement(cx, moduleInfoArray, index++, &val)) { + return NS_ERROR_FAILURE; + } + + // "PDB Signature" GUID + str = JS_NewStringCopyZ(cx, module.mPdbSignature.c_str()); + if (!str) { + return NS_ERROR_FAILURE; + } + val = STRING_TO_JSVAL(str); + if (!JS_SetElement(cx, moduleInfoArray, index++, &val)) { + return NS_ERROR_FAILURE; + } + + // Name of associated PDB file + str = JS_NewStringCopyZ(cx, module.mPdbName.c_str()); + if (!str) { + return NS_ERROR_FAILURE; + } + val = STRING_TO_JSVAL(str); + if (!JS_SetElement(cx, moduleInfoArray, index++, &val)) { + return NS_ERROR_FAILURE; + } + } + JSObject *reportArray = JS_NewArrayObject(cx, 0, nullptr); if (!reportArray) { return NS_ERROR_FAILURE; } - *ret = OBJECT_TO_JSVAL(reportArray); + ok = JS_DefineProperty(cx, fullReportObj, "stacks", + OBJECT_TO_JSVAL(reportArray), + NULL, NULL, JSPROP_ENUMERATE); + if (!ok) { + return NS_ERROR_FAILURE; + } - // Each hang report is an object in the 'chromeHangs' array - for (size_t i = 0; i < mHangReports.GetStackCount(); ++i) { - const CombinedStacks::Stack &stack = mHangReports.GetStack(i); - JSObject *reportObj = JS_NewObject(cx, NULL, NULL, NULL); - if (!reportObj) { - return NS_ERROR_FAILURE; - } - jsval reportObjVal = OBJECT_TO_JSVAL(reportObj); - if (!JS_SetElement(cx, reportArray, i, &reportObjVal)) { + JSObject *durationArray = JS_NewArrayObject(cx, 0, nullptr); + ok = JS_DefineProperty(cx, fullReportObj, "durations", + OBJECT_TO_JSVAL(durationArray), + NULL, NULL, JSPROP_ENUMERATE); + if (!ok) { + return NS_ERROR_FAILURE; + } + + for (size_t i = 0, n = mHangReports.GetStackCount(); i < n; ++i) { + jsval duration = INT_TO_JSVAL(mHangReports.GetDuration(i)); + if (!JS_SetElement(cx, durationArray, i, &duration)) { return NS_ERROR_FAILURE; } - // Record the hang duration (expressed in seconds) - JSBool ok = JS_DefineProperty(cx, reportObj, "duration", - INT_TO_JSVAL(mHangReports.GetDuration(i)), - NULL, NULL, JSPROP_ENUMERATE); - if (!ok) { - return NS_ERROR_FAILURE; - } - - // Represent call stack PCs as strings - // (JS can't represent all 64-bit integer values) + // Represent call stack PCs as (module index, offset) pairs. JSObject *pcArray = JS_NewArrayObject(cx, 0, nullptr); if (!pcArray) { return NS_ERROR_FAILURE; } - ok = JS_DefineProperty(cx, reportObj, "stack", OBJECT_TO_JSVAL(pcArray), - NULL, NULL, JSPROP_ENUMERATE); - if (!ok) { + + jsval pcArrayVal = OBJECT_TO_JSVAL(pcArray); + if (!JS_SetElement(cx, reportArray, i, &pcArrayVal)) { return NS_ERROR_FAILURE; } + const CombinedStacks::Stack& stack = mHangReports.GetStack(i); const uint32_t pcCount = stack.size(); for (size_t pcIndex = 0; pcIndex < pcCount; ++pcIndex) { - nsAutoCString pcString; - const Telemetry::ProcessedStack::Frame &Frame = stack[pcIndex]; - pcString.AppendPrintf("0x%p", Frame.mOffset); - JSString *str = JS_NewStringCopyZ(cx, pcString.get()); - if (!str) { + const Telemetry::ProcessedStack::Frame& frame = stack[pcIndex]; + JSObject *framePair = JS_NewArrayObject(cx, 0, nullptr); + if (!framePair) { return NS_ERROR_FAILURE; } - jsval v = STRING_TO_JSVAL(str); - if (!JS_SetElement(cx, pcArray, pcIndex, &v)) { + int modIndex = (std::numeric_limits::max() == frame.mModIndex) ? + -1 : frame.mModIndex; + jsval modIndexVal = INT_TO_JSVAL(modIndex); + if (!JS_SetElement(cx, framePair, 0, &modIndexVal)) { return NS_ERROR_FAILURE; } - } - - // Record memory map info - JSObject *moduleArray = JS_NewArrayObject(cx, 0, nullptr); - if (!moduleArray) { - return NS_ERROR_FAILURE; - } - ok = JS_DefineProperty(cx, reportObj, "memoryMap", - OBJECT_TO_JSVAL(moduleArray), - NULL, NULL, JSPROP_ENUMERATE); - if (!ok) { - return NS_ERROR_FAILURE; - } - - const uint32_t moduleCount = (i == 0) ? mHangReports.GetModuleCount() : 0; - for (size_t moduleIndex = 0; moduleIndex < moduleCount; ++moduleIndex) { - // Current module - const Telemetry::ProcessedStack::Module &module = - mHangReports.GetModule(moduleIndex); - - JSObject *moduleInfoArray = JS_NewArrayObject(cx, 0, nullptr); - if (!moduleInfoArray) { + jsval mOffsetVal = INT_TO_JSVAL(frame.mOffset); + if (!JS_SetElement(cx, framePair, 1, &mOffsetVal)) { return NS_ERROR_FAILURE; } - jsval val = OBJECT_TO_JSVAL(moduleInfoArray); - if (!JS_SetElement(cx, moduleArray, moduleIndex, &val)) { - return NS_ERROR_FAILURE; - } - - // Start address - nsAutoCString addressString; - addressString.AppendPrintf("0x%p", module.mStart); - JSString *str = JS_NewStringCopyZ(cx, addressString.get()); - if (!str) { - return NS_ERROR_FAILURE; - } - val = STRING_TO_JSVAL(str); - if (!JS_SetElement(cx, moduleInfoArray, 0, &val)) { - return NS_ERROR_FAILURE; - } - - // Module name - str = JS_NewStringCopyZ(cx, module.mName.c_str()); - if (!str) { - return NS_ERROR_FAILURE; - } - val = STRING_TO_JSVAL(str); - if (!JS_SetElement(cx, moduleInfoArray, 1, &val)) { - return NS_ERROR_FAILURE; - } - - // Module size in memory - val = INT_TO_JSVAL(int32_t(module.mMappingSize)); - if (!JS_SetElement(cx, moduleInfoArray, 2, &val)) { - return NS_ERROR_FAILURE; - } - - // "PDB Age" identifier - val = INT_TO_JSVAL(module.mPdbAge); - if (!JS_SetElement(cx, moduleInfoArray, 3, &val)) { - return NS_ERROR_FAILURE; - } - - // "PDB Signature" GUID - str = JS_NewStringCopyZ(cx, module.mPdbSignature.c_str()); - if (!str) { - return NS_ERROR_FAILURE; - } - val = STRING_TO_JSVAL(str); - if (!JS_SetElement(cx, moduleInfoArray, 4, &val)) { - return NS_ERROR_FAILURE; - } - - // Name of associated PDB file - str = JS_NewStringCopyZ(cx, module.mPdbName.c_str()); - if (!str) { - return NS_ERROR_FAILURE; - } - val = STRING_TO_JSVAL(str); - if (!JS_SetElement(cx, moduleInfoArray, 5, &val)) { + jsval framePairVal = OBJECT_TO_JSVAL(framePair); + if (!JS_SetElement(cx, pcArray, pcIndex, &framePairVal)) { return NS_ERROR_FAILURE; } } @@ -1763,8 +1761,6 @@ void ProcessedStack::Clear() { bool ProcessedStack::Module::operator==(const Module& aOther) const { return mName == aOther.mName && - mStart == aOther.mStart && - mMappingSize == aOther.mMappingSize && mPdbAge == aOther.mPdbAge && mPdbSignature == aOther.mPdbSignature && mPdbName == aOther.mPdbName; @@ -1790,7 +1786,8 @@ static bool CompareByIndex(const StackFrame &a, const StackFrame &b) } #endif -ProcessedStack GetStackAndModules(const std::vector &aPCs, bool aRelative) +ProcessedStack +GetStackAndModules(const std::vector& aPCs) { std::vector rawStack; for (std::vector::const_iterator i = aPCs.begin(), @@ -1828,8 +1825,7 @@ ProcessedStack GetStackAndModules(const std::vector &aPCs, bool aRela // If the current PC is within the current module, mark // module as used moduleReferenced = true; - if (aRelative) - rawStack[stackIndex].mPC -= moduleStart; + rawStack[stackIndex].mPC -= moduleStart; rawStack[stackIndex].mModIndex = moduleIndex; } else { // PC does not belong to any module. It is probably from @@ -1870,8 +1866,6 @@ ProcessedStack GetStackAndModules(const std::vector &aPCs, bool aRela const SharedLibrary &info = rawModules.GetEntry(i); ProcessedStack::Module module = { info.GetName(), - info.GetStart(), - info.GetEnd() - info.GetStart(), #ifdef XP_WIN info.GetPdbAge(), "", // mPdbSignature diff --git a/toolkit/content/aboutTelemetry.js b/toolkit/content/aboutTelemetry.js index 67ffab63a626..7d11d161e152 100644 --- a/toolkit/content/aboutTelemetry.js +++ b/toolkit/content/aboutTelemetry.js @@ -222,17 +222,19 @@ let ChromeHangs = { document.getElementById("hide-symbols").classList.add("hidden"); let hangs = Telemetry.chromeHangs; - if (hangs.length == 0) { + let stacks = hangs.stacks; + if (stacks.length == 0) { showEmptySectionMessage("chrome-hangs-section"); return; } this.renderMemoryMap(hangsDiv); - for (let i = 0; i < hangs.length; ++i) { - let currentHang = hangs[i]; - this.renderHangHeader(hangsDiv, i + 1, currentHang.duration); - this.renderStack(hangsDiv, currentHang.stack) + let durations = hangs.durations; + for (let i = 0; i < stacks.length; ++i) { + let stack = stacks[i]; + this.renderHangHeader(hangsDiv, i + 1, durations[i]); + this.renderStack(hangsDiv, stack) } }, @@ -279,8 +281,9 @@ let ChromeHangs = { aDiv.appendChild(document.createTextNode(this.memoryMapTitle)); aDiv.appendChild(document.createElement("br")); - let singleMemoryMap = Telemetry.chromeHangs[0].memoryMap; - for (let currentModule of singleMemoryMap) { + let hangs = Telemetry.chromeHangs; + let memoryMap = hangs.memoryMap; + for (let currentModule of memoryMap) { aDiv.appendChild(document.createTextNode(currentModule.join(" "))); aDiv.appendChild(document.createElement("br")); } @@ -295,16 +298,21 @@ let ChromeHangs = { let symbolServerURI = getPref(PREF_SYMBOL_SERVER_URI, DEFAULT_SYMBOL_SERVER_URI); - let chromeHangsJSON = JSON.stringify(Telemetry.chromeHangs); + let hangs = Telemetry.chromeHangs; + let memoryMap = hangs.memoryMap; + let stacks = hangs.stacks; + let request = {"memoryMap" : memoryMap, "stacks" : stacks, + "version" : 2}; + let requestJSON = JSON.stringify(request); this.symbolRequest = XMLHttpRequest(); this.symbolRequest.open("POST", symbolServerURI, true); this.symbolRequest.setRequestHeader("Content-type", "application/json"); - this.symbolRequest.setRequestHeader("Content-length", chromeHangsJSON.length); + this.symbolRequest.setRequestHeader("Content-length", requestJSON.length); this.symbolRequest.setRequestHeader("Connection", "close"); this.symbolRequest.onreadystatechange = this.handleSymbolResponse.bind(this); - this.symbolRequest.send(chromeHangsJSON); + this.symbolRequest.send(requestJSON); }, /** @@ -335,9 +343,11 @@ let ChromeHangs = { } let hangs = Telemetry.chromeHangs; + let stacks = hangs.stacks; + let durations = hangs.durations; for (let i = 0; i < jsonResponse.length; ++i) { let stack = jsonResponse[i]; - let hangDuration = hangs[i].duration; + let hangDuration = durations[i]; this.renderHangHeader(hangsDiv, i + 1, hangDuration); for (let symbol of stack) { diff --git a/xpcom/build/mozPoisonWriteMac.cpp b/xpcom/build/mozPoisonWriteMac.cpp index 2401fed7065d..f587527d6070 100644 --- a/xpcom/build/mozPoisonWriteMac.cpp +++ b/xpcom/build/mozPoisonWriteMac.cpp @@ -96,7 +96,7 @@ bool ValidWriteAssert(bool ok) std::vector rawStack; NS_StackWalk(RecordStackWalker, 0, reinterpret_cast(&rawStack), 0); - Telemetry::ProcessedStack stack = Telemetry::GetStackAndModules(rawStack, true); + Telemetry::ProcessedStack stack = Telemetry::GetStackAndModules(rawStack); nsPrintfCString nameAux("%s%s", sProfileDirectory, "/Telemetry.LateWriteTmpXXXXXX"); diff --git a/xpcom/threads/HangMonitor.cpp b/xpcom/threads/HangMonitor.cpp index aa5fbd62dc04..f351b01d914d 100644 --- a/xpcom/threads/HangMonitor.cpp +++ b/xpcom/threads/HangMonitor.cpp @@ -138,7 +138,7 @@ GetChromeHangReport(Telemetry::ProcessedStack &aStack) ret = ::ResumeThread(winMainThreadHandle); if (ret == -1) return; - aStack = Telemetry::GetStackAndModules(rawStack, false); + aStack = Telemetry::GetStackAndModules(rawStack); } #endif From b1fa9ef04944e080cf7dfcb6041a205439637c54 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Tue, 20 Nov 2012 15:24:27 +0000 Subject: [PATCH 12/75] Bug 808410 - remotereftest.py shouldn't ignore the runTests() exit code; r=jmaher --- layout/tools/reftest/remotereftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/tools/reftest/remotereftest.py b/layout/tools/reftest/remotereftest.py index de8347c11bd9..408bc847a5a7 100644 --- a/layout/tools/reftest/remotereftest.py +++ b/layout/tools/reftest/remotereftest.py @@ -442,7 +442,7 @@ def main(args): if options.bootstrap: cmdlineArgs = [] dm.recordLogcat() - reftest.runTests(manifest, options, cmdlineArgs) + retVal = reftest.runTests(manifest, options, cmdlineArgs) except: print "Automation Error: Exception caught while running tests" traceback.print_exc() From bb1131372a41afa32dc20ecf9db4a1591e6a5ec9 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Tue, 20 Nov 2012 15:24:28 +0000 Subject: [PATCH 13/75] Bug 808410 - Ensure non-zero return values for robocop tests aren't overwritten by later success; r=gbrown --- testing/mochitest/runtestsremote.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/testing/mochitest/runtestsremote.py b/testing/mochitest/runtestsremote.py index c0aafb4c6cf5..d307729b5f14 100644 --- a/testing/mochitest/runtestsremote.py +++ b/testing/mochitest/runtestsremote.py @@ -496,7 +496,10 @@ def main(): try: dm.recordLogcat() - retVal = mochitest.runTests(options) + result = mochitest.runTests(options) + # Ensure earlier failures aren't overwritten by success on this run + if retVal is None or retVal == 0: + retVal = result mochitest.addLogData() except: print "Automation Error: Exception caught while running tests" From b138aec7f5dc90c7502d763dd51b68a0f07a6781 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Tue, 20 Nov 2012 15:24:28 +0000 Subject: [PATCH 14/75] Bug 808410 - checkForCrashes should return true for cases where we hit an exception during minidump stackwalk; r=jmaher --- build/automationutils.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/build/automationutils.py b/build/automationutils.py index 2376ad015cd9..d1a9971df7a3 100644 --- a/build/automationutils.py +++ b/build/automationutils.py @@ -146,7 +146,6 @@ def checkForCrashes(dumpDir, symbolsPath, testName=None): if len(dumps) == 0: return False - foundCrash = False removeSymbolsPath = False # If our symbols are at a remote URL, download them now @@ -198,12 +197,11 @@ def checkForCrashes(dumpDir, symbolsPath, testName=None): extra = os.path.splitext(d)[0] + ".extra" if os.path.exists(extra): os.remove(extra) - foundCrash = True finally: if removeSymbolsPath: shutil.rmtree(symbolsPath) - return foundCrash + return True def getFullPath(directory, path): "Get an absolute path relative to 'directory'." From 527f7e728c1f86aff10edae52d6679dc96aa68a8 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Tue, 20 Nov 2012 15:24:28 +0000 Subject: [PATCH 15/75] Bug 808410 - Make peptest's checkForCrashes more consistent with the version in automationutils.py; r=jmaher --- testing/peptest/peptest/runpeptests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testing/peptest/peptest/runpeptests.py b/testing/peptest/peptest/runpeptests.py index 19c0085814f8..bbbc0f9370e1 100644 --- a/testing/peptest/peptest/runpeptests.py +++ b/testing/peptest/peptest/runpeptests.py @@ -172,15 +172,15 @@ class Peptest(): except: testName = "unknown" - foundCrash = False dumpDir = os.path.join(self.profile.profile, 'minidumps') dumps = glob.glob(os.path.join(dumpDir, '*.dmp')) + if len(dumps) == 0: + return False symbolsPath = self.options.symbolsPath for d in dumps: import subprocess - foundCrash = True self.logger.info("PROCESS-CRASH | %s | application crashed (minidump found)", testName) print "Crash dump filename: " + d @@ -213,7 +213,7 @@ class Peptest(): if utils.isURL(self.options.symbolsPath): if os.path.exists(symbolsPath): shutil.rmtree(symbolsPath) - return foundCrash + return True class FirefoxPeptest(Peptest): profile_class = FirefoxProfile From 4ad312620ddb2c307e328dadd2d5797c7d9bfa60 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Tue, 20 Nov 2012 15:24:28 +0000 Subject: [PATCH 16/75] Bug 808410 - Callers of checkForCrashes should use its return value to ensure shutdown crashes actually make the run fail; r=jmaher f=gps --- build/automation.py.in | 8 ++++++-- build/mobile/b2gautomation.py | 3 ++- build/mobile/remoteautomation.py | 25 +++++++++++++------------ testing/xpcshell/runxpcshelltests.py | 11 ++++++++++- 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/build/automation.py.in b/build/automation.py.in index 90a76935da03..0b1fa76382f4 100644 --- a/build/automation.py.in +++ b/build/automation.py.in @@ -998,7 +998,7 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t self.killPid(processPID) def checkForCrashes(self, profileDir, symbolsPath): - automationutils.checkForCrashes(os.path.join(profileDir, "minidumps"), symbolsPath, self.lastTestSeen) + return automationutils.checkForCrashes(os.path.join(profileDir, "minidumps"), symbolsPath, self.lastTestSeen) def runApp(self, testURL, env, app, profileDir, extraArgs, runSSLTunnel = False, utilityPath = None, @@ -1066,7 +1066,11 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t # Do a final check for zombie child processes. self.checkForZombies(processLog) - self.checkForCrashes(profileDir, symbolsPath) + + crashed = self.checkForCrashes(profileDir, symbolsPath) + + if crashed: + status = 1 if os.path.exists(processLog): os.unlink(processLog) diff --git a/build/mobile/b2gautomation.py b/build/mobile/b2gautomation.py index c5492ce3b2a4..11732f2176e8 100644 --- a/build/mobile/b2gautomation.py +++ b/build/mobile/b2gautomation.py @@ -99,11 +99,12 @@ class B2GRemoteAutomation(Automation): # is in place. dumpDir = tempfile.mkdtemp() self._devicemanager.getDirectory(self._remoteProfile + '/minidumps/', dumpDir) - automationutils.checkForCrashes(dumpDir, symbolsPath, self.lastTestSeen) + crashed = automationutils.checkForCrashes(dumpDir, symbolsPath, self.lastTestSeen) try: shutil.rmtree(dumpDir) except: print "WARNING: unable to remove directory: %s" % (dumpDir) + return crashed def initializeProfile(self, profileDir, extraPrefs = [], useServerLocations = False): # add b2g specific prefs diff --git a/build/mobile/remoteautomation.py b/build/mobile/remoteautomation.py index 979996c81cbc..dcd20ccdb52b 100644 --- a/build/mobile/remoteautomation.py +++ b/build/mobile/remoteautomation.py @@ -85,21 +85,22 @@ class RemoteAutomation(Automation): def checkForCrashes(self, directory, symbolsPath): remoteCrashDir = self._remoteProfile + '/minidumps/' - if self._devicemanager.dirExists(remoteCrashDir): - dumpDir = tempfile.mkdtemp() - self._devicemanager.getDirectory(remoteCrashDir, dumpDir) - automationutils.checkForCrashes(dumpDir, symbolsPath, - self.lastTestSeen) - try: - shutil.rmtree(dumpDir) - except: - print "WARNING: unable to remove directory: %s" % dumpDir - else: + if not self._devicemanager.dirExists(remoteCrashDir): # As of this writing, the minidumps directory is automatically # created when fennec (first) starts, so its lack of presence # is a hint that something went wrong. - print "WARNING: No crash directory (%s) on remote " \ - "device" % remoteCrashDir + print "Automation Error: No crash directory (%s) found on remote device" % remoteCrashDir + # Whilst no crash was found, the run should still display as a failure + return True + dumpDir = tempfile.mkdtemp() + self._devicemanager.getDirectory(remoteCrashDir, dumpDir) + crashed = automationutils.checkForCrashes(dumpDir, symbolsPath, + self.lastTestSeen) + try: + shutil.rmtree(dumpDir) + except: + print "WARNING: unable to remove directory: %s" % dumpDir + return crashed def buildCommandLine(self, app, debuggerInfo, profileDir, testURL, extraArgs): # If remote profile is specified, use that instead diff --git a/testing/xpcshell/runxpcshelltests.py b/testing/xpcshell/runxpcshelltests.py index d638f69c018b..0089370df44b 100644 --- a/testing/xpcshell/runxpcshelltests.py +++ b/testing/xpcshell/runxpcshelltests.py @@ -870,7 +870,16 @@ class XPCShellTests(object): self.todoCount += 1 xunitResult["todo"] = True - checkForCrashes(testdir, self.symbolsPath, testName=name) + if checkForCrashes(testdir, self.symbolsPath, testName=name): + message = "PROCESS-CRASH | %s | application crashed" % name + self.failCount += 1 + xunitResult["passed"] = False + xunitResult["failure"] = { + "type": "PROCESS-CRASH", + "message": message, + "text": stdout + } + # Find child process(es) leak log(s), if any: See InitLog() in # xpcom/base/nsTraceRefcntImpl.cpp for logfile naming logic leakLogs = [self.leakLogFile] From 5bbd06f4ebfa7a2e7051d195c35cfa4585b7912c Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Tue, 20 Nov 2012 15:24:28 +0000 Subject: [PATCH 17/75] Bug 808410 - Ensure retVal is set even when mochitest.cleanup did not generate an exception; r=ahal --- testing/mochitest/runtestsb2g.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/mochitest/runtestsb2g.py b/testing/mochitest/runtestsb2g.py index fb5861dcf896..63e8992e25a4 100644 --- a/testing/mochitest/runtestsb2g.py +++ b/testing/mochitest/runtestsb2g.py @@ -533,7 +533,7 @@ def main(): mochitest.cleanup(None, options) except: pass - sys.exit(1) + retVal = 1 sys.exit(retVal) From f5df1490d4e86bf2f7add7cb13b435c344f8e251 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Tue, 20 Nov 2012 15:24:28 +0000 Subject: [PATCH 18/75] Bug 812135 - checkForZombies should return the result; r=jmaher --- build/automation.py.in | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/build/automation.py.in b/build/automation.py.in index 0b1fa76382f4..353f07d6fcdd 100644 --- a/build/automation.py.in +++ b/build/automation.py.in @@ -978,24 +978,29 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t def checkForZombies(self, processLog): """ Look for hung processes """ if not os.path.exists(processLog): - self.log.info('INFO | automation.py | PID log not found: %s', processLog) - else: - self.log.info('INFO | automation.py | Reading PID log: %s', processLog) - processList = [] - pidRE = re.compile(r'launched child process (\d+)$') - processLogFD = open(processLog) - for line in processLogFD: - self.log.info(line.rstrip()) - m = pidRE.search(line) - if m: - processList.append(int(m.group(1))) - processLogFD.close() + self.log.info('Automation Error: PID log not found: %s', processLog) + # Whilst no hung process was found, the run should still display as a failure + return True - for processPID in processList: - self.log.info("INFO | automation.py | Checking for orphan process with PID: %d", processPID) - if self.isPidAlive(processPID): - self.log.info("TEST-UNEXPECTED-FAIL | automation.py | child process %d still alive after shutdown", processPID) - self.killPid(processPID) + foundZombie = False + self.log.info('INFO | automation.py | Reading PID log: %s', processLog) + processList = [] + pidRE = re.compile(r'launched child process (\d+)$') + processLogFD = open(processLog) + for line in processLogFD: + self.log.info(line.rstrip()) + m = pidRE.search(line) + if m: + processList.append(int(m.group(1))) + processLogFD.close() + + for processPID in processList: + self.log.info("INFO | automation.py | Checking for orphan process with PID: %d", processPID) + if self.isPidAlive(processPID): + foundZombie = True + self.log.info("TEST-UNEXPECTED-FAIL | automation.py | child process %d still alive after shutdown", processPID) + self.killPid(processPID) + return foundZombie def checkForCrashes(self, profileDir, symbolsPath): return automationutils.checkForCrashes(os.path.join(profileDir, "minidumps"), symbolsPath, self.lastTestSeen) From c385ba722ee5947bdb0cee27b74ad7f2c99ec019 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Tue, 20 Nov 2012 15:24:28 +0000 Subject: [PATCH 19/75] Bug 812135 - Use the checkForZombies result to determine run status; r=jmaher --- build/automation.py.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/automation.py.in b/build/automation.py.in index 353f07d6fcdd..e70c55583360 100644 --- a/build/automation.py.in +++ b/build/automation.py.in @@ -1070,11 +1070,11 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t self.log.info("INFO | automation.py | Application ran for: %s", str(datetime.now() - startTime)) # Do a final check for zombie child processes. - self.checkForZombies(processLog) + zombieProcesses = self.checkForZombies(processLog) crashed = self.checkForCrashes(profileDir, symbolsPath) - if crashed: + if crashed or zombieProcesses: status = 1 if os.path.exists(processLog): From e716f0247497afd03981c4a8c280b03d724d3471 Mon Sep 17 00:00:00 2001 From: Benjamin Smedberg Date: Tue, 20 Nov 2012 10:32:41 -0500 Subject: [PATCH 20/75] Bug 791244 test fixup - allow for the pref to be unset by default, r=gfritzsche --HG-- extra : transplant_source : kuU%89j%A3%2A%DF%E0%D0%A5S%07%5D%99z%1D%7B%B1%C8 --- dom/plugins/test/mochitest/test_hang_submit.xul | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/dom/plugins/test/mochitest/test_hang_submit.xul b/dom/plugins/test/mochitest/test_hang_submit.xul index b363df2bcb51..b92dd0669b9f 100644 --- a/dom/plugins/test/mochitest/test_hang_submit.xul +++ b/dom/plugins/test/mochitest/test_hang_submit.xul @@ -32,9 +32,17 @@ const Cc = Components.classes; const Ci = Components.interfaces; const crashReporter = Cc["@mozilla.org/toolkit/crash-reporter;1"].getService(Ci.nsICrashReporter); -const oldServerPref = Services.prefs.getCharPref("toolkit.crashreporter.pluginHangSubmitURL"); const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs"; +const serverPrefName = "toolkit.crashreporter.pluginHangSubmitURL"; + +var oldServerPref; +try { + oldServerPref = Services.prefs.getCharPref(serverPrefName); +} +catch(e) { +} + const oldTimeoutPref = Services.prefs.getIntPref("dom.ipc.plugins.timeoutSecs"); var testObserver = { @@ -81,7 +89,12 @@ var testObserver = { env.set("MOZ_CRASHREPORTER_NO_REPORT", "1"); // Finally re-set prefs - Services.prefs.setCharPref("toolkit.crashreporter.pluginHangSubmitURL", oldServerPref); + if (oldServerPref === undefined) { + Services.prefs.clearUserPref(serverPrefName); + } + else { + Services.prefs.setCharPref(serverPrefName, oldServerPref); + } Services.prefs.setIntPref("dom.ipc.plugins.timeoutSecs", oldTimeoutPref); SimpleTest.finish(); }, From 69f2d996f4ba6106b6c1a29a5771c14c8263ea44 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Tue, 20 Nov 2012 15:43:10 +0000 Subject: [PATCH 21/75] Bug 805292 - Make a 'pick' activity without a type to work, r=mounir --- dom/activities/src/ActivitiesService.jsm | 34 +++++++++++++++++++----- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/dom/activities/src/ActivitiesService.jsm b/dom/activities/src/ActivitiesService.jsm index 6ad759b09459..814ffe9c1ca0 100644 --- a/dom/activities/src/ActivitiesService.jsm +++ b/dom/activities/src/ActivitiesService.jsm @@ -258,16 +258,38 @@ let Activities = { }; let matchFunc = function matchFunc(aResult) { - // Bug 773383: arrays of strings / regexp. - for (let prop in aResult.description.filters) { - if (Array.isArray(aResult.description.filters[prop])) { - if (aResult.description.filters[prop].indexOf(aMsg.options.data[prop]) == -1) { - return false; + + function matchFuncValue(aValue, aFilter) { + // Bug 805822 - Regexp support for MozActivity + + let values = Array.isArray(aValue) ? aValue : [aValue]; + let filters = Array.isArray(aFilter) ? aFilter : [aFilter]; + + // At least 1 value must match. + let ret = false; + values.forEach(function(value) { + if (filters.indexOf(value) != -1) { + ret = true; } - } else if (aResult.description.filters[prop] !== aMsg.options.data[prop] ) { + }); + + return ret; + } + + // For any incoming property. + for (let prop in aMsg.options.data) { + + // If this is unknown for the app, this app must be excluded. + if (!(prop in aResult.description.filters)) { + return false; + } + + // Otherwise, let's check the value against the filter. + if (!matchFuncValue(aMsg.options.data[prop], aResult.description.filters[prop])) { return false; } } + return true; }; From 03c3026df2850e1dcd0a1723f4abd3c77591a773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20=C3=81vila=20de=20Esp=C3=ADndola?= Date: Tue, 20 Nov 2012 10:50:50 -0500 Subject: [PATCH 22/75] Bug 813076 - Upgrade clang to 168304 in the 3.2 branch. r=rail. Update the manifests. --- b2g/config/tooltool-manifests/macosx64/releng.manifest | 6 +++--- browser/config/tooltool-manifests/linux32/clang.manifest | 6 +++--- browser/config/tooltool-manifests/linux64/clang.manifest | 6 +++--- browser/config/tooltool-manifests/macosx32/releng.manifest | 6 +++--- browser/config/tooltool-manifests/macosx64/releng.manifest | 6 +++--- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/b2g/config/tooltool-manifests/macosx64/releng.manifest b/b2g/config/tooltool-manifests/macosx64/releng.manifest index 788f70c2a326..e5650b9b708b 100644 --- a/b2g/config/tooltool-manifests/macosx64/releng.manifest +++ b/b2g/config/tooltool-manifests/macosx64/releng.manifest @@ -1,6 +1,6 @@ [ { -"clang_version": "r167750" +"clang_version": "r168304" }, { "size": 47, @@ -9,8 +9,8 @@ "filename": "setup.sh" }, { -"size": 56161789, -"digest": "43a35be63f9ea1c73a1b22532b5484b131f0c25bdb6a2f39e31c968b6c3477f6640450cc8dab8e17df80f20e367b8cbc0a74986a4eefd7ac9b9adf2b0859e55e", +"size": 56144782, +"digest": "7e7dd6775d71d074cced8407fac82dc5e161a9034927bd059c84fc06da161da39d32bbd95ac9b6efdf550370fa351361bc476f0b327387dc8d503dc446a776d6", "algorithm": "sha512", "filename": "clang.tar.bz2" } diff --git a/browser/config/tooltool-manifests/linux32/clang.manifest b/browser/config/tooltool-manifests/linux32/clang.manifest index d0d308be4803..18003ddfe90e 100644 --- a/browser/config/tooltool-manifests/linux32/clang.manifest +++ b/browser/config/tooltool-manifests/linux32/clang.manifest @@ -1,6 +1,6 @@ [ { -"clang_version": "r167750" +"clang_version": "r168304" }, { "size": 47, @@ -9,8 +9,8 @@ "filename": "setup.sh" }, { -"size": 62553019, -"digest": "31dd1ef281d0508bda0c470a29f244f062f42a4c521664dd1833f0f760c4d0cc0a222a8ba23063ad4cf50b678c2ee057519bd480e4a4f6804c3c7fb40f841a92", +"size": 62536221, +"digest": "a8381234d896ba2eeeef287b948f9d8ffc73bf4d4608ce74002eb666f1ac06d00047fd09b1b8f241c7160561b5dc7a40faf7f8bec94bb7939b9b77ba76af5967", "algorithm": "sha512", "filename": "clang.tar.bz2" } diff --git a/browser/config/tooltool-manifests/linux64/clang.manifest b/browser/config/tooltool-manifests/linux64/clang.manifest index 2f5cdac89e27..8a165a61820d 100644 --- a/browser/config/tooltool-manifests/linux64/clang.manifest +++ b/browser/config/tooltool-manifests/linux64/clang.manifest @@ -1,6 +1,6 @@ [ { -"clang_version": "r167750" +"clang_version": "r168304" }, { "size": 47, @@ -9,8 +9,8 @@ "filename": "setup.sh" }, { -"size": 62858526, -"digest": "3c8280e001420eea4c352b05dfffda317ecb9c3be1eb23bda5cb16efebd4fe1b38f752b644acf33c6d34858ae01aa026cbb4c6f319fd6ee8d372517922063ad8", +"size": 62877504, +"digest": "837884b29c176e652b81e9cdaaeda34cf0bf41b7fe17a7f84ed30269ad7daedc9d72ba0d188b8f1551456f307f2dd72583daf99539e62403c0f2b5a83735658e", "algorithm": "sha512", "filename": "clang.tar.bz2" } diff --git a/browser/config/tooltool-manifests/macosx32/releng.manifest b/browser/config/tooltool-manifests/macosx32/releng.manifest index 788f70c2a326..e5650b9b708b 100644 --- a/browser/config/tooltool-manifests/macosx32/releng.manifest +++ b/browser/config/tooltool-manifests/macosx32/releng.manifest @@ -1,6 +1,6 @@ [ { -"clang_version": "r167750" +"clang_version": "r168304" }, { "size": 47, @@ -9,8 +9,8 @@ "filename": "setup.sh" }, { -"size": 56161789, -"digest": "43a35be63f9ea1c73a1b22532b5484b131f0c25bdb6a2f39e31c968b6c3477f6640450cc8dab8e17df80f20e367b8cbc0a74986a4eefd7ac9b9adf2b0859e55e", +"size": 56144782, +"digest": "7e7dd6775d71d074cced8407fac82dc5e161a9034927bd059c84fc06da161da39d32bbd95ac9b6efdf550370fa351361bc476f0b327387dc8d503dc446a776d6", "algorithm": "sha512", "filename": "clang.tar.bz2" } diff --git a/browser/config/tooltool-manifests/macosx64/releng.manifest b/browser/config/tooltool-manifests/macosx64/releng.manifest index 788f70c2a326..e5650b9b708b 100644 --- a/browser/config/tooltool-manifests/macosx64/releng.manifest +++ b/browser/config/tooltool-manifests/macosx64/releng.manifest @@ -1,6 +1,6 @@ [ { -"clang_version": "r167750" +"clang_version": "r168304" }, { "size": 47, @@ -9,8 +9,8 @@ "filename": "setup.sh" }, { -"size": 56161789, -"digest": "43a35be63f9ea1c73a1b22532b5484b131f0c25bdb6a2f39e31c968b6c3477f6640450cc8dab8e17df80f20e367b8cbc0a74986a4eefd7ac9b9adf2b0859e55e", +"size": 56144782, +"digest": "7e7dd6775d71d074cced8407fac82dc5e161a9034927bd059c84fc06da161da39d32bbd95ac9b6efdf550370fa351361bc476f0b327387dc8d503dc446a776d6", "algorithm": "sha512", "filename": "clang.tar.bz2" } From 78c89911196535ab2bdf9c0380ec8042b238acf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20=C3=81vila=20de=20Esp=C3=ADndola?= Date: Tue, 20 Nov 2012 10:51:56 -0500 Subject: [PATCH 23/75] Bug 813076 - Upgrade clang to 168304 in the 3.2 branch. r=rail. Update the build script. --- build/unix/build-clang/build-clang.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/unix/build-clang/build-clang.py b/build/unix/build-clang/build-clang.py index b24873b11006..12c9da0d7539 100755 --- a/build/unix/build-clang/build-clang.py +++ b/build/unix/build-clang/build-clang.py @@ -3,7 +3,7 @@ # 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/. -llvm_revision = "167750" +llvm_revision = "168304" moz_version = "moz0" ############################################## From 45165aa7cfe2c0f1973f95907564608a7afaef5c Mon Sep 17 00:00:00 2001 From: Joel Maher Date: Tue, 20 Nov 2012 11:33:24 -0500 Subject: [PATCH 24/75] Bug 813105 - upload a new talos.zip to turn datazilla back on. r=Callek --- testing/talos/talos.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/talos/talos.json b/testing/talos/talos.json index 33965d401584..1b69d8e8ad8d 100644 --- a/testing/talos/talos.json +++ b/testing/talos/talos.json @@ -1,6 +1,6 @@ { "talos.zip": { - "url": "http://build.mozilla.org/talos/zips/talos.22211d6cecfb.zip", + "url": "http://build.mozilla.org/talos/zips/talos.a7c94dd16de9.zip", "path": "" } } From 5b5182548512e6c55f3974f18314ca4d5bc0b083 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 20 Nov 2012 11:36:06 -0500 Subject: [PATCH 25/75] Bug 812789. Remove some dead code for converting jsvals to Matrix objects. r=nrc --- content/canvas/src/CanvasUtils.cpp | 95 ------------------------------ content/canvas/src/CanvasUtils.h | 12 ---- 2 files changed, 107 deletions(-) diff --git a/content/canvas/src/CanvasUtils.cpp b/content/canvas/src/CanvasUtils.cpp index 2a5f8cd92a48..6cf0f538b5a4 100644 --- a/content/canvas/src/CanvasUtils.cpp +++ b/content/canvas/src/CanvasUtils.cpp @@ -85,100 +85,5 @@ CoerceDouble(jsval v, double* d) return true; } -template -static bool -JSValToMatrixElts(JSContext* cx, const jsval& val, - double* (&elts)[N], nsresult* rv) -{ - JSObject* obj; - uint32_t length; - - if (JSVAL_IS_PRIMITIVE(val) || - !(obj = JSVAL_TO_OBJECT(val)) || - !JS_GetArrayLength(cx, obj, &length) || - N != length) { - // Not an array-like thing or wrong size - *rv = NS_ERROR_INVALID_ARG; - return false; - } - - for (uint32_t i = 0; i < N; ++i) { - jsval elt; - double d; - if (!JS_GetElement(cx, obj, i, &elt)) { - *rv = NS_ERROR_FAILURE; - return false; - } - if (!CoerceDouble(elt, &d)) { - *rv = NS_ERROR_INVALID_ARG; - return false; - } - if (!FloatValidate(d)) { - // This is weird, but it's the behavior of SetTransform() - *rv = NS_OK; - return false; - } - *elts[i] = d; - } - - *rv = NS_OK; - return true; -} - -bool -JSValToMatrix(JSContext* cx, const jsval& val, gfxMatrix* matrix, nsresult* rv) -{ - double* elts[] = { &matrix->xx, &matrix->yx, &matrix->xy, &matrix->yy, - &matrix->x0, &matrix->y0 }; - return JSValToMatrixElts(cx, val, elts, rv); -} - -bool -JSValToMatrix(JSContext* cx, const jsval& val, Matrix* matrix, nsresult* rv) -{ - gfxMatrix m; - if (!JSValToMatrix(cx, val, &m, rv)) - return false; - *matrix = Matrix(Float(m.xx), Float(m.yx), Float(m.xy), Float(m.yy), - Float(m.x0), Float(m.y0)); - return true; -} - -template -static nsresult -MatrixEltsToJSVal(/*const*/ jsval (&elts)[N], JSContext* cx, jsval* val) -{ - JSObject* obj = JS_NewArrayObject(cx, N, elts); - if (!obj) { - return NS_ERROR_OUT_OF_MEMORY; - } - - *val = OBJECT_TO_JSVAL(obj); - - return NS_OK; -} - -nsresult -MatrixToJSVal(const gfxMatrix& matrix, JSContext* cx, jsval* val) -{ - jsval elts[] = { - DOUBLE_TO_JSVAL(matrix.xx), DOUBLE_TO_JSVAL(matrix.yx), - DOUBLE_TO_JSVAL(matrix.xy), DOUBLE_TO_JSVAL(matrix.yy), - DOUBLE_TO_JSVAL(matrix.x0), DOUBLE_TO_JSVAL(matrix.y0) - }; - return MatrixEltsToJSVal(elts, cx, val); -} - -nsresult -MatrixToJSVal(const Matrix& matrix, JSContext* cx, jsval* val) -{ - jsval elts[] = { - DOUBLE_TO_JSVAL(matrix._11), DOUBLE_TO_JSVAL(matrix._12), - DOUBLE_TO_JSVAL(matrix._21), DOUBLE_TO_JSVAL(matrix._22), - DOUBLE_TO_JSVAL(matrix._31), DOUBLE_TO_JSVAL(matrix._32) - }; - return MatrixEltsToJSVal(elts, cx, val); -} - } // namespace CanvasUtils } // namespace mozilla diff --git a/content/canvas/src/CanvasUtils.h b/content/canvas/src/CanvasUtils.h index 9b3603d8ff22..bef1ba7ff5df 100644 --- a/content/canvas/src/CanvasUtils.h +++ b/content/canvas/src/CanvasUtils.h @@ -49,18 +49,6 @@ void DoDrawImageSecurityCheck(nsHTMLCanvasElement *aCanvasElement, // succeeded. bool CoerceDouble(jsval v, double* d); -// Return true iff the conversion succeeded, false otherwise. *rv is -// the value to return to script if this returns false. -bool JSValToMatrix(JSContext* cx, const jsval& val, - gfxMatrix* matrix, nsresult* rv); -bool JSValToMatrix(JSContext* cx, const jsval& val, - gfx::Matrix* matrix, nsresult* rv); - -nsresult MatrixToJSVal(const gfxMatrix& matrix, - JSContext* cx, jsval* val); -nsresult MatrixToJSVal(const gfx::Matrix& matrix, - JSContext* cx, jsval* val); - /* Float validation stuff */ #define VALIDATE(_f) if (!NS_finite(_f)) return false From 77eb8146ff5430e9388c034084afea00325a0d5e Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 20 Nov 2012 11:36:06 -0500 Subject: [PATCH 26/75] Bug 813419. Add a non-null-checking version of xpc_UnmarkGrayObject. r=mccr8 --- dom/bindings/BindingUtils.h | 11 +++++++---- js/xpconnect/src/xpcpublic.h | 17 ++++++++++++----- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h index 2f1929aee503..db3ed821f455 100644 --- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -478,10 +478,13 @@ template inline bool WrapNewBindingObject(JSContext* cx, JSObject* scope, T* value, JS::Value* vp) { - JSObject* obj = value->GetWrapper(); - if (obj && js::GetObjectCompartment(obj) == js::GetObjectCompartment(scope)) { - *vp = JS::ObjectValue(*obj); - return true; + JSObject* obj = value->GetWrapperPreserveColor(); + if (obj) { + xpc_UnmarkNonNullGrayObject(obj); + if (js::GetObjectCompartment(obj) == js::GetObjectCompartment(scope)) { + *vp = JS::ObjectValue(*obj); + return true; + } } if (!obj) { diff --git a/js/xpconnect/src/xpcpublic.h b/js/xpconnect/src/xpcpublic.h index e9639fbc0eb4..d8eca979c9cd 100644 --- a/js/xpconnect/src/xpcpublic.h +++ b/js/xpconnect/src/xpcpublic.h @@ -140,16 +140,23 @@ xpc_GCThingIsGrayCCThing(void *thing); extern void xpc_UnmarkGrayGCThingRecursive(void *thing, JSGCTraceKind kind); +// Unmark gray for known-nonnull cases +MOZ_ALWAYS_INLINE void +xpc_UnmarkNonNullGrayObject(JSObject *obj) +{ + if (xpc_IsGrayGCThing(obj)) + xpc_UnmarkGrayGCThingRecursive(obj, JSTRACE_OBJECT); + else if (JS::IsIncrementalBarrierNeededOnGCThing(obj)) + js::IncrementalReferenceBarrier(obj); +} + // Remove the gray color from the given JSObject and any other objects that can // be reached through it. -inline JSObject * +MOZ_ALWAYS_INLINE JSObject * xpc_UnmarkGrayObject(JSObject *obj) { if (obj) { - if (xpc_IsGrayGCThing(obj)) - xpc_UnmarkGrayGCThingRecursive(obj, JSTRACE_OBJECT); - else if (JS::IsIncrementalBarrierNeededOnGCThing(obj)) - js::IncrementalReferenceBarrier(obj); + xpc_UnmarkNonNullGrayObject(obj); } return obj; } From b6b9137a48ef22e38d34e33724cb9f054195249f Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 20 Nov 2012 11:36:06 -0500 Subject: [PATCH 27/75] Bug 813423. A bit more inlining for stuff that should really be inline. r=peterv --- dom/bindings/BindingUtils.h | 2 +- js/xpconnect/src/XPCQuickStubs.h | 2 +- js/xpconnect/src/nsDOMQS.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h index db3ed821f455..ed4fe2e45606 100644 --- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -475,7 +475,7 @@ public: // non-wrapper-cached object using WebIDL bindings. "value" must implement a // WrapObject() method taking a JSContext and a scope. template -inline bool +MOZ_ALWAYS_INLINE bool WrapNewBindingObject(JSContext* cx, JSObject* scope, T* value, JS::Value* vp) { JSObject* obj = value->GetWrapperPreserveColor(); diff --git a/js/xpconnect/src/XPCQuickStubs.h b/js/xpconnect/src/XPCQuickStubs.h index c60b5e9a49ef..cfb0796b0f05 100644 --- a/js/xpconnect/src/XPCQuickStubs.h +++ b/js/xpconnect/src/XPCQuickStubs.h @@ -526,7 +526,7 @@ xpc_qsUnwrapArg(JSContext *cx, jsval v, Interface **ppArg, return rv; } -inline nsISupports* +MOZ_ALWAYS_INLINE nsISupports* castNativeArgFromWrapper(JSContext *cx, jsval v, uint32_t bit, diff --git a/js/xpconnect/src/nsDOMQS.h b/js/xpconnect/src/nsDOMQS.h index 93c478fdb5cb..4ef648704d32 100644 --- a/js/xpconnect/src/nsDOMQS.h +++ b/js/xpconnect/src/nsDOMQS.h @@ -62,7 +62,7 @@ xpc_qsUnwrapThis<_interface>(JSContext *cx, \ } \ \ template <> \ -inline nsresult \ +MOZ_ALWAYS_INLINE nsresult \ xpc_qsUnwrapArg<_interface>(JSContext *cx, \ jsval v, \ _interface **ppArg, \ From 54e62448019a2a484bbd677ea0512d39b48f4761 Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Tue, 20 Nov 2012 08:44:04 -0800 Subject: [PATCH 28/75] Backout b7e492bf7c13, a64c112c6858, 84b9a773104b, 4bd4aabbaf28 and 24ad2de34061 (bug 548206) for Win Ru orange --- content/base/public/DirectionalityUtils.h | 92 +- content/base/public/Element.h | 24 +- content/base/public/nsIDocument.h | 4 +- content/base/public/nsINode.h | 61 +- content/base/src/DirectionalityUtils.cpp | 810 +----------------- content/base/src/Element.cpp | 39 +- content/base/src/nsDocument.cpp | 1 + content/base/src/nsDocument.h | 2 +- content/base/src/nsGenericDOMDataNode.cpp | 5 - content/base/src/nsGkAtomList.h | 2 - content/base/src/nsTextNode.cpp | 23 - content/base/src/nsTextNode.h | 6 - .../html/content/src/nsGenericHTMLElement.cpp | 50 +- .../html/content/src/nsGenericHTMLElement.h | 4 - .../html/content/src/nsHTMLInputElement.cpp | 30 - content/html/content/src/nsHTMLInputElement.h | 2 - .../html/content/src/nsHTMLUnknownElement.h | 3 - content/html/content/test/test_bug660663.html | 5 +- .../bidi/dirAuto/dir_auto-EN-L-ref.html | 58 -- .../reftests/bidi/dirAuto/dir_auto-EN-L.html | 58 -- .../bidi/dirAuto/dir_auto-EN-R-ref.html | 58 -- .../reftests/bidi/dirAuto/dir_auto-EN-R.html | 58 -- .../reftests/bidi/dirAuto/dir_auto-L-ref.html | 58 -- layout/reftests/bidi/dirAuto/dir_auto-L.html | 58 -- .../bidi/dirAuto/dir_auto-N-EN-L-ref.html | 58 -- .../bidi/dirAuto/dir_auto-N-EN-L.html | 58 -- .../bidi/dirAuto/dir_auto-N-EN-R-ref.html | 58 -- .../bidi/dirAuto/dir_auto-N-EN-R.html | 58 -- .../bidi/dirAuto/dir_auto-N-EN-ref.html | 51 -- .../reftests/bidi/dirAuto/dir_auto-N-EN.html | 51 -- .../bidi/dirAuto/dir_auto-N-L-ref.html | 58 -- .../reftests/bidi/dirAuto/dir_auto-N-L.html | 58 -- .../bidi/dirAuto/dir_auto-N-R-ref.html | 58 -- .../reftests/bidi/dirAuto/dir_auto-N-R.html | 58 -- .../reftests/bidi/dirAuto/dir_auto-R-ref.html | 59 -- layout/reftests/bidi/dirAuto/dir_auto-R.html | 58 -- .../dirAuto/dir_auto-contained-L-ref.html | 62 -- .../bidi/dirAuto/dir_auto-contained-L.html | 62 -- .../dirAuto/dir_auto-contained-R-ref.html | 58 -- .../bidi/dirAuto/dir_auto-contained-R.html | 58 -- .../dirAuto/dir_auto-contained-bdi-L-ref.html | 64 -- .../dirAuto/dir_auto-contained-bdi-L.html | 64 -- .../dirAuto/dir_auto-contained-bdi-R-ref.html | 61 -- .../dirAuto/dir_auto-contained-bdi-R.html | 61 -- .../dirAuto/dir_auto-contained-dir-L-ref.html | 61 -- .../dirAuto/dir_auto-contained-dir-L.html | 61 -- .../dirAuto/dir_auto-contained-dir-R-ref.html | 58 -- .../dirAuto/dir_auto-contained-dir-R.html | 58 -- .../dir_auto-contained-dir_auto-L-ref.html | 61 -- .../dir_auto-contained-dir_auto-L.html | 61 -- .../dir_auto-contained-dir_auto-R-ref.html | 58 -- .../dir_auto-contained-dir_auto-R.html | 58 -- .../dir_auto-contained-script-L-ref.html | 58 -- .../dirAuto/dir_auto-contained-script-L.html | 58 -- .../dir_auto-contained-script-R-ref.html | 58 -- .../dirAuto/dir_auto-contained-script-R.html | 58 -- .../dir_auto-contained-style-L-ref.html | 70 -- .../dirAuto/dir_auto-contained-style-L.html | 70 -- .../dir_auto-contained-style-R-ref.html | 70 -- .../dirAuto/dir_auto-contained-style-R.html | 70 -- .../dir_auto-contained-textarea-L-ref.html | 61 -- .../dir_auto-contained-textarea-L.html | 61 -- .../dir_auto-contained-textarea-R-ref.html | 58 -- .../dir_auto-contained-textarea-R.html | 58 -- .../bidi/dirAuto/dir_auto-input-EN-L-ref.html | 59 -- .../bidi/dirAuto/dir_auto-input-EN-L.html | 59 -- .../bidi/dirAuto/dir_auto-input-EN-R-ref.html | 59 -- .../bidi/dirAuto/dir_auto-input-EN-R.html | 59 -- .../bidi/dirAuto/dir_auto-input-L-ref.html | 59 -- .../bidi/dirAuto/dir_auto-input-L.html | 59 -- .../dirAuto/dir_auto-input-N-EN-L-ref.html | 59 -- .../bidi/dirAuto/dir_auto-input-N-EN-L.html | 59 -- .../dirAuto/dir_auto-input-N-EN-R-ref.html | 59 -- .../bidi/dirAuto/dir_auto-input-N-EN-R.html | 59 -- .../bidi/dirAuto/dir_auto-input-N-EN-ref.html | 54 -- .../bidi/dirAuto/dir_auto-input-N-EN.html | 54 -- .../bidi/dirAuto/dir_auto-input-N-L-ref.html | 59 -- .../bidi/dirAuto/dir_auto-input-N-L.html | 59 -- .../bidi/dirAuto/dir_auto-input-N-R-ref.html | 59 -- .../bidi/dirAuto/dir_auto-input-N-R.html | 59 -- .../bidi/dirAuto/dir_auto-input-R-ref.html | 59 -- .../bidi/dirAuto/dir_auto-input-R.html | 59 -- .../dir_auto-input-script-EN-L-ref.html | 59 -- .../dirAuto/dir_auto-input-script-EN-L.html | 68 -- .../dir_auto-input-script-EN-R-ref.html | 59 -- .../dirAuto/dir_auto-input-script-EN-R.html | 68 -- .../dirAuto/dir_auto-input-script-L-ref.html | 59 -- .../bidi/dirAuto/dir_auto-input-script-L.html | 68 -- .../dir_auto-input-script-N-EN-L-ref.html | 59 -- .../dirAuto/dir_auto-input-script-N-EN-L.html | 68 -- .../dir_auto-input-script-N-EN-R-ref.html | 59 -- .../dirAuto/dir_auto-input-script-N-EN-R.html | 68 -- .../dir_auto-input-script-N-EN-ref.html | 54 -- .../dirAuto/dir_auto-input-script-N-EN.html | 63 -- .../dir_auto-input-script-N-L-ref.html | 59 -- .../dirAuto/dir_auto-input-script-N-L.html | 68 -- .../dir_auto-input-script-N-R-ref.html | 59 -- .../dirAuto/dir_auto-input-script-N-R.html | 68 -- .../dirAuto/dir_auto-input-script-R-ref.html | 59 -- .../bidi/dirAuto/dir_auto-input-script-R.html | 68 -- .../bidi/dirAuto/dir_auto-isolate-ref.html | 56 -- .../bidi/dirAuto/dir_auto-isolate.html | 58 -- .../bidi/dirAuto/dir_auto-pre-N-EN-ref.html | 49 -- .../bidi/dirAuto/dir_auto-pre-N-EN.html | 66 -- .../dir_auto-pre-N-between-Rs-ref.html | 61 -- .../dirAuto/dir_auto-pre-N-between-Rs.html | 76 -- .../bidi/dirAuto/dir_auto-pre-mixed-ref.html | 61 -- .../bidi/dirAuto/dir_auto-pre-mixed.html | 77 -- .../dirAuto/dir_auto-set-contained-dir-L.html | 74 -- .../dirAuto/dir_auto-set-contained-dir-R.html | 71 -- .../dir_auto-set-contained-invalid-dir-L.html | 75 -- .../dir_auto-set-contained-invalid-dir-R.html | 72 -- .../dirAuto/dir_auto-textarea-N-EN-ref.html | 49 -- .../bidi/dirAuto/dir_auto-textarea-N-EN.html | 66 -- .../dir_auto-textarea-N-between-Rs-ref.html | 65 -- .../dir_auto-textarea-N-between-Rs.html | 79 -- .../dirAuto/dir_auto-textarea-mixed-ref.html | 64 -- .../bidi/dirAuto/dir_auto-textarea-mixed.html | 80 -- .../dir_auto-textarea-script-N-EN-ref.html | 49 -- .../dir_auto-textarea-script-N-EN.html | 75 -- ...auto-textarea-script-N-between-Rs-ref.html | 65 -- ...dir_auto-textarea-script-N-between-Rs.html | 84 -- .../dir_auto-textarea-script-mixed-ref.html | 64 -- .../dir_auto-textarea-script-mixed.html | 98 --- .../dir_auto-unset-contained-dir-L-ref.html | 61 -- .../dir_auto-unset-contained-dir-L.html | 71 -- .../dir_auto-unset-contained-dir-R-ref.html | 64 -- .../dir_auto-unset-contained-dir-R.html | 74 -- .../dynamicDirAuto-ChangeText-LTR1.html | 18 - .../dynamicDirAuto-ChangeText-LTR10.html | 18 - .../dynamicDirAuto-ChangeText-LTR2.html | 18 - .../dynamicDirAuto-ChangeText-LTR3.html | 18 - .../dynamicDirAuto-ChangeText-LTR4.html | 18 - .../dynamicDirAuto-ChangeText-LTR5.html | 18 - .../dynamicDirAuto-ChangeText-LTR6.html | 18 - .../dynamicDirAuto-ChangeText-LTR7.html | 18 - .../dynamicDirAuto-ChangeText-LTR8.html | 18 - .../dynamicDirAuto-ChangeText-LTR9.html | 18 - .../dynamicDirAuto-ChangeText-RTL1.html | 18 - .../dynamicDirAuto-ChangeText-RTL10.html | 18 - .../dynamicDirAuto-ChangeText-RTL2.html | 18 - .../dynamicDirAuto-ChangeText-RTL3.html | 18 - .../dynamicDirAuto-ChangeText-RTL4.html | 18 - .../dynamicDirAuto-ChangeText-RTL5.html | 18 - .../dynamicDirAuto-ChangeText-RTL6.html | 18 - .../dynamicDirAuto-ChangeText-RTL7.html | 18 - .../dynamicDirAuto-ChangeText-RTL8.html | 18 - .../dynamicDirAuto-ChangeText-RTL9.html | 18 - .../dynamicDirAuto-DeleteText-LTR1.html | 18 - .../dynamicDirAuto-DeleteText-LTR2.html | 18 - .../dynamicDirAuto-DeleteText-LTR3.html | 18 - .../dynamicDirAuto-DeleteText-RTL1.html | 18 - .../dynamicDirAuto-DeleteText-RTL2.html | 18 - .../dynamicDirAuto-DeleteText-RTL3.html | 18 - .../dirAuto/dynamicDirAuto-addLTR-Auto.html | 14 - .../dirAuto/dynamicDirAuto-addRTL-Auto.html | 14 - .../dirAuto/dynamicDirAuto-refLTR-LTR.html | 17 - .../dirAuto/dynamicDirAuto-refLTR-RTL.html | 17 - .../dirAuto/dynamicDirAuto-refRTL-LTR.html | 17 - .../dirAuto/dynamicDirAuto-refRTL-NoDir.html | 20 - .../dirAuto/dynamicDirAuto-refRTL-RTL.html | 17 - .../dirAuto/dynamicDirAuto-setLTR-Auto1.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-Auto2.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-Auto3.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-Auto4.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-Auto5.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-Auto6.html | 18 - .../dynamicDirAuto-setLTR-InvalidDir1.html | 18 - .../dynamicDirAuto-setLTR-InvalidDir2.html | 18 - .../dynamicDirAuto-setLTR-InvalidDir3.html | 18 - .../dynamicDirAuto-setLTR-InvalidDir4.html | 18 - .../dynamicDirAuto-setLTR-InvalidDir5.html | 18 - .../dynamicDirAuto-setLTR-InvalidDir6.html | 18 - .../dynamicDirAuto-setLTR-InvalidDir7.html | 18 - .../dynamicDirAuto-setLTR-InvalidDir8.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-LTR1.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-LTR2.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-LTR3.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-LTR4.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-LTR5.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-LTR6.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-LTR7.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-LTR8.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-NoDir1.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-NoDir2.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-NoDir3.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-NoDir4.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-NoDir5.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-NoDir6.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-NoDir7.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-NoDir8.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-RTL1.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-RTL2.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-RTL3.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-RTL4.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-RTL5.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-RTL6.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-RTL7.html | 18 - .../dirAuto/dynamicDirAuto-setLTR-RTL8.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-Auto1.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-Auto2.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-Auto3.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-Auto4.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-Auto5.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-Auto6.html | 18 - .../dynamicDirAuto-setRTL-InvalidDir1.html | 18 - .../dynamicDirAuto-setRTL-InvalidDir2.html | 18 - .../dynamicDirAuto-setRTL-InvalidDir3.html | 18 - .../dynamicDirAuto-setRTL-InvalidDir4.html | 18 - .../dynamicDirAuto-setRTL-InvalidDir5.html | 18 - .../dynamicDirAuto-setRTL-InvalidDir6.html | 18 - .../dynamicDirAuto-setRTL-InvalidDir7.html | 18 - .../dynamicDirAuto-setRTL-InvalidDir8.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-LTR1.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-LTR2.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-LTR3.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-LTR4.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-LTR5.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-LTR6.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-LTR7.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-LTR8.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-NoDir1.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-NoDir2.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-NoDir3.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-NoDir4.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-NoDir5.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-NoDir6.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-NoDir7.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-NoDir8.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-RTL1.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-RTL2.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-RTL3.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-RTL4.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-RTL5.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-RTL6.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-RTL7.html | 18 - .../dirAuto/dynamicDirAuto-setRTL-RTL8.html | 18 - layout/reftests/bidi/dirAuto/reftest.list | 161 ---- layout/reftests/bidi/dirAuto/setDir.js | 199 ----- layout/reftests/bidi/reftest.list | 1 - layout/style/html.css | 3 - 241 files changed, 44 insertions(+), 10271 deletions(-) delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-EN-L-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-EN-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-EN-R-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-EN-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-L-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-N-EN-L-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-N-EN-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-N-EN-R-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-N-EN-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-N-EN-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-N-EN.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-N-L-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-N-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-N-R-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-N-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-R-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-L-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-R-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-L-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-R-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-dir-L-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-dir-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-dir-R-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-dir-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-L-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-R-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-script-L-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-script-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-script-R-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-script-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-style-L-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-style-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-style-R-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-style-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-L-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-R-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-EN-L-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-EN-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-EN-R-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-EN-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-L-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-L-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-R-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-N-EN.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-N-L-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-N-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-N-R-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-N-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-R-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-L-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-R-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-L-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-L-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-R-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-N-L-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-N-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-N-R-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-N-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-R-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-input-script-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-isolate-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-isolate.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-pre-N-EN-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-pre-N-EN.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-pre-N-between-Rs-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-pre-N-between-Rs.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-pre-mixed-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-pre-mixed.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-set-contained-dir-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-set-contained-dir-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-set-contained-invalid-dir-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-set-contained-invalid-dir-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-N-EN-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-N-EN.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-N-between-Rs-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-N-between-Rs.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-mixed-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-mixed.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-EN-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-EN.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-between-Rs-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-between-Rs.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-script-mixed-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-textarea-script-mixed.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-L-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-L.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-R-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-R.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR1.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR10.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR2.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR3.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR4.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR5.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR6.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR7.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR8.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR9.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL1.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL10.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL2.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL3.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL4.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL5.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL6.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL7.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL8.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL9.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR1.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR2.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR3.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL1.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL2.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL3.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-addLTR-Auto.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-addRTL-Auto.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-refLTR-LTR.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-refLTR-RTL.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-LTR.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-NoDir.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-RTL.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto1.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto2.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto3.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto4.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto5.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto6.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir1.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir2.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir3.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir4.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir5.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir6.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir7.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir8.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR1.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR2.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR3.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR4.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR5.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR6.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR7.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR8.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir1.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir2.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir3.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir4.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir5.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir6.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir7.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir8.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL1.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL2.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL3.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL4.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL5.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL6.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL7.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL8.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto1.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto2.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto3.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto4.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto5.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto6.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir1.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir2.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir3.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir4.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir5.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir6.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir7.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir8.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR1.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR2.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR3.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR4.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR5.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR6.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR7.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR8.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir1.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir2.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir3.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir4.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir5.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir6.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir7.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir8.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL1.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL2.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL3.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL4.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL5.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL6.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL7.html delete mode 100644 layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL8.html delete mode 100644 layout/reftests/bidi/dirAuto/reftest.list delete mode 100644 layout/reftests/bidi/dirAuto/setDir.js diff --git a/content/base/public/DirectionalityUtils.h b/content/base/public/DirectionalityUtils.h index 9d4a4000dbff..195f7009de2f 100644 --- a/content/base/public/DirectionalityUtils.h +++ b/content/base/public/DirectionalityUtils.h @@ -7,15 +7,9 @@ #ifndef DirectionalityUtils_h___ #define DirectionalityUtils_h___ -#include "prtypes.h" -#include "mozilla/StandardInteger.h" - class nsIContent; class nsIDocument; class nsINode; -class nsAString; -class nsAttrValue; -class nsTextNode; namespace mozilla { namespace dom { @@ -25,11 +19,12 @@ class Element; namespace mozilla { +namespace directionality { + enum Directionality { - eDir_NotSet, - eDir_RTL, - eDir_LTR, - eDir_Auto + eDir_NotSet = 0, + eDir_RTL = 1, + eDir_LTR = 2 }; /** @@ -49,84 +44,11 @@ Directionality RecomputeDirectionality(mozilla::dom::Element* aElement, * of setting the dir attribute, rather than walking up the ancestor tree in * the much more common case of getting the element's directionality. */ -void SetDirectionalityOnDescendants(mozilla::dom::Element* aElement, +void SetDirectionalityOnDescendants(mozilla::dom::Element* aElement, Directionality aDir, bool aNotify = true); -/** - * Walk the descendants of a node in tree order and, for any text node - * descendant that determines the directionality of some element and is not a - * descendant of another descendant of the original node with dir=auto, - * redetermine that element's directionality - */ -void WalkDescendantsResetAutoDirection(mozilla::dom::Element* aElement); - -/** - * After setting dir=auto on an element, walk its descendants in tree order. - * If the node doesn't have the NODE_ANCESTOR_HAS_DIR_AUTO flag, set the - * NODE_ANCESTOR_HAS_DIR_AUTO flag on all of its descendants. - * Resolve the directionality of the element by the "downward propagation - * algorithm" (defined in section 3 in the comments at the beginning of - * DirectionalityUtils.cpp) - */ -void WalkDescendantsSetDirAuto(mozilla::dom::Element* aElement, - bool aNotify = true); - -/** - * After unsetting dir=auto on an element, walk its descendants in tree order, - * skipping any that have dir=auto themselves, and unset the - * NODE_ANCESTOR_HAS_DIR_AUTO flag - */ -void WalkDescendantsClearAncestorDirAuto(mozilla::dom::Element* aElement); - -/** - * Walk the parent chain of a text node whose dir attribute has been removed and - * reset the direction of any of its ancestors which have dir=auto and whose - * directionality is determined by a text node descendant. - */ -void WalkAncestorsResetAutoDirection(mozilla::dom::Element* aElement, - bool aNotify = true); - -/** - * When the contents of a text node have changed, deal with any elements whose - * directionality needs to change - */ -void SetDirectionFromChangedTextNode(nsIContent* aTextNode, uint32_t aOffset, - const PRUnichar* aBuffer, uint32_t aLength, - bool aNotify); - -/** - * When a text node is appended to an element, find any ancestors with dir=auto - * whose directionality will be determined by the text node - */ -void SetDirectionFromNewTextNode(nsTextNode* aTextNode); - -/** - * When a text node is removed from a document, find any ancestors whose - * directionality it determined and redetermine their directionality - */ -void ResetDirectionSetByTextNode(nsTextNode* aTextNode); - -/** - * Set the directionality of an element according to the directionality of the - * text in aValue - */ -void SetDirectionalityFromValue(mozilla::dom::Element* aElement, - const nsAString& aValue, - bool aNotify); - -/** - * Called when setting the dir attribute on an element, immediately after - * AfterSetAttr. This is instead of using BeforeSetAttr or AfterSetAttr, because - * in AfterSetAttr we don't know the old value, so we can't identify all cases - * where we need to walk up or down the document tree and reset the direction; - * and in BeforeSetAttr we can't do the walk because this element hasn't had the - * value set yet so the results will be wrong. - */ -void OnSetDirAttr(mozilla::dom::Element* aElement, - const nsAttrValue* aNewValue, - bool hadValidDir, - bool aNotify); +} // end namespace directionality } // end namespace mozilla diff --git a/content/base/public/Element.h b/content/base/public/Element.h index 8ab3e2557e8e..b4800755ce9d 100644 --- a/content/base/public/Element.h +++ b/content/base/public/Element.h @@ -282,33 +282,34 @@ public: */ virtual nsIAtom *GetClassAttributeName() const; - inline Directionality GetDirectionality() const { + inline directionality::Directionality GetDirectionality() const { if (HasFlag(NODE_HAS_DIRECTION_RTL)) { - return eDir_RTL; + return directionality::eDir_RTL; } if (HasFlag(NODE_HAS_DIRECTION_LTR)) { - return eDir_LTR; + return directionality::eDir_LTR; } - return eDir_NotSet; + return directionality::eDir_NotSet; } - inline void SetDirectionality(Directionality aDir, bool aNotify) { + inline void SetDirectionality(directionality::Directionality aDir, + bool aNotify) { UnsetFlags(NODE_ALL_DIRECTION_FLAGS); if (!aNotify) { RemoveStatesSilently(DIRECTION_STATES); } switch (aDir) { - case (eDir_RTL): + case (directionality::eDir_RTL): SetFlags(NODE_HAS_DIRECTION_RTL); if (!aNotify) { AddStatesSilently(NS_EVENT_STATE_RTL); } break; - case(eDir_LTR): + case(directionality::eDir_LTR): SetFlags(NODE_HAS_DIRECTION_LTR); if (!aNotify) { AddStatesSilently(NS_EVENT_STATE_LTR); @@ -331,15 +332,6 @@ public: bool GetBindingURL(nsIDocument *aDocument, css::URLValue **aResult); - // The bdi element defaults to dir=auto if it has no dir attribute set. - // Other elements will only have dir=auto if they have an explicit dir=auto, - // which will mean that HasValidDir() returns true but HasFixedDir() returns - // false - inline bool HasDirAuto() const { - return (!HasFixedDir() && - (HasValidDir() || NodeInfo()->Equals(nsGkAtoms::bdi))); - } - protected: /** * Method to get the _intrinsic_ content state of this element. This is the diff --git a/content/base/public/nsIDocument.h b/content/base/public/nsIDocument.h index 3fc21aeed2f2..d37b1b5de01c 100644 --- a/content/base/public/nsIDocument.h +++ b/content/base/public/nsIDocument.h @@ -419,7 +419,7 @@ public: mSandboxFlags = sandboxFlags; } - inline mozilla::Directionality GetDocumentDirectionality() { + inline mozilla::directionality::Directionality GetDocumentDirectionality() { return mDirectionality; } @@ -1916,7 +1916,7 @@ protected: uint32_t mSandboxFlags; // The root directionality of this document. - mozilla::Directionality mDirectionality; + mozilla::directionality::Directionality mDirectionality; nsCString mContentLanguage; private: diff --git a/content/base/public/nsINode.h b/content/base/public/nsINode.h index 2775c08a1c10..5bbab1d1950d 100644 --- a/content/base/public/nsINode.h +++ b/content/base/public/nsINode.h @@ -1295,21 +1295,8 @@ private: NodeIsContent, // Set if the node has animations or transitions ElementHasAnimations, - // Set if node has a dir attribute with a valid value (ltr, rtl, or auto) + // Set if node has a dir attribute with a valid value (ltr or rtl) NodeHasValidDirAttribute, - // Set if node has a dir attribute with a fixed value (ltr or rtl, NOT auto) - NodeHasFixedDir, - // Set if the node has dir=auto and has a property pointing to the text - // node that determines its direction - NodeHasDirAutoSet, - // Set if the node is a text node descendant of a node with dir=auto - // and has a TextNodeDirectionalityMap property listing the elements whose - // direction it determines. - NodeHasTextNodeDirectionalityMap, - // Set if the node has dir=auto. - NodeHasDirAuto, - // Set if a node in the node's parent chain has dir=auto. - NodeAncestorHasDirAuto, // Guard value BooleanFlagCount }; @@ -1380,52 +1367,6 @@ public: void SetHasValidDir() { SetBoolFlag(NodeHasValidDirAttribute); } void ClearHasValidDir() { ClearBoolFlag(NodeHasValidDirAttribute); } bool HasValidDir() const { return GetBoolFlag(NodeHasValidDirAttribute); } - void SetHasFixedDir() { - MOZ_ASSERT(NodeType() != nsIDOMNode::TEXT_NODE, - "SetHasFixedDir on text node"); - SetBoolFlag(NodeHasFixedDir); - } - void ClearHasFixedDir() { - MOZ_ASSERT(NodeType() != nsIDOMNode::TEXT_NODE, - "ClearHasFixedDir on text node"); - ClearBoolFlag(NodeHasFixedDir); - } - bool HasFixedDir() const { return GetBoolFlag(NodeHasFixedDir); } - void SetHasDirAutoSet() { - MOZ_ASSERT(NodeType() != nsIDOMNode::TEXT_NODE, - "SetHasDirAutoSet on text node"); - SetBoolFlag(NodeHasDirAutoSet); - } - void ClearHasDirAutoSet() { - MOZ_ASSERT(NodeType() != nsIDOMNode::TEXT_NODE, - "ClearHasDirAutoSet on text node"); - ClearBoolFlag(NodeHasDirAutoSet); - } - bool HasDirAutoSet() const - { return GetBoolFlag(NodeHasDirAutoSet); } - void SetHasTextNodeDirectionalityMap() { - MOZ_ASSERT(NodeType() == nsIDOMNode::TEXT_NODE, - "SetHasTextNodeDirectionalityMap on non-text node"); - SetBoolFlag(NodeHasTextNodeDirectionalityMap); - } - void ClearHasTextNodeDirectionalityMap() { - MOZ_ASSERT(NodeType() == nsIDOMNode::TEXT_NODE, - "ClearHasTextNodeDirectionalityMap on non-text node"); - ClearBoolFlag(NodeHasTextNodeDirectionalityMap); - } - bool HasTextNodeDirectionalityMap() const - { return GetBoolFlag(NodeHasTextNodeDirectionalityMap); } - - void SetHasDirAuto() { SetBoolFlag(NodeHasDirAuto); } - void ClearHasDirAuto() { ClearBoolFlag(NodeHasDirAuto); } - bool HasDirAuto() const { return GetBoolFlag(NodeHasDirAuto); } - - void SetAncestorHasDirAuto() { SetBoolFlag(NodeAncestorHasDirAuto); } - void ClearAncestorHasDirAuto() { ClearBoolFlag(NodeAncestorHasDirAuto); } - bool AncestorHasDirAuto() const { return GetBoolFlag(NodeAncestorHasDirAuto); } - - bool NodeOrAncestorHasDirAuto() const - { return HasDirAuto() || AncestorHasDirAuto(); } protected: void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); } void SetInDocument() { SetBoolFlag(IsInDocument); } diff --git a/content/base/src/DirectionalityUtils.cpp b/content/base/src/DirectionalityUtils.cpp index 59a565cdb780..8523e25a333a 100644 --- a/content/base/src/DirectionalityUtils.cpp +++ b/content/base/src/DirectionalityUtils.cpp @@ -4,554 +4,25 @@ * 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/. */ -/* - Implementation description from https://etherpad.mozilla.org/dir-auto - - Static case - =========== - When we see a new content node with @dir=auto from the parser, we set the - NodeHasDirAuto flag on the node. We won't have enough information to - decide the directionality of the node at this point. - - When we bind a new content node to the document, if its parent has either of - the NodeAncestorHasDirAuto or NodeHasDirAuto flags, we set the - NodeAncestorHasDirAuto flag on the node. - - When a new input with @type=text/search/tel/url/email and @dir=auto is added - from the parser, we resolve the directionality based on its @value. - - When a new text node with non-neutral content is appended to a textarea - element with NodeHasDirAuto, if the directionality of the textarea element - is still unresolved, it is resolved based on the value of the text node. - Elements with unresolved directionality behave as LTR. - - When a new text node with non-neutral content is appended to an element that - is not a textarea but has either of the NodeAncestorHasDirAuto or - NodeHasDirAuto flags, we walk up the parent chain while the - NodeAncestorHasDirAuto flag is present, and when we reach an element with - NodeHasDirAuto and no resolved directionality, we resolve the directionality - based on the contents of the text node and cease walking the parent chain. - Note that we should ignore elements with NodeHasDirAuto with resolved - directionality, so that the second text node in this example tree doesn't - affect the directionality of the div: - -
- foo - بار -
- - The parent chain walk will be aborted if we hit a script or style element, or - if we hit an element with @dir=ltr or @dir=rtl. - - I will call this algorithm "upward propagation". - - Each text node should maintain a list of elements which have their - directionality determined by the first strong character of that text node. - This is useful to make dynamic changes more efficient. One way to implement - this is to have a per-document hash table mapping a text node to a set of - elements. I'll call this data structure TextNodeDirectionalityMap. The - algorithm for appending a new text node above needs to update this data - structure. - - *IMPLEMENTATION NOTE* - In practice, the implementation uses two per-node properties: - - dirAutoSetBy, which is set on a node with auto-directionality, and points to - the textnode that contains the strong character which determines the - directionality of the node. - - textNodeDirectionalityMap, which is set on a text node and points to a hash - table listing the nodes whose directionality is determined by the text node. - - Handling dynamic changes - ======================== - - We need to handle the following cases: - - 1. When the value of an input element with @type=text/search/tel/url/email is - changed, if it has NodeHasDirAuto, we update the resolved directionality. - - 2. When the dir attribute is changed from something else (including the case - where it doesn't exist) to auto on a textarea or an input element with - @type=text/search/tel/url/email, we set the NodeHasDirAuto flag and resolve - the directionality based on the value of the element. - - 3. When the dir attribute is changed from something else (including the case - where it doesn't exist) to auto on any element except case 1 above and the bdi - element, we run the following algorithm: - * We set the NodeHasDirAuto flag. - * If the element doesn't have the NodeAncestorHasDirAuto flag, we set the - NodeAncestorHasDirAuto flag on all of its child nodes. (Note that if the - element does have NodeAncestorHasDirAuto, all of its children should - already have this flag too. We can assert this in debug builds.) - * To resolve the directionality of the element, we run the algorithm explained - in http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#the-dir-attribute - (I'll call this the "downward propagation algorithm".) by walking the child - subtree in tree order. Note that an element with @dir=auto should not affect - other elements in its document with @dir=auto. So there is no need to walk up - the parent chain in this case. TextNodeDirectionalityMap needs to be updated - as appropriate. - - 3a. When the dir attribute is set to any valid value on an element that didn't - have a valid dir attribute before, this means that any descendant of that - element will not affect the directionality of any of its ancestors. So we need - to check whether any text node descendants of the element are listed in - TextNodeDirectionalityMap, and whether the elements whose direction they set - are ancestors of the element. If so, we need to rerun the downward propagation - algorithm for those ancestors. - - 4. When the dir attribute is changed from auto to something else (including - the case where it gets removed) on a textarea or an input element with - @type=text/search/tel/url/email, we unset the NodeHasDirAuto flag and - resolve the directionality based on the directionality of the value of the @dir - attribute on element itself or its parent element. - - 5. When the dir attribute is changed from auto to something else (including the - case where it gets removed) on any element except case 4 above and the bdi - element, we run the following algorithm: - * We unset the NodeHasDirAuto flag. - * If the element does not have the NodeAncestorHasDirAuto flag, we unset - the NodeAncestorHasDirAuto flag on all of its child nodes, except those - who are a descendant of another element with NodeHasDirAuto. (Note that if - the element has the NodeAncestorHasDirAuto flag, all of its child nodes - should still retain the same flag.) - * We resolve the directionality of the element based on the value of the @dir - attribute on the element itself or its parent element. - TextNodeDirectionalityMap needs to be updated as appropriate. - - 5a. When the dir attribute is removed or set to an invalid value on any - element (except a bdi element) with the NodeAncestorHasDirAuto flag which - previously had a valid dir attribute, it might have a text node descendant that - did not previously affect the directionality of any of its ancestors but should - now begin to affect them. - We run the following algorithm: - * Walk up the parent chain from the element. - * For any element that appears in the TextNodeDirectionalityMap, remove the - element from the map and rerun the downward propagation algorithm - (see section 3). - * If we reach an element without either of the NodeHasDirAuto or - NodeAncestorHasDirAuto flags, abort the parent chain walk. - - 6. When an element with @dir=auto is added to the document, we should handle it - similar to the case 2/3 above. - - 7. When an element with NodeHasDirAuto or NodeAncestorHasDirAuto is - removed from the document, we should handle it similar to the case 4/5 above, - except that we don't need to handle anything in the child subtree. We should - also remove all of the occurrences of that node and its descendants from - TextNodeDirectionalityMap. (This is the conceptual description of what needs to - happen but in the implementation UnbindFromTree is going to be called on all of - the descendants so we don't need to descend into the child subtree). - - 8. When the contents of a text node is changed either from script or by the - user, we need to run the following algorithm: - * If the change has happened after the first character with strong - directionality in the text node, do nothing. - * If the text node is a child of a bdi, script or style element, do nothing. - * If the text node belongs to a textarea with NodeHasDirAuto, we need to - update the directionality of the textarea. - * Grab a list of elements affected by this text node from - TextNodeDirectionalityMap and re-resolve the directionality of each one of them - based on the new contents of the text node. - * If the text node does not exist in TextNodeDirectionalityMap, and it has the - NodeAncestorHasDirAuto flag set, this could potentially be a text node - which is going to start affecting the directionality of its parent @dir=auto - elements. In this case, we need to fall back to the (potentially expensive) - "upward propagation algorithm". The TextNodeDirectionalityMap data structure - needs to be update during this algorithm. - * If the new contents of the text node do not have any strong characters, and - the old contents used to, and the text node used to exist in - TextNodeDirectionalityMap and it has the NodeAncestorHasDirAuto flag set, - the elements associated with this text node inside TextNodeDirectionalityMap - will now get their directionality from another text node. In this case, for - each element in the list retrieved from TextNodeDirectionalityMap, run the - downward propagation algorithm (section 3), and remove the text node from - TextNodeDirectionalityMap. - - 9. When a new text node is injected into a document, we need to run the - following algorithm: - * If the contents of the text node do not have any characters with strong - direction, do nothing. - * If the text node is a child of a bdi, script or style element, do nothing. - * If the text node is appended to a textarea element with NodeHasDirAuto, we - need to update the directionality of the textarea. - * If the text node has NodeAncestorHasDirAuto, we need to run the "upward - propagation algorithm". The TextNodeDirectionalityMap data structure needs to - be update during this algorithm. - - 10. When a text node is removed from a document, we need to run the following - algorithm: - * If the contents of the text node do not have any characters with strong - direction, do nothing. - * If the text node is a child of a bdi, script or style element, do nothing. - * If the text node is removed from a textarea element with NodeHasDirAuto, - set the directionality to "ltr". (This is what the spec currently says, but I'm - filing a spec bug to get it fixed -- the directionality should depend on the - parent element here.) - * If the text node has NodeAncestorHasDirAuto, we need to look at the list - of elements being affected by this text node from TextNodeDirectionalityMap, - run the "downward propagation algorithm" (section 3) for each one of them, - while updating TextNodeDirectionalityMap along the way. - - 11. If the value of the @dir attribute on a bdi element is changed to an - invalid value (or if it's removed), determine the new directionality similar - to the case 3 above. - - == Implemention Notes == - When a new node gets bound to the tree, the BindToTree function gets called. - The reverse case is UnbindFromTree. - When the contents of a text node change, nsGenericDOMDataNode::SetTextInternal - gets called. - */ - #include "mozilla/dom/DirectionalityUtils.h" #include "nsINode.h" #include "nsIContent.h" #include "nsIDocument.h" #include "mozilla/dom/Element.h" +#include "nsIDOMNodeFilter.h" +#include "nsTreeWalker.h" #include "nsIDOMHTMLDocument.h" -#include "nsUnicodeProperties.h" -#include "nsTextFragment.h" -#include "nsAttrValue.h" -#include "nsContentUtils.h" -#include "nsTextNode.h" -#include "nsCheapSets.h" + namespace mozilla { +namespace directionality { + typedef mozilla::dom::Element Element; -/** - * Returns true if aNode is one of the elements whose text content should not - * affect its own direction, nor the direction of ancestors with dir=auto. - * - * Note that this does not include , whose content does affect its own - * direction when it has dir=auto (which it has by default), so one needs to - * test for it separately. - * It *does* include textarea, because even if a textarea has dir=auto, it has - * unicode-bidi: plaintext and is handled automatically in bidi resolution. - */ -static bool -DoesNotParticipateInAutoDirection(const Element* aElement) -{ - nsINodeInfo* nodeInfo = aElement->NodeInfo(); - return (aElement->IsHTML() && - (nodeInfo->Equals(nsGkAtoms::script) || - nodeInfo->Equals(nsGkAtoms::style) || - nodeInfo->Equals(nsGkAtoms::textarea))); -} - -/** - * Returns the directionality of a Unicode character - */ -static Directionality -GetDirectionFromChar(uint32_t ch) -{ - switch(mozilla::unicode::GetBidiCat(ch)) { - case eCharType_RightToLeft: - case eCharType_RightToLeftArabic: - return eDir_RTL; - - case eCharType_LeftToRight: - return eDir_LTR; - - default: - return eDir_NotSet; - } -} - -inline static bool NodeAffectsDirAutoAncestor(nsINode* aTextNode) -{ - Element* parent = aTextNode->GetElementParent(); - return (parent && - !DoesNotParticipateInAutoDirection(parent) && - parent->NodeOrAncestorHasDirAuto()); -} - -/** - * Various methods for returning the directionality of a string using the - * first-strong algorithm defined in http://unicode.org/reports/tr9/#P2 - * - * @param[out] aFirstStrong the offset to the first character in the string with - * strong directionality, or PR_UINT32_MAX if there is none (return - value is eDir_NotSet). - * @return the directionality of the string - */ -static Directionality -GetDirectionFromText(const PRUnichar* aText, const uint32_t aLength, - uint32_t* aFirstStrong = nullptr) -{ - const PRUnichar* start = aText; - const PRUnichar* end = aText + aLength; - - while (start < end) { - uint32_t current = start - aText; - uint32_t ch = *start++; - - if (NS_IS_HIGH_SURROGATE(ch) && - start < end && - NS_IS_LOW_SURROGATE(*start)) { - ch = SURROGATE_TO_UCS4(ch, *start++); - } - - Directionality dir = GetDirectionFromChar(ch); - if (dir != eDir_NotSet) { - if (aFirstStrong) { - *aFirstStrong = current; - } - return dir; - } - } - - if (aFirstStrong) { - *aFirstStrong = PR_UINT32_MAX; - } - return eDir_NotSet; -} - -static Directionality -GetDirectionFromText(const char* aText, const uint32_t aLength, - uint32_t* aFirstStrong = nullptr) -{ - const char* start = aText; - const char* end = aText + aLength; - - while (start < end) { - uint32_t current = start - aText; - unsigned char ch = (unsigned char)*start++; - - Directionality dir = GetDirectionFromChar(ch); - if (dir != eDir_NotSet) { - if (aFirstStrong) { - *aFirstStrong = current; - } - return dir; - } - } - - if (aFirstStrong) { - *aFirstStrong = PR_UINT32_MAX; - } - return eDir_NotSet; -} - -static Directionality -GetDirectionFromText(const nsTextFragment* aFrag, - uint32_t* aFirstStrong = nullptr) -{ - if (aFrag->Is2b()) { - return GetDirectionFromText(aFrag->Get2b(), aFrag->GetLength(), - aFirstStrong); - } - - return GetDirectionFromText(aFrag->Get1b(), aFrag->GetLength(), - aFirstStrong); -} - -/** - * Set the directionality of a node with dir=auto as defined in - * http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#the-directionality - * - * @param[in] aStartAfterNode as an optimization, a caller may pass in a node - * from which to begin walking the descendants of aElement, if it is - * known that all text nodes before this node do not contain any - * strong directional characters - * @return the text node containing the character that determined the direction - */ -static nsINode* -WalkDescendantsSetDirectionFromText(Element* aElement, bool aNotify = true, - nsINode* aStartAfterNode = nullptr) -{ - MOZ_ASSERT(aElement, "aElement is null"); - - nsIContent* child; - if (aStartAfterNode && - nsContentUtils::ContentIsDescendantOf(aStartAfterNode, aElement)) { -#ifdef DEBUG - child = aElement->GetFirstChild(); - while (child && child != aStartAfterNode) { - if (child->NodeType() == nsIDOMNode::TEXT_NODE) { - MOZ_ASSERT(GetDirectionFromText(child->GetText()) == eDir_NotSet, - "Strong directional characters before aStartAfterNode"); - } - child = child->GetNextNode(aElement); - } -#endif - child = aStartAfterNode->GetNextNode(aElement); - } else { - child = aElement->GetFirstChild(); - } - - while (child) { - if (child->IsElement() && - (DoesNotParticipateInAutoDirection(child->AsElement()) || - child->NodeInfo()->Equals(nsGkAtoms::bdi) || - child->HasFixedDir())) { - child = child->GetNextNonChildNode(aElement); - continue; - } - - if (child->NodeType() == nsIDOMNode::TEXT_NODE) { - Directionality textNodeDir = GetDirectionFromText(child->GetText()); - if (textNodeDir != eDir_NotSet) { - // We found a descendant text node with strong directional characters. - // Set the directionality of aElement to the corresponding value. - aElement->SetDirectionality(textNodeDir, aNotify); - return child; - } - } - child = child->GetNextNode(aElement); - } - - // We walked all the descendants without finding a text node with strong - // directional characters. Set the directionality to LTR - aElement->SetDirectionality(eDir_LTR, aNotify); - return nullptr; -} - -class nsTextNodeDirectionalityMap -{ - static void - nsTextNodeDirectionalityMapDtor(void *aObject, nsIAtom* aPropertyName, - void *aPropertyValue, void* aData) - { - nsTextNodeDirectionalityMap* map = - reinterpret_cast(aPropertyValue); - delete map; - } - -public: - nsTextNodeDirectionalityMap(nsINode* aTextNode) - { - MOZ_ASSERT(aTextNode, "Null text node"); - MOZ_COUNT_CTOR(nsTextNodeDirectionalityMap); - aTextNode->SetProperty(nsGkAtoms::textNodeDirectionalityMap, this, - nsTextNodeDirectionalityMapDtor); - aTextNode->SetHasTextNodeDirectionalityMap(); - } - - ~nsTextNodeDirectionalityMap() - { - MOZ_COUNT_DTOR(nsTextNodeDirectionalityMap); - } - - void AddEntry(nsINode* aTextNode, Element* aElement) - { - if (!mElements.Contains(aElement)) { - mElements.Put(aElement); - aElement->SetProperty(nsGkAtoms::dirAutoSetBy, aTextNode); - aElement->SetHasDirAutoSet(); - } - } - - void RemoveEntry(nsINode* aTextNode, Element* aElement) - { - if (mElements.Contains(aElement)) { - mElements.Remove(aElement); - - aElement->ClearHasDirAutoSet(); - aElement->UnsetProperty(nsGkAtoms::dirAutoSetBy); - } - } - -private: - nsCheapSet > mElements; - - static nsTextNodeDirectionalityMap* GetDirectionalityMap(nsINode* aTextNode) - { - MOZ_ASSERT(aTextNode->NodeType() == nsIDOMNode::TEXT_NODE, - "Must be a text node"); - nsTextNodeDirectionalityMap* map = nullptr; - - if (aTextNode->HasTextNodeDirectionalityMap()) { - map = static_cast - (aTextNode->GetProperty(nsGkAtoms::textNodeDirectionalityMap)); - } - - return map; - } - - static PLDHashOperator SetNodeDirection(nsPtrHashKey* aEntry, void* aDir) - { - MOZ_ASSERT(aEntry->GetKey()->IsElement(), "Must be an Element"); - aEntry->GetKey()->SetDirectionality(*reinterpret_cast(aDir), - true); - return PL_DHASH_NEXT; - } - - static PLDHashOperator ResetNodeDirection(nsPtrHashKey* aEntry, void* aData) - { - MOZ_ASSERT(aEntry->GetKey()->IsElement(), "Must be an Element"); - // run the downward propagation algorithm - // and remove the text node from the map - nsINode* startAfterNode = static_cast(aData); - Element* rootNode = aEntry->GetKey(); - nsINode* textNode = WalkDescendantsSetDirectionFromText(rootNode, true, - startAfterNode); - if (textNode) { - nsTextNodeDirectionalityMap::AddEntryToMap(textNode, rootNode); - } - return PL_DHASH_REMOVE; - } - -public: - void UpdateAutoDirection(Directionality aDir) - { - mElements.EnumerateEntries(SetNodeDirection, &aDir); - } - - void ResetAutoDirection(nsINode* aTextNode, nsINode* aStartAfterNode) - { - mElements.EnumerateEntries(ResetNodeDirection, aStartAfterNode); - } - - static void RemoveElementFromMap(nsINode* aTextNode, Element* aElement) - { - if (aTextNode->HasTextNodeDirectionalityMap()) { - GetDirectionalityMap(aTextNode)->RemoveEntry(aTextNode, aElement); - } - } - - static void AddEntryToMap(nsINode* aTextNode, Element* aElement) - { - nsTextNodeDirectionalityMap* map = GetDirectionalityMap(aTextNode); - if (!map) { - map = new nsTextNodeDirectionalityMap(aTextNode); - } - - map->AddEntry(aTextNode, aElement); - } - - static void UpdateTextNodeDirection(nsINode* aTextNode, Directionality aDir) - { - MOZ_ASSERT(aTextNode->HasTextNodeDirectionalityMap(), - "Map missing in UpdateTextNodeDirection"); - GetDirectionalityMap(aTextNode)->UpdateAutoDirection(aDir); - } - - static void ResetTextNodeDirection(nsINode* aTextNode, - nsINode* aStartAfterNode = nullptr) - { - MOZ_ASSERT(aTextNode->HasTextNodeDirectionalityMap(), - "Map missing in ResetTextNodeDirection"); - GetDirectionalityMap(aTextNode)->ResetAutoDirection(aTextNode, - aStartAfterNode); - } -}; - Directionality RecomputeDirectionality(Element* aElement, bool aNotify) { - MOZ_ASSERT(!aElement->HasDirAuto(), - "RecomputeDirectionality called with dir=auto"); - if (aElement->HasDirAutoSet()) { - nsINode* setByNode = - static_cast(aElement->GetProperty(nsGkAtoms::dirAutoSetBy)); - if (setByNode) { - nsTextNodeDirectionalityMap::RemoveElementFromMap(setByNode, aElement); - } - } - Directionality dir = eDir_LTR; if (aElement->HasValidDir()) { @@ -575,7 +46,7 @@ RecomputeDirectionality(Element* aElement, bool aNotify) dir = documentDir; } } - + aElement->SetDirectionality(dir, aNotify); } return dir; @@ -592,7 +63,7 @@ SetDirectionalityOnDescendants(Element* aElement, Directionality aDir, } Element* element = child->AsElement(); - if (element->HasValidDir() || element->HasDirAuto()) { + if (element->HasValidDir()) { child = child->GetNextNonChildNode(aElement); continue; } @@ -601,272 +72,7 @@ SetDirectionalityOnDescendants(Element* aElement, Directionality aDir, } } -void -WalkAncestorsResetAutoDirection(Element* aElement, bool aNotify) -{ - nsINode* setByNode; - Element* parent = aElement->GetElementParent(); - - while (parent && parent->NodeOrAncestorHasDirAuto()) { - if (parent->HasDirAutoSet()) { - // If the parent has the DirAutoSet flag, its direction is determined by - // some text node descendant. - // Remove it from the map and reset its direction by the downward - // propagation algorithm - setByNode = - static_cast(parent->GetProperty(nsGkAtoms::dirAutoSetBy)); - if (setByNode) { - nsTextNodeDirectionalityMap::RemoveElementFromMap(setByNode, parent); - } - } - if (parent->HasDirAuto()) { - setByNode = WalkDescendantsSetDirectionFromText(parent, aNotify); - if (setByNode) { - nsTextNodeDirectionalityMap::AddEntryToMap(setByNode, parent); - } - break; - } - parent = parent->GetElementParent(); - } -} - -void -WalkDescendantsResetAutoDirection(Element* aElement) -{ - nsIContent* child = aElement->GetFirstChild(); - while (child) { - if (child->HasDirAuto()) { - child = child->GetNextNonChildNode(aElement); - continue; - } - - if (child->HasTextNodeDirectionalityMap()) { - nsTextNodeDirectionalityMap::ResetTextNodeDirection(child, child); - } - child = child->GetNextNode(aElement); - } -} - -void -WalkDescendantsSetDirAuto(Element* aElement, bool aNotify) -{ - bool setAncestorDirAutoFlag = -#ifdef DEBUG - true; -#else - !aElement->AncestorHasDirAuto(); -#endif - - if (setAncestorDirAutoFlag) { - nsIContent* child = aElement->GetFirstChild(); - while (child) { - MOZ_ASSERT(!aElement->AncestorHasDirAuto() || - child->AncestorHasDirAuto(), - "AncestorHasDirAuto set on node but not its children"); - child->SetHasDirAuto(); - child = child->GetNextNode(aElement); - } - } - - nsINode* textNode = WalkDescendantsSetDirectionFromText(aElement, aNotify); - if (textNode) { - nsTextNodeDirectionalityMap::AddEntryToMap(textNode, aElement); - } -} - -void -WalkDescendantsClearAncestorDirAuto(Element* aElement) -{ - nsIContent* child = aElement->GetFirstChild(); - while (child) { - if (child->HasDirAuto()) { - child = child->GetNextNonChildNode(aElement); - continue; - } - - child->ClearAncestorHasDirAuto(); - child = child->GetNextNode(aElement); - } -} - -void SetAncestorDirectionIfAuto(nsINode* aTextNode, Directionality aDir, - bool aNotify = true) -{ - MOZ_ASSERT(aTextNode->NodeType() == nsIDOMNode::TEXT_NODE, - "Must be a text node"); - - Element* parent = aTextNode->GetElementParent(); - while (parent && parent->NodeOrAncestorHasDirAuto()) { - if (DoesNotParticipateInAutoDirection(parent) || parent->HasFixedDir()) { - break; - } - - if (parent->HasDirAuto()) { - bool resetDirection = false; - - if (!parent->HasDirAutoSet()) { - // Fast path if parent's direction is not yet set by any descendant - resetDirection = true; - } else { - // If parent's direction is already set, we need to know if - // aTextNode is before or after the text node that had set it. - // We will walk parent's descendants in tree order starting from - // aTextNode to optimize for the most common case where text nodes are - // being appended to tree. - nsINode* directionWasSetByTextNode = - static_cast(parent->GetProperty(nsGkAtoms::dirAutoSetBy)); - if (!directionWasSetByTextNode) { - resetDirection = true; - } else if (directionWasSetByTextNode != aTextNode) { - nsIContent* child = aTextNode->GetNextNode(parent); - while (child) { - if (child->IsElement() && - (DoesNotParticipateInAutoDirection(child->AsElement()) || - child->NodeInfo()->Equals(nsGkAtoms::bdi) || - child->HasFixedDir())) { - child = child->GetNextNonChildNode(parent); - continue; - } - - if (child == directionWasSetByTextNode) { - // we found the node that set the element's direction after our - // text node, so we need to reset the direction - resetDirection = true; - break; - } - - child = child->GetNextNode(parent); - } - } - } - - if (resetDirection) { - parent->SetDirectionality(aDir, aNotify); - nsTextNodeDirectionalityMap::AddEntryToMap(aTextNode, parent); - SetDirectionalityOnDescendants(parent, aDir, aNotify); - } - - // Since we found an element with dir=auto, we can stop walking the - // parent chain: none of its ancestors will have their direction set by - // any of its descendants. - return; - } - parent = parent->GetElementParent(); - } -} - -void -SetDirectionFromChangedTextNode(nsIContent* aTextNode, uint32_t aOffset, - const PRUnichar* aBuffer, uint32_t aLength, - bool aNotify) -{ - if (!NodeAffectsDirAutoAncestor(aTextNode)) { - return; - } - - uint32_t firstStrong; - Directionality oldDir = GetDirectionFromText(aTextNode->GetText(), - &firstStrong); - if (aOffset > firstStrong) { - return; - } - - Directionality newDir = GetDirectionFromText(aBuffer, aLength); - if (newDir == eDir_NotSet) { - if (oldDir != eDir_NotSet && aTextNode->HasTextNodeDirectionalityMap()) { - // This node used to have a strong directional character but no - // longer does. ResetTextNodeDirection() will re-resolve the - // directionality of any elements whose directionality was - // determined by this node. - nsTextNodeDirectionalityMap::ResetTextNodeDirection(aTextNode); - } - } else { - // This node has a strong directional character. If it has a - // TextNodeDirectionalityMap property, it already determines the - // directionality of some element(s), so call UpdateTextNodeDirection to - // reresolve their directionality. Otherwise call - // SetAncestorDirectionIfAuto to find ancestor elements which should - // have their directionality determined by this node. - if (aTextNode->HasTextNodeDirectionalityMap()) { - nsTextNodeDirectionalityMap::UpdateTextNodeDirection(aTextNode, newDir); - } else { - SetAncestorDirectionIfAuto(aTextNode, newDir, aNotify); - } - } -} - -void -SetDirectionFromNewTextNode(nsTextNode* aTextNode) -{ - if (!NodeAffectsDirAutoAncestor(aTextNode)) { - return; - } - - Directionality dir = GetDirectionFromText(aTextNode->GetText()); - if (dir != eDir_NotSet) { - SetAncestorDirectionIfAuto(aTextNode, dir); - } -} - -void -ResetDirectionSetByTextNode(nsTextNode* aTextNode) -{ - if (!NodeAffectsDirAutoAncestor(aTextNode)) { - return; - } - - Directionality dir = GetDirectionFromText(aTextNode->GetText()); - if (dir != eDir_NotSet && aTextNode->HasTextNodeDirectionalityMap()) { - nsTextNodeDirectionalityMap::ResetTextNodeDirection(aTextNode); - } -} - -void -SetDirectionalityFromValue(Element* aElement, const nsAString& value, - bool aNotify) -{ - Directionality dir = GetDirectionFromText(PromiseFlatString(value).get(), - value.Length()); - if (dir == eDir_NotSet) { - dir = eDir_LTR; - } - - aElement->SetDirectionality(dir, aNotify); -} - -void -OnSetDirAttr(Element* aElement, const nsAttrValue* aNewValue, - bool hadValidDir, bool aNotify) -{ - if (aElement->IsHTML() && aElement->NodeInfo()->Equals(nsGkAtoms::input)) { - return; - } - - if (aElement->AncestorHasDirAuto()) { - if (!hadValidDir) { - // The element is a descendant of an element with dir = auto, is - // having its dir attribute set, and previously didn't have a valid dir - // attribute. - // Check whether any of its text node descendants determine the - // direction of any of its ancestors, and redetermine their direction - WalkDescendantsResetAutoDirection(aElement); - } else if (!aElement->HasValidDir()) { - // The element is a descendant of an element with dir = auto and is - // having its dir attribute removed or set to an invalid value. - // Reset the direction of any of its ancestors whose direction is - // determined by a text node descendant - WalkAncestorsResetAutoDirection(aElement, aNotify); - } - } - - if (aElement->HasDirAuto()) { - WalkDescendantsSetDirAuto(aElement, aNotify); - } else { - SetDirectionalityOnDescendants(aElement, - RecomputeDirectionality(aElement, aNotify), - aNotify); - } -} +} // end namespace directionality } // end namespace mozilla diff --git a/content/base/src/Element.cpp b/content/base/src/Element.cpp index 06f5f912a00d..b77f7c957b85 100644 --- a/content/base/src/Element.cpp +++ b/content/base/src/Element.cpp @@ -130,6 +130,7 @@ using namespace mozilla; using namespace mozilla::dom; +using namespace mozilla::directionality; nsEventStates Element::IntrinsicState() const @@ -1162,21 +1163,7 @@ Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent, // because it has to happen after updating the parent pointer, but before // recursively binding the kids. if (IsHTML()) { - if (aParent && aParent->NodeOrAncestorHasDirAuto()) { - SetAncestorHasDirAuto(); - // if we are binding an element to the tree that already has descendants, - // and the parent has NodeHasDirAuto or NodeAncestorHasDirAuto, we may - // need to reset the direction of an ancestor with dir=auto - if (GetFirstChild()) { - WalkAncestorsResetAutoDirection(this); - } - } - - if (!HasDirAuto()) { - // if the element doesn't have dir=auto, set its directionality from - // the dir attribute or by inheriting from its ancestors. - RecomputeDirectionality(this, false); - } + RecomputeDirectionality(this, false); } // If NODE_FORCE_XBL_BINDINGS was set we might have anonymous children @@ -1367,7 +1354,7 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent) // This has to be here, rather than in nsGenericHTMLElement::UnbindFromTree, // because it has to happen after unsetting the parent pointer, but before // recursively unbinding the kids. - if (IsHTML() && !HasDirAuto()) { + if (IsHTML()) { RecomputeDirectionality(this, false); } @@ -1840,13 +1827,7 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, aValueForAfterSetAttr.SetTo(aParsedValue); } - bool hadValidDir = false; - if (aNamespaceID == kNameSpaceID_None) { - if (aName == nsGkAtoms::dir) { - hadValidDir = HasValidDir() || NodeInfo()->Equals(nsGkAtoms::bdi); - } - // XXXbz Perhaps we should push up the attribute mapping function // stuff to Element? if (!IsAttributeMapped(aName) || @@ -1882,10 +1863,6 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, if (aCallAfterSetAttr) { rv = AfterSetAttr(aNamespaceID, aName, &aValueForAfterSetAttr, aNotify); NS_ENSURE_SUCCESS(rv, rv); - - if (aNamespaceID == kNameSpaceID_None && aName == nsGkAtoms::dir) { - OnSetDirAttr(this, &aValueForAfterSetAttr, hadValidDir, aNotify); - } } if (aFireMutation) { @@ -2088,12 +2065,6 @@ Element::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName, // react to unexpected attribute changes. nsMutationGuard::DidMutate(); - bool hadValidDir = false; - - if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::dir) { - hadValidDir = HasValidDir() || NodeInfo()->Equals(nsGkAtoms::bdi); - } - nsAttrValue oldValue; rv = mAttrsAndChildren.RemoveAttrAt(index, oldValue); NS_ENSURE_SUCCESS(rv, rv); @@ -2116,10 +2087,6 @@ Element::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName, rv = AfterSetAttr(aNameSpaceID, aName, nullptr, aNotify); NS_ENSURE_SUCCESS(rv, rv); - if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::dir) { - OnSetDirAttr(this, nullptr, hadValidDir, aNotify); - } - if (hasMutationListeners) { nsCOMPtr node = do_QueryObject(this); nsMutationEvent mutation(true, NS_MUTATION_ATTRMODIFIED); diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index bd11aed738e4..e2bc9b7e32c0 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -177,6 +177,7 @@ using namespace mozilla; using namespace mozilla::dom; +using namespace mozilla::directionality; typedef nsTArray LinkArray; diff --git a/content/base/src/nsDocument.h b/content/base/src/nsDocument.h index 297a95029b53..0235edad50dc 100644 --- a/content/base/src/nsDocument.h +++ b/content/base/src/nsDocument.h @@ -1053,7 +1053,7 @@ protected: nsresult SetFirstBaseNodeWithHref(nsIContent *node); inline void - SetDocumentDirectionality(mozilla::Directionality aDir) + SetDocumentDirectionality(mozilla::directionality::Directionality aDir) { mDirectionality = aDir; } diff --git a/content/base/src/nsGenericDOMDataNode.cpp b/content/base/src/nsGenericDOMDataNode.cpp index 34e5b285201a..3889998b8814 100644 --- a/content/base/src/nsGenericDOMDataNode.cpp +++ b/content/base/src/nsGenericDOMDataNode.cpp @@ -26,7 +26,6 @@ #include "nsEventDispatcher.h" #include "nsCOMArray.h" #include "nsNodeUtils.h" -#include "mozilla/dom/DirectionalityUtils.h" #include "nsBindingManager.h" #include "nsCCUncollectableMarker.h" #include "mozAutoDocUpdate.h" @@ -280,10 +279,6 @@ nsGenericDOMDataNode::SetTextInternal(uint32_t aOffset, uint32_t aCount, nsNodeUtils::CharacterDataWillChange(this, &info); } - if (NodeType() == nsIDOMNode::TEXT_NODE) { - SetDirectionFromChangedTextNode(this, aOffset, aBuffer, aLength, aNotify); - } - if (aOffset == 0 && endOffset == textLength) { // Replacing whole text or old text was empty. Don't bother to check for // bidi in this string if the document already has bidi enabled. diff --git a/content/base/src/nsGkAtomList.h b/content/base/src/nsGkAtomList.h index 9a4301fbe839..98ebc34b8e50 100644 --- a/content/base/src/nsGkAtomList.h +++ b/content/base/src/nsGkAtomList.h @@ -276,7 +276,6 @@ GK_ATOM(dialog, "dialog") GK_ATOM(difference, "difference") GK_ATOM(digit, "digit") GK_ATOM(dir, "dir") -GK_ATOM(dirAutoSetBy, "dirAutoSetBy") GK_ATOM(directionality, "directionality") GK_ATOM(disableOutputEscaping, "disable-output-escaping") GK_ATOM(disabled, "disabled") @@ -1034,7 +1033,6 @@ GK_ATOM(text, "text") GK_ATOM(textarea, "textarea") GK_ATOM(textbox, "textbox") GK_ATOM(textnode, "textnode") -GK_ATOM(textNodeDirectionalityMap, "textNodeDirectionalityMap") GK_ATOM(tfoot, "tfoot") GK_ATOM(th, "th") GK_ATOM(thead, "thead") diff --git a/content/base/src/nsTextNode.cpp b/content/base/src/nsTextNode.cpp index 09fd9df926b4..db2ffb24e683 100644 --- a/content/base/src/nsTextNode.cpp +++ b/content/base/src/nsTextNode.cpp @@ -9,7 +9,6 @@ #include "nsTextNode.h" #include "nsContentUtils.h" -#include "mozilla/dom/DirectionalityUtils.h" #include "nsIDOMEventListener.h" #include "nsIDOMMutationEvent.h" #include "nsIDocument.h" @@ -19,7 +18,6 @@ #include "nsRange.h" #endif -using namespace mozilla; using namespace mozilla::dom; /** @@ -164,27 +162,6 @@ nsTextNode::AppendTextForNormalize(const PRUnichar* aBuffer, uint32_t aLength, return SetTextInternal(mText.GetLength(), 0, aBuffer, aLength, aNotify, &details); } -nsresult -nsTextNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent, - nsIContent* aBindingParent, bool aCompileEventHandlers) -{ - nsresult rv = nsGenericDOMDataNode::BindToTree(aDocument, aParent, - aBindingParent, - aCompileEventHandlers); - NS_ENSURE_SUCCESS(rv, rv); - - SetDirectionFromNewTextNode(this); - - return NS_OK; -} - -void nsTextNode::UnbindFromTree(bool aDeep, bool aNullParent) -{ - ResetDirectionSetByTextNode(this); - - nsGenericDOMDataNode::UnbindFromTree(aDeep, aNullParent); -} - #ifdef DEBUG void nsTextNode::List(FILE* out, int32_t aIndent) const diff --git a/content/base/src/nsTextNode.h b/content/base/src/nsTextNode.h index 506d7106ca5b..b10a27c6d30d 100644 --- a/content/base/src/nsTextNode.h +++ b/content/base/src/nsTextNode.h @@ -40,12 +40,6 @@ public: virtual nsXPCClassInfo* GetClassInfo(); - virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, - nsIContent* aBindingParent, - bool aCompileEventHandlers); - virtual void UnbindFromTree(bool aDeep = true, - bool aNullParent = true); - nsresult AppendTextForNormalize(const PRUnichar* aBuffer, uint32_t aLength, bool aNotify, nsIContent* aNextSibling); diff --git a/content/html/content/src/nsGenericHTMLElement.cpp b/content/html/content/src/nsGenericHTMLElement.cpp index cc4e95614850..682a78c73b64 100644 --- a/content/html/content/src/nsGenericHTMLElement.cpp +++ b/content/html/content/src/nsGenericHTMLElement.cpp @@ -68,7 +68,6 @@ #include "nsIDOMHTMLFormElement.h" #include "nsHTMLFormElement.h" #include "nsFocusManager.h" -#include "nsAttrValueOrString.h" #include "nsMutationEvent.h" @@ -103,6 +102,7 @@ using namespace mozilla; using namespace mozilla::dom; +using namespace mozilla::directionality; class nsINodeInfo; class nsIDOMNodeList; @@ -347,9 +347,8 @@ nsGenericHTMLElement::ClearDataset() } static const nsAttrValue::EnumTable kDirTable[] = { - { "ltr", eDir_LTR }, - { "rtl", eDir_RTL }, - { "auto", eDir_Auto }, + { "ltr", NS_STYLE_DIRECTION_LTR }, + { "rtl", NS_STYLE_DIRECTION_RTL }, { 0 } }; @@ -1699,23 +1698,6 @@ nsGenericHTMLElement::GetHrefURIForAnchors() const return uri.forget(); } -nsresult -nsGenericHTMLElement::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, - bool aNotify) -{ - if (aNamespaceID == kNameSpaceID_None && - aName == nsGkAtoms::dir && - HasDirAuto()) { - // setting dir on an element that currently has dir=auto - WalkDescendantsClearAncestorDirAuto(this); - SetHasDirAuto(); - } - - return nsGenericHTMLElementBase::BeforeSetAttr(aNamespaceID, aName, - aValue, aNotify); -} - nsresult nsGenericHTMLElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName, const nsAttrValue* aValue, bool aNotify) @@ -1737,28 +1719,16 @@ nsGenericHTMLElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName, SyncEditorsOnSubtree(this); } else if (aName == nsGkAtoms::dir) { - Directionality dir = eDir_LTR; - if (aValue && aValue->Type() == nsAttrValue::eEnum) { + Directionality dir; + if (aValue && + (aValue->Equals(nsGkAtoms::ltr, eIgnoreCase) || + aValue->Equals(nsGkAtoms::rtl, eIgnoreCase))) { SetHasValidDir(); - Directionality dirValue = (Directionality)aValue->GetEnumValue(); - if (dirValue == eDir_Auto) { - SetHasDirAuto(); - ClearHasFixedDir(); - } else { - dir = dirValue; - SetDirectionality(dir, aNotify); - ClearHasDirAuto(); - ClearHasDirAutoSet(); - SetHasFixedDir(); - } + dir = aValue->Equals(nsGkAtoms::rtl, eIgnoreCase) ? eDir_RTL : eDir_LTR; + SetDirectionality(dir, aNotify); } else { ClearHasValidDir(); - ClearHasFixedDir(); - if (NodeInfo()->Equals(nsGkAtoms::bdi)) { - SetHasDirAuto(); - } else { - dir = RecomputeDirectionality(this, aNotify); - } + dir = RecomputeDirectionality(this, aNotify); } SetDirectionalityOnDescendants(this, dir, aNotify); } diff --git a/content/html/content/src/nsGenericHTMLElement.h b/content/html/content/src/nsGenericHTMLElement.h index b701145cb32e..a1a92c33e834 100644 --- a/content/html/content/src/nsGenericHTMLElement.h +++ b/content/html/content/src/nsGenericHTMLElement.h @@ -777,10 +777,6 @@ protected: */ bool IsEventName(nsIAtom* aName); - virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, - bool aNotify); - virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName, const nsAttrValue* aValue, bool aNotify); diff --git a/content/html/content/src/nsHTMLInputElement.cpp b/content/html/content/src/nsHTMLInputElement.cpp index 5fa870ffd92a..6b49672e5521 100644 --- a/content/html/content/src/nsHTMLInputElement.cpp +++ b/content/html/content/src/nsHTMLInputElement.cpp @@ -81,7 +81,6 @@ #include "mozAutoDocUpdate.h" #include "nsContentCreatorFunctions.h" #include "nsContentUtils.h" -#include "mozilla/dom/DirectionalityUtils.h" #include "nsRadioVisitor.h" #include "mozilla/LookAndFeel.h" @@ -761,10 +760,6 @@ nsHTMLInputElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, } } else if (aNotify && aName == nsGkAtoms::disabled) { mDisabledChanged = true; - } else if (aName == nsGkAtoms::dir && - AttrValueIs(kNameSpaceID_None, nsGkAtoms::dir, - nsGkAtoms::_auto, eIgnoreCase)) { - SetDirectionIfAuto(false, aNotify); } } @@ -871,9 +866,6 @@ nsHTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, UpdateStepMismatchValidityState(); } else if (aName == nsGkAtoms::step) { UpdateStepMismatchValidityState(); - } else if (aName == nsGkAtoms::dir && - aValue && aValue->Equals(nsGkAtoms::_auto, eIgnoreCase)) { - SetDirectionIfAuto(true, aNotify); } UpdateState(aNotify); @@ -2590,9 +2582,6 @@ nsHTMLInputElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent, AddedToRadioGroup(); } - // Set direction based on value if dir=auto - SetDirectionIfAuto(HasDirAuto(), false); - // An element can't suffer from value missing if it is not in a document. // We have to check if we suffer from that as we are now in a document. UpdateValueMissingValidityState(); @@ -3208,21 +3197,6 @@ nsHTMLInputElement::SetDefaultValueAsValue() return SetValueInternal(resetVal, false, false); } -void -nsHTMLInputElement::SetDirectionIfAuto(bool aAuto, bool aNotify) -{ - if (aAuto) { - SetHasDirAuto(); - if (IsSingleLineTextControl(true)) { - nsAutoString value; - GetValue(value); - SetDirectionalityFromValue(this, value, aNotify); - } - } else { - ClearHasDirAuto(); - } -} - NS_IMETHODIMP nsHTMLInputElement::Reset() { @@ -4632,10 +4606,6 @@ NS_IMETHODIMP_(void) nsHTMLInputElement::OnValueChanged(bool aNotify) { UpdateAllValidityStates(aNotify); - - if (HasDirAuto()) { - SetDirectionIfAuto(true, aNotify); - } } NS_IMETHODIMP_(bool) diff --git a/content/html/content/src/nsHTMLInputElement.h b/content/html/content/src/nsHTMLInputElement.h index 5dc742c02f0d..35f4c58a390a 100644 --- a/content/html/content/src/nsHTMLInputElement.h +++ b/content/html/content/src/nsHTMLInputElement.h @@ -511,8 +511,6 @@ protected: */ nsresult SetDefaultValueAsValue(); - virtual void SetDirectionIfAuto(bool aAuto, bool aNotify); - /** * Return if an element should have a specific validity UI * (with :-moz-ui-invalid and :-moz-ui-valid pseudo-classes). diff --git a/content/html/content/src/nsHTMLUnknownElement.h b/content/html/content/src/nsHTMLUnknownElement.h index 2b6d70c69123..bf450106d03a 100644 --- a/content/html/content/src/nsHTMLUnknownElement.h +++ b/content/html/content/src/nsHTMLUnknownElement.h @@ -15,9 +15,6 @@ public: nsHTMLUnknownElement(already_AddRefed aNodeInfo) : nsGenericHTMLElement(aNodeInfo) { - if (NodeInfo()->Equals(nsGkAtoms::bdi)) { - SetHasDirAuto(); - } } // nsISupports diff --git a/content/html/content/test/test_bug660663.html b/content/html/content/test/test_bug660663.html index 2ce3f9ac694a..1e79740dfa35 100644 --- a/content/html/content/test/test_bug660663.html +++ b/content/html/content/test/test_bug660663.html @@ -21,8 +21,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=660663 reflectLimitedEnumerated({ element: document.createElement("div"), attribute: "dir", - validValues: ["ltr", "rtl", "auto"], - invalidValues: ["cheesecake", ""] + validValues: ["ltr", "rtl"], + invalidValues: ["cheesecake", ""], + unsupportedValues: ["auto"] }); diff --git a/layout/reftests/bidi/dirAuto/dir_auto-EN-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-EN-L-ref.html deleted file mode 100644 index b53ed1fb795f..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-EN-L-ref.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with EN, then L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

123ABCאבג.

-
-
-

123ABCאבג.

-
-
-
-
-

123ABCאבג.

-
-
-

123ABCאבג.

-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-EN-L.html b/layout/reftests/bidi/dirAuto/dir_auto-EN-L.html deleted file mode 100644 index 57f074a2bc1f..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-EN-L.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with EN, then L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

123ABCאבג.

-
-
-

123ABCאבג.

-
-
-
-
-

123ABCאבג.

-
-
-

123ABCאבג.

-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-EN-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-EN-R-ref.html deleted file mode 100644 index d695e5ab570a..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-EN-R-ref.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with EN, then R - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

123אבגABC.

-
-
-

123אבגABC.

-
-
-
-
-

123אבגABC.

-
-
-

123אבגABC.

-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-EN-R.html b/layout/reftests/bidi/dirAuto/dir_auto-EN-R.html deleted file mode 100644 index 1ab3112440f0..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-EN-R.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with EN, then R - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

123אבגABC.

-
-
-

123אבגABC.

-
-
-
-
-

123אבגABC.

-
-
-

123אבגABC.

-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-L-ref.html deleted file mode 100644 index 64b178d7b594..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-L-ref.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

ABCאבג.

-
-
-

ABCאבג.

-
-
-
-
-

ABCאבג.

-
-
-

ABCאבג.

-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-L.html b/layout/reftests/bidi/dirAuto/dir_auto-L.html deleted file mode 100644 index 1da642cc19b7..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-L.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

ABCאבג.

-
-
-

ABCאבג.

-
-
-
-
-

ABCאבג.

-
-
-

ABCאבג.

-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-N-EN-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-N-EN-L-ref.html deleted file mode 100644 index 71da52633ea6..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-N-EN-L-ref.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with N, then EN, then L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

.-=123ABCאבג.

-
-
-

.-=123ABCאבג.

-
-
-
-
-

.-=123ABCאבג.

-
-
-

.-=123ABCאבג.

-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-N-EN-L.html b/layout/reftests/bidi/dirAuto/dir_auto-N-EN-L.html deleted file mode 100644 index 9372a42628da..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-N-EN-L.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with N, then EN, then L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

.-=123ABCאבג.

-
-
-

.-=123ABCאבג.

-
-
-
-
-

.-=123ABCאבג.

-
-
-

.-=123ABCאבג.

-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-N-EN-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-N-EN-R-ref.html deleted file mode 100644 index 856a6ee3e2ef..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-N-EN-R-ref.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with N, then EN, then R - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

.-=123אבגABC.

-
-
-

.-=123אבגABC.

-
-
-
-
-

.-=123אבגABC.

-
-
-

.-=123אבגABC.

-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-N-EN-R.html b/layout/reftests/bidi/dirAuto/dir_auto-N-EN-R.html deleted file mode 100644 index 4f0126b1a48b..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-N-EN-R.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with N, then EN, then R - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

.-=123אבגABC.

-
-
-

.-=123אבגABC.

-
-
-
-
-

.-=123אבגABC.

-
-
-

.-=123אבגABC.

-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-N-EN-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-N-EN-ref.html deleted file mode 100644 index df0339f1342e..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-N-EN-ref.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - HTML Test: dir=auto, start with N, then EN, then L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
-
-

@123!

-
-
-

@123!

-
-
-
-
-

@123!

-
-
-

@123!

-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-N-EN.html b/layout/reftests/bidi/dirAuto/dir_auto-N-EN.html deleted file mode 100644 index a7c6db6d6a79..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-N-EN.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - HTML Test: dir=auto, start with N, then EN, then L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
-
-

@123!

-
-
-

@123!

-
-
-
-
-

@123!

-
-
-

@123!

-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-N-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-N-L-ref.html deleted file mode 100644 index 818b9c0e6746..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-N-L-ref.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with N, then L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

.-=ABCאבג.

-
-
-

.-=ABCאבג.

-
-
-
-
-

.-=ABCאבג.

-
-
-

.-=ABCאבג.

-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-N-L.html b/layout/reftests/bidi/dirAuto/dir_auto-N-L.html deleted file mode 100644 index eab63560c7be..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-N-L.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with N, then L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

.-=ABCאבג.

-
-
-

.-=ABCאבג.

-
-
-
-
-

.-=ABCאבג.

-
-
-

.-=ABCאבג.

-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-N-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-N-R-ref.html deleted file mode 100644 index a2c82541a557..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-N-R-ref.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with N, then R - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

.-=אבגABC.

-
-
-

.-=אבגABC.

-
-
-
-
-

.-=אבגABC.

-
-
-

.-=אבגABC.

-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-N-R.html b/layout/reftests/bidi/dirAuto/dir_auto-N-R.html deleted file mode 100644 index 352b8f80a7d4..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-N-R.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with N, then R - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

.-=אבגABC.

-
-
-

.-=אבגABC.

-
-
-
-
-

.-=אבגABC.

-
-
-

.-=אבגABC.

-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-R-ref.html deleted file mode 100644 index 61ff12f2f8f8..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-R-ref.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: dir=auto, start with R - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
- -
-
-

אבגABC.

-
-
-

אבגABC.

-
-
-
-
-

אבגABC.

-
-
-

אבגABC.

-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-R.html b/layout/reftests/bidi/dirAuto/dir_auto-R.html deleted file mode 100644 index 52677931cabf..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-R.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with R - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

אבגABC.

-
-
-

אבגABC.

-
-
-
-
-

אבגABC.

-
-
-

אבגABC.

-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-L-ref.html deleted file mode 100644 index 9048362d0a75..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-L-ref.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - HTML Test: dir=auto, start with L within contained element - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). - ד - The Hebrew letter Dalet (strongly RTL). - ה - The Hebrew letter He (strongly RTL). - ו - The Hebrew letter Vav (strongly RTL). - ז - The Hebrew letter Zayin (strongly RTL). -
-
-
-
ABCאבג.
דה
ו
-
-
-
ABCאבג.
דה
ו
-
-
-
-
-
ABCאבג.
דה
ו
-
-
-
ABCאבג.
דה
ו
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-L.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-L.html deleted file mode 100644 index 994bfbe78452..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-L.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - HTML Test: dir=auto, start with L within contained element - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). - ד - The Hebrew letter Dalet (strongly RTL). - ה - The Hebrew letter He (strongly RTL). - ו - The Hebrew letter Vav (strongly RTL). - ז - The Hebrew letter Zayin (strongly RTL). -
-
-
-
ABCאבג.
דה
ו
-
-
-
ABCאבג.
דה
ו
-
-
-
-
-
ABCאבג.
דה
ו
-
-
-
ABCאבג.
דה
ו
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-R-ref.html deleted file mode 100644 index 0cee718c43de..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-R-ref.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with R within contained element - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-
אבגABC.
XY
Z
-
-
-
אבגABC.
XY
Z
-
-
-
-
-
אבגABC.
XY
Z
-
-
-
אבגABC.
XY
Z
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-R.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-R.html deleted file mode 100644 index 113eb073ccaf..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-R.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with R within contained element - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-
אבגABC.
XY
Z
-
-
-
אבגABC.
XY
Z
-
-
-
-
-
אבגABC.
XY
Z
-
-
-
אבגABC.
XY
Z
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-L-ref.html deleted file mode 100644 index 745eea114eb2..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-L-ref.html +++ /dev/null @@ -1,64 +0,0 @@ - - - - - HTML Test: dir=auto, start with bdi, then L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). - ד - The Hebrew letter Dalet (strongly RTL). - ה - The Hebrew letter He (strongly RTL). - ו - The Hebrew letter Vav (strongly RTL). -
-
-
-
123דהוABCאבג.
-
-
-
123דהוABCאבג.
-
-
-
-
-
123דהוABCאבג.
-
-
-
123דהוABCאבג.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-L.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-L.html deleted file mode 100644 index cd0292c5cf4f..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-L.html +++ /dev/null @@ -1,64 +0,0 @@ - - - - - HTML Test: dir=auto, start with bdi, then L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). - ד - The Hebrew letter Dalet (strongly RTL). - ה - The Hebrew letter He (strongly RTL). - ו - The Hebrew letter Vav (strongly RTL). -
-
-
-
123דהוABCאבג.
-
-
-
123דהוABCאבג.
-
-
-
-
-
123דהוABCאבג.
-
-
-
123דהוABCאבג.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-R-ref.html deleted file mode 100644 index 43405ea6e799..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-R-ref.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - HTML Test: dir=auto, start with bdi, then R - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-
123DEFאבגABC.
-
-
-
123DEFאבגABC.
-
-
-
-
-
123DEFאבגABC.
-
-
-
123DEFאבגABC.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-R.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-R.html deleted file mode 100644 index cce36bddf2a1..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-bdi-R.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - HTML Test: dir=auto, start with bdi, then R - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-
123DEFאבגABC.
-
-
-
123DEFאבגABC.
-
-
-
-
-
123DEFאבגABC.
-
-
-
123DEFאבגABC.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-L-ref.html deleted file mode 100644 index d5935d83f612..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-L-ref.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - HTML Test: dir=auto, start with dir, then L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). - ד - The Hebrew letter Dalet (strongly RTL). - ה - The Hebrew letter He (strongly RTL). - ו - The Hebrew letter Vav (strongly RTL). -
-
-
-

דהו

ABCאבג.
-
-
-

דהו

ABCאבג.
-
-
-
-
-

דהו

ABCאבג.
-
-
-

דהו

ABCאבג.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-L.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-L.html deleted file mode 100644 index 292c753fdd1a..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-L.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - HTML Test: dir=auto, start with dir, then L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). - ד - The Hebrew letter Dalet (strongly RTL). - ה - The Hebrew letter He (strongly RTL). - ו - The Hebrew letter Vav (strongly RTL). -
-
-
-

דהו

ABCאבג.
-
-
-

דהו

ABCאבג.
-
-
-
-
-

דהו

ABCאבג.
-
-
-

דהו

ABCאבג.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-R-ref.html deleted file mode 100644 index 5ae48d897043..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-R-ref.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with dir, then R - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

DEF

אבגABC.
-
-
-

DEF

אבגABC.
-
-
-
-
-

DEF

אבגABC.
-
-
-

DEF

אבגABC.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-R.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-R.html deleted file mode 100644 index cc625553f828..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir-R.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with dir, then R - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

DEF

אבגABC.
-
-
-

DEF

אבגABC.
-
-
-
-
-

DEF

אבגABC.
-
-
-

DEF

אבגABC.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-L-ref.html deleted file mode 100644 index ac1f178799ae..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-L-ref.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - HTML Test: dir=auto, start with dir=auto, then L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). - ד - The Hebrew letter Dalet (strongly RTL). - ה - The Hebrew letter He (strongly RTL). - ו - The Hebrew letter Vav (strongly RTL). -
-
-
-

דהו

ABCאבג.
-
-
-

דהו

ABCאבג.
-
-
-
-
-

דהו

ABCאבג.
-
-
-

דהו

ABCאבג.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-L.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-L.html deleted file mode 100644 index 892894e8e990..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-L.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - HTML Test: dir=auto, start with dir=auto, then L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). - ד - The Hebrew letter Dalet (strongly RTL). - ה - The Hebrew letter He (strongly RTL). - ו - The Hebrew letter Vav (strongly RTL). -
-
-
-

דהו

ABCאבג.
-
-
-

דהו

ABCאבג.
-
-
-
-
-

דהו

ABCאבג.
-
-
-

דהו

ABCאבג.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-R-ref.html deleted file mode 100644 index d7157de5c89b..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-R-ref.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with dir=auto, then R - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

DEF

.-=123אבגABC.
-
-
-

DEF

.-=123אבגABC.
-
-
-
-
-

DEF

.-=123אבגABC.
-
-
-

DEF

.-=123אבגABC.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-R.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-R.html deleted file mode 100644 index 328104cb8783..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-dir_auto-R.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with dir=auto, then R - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

DEF

.-=123אבגABC.
-
-
-

DEF

.-=123אבגABC.
-
-
-
-
-

DEF

.-=123אבגABC.
-
-
-

DEF

.-=123אבגABC.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-script-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-script-L-ref.html deleted file mode 100644 index ad844fd1da23..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-script-L-ref.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with script, then L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-
ABCאבג.
-
-
-
ABCאבג.
-
-
-
-
-
ABCאבג.
-
-
-
ABCאבג.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-script-L.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-script-L.html deleted file mode 100644 index d5e685ee0eb6..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-script-L.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with script, then L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-
ABCאבג.
-
-
-
ABCאבג.
-
-
-
-
-
ABCאבג.
-
-
-
ABCאבג.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-script-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-script-R-ref.html deleted file mode 100644 index 8225443c86a1..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-script-R-ref.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with script, then R - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-
אבגABC.
-
-
-
אבגABC.
-
-
-
-
-
אבגABC.
-
-
-
אבגABC.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-script-R.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-script-R.html deleted file mode 100644 index 4d131a2d480d..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-script-R.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with script, then R - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-
אבגABC.
-
-
-
אבגABC.
-
-
-
-
-
אבגABC.
-
-
-
אבגABC.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-style-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-style-L-ref.html deleted file mode 100644 index 46e713774051..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-style-L-ref.html +++ /dev/null @@ -1,70 +0,0 @@ - - - - - HTML Test: dir=auto, start with style, then L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-
ABCאבג.
-
-
-
ABCאבג.
-
-
-
-
-
ABCאבג.
-
-
-
ABCאבג.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-style-L.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-style-L.html deleted file mode 100644 index 5ad03180f2ec..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-style-L.html +++ /dev/null @@ -1,70 +0,0 @@ - - - - - HTML Test: dir=auto, start with style, then L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-
ABCאבג.
-
-
-
ABCאבג.
-
-
-
-
-
ABCאבג.
-
-
-
ABCאבג.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-style-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-style-R-ref.html deleted file mode 100644 index 6cf5e1d24b2d..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-style-R-ref.html +++ /dev/null @@ -1,70 +0,0 @@ - - - - - HTML Test: dir=auto, start with style, then R - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-
אבגABC.
-
-
-
אבגABC.
-
-
-
-
-
אבגABC.
-
-
-
אבגABC.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-style-R.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-style-R.html deleted file mode 100644 index 133ce1be0510..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-style-R.html +++ /dev/null @@ -1,70 +0,0 @@ - - - - - HTML Test: dir=auto, start with style, then R - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-
אבגABC.
-
-
-
אבגABC.
-
-
-
-
-
אבגABC.
-
-
-
אבגABC.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-L-ref.html deleted file mode 100644 index d13f702557a1..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-L-ref.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - HTML Test: dir=auto, start with textarea, then L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). - ד - The Hebrew letter Dalet (strongly RTL). - ה - The Hebrew letter He (strongly RTL). - ו - The Hebrew letter Vav (strongly RTL). -
-
-
-
ABCאבג.
-
-
-
ABCאבג.
-
-
-
-
-
ABCאבג.
-
-
-
ABCאבג.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-L.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-L.html deleted file mode 100644 index 51468ce17c82..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-L.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - HTML Test: dir=auto, start with textarea, then L - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). - ד - The Hebrew letter Dalet (strongly RTL). - ה - The Hebrew letter He (strongly RTL). - ו - The Hebrew letter Vav (strongly RTL). -
-
-
-
ABCאבג.
-
-
-
ABCאבג.
-
-
-
-
-
ABCאבג.
-
-
-
ABCאבג.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-R-ref.html deleted file mode 100644 index ffa5ba5c92c3..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-R-ref.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with textarea, then R - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-
אבגABC.
-
-
-
אבגABC.
-
-
-
-
-
אבגABC.
-
-
-
אבגABC.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-R.html b/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-R.html deleted file mode 100644 index 83875ef58a41..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-contained-textarea-R.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, start with textarea, then R - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-
אבגABC.
-
-
-
אבגABC.
-
-
-
-
-
אבגABC.
-
-
-
אבגABC.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-EN-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-EN-L-ref.html deleted file mode 100644 index cedc14acf026..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-EN-L-ref.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, start with EN+L - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-EN-L.html b/layout/reftests/bidi/dirAuto/dir_auto-input-EN-L.html deleted file mode 100644 index 9d32b7a59084..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-EN-L.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, start with EN+L - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-EN-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-EN-R-ref.html deleted file mode 100644 index 91c1bf568692..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-EN-R-ref.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, start with EN+R - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-EN-R.html b/layout/reftests/bidi/dirAuto/dir_auto-input-EN-R.html deleted file mode 100644 index 7ac8b11f6c04..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-EN-R.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, start with EN+R - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-L-ref.html deleted file mode 100644 index a16ecdbd12d1..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-L-ref.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, start with L - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-L.html b/layout/reftests/bidi/dirAuto/dir_auto-input-L.html deleted file mode 100644 index adefc3b80298..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-L.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, start with L - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-L-ref.html deleted file mode 100644 index 1e68258423b8..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-L-ref.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, start with N+EN+L - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-L.html b/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-L.html deleted file mode 100644 index 5ad1d24a14dc..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-L.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, start with N+EN+L - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-R-ref.html deleted file mode 100644 index fe2ba0b3f715..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-R-ref.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, start with N+EN+R - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-R.html b/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-R.html deleted file mode 100644 index fba3dda45499..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-R.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, start with N+EN+R - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-ref.html deleted file mode 100644 index 6a9db60ab10b..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN-ref.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - - HTML Test: input with dir=auto, all N+EN - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN.html b/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN.html deleted file mode 100644 index 649beca1a6e8..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-N-EN.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - - HTML Test: input with dir=auto, all N+EN - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-N-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-N-L-ref.html deleted file mode 100644 index 03b396d4bff8..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-N-L-ref.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, start with N+L - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-N-L.html b/layout/reftests/bidi/dirAuto/dir_auto-input-N-L.html deleted file mode 100644 index 14bd05fb270c..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-N-L.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, start with N+L - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-N-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-N-R-ref.html deleted file mode 100644 index 474b5c7e7623..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-N-R-ref.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, start with N+R - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-N-R.html b/layout/reftests/bidi/dirAuto/dir_auto-input-N-R.html deleted file mode 100644 index f78f28981800..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-N-R.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, start with N+R - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-R-ref.html deleted file mode 100644 index 6942d3ffb8a4..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-R-ref.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, start with R - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-R.html b/layout/reftests/bidi/dirAuto/dir_auto-input-R.html deleted file mode 100644 index 70163671dcfe..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-R.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, start with R - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-L-ref.html deleted file mode 100644 index a58f6c166696..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-L-ref.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, script assigns to start with EN+L - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-L.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-L.html deleted file mode 100644 index 03850c990ded..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-L.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - HTML Test: input with dir=auto, script assigns to start with EN+L - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
- -
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-R-ref.html deleted file mode 100644 index 33061e92917f..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-R-ref.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, script assigns to start with EN+R - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-R.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-R.html deleted file mode 100644 index 207652d2505c..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-script-EN-R.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - HTML Test: input with dir=auto, script assigns to start with EN+R - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
- -
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-L-ref.html deleted file mode 100644 index b14ec45e6745..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-script-L-ref.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, script assigns to start with L - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-L.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-L.html deleted file mode 100644 index 6ee4ee471ef1..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-script-L.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - HTML Test: input with dir=auto, script assigns to start with L - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
- -
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-L-ref.html deleted file mode 100644 index eda0b659dea4..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-L-ref.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, script assigns to start with N+EN+L - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-L.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-L.html deleted file mode 100644 index 50222dd07f05..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-L.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - HTML Test: input with dir=auto, script assigns to start with N+EN+L - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
- -
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-R-ref.html deleted file mode 100644 index f78ef0bbc9a0..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-R-ref.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, script assigns to start with N+EN+R - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-R.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-R.html deleted file mode 100644 index e87f8f13bb8c..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-R.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - HTML Test: input with dir=auto, script assigns to start with N+EN+R - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
- -
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-ref.html deleted file mode 100644 index b61f677dc71c..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN-ref.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - - HTML Test: input with dir=auto, script assigns to all N+EN - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN.html deleted file mode 100644 index 088036a25516..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-EN.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - - HTML Test: input with dir=auto, script assigns to all N+EN - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- -
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-L-ref.html deleted file mode 100644 index 55ff0d53c438..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-L-ref.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, script assigns to start with N+L - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-L.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-L.html deleted file mode 100644 index 1f3486c0ed14..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-L.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - HTML Test: input with dir=auto, script assigns to start with N+L - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
- -
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-R-ref.html deleted file mode 100644 index f06f47738ed9..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-R-ref.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, script assigns to start with N+R - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-R.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-R.html deleted file mode 100644 index 941b55143543..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-script-N-R.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - HTML Test: input with dir=auto, script assigns to start with N+R - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
- -
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-R-ref.html deleted file mode 100644 index 2b9ea5d73362..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-script-R-ref.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - HTML Test: input with dir=auto, script assigns to start with R - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-input-script-R.html b/layout/reftests/bidi/dirAuto/dir_auto-input-script-R.html deleted file mode 100644 index 304189e189b0..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-input-script-R.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - HTML Test: input with dir=auto, script assigns to start with R - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
- -
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-isolate-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-isolate-ref.html deleted file mode 100644 index 4583ac2c7a64..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-isolate-ref.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - - HTML Test: dir=auto, isolated in LTR text - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). -
-
-
- ‭1 a! א‬ -
-
- ‭a !א 1‬ -
-
-
-
- ‭1 a! א‬ -
-
- ‭a !א 1‬ -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-isolate.html b/layout/reftests/bidi/dirAuto/dir_auto-isolate.html deleted file mode 100644 index 71f929204ed9..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-isolate.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - HTML Test: dir=auto, isolated in LTR text - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ‭ - The LRO (left-to-right-override) formatting character. - ‬ - The PDF (pop directional formatting) formatting character; closes LRO. -
-
-
- א a! 1 -
-
- a א! 1 -
-
-
-
- ‭1 a! א‬ -
-
- ‭a !א 1‬ -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-pre-N-EN-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-pre-N-EN-ref.html deleted file mode 100644 index c951c30b2023..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-pre-N-EN-ref.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
-
-
-@123!
-        
-
-
-
-@123!
-        
-
-
-
-
-
-@123!
-        
-
-
-
-@123!
-        
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-pre-N-EN.html b/layout/reftests/bidi/dirAuto/dir_auto-pre-N-EN.html deleted file mode 100644 index ed923a908d99..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-pre-N-EN.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - - HTML Test: pre with dir=auto, all N+EN - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - ‎ - LRM, the invisible left-to-right mark (strongly LTR). - ‏ - RLM, the invisible right-to-left mark (strongly RTL). - We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext - specification states whether text-align:start and text-align:end should obey the paragraph - direction or the direction property in a unicode-bidi:plaintext element. -
-
-
-
-@123!
-        
-
-
-
-@123!
-        
-
-
-
-
-
-@123!
-        
-
-
-
-@123!
-        
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-pre-N-between-Rs-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-pre-N-between-Rs-ref.html deleted file mode 100644 index 2d9caf062d24..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-pre-N-between-Rs-ref.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). -
-
-
-
-א
-!...
-א
-        
-
-
-
-א
-!...
-א
-        
-
-
-
-
-
-א
-!...
-א
-        
-
-
-
-א
-!...
-א
-        
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-pre-N-between-Rs.html b/layout/reftests/bidi/dirAuto/dir_auto-pre-N-between-Rs.html deleted file mode 100644 index 00115a401003..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-pre-N-between-Rs.html +++ /dev/null @@ -1,76 +0,0 @@ - - - - - HTML Test: pre with dir=auto, all-N between all-Rs - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext - specification states whether text-align:start and text-align:end should obey the paragraph - direction or the direction property in a unicode-bidi:plaintext element. - The ...! paragraph, being neutral, is supposed to be displayed LTR (i.e. as ...!, not as !...) - despite both the paragraph before it and the paragraph after it being all-RTL, which makes the - element as a whole RTL. -
-
-
-
-א
-...!
-א
-        
-
-
-
-א
-...!
-א
-        
-
-
-
-
-
-א
-!...
-א
-        
-
-
-
-א
-!...
-א
-        
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-pre-mixed-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-pre-mixed-ref.html deleted file mode 100644 index 10bd02433b45..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-pre-mixed-ref.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
-
-
-@123!
-@123!
-@123!
-@123!
-        
-
-
-
-@123!
-@123!
-@123!
-@123!
-        
-
-
-
-
-
-@123!
-@123!
-@123!
-@123!
-        
-
-
-
-@123!
-@123!
-@123!
-@123!
-        
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-pre-mixed.html b/layout/reftests/bidi/dirAuto/dir_auto-pre-mixed.html deleted file mode 100644 index 46eac9551d4b..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-pre-mixed.html +++ /dev/null @@ -1,77 +0,0 @@ - - - - - HTML Test: pre with dir=auto, mixed L and R paragraphs - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - ‎ - LRM, the invisible left-to-right mark (strongly LTR). - ‏ - RLM, the invisible right-to-left mark (strongly RTL). - We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext - specification states whether text-align:start and text-align:end should obey the paragraph - direction or the direction property in a unicode-bidi:plaintext element. -
-
-
-
-@‎123‏!
-!‏123‎@
-@123‎‏!
-!123‏‎@
-        
-
-
-
-@‎123‏!
-!‏123‎@
-@123‎‏!
-!123‏‎@
-        
-
-
-
-
-
-@123!
-@123!
-@123!
-@123!
-        
-
-
-
-@123!
-@123!
-@123!
-@123!
-        
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-set-contained-dir-L.html b/layout/reftests/bidi/dirAuto/dir_auto-set-contained-dir-L.html deleted file mode 100644 index 41bf37180e9f..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-set-contained-dir-L.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - - HTML Test: dir=auto, start with dir, then L - - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). - ד - The Hebrew letter Dalet (strongly RTL). - ה - The Hebrew letter He (strongly RTL). - ו - The Hebrew letter Vav (strongly RTL). -
-
-
-

דהו

ABCאבג.
-
-
-

דהו

ABCאבג.
-
-
-
-
-

דהו

ABCאבג.
-
-
-

דהו

ABCאבג.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-set-contained-dir-R.html b/layout/reftests/bidi/dirAuto/dir_auto-set-contained-dir-R.html deleted file mode 100644 index 0c74b3f3b4d0..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-set-contained-dir-R.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - HTML Test: dir=auto, start with dir, then R - - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

DEF

אבגABC.
-
-
-

DEF

אבגABC.
-
-
-
-
-

DEF

אבגABC.
-
-
-

DEF

אבגABC.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-set-contained-invalid-dir-L.html b/layout/reftests/bidi/dirAuto/dir_auto-set-contained-invalid-dir-L.html deleted file mode 100644 index 10a75a4cee85..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-set-contained-invalid-dir-L.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - - HTML Test: dir=auto, start with dir, then L - - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). - ד - The Hebrew letter Dalet (strongly RTL). - ה - The Hebrew letter He (strongly RTL). - ו - The Hebrew letter Vav (strongly RTL). -
-
-
-

דהו

ABCאבג.
-
-
-

דהו

ABCאבג.
-
-
-
-
-

דהו

ABCאבג.
-
-
-

דהו

ABCאבג.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-set-contained-invalid-dir-R.html b/layout/reftests/bidi/dirAuto/dir_auto-set-contained-invalid-dir-R.html deleted file mode 100644 index 0ff92cb55d9c..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-set-contained-invalid-dir-R.html +++ /dev/null @@ -1,72 +0,0 @@ - - - - - HTML Test: dir=auto, start with dir, then R - - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

DEF

אבגABC.
-
-
-

DEF

אבגABC.
-
-
-
-
-

DEF

אבגABC.
-
-
-

DEF

אבגABC.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-EN-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-EN-ref.html deleted file mode 100644 index 253b84459eef..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-EN-ref.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-EN.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-EN.html deleted file mode 100644 index fd05e30dec6b..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-EN.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - - HTML Test: textarea with dir=auto, all N+EN - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - ‎ - LRM, the invisible left-to-right mark (strongly LTR). - ‏ - RLM, the invisible right-to-left mark (strongly RTL). - We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext - specification states whether text-align:start and text-align:end should obey the paragraph - direction or the direction property in a unicode-bidi:plaintext element. -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-between-Rs-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-between-Rs-ref.html deleted file mode 100644 index 558e27171bc8..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-between-Rs-ref.html +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-between-Rs.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-between-Rs.html deleted file mode 100644 index d48a6141d874..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-textarea-N-between-Rs.html +++ /dev/null @@ -1,79 +0,0 @@ - - - - - HTML Test: textarea with dir=auto, all-N between all-Rs - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext - specification states whether text-align:start and text-align:end should obey the paragraph - direction or the direction property in a unicode-bidi:plaintext element. - The ...! paragraph, being neutral, is supposed to be displayed LTR (i.e. as ...!, not as !...) - despite both the paragraph before it and the paragraph after it being all-RTL, which makes the - element as a whole RTL. -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-mixed-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-mixed-ref.html deleted file mode 100644 index a5a84480f6f4..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-textarea-mixed-ref.html +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-mixed.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-mixed.html deleted file mode 100644 index db53d8ff43f1..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-textarea-mixed.html +++ /dev/null @@ -1,80 +0,0 @@ - - - - - HTML Test: textarea with dir=auto, mixed L and R paragraphs - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - ‎ - LRM, the invisible left-to-right mark (strongly LTR). - ‏ - RLM, the invisible right-to-left mark (strongly RTL). - We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext - specification states whether text-align:start and text-align:end should obey the paragraph - direction or the direction property in a unicode-bidi:plaintext element. -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-EN-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-EN-ref.html deleted file mode 100644 index 253b84459eef..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-EN-ref.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-EN.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-EN.html deleted file mode 100644 index a622db584b53..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-EN.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - - HTML Test: textarea with dir=auto, script assigns to all N+EN - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - ‎ - LRM, the invisible left-to-right mark (strongly LTR). - ‏ - RLM, the invisible right-to-left mark (strongly RTL). - We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext - specification states whether text-align:start and text-align:end should obey the paragraph - direction or the direction property in a unicode-bidi:plaintext element. -
-
- -
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-between-Rs-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-between-Rs-ref.html deleted file mode 100644 index 558e27171bc8..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-between-Rs-ref.html +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-between-Rs.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-between-Rs.html deleted file mode 100644 index 407e3414fb3f..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-N-between-Rs.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - - HTML Test: textarea with dir=auto, script assigns to all-N between all-Rs - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext - specification states whether text-align:start and text-align:end should obey the paragraph - direction or the direction property in a unicode-bidi:plaintext element. - The ...! paragraph, being neutral, is supposed to be displayed LTR (i.e. as ...!, not as !...) - despite both the paragraph before it and the paragraph after it being all-RTL, which makes the - element as a whole RTL. -
-
- -
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-mixed-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-mixed-ref.html deleted file mode 100644 index a5a84480f6f4..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-mixed-ref.html +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
-
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-mixed.html b/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-mixed.html deleted file mode 100644 index f5a5ece56f28..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-textarea-script-mixed.html +++ /dev/null @@ -1,98 +0,0 @@ - - - - - HTML Test: textarea with dir=auto, script assigns to mixed L and R paragraphs - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - ‎ - LRM, the invisible left-to-right mark (strongly LTR). - ‏ - RLM, the invisible right-to-left mark (strongly RTL). - We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext - specification states whether text-align:start and text-align:end should obey the paragraph - direction or the direction property in a unicode-bidi:plaintext element. -
-
- -
- -
-
- -
-
-
-
- -
-
- -
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-L-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-L-ref.html deleted file mode 100644 index a786430499bd..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-L-ref.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - HTML Test: dir=auto, start with dir, then R - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

DEF

אבגABC.
-
-
-

DEF

אבגABC.
-
-
-
-
-

DEF

אבגABC.
-
-
-

DEF

אבגABC.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-L.html b/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-L.html deleted file mode 100644 index c2cbdc2415ed..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-L.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - HTML Test: dir=auto, start with dir, then R - - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). -
-
-
-

DEF

אבגABC.
-
-
-

DEF

אבגABC.
-
-
-
-
-

DEF

אבגABC.
-
-
-

DEF

אבגABC.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-R-ref.html b/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-R-ref.html deleted file mode 100644 index f383652215c9..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-R-ref.html +++ /dev/null @@ -1,64 +0,0 @@ - - - - - HTML Test: dir=auto, start with dir, then L - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). - ד - The Hebrew letter Dalet (strongly RTL). - ה - The Hebrew letter He (strongly RTL). - ו - The Hebrew letter Vav (strongly RTL). -
-
-
-

דהו

ABCאבג.
-
-
-

דהו

ABCאבג.
-
-
-
-
-

דהו

ABCאבג.
-
-
-

דהו

ABCאבג.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-R.html b/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-R.html deleted file mode 100644 index a63f718ce1a0..000000000000 --- a/layout/reftests/bidi/dirAuto/dir_auto-unset-contained-dir-R.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - - HTML Test: dir=auto, start with dir, then L - - - - - - - - - - - -

Test passes if the two boxes below look exactly the same.

-
- Key to entities used below: - א - The Hebrew letter Alef (strongly RTL). - ב - The Hebrew letter Bet (strongly RTL). - ג - The Hebrew letter Gimel (strongly RTL). - ד - The Hebrew letter Dalet (strongly RTL). - ה - The Hebrew letter He (strongly RTL). - ו - The Hebrew letter Vav (strongly RTL). -
-
-
-

דהו

ABCאבג.
-
-
-

דהו

ABCאבג.
-
-
-
-
-

דהו

ABCאבג.
-
-
-

דהו

ABCאבג.
-
-
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR1.html deleted file mode 100644 index 223aa56e6dbf..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR1.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR10.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR10.html deleted file mode 100644 index bd3dad92a84b..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR10.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
...
-
-
-
...
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR2.html deleted file mode 100644 index f9af6b961fdb..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR2.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
...
-
-
-
...
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR3.html deleted file mode 100644 index 2d07131d57b9..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR3.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
­
-
-
-
­
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR4.html deleted file mode 100644 index 38801d2a47c7..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR4.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
­
-
-
-
­
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR5.html deleted file mode 100644 index 7cd5db77c461..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR5.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
­
-
-
-
­
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR6.html deleted file mode 100644 index b66f5e30612b..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR6.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
­
-
-
-
­
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR7.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR7.html deleted file mode 100644 index 461118996689..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR7.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR8.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR8.html deleted file mode 100644 index 2fb2148f994e..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR8.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
...
-
-
-
...
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR9.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR9.html deleted file mode 100644 index 087d5104fc98..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-LTR9.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL1.html deleted file mode 100644 index 361fcd1e725b..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL1.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL10.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL10.html deleted file mode 100644 index 01e6f6bcba64..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL10.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
...
-
-
-
...
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL2.html deleted file mode 100644 index f243dec4fa3a..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL2.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
...
-
-
-
...
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL3.html deleted file mode 100644 index 0aaedfe4a1b1..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL3.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
­
-
-
-
­
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL4.html deleted file mode 100644 index 60df2980c6fe..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL4.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
­
-
-
-
­
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL5.html deleted file mode 100644 index 36d2940e585b..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL5.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
­
-
-
-
­
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL6.html deleted file mode 100644 index 440945bb5875..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL6.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
­
-
-
-
­
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL7.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL7.html deleted file mode 100644 index 032c2f4eb11c..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL7.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL8.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL8.html deleted file mode 100644 index 9c1da6b0fc7a..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL8.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
...
-
-
-
...
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL9.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL9.html deleted file mode 100644 index b7c4c36533cf..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-ChangeText-RTL9.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR1.html deleted file mode 100644 index 4ba7a037f638..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR1.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
DEF ABC אבג
-
-
-
DEF ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR2.html deleted file mode 100644 index 4bea44d83be8..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR2.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
גדה ABC אבג
-
-
-
גדה ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR3.html deleted file mode 100644 index 2c16829530ff..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-LTR3.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
... ABC אבג
-
-
-
... ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL1.html deleted file mode 100644 index ab08388b8206..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL1.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
DEF אבג ABC
-
-
-
DEF אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL2.html deleted file mode 100644 index 477e155a0bde..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL2.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
גדה אבג ABC
-
-
-
גדה אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL3.html deleted file mode 100644 index cf4069567e05..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-DeleteText-RTL3.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
... אבג ABC
-
-
-
... אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-addLTR-Auto.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-addLTR-Auto.html deleted file mode 100644 index 16dc62b5b936..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-addLTR-Auto.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-addRTL-Auto.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-addRTL-Auto.html deleted file mode 100644 index 52c0949c91f1..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-addRTL-Auto.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-refLTR-LTR.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-refLTR-LTR.html deleted file mode 100644 index 62a74bf334d8..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-refLTR-LTR.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - Set and unset dir="auto" - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-refLTR-RTL.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-refLTR-RTL.html deleted file mode 100644 index 60619730a8cd..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-refLTR-RTL.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - Set and unset dir="auto" - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-LTR.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-LTR.html deleted file mode 100644 index 4ea471a8d1cf..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-LTR.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - Set and unset dir="auto" - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-NoDir.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-NoDir.html deleted file mode 100644 index b2f56c1ac115..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-NoDir.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - Set and unset dir="auto" - - - -
-
אבג ABC
-
-
- -
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-RTL.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-RTL.html deleted file mode 100644 index 71c42ea3e426..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-refRTL-RTL.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - Set and unset dir="auto" - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto1.html deleted file mode 100644 index 2c1c525f97b8..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto1.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto2.html deleted file mode 100644 index f0400e0d0050..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto2.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto3.html deleted file mode 100644 index 2cbf52716ccb..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto3.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto4.html deleted file mode 100644 index 5bcec0648d48..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto4.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto5.html deleted file mode 100644 index a0423c2468cc..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto5.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto6.html deleted file mode 100644 index 2574c867fa38..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-Auto6.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir1.html deleted file mode 100644 index 1913335b8b9c..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir1.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir2.html deleted file mode 100644 index 596f1143af99..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir2.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir3.html deleted file mode 100644 index f22dd147d1ba..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir3.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir4.html deleted file mode 100644 index f876484e4beb..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir4.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="foopy" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir5.html deleted file mode 100644 index 6da8dff2f35c..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir5.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir6.html deleted file mode 100644 index b63c0dd0d24f..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir6.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir7.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir7.html deleted file mode 100644 index e1b9d82c1cdb..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir7.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir8.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir8.html deleted file mode 100644 index 9b80f42d0b02..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-InvalidDir8.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="foopy" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR1.html deleted file mode 100644 index e89fc792119e..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR1.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR2.html deleted file mode 100644 index 5a8e4f122161..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR2.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR3.html deleted file mode 100644 index bbc5f8090044..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR3.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR4.html deleted file mode 100644 index 08b21e09a458..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR4.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="foopy" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR5.html deleted file mode 100644 index cffe2556b84f..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR5.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR6.html deleted file mode 100644 index b54417b6f4e2..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR6.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR7.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR7.html deleted file mode 100644 index 0baeb9fc6d32..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR7.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR8.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR8.html deleted file mode 100644 index ec1de35425e1..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-LTR8.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="foopy" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir1.html deleted file mode 100644 index 2040663c3590..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir1.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir2.html deleted file mode 100644 index f8c2e99a744a..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir2.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir3.html deleted file mode 100644 index c295012dba84..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir3.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir4.html deleted file mode 100644 index 13e0e5fc8ff7..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir4.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="foopy" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir5.html deleted file mode 100644 index 6dce96a6065c..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir5.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir6.html deleted file mode 100644 index 2d9973fa1d33..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir6.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir7.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir7.html deleted file mode 100644 index dd1964e01ff6..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir7.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir8.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir8.html deleted file mode 100644 index b25d70232366..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-NoDir8.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="foopy" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL1.html deleted file mode 100644 index c5a9bf42df7d..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL1.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL2.html deleted file mode 100644 index b8ed6cda812a..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL2.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL3.html deleted file mode 100644 index 528ffde04e6a..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL3.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL4.html deleted file mode 100644 index 884c8fa852e2..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL4.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="foopy" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL5.html deleted file mode 100644 index 5cf486c905bc..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL5.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL6.html deleted file mode 100644 index 61c7331bd3b2..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL6.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL7.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL7.html deleted file mode 100644 index c4cc154cbe88..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL7.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL8.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL8.html deleted file mode 100644 index 18e333978c8e..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setLTR-RTL8.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="foopy" - - - - -
-
ABC אבג
-
-
-
ABC אבג
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto1.html deleted file mode 100644 index 483d79fd518f..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto1.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto2.html deleted file mode 100644 index b0773e6f6c4d..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto2.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto3.html deleted file mode 100644 index 77ce26cb3b1a..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto3.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto4.html deleted file mode 100644 index f8cabec1ee8f..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto4.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto5.html deleted file mode 100644 index 20621a5a756e..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto5.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto6.html deleted file mode 100644 index c9e1b560f77f..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-Auto6.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir1.html deleted file mode 100644 index a2ddd5292f54..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir1.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir2.html deleted file mode 100644 index 87eb1181902a..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir2.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir3.html deleted file mode 100644 index 17ec5b453b5d..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir3.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir4.html deleted file mode 100644 index b4c5ebc09194..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir4.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="foopy" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir5.html deleted file mode 100644 index 1859e89bc6f3..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir5.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir6.html deleted file mode 100644 index 06c3d71703ec..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir6.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir7.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir7.html deleted file mode 100644 index 03239e88b701..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir7.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir8.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir8.html deleted file mode 100644 index fc353ac22f7c..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-InvalidDir8.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="foopy" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR1.html deleted file mode 100644 index 52fcf96b37a1..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR1.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR2.html deleted file mode 100644 index 074eeab1042b..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR2.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR3.html deleted file mode 100644 index 2bb5ad2de54e..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR3.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR4.html deleted file mode 100644 index 79372c6ed3f6..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR4.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="foopy" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR5.html deleted file mode 100644 index 21201701535d..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR5.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR6.html deleted file mode 100644 index 272d5f9fcea0..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR6.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR7.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR7.html deleted file mode 100644 index d1d1185d2d67..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR7.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR8.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR8.html deleted file mode 100644 index a6f9fa09a271..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-LTR8.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="foopy" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir1.html deleted file mode 100644 index ba2bd8bab5db..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir1.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir2.html deleted file mode 100644 index 5833b2e4adff..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir2.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir3.html deleted file mode 100644 index 1a031d043819..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir3.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir4.html deleted file mode 100644 index 53074850d35f..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir4.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="foopy" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir5.html deleted file mode 100644 index 63fc1a746588..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir5.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir6.html deleted file mode 100644 index 31af1459d2ea..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir6.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir7.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir7.html deleted file mode 100644 index 5fd61d42e618..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir7.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir8.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir8.html deleted file mode 100644 index d388d5377fdc..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-NoDir8.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="foopy" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL1.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL1.html deleted file mode 100644 index 45ee5c571375..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL1.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL2.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL2.html deleted file mode 100644 index 0df2fc8de199..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL2.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL3.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL3.html deleted file mode 100644 index 0dee370b6b37..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL3.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL4.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL4.html deleted file mode 100644 index dbfbe2125adb..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL4.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="foopy" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL5.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL5.html deleted file mode 100644 index 1b401367c12a..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL5.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL6.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL6.html deleted file mode 100644 index d2c70793c25f..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL6.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL7.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL7.html deleted file mode 100644 index ca0153cc2f53..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL7.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="auto" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL8.html b/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL8.html deleted file mode 100644 index 15b323976eed..000000000000 --- a/layout/reftests/bidi/dirAuto/dynamicDirAuto-setRTL-RTL8.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Set and unset dir="foopy" - - - - -
-
אבג ABC
-
-
-
אבג ABC
- - diff --git a/layout/reftests/bidi/dirAuto/reftest.list b/layout/reftests/bidi/dirAuto/reftest.list deleted file mode 100644 index a280551522b1..000000000000 --- a/layout/reftests/bidi/dirAuto/reftest.list +++ /dev/null @@ -1,161 +0,0 @@ -== dir_auto-contained-bdi-L.html dir_auto-contained-bdi-L-ref.html -== dir_auto-contained-bdi-R.html dir_auto-contained-bdi-R-ref.html -== dir_auto-contained-dir-L.html dir_auto-contained-dir-L-ref.html -== dir_auto-contained-dir-R.html dir_auto-contained-dir-R-ref.html -== dir_auto-set-contained-dir-L.html dir_auto-contained-dir-L-ref.html -== dir_auto-set-contained-dir-R.html dir_auto-contained-dir-R-ref.html -== dir_auto-set-contained-invalid-dir-L.html dir_auto-contained-dir-L-ref.html -== dir_auto-set-contained-invalid-dir-R.html dir_auto-contained-dir-R-ref.html -== dir_auto-unset-contained-dir-L.html dir_auto-unset-contained-dir-L-ref.html -== dir_auto-unset-contained-dir-R.html dir_auto-unset-contained-dir-R-ref.html -== dir_auto-contained-dir_auto-L.html dir_auto-contained-dir_auto-L-ref.html -== dir_auto-contained-dir_auto-R.html dir_auto-contained-dir_auto-R-ref.html -== dir_auto-contained-L.html dir_auto-contained-L-ref.html -== dir_auto-contained-R.html dir_auto-contained-R-ref.html -== dir_auto-contained-script-L.html dir_auto-contained-script-L-ref.html -== dir_auto-contained-script-R.html dir_auto-contained-script-R-ref.html -== dir_auto-contained-style-L.html dir_auto-contained-style-L-ref.html -== dir_auto-contained-style-R.html dir_auto-contained-style-R-ref.html -== dir_auto-contained-textarea-L.html dir_auto-contained-textarea-L-ref.html -== dir_auto-contained-textarea-R.html dir_auto-contained-textarea-R-ref.html -== dir_auto-EN-L.html dir_auto-EN-L-ref.html -== dir_auto-EN-R.html dir_auto-EN-R-ref.html -== dir_auto-input-EN-L.html dir_auto-input-EN-L-ref.html -== dir_auto-input-EN-R.html dir_auto-input-EN-R-ref.html -== dir_auto-input-L.html dir_auto-input-L-ref.html -== dir_auto-input-N-EN-L.html dir_auto-input-N-EN-L-ref.html -== dir_auto-input-N-EN-R.html dir_auto-input-N-EN-R-ref.html -== dir_auto-input-N-EN.html dir_auto-input-N-EN-ref.html -== dir_auto-input-N-L.html dir_auto-input-N-L-ref.html -== dir_auto-input-N-R.html dir_auto-input-N-R-ref.html -== dir_auto-input-R.html dir_auto-input-R-ref.html -== dir_auto-input-script-EN-L.html dir_auto-input-script-EN-L-ref.html -== dir_auto-input-script-EN-R.html dir_auto-input-script-EN-R-ref.html -== dir_auto-input-script-L.html dir_auto-input-script-L-ref.html -== dir_auto-input-script-N-EN-L.html dir_auto-input-script-N-EN-L-ref.html -== dir_auto-input-script-N-EN-R.html dir_auto-input-script-N-EN-R-ref.html -== dir_auto-input-script-N-EN.html dir_auto-input-script-N-EN-ref.html -== dir_auto-input-script-N-L.html dir_auto-input-script-N-L-ref.html -== dir_auto-input-script-N-R.html dir_auto-input-script-N-R-ref.html -== dir_auto-input-script-R.html dir_auto-input-script-R-ref.html -== dir_auto-isolate.html dir_auto-isolate-ref.html -== dir_auto-L.html dir_auto-L-ref.html -== dir_auto-N-EN-L.html dir_auto-N-EN-L-ref.html -== dir_auto-N-EN-R.html dir_auto-N-EN-R-ref.html -== dir_auto-N-EN.html dir_auto-N-EN-ref.html -== dir_auto-N-L.html dir_auto-N-L-ref.html -== dir_auto-N-R.html dir_auto-N-R-ref.html -== dir_auto-pre-mixed.html dir_auto-pre-mixed-ref.html -== dir_auto-pre-N-between-Rs.html dir_auto-pre-N-between-Rs-ref.html -== dir_auto-pre-N-EN.html dir_auto-pre-N-EN-ref.html -== dir_auto-R.html dir_auto-R-ref.html -== dir_auto-textarea-mixed.html dir_auto-textarea-mixed-ref.html -== dir_auto-textarea-N-between-Rs.html dir_auto-textarea-N-between-Rs-ref.html -== dir_auto-textarea-N-EN.html dir_auto-textarea-N-EN-ref.html -== dir_auto-textarea-script-mixed.html dir_auto-textarea-script-mixed-ref.html -== dir_auto-textarea-script-N-between-Rs.html dir_auto-textarea-script-N-between-Rs-ref.html -== dir_auto-textarea-script-N-EN.html dir_auto-textarea-script-N-EN-ref.html -== dynamicDirAuto-setLTR-Auto1.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-Auto2.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-Auto3.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-Auto4.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-Auto5.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-Auto6.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-LTR1.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-LTR2.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-LTR3.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-LTR4.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-LTR5.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-LTR6.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-LTR7.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-LTR8.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-RTL1.html dynamicDirAuto-refLTR-RTL.html -== dynamicDirAuto-setLTR-RTL2.html dynamicDirAuto-refLTR-RTL.html -== dynamicDirAuto-setLTR-RTL3.html dynamicDirAuto-refLTR-RTL.html -== dynamicDirAuto-setLTR-RTL4.html dynamicDirAuto-refLTR-RTL.html -== dynamicDirAuto-setLTR-RTL5.html dynamicDirAuto-refLTR-RTL.html -== dynamicDirAuto-setLTR-RTL6.html dynamicDirAuto-refLTR-RTL.html -== dynamicDirAuto-setLTR-RTL7.html dynamicDirAuto-refLTR-RTL.html -== dynamicDirAuto-setLTR-RTL8.html dynamicDirAuto-refLTR-RTL.html -== dynamicDirAuto-setLTR-NoDir1.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-NoDir2.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-NoDir3.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-NoDir4.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-NoDir5.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-NoDir6.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-NoDir7.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-NoDir8.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-InvalidDir1.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-InvalidDir2.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-InvalidDir3.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-InvalidDir4.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-InvalidDir5.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-InvalidDir6.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-InvalidDir7.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setLTR-InvalidDir7.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-setRTL-Auto1.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-setRTL-Auto2.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-setRTL-Auto3.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-setRTL-Auto4.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-setRTL-Auto5.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-setRTL-Auto6.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-setRTL-LTR1.html dynamicDirAuto-refRTL-LTR.html -== dynamicDirAuto-setRTL-LTR2.html dynamicDirAuto-refRTL-LTR.html -== dynamicDirAuto-setRTL-LTR3.html dynamicDirAuto-refRTL-LTR.html -== dynamicDirAuto-setRTL-LTR4.html dynamicDirAuto-refRTL-LTR.html -== dynamicDirAuto-setRTL-LTR5.html dynamicDirAuto-refRTL-LTR.html -== dynamicDirAuto-setRTL-LTR6.html dynamicDirAuto-refRTL-LTR.html -== dynamicDirAuto-setRTL-LTR7.html dynamicDirAuto-refRTL-LTR.html -== dynamicDirAuto-setRTL-LTR8.html dynamicDirAuto-refRTL-LTR.html -== dynamicDirAuto-setRTL-RTL1.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-setRTL-RTL2.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-setRTL-RTL3.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-setRTL-RTL4.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-setRTL-RTL5.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-setRTL-RTL6.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-setRTL-RTL7.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-setRTL-RTL8.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-setRTL-NoDir1.html dynamicDirAuto-refRTL-NoDir.html -== dynamicDirAuto-setRTL-NoDir2.html dynamicDirAuto-refRTL-NoDir.html -== dynamicDirAuto-setRTL-NoDir3.html dynamicDirAuto-refRTL-NoDir.html -== dynamicDirAuto-setRTL-NoDir4.html dynamicDirAuto-refRTL-NoDir.html -== dynamicDirAuto-setRTL-NoDir5.html dynamicDirAuto-refRTL-NoDir.html -== dynamicDirAuto-setRTL-NoDir6.html dynamicDirAuto-refRTL-NoDir.html -== dynamicDirAuto-setRTL-NoDir7.html dynamicDirAuto-refRTL-NoDir.html -== dynamicDirAuto-setRTL-NoDir8.html dynamicDirAuto-refRTL-NoDir.html -== dynamicDirAuto-setRTL-InvalidDir1.html dynamicDirAuto-refRTL-NoDir.html -== dynamicDirAuto-setRTL-InvalidDir2.html dynamicDirAuto-refRTL-NoDir.html -== dynamicDirAuto-setRTL-InvalidDir3.html dynamicDirAuto-refRTL-NoDir.html -== dynamicDirAuto-setRTL-InvalidDir4.html dynamicDirAuto-refRTL-NoDir.html -== dynamicDirAuto-setRTL-InvalidDir5.html dynamicDirAuto-refRTL-NoDir.html -== dynamicDirAuto-setRTL-InvalidDir6.html dynamicDirAuto-refRTL-NoDir.html -== dynamicDirAuto-setRTL-InvalidDir7.html dynamicDirAuto-refRTL-NoDir.html -== dynamicDirAuto-setRTL-InvalidDir8.html dynamicDirAuto-refRTL-NoDir.html -== dynamicDirAuto-addLTR-Auto.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-addRTL-Auto.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-ChangeText-LTR1.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-ChangeText-LTR2.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-ChangeText-LTR3.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-ChangeText-LTR4.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-ChangeText-LTR5.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-ChangeText-LTR6.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-ChangeText-LTR7.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-ChangeText-LTR8.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-ChangeText-LTR9.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-ChangeText-LTR10.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-ChangeText-RTL1.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-ChangeText-RTL2.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-ChangeText-RTL3.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-ChangeText-RTL4.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-ChangeText-RTL5.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-ChangeText-RTL6.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-ChangeText-RTL7.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-ChangeText-RTL8.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-ChangeText-RTL9.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-ChangeText-RTL10.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-DeleteText-LTR1.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-DeleteText-LTR2.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-DeleteText-LTR3.html dynamicDirAuto-refLTR-LTR.html -== dynamicDirAuto-DeleteText-RTL1.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-DeleteText-RTL2.html dynamicDirAuto-refRTL-RTL.html -== dynamicDirAuto-DeleteText-RTL3.html dynamicDirAuto-refRTL-RTL.html diff --git a/layout/reftests/bidi/dirAuto/setDir.js b/layout/reftests/bidi/dirAuto/setDir.js deleted file mode 100644 index 19a9fb66953b..000000000000 --- a/layout/reftests/bidi/dirAuto/setDir.js +++ /dev/null @@ -1,199 +0,0 @@ -function setAllDir(value) -{ - for (var i = 0; ; ++i) { - try { - theElement = document.getElementById("set" + i); - theElement.dir = value; - } catch(e) { - break; - } - } -} - -function setAllDirAttribute(value) -{ - for (var i = 0; ; ++i) { - try { - theElement = document.getElementById("set" + i); - theElement.setAttribute("dir", value); - } catch(e) { - break; - } - } -} - -function removeAllDirAttribute() -{ - for (var i = 0; ; ++i) { - try { - theElement = document.getElementById("set" + i); - theElement.removeAttribute("dir"); - } catch(e) { - break; - } - } -} - -function addOneElement(innerHTML) -{ - var container = document.getElementById("container"); - var elem = document.createElement("div"); - elem.innerHTML = innerHTML; - container.appendChild(elem); -} - -function addLTRAutoElements() -{ - addOneElement(''); - addOneElement('ABC אבג'); - addOneElement(''); - addOneElement(''); - addOneElement('ABC אבג'); -} - -function addRTLAutoElements() -{ - addOneElement(''); - addOneElement('אבג ABC'); - addOneElement(''); - addOneElement(''); - addOneElement('אבג ABC'); -} - -function setAllTextValuesTo(newText) -{ - for (var i = 0; ; ++i) { - theElement = document.getElementById("set" + i); - if (!theElement) { - break; - } - if (theElement.tagName == "INPUT" || - theElement.tagName == "TEXTAREA") { - theElement.value = newText; - } else { - theElement.firstChild.textContent = newText; - } - } -} - -function setAllTextDefaultValuesTo(newText) -{ - for (var i = 0; ; ++i) { - theElement = document.getElementById("set" + i); - if (!theElement) { - break; - } - if (theElement.tagName == "INPUT" || - theElement.tagName == "TEXTAREA") { - theElement.defaultValue = newText; - } else { - theElement.firstChild.textContent = newText; - } - } -} - -function setAllTextChildrenTo(newText) -{ - for (var i = 0; ; ++i) { - theElement = document.getElementById("set" + i); - if (!theElement) { - break; - } - if (theElement.tagName == "INPUT") { - theElement.value = newText; - } else { - theElement.firstChild.textContent = newText; - } - } -} - -function appendTextFromArray(textArray) -{ - for (var i = 0; ; ++i) { - theElement = document.getElementById("set" + i); - if (!theElement) { - break; - } - for (var j = 0; j < textArray.length; ++j) { - if (theElement.tagName == "INPUT") { - theElement.value += textArray[j]; - } else { - var textNode = document.createTextNode(textArray[j]); - theElement.appendChild(textNode); - } - } - } -} - -function appendSpansFromArray(textArray) -{ - for (var i = 0; ; ++i) { - theElement = document.getElementById("set" + i); - if (!theElement) { - break; - } - for (var j = 0; j < textArray.length; ++j) { - // fake the result for elements that can't have markup content - if (theElement.tagName == "INPUT") { - theElement.value += textArray[j]; - } else if (theElement.tagName == "TEXTAREA") { - theElement.innerHTML += textArray[j]; - } else { - var span = document.createElement("span"); - span.innerHTML = textArray[j]; - theElement.appendChild(span); - } - } - } -} - -function prependTextFromArray(textArray) -{ - for (var i = 0; ; ++i) { - theElement = document.getElementById("set" + i); - if (!theElement) { - break; - } - for (var j = 0; j < textArray.length; ++j) { - if (theElement.tagName == "INPUT") { - theElement.value = textArray[j] + theElement.value; - } else { - var textNode = document.createTextNode(textArray[j]); - theElement.insertBefore(textNode, theElement.firstChild); - } - } - } -} - -function prependSpansFromArray(textArray) -{ - for (var i = 0; ; ++i) { - theElement = document.getElementById("set" + i); - if (!theElement) { - break; - } - for (var j = 0; j < textArray.length; ++j) { - // fake the result for elements that can't have markup content - if (theElement.tagName == "INPUT") { - theElement.value = textArray[j] + theElement.value; - } else if (theElement.tagName == "TEXTAREA") { - theElement.innerHTML = textArray[j] + theElement.innerHTML; - } else { - var span = document.createElement("span"); - span.innerHTML = textArray[j]; - theElement.insertBefore(span, theElement.firstChild); - } - } - } -} - -function removeElements() -{ - for (var i = 0; ; ++i) { - theElement = document.getElementById("set" + i); - if (!theElement) { - break; - } - theElement.parentNode.removeChild(theElement); - } -} diff --git a/layout/reftests/bidi/reftest.list b/layout/reftests/bidi/reftest.list index bf2191c7dd46..f0347219da9a 100644 --- a/layout/reftests/bidi/reftest.list +++ b/layout/reftests/bidi/reftest.list @@ -1,4 +1,3 @@ -include dirAuto/reftest.list == bdi-element.html bdi-element-ref.html == bidi-000.html bidi-000-ref.html == bidi-001.html bidi-001-ref.html diff --git a/layout/style/html.css b/layout/style/html.css index a988d6896b59..42bd05def8a3 100644 --- a/layout/style/html.css +++ b/layout/style/html.css @@ -16,9 +16,6 @@ unicode-bidi: embed; } -bdi:-moz-dir(ltr), [dir="auto"]:-moz-dir(ltr) { direction: ltr; } -bdi:-moz-dir(rtl), [dir="auto"]:-moz-dir(rtl) { direction: rtl; } - /* To ensure http://www.w3.org/TR/REC-html40/struct/dirlang.html#style-bidi: * * "When a block element that does not have a dir attribute is transformed to From 14e4031ee36d3954b7411704e1259c28033a6769 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 20 Nov 2012 11:29:42 -0600 Subject: [PATCH 29/75] Bug 795104 - Don't abort compression, which isn't happening. r=jorendorff --- js/src/frontend/Parser.cpp | 2 +- js/src/jsapi-tests/Makefile.in | 1 + js/src/jsapi-tests/testSourcePolicy.cpp | 23 +++++++++++++++++++++++ js/src/jsscript.cpp | 5 +++-- js/src/jsscript.h | 1 + 5 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 js/src/jsapi-tests/testSourcePolicy.cpp diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index d237bda5c6c4..83c989a28548 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -6464,7 +6464,7 @@ Parser::atomNode(ParseNodeKind kind, JSOp op) // them, so we don't wait for a long time for compression to finish at the // end of compilation. const size_t HUGE_STRING = 50000; - if (sct && kind == PNK_STRING && node->pn_atom->length() >= HUGE_STRING) + if (sct && sct->active() && kind == PNK_STRING && node->pn_atom->length() >= HUGE_STRING) sct->abort(); return node; diff --git a/js/src/jsapi-tests/Makefile.in b/js/src/jsapi-tests/Makefile.in index dc61e359855c..51f3260f2be0 100644 --- a/js/src/jsapi-tests/Makefile.in +++ b/js/src/jsapi-tests/Makefile.in @@ -57,6 +57,7 @@ CPPSRCS = \ testScriptInfo.cpp \ testScriptObject.cpp \ testSetProperty.cpp \ + testSourcePolicy.cpp \ testStringBuffer.cpp \ testTrap.cpp \ testTypedArrays.cpp \ diff --git a/js/src/jsapi-tests/testSourcePolicy.cpp b/js/src/jsapi-tests/testSourcePolicy.cpp new file mode 100644 index 000000000000..f18ccf2f0ebb --- /dev/null +++ b/js/src/jsapi-tests/testSourcePolicy.cpp @@ -0,0 +1,23 @@ +/* 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 "tests.h" + +BEGIN_TEST(testBug795104) +{ + JS::CompileOptions opts(cx); + opts.setSourcePolicy(JS::CompileOptions::NO_SOURCE); + const size_t strLen = 60002; + char *s = static_cast(JS_malloc(cx, strLen)); + CHECK(s); + s[0] = '"'; + memset(s + 1, 'x', strLen - 2); + s[strLen - 1] = '"'; + CHECK(JS::Evaluate(cx, global, opts, s, strLen, NULL)); + CHECK(JS::CompileFunction(cx, global, opts, "f", 0, NULL, s, strLen)); + JS_free(cx, s); + + return true; +} +END_TEST(testBug795104) diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index da92950c690d..37e2839a9845 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -1256,9 +1256,9 @@ SourceCompressionToken::complete() { JS_ASSERT_IF(!ss, !chars); #ifdef JS_THREADSAFE - if (ss) { + if (active()) { cx->runtime->sourceCompressorThread.waitOnCompression(this); - JS_ASSERT(!ss); + JS_ASSERT(!active()); } if (oom) { JS_ReportOutOfMemory(cx); @@ -1271,6 +1271,7 @@ SourceCompressionToken::complete() void SourceCompressionToken::abort() { + JS_ASSERT(active()); #ifdef JS_THREADSAFE cx->runtime->sourceCompressorThread.abort(this); #endif diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 66c2d2ee8189..77596c963088 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -1202,6 +1202,7 @@ struct SourceCompressionToken bool complete(); void abort(); + bool active() const { return !!ss; } }; extern void From 645c634f599873bccc2115f99d450261e4a94ebe Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 20 Nov 2012 11:29:53 -0600 Subject: [PATCH 30/75] Bug 795104 - Load source if needed in JS_DecompileScript. r=jorendorff --- js/src/jsapi.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 6c77b904fdde..74e8a3bd442d 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -5478,16 +5478,20 @@ JS_CompileFunction(JSContext *cx, JSObject *objArg, const char *name, } JS_PUBLIC_API(JSString *) -JS_DecompileScript(JSContext *cx, JSScript *script, const char *name, unsigned indent) +JS_DecompileScript(JSContext *cx, JSScript *scriptArg, const char *name, unsigned indent) { JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment); AssertHeapIsIdle(cx); CHECK_REQUEST(cx); + RootedScript script(cx, scriptArg); RootedFunction fun(cx, script->function()); if (fun) return JS_DecompileFunction(cx, fun, indent); - return script->sourceData(cx); + bool haveSource = script->scriptSource()->hasSourceData(); + if (!haveSource && !JSScript::loadSource(cx, script, &haveSource)) + return NULL; + return haveSource ? script->sourceData(cx) : js_NewStringCopyZ(cx, "[no source]"); } JS_PUBLIC_API(JSString *) From 2726941d9107623bbd8be3a2d311a3059a7d8d82 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 20 Nov 2012 11:30:03 -0600 Subject: [PATCH 31/75] Bug 795104 - Sources with a custom charset can't be lazily loaded. r=bz --- js/xpconnect/loader/mozJSSubScriptLoader.cpp | 6 ++++-- js/xpconnect/tests/chrome/Makefile.in | 1 + js/xpconnect/tests/chrome/test_chrometoSource.xul | 6 ++++++ js/xpconnect/tests/chrome/utf8_subscript.js | 3 +++ 4 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 js/xpconnect/tests/chrome/utf8_subscript.js diff --git a/js/xpconnect/loader/mozJSSubScriptLoader.cpp b/js/xpconnect/loader/mozJSSubScriptLoader.cpp index c56b2823f81e..999302a41f0c 100644 --- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp +++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp @@ -119,8 +119,7 @@ mozJSSubScriptLoader::ReadScript(nsIURI *uri, JSContext *cx, JSObject *target_ob JS::CompileOptions options(cx); options.setPrincipals(nsJSPrincipals::get(principal)) - .setFileAndLine(uriStr, 1) - .setSourcePolicy(JS::CompileOptions::LAZY_SOURCE); + .setFileAndLine(uriStr, 1); js::RootedObject target_obj_root(cx, target_obj); if (!charset.IsVoid()) { nsString script; @@ -134,6 +133,9 @@ mozJSSubScriptLoader::ReadScript(nsIURI *uri, JSContext *cx, JSObject *target_ob *scriptp = JS::Compile(cx, target_obj_root, options, reinterpret_cast(script.get()), script.Length()); } else { + // We only use LAZY_SOURCE when no special encoding is specified because + // the lazy source loader doesn't know the encoding. + options.setSourcePolicy(JS::CompileOptions::LAZY_SOURCE); *scriptp = JS::Compile(cx, target_obj_root, options, buf.get(), len); } diff --git a/js/xpconnect/tests/chrome/Makefile.in b/js/xpconnect/tests/chrome/Makefile.in index 026fbfa8bd3f..96f87ae555e1 100644 --- a/js/xpconnect/tests/chrome/Makefile.in +++ b/js/xpconnect/tests/chrome/Makefile.in @@ -50,6 +50,7 @@ MOCHITEST_CHROME_FILES = \ test_chrometoSource.xul \ outoflinexulscript.js \ subscript.js \ + utf8_subscript.js \ test_cows.xul \ test_documentdomain.xul \ test_doublewrappedcompartments.xul \ diff --git a/js/xpconnect/tests/chrome/test_chrometoSource.xul b/js/xpconnect/tests/chrome/test_chrometoSource.xul index 305d006e2534..9a1be4bae265 100644 --- a/js/xpconnect/tests/chrome/test_chrometoSource.xul +++ b/js/xpconnect/tests/chrome/test_chrometoSource.xul @@ -42,9 +42,15 @@ isnot(src.indexOf("return"), -1, "subscript should have source"); var base = /.*\//.exec(window.location.href)[0]; var reg = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry); var resolvedBase = reg.convertChromeURL(NetUtil.newURI(base)).spec; + ns = {}; Services.scriptloader.loadSubScript(resolvedBase + "subscript.js", ns); src = ns.NetUtil.asyncFetch.toSource(); isnot(src.indexOf("return"), -1, "subscript of a subscript should have source"); + +ns = {}; +Services.scriptloader.loadSubScript(resolvedBase + "utf8_subscript.js", ns, "UTF-8"); +src = ns.f.toSource(); +isnot(src.indexOf("return 42;"), -1, "encoded subscript should have correct source"); ]]> diff --git a/js/xpconnect/tests/chrome/utf8_subscript.js b/js/xpconnect/tests/chrome/utf8_subscript.js new file mode 100644 index 000000000000..b9ec4e6a6c0e --- /dev/null +++ b/js/xpconnect/tests/chrome/utf8_subscript.js @@ -0,0 +1,3 @@ +// -*- coding: utf-8 -*- +var str = "𝔘𝔫𝔦𝔠𝔬𝔡𝔢"; +function f() { return 42; } From 81a4b4ea9b2dc35c776dc6f14a4c924a84468dae Mon Sep 17 00:00:00 2001 From: Geoff Brown Date: Tue, 20 Nov 2012 10:41:03 -0700 Subject: [PATCH 32/75] Bug 764901 - Disable part of testPasswordEncrypt to resolve intermittent orange; r=wesj --- mobile/android/base/tests/testPasswordEncrypt.java.in | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mobile/android/base/tests/testPasswordEncrypt.java.in b/mobile/android/base/tests/testPasswordEncrypt.java.in index c9102ef22c39..1b7036d7be76 100644 --- a/mobile/android/base/tests/testPasswordEncrypt.java.in +++ b/mobile/android/base/tests/testPasswordEncrypt.java.in @@ -92,10 +92,12 @@ public class testPasswordEncrypt extends BaseTest { toggleMasterPassword("password"); try { uri = cr.insert(passwordUri, cvs); - mAsserter.is(uri, null, "Storing a password while MP was set should fail"); + // TODO: restore this assertion -- see bug 764901 + // mAsserter.is(uri, null, "Storing a password while MP was set should fail"); Cursor c = cr.query(passwordUri, null, null, null, null); - mAsserter.is(c, null, "Querying passwords while MP was set should fail"); + // TODO: restore this assertion -- see bug 764901 + // mAsserter.is(c, null, "Querying passwords while MP was set should fail"); } catch (Exception ex) { // Password provider currently can not throw across process // so we should not catch this exception here From abc33a43d4f66186bace8b522faabaad2b2a9f1c Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Tue, 20 Nov 2012 12:51:39 -0500 Subject: [PATCH 33/75] Bug 813616 - Ensure the reflow-on-zoom pref change is picked up even while the content document is not visible. r=jwir3 --- mobile/android/chrome/content/browser.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index d23766d7c78d..db749fda323e 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -3721,6 +3721,11 @@ var BrowserEventHandler = { } }); return; + } else if (aTopic == "nsPref:changed") { + if (aData == "browser.zoom.reflowOnZoom") { + this.updateReflozPref(); + } + return; } // the remaining events are all dependent on the browser content document being the @@ -3800,10 +3805,6 @@ var BrowserEventHandler = { this.onPinch(aData); } else if (aTopic == "MozMagnifyGesture") { this.onPinchFinish(aData, this._mLastPinchPoint.x, this._mLastPinchPoint.y); - } else if (aTopic == "nsPref:changed") { - if (aData == "browser.zoom.reflowOnZoom") { - this.updateReflozPref(); - } } }, From bc72f9ee9e4debf817dd5e35ea76d020a2532230 Mon Sep 17 00:00:00 2001 From: Mounir Lamouri Date: Tue, 20 Nov 2012 18:21:39 +0000 Subject: [PATCH 34/75] Bug 810796 - Fix invalid CSS in forms.css. r=bz --- layout/style/forms.css | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/layout/style/forms.css b/layout/style/forms.css index d90dc1bef441..d5bc6462b1b4 100644 --- a/layout/style/forms.css +++ b/layout/style/forms.css @@ -81,13 +81,11 @@ input::-moz-placeholder { cmd_switchTextDirection (which applies a dir attribute to the input box's anonymous div. */ @-moz-document url-prefix(chrome://) { - input.uri-element-right-align:-moz-locale-dir(rtl) > .anonymous-div, - input.uri-element-right-align:-moz-locale-dir(rtl)::-moz-placeholder { + input.uri-element-right-align:-moz-locale-dir(rtl) > .anonymous-div { text-align: right !important; } - input.uri-element-right-align:-moz-locale-dir(rtl) > .anonymous-div[dir=ltr], - input.uri-element-right-align:-moz-locale-dir(rtl)::-moz-placeholder[dir=ltr] { + input.uri-element-right-align:-moz-locale-dir(rtl) > .anonymous-div[dir=ltr] { text-align: left !important; } } From 89a7b7987c0d5f610e3f693de430e5f1577195fd Mon Sep 17 00:00:00 2001 From: Ralph Giles Date: Mon, 19 Nov 2012 15:13:43 -0800 Subject: [PATCH 35/75] [PATCH] Bug 812847 - Test Opus channel count validation - r=kinetik From 49f5e33d79df3713bc510e611a5064858bf24e4a Mon Sep 17 00:00:00 2001 These files have specially crafted headers which should be rejected by the new checks added to resolve this bug. If any audio output is produced then this bug has re-occured. The audio data is the phrase "invalid file", in one or six channels, to make this more obvious. The new mochitest test_invalid_reject.html tries to load and play each of the new invalid files and verifies that an error event is triggered. Since the invalid data is in the file headers, this should happen after network load but before metadata is ready, so the test also asserts errors if loadedmetadata or a number of subsequent events are triggered. The test will time out if no error event is fired at all. Thanks to Matthew Gregan for assistance writing the mochitest. --- content/media/test/Makefile.in | 11 ++++++ content/media/test/invalid-cmap-s0c0.opus | Bin 0 -> 6835 bytes content/media/test/invalid-cmap-s0c2.opus | Bin 0 -> 6834 bytes content/media/test/invalid-cmap-s1c2.opus | Bin 0 -> 6848 bytes content/media/test/invalid-cmap-short.opus | Bin 0 -> 6854 bytes content/media/test/invalid-m0c0.opus | Bin 0 -> 2471 bytes content/media/test/invalid-m0c3.opus | Bin 0 -> 2471 bytes content/media/test/invalid-m1c0.opus | Bin 0 -> 6836 bytes content/media/test/invalid-m1c9.opus | Bin 0 -> 6836 bytes content/media/test/invalid-m2c0.opus | Bin 0 -> 2471 bytes content/media/test/invalid-m2c1.opus | Bin 0 -> 2455 bytes content/media/test/manifest.js | 14 ++++++++ content/media/test/test_invalid_reject.html | 52 ++++++++++++++++++++++++++++ 13 files changed, 77 insertions(+) create mode 100644 content/media/test/invalid-cmap-s0c0.opus create mode 100644 content/media/test/invalid-cmap-s0c2.opus create mode 100644 content/media/test/invalid-cmap-s1c2.opus create mode 100644 content/media/test/invalid-cmap-short.opus create mode 100644 content/media/test/invalid-m0c0.opus create mode 100644 content/media/test/invalid-m0c3.opus create mode 100644 content/media/test/invalid-m1c0.opus create mode 100644 content/media/test/invalid-m1c9.opus create mode 100644 content/media/test/invalid-m2c0.opus create mode 100644 content/media/test/invalid-m2c1.opus create mode 100644 content/media/test/test_invalid_reject.html --- content/media/test/Makefile.in | 11 +++++ content/media/test/invalid-cmap-s0c0.opus | Bin 0 -> 6835 bytes content/media/test/invalid-cmap-s0c2.opus | Bin 0 -> 6834 bytes content/media/test/invalid-cmap-s1c2.opus | Bin 0 -> 6848 bytes content/media/test/invalid-cmap-short.opus | Bin 0 -> 6854 bytes content/media/test/invalid-m0c0.opus | Bin 0 -> 2471 bytes content/media/test/invalid-m0c3.opus | Bin 0 -> 2471 bytes content/media/test/invalid-m1c0.opus | Bin 0 -> 6836 bytes content/media/test/invalid-m1c9.opus | Bin 0 -> 6836 bytes content/media/test/invalid-m2c0.opus | Bin 0 -> 2471 bytes content/media/test/invalid-m2c1.opus | Bin 0 -> 2455 bytes content/media/test/manifest.js | 14 ++++++ content/media/test/test_invalid_reject.html | 52 ++++++++++++++++++++ 13 files changed, 77 insertions(+) create mode 100644 content/media/test/invalid-cmap-s0c0.opus create mode 100644 content/media/test/invalid-cmap-s0c2.opus create mode 100644 content/media/test/invalid-cmap-s1c2.opus create mode 100644 content/media/test/invalid-cmap-short.opus create mode 100644 content/media/test/invalid-m0c0.opus create mode 100644 content/media/test/invalid-m0c3.opus create mode 100644 content/media/test/invalid-m1c0.opus create mode 100644 content/media/test/invalid-m1c9.opus create mode 100644 content/media/test/invalid-m2c0.opus create mode 100644 content/media/test/invalid-m2c1.opus create mode 100644 content/media/test/test_invalid_reject.html diff --git a/content/media/test/Makefile.in b/content/media/test/Makefile.in index 1cc056bd982b..ac6ad6986ef6 100644 --- a/content/media/test/Makefile.in +++ b/content/media/test/Makefile.in @@ -81,6 +81,7 @@ MOCHITEST_FILES = \ test_delay_load.html \ test_error_on_404.html \ test_info_leak.html \ + test_invalid_reject.html \ test_load.html \ test_load_candidates.html \ test_load_same_resource.html \ @@ -246,6 +247,16 @@ MOCHITEST_FILES += \ # Other files MOCHITEST_FILES += \ bogus.duh \ + invalid-m0c0.opus \ + invalid-m0c3.opus \ + invalid-m1c0.opus \ + invalid-m1c9.opus \ + invalid-m2c0.opus \ + invalid-m2c1.opus \ + invalid-cmap-short.opus \ + invalid-cmap-s0c0.opus \ + invalid-cmap-s0c2.opus \ + invalid-cmap-s1c2.opus \ $(NULL) # These tests contain backend-specific tests. Try to write backend diff --git a/content/media/test/invalid-cmap-s0c0.opus b/content/media/test/invalid-cmap-s0c0.opus new file mode 100644 index 0000000000000000000000000000000000000000..0b9958786590c6ce854a137248fea2ab00864c52 GIT binary patch literal 6835 zcmX|G1yohR*1q()ba!038>Bltbg8s-H(a_d-60{;&80y)1r$W3QxK#&)IWdwsLNGc$W;Z9OL^BM3U=f8~7fMex7o=`GPR8l9fEzaQveV~>U{iH7L^ zr$<9oOf+;1EWLkb|6l%@{p)%X+aZkh`=8k(8z(;kl*Zk~)(a)Vgaw2Igt1TxVN_Mq zRnb#bGnD(+x9e?$BPZG#0x1%w3EP-bu!xVwX#hG&3{yNf-{8RfQvFU;4$)xi$# z;^hg0JNUt2{4ft2Z*Lb*Cm7tu*4+UX=mK|!g*f85H5`<>TmJZ)It2 zVhX|_ZKU`XpJTEiWG@Z5BTL>d3zY}!)yw-|;}c9We&kjH@$e2FmvB9;)T%t%0-*R- zb}+2|9;nMD{>v4lOWe`xNAh2oVGLa zvl$I*A0H$KcHVKYtWh$qV1<4c)eFLVafT5A5OH~^-gnGwGm49vg@8JEK#Zp>Qk?*M z^*~tOjt@GxU5EfV6H417i@n#|G<%R(HQbI)mDV)hDOqJUlQ5lqvnVFKgUy}LzAPw$ z9Pz!^r=iToNp$KAZv2}P ziIx@UHg*q>npt1-W9fAXCcRSUk2ptwya`Y4u%ng_pLJ&owQ>k$Sgnke+N6wl;L&tS z|9YV>yZb`WclBW4Ngr1T6d;QVCMEu(W;^2kMK_Tgxh3_Zh#08Piy=pQugw0V$y6LX zKARq{N4seSg{pQl2VbB|c4pDvL(Fs(M5fn5Pn%}wx8vDjCR_#d>7GrA`Je7B4IU}` zcY5X4H-nsrmz8niXOHH6*i&8FXq!k~-+DfWs6F8`V(@ervK%+?bIti0g3$_)#&VvH zzqf|$dBUBeDC}e~qgMc=zL;9~E;g~JFIG9lBQxaOM_sJ#r;ofkHW8pmWrnN16=B`B z5#kv4SjCB^K7FfMR{-AOVXQRp%2-Cy|FqXb;o?D%shWUpw9jY~3jhjKlQ;c1vexIj z7n=B-oYJ}oalNH#ihL#H96L}DWsKj>2el6x8hMS^)+RucIt!3>zQl?9Ol1t{`@FZp zV4Fzz=tT+C==|+Xp)F1mc-VP28{TdSR~9uXI(PmA14T;n-dQaxJT3D$p};*DIQmxQ zdFb?Pqn(hQb@9>0oa{V@We#Rh{QBDu`~w@Oi93hw`u`Y37D49cEa;{ql38{ZufxM> z$!r-k=StZV=?Pvc;D-dJ`eB%UM{!&i{7A&83Ltvfqj={kJJUji6dWBZL;y9JmJL6i z&&L^-_7>7l#8EAD60>!hPrdQf2l-3JrpFJ8hN#8e49?j_+B!nzT2=-+tW!fmONfu^ zt8p`|yU4t>YPN=Hm%gJMs9=0^L3vtGImm#)p1Zv;)^3bNbktxw?d=yh_hEBWC&F`5 zx>)12i(XvfePmXRa()>=)fhoobt`w_*;#XywQ@%shP|m3;T#MDkdd+#%WKZH%o-=r zu-DVFw}wsStZZ7o$|j3{gh19Z$Zlfe1`~Il*N8=>vu@jQ=t|WemXO6=0zKvL=lMBK zj}f3?N#CK@QR#rF85iX-xHLUNH`B~qw5{;C=uAi4)x#-5twl5NyTUo1+fX2R*PJy# z)Z9|8V?mW(Nw;$Ur14-1sM^9oydRYfUYi3)Bx!HG&zQaa67Ag+LEh3aQ);HyrUxp0 z&nXL3O_~+Pg^@*y9GiAj<%$}A58dcqz7f}&F>=RNPXPH!N_&e3`${3llKGNQkL@+X z#^a+gAg3ZrT~nr$mkp_dto z`)9!H-fo1ooq?Kj>udPI^=t#kHMkSjm_q5sUd)y8bzX-r<=5+6)965)EkF$8_?Myy z6FFVXnjU-I0BUhj?fb1=d@s2PhlWE@Hf+Ez~CxpvUpi$YN-Q{Z_XLP{DH}Zu(q0M2^acOO-b#76G?N z2!TAdH)_&^^MQO7<9%C^vc*`G-hE5n9C8|SI-N9lePwOY1F?M-ruPOXTPJ@*m9l0R z;Uv#Np3*ct{vM4Hp3uvP4Ep%1tF$rc;`^Ad1n7OzZ8xfI7!o^vypl-V-|Yy1s0K%s zlPv(>lYTp_byTY#DCdjl&ArEapLuQNf(Ioa8ou(kX0rw*Y8GfIh?rjfEhVFtEBWS^ zW)&1D#ur*0TbF@fX_YFhZj4>^`Ub!2-PBF$K$JnUO8Y7iX&C_8IcKOnzU_`Q-ceFwKF_nXwU zGT#~o%6W3v2XcFPzp-U0#){H9O>r+#tAfIfSD9MotE{g!1Cnk^^42@5ZzU$BALNU+ zF<#i7jw774{T?Rcb0ibSO?rQo`KXlK2TD|DxjuMLseQYARmc}^(994MuE>1;i?Lt4 z*UiMj4x_NEo|b;+6hlg0`JGFwYOGOhE)4w)Vgiu&ea=8ra`;w_yDi zIvrb)UpGbChvaQvI?$0mLIBkLcdktk)#d4Q_ELdzF9F=zdMWuxdyg%kBrWi{+tUcA z5Wn)2uY`mzW`hu*KudE%ze|dZP09g=@fm%6(vF(nr53!f=7=`a88-{JXMyIAKVnlS-)%_`K z+&*?@7$6_OZO<8SE{d0Y!?w3^a99s8q~anq*t3@~~{fTI8GPZgJn z&-DmqIC_{XsjSJVhG{rZ1ONwv2mP zTV+5|D(weC1q%PAPZHGSE4SqzdC{fX$kc8>-SdIm$SqJ7n)i-CKN(ZAJ}bG*M#K(} zOpEBP@Fl>7G<2zAt>zkRTNv9-1_c{T-VeGNW&1aUJqS%ymkM<v->nY)!mjh@_=|Q)z5w7H`^-6 zRsVB38KK0EhjXm8ZpcPt_47nMrq@}w%&t+BWF(7(@~r>MY3q^RFhJIIl%!%CW?LQh zzF7X#7PNT(Yzrv-QLuZq8J~r$!zdFt>CdRz$@+t`Pp36Bf*HcY2k^J!yV zE`N?|tU^SFH${;&NSxCjrq+M}Y1h7%s?+VK%ct6<^6*0y8LtVTF!#K4R)$;Qs|op3 zt9z>sl{LyQvO%Q-Kfk$27weDY$M(>evOOID`%)DiW*oojKQXK!WStze?F$2WYMv{< z3CnLTw2D`D3N@MBq2>u=jMtqSPSQ$|lzt#zliHD-cpR(~!GyXr^mw?TaV=+6b0R#s z?n&f(xZ?}ccxar2Z_Grsq~`uEB>}12)g;JU)^EFFLH5!_{btwmxQ~{sKIbCS?;ic) z2R0IA{e=0a=j~QyDSrPP%L{l15Z9ugSo6sSg>h0Pb>L&5c>|b^8P>}9Y8^f85rZ&7 z=T1@J_v|ppnUeS2EW71$zSHL*;N*qgE7EuQ>37fzfzbtpJcS&C!k`Qy=C5;#AnSuN zyy(nhGdu&N*Ed0t={%S}biXK0({+UZs6tjalMXSO2oPb5Sa075|Ar@}hHcMCApQ%A zam)SWd-q>0R<0y%kTd#&eex4|cgA~$?#py_@1F&3LP%5aqsy$rtDbhF0G2`P6Ww&y zZy<|AhQ;e;U3Ok>w7O_^N;<7~8UxWU!#dkXe?fy?&&h&0P_a9P(5m>Z|G5_3-f$Zu z*+T%+#%^3E2i}-gEAivkX-mKi$dyj}O@X2kcE;=e*@sM8Am>I_nq!p3H*)=iaA^Du z2RDB2bKj!yiY<^knx`myNvqZD>o(7kp($bG2EMwMSwn%n{cHcQ`L)&)l|^$Ju7IxQ zf4EC}UKfkch;u-XJL)4CfXTx;u9I7B)4f$7_>*?PRUH*_YLqIU9u9&clISl|`4wMb zGk*>{frPZLetB@aQBVoZ$e6kb^;;izh(vAMs!b-fytGaMv^#f}UuqLUw?lK} zhgqpfee|o(#pfT_o!a+)_@2ep+zX)apZQ@(MNVc$%f+(35`79_obMUb8lelM>@Tf$ zkvx@o2MSloryfNMwPXnb>e>3)h^fbfnJYkvYSA0XFQgPsB|X}2$=D_)4(RLB1y`a~ z*~_$)0p{}yI^3#l%9_aib)WX`NDuxMfH)R06V`emfh~3V zw~bo<5CLEe&scNB<&Xp^TChtGa$AFZ^~91*n%-})^;e>QvL4K*)X!{d)`q6BuPbRq z@DJbkQpnPm;qTR*)9r<1f*jF*ZMj5m>q~uJ-ZPAnAl?|(ofht;S4t*n_6Y`a8Aup? zBTGgI0hB!f2jndn8nY=lCXmLT!{k!vb0w^^|Amh)#^_(c&k_m0NCvs<91rCdi`VX( zN@#^C0d^&(*gkrf%d9#p%#Bq@h?e!Q?XnC(7rS;7kRN%IlKsbz>#ElG()4=sx!>nD zIj$op{tsP7wrfc=lU81B$Ldoli7R9JWeNm9)tx?z{r*(-&{1L&ee@6iM}6ZnFFccB z0HeFgpm{LQ$0^NJ{5eDJq9Q0*Ym*CSGVLU{V!doTkC~({BuQ$R`Q2jpsBh@~_cvLA zCRpQE^qoascun#lKVPAiOWlV6E7u?O=opW(4uaEi3^GJL`(iR8pBMr|A8ogzv?~-A zT7v@#>FyBz-?YmB^6u~w$?0;H!nP|pZ=nVKmw~Z~)&Pe8XG*G}w5V&eRr1#p3$-9; zo#K#K`Ie`D4PCCnNED!#zyB7KH#=E6sL5ISqvlCZZeoyA+*f*#r`GC&*(`LsY((21 z(!80SB6WsU3R7=Z9eZ}RkM}oO8<$)`GRuB8Qpg&h?mBJU5f&PF{^gJJhIs3wc+Aa& z>XOtwiU`Ly#ucR@2ZB#t6w-89YBz9d*MiRc&>*-YTk%u{r50XN)L&+|&kN zEgsXK=cA!cq1q7LhmxsMjpkXJU(D#Pd-9}OKAmN^P}u@%9Y<_ZL+pn)X*m$o#_Q(R zrCER`kNgS~PT*OpI4og# z^mgU7&*UkI5yoe(O%?VPM_;UgDFiBXmWEdRQ^XvRMRBZy#hfuQ!t5@L( zZ6g=OkVmYtMUcsT@C zI#cevFs~=&!wWmnB1FeTYYTf=ylCXtGVvCWEw*^IOVz&XPhJRsqC0b%jwZbXyL30& z&?`>4+lVm97XdKNhdupqYPe*wA|H`65<`eOOOTE|Zy6*Bb}}%nq=+!FF2c^EjduIf z;`0|y=y^2H#WUI#+HD{Yn+uJSf$YG?J8{F1E)M_j+k6>e1%m3QT zPU4ctVhvDqk;QjU#MC#y;tFnxff!?*e9eRZKwBrgtCD-e*|Q>m06A)yDwS~XH`_3& zk7V80YOrGL*>ko0U1qLsMxFAR_1q5fm-22AARp3xc;*hxhDDyyB`G@U`%0@j#c=#f zdXbzuEHckxXuP1CQ#U=oPllo`#K4$<#=^sWn)MT=ESC$UBB~b4T)YB}i1zwT4zt zhAcFx5CC19!WWr%+)lq0?H3?dWxHO&FI5h1{^`N{K8vF=`o_g=jp?MjiJQ#DJad;X zXGtC`7;k>VK#uCYvLQR6x33Kc+rG7-_Zr7?4rCo*V?O}4j?8Dz+0uaWM zH-ImV#?!<>Vz3aZy zH^R#T^)QgHGUSFfNZczyp}=l2?-WmrP}A+gYdpxt?A~i%dZg%3r}na!YU^S7;ZylT zfFxERZ%#4r%SNZULcHou>UY$u3KMH??($O_d0nl{$6-{^kH#jn0tq(NnfPpH{BLXf zK5lQHRTsCjnb^&pi{ZF-9+iPCP)Z4^a5!aw6<<(zlT#^YCig%m?nkqK;sjrL=V96`)jdMv9 z7{uwkgxjsA-5)_9W~>M@NhI(sq;FK1Z)SFPSvxoW8aU?9P_;Gai`IZLuS`4uh-IbS z=!v2E;6)@0KY#-l~^@B&1#^fyqBw0`&| z6Fr;I9cn`w_F=6DGn1w~`(zfo1u}|_nwGI#D_vQ*JwWGk;MuiKAkY&?wexKIMyDEq z0AUi6c2Wr@Nk1!KZaG&Af{))I@p-(p6d_E^c`-Hy3J8Eu2AnpUk}NCpdBw$A!U#}A z!3;kBj0lgD*;oV_1a6@7N$XhyWF4cjX{9agi)?5oa~3K%xjXN^D1ru*L56L28g7k9|!3|fFc$?bYJfPUVwaG+ZRU&#A=3zs40Rp zy!wF-JotXhGv8gbZRL0&Yj2lTl&8o;^+9Hl1Un~(U77(uC4Fs=+?Nio9AE5fdwh~3 zRA@PE&{}NJ2M8oS9+@*8oL0~UiO2!~sncVt0TWLWoC)+^ILOHD!l^1J5@+4-OgiMh z{)d0F6nPtzKUt+l(b0ai3DWaZYipQ1G{muAK45&?vM``-Cp8dr6eH~Y!QBkN7rRwT z#UZ^a!W!nNz{^*`8IQAp#(|arz|z z`6H7o_MbEY=ED!D+yScmOCw;Qz7qb29hh3`V$vW1u0#(XDYEiPXfJ@D3xshZycyrG zlgs~@4|$Z9EIZe~&J?uDn;~hpDSNc=sBjp-HEk`qz&2?!;XC38@2c@zsWN2XsmE5bi*- z&DL6<_;B63zdNz^7SkX;G`e<#XGC`eJvML{grcNjii-~&EC4>f7=z(6qw3FYlM-b> XvZ~*}s|a?!-tdc00#Bjd<6Hj+?G;*% literal 0 HcmV?d00001 diff --git a/content/media/test/invalid-cmap-s0c2.opus b/content/media/test/invalid-cmap-s0c2.opus new file mode 100644 index 0000000000000000000000000000000000000000..a921894fee5e43983126478ee5a781fa53e938df GIT binary patch literal 6834 zcmX|G1yoc)_h0%g-5pDJgLJy!qf4cwyJ6{CxeR1%#gE{(odBFZDf(S1!cRv`~RY+1$Tw2gcM#@IgPSTMa9c1H+aPdPZ zczA`lxVzg3dHFh#psn^c2nPi*5m7NgQBgrr8F949-Nnwq)6YS{8G-PY6&AMhb+AFW z1UT4vd3bnv`uz(O{-2AVux+rgxR8jj8afQ&f^c_G(C`efad)wYIis_7@P+w0xH{M& zT)aGC2nRm|Oc3T_$XA*t$Ew0$mW!un-4dFPI+!4ddbWUt0c46$J8+mVeC7 zlCpM+so4f6retRoAQN(;v!CUp=4U2`#Rnt3e0{uwBSRzO5|Q2skwFo@UOtWv_EwhW zCZ-?^(nd~b@i`_NLh-_oH?rj22a)n%y?RCeD?*}4=8wE8AOXStqY|Dcm0FdDn*fy1 zs*cs`h&JpBAcQV7?PyKj5~_k+Ff5O598d92HfC-*@!xM-ZN;v_a}pH#4R?&Flhd|G zel}y^>=A;L!1h}%wpD88Wt`CO;(9>@&rh);01_S#_+7`$7PF+dSqP{@0K|C8qtuCT zSN25}?F68MTZKrFJE62avejl|K<2k!U+07){DF4YDzf-JG2 zC$ZD32WWIgsC8z^Uq7%3G1E7hCeCd=koPoW!8c?$e-}|7B}j{!PD++kyb8|46Eg_Qk#?!4+6SQ z*yN{JnrKOfdUj!!Q`ZW)NDuGzvw1XqBdoI6p;e;c`=k2?^HQ|G?_|* zN2k-n^%&Q!ph(qD=HPQo>CP<1JBXQ%lGyZW=tl@E!5VgkwMogX#Lzd$Pey%xRL$F!_@>uSZ z@psmcT~CB_6qTJEcJwlU(w9){-oYjH^u;NsdT554`>2bv_2i*f#|9DUvd3qb9IhDKfyw6zJ*rOpBroiFg>KGPTj`abWh zus9|XK6+6DH9CKLQ|OD+gdTL>&W5*JB2>jqiq4!r!9cOnyth^#l%AA%98=-%4;+50 z@;q>Qy53IA$-ek-eNKL!%Q6SMD1PnDd%=PAlf>{ z^c1#CnscR`iHt-qln6rtQ~j_^zoR*>3w|hOR0WW{=uy6Pm7i&$K?#qJ6(WI}Ov{EJ z&*tL{OM43$C*o)pI!QS?&8J>_>VtwMW7FgNMMJcbZU$$ZVr?Cv3N6b69oDHKp(Uh; z_0{+p)?E}{S~Z))^h@8-2~;q@KBqn@s2pU%;>_Jz7;87iAvtWYo%Z$%oO{2qp%dXb zDO;@Z%0(|O@h&o}Mm4_-plOUCuDVe;_w1~>%v!!B4a42gif|5w0jNm%iVv&KwX7P) z(Xdz3@;8P}- z`<_u3z)hN!#zj#@%3K?EH08<~e-GRkUc8pnnlW<6RZjo~N=kc+2m4APN7DJyP>-!u z!^We-G1P@RzI9x~*QdCg#SCl%@H;t;negsFfV^d5=U{_WL1Z=}^gc5@9>ca3sL;y{ z#s4#4c4s%j-p)kJz4t@~ZU8;FX!iV;FRxlL_>yf~epilhTCp58=y55MJ<7u@9ER?l_mgFb=yV>R z1@THb3wMgz=>yb_YUeTD(H80x3DBeXXjCyY!+x{d1gPMu>c+TLudWHZ-cDVo4n!Fw+q88-J0JS8gM3AU#J8o|MRZK? zm5dq$hj{-3jUC=8VT!#A+YKF2-Sp%o05+Fx!_$dybSH|hOV?xRX_A1GCw<$CWOwf4=2%R+&0gJ!0faAnrBU(EfI zy>2EJc36d7_4JI}Cs;Cys&8Fl;ju=wxiHLAhzUU1_c;SY#o=2uiVJt31WPLP4IgPD zP_{g8bvUNF`xko(diCd&yjcMW3N|Uff7_+Yhedco{yF6Hw?+03`|U09!h;b_6OGK_ zRhg}tTotmud8r=h>nii0WJ4@NqUi<6jAOT*cd$^9=Xkh@DqHok#<-o&0*XtnrfKB) z(#hDe;+iSSJ|u7J!hwPOArheNzjbYbz&}iGZHHY+>&iGmQ9p_bFSmxpd zI8z|nsqy}3X0PN{d0VNTZeVFb{=i4_^4twX&VpLm&^4vm!_%Ah8-p5L%!uT)tNT;f zxP9!*FhDtg-=0HiHfZNBw+84X35_jGlIQ}(g5$_{?@9!u?2~p!s}v6;k)T8aTw(E5 z$?=bwFXs3yPiX{20+WqPuovA@Y=SRQyFYw7KNw6Et)qlxus z&KSv6tWtS7u(`lEnwzp2TEUIgJhJuoOIHM?CFc_k|vnT3LR43sCm|SW1x=g5(@hNX|y)$LS5i^WG zj<|PgZD{W(GZR?UzEyU)qz~DoF8u8YoDIj8!iHh$UCp!ydvAoeo479 z5j;;H=JdOA6XdCJh}6LJ{`kCRqEaB?F#W4WjPshys@ZWp<64WFuK*)TjMlPFfH3h5?GM!=(GRVYby_ z?}`;aZ9BtWTLRYA`g#nbVrh;x#m zz7?8y5=t9sWfsmuUr?k%j&qfF_8jXa)7{fykgtxwpvRSnxs7uen((M#cinWFJ)b`2 z#fQ&vjaA6V@TMrT2B|Z~gVY)jAn)4Kf;-)Ox_F{ps)#taFXuG@6y~0l&dTvBeKnz+ zYISebp|M8iMKP$d@8>r+>0#+RhLaTUHr%;p0ZCbuC=6Kzy;UujTY1w;Bqbx@fB2DqjGqAoqMg^341~lNOiNhZ>`0Im zC#sv^u{)tCorlJ8`1(v#OKR@#QZkUnT}_IzW$mUb7UV2V)Ngh@i~DHF?sFzK{r2H6 zL0~;m-cM9;dfskDp6d6{vAlq{0BJ4ev9*AFP#8B&QU@UxhBtuim|?9-sMgWb9x(_b zcJ34he$Nhr+$nkA&9YlA<~x1%1CF2Ty(E8|pMDEH7aCnq%2UcQC=ALVVf{L%46@%V zBZ$sCG9xfRd3_TWo6dvzL-&f}G+jpo4=dzFGZ~Phi2w<%nDy4R=x;<)YS`9{6!O2I zSU0?nzjy!DV&_TH2Dzi(+b2I(bZ5R}>b^)<_x@SnCW0~rKf261yzFT=3Sb+wKGscV z{|2&2WmvrWpv%e6i%}QNNzI`3R%0OgMObJ1=r3rn>lsBb7rJ)G5L*@B_CM2N*d1e1FlLjwhh2 z`5*3*p4a)}Q_>vJ+xXa8*Z_oEnwNCkKO|m^9||R6*sJ zxU8SUjv*oKD_`#2tQS;5Gcu;G19?pFNB!2u9U{@wwrYb#EibK82;-h!f4im8XuA}v|MfO@umHgf6_app2m0xx3B>L5COKrmBhBTk~n}j`R>*21sL(GhwagQn)fF zf7@sk50C)X@QgKATn<@~vIVE?Ag?tjP){n|r0M+{SARMBC;R?oIak6y`(OC@VyymU!Yr}y^JI{>&hbEDv3T{a zsf1pX8sJo6iS1)_xyY)s!d_p2glJj++A7NscCl+W0R>UlDcOJgcrI&wFHEmCp80)l zQ{Xv-68_L-=D3o^Flpu2cC0>;k-9Wy{6K{SXu8v9ao?T54;-a7Fh~Cge$+QU^&&7C z2C%xT44Mb?e4NruC7&_nE-Hh^wD-JO1na7 zp*1*=nBf-b|4q9LpzIDWk)AHUU)Xl3;4QMC{~|Cp(Hg+=|4dCYlooY`u|oN3Vxbn~ zu2UY8DBtw-uVKhl8i@k*^7r0g^Jgc^1~oa$e$+hf$xRG$iu=k4^3__sH=BiSm5pfo zLz*|TQ)EtYN@42F@Uf?-djx-zwecyHq_ga2BSowM+OCtvZBdbdXJ7s}uS>R0O2%AI zz?Wq1&_p=CHm)cQ*%yBNypZlSu`5QmXCp6g=#}|A4sRlG@55=elcUX>dBL7`E;7yLSqZ4bsTcY3~?S@r{zG<6R(?B zmu>-?Jn}0b;Os5|24K;DraI!LZmWDs{>tQ585FH=qL8@~BF~pxF?vQ|C*Tn|(e3W>C&S>NUQp-H0lW#o976XZto}Y< zXd9(CmLfWBREYH1&n3isz;nMArEBP?d3KXYyCEaW`xO-8*jw!Q9M9YyqyIS>K#)UZ zr8DKu5A%9lKD@9UEk<%gvbwN~!;e9EB^Pf2+2n{1-A2SozDR(1KJ3Yl6T>BwWyOe`kr-n1T7q)ydBY@4w4H%%B}0OZa~^gUZM4&$ z7O!1x@VT)0V$1CD!k4ck?p0(WAV)pks5!@U+U`zqM-DUH+~Ah}fmUOIc?1X3YW~+= zPBNE7Hfw;Yiz2>zBBs6p7FTdx48$1g&zY;`?=o|FJ?fOts^_+!zm#`_1O-s`!!x%SHf)N_E=kc*-MfU;vqH+LjYSBmUDrq$5m4V{Ba9(wI)Vow&|i%rkfS za+>79hV}Y44CJcbEgP~EdGpF}uS@ee~lMsy>1ZCIE3P zWdr!aXlzRn53ZZE3DBk~9Y3e*=wNTFodsEBoGOv_B9}C$0o_#TpVOl5b|&7>>0R}m zycYc+R1X6MDnqX6gCxBYlnU$?^G*mPh&A2Ly~cxV%wyM2ST&H;Ro5>m)RnG+B=`H zT<--C$@fw&3@(yQhxbx`N1sicmGKRFQeOU*#V4CUqj<+TV8C&CPkiNk084&JZ@deV zz#wktCH!tR?fwWN31elDMJhpHA$`5Vd?T~F%i6i|*T9ir2He)5FIof2x;$|YAeEPO zV0bIS4WzgEcxy^t2g-+WvL>66I36RKj~^hBXS{}TrS&5= zSQt4(ZqXCcun%V~n3X)`=_j+;O^{h))U=H4O6AhR?H;Cp1K*By0+F6js-0)sHwJhF z5`;-f+sP!DB>k*_x#e6g2tRs_BINVdQiiaw=Ec|;C?Nr2IdIx&O1iAf=Oqt&2{S+y z1vB{gGa@`rZhaAC61s-YC#_`-P;`vSrS2zVy?v*rcWKyRPG~DnKGD`zS~k0u-?cVETFo@B@^4+P-)qAWkzPL`@l_ z7o%!yfZL7c!S$*^2zUmZZs6NOlmSE@PutPWCr=qXzk^92orQ`EGZI4e1 z#7ZqE4O)v0`T&vC$3t_L{gVoYATfCWAa{CXHDKaNhBtxPivXE zYkvecN>MjK`IA*@R2}Vy8z7?~t+s~A14BIf5Btn-S{4S>?PLaG4r4^U-@BUugc3I@ zsd(g%k89i zx9^HJNY9&(+#!)q6&9@VuiC!x+V7l93bL}kJ$wHaAd*|R&~M(czYuIKbqQIJ2w$p4fE-nMDY6?N$OFQ-k>1Sj z)+iN!%!fQoOO~JOUtGVIFf3w?kIkkAR2jw?Av8n686 zqy&keIeszRIJ2Tn62`qqkczz>f|{Rb*@DU|Q4c?5;1$WHw;=_H2;l*B`$qw!6A0Yd zWgvdfUULMdKN$3gGdwlc%0KJ@47XSbN literal 0 HcmV?d00001 diff --git a/content/media/test/invalid-cmap-s1c2.opus b/content/media/test/invalid-cmap-s1c2.opus new file mode 100644 index 0000000000000000000000000000000000000000..95a84f523c7cd86db5fc6ef50198cd74f74843dd GIT binary patch literal 6848 zcmX|G1yohR*1q()ba!038>Bltbg8s-H(a_d-61L6TpFZPKtWWx6a;CIRzyKi_1?l1U zUylAu90c-@qklY~=7ql(QL_zBOv%nFL?q-yXXoXl7Gx%d#Rnt2e0{uwBSRzO5)s}B zkwFo@UOtWv_EwhWCZ-?^(oTwR@i`_NLiWOtJF@iM2ce2!y#{&zYkYz!#*f@eARgYq z<5I4tRa#X?TL2W_s-D^Fm^$nlz=tk2?`lom;VXk2Fbt0#EKku-HfC-*@!#*-Y(=ia za}wkR40nwvlhbxaf3~1u?c;;wz|LC^mNiPo6|B(jqIyAi&(AO-03t3A)%(ubZANiX zvk*`R4~X%UMXD2EuO0}?+wnn%wu=xTXF^#=WQq5ByJjyEtCri*smhw>J0+{kW)h~e zZx+R*cd)q=+LuK|kR!hDn!H1%;>Co45k?7l`V$;1Bd%C!#vUX~P)!Tr8?ob`58ZM3 z0HS09U5ZUcI7wn-Z(^5MFVN%+SL@1>y?JO8Vy16yFK_$aQdjf`C=ji`$Hun!%->^7 z@idg#IEhZ3!Hs`YBGIxE-Nx?WQ48xUek{Fi!K9b!{1N8}kT>DU9d^`*!)HC<wyE z8CEOfWi~0J9(Xie(!ZYT%kDlG^j$p|eA3Sq0tLvTf=P-0sM(IXf6+}OM{Y^|C?*CP z@?*%+-YK*HXf_oGkI!aC8qjXqK%wg0%%SJ#l3iK!_YgB31(BJx(9`Bw`t5kOm`PUw zeY$7UV*aOl%R@)X{#{(aQs)4& zt`|6QpQ(%ieV=z$7;KXXAH67nTAjarDYPYN0uQ_H=E6HH;mV>W#plkSV4z4@{#&aL z3Qx;DPAG5>29Lf~dmcJH+vp%jX< zXT1Fa=ihH`>O^=>NtbB6a?y)RypPPPRW2w8sG1@Ot8e8lJiBVIvR3Yh!>~8CBAkO^ z05Vdx^23^Q9ka$sH0;%k?5$yQ1uL7Dud>O~A0d#n9I~6(w86xk?=@;s<*eI&9J*5d zhb3fbmq1VX`*}f*(_;iESlWN+byPMeYQ{x*3@*=%(#^Io7jG*(Ec=vYvtSJAE9KWRFc2CBDk5bwrhgV*N4QAyfc?=xm^zeIcY zM3A>^+?1N>mFa;>e;#F_s!5B&gfOyLkz>=2szOoY@1Yyri`U{>vqtXN>IooUX<1*% zP=6WZSh7G8>ao3M*mQg}j=WUIwT^52`V5=BgpOrU^$A4E+qs(rtetLrv2o@CqB-&N!6R!ql@dK~g3kMq%s zMxgr_10-2OI$bB{LEI9~f?dLP`T%8<+C_|aw1xU)0`xdO8d(C(u;1!20V;WJ#7*<0 zL*%H8xKw#_Vi9nQgb>JMd!uGeI3LJYInlorDO-X?>D|BV%^{~TuhT_?*I(WqJs8_x zX?kyPvUTz|R4Hq22~Ls+@|30F@%L(s@`PSSWYEW7U8Rjnm)ysEB|z_&Zog4&$B@|Z z{_a2kM721ooNNL3p7h&cZDU#kKm}h!U+z8LyUc4V7d$8d(a4p*HJddkQM*V> zLB#apZy6c2TMik2cry07u(h2NB}mHE~PP{EVCKA79b`;9G2F;@bSD8))fwPBEn9mEXF=s>T}C<-*X5mo)zP@}-e1gV==Gm7(iS-c$lt8^{%yA|4+j1z>F1Eo--oXMvo)h6F$}BZ2 z8WVOti%1Tc+UC*c%ctWj^6REZ`;h$YO9wjAM+ks=;Lf!fqWWPboxMz;!b&_BDn0oz`^6l$^%)hvP++ogDdv(}icRnpa_@&v*9U{?;tiyr6sA3$ zKtgeWWr)ETDA>C5*%>Xlnpq-02R0uVM|E31OHF^p!1!A_MIP6}8m+c0U&sFFMcj;O z0|Sg+5ug}2`%}%O;&VNU8IB(2N-Aq|s$m)q6nhuI?*f$F7wB;=ZqkMRNLt@(MRm1v zs~Unr4Zr^yIn*gxknz7+%voXxQp6-r$m?F(cNhv7Ma0#8;d9w*Q<-kBv=9$E$c7L+ z0(qKFpD5Ir^^QbRj z#%J8g4bJ41$BZ!EIKsZ|_2K>F%uHZO`%WH)Gl=p=Pw7Nas}r$OwJ_4Q-!U_}KT-@7 zlXl&_c}237{gQljGI)VD%;|U47RXiW5UGLg{qcG2WEEe+QTkVn80U4DHM>s}(>?8J zqYsGZQ~lgGezUEDTn#^Gk`YSmcsR#e>xOJZRzFYFWBQzR%k7#pNk+3sD9;AIoVFe5 zjR0ibM@cHSVYW44?@Hu9Z9z-+&$fV~ABDSToAFs#`&pK>yRKUsg`jY4C?`KZBtW4; zSx(Ox$<_I(n0<<_p$(dN8cH2$WfsmwTUe|_iglfT{v6{a!~L@nkf$Ecpx2dvv7LPc zn((-AZ^LwkwSYF}#fQ&vP1T6V@a8CzMu~I!!_-<3Ano4QQgyohboo@fOdfuyBI7j) z6y=_m&B<^pd^I7TZgX$bp|VEBMK+{#;O93# zgshW;wtZnBPi>y^>#%~BBCB|1r%;or9crF1#(3T7ktD4YN$CgjwW*!SiO0b@5lpB< zL$8M$8rO%c8cu{K*FA|mP{gp3($ldC#XbJh)VSGyg8Q7WnDdH{S+-Yy?!4_Wdr_-iDXW z3mY{(^B2updpW`Voy6@yB8vU?@!ADTrOP{<%t?5T!FuQdJy2NViC9Fg)|)u!R|}Za zQDDshAPmc`;-R+K=+P&zX;GVL-Cr{qBJQc45E%Bu?V=Z6K@9TMJ+XrSU9u!0=7mI6 zeDfKKO7-QiwB|`_yrPq|5Y1M$mAoY)ZRc7z^V>oI1kK-B#Kj|2|L`LI80P_n!d*92 zbohjq49gfjtO$@9E2;T@nK^Y+m%eqbX})=!v!X2EV%mg4u%@%(_d0C64qi8Y^WP#7mwQYStJnm2&y zm|?Aquh!Yy5itZKbnX%be$S17oGJO=&9YlB7rJ~70#2Umy(E2GkbVcf5Exrj$XCcQ zC<@9TV*Wa>2(msX$BWK9Hp4SOdVLcVnaPLwL-&j0G+jsek1Az_GwBdxi2xC{i1qf3 z@NalhYS{Ly1meG-7`NO{zW4mqV&zKG205eO+b2JfcW1n3=($W+_x@SvCWJHvKf260 zyzK2T3Sb$sKG98Q{RXl~WLUiVpv%t7jaDDcPD!WrR%0;wMOatI*e__X>p5942P${R z5L%Vo4diLj?TxfEl05`4ZR{p=a^OvAbrL^*owf$df?Vme-xMgSU}wDUpMA)r1#)g= zr8&k}d?VLS2!|(Lb8zGL<@pweS8jpa(LBZB%UW$_U$=RV3{44}Ht^N8%o+>r?O*wa zEv&Vjs4SV&a0PU?{KH+=^SW4iMw|nB+)*FF08Ad%37y;;o1U#g!Jo8)uIi|iQ>#?< z^l%6ikwkx<%CGnmoB4Ct2_&Rr^~;0XjlwEuM#l6_AeRa5nBV$@LnLb1R&O$?<)?KC zpxwE%{8F0?x*eV;Kg>!^>Zf1L6JK~-e`??N{(BZzOCNy3f98iF6*-j|Ef>rBQuHZ+ zalU6zXM`@0vcJ6AP4ZOcEhtk{X08CGs>QD*zmQTmmG)}C zA!D1IJfN>n7hH)}jr+C*vPLggqUC0n3#Bp)WPhNg3@~3<)ZtcbSJp)CulscLM0)VA z0K~C~*|4??32dp;zwOlWhX?>;WY(G^E{7yY(Sluih}# zy-G4kvtKZn%Rs{D8(A_!2%zi@I3RDu(3nfXF@ZGw93huNpD$&d`!9Ta3C6$*ewIl1 zMKZ`;?|3M;RI+y8TuLiU39u_M#rD&?TxQiVy4ZD?fc(gtlh1}#JRK2B+-;&}|YONyXiolP#B$+U~yiuJPnJZ6fzh$N|T z_IIn{qyFJ{-(P11nqW;>(RUSl;Wf*L{CtU;F7@vNtXzLIpkqABItWh7F~|`0?2pNa zd}0U;f3)3>(ymlkYzqz~q`O1-f731p$a}&|C1)yBirTN_yoDC^Uj)V`S_2sVpDC$^ z)1t1?R>@yYF4lpZ^@_t{6T(@=+O4e_=q@tB)Q)n%!B6cLWEjVsGS4g{Y(FQR!(s0gyvF?fEaI_iN}soLspy-`#f zXLHh5&KOnpxTy=iS~{jbFF-@>LUkd!4<%Ejn#{8_znIZo_vTBremcu;rLqOoI*-_- zhS?8q(sCfEh1bKaOS1?~9{m*%aDJZv12AYmQyg&oeWGX zDI!d)i?H)(quqhDca;i_L4H&cz{mr5;?vENAQ!q6H|sGvIY4JA>sMvrYbFQ|dua zZ*tY`5dg#5S8o1D+@VzJ^PNY3+d$^%P%GpWuCsxM2^4lIXJFg$u3p0GL%cdM@|f;i zKuInh$ZYtQ+QoOb;TVAF8hW8ZkOMR_H&S{szWc~mnsK0|IE;Rzr|5Gebdsm z#!S-P0%SM;ELcHou>UY$w3KMI7{_;~Ad3~MC#}QQ0kH#jn z0tq(NnfPpH{cr2~KW=ZI)s%Fwnb^&ri{ZF-9hHMD6&?rqhHmY?8Y_m*SOwh!Kxo!C z+#ov@scrmceG3UI4PF3&Y#;gJ&=Sc^cpv$9)ZN5c5!awM<>g;#T#`u?ig%m?nkqK; zsjrL=V96`)jdMv97{uwkjN7B8JrF@4W~>M@NhI(srf*c5Z)Wy%TRS)X8a(FDP_;Ga zkJf-PuS`Awh-IbS=!v22IJMX#?<0CVDoZJJfaf^OB3Tlo6naf*E}L84(^Qv#|s+2;4vylGd{Z$vVem)5=;qme|lv<}Flka(CW- zQ3M$t7+3ZhM~8^s7dg%Ns#6ngEdO*YF=;LOuIo6W3=m06KMvA`0L3hP=)T?oya4&W zwl9tlh}8lQQBwqIc=ZDvc<}w0XTQ5>+sg4m*4}(jQJy9b)d!hH66~BDc4-Fvl=QVd za$h*SbbP+A?eR&DP@(m-QERDDA0UwUcx29Wa9T+hBq9p{q)v~m22DIka3<0F;2dut*v45&=AM|!vW))*2O_}JE_5# zqZncD_wHr@zSyl&Dh}yYG3NM4B|vKNB~Z*(F{;d*9AxIiu#fzW5PI`W6AL6X&fmWU2*j2%&zuTp z&i1T|3=sgyjngj)$RC+xvHz42Fdx20)ecbYUl{=d^%nO(DZtcH7n24Fa3y;ANRd@n zLVE%HTp)}S;m!DNom~FMLdc`EWZC(Fb*7+I-V8~*P1&QxM@1t5F4xE_!|t5^(1+*% z5shHkgo0zF@#>#0a*zO;;}^q;H7DFGX55DWDOfuo$c4$)ZK$jQ<;XKSZlP>i8)AR} zUp1iq;5dMI5{^B$0>tmzYp%g_PuJ0NEvcyPO+Z{|PN6u1c15b!)xUnMcNgZ`Pe?t0 zi?244JE%*Vk8lT)ZMN3>#YgJj{@sbSx0nI(q0x1tJfpfR=&^w#AQUByP+Yw4WC8H; j#TX2q8P$Ato02F8l2!c%Uq-O=^@U%25_k&rp4j?7B$!vM literal 0 HcmV?d00001 diff --git a/content/media/test/invalid-cmap-short.opus b/content/media/test/invalid-cmap-short.opus new file mode 100644 index 0000000000000000000000000000000000000000..fcd7eb506ade90a7cbfbc3509bff2f6974d2ca73 GIT binary patch literal 6854 zcmX|G1yoc~^I!Tc-5pDJgLDe`=u&CvjwP0^r8^`*{eQ$Rsfx)cOykXA%NP~^XU z-*^6V&O7hUygO&^{NA0Jd(Y@QI~zkVA^)T6lWL!T!wFPZ9|pa?x4$3gXzPH1D~*Bd z|0l=5#)M#FU}EY2)B1ng@0chz3gF5zHm?2KSmG%hkN+J&{KsZ1;wQWon@qKCG91h$k9r+z6e)8 zgn}nL#MQ&YRtWCvOoEm=*diPi#6(2J1Vu#!MPg5b`vh{TJ2!@Hm0$mX<|1U+@+Icv_;9ia}yI_PP%+Cex zi}){8|Ah|%`3KcMw3U{Oxy01%f)i7+vkH(2InmkAa#Hg%6T{+zk#Juh@8HPL$hbtL zcS2-PgfHC3$G|BvtR|O;> z*nd>Q^Q2O{@^BM?5?a@>!jEXft^h*lLeq}+334Ztwnr9wueE9Qpm1tH)0!!hQGm1XWmu?1B(6Tgu-`uV^E zUjQIUCeowYU`CK7HuNNR!h3*57le9emi+Yt+YoaD3kOBJ_f~r1KR}^qgIx}eg{S_W zqsk|ttR_he8cgnj8&Zi@6_~d64-T8zUkT#qcL^uG)DVm~LxTJXk8g3KJ{&yl&K7Cq z63MV$9xJs?8Sx~b>y-WV+(3Tkxv=lb{=nlto)9QN5fw~M`bXVv#N&%zA|+~5=0_1J zP@fk=iSbUA^GB1JBzSZ>JzS4*-3p3S?PLx<$CU2OV!VTx>ne#&uZEs9%`k4obHq%z z2^lavos#fB*b;&A^(tZp#>XgnxA3nXW#4vsq6F(cx*LGVszwPTK#Z*Hh{IUXYo(kY2RU zXc8L$3RP1!{W!ES5V#YW_?(>5x(IQ*p=pYIDdG}4P!MH8*e(Ed2pSrBMbOqJM3*`X zP;|b)i~CGt0vPzbv&Q0>Ncae+25NNw_NLGmrwKjiyqyhiw?e3jn--n9e1d^urFn0y zKPWvZ^E{@)-yb;qR^@fz{B*sYn3H|+;rg8XJeO4tc2WG=oA-hP>nDlZ2ki#`5JeS1 z=I1OKrX!NswimC$!|5sPn6&0fITIO)UMLZU1g837nSDoNTo?RM%(x05dC{YM>n19VJMAU;tr9%>i4t!9Op+!P`IS;0Df3HAa2e>eFQE|k1)(MvleYBJt{iYm2~rTj!Jp8~2j@sRIE<%3t}z!7Qs8}CzAZ@)wb zk3^8abj*yF<(1j~{k~_^1!|_vO5>uaB4w@(dzx}(&A$ik3@=_wYR?#Z;A$j*0wtxr z#e;pNkR$1QX{hJcs!`+7;TY;d1K%dD;pV(=x~wfwFeYkpj9aO=9gw26euAOS{+-LL0D;>Dym_ETlMOiuqV`F43xiqK%iC+7>J9FE;{` zu1oUPI;wA^CS~vCi?=bK+ntOfU3B~&BolHa6UR+@f0g^FlH3PMRcE=~dq=Hv^Wm~k zAl$H-DJEQ*_3RgOzhtkwsii$uVOKppL==&-8Vbc~G(;mLbvXf@H?2+ul1^D9CF(+*FmV zdRcSa-e&>DC0Ell@_gxJY*}&54CN4#w{_vjK>iR3(DvWDH9^!qOs8{}3YEi!@N4U3 z6eArxH-VD0z-R7HBAi3~%2U1)6F;8~LV`jq%?bUkDYmvL`&cHYjP*&|>V6m6h{Bpf z`b-!6Ec}l1sxK^a@dBJF5S`R`e>AdJa;v<=fM)LAJ3`Nd@TG`MwrP2uL|3 z?T%I{9!MfVi3T-=#aAWAKW4sI;I}-b5flkbHYvegbWgDjzC`W*@agkQU0^?|I%4TR8FPWHs%cdyeTiRgMl;-I=9KMK~ zHmhfXF)9O8{ilDbc<%dLjbMjkhPjc;o1SQzg#$(2`H0&9RgZZ_yz}dHkw4NlciK^% zZM8c!Z8Rh#!w@M0rRnJvRG(=an$ACb>#Zb*lv;3+%d>HNAc^r+O@>f>90vbWEh z&gg|J+g|wwT^6<-^RD)08Bml;|DITh%75vT6m9wPP5DQDOqn(c^_x$30w6DH6O@PM zy(Kb8#@4FON-nb%vnQa?CV3-z0q~%VT&vitc?R1S#&(iH;Re%pgYL%J{!L-`LK8J) zLY+-cd6Vm1C@YSbVf=B#y<2NTdqz@pBrA`EW;y&8R$V`c3Q$hc|C~-ns&EqE9cix_agbR5Jl2Tmb$!cJ z&9wQ$mvcglLO-p*N_OY~^J90Xjxk11sFq!VF4Jy;AJSq;n2vk>ZQ#dxKzT{;?;@Qo zMCqKUapO~e@vPOCwUQx{UK$C3VL#l@dl2QMpg`?oYsBA0D>71k zNL2YZpTVe9UoI;fzNCgr25C$2Y*jny8xrz1p7~S1O(a0n^qoyoGD7VSKk|>sGoV1U z^SY9OkobaW39FkO39{lubrU@HAQYwZ)I1JfpNVQo&HY_U2GV$_OHsD0-E_r*oTZ5d z&2DFLAFbGZ&cvqQKKvyJtS8F*i3(27+pow|{r)+Y7w{G!t;IaH5s(iG}LS8hJ0Xdookl>2h zY+Z}~MkJ+%ZOup_|7#TMhWGLJ?!VgXJV`nrcl3LQY_QR8MNPO4n)5Q>uewW1r2sPqX_0g z*X|f%>*Cw~XW9(A!)?qI4*+ai`*GbIL}Oa5)Q?{$EdetiPdfcKC8|o;DZj^O9|~Ea zoNIYmu2DAM$hBkQq4C#Tyo9~ae2c;>HbLHKzM}9Y?N;-zTYQH`X2gx_gc{oB4FwJk zul&R2S6h$oFIv#?1avk3v%91ZKVN)Gnge>?(jLM9Y(DmJ-P~&1?#%+>pY#K68t9T! zqf+_gU=S3O#(bVCsQeO_^>f%UB&2=i%e|ZRf=Xyc#?*Bnk177B-`coiBsy%XHdxg2 z(mI7OZavt3sZRvm49!sCt&Z!7(wh&sdi(yd13-_iYnok6x<4$jvSjNoDHK{y3j15;@4q1@0C8z8luMH?rPb%G{<^3AhU^)6H z`~G}N{mhnDZD<OW;PACCl{{k^;cnd-!){0>$QAw9jz|2azSQT%9n&Zo^0iUj zN#SmKrF4>3pKvgbp_K7Aie#h+K;09tPuYT{Ih%rK3TgZ~OeupoSHeE~U-R+BSpCa{ zSz_Vm$sli?(}BWb@#ZF3PUW}TGQ>=$ikF_W}~ zWJwJ(zgvtR_6@!J{yHnr6ldI;v9kzH(4-jh^Cfz_)V&X|cKcC}iS;mRKR7MNFhks{ zFD4`Mu@Nxz(QYeBr$T9=H8_x%;TGxtO{WZ?><%xHo-V&%*mkMlEwW(nA}}`52Eg+F zOieSC7IlTOLiuW9p%&z>Qy!8i-}LgYVaQb)i30TV_ugRhXD7=BHMz)s)H?3TO$>65 z`^pIN)mpzdpM`Ffjp+D8nm4jjWKMBPVH(Y9V^2@_2>vGP;8Q9|XF1G9ir4_OT_=s( zq9Oy&zWi}nmu#JsjJcjrTavj$1L5@Aq@pxrU-Snw{R} z8)fw|4rc?^j1g7O>)PPU#UsYEd<=9JstwV5Ae}1HXpyD$#hl@)Cr_s3(`j}KjUAxg zamXPv#CdR?mIFZtUN^5E-2yauWys#ZDMsh^5y0DAGk3o4Q7jFsK!2bm=9yr906^@Ho|OW8x%VB)~i$_Tr@+lE^NNoGJm}At*RKX+MXv3yGly~Q-!HIF;%+>aHow>XobJ#?8FQ})JwV-+fv7Fs9w_6QY4oR< z)ChWVovY!11ejL8@(M=c52n(dZ9n|m3bICrTB9!UT?{=A=mUllJEqj0{g|h69NfhE%$Tyc#y669ehuA zr077m_M(?&^FjH+6U767ELJFQPC4+)dZ&d_yxMl^cl50a8)t6r;!_%BU9H^5VRX@t z#wE4}i8eG?1ng$~Z)*EKZf%`b7q@em+RvRy;JI}kmVs>Lp8I)5?rpxB%SJ9Z`Ca`$ zXx2CUAp83=TZB)0=M$Fe;Q*0*FXh7EBH46!FXeai-NZ#1->@g;m?>I*c zHC)~kUpXJZieJ(j?}8*Sh}&fezgu0WKY~cYL>Xj}N)T8`U$3y($n5U2acTTDa3q+a zW@p$JtqEmap122)%FDVll0<2qoH90^^00OA094X!A2L(qk0B41(Z%haQ*YNj1eXNC zIezu4Sp>QB@~21ml-9g-FMXFL(%WLZH6^bD<-<5xlg&sR zj}gts50J<+UPHOk`Vku}j2t4j=zuip!&wVvB~N+!$vk!wWR@5;D`UG-xwLe@hbiF5 zw_}q)q%V|e@74B=K`jCa!lb0_WfDx2epbNTb1oNzAH7Bq@_B13Ls(ezVr&hSkN~k9 zIBh&7T~_Avl83#78K8=S8Gig35gsSEz6df2T|?)S*0KgDI!5KwN?Y0&IWUgrEbrsx zZomDa3^Ls_spv6@4iUdAbe{Irpe0^k`sq|`+EVyk&uLf{Ad!`Q6r=|Mir54&eZ2$t z0m?lcUpx^Irx_8Vt_;%g8w5J?5&E&te0SBcQ{acJzWH!pb&4|70Av+Quy=Ocp&Rg1 zG0^eMec|}h>G__H=O+bXrIwQh?ZpNIfJo}&p#{tSNd-fYm^=WGJ3q1>F!dtCo51Wv zfXuwE+-eG9aW?%f`^;}z76vrz zWd>pnV?@2*dzb@+5;rQTc;uHw*ki*L0J-ItKnXkLs8S0`kd+(DA@Vm;$=U-BgKXSy8(hcAdDO7&HQeSQt`)p$iuW``MLfzmY@~>3~Bof`NM^Wg~I?o&+sdwuAIKm z2bcf}op9;6l2fF~%AZb3kO-RN7sHJ+E7~Ms(u)MC*xMnf`H7Y-sJs&O@KXj}k!*Tf zQhN|gc0YJLMRBRBD literal 0 HcmV?d00001 diff --git a/content/media/test/invalid-m0c0.opus b/content/media/test/invalid-m0c0.opus new file mode 100644 index 0000000000000000000000000000000000000000..86555f60ebd98da144feabdcc5b851d926c78091 GIT binary patch literal 2471 zcmX|?c{CJiAIHa1*|H9t+nW?A>W+KvdB5j8=RDu<^Z7mJJl}sF43X#p5rq7!8K@g#e>)*L zRWBfi2?=8WJT_1OVj>XF`3J%5Up!eE$Sb#lZ-48U?m*;7l5g%z*Jxgc01p1Wq(Pg*Cz%5oGy8SUQu$ zV472CQ6w@Mi=feoQv5U!%fy@OqtN*^ul+Hhk-L!>@JTL%f((}U@$pU~FRLg*bw>uADt;X21o9))SZG&JOZAZjSi zot2k+%5+TK%d#zeJvQM2WKxnVZjf-HsHw9FB)gF%ty$6+%<1$g?L_Fa%t;^aaO=7l z(&g?v=4rp>fWwEnW>PL?3#3HoJn$^L06%YF`YKE*C(k}zFxZ#(^QDnocEaU>ldy&l z(F5^-z5a`9Z@`o)dI?>(k>tm&bykK}+g7*f%7(TjvkE~F6DjzU$E!Q-ydj#!&Q-*Nj7O%-P1a-KPv zM=7TF)e`WJdMksM23=R5cd8nQt9kB%;ts2f`H8xgvfi&wPJ7NZBie>LTcW$mT33dq zN2*i(1YB7C%Qxg*)w2dLPG@ zd@2h-QPa;|vH2#>w?p$@b$EDDS=shS%5jO^T<&jdwKBoA6JE_eY4DK^P{pIQ>=8CE z<%cfXhKvc!#OdCvL0nH;490lQF!P+IMRYkHmwskNl_nLCqm{n$(|BpPv~%36ZUu zy=X$H{i>Oyn&a%MVpe8X@ktoB$55cho?cM9f2`&y5tFQDP5_``&Jf)q-c=pim{VO~ zb3Pq#v%BUMh2!Ll_2-AHcEc}AWJfkVlkObs4lzGhpA$VtUOtwS1Fe634 zZY7Q9eLLGXTB%Q18dQ6aTg>X&QC_8m9(@mXf2zmz_q|rzB%Hj9BM#nL(NXvu$=g?6qQ^{yT;?)H`+^D;a=*-kF&*?mXb_UZ_T5}xmI!a>{#*!zBnCA?Sxaw z1qa0hXF>Vq`t)?7`C(r<@2jpQsy%GEzToewe?%|CmQc`JI`@v0n>R^@ZTHW>PJ+7L z-;ecs`UXQAP1}`ZbUk-gwvo0S2c+ln>bLg-Z@_XKXM*EF-MlG@d*m4JUYLzh?A`76 z%?cPUjm*wfy;344ZipN|Px!tzjh z1_BDI&fFQa-I&`5Z50vi4UMbde2<-aVKaD;y0_!&`mRq&y>GoR5t_Fez&Sa~3N@$$ zbzQt$@AQbfR(;F;J+z78-#WH>`kbTMjy{+^tMQZ;;I5um@}hTy6$5Goy>lL{LZQCS zHNS4UPjp!!k1su*`RbJFfvQ}k7SWq7Ry+Z-skSZj9}a6lmvRd~dY*x} zGZ&Lq+ZRkQ)>{|lZ~22W@DgJ}zf3hg?GJcF?O8{^9+3MV3TIs}FgY}X15W=HX8+Rt zFXZ5|@{Y2j*4T+G{L1R%^hToz#Yu(AC16HCn#gxldN=Q`CDBLjX*FHWkqz{WuJf3g zq+%c6;D42;z8I|JR0aB{{ZfYxc=@&M4b70#peIYTZG@agZ^i>-cbDb$G`52}=Hc*= zFroZz_o26j52wUuVoN#+=d1O92S$RD+eDMeG_x?tw;9@oUPH}yWVUH-H#Wk~Vx(;- anejk45pqc8chc=<^=ZPE(BjhJ^M3N!0vA&L?UT^%KJJbsG7bw8GAW2AurL(D z5P>=%2vCA$?|cqpXYXpce}bptU<5ji0^2umCXGgBzyv751dcX?6U|RyO>iazdBG5t z&LlCImK0hHiA=^KXmp~CAPvSc@s>u0C?hxu1xJ~q1reEq!&4b}%Md0r%mRtT(eYR& ziG|0}C=?o%u|J6X2Vo$CqLFBXA<{uG#w0PxcuPkr3ri*i!$Jhl#nWMQd?+5rB+;la zCZ55B!C@3^SQv>)gb}b55;+=X2*ZV7sZ=}}hNDGLnK1OMX2QFJKhiu_2>P3X*7?Wbb0V3 ztnowaU?N~|{Nmo%Eba-NO`jLF3&;b3_?uw8>nUtZyyv`|9Gd=UO|eYrL~1zPqAx zWq4+^COtsNjWtm5BhoWA@GL0lo=9+Ace~TUJ01V&Qhee;_;m*ef)zv2!53Ck zwe$3YQ__TDIy3Jlf|69zGFvi#{zsD3gHrpX>(Yk8i({r22H*a*0TXuoYEW6U(=l!E zaeUdYst^=6|J)s4VCH%|JpWavmk*Vd<9MV3m)yhU{>IiQ7hXT%)8dx_ALWB;9<6nc zuz7I~ITi-o4zeOU%~d{e+x)*dbyS&+<9#%~+j@B=ADnv>I2{OT53w_3{uA^0neme_ z`RcigW`w%0+9~R}uI_3U)yNp;F;KPqvH1StNkS+ z*6T&vUG4w*H7%z)BpVU5822iKcu2ONS1A%2Jz-RMo;91WGtU6h>4cruVN&@e7m@K~-%M<$!!?vDbc>lo?p2L6+a?OpBi{H9hs#)6)rEj_*YX-%kWF6 z^bN^)7>N|bw|uXs9WGKI z>sn07iZ*k)6#a6-zZGce_-Fsl&C~xaHMhuRt`Hp5)qRb*>Yw4T8Ni>20^hK&vgFjF zM+2WQ_N>zH8-h%tkC@^@OVm%f)S&dn+MV(d1<4T^D!Gn!jmNuhvX`>PIgqf#i274W z3?vyL;4;~tksXyJt=E;@Chw&oY2h`)Sl^!CRn+2w+5me3`b(%(|I}m=-8|X5w$rVq zglycYW9R53)j6TF9(l9W)2=uXB;h!X_tN=4&X!+9cd_U@4;gaeCIe zNvBc^4@wBnfr`zInVDqE!~P1sSKUk1d)W&8q2Ja2j9q~(8$xgC-8)iY*(@EgJunM9 z3F`a)I5yzz9|~4j5q2i= zcemfSC}FrXGCNQGN~waRF>>NO;SsQh2-zZ9k=C1{DPR_By z(ejOYfSsm2Qz22p3;ImHSl=-Na0>K$*# zTHy`&eXa8TVQZWArO>IoAl;mfV7mVm$WpA+gQ5 z^|ug?KX|b&L&|Y(j&_1d)l#fR>nKQz#k&r{uSM|AQL?SANgjJ%CqHHfoF504(vS^& z+&S-&bopbYx0ci{sLUK<)RWQSby^9LACz7F!oX=aZ33B_9VwG;-%9`Cv>tLPujr%q z8HguyDP^r=(F|j|by4wFAUFdrH6;wl)!;M!gh$n#bq?qSdHkNw2N@Q#^?`VA}qa4G@Ht>h>(7pscY;r+;T^5o7R4lA8{5V cYe&gS1ft21LvnwRZntR85Vk~?mJgr*AA(SBs{jB1 literal 0 HcmV?d00001 diff --git a/content/media/test/invalid-m1c0.opus b/content/media/test/invalid-m1c0.opus new file mode 100644 index 0000000000000000000000000000000000000000..c7728f79ee55185146d4eb0e100fc2a55a88d71c GIT binary patch literal 6836 zcmX|G1yoc~^I!Tc-5pDJgLH?FE|r$*F0985$Xvi11E`42tme@^N&q zx3V-hF$H0eHd1_x&oS8$vX_S3ktOe!h025V>gD~f@d+jwKXNO9cz6eoOSqm^YE>R> z0Z@FaI%cn9>ac47AG*-At2KFtuMBd)Fg&`kJVig*n7Qf1f4^(B6}b-2Ns#L|+%=+1 zPTLvz*^Gv@j}MXqJMTDH)+iZQutL9!>ILDwIKzklh`2md?>lC;8O24-LO>lnAjVS` zsZM~sdLS%s#|ItUE<}Kw38n3k#op^}nmtIY8g56YN^6?$l&mtFNtn*QSrilA!RAhA zUltTWj`-ed@^+c>m*WOT7{%o2PjIk|xMHOlyOAtG)y;%&#g2bIbjRfbh>{6(DK;75 zB#8|@iJe|OK%+BUtussZ=Ali9nZCKbyzK`|UC|$)K(ziI8{5J&e~(ec(@n2E3XnwwlM???vmJ5&qMJyL+>-iHL=4pD#gL=DS7!gw zWGW6GpG^wU9-&;fWJmJn!6m~M0(JKH_Ureog7n|7A7pt7&kr{ICqb}C=(??z%n+Q;(GQ(Bh zim-0m2yu*itl~sdpT5R82rP+GjM01po!A$(w#0 zS?lxN3r&1ZPHA0)xZYAVMZOYpjvXk7GRAM`gW3lTjl9NdYZIVJodw7`U*g1lrZNWf zecoGPuuUX<^r8f6bpH0H&=#i&JnX!i4R5!ED~p;GojZSmfg+`O@2r*;o|bu>P~aX6 z9DS?uJal@t(N4(Dy7*{gPIjKdG6%CLe*NtS{(+6t#GS)-{eOreiy-rJ7If1Q$t*jI z*Wux`WVQ^NbEWKw^aL*z@IwMq{V+_wqcE-uek5X41rWXLQM_}NooS&$3XYByB7mAq z%Z4A%=i>}Zdkg6&;;0rniP<{Mr`~w#gZw39)8hw4L)7AK2IuS|Z5^R$`>?sG z6X7{2U99oiMK3P#J~FFDIll~`YK$PPx|O@|?5w%UTDc<*!`{@2a1Mq6$Vl0Ww{sB}QojEnLZT$&!Cn`ve)+E#d6bfzQj>fscj)}k5sUEv(hZ77hu zYt9-VYHlglv7kz?q+7Xv(s(chRBhoP-jB)#ug!rYlC-zpXUyJyiT3V^AaCiIDK*n; z(*u>h=adDiCd~@t!pI^;j!iqNaz%~5hi-H)--v6?7`bDsCxCn%^I+g*|dl`+H@a{l>v}I!VaFbY0Xf`5Lg;6yg&9)V& z(8~w9dbR=N8r%tMOrdmRFXqblI=gY79fUk z{7cb~90JXWO_Wf3_u3OP~l5JalSB|k;F&#JPambTA&O7&8UI1iS|F#*yWxQB-_8V-P94*O;27zEQs14HHZ!Xl%2J!ACO-v{9Z|!zJpto z`%UUvnQsjP<2>teSt{$fr+um7BpHp?ME{wBo_@49q(Fz`=FKZkt&w#d4C(B2X+I2h41 z(a0EHmD#GvQ6cS{m+Fzep)?PQH^kBhg3td#OOVmjG^Uy_9^Uy~h?%k{0;f z?P-Klh+lciS3<%Uvq1<@prtvX-zCMyCglLb_>8_jX-CcPQVU*Kb3~izjGKkqaZ&Y! zX)d0RJq4nj8t;!n_F86*yOrYECWa>DkLpNXp1Xn2c~C10s-`r1czSbxqf=8AF(Nwa z>i!fqZXY`{43H1tw&xI=4cht3tOI&U0%Hr4M7lsR|2X3P`w~70`=q_mD)~ck1Sr;^ zD!2H$b7i#n*NG`@waq}Jg$W`T1{!5j{VWgxM|aR1{l2}K+%8p zr;1C(=XwM)96ijHRMzBF!!#Ty^3I3f1t`1E)8ky+qznC#w7%Dh>TKgyH3Ws~fB!Xd zs8zBc5m)<#&thLOkdo8$$31UONBZapK&MGJCj!& zGs1Y|2z$5JhxU&%Gl50zJ9!w+0BSXQN+*h19f+06`Qg_6_UVcJ;Ub`jwDaceYm%+( zSLCY`!Sl3XPQNR+K&~2xNDXxFk1uK_D)|zQ(!XlNIIp{`*?k(H>TXLLc|bgu>gT@k zn{5^3s{c8ij8J07!#UPkH)JES`gx)r)9b8TX4j}mGLl6?dDj2swDm}D7$EC9N>Z^6 zv#kz$Uo8J=3tGH?wgnXaDA+yQjL*W_&$6W5b=}%10EKHpIr;e^0Se{Ha(d24u8vPd z?2~l$tmJ+1_dZS2F)gvSMY8>Z8& z`Lr=Fmp{ifRv{w8o1#b>B+ls%Q)@tgv}<2W)#>)r!*`5x7eW?l$Gmc;NpBUBi<&5l~*z`@2Yc8(ummY}EM7Uo>m& z)j0Qe61NA5DD>OLYUVAKF7I$MC*U~->!I`XKtZ)9Vgb2YXX2n=C16fRfi(+&Ff6z7 zhuUHzN1wpP1#PBvf6ZiwxTktTVAv10iynA6G00c@#0vg*(UOFi7ZO$e&1Wzw)tAH4 znkT8@icZo(G+WtL@|K9SjcfkQZwmnsG<|0g7mrZ=!;AQ1{2V9{?!2j_!za9CSi
    $hF8AbV+|ezWU&+(%1RpL3Dv zcaMJY0~?95e!~3I^LDGU6u*Ctjya7zd3~Ob4wT_kbEhcqdv+M)Ov(FhmfdnW-|2G@aPmU$73sVD^gHNs>zkm+bRNtfx?dEh={mxHR3R&zNrxCs1c0R<0y%kTd#&eex4|cgA~$?#py_@1F&3LP%5aqsy$rtDbhF0G2`P z6Ww&yZy<|AhQ;e;U3Ok>w7O_^N;<7~8UxWU!#dkXe?fy?&&h&0P_;XT(5m>Z|G5_3 z-f$Zu*+T%+#%^3E2i}-gEAivkX-mKi$dyj}O@X2kcE;=e*@sM8Am>I_nq!p3H*)=i zaA^Du2RDB2bKj!yiY<^knx`myNvqZD>o(7kp($bG2EMwMSwn%n{cHcQ`L)&)l|^$J zu7IxQe|DGjye<}>5$Av&chpBP0F#GxTqn2MrhBVE@F(qnt2(OW)F@RxJsbo@B+*}_ z@+-c=X8s&@0tsnf{qo>;qo5L+kuh}>$Yp{%>bE}b5Qz%gs!b-fytGaMv^#f}UuqLU zw?lK}hgqpfee|o(#pfT_o!a+)_@2ep+zX)WKl8(oik!@hmWyS5CHfS=INvj4lCe!p9MIRL z3$8?~#(moYS)-RK&~mfOgi;y$vzKWp1I*_abhuU9lr@q2>ptz>kskaj0C6m0Cam>B z0$b|zZyUAzAp*b{p0VbL%OMF;v|yJWWL+rG`-(o>#s!rWIdQqsh`=_tPM?L zUsuwK;2*y6rI4jB!{4hrr`rq31UaJr+H#5B)|dLcyk{6CLA)`nJ1yKxuar#E>=O*; zGLSI(MwW~a0w{X|4#-!h9ji~JB(99R>@ya zEYyOWb&5k`7RJGOJdaI~5#^$82oH3&8 zaZ?+7wRlW_o{xsgLbV~f4<%Ej8qKpbznIZo_vA^nd^*c+p|SN0VNH zUAh}>=oP2jZA6&livSqs!=C;)HC!@Tk&nn3i6KPg5~O3#TLwvjoeWGXDI!d)i?H)( zquu_rc{$^&fE+bUl}b4H zn{AlXN3w2gHCQqB?73S0E;Cm*qfYtEdTs~#OL?~lkPm4;JadO;!y?b-MWx#8TcLvHhW*Ys;Ce?$U-sGy=BLIfA zuiX5RxPz(G=R1%7wt~#jp;pK%TxSCh6DaIb&cL?)eVv5Wa=bb*@|f;iKuInh#~ApQ+QoOb;cbBF8PK6Zl~Xh_6v}!vRyCXmnsK0|McK}pT$ubedFS`#&pu%#7*X6 zp1I4Hvm_4|j5ohwAV>9H*^r&k+t-GJZQt6^dyQi`2eJ;ZF`xcOGPgABqaCkM_Tg_Z z0SIHs8^D)FW83mLs=7&A0Ck$e$qSl}4%W8XS&&J}sS;r?bVYR*&`pv4IW6jbcjCjG z-gV#U8{uVvdKk!88FE7#B<_`JyLY2Q+wGVi*WuwzvAzpPS^*icTg^4vccljxeyslQ}<1nh|M`IIOfdrfCOnkO8 z{yqEkt>Tcq!h-=W3^6IZNF3AMSig%m?nkqK;sjrL=V96`) zjdMv97{uwkgxjsA-5)_9W~>M@NhI(sq;FK1Z)SFPSvxoW8aU?9P_;Gai`IZLuS`4u zh-IbS=!v2E;6)@0KY#-l~^@B&1#^fyqB zw0`&|6Fr;I9V#FV`>@u7nMqTgeKL#P0vW|dP0LuWm98w@9-#9%@a$SA5a+?{t{6hVdu#uYur z(IKMug-+AH>ePfAOFtcpOpBiA14Po&kArj}KoJWcy03QtFF?Mp?TaG>Vl~4< z)D%G)Uj0A^9(+IMneQ&zwsO3XwYSSE%2VW_`XIANf}NAYF3o_SlD@V_?n{SPjxYAL zJwC}1Dzuz7Xe~DA0|XKukIb14PAlkwL}USg)akL+fQcsw&IEcd9AxBn;Z&6qiL>r^ zCLQu$|HHpoio6ZVpR7`&=x9IM1nK#ywKYs08sgY5A27acSr|~alNyLQiV^ny;BE%s zi`^=v;*eeyVU7(~0HhXQ0>x|Yxz<6Z zaO~L?Ab#Ioa}Az*x{jV}Nkw&U0^&k*3d9+-%Tv9s{*7b3J2BUOLh1lqe6``+0bSBO zggcOIv$fVIK3wU%Qjkt*MHB=<{_FRB z=RfDX^X|;MbLP(P-I=-fjIN`jAsPnS|0vBk`oX^;weGj~==8c?e!if+wH-P{3LVk+ zPmYd-frf>Sfr+jAPwoHdpBg%f6Z~vUiGKS}?Xk6^FCj|e=4|7MVxb~}!h#~$D1iv- zQPp{<3sW_a|M$h-!xrk`7hvsHuVy0%B4Ej?$9W61EZ!WGE$TAGotG zT;AO?*xAj^TF}$Skr*YlvxeKtiwcW~3W$gZh)9c}L~hQu_8z|W@=kELmyD2*t&hDm z+}YpW*3;eH)5G_lqR{`Q_zKws35f{`3#p;h;LdP2dwF#ae`_~qJE#-NZF?W6kG+e% zE!^4D0}8kIg+m3P?$%yj&K{0X2Wxj{w;-qp)Yi$`!^7SUYU}Ce0f$Qe7nlEng@*PI zmw(u@SiVAts@eo4BxhyjBjU58vR-7T)Dl{t& zHvtHNWi5;65l!e7KmeI<+|iu4BTxZ3p_uMn*dAhEtW90D<9^(=*oa<*Wyj0+8SEHR zC8cf;|7t?V-Xj1hfbI93tSeMZOV}Yl#B>AkU!G!y1H|0!u>1DuEhY&u(_l~=ABgsl zL#h$tEbogb*z!XLwh9m+SA0oZM3L8Ot422xyPC(rvBHY>2Nj#_Mk1DzPbTHKSCE+_ z`qz0SkTb65ilR-n?A4gQA!ZRp+EZL?L+%(ErY*JMp7mkKFM10pcV=9m)+R zIB7zCcS46}H_+e&SMA7@yMAOHY^rBwr(pBZLPzW;C>W);%g#Rk+|PYP=_G{3D3M-` z(N$nWGQpx8!`k-IVH4XM0c_n)p~Tl}0^w%}kT3q}9Zuw@gXdjY!Y!P_>6S~QCDzHq z?)bDFGQVHy$?d!p@>$;Rf7;6(3<1a^gUCp3Rc(gdzUm}UAUCCd7LovUxzQBpA5=Jg zHkwF)N2gOmb?DbEpm60*#=uJqsg6vBdo)vRMbW91kdww~hOIdE=y4Z8J^JU9;(jN) zivx!$ejT1Ubxj}_;#Ebg#OdQXZ;lk_R=P$qmv4_b`r`?_R*3&v~# z$YQuo#y(h~?RvnSA}MWUv7(j$q@K8H*A5PehYxlc}MV9t!Ixt+cyxPXhph< zo+VN3mLcK@@93c;ZC%=Cla3&~-Q7sJ|Fw~T-5Bv&*eRwzKhlVxjUQqcI5_+UzqM76Hf07N?|6k9yGCsU z=y`vz#AF|j|LjQxRBQk3Nv11G6@1ijHxt%o0ap<-E2iwBq^;x+&PK#`;!noCU9|ii?PZG8d+VuV*iY!E%n>DAO3QuC) zUbqSiqa(Lr)R-;dNMIm*rAQDQkm8GJ@&ko&ZO~&;!%BeoRkzZei`;ZGHBx9~v;YBA zXIRw#d@&bmP|{PtFdj=i-$BCOVK({JLk|=v9-SK7FC3(iaMeHK5N&M_k#An=Z?{Sb z4k;!%tgFIHx9TMK)U4hdqFelda-f{)?K#y+e#HPICP&WJ{AimIHt}J-&6JmK!0gA3 z4efA`37I1GH_p1T3HK41)hcSX1G%j6hKDEm48}s zs$o$-j)K0KlDjczEMsHW^ieThxD^K3O3`)_8rGS4ay^I5E1Yy%k3yCzZ&`yEb_jJ< zew^iHJ3c{xLdCrYo`)sm{nLj1NuY8Q7x7_4E@)*I9G0TH@j7Mk@=dUFO91&wMonm# z-N9391}qnDsgVuQkN;I|2=S}fAv;EbK1}iM=c)YFD~gR8t5%SJCe$i zg1B$37&IImjv_DA@T_9%zdgs{D57WWhuzDnPlt5{0A$VMI|myi^1?IWArF~gap*QJ zK)G&42;ObK>AmeRTN@({*XFmd{i~UJkb7V|v>}lUZ7RV#%B-9~ds|QdusGdiAMVYIO$3u?dqL4+9bi2(iW1yV(TEgUoOt3t)AvcUK zI|czaj}JzBVrST>0p|z#%g1^*Bjk#(sl0j@y*TC7XSF+M@q0^Kqxxfd%T4a}k2jD1 zhA3ywEWk-$fV?HC_yXPP!@MCE;pq%Oct(cPAzI;+hygzLS zfVdhL#>MVW;K8sJ+A^Zq2bA%L_vGB;f5^D9bjF7e5)WPaS+QGzlGXEcl*G)h{+5u_ z$QOV2O|=XR5a$o6im6Q}sIW{CQ8U7+d~;3E`F`>`r9VH4(rAG0jiFg<&Vg(<-V__P2R)J z%X}wvEX_8DfHK~k)&86wzVGarN-<(|j*~o#G%!%4;W9(hY?{%J$!@keoRE#h8*I z?|4ZPfYPNo%fnHX-M?6qkgMBMvL<;1DA1_%@qMQbFDAhW*;?@0_XW03`)$o}LIdHA z;|)woaHh;xhd{x>&kPWM12f>g2@H(v_qGzSCC+!$5@!L3TxGp`k1ZvJd#tk zx^ejB;>qZe!m0_h8l5uKC2p(wUTDG#st@ThobWR7+RrP$ zGS9~Gb0ni_rNsH6kiC*!;c20KzJaNMb_*NM&2`fkJ_~GNMb(rhcMmU~@ARrLQA6U> z&aN+^V|FpqLjXlTURySa>42@D>?)v}C^$MlL97E535+2=d?@CZv`gF_sZ=P?*8=d_@qBsxQ-N(#Ly`8p;sRK&R@lCjsf@lI!*Xi%IaP-vZIv;W&jG;{rPKX zU!!bJF7R$Xdx0@f35z2BMd!kv{eb^4BDUr$zw>U(!^zfibBVzHEHuK$AaBFTQ^hLN zUUD8R#3_?`C`Kwq`r9M2S@jL6&}3XC2VAY+4+Wo;SXz934^Z^Ox%!eV}O0IhI<(?npL2iO_klgo#dP!Isb(u+} z)}prf}>-^|W5-3z}{9(Y=Fw3to^g&31nskVx(J4<-ofAd* z5fhXzmZ)cIb#U(}BLi5_x>JDS_M=v#t9-1a*^XGMm>X)@YnvM18!7|}$vUpzy&>Jq zdQGuB9yCW6>iDN(6XdS8k5I?(`uwtbyn;XeFzuUqw9~5ditU%N$*$Ja;RhtMDZXy& zf7q8n?z&%7NeE>QeB2|=RReZn%U{Q8(LGK&rM3+kq{Eq{RHuDkPg)LjhXC@?P)F#{1_(Aa5qYM?z+ho zTOM8Xt50jO4V8$9u*OKzddV|}gOq9zAnV-IggM@Pxp<~kq5wa5DC;>66y%(h%*gU6 zelw<+Y;kMRrnW-)MLwXs@9R4|;cWGp;>ZpXUAn6c;9S7qp+<4be&a*x!d6LvTRu>b zxB7+3+t9qG0?RlR#}MO*Z5rNCrZ}C+p+wDODVYZf)hX>s2}eQN;moK*L$|vtI`^l{ zDlUWv_dTfsP{6p9+|{-L!8^KbsNd+lMt~fZ87Y%u&Wua0>>4j^Q>~^JqjB$9j{%Xh^1CU?kftW`w*BaaFRSKHXQ)15mAQaoR z?2(rE@ZlG*VP1=Q)lVY{O~OMhJ|Og`>v=c4j0EJbd1?v&yI?^|!iN@F_T76RGR23} z!iqPs{*qqGTr5k)M(T!`td)E2)OQmB5H|i`m5>OB-SQ!Bja~rxA|2Ni^aMl~jEk6E zYzUAAJF*M^sT+X^t-Jbh*!py2b4t#i5>k-bO;wVjdG)3<2IMG7&}(uzi~VfD=6xnQ z_5Sg10bo5r&R0ZWYR-09j`Gj1(Om!c07(tTu@%2uU?>-LVmkpQx)*@ukZz?ypxWNu z7Crzaa_SHR{>%)4T*>yUsMXfB$RBuOO6biRD{^%*maSn=JhMzRTyakes-R*f8E_?=+8P} zb*z)d_8nxEOgDe?Nr!`v2fa3mgNk1By?TGttI&?Nk>8LYmoxGpPE_rVCbBHL>wBR| zzdO{*ME(fCvbG)5&W1On)=2*RebVed4RWW^eOIKcfS&TXt$CBn2xec)$#9Oa`b4ZA z6Ag~N<>VpgdErwSR=x@HMDZ4eEo!!ye%s7U(2UC;A{=Oo#n`yI_86u{zT8`I9IvhLc<7y3ol@1lk(In~M)&khDaQ7Md< zDFRBbaah(ukI{nLmcKr@SMI$gV{y0EJ975%@qLEc zG@+#^SnT&rkS%Jl96cwiR5*pPFY6N>mA~2CyfzQ4RYe22x9Z*272z(h1dzlarbAoK zC2^!r{+LMCavpUjm2~#Q~-xEb4)LT^F?N@CD!^fTCk?o@2%2wA!pk*V^9Ejot$;+%Y9knb769| z@xphlRi670Lhw_EiTz3n-MEEM%c1H-TJq9};S(hSpzcbW!TE3kJ8+QPz!WObW1YmYm>NgGKdON0?NW5UoSx^FnYOHhM%qATamTVWTXVDWh1*D1f(|?)`9`_D@ z`0+L~z!-bXlA)u}6TeX*_}6RHcB%d7Z|U;04g>RX=6+CWwtl*pM{jg`#8U%c@UzWU zq*l4&d`nOO5&a#)@4HqhK+zReEHzd3u%Pu)-b;91?^Qrdf)#-2w?;)hm>PM7zD)6E ze7*+cs#O{kFWdC+tESIU9F7EZ^Y-3h@nt2+1U5R!eAYPb&PfP#jQz#{^43^>G@XHL zl@4q9p*3w}B}<=Tmq68;V584Z_wfHFY2i^QN@d#3LQ!VUvLZ&yKG}tC0@}9+utor55VeZX zx`(_WtrTLI3MjXc!BS_x7U6ULFMXR8uOVON*o-G^2MsA6mXnKNZL#68zi@qu`sbto zem0?{_M{sh)bnZC(EN6kDDe^T%KR=iA3DXAY@9jTCVQOf1+4e#izfo0?8=y;r%fxy zDcOlK@QhXIG9*g$K>$p1q0fGv7%UnuDTHSaM-!oP3DTka9itTCb~=`&G%*(TdFWY` z;Z9#_oK}_oT0zsrmg&>^uiuE>DoKSw_Bz}VGxn*}-JPQLY$n>-fi1lQ&4zrlaCXL( zyl*`mq|OPfRsdxud0f|cbX`3(HvhT^h&IyB)7bxyX{-46mGW=7x|akIAZImmg)%O| zMk^N0p`0swHFmTeM~F}DO?fz2E=>|XY3AMmy*Ewo-2!L_r z8;?K)-arb?+4keVEg(x&h$Zq8&q?3i7y`YJ*SBf=P%CNqDNc<9c|?CEs4O1`@>b=a z@0wtm)u!}p80uKMb?hqa$4l}su*4~-c3Q%-C_T?3J7SLl7JWhhiuOUBoZ(y@Nz#WH znuE*7gXS942!Os-@vCecUWf0J)=QAPqD?pcH;j`s*K$EI?{F1i4ovpQI24t3YtU%ZaUs9j?cTuLTrAFTGjDMWf zz3M%AEAmOO4hr&D1YgqyN_fUA=G!jhp5TiUX}F$yjs;qq-h1xJ3>O|~*Ie{aZ$2tJ zc&2awkj4n+&MF0bUGFecjDu~b{6O8Ru&`%mFTSKw)Yiy;9zqrUC>$b7kZ?ndncrsG z@1~~r^VZgBRZ$zevF+@cIIc^_VJXO3=Dwe6;M(e=zGUEpo!8k1gk*ll3$%SGy+!c6 zXD)uJ&J!S%>!Fw*SRkDW>!J98x|=vD;pulLzy2$OM>>wO;uUL;4#VL&@safgEchh6 za4(1h0=b+P@w!yC`oamtjg&xU$$0+xwDoecjf}2NE2oCv{YL`nFdO~eD0K+S()a^_ zL{7$)fjCnAo&ja1)e1LALlTy|z0#jr5GpBUD;;l~_^TZ1nteGh^yDp)fY(b?35}U0H`-cX5djd%f>VZ*Ql+KduesTZ znE=X2sQ%|);bF0|>kA;G;5B3}aW%7_ynRG2wWPUifgSyL*8CxE&i4DSN+9C{qw;Q} zs9>@C0>>#IH5#Jz#a|9Z#?1vkbR33M0Ad-LCxJR>Kp`tXhL4v&A3(9E<%25>VmHBq zRh2+mKD_{YUIJg1=^xHoHu8LEEAKu%RGFj*(F0jT<82-7cWC>4mG!jTb6(lMc6hm` z<^DyUNU`~(UUQ*d4Fj~axqnjx} zAbz8qf=hN;h&4J?4v?9D4G_0ciYzgs09m*&?IQjlgx@{az=n*RmQ8JyfH) zzMBy1@>$jb>3H%GJH&D+LITx(mD@L-`yCUBftFTxXCL1KgyM@Cr;hnkr@NK~1_*%k z+VQs}+O2Go_+$IJFK&W5fd;3LQvcg<@v{UR)By&oYCO9Vbz-J bgk&j@1oQ2G9nQhu6L$VZ@EOEwZ1evBiR)8- literal 0 HcmV?d00001 diff --git a/content/media/test/invalid-m2c0.opus b/content/media/test/invalid-m2c0.opus new file mode 100644 index 0000000000000000000000000000000000000000..5c3f97e2ab68993008ce409360630775cb5d3e3a GIT binary patch literal 2471 zcmX|?c{CJiAIHa1*|H9YDe4{Xx##_!^PKa1zt89Qob!DDc`ziB8$=lLk1#}<!q5m5 z0)0Rbpasj``5ea1-qmvdgh0c?hzvRvwr}7pI-SCV2~dOy+{g@0GCzeg!J81}1w%Ln zi_BzMQt8oT3I&ItGe|OmGziBcSQ?_xhHx|*jy5+EL=-ZfKw}atgITOl3nUWHAmCVJ zHUUqkQt342{vh%ngozA{LK-1ZNC&|fi_D@BEFEcV9EBVN3l=<=z<@CbAp|^&OsBzE z1SSgxhf#5%p=25fM#NFclqi@X3?Gc6(Fhb6o*qtP!BGF}Mbx`daG^l^z3g{dTb;gb zsHvxe(njkWAmO@jQ)6SKAwpLV2{$l+8EBr+HPAsA97pSE!}Z~M$4(xFX~DF#6o4>l zDBhEumwU>5Ow-4@En+<`@d9L0nkQ+Lc%i7Nvk9blP^4|yvKK5Fj49nD=(Eg8Ki+Wb zx&+eg?mXsczx9CAhq`8RE_Dl}M(REAF1r9fZ)E-|TqP&Z@uqMHmjCmmkz7vV<$;s1 zh7U0V34pWyi+gXAxF>WbZBEqAKWi|3Ei=34Y5l?9;`LAe5HVs22g%zZ=eov7Lp3y zIhjYP=Jz!c36FX!LzV{JSD$yP8%b(-?}FkEn~eF1x|XuuuP!cot~DdN#yeZ$yURLP zhNefV)BJ_p*!|@{B0OUP&Vu5u@p#uYw>$0p({Z0J#U;##*~eOk-Ee>)*wIuSLP2?D z8(%*tIaMgSBjbJoC{8ggwWVy#{YaF0P-35WLmDN#Flu^X;O*b*Fk#291{H-n?NbIH z$Cmsm3qVoR&s}l(X0E@7<-O|g@}aS_9gmdble&4lUpX3O!fPjdn*Gw@BO9QKPjA^H zZeE;4j)nragY1Y7bCplLR_r&Y_DZucf{(^`TQ9GqgR_qUrUF3CAx^r?U(uhR89xb? zubRDRMy&m+ovfbY>aJ!{=1}oT6u-w*V#J+Z(71oB<|zr2qG3q{pkdA!-6Gjl9oCpr zU0`?qCg5dv%`1z>D;68h4_EC*T$aj?YI-KyIoKU)d9FgW_RSjro{0@LC~iN$+E*-M zy;iv0+4k4<)apOrV>2dUoXECvL@ArQC^?n#Wgw%VeoQR?v0S6d6Vms}1&{i= z4Y!mJ*U+laEmk(AM>WE1nfy~+*CUq*K{2Y^yQwos(XG^}i;)H7%$dqg)Rz$H zo04%b@bqS#bEzcnDPtgxoPE`U`I-JreYSPV_EErbbL~g>I0xc<2ow5*?ihcD)rp2ufzdeMH{Q zO=7YqxS=A+8~;g$U1@vd2YG|Bb4;e(_PvpMxKLTG=&Iwf1n{tjpH93C+blZiSej?8 zYcVM++QjWt^ve$WmanOU&H9a(tN&|CPNB%GFhLI?GfHMyLB}A%ka-xu7p5$HA;Z|Kt zG49Z@b99pG7}r^gxK-k5SCjw}@!W=cX&XPz7GqjUGR=Lpj~?gQ#NTsZD;i<(de*v$ zr&0=_Jd;SOwp!?j`Cy9EHA+@9KZXEW?&i(A#?Vj+9$ANr!Lu&%jQC zy52vI^?PGOppEA3DsuYXJ1g5r`;G&$b9wdKdqKBgInFa737~G?oXk6NjDIiO&Lr;c z_WNcf43AFXmOQIIr7j-Mxf;+my-jPATNiWSfn&sOZDltnnfD;h~pI05t1-z2{D zdTyIex|3`9_Npx+gDduIcc*xE0H~$NqOfr=|Moir(ymS4a(@qfV))mNt)4#D=(eK|rq60Ur3ZRy=9RqY9bw0UT4CRu2dhvh z*0tvPrsqVL4f6QX0-qbP^&M$$h05+UQUv)yw(Cb_Yl5%$J=mL z1cMFA@~Mf=jDUfSJXJ9zss4~KP}M4K6D7Xn40*X%yw2=#_?+?Y_~Dx1DPn!$x6u(O zTeVk@RdLZYNnHn2pu7iVm5rZIi!WR*=KkbmQY+&9<+-w)Yq)H4PX0$RK42mUaZNGvz?owoS;%QRI8C%D$-)%u0zmk5rT81Y)ea`$DY^8k6Hfb$AG0YWStOu z&U-jb{#eQFMYRhm(}$RK6r-?Ot@wx!%C3H);Ix}Ik;2Q0kV&&|Vf=7f3%-=nNXfos$2pVM5LKwN2PD`?piWq9Cr=)jj>+uqQPxeW&LB>P6lY4m0SF!gj>UQg#ZX<{A@ z4~Y`X?{*)0Yy5CZawe{%lX$+`@DE@jEWJ%Kn@qO|mwua}YwR=Bd`E7Z-gavv{47S+ bj+&VOM3W$gp+wGp4#n={|JOb)Byf8}G&>>wKJJDiG7bw8GAWQMuy8ce z0Es>z2+)FM=X4HhYv*FIe}WGSf)nUe3Vh!nm{cm60T-Z1V+6(&K{PvsGY&E)$O(pU zbS8bbKg2h)JS` z!I^jl6OMpWa5Nezj0h*-C?s+;-0*)rh4P9*mEwr9K3Za8A zF)~6KB6W082z`CHzQze1eQl)vakQ=$LJy&P?Br3nCR|ff9zYF-6FgY?d8f?AHN36b zBl+=37a&toTnS9lh2rL}W{~Pmma<{VT(F?ir*)EH&$6a`xg%|Sag^)b1?D1`Mm}x#~wlrWVr(>PKO!so-&US!cX$k>7;FhvrIi33;#FtfLgO`|3&fM}1YH z%R_E!&%4wx66#*Nprq3}b78W+wY=}Ev-6%y?Wm5?&X(BjiuRS^nbDebe<4@aK*f(p zkJx~-prm^u!DZd`P6zLF{HIIti3{O&aaQ5i?IB233`HAXSW(r^(+f^X6N>4~yq^e4 zQccQi$Q$!Nk|ZCL+9h3=GJr0QnOqor`!^pBb@-}ZS+vtJt^aX+*|(|?6gU6e9baJT z@_Tsxt4>evFjkJkk&2+?9xnGLTfH2*e!{!OHv=)c0jhb_);+@J#W~a%4Y(d;MRuAg zf8w_JeRJ%nG9AZztADrg^h`cD_b6aG0Ms60XGs4Q^ZA+46PjH0+(lDD-B+y?wOkiB zRr7ND%1E~4nhel5r7T!22{Fyf4!S)1=FGT#WH_kewiTyB6KJ#)lj-_^$dF}2I z`?6T;adD$0mZgJ%l9{ujV;N5xG6ovPMGGFwHYq_|Z>ZmJP5p2UtpeL(=8$_; zB2Bl6LiC6?KEvVCmggW&YB_D7{yj^I@){}oE|NwooHZ+Hwpl%pj42S`denI*rXZ7x z( z`y*e-8?3EE3i-Cr^|Zr9N~*d-?({tH&b(qoaYL`K^>jf*sFdS_M8426H(wB?p2noYV>Hp6ULrp`h5eCN%R&~ zSZIm*DK{)Iy|H$ud_-PiL^_OIN4>`5-8bG#S>qf?SYkx|sVEAP43P-w?9ZrI7)U-Xs<`! zD)q1}P6SCooW^_U8$ZsLU|UPG%zU(t9_Lyo+_PsXVElq~t#p!3r4}9(ht7eDP5#VG zvc+LPd7rCprE0xw`To%FYJbMAz?ThRw{`Cwsjz64ir5~Qg`WiVeSaJq@bU|VHJNoN z%j$XUtZt+1IuFRq=QnKc1>b__I?aYAg8BtB68Fe4-n|H0EJr*@@O zUcv}9ah~vrW18+hw(}AbC!o!rt=dW|3A001)svsF0~Th!iGS(y*fyDRBh~TjR9c0H zR_$1BjtQ&)P)C-|a1RyXhl&?%Ea@pXok_Uj|0e#L;aGmJzs-uK2LlNM)o1Pu*=@{k zgtv)`^@S%?a=yn;zpx!T7`C_L=k~5&S)-p{lnl#X3*?-fV})btL47yx_B(yzu66&) zKreN2iF{G z*{{y&o(5HGVa4?3iov_!J=Ss3J5i%{g1s_Fu?BzqEn{(@LAsj#OVqKb)drd(_kz5CQ8;}4;MDL;4mkaHgu_dZzfnUgDmyAp+T$m( z@vCc(Z!{TCDorU?Edz4`%2c7V%BN*_J%v7cPrLbYu3WHJY`y2~R2c5@Ex}iL>I-Hy zw>mf=UC`MtwP=T@&OqdNUE2c(|_cGuVzA*oPy-B7};&J%`>JJ)D-9 zjW6vYoUbwb0~kZ4wuz=w8RijEZ!>j_yoX!v$Zk{HZ*4@J#md-HvJ!zvGUSl#AEe(~ OG-e1}!b{7C&;J)U-e?;D literal 0 HcmV?d00001 diff --git a/content/media/test/manifest.js b/content/media/test/manifest.js index 48c59f75e6e8..789749ea590a 100644 --- a/content/media/test/manifest.js +++ b/content/media/test/manifest.js @@ -167,6 +167,20 @@ var gSnifferTests = [ { name:"bogus.duh", type:"bogus/duh" } ]; +// Files we must reject as invalid. +var gInvalidTests = [ + { name:"invalid-m0c0.opus", type:"audio/ogg; codecs=opus"}, + { name:"invalid-m0c3.opus", type:"audio/ogg; codecs=opus"}, + { name:"invalid-m1c0.opus", type:"audio/ogg; codecs=opus"}, + { name:"invalid-m1c9.opus", type:"audio/ogg; codecs=opus"}, + { name:"invalid-m2c0.opus", type:"audio/ogg; codecs=opus"}, + { name:"invalid-m2c1.opus", type:"audio/ogg; codecs=opus"}, + { name:"invalid-cmap-short.opus", type:"audio/ogg; codecs=opus"}, + { name:"invalid-cmap-s0c0.opus", type:"audio/ogg; codecs=opus"}, + { name:"invalid-cmap-s0c2.opus", type:"audio/ogg; codecs=opus"}, + { name:"invalid-cmap-s1c2.opus", type:"audio/ogg; codecs=opus"}, +]; + // Converts a path/filename to a file:// URI which we can load from disk. // Optionally checks whether the file actually exists on disk at the location // we've specified. diff --git a/content/media/test/test_invalid_reject.html b/content/media/test/test_invalid_reject.html new file mode 100644 index 000000000000..8359b4064103 --- /dev/null +++ b/content/media/test/test_invalid_reject.html @@ -0,0 +1,52 @@ + + + + + Test rejection of invalid files + + + + + +
    +
    +
    + + From be859975cee9b2c0aa8f7eb6c82c843ac1e377b1 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Tue, 20 Nov 2012 13:32:22 -0500 Subject: [PATCH 36/75] Bug 813640 - Split out the user event handlers into a separate function for clarity. r=jwir3 --- mobile/android/chrome/content/browser.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index db749fda323e..00fff098fcc0 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -3731,9 +3731,12 @@ var BrowserEventHandler = { // the remaining events are all dependent on the browser content document being the // same as the browser displayed document. if they are not the same, we should ignore // the event. - if (!BrowserApp.isBrowserContentDocumentDisplayed()) - return; + if (BrowserApp.isBrowserContentDocumentDisplayed()) { + this.handleUserEvent(aTopic, aData); + } + }, + handleUserEvent: function(aTopic, aData) { if (aTopic == "Gesture:Scroll") { // If we've lost our scrollable element, return. Don't cancel the // override, as we probably don't want Java to handle panning until the From 380bea421b98f1ffae7feb8bbf81efbc4561ccab Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Tue, 20 Nov 2012 13:38:47 -0500 Subject: [PATCH 37/75] Bug 813311 - Hide Axis so that it is not unnecessarily exposed to the world. r=Cwiiis --- mobile/android/base/gfx/GeckoLayerClient.java | 9 ++------- mobile/android/base/ui/Axis.java | 6 +++--- mobile/android/base/ui/PanZoomController.java | 4 ---- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/mobile/android/base/gfx/GeckoLayerClient.java b/mobile/android/base/gfx/GeckoLayerClient.java index bca3b0fe0b01..09377d696923 100644 --- a/mobile/android/base/gfx/GeckoLayerClient.java +++ b/mobile/android/base/gfx/GeckoLayerClient.java @@ -13,7 +13,6 @@ import org.mozilla.gecko.ScreenshotHandler; import org.mozilla.gecko.Tab; import org.mozilla.gecko.Tabs; import org.mozilla.gecko.ZoomConstraints; -import org.mozilla.gecko.ui.Axis; import org.mozilla.gecko.ui.PanZoomController; import org.mozilla.gecko.ui.PanZoomTarget; import org.mozilla.gecko.util.EventDispatcher; @@ -691,12 +690,8 @@ public class GeckoLayerClient if (BrowserApp.mBrowserToolbar == null) { return; } - Axis.Overscroll overscroll = mPanZoomController.getOverscrollY(); - if (overscroll == Axis.Overscroll.PLUS || overscroll == Axis.Overscroll.NONE) { - BrowserApp.mBrowserToolbar.setShadowVisibility(true); - } else { - BrowserApp.mBrowserToolbar.setShadowVisibility(false); - } + ImmutableViewportMetrics m = mViewportMetrics; + BrowserApp.mBrowserToolbar.setShadowVisibility(m.viewportRectTop >= m.pageRectTop); } }); } diff --git a/mobile/android/base/ui/Axis.java b/mobile/android/base/ui/Axis.java index 7526df445fc2..57772b221716 100644 --- a/mobile/android/base/ui/Axis.java +++ b/mobile/android/base/ui/Axis.java @@ -22,7 +22,7 @@ import java.util.Map; * like displacement, velocity, viewport dimensions, etc. pertaining to * a particular axis. */ -public abstract class Axis { +abstract class Axis { private static final String LOGTAG = "GeckoAxis"; private static final String PREF_SCROLLING_FRICTION_SLOW = "ui.scrolling.friction_slow"; @@ -117,7 +117,7 @@ public abstract class Axis { FLINGING, } - public enum Overscroll { + private enum Overscroll { NONE, MINUS, // Overscrolled in the negative direction PLUS, // Overscrolled in the positive direction @@ -203,7 +203,7 @@ public abstract class Axis { return getOverscroll() != Overscroll.NONE; } - public Overscroll getOverscroll() { + private Overscroll getOverscroll() { boolean minus = (getOrigin() < getPageStart()); boolean plus = (getViewportEnd() > getPageEnd()); if (minus && plus) { diff --git a/mobile/android/base/ui/PanZoomController.java b/mobile/android/base/ui/PanZoomController.java index 186b32de9bef..2f00a5887fbe 100644 --- a/mobile/android/base/ui/PanZoomController.java +++ b/mobile/android/base/ui/PanZoomController.java @@ -1061,8 +1061,4 @@ public class PanZoomController public int getOverScrollMode() { return mX.getOverScrollMode(); } - - public Axis.Overscroll getOverscrollY() { - return mY.getOverscroll(); - } } From 742e117df4f23afbcbcbfd0307aa7ad75371e7b3 Mon Sep 17 00:00:00 2001 From: Bill McCloskey Date: Tue, 20 Nov 2012 10:45:43 -0800 Subject: [PATCH 38/75] Backout 2ee20348ae59 (bug 747066) for Win64 crashes --- js/public/HeapAPI.h | 71 +----------------------------------- js/src/gc/Heap.h | 59 +++++++++++++++++------------- js/src/gc/Marking.cpp | 4 +- js/src/ion/Ion.cpp | 2 +- js/src/jscompartment.cpp | 1 + js/src/jscompartment.h | 3 +- js/src/jsfriendapi.cpp | 19 ++++++++++ js/src/jsfriendapi.h | 9 +++++ js/src/jsgc.cpp | 2 +- js/src/jsgc.h | 2 +- js/src/jsscript.h | 2 +- js/src/vm/String.h | 4 +- js/xpconnect/src/xpcpublic.h | 9 ++--- 13 files changed, 79 insertions(+), 108 deletions(-) diff --git a/js/public/HeapAPI.h b/js/public/HeapAPI.h index f0aad6077d87..9e83bec84a41 100644 --- a/js/public/HeapAPI.h +++ b/js/public/HeapAPI.h @@ -36,26 +36,11 @@ const size_t ChunkShift = 20; const size_t ChunkSize = size_t(1) << ChunkShift; const size_t ChunkMask = ChunkSize - 1; -const size_t CellShift = 3; -const size_t CellSize = size_t(1) << CellShift; -const size_t CellMask = CellSize - 1; - -/* These are magic constants derived from actual offsets in gc/Heap.h. */ -const size_t ChunkMarkBitmapOffset = 1032376; -const size_t ChunkMarkBitmapBits = 129024; - -/* - * Live objects are marked black. How many other additional colors are available - * depends on the size of the GCThing. Objects marked gray are eligible for - * cycle collection. - */ -static const uint32_t BLACK = 0; -static const uint32_t GRAY = 1; - } /* namespace gc */ } /* namespace js */ namespace JS { + namespace shadow { struct ArenaHeader @@ -63,39 +48,7 @@ struct ArenaHeader JSCompartment *compartment; }; -struct Compartment -{ - bool needsBarrier_; - - Compartment() : needsBarrier_(false) {} -}; - } /* namespace shadow */ -} /* namespace JS */ - -namespace js { -namespace gc { - -static inline uintptr_t * -GetGCThingMarkBitmap(const void *thing) -{ - uintptr_t addr = uintptr_t(thing); - addr &= ~js::gc::ChunkMask; - addr |= js::gc::ChunkMarkBitmapOffset; - return reinterpret_cast(addr); -} - -static inline void -GetGCThingMarkWordAndMask(const void *thing, uint32_t color, - uintptr_t **wordp, uintptr_t *maskp) -{ - uintptr_t addr = uintptr_t(thing); - size_t bit = (addr & js::gc::ChunkMask) / js::gc::CellSize + color; - JS_ASSERT(bit < js::gc::ChunkMarkBitmapBits); - uintptr_t *bitmap = GetGCThingMarkBitmap(thing); - *maskp = uintptr_t(1) << (bit % JS_BITS_PER_WORD); - *wordp = &bitmap[bit / JS_BITS_PER_WORD]; -} static inline shadow::ArenaHeader * GetGCThingArena(void *thing) @@ -105,16 +58,11 @@ GetGCThingArena(void *thing) return reinterpret_cast(addr); } -} /* namespace gc */ -} /* namespace js */ - -namespace JS { - static inline JSCompartment * GetGCThingCompartment(void *thing) { JS_ASSERT(thing); - return js::gc::GetGCThingArena(thing)->compartment; + return GetGCThingArena(thing)->compartment; } static inline JSCompartment * @@ -123,21 +71,6 @@ GetObjectCompartment(JSObject *obj) return GetGCThingCompartment(obj); } -static inline bool -GCThingIsMarkedGray(void *thing) -{ - uintptr_t *word, mask; - js::gc::GetGCThingMarkWordAndMask(thing, js::gc::GRAY, &word, &mask); - return *word & mask; -} - -static inline bool -IsIncrementalBarrierNeededOnGCThing(void *thing) -{ - JSCompartment *comp = GetGCThingCompartment(thing); - return reinterpret_cast(comp)->needsBarrier_; -} - } /* namespace JS */ #endif /* js_heap_api_h___ */ diff --git a/js/src/gc/Heap.h b/js/src/gc/Heap.h index 722af42b1ec1..6cc092f977e7 100644 --- a/js/src/gc/Heap.h +++ b/js/src/gc/Heap.h @@ -34,6 +34,14 @@ struct Arena; struct ArenaHeader; struct Chunk; +/* + * Live objects are marked black. How many other additional colors are available + * depends on the size of the GCThing. Objects marked gray are eligible for + * cycle collection. + */ +static const uint32_t BLACK = 0; +static const uint32_t GRAY = 1; + /* The GC allocation kinds. */ enum AllocKind { FINALIZE_OBJECT0, @@ -77,6 +85,10 @@ static const size_t MAX_BACKGROUND_FINALIZE_KINDS = FINALIZE_LIMIT - FINALIZE_OB */ struct Cell { + static const size_t CellShift = 3; + static const size_t CellSize = size_t(1) << CellShift; + static const size_t CellMask = CellSize - 1; + inline uintptr_t address() const; inline ArenaHeader *arenaHeader() const; inline Chunk *chunk() const; @@ -104,7 +116,7 @@ const static uint32_t FreeCommittedArenasThreshold = (32 << 20) / ArenaSize; * accessing the bitmap. In addition this allows to use some bits for colored * marking during the cycle GC. */ -const size_t ArenaCellCount = size_t(1) << (ArenaShift - CellShift); +const size_t ArenaCellCount = size_t(1) << (ArenaShift - Cell::CellShift); const size_t ArenaBitmapBits = ArenaCellCount; const size_t ArenaBitmapBytes = ArenaBitmapBits / 8; const size_t ArenaBitmapWords = ArenaBitmapBits / JS_BITS_PER_WORD; @@ -133,7 +145,7 @@ const size_t ArenaBitmapWords = ArenaBitmapBits / JS_BITS_PER_WORD; * fully used. * * Also only for the last span (|last| & 1)! = 0 as all allocation sizes are - * multiples of CellSize. + * multiples of Cell::CellSize. */ struct FreeSpan { @@ -250,7 +262,7 @@ struct FreeSpan /* See comments before FreeSpan for details. */ MOZ_ALWAYS_INLINE void *allocate(size_t thingSize) { - JS_ASSERT(thingSize % CellSize == 0); + JS_ASSERT(thingSize % Cell::CellSize == 0); checkSpan(); uintptr_t thing = first; if (thing < last) { @@ -271,7 +283,7 @@ struct FreeSpan /* A version of allocate when we know that the span is not empty. */ MOZ_ALWAYS_INLINE void *infallibleAllocate(size_t thingSize) { - JS_ASSERT(thingSize % CellSize == 0); + JS_ASSERT(thingSize % Cell::CellSize == 0); checkSpan(); uintptr_t thing = first; if (thing < last) { @@ -319,7 +331,7 @@ struct FreeSpan return; } size_t spanLength = last - first + 1; - JS_ASSERT(spanLength % CellSize == 0); + JS_ASSERT(spanLength % Cell::CellSize == 0); /* Start and end must belong to the same arena. */ JS_ASSERT((first & ~ArenaMask) == arenaAddr); @@ -329,7 +341,7 @@ struct FreeSpan /* The span is not the last and we have more spans to follow. */ JS_ASSERT(first <= last); size_t spanLengthWithoutOneThing = last - first; - JS_ASSERT(spanLengthWithoutOneThing % CellSize == 0); + JS_ASSERT(spanLengthWithoutOneThing % Cell::CellSize == 0); JS_ASSERT((first & ~ArenaMask) == arenaAddr); @@ -339,7 +351,7 @@ struct FreeSpan * storing useless empty span reference. */ size_t beforeTail = ArenaSize - (last & ArenaMask); - JS_ASSERT(beforeTail >= sizeof(FreeSpan) + CellSize); + JS_ASSERT(beforeTail >= sizeof(FreeSpan) + Cell::CellSize); FreeSpan *next = reinterpret_cast(last); @@ -537,7 +549,7 @@ struct Arena } static size_t thingsPerArena(size_t thingSize) { - JS_ASSERT(thingSize % CellSize == 0); + JS_ASSERT(thingSize % Cell::CellSize == 0); /* We should be able to fit FreeSpan in any GC thing. */ JS_ASSERT(thingSize >= sizeof(FreeSpan)); @@ -587,14 +599,6 @@ struct ChunkInfo /* Free arenas are linked together with aheader.next. */ ArenaHeader *freeArenasHead; -#if JS_BITS_PER_WORD == 32 - /* - * Calculating sizes and offsets is simpler if sizeof(ChunkInfo) is - * architecture-independent. - */ - char padding[12]; -#endif - /* * Decommitted arenas are tracked by a bitmap in the chunk header. We use * this offset to start our search iteration close to a decommitted arena @@ -652,10 +656,7 @@ struct ChunkBitmap uintptr_t bitmap[ArenaBitmapWords * ArenasPerChunk]; MOZ_ALWAYS_INLINE void getMarkWordAndMask(const Cell *cell, uint32_t color, - uintptr_t **wordp, uintptr_t *maskp) - { - GetGCThingMarkWordAndMask(cell, color, wordp, maskp); - } + uintptr_t **wordp, uintptr_t *maskp); MOZ_ALWAYS_INLINE bool isMarked(const Cell *cell, uint32_t color) { uintptr_t *word, mask; @@ -707,7 +708,6 @@ struct ChunkBitmap }; JS_STATIC_ASSERT(ArenaBitmapBytes * ArenasPerChunk == sizeof(ChunkBitmap)); -JS_STATIC_ASSERT(js::gc::ChunkMarkBitmapBits == ArenaBitmapBits * ArenasPerChunk); typedef BitArray PerArenaBitmap; @@ -810,13 +810,12 @@ struct Chunk }; JS_STATIC_ASSERT(sizeof(Chunk) == ChunkSize); -JS_STATIC_ASSERT(js::gc::ChunkMarkBitmapOffset == offsetof(Chunk, bitmap)); inline uintptr_t Cell::address() const { uintptr_t addr = uintptr_t(this); - JS_ASSERT(addr % CellSize == 0); + JS_ASSERT(addr % Cell::CellSize == 0); JS_ASSERT(Chunk::withinArenasRange(addr)); return addr; } @@ -920,12 +919,22 @@ ArenaHeader::unsetAllocDuringSweep() auxNextLink = 0; } +JS_ALWAYS_INLINE void +ChunkBitmap::getMarkWordAndMask(const Cell *cell, uint32_t color, + uintptr_t **wordp, uintptr_t *maskp) +{ + size_t bit = (cell->address() & ChunkMask) / Cell::CellSize + color; + JS_ASSERT(bit < ArenaBitmapBits * ArenasPerChunk); + *maskp = uintptr_t(1) << (bit % JS_BITS_PER_WORD); + *wordp = &bitmap[bit / JS_BITS_PER_WORD]; +} + static void AssertValidColor(const void *thing, uint32_t color) { #ifdef DEBUG ArenaHeader *aheader = reinterpret_cast(thing)->arenaHeader(); - JS_ASSERT_IF(color, color < aheader->getThingSize() / CellSize); + JS_ASSERT_IF(color, color < aheader->getThingSize() / Cell::CellSize); #endif } @@ -941,7 +950,7 @@ Chunk * Cell::chunk() const { uintptr_t addr = uintptr_t(this); - JS_ASSERT(addr % CellSize == 0); + JS_ASSERT(addr % Cell::CellSize == 0); addr &= ~(ChunkSize - 1); return reinterpret_cast(addr); } diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index 3b1be1744ebe..60c8faa5b317 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -1118,7 +1118,7 @@ GCMarker::processMarkStackOther(SliceBudget &budget, uintptr_t tag, uintptr_t ad if (tag == TypeTag) { ScanTypeObject(this, reinterpret_cast(addr)); } else if (tag == SavedValueArrayTag) { - JS_ASSERT(!(addr & CellMask)); + JS_ASSERT(!(addr & Cell::CellMask)); JSObject *obj = reinterpret_cast(addr); HeapValue *vp, *end; if (restoreValueArray(obj, (void **)&vp, (void **)&end)) @@ -1183,7 +1183,7 @@ GCMarker::processMarkStackTop(SliceBudget &budget) if (tag == ValueArrayTag) { JS_STATIC_ASSERT(ValueArrayTag == 0); - JS_ASSERT(!(addr & CellMask)); + JS_ASSERT(!(addr & Cell::CellMask)); obj = reinterpret_cast(addr); uintptr_t addr2 = stack.pop(); uintptr_t addr3 = stack.pop(); diff --git a/js/src/ion/Ion.cpp b/js/src/ion/Ion.cpp index 6df99cd0e5c1..7d5a823bacc9 100644 --- a/js/src/ion/Ion.cpp +++ b/js/src/ion/Ion.cpp @@ -50,7 +50,7 @@ using namespace js::ion; IonOptions ion::js_IonOptions; // Assert that IonCode is gc::Cell aligned. -JS_STATIC_ASSERT(sizeof(IonCode) % gc::CellSize == 0); +JS_STATIC_ASSERT(sizeof(IonCode) % gc::Cell::CellSize == 0); #ifdef JS_THREADSAFE static bool IonTLSInitialized = false; diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index 8e7775db6f22..df6bde2423fa 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -50,6 +50,7 @@ JSCompartment::JSCompartment(JSRuntime *rt) #ifdef JSGC_GENERATIONAL gcStoreBuffer(&gcNursery), #endif + needsBarrier_(false), ionUsingBarriers_(false), gcScheduled(false), gcState(NoGC), diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index d2b9e90388b4..0fec7d8664bb 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -116,7 +116,7 @@ namespace js { class AutoDebugModeGC; } -struct JSCompartment : private JS::shadow::Compartment +struct JSCompartment { JSRuntime *rt; JSPrincipals *principals; @@ -156,6 +156,7 @@ struct JSCompartment : private JS::shadow::Compartment #endif private: + bool needsBarrier_; bool ionUsingBarriers_; public: diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index 09c4ef424a3a..e6e3018220d1 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -546,6 +546,13 @@ js::TraceWeakMaps(WeakMapTracer *trc) WatchpointMap::traceAll(trc); } +JS_FRIEND_API(bool) +js::GCThingIsMarkedGray(void *thing) +{ + JS_ASSERT(thing); + return reinterpret_cast(thing)->isMarked(gc::GRAY); +} + JS_FRIEND_API(JSGCTraceKind) js::GCThingTraceKind(void *thing) { @@ -877,6 +884,18 @@ IsIncrementalBarrierNeeded(JSContext *cx) return IsIncrementalBarrierNeeded(cx->runtime); } +JS_FRIEND_API(bool) +IsIncrementalBarrierNeededOnObject(RawObject obj) +{ + return obj->compartment()->needsBarrier(); +} + +JS_FRIEND_API(bool) +IsIncrementalBarrierNeededOnScript(JSScript *script) +{ + return script->compartment()->needsBarrier(); +} + extern JS_FRIEND_API(void) IncrementalReferenceBarrier(void *ptr) { diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index e9fee656a014..dd200be779a3 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -266,6 +266,9 @@ struct WeakMapTracer { extern JS_FRIEND_API(void) TraceWeakMaps(WeakMapTracer *trc); +extern JS_FRIEND_API(bool) +GCThingIsMarkedGray(void *thing); + JS_FRIEND_API(void) UnmarkGrayGCThing(void *thing); @@ -882,6 +885,12 @@ IsIncrementalBarrierNeeded(JSRuntime *rt); extern JS_FRIEND_API(bool) IsIncrementalBarrierNeeded(JSContext *cx); +extern JS_FRIEND_API(bool) +IsIncrementalBarrierNeededOnObject(RawObject obj); + +extern JS_FRIEND_API(bool) +IsIncrementalBarrierNeededOnScript(JSScript *obj); + extern JS_FRIEND_API(void) IncrementalReferenceBarrier(void *ptr); diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 36ab61d1380d..18fa641cd78b 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -321,7 +321,7 @@ inline bool Arena::finalize(FreeOp *fop, AllocKind thingKind, size_t thingSize) { /* Enforce requirements on size of T. */ - JS_ASSERT(thingSize % CellSize == 0); + JS_ASSERT(thingSize % Cell::CellSize == 0); JS_ASSERT(thingSize <= 255); JS_ASSERT(aheader.allocated()); diff --git a/js/src/jsgc.h b/js/src/jsgc.h index 6f1d52d91677..1c6d2cc65de1 100644 --- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -904,7 +904,7 @@ struct GCMarker : public JSTracer { static void staticAsserts() { JS_STATIC_ASSERT(StackTagMask >= uintptr_t(LastTag)); - JS_STATIC_ASSERT(StackTagMask <= gc::CellMask); + JS_STATIC_ASSERT(StackTagMask <= gc::Cell::CellMask); } public: diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 77596c963088..62fd7d38acce 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -928,7 +928,7 @@ struct JSScript : public js::gc::Cell JS_STATIC_ASSERT(sizeof(JSScript::ArrayBitsT) * 8 >= JSScript::LIMIT); /* If this fails, add/remove padding within JSScript. */ -JS_STATIC_ASSERT(sizeof(JSScript) % js::gc::CellSize == 0); +JS_STATIC_ASSERT(sizeof(JSScript) % js::gc::Cell::CellSize == 0); namespace js { diff --git a/js/src/vm/String.h b/js/src/vm/String.h index a378d08f916a..fa8f7e96050e 100644 --- a/js/src/vm/String.h +++ b/js/src/vm/String.h @@ -653,11 +653,11 @@ JS_STATIC_ASSERT(sizeof(JSInlineString) == sizeof(JSString)); class JSShortString : public JSInlineString { - /* This can be any value that is a multiple of CellSize. */ + /* This can be any value that is a multiple of Cell::CellSize. */ static const size_t INLINE_EXTENSION_CHARS = sizeof(JSString::Data) / sizeof(jschar); static void staticAsserts() { - JS_STATIC_ASSERT(INLINE_EXTENSION_CHARS % js::gc::CellSize == 0); + JS_STATIC_ASSERT(INLINE_EXTENSION_CHARS % js::gc::Cell::CellSize == 0); JS_STATIC_ASSERT(MAX_SHORT_LENGTH + 1 == (sizeof(JSShortString) - offsetof(JSShortString, d.inlineStorage)) / sizeof(jschar)); diff --git a/js/xpconnect/src/xpcpublic.h b/js/xpconnect/src/xpcpublic.h index d8eca979c9cd..4ead001c47e9 100644 --- a/js/xpconnect/src/xpcpublic.h +++ b/js/xpconnect/src/xpcpublic.h @@ -128,7 +128,7 @@ xpc_FastGetCachedWrapper(nsWrapperCache *cache, JSObject *scope, jsval *vp) inline JSBool xpc_IsGrayGCThing(void *thing) { - return JS::GCThingIsMarkedGray(thing); + return js::GCThingIsMarkedGray(thing); } // The cycle collector only cares about some kinds of GCthings that are @@ -146,7 +146,7 @@ xpc_UnmarkNonNullGrayObject(JSObject *obj) { if (xpc_IsGrayGCThing(obj)) xpc_UnmarkGrayGCThingRecursive(obj, JSTRACE_OBJECT); - else if (JS::IsIncrementalBarrierNeededOnGCThing(obj)) + else if (js::IsIncrementalBarrierNeededOnObject(obj)) js::IncrementalReferenceBarrier(obj); } @@ -155,9 +155,8 @@ xpc_UnmarkNonNullGrayObject(JSObject *obj) MOZ_ALWAYS_INLINE JSObject * xpc_UnmarkGrayObject(JSObject *obj) { - if (obj) { + if (obj) xpc_UnmarkNonNullGrayObject(obj); - } return obj; } @@ -167,7 +166,7 @@ xpc_UnmarkGrayScript(JSScript *script) if (script) { if (xpc_IsGrayGCThing(script)) xpc_UnmarkGrayGCThingRecursive(script, JSTRACE_SCRIPT); - else if (JS::IsIncrementalBarrierNeededOnGCThing(script)) + else if (js::IsIncrementalBarrierNeededOnScript(script)) js::IncrementalReferenceBarrier(script); } return script; From f37d92601c5c4cc2d07aa5f78107c96c823d4c8a Mon Sep 17 00:00:00 2001 From: Eitan Isaacson Date: Tue, 20 Nov 2012 11:06:38 -0800 Subject: [PATCH 39/75] Bug 812515 - Land on static text if it is not a list bullet item. r=davidb --- accessible/src/jsat/TraversalRules.jsm | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/accessible/src/jsat/TraversalRules.jsm b/accessible/src/jsat/TraversalRules.jsm index ddec7376a9a4..756cfe31a861 100644 --- a/accessible/src/jsat/TraversalRules.jsm +++ b/accessible/src/jsat/TraversalRules.jsm @@ -50,10 +50,7 @@ var gSimpleTraversalRoles = Ci.nsIAccessibleRole.ROLE_LINK, Ci.nsIAccessibleRole.ROLE_PAGETAB, Ci.nsIAccessibleRole.ROLE_GRAPHIC, - // XXX: Find a better solution for ROLE_STATICTEXT. - // It allows to filter list bullets but at the same time it - // filters CSS generated content too as an unwanted side effect. - // Ci.nsIAccessibleRole.ROLE_STATICTEXT, + Ci.nsIAccessibleRole.ROLE_STATICTEXT, Ci.nsIAccessibleRole.ROLE_TEXT_LEAF, Ci.nsIAccessibleRole.ROLE_PUSHBUTTON, Ci.nsIAccessibleRole.ROLE_CHECKBUTTON, @@ -95,6 +92,16 @@ this.TraversalRules = { return Ci.nsIAccessibleTraversalRule.FILTER_MATCH; else return Ci.nsIAccessibleTraversalRule.FILTER_IGNORE; + case Ci.nsIAccessibleRole.ROLE_STATICTEXT: + { + let parent = aAccessible.parent; + // Ignore prefix static text in list items. They are typically bullets or numbers. + if (parent.childCount > 1 && aAccessible.indexInParent == 0 && + parent.role == Ci.nsIAccessibleRole.ROLE_LISTITEM) + return Ci.nsIAccessibleTraversalRule.FILTER_IGNORE; + + return Ci.nsIAccessibleTraversalRule.FILTER_MATCH; + } default: // Ignore the subtree, if there is one. So that we don't land on // the same content that was already presented by its parent. From cc5c8dd282a6603c6c1e5b515c8b9dd50d4290ef Mon Sep 17 00:00:00 2001 From: Joe Drew Date: Tue, 20 Nov 2012 14:27:39 -0500 Subject: [PATCH 40/75] Bug 812602 - Don't use the DecodeStyle enum namespace, since it doesn't actually exist. r=jrmuizel --HG-- extra : rebase_source : ac71cc01359c39e275e8b12c44e7d4e5fb04a81b --- image/src/RasterImage.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/image/src/RasterImage.cpp b/image/src/RasterImage.cpp index bc6ad19a6e9a..ca6a41d32592 100644 --- a/image/src/RasterImage.cpp +++ b/image/src/RasterImage.cpp @@ -2525,8 +2525,8 @@ RasterImage::InitDecoder(bool aDoSizeDecode) // If we have all the data we don't want to waste cpu time doing // a progressive decode mDecoder = new nsJPEGDecoder(*this, observer, - mHasBeenDecoded ? Decoder::DecodeStyle::SEQUENTIAL : - Decoder::DecodeStyle::PROGRESSIVE); + mHasBeenDecoded ? Decoder::SEQUENTIAL : + Decoder::PROGRESSIVE); break; case eDecoderType_bmp: mDecoder = new nsBMPDecoder(*this, observer); From 3708bf0225f4ce58d383b5bfbe0118bdf145ffad Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Tue, 20 Nov 2012 14:47:45 -0500 Subject: [PATCH 41/75] Bug 813533 - Ensure windows opened in global private browsing mode with no parent present are still marked as private. r=ehsan --- browser/base/content/browser.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 10e7b7c2554b..e34523e7744f 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -3536,15 +3536,18 @@ function OpenBrowserWindow(options) var wintype = document.documentElement.getAttribute('windowtype'); var extraFeatures = ""; + var forcePrivate = false; #ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING - if (typeof options == "object" && - "private" in options && - options.private) { + forcePrivate = typeof options == "object" && "private" in options && options.private; +#else + forcePrivate = gPrivateBrowsingUI.privateBrowsingEnabled; +#endif + + if (forcePrivate) { extraFeatures = ",private"; // Force the new window to load about:privatebrowsing instead of the default home page defaultArgs = "about:privatebrowsing"; } -#endif // if and only if the current window is a browser window and it has a document with a character // set, then extract the current charset menu setting from the current document and use it to From 00039d4d53400a8bcf21c623a4f625652a0d03ca Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Tue, 20 Nov 2012 11:55:14 -0800 Subject: [PATCH 42/75] Bug 803908: Enable font inflation for async pan/zoomed browsers. r=dbaron --- b2g/app/b2g.js | 3 + layout/base/nsIPresShell.h | 5 + layout/base/nsLayoutUtils.cpp | 11 ++ layout/base/nsLayoutUtils.h | 5 + layout/base/nsPresShell.cpp | 1 + layout/reftests/font-inflation/reftest.list | 180 ++++++++++---------- modules/libpref/src/init/all.js | 11 ++ 7 files changed, 126 insertions(+), 90 deletions(-) diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js index 6807c2ad0d44..26a06cee6e14 100644 --- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -584,6 +584,9 @@ pref("network.activity.blipIntervalMilliseconds", 250); pref("jsloader.reuseGlobal", true); +// Enable font inflation for browser tab content. +pref("font.size.inflation.minTwips", 120); + // Enable freeing dirty pages when minimizing memory; this reduces memory // consumption when applications are sent to the background. pref("memory.free_dirty_pages", true); diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index dd857204c357..a78be2f87667 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -1294,6 +1294,10 @@ public: return mFontSizeInflationLineThreshold; } + bool FontSizeInflationForceEnabled() const { + return mFontSizeInflationForceEnabled; + } + virtual void AddInvalidateHiddenPresShellObserver(nsRefreshDriver *aDriver) = 0; void InvalidatePresShellIfHidden(); @@ -1445,6 +1449,7 @@ protected: uint32_t mFontSizeInflationEmPerLine; uint32_t mFontSizeInflationMinTwips; uint32_t mFontSizeInflationLineThreshold; + bool mFontSizeInflationForceEnabled; // The maximum width of a line box. Text on a single line that exceeds this // width will be wrapped. A value of 0 indicates that no limit is enforced. diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 50d1a01d7cbc..7a8690490c28 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -78,6 +78,8 @@ #include "nsSVGOuterSVGFrame.h" #include "nsStyleStructInlines.h" +#include "mozilla/dom/PBrowserChild.h" +#include "mozilla/dom/TabChild.h" #include "mozilla/Preferences.h" #ifdef MOZ_XUL @@ -108,6 +110,7 @@ typedef FrameMetrics::ViewID ViewID; /* static */ uint32_t nsLayoutUtils::sFontSizeInflationLineThreshold; /* static */ int32_t nsLayoutUtils::sFontSizeInflationMappingIntercept; /* static */ uint32_t nsLayoutUtils::sFontSizeInflationMaxRatio; +/* static */ bool nsLayoutUtils::sFontSizeInflationForceEnabled; static ViewID sScrollIdCounter = FrameMetrics::START_SCROLL_ID; @@ -4752,6 +4755,8 @@ nsLayoutUtils::Initialize() "font.size.inflation.lineThreshold"); Preferences::AddIntVarCache(&sFontSizeInflationMappingIntercept, "font.size.inflation.mappingIntercept"); + Preferences::AddBoolVarCache(&sFontSizeInflationForceEnabled, + "font.size.inflation.forceEnabled"); #ifdef MOZ_FLEXBOX Preferences::RegisterCallback(FlexboxEnabledPrefChangeCallback, @@ -5136,6 +5141,12 @@ nsLayoutUtils::FontSizeInflationEnabled(nsPresContext *aPresContext) aPresContext->IsChrome()) { return false; } + if (TabChild* tab = GetTabChildFrom(presShell)) { + if (!presShell->FontSizeInflationForceEnabled() && + !tab->IsAsyncPanZoomEnabled()) { + return false; + } + } // XXXjwir3: // See bug 706918, comment 23 for more information on this particular section diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index f59512a7b673..f241cd2847d2 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -1643,6 +1643,10 @@ public: return sFontSizeInflationLineThreshold; } + static bool FontSizeInflationForceEnabled() { + return sFontSizeInflationForceEnabled; + } + /** * See comment above "font.size.inflation.mappingIntercept" in * modules/libpref/src/init/all.js . @@ -1761,6 +1765,7 @@ private: static uint32_t sFontSizeInflationLineThreshold; static int32_t sFontSizeInflationMappingIntercept; static uint32_t sFontSizeInflationMaxRatio; + static bool sFontSizeInflationForceEnabled; }; template diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 732862e94675..380f0dd69c68 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -9167,6 +9167,7 @@ PresShell::SetupFontInflation() mFontSizeInflationEmPerLine = nsLayoutUtils::FontSizeInflationEmPerLine(); mFontSizeInflationMinTwips = nsLayoutUtils::FontSizeInflationMinTwips(); mFontSizeInflationLineThreshold = nsLayoutUtils::FontSizeInflationLineThreshold(); + mFontSizeInflationForceEnabled = nsLayoutUtils::FontSizeInflationForceEnabled(); } void diff --git a/layout/reftests/font-inflation/reftest.list b/layout/reftests/font-inflation/reftest.list index 1e16aed37809..7b9002dc0834 100644 --- a/layout/reftests/font-inflation/reftest.list +++ b/layout/reftests/font-inflation/reftest.list @@ -5,99 +5,99 @@ # with the lineThreshold preference explicitly set to zero. However, # newer tests should probably focus more on testing nonzero values of # that preference. -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) test-pref(font.size.inflation.maxRatio,200) == maxRatio-1.html maxRatio-1-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == text-1.html text-1-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == text-2.html text-2-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == text-3.html text-3-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == text-4.html text-4-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == height-constraint-percent-1.html height-constraint-percent-1-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == height-constraint-percent-2.html height-constraint-percent-2-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == height-constraint-percent-3.html height-constraint-percent-3-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == height-constraint-percent-4.html height-constraint-percent-4-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == height-constraint-percent-5.html height-constraint-percent-5-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == height-constraint-percent-6.html height-constraint-percent-6-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == height-constraint-percent-7.html height-constraint-percent-7-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == height-constraint-percent-8.html height-constraint-percent-8-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == decoration-1.html decoration-1-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == bullet-1.html bullet-1-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == input-text-1-height.html input-text-1-height-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == input-text-1-noheight.html input-text-1-noheight-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == input-text-2-height.html input-text-2-height-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == input-text-2-noheight.html input-text-2-noheight-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == input-text-3-height.html input-text-3-height-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == input-text-3-noheight.html input-text-3-noheight-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == textarea-1.html textarea-1-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == textarea-2.html textarea-2-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == textarea-3.html textarea-3-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == css-transform-1.html css-transform-1-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == css-transform-2.html css-transform-2-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == container-with-clamping.html container-with-clamping-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) load video-1.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) HTTP(..) == intrinsic-min-1.html intrinsic-min-1-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) HTTP(..) == intrinsic-max-1.html intrinsic-max-1-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) HTTP(..) == intrinsic-fit-1a.html intrinsic-fit-1a-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) HTTP(..) == intrinsic-fit-1b.html intrinsic-fit-1b-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) HTTP(..) == intrinsic-fit-1c.html intrinsic-fit-1c-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) HTTP(..) == intrinsic-fit-2a.html intrinsic-fit-1a-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) HTTP(..) == intrinsic-fit-2b.html intrinsic-fit-1b-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) HTTP(..) == intrinsic-fit-2c.html intrinsic-fit-1c-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == select-listbox-1.html select-listbox-1-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) != select-listbox-1.html select-listbox-1.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == select-combobox-1.html select-combobox-1-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) != select-combobox-1.html select-combobox-1.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == select-listbox-2.html select-listbox-2-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) != select-listbox-2.html select-listbox-2.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == select-combobox-2.html select-combobox-2-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) != select-combobox-2.html select-combobox-2.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == select-combobox-3.html select-combobox-3-ref.html -asserts-if(gtk2Widget,0-4) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) != input-checkbox.html input-checkbox.html -asserts-if(gtk2Widget,0-4) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) != input-radio.html input-radio.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == disable-fontinfl-on-mobile.html disable-fontinfl-on-mobile-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == disable-fontinfl-on-mobile-2.html disable-fontinfl-on-mobile-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == disable-fontinfl-on-mobile-3.html disable-fontinfl-on-mobile-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == disable-fontinfl-on-mobile-4.html disable-fontinfl-on-mobile-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) != disable-fontinfl-on-mobile-5.html disable-fontinfl-on-mobile-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == preformatted-text.html preformatted-text-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == fixed-height-body.html fixed-height-body-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == fixed-height-body-child.html fixed-height-body-child-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == consecutive-inline.html consecutive-inline-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) test-pref(font.size.inflation.maxRatio,200) == maxRatio-1.html maxRatio-1-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == text-1.html text-1-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == text-2.html text-2-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == text-3.html text-3-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == text-4.html text-4-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == height-constraint-percent-1.html height-constraint-percent-1-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == height-constraint-percent-2.html height-constraint-percent-2-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == height-constraint-percent-3.html height-constraint-percent-3-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == height-constraint-percent-4.html height-constraint-percent-4-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == height-constraint-percent-5.html height-constraint-percent-5-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == height-constraint-percent-6.html height-constraint-percent-6-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == height-constraint-percent-7.html height-constraint-percent-7-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == height-constraint-percent-8.html height-constraint-percent-8-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == decoration-1.html decoration-1-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == bullet-1.html bullet-1-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == input-text-1-height.html input-text-1-height-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == input-text-1-noheight.html input-text-1-noheight-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == input-text-2-height.html input-text-2-height-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == input-text-2-noheight.html input-text-2-noheight-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == input-text-3-height.html input-text-3-height-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == input-text-3-noheight.html input-text-3-noheight-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == textarea-1.html textarea-1-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == textarea-2.html textarea-2-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == textarea-3.html textarea-3-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == css-transform-1.html css-transform-1-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == css-transform-2.html css-transform-2-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == container-with-clamping.html container-with-clamping-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) load video-1.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) HTTP(..) == intrinsic-min-1.html intrinsic-min-1-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) HTTP(..) == intrinsic-max-1.html intrinsic-max-1-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) HTTP(..) == intrinsic-fit-1a.html intrinsic-fit-1a-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) HTTP(..) == intrinsic-fit-1b.html intrinsic-fit-1b-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) HTTP(..) == intrinsic-fit-1c.html intrinsic-fit-1c-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) HTTP(..) == intrinsic-fit-2a.html intrinsic-fit-1a-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) HTTP(..) == intrinsic-fit-2b.html intrinsic-fit-1b-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) HTTP(..) == intrinsic-fit-2c.html intrinsic-fit-1c-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == select-listbox-1.html select-listbox-1-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) != select-listbox-1.html select-listbox-1.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == select-combobox-1.html select-combobox-1-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) != select-combobox-1.html select-combobox-1.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == select-listbox-2.html select-listbox-2-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) != select-listbox-2.html select-listbox-2.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == select-combobox-2.html select-combobox-2-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) != select-combobox-2.html select-combobox-2.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == select-combobox-3.html select-combobox-3-ref.html +asserts-if(gtk2Widget,0-4) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) != input-checkbox.html input-checkbox.html +asserts-if(gtk2Widget,0-4) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) != input-radio.html input-radio.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == disable-fontinfl-on-mobile.html disable-fontinfl-on-mobile-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == disable-fontinfl-on-mobile-2.html disable-fontinfl-on-mobile-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == disable-fontinfl-on-mobile-3.html disable-fontinfl-on-mobile-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == disable-fontinfl-on-mobile-4.html disable-fontinfl-on-mobile-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) != disable-fontinfl-on-mobile-5.html disable-fontinfl-on-mobile-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == preformatted-text.html preformatted-text-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == fixed-height-body.html fixed-height-body-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == fixed-height-body-child.html fixed-height-body-child-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == consecutive-inline.html consecutive-inline-ref.html # The tests below use nonzero values of the lineThreshold preference. -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == text-1.html text-1.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) HTTP(..) == list-1.html list-1-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-1a.html threshold-1a.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-1b.html threshold-1b-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-1c.html threshold-1c-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-2.html threshold-2-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-3.html threshold-3-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-scope-float-1.html threshold-scope-float-1-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-scope-float-2.html threshold-scope-float-2-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-scope-float-overflow-1.html threshold-scope-float-overflow-1-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-scope-float-overflow-2.html threshold-scope-float-overflow-2-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-scope-cell-1.html threshold-scope-cell-1-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-scope-cell-2.html threshold-scope-cell-2-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-scope-cell-3.html threshold-scope-cell-3-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == text-1.html text-1.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) HTTP(..) == list-1.html list-1-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-1a.html threshold-1a.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-1b.html threshold-1b-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-1c.html threshold-1c-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-2.html threshold-2-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-3.html threshold-3-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-scope-float-1.html threshold-scope-float-1-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-scope-float-2.html threshold-scope-float-2-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-scope-float-overflow-1.html threshold-scope-float-overflow-1-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-scope-float-overflow-2.html threshold-scope-float-overflow-2-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-scope-cell-1.html threshold-scope-cell-1-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-scope-cell-2.html threshold-scope-cell-2-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-scope-cell-3.html threshold-scope-cell-3-ref.html -fuzzy-if(gtk2Widget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-textarea-contents-under-1.html threshold-textarea-contents-under-1.html -fuzzy-if(gtk2Widget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-textarea-contents-under-2.html threshold-textarea-contents-under-2.html -fuzzy-if(gtk2Widget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-textarea-contents-at-1.html threshold-textarea-contents-at-1-ref.html -fuzzy-if(gtk2Widget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-textarea-contents-at-2.html threshold-textarea-contents-at-2-ref.html -fuzzy-if(gtk2Widget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-input-text-contents-under-1.html threshold-input-text-contents-under-1.html -fuzzy-if(gtk2Widget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-input-text-contents-under-2.html threshold-input-text-contents-under-2.html -fuzzy-if(gtk2Widget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-input-text-contents-at-1.html threshold-input-text-contents-at-1-ref.html -fuzzy-if(gtk2Widget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-input-text-contents-at-2.html threshold-input-text-contents-at-2-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-select-listbox-contents-under-1.html threshold-select-listbox-contents-under-1.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-select-listbox-contents-under-2.html threshold-select-listbox-contents-under-2.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-select-listbox-contents-at-1.html threshold-select-listbox-contents-at-1-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-select-listbox-contents-at-2.html threshold-select-listbox-contents-at-2-ref.html -fuzzy-if(gtk2Widget,1,8) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-select-combobox-contents-under-1.html threshold-select-combobox-contents-under-1.html -fuzzy-if(gtk2Widget,1,8) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-select-combobox-contents-under-2.html threshold-select-combobox-contents-under-2.html -fuzzy-if(gtk2Widget,1,8) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-select-combobox-contents-at-1.html threshold-select-combobox-contents-at-1-ref.html -fuzzy-if(gtk2Widget,1,8) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) == threshold-select-combobox-contents-at-2.html threshold-select-combobox-contents-at-2-ref.html +fuzzy-if(gtk2Widget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-textarea-contents-under-1.html threshold-textarea-contents-under-1.html +fuzzy-if(gtk2Widget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-textarea-contents-under-2.html threshold-textarea-contents-under-2.html +fuzzy-if(gtk2Widget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-textarea-contents-at-1.html threshold-textarea-contents-at-1-ref.html +fuzzy-if(gtk2Widget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-textarea-contents-at-2.html threshold-textarea-contents-at-2-ref.html +fuzzy-if(gtk2Widget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-input-text-contents-under-1.html threshold-input-text-contents-under-1.html +fuzzy-if(gtk2Widget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-input-text-contents-under-2.html threshold-input-text-contents-under-2.html +fuzzy-if(gtk2Widget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-input-text-contents-at-1.html threshold-input-text-contents-at-1-ref.html +fuzzy-if(gtk2Widget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-input-text-contents-at-2.html threshold-input-text-contents-at-2-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-select-listbox-contents-under-1.html threshold-select-listbox-contents-under-1.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-select-listbox-contents-under-2.html threshold-select-listbox-contents-under-2.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-select-listbox-contents-at-1.html threshold-select-listbox-contents-at-1-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-select-listbox-contents-at-2.html threshold-select-listbox-contents-at-2-ref.html +fuzzy-if(gtk2Widget,1,8) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-select-combobox-contents-under-1.html threshold-select-combobox-contents-under-1.html +fuzzy-if(gtk2Widget,1,8) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-select-combobox-contents-under-2.html threshold-select-combobox-contents-under-2.html +fuzzy-if(gtk2Widget,1,8) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-select-combobox-contents-at-1.html threshold-select-combobox-contents-at-1-ref.html +fuzzy-if(gtk2Widget,1,8) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-select-combobox-contents-at-2.html threshold-select-combobox-contents-at-2-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == relevant-width-1.html relevant-width-1-ref.html -test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,0) == relevant-width-overflow-1.html relevant-width-overflow-1-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == relevant-width-1.html relevant-width-1-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == relevant-width-overflow-1.html relevant-width-overflow-1-ref.html -pref(font.size.inflation.emPerLine,15) pref(font.size.inflation.lineThreshold,0) == min-width-passes-1.html min-width-passes-1-ref.html +pref(font.size.inflation.emPerLine,15) pref(font.size.inflation.forceEnabled,true) pref(font.size.inflation.lineThreshold,0) == min-width-passes-1.html min-width-passes-1-ref.html -pref(font.size.inflation.emPerLine,15) == xul-reflow-1.html xul-reflow-1-ref.html +pref(font.size.inflation.emPerLine,15) pref(font.size.inflation.forceEnabled,true) == xul-reflow-1.html xul-reflow-1-ref.html diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 170c3fa99912..8af08cdf54da 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -1784,6 +1784,17 @@ pref("font.size.inflation.emPerLine", 0); * used. */ pref("font.size.inflation.minTwips", 0); +/* + * In products with multi-mode pan-and-zoom and non-pan-and-zoom UIs, + * this pref forces font inflation to always be enabled in all modes. + * That is, any heuristics used to detect pan-and-zoom + * vs. non-pan-and-zoom modes are disabled and all content is treated + * as pan-and-zoom mode wrt font inflation. + * + * This pref has no effect if font inflation is not enabled through + * either of the prefs above. It has no meaning in single-mode UIs. + */ +pref("font.size.inflation.forceEnabled", false); /* * Since the goal of font size inflation is to avoid having to * repeatedly scroll side to side to read a block of text, and there are From f04e40072d444472f85144258032c586e09e1da8 Mon Sep 17 00:00:00 2001 From: "L. David Baron" Date: Tue, 20 Nov 2012 11:55:14 -0800 Subject: [PATCH 43/75] Bug 813373, patch 1: Remove pres context parameters from nsStyleAnimation::UncomputeValue. r=dholbert --- content/smil/nsSMILCSSValueType.cpp | 2 +- layout/style/AnimationCommon.cpp | 4 +--- layout/style/nsStyleAnimation.cpp | 8 +------- layout/style/nsStyleAnimation.h | 10 ++++------ 4 files changed, 7 insertions(+), 17 deletions(-) diff --git a/content/smil/nsSMILCSSValueType.cpp b/content/smil/nsSMILCSSValueType.cpp index a5edb939f8ae..9c279d13c2d0 100644 --- a/content/smil/nsSMILCSSValueType.cpp +++ b/content/smil/nsSMILCSSValueType.cpp @@ -412,6 +412,6 @@ nsSMILCSSValueType::ValueToString(const nsSMILValue& aValue, "Unexpected SMIL value type"); const ValueWrapper* wrapper = ExtractValueWrapper(aValue); return !wrapper || - nsStyleAnimation::UncomputeValue(wrapper->mPropID, wrapper->mPresContext, + nsStyleAnimation::UncomputeValue(wrapper->mPropID, wrapper->mCSSValue, aString); } diff --git a/layout/style/AnimationCommon.cpp b/layout/style/AnimationCommon.cpp index 8f084f2684e9..2db9dfe5adad 100644 --- a/layout/style/AnimationCommon.cpp +++ b/layout/style/AnimationCommon.cpp @@ -174,9 +174,7 @@ AnimValuesStyleRule::MapRuleInfoInto(nsRuleData* aRuleData) #ifdef DEBUG bool ok = #endif - nsStyleAnimation::UncomputeValue(cv.mProperty, - aRuleData->mPresContext, - cv.mValue, *prop); + nsStyleAnimation::UncomputeValue(cv.mProperty, cv.mValue, *prop); NS_ABORT_IF_FALSE(ok, "could not store computed value"); } } diff --git a/layout/style/nsStyleAnimation.cpp b/layout/style/nsStyleAnimation.cpp index 71bb8df3aaf0..760c3d7fadde 100644 --- a/layout/style/nsStyleAnimation.cpp +++ b/layout/style/nsStyleAnimation.cpp @@ -2338,12 +2338,9 @@ nsStyleAnimation::ComputeValue(nsCSSProperty aProperty, bool nsStyleAnimation::UncomputeValue(nsCSSProperty aProperty, - nsPresContext* aPresContext, const Value& aComputedValue, nsCSSValue& aSpecifiedValue) { - NS_ABORT_IF_FALSE(aPresContext, "null pres context"); - switch (aComputedValue.GetUnit()) { case eUnit_Normal: aSpecifiedValue.SetNormalValue(); @@ -2430,11 +2427,9 @@ nsStyleAnimation::UncomputeValue(nsCSSProperty aProperty, bool nsStyleAnimation::UncomputeValue(nsCSSProperty aProperty, - nsPresContext* aPresContext, const Value& aComputedValue, nsAString& aSpecifiedValue) { - NS_ABORT_IF_FALSE(aPresContext, "null pres context"); aSpecifiedValue.Truncate(); // Clear outparam, if it's not already empty if (aComputedValue.GetUnit() == eUnit_UnparsedString) { @@ -2442,8 +2437,7 @@ nsStyleAnimation::UncomputeValue(nsCSSProperty aProperty, return true; } nsCSSValue val; - if (!nsStyleAnimation::UncomputeValue(aProperty, aPresContext, - aComputedValue, val)) { + if (!nsStyleAnimation::UncomputeValue(aProperty, aComputedValue, val)) { return false; } diff --git a/layout/style/nsStyleAnimation.h b/layout/style/nsStyleAnimation.h index 3a8702638f3b..8b6f222d6b45 100644 --- a/layout/style/nsStyleAnimation.h +++ b/layout/style/nsStyleAnimation.h @@ -169,13 +169,11 @@ public: * @return true on success, false on failure. */ static bool UncomputeValue(nsCSSProperty aProperty, - nsPresContext* aPresContext, - const Value& aComputedValue, - nsCSSValue& aSpecifiedValue); + const Value& aComputedValue, + nsCSSValue& aSpecifiedValue); static bool UncomputeValue(nsCSSProperty aProperty, - nsPresContext* aPresContext, - const Value& aComputedValue, - nsAString& aSpecifiedValue); + const Value& aComputedValue, + nsAString& aSpecifiedValue); /** * Gets the computed value for the given property from the given style From 73f5df73c7d4581a563de1ce4ccd142eb9b49f8e Mon Sep 17 00:00:00 2001 From: "L. David Baron" Date: Tue, 20 Nov 2012 11:55:14 -0800 Subject: [PATCH 44/75] Bug 813373, patch 2: Remove pres context member from ValueWrapper. r=dholbert --- content/smil/nsSMILCSSValueType.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/content/smil/nsSMILCSSValueType.cpp b/content/smil/nsSMILCSSValueType.cpp index 9c279d13c2d0..6798c74139fd 100644 --- a/content/smil/nsSMILCSSValueType.cpp +++ b/content/smil/nsSMILCSSValueType.cpp @@ -21,13 +21,11 @@ using namespace mozilla::dom; /*static*/ nsSMILCSSValueType nsSMILCSSValueType::sSingleton; struct ValueWrapper { - ValueWrapper(nsCSSProperty aPropID, const nsStyleAnimation::Value& aValue, - nsPresContext* aPresContext) : - mPropID(aPropID), mCSSValue(aValue), mPresContext(aPresContext) {} + ValueWrapper(nsCSSProperty aPropID, const nsStyleAnimation::Value& aValue) : + mPropID(aPropID), mCSSValue(aValue) {} nsCSSProperty mPropID; nsStyleAnimation::Value mCSSValue; - nsPresContext* mPresContext; }; // Helper "zero" values of various types @@ -194,7 +192,6 @@ nsSMILCSSValueType::IsEqual(const nsSMILValue& aLeft, // Both non-null NS_WARN_IF_FALSE(leftWrapper != rightWrapper, "Two nsSMILValues with matching ValueWrapper ptr"); - // mPresContext doesn't really matter for equality comparison return (leftWrapper->mPropID == rightWrapper->mPropID && leftWrapper->mCSSValue == rightWrapper->mCSSValue); } @@ -247,7 +244,7 @@ nsSMILCSSValueType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd, // Handle barely-initialized "zero" destination. if (!destWrapper) { aDest.mU.mPtr = destWrapper = - new ValueWrapper(property, *destValue, valueToAddWrapper->mPresContext); + new ValueWrapper(property, *destValue); } return nsStyleAnimation::Add(property, @@ -311,8 +308,7 @@ nsSMILCSSValueType::Interpolate(const nsSMILValue& aStartVal, if (nsStyleAnimation::Interpolate(endWrapper->mPropID, *startCSSValue, *endCSSValue, aUnitDistance, resultValue)) { - aResult.mU.mPtr = new ValueWrapper(endWrapper->mPropID, resultValue, - endWrapper->mPresContext); + aResult.mU.mPtr = new ValueWrapper(endWrapper->mPropID, resultValue); return NS_OK; } return NS_ERROR_FAILURE; @@ -399,7 +395,7 @@ nsSMILCSSValueType::ValueFromString(nsCSSProperty aPropID, if (ValueFromStringHelper(aPropID, aTargetElement, presContext, aString, parsedValue, aIsContextSensitive)) { sSingleton.Init(aValue); - aValue.mU.mPtr = new ValueWrapper(aPropID, parsedValue, presContext); + aValue.mU.mPtr = new ValueWrapper(aPropID, parsedValue); } } From 43366dc10ff8719602398ca6cb372c3164c3a0a2 Mon Sep 17 00:00:00 2001 From: "L. David Baron" Date: Tue, 20 Nov 2012 11:55:14 -0800 Subject: [PATCH 45/75] Bug 813373, patch 3: Make sure all style rules have non-empty List implementations. r=bzbarsky --- .../html/content/src/nsHTMLBodyElement.cpp | 2 ++ layout/style/AnimationCommon.cpp | 11 +++++- layout/style/nsCSSRules.cpp | 36 +++++++++++++------ layout/style/nsCSSRules.h | 2 ++ layout/style/nsHTMLStyleSheet.cpp | 4 +++ layout/style/nsStyleSet.cpp | 4 +++ 6 files changed, 48 insertions(+), 11 deletions(-) diff --git a/content/html/content/src/nsHTMLBodyElement.cpp b/content/html/content/src/nsHTMLBodyElement.cpp index 8101df6562c7..7f0e02ac098a 100644 --- a/content/html/content/src/nsHTMLBodyElement.cpp +++ b/content/html/content/src/nsHTMLBodyElement.cpp @@ -256,6 +256,8 @@ BodyRule::MapRuleInfoInto(nsRuleData* aData) /* virtual */ void BodyRule::List(FILE* out, int32_t aIndent) const { + for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out); + printf("[body rule] {}\n"); } #endif diff --git a/layout/style/AnimationCommon.cpp b/layout/style/AnimationCommon.cpp index 2db9dfe5adad..bd06b43111e6 100644 --- a/layout/style/AnimationCommon.cpp +++ b/layout/style/AnimationCommon.cpp @@ -185,7 +185,16 @@ AnimValuesStyleRule::MapRuleInfoInto(nsRuleData* aRuleData) /* virtual */ void AnimValuesStyleRule::List(FILE* out, int32_t aIndent) const { - // WRITE ME? + for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out); + printf("[anim values] { "); + for (uint32_t i = 0, i_end = mPropertyValuePairs.Length(); i < i_end; ++i) { + const PropertyValuePair &pair = mPropertyValuePairs[i]; + nsAutoString value; + nsStyleAnimation::UncomputeValue(pair.mProperty, pair.mValue, value); + printf("%s: %s; ", nsCSSProps::GetStringValue(pair.mProperty).get(), + NS_ConvertUTF16toUTF8(value).get()); + } + printf("}\n"); } #endif diff --git a/layout/style/nsCSSRules.cpp b/layout/style/nsCSSRules.cpp index af451d257a75..2da32d30b7de 100644 --- a/layout/style/nsCSSRules.cpp +++ b/layout/style/nsCSSRules.cpp @@ -1991,7 +1991,14 @@ nsCSSKeyframeRule::MapRuleInfoInto(nsRuleData* aRuleData) void nsCSSKeyframeRule::List(FILE* out, int32_t aIndent) const { - // FIXME: WRITE ME + for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out); + + nsAutoString tmp; + DoGetKeyText(tmp); + fputs(NS_ConvertUTF16toUTF8(tmp).get(), out); + fputs(" ", out); + mDeclaration->List(out, aIndent); + fputs("\n", out); } #endif @@ -2011,7 +2018,7 @@ nsCSSKeyframeRule::GetType(uint16_t* aType) NS_IMETHODIMP nsCSSKeyframeRule::GetCssText(nsAString& aCssText) { - nsCSSKeyframeRule::GetKeyText(aCssText); + DoGetKeyText(aCssText); aCssText.AppendLiteral(" { "); nsAutoString tmp; mDeclaration->ToString(tmp); @@ -2041,6 +2048,13 @@ nsCSSKeyframeRule::GetParentRule(nsIDOMCSSRule** aParentRule) NS_IMETHODIMP nsCSSKeyframeRule::GetKeyText(nsAString& aKeyText) +{ + DoGetKeyText(aKeyText); + return NS_OK; +} + +void +nsCSSKeyframeRule::DoGetKeyText(nsAString& aKeyText) const { aKeyText.Truncate(); uint32_t i = 0, i_end = mKeys.Length(); @@ -2053,7 +2067,6 @@ nsCSSKeyframeRule::GetKeyText(nsAString& aKeyText) } aKeyText.AppendLiteral(", "); } - return NS_OK; } NS_IMETHODIMP @@ -2157,7 +2170,10 @@ NS_INTERFACE_MAP_END_INHERITING(GroupRule) void nsCSSKeyframesRule::List(FILE* out, int32_t aIndent) const { - // FIXME: WRITE ME + for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out); + + fprintf(out, "@keyframes %s", NS_ConvertUTF16toUTF8(mName).get()); + GroupRule::List(out, aIndent); } #endif @@ -2440,7 +2456,11 @@ IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(nsCSSPageRule, Rule) void nsCSSPageRule::List(FILE* out, int32_t aIndent) const { - // FIXME: WRITE ME + for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out); + + fputs("@page ", out); + mDeclaration->List(out, aIndent); + fputs("\n", out); } #endif @@ -2555,12 +2575,8 @@ CSSSupportsRule::List(FILE* out, int32_t aIndent) const { for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out); - nsAutoString buffer; - fputs("@supports ", out); - - fputs(NS_LossyConvertUTF16toASCII(mCondition).get(), out); - + fputs(NS_ConvertUTF16toUTF8(mCondition).get(), out); css::GroupRule::List(out, aIndent); } #endif diff --git a/layout/style/nsCSSRules.h b/layout/style/nsCSSRules.h index eb79435e276c..6eb6104ae8ff 100644 --- a/layout/style/nsCSSRules.h +++ b/layout/style/nsCSSRules.h @@ -371,6 +371,8 @@ public: virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const MOZ_OVERRIDE; + void DoGetKeyText(nsAString &aKeyText) const; + private: nsAutoTArray mKeys; nsAutoPtr mDeclaration; diff --git a/layout/style/nsHTMLStyleSheet.cpp b/layout/style/nsHTMLStyleSheet.cpp index 4f9b872bb6b3..3f03dd12450d 100644 --- a/layout/style/nsHTMLStyleSheet.cpp +++ b/layout/style/nsHTMLStyleSheet.cpp @@ -58,6 +58,8 @@ nsHTMLStyleSheet::HTMLColorRule::MapRuleInfoInto(nsRuleData* aRuleData) /* virtual */ void nsHTMLStyleSheet::HTMLColorRule::List(FILE* out, int32_t aIndent) const { + for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out); + printf("[html color rule] {}\n"); } #endif @@ -68,6 +70,8 @@ NS_IMPL_ISUPPORTS1(nsHTMLStyleSheet::GenericTableRule, nsIStyleRule) /* virtual */ void nsHTMLStyleSheet::GenericTableRule::List(FILE* out, int32_t aIndent) const { + for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out); + printf("[generic table rule] {}\n"); } #endif diff --git a/layout/style/nsStyleSet.cpp b/layout/style/nsStyleSet.cpp index 010b06d85618..e735ad2e3072 100644 --- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -45,6 +45,8 @@ nsEmptyStyleRule::MapRuleInfoInto(nsRuleData* aRuleData) /* virtual */ void nsEmptyStyleRule::List(FILE* out, int32_t aIndent) const { + for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out); + printf("[empty style rule] {}\n"); } #endif @@ -89,6 +91,8 @@ nsInitialStyleRule::MapRuleInfoInto(nsRuleData* aRuleData) /* virtual */ void nsInitialStyleRule::List(FILE* out, int32_t aIndent) const { + for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out); + printf("[initial style rule] {}\n"); } #endif From e44698198523e7151ed481b674c2453d2eec390c Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Tue, 20 Nov 2012 21:14:15 +0100 Subject: [PATCH 46/75] Bug 803924 - Crash with range, splitText. r=smaug --- content/base/src/nsRange.cpp | 65 +++++- content/base/src/nsRange.h | 12 + content/base/test/Makefile.in | 1 + .../test_textnode_split_in_selection.html | 221 ++++++++++++++++++ .../DOMCore/tests/approved/Makefile.in | 1 + .../approved/test_Range-mutations.html.json | 12 + 6 files changed, 310 insertions(+), 2 deletions(-) create mode 100644 content/base/test/test_textnode_split_in_selection.html create mode 100644 dom/imptests/failures/webapps/DOMCore/tests/approved/test_Range-mutations.html.json diff --git a/content/base/src/nsRange.cpp b/content/base/src/nsRange.cpp index f0cd36915d50..cce57dcfedbb 100644 --- a/content/base/src/nsRange.cpp +++ b/content/base/src/nsRange.cpp @@ -375,6 +375,8 @@ nsRange::CharacterDataChanged(nsIDocument* aDocument, nsIContent* aContent, CharacterDataChangeInfo* aInfo) { + MOZ_ASSERT(mAssertNextInsertOrAppendIndex == -1, + "splitText failed to notify insert/append?"); NS_ASSERTION(mIsPositioned, "shouldn't be notified if not positioned"); nsINode* newRoot = nullptr; @@ -383,6 +385,35 @@ nsRange::CharacterDataChanged(nsIDocument* aDocument, uint32_t newStartOffset = 0; uint32_t newEndOffset = 0; + if (aInfo->mDetails && + aInfo->mDetails->mType == CharacterDataChangeInfo::Details::eSplit) { + // If the splitted text node is immediately before a range boundary point + // that refers to a child index (i.e. its parent is the boundary container) + // then we need to increment the corresponding offset to account for the new + // text node that will be inserted. If so, we need to prevent the next + // ContentInserted or ContentAppended for this range from incrementing it + // again (when the new text node is notified). + nsINode* parentNode = aContent->GetParentNode(); + int32_t index = -1; + if (parentNode == mEndParent && mEndOffset > 0 && + (index = parentNode->IndexOf(aContent)) + 1 == mEndOffset) { + ++mEndOffset; + mEndOffsetWasIncremented = true; + } + if (parentNode == mStartParent && mStartOffset > 0 && + (index != -1 ? index : parentNode->IndexOf(aContent)) + 1 == mStartOffset) { + ++mStartOffset; + mStartOffsetWasIncremented = true; + } +#ifdef DEBUG + if (mStartOffsetWasIncremented || mEndOffsetWasIncremented) { + mAssertNextInsertOrAppendIndex = + (mStartOffsetWasIncremented ? mStartOffset : mEndOffset) - 1; + mAssertNextInsertOrAppendNode = aInfo->mDetails->mNextSibling; + } +#endif + } + // If the changed node contains our start boundary and the change starts // before the boundary we'll need to adjust the offset. if (aContent == mStartParent && @@ -504,6 +535,17 @@ nsRange::ContentAppended(nsIDocument* aDocument, child = child->GetNextSibling(); } } + + if (mStartOffsetWasIncremented || mEndOffsetWasIncremented) { + MOZ_ASSERT(mAssertNextInsertOrAppendIndex == aNewIndexInContainer); + MOZ_ASSERT(mAssertNextInsertOrAppendNode == aFirstNewContent); + MOZ_ASSERT(aFirstNewContent->IsNodeOfType(nsINode::eTEXT)); + mStartOffsetWasIncremented = mEndOffsetWasIncremented = false; +#ifdef DEBUG + mAssertNextInsertOrAppendIndex = -1; + mAssertNextInsertOrAppendNode = nullptr; +#endif + } } void @@ -517,10 +559,12 @@ nsRange::ContentInserted(nsIDocument* aDocument, nsINode* container = NODE_FROM(aContainer, aDocument); // Adjust position if a sibling was inserted. - if (container == mStartParent && aIndexInContainer < mStartOffset) { + if (container == mStartParent && aIndexInContainer < mStartOffset && + !mStartOffsetWasIncremented) { ++mStartOffset; } - if (container == mEndParent && aIndexInContainer < mEndOffset) { + if (container == mEndParent && aIndexInContainer < mEndOffset && + !mEndOffsetWasIncremented) { ++mEndOffset; } if (container->IsSelectionDescendant() && @@ -528,6 +572,17 @@ nsRange::ContentInserted(nsIDocument* aDocument, MarkDescendants(aChild); aChild->SetDescendantOfCommonAncestorForRangeInSelection(); } + + if (mStartOffsetWasIncremented || mEndOffsetWasIncremented) { + MOZ_ASSERT(mAssertNextInsertOrAppendIndex == aIndexInContainer); + MOZ_ASSERT(mAssertNextInsertOrAppendNode == aChild); + MOZ_ASSERT(aChild->IsNodeOfType(nsINode::eTEXT)); + mStartOffsetWasIncremented = mEndOffsetWasIncremented = false; +#ifdef DEBUG + mAssertNextInsertOrAppendIndex = -1; + mAssertNextInsertOrAppendNode = nullptr; +#endif + } } void @@ -538,6 +593,9 @@ nsRange::ContentRemoved(nsIDocument* aDocument, nsIContent* aPreviousSibling) { NS_ASSERTION(mIsPositioned, "shouldn't be notified if not positioned"); + MOZ_ASSERT(!mStartOffsetWasIncremented && !mEndOffsetWasIncremented && + mAssertNextInsertOrAppendIndex == -1, + "splitText failed to notify insert/append?"); nsINode* container = NODE_FROM(aContainer, aDocument); bool gravitateStart = false; @@ -581,6 +639,9 @@ nsRange::ContentRemoved(nsIDocument* aDocument, void nsRange::ParentChainChanged(nsIContent *aContent) { + MOZ_ASSERT(!mStartOffsetWasIncremented && !mEndOffsetWasIncremented && + mAssertNextInsertOrAppendIndex == -1, + "splitText failed to notify insert/append?"); NS_ASSERTION(mRoot == aContent, "Wrong ParentChainChanged notification?"); nsINode* newRoot = IsValidBoundary(mStartParent); NS_ASSERTION(newRoot, "No valid boundary or root found!"); diff --git a/content/base/src/nsRange.h b/content/base/src/nsRange.h index 6c6e61592e71..e2c2d114caaf 100644 --- a/content/base/src/nsRange.h +++ b/content/base/src/nsRange.h @@ -30,6 +30,12 @@ public: , mIsDetached(false) , mMaySpanAnonymousSubtrees(false) , mInSelection(false) + , mStartOffsetWasIncremented(false) + , mEndOffsetWasIncremented(false) +#ifdef DEBUG + , mAssertNextInsertOrAppendIndex(-1) + , mAssertNextInsertOrAppendNode(nullptr) +#endif {} virtual ~nsRange(); @@ -229,6 +235,12 @@ protected: bool mIsDetached; bool mMaySpanAnonymousSubtrees; bool mInSelection; + bool mStartOffsetWasIncremented; + bool mEndOffsetWasIncremented; +#ifdef DEBUG + int32_t mAssertNextInsertOrAppendIndex; + nsINode* mAssertNextInsertOrAppendNode; +#endif }; #endif /* nsRange_h___ */ diff --git a/content/base/test/Makefile.in b/content/base/test/Makefile.in index 1b82f0de8b23..18a1b1df569b 100644 --- a/content/base/test/Makefile.in +++ b/content/base/test/Makefile.in @@ -593,6 +593,7 @@ MOCHITEST_FILES_B = \ file_bug804395.jar \ test_bug804395.html \ test_bug809003.html \ + test_textnode_split_in_selection.html \ $(NULL) # OOP tests don't work on Windows (bug 763081) or native-fennec diff --git a/content/base/test/test_textnode_split_in_selection.html b/content/base/test/test_textnode_split_in_selection.html new file mode 100644 index 000000000000..e9bcba2ea666 --- /dev/null +++ b/content/base/test/test_textnode_split_in_selection.html @@ -0,0 +1,221 @@ + + + + + + Test for Bug 803924 + + + + +Mozilla Bug 803924 +

    + +
    +
    +
    + + diff --git a/dom/imptests/failures/webapps/DOMCore/tests/approved/Makefile.in b/dom/imptests/failures/webapps/DOMCore/tests/approved/Makefile.in index d1c6c2e4c14a..ec5a2c971117 100644 --- a/dom/imptests/failures/webapps/DOMCore/tests/approved/Makefile.in +++ b/dom/imptests/failures/webapps/DOMCore/tests/approved/Makefile.in @@ -23,6 +23,7 @@ MOCHITEST_FILES := \ test_Range-extractContents.html.json \ test_Range-intersectsNode.html.json \ test_Range-isPointInRange.html.json \ + test_Range-mutations.html.json \ test_Range-set.html.json \ test_interfaces.html.json \ $(NULL) diff --git a/dom/imptests/failures/webapps/DOMCore/tests/approved/test_Range-mutations.html.json b/dom/imptests/failures/webapps/DOMCore/tests/approved/test_Range-mutations.html.json new file mode 100644 index 000000000000..f1cc49d345bc --- /dev/null +++ b/dom/imptests/failures/webapps/DOMCore/tests/approved/test_Range-mutations.html.json @@ -0,0 +1,12 @@ +{ + "paras[0].firstChild.splitText(1), with unselected range on paras[0] from 0 to 1": true, + "paras[0].firstChild.splitText(1), with selected range on paras[0] from 0 to 1": true, + "paras[0].firstChild.splitText(1), with unselected range collapsed at (paras[0], 1)": true, + "paras[0].firstChild.splitText(1), with selected range collapsed at (paras[0], 1)": true, + "paras[0].firstChild.splitText(1), with unselected range from (paras[0].firstChild, 1) to (paras[0], 1)": true, + "paras[0].firstChild.splitText(1), with selected range from (paras[0].firstChild, 1) to (paras[0], 1)": true, + "paras[0].firstChild.splitText(2), with unselected range from (paras[0].firstChild, 1) to (paras[0], 1)": true, + "paras[0].firstChild.splitText(2), with selected range from (paras[0].firstChild, 1) to (paras[0], 1)": true, + "paras[0].firstChild.splitText(3), with unselected range from (paras[0].firstChild, 1) to (paras[0], 1)": true, + "paras[0].firstChild.splitText(3), with selected range from (paras[0].firstChild, 1) to (paras[0], 1)": true +} From 3c6ed39490a5c17fa52a18d23f7836464a46b204 Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Tue, 20 Nov 2012 21:14:15 +0100 Subject: [PATCH 47/75] Bug 804784 - Crash with range, normalize. r=smaug --- content/base/src/nsRange.cpp | 20 ++ content/base/test/Makefile.in | 1 + .../test_textnode_normalize_in_selection.html | 201 ++++++++++++++++++ 3 files changed, 222 insertions(+) create mode 100644 content/base/test/test_textnode_normalize_in_selection.html diff --git a/content/base/src/nsRange.cpp b/content/base/src/nsRange.cpp index cce57dcfedbb..c18a3b770f02 100644 --- a/content/base/src/nsRange.cpp +++ b/content/base/src/nsRange.cpp @@ -500,7 +500,27 @@ nsRange::CharacterDataChanged(nsIDocument* aDocument, newRoot = IsValidBoundary(newEndNode); } } + // When the removed text node's parent is one of our boundary nodes we may + // need to adjust the offset to account for the removed node. However, + // there will also be a ContentRemoved notification later so the only cases + // we need to handle here is when the removed node is the text node after + // the boundary. (The m*Offset > 0 check is an optimization - a boundary + // point before the first child is never affected by normalize().) + nsINode* parentNode = aContent->GetParentNode(); + if (parentNode == mStartParent && mStartOffset > 0 && + mStartOffset < parentNode->GetChildCount() && + removed == parentNode->GetChildAt(mStartOffset)) { + newStartNode = aContent; + newStartOffset = aInfo->mChangeStart; + } + if (parentNode == mEndParent && mEndOffset > 0 && + mEndOffset < parentNode->GetChildCount() && + removed == parentNode->GetChildAt(mEndOffset)) { + newEndNode = aContent; + newEndOffset = aInfo->mChangeEnd; + } } + if (newStartNode || newEndNode) { if (!newStartNode) { newStartNode = mStartParent; diff --git a/content/base/test/Makefile.in b/content/base/test/Makefile.in index 18a1b1df569b..07f5ee698851 100644 --- a/content/base/test/Makefile.in +++ b/content/base/test/Makefile.in @@ -594,6 +594,7 @@ MOCHITEST_FILES_B = \ test_bug804395.html \ test_bug809003.html \ test_textnode_split_in_selection.html \ + test_textnode_normalize_in_selection.html \ $(NULL) # OOP tests don't work on Windows (bug 763081) or native-fennec diff --git a/content/base/test/test_textnode_normalize_in_selection.html b/content/base/test/test_textnode_normalize_in_selection.html new file mode 100644 index 000000000000..f87973214655 --- /dev/null +++ b/content/base/test/test_textnode_normalize_in_selection.html @@ -0,0 +1,201 @@ + + + + + + Test for Bug 804784 + + + + +Mozilla Bug 804784 +

    + +
    +
    +
    + + From b87586b90215331df3602ff3697fe4abc18b030e Mon Sep 17 00:00:00 2001 From: "Mario Alvarado [:marioalv]" Date: Tue, 20 Nov 2012 10:57:02 -0600 Subject: [PATCH 48/75] Bug 806688 - Port browser_privatebrowsing_localStorage_before_after.js to the new per-window PB APIs; r=ehsan --HG-- rename : browser/components/privatebrowsing/test/browser/global/browser_privatebrowsing_localStorage_before_after.js => browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after.js rename : browser/components/privatebrowsing/test/browser/global/browser_privatebrowsing_localStorage_before_after_page.html => browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after_page.html rename : browser/components/privatebrowsing/test/browser/global/browser_privatebrowsing_localStorage_before_after_page2.html => browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after_page2.html extra : rebase_source : e22dc284a5839939d564a30be5c5a53f976dff87 --- .../test/browser/perwindow/Makefile.in | 3 + ...ivatebrowsing_localStorage_before_after.js | 66 +++++++++++++++++++ ...owsing_localStorage_before_after_page.html | 11 ++++ ...wsing_localStorage_before_after_page2.html | 10 +++ 4 files changed, 90 insertions(+) create mode 100644 browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after.js create mode 100644 browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after_page.html create mode 100644 browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after_page2.html diff --git a/browser/components/privatebrowsing/test/browser/perwindow/Makefile.in b/browser/components/privatebrowsing/test/browser/perwindow/Makefile.in index 5d18eaf04486..c2c6d425b499 100644 --- a/browser/components/privatebrowsing/test/browser/perwindow/Makefile.in +++ b/browser/components/privatebrowsing/test/browser/perwindow/Makefile.in @@ -25,6 +25,9 @@ MOCHITEST_BROWSER_FILES = \ browser_privatebrowsing_geoprompt_page.html \ browser_privatebrowsing_lastpbcontextexited.js \ browser_privatebrowsing_localStorage.js \ + browser_privatebrowsing_localStorage_before_after.js \ + browser_privatebrowsing_localStorage_before_after_page.html \ + browser_privatebrowsing_localStorage_before_after_page2.html \ browser_privatebrowsing_localStorage_page1.html \ browser_privatebrowsing_localStorage_page2.html \ browser_privatebrowsing_opendir.js \ diff --git a/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after.js b/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after.js new file mode 100644 index 000000000000..523d58341edd --- /dev/null +++ b/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after.js @@ -0,0 +1,66 @@ +/* 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/. */ + +// Ensure that a storage instance used by both private and public sessions at different times does not +// allow any data to leak due to cached values. + +// Step 1: Load browser_privatebrowsing_localStorage_before_after_page.html in a private tab, causing a storage +// item to exist. Close the tab. +// Step 2: Load the same page in a non-private tab, ensuring that the storage instance reports only one item +// existing. + +function test() { + // initialization + waitForExplicitFinish(); + let windowsToClose = []; + let testURI = "about:blank"; + let prefix = 'http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/perwindow/'; + + function doTest(aIsPrivateMode, aWindow, aCallback) { + aWindow.gBrowser.selectedBrowser.addEventListener("load", function onLoad() { + aWindow.gBrowser.selectedBrowser.removeEventListener("load", onLoad, true); + + if (aIsPrivateMode) { + // do something when aIsPrivateMode is true + is(aWindow.gBrowser.contentWindow.document.title, '1', "localStorage should contain 1 item"); + } else { + // do something when aIsPrivateMode is false + is(aWindow.gBrowser.contentWindow.document.title, 'null|0', 'localStorage should contain 0 items'); + } + + aCallback(); + }, true); + + aWindow.gBrowser.selectedBrowser.loadURI(testURI); + } + + function testOnWindow(aOptions, aCallback) { + whenNewWindowLoaded(aOptions, function(aWin) { + windowsToClose.push(aWin); + // execute should only be called when need, like when you are opening + // web pages on the test. If calling executeSoon() is not necesary, then + // call whenNewWindowLoaded() instead of testOnWindow() on your test. + executeSoon(function() aCallback(aWin)); + }); + }; + + // this function is called after calling finish() on the test. + registerCleanupFunction(function() { + windowsToClose.forEach(function(aWin) { + aWin.close(); + }); + }); + + // test first when on private mode + testOnWindow({private: true}, function(aWin) { + testURI = prefix + 'browser_privatebrowsing_localStorage_before_after_page.html'; + doTest(true, aWin, function() { + // then test when not on private mode + testOnWindow({}, function(aWin) { + testURI = prefix + 'browser_privatebrowsing_localStorage_before_after_page2.html'; + doTest(false, aWin, finish); + }); + }); + }); +} diff --git a/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after_page.html b/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after_page.html new file mode 100644 index 000000000000..143fea4e72a6 --- /dev/null +++ b/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after_page.html @@ -0,0 +1,11 @@ + + + + + + + diff --git a/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after_page2.html b/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after_page2.html new file mode 100644 index 000000000000..9a7e2da630dd --- /dev/null +++ b/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after_page2.html @@ -0,0 +1,10 @@ + + + + + + + From ff43923ab2e3c88371eeef09eb52c5bb6a0b42bf Mon Sep 17 00:00:00 2001 From: Andres Hernandez Date: Tue, 20 Nov 2012 13:41:40 -0600 Subject: [PATCH 49/75] Bug 806693 - Port browser_privatebrowsing_placestitle.js to the new per-window PB APIs; r=ehsan --HG-- rename : browser/components/privatebrowsing/test/browser/global/browser_privatebrowsing_placestitle.js => browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_placestitle.js rename : browser/components/privatebrowsing/test/browser/global/title.sjs => browser/components/privatebrowsing/test/browser/perwindow/title.sjs --- .../test/browser/perwindow/Makefile.in | 2 + .../browser_privatebrowsing_placestitle.js | 109 ++++++++++++++++++ .../test/browser/perwindow/title.sjs | 22 ++++ 3 files changed, 133 insertions(+) create mode 100644 browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_placestitle.js create mode 100644 browser/components/privatebrowsing/test/browser/perwindow/title.sjs diff --git a/browser/components/privatebrowsing/test/browser/perwindow/Makefile.in b/browser/components/privatebrowsing/test/browser/perwindow/Makefile.in index c2c6d425b499..e36dd32124f5 100644 --- a/browser/components/privatebrowsing/test/browser/perwindow/Makefile.in +++ b/browser/components/privatebrowsing/test/browser/perwindow/Makefile.in @@ -33,6 +33,7 @@ MOCHITEST_BROWSER_FILES = \ browser_privatebrowsing_opendir.js \ browser_privatebrowsing_openlocation.js \ browser_privatebrowsing_openLocationLastURL.js \ + browser_privatebrowsing_placestitle.js \ browser_privatebrowsing_popupblocker.js \ browser_privatebrowsing_protocolhandler.js \ browser_privatebrowsing_protocolhandler_page.html \ @@ -42,6 +43,7 @@ MOCHITEST_BROWSER_FILES = \ browser_privatebrowsing_windowtitle_page.html \ browser_privatebrowsing_zoomrestore.js \ popup.html \ + title.sjs \ $(NULL) include $(topsrcdir)/config/rules.mk diff --git a/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_placestitle.js b/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_placestitle.js new file mode 100644 index 000000000000..18b18abcce15 --- /dev/null +++ b/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_placestitle.js @@ -0,0 +1,109 @@ +/* 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/. */ + +// This test makes sure that the title of existing history entries does not +// change inside a private window. + +function test() { + waitForExplicitFinish(); + + const TEST_URL = "http://mochi.test:8888/browser/browser/components/" + + "privatebrowsing/test/browser/perwindow/title.sjs"; + let cm = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager); + + function waitForCleanup(aCallback) { + // delete all cookies + cm.removeAll(); + // delete all history items + Services.obs.addObserver(function observeCH(aSubject, aTopic, aData) { + Services.obs.removeObserver(observeCH, PlacesUtils.TOPIC_EXPIRATION_FINISHED); + aCallback(); + }, PlacesUtils.TOPIC_EXPIRATION_FINISHED, false); + PlacesUtils.bhistory.removeAllPages(); + } + + let testNumber = 0; + let historyObserver = { + onTitleChanged: function(aURI, aPageTitle) { + if (aURI.spec != TEST_URL) + return; + switch (++testNumber) { + case 1: + // The first time that the page is loaded + is(aPageTitle, "No Cookie", + "The page should be loaded without any cookie for the first time"); + openTestPage(selectedWin); + break; + case 2: + // The second time that the page is loaded + is(aPageTitle, "Cookie", + "The page should be loaded with a cookie for the second time"); + waitForCleanup(function () { + openTestPage(selectedWin); + }); + break; + case 3: + // After clean up + is(aPageTitle, "No Cookie", + "The page should be loaded without any cookie again"); + testOnWindow(true, function(win) { + whenPageLoad(win, function() { + waitForCleanup(finish); + }); + }); + break; + default: + // Checks that opening the page in a private window should not fire a + // title change. + ok(false, "Title changed. Unexpected pass: " + testNumber); + } + }, + + onBeginUpdateBatch: function () {}, + onEndUpdateBatch: function () {}, + onVisit: function () {}, + onBeforeDeleteURI: function () {}, + onDeleteURI: function () {}, + onClearHistory: function () {}, + onPageChanged: function () {}, + onDeleteVisits: function() {}, + QueryInterface: XPCOMUtils.generateQI([Ci.nsINavHistoryObserver]) + }; + PlacesUtils.history.addObserver(historyObserver, false); + + let selectedWin = null; + let windowsToClose = []; + registerCleanupFunction(function() { + PlacesUtils.history.removeObserver(historyObserver); + windowsToClose.forEach(function(win) { + win.close(); + }); + }); + + function openTestPage(aWin) { + aWin.gBrowser.selectedTab = aWin.gBrowser.addTab(TEST_URL); + } + + function whenPageLoad(aWin, aCallback) { + aWin.gBrowser.selectedBrowser.addEventListener("load", function onLoad() { + aWin.gBrowser.selectedBrowser.removeEventListener("load", onLoad, true); + aCallback(); + }, true); + aWin.gBrowser.selectedBrowser.loadURI(TEST_URL); + } + + function testOnWindow(aPrivate, aCallback) { + whenNewWindowLoaded({ private: aPrivate }, function(win) { + selectedWin = win; + windowsToClose.push(win); + executeSoon(function() { aCallback(win) }); + }); + } + + waitForCleanup(function() { + testOnWindow(false, function(win) { + openTestPage(win); + }); + }); +} diff --git a/browser/components/privatebrowsing/test/browser/perwindow/title.sjs b/browser/components/privatebrowsing/test/browser/perwindow/title.sjs new file mode 100644 index 000000000000..568e235be192 --- /dev/null +++ b/browser/components/privatebrowsing/test/browser/perwindow/title.sjs @@ -0,0 +1,22 @@ +/* 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/. */ + +// This provides the tests with a page with different titles based on whether +// a cookie is present or not. + +function handleRequest(request, response) { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "text/html", false); + + var cookie = "name=value"; + var title = "No Cookie"; + if (request.hasHeader("Cookie") && request.getHeader("Cookie") == cookie) + title = "Cookie"; + else + response.setHeader("Set-Cookie", cookie, false); + + response.write(""); + response.write(title); + response.write("test page"); +} From f1d3e667045f211865955eafa8125c8cb1d588d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez?= Date: Tue, 20 Nov 2012 21:50:48 +0100 Subject: [PATCH 50/75] Bug 813468 - [Apps] Unable to install packaged apps when running OOP;r=fabrice --- dom/apps/src/Webapps.jsm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dom/apps/src/Webapps.jsm b/dom/apps/src/Webapps.jsm index 4c00ef6f7e43..30ea7a5bac63 100644 --- a/dom/apps/src/Webapps.jsm +++ b/dom/apps/src/Webapps.jsm @@ -1104,6 +1104,7 @@ this.DOMApplicationRegistry = { appObject.localId = localId; appObject.basePath = FileUtils.getDir(DIRECTORY_NAME, ["webapps"], true, true).path; let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", id], true, true); + dir.permissions = FileUtils.PERMS_DIRECTORY; let manFile = dir.clone(); manFile.append(manifestName); let jsonManifest = aData.isPackage ? app.updateManifest : app.manifest; @@ -1180,6 +1181,7 @@ this.DOMApplicationRegistry = { let zipFile = FileUtils.getFile("TmpD", ["webapps", aId, "application.zip"], true); let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", aId], true, true); zipFile.moveTo(dir, "application.zip"); + zipFile.permissions = FileUtils.PERMS_FILE; let tmpDir = FileUtils.getDir("TmpD", ["webapps", aId], true, true); try { tmpDir.remove(true); From d5505fd697ee2ba3f9cdf90112de0947747a34af Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Tue, 20 Nov 2012 15:59:36 -0500 Subject: [PATCH 51/75] Bug 813705 - Initialize nsresult value before possibly using it. r=roc --- layout/base/nsPresContext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp index 036b483889dd..38f8c5555768 100644 --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -414,7 +414,7 @@ nsPresContext::GetFontPrefsForLang(nsIAtom *aLanguage) const { // Get language group for aLanguage: - nsresult rv; + nsresult rv = NS_OK; nsIAtom *langGroupAtom = nullptr; if (!aLanguage) { aLanguage = mLanguage; From c054a5ad9d9c4b5ccdf371ec63c57322bfdb0bde Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Mon, 5 Nov 2012 12:49:34 -0800 Subject: [PATCH 52/75] Bug 806591 - Add CommonUtils.generateUUID utility function; r=rnewman --- services/common/tests/unit/test_utils_uuid.js | 12 ++++++++++++ services/common/tests/unit/xpcshell.ini | 1 + services/common/utils.js | 16 ++++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 services/common/tests/unit/test_utils_uuid.js diff --git a/services/common/tests/unit/test_utils_uuid.js b/services/common/tests/unit/test_utils_uuid.js new file mode 100644 index 000000000000..f1eabf50e485 --- /dev/null +++ b/services/common/tests/unit/test_utils_uuid.js @@ -0,0 +1,12 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +function run_test() { + let uuid = CommonUtils.generateUUID(); + do_check_eq(uuid.length, 36); + do_check_eq(uuid[8], "-"); + + run_next_test(); +} diff --git a/services/common/tests/unit/xpcshell.ini b/services/common/tests/unit/xpcshell.ini index ceca3805bdca..b8f4a7013100 100644 --- a/services/common/tests/unit/xpcshell.ini +++ b/services/common/tests/unit/xpcshell.ini @@ -15,6 +15,7 @@ tail = [test_utils_namedTimer.js] [test_utils_stackTrace.js] [test_utils_utf8.js] +[test_utils_uuid.js] [test_aitc_server.js] [test_async_chain.js] diff --git a/services/common/utils.js b/services/common/utils.js index abb64318598e..c21c593df461 100644 --- a/services/common/utils.js +++ b/services/common/utils.js @@ -467,6 +467,22 @@ this.CommonUtils = { return new BinaryInputStream(stream).readBytes(count); }, + + /** + * Generate a new UUID using nsIUUIDGenerator. + * + * Example value: "1e00a2e2-1570-443e-bf5e-000354124234" + * + * @return string A hex-formatted UUID string. + */ + generateUUID: function generateUUID() { + let uuid = Cc["@mozilla.org/uuid-generator;1"] + .getService(Ci.nsIUUIDGenerator) + .generateUUID() + .toString(); + + return uuid.substring(1, uuid.length - 1); + }, }; XPCOMUtils.defineLazyGetter(CommonUtils, "_utf8Converter", function() { From 8d86dcf0f018831077d123751d257c4603c9b36a Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Mon, 5 Nov 2012 12:49:42 -0800 Subject: [PATCH 53/75] Bug 807231 - Add CommonUtils.{getDatePref,setDatePref}; r=rnewman --- .../common/tests/unit/test_utils_dateprefs.js | 85 +++++++++++++ services/common/tests/unit/xpcshell.ini | 1 + services/common/utils.js | 113 ++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 services/common/tests/unit/test_utils_dateprefs.js diff --git a/services/common/tests/unit/test_utils_dateprefs.js b/services/common/tests/unit/test_utils_dateprefs.js new file mode 100644 index 000000000000..a11d354c7e5e --- /dev/null +++ b/services/common/tests/unit/test_utils_dateprefs.js @@ -0,0 +1,85 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +Cu.import("resource://services-common/preferences.js"); +Cu.import("resource://services-common/utils.js"); + + +let prefs = new Preferences("servicescommon.tests."); + +function DummyLogger() { + this.messages = []; +} +DummyLogger.prototype.warn = function warn(message) { + this.messages.push(message); +}; + +function run_test() { + run_next_test(); +} + +add_test(function test_set_basic() { + let now = new Date(); + + CommonUtils.setDatePref(prefs, "test00", now); + let value = prefs.get("test00"); + do_check_eq(value, "" + now.getTime()); + + let now2 = CommonUtils.getDatePref(prefs, "test00"); + + do_check_eq(now.getTime(), now2.getTime()); + + run_next_test(); +}); + +add_test(function test_set_bounds_checking() { + let d = new Date(2342354); + + let failed = false; + try { + CommonUtils.setDatePref(prefs, "test01", d); + } catch (ex) { + do_check_true(ex.message.startsWith("Trying to set")); + failed = true; + } + + do_check_true(failed); + run_next_test(); +}); + +add_test(function test_get_bounds_checking() { + prefs.set("test_bounds_checking", "13241431"); + + let log = new DummyLogger(); + let d = CommonUtils.getDatePref(prefs, "test_bounds_checking", 0, log); + do_check_eq(d.getTime(), 0); + do_check_eq(log.messages.length, 1); + + run_next_test(); +}); + +add_test(function test_get_bad_default() { + let failed = false; + try { + CommonUtils.getDatePref(prefs, "get_bad_default", new Date()); + } catch (ex) { + do_check_true(ex.message.startsWith("Default value is not a number")); + failed = true; + } + + do_check_true(failed); + run_next_test(); +}); + +add_test(function test_get_invalid_number() { + prefs.set("get_invalid_number", "hello world"); + + let log = new DummyLogger(); + let d = CommonUtils.getDatePref(prefs, "get_invalid_number", 42, log); + do_check_eq(d.getTime(), 42); + do_check_eq(log.messages.length, 1); + + run_next_test(); +}); diff --git a/services/common/tests/unit/xpcshell.ini b/services/common/tests/unit/xpcshell.ini index b8f4a7013100..cd5c2ff85785 100644 --- a/services/common/tests/unit/xpcshell.ini +++ b/services/common/tests/unit/xpcshell.ini @@ -6,6 +6,7 @@ tail = [test_load_modules.js] [test_utils_atob.js] +[test_utils_dateprefs.js] [test_utils_deepCopy.js] [test_utils_encodeBase32.js] [test_utils_encodeBase64URL.js] diff --git a/services/common/utils.js b/services/common/utils.js index c21c593df461..52d5ce451717 100644 --- a/services/common/utils.js +++ b/services/common/utils.js @@ -483,6 +483,119 @@ this.CommonUtils = { return uuid.substring(1, uuid.length - 1); }, + + /** + * Obtain an epoch value from a preference. + * + * This reads a string preference and returns an integer. The string + * preference is expected to contain the integer milliseconds since epoch. + * For best results, only read preferences that have been saved with + * setDatePref(). + * + * We need to store times as strings because integer preferences are only + * 32 bits and likely overflow most dates. + * + * If the pref contains a non-integer value, the specified default value will + * be returned. + * + * @param branch + * (Preferences) Branch from which to retrieve preference. + * @param pref + * (string) The preference to read from. + * @param def + * (Number) The default value to use if the preference is not defined. + * @param log + * (Log4Moz.Logger) Logger to write warnings to. + */ + getEpochPref: function getEpochPref(branch, pref, def=0, log=null) { + if (!Number.isInteger(def)) { + throw new Error("Default value is not a number: " + def); + } + + let valueStr = branch.get(pref, null); + + if (valueStr !== null) { + let valueInt = parseInt(valueStr, 10); + if (Number.isNaN(valueInt)) { + if (log) { + log.warn("Preference value is not an integer. Using default. " + + pref + "=" + valueStr + " -> " + def); + } + + return def; + } + + return valueInt; + } + + return def; + }, + + /** + * Obtain a Date from a preference. + * + * This is a wrapper around getEpochPref. It converts the value to a Date + * instance and performs simple range checking. + * + * The range checking ensures the date is newer than the oldestYear + * parameter. + * + * @param branch + * (Preferences) Branch from which to read preference. + * @param pref + * (string) The preference from which to read. + * @param def + * (Number) The default value (in milliseconds) if the preference is + * not defined or invalid. + * @param log + * (Log4Moz.Logger) Logger to write warnings to. + * @param oldestYear + * (Number) Oldest year to accept in read values. + */ + getDatePref: function getDatePref(branch, pref, def=0, log=null, + oldestYear=2010) { + + let valueInt = this.getEpochPref(branch, pref, def, log); + let date = new Date(valueInt); + + if (valueInt == def || date.getFullYear() >= oldestYear) { + return date; + } + + if (log) { + log.warn("Unexpected old date seen in pref. Returning default: " + + pref + "=" + date + " -> " + def); + } + + return new Date(def); + }, + + /** + * Store a Date in a preference. + * + * This is the opposite of getDatePref(). The same notes apply. + * + * If the range check fails, an Error will be thrown instead of a default + * value silently being used. + * + * @param branch + * (Preference) Branch from which to read preference. + * @param pref + * (string) Name of preference to write to. + * @param date + * (Date) The value to save. + * @param oldestYear + * (Number) The oldest year to accept for values. + */ + setDatePref: function setDatePref(branch, pref, date, oldestYear=2010) { + if (date.getFullYear() < oldestYear) { + throw new Error("Trying to set " + pref + " to a very old time: " + + date + ". The current time is " + new Date() + + ". Is the system clock wrong?"); + } + + branch.set(pref, "" + date.getTime()); + }, }; XPCOMUtils.defineLazyGetter(CommonUtils, "_utf8Converter", function() { From 24fc9cb26630e07793881ce846b3643734715ca8 Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Tue, 6 Nov 2012 08:37:53 -0800 Subject: [PATCH 54/75] Bug 803377 - Add CommonUtils.convertString; r=rnewman --- .../tests/unit/test_utils_convert_string.js | 55 +++++++++++++++++++ services/common/tests/unit/xpcshell.ini | 1 + services/common/utils.js | 54 ++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 services/common/tests/unit/test_utils_convert_string.js diff --git a/services/common/tests/unit/test_utils_convert_string.js b/services/common/tests/unit/test_utils_convert_string.js new file mode 100644 index 000000000000..bbe94e4027d3 --- /dev/null +++ b/services/common/tests/unit/test_utils_convert_string.js @@ -0,0 +1,55 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +Cu.import("resource://services-common/utils.js"); + + +function run_test() { + run_next_test(); +} + +add_test(function test_compress_string() { + const INPUT = "hello"; + + let result = CommonUtils.convertString(INPUT, "uncompressed", "deflate"); + do_check_eq(result.length, 13); + + let result2 = CommonUtils.convertString(INPUT, "uncompressed", "deflate"); + do_check_eq(result, result2); + + let result3 = CommonUtils.convertString(result, "deflate", "uncompressed"); + do_check_eq(result3, INPUT); + + run_next_test(); +}); + +add_test(function test_compress_utf8() { + const INPUT = "Árvíztűrő tükörfúrógép いろはにほへとちりぬるを Pijamalı hasta, yağız şoföre çabucak güvendi."; + let inputUTF8 = CommonUtils.encodeUTF8(INPUT); + + let compressed = CommonUtils.convertString(inputUTF8, "uncompressed", "deflate"); + let uncompressed = CommonUtils.convertString(compressed, "deflate", "uncompressed"); + + do_check_eq(uncompressed, inputUTF8); + + let outputUTF8 = CommonUtils.decodeUTF8(uncompressed); + do_check_eq(outputUTF8, INPUT); + + run_next_test(); +}); + +add_test(function test_bad_argument() { + let failed = false; + try { + CommonUtils.convertString(null, "uncompressed", "deflate"); + } catch (ex) { + failed = true; + do_check_true(ex.message.startsWith("Input string must be defined")); + } finally { + do_check_true(failed); + } + + run_next_test(); +}); diff --git a/services/common/tests/unit/xpcshell.ini b/services/common/tests/unit/xpcshell.ini index cd5c2ff85785..5709890119f3 100644 --- a/services/common/tests/unit/xpcshell.ini +++ b/services/common/tests/unit/xpcshell.ini @@ -6,6 +6,7 @@ tail = [test_load_modules.js] [test_utils_atob.js] +[test_utils_convert_string.js] [test_utils_dateprefs.js] [test_utils_deepCopy.js] [test_utils_encodeBase32.js] diff --git a/services/common/utils.js b/services/common/utils.js index 52d5ce451717..0922f2fce8ec 100644 --- a/services/common/utils.js +++ b/services/common/utils.js @@ -596,6 +596,55 @@ this.CommonUtils = { branch.set(pref, "" + date.getTime()); }, + + /** + * Convert a string between two encodings. + * + * Output is only guaranteed if the input stream is composed of octets. If + * the input string has characters with values larger than 255, data loss + * will occur. + * + * The returned string is guaranteed to consist of character codes no greater + * than 255. + * + * @param s + * (string) The source string to convert. + * @param source + * (string) The current encoding of the string. + * @param dest + * (string) The target encoding of the string. + * + * @return string + */ + convertString: function convertString(s, source, dest) { + if (!s) { + throw new Error("Input string must be defined."); + } + + let is = Cc["@mozilla.org/io/string-input-stream;1"] + .createInstance(Ci.nsIStringInputStream); + is.setData(s, s.length); + + let listener = Cc["@mozilla.org/network/stream-loader;1"] + .createInstance(Ci.nsIStreamLoader); + + let result; + + listener.init({ + onStreamComplete: function onStreamComplete(loader, context, status, + length, data) { + result = String.fromCharCode.apply(this, data); + }, + }); + + let converter = this._converterService.asyncConvertData(source, dest, + listener, null); + converter.onStartRequest(null, null); + converter.onDataAvailable(null, null, is, 0, s.length); + converter.onStopRequest(null, null, null); + + return result; + }, }; XPCOMUtils.defineLazyGetter(CommonUtils, "_utf8Converter", function() { @@ -604,3 +653,8 @@ XPCOMUtils.defineLazyGetter(CommonUtils, "_utf8Converter", function() { converter.charset = "UTF-8"; return converter; }); + +XPCOMUtils.defineLazyGetter(CommonUtils, "_converterService", function() { + return Cc["@mozilla.org/streamConverters;1"] + .getService(Ci.nsIStreamConverterService); +}); From 1edab3eadbf1266f36f33fe98b14fa4c6fd79d67 Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Mon, 5 Nov 2012 12:49:58 -0800 Subject: [PATCH 55/75] Bug 718067 - Part 1: Create skeletons for services/{metrics,healthreport}; r=rnewman services/metrics will hold generic metrics code. services/healthreport report will build on top of that to provide the Firefox Health Report feature. All functionality will land in subsequent patches. --- b2g/confvars.sh | 2 ++ browser/confvars.sh | 2 ++ configure.in | 12 +++++++++ mobile/android/confvars.sh | 4 +++ mobile/xul/confvars.sh | 2 ++ services/Makefile.in | 9 ++++++- services/healthreport/Makefile.in | 27 +++++++++++++++++++ services/healthreport/tests/Makefile.in | 15 +++++++++++ services/healthreport/tests/xpcshell/head.js | 13 +++++++++ .../tests/xpcshell/test_load_modules.js | 23 ++++++++++++++++ .../healthreport/tests/xpcshell/xpcshell.ini | 5 ++++ services/makefiles.sh | 4 +++ services/metrics/Makefile.in | 27 +++++++++++++++++++ services/metrics/tests/Makefile.in | 15 +++++++++++ services/metrics/tests/xpcshell/head.js | 13 +++++++++ .../tests/xpcshell/test_load_modules.js | 23 ++++++++++++++++ services/metrics/tests/xpcshell/xpcshell.ini | 5 ++++ testing/xpcshell/xpcshell.ini | 2 ++ 18 files changed, 202 insertions(+), 1 deletion(-) mode change 100755 => 100644 mobile/android/confvars.sh create mode 100644 services/healthreport/Makefile.in create mode 100644 services/healthreport/tests/Makefile.in create mode 100644 services/healthreport/tests/xpcshell/head.js create mode 100644 services/healthreport/tests/xpcshell/test_load_modules.js create mode 100644 services/healthreport/tests/xpcshell/xpcshell.ini create mode 100644 services/metrics/Makefile.in create mode 100644 services/metrics/tests/Makefile.in create mode 100644 services/metrics/tests/xpcshell/head.js create mode 100644 services/metrics/tests/xpcshell/test_load_modules.js create mode 100644 services/metrics/tests/xpcshell/xpcshell.ini diff --git a/b2g/confvars.sh b/b2g/confvars.sh index b9506724dfd7..bed44ee4288e 100755 --- a/b2g/confvars.sh +++ b/b2g/confvars.sh @@ -18,6 +18,8 @@ MOZ_OFFICIAL_BRANDING_DIRECTORY=b2g/branding/official MOZ_SAFE_BROWSING= MOZ_SERVICES_COMMON=1 +MOZ_SERVICES_HEALTHREPORT=1 +MOZ_SERVICES_METRICS=1 MOZ_WEBSMS_BACKEND=1 MOZ_DISABLE_DOMCRYPTO=1 diff --git a/browser/confvars.sh b/browser/confvars.sh index fd0ed0bd6477..452fc12e9c5d 100755 --- a/browser/confvars.sh +++ b/browser/confvars.sh @@ -21,6 +21,8 @@ MOZ_SAFE_BROWSING=1 MOZ_SERVICES_AITC=1 MOZ_SERVICES_COMMON=1 MOZ_SERVICES_CRYPTO=1 +MOZ_SERVICES_HEALTHREPORT=1 +MOZ_SERVICES_METRICS=1 MOZ_SERVICES_NOTIFICATIONS=1 MOZ_SERVICES_SYNC=1 MOZ_APP_VERSION=$FIREFOX_VERSION diff --git a/configure.in b/configure.in index 624e57c1c44d..47f8ec4c19ce 100644 --- a/configure.in +++ b/configure.in @@ -8214,6 +8214,18 @@ if test -n "$MOZ_SERVICES_CRYPTO"; then AC_DEFINE(MOZ_SERVICES_CRYPTO) fi +dnl Build Firefox Health Reporter Service +AC_SUBST(MOZ_SERVICES_HEALTHREPORT) +if test -n "$MOZ_SERVICES_HEALTHREPORT"; then + AC_DEFINE(MOZ_SERVICES_HEALTHREPORT) +fi + +dnl Build Services metrics component +AC_SUBST(MOZ_SERVICES_METRICS) +if test -n "$MOZ_SERVICES_METRICS"; then + AC_DEFINE(MOZ_SERVICES_METRICS) +fi + dnl Build Notifications if required AC_SUBST(MOZ_SERVICES_NOTIFICATIONS) if test -n "$MOZ_SERVICES_NOTIFICATIONS"; then diff --git a/mobile/android/confvars.sh b/mobile/android/confvars.sh old mode 100755 new mode 100644 index d8a1d7d33565..51a71763a706 --- a/mobile/android/confvars.sh +++ b/mobile/android/confvars.sh @@ -19,6 +19,10 @@ MOZ_DISABLE_DOMCRYPTO=1 # Enable getUserMedia MOZ_MEDIA_NAVIGATOR=1 +MOZ_SERVICES_COMMON=1 +MOZ_SERVICES_HEALTHREPORT=1 +MOZ_SERVICES_METRICS=1 + if test "$LIBXUL_SDK"; then MOZ_XULRUNNER=1 else diff --git a/mobile/xul/confvars.sh b/mobile/xul/confvars.sh index 4c68d44608e8..ad58f3d02338 100755 --- a/mobile/xul/confvars.sh +++ b/mobile/xul/confvars.sh @@ -15,6 +15,8 @@ MOZ_SAFE_BROWSING= MOZ_SERVICES_COMMON=1 MOZ_SERVICES_CRYPTO=1 +MOZ_SERVICES_HEALTHREPORT=1 +MOZ_SERVICES_METRICS=1 MOZ_SERVICES_SYNC=1 MOZ_DISABLE_DOMCRYPTO=1 diff --git a/services/Makefile.in b/services/Makefile.in index f0c818426ade..f5575e9062c6 100644 --- a/services/Makefile.in +++ b/services/Makefile.in @@ -1,4 +1,3 @@ -# # 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/. @@ -22,6 +21,14 @@ ifdef MOZ_SERVICES_AITC PARALLEL_DIRS += aitc endif +ifdef MOZ_SERVICES_HEALTHREPORT +PARALLEL_DIRS += healthreport +endif + +ifdef MOZ_SERVICES_METRICS +PARALLEL_DIRS += metrics +endif + ifdef MOZ_SERVICES_NOTIFICATIONS PARALLEL_DIRS += notifications endif diff --git a/services/healthreport/Makefile.in b/services/healthreport/Makefile.in new file mode 100644 index 000000000000..63703100490b --- /dev/null +++ b/services/healthreport/Makefile.in @@ -0,0 +1,27 @@ +# 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/. + +DEPTH = @DEPTH@ +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +modules := \ + $(NULL) + +testing_modules := \ + $(NULL) + +TEST_DIRS += tests + +MODULES_FILES := $(modules) +MODULES_DEST = $(FINAL_TARGET)/modules/services/healthreport +INSTALL_TARGETS += MODULES + +TESTING_JS_MODULES := $(addprefix modules-testing/,$(testing_modules)) +TESTING_JS_MODULE_DIR := services/healthreport + +include $(topsrcdir)/config/rules.mk diff --git a/services/healthreport/tests/Makefile.in b/services/healthreport/tests/Makefile.in new file mode 100644 index 000000000000..85f9980a0340 --- /dev/null +++ b/services/healthreport/tests/Makefile.in @@ -0,0 +1,15 @@ +# 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/. + +DEPTH = @DEPTH@ +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ +relativesrcdir = @relativesrcdir@ + +include $(DEPTH)/config/autoconf.mk + +XPCSHELL_TESTS = xpcshell + +include $(topsrcdir)/config/rules.mk diff --git a/services/healthreport/tests/xpcshell/head.js b/services/healthreport/tests/xpcshell/head.js new file mode 100644 index 000000000000..4c9b52df0b0c --- /dev/null +++ b/services/healthreport/tests/xpcshell/head.js @@ -0,0 +1,13 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +(function initMetricsTestingInfrastructure() { + let ns = {}; + Components.utils.import("resource://testing-common/services-common/logging.js", + ns); + + ns.initTestLogging(); +}).call(this); + diff --git a/services/healthreport/tests/xpcshell/test_load_modules.js b/services/healthreport/tests/xpcshell/test_load_modules.js new file mode 100644 index 000000000000..70ab420f9590 --- /dev/null +++ b/services/healthreport/tests/xpcshell/test_load_modules.js @@ -0,0 +1,23 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const modules = [ +]; + +const test_modules = [ +]; + +function run_test() { + for (let m of modules) { + let resource = "resource://gre/modules/services/healthreport/" + m; + Components.utils.import(resource, {}); + } + + for (let m of test_modules) { + let resource = "resource://testing-common/services/healthreport/" + m; + Components.utils.import(resource, {}); + } +} + diff --git a/services/healthreport/tests/xpcshell/xpcshell.ini b/services/healthreport/tests/xpcshell/xpcshell.ini new file mode 100644 index 000000000000..fd7581cfb799 --- /dev/null +++ b/services/healthreport/tests/xpcshell/xpcshell.ini @@ -0,0 +1,5 @@ +[DEFAULT] +head = head.js +tail = + +[test_load_modules.js] diff --git a/services/makefiles.sh b/services/makefiles.sh index 1acfbf2da444..e6a3b920e370 100644 --- a/services/makefiles.sh +++ b/services/makefiles.sh @@ -8,6 +8,8 @@ add_makefiles " services/common/Makefile services/crypto/Makefile services/crypto/component/Makefile + services/healthreport/Makefile + services/metrics/Makefile services/notifications/Makefile services/sync/Makefile services/sync/locales/Makefile @@ -18,6 +20,8 @@ if [ "$ENABLE_TESTS" ]; then services/aitc/tests/Makefile services/common/tests/Makefile services/crypto/tests/Makefile + services/healthreport/tests/Makefile + services/metrics/tests/Makefile services/notifications/tests/Makefile services/sync/tests/Makefile " diff --git a/services/metrics/Makefile.in b/services/metrics/Makefile.in new file mode 100644 index 000000000000..b46acf5f2d4b --- /dev/null +++ b/services/metrics/Makefile.in @@ -0,0 +1,27 @@ +# 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/. + +DEPTH = @DEPTH@ +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +modules := \ + $(NULL) + +testing_modules := \ + $(NULL) + +TEST_DIRS += tests + +MODULES_FILES := $(modules) +MODULES_DEST = $(FINAL_TARGET)/modules/services/metrics +INSTALL_TARGETS += MODULES + +TESTING_JS_MODULES := $(addprefix modules-testing/,$(testing_modules)) +TESTING_JS_MODULE_DIR := services/metrics + +include $(topsrcdir)/config/rules.mk diff --git a/services/metrics/tests/Makefile.in b/services/metrics/tests/Makefile.in new file mode 100644 index 000000000000..85f9980a0340 --- /dev/null +++ b/services/metrics/tests/Makefile.in @@ -0,0 +1,15 @@ +# 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/. + +DEPTH = @DEPTH@ +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ +relativesrcdir = @relativesrcdir@ + +include $(DEPTH)/config/autoconf.mk + +XPCSHELL_TESTS = xpcshell + +include $(topsrcdir)/config/rules.mk diff --git a/services/metrics/tests/xpcshell/head.js b/services/metrics/tests/xpcshell/head.js new file mode 100644 index 000000000000..4c9b52df0b0c --- /dev/null +++ b/services/metrics/tests/xpcshell/head.js @@ -0,0 +1,13 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +(function initMetricsTestingInfrastructure() { + let ns = {}; + Components.utils.import("resource://testing-common/services-common/logging.js", + ns); + + ns.initTestLogging(); +}).call(this); + diff --git a/services/metrics/tests/xpcshell/test_load_modules.js b/services/metrics/tests/xpcshell/test_load_modules.js new file mode 100644 index 000000000000..ce91fbab24fe --- /dev/null +++ b/services/metrics/tests/xpcshell/test_load_modules.js @@ -0,0 +1,23 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const modules = [ +]; + +const test_modules = [ +]; + +function run_test() { + for (let m of modules) { + let resource = "resource://gre/modules/services/metrics/" + m; + Components.utils.import(resource, {}); + } + + for (let m of test_modules) { + let resource = "resource://testing-common/services/metrics/" + m; + Components.utils.import(resource, {}); + } +} + diff --git a/services/metrics/tests/xpcshell/xpcshell.ini b/services/metrics/tests/xpcshell/xpcshell.ini new file mode 100644 index 000000000000..fd7581cfb799 --- /dev/null +++ b/services/metrics/tests/xpcshell/xpcshell.ini @@ -0,0 +1,5 @@ +[DEFAULT] +head = head.js +tail = + +[test_load_modules.js] diff --git a/testing/xpcshell/xpcshell.ini b/testing/xpcshell/xpcshell.ini index 141dd7db7da7..a97a98355c1c 100644 --- a/testing/xpcshell/xpcshell.ini +++ b/testing/xpcshell/xpcshell.ini @@ -85,6 +85,8 @@ skip-if = os == "android" [include:services/common/tests/unit/xpcshell.ini] [include:services/crypto/tests/unit/xpcshell.ini] [include:services/crypto/components/tests/unit/xpcshell.ini] +[include:services/healthreport/tests/xpcshell/xpcshell.ini] +[include:services/metrics/tests/xpcshell/xpcshell.ini] [include:services/notifications/tests/unit/xpcshell.ini] [include:services/sync/tests/unit/xpcshell.ini] # Bug 676978: tests hang on Android From b991b8e9ac42356ca7b6140bafcf4df9daac90a4 Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Mon, 5 Nov 2012 12:50:11 -0800 Subject: [PATCH 56/75] Bug 718067 - Part 2: Define types for representing metrics data; r=rnewman --- services/metrics/Makefile.in | 2 + services/metrics/dataprovider.jsm | 476 ++++++++++++++++++ services/metrics/modules-testing/mocks.jsm | 55 ++ .../tests/xpcshell/test_load_modules.js | 2 + .../test_metrics_collection_result.js | 231 +++++++++ .../xpcshell/test_metrics_measurement.js | 115 +++++ .../tests/xpcshell/test_metrics_provider.js | 63 +++ services/metrics/tests/xpcshell/xpcshell.ini | 3 + 8 files changed, 947 insertions(+) create mode 100644 services/metrics/dataprovider.jsm create mode 100644 services/metrics/modules-testing/mocks.jsm create mode 100644 services/metrics/tests/xpcshell/test_metrics_collection_result.js create mode 100644 services/metrics/tests/xpcshell/test_metrics_measurement.js create mode 100644 services/metrics/tests/xpcshell/test_metrics_provider.js diff --git a/services/metrics/Makefile.in b/services/metrics/Makefile.in index b46acf5f2d4b..d32bcb72347f 100644 --- a/services/metrics/Makefile.in +++ b/services/metrics/Makefile.in @@ -10,9 +10,11 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk modules := \ + dataprovider.jsm \ $(NULL) testing_modules := \ + mocks.jsm \ $(NULL) TEST_DIRS += tests diff --git a/services/metrics/dataprovider.jsm b/services/metrics/dataprovider.jsm new file mode 100644 index 000000000000..c82af71167c1 --- /dev/null +++ b/services/metrics/dataprovider.jsm @@ -0,0 +1,476 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +this.EXPORTED_SYMBOLS = [ + "MetricsCollectionResult", + "MetricsMeasurement", + "MetricsProvider", +]; + +const {utils: Cu} = Components; + +Cu.import("resource://gre/modules/commonjs/promise/core.js"); +Cu.import("resource://services-common/log4moz.js"); + + +/** + * Represents a measurement of data. + * + * This is how data is recorded and represented. Each instance of this type + * represents a related set of data. + * + * Each data set has some basic metadata associated with it. This includes a + * name and version. + * + * This type is meant to be an abstract base type. Child types should define + * a `fields` property which is a mapping of field names to metadata describing + * that field. This field constitutes the "schema" of the measurement/type. + * + * Data is added to instances by calling `setValue()`. Values are validated + * against the schema at add time. + * + * Field Specification + * =================== + * + * The `fields` property is a mapping of string field names to a mapping of + * metadata describing the field. This mapping can have the following + * properties: + * + * type -- A string corresponding to the TYPE_* property name describing a + * field type. The TYPE_* properties are defined on this type. e.g. + * "TYPE_STRING". + * + * optional -- If true, this field is optional. If omitted, the field is + * required. + * + * @param name + * (string) Name of this data set. + * @param version + * (Number) Integer version of the data in this set. + */ +this.MetricsMeasurement = function MetricsMeasurement(name, version) { + if (!this.fields) { + throw new Error("fields not defined on instance. You are likely using " + + "this type incorrectly."); + } + + if (!name) { + throw new Error("Must define a name for this measurement."); + } + + if (!version) { + throw new Error("Must define a version for this measurement."); + } + + if (!Number.isInteger(version)) { + throw new Error("version must be an integer: " + version); + } + + this.name = name; + this.version = version; + + this.values = new Map(); +} + +MetricsMeasurement.prototype = { + /** + * An unsigned integer field stored in 32 bits. + * + * This holds values from 0 to 2^32 - 1. + */ + TYPE_UINT32: { + validate: function validate(value) { + if (!Number.isInteger(value)) { + throw new Error("UINT32 field expects an integer. Got " + value); + } + + if (value < 0) { + throw new Error("UINT32 field expects a positive integer. Got " + value); + } + + if (value >= 0xffffffff) { + throw new Error("Value is too large to fit within 32 bits: " + value); + } + }, + }, + + /** + * A string field. + * + * Values must be valid UTF-8 strings. + */ + TYPE_STRING: { + validate: function validate(value) { + if (typeof(value) != "string") { + throw new Error("STRING field expects a string. Got " + typeof(value)); + } + }, + }, + + /** + * Set the value of a field. + * + * This is ultimately how fields are set. All field sets should go through + * this function. + * + * Values are validated when they are set. If the value passed does not + * validate against the field's specification, an Error will be thrown. + * + * @param name + * (string) The name of the field whose value to set. + * @param value + * The value to set the field to. + */ + setValue: function setValue(name, value) { + if (!this.fields[name]) { + throw new Error("Attempting to set unknown field: " + name); + } + + let type = this.fields[name].type; + + if (!(type in this)) { + throw new Error("Unknown field type: " + type); + } + + this[type].validate(value); + this.values.set(name, value); + }, + + /** + * Obtain the value of a named field. + * + * @param name + * (string) The name of the field to retrieve. + */ + getValue: function getValue(name) { + return this.values.get(name); + }, + + /** + * Validate that this instance is in conformance with the specification. + * + * This ensures all required fields are present. Field value validation + * occurs when individual fields are set. + */ + validate: function validate() { + for (let field in this.fields) { + let spec = this.fields[field]; + + if (!spec.optional && !(field in this.values)) { + throw new Error("Required field not defined: " + field); + } + } + }, + + toJSON: function toJSON() { + let fields = {}; + for (let [k, v] of this.values) { + fields[k] = v; + } + + return { + name: this.name, + version: this.version, + fields: fields, + }; + }, +}; + +Object.freeze(MetricsMeasurement.prototype); + + +/** + * Entity which provides metrics data for recording. + * + * This essentially provides an interface that different systems must implement + * to provide collected metrics data. + * + * This type consists of various collect* functions. These functions are called + * by the metrics collector at different points during the application's + * lifetime. These functions return a `MetricsCollectionResult` instance. + * This type behaves a lot like a promise. It has a `onFinished()` that can chain + * deferred events until after the result is populated. + * + * Implementations of collect* functions should call `createResult()` to create + * a new `MetricsCollectionResult` instance. When called, they should + * initiate population of this instance. Once population has finished (perhaps + * asynchronously), they should call `finish()` on the instance. + * + * Receivers of created `MetricsCollectionResult` instances should wait + * until population has finished. They can do this by chaining on to the + * promise inside that instance by calling `onFinished()`. + * + * The collect* functions can return null to signify that they will never + * provide any data. This is the default implementation. An implemented + * collect* function should *never* return null. Instead, it should return + * a `MetricsCollectionResult` with expected measurements that has finished + * populating (i.e. an empty result). + * + * @param name + * (string) The name of this provider. + */ +this.MetricsProvider = function MetricsProvider(name) { + if (!name) { + throw new Error("MetricsProvider must have a name."); + } + + if (typeof(name) != "string") { + throw new Error("name must be a string. Got: " + typeof(name)); + } + + this._log = Log4Moz.repository.getLogger("Services.Metrics.MetricsProvider"); + + this.name = name; +} + +MetricsProvider.prototype = { + /** + * Collects constant measurements. + * + * Constant measurements are data that doesn't change during the lifetime of + * the application/process. The metrics collector only needs to call this + * once per `MetricsProvider` instance per process lifetime. + */ + collectConstantMeasurements: function collectConstantMeasurements() { + return null; + }, + + /** + * Create a new `MetricsCollectionResult` tied to this provider. + */ + createResult: function createResult() { + return new MetricsCollectionResult(this.name); + }, +}; + +Object.freeze(MetricsProvider.prototype); + + +/** + * Holds the result of metrics collection. + * + * This is the type eventually returned by the MetricsProvider.collect* + * functions. It holds all results and any state/errors that occurred while + * collecting. + * + * This type is essentially a container for `MetricsMeasurement` instances that + * provides some smarts useful for capturing state. + * + * The first things consumers of new instances should do is define the set of + * expected measurements this result will contain via `expectMeasurement`. If + * population of this instance is aborted or times out, downstream consumers + * will know there is missing data. + * + * Next, they should add empty `MetricsMeasurement` instances to it via + * `addMeasurement`. Finally, they should populate these measurements with + * `setValue`. + * + * It is preferred to populate via this type instead of directly on + * `MetricsMeasurement` instances so errors with data population can be + * captured and reported. + * + * Once population has finished, `finish()` must be called. + * + * @param name + * (string) The name of the provider this result came from. + */ +this.MetricsCollectionResult = function MetricsCollectionResult(name) { + if (!name || typeof(name) != "string") { + throw new Error("Must provide name argument to MetricsCollectionResult."); + } + + this._log = Log4Moz.repository.getLogger("Services.Metrics.MetricsCollectionResult"); + + this.name = name; + + this.measurements = new Map(); + this.expectedMeasurements = new Set(); + this.errors = []; + + this._deferred = Promise.defer(); +} + +MetricsCollectionResult.prototype = { + /** + * The Set of `MetricsMeasurement` names currently missing from this result. + */ + get missingMeasurements() { + let missing = new Set(); + + for (let name of this.expectedMeasurements) { + if (this.measurements.has(name)) { + continue; + } + + missing.add(name); + } + + return missing; + }, + + /** + * Record that this result is expected to provide a named measurement. + * + * This function should be called ASAP on new `MetricsCollectionResult` + * instances. It defines expectations about what data should be present. + * + * @param name + * (string) The name of the measurement this result should contain. + */ + expectMeasurement: function expectMeasurement(name) { + this.expectedMeasurements.add(name); + }, + + /** + * Add a `MetricsMeasurement` to this result. + */ + addMeasurement: function addMeasurement(data) { + if (!(data instanceof MetricsMeasurement)) { + throw new Error("addMeasurement expects a MetricsMeasurement instance."); + } + + if (!this.expectedMeasurements.has(data.name)) { + throw new Error("Not expecting this measurement: " + data.name); + } + + if (this.measurements.has(data.name)) { + throw new Error("Measurement of this name already present: " + data.name); + } + + this.measurements.set(data.name, data); + }, + + /** + * Sets the value of a field in a registered measurement instance. + * + * This is a convenience function to set a field on a measurement. If an + * error occurs, it will record that error in the errors container. + * + * Attempting to set a value on a measurement that does not exist results + * in an Error being thrown. Attempting a bad assignment on an existing + * measurement will not throw unless `rethrow` is true. + * + * @param name + * (string) The `MetricsMeasurement` on which to set the value. + * @param field + * (string) The field we are setting. + * @param value + * The value being set. + * @param rethrow + * (bool) Whether to rethrow any errors encountered. + * + * @return bool + * Whether the assignment was successful. + */ + setValue: function setValue(name, field, value, rethrow=false) { + let m = this.measurements.get(name); + if (!m) { + throw new Error("Attempting to operate on an undefined measurement: " + + name); + } + + try { + m.setValue(field, value); + return true; + } catch (ex) { + this.addError(ex); + + if (rethrow) { + throw ex; + } + + return false; + } + }, + + /** + * Record an error that was encountered when populating this result. + */ + addError: function addError(error) { + this.errors.push(error); + }, + + /** + * Aggregate another MetricsCollectionResult into this one. + * + * Instances can only be aggregated together if they belong to the same + * provider (they have the same name). + */ + aggregate: function aggregate(other) { + if (!(other instanceof MetricsCollectionResult)) { + throw new Error("aggregate expects a MetricsCollectionResult instance."); + } + + if (this.name != other.name) { + throw new Error("Can only aggregate MetricsCollectionResult from " + + "the same provider. " + this.name + " != " + other.name); + } + + for (let name of other.expectedMeasurements) { + this.expectedMeasurements.add(name); + } + + for (let [name, m] of other.measurements) { + if (this.measurements.has(name)) { + throw new Error("Incoming result has same measurement as us: " + name); + } + + this.measurements.set(name, m); + } + + this.errors = this.errors.concat(other.errors); + }, + + toJSON: function toJSON() { + let o = { + measurements: {}, + missing: [], + errors: [], + }; + + for (let [name, value] of this.measurements) { + o.measurements[name] = value; + } + + for (let missing of this.missingMeasurements) { + o.missing.push(missing); + } + + for (let error of this.errors) { + if (error.message) { + o.errors.push(error.message); + } else { + o.errors.push(error); + } + } + + return o; + }, + + /** + * Signal that population of the result has finished. + * + * This will resolve the internal promise. + */ + finish: function finish() { + this._deferred.resolve(this); + }, + + /** + * Chain deferred behavior until after the result has finished population. + * + * This is a wrapped around the internal promise's `then`. + * + * We can't call this "then" because the core promise library will get + * confused. + */ + onFinished: function onFinished(onFulfill, onError) { + return this._deferred.promise.then(onFulfill, onError); + }, +}; + +Object.freeze(MetricsCollectionResult.prototype); + diff --git a/services/metrics/modules-testing/mocks.jsm b/services/metrics/modules-testing/mocks.jsm new file mode 100644 index 000000000000..729501dc030f --- /dev/null +++ b/services/metrics/modules-testing/mocks.jsm @@ -0,0 +1,55 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +this.EXPORTED_SYMBOLS = [ + "DummyMeasurement", + "DummyProvider", +]; + +const {utils: Cu} = Components; + +Cu.import("resource://gre/modules/services/metrics/dataprovider.jsm"); + +this.DummyMeasurement = function DummyMeasurement(name="DummyMeasurement") { + MetricsMeasurement.call(this, name, 2); +} +DummyMeasurement.prototype = { + __proto__: MetricsMeasurement.prototype, + + fields: { + "string": { + type: "TYPE_STRING", + }, + + "uint32": { + type: "TYPE_UINT32", + optional: true, + }, + }, +}; + + +this.DummyProvider = function DummyProvider(name="DummyProvider") { + MetricsProvider.call(this, name); + + this.constantMeasurementName = "DummyMeasurement"; +} +DummyProvider.prototype = { + __proto__: MetricsProvider.prototype, + + collectConstantMeasurements: function collectConstantMeasurements() { + let result = this.createResult(); + result.expectMeasurement(this.constantMeasurementName); + result.addMeasurement(new DummyMeasurement(this.constantMeasurementName)); + + result.setValue(this.constantMeasurementName, "string", "foo"); + result.setValue(this.constantMeasurementName, "uint32", 24); + + result.finish(); + + return result; + }, +}; diff --git a/services/metrics/tests/xpcshell/test_load_modules.js b/services/metrics/tests/xpcshell/test_load_modules.js index ce91fbab24fe..9d17c15c8c3e 100644 --- a/services/metrics/tests/xpcshell/test_load_modules.js +++ b/services/metrics/tests/xpcshell/test_load_modules.js @@ -4,9 +4,11 @@ "use strict"; const modules = [ + "dataprovider.jsm", ]; const test_modules = [ + "mocks.jsm", ]; function run_test() { diff --git a/services/metrics/tests/xpcshell/test_metrics_collection_result.js b/services/metrics/tests/xpcshell/test_metrics_collection_result.js new file mode 100644 index 000000000000..3e61a7928b6e --- /dev/null +++ b/services/metrics/tests/xpcshell/test_metrics_collection_result.js @@ -0,0 +1,231 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const {utils: Cu} = Components; + +Cu.import("resource://gre/modules/services/metrics/dataprovider.jsm"); +Cu.import("resource://testing-common/services/metrics/mocks.jsm"); + + +function run_test() { + run_next_test(); +}; + +add_test(function test_constructor() { + let result = new MetricsCollectionResult("foo"); + do_check_eq(result.name, "foo"); + + let failed = false; + try { + new MetricsCollectionResult(); + } catch(ex) { + do_check_true(ex.message.startsWith("Must provide name argument to Metrics")); + failed = true; + } finally { + do_check_true(failed); + } + + run_next_test(); +}); + +add_test(function test_expected_measurements() { + let result = new MetricsCollectionResult("foo"); + do_check_eq(result.missingMeasurements.size(), 0); + + result.expectMeasurement("foo"); + result.expectMeasurement("bar"); + do_check_eq(result.missingMeasurements.size(), 2); + do_check_true(result.missingMeasurements.has("foo")); + do_check_true(result.missingMeasurements.has("bar")); + + run_next_test(); +}); + +add_test(function test_missing_measurements() { + let result = new MetricsCollectionResult("foo"); + + let missing = result.missingMeasurements; + do_check_eq(missing.size(), 0); + + result.expectMeasurement("DummyMeasurement"); + result.expectMeasurement("b"); + + missing = result.missingMeasurements; + do_check_eq(missing.size(), 2); + do_check_true(missing.has("DummyMeasurement")); + do_check_true(missing.has("b")); + + result.addMeasurement(new DummyMeasurement()); + missing = result.missingMeasurements; + do_check_eq(missing.size(), 1); + do_check_true(missing.has("b")); + + run_next_test(); +}); + +add_test(function test_add_measurement() { + let result = new MetricsCollectionResult("add_measurement"); + + let failed = false; + try { + result.addMeasurement(new DummyMeasurement()); + } catch (ex) { + do_check_true(ex.message.startsWith("Not expecting this measurement")); + failed = true; + } finally { + do_check_true(failed); + failed = false; + } + + result.expectMeasurement("foo"); + result.addMeasurement(new DummyMeasurement("foo")); + + do_check_eq(result.measurements.size(), 1); + do_check_true(result.measurements.has("foo")); + + run_next_test(); +}); + +add_test(function test_set_value() { + let result = new MetricsCollectionResult("set_value"); + result.expectMeasurement("DummyMeasurement"); + result.addMeasurement(new DummyMeasurement()); + + do_check_true(result.setValue("DummyMeasurement", "string", "hello world")); + + let failed = false; + try { + result.setValue("unknown", "irrelevant", "irrelevant"); + } catch (ex) { + do_check_true(ex.message.startsWith("Attempting to operate on an undefined measurement")); + failed = true; + } finally { + do_check_true(failed); + failed = false; + } + + do_check_eq(result.errors.length, 0); + do_check_false(result.setValue("DummyMeasurement", "string", 42)); + do_check_eq(result.errors.length, 1); + + try { + result.setValue("DummyMeasurement", "string", 42, true); + } catch (ex) { + failed = true; + } finally { + do_check_true(failed); + failed = false; + } + + run_next_test(); +}); + +add_test(function test_aggregate_bad_argument() { + let result = new MetricsCollectionResult("bad_argument"); + + let failed = false; + try { + result.aggregate(null); + } catch (ex) { + do_check_true(ex.message.startsWith("aggregate expects a MetricsCollection")); + failed = true; + } finally { + do_check_true(failed); + failed = false; + } + + try { + let result2 = new MetricsCollectionResult("bad_argument2"); + result.aggregate(result2); + } catch (ex) { + do_check_true(ex.message.startsWith("Can only aggregate")); + failed = true; + } finally { + do_check_true(failed); + failed = false; + } + + run_next_test(); +}); + +add_test(function test_aggregate_side_effects() { + let result1 = new MetricsCollectionResult("aggregate"); + let result2 = new MetricsCollectionResult("aggregate"); + + result1.expectMeasurement("dummy1"); + result1.expectMeasurement("foo"); + + result2.expectMeasurement("dummy2"); + result2.expectMeasurement("bar"); + + result1.addMeasurement(new DummyMeasurement("dummy1")); + result1.setValue("dummy1", "invalid", "invalid"); + + result2.addMeasurement(new DummyMeasurement("dummy2")); + result2.setValue("dummy2", "another", "invalid"); + + result1.aggregate(result2); + + do_check_eq(result1.expectedMeasurements.size(), 4); + do_check_true(result1.expectedMeasurements.has("bar")); + + do_check_eq(result1.measurements.size(), 2); + do_check_true(result1.measurements.has("dummy1")); + do_check_true(result1.measurements.has("dummy2")); + + do_check_eq(result1.missingMeasurements.size(), 2); + do_check_true(result1.missingMeasurements.has("bar")); + + do_check_eq(result1.errors.length, 2); + + run_next_test(); +}); + +add_test(function test_json() { + let result = new MetricsCollectionResult("json"); + result.expectMeasurement("dummy1"); + result.expectMeasurement("dummy2"); + result.expectMeasurement("missing1"); + result.expectMeasurement("missing2"); + + result.addMeasurement(new DummyMeasurement("dummy1")); + result.addMeasurement(new DummyMeasurement("dummy2")); + + result.setValue("dummy1", "string", "hello world"); + result.setValue("dummy2", "uint32", 42); + result.setValue("dummy1", "invalid", "irrelevant"); + + let json = JSON.parse(JSON.stringify(result)); + + do_check_eq(Object.keys(json).length, 3); + do_check_true("measurements" in json); + do_check_true("missing" in json); + do_check_true("errors" in json); + + do_check_eq(Object.keys(json.measurements).length, 2); + do_check_true("dummy1" in json.measurements); + do_check_true("dummy2" in json.measurements); + + do_check_eq(json.missing.length, 2); + let missing = new Set(json.missing); + do_check_true(missing.has("missing1")); + do_check_true(missing.has("missing2")); + + do_check_eq(json.errors.length, 1); + + run_next_test(); +}); + +add_test(function test_finish() { + let result = new MetricsCollectionResult("finish"); + + result.onFinished(function onFinished(result2) { + do_check_eq(result, result2); + + run_next_test(); + }); + + result.finish(); +}); diff --git a/services/metrics/tests/xpcshell/test_metrics_measurement.js b/services/metrics/tests/xpcshell/test_metrics_measurement.js new file mode 100644 index 000000000000..6daac3f036c2 --- /dev/null +++ b/services/metrics/tests/xpcshell/test_metrics_measurement.js @@ -0,0 +1,115 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const {utils: Cu} = Components; + +Cu.import("resource://testing-common/services/metrics/mocks.jsm"); + + +function run_test() { + run_next_test(); +}; + +add_test(function test_constructor() { + let m = new DummyMeasurement(); + do_check_eq(m.name, "DummyMeasurement"); + do_check_eq(m.version, 2); + + run_next_test(); +}); + +add_test(function test_add_string() { + let m = new DummyMeasurement(); + + m.setValue("string", "hello world"); + do_check_eq(m.getValue("string"), "hello world"); + + let failed = false; + try { + m.setValue("string", 46); + } catch (ex) { + do_check_true(ex.message.startsWith("STRING field expects a string")); + failed = true; + } finally { + do_check_true(failed); + } + + run_next_test(); +}); + +add_test(function test_add_uint32() { + let m = new DummyMeasurement(); + + m.setValue("uint32", 52342); + do_check_eq(m.getValue("uint32"), 52342); + + let failed = false; + try { + m.setValue("uint32", -1); + } catch (ex) { + failed = true; + do_check_true(ex.message.startsWith("UINT32 field expects a positive")); + } finally { + do_check_true(failed); + failed = false; + } + + try { + m.setValue("uint32", "foo"); + } catch (ex) { + failed = true; + do_check_true(ex.message.startsWith("UINT32 field expects an integer")); + } finally { + do_check_true(failed); + failed = false; + } + + try { + m.setValue("uint32", Math.pow(2, 32)); + } catch (ex) { + failed = true; + do_check_true(ex.message.startsWith("Value is too large")); + } finally { + do_check_true(failed); + failed = false; + } + + run_next_test(); +}); + +add_test(function test_validate() { + let m = new DummyMeasurement(); + + let failed = false; + try { + m.validate(); + } catch (ex) { + failed = true; + do_check_true(ex.message.startsWith("Required field not defined")); + } finally { + do_check_true(failed); + failed = false; + } + + run_next_test(); +}); + +add_test(function test_toJSON() { + let m = new DummyMeasurement(); + + m.setValue("string", "foo bar"); + + let json = JSON.parse(JSON.stringify(m)); + do_check_eq(Object.keys(json).length, 3); + do_check_eq(json.name, "DummyMeasurement"); + do_check_eq(json.version, 2); + do_check_true("fields" in json); + + do_check_eq(Object.keys(json.fields).length, 1); + do_check_eq(json.fields.string, "foo bar"); + + run_next_test(); +}); + diff --git a/services/metrics/tests/xpcshell/test_metrics_provider.js b/services/metrics/tests/xpcshell/test_metrics_provider.js new file mode 100644 index 000000000000..b7a2f5d1ace0 --- /dev/null +++ b/services/metrics/tests/xpcshell/test_metrics_provider.js @@ -0,0 +1,63 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const {utils: Cu} = Components; + +Cu.import("resource://gre/modules/services/metrics/dataprovider.jsm"); +Cu.import("resource://testing-common/services/metrics/mocks.jsm"); + + +function run_test() { + run_next_test(); +}; + +add_test(function test_constructor() { + let provider = new MetricsProvider("foo"); + + let failed = false; + try { + new MetricsProvider(); + } catch(ex) { + do_check_true(ex.message.startsWith("MetricsProvider must have a name")); + failed = true; + } + finally { + do_check_true(failed); + } + + run_next_test(); +}); + +add_test(function test_default_collectors() { + let provider = new MetricsProvider("foo"); + + for (let property in MetricsProvider.prototype) { + if (!property.startsWith("collect")) { + continue; + } + + let result = provider[property](); + do_check_null(result); + } + + run_next_test(); +}); + +add_test(function test_collect_synchronous() { + let provider = new DummyProvider(); + + let result = provider.collectConstantMeasurements(); + do_check_true(result instanceof MetricsCollectionResult); + + result.onFinished(function onResult(res2) { + do_check_eq(result, res2); + + let m = result.measurements.get("DummyMeasurement"); + do_check_eq(m.getValue("uint32"), 24); + + run_next_test(); + }); +}); + diff --git a/services/metrics/tests/xpcshell/xpcshell.ini b/services/metrics/tests/xpcshell/xpcshell.ini index fd7581cfb799..1f96d51f441d 100644 --- a/services/metrics/tests/xpcshell/xpcshell.ini +++ b/services/metrics/tests/xpcshell/xpcshell.ini @@ -3,3 +3,6 @@ head = head.js tail = [test_load_modules.js] +[test_metrics_collection_result.js] +[test_metrics_measurement.js] +[test_metrics_provider.js] From 56416b1cffd534b3f1998519bce2ba5b4a3223c7 Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Mon, 5 Nov 2012 13:45:35 -0800 Subject: [PATCH 57/75] Bug 718067 - Part 3: Add MetricsCollector; r=rnewman --- services/metrics/Makefile.in | 1 + services/metrics/collector.jsm | 140 ++++++++++++++++++ services/metrics/modules-testing/mocks.jsm | 3 + .../tests/xpcshell/test_load_modules.js | 1 + .../test_metrics_collection_result.js | 18 +-- .../tests/xpcshell/test_metrics_collector.js | 124 ++++++++++++++++ services/metrics/tests/xpcshell/xpcshell.ini | 1 + 7 files changed, 279 insertions(+), 9 deletions(-) create mode 100644 services/metrics/collector.jsm create mode 100644 services/metrics/tests/xpcshell/test_metrics_collector.js diff --git a/services/metrics/Makefile.in b/services/metrics/Makefile.in index d32bcb72347f..db4e556ec204 100644 --- a/services/metrics/Makefile.in +++ b/services/metrics/Makefile.in @@ -10,6 +10,7 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk modules := \ + collector.jsm \ dataprovider.jsm \ $(NULL) diff --git a/services/metrics/collector.jsm b/services/metrics/collector.jsm new file mode 100644 index 000000000000..f4ff9f4b28e4 --- /dev/null +++ b/services/metrics/collector.jsm @@ -0,0 +1,140 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +this.EXPORTED_SYMBOLS = ["MetricsCollector"]; + +const {utils: Cu} = Components; + +Cu.import("resource://gre/modules/commonjs/promise/core.js"); +Cu.import("resource://services-common/log4moz.js"); +Cu.import("resource://gre/modules/services/metrics/dataprovider.jsm"); + + +/** + * Handles and coordinates the collection of metrics data from providers. + * + * This provides an interface for managing `MetricsProvider` instances. It + * provides APIs for bulk collection of data. + */ +this.MetricsCollector = function MetricsCollector() { + this._log = Log4Moz.repository.getLogger("Metrics.MetricsCollector"); + + this._providers = []; + this.collectionResults = new Map(); +} + +MetricsCollector.prototype = { + /** + * Registers a `MetricsProvider` with this collector. + * + * Once a `MetricsProvider` is registered, data will be collected from it + * whenever we collect data. + * + * @param provider + * (MetricsProvider) The provider instance to register. + */ + registerProvider: function registerProvider(provider) { + if (!(provider instanceof MetricsProvider)) { + throw new Error("argument must be a MetricsProvider instance."); + } + + for (let p of this._providers) { + if (p.provider == provider) { + return; + } + } + + this._providers.push({ + provider: provider, + constantsCollected: false, + }); + }, + + /** + * Collects all constant measurements from all providers. + * + * Returns a Promise that will be fulfilled once all data providers have + * provided their constant data. A side-effect of this promise fulfillment + * is that the collector is populated with the obtained collection results. + * The resolved value to the promise is this `MetricsCollector` instance. + */ + collectConstantMeasurements: function collectConstantMeasurements() { + let promises = []; + + for (let provider of this._providers) { + if (provider.constantsCollected) { + this._log.trace("Provider has already provided constant data: " + + provider.name); + continue; + } + + let result = provider.provider.collectConstantMeasurements(); + if (!result) { + this._log.trace("Provider does not provide constant data: " + + provider.name); + continue; + } + + // Chain an invisible promise that updates state. + let promise = result.onFinished(function onFinished(result) { + provider.constantsCollected = true; + + return Promise.resolve(result); + }); + + promises.push(promise); + } + + return this._handleCollectionPromises(promises); + }, + + /** + * Handles promises returned by the collect* functions. + * + * This consumes the data resolved by the promises and returns a new promise + * that will be resolved once all promises have been resolved. + */ + _handleCollectionPromises: function _handleCollectionPromises(promises) { + if (!promises.length) { + return Promise.resolve(this); + } + + let deferred = Promise.defer(); + let finishedCount = 0; + + let onResult = function onResult(result) { + try { + this._log.debug("Got result for " + result.name); + + if (this.collectionResults.has(result.name)) { + this.collectionResults.get(result.name).aggregate(result); + } else { + this.collectionResults.set(result.name, result); + } + } finally { + finishedCount++; + if (finishedCount >= promises.length) { + deferred.resolve(this); + } + } + }.bind(this); + + let onError = function onError(error) { + this._log.warn("Error when handling result: " + + CommonUtils.exceptionStr(error)); + deferred.reject(error); + }.bind(this); + + for (let promise of promises) { + promise.then(onResult, onError); + } + + return deferred.promise; + }, +}; + +Object.freeze(MetricsCollector.prototype); + diff --git a/services/metrics/modules-testing/mocks.jsm b/services/metrics/modules-testing/mocks.jsm index 729501dc030f..05623a3297f2 100644 --- a/services/metrics/modules-testing/mocks.jsm +++ b/services/metrics/modules-testing/mocks.jsm @@ -36,11 +36,14 @@ this.DummyProvider = function DummyProvider(name="DummyProvider") { MetricsProvider.call(this, name); this.constantMeasurementName = "DummyMeasurement"; + this.collectConstantCount = 0; } DummyProvider.prototype = { __proto__: MetricsProvider.prototype, collectConstantMeasurements: function collectConstantMeasurements() { + this.collectConstantCount++; + let result = this.createResult(); result.expectMeasurement(this.constantMeasurementName); result.addMeasurement(new DummyMeasurement(this.constantMeasurementName)); diff --git a/services/metrics/tests/xpcshell/test_load_modules.js b/services/metrics/tests/xpcshell/test_load_modules.js index 9d17c15c8c3e..e597a926b7e2 100644 --- a/services/metrics/tests/xpcshell/test_load_modules.js +++ b/services/metrics/tests/xpcshell/test_load_modules.js @@ -4,6 +4,7 @@ "use strict"; const modules = [ + "collector.jsm", "dataprovider.jsm", ]; diff --git a/services/metrics/tests/xpcshell/test_metrics_collection_result.js b/services/metrics/tests/xpcshell/test_metrics_collection_result.js index 3e61a7928b6e..57bb9a4dd885 100644 --- a/services/metrics/tests/xpcshell/test_metrics_collection_result.js +++ b/services/metrics/tests/xpcshell/test_metrics_collection_result.js @@ -32,11 +32,11 @@ add_test(function test_constructor() { add_test(function test_expected_measurements() { let result = new MetricsCollectionResult("foo"); - do_check_eq(result.missingMeasurements.size(), 0); + do_check_eq(result.missingMeasurements.size0); result.expectMeasurement("foo"); result.expectMeasurement("bar"); - do_check_eq(result.missingMeasurements.size(), 2); + do_check_eq(result.missingMeasurements.size, 2); do_check_true(result.missingMeasurements.has("foo")); do_check_true(result.missingMeasurements.has("bar")); @@ -47,19 +47,19 @@ add_test(function test_missing_measurements() { let result = new MetricsCollectionResult("foo"); let missing = result.missingMeasurements; - do_check_eq(missing.size(), 0); + do_check_eq(missing.size, 0); result.expectMeasurement("DummyMeasurement"); result.expectMeasurement("b"); missing = result.missingMeasurements; - do_check_eq(missing.size(), 2); + do_check_eq(missing.size, 2); do_check_true(missing.has("DummyMeasurement")); do_check_true(missing.has("b")); result.addMeasurement(new DummyMeasurement()); missing = result.missingMeasurements; - do_check_eq(missing.size(), 1); + do_check_eq(missing.size, 1); do_check_true(missing.has("b")); run_next_test(); @@ -82,7 +82,7 @@ add_test(function test_add_measurement() { result.expectMeasurement("foo"); result.addMeasurement(new DummyMeasurement("foo")); - do_check_eq(result.measurements.size(), 1); + do_check_eq(result.measurements.size, 1); do_check_true(result.measurements.has("foo")); run_next_test(); @@ -168,14 +168,14 @@ add_test(function test_aggregate_side_effects() { result1.aggregate(result2); - do_check_eq(result1.expectedMeasurements.size(), 4); + do_check_eq(result1.expectedMeasurements.size, 4); do_check_true(result1.expectedMeasurements.has("bar")); - do_check_eq(result1.measurements.size(), 2); + do_check_eq(result1.measurements.size, 2); do_check_true(result1.measurements.has("dummy1")); do_check_true(result1.measurements.has("dummy2")); - do_check_eq(result1.missingMeasurements.size(), 2); + do_check_eq(result1.missingMeasurements.size, 2); do_check_true(result1.missingMeasurements.has("bar")); do_check_eq(result1.errors.length, 2); diff --git a/services/metrics/tests/xpcshell/test_metrics_collector.js b/services/metrics/tests/xpcshell/test_metrics_collector.js new file mode 100644 index 000000000000..cb63de34fd6b --- /dev/null +++ b/services/metrics/tests/xpcshell/test_metrics_collector.js @@ -0,0 +1,124 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const {utils: Cu} = Components; + +Cu.import("resource://gre/modules/services/metrics/collector.jsm"); +Cu.import("resource://gre/modules/services/metrics/dataprovider.jsm"); +Cu.import("resource://testing-common/services/metrics/mocks.jsm"); + + +function run_test() { + run_next_test(); +}; + +add_test(function test_constructor() { + let collector = new MetricsCollector(); + + run_next_test(); +}); + +add_test(function test_register_provider() { + let collector = new MetricsCollector(); + let dummy = new DummyProvider(); + + collector.registerProvider(dummy); + do_check_eq(collector._providers.length, 1); + collector.registerProvider(dummy); + do_check_eq(collector._providers.length, 1); + + let failed = false; + try { + collector.registerProvider({}); + } catch (ex) { + do_check_true(ex.message.startsWith("argument must be a MetricsProvider")); + failed = true; + } finally { + do_check_true(failed); + failed = false; + } + + run_next_test(); +}); + +add_test(function test_collect_constant_measurements() { + let collector = new MetricsCollector(); + let provider = new DummyProvider(); + collector.registerProvider(provider); + + do_check_eq(provider.collectConstantCount, 0); + + collector.collectConstantMeasurements().then(function onResult() { + do_check_eq(provider.collectConstantCount, 1); + do_check_eq(collector.collectionResults.size, 1); + do_check_true(collector.collectionResults.has("DummyProvider")); + + let result = collector.collectionResults.get("DummyProvider"); + do_check_true(result instanceof MetricsCollectionResult); + + do_check_true(collector._providers[0].constantsCollected); + + run_next_test(); + }); +}); + +add_test(function test_collect_constant_onetime() { + let collector = new MetricsCollector(); + let provider = new DummyProvider(); + collector.registerProvider(provider); + + collector.collectConstantMeasurements().then(function onResult() { + do_check_eq(provider.collectConstantCount, 1); + + collector.collectConstantMeasurements().then(function onResult() { + do_check_eq(provider.collectConstantCount, 1); + + run_next_test(); + }); + }); +}); + +add_test(function test_collect_multiple() { + let collector = new MetricsCollector(); + + for (let i = 0; i < 10; i++) { + collector.registerProvider(new DummyProvider("provider" + i)); + } + + do_check_eq(collector._providers.length, 10); + + collector.collectConstantMeasurements().then(function onResult(innerCollector) { + do_check_eq(collector, innerCollector); + do_check_eq(collector.collectionResults.size, 10); + + run_next_test(); + }); +}); + +add_test(function test_collect_aggregate() { + let collector = new MetricsCollector(); + + let dummy1 = new DummyProvider(); + dummy1.constantMeasurementName = "measurement1"; + + let dummy2 = new DummyProvider(); + dummy2.constantMeasurementName = "measurement2"; + + collector.registerProvider(dummy1); + collector.registerProvider(dummy2); + do_check_eq(collector._providers.length, 2); + + collector.collectConstantMeasurements().then(function onResult() { + do_check_eq(collector.collectionResults.size, 1); + + let measurements = collector.collectionResults.get("DummyProvider").measurements; + do_check_eq(measurements.size, 2); + do_check_true(measurements.has("measurement1")); + do_check_true(measurements.has("measurement2")); + + run_next_test(); + }); +}); + diff --git a/services/metrics/tests/xpcshell/xpcshell.ini b/services/metrics/tests/xpcshell/xpcshell.ini index 1f96d51f441d..ec8bae4899bb 100644 --- a/services/metrics/tests/xpcshell/xpcshell.ini +++ b/services/metrics/tests/xpcshell/xpcshell.ini @@ -6,3 +6,4 @@ tail = [test_metrics_collection_result.js] [test_metrics_measurement.js] [test_metrics_provider.js] +[test_metrics_collector.js] From f26f0a02e2e42eef4ce321f4563ec11f2ce09423 Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Wed, 7 Nov 2012 16:09:13 -0800 Subject: [PATCH 58/75] Bug 804491 - Data submission policy and scheduling driver for Firefox Health Report; r=rnewman --- services/healthreport/Makefile.in | 2 + .../healthreport/modules-testing/mocks.jsm | 37 + services/healthreport/policy.jsm | 850 ++++++++++++++++++ .../tests/xpcshell/test_load_modules.js | 2 + .../tests/xpcshell/test_policy.js | 538 +++++++++++ .../healthreport/tests/xpcshell/xpcshell.ini | 1 + 6 files changed, 1430 insertions(+) create mode 100644 services/healthreport/modules-testing/mocks.jsm create mode 100644 services/healthreport/policy.jsm create mode 100644 services/healthreport/tests/xpcshell/test_policy.js diff --git a/services/healthreport/Makefile.in b/services/healthreport/Makefile.in index 63703100490b..835c6f4a720e 100644 --- a/services/healthreport/Makefile.in +++ b/services/healthreport/Makefile.in @@ -10,9 +10,11 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk modules := \ + policy.jsm \ $(NULL) testing_modules := \ + mocks.jsm \ $(NULL) TEST_DIRS += tests diff --git a/services/healthreport/modules-testing/mocks.jsm b/services/healthreport/modules-testing/mocks.jsm new file mode 100644 index 000000000000..fbd377c751ef --- /dev/null +++ b/services/healthreport/modules-testing/mocks.jsm @@ -0,0 +1,37 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +this.EXPORTED_SYMBOLS = ["MockPolicyListener"]; + +const {utils: Cu} = Components; + +Cu.import("resource://services-common/log4moz.js"); + + +this.MockPolicyListener = function MockPolicyListener() { + this._log = Log4Moz.repository.getLogger("HealthReport.Testing.MockPolicyListener"); + this._log.level = Log4Moz.Level["Debug"]; + + this.requestDataSubmissionCount = 0; + this.lastDataRequest = null; + + this.notifyUserCount = 0; + this.lastNotifyRequest = null; +} + +MockPolicyListener.prototype = { + onRequestDataSubmission: function onRequestDataSubmission(request) { + this._log.info("onRequestDataSubmission invoked."); + this.requestDataSubmissionCount++; + this.lastDataRequest = request; + }, + + onNotifyDataPolicy: function onNotifyDataPolicy(request) { + this._log.info("onNotifyUser invoked."); + this.notifyUserCount++; + this.lastNotifyRequest = request; + }, +}; diff --git a/services/healthreport/policy.jsm b/services/healthreport/policy.jsm new file mode 100644 index 000000000000..39d64c70eb8e --- /dev/null +++ b/services/healthreport/policy.jsm @@ -0,0 +1,850 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +this.EXPORTED_SYMBOLS = [ + "HealthReportPolicy", +]; + +const {classes: Cc, interfaces: Ci, utils: Cu} = Components; + +Cu.import("resource://gre/modules/commonjs/promise/core.js"); +Cu.import("resource://gre/modules/services-common/log4moz.js"); +Cu.import("resource://gre/modules/services-common/utils.js"); + +const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000; + +// Used as a sanity lower bound for dates stored in prefs. This module was +// implemented in 2012, so any earlier dates indicate an incorrect clock. +const OLDEST_ALLOWED_YEAR = 2012; + +/** + * Represents a request to display data policy. + * + * Instances of this are created when the policy is requesting the user's + * approval to agree to the data submission policy. + * + * Receivers of these instances are expected to call one or more of the on* + * functions when events occur. + * + * When one of these requests is received, the first thing a callee should do + * is present notification to the user of the data policy. When the notice + * is displayed to the user, the callee should call `onUserNotifyComplete`. + * This begins a countdown timer that upon completion will signal implicit + * acceptance of the policy. If for whatever reason the callee could not + * display a notice, it should call `onUserNotifyFailed`. + * + * Once the user is notified of the policy, the callee has the option of + * signaling explicit user acceptance or rejection of the policy. They do this + * by calling `onUserAccept` or `onUserReject`, respectively. These functions + * are essentially proxies to + * HealthReportPolicy.{recordUserAcceptance,recordUserRejection}. + * + * If the user never explicitly accepts or rejects the policy, it will be + * implicitly accepted after a specified duration of time. The notice is + * expected to remain displayed even after implicit acceptance (in case the + * user is away from the device). So, no event signaling implicit acceptance + * is exposed. + * + * Receivers of instances of this type should treat it as a black box with + * the exception of the on* functions. + * + * @param policy + * (HealthReportPolicy) The policy instance this request came from. + * @param promise + * (deferred) The promise that will be fulfilled when display occurs. + */ +function NotifyPolicyRequest(policy, promise) { + this.policy = policy; + this.promise = promise; +} +NotifyPolicyRequest.prototype = { + /** + * Called when the user is notified of the policy. + * + * This starts a countdown timer that will eventually signify implicit + * acceptance of the data policy. + */ + onUserNotifyComplete: function onUserNotified() { + this.promise.resolve(); + }, + + /** + * Called when there was an error notifying the user about the policy. + * + * @param error + * (Error) Explains what went wrong. + */ + onUserNotifyFailed: function onUserNotifyFailed(error) { + this.promise.reject(error); + }, + + /** + * Called when the user agreed to the data policy. + * + * @param reason + * (string) How the user agreed to the policy. + */ + onUserAccept: function onUserAccept(reason) { + this.policy.recordUserAcceptance(reason); + }, + + /** + * Called when the user rejected the data policy. + * + * @param reason + * (string) How the user rejected the policy. + */ + onUserReject: function onUserReject(reason) { + this.policy.recordUserRejection(reason); + }, +}; + +Object.freeze(NotifyPolicyRequest.prototype); + +/** + * Represents a request to submit data. + * + * Instances of this are created when the policy requests data submission. + * Receivers are expected to call one of the provided on* functions to signal + * completion of the request. + * + * Instances of this type should not be instantiated outside of this file. + * Receivers of instances of this type should not attempt to do anything with + * the instance except call one of the on* methods. + */ +function DataSubmissionRequest(promise, expiresDate) { + this.promise = promise; + this.expiresDate = expiresDate; + + this.state = null; + this.reason = null; +} + +DataSubmissionRequest.prototype = { + NO_DATA_AVAILABLE: "no-data-available", + SUBMISSION_SUCCESS: "success", + SUBMISSION_FAILURE_SOFT: "failure-soft", + SUBMISSION_FAILURE_HARD: "failure-hard", + + /** + * No submission was attempted because no data was available. + */ + onNoDataAvailable: function onNoDataAvailable() { + this.state = this.NO_DATA_AVAILABLE; + this.promise.resolve(this); + }, + + /** + * Data submission has completed successfully. + * + * @param date + * (Date) When data submission occurred. + */ + onSubmissionSuccess: function onSubmissionSuccess(date) { + this.state = this.SUBMISSION_SUCCESS; + this.submissionDate = date; + this.promise.resolve(this); + }, + + /** + * There was a recoverable failure when submitting data. + * + * Perhaps the server was down. Perhaps the network wasn't available. The + * policy may request submission again after a short delay. + * + * @param reason + * (string) Why the failure occurred. For logging purposes only. + */ + onSubmissionFailureSoft: function onSubmissionFailureSoft(reason=null) { + this.state = this.SUBMISSION_FAILURE_SOFT; + this.reason = reason; + this.promise.resolve(this); + }, + + /** + * There was an unrecoverable failure when submitting data. + * + * Perhaps the client is misconfigured. Perhaps the server rejected the data. + * Attempts at performing submission again will yield the same result. So, + * the policy should not try again (until the next day). + * + * @param reason + * (string) Why the failure occurred. For logging purposes only. + */ + onSubmissionFailureHard: function onSubmissionFailureHard(reason=null) { + this.state = this.SUBMISSION_FAILURE_HARD; + this.reason = reason; + this.promise.resolve(this); + }, +}; + +Object.freeze(DataSubmissionRequest.prototype); + +/** + * Manages scheduling of Firefox Health Report data submission. + * + * The rules of data submission are as follows: + * + * 1. Do not submit data more than once every 24 hours. + * 2. Try to submit as close to 24 hours apart as possible. + * 3. Do not submit too soon after application startup so as to not negatively + * impact performance at startup. + * 4. Before first ever data submission, the user should be notified about + * data collection practices. + * 5. User should have opportunity to react to this notification before + * data submission. + * 6. Display of notification without any explicit user action constitutes + * implicit consent after a certain duration of time. + * 7. If data submission fails, try at most 2 additional times before giving + * up on that day's submission. + * + * The listener passed into the instance must have the following properties + * (which are callbacks that will be invoked at certain key events): + * + * * onRequestDataSubmission(request) - Called when the policy is requesting + * data to be submitted. The function is passed a `DataSubmissionRequest`. + * The listener should call one of the special resolving functions on that + * instance (see the documentation for that type). + * + * * onNotifyDataPolicy(request) - Called when the policy is requesting the + * user to be notified that data submission will occur. The function + * receives a `NotifyPolicyRequest` instance. The callee should call one or + * more of the functions on that instance when specific events occur. See + * the documentation for that type for more. + * + * Note that the notification method is abstracted. Different applications + * can have different mechanisms by which they notify the user of data + * submission practices. + * + * @param prefs + * (Preferences) Handle on preferences branch on which state will be + * queried and stored. + * @param listener + * (object) Object with callbacks that will be invoked at certain key + * events. + */ +this.HealthReportPolicy = function HealthReportPolicy(prefs, listener) { + this._log = Log4Moz.repository.getLogger("HealthReport.Policy"); + this._log.level = Log4Moz.Level["Debug"]; + + for (let handler of this.REQUIRED_LISTENERS) { + if (!listener[handler]) { + throw new Error("Passed listener does not contain required handler: " + + handler); + } + } + + this._prefs = prefs; + this._listener = listener; + + // If we've never run before, record the current time. + if (!this.firstRunDate.getTime()) { + this.firstRunDate = this.now(); + } + + // Ensure we are scheduled to submit. + if (!this.nextDataSubmissionDate.getTime()) { + this.nextDataSubmissionDate = this._futureDate(MILLISECONDS_PER_DAY); + } + + // Date at which we performed user notification of acceptance. + // This is an instance variable because implicit acceptance should only + // carry forward through a single application instance. + this._dataSubmissionPolicyNotifiedDate = null; + + // Record when we last requested for submitted data to be sent. This is + // to avoid having multiple outstanding requests. + this._inProgressSubmissionRequest = null; +} + +HealthReportPolicy.prototype = { + /** + * How long after first run we should notify about data submission. + */ + SUBMISSION_NOTIFY_INTERVAL_MSEC: 12 * 60 * 60 * 1000, + + /** + * Time that must elapse with no user action for implicit acceptance. + * + * THERE ARE POTENTIAL LEGAL IMPLICATIONS OF CHANGING THIS VALUE. Check with + * Privacy and/or Legal before modifying. + */ + IMPLICIT_ACCEPTANCE_INTERVAL_MSEC: 5 * 60 * 1000, + + /** + * How often to poll to see if we need to do something. + * + * The interval needs to be short enough such that short-lived applications + * have an opportunity to submit data. But, it also needs to be long enough + * to not negatively impact performance. + * + * The random bit is to ensure that other systems scheduling around the same + * interval don't all get scheduled together. + */ + POLL_INTERVAL_MSEC: (60 * 1000) + Math.floor(2.5 * 1000 * Math.random()), + + /** + * How long individual data submission requests live before expiring. + * + * Data submission requests have this long to complete before we give up on + * them and try again. + * + * We want this to be short enough that we retry frequently enough but long + * enough to give slow networks and systems time to handle it. + */ + SUBMISSION_REQUEST_EXPIRE_INTERVAL_MSEC: 10 * 60 * 1000, + + /** + * Our backoff schedule in case of submission failure. + * + * This dictates both the number of times we retry a daily submission and + * when to retry after each failure. + * + * Each element represents how long to wait after each recoverable failure. + * After the first failure, we wait the time in element 0 before trying + * again. After the second failure, we wait the time in element 1. Once + * we run out of values in this array, we give up on that day's submission + * and schedule for a day out. + */ + FAILURE_BACKOFF_INTERVALS: [ + 15 * 60 * 1000, + 60 * 60 * 1000, + ], + + /** + * State of user notification of data submission. + */ + STATE_NOTIFY_UNNOTIFIED: "not-notified", + STATE_NOTIFY_WAIT: "waiting", + STATE_NOTIFY_COMPLETE: "ok", + + REQUIRED_LISTENERS: ["onRequestDataSubmission", "onNotifyDataPolicy"], + + /** + * The first time the health report policy came into existence. + * + * This is used for scheduling of the initial submission. + */ + get firstRunDate() { + return CommonUtils.getDatePref(this._prefs, "firstRunTime", 0, this._log, + OLDEST_ALLOWED_YEAR); + }, + + set firstRunDate(value) { + this._log.debug("Setting first-run date: " + value); + CommonUtils.setDatePref(this._prefs, "firstRunTime", value, + OLDEST_ALLOWED_YEAR); + }, + + /** + * When the user was notified that data submission could occur. + * + * This is used for logging purposes. this._dataSubmissionPolicyNotifiedDate + * is what's used internally. + */ + get dataSubmissionPolicyNotifiedDate() { + return CommonUtils.getDatePref(this._prefs, + "dataSubmissionPolicyNotifiedTime", 0, + this._log, OLDEST_ALLOWED_YEAR); + }, + + set dataSubmissionPolicyNotifiedDate(value) { + this._log.debug("Setting user notified date: " + value); + CommonUtils.setDatePref(this._prefs, "dataSubmissionPolicyNotifiedTime", + value, OLDEST_ALLOWED_YEAR); + }, + + /** + * When the user accepted or rejected the data submission policy. + * + * If there was implicit acceptance, this will be set to the time of that. + */ + get dataSubmissionPolicyResponseDate() { + return CommonUtils.getDatePref(this._prefs, + "dataSubmissionPolicyResponseTime", + 0, this._log, OLDEST_ALLOWED_YEAR); + }, + + set dataSubmissionPolicyResponseDate(value) { + this._log.debug("Setting user notified reaction date: " + value); + CommonUtils.setDatePref(this._prefs, + "dataSubmissionPolicyResponseTime", + value, OLDEST_ALLOWED_YEAR); + }, + + /** + * Records the result of user notification of data submission policy. + * + * This is used for logging and diagnostics purposes. It can answer the + * question "how was data submission agreed to on this profile?" + * + * Not all values are defined by this type and can come from other systems. + * + * The value must be a string and should be something machine readable. e.g. + * "accept-user-clicked-ok-button-in-info-bar" + */ + get dataSubmissionPolicyResponseType() { + return this._prefs.get("dataSubmissionPolicyResponseType", + "none-recorded"); + }, + + set dataSubmissionPolicyResponseType(value) { + if (typeof(value) != "string") { + throw new Error("Value must be a string. Got " + typeof(value)); + } + + this._prefs.set("dataSubmissionPolicyResponseType", value); + }, + + /** + * Whether submission of data is allowed. + * + * This is the master switch for data submission. If it is off, we will + * never submit data, even if the user has agreed to it. + */ + get dataSubmissionEnabled() { + // Default is true because we are opt-out. + return this._prefs.get("dataSubmissionEnabled", true); + }, + + set dataSubmissionEnabled(value) { + this._prefs.set("dataSubmissionEnabled", !!value); + }, + + /** + * Whether the user has accepted that data submission can occur. + * + * This overrides dataSubmissionEnabled. + */ + get dataSubmissionPolicyAccepted() { + // Be conservative and default to false. + return this._prefs.get("dataSubmissionPolicyAccepted", false); + }, + + set dataSubmissionPolicyAccepted(value) { + this._prefs.set("dataSubmissionPolicyAccepted", !!value); + }, + + /** + * The state of user notification of the data policy. + * + * This must be HealthReportPolicy.STATE_NOTIFY_COMPLETE before data + * submission can occur. + * + * @return HealthReportPolicy.STATE_NOTIFY_* constant. + */ + get notifyState() { + if (this.dataSubmissionPolicyResponseDate.getTime()) { + return this.STATE_NOTIFY_COMPLETE; + } + + // We get the local state - not the state from prefs - because we don't want + // a value from a previous application run to interfere. This prevents + // a scenario where notification occurs just before application shutdown and + // notification is displayed for shorter than the policy requires. + if (!this._dataSubmissionPolicyNotifiedDate) { + return this.STATE_NOTIFY_UNNOTIFIED; + } + + return this.STATE_NOTIFY_WAIT; + }, + + /** + * When this policy last requested data submission. + * + * This is used mainly for forensics purposes and should have no bearing + * on scheduling or run-time behavior. + */ + get lastDataSubmissionRequestedDate() { + return CommonUtils.getDatePref(this._prefs, + "lastDataSubmissionRequestedTime", 0, + this._log, OLDEST_ALLOWED_YEAR); + }, + + set lastDataSubmissionRequestedDate(value) { + CommonUtils.setDatePref(this._prefs, "lastDataSubmissionRequestedTime", + value, OLDEST_ALLOWED_YEAR); + }, + + /** + * When the last data submission actually occurred. + * + * This is used mainly for forensics purposes and should have no bearing on + * actual scheduling. + */ + get lastDataSubmissionSuccessfulDate() { + return CommonUtils.getDatePref(this._prefs, + "lastDataSubmissionSuccessfulTime", 0, + this._log, OLDEST_ALLOWED_YEAR); + }, + + set lastDataSubmissionSuccessfulDate(value) { + CommonUtils.setDatePref(this._prefs, "lastDataSubmissionSuccessfulTime", + value, OLDEST_ALLOWED_YEAR); + }, + + /** + * When we last encountered a submission failure. + * + * This is used for forensics purposes and should have no bearing on + * scheduling. + */ + get lastDataSubmissionFailureDate() { + return CommonUtils.getDatePref(this._prefs, "lastDataSubmissionFailureTime", + 0, this._log, OLDEST_ALLOWED_YEAR); + }, + + set lastDataSubmissionFailureDate(value) { + CommonUtils.setDatePref(this._prefs, "lastDataSubmissionFailureTime", value, + OLDEST_ALLOWED_YEAR); + }, + + /** + * When the next data submission is scheduled to occur. + * + * This is maintained internally by this type. External users should not + * mutate this value. + */ + get nextDataSubmissionDate() { + return CommonUtils.getDatePref(this._prefs, "nextDataSubmissionTime", 0, + this._log, OLDEST_ALLOWED_YEAR); + }, + + set nextDataSubmissionDate(value) { + CommonUtils.setDatePref(this._prefs, "nextDataSubmissionTime", value, + OLDEST_ALLOWED_YEAR); + }, + + /** + * The number of submission failures for this day's upload. + * + * This is used to drive backoff and scheduling. + */ + get currentDaySubmissionFailureCount() { + let v = this._prefs.get("currentDaySubmissionFailureCount", 0); + + if (!Number.isInteger(v)) { + v = 0; + } + + return v; + }, + + set currentDaySubmissionFailureCount(value) { + if (!Number.isInteger(value)) { + throw new Error("Value must be integer: " + value); + } + + this._prefs.set("currentDaySubmissionFailureCount", value); + }, + + /** + * Record user acceptance of data submission policy. + * + * Data submission will not be allowed to occur until this is called. + * + * This is typically called through the `onUserAccept` property attached to + * the promise passed to `onUserNotify` in the policy listener. But, it can + * be called through other interfaces at any time and the call will have + * an impact on future data submissions. + * + * @param reason + * (string) How the user accepted the data submission policy. + */ + recordUserAcceptance: function recordUserAcceptance(reason="no-reason") { + this._log.info("User accepted data submission policy: " + reason); + this.dataSubmissionPolicyResponseDate = this.now(); + this.dataSubmissionPolicyResponseType = "accepted-" + reason; + this.dataSubmissionPolicyAccepted = true; + }, + + /** + * Record user rejection of submission policy. + * + * Data submission will not be allowed to occur if this is called. + * + * This is typically called through the `onUserReject` property attached to + * the promise passed to `onUserNotify` in the policy listener. But, it can + * be called through other interfaces at any time and the call will have an + * impact on future data submissions. + */ + recordUserRejection: function recordUserRejection(reason="no-reason") { + this._log.info("User rejected data submission policy: " + reason); + this.dataSubmissionPolicyResponseDate = this.now(); + this.dataSubmissionPolicyResponseType = "rejected-" + reason; + this.dataSubmissionPolicyAccepted = false; + }, + + /** + * Start background polling for activity. + * + * This will set up a recurring timer that will periodically check if + * activity is warranted. + * + * You typically call this function for each constructed instance. + */ + startPolling: function startPolling() { + this.stopPolling(); + + this._timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + this._timer.initWithCallback({ + notify: function notify() { + this.checkStateAndTrigger(); + }.bind(this) + }, this.POLL_INTERVAL_MSEC, this._timer.TYPE_REPEATING_SLACK); + }, + + /** + * Stop background polling for activity. + * + * This should be called when the instance is no longer needed. + */ + stopPolling: function stopPolling() { + if (this._timer) { + this._timer.cancel(); + this._timer = null; + } + }, + + /** + * Abstraction for obtaining current time. + * + * The purpose of this is to facilitate testing. Testing code can monkeypatch + * this on instances instead of modifying the singleton Date object. + */ + now: function now() { + return new Date(); + }, + + /** + * Check state and trigger actions, if necessary. + * + * This is what enforces the submission and notification policy detailed + * above. You can think of this as the driver for health report data + * submission. + * + * Typically this function is called automatically by the background polling. + * But, it can safely be called manually as needed. + */ + checkStateAndTrigger: function checkStateAndTrigger() { + // If the master data submission kill switch is toggled, we have nothing + // to do. We don't notify about data policies because this would have + // no effect. + if (!this.dataSubmissionEnabled) { + this._log.debug("Data submission is disabled. Doing nothing."); + return; + } + + let now = this.now(); + let nowT = now.getTime(); + + // If the user hasn't responded to the data policy, don't do anything. + if (!this.ensureNotifyResponse(now)) { + return; + } + + // User has opted out of data submission. + if (!this.dataSubmissionPolicyAccepted) { + this._log.debug("Data submission has been disabled per user request."); + return; + } + + // User has responded to data policy and data submission is enabled. Now + // comes the scheduling part. + + let nextSubmissionDate = this.nextDataSubmissionDate; + + if (nowT < nextSubmissionDate.getTime()) { + this._log.debug("Next data submission is scheduled in the future: " + + nextSubmissionDate); + return; + } + + if (this._inProgressSubmissionRequest) { + if (this._inProgressSubmissionRequest.expiresDate.getTime() > nowT) { + this._log.info("Waiting on in-progress submission request to finish."); + return; + } + + this._log.warn("Old submission request has expired from no activity."); + this._inProgressSubmissionRequest.promise.reject(new Error("Request has expired.")); + this._inProgressSubmissionRequest = null; + if (!this._handleSubmissionFailure()) { + return; + } + } + + // We're past our scheduled next data submission date, so let's do it! + this.lastDataSubmissionRequestedDate = now; + let deferred = Promise.defer(); + let requestExpiresDate = + this._futureDate(this.SUBMISSION_REQUEST_EXPIRE_INTERVAL_MSEC); + this._inProgressSubmissionRequest = new DataSubmissionRequest(deferred, + requestExpiresDate); + + let onSuccess = function onSuccess(result) { + this._inProgressSubmissionRequest = null; + this._handleSubmissionResult(result); + }.bind(this); + + let onError = function onError(error) { + this._log.error("Error when handling data submission result: " + + CommonUtils.exceptionStr(result)); + this._inProgressSubmissionRequest = null; + this._handleSubmissionFailure(); + }.bind(this); + + deferred.promise.then(onSuccess, onError); + + this._log.info("Requesting data submission. Will expire at " + + requestExpiresDate); + try { + this._listener.onRequestDataSubmission(this._inProgressSubmissionRequest); + } catch (ex) { + this._log.warn("Exception when calling onRequestDataSubmission: " + + CommonUtils.exceptionStr(ex)); + this._inProgressSubmissionRequest = null; + this._handleSubmissionFailure(); + return; + } + }, + + /** + * Ensure user has responded to data submission policy. + * + * This must be called before data submission. If the policy has not been + * responded to, data submission must not occur. + * + * @return bool Whether user has responded to data policy. + */ + ensureNotifyResponse: function ensureNotifyResponse(now) { + let notifyState = this.notifyState; + + if (notifyState == this.STATE_NOTIFY_UNNOTIFIED) { + let notifyAt = new Date(this.firstRunDate.getTime() + + this.SUBMISSION_NOTIFY_INTERVAL_MSEC); + + if (now.getTime() < notifyAt.getTime()) { + this._log.debug("Don't have to notify about data submission yet."); + return false; + } + + let onComplete = function onComplete() { + this._log.info("Data submission notification presented."); + let now = this.now(); + + this._dataSubmissionPolicyNotifiedDate = now; + this.dataSubmissionPolicyNotifiedDate = now; + }.bind(this); + + let deferred = Promise.defer(); + + deferred.promise.then(onComplete, function onError(error) { + this._log.warn("Data policy notification presentation failed: " + + CommonUtils.exceptionStr(error)); + }); + + this._log.info("Requesting display of data policy."); + let request = new NotifyPolicyRequest(this, deferred); + + try { + this._listener.onNotifyDataPolicy(request); + } catch (ex) { + this._log.warn("Exception when calling onNotifyDataPolicy: " + + CommonUtils.exceptionStr(ex)); + } + return false; + } + + // We're waiting for user action or implicit acceptance after display. + if (notifyState == this.STATE_NOTIFY_WAIT) { + // Check for implicit acceptance. + let implicitAcceptanceDate = + new Date(this._dataSubmissionPolicyNotifiedDate.getTime() + + this.IMPLICIT_ACCEPTANCE_INTERVAL_MSEC); + + if (now.getTime() < implicitAcceptanceDate.getTime()) { + this._log.debug("Still waiting for reaction or implicit acceptance."); + return false; + } + + this.recordUserAcceptance("implicit-time-elapsed"); + return true; + } + + // If this happens, we have a coding error in this file. + if (notifyState != this.STATE_NOTIFY_COMPLETE) { + throw new Error("Unknown notification state: " + notifyState); + } + + return true; + }, + + _handleSubmissionResult: function _handleSubmissionResult(request) { + let state = request.state; + let reason = request.reason || "no reason"; + this._log.info("Got submission request result: " + state); + + if (state == request.SUBMISSION_SUCCESS) { + this._log.info("Successful data submission reported."); + this.lastDataSubmissionSuccessfulDate = request.submissionDate; + this.nextDataSubmissionDate = + new Date(request.submissionDate.getTime() + MILLISECONDS_PER_DAY); + this.currentDaySubmissionFailureCount = 0; + return; + } + + if (state == request.NO_DATA_AVAILABLE) { + this._log.info("No data was available to submit. May try later."); + this._handleSubmissionFailure(); + return; + } + + if (state == request.SUBMISSION_FAILURE_SOFT) { + this._log.warn("Soft error submitting data: " + reason); + this.lastDataSubmissionFailureDate = this.now(); + this._handleSubmissionFailure(); + return; + } + + if (state == request.SUBMISSION_FAILURE_HARD) { + this._log.warn("Hard error submitting data: " + reason); + this.lastDataSubmissionFailureDate = this.now(); + this._moveScheduleForward24h(); + return; + } + + throw new Error("Unknown state on DataSubmissionRequest: " + request.state); + }, + + _handleSubmissionFailure: function _handleSubmissionFailure() { + if (this.currentDaySubmissionFailureCount >= this.FAILURE_BACKOFF_INTERVALS.length) { + this._log.warn("Reached the limit of daily submission attempts. " + + "Rescheduling for tomorrow."); + this._moveScheduleForward24h(); + return false; + } + + let offset = this.FAILURE_BACKOFF_INTERVALS[this.currentDaySubmissionFailureCount]; + this.nextDataSubmissionDate = this._futureDate(offset); + this.currentDaySubmissionFailureCount++; + return true; + }, + + _moveScheduleForward24h: function _moveScheduleForward24h() { + let d = this._futureDate(MILLISECONDS_PER_DAY); + this._log.info("Setting next scheduled data submission for " + d); + + this.nextDataSubmissionDate = d; + this.currentDaySubmissionFailureCount = 0; + }, + + _futureDate: function _futureDate(offset) { + return new Date(this.now().getTime() + offset); + }, +}; + +Object.freeze(HealthReportPolicy.prototype); diff --git a/services/healthreport/tests/xpcshell/test_load_modules.js b/services/healthreport/tests/xpcshell/test_load_modules.js index 70ab420f9590..af9b4dc20d3a 100644 --- a/services/healthreport/tests/xpcshell/test_load_modules.js +++ b/services/healthreport/tests/xpcshell/test_load_modules.js @@ -4,9 +4,11 @@ "use strict"; const modules = [ + "policy.jsm", ]; const test_modules = [ + "mocks.jsm", ]; function run_test() { diff --git a/services/healthreport/tests/xpcshell/test_policy.js b/services/healthreport/tests/xpcshell/test_policy.js new file mode 100644 index 000000000000..05c62c873790 --- /dev/null +++ b/services/healthreport/tests/xpcshell/test_policy.js @@ -0,0 +1,538 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const {utils: Cu} = Components; + +Cu.import("resource://services-common/preferences.js"); +Cu.import("resource://gre/modules/services/healthreport/policy.jsm"); +Cu.import("resource://testing-common/services/healthreport/mocks.jsm"); + + +function getPolicy(name) { + let prefs = new Preferences(name); + let listener = new MockPolicyListener(); + + return [new HealthReportPolicy(prefs, listener), prefs, listener]; +} + +function defineNow(policy, now) { + print("Adjusting fake system clock to " + now); + Object.defineProperty(policy, "now", { + value: function customNow() { + return now; + }, + writable: true, + }); +} + +function run_test() { + run_next_test(); +} + +add_test(function test_constructor() { + let prefs = new Preferences("foo.bar"); + let listener = { + onRequestDataSubmission: function() {}, + onNotifyDataPolicy: function() {}, + }; + + let policy = new HealthReportPolicy(prefs, listener); + do_check_true(Date.now() - policy.firstRunDate.getTime() < 1000); + + let tomorrow = Date.now() + 24 * 60 * 60 * 1000; + do_check_true(tomorrow - policy.nextDataSubmissionDate.getTime() < 1000); + + do_check_eq(policy.notifyState, policy.STATE_NOTIFY_UNNOTIFIED); + + run_next_test(); +}); + +add_test(function test_prefs() { + let [policy, prefs, listener] = getPolicy("prefs"); + + let now = new Date(); + let nowT = now.getTime(); + + policy.firstRunDate = now; + do_check_eq(prefs.get("firstRunTime"), nowT); + do_check_eq(policy.firstRunDate.getTime(), nowT); + + policy.dataSubmissionPolicyNotifiedDate= now; + do_check_eq(prefs.get("dataSubmissionPolicyNotifiedTime"), nowT); + do_check_eq(policy.dataSubmissionPolicyNotifiedDate.getTime(), nowT); + + policy.dataSubmissionPolicyResponseDate = now; + do_check_eq(prefs.get("dataSubmissionPolicyResponseTime"), nowT); + do_check_eq(policy.dataSubmissionPolicyResponseDate.getTime(), nowT); + + policy.dataSubmissionPolicyResponseType = "type-1"; + do_check_eq(prefs.get("dataSubmissionPolicyResponseType"), "type-1"); + do_check_eq(policy.dataSubmissionPolicyResponseType, "type-1"); + + policy.dataSubmissionEnabled = false; + do_check_false(prefs.get("dataSubmissionEnabled", true)); + do_check_false(policy.dataSubmissionEnabled); + + policy.dataSubmissionPolicyAccepted = false; + do_check_false(prefs.get("dataSubmissionPolicyAccepted", true)); + do_check_false(policy.dataSubmissionPolicyAccepted); + + policy.lastDataSubmissionRequestedDate = now; + do_check_eq(prefs.get("lastDataSubmissionRequestedTime"), nowT); + do_check_eq(policy.lastDataSubmissionRequestedDate.getTime(), nowT); + + policy.lastDataSubmissionSuccessfulDate = now; + do_check_eq(prefs.get("lastDataSubmissionSuccessfulTime"), nowT); + do_check_eq(policy.lastDataSubmissionSuccessfulDate.getTime(), nowT); + + policy.lastDataSubmissionFailureDate = now; + do_check_eq(prefs.get("lastDataSubmissionFailureTime"), nowT); + do_check_eq(policy.lastDataSubmissionFailureDate.getTime(), nowT); + + policy.nextDataSubmissionDate = now; + do_check_eq(prefs.get("nextDataSubmissionTime"), nowT); + do_check_eq(policy.nextDataSubmissionDate.getTime(), nowT); + + policy.currentDaySubmissionFailureCount = 2; + do_check_eq(prefs.get("currentDaySubmissionFailureCount", 0), 2); + do_check_eq(policy.currentDaySubmissionFailureCount, 2); + + run_next_test(); +}); + +add_test(function test_notify_state_prefs() { + let [policy, prefs, listener] = getPolicy("notify_state_prefs"); + + do_check_eq(policy.notifyState, policy.STATE_NOTIFY_UNNOTIFIED); + + policy._dataSubmissionPolicyNotifiedDate = new Date(); + do_check_eq(policy.notifyState, policy.STATE_NOTIFY_WAIT); + + policy.dataSubmissionPolicyResponseDate = new Date(); + policy._dataSubmissionPolicyNotifiedDate = null; + do_check_eq(policy.notifyState, policy.STATE_NOTIFY_COMPLETE); + + run_next_test(); +}); + +add_test(function test_initial_submission_notification() { + let [policy, prefs, listener] = getPolicy("initial_submission_notification"); + + do_check_eq(listener.notifyUserCount, 0); + + // Fresh instances should not do anything initially. + policy.checkStateAndTrigger(); + do_check_eq(listener.notifyUserCount, 0); + + // We still shouldn't notify up to the millisecond before the barrier. + defineNow(policy, new Date(policy.firstRunDate.getTime() + + policy.SUBMISSION_NOTIFY_INTERVAL_MSEC - 1)); + policy.checkStateAndTrigger(); + do_check_eq(listener.notifyUserCount, 0); + do_check_null(policy._dataSubmissionPolicyNotifiedDate); + do_check_eq(policy.dataSubmissionPolicyNotifiedDate.getTime(), 0); + + // We have crossed the threshold. We should see notification. + defineNow(policy, new Date(policy.firstRunDate.getTime() + + policy.SUBMISSION_NOTIFY_INTERVAL_MSEC)); + policy.checkStateAndTrigger(); + do_check_eq(listener.notifyUserCount, 1); + listener.lastNotifyRequest.onUserNotifyComplete(); + do_check_true(policy._dataSubmissionPolicyNotifiedDate instanceof Date); + do_check_true(policy.dataSubmissionPolicyNotifiedDate.getTime() > 0); + do_check_eq(policy.dataSubmissionPolicyNotifiedDate.getTime(), + policy._dataSubmissionPolicyNotifiedDate.getTime()); + do_check_eq(policy.notifyState, policy.STATE_NOTIFY_WAIT); + + run_next_test(); +}); + +add_test(function test_notification_implicit_acceptance() { + let [policy, prefs, listener] = getPolicy("notification_implicit_acceptance"); + + let now = new Date(policy.nextDataSubmissionDate.getTime() - + policy.SUBMISSION_NOTIFY_INTERVAL_MSEC + 1); + defineNow(policy, now); + policy.checkStateAndTrigger(); + do_check_eq(listener.notifyUserCount, 1); + listener.lastNotifyRequest.onUserNotifyComplete(); + do_check_eq(policy.dataSubmissionPolicyResponseType, "none-recorded"); + + do_check_true(5000 < policy.IMPLICIT_ACCEPTANCE_INTERVAL_MSEC); + defineNow(policy, new Date(now.getTime() + 5000)); + policy.checkStateAndTrigger(); + do_check_eq(listener.notifyUserCount, 1); + do_check_eq(policy.notifyState, policy.STATE_NOTIFY_WAIT); + do_check_eq(policy.dataSubmissionPolicyResponseDate.getTime(), 0); + do_check_eq(policy.dataSubmissionPolicyResponseType, "none-recorded"); + + defineNow(policy, new Date(now.getTime() + policy.IMPLICIT_ACCEPTANCE_INTERVAL_MSEC + 1)); + policy.checkStateAndTrigger(); + do_check_eq(listener.notifyUserCount, 1); + do_check_eq(policy.notifyState, policy.STATE_NOTIFY_COMPLETE); + do_check_eq(policy.dataSubmissionPolicyResponseDate.getTime(), policy.now().getTime()); + do_check_eq(policy.dataSubmissionPolicyResponseType, "accepted-implicit-time-elapsed"); + + run_next_test(); +}); + +add_test(function test_notification_rejected() { + // User notification failed. We should not record it as being presented. + let [policy, prefs, listener] = getPolicy("notification_failed"); + + let now = new Date(policy.nextDataSubmissionDate.getTime() - + policy.SUBMISSION_NOTIFY_INTERVAL_MSEC + 1); + defineNow(policy, now); + policy.checkStateAndTrigger(); + do_check_eq(listener.notifyUserCount, 1); + listener.lastNotifyRequest.onUserNotifyFailed(new Error("testing failed.")); + do_check_null(policy._dataSubmissionPolicyNotifiedDate); + do_check_eq(policy.dataSubmissionPolicyNotifiedDate.getTime(), 0); + do_check_eq(policy.notifyState, policy.STATE_NOTIFY_UNNOTIFIED); + + run_next_test(); +}); + +add_test(function test_notification_accepted() { + let [policy, prefs, listener] = getPolicy("notification_accepted"); + + let now = new Date(policy.nextDataSubmissionDate.getTime() - + policy.SUBMISSION_NOTIFY_INTERVAL_MSEC + 1); + defineNow(policy, now); + policy.checkStateAndTrigger(); + listener.lastNotifyRequest.onUserNotifyComplete(); + do_check_eq(policy.notifyState, policy.STATE_NOTIFY_WAIT); + do_check_false(policy.dataSubmissionPolicyAccepted); + listener.lastNotifyRequest.onUserNotifyComplete(); + listener.lastNotifyRequest.onUserAccept("foo-bar"); + do_check_eq(policy.notifyState, policy.STATE_NOTIFY_COMPLETE); + do_check_eq(policy.dataSubmissionPolicyResponseType, "accepted-foo-bar"); + do_check_true(policy.dataSubmissionPolicyAccepted); + do_check_eq(policy.dataSubmissionPolicyResponseDate.getTime(), now.getTime()); + + run_next_test(); +}); + +add_test(function test_notification_rejected() { + let [policy, prefs, listener] = getPolicy("notification_rejected"); + + let now = new Date(policy.nextDataSubmissionDate.getTime() - + policy.SUBMISSION_NOTIFY_INTERVAL_MSEC + 1); + defineNow(policy, now); + policy.checkStateAndTrigger(); + listener.lastNotifyRequest.onUserNotifyComplete(); + do_check_eq(policy.notifyState, policy.STATE_NOTIFY_WAIT); + do_check_false(policy.dataSubmissionPolicyAccepted); + listener.lastNotifyRequest.onUserReject(); + do_check_eq(policy.notifyState, policy.STATE_NOTIFY_COMPLETE); + do_check_eq(policy.dataSubmissionPolicyResponseType, "rejected-no-reason"); + do_check_false(policy.dataSubmissionPolicyAccepted); + + // No requests for submission should occur if user has rejected. + defineNow(policy, new Date(policy.nextDataSubmissionDate.getTime() + 10000)); + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataSubmissionCount, 0); + + run_next_test(); +}); + +add_test(function test_submission_kill_switch() { + let [policy, prefs, listener] = getPolicy("submission_kill_switch"); + + policy.firstRunDate = new Date(Date.now() - 3 * 24 * 60 * 60 * 1000); + policy.nextDataSubmissionDate = new Date(Date.now() - 24 * 60 * 60 * 1000); + policy.recordUserAcceptance("accept-old-ack"); + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataSubmissionCount, 1); + + defineNow(policy, + new Date(Date.now() + policy.SUBMISSION_REQUEST_EXPIRE_INTERVAL_MSEC + 100)); + policy.dataSubmissionEnabled = false; + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataSubmissionCount, 1); + + run_next_test(); +}); + +add_test(function test_data_submission_no_data() { + let [policy, prefs, listener] = getPolicy("data_submission_no_data"); + + policy.dataSubmissionPolicyResponseDate = new Date(Date.now() - 24 * 60 * 60 * 1000); + policy.dataSubmissionPolicyAccepted = true; + let now = new Date(policy.nextDataSubmissionDate.getTime() + 1); + defineNow(policy, now); + do_check_eq(listener.requestDataSubmissionCount, 0); + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataSubmissionCount, 1); + listener.lastDataRequest.onNoDataAvailable(); + + // The next trigger should try again. + defineNow(policy, new Date(now.getTime() + 155 * 60 * 1000)); + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataSubmissionCount, 2); + + run_next_test(); +}); + +add_test(function test_data_submission_submit_failure_hard() { + let [policy, prefs, listener] = getPolicy("data_submission_submit_failure_hard"); + + policy.dataSubmissionPolicyResponseDate = new Date(Date.now() - 24 * 60 * 60 * 1000); + policy.dataSubmissionPolicyAccepted = true; + let nextDataSubmissionDate = policy.nextDataSubmissionDate; + let now = new Date(policy.nextDataSubmissionDate.getTime() + 1); + defineNow(policy, now); + + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataSubmissionCount, 1); + listener.lastDataRequest.onSubmissionFailureHard(); + do_check_eq(listener.lastDataRequest.state, + listener.lastDataRequest.SUBMISSION_FAILURE_HARD); + + let expected = new Date(now.getTime() + 24 * 60 * 60 * 1000); + do_check_eq(policy.nextDataSubmissionDate.getTime(), expected.getTime()); + + defineNow(policy, new Date(now.getTime() + 10)); + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataSubmissionCount, 1); + + run_next_test(); +}); + +add_test(function test_data_submission_submit_try_again() { + let [policy, prefs, listener] = getPolicy("data_submission_failure_soft"); + + policy.recordUserAcceptance(); + let nextDataSubmissionDate = policy.nextDataSubmissionDate; + let now = new Date(policy.nextDataSubmissionDate.getTime()); + defineNow(policy, now); + policy.checkStateAndTrigger(); + listener.lastDataRequest.onSubmissionFailureSoft(); + do_check_eq(policy.nextDataSubmissionDate.getTime(), + nextDataSubmissionDate.getTime() + 15 * 60 * 1000); + + run_next_test(); +}); + +add_test(function test_submission_daily_scheduling() { + let [policy, prefs, listener] = getPolicy("submission_daily_scheduling"); + + policy.dataSubmissionPolicyResponseDate = new Date(Date.now() - 24 * 60 * 60 * 1000); + policy.dataSubmissionPolicyAccepted = true; + let nextDataSubmissionDate = policy.nextDataSubmissionDate; + + // Skip ahead to next submission date. We should get a submission request. + let now = new Date(policy.nextDataSubmissionDate.getTime()); + defineNow(policy, now); + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataSubmissionCount, 1); + do_check_eq(policy.lastDataSubmissionRequestedDate.getTime(), now.getTime()); + + let finishedDate = new Date(now.getTime() + 250); + defineNow(policy, new Date(finishedDate.getTime() + 50)); + listener.lastDataRequest.onSubmissionSuccess(finishedDate); + do_check_eq(policy.lastDataSubmissionSuccessfulDate.getTime(), finishedDate.getTime()); + + // Next scheduled submission should be exactly 1 day after the reported + // submission success. + + let nextScheduled = new Date(finishedDate.getTime() + 24 * 60 * 60 * 1000); + do_check_eq(policy.nextDataSubmissionDate.getTime(), nextScheduled.getTime()); + + // Fast forward some arbitrary time. We shouldn't do any work yet. + defineNow(policy, new Date(now.getTime() + 40000)); + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataSubmissionCount, 1); + + defineNow(policy, nextScheduled); + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataSubmissionCount, 2); + listener.lastDataRequest.onSubmissionSuccess(new Date(nextScheduled.getTime() + 200)); + do_check_eq(policy.nextDataSubmissionDate.getTime(), + new Date(nextScheduled.getTime() + 24 * 60 * 60 * 1000 + 200).getTime()); + + run_next_test(); +}); + +add_test(function test_submission_backoff() { + let [policy, prefs, listener] = getPolicy("submission_backoff"); + + do_check_eq(policy.FAILURE_BACKOFF_INTERVALS.length, 2); + + policy.dataSubmissionPolicyResponseDate = new Date(Date.now() - 24 * 60 * 60 * 1000); + policy.dataSubmissionPolicyAccepted = true; + + let now = new Date(policy.nextDataSubmissionDate.getTime()); + defineNow(policy, now); + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataSubmissionCount, 1); + do_check_eq(policy.currentDaySubmissionFailureCount, 0); + + now = new Date(now.getTime() + 5000); + defineNow(policy, now); + + // On first soft failure we should back off by scheduled interval. + listener.lastDataRequest.onSubmissionFailureSoft(); + do_check_eq(policy.currentDaySubmissionFailureCount, 1); + do_check_eq(policy.nextDataSubmissionDate.getTime(), + new Date(now.getTime() + policy.FAILURE_BACKOFF_INTERVALS[0]).getTime()); + do_check_eq(policy.lastDataSubmissionFailureDate.getTime(), now.getTime()); + + // Should not request submission until scheduled. + now = new Date(policy.nextDataSubmissionDate.getTime() - 1); + defineNow(policy, now); + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataSubmissionCount, 1); + + // 2nd request for submission. + now = new Date(policy.nextDataSubmissionDate.getTime()); + defineNow(policy, now); + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataSubmissionCount, 2); + + now = new Date(now.getTime() + 5000); + defineNow(policy, now); + + // On second failure we should back off by more. + listener.lastDataRequest.onSubmissionFailureSoft(); + do_check_eq(policy.currentDaySubmissionFailureCount, 2); + do_check_eq(policy.nextDataSubmissionDate.getTime(), + new Date(now.getTime() + policy.FAILURE_BACKOFF_INTERVALS[1]).getTime()); + + now = new Date(policy.nextDataSubmissionDate.getTime()); + defineNow(policy, now); + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataSubmissionCount, 3); + + now = new Date(now.getTime() + 5000); + defineNow(policy, now); + + // On 3rd failure we should back off by a whole day. + listener.lastDataRequest.onSubmissionFailureSoft(); + do_check_eq(policy.currentDaySubmissionFailureCount, 0); + do_check_eq(policy.nextDataSubmissionDate.getTime(), + new Date(now.getTime() + 24 * 60 * 60 * 1000).getTime()); + + run_next_test(); +}); + +// Ensure that only one submission request can be active at a time. +add_test(function test_submission_expiring() { + let [policy, prefs, listener] = getPolicy("submission_expiring"); + + policy.dataSubmissionPolicyResponseDate = new Date(Date.now() - 24 * 60 * 60 * 1000); + policy.dataSubmissionPolicyAccepted = true; + let nextDataSubmission = policy.nextDataSubmissionDate; + let now = new Date(policy.nextDataSubmissionDate.getTime()); + defineNow(policy, now); + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataSubmissionCount, 1); + defineNow(policy, new Date(now.getTime() + 500)); + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataSubmissionCount, 1); + + defineNow(policy, new Date(policy.now().getTime() + + policy.SUBMISSION_REQUEST_EXPIRE_INTERVAL_MSEC)); + + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataSubmissionCount, 2); + + run_next_test(); +}); + +add_test(function test_polling() { + let [policy, prefs, listener] = getPolicy("polling"); + + // Ensure checkStateAndTrigger is called at a regular interval. + let now = new Date(); + Object.defineProperty(policy, "POLL_INTERVAL_MSEC", { + value: 500, + }); + let count = 0; + + Object.defineProperty(policy, "checkStateAndTrigger", { + value: function fakeCheckStateAndTrigger() { + let now2 = new Date(); + count++; + + do_check_true(now2.getTime() - now.getTime() >= 500); + now = now2; + HealthReportPolicy.prototype.checkStateAndTrigger.call(policy); + + if (count >= 2) { + policy.stopPolling(); + + do_check_eq(listener.notifyUserCount, 0); + do_check_eq(listener.requestDataSubmissionCount, 0); + + run_next_test(); + } + } + }); + policy.startPolling(); +}); + +// Ensure that implicit acceptance of policy is resolved through polling. +// +// This is probably covered by other tests. But, it's best to have explicit +// coverage from a higher-level. +add_test(function test_polling_implicit_acceptance() { + let [policy, prefs, listener] = getPolicy("polling_implicit_acceptance"); + + // Redefine intervals with shorter, test-friendly values. + Object.defineProperty(policy, "POLL_INTERVAL_MSEC", { + value: 250, + }); + + Object.defineProperty(policy, "IMPLICIT_ACCEPTANCE_INTERVAL_MSEC", { + value: 750, + }); + + let count = 0; + Object.defineProperty(policy, "checkStateAndTrigger", { + value: function CheckStateAndTriggerProxy() { + count++; + print("checkStateAndTrigger count: " + count); + + // Account for some slack. + HealthReportPolicy.prototype.checkStateAndTrigger.call(policy); + + // What should happen on different invocations: + // + // 1) We are inside the prompt interval so user gets prompted. + // 2) still ~300ms away from implicit acceptance + // 3) still ~50ms away from implicit acceptance + // 4) Implicit acceptance recorded. Data submission requested. + // 5) Request still pending. No new submission requested. + + do_check_eq(listener.notifyUserCount, 1); + + if (count == 1) { + listener.lastNotifyRequest.onUserNotifyComplete(); + } + + if (count < 4) { + do_check_false(policy.dataSubmissionPolicyAccepted); + do_check_eq(listener.requestDataSubmissionCount, 0); + } else { + do_check_true(policy.dataSubmissionPolicyAccepted); + do_check_eq(policy.dataSubmissionPolicyResponseType, + "accepted-implicit-time-elapsed"); + do_check_eq(listener.requestDataSubmissionCount, 1); + } + + if (count > 4) { + do_check_eq(listener.requestDataSubmissionCount, 1); + policy.stopPolling(); + run_next_test(); + } + } + }); + + policy.firstRunDate = new Date(Date.now() - 4 * 24 * 60 * 60 * 1000); + policy.nextDataSubmissionDate = new Date(Date.now()); + policy.startPolling(); +}); + diff --git a/services/healthreport/tests/xpcshell/xpcshell.ini b/services/healthreport/tests/xpcshell/xpcshell.ini index fd7581cfb799..57854778d3e1 100644 --- a/services/healthreport/tests/xpcshell/xpcshell.ini +++ b/services/healthreport/tests/xpcshell/xpcshell.ini @@ -3,3 +3,4 @@ head = head.js tail = [test_load_modules.js] +[test_policy.js] From 49d33ed1c3fde7df3f85949076d9ce65f4fe45fa Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Wed, 7 Nov 2012 16:25:09 -0800 Subject: [PATCH 59/75] Bug 802914 - Implement Bagheera client and server; r=rnewman --- services/common/Makefile.in | 18 +- services/common/bagheeraclient.js | 226 +++++++++++++ .../common/modules-testing/bagheeraserver.js | 296 ++++++++++++++++++ services/common/tests/run_bagheera_server.js | 26 ++ .../common/tests/unit/test_bagheera_client.js | 89 ++++++ .../common/tests/unit/test_bagheera_server.js | 45 +++ .../common/tests/unit/test_load_modules.js | 2 + services/common/tests/unit/xpcshell.ini | 2 + 8 files changed, 694 insertions(+), 10 deletions(-) create mode 100644 services/common/bagheeraclient.js create mode 100644 services/common/modules-testing/bagheeraserver.js create mode 100644 services/common/tests/run_bagheera_server.js create mode 100644 services/common/tests/unit/test_bagheera_client.js create mode 100644 services/common/tests/unit/test_bagheera_server.js diff --git a/services/common/Makefile.in b/services/common/Makefile.in index beae39aedaa6..9b310ab17179 100644 --- a/services/common/Makefile.in +++ b/services/common/Makefile.in @@ -11,6 +11,7 @@ include $(DEPTH)/config/autoconf.mk modules := \ async.js \ + bagheeraclient.js \ log4moz.js \ observers.js \ preferences.js \ @@ -23,6 +24,7 @@ modules := \ testing_modules := \ aitcserver.js \ + bagheeraserver.js \ logging.js \ storageserver.js \ utils.js \ @@ -46,20 +48,16 @@ include $(topsrcdir)/config/rules.mk # ever consolidate our Python code, and/or have a supplemental driver for the # build system, this can go away. -storage_server_hostname := localhost -storage_server_port := 8080 - -head_path = $(srcdir)/tests/unit +server_port := 8080 storage-server: $(PYTHON) $(srcdir)/tests/run_server.py $(topsrcdir) \ - $(MOZ_BUILD_ROOT) run_storage_server.js --port $(storage_server_port) - -# And the same thing for an AITC server. -aitc_server_hostname := localhost -aitc_server_port := 8080 + $(MOZ_BUILD_ROOT) run_storage_server.js --port $(server_port) aitc-server: $(PYTHON) $(srcdir)/tests/run_server.py $(topsrcdir) \ - $(MOZ_BUILD_ROOT) run_aitc_server.js --port $(aitc_server_port) + $(MOZ_BUILD_ROOT) run_aitc_server.js --port $(server_port) +bagheera-server: + $(PYTHON) $(srcdir)/tests/run_server.py $(topsrcdir) \ + $(MOZ_BUILD_ROOT) run_bagheera_server.js --port $(server_port) diff --git a/services/common/bagheeraclient.js b/services/common/bagheeraclient.js new file mode 100644 index 000000000000..5944665ed7f3 --- /dev/null +++ b/services/common/bagheeraclient.js @@ -0,0 +1,226 @@ +/* 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/. */ + +/** + * This file contains a client API for the Bagheera data storage service. + * + * Information about Bagheera is available at + * https://github.com/mozilla-metrics/bagheera + */ + +"use strict"; + +this.EXPORTED_SYMBOLS = [ + "BagheeraClient", + "BagheeraClientRequestResult", +]; + +const {classes: Cc, interfaces: Ci, utils: Cu} = Components; + +Cu.import("resource://gre/modules/commonjs/promise/core.js"); +Cu.import("resource://gre/modules/services-common/log4moz.js"); +Cu.import("resource://gre/modules/services-common/rest.js"); +Cu.import("resource://gre/modules/services-common/utils.js"); + + +/** + * Represents the result of a Bagheera request. + */ +this.BagheeraClientRequestResult = function BagheeraClientRequestResult() { + this.transportSuccess = false; + this.serverSuccess = false; + this.request = null; +} + +Object.freeze(BagheeraClientRequestResult.prototype); + +/** + * Create a new Bagheera client instance. + * + * Each client is associated with a specific Bagheera HTTP URI endpoint. + * + * @param baseURI + * (string) The base URI of the Bagheera HTTP endpoint. + */ +this.BagheeraClient = function BagheeraClient(baseURI) { + if (!baseURI) { + throw new Error("baseURI argument must be defined."); + } + + this._log = Log4Moz.repository.getLogger("Services.BagheeraClient"); + this._log.level = Log4Moz.Level["Debug"]; + + this.baseURI = baseURI; + + if (!baseURI.endsWith("/")) { + this.baseURI += "/"; + } +} + +BagheeraClient.prototype = { + /** + * Channel load flags for all requests. + * + * Caching is not applicable, so we bypass and disable it. We also + * ignore any cookies that may be present for the domain because + * Bagheera does not utilize cookies and the release of cookies may + * inadvertantly constitute unncessary information disclosure. + */ + _loadFlags: Ci.nsIRequest.LOAD_BYPASS_CACHE | + Ci.nsIRequest.INHIBIT_CACHING | + Ci.nsIRequest.LOAD_ANONYMOUS, + + DEFAULT_TIMEOUT_MSEC: 5 * 60 * 1000, // 5 minutes. + + _RE_URI_IDENTIFIER: /^[a-zA-Z0-9_-]+$/, + + /** + * Upload a JSON payload to the server. + * + * The return value is a Promise which will be resolved with a + * BagheeraClientRequestResult when the request has finished. + * + * @param namespace + * (string) The namespace to post this data to. + * @param id + * (string) The ID of the document being uploaded. This is typically + * a UUID in hex form. + * @param payload + * (string|object) Data to upload. Can be specified as a string (which + * is assumed to be JSON) or an object. If an object, it will be fed into + * JSON.stringify() for serialization. + * @param deleteOldID + * (string) Old document ID to delete as part of upload. If not + * specified, no old documents will be deleted as part of upload. The + * string value is typically a UUID in hex form. + * + * @return Promise + */ + uploadJSON: function uploadJSON(namespace, id, payload, deleteOldID=null) { + if (!namespace) { + throw new Error("namespace argument must be defined."); + } + + if (!id) { + throw new Error("id argument must be defined."); + } + + if (!payload) { + throw new Error("payload argument must be defined."); + } + + let uri = this._submitURI(namespace, id); + + let data = payload; + + if (typeof(payload) == "object") { + data = JSON.stringify(payload); + } + + if (typeof(data) != "string") { + throw new Error("Unknown type for payload: " + typeof(data)); + } + + this._log.info("Uploading data to " + uri); + + let request = new RESTRequest(uri); + request.loadFlags = this._loadFlags; + request.timeout = this.DEFAULT_TIMEOUT_MSEC; + + if (deleteOldID) { + request.setHeader("X-Obsolete-Document", deleteOldID); + } + + let deferred = Promise.defer(); + + data = CommonUtils.convertString(data, "uncompressed", "deflate"); + // TODO proper header per bug 807134. + request.setHeader("Content-Type", "application/json+zlib; charset=utf-8"); + + this._log.info("Request body length: " + data.length); + + let result = new BagheeraClientRequestResult(); + result.namespace = namespace; + result.id = id; + + request.onComplete = this._onComplete.bind(this, request, deferred, result); + request.post(data); + + return deferred.promise; + }, + + /** + * Delete the specified document. + * + * @param namespace + * (string) Namespace from which to delete the document. + * @param id + * (string) ID of document to delete. + * + * @return Promise + */ + deleteDocument: function deleteDocument(namespace, id) { + let uri = this._submitURI(namespace, id); + + let request = new RESTRequest(uri); + request.loadFlags = this._loadFlags; + request.timeout = this.DEFAULT_TIMEOUT_MSEC; + + let result = new BagheeraClientRequestResult(); + result.namespace = namespace; + result.id = id; + let deferred = Promise.defer(); + + request.onComplete = this._onComplete.bind(this, request, deferred, result); + request.delete(); + + return deferred.promise; + }, + + _submitURI: function _submitURI(namespace, id) { + if (!this._RE_URI_IDENTIFIER.test(namespace)) { + throw new Error("Illegal namespace name. Must be alphanumeric + [_-]: " + + namespace); + } + + if (!this._RE_URI_IDENTIFIER.test(id)) { + throw new Error("Illegal id value. Must be alphanumeric + [_-]: " + id); + } + + return this.baseURI + "1.0/submit/" + namespace + "/" + id; + }, + + _onComplete: function _onComplete(request, deferred, result, error) { + result.request = request; + + if (error) { + this._log.info("Transport failure on request: " + + CommonUtils.exceptionStr(error)); + result.transportSuccess = false; + deferred.resolve(result); + return; + } + + result.transportSuccess = true; + + let response = request.response; + + switch (response.status) { + case 200: + case 201: + result.serverSuccess = true; + break; + + default: + result.serverSuccess = false; + + this._log.info("Received unexpected status code: " + response.status); + this._log.debug("Response body: " + response.body); + } + + deferred.resolve(result); + }, +}; + +Object.freeze(BagheeraClient.prototype); diff --git a/services/common/modules-testing/bagheeraserver.js b/services/common/modules-testing/bagheeraserver.js new file mode 100644 index 000000000000..35e17bd52916 --- /dev/null +++ b/services/common/modules-testing/bagheeraserver.js @@ -0,0 +1,296 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const {utils: Cu} = Components; + +this.EXPORTED_SYMBOLS = ["BagheeraServer"]; + +Cu.import("resource://gre/modules/services-common/log4moz.js"); +Cu.import("resource://gre/modules/services-common/utils.js"); +Cu.import("resource://testing-common/httpd.js"); + + +/** + * This is an implementation of the Bagheera server. + * + * The purpose of the server is to facilitate testing of the Bagheera + * client and the Firefox Health report. It is *not* meant to be a + * production grade server. + * + * The Bagheera server is essentially a glorified document store. + */ +this.BagheeraServer = function BagheeraServer(serverURI="http://localhost") { + this._log = Log4Moz.repository.getLogger("metrics.BagheeraServer"); + + this.serverURI = serverURI; + this.server = new HttpServer(); + this.port = 8080; + this.namespaces = {}; + + this.allowAllNamespaces = false; +} + +BagheeraServer.prototype = { + /** + * Whether this server has a namespace defined. + * + * @param ns + * (string) Namepsace whose existence to query for. + * @return bool + */ + hasNamespace: function hasNamespace(ns) { + return ns in this.namespaces; + }, + + /** + * Whether this server has an ID in a particular namespace. + * + * @param ns + * (string) Namespace to look for item in. + * @param id + * (string) ID of object to look for. + * @return bool + */ + hasDocument: function hasDocument(ns, id) { + let namespace = this.namespaces[ns]; + + if (!namespace) { + return false; + } + + return id in namespace; + }, + + /** + * Obtain a document from the server. + * + * @param ns + * (string) Namespace to retrieve document from. + * @param id + * (string) ID of document to retrieve. + * + * @return string The content of the document or null if the document + * does not exist. + */ + getDocument: function getDocument(ns, id) { + let namespace = this.namespaces[ns]; + + if (!namespace) { + return null; + } + + return namespace[id]; + }, + + /** + * Set the contents of a document in the server. + * + * @param ns + * (string) Namespace to add document to. + * @param id + * (string) ID of document being added. + * @param payload + * (string) The content of the document. + */ + setDocument: function setDocument(ns, id, payload) { + let namespace = this.namespaces[ns]; + + if (!namespace) { + if (!this.allowAllNamespaces) { + throw new Error("Namespace does not exist: " + ns); + } + + this.createNamespace(ns); + namespace = this.namespaces[ns]; + } + + namespace[id] = payload; + }, + + /** + * Create a namespace in the server. + * + * The namespace will initially be empty. + * + * @param ns + * (string) The name of the namespace to create. + */ + createNamespace: function createNamespace(ns) { + if (ns in this.namespaces) { + throw new Error("Namespace already exists: " + ns); + } + + this.namespaces[ns] = {}; + }, + + start: function start(port) { + if (!port) { + throw new Error("port argument must be specified."); + } + + this.port = port; + + this.server.registerPrefixHandler("/", this._handleRequest.bind(this)); + this.server.start(port); + }, + + stop: function stop(cb) { + let handler = {onStopped: cb}; + + this.server.stop(handler); + }, + + /** + * Our root path handler. + */ + _handleRequest: function _handleRequest(request, response) { + let path = request.path; + this._log.info("Received request: " + request.method + " " + path + " " + + "HTTP/" + request.httpVersion); + + try { + if (path.startsWith("/1.0/submit/")) { + return this._handleV1Submit(request, response, + path.substr("/1.0/submit/".length)); + } else { + throw HTTP_404; + } + } catch (ex) { + if (ex instanceof HttpError) { + this._log.info("HttpError thrown: " + ex.code + " " + ex.description); + } else { + this._log.warn("Exception processing request: " + + CommonUtils.exceptionStr(ex)); + } + + throw ex; + } + }, + + /** + * Handles requests to /submit/*. + */ + _handleV1Submit: function _handleV1Submit(request, response, rest) { + if (!rest.length) { + throw HTTP_404; + } + + let namespace; + let index = rest.indexOf("/"); + if (index == -1) { + namespace = rest; + rest = ""; + } else { + namespace = rest.substr(0, index); + rest = rest.substr(index + 1); + } + + this._handleNamespaceSubmit(namespace, rest, request, response); + }, + + _handleNamespaceSubmit: function _handleNamespaceSubmit(namespace, rest, + request, response) { + if (!this.hasNamespace(namespace)) { + if (!this.allowAllNamespaces) { + this._log.info("Request to unknown namespace: " + namespace); + throw HTTP_404; + } + + this.createNamespace(namespace); + } + + if (!rest) { + this._log.info("No ID defined."); + throw HTTP_404; + } + + let id = rest; + if (id.contains("/")) { + this._log.info("URI has too many components."); + throw HTTP_404; + } + + if (request.method == "POST") { + return this._handleNamespaceSubmitPost(namespace, id, request, response); + } + + if (request.method == "DELETE") { + return this._handleNamespaceSubmitDelete(namespace, id, request, response); + } + + this._log.info("Unsupported HTTP method on namespace handler: " + + request.method); + response.setHeader("Allow", "POST,DELETE"); + throw HTTP_405; + }, + + _handleNamespaceSubmitPost: + function _handleNamespaceSubmitPost(namespace, id, request, response) { + + this._log.info("Handling data upload for " + namespace + ":" + id); + + let requestBody = CommonUtils.readBytesFromInputStream(request.bodyInputStream); + this._log.info("Raw body length: " + requestBody.length); + + if (!request.hasHeader("Content-Type")) { + this._log.info("Request does not have Content-Type header."); + throw HTTP_400; + } + + const ALLOWED_TYPES = [ + // TODO proper content types from bug 807134. + "application/json; charset=utf-8", + "application/json+zlib; charset=utf-8", + ]; + + let ct = request.getHeader("Content-Type"); + if (ALLOWED_TYPES.indexOf(ct) == -1) { + this._log.info("Unknown media type: " + ct); + // Should generate proper HTTP response headers for this error. + throw HTTP_415; + } + + if (ct.startsWith("application/json+zlib")) { + this._log.debug("Uncompressing entity body with deflate."); + requestBody = CommonUtils.convertString(requestBody, "deflate", + "uncompressed"); + } + + this._log.debug("HTTP request body: " + requestBody); + + let doc; + try { + doc = JSON.parse(requestBody); + } catch(ex) { + this._log.info("JSON parse error."); + throw HTTP_400; + } + + this.namespaces[namespace][id] = doc; + + if (request.hasHeader("X-Obsolete-Document")) { + let obsolete = request.getHeader("X-Obsolete-Document"); + delete this.namespaces[namespace][obsolete]; + } + + response.setStatusLine(request.httpVersion, 201, "Created"); + response.setHeader("Content-Type", "text/plain"); + + let body = id; + response.bodyOutputStream.write(body, body.length); + }, + + _handleNamespaceSubmitDelete: + function _handleNamespaceSubmitDelete(namespace, id, request, response) { + + delete this.namespaces[namespace][id]; + + let body = id; + response.bodyOutputStream.write(body, body.length); + }, +}; + +Object.freeze(BagheeraServer.prototype); diff --git a/services/common/tests/run_bagheera_server.js b/services/common/tests/run_bagheera_server.js new file mode 100644 index 000000000000..631cdb84377f --- /dev/null +++ b/services/common/tests/run_bagheera_server.js @@ -0,0 +1,26 @@ +/* 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/. */ + +/** + * This file runs a stub Bagheera server. + * + * It is meant to be executed with an xpcshell. + * + * The Makefile in this directory contains a target to run it: + * + * $ make bagheera-server + */ + +Cu.import("resource://testing-common/services-common/bagheeraserver.js"); + +initTestLogging(); + +let server = new BagheeraServer(); +server.allowAllNamespaces = true; +server.start(SERVER_PORT); +_("Bagheera server started on port " + SERVER_PORT); + +// Launch the thread manager. +_do_main(); + diff --git a/services/common/tests/unit/test_bagheera_client.js b/services/common/tests/unit/test_bagheera_client.js new file mode 100644 index 000000000000..3200fcde779f --- /dev/null +++ b/services/common/tests/unit/test_bagheera_client.js @@ -0,0 +1,89 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +Cu.import("resource://services-common/bagheeraclient.js"); +Cu.import("resource://services-common/rest.js"); +Cu.import("resource://testing-common/services-common/bagheeraserver.js"); + + +const PORT = 8080; + +function getClientAndServer(port=PORT) { + let uri = "http://localhost"; + let server = new BagheeraServer(uri); + + server.start(port); + + let client = new BagheeraClient(uri + ":" + port); + + return [client, server]; +} + +function run_test() { + initTestLogging("Trace"); + run_next_test(); +} + +add_test(function test_constructor() { + let client = new BagheeraClient("http://localhost:8080/"); + + run_next_test(); +}); + +add_test(function test_post_json_transport_failure() { + let client = new BagheeraClient("http://localhost:8080/"); + + client.uploadJSON("foo", "bar", {}).then(function onResult(result) { + do_check_false(result.transportSuccess); + + run_next_test(); + }); +}); + +add_test(function test_post_json_simple() { + let [client, server] = getClientAndServer(); + + server.createNamespace("foo"); + let promise = client.uploadJSON("foo", "bar", {foo: "bar", biz: "baz"}); + + promise.then(function onSuccess(result) { + do_check_true(result instanceof BagheeraClientRequestResult); + do_check_true(result.request instanceof RESTRequest); + do_check_true(result.transportSuccess); + do_check_true(result.serverSuccess); + + server.stop(run_next_test); + }, do_check_null); +}); + +add_test(function test_post_json_bad_data() { + let [client, server] = getClientAndServer(); + + server.createNamespace("foo"); + + client.uploadJSON("foo", "bar", "{this is invalid json}").then( + function onResult(result) { + do_check_true(result.transportSuccess); + do_check_false(result.serverSuccess); + + server.stop(run_next_test); + }); +}); + +add_test(function test_delete_document() { + let [client, server] = getClientAndServer(); + + server.createNamespace("foo"); + server.setDocument("foo", "bar", "{}"); + + client.deleteDocument("foo", "bar").then(function onResult(result) { + do_check_true(result.transportSuccess); + do_check_true(result.serverSuccess); + + do_check_null(server.getDocument("foo", "bar")); + + server.stop(run_next_test); + }); +}); diff --git a/services/common/tests/unit/test_bagheera_server.js b/services/common/tests/unit/test_bagheera_server.js new file mode 100644 index 000000000000..df467e08aa24 --- /dev/null +++ b/services/common/tests/unit/test_bagheera_server.js @@ -0,0 +1,45 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +Cu.import("resource://testing-common/services-common/bagheeraserver.js"); + +const PORT = 8080; + +function run_test() { + run_next_test(); +} + +add_test(function test_server_empty() { + let server = new BagheeraServer(); + + do_check_false(server.hasNamespace("foo")); + do_check_false(server.hasDocument("foo", "bar")); + do_check_null(server.getDocument("foo", "bar")); + + server.createNamespace("foo"); + do_check_true(server.hasNamespace("foo")); + + run_next_test(); +}); + +add_test(function test_server_start_no_port() { + let server = new BagheeraServer(); + + try { + server.start(); + } catch (ex) { + do_check_true(ex.message.startsWith("port argument must be")); + } + + run_next_test(); +}); + +add_test(function test_server_start() { + let server = new BagheeraServer(); + server.start(PORT); + + server.stop(run_next_test); +}); + diff --git a/services/common/tests/unit/test_load_modules.js b/services/common/tests/unit/test_load_modules.js index cf51e86ec076..572a58f017ed 100644 --- a/services/common/tests/unit/test_load_modules.js +++ b/services/common/tests/unit/test_load_modules.js @@ -3,6 +3,7 @@ const modules = [ "async.js", + "bagheeraclient.js", "log4moz.js", "preferences.js", "rest.js", @@ -14,6 +15,7 @@ const modules = [ const test_modules = [ "aitcserver.js", + "bagheeraserver.js", "logging.js", "storageserver.js", ]; diff --git a/services/common/tests/unit/xpcshell.ini b/services/common/tests/unit/xpcshell.ini index 5709890119f3..9f386c473a1d 100644 --- a/services/common/tests/unit/xpcshell.ini +++ b/services/common/tests/unit/xpcshell.ini @@ -22,6 +22,8 @@ tail = [test_aitc_server.js] [test_async_chain.js] [test_async_querySpinningly.js] +[test_bagheera_server.js] +[test_bagheera_client.js] [test_log4moz.js] [test_observers.js] [test_preferences.js] From f419461ab67b1f25a0265668e5819254794c0a0f Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Thu, 8 Nov 2012 15:24:56 -0800 Subject: [PATCH 60/75] Bug 810053 - Add explicit test for obsolete document deletion; r=rnewman --- .../common/modules-testing/bagheeraserver.js | 1 + .../common/tests/unit/test_bagheera_client.js | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/services/common/modules-testing/bagheeraserver.js b/services/common/modules-testing/bagheeraserver.js index 35e17bd52916..a8756a4248a8 100644 --- a/services/common/modules-testing/bagheeraserver.js +++ b/services/common/modules-testing/bagheeraserver.js @@ -273,6 +273,7 @@ BagheeraServer.prototype = { if (request.hasHeader("X-Obsolete-Document")) { let obsolete = request.getHeader("X-Obsolete-Document"); + this._log.info("Deleting from X-Obsolete-Document header: " + obsolete); delete this.namespaces[namespace][obsolete]; } diff --git a/services/common/tests/unit/test_bagheera_client.js b/services/common/tests/unit/test_bagheera_client.js index 3200fcde779f..e936076f27fa 100644 --- a/services/common/tests/unit/test_bagheera_client.js +++ b/services/common/tests/unit/test_bagheera_client.js @@ -72,6 +72,22 @@ add_test(function test_post_json_bad_data() { }); }); +add_test(function test_post_json_delete_obsolete() { + let [client, server] = getClientAndServer(); + server.createNamespace("foo"); + server.setDocument("foo", "obsolete", "Old payload"); + + let promise = client.uploadJSON("foo", "new", {foo: "bar"}, "obsolete"); + promise.then(function onSuccess(result) { + do_check_true(result.transportSuccess); + do_check_true(result.serverSuccess); + do_check_true(server.hasDocument("foo", "new")); + do_check_false(server.hasDocument("foo", "obsolete")); + + server.stop(run_next_test); + }); +}); + add_test(function test_delete_document() { let [client, server] = getClientAndServer(); From 48d4b18c33d015aa8b0a2a7cb99563ecd734c1ac Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Thu, 8 Nov 2012 15:32:49 -0800 Subject: [PATCH 61/75] Bug 809930 - Make metrics provider collection API more robust; r=rnewman --- services/metrics/collector.jsm | 34 +++++++++++++++-- services/metrics/dataprovider.jsm | 29 +++++++++++--- services/metrics/modules-testing/mocks.jsm | 20 +++++++++- .../test_metrics_collection_result.js | 14 ++++++- .../tests/xpcshell/test_metrics_collector.js | 38 +++++++++++++++++++ .../tests/xpcshell/test_metrics_provider.js | 3 +- 6 files changed, 124 insertions(+), 14 deletions(-) diff --git a/services/metrics/collector.jsm b/services/metrics/collector.jsm index f4ff9f4b28e4..aedeb15f2ab3 100644 --- a/services/metrics/collector.jsm +++ b/services/metrics/collector.jsm @@ -10,6 +10,7 @@ const {utils: Cu} = Components; Cu.import("resource://gre/modules/commonjs/promise/core.js"); Cu.import("resource://services-common/log4moz.js"); +Cu.import("resource://services-common/utils.js"); Cu.import("resource://gre/modules/services/metrics/dataprovider.jsm"); @@ -24,6 +25,7 @@ this.MetricsCollector = function MetricsCollector() { this._providers = []; this.collectionResults = new Map(); + this.providerErrors = new Map(); } MetricsCollector.prototype = { @@ -51,6 +53,8 @@ MetricsCollector.prototype = { provider: provider, constantsCollected: false, }); + + this.providerErrors.set(provider.name, []); }, /** @@ -65,16 +69,38 @@ MetricsCollector.prototype = { let promises = []; for (let provider of this._providers) { + let name = provider.provider.name; + if (provider.constantsCollected) { this._log.trace("Provider has already provided constant data: " + - provider.name); + name); + continue; + } + + let result; + try { + result = provider.provider.collectConstantMeasurements(); + } catch (ex) { + this._log.warn("Exception when calling " + name + + ".collectConstantMeasurements: " + + CommonUtils.exceptionStr(ex)); + this.providerErrors.get(name).push(ex); continue; } - let result = provider.provider.collectConstantMeasurements(); if (!result) { - this._log.trace("Provider does not provide constant data: " + - provider.name); + this._log.trace("Provider does not provide constant data: " + name); + continue; + } + + try { + this._log.debug("Populating constant measurements: " + name); + result.populate(result); + } catch (ex) { + this._log.warn("Exception when calling " + name + ".populate(): " + + CommonUtils.exceptionStr(ex)); + result.addError(ex); + promises.push(Promise.resolve(result)); continue; } diff --git a/services/metrics/dataprovider.jsm b/services/metrics/dataprovider.jsm index c82af71167c1..175db36c82e4 100644 --- a/services/metrics/dataprovider.jsm +++ b/services/metrics/dataprovider.jsm @@ -195,9 +195,18 @@ Object.freeze(MetricsMeasurement.prototype); * deferred events until after the result is populated. * * Implementations of collect* functions should call `createResult()` to create - * a new `MetricsCollectionResult` instance. When called, they should - * initiate population of this instance. Once population has finished (perhaps - * asynchronously), they should call `finish()` on the instance. + * a new `MetricsCollectionResult` instance. They should then register + * expected measurements with this instance, define a `populate` function on + * it, then return the instance. + * + * It is important for the collect* functions to just create the empty + * `MetricsCollectionResult` and nothing more. This is to enable the callee + * to handle errors gracefully. If the collect* function were to raise, the + * callee may not receive a `MetricsCollectionResult` instance and it would not + * know what data is missing. + * + * See the documentation for `MetricsCollectionResult` for details on how + * to perform population. * * Receivers of created `MetricsCollectionResult` instances should wait * until population has finished. They can do this by chaining on to the @@ -264,9 +273,12 @@ Object.freeze(MetricsProvider.prototype); * population of this instance is aborted or times out, downstream consumers * will know there is missing data. * - * Next, they should add empty `MetricsMeasurement` instances to it via - * `addMeasurement`. Finally, they should populate these measurements with - * `setValue`. + * Next, they should define the `populate` property to a function that + * populates the instance. + * + * The `populate` function implementation should add empty `MetricsMeasurement` + * instances to the result via `addMeasurement`. Then, it should populate these + * measurements via `setValue`. * * It is preferred to populate via this type instead of directly on * `MetricsMeasurement` instances so errors with data population can be @@ -290,6 +302,11 @@ this.MetricsCollectionResult = function MetricsCollectionResult(name) { this.expectedMeasurements = new Set(); this.errors = []; + this.populate = function populate() { + throw new Error("populate() must be defined on MetricsCollectionResult " + + "instance."); + }; + this._deferred = Promise.defer(); } diff --git a/services/metrics/modules-testing/mocks.jsm b/services/metrics/modules-testing/mocks.jsm index 05623a3297f2..9f65d4ebd0e4 100644 --- a/services/metrics/modules-testing/mocks.jsm +++ b/services/metrics/modules-testing/mocks.jsm @@ -37,6 +37,8 @@ this.DummyProvider = function DummyProvider(name="DummyProvider") { this.constantMeasurementName = "DummyMeasurement"; this.collectConstantCount = 0; + this.throwDuringCollectConstantMeasurements = null; + this.throwDuringConstantPopulate = null; } DummyProvider.prototype = { __proto__: MetricsProvider.prototype, @@ -46,13 +48,27 @@ DummyProvider.prototype = { let result = this.createResult(); result.expectMeasurement(this.constantMeasurementName); + + result.populate = this._populateConstantResult.bind(this); + + if (this.throwDuringCollectConstantMeasurements) { + throw new Error(this.throwDuringCollectConstantMeasurements); + } + + return result; + }, + + _populateConstantResult: function _populateConstantResult(result) { + if (this.throwDuringConstantPopulate) { + throw new Error(this.throwDuringConstantPopulate); + } + + this._log.debug("Populating constant measurement in DummyProvider."); result.addMeasurement(new DummyMeasurement(this.constantMeasurementName)); result.setValue(this.constantMeasurementName, "string", "foo"); result.setValue(this.constantMeasurementName, "uint32", 24); result.finish(); - - return result; }, }; diff --git a/services/metrics/tests/xpcshell/test_metrics_collection_result.js b/services/metrics/tests/xpcshell/test_metrics_collection_result.js index 57bb9a4dd885..1331e1614660 100644 --- a/services/metrics/tests/xpcshell/test_metrics_collection_result.js +++ b/services/metrics/tests/xpcshell/test_metrics_collection_result.js @@ -20,11 +20,22 @@ add_test(function test_constructor() { let failed = false; try { new MetricsCollectionResult(); - } catch(ex) { + } catch (ex) { do_check_true(ex.message.startsWith("Must provide name argument to Metrics")); failed = true; } finally { do_check_true(failed); + failed = false; + } + + try { + result.populate(); + } catch (ex) { + do_check_true(ex.message.startsWith("populate() must be defined")); + failed = true; + } finally { + do_check_true(failed); + failed = false; } run_next_test(); @@ -229,3 +240,4 @@ add_test(function test_finish() { result.finish(); }); + diff --git a/services/metrics/tests/xpcshell/test_metrics_collector.js b/services/metrics/tests/xpcshell/test_metrics_collector.js index cb63de34fd6b..9d615d9f5d1d 100644 --- a/services/metrics/tests/xpcshell/test_metrics_collector.js +++ b/services/metrics/tests/xpcshell/test_metrics_collector.js @@ -28,6 +28,7 @@ add_test(function test_register_provider() { do_check_eq(collector._providers.length, 1); collector.registerProvider(dummy); do_check_eq(collector._providers.length, 1); + do_check_eq(collector.providerErrors.size, 1); let failed = false; try { @@ -59,6 +60,43 @@ add_test(function test_collect_constant_measurements() { do_check_true(result instanceof MetricsCollectionResult); do_check_true(collector._providers[0].constantsCollected); + do_check_eq(collector.providerErrors.get("DummyProvider").length, 0); + + run_next_test(); + }); +}); + +add_test(function test_collect_constant_throws() { + let collector = new MetricsCollector(); + let provider = new DummyProvider(); + provider.throwDuringCollectConstantMeasurements = "Fake error during collect"; + collector.registerProvider(provider); + + collector.collectConstantMeasurements().then(function onResult() { + do_check_eq(collector.providerErrors.get("DummyProvider").length, 1); + do_check_eq(collector.providerErrors.get("DummyProvider")[0].message, + provider.throwDuringCollectConstantMeasurements); + + run_next_test(); + }); +}); + +add_test(function test_collect_constant_populate_throws() { + let collector = new MetricsCollector(); + let provider = new DummyProvider(); + provider.throwDuringConstantPopulate = "Fake error during constant populate"; + collector.registerProvider(provider); + + collector.collectConstantMeasurements().then(function onResult() { + do_check_eq(collector.collectionResults.size, 1); + do_check_true(collector.collectionResults.has("DummyProvider")); + + let result = collector.collectionResults.get("DummyProvider"); + do_check_eq(result.errors.length, 1); + do_check_eq(result.errors[0].message, provider.throwDuringConstantPopulate); + + do_check_false(collector._providers[0].constantsCollected); + do_check_eq(collector.providerErrors.get("DummyProvider").length, 0); run_next_test(); }); diff --git a/services/metrics/tests/xpcshell/test_metrics_provider.js b/services/metrics/tests/xpcshell/test_metrics_provider.js index b7a2f5d1ace0..2a969ae280f0 100644 --- a/services/metrics/tests/xpcshell/test_metrics_provider.js +++ b/services/metrics/tests/xpcshell/test_metrics_provider.js @@ -45,11 +45,12 @@ add_test(function test_default_collectors() { run_next_test(); }); -add_test(function test_collect_synchronous() { +add_test(function test_collect_constant_synchronous() { let provider = new DummyProvider(); let result = provider.collectConstantMeasurements(); do_check_true(result instanceof MetricsCollectionResult); + result.populate(result); result.onFinished(function onResult(res2) { do_check_eq(result, res2); From 92c4938c9e0b352bca22d57823933277fc12f10f Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Fri, 9 Nov 2012 09:27:00 -0800 Subject: [PATCH 62/75] Bug 809954 - Handle unexpected future dates; r=rnewman --- services/healthreport/policy.jsm | 18 ++++++++++++-- .../tests/xpcshell/test_policy.js | 24 +++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/services/healthreport/policy.jsm b/services/healthreport/policy.jsm index 39d64c70eb8e..0310d473beda 100644 --- a/services/healthreport/policy.jsm +++ b/services/healthreport/policy.jsm @@ -640,6 +640,22 @@ HealthReportPolicy.prototype = { let now = this.now(); let nowT = now.getTime(); + let nextSubmissionDate = this.nextDataSubmissionDate; + + // If the system clock were ever set to a time in the distant future, + // it's possible our next schedule date is far out as well. We know + // we shouldn't schedule for more than a day out, so we reset the next + // scheduled date appropriately. 3 days was chosen arbitrarily. + if (nextSubmissionDate.getTime() >= nowT + 3 * MILLISECONDS_PER_DAY) { + this._log.warn("Next data submission time is far away. Was the system " + + "clock recently readjusted? " + nextSubmissionDate); + + // It shouldn't really matter what we set this to. 1 day in the future + // should be pretty safe. + this._moveScheduleForward24h(); + + // Fall through and prompt for user notification, if necessary. + } // If the user hasn't responded to the data policy, don't do anything. if (!this.ensureNotifyResponse(now)) { @@ -655,8 +671,6 @@ HealthReportPolicy.prototype = { // User has responded to data policy and data submission is enabled. Now // comes the scheduling part. - let nextSubmissionDate = this.nextDataSubmissionDate; - if (nowT < nextSubmissionDate.getTime()) { this._log.debug("Next data submission is scheduled in the future: " + nextSubmissionDate); diff --git a/services/healthreport/tests/xpcshell/test_policy.js b/services/healthreport/tests/xpcshell/test_policy.js index 05c62c873790..0eb4e5e2c175 100644 --- a/services/healthreport/tests/xpcshell/test_policy.js +++ b/services/healthreport/tests/xpcshell/test_policy.js @@ -356,6 +356,30 @@ add_test(function test_submission_daily_scheduling() { run_next_test(); }); +add_test(function test_submission_far_future_scheduling() { + let [policy, prefs, listener] = getPolicy("submission_far_future_scheduling"); + + let now = new Date(Date.now() - 24 * 60 * 60 * 1000); + defineNow(policy, now); + policy.recordUserAcceptance(); + now = new Date(); + defineNow(policy, now); + + let nextDate = policy._futureDate(3 * 24 * 60 * 60 * 1000 - 1); + policy.nextDataSubmissionDate = nextDate; + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataSubmissionCount, 0); + do_check_eq(policy.nextDataSubmissionDate.getTime(), nextDate.getTime()); + + policy.nextDataSubmissionDate = new Date(nextDate.getTime() + 1); + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataSubmissionCount, 0); + do_check_eq(policy.nextDataSubmissionDate.getTime(), + policy._futureDate(24 * 60 * 60 * 1000).getTime()); + + run_next_test(); +}); + add_test(function test_submission_backoff() { let [policy, prefs, listener] = getPolicy("submission_backoff"); From c5073721cae2a0f9572454c3a2eae34476b3c3d5 Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Fri, 9 Nov 2012 13:59:40 -0800 Subject: [PATCH 63/75] Bug 810132 - Add remote deletion requests to policy; r=rnewman --- .../healthreport/modules-testing/mocks.jsm | 17 +- services/healthreport/policy.jsm | 241 ++++++++++++++---- .../tests/xpcshell/test_policy.js | 182 +++++++++++-- 3 files changed, 355 insertions(+), 85 deletions(-) diff --git a/services/healthreport/modules-testing/mocks.jsm b/services/healthreport/modules-testing/mocks.jsm index fbd377c751ef..ea0b40a11747 100644 --- a/services/healthreport/modules-testing/mocks.jsm +++ b/services/healthreport/modules-testing/mocks.jsm @@ -15,20 +15,29 @@ this.MockPolicyListener = function MockPolicyListener() { this._log = Log4Moz.repository.getLogger("HealthReport.Testing.MockPolicyListener"); this._log.level = Log4Moz.Level["Debug"]; - this.requestDataSubmissionCount = 0; + this.requestDataUploadCount = 0; this.lastDataRequest = null; + this.requestRemoteDeleteCount = 0; + this.lastRemoteDeleteRequest = null; + this.notifyUserCount = 0; this.lastNotifyRequest = null; } MockPolicyListener.prototype = { - onRequestDataSubmission: function onRequestDataSubmission(request) { - this._log.info("onRequestDataSubmission invoked."); - this.requestDataSubmissionCount++; + onRequestDataUpload: function onRequestDataUpload(request) { + this._log.info("onRequestDataUpload invoked."); + this.requestDataUploadCount++; this.lastDataRequest = request; }, + onRequestRemoteDelete: function onRequestRemoteDelete(request) { + this._log.info("onRequestRemoteDelete invoked."); + this.requestRemoteDeleteCount++; + this.lastRemoteDeleteRequest = request; + }, + onNotifyDataPolicy: function onNotifyDataPolicy(request) { this._log.info("onNotifyUser invoked."); this.notifyUserCount++; diff --git a/services/healthreport/policy.jsm b/services/healthreport/policy.jsm index 0310d473beda..ff181c213dd5 100644 --- a/services/healthreport/policy.jsm +++ b/services/healthreport/policy.jsm @@ -107,7 +107,9 @@ Object.freeze(NotifyPolicyRequest.prototype); /** * Represents a request to submit data. * - * Instances of this are created when the policy requests data submission. + * Instances of this are created when the policy requests data upload or + * deletion. + * * Receivers are expected to call one of the provided on* functions to signal * completion of the request. * @@ -115,9 +117,10 @@ Object.freeze(NotifyPolicyRequest.prototype); * Receivers of instances of this type should not attempt to do anything with * the instance except call one of the on* methods. */ -function DataSubmissionRequest(promise, expiresDate) { +function DataSubmissionRequest(promise, expiresDate, isDelete) { this.promise = promise; this.expiresDate = expiresDate; + this.isDelete = isDelete; this.state = null; this.reason = null; @@ -131,6 +134,10 @@ DataSubmissionRequest.prototype = { /** * No submission was attempted because no data was available. + * + * In the case of upload, this means there is no data to upload (perhaps + * it isn't available yet). In case of remote deletion, it means that there + * is no remote data to delete. */ onNoDataAvailable: function onNoDataAvailable() { this.state = this.NO_DATA_AVAILABLE; @@ -140,6 +147,9 @@ DataSubmissionRequest.prototype = { /** * Data submission has completed successfully. * + * In case of upload, this means the upload completed successfully. In case + * of deletion, the data was deleted successfully. + * * @param date * (Date) When data submission occurred. */ @@ -204,11 +214,16 @@ Object.freeze(DataSubmissionRequest.prototype); * The listener passed into the instance must have the following properties * (which are callbacks that will be invoked at certain key events): * - * * onRequestDataSubmission(request) - Called when the policy is requesting + * * onRequestDataUpload(request) - Called when the policy is requesting * data to be submitted. The function is passed a `DataSubmissionRequest`. * The listener should call one of the special resolving functions on that * instance (see the documentation for that type). * + * * onRequestRemoteDelete(request) - Called when the policy is requesting + * deletion of remotely stored data. The function is passed a + * `DataSubmissionRequest`. The listener should call one of the special + * resolving functions on that instance (just like `onRequestDataUpload`). + * * * onNotifyDataPolicy(request) - Called when the policy is requesting the * user to be notified that data submission will occur. The function * receives a `NotifyPolicyRequest` instance. The callee should call one or @@ -321,7 +336,11 @@ HealthReportPolicy.prototype = { STATE_NOTIFY_WAIT: "waiting", STATE_NOTIFY_COMPLETE: "ok", - REQUIRED_LISTENERS: ["onRequestDataSubmission", "onNotifyDataPolicy"], + REQUIRED_LISTENERS: [ + "onRequestDataUpload", + "onRequestRemoteDelete", + "onNotifyDataPolicy", + ], /** * The first time the health report policy came into existence. @@ -402,8 +421,8 @@ HealthReportPolicy.prototype = { /** * Whether submission of data is allowed. * - * This is the master switch for data submission. If it is off, we will - * never submit data, even if the user has agreed to it. + * This is the master switch for remote server communication. If it is + * false, we never request upload or deletion. */ get dataSubmissionEnabled() { // Default is true because we are opt-out. @@ -414,6 +433,22 @@ HealthReportPolicy.prototype = { this._prefs.set("dataSubmissionEnabled", !!value); }, + /** + * Whether upload of data is allowed. + * + * This is a kill switch for upload. It is meant to reflect a system or + * deployment policy decision. User intent should be reflected in the + * "dataSubmissionPolicy" prefs. + */ + get dataUploadEnabled() { + // Default is true because we are opt-out. + return this._prefs.get("dataUploadEnabled", true); + }, + + set dataUploadEnabled(value) { + this._prefs.set("dataUploadEnabled", !!value); + }, + /** * Whether the user has accepted that data submission can occur. * @@ -541,6 +576,21 @@ HealthReportPolicy.prototype = { this._prefs.set("currentDaySubmissionFailureCount", value); }, + /** + * Whether a request to delete remote data is awaiting completion. + * + * If this is true, the policy will request that remote data be deleted. + * Furthermore, no new data will be uploaded (if it's even allowed) until + * the remote deletion is fulfilled. + */ + get pendingDeleteRemoteData() { + return !!this._prefs.get("pendingDeleteRemoteData", false); + }, + + set pendingDeleteRemoteData(value) { + this._prefs.set("pendingDeleteRemoteData", !!value); + }, + /** * Record user acceptance of data submission policy. * @@ -578,6 +628,25 @@ HealthReportPolicy.prototype = { this.dataSubmissionPolicyAccepted = false; }, + /** + * Request that remote data be deleted. + * + * This will record an intent that previously uploaded data is to be deleted. + * The policy will eventually issue a request to the listener for data + * deletion. It will keep asking for deletion until the listener acknowledges + * that data has been deleted. + */ + deleteRemoteData: function deleteRemoteData(reason="no-reason") { + this._log.info("Remote data deletion requested: " + reason); + + this.pendingDeleteRemoteData = true; + + // We want delete deletion to occur as soon as possible. Move up any + // pending scheduled data submission and try to trigger. + this.nextDataSubmissionDate = this.now(); + this.checkStateAndTrigger(); + }, + /** * Start background polling for activity. * @@ -654,7 +723,29 @@ HealthReportPolicy.prototype = { // should be pretty safe. this._moveScheduleForward24h(); - // Fall through and prompt for user notification, if necessary. + // Fall through since we may have other actions. + } + + // Tend to any in progress work. + if (this._processInProgressSubmission()) { + return; + } + + // Requests to delete remote data take priority above everything else. + if (this.pendingDeleteRemoteData) { + if (nowT < nextSubmissionDate.getTime()) { + this._log.debug("Deletion request is scheduled for the future: " + + nextSubmissionDate); + return; + } + + this._dispatchSubmissionRequest("onRequestRemoteDelete", true); + return; + } + + if (!this.dataUploadEnabled) { + this._log.debug("Data upload is disabled. Doing nothing."); + return; } // If the user hasn't responded to the data policy, don't do anything. @@ -677,53 +768,7 @@ HealthReportPolicy.prototype = { return; } - if (this._inProgressSubmissionRequest) { - if (this._inProgressSubmissionRequest.expiresDate.getTime() > nowT) { - this._log.info("Waiting on in-progress submission request to finish."); - return; - } - - this._log.warn("Old submission request has expired from no activity."); - this._inProgressSubmissionRequest.promise.reject(new Error("Request has expired.")); - this._inProgressSubmissionRequest = null; - if (!this._handleSubmissionFailure()) { - return; - } - } - - // We're past our scheduled next data submission date, so let's do it! - this.lastDataSubmissionRequestedDate = now; - let deferred = Promise.defer(); - let requestExpiresDate = - this._futureDate(this.SUBMISSION_REQUEST_EXPIRE_INTERVAL_MSEC); - this._inProgressSubmissionRequest = new DataSubmissionRequest(deferred, - requestExpiresDate); - - let onSuccess = function onSuccess(result) { - this._inProgressSubmissionRequest = null; - this._handleSubmissionResult(result); - }.bind(this); - - let onError = function onError(error) { - this._log.error("Error when handling data submission result: " + - CommonUtils.exceptionStr(result)); - this._inProgressSubmissionRequest = null; - this._handleSubmissionFailure(); - }.bind(this); - - deferred.promise.then(onSuccess, onError); - - this._log.info("Requesting data submission. Will expire at " + - requestExpiresDate); - try { - this._listener.onRequestDataSubmission(this._inProgressSubmissionRequest); - } catch (ex) { - this._log.warn("Exception when calling onRequestDataSubmission: " + - CommonUtils.exceptionStr(ex)); - this._inProgressSubmissionRequest = null; - this._handleSubmissionFailure(); - return; - } + this._dispatchSubmissionRequest("onRequestDataUpload", false); }, /** @@ -797,26 +842,109 @@ HealthReportPolicy.prototype = { return true; }, + _processInProgressSubmission: function _processInProgressSubmission() { + if (!this._inProgressSubmissionRequest) { + return false; + } + + let now = this.now().getTime(); + if (this._inProgressSubmissionRequest.expiresDate.getTime() > now) { + this._log.info("Waiting on in-progress submission request to finish."); + return true; + } + + this._log.warn("Old submission request has expired from no activity."); + this._inProgressSubmissionRequest.promise.reject(new Error("Request has expired.")); + this._inProgressSubmissionRequest = null; + this._handleSubmissionFailure(); + + return false; + }, + + _dispatchSubmissionRequest: function _dispatchSubmissionRequest(handler, isDelete) { + let now = this.now(); + + // We're past our scheduled next data submission date, so let's do it! + this.lastDataSubmissionRequestedDate = now; + let deferred = Promise.defer(); + let requestExpiresDate = + this._futureDate(this.SUBMISSION_REQUEST_EXPIRE_INTERVAL_MSEC); + this._inProgressSubmissionRequest = new DataSubmissionRequest(deferred, + requestExpiresDate, + isDelete); + + let onSuccess = function onSuccess(result) { + this._inProgressSubmissionRequest = null; + this._handleSubmissionResult(result); + }.bind(this); + + let onError = function onError(error) { + this._log.error("Error when handling data submission result: " + + CommonUtils.exceptionStr(result)); + this._inProgressSubmissionRequest = null; + this._handleSubmissionFailure(); + }.bind(this); + + deferred.promise.then(onSuccess, onError); + + this._log.info("Requesting data submission. Will expire at " + + requestExpiresDate); + try { + this._listener[handler](this._inProgressSubmissionRequest); + } catch (ex) { + this._log.warn("Exception when calling " + handler + ": " + + CommonUtils.exceptionStr(ex)); + this._inProgressSubmissionRequest = null; + this._handleSubmissionFailure(); + return; + } + }, + _handleSubmissionResult: function _handleSubmissionResult(request) { let state = request.state; let reason = request.reason || "no reason"; this._log.info("Got submission request result: " + state); if (state == request.SUBMISSION_SUCCESS) { - this._log.info("Successful data submission reported."); + if (request.isDelete) { + this.pendingDeleteRemoteData = false; + this._log.info("Successful data delete reported."); + } else { + this._log.info("Successful data upload reported."); + } + this.lastDataSubmissionSuccessfulDate = request.submissionDate; - this.nextDataSubmissionDate = + + let nextSubmissionDate = new Date(request.submissionDate.getTime() + MILLISECONDS_PER_DAY); + + // Schedule pending deletes immediately. This has potential to overload + // the server. However, the frequency of delete requests across all + // clients should be low, so this shouldn't pose a problem. + if (this.pendingDeleteRemoteData) { + nextSubmissionDate = this.now(); + } + + this.nextDataSubmissionDate = nextSubmissionDate; this.currentDaySubmissionFailureCount = 0; return; } if (state == request.NO_DATA_AVAILABLE) { + if (request.isDelete) { + this._log.info("Remote data delete requested but no remote data was stored."); + this.pendingDeleteRemoteData = false; + return; + } + this._log.info("No data was available to submit. May try later."); this._handleSubmissionFailure(); return; } + // We don't special case request.isDelete for these failures because it + // likely means there was a server error. + if (state == request.SUBMISSION_FAILURE_SOFT) { this._log.warn("Soft error submitting data: " + reason); this.lastDataSubmissionFailureDate = this.now(); @@ -862,3 +990,4 @@ HealthReportPolicy.prototype = { }; Object.freeze(HealthReportPolicy.prototype); + diff --git a/services/healthreport/tests/xpcshell/test_policy.js b/services/healthreport/tests/xpcshell/test_policy.js index 0eb4e5e2c175..a91d23cb4f24 100644 --- a/services/healthreport/tests/xpcshell/test_policy.js +++ b/services/healthreport/tests/xpcshell/test_policy.js @@ -34,7 +34,8 @@ function run_test() { add_test(function test_constructor() { let prefs = new Preferences("foo.bar"); let listener = { - onRequestDataSubmission: function() {}, + onRequestDataUpload: function() {}, + onRequestRemoteDelete: function() {}, onNotifyDataPolicy: function() {}, }; @@ -99,6 +100,10 @@ add_test(function test_prefs() { do_check_eq(prefs.get("currentDaySubmissionFailureCount", 0), 2); do_check_eq(policy.currentDaySubmissionFailureCount, 2); + policy.pendingDeleteRemoteData = true; + do_check_true(prefs.get("pendingDeleteRemoteData")); + do_check_true(policy.pendingDeleteRemoteData); + run_next_test(); }); @@ -233,7 +238,7 @@ add_test(function test_notification_rejected() { // No requests for submission should occur if user has rejected. defineNow(policy, new Date(policy.nextDataSubmissionDate.getTime() + 10000)); policy.checkStateAndTrigger(); - do_check_eq(listener.requestDataSubmissionCount, 0); + do_check_eq(listener.requestDataUploadCount, 0); run_next_test(); }); @@ -245,13 +250,30 @@ add_test(function test_submission_kill_switch() { policy.nextDataSubmissionDate = new Date(Date.now() - 24 * 60 * 60 * 1000); policy.recordUserAcceptance("accept-old-ack"); policy.checkStateAndTrigger(); - do_check_eq(listener.requestDataSubmissionCount, 1); + do_check_eq(listener.requestDataUploadCount, 1); defineNow(policy, new Date(Date.now() + policy.SUBMISSION_REQUEST_EXPIRE_INTERVAL_MSEC + 100)); policy.dataSubmissionEnabled = false; policy.checkStateAndTrigger(); - do_check_eq(listener.requestDataSubmissionCount, 1); + do_check_eq(listener.requestDataUploadCount, 1); + + run_next_test(); +}); + +add_test(function test_upload_kill_switch() { + let [policy, prefs, listener] = getPolicy("upload_kill_switch"); + + defineNow(policy, policy._futureDate(-24 * 60 * 60 * 1000)); + policy.recordUserAcceptance(); + defineNow(policy, policy.nextDataSubmissionDate); + + policy.dataUploadEnabled = false; + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataUploadCount, 0); + policy.dataUploadEnabled = true; + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataUploadCount, 1); run_next_test(); }); @@ -263,15 +285,15 @@ add_test(function test_data_submission_no_data() { policy.dataSubmissionPolicyAccepted = true; let now = new Date(policy.nextDataSubmissionDate.getTime() + 1); defineNow(policy, now); - do_check_eq(listener.requestDataSubmissionCount, 0); + do_check_eq(listener.requestDataUploadCount, 0); policy.checkStateAndTrigger(); - do_check_eq(listener.requestDataSubmissionCount, 1); + do_check_eq(listener.requestDataUploadCount, 1); listener.lastDataRequest.onNoDataAvailable(); // The next trigger should try again. defineNow(policy, new Date(now.getTime() + 155 * 60 * 1000)); policy.checkStateAndTrigger(); - do_check_eq(listener.requestDataSubmissionCount, 2); + do_check_eq(listener.requestDataUploadCount, 2); run_next_test(); }); @@ -286,7 +308,7 @@ add_test(function test_data_submission_submit_failure_hard() { defineNow(policy, now); policy.checkStateAndTrigger(); - do_check_eq(listener.requestDataSubmissionCount, 1); + do_check_eq(listener.requestDataUploadCount, 1); listener.lastDataRequest.onSubmissionFailureHard(); do_check_eq(listener.lastDataRequest.state, listener.lastDataRequest.SUBMISSION_FAILURE_HARD); @@ -296,7 +318,7 @@ add_test(function test_data_submission_submit_failure_hard() { defineNow(policy, new Date(now.getTime() + 10)); policy.checkStateAndTrigger(); - do_check_eq(listener.requestDataSubmissionCount, 1); + do_check_eq(listener.requestDataUploadCount, 1); run_next_test(); }); @@ -327,7 +349,7 @@ add_test(function test_submission_daily_scheduling() { let now = new Date(policy.nextDataSubmissionDate.getTime()); defineNow(policy, now); policy.checkStateAndTrigger(); - do_check_eq(listener.requestDataSubmissionCount, 1); + do_check_eq(listener.requestDataUploadCount, 1); do_check_eq(policy.lastDataSubmissionRequestedDate.getTime(), now.getTime()); let finishedDate = new Date(now.getTime() + 250); @@ -344,11 +366,11 @@ add_test(function test_submission_daily_scheduling() { // Fast forward some arbitrary time. We shouldn't do any work yet. defineNow(policy, new Date(now.getTime() + 40000)); policy.checkStateAndTrigger(); - do_check_eq(listener.requestDataSubmissionCount, 1); + do_check_eq(listener.requestDataUploadCount, 1); defineNow(policy, nextScheduled); policy.checkStateAndTrigger(); - do_check_eq(listener.requestDataSubmissionCount, 2); + do_check_eq(listener.requestDataUploadCount, 2); listener.lastDataRequest.onSubmissionSuccess(new Date(nextScheduled.getTime() + 200)); do_check_eq(policy.nextDataSubmissionDate.getTime(), new Date(nextScheduled.getTime() + 24 * 60 * 60 * 1000 + 200).getTime()); @@ -368,12 +390,12 @@ add_test(function test_submission_far_future_scheduling() { let nextDate = policy._futureDate(3 * 24 * 60 * 60 * 1000 - 1); policy.nextDataSubmissionDate = nextDate; policy.checkStateAndTrigger(); - do_check_eq(listener.requestDataSubmissionCount, 0); + do_check_eq(listener.requestDataUploadCount, 0); do_check_eq(policy.nextDataSubmissionDate.getTime(), nextDate.getTime()); policy.nextDataSubmissionDate = new Date(nextDate.getTime() + 1); policy.checkStateAndTrigger(); - do_check_eq(listener.requestDataSubmissionCount, 0); + do_check_eq(listener.requestDataUploadCount, 0); do_check_eq(policy.nextDataSubmissionDate.getTime(), policy._futureDate(24 * 60 * 60 * 1000).getTime()); @@ -391,7 +413,7 @@ add_test(function test_submission_backoff() { let now = new Date(policy.nextDataSubmissionDate.getTime()); defineNow(policy, now); policy.checkStateAndTrigger(); - do_check_eq(listener.requestDataSubmissionCount, 1); + do_check_eq(listener.requestDataUploadCount, 1); do_check_eq(policy.currentDaySubmissionFailureCount, 0); now = new Date(now.getTime() + 5000); @@ -408,13 +430,13 @@ add_test(function test_submission_backoff() { now = new Date(policy.nextDataSubmissionDate.getTime() - 1); defineNow(policy, now); policy.checkStateAndTrigger(); - do_check_eq(listener.requestDataSubmissionCount, 1); + do_check_eq(listener.requestDataUploadCount, 1); // 2nd request for submission. now = new Date(policy.nextDataSubmissionDate.getTime()); defineNow(policy, now); policy.checkStateAndTrigger(); - do_check_eq(listener.requestDataSubmissionCount, 2); + do_check_eq(listener.requestDataUploadCount, 2); now = new Date(now.getTime() + 5000); defineNow(policy, now); @@ -428,7 +450,7 @@ add_test(function test_submission_backoff() { now = new Date(policy.nextDataSubmissionDate.getTime()); defineNow(policy, now); policy.checkStateAndTrigger(); - do_check_eq(listener.requestDataSubmissionCount, 3); + do_check_eq(listener.requestDataUploadCount, 3); now = new Date(now.getTime() + 5000); defineNow(policy, now); @@ -452,16 +474,126 @@ add_test(function test_submission_expiring() { let now = new Date(policy.nextDataSubmissionDate.getTime()); defineNow(policy, now); policy.checkStateAndTrigger(); - do_check_eq(listener.requestDataSubmissionCount, 1); + do_check_eq(listener.requestDataUploadCount, 1); defineNow(policy, new Date(now.getTime() + 500)); policy.checkStateAndTrigger(); - do_check_eq(listener.requestDataSubmissionCount, 1); + do_check_eq(listener.requestDataUploadCount, 1); defineNow(policy, new Date(policy.now().getTime() + policy.SUBMISSION_REQUEST_EXPIRE_INTERVAL_MSEC)); policy.checkStateAndTrigger(); - do_check_eq(listener.requestDataSubmissionCount, 2); + do_check_eq(listener.requestDataUploadCount, 2); + + run_next_test(); +}); + +add_test(function test_delete_remote_data() { + let [policy, prefs, listener] = getPolicy("delete_remote_data"); + + do_check_false(policy.pendingDeleteRemoteData); + let nextSubmissionDate = policy.nextDataSubmissionDate; + + let now = new Date(); + defineNow(policy, now); + + policy.deleteRemoteData(); + do_check_true(policy.pendingDeleteRemoteData); + do_check_neq(nextSubmissionDate.getTime(), + policy.nextDataSubmissionDate.getTime()); + do_check_eq(now.getTime(), policy.nextDataSubmissionDate.getTime()); + + do_check_eq(listener.requestRemoteDeleteCount, 1); + do_check_true(listener.lastRemoteDeleteRequest.isDelete); + defineNow(policy, policy._futureDate(1000)); + + listener.lastRemoteDeleteRequest.onSubmissionSuccess(policy.now()); + do_check_false(policy.pendingDeleteRemoteData); + + run_next_test(); +}); + +// Ensure that deletion requests take priority over regular data submission. +add_test(function test_delete_remote_data_priority() { + let [policy, prefs, listener] = getPolicy("delete_remote_data_priority"); + + let now = new Date(); + defineNow(policy, policy._futureDate(-24 * 60 * 60 * 1000)); + policy.recordUserAcceptance(); + defineNow(policy, new Date(now.getTime() + 3 * 24 * 60 * 60 * 1000)); + + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataUploadCount, 1); + policy._inProgressSubmissionRequest = null; + + policy.deleteRemoteData(); + policy.checkStateAndTrigger(); + + do_check_eq(listener.requestRemoteDeleteCount, 1); + do_check_eq(listener.requestDataUploadCount, 1); + + run_next_test(); +}); + +add_test(function test_delete_remote_data_backoff() { + let [policy, prefs, listener] = getPolicy("delete_remote_data_backoff"); + + let now = new Date(); + defineNow(policy, policy._futureDate(-24 * 60 * 60 * 1000)); + policy.recordUserAcceptance(); + defineNow(policy, now); + policy.nextDataSubmissionDate = now; + policy.deleteRemoteData(); + + policy.checkStateAndTrigger(); + do_check_eq(listener.requestRemoteDeleteCount, 1); + defineNow(policy, policy._futureDate(1000)); + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataUploadCount, 0); + do_check_eq(listener.requestRemoteDeleteCount, 1); + + defineNow(policy, policy._futureDate(500)); + listener.lastRemoteDeleteRequest.onSubmissionFailureSoft(); + defineNow(policy, policy._futureDate(50)); + + policy.checkStateAndTrigger(); + do_check_eq(listener.requestRemoteDeleteCount, 1); + + defineNow(policy, policy._futureDate(policy.FAILURE_BACKOFF_INTERVALS[0] - 50)); + policy.checkStateAndTrigger(); + do_check_eq(listener.requestRemoteDeleteCount, 2); + + run_next_test(); +}); + +// If we request delete while an upload is in progress, delete should be +// scheduled immediately after upload. +add_test(function test_delete_remote_data_in_progress_upload() { + let [policy, prefs, listener] = getPolicy("delete_remote_data_in_progress_upload"); + + let now = new Date(); + defineNow(policy, policy._futureDate(-24 * 60 * 60 * 1000)); + policy.recordUserAcceptance(); + defineNow(policy, policy.nextDataSubmissionDate); + + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataUploadCount, 1); + defineNow(policy, policy._futureDate(50 * 1000)); + + // If we request a delete during a pending request, nothing should be done. + policy.deleteRemoteData(); + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataUploadCount, 1); + do_check_eq(listener.requestRemoteDeleteCount, 0); + + // Now wait a little bit and finish the request. + defineNow(policy, policy._futureDate(10 * 1000)); + listener.lastDataRequest.onSubmissionSuccess(policy._futureDate(1000)); + defineNow(policy, policy._futureDate(5000)); + + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataUploadCount, 1); + do_check_eq(listener.requestRemoteDeleteCount, 1); run_next_test(); }); @@ -489,7 +621,7 @@ add_test(function test_polling() { policy.stopPolling(); do_check_eq(listener.notifyUserCount, 0); - do_check_eq(listener.requestDataSubmissionCount, 0); + do_check_eq(listener.requestDataUploadCount, 0); run_next_test(); } @@ -539,16 +671,16 @@ add_test(function test_polling_implicit_acceptance() { if (count < 4) { do_check_false(policy.dataSubmissionPolicyAccepted); - do_check_eq(listener.requestDataSubmissionCount, 0); + do_check_eq(listener.requestDataUploadCount, 0); } else { do_check_true(policy.dataSubmissionPolicyAccepted); do_check_eq(policy.dataSubmissionPolicyResponseType, "accepted-implicit-time-elapsed"); - do_check_eq(listener.requestDataSubmissionCount, 1); + do_check_eq(listener.requestDataUploadCount, 1); } if (count > 4) { - do_check_eq(listener.requestDataSubmissionCount, 1); + do_check_eq(listener.requestDataUploadCount, 1); policy.stopPolling(); run_next_test(); } From 9fe6a8cad5a0f18233d72ddfc4cf90417faaef2b Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Tue, 13 Nov 2012 20:22:09 -0800 Subject: [PATCH 64/75] Bug 808219 - Firefox Health Reporter service; r=rnewman --- b2g/installer/package-manifest.in | 7 + browser/installer/package-manifest.in | 7 + mobile/android/installer/package-manifest.in | 8 + mobile/xul/installer/package-manifest.in | 7 + .../HealthReportComponents.manifest | 11 + services/healthreport/HealthReportService.js | 132 ++++++ services/healthreport/Makefile.in | 8 + services/healthreport/README.rst | 45 ++ services/healthreport/healthreport-prefs.js | 21 + services/healthreport/healthreporter.jsm | 427 ++++++++++++++++++ services/healthreport/policy.jsm | 14 +- .../tests/xpcshell/test_healthreporter.js | 262 +++++++++++ .../tests/xpcshell/test_load_modules.js | 1 + .../healthreport/tests/xpcshell/xpcshell.ini | 1 + 14 files changed, 945 insertions(+), 6 deletions(-) create mode 100644 services/healthreport/HealthReportComponents.manifest create mode 100644 services/healthreport/HealthReportService.js create mode 100644 services/healthreport/README.rst create mode 100644 services/healthreport/healthreport-prefs.js create mode 100644 services/healthreport/healthreporter.jsm create mode 100644 services/healthreport/tests/xpcshell/test_healthreporter.js diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in index 11637ab7f447..dad20310e996 100644 --- a/b2g/installer/package-manifest.in +++ b/b2g/installer/package-manifest.in @@ -483,6 +483,10 @@ @BINPATH@/components/WeaveCrypto.manifest @BINPATH@/components/WeaveCrypto.js #endif +#ifdef MOZ_SERVICES_HEALTHREPORT +@BINPATH@/components/HealthReportComponents.manifest +@BINPATH@/components/HealthReportService.js +#endif @BINPATH@/components/TelemetryPing.js @BINPATH@/components/TelemetryPing.manifest @BINPATH@/components/Webapps.js @@ -574,6 +578,9 @@ #ifdef MOZ_SERVICES_SYNC @BINPATH@/@PREF_DIR@/services-sync.js #endif +#ifdef MOZ_SERVICES_HEALTHREPORT +@BINPATH@/@PREF_DIR@/healthreport-prefs.js +#endif @BINPATH@/greprefs.js @BINPATH@/defaults/autoconfig/platform.js @BINPATH@/defaults/autoconfig/prefcalls.js diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 1e2d188a248b..aa25bbdd962b 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -463,6 +463,10 @@ @BINPATH@/components/AitcComponents.manifest @BINPATH@/components/Aitc.js #endif +#ifdef MOZ_SERVICES_HEALTHREPORT +@BINPATH@/components/HealthReportComponents.manifest +@BINPATH@/components/HealthReportService.js +#endif #ifdef MOZ_SERVICES_NOTIFICATIONS @BINPATH@/components/NotificationsComponents.manifest #endif @@ -570,6 +574,9 @@ #ifdef MOZ_SERVICES_SYNC @BINPATH@/@PREF_DIR@/services-sync.js #endif +#ifdef MOZ_SERVICES_HEALTHREPORT +@BINPATH@/@PREF_DIR@/healthreport-prefs.js +#endif @BINPATH@/greprefs.js @BINPATH@/defaults/autoconfig/platform.js @BINPATH@/defaults/autoconfig/prefcalls.js diff --git a/mobile/android/installer/package-manifest.in b/mobile/android/installer/package-manifest.in index 4f0a72ed88fd..557f78452a10 100644 --- a/mobile/android/installer/package-manifest.in +++ b/mobile/android/installer/package-manifest.in @@ -357,6 +357,11 @@ @BINPATH@/components/TCPSocketParentIntermediary.js @BINPATH@/components/TCPSocket.manifest +#ifdef MOZ_SERVICES_HEALTHREPORT +@BINPATH@/components/HealthReportComponents.manifest +@BINPATH@/components/HealthReportService.js +#endif + ; Modules @BINPATH@/modules/* @@ -403,6 +408,9 @@ @BINPATH@/@PREF_DIR@/mobile.js @BINPATH@/@PREF_DIR@/mobile-branding.js @BINPATH@/@PREF_DIR@/channel-prefs.js +#ifdef MOZ_SERVICES_HEALTHREPORT +@BINPATH@/@PREF_DIR@/healthreport-prefs.js +#endif @BINPATH@/greprefs.js @BINPATH@/defaults/autoconfig/platform.js @BINPATH@/defaults/autoconfig/prefcalls.js diff --git a/mobile/xul/installer/package-manifest.in b/mobile/xul/installer/package-manifest.in index d1037db0c838..c4d01f0dc5ec 100644 --- a/mobile/xul/installer/package-manifest.in +++ b/mobile/xul/installer/package-manifest.in @@ -435,6 +435,10 @@ @BINPATH@/components/WeaveCrypto.manifest @BINPATH@/components/WeaveCrypto.js #endif +#ifdef MOZ_SERVICES_HEALTHREPORT +@BINPATH@/components/HealthReportComponents.manifest +@BINPATH@/components/HealthReportService.js +#endif @BINPATH@/components/TelemetryPing.js @BINPATH@/components/TelemetryPing.manifest @@ -501,6 +505,9 @@ #ifdef MOZ_SERVICES_SYNC @BINPATH@/@PREF_DIR@/services-sync.js #endif +#ifdef MOZ_SERVICES_HEALTHREPORT +@BINPATH@/@PREF_DIR@/healthreport-prefs.js +#endif @BINPATH@/greprefs.js @BINPATH@/defaults/autoconfig/platform.js @BINPATH@/defaults/autoconfig/prefcalls.js diff --git a/services/healthreport/HealthReportComponents.manifest b/services/healthreport/HealthReportComponents.manifest new file mode 100644 index 000000000000..f750c51d33b9 --- /dev/null +++ b/services/healthreport/HealthReportComponents.manifest @@ -0,0 +1,11 @@ +# b2g: {3c2e2abc-06d4-11e1-ac3b-374f68613e61} +# browser: {ec8030f7-c20a-464f-9b0e-13a3a9e97384} +# mobile/android: {aa3c5121-dab2-40e2-81ca-7ea25febc110} +# mobile/xul: {a23983c0-fd0e-11dc-95ff-0800200c9a66} +# suite (comm): {92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} +# metro browser: {99bceaaa-e3c6-48c1-b981-ef9b46b67d60} + +component {e354c59b-b252-4040-b6dd-b71864e3e35c} HealthReportService.js +contract @mozilla.org/healthreport/service;1 {e354c59b-b252-4040-b6dd-b71864e3e35c} +category app-startup HealthReportService service,@mozilla.org/healthreport/service;1 application={3c2e2abc-06d4-11e1-ac3b-374f68613e61} application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} application={aa3c5121-dab2-40e2-81ca-7ea25febc110} application={a23983c0-fd0e-11dc-95ff-0800200c9a66} + diff --git a/services/healthreport/HealthReportService.js b/services/healthreport/HealthReportService.js new file mode 100644 index 000000000000..1d8eba914309 --- /dev/null +++ b/services/healthreport/HealthReportService.js @@ -0,0 +1,132 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const {classes: Cc, interfaces: Ci, utils: Cu} = Components; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://services-common/preferences.js"); + + +const INITIAL_STARTUP_DELAY_MSEC = 10 * 1000; +const BRANCH = "healthreport."; +const JS_PROVIDERS_CATEGORY = "healthreport-js-provider"; + + +/** + * The Firefox Health Report XPCOM service. + * + * This instantiates an instance of HealthReporter (assuming it is enabled) + * and starts it upon application startup. + * + * One can obtain a reference to the underlying HealthReporter instance by + * accessing .reporter. If this property is null, the reporter isn't running + * yet or has been disabled. + */ +this.HealthReportService = function HealthReportService() { + this.wrappedJSObject = this; + + this.prefs = new Preferences(BRANCH); + this._reporter = null; +} + +HealthReportService.prototype = { + classID: Components.ID("{e354c59b-b252-4040-b6dd-b71864e3e35c}"), + + QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, + Ci.nsISupportsWeakReference]), + + observe: function observe(subject, topic, data) { + // If the background service is disabled, don't do anything. + if (!this.prefs.get("serviceEnabled", true)) { + return; + } + + let os = Cc["@mozilla.org/observer-service;1"] + .getService(Ci.nsIObserverService); + + switch (topic) { + case "app-startup": + os.addObserver(this, "final-ui-startup", true); + break; + + case "final-ui-startup": + os.removeObserver(this, "final-ui-startup"); + os.addObserver(this, "quit-application", true); + + // Delay service loading a little more so things have an opportunity + // to cool down first. + this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + this.timer.initWithCallback({ + notify: function notify() { + // Side effect: instantiates the reporter instance if not already + // accessed. + let reporter = this.reporter; + delete this.timer; + }.bind(this), + }, INITIAL_STARTUP_DELAY_MSEC, this.timer.TYPE_ONE_SHOT); + + break; + + case "quit-application-granted": + if (this.reporter) { + this.reporter.stop(); + } + + os.removeObserver(this, "quit-application"); + break; + } + }, + + /** + * The HealthReporter instance associated with this service. + */ + get reporter() { + if (!this.prefs.get("serviceEnabled", true)) { + return null; + } + + if (this._reporter) { + return this._reporter; + } + + // Lazy import so application startup isn't adversely affected. + let ns = {}; + Cu.import("resource://services-common/log4moz.js", ns); + Cu.import("resource://gre/modules/services/healthreport/healthreporter.jsm", ns); + + // How many times will we rewrite this code before rolling it up into a + // generic module? See also bug 451283. + const LOGGERS = [ + "Metrics", + "Services.HealthReport", + "Services.Metrics", + "Services.BagheeraClient", + ]; + + let prefs = new Preferences(BRANCH + "logging."); + if (prefs.get("consoleEnabled", true)) { + let level = prefs.get("consoleLevel", "Warn"); + let appender = new ns.Log4Moz.ConsoleAppender(); + appender.level = ns.Log4Moz.Level[level] || ns.Log4Moz.Level.Warn; + + for (let name of LOGGERS) { + let logger = ns.Log4Moz.repository.getLogger(name); + logger.addAppender(appender); + } + } + + this._reporter = new ns.HealthReporter(BRANCH); + this._reporter.registerProvidersFromCategoryManager(JS_PROVIDERS_CATEGORY); + this._reporter.start(); + + return this._reporter; + }, +}; + +Object.freeze(HealthReportService.prototype); + +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([HealthReportService]); + diff --git a/services/healthreport/Makefile.in b/services/healthreport/Makefile.in index 835c6f4a720e..3e203021a4c8 100644 --- a/services/healthreport/Makefile.in +++ b/services/healthreport/Makefile.in @@ -10,6 +10,7 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk modules := \ + healthreporter.jsm \ policy.jsm \ $(NULL) @@ -26,4 +27,11 @@ INSTALL_TARGETS += MODULES TESTING_JS_MODULES := $(addprefix modules-testing/,$(testing_modules)) TESTING_JS_MODULE_DIR := services/healthreport +EXTRA_COMPONENTS := \ + HealthReportComponents.manifest \ + HealthReportService.js \ + $(NULL) + +PREF_JS_EXPORTS := healthreport-prefs.js + include $(topsrcdir)/config/rules.mk diff --git a/services/healthreport/README.rst b/services/healthreport/README.rst new file mode 100644 index 000000000000..a07948bf9fc4 --- /dev/null +++ b/services/healthreport/README.rst @@ -0,0 +1,45 @@ +===================== +Firefox Health Report +===================== + +This directory contains the implementation of the Firefox Health Report +(FHR). + +Firefox Health Report is a background service that collects application +metrics and periodically submits them to a central server. + +Implementation Notes +==================== + +The XPCOM service powering FHR is defined in HealthReportService.js. It +simply instantiates an instance of HealthReporter from healthreporter.jsm. + +All the logic for enforcing the privacy policy and for scheduling data +submissions lives in policy.jsm. + +Preferences +=========== + +Preferences controlling behavior of Firefox Health Report live in the +*healthreport.* branch. + +Some important preferences are: + +* **healthreport.serviceEnabled** - Controls whether the entire health report + service runs. The overall service performs data collection, storing, and + submission. + +* **healthreport.policy.dataSubmissionEnabled** - Controls whether data + submission is enabled. If this is *false*, data will still be collected + and stored - it just won't ever be submitted to a remote server. + +If the entire service is disabled, you lose data collection. This means that +data analysis won't be available because there is no data to analyze! + +Other Notes +=========== + +There are many legal and privacy concerns with this code, especially +around the data that is submitted. Changes to submitted data should be +signed off by responsible parties. + diff --git a/services/healthreport/healthreport-prefs.js b/services/healthreport/healthreport-prefs.js new file mode 100644 index 000000000000..01b5cd454cf8 --- /dev/null +++ b/services/healthreport/healthreport-prefs.js @@ -0,0 +1,21 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +pref("healthreport.documentServerURI", "https://data.mozilla.com/"); +pref("healthreport.documentServerNamespace", "metrics"); +pref("healthreport.serviceEnabled", true); +pref("healthreport.logging.consoleEnabled", true); +pref("healthreport.logging.consoleLevel", "Warn"); +pref("healthreport.policy.currentDaySubmissionFailureCount", 0); +pref("healthreport.policy.dataSubmissionEnabled", true); +pref("healthreport.policy.dataSubmissionPolicyAccepted", false); +pref("healthreport.policy.dataSubmissionPolicyNotifiedTime", "0"); +pref("healthreport.policy.dataSubmissionPolicyResponseType", ""); +pref("healthreport.policy.dataSubmissionPolicyResponseTime", "0"); +pref("healthreport.policy.firstRunTime", "0"); +pref("healthreport.policy.lastDataSubmissionFailureTime", "0"); +pref("healthreport.policy.lastDataSubmissionRequestedTime", "0"); +pref("healthreport.policy.lastDataSubmissionSuccessfulTime", "0"); +pref("healthreport.policy.nextDataSubmissionTime", "0"); + diff --git a/services/healthreport/healthreporter.jsm b/services/healthreport/healthreporter.jsm new file mode 100644 index 000000000000..7c73e2482266 --- /dev/null +++ b/services/healthreport/healthreporter.jsm @@ -0,0 +1,427 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +this.EXPORTED_SYMBOLS = ["HealthReporter"]; + +const {classes: Cc, interfaces: Ci, utils: Cu} = Components; + +Cu.import("resource://services-common/bagheeraclient.js"); +Cu.import("resource://services-common/log4moz.js"); +Cu.import("resource://services-common/observers.js"); +Cu.import("resource://services-common/preferences.js"); +Cu.import("resource://services-common/utils.js"); +Cu.import("resource://gre/modules/commonjs/promise/core.js"); +Cu.import("resource://gre/modules/services/healthreport/policy.jsm"); +Cu.import("resource://gre/modules/services/metrics/collector.jsm"); + + +// Oldest year to allow in date preferences. This module was implemented in +// 2012 and no dates older than that should be encountered. +const OLDEST_ALLOWED_YEAR = 2012; + + +/** + * Coordinates collection and submission of metrics. + * + * This is the main type for Firefox Health Report. It glues all the + * lower-level components (such as collection and submission) together. + * + * An instance of this type is created as an XPCOM service. See + * HealthReportService.js and HealthReportComponents.manifest. + * + * It is theoretically possible to have multiple instances of this running + * in the application. For example, this type may one day handle submission + * of telemetry data as well. However, there is some moderate coupling between + * this type and *the* Firefox Health Report (e.g. the policy). This could + * be abstracted if needed. + * + * @param branch + * (string) The preferences branch to use for state storage. The value + * must end with a period (.). + */ +this.HealthReporter = function HealthReporter(branch) { + if (!branch.endsWith(".")) { + throw new Error("Branch argument must end with a period (.): " + branch); + } + + this._log = Log4Moz.repository.getLogger("Services.HealthReport.HealthReporter"); + + this._prefs = new Preferences(branch); + + let policyBranch = new Preferences(branch + "policy."); + this._policy = new HealthReportPolicy(policyBranch, this); + this._collector = new MetricsCollector(); + + if (!this.serverURI) { + throw new Error("No server URI defined. Did you forget to define the pref?"); + } + + if (!this.serverNamespace) { + throw new Error("No server namespace defined. Did you forget a pref?"); + } +} + +HealthReporter.prototype = { + /** + * When we last successfully submitted data to the server. + * + * This is sent as part of the upload. This is redundant with similar data + * in the policy because we like the modules to be loosely coupled and the + * similar data in the policy is only used for forensic purposes. + */ + get lastPingDate() { + return CommonUtils.getDatePref(this._prefs, "lastPingTime", 0, this._log, + OLDEST_ALLOWED_YEAR); + }, + + set lastPingDate(value) { + CommonUtils.setDatePref(this._prefs, "lastPingTime", value, + OLDEST_ALLOWED_YEAR); + }, + + /** + * The base URI of the document server to which to submit data. + * + * This is typically a Bagheera server instance. It is the URI up to but not + * including the version prefix. e.g. https://data.metrics.mozilla.com/ + */ + get serverURI() { + return this._prefs.get("documentServerURI", null); + }, + + set serverURI(value) { + if (!value) { + throw new Error("serverURI must have a value."); + } + + if (typeof(value) != "string") { + throw new Error("serverURI must be a string: " + value); + } + + this._prefs.set("documentServerURI", value); + }, + + /** + * The namespace on the document server to which we will be submitting data. + */ + get serverNamespace() { + return this._prefs.get("documentServerNamespace", "metrics"); + }, + + set serverNamespace(value) { + if (!value) { + throw new Error("serverNamespace must have a value."); + } + + if (typeof(value) != "string") { + throw new Error("serverNamespace must be a string: " + value); + } + + this._prefs.set("documentServerNamespace", value); + }, + + /** + * The document ID for data to be submitted to the server. + * + * This should be a UUID. + * + * We generate a new UUID when we upload data to the server. When we get a + * successful response for that upload, we record that UUID in this value. + * On the subsequent upload, this ID will be deleted from the server. + */ + get lastSubmitID() { + return this._prefs.get("lastSubmitID", null) || null; + }, + + set lastSubmitID(value) { + this._prefs.set("lastSubmitID", value || ""); + }, + + /** + * Whether remote data is currently stored. + * + * @return bool + */ + haveRemoteData: function haveRemoteData() { + return !!this.lastSubmitID; + }, + + /** + * Start background functionality. + * + * If this isn't called, no data upload will occur. + */ + start: function start() { + this._policy.startPolling(); + this._log.info("HealthReporter started."); + }, + + /** + * Stop background functionality. + */ + stop: function stop() { + this._policy.stopPolling(); + }, + + /** + * Register a `MetricsProvider` with this instance. + * + * This needs to be called or no data will be collected. See also + * registerProvidersFromCategoryManager`. + * + * @param provider + * (MetricsProvider) The provider to register for collection. + */ + registerProvider: function registerProvider(provider) { + return this._collector.registerProvider(provider); + }, + + /** + * Registers providers from a category manager category. + * + * This examines the specified category entries and registers found + * providers. + * + * Category entries are essentially JS modules and the name of the symbol + * within that module that is a `MetricsProvider` instance. + * + * The category entry name is the name of the JS type for the provider. The + * value is the resource:// URI to import which makes this type available. + * + * Example entry: + * + * FooProvider resource://gre/modules/foo.jsm + * + * One can register entries in the application's .manifest file. e.g. + * + * category healthreport-js-provider FooProvider resource://gre/modules/foo.jsm + * + * Then to load them: + * + * let reporter = new HealthReporter("healthreport."); + * reporter.registerProvidersFromCategoryManager("healthreport-js-provider"); + * + * @param category + * (string) Name of category to query and load from. + */ + registerProvidersFromCategoryManager: + function registerProvidersFromCategoryManager(category) { + + let cm = Cc["@mozilla.org/categorymanager;1"] + .getService(Ci.nsICategoryManager); + + let enumerator = cm.enumerateCategory(category); + while (enumerator.hasMoreElements()) { + let entry = enumerator.getNext() + .QueryInterface(Ci.nsISupportsCString) + .toString(); + + let uri = cm.getCategoryEntry(category, entry); + this._log.info("Attempting to load provider from category manager: " + + entry + " from " + uri); + + try { + let ns = {}; + Cu.import(uri, ns); + + let provider = new ns[entry](); + this.registerProvider(provider); + } catch (ex) { + this._log.warn("Error registering provider from category manager: " + + entry + "; " + CommonUtils.exceptionStr(ex)); + continue; + } + } + }, + + /** + * Collect all measurements for all registered providers. + */ + collectMeasurements: function collectMeasurements() { + return this._collector.collectConstantMeasurements(); + }, + + /** + * Record the user's rejection of the data submission policy. + * + * This should be what everything uses to disable data submission. + * + * @param reason + * (string) Why data submission is being disabled. + */ + recordPolicyRejection: function recordPolicyRejection(reason) { + this._policy.recordUserRejection(reason); + }, + + /** + * Record the user's acceptance of the data submission policy. + * + * This should be what everything uses to enable data submission. + * + * @param reason + * (string) Why data submission is being enabled. + */ + recordPolicyAcceptance: function recordPolicyAcceptance(reason) { + this._policy.recordUserAcceptance(reason); + }, + + /** + * Whether the data submission policy has been accepted. + * + * If this is true, health data will be submitted unless one of the kill + * switches is active. + */ + get dataSubmissionPolicyAccepted() { + return this._policy.dataSubmissionPolicyAccepted; + }, + + /** + * Whether this health reporter will upload data to a server. + */ + get willUploadData() { + return this._policy.dataSubmissionPolicyAccepted && + this._policy.dataUploadEnabled; + }, + + /** + * Request that server data be deleted. + * + * If deletion is scheduled to occur immediately, a promise will be returned + * that will be fulfilled when the deletion attempt finishes. Otherwise, + * callers should poll haveRemoteData() to determine when remote data is + * deleted. + */ + requestDeleteRemoteData: function requestDeleteRemoteData(reason) { + if (!this.lastSubmitID) { + return; + } + + return this._policy.deleteRemoteData(reason); + }, + + getJSONPayload: function getJSONPayload() { + let o = { + version: 1, + thisPingDate: this._formatDate(this._now()), + providers: {}, + }; + + let lastPingDate = this.lastPingDate; + if (lastPingDate.getTime() > 0) { + o.lastPingDate = this._formatDate(lastPingDate); + } + + for (let [name, provider] of this._collector.collectionResults) { + o.providers[name] = provider; + } + + return JSON.stringify(o); + }, + + _onBagheeraResult: function _onBagheeraResult(request, isDelete, result) { + this._log.debug("Received Bagheera result."); + + let promise = Promise.resolve(null); + + if (!result.transportSuccess) { + request.onSubmissionFailureSoft("Network transport error."); + return promise; + } + + if (!result.serverSuccess) { + request.onSubmissionFailureHard("Server failure."); + return promise; + } + + let now = this._now(); + + if (isDelete) { + this.lastSubmitID = null; + } else { + this.lastSubmitID = result.id; + this.lastPingDate = now; + } + + request.onSubmissionSuccess(now); + + return promise; + }, + + _onSubmitDataRequestFailure: function _onSubmitDataRequestFailure(error) { + this._log.error("Error processing request to submit data: " + + CommonUtils.exceptionStr(error)); + }, + + _formatDate: function _formatDate(date) { + // Why, oh, why doesn't JS have a strftime() equivalent? + return date.toISOString().substr(0, 10); + }, + + + _uploadData: function _uploadData(request) { + let id = CommonUtils.generateUUID(); + + this._log.info("Uploading data to server: " + this.serverURI + " " + + this.serverNamespace + ":" + id); + let client = new BagheeraClient(this.serverURI); + + let payload = this.getJSONPayload(); + + let promise = client.uploadJSON(this.serverNamespace, + id, + payload, + this.lastSubmitID); + + return promise.then(this._onBagheeraResult.bind(this, request, false)); + }, + + _deleteRemoteData: function _deleteRemoteData(request) { + if (!this.lastSubmitID) { + this._log.info("Received request to delete remote data but no data stored."); + request.onNoDataAvailable(); + return; + } + + this._log.warn("Deleting remote data."); + let client = new BagheeraClient(this.serverURI); + + return client.deleteDocument(this.serverNamespace, this.lastSubmitID) + .then(this._onBagheeraResult.bind(this, request, true), + this._onSubmitDataRequestFailure.bind(this)); + + }, + + _now: function _now() { + return new Date(); + }, + + //----------------------------- + // HealthReportPolicy listeners + //----------------------------- + + onRequestDataUpload: function onRequestDataSubmission(request) { + this.collectMeasurements() + .then(this._uploadData.bind(this, request), + this._onSubmitDataRequestFailure.bind(this)); + }, + + onNotifyDataPolicy: function onNotifyDataPolicy(request) { + // This isn't very loosely coupled. We may want to have this call + // registered listeners instead. + Observers.notify("healthreport:notify-data-policy:request", request); + }, + + onRequestRemoteDelete: function onRequestRemoteDelete(request) { + this._deleteRemoteData(request); + }, + + //------------------------------------ + // End of HealthReportPolicy listeners + //------------------------------------ +}; + +Object.freeze(HealthReporter.prototype); + diff --git a/services/healthreport/policy.jsm b/services/healthreport/policy.jsm index ff181c213dd5..2e9b56fa4a36 100644 --- a/services/healthreport/policy.jsm +++ b/services/healthreport/policy.jsm @@ -5,6 +5,7 @@ "use strict"; this.EXPORTED_SYMBOLS = [ + "DataSubmissionRequest", // For test use only. "HealthReportPolicy", ]; @@ -242,7 +243,7 @@ Object.freeze(DataSubmissionRequest.prototype); * events. */ this.HealthReportPolicy = function HealthReportPolicy(prefs, listener) { - this._log = Log4Moz.repository.getLogger("HealthReport.Policy"); + this._log = Log4Moz.repository.getLogger("Services.HealthReport.Policy"); this._log.level = Log4Moz.Level["Debug"]; for (let handler of this.REQUIRED_LISTENERS) { @@ -644,7 +645,7 @@ HealthReportPolicy.prototype = { // We want delete deletion to occur as soon as possible. Move up any // pending scheduled data submission and try to trigger. this.nextDataSubmissionDate = this.now(); - this.checkStateAndTrigger(); + return this.checkStateAndTrigger(); }, /** @@ -739,8 +740,7 @@ HealthReportPolicy.prototype = { return; } - this._dispatchSubmissionRequest("onRequestRemoteDelete", true); - return; + return this._dispatchSubmissionRequest("onRequestRemoteDelete", true); } if (!this.dataUploadEnabled) { @@ -768,7 +768,7 @@ HealthReportPolicy.prototype = { return; } - this._dispatchSubmissionRequest("onRequestDataUpload", false); + return this._dispatchSubmissionRequest("onRequestDataUpload", false); }, /** @@ -885,7 +885,7 @@ HealthReportPolicy.prototype = { this._handleSubmissionFailure(); }.bind(this); - deferred.promise.then(onSuccess, onError); + let chained = deferred.promise.then(onSuccess, onError); this._log.info("Requesting data submission. Will expire at " + requestExpiresDate); @@ -898,6 +898,8 @@ HealthReportPolicy.prototype = { this._handleSubmissionFailure(); return; } + + return chained; }, _handleSubmissionResult: function _handleSubmissionResult(request) { diff --git a/services/healthreport/tests/xpcshell/test_healthreporter.js b/services/healthreport/tests/xpcshell/test_healthreporter.js new file mode 100644 index 000000000000..275870b719db --- /dev/null +++ b/services/healthreport/tests/xpcshell/test_healthreporter.js @@ -0,0 +1,262 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const {classes: Cc, interfaces: Ci, utils: Cu} = Components; + +Cu.import("resource://services-common/observers.js"); +Cu.import("resource://services-common/preferences.js"); +Cu.import("resource://gre/modules/commonjs/promise/core.js"); +Cu.import("resource://gre/modules/services/healthreport/healthreporter.jsm"); +Cu.import("resource://gre/modules/services/healthreport/policy.jsm"); +Cu.import("resource://testing-common/services-common/bagheeraserver.js"); +Cu.import("resource://testing-common/services/metrics/mocks.jsm"); + + +const SERVER_HOSTNAME = "localhost"; +const SERVER_PORT = 8080; +const SERVER_URI = "http://" + SERVER_HOSTNAME + ":" + SERVER_PORT; + + +function defineNow(policy, now) { + print("Adjusting fake system clock to " + now); + Object.defineProperty(policy, "now", { + value: function customNow() { + return now; + }, + writable: true, + }); +} + +function getReporter(name, uri=SERVER_URI) { + let branch = "healthreport.testing. " + name + "."; + + let prefs = new Preferences(branch); + prefs.set("documentServerURI", uri); + + return new HealthReporter(branch); +} + +function getReporterAndServer(name, namespace="test") { + let reporter = getReporter(name, SERVER_URI); + reporter.serverNamespace = namespace; + + let server = new BagheeraServer(SERVER_URI); + server.createNamespace(namespace); + + server.start(SERVER_PORT); + + return [reporter, server]; +} + +function run_test() { + run_next_test(); +} + +add_test(function test_constructor() { + let reporter = getReporter("constructor"); + + do_check_eq(reporter.lastPingDate.getTime(), 0); + do_check_null(reporter.lastSubmitID); + + reporter.lastSubmitID = "foo"; + do_check_eq(reporter.lastSubmitID, "foo"); + reporter.lastSubmitID = null; + do_check_null(reporter.lastSubmitID); + + let failed = false; + try { + new HealthReporter("foo.bar"); + } catch (ex) { + failed = true; + do_check_true(ex.message.startsWith("Branch argument must end")); + } finally { + do_check_true(failed); + failed = false; + } + + run_next_test(); +}); + +add_test(function test_register_providers_from_category_manager() { + const category = "healthreporter-js-modules"; + + let cm = Cc["@mozilla.org/categorymanager;1"] + .getService(Ci.nsICategoryManager); + cm.addCategoryEntry(category, "DummyProvider", + "resource://testing-common/services/metrics/mocks.jsm", + false, true); + + let reporter = getReporter("category_manager"); + do_check_eq(reporter._collector._providers.length, 0); + reporter.registerProvidersFromCategoryManager(category); + do_check_eq(reporter._collector._providers.length, 1); + + run_next_test(); +}); + +add_test(function test_json_payload_simple() { + let reporter = getReporter("json_payload_simple"); + + let now = new Date(); + let payload = reporter.getJSONPayload(); + let original = JSON.parse(payload); + + do_check_eq(original.version, 1); + do_check_eq(original.thisPingDate, reporter._formatDate(now)); + do_check_eq(Object.keys(original.providers).length, 0); + + reporter.lastPingDate = new Date(now.getTime() - 24 * 60 * 60 * 1000 - 10); + + original = JSON.parse(reporter.getJSONPayload()); + do_check_eq(original.lastPingDate, reporter._formatDate(reporter.lastPingDate)); + + // This could fail if we cross UTC day boundaries at the exact instance the + // test is executed. Let's tempt fate. + do_check_eq(original.thisPingDate, reporter._formatDate(now)); + + run_next_test(); +}); + +add_test(function test_json_payload_dummy_provider() { + let reporter = getReporter("json_payload_dummy_provider"); + + reporter.registerProvider(new DummyProvider()); + reporter.collectMeasurements().then(function onResult() { + let o = JSON.parse(reporter.getJSONPayload()); + + do_check_eq(Object.keys(o.providers).length, 1); + do_check_true("DummyProvider" in o.providers); + do_check_true("measurements" in o.providers.DummyProvider); + do_check_true("DummyMeasurement" in o.providers.DummyProvider.measurements); + + run_next_test(); + }); +}); + +add_test(function test_notify_policy_observers() { + let reporter = getReporter("notify_policy_observers"); + + Observers.add("healthreport:notify-data-policy:request", + function onObserver(subject, data) { + Observers.remove("healthreport:notify-data-policy:request", onObserver); + + do_check_true("foo" in subject); + + run_next_test(); + }); + + reporter.onNotifyDataPolicy({foo: "bar"}); +}); + +add_test(function test_data_submission_transport_failure() { + let reporter = getReporter("data_submission_transport_failure"); + reporter.serverURI = "http://localhost:8080/"; + reporter.serverNamespace = "test00"; + + let deferred = Promise.defer(); + deferred.promise.then(function onResult(request) { + do_check_eq(request.state, request.SUBMISSION_FAILURE_SOFT); + + run_next_test(); + }); + + let request = new DataSubmissionRequest(deferred, new Date(Date.now + 30000)); + reporter.onRequestDataUpload(request); +}); + +add_test(function test_data_submission_success() { + let [reporter, server] = getReporterAndServer("data_submission_success"); + + do_check_eq(reporter.lastPingDate.getTime(), 0); + do_check_false(reporter.haveRemoteData()); + + let deferred = Promise.defer(); + deferred.promise.then(function onResult(request) { + do_check_eq(request.state, request.SUBMISSION_SUCCESS); + do_check_neq(reporter.lastPingDate.getTime(), 0); + do_check_true(reporter.haveRemoteData()); + + server.stop(run_next_test); + }); + + let request = new DataSubmissionRequest(deferred, new Date()); + reporter.onRequestDataUpload(request); +}); + +add_test(function test_recurring_daily_pings() { + let [reporter, server] = getReporterAndServer("recurring_daily_pings"); + reporter.registerProvider(new DummyProvider()); + + let policy = reporter._policy; + + defineNow(policy, policy._futureDate(-24 * 60 * 68 * 1000)); + policy.recordUserAcceptance(); + defineNow(policy, policy.nextDataSubmissionDate); + let promise = policy.checkStateAndTrigger(); + do_check_neq(promise, null); + + promise.then(function onUploadComplete() { + let lastID = reporter.lastSubmitID; + + do_check_neq(lastID, null); + do_check_true(server.hasDocument(reporter.serverNamespace, lastID)); + + // Skip forward to next scheduled submission time. + defineNow(policy, policy.nextDataSubmissionDate); + let promise = policy.checkStateAndTrigger(); + do_check_neq(promise, null); + promise.then(function onSecondUploadCOmplete() { + do_check_neq(reporter.lastSubmitID, lastID); + do_check_true(server.hasDocument(reporter.serverNamespace, reporter.lastSubmitID)); + do_check_false(server.hasDocument(reporter.serverNamespace, lastID)); + + server.stop(run_next_test); + }); + }); +}); + +add_test(function test_request_remote_data_deletion() { + let [reporter, server] = getReporterAndServer("request_remote_data_deletion"); + + let policy = reporter._policy; + defineNow(policy, policy._futureDate(-24 * 60 * 60 * 1000)); + policy.recordUserAcceptance(); + defineNow(policy, policy.nextDataSubmissionDate); + policy.checkStateAndTrigger().then(function onUploadComplete() { + let id = reporter.lastSubmitID; + do_check_neq(id, null); + do_check_true(server.hasDocument(reporter.serverNamespace, id)); + + defineNow(policy, policy._futureDate(10 * 1000)); + + let promise = reporter.requestDeleteRemoteData(); + do_check_neq(promise, null); + promise.then(function onDeleteComplete() { + do_check_null(reporter.lastSubmitID); + do_check_false(reporter.haveRemoteData()); + do_check_false(server.hasDocument(reporter.serverNamespace, id)); + + server.stop(run_next_test); + }); + }); +}); + +add_test(function test_policy_accept_reject() { + let [reporter, server] = getReporterAndServer("policy_accept_reject"); + + do_check_false(reporter.dataSubmissionPolicyAccepted); + do_check_false(reporter.willUploadData); + + reporter.recordPolicyAcceptance(); + do_check_true(reporter.dataSubmissionPolicyAccepted); + do_check_true(reporter.willUploadData); + + reporter.recordPolicyRejection(); + do_check_false(reporter.dataSubmissionPolicyAccepted); + do_check_false(reporter.willUploadData); + + server.stop(run_next_test); +}); + diff --git a/services/healthreport/tests/xpcshell/test_load_modules.js b/services/healthreport/tests/xpcshell/test_load_modules.js index af9b4dc20d3a..384355e46181 100644 --- a/services/healthreport/tests/xpcshell/test_load_modules.js +++ b/services/healthreport/tests/xpcshell/test_load_modules.js @@ -4,6 +4,7 @@ "use strict"; const modules = [ + "healthreporter.jsm", "policy.jsm", ]; diff --git a/services/healthreport/tests/xpcshell/xpcshell.ini b/services/healthreport/tests/xpcshell/xpcshell.ini index 57854778d3e1..77cf67abad47 100644 --- a/services/healthreport/tests/xpcshell/xpcshell.ini +++ b/services/healthreport/tests/xpcshell/xpcshell.ini @@ -4,3 +4,4 @@ tail = [test_load_modules.js] [test_policy.js] +[test_healthreporter.js] From ba1800874bbd70ef76aac5de83fe97df7d0beeb3 Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Mon, 12 Nov 2012 15:50:04 -0800 Subject: [PATCH 65/75] Bug 809644 - Health Report provider for application info; r=rnewman --- .../HealthReportComponents.manifest | 2 + services/healthreport/Makefile.in | 1 + services/healthreport/providers.jsm | 154 ++++++++++++++++++ .../tests/xpcshell/test_load_modules.js | 1 + .../tests/xpcshell/test_provider_appinfo.js | 81 +++++++++ .../healthreport/tests/xpcshell/xpcshell.ini | 1 + 6 files changed, 240 insertions(+) create mode 100644 services/healthreport/providers.jsm create mode 100644 services/healthreport/tests/xpcshell/test_provider_appinfo.js diff --git a/services/healthreport/HealthReportComponents.manifest b/services/healthreport/HealthReportComponents.manifest index f750c51d33b9..00ec28a9403d 100644 --- a/services/healthreport/HealthReportComponents.manifest +++ b/services/healthreport/HealthReportComponents.manifest @@ -9,3 +9,5 @@ component {e354c59b-b252-4040-b6dd-b71864e3e35c} HealthReportService.js contract @mozilla.org/healthreport/service;1 {e354c59b-b252-4040-b6dd-b71864e3e35c} category app-startup HealthReportService service,@mozilla.org/healthreport/service;1 application={3c2e2abc-06d4-11e1-ac3b-374f68613e61} application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} application={aa3c5121-dab2-40e2-81ca-7ea25febc110} application={a23983c0-fd0e-11dc-95ff-0800200c9a66} +category healthreport-js-provider AppInfoProvider resource://gre/modules/services/healthreport/providers.jsm + diff --git a/services/healthreport/Makefile.in b/services/healthreport/Makefile.in index 3e203021a4c8..d419f8e16897 100644 --- a/services/healthreport/Makefile.in +++ b/services/healthreport/Makefile.in @@ -12,6 +12,7 @@ include $(DEPTH)/config/autoconf.mk modules := \ healthreporter.jsm \ policy.jsm \ + providers.jsm \ $(NULL) testing_modules := \ diff --git a/services/healthreport/providers.jsm b/services/healthreport/providers.jsm new file mode 100644 index 000000000000..273d022418f7 --- /dev/null +++ b/services/healthreport/providers.jsm @@ -0,0 +1,154 @@ +/* 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/. */ + +/** + * This file contains metrics data providers for the Firefox Health + * Report. Ideally each provider in this file exists in separate modules + * and lives close to the code it is querying. However, because of the + * overhead of JS compartments (which are created for each module), we + * currently have all the code in one file. When the overhead of + * compartments reaches a reasonable level, this file should be split + * up. + */ + +"use strict"; + +this.EXPORTED_SYMBOLS = [ + "AppInfoProvider" +]; + +const {classes: Cc, interfaces: Ci, utils: Cu} = Components; + +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/services/metrics/dataprovider.jsm"); +Cu.import("resource://services-common/preferences.js"); +Cu.import("resource://services-common/utils.js"); + + +const REQUIRED_STRING_TYPE = {type: "TYPE_STRING"}; + +XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel", + "resource://gre/modules/UpdateChannel.jsm"); + +/** + * Represents basic application state. + * + * This is roughly a union of nsIXULAppInfo, nsIXULRuntime, with a few extra + * pieces thrown in. + */ +function AppInfoMeasurement() { + MetricsMeasurement.call(this, "appinfo", 1); +} + +AppInfoMeasurement.prototype = { + __proto__: MetricsMeasurement.prototype, + + fields: { + vendor: REQUIRED_STRING_TYPE, + name: REQUIRED_STRING_TYPE, + id: REQUIRED_STRING_TYPE, + version: REQUIRED_STRING_TYPE, + appBuildID: REQUIRED_STRING_TYPE, + platformVersion: REQUIRED_STRING_TYPE, + platformBuildID: REQUIRED_STRING_TYPE, + os: REQUIRED_STRING_TYPE, + xpcomabi: REQUIRED_STRING_TYPE, + updateChannel: REQUIRED_STRING_TYPE, + distributionID: REQUIRED_STRING_TYPE, + distributionVersion: REQUIRED_STRING_TYPE, + hotfixVersion: REQUIRED_STRING_TYPE, + locale: REQUIRED_STRING_TYPE, + }, +}; + +Object.freeze(AppInfoMeasurement.prototype); + + +this.AppInfoProvider = function AppInfoProvider() { + MetricsProvider.call(this, "app-info"); + + this._prefs = new Preferences({defaultBranch: null}); +} +AppInfoProvider.prototype = { + __proto__: MetricsProvider.prototype, + + appInfoFields: { + // From nsIXULAppInfo. + vendor: "vendor", + name: "name", + id: "ID", + version: "version", + appBuildID: "appBuildID", + platformVersion: "platformVersion", + platformBuildID: "platformBuildID", + + // From nsIXULRuntime. + os: "OS", + xpcomabi: "XPCOMABI", + }, + + collectConstantMeasurements: function collectConstantMeasurements() { + let result = this.createResult(); + result.expectMeasurement("appinfo"); + + result.populate = this._populateConstants.bind(this); + return result; + }, + + _populateConstants: function _populateConstants(result) { + result.addMeasurement(new AppInfoMeasurement()); + + let ai; + try { + ai = Services.appinfo; + } catch (ex) { + this._log.warn("Could not obtain Services.appinfo: " + + CommonUtils.exceptionStr(ex)); + throw ex; + } + + if (!ai) { + this._log.warn("Services.appinfo is unavailable."); + throw ex; + } + + for (let [k, v] in Iterator(this.appInfoFields)) { + try { + result.setValue("appinfo", k, ai[v]); + } catch (ex) { + this._log.warn("Error obtaining Services.appinfo." + v); + result.addError(ex); + } + } + + try { + result.setValue("appinfo", "updateChannel", UpdateChannel.get()); + } catch (ex) { + this._log.warn("Could not obtain update channel: " + + CommonUtils.exceptionStr(ex)); + result.addError(ex); + } + + result.setValue("appinfo", "distributionID", this._prefs.get("distribution.id", "")); + result.setValue("appinfo", "distributionVersion", this._prefs.get("distribution.version", "")); + result.setValue("appinfo", "hotfixVersion", this._prefs.get("extensions.hotfix.lastVersion", "")); + + try { + let locale = Cc["@mozilla.org/chrome/chrome-registry;1"] + .getService(Ci.nsIXULChromeRegistry) + .getSelectedLocale("global"); + result.setValue("appinfo", "locale", locale); + } catch (ex) { + this._log.warn("Could not obtain application locale: " + + CommonUtils.exceptionStr(ex)); + result.addError(ex); + } + + result.finish(); + }, +}; + +Object.freeze(AppInfoProvider.prototype); + diff --git a/services/healthreport/tests/xpcshell/test_load_modules.js b/services/healthreport/tests/xpcshell/test_load_modules.js index 384355e46181..d41ef5bad76f 100644 --- a/services/healthreport/tests/xpcshell/test_load_modules.js +++ b/services/healthreport/tests/xpcshell/test_load_modules.js @@ -6,6 +6,7 @@ const modules = [ "healthreporter.jsm", "policy.jsm", + "providers.jsm", ]; const test_modules = [ diff --git a/services/healthreport/tests/xpcshell/test_provider_appinfo.js b/services/healthreport/tests/xpcshell/test_provider_appinfo.js new file mode 100644 index 000000000000..5baba7a5a387 --- /dev/null +++ b/services/healthreport/tests/xpcshell/test_provider_appinfo.js @@ -0,0 +1,81 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const {interfaces: Ci, results: Cr, utils: Cu} = Components; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/services/healthreport/providers.jsm"); +Cu.import("resource://gre/modules/services/metrics/dataprovider.jsm"); + +function run_test() { + let appInfo = { + vendor: "Mozilla", + name: "xpcshell", + ID: "xpcshell@tests.mozilla.org", + version: "1", + appBuildID: "20121107", + platformVersion: "p-ver", + platformBuildID: "20121106", + inSafeMode: false, + logConsoleErrors: true, + OS: "XPCShell", + XPCOMABI: "noarch-spidermonkey", + QueryInterface: XPCOMUtils.generateQI([Ci.nsIXULAppInfo, Ci.nsIXULRuntime]), + invalidateCachesOnRestart: function() {}, + }; + + let factory = { + createInstance: function createInstance(outer, iid) { + if (outer != null) { + throw Cr.NS_ERROR_NO_AGGREGATION; + } + + return appInfo.QueryInterface(iid); + }, + }; + + let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); + registrar.registerFactory(Components.ID("{fbfae60b-64a4-44ef-a911-08ceb70b9f31}"), + "XULAppInfo", "@mozilla.org/xre/app-info;1", + factory); + + run_next_test(); +} + +add_test(function test_constructor() { + let provider = new AppInfoProvider(); + + run_next_test(); +}); + +add_test(function test_collect_smoketest() { + let provider = new AppInfoProvider(); + + let result = provider.collectConstantMeasurements(); + do_check_true(result instanceof MetricsCollectionResult); + + result.onFinished(function onFinished() { + do_check_eq(result.expectedMeasurements.size, 1); + do_check_true(result.expectedMeasurements.has("appinfo")); + do_check_eq(result.measurements.size, 1); + do_check_true(result.measurements.has("appinfo")); + do_check_eq(result.errors.length, 0); + + let ai = result.measurements.get("appinfo"); + do_check_eq(ai.getValue("vendor"), "Mozilla"); + do_check_eq(ai.getValue("name"), "xpcshell"); + do_check_eq(ai.getValue("id"), "xpcshell@tests.mozilla.org"); + do_check_eq(ai.getValue("version"), "1"); + do_check_eq(ai.getValue("appBuildID"), "20121107"); + do_check_eq(ai.getValue("platformVersion"), "p-ver"); + do_check_eq(ai.getValue("platformBuildID"), "20121106"); + do_check_eq(ai.getValue("os"), "XPCShell"); + do_check_eq(ai.getValue("xpcomabi"), "noarch-spidermonkey"); + + run_next_test(); + }); + + result.populate(result); +}); diff --git a/services/healthreport/tests/xpcshell/xpcshell.ini b/services/healthreport/tests/xpcshell/xpcshell.ini index 77cf67abad47..aa2c709201b4 100644 --- a/services/healthreport/tests/xpcshell/xpcshell.ini +++ b/services/healthreport/tests/xpcshell/xpcshell.ini @@ -5,3 +5,4 @@ tail = [test_load_modules.js] [test_policy.js] [test_healthreporter.js] +[test_provider_appinfo.js] From 6d778b7eaf586af4fa1782c8c1be7d98cead78df Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Fri, 16 Nov 2012 10:05:19 -0800 Subject: [PATCH 66/75] Bug 811159 - Save last submitted health report to profile; r=rnewman --- services/healthreport/healthreporter.jsm | 102 ++++++++++++++++-- services/healthreport/tests/xpcshell/head.js | 3 + .../tests/xpcshell/test_healthreporter.js | 23 ++++ 3 files changed, 119 insertions(+), 9 deletions(-) diff --git a/services/healthreport/healthreporter.jsm b/services/healthreport/healthreporter.jsm index 7c73e2482266..0e6f372dcfdd 100644 --- a/services/healthreport/healthreporter.jsm +++ b/services/healthreport/healthreporter.jsm @@ -14,6 +14,7 @@ Cu.import("resource://services-common/observers.js"); Cu.import("resource://services-common/preferences.js"); Cu.import("resource://services-common/utils.js"); Cu.import("resource://gre/modules/commonjs/promise/core.js"); +Cu.import("resource://gre/modules/osfile.jsm"); Cu.import("resource://gre/modules/services/healthreport/policy.jsm"); Cu.import("resource://gre/modules/services/metrics/collector.jsm"); @@ -150,13 +151,24 @@ HealthReporter.prototype = { }, /** - * Start background functionality. + * Perform post-construction initialization and start background activity. * * If this isn't called, no data upload will occur. + * + * This returns a promise that will be fulfilled when all initialization + * activity is completed. It is not safe for this instance to perform + * additional actions until this promise has been resolved. */ start: function start() { - this._policy.startPolling(); - this._log.info("HealthReporter started."); + let onExists = function onExists() { + this._policy.startPolling(); + this._log.info("HealthReporter started."); + + return Promise.resolve(); + }.bind(this); + + return this._ensureDirectoryExists(this._stateDir) + .then(onExists); }, /** @@ -370,12 +382,13 @@ HealthReporter.prototype = { let payload = this.getJSONPayload(); - let promise = client.uploadJSON(this.serverNamespace, - id, - payload, - this.lastSubmitID); - - return promise.then(this._onBagheeraResult.bind(this, request, false)); + return this._saveLastPayload(payload) + .then(client.uploadJSON.bind(client, + this.serverNamespace, + id, + payload, + this.lastSubmitID)) + .then(this._onBagheeraResult.bind(this, request, false)); }, _deleteRemoteData: function _deleteRemoteData(request) { @@ -394,6 +407,77 @@ HealthReporter.prototype = { }, + get _stateDir() { + let profD = OS.Constants.Path.profileDir; + + // Work around bug 810543 until OS.File is more resilient. + if (!profD || !profD.length) { + throw new Error("Could not obtain profile directory. OS.File not " + + "initialized properly?"); + } + + return OS.Path.join(profD, "healthreport"); + }, + + _ensureDirectoryExists: function _ensureDirectoryExists(path) { + let deferred = Promise.defer(); + + OS.File.makeDir(path).then( + function onResult() { + deferred.resolve(true); + }, + function onError(error) { + if (error.becauseExists) { + deferred.resolve(true); + return; + } + + deferred.reject(error); + } + ); + + return deferred.promise; + }, + + get _lastPayloadPath() { + return OS.Path.join(this._stateDir, "lastpayload.json"); + }, + + _saveLastPayload: function _saveLastPayload(payload) { + let path = this._lastPayloadPath; + let pathTmp = path + ".tmp"; + + let encoder = new TextEncoder(); + let buffer = encoder.encode(payload); + + return OS.File.writeAtomic(path, buffer, {tmpPath: pathTmp}); + }, + + /** + * Obtain the last uploaded payload. + * + * The promise is resolved to a JSON-decoded object on success. The promise + * is rejected if the last uploaded payload could not be found or there was + * an error reading or parsing it. + * + * @return Promise + */ + getLastPayload: function getLoadPayload() { + let path = this._lastPayloadPath; + + return OS.File.read(path).then( + function onData(buffer) { + let decoder = new TextDecoder(); + let json = JSON.parse(decoder.decode(buffer)); + + return Promise.resolve(json); + }, + function onError(error) { + return Promise.reject(error); + } + ); + }, + _now: function _now() { return new Date(); }, diff --git a/services/healthreport/tests/xpcshell/head.js b/services/healthreport/tests/xpcshell/head.js index 4c9b52df0b0c..e7bb37f8f678 100644 --- a/services/healthreport/tests/xpcshell/head.js +++ b/services/healthreport/tests/xpcshell/head.js @@ -3,6 +3,9 @@ "use strict"; +// We need to initialize the profile or OS.File may not work. See bug 810543. +do_get_profile(); + (function initMetricsTestingInfrastructure() { let ns = {}; Components.utils.import("resource://testing-common/services-common/logging.js", diff --git a/services/healthreport/tests/xpcshell/test_healthreporter.js b/services/healthreport/tests/xpcshell/test_healthreporter.js index 275870b719db..3ba86500c36a 100644 --- a/services/healthreport/tests/xpcshell/test_healthreporter.js +++ b/services/healthreport/tests/xpcshell/test_healthreporter.js @@ -96,6 +96,14 @@ add_test(function test_register_providers_from_category_manager() { run_next_test(); }); +add_test(function test_start() { + let reporter = getReporter("start"); + reporter.start().then(function onStarted() { + reporter.stop(); + run_next_test(); + }); +}); + add_test(function test_json_payload_simple() { let reporter = getReporter("json_payload_simple"); @@ -260,3 +268,18 @@ add_test(function test_policy_accept_reject() { server.stop(run_next_test); }); + +add_test(function test_upload_save_payload() { + let [reporter, server] = getReporterAndServer("upload_save_payload"); + + let deferred = Promise.defer(); + let request = new DataSubmissionRequest(deferred, new Date(), false); + + reporter._uploadData(request).then(function onUpload() { + reporter.getLastPayload().then(function onJSON(json) { + do_check_true("thisPingDate" in json); + server.stop(run_next_test); + }); + }); +}); + From e2ec35f022ff134cd9e1782a63989c66eedf49b7 Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Mon, 19 Nov 2012 11:31:19 -0800 Subject: [PATCH 67/75] Bug 813226 - Add ability to bypass policy acceptance; r=rnewman This is needed to support background "always OK" data submission, such as ADU pings. --- services/healthreport/healthreport-prefs.js | 1 + services/healthreport/policy.jsm | 16 +++++++++++++++- .../healthreport/tests/xpcshell/test_policy.js | 17 +++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/services/healthreport/healthreport-prefs.js b/services/healthreport/healthreport-prefs.js index 01b5cd454cf8..83ff1a9aba86 100644 --- a/services/healthreport/healthreport-prefs.js +++ b/services/healthreport/healthreport-prefs.js @@ -10,6 +10,7 @@ pref("healthreport.logging.consoleLevel", "Warn"); pref("healthreport.policy.currentDaySubmissionFailureCount", 0); pref("healthreport.policy.dataSubmissionEnabled", true); pref("healthreport.policy.dataSubmissionPolicyAccepted", false); +pref("healthreport.policy.dataSubmissionPolicyBypassAcceptance", false); pref("healthreport.policy.dataSubmissionPolicyNotifiedTime", "0"); pref("healthreport.policy.dataSubmissionPolicyResponseType", ""); pref("healthreport.policy.dataSubmissionPolicyResponseTime", "0"); diff --git a/services/healthreport/policy.jsm b/services/healthreport/policy.jsm index 2e9b56fa4a36..900f9a5eae8a 100644 --- a/services/healthreport/policy.jsm +++ b/services/healthreport/policy.jsm @@ -359,6 +359,16 @@ HealthReportPolicy.prototype = { OLDEST_ALLOWED_YEAR); }, + /** + * Short circuit policy checking and always assume acceptance. + * + * This shuld never be set by the user. Instead, it is a per-application or + * per-deployment default pref. + */ + get dataSubmissionPolicyBypassAcceptance() { + return this._prefs.get("dataSubmissionPolicyBypassAcceptance", false); + }, + /** * When the user was notified that data submission could occur. * @@ -754,7 +764,7 @@ HealthReportPolicy.prototype = { } // User has opted out of data submission. - if (!this.dataSubmissionPolicyAccepted) { + if (!this.dataSubmissionPolicyAccepted && !this.dataSubmissionPolicyBypassAcceptance) { this._log.debug("Data submission has been disabled per user request."); return; } @@ -780,6 +790,10 @@ HealthReportPolicy.prototype = { * @return bool Whether user has responded to data policy. */ ensureNotifyResponse: function ensureNotifyResponse(now) { + if (this.dataSubmissionPolicyBypassAcceptance) { + return true; + } + let notifyState = this.notifyState; if (notifyState == this.STATE_NOTIFY_UNNOTIFIED) { diff --git a/services/healthreport/tests/xpcshell/test_policy.js b/services/healthreport/tests/xpcshell/test_policy.js index a91d23cb4f24..c0c6a56dc351 100644 --- a/services/healthreport/tests/xpcshell/test_policy.js +++ b/services/healthreport/tests/xpcshell/test_policy.js @@ -80,6 +80,10 @@ add_test(function test_prefs() { do_check_false(prefs.get("dataSubmissionPolicyAccepted", true)); do_check_false(policy.dataSubmissionPolicyAccepted); + do_check_false(policy.dataSubmissionPolicyBypassAcceptance); + prefs.set("dataSubmissionPolicyBypassAcceptance", true); + do_check_true(policy.dataSubmissionPolicyBypassAcceptance); + policy.lastDataSubmissionRequestedDate = now; do_check_eq(prefs.get("lastDataSubmissionRequestedTime"), nowT); do_check_eq(policy.lastDataSubmissionRequestedDate.getTime(), nowT); @@ -154,6 +158,19 @@ add_test(function test_initial_submission_notification() { run_next_test(); }); +add_test(function test_bypass_acceptance() { + let [policy, prefs, listener] = getPolicy("bypass_acceptance"); + + prefs.set("dataSubmissionPolicyBypassAcceptance", true); + do_check_false(policy.dataSubmissionPolicyAccepted); + do_check_true(policy.dataSubmissionPolicyBypassAcceptance); + defineNow(policy, new Date(policy.nextDataSubmissionDate.getTime())); + policy.checkStateAndTrigger(); + do_check_eq(listener.requestDataUploadCount, 1); + + run_next_test(); +}); + add_test(function test_notification_implicit_acceptance() { let [policy, prefs, listener] = getPolicy("notification_implicit_acceptance"); From d527aba7e0c26ce660b6eaefdfefe69291fc8528 Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Mon, 19 Nov 2012 13:18:30 -0800 Subject: [PATCH 68/75] Bug 812377 - Health report provider for collecting system info; r=rnewman --- .../HealthReportComponents.manifest | 1 + services/healthreport/providers.jsm | 102 +++++++++++++++++- .../tests/xpcshell/test_provider_sysinfo.js | 45 ++++++++ .../healthreport/tests/xpcshell/xpcshell.ini | 2 + 4 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 services/healthreport/tests/xpcshell/test_provider_sysinfo.js diff --git a/services/healthreport/HealthReportComponents.manifest b/services/healthreport/HealthReportComponents.manifest index 00ec28a9403d..1157c14eccc1 100644 --- a/services/healthreport/HealthReportComponents.manifest +++ b/services/healthreport/HealthReportComponents.manifest @@ -10,4 +10,5 @@ contract @mozilla.org/healthreport/service;1 {e354c59b-b252-4040-b6dd-b71864e3e3 category app-startup HealthReportService service,@mozilla.org/healthreport/service;1 application={3c2e2abc-06d4-11e1-ac3b-374f68613e61} application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} application={aa3c5121-dab2-40e2-81ca-7ea25febc110} application={a23983c0-fd0e-11dc-95ff-0800200c9a66} category healthreport-js-provider AppInfoProvider resource://gre/modules/services/healthreport/providers.jsm +category healthreport-js-provider SysInfoProvider resource://gre/modules/services/healthreport/providers.jsm diff --git a/services/healthreport/providers.jsm b/services/healthreport/providers.jsm index 273d022418f7..ea222548e9a4 100644 --- a/services/healthreport/providers.jsm +++ b/services/healthreport/providers.jsm @@ -15,7 +15,8 @@ "use strict"; this.EXPORTED_SYMBOLS = [ - "AppInfoProvider" + "AppInfoProvider", + "SysInfoProvider", ]; const {classes: Cc, interfaces: Ci, utils: Cu} = Components; @@ -28,6 +29,8 @@ Cu.import("resource://services-common/utils.js"); const REQUIRED_STRING_TYPE = {type: "TYPE_STRING"}; +const OPTIONAL_STRING_TYPE = {type: "TYPE_STRING", optional: true}; +const REQUIRED_UINT32_TYPE = {type: "TYPE_UINT32"}; XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel", "resource://gre/modules/UpdateChannel.jsm"); @@ -152,3 +155,100 @@ AppInfoProvider.prototype = { Object.freeze(AppInfoProvider.prototype); + +function SysInfoMeasurement() { + MetricsMeasurement.call(this, "sysinfo", 1); +} + +SysInfoMeasurement.prototype = { + __proto__: MetricsMeasurement.prototype, + + fields: { + cpuCount: REQUIRED_UINT32_TYPE, + memoryMB: REQUIRED_UINT32_TYPE, + manufacturer: OPTIONAL_STRING_TYPE, + device: OPTIONAL_STRING_TYPE, + hardware: OPTIONAL_STRING_TYPE, + name: OPTIONAL_STRING_TYPE, + version: OPTIONAL_STRING_TYPE, + architecture: OPTIONAL_STRING_TYPE, + }, +}, + +Object.freeze(SysInfoMeasurement.prototype); + + +this.SysInfoProvider = function SysInfoProvider() { + MetricsProvider.call(this, "sys-info"); +}; + +SysInfoProvider.prototype = { + __proto__: MetricsProvider.prototype, + + sysInfoFields: { + cpucount: "cpuCount", + memsize: "memoryMB", + manufacturer: "manufacturer", + device: "device", + hardware: "hardware", + name: "name", + version: "version", + arch: "architecture", + }, + + INT_FIELDS: new Set("cpucount", "memsize"), + + collectConstantMeasurements: function collectConstantMeasurements() { + let result = this.createResult(); + result.expectMeasurement("sysinfo"); + + result.populate = this._populateConstants.bind(this); + + return result; + }, + + _populateConstants: function _populateConstants(result) { + result.addMeasurement(new SysInfoMeasurement()); + + let si = Cc["@mozilla.org/system-info;1"] + .getService(Ci.nsIPropertyBag2); + + for (let [k, v] in Iterator(this.sysInfoFields)) { + try { + if (!si.hasKey(k)) { + this._log.debug("Property not available: " + k); + continue; + } + + let value = si.getProperty(k); + + if (this.INT_FIELDS.has(k)) { + let converted = parseInt(value, 10); + if (Number.isNaN(converted)) { + result.addError(new Error("Value is not an integer: " + k + "=" + + value)); + continue; + } + + value = converted; + } + + // Round memory to mebibytes. + if (k == "memsize") { + value = Math.round(value / 1048576); + } + + result.setValue("sysinfo", v, value); + } catch (ex) { + this._log.warn("Error obtaining system info field: " + k + " " + + CommonUtils.exceptionStr(ex)); + result.addError(ex); + } + } + + result.finish(); + }, +}; + +Object.freeze(SysInfoProvider.prototype); + diff --git a/services/healthreport/tests/xpcshell/test_provider_sysinfo.js b/services/healthreport/tests/xpcshell/test_provider_sysinfo.js new file mode 100644 index 000000000000..921a73074ce3 --- /dev/null +++ b/services/healthreport/tests/xpcshell/test_provider_sysinfo.js @@ -0,0 +1,45 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const {interfaces: Ci, results: Cr, utils: Cu} = Components; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/services/healthreport/providers.jsm"); +Cu.import("resource://gre/modules/services/metrics/dataprovider.jsm"); + + +function run_test() { + run_next_test(); +} + +add_test(function test_constructor() { + let provider = new SysInfoProvider(); + + run_next_test(); +}); + +add_test(function test_collect_smoketest() { + let provider = new SysInfoProvider(); + + let result = provider.collectConstantMeasurements(); + do_check_true(result instanceof MetricsCollectionResult); + + result.onFinished(function onFinished() { + do_check_eq(result.expectedMeasurements.size, 1); + do_check_true(result.expectedMeasurements.has("sysinfo")); + do_check_eq(result.measurements.size, 1); + do_check_true(result.measurements.has("sysinfo")); + do_check_eq(result.errors.length, 0); + + let si = result.measurements.get("sysinfo"); + do_check_true(si.getValue("cpuCount") > 0); + do_check_neq(si.getValue("name"), null); + + run_next_test(); + }); + + result.populate(result); +}); + diff --git a/services/healthreport/tests/xpcshell/xpcshell.ini b/services/healthreport/tests/xpcshell/xpcshell.ini index aa2c709201b4..069c43ef5dd5 100644 --- a/services/healthreport/tests/xpcshell/xpcshell.ini +++ b/services/healthreport/tests/xpcshell/xpcshell.ini @@ -6,3 +6,5 @@ tail = [test_policy.js] [test_healthreporter.js] [test_provider_appinfo.js] +[test_provider_sysinfo.js] + From 431420affc37b68fbceaadef3dc9baa98059b701 Mon Sep 17 00:00:00 2001 From: Richard Newman Date: Mon, 19 Nov 2012 19:00:58 -0800 Subject: [PATCH 69/75] Bug 718066 - Pref off FHR on all platforms. r=gps --- services/healthreport/healthreport-prefs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/healthreport/healthreport-prefs.js b/services/healthreport/healthreport-prefs.js index 83ff1a9aba86..7257278bbdf1 100644 --- a/services/healthreport/healthreport-prefs.js +++ b/services/healthreport/healthreport-prefs.js @@ -4,7 +4,7 @@ pref("healthreport.documentServerURI", "https://data.mozilla.com/"); pref("healthreport.documentServerNamespace", "metrics"); -pref("healthreport.serviceEnabled", true); +pref("healthreport.serviceEnabled", false); pref("healthreport.logging.consoleEnabled", true); pref("healthreport.logging.consoleLevel", "Warn"); pref("healthreport.policy.currentDaySubmissionFailureCount", 0); From 1fa65c0321532085653f42eb3e4e4911e388186d Mon Sep 17 00:00:00 2001 From: Richard Newman Date: Mon, 19 Nov 2012 19:09:45 -0800 Subject: [PATCH 70/75] Bug 718066 - Build-time disable FHR on all platforms apart from B2G. r=gps --- browser/confvars.sh | 1 - mobile/android/confvars.sh | 1 - mobile/xul/confvars.sh | 1 - 3 files changed, 3 deletions(-) diff --git a/browser/confvars.sh b/browser/confvars.sh index 452fc12e9c5d..3f8858abec9d 100755 --- a/browser/confvars.sh +++ b/browser/confvars.sh @@ -21,7 +21,6 @@ MOZ_SAFE_BROWSING=1 MOZ_SERVICES_AITC=1 MOZ_SERVICES_COMMON=1 MOZ_SERVICES_CRYPTO=1 -MOZ_SERVICES_HEALTHREPORT=1 MOZ_SERVICES_METRICS=1 MOZ_SERVICES_NOTIFICATIONS=1 MOZ_SERVICES_SYNC=1 diff --git a/mobile/android/confvars.sh b/mobile/android/confvars.sh index 51a71763a706..5845ac249e6f 100644 --- a/mobile/android/confvars.sh +++ b/mobile/android/confvars.sh @@ -20,7 +20,6 @@ MOZ_DISABLE_DOMCRYPTO=1 MOZ_MEDIA_NAVIGATOR=1 MOZ_SERVICES_COMMON=1 -MOZ_SERVICES_HEALTHREPORT=1 MOZ_SERVICES_METRICS=1 if test "$LIBXUL_SDK"; then diff --git a/mobile/xul/confvars.sh b/mobile/xul/confvars.sh index ad58f3d02338..8c8e224e9b9d 100755 --- a/mobile/xul/confvars.sh +++ b/mobile/xul/confvars.sh @@ -15,7 +15,6 @@ MOZ_SAFE_BROWSING= MOZ_SERVICES_COMMON=1 MOZ_SERVICES_CRYPTO=1 -MOZ_SERVICES_HEALTHREPORT=1 MOZ_SERVICES_METRICS=1 MOZ_SERVICES_SYNC=1 From 2d99cbf92490170411efd60fcd62046c02ee00bb Mon Sep 17 00:00:00 2001 From: "L. David Baron" Date: Tue, 20 Nov 2012 13:22:35 -0800 Subject: [PATCH 71/75] Bug 813373, patch 4: fix printfs that crept in in patch 3. --- content/html/content/src/nsHTMLBodyElement.cpp | 2 +- layout/style/AnimationCommon.cpp | 8 ++++---- layout/style/nsHTMLStyleSheet.cpp | 4 ++-- layout/style/nsStyleSet.cpp | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/content/html/content/src/nsHTMLBodyElement.cpp b/content/html/content/src/nsHTMLBodyElement.cpp index 7f0e02ac098a..3d4524cf958b 100644 --- a/content/html/content/src/nsHTMLBodyElement.cpp +++ b/content/html/content/src/nsHTMLBodyElement.cpp @@ -257,7 +257,7 @@ BodyRule::MapRuleInfoInto(nsRuleData* aData) BodyRule::List(FILE* out, int32_t aIndent) const { for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out); - printf("[body rule] {}\n"); + fputs("[body rule] {}\n", out); } #endif diff --git a/layout/style/AnimationCommon.cpp b/layout/style/AnimationCommon.cpp index bd06b43111e6..bb1c56e41331 100644 --- a/layout/style/AnimationCommon.cpp +++ b/layout/style/AnimationCommon.cpp @@ -186,15 +186,15 @@ AnimValuesStyleRule::MapRuleInfoInto(nsRuleData* aRuleData) AnimValuesStyleRule::List(FILE* out, int32_t aIndent) const { for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out); - printf("[anim values] { "); + fputs("[anim values] { ", out); for (uint32_t i = 0, i_end = mPropertyValuePairs.Length(); i < i_end; ++i) { const PropertyValuePair &pair = mPropertyValuePairs[i]; nsAutoString value; nsStyleAnimation::UncomputeValue(pair.mProperty, pair.mValue, value); - printf("%s: %s; ", nsCSSProps::GetStringValue(pair.mProperty).get(), - NS_ConvertUTF16toUTF8(value).get()); + fprintf(out, "%s: %s; ", nsCSSProps::GetStringValue(pair.mProperty).get(), + NS_ConvertUTF16toUTF8(value).get()); } - printf("}\n"); + fputs("}\n", out); } #endif diff --git a/layout/style/nsHTMLStyleSheet.cpp b/layout/style/nsHTMLStyleSheet.cpp index 3f03dd12450d..59f241386c6a 100644 --- a/layout/style/nsHTMLStyleSheet.cpp +++ b/layout/style/nsHTMLStyleSheet.cpp @@ -59,7 +59,7 @@ nsHTMLStyleSheet::HTMLColorRule::MapRuleInfoInto(nsRuleData* aRuleData) nsHTMLStyleSheet::HTMLColorRule::List(FILE* out, int32_t aIndent) const { for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out); - printf("[html color rule] {}\n"); + fputs("[html color rule] {}\n", out); } #endif @@ -71,7 +71,7 @@ NS_IMPL_ISUPPORTS1(nsHTMLStyleSheet::GenericTableRule, nsIStyleRule) nsHTMLStyleSheet::GenericTableRule::List(FILE* out, int32_t aIndent) const { for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out); - printf("[generic table rule] {}\n"); + fputs("[generic table rule] {}\n", out); } #endif diff --git a/layout/style/nsStyleSet.cpp b/layout/style/nsStyleSet.cpp index e735ad2e3072..d13890f16518 100644 --- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -46,7 +46,7 @@ nsEmptyStyleRule::MapRuleInfoInto(nsRuleData* aRuleData) nsEmptyStyleRule::List(FILE* out, int32_t aIndent) const { for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out); - printf("[empty style rule] {}\n"); + fputs("[empty style rule] {}\n", out); } #endif @@ -92,7 +92,7 @@ nsInitialStyleRule::MapRuleInfoInto(nsRuleData* aRuleData) nsInitialStyleRule::List(FILE* out, int32_t aIndent) const { for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out); - printf("[initial style rule] {}\n"); + fputs("[initial style rule] {}\n", out); } #endif From 2b007959afe1760f66a884cff8d4623f1b601d19 Mon Sep 17 00:00:00 2001 From: Erick Dransch Date: Tue, 20 Nov 2012 16:38:20 -0500 Subject: [PATCH 72/75] Bug 801499 - Move WebGLBuffer to a separate file. r=bjacob --- content/canvas/src/Makefile.in | 1 + content/canvas/src/WebGLBuffer.cpp | 46 +++ content/canvas/src/WebGLBuffer.h | 74 +++++ content/canvas/src/WebGLContext.cpp | 1 + content/canvas/src/WebGLContext.h | 387 +----------------------- content/canvas/src/WebGLObjectModel.cpp | 19 ++ content/canvas/src/WebGLObjectModel.h | 306 +++++++++++++++++++ 7 files changed, 452 insertions(+), 382 deletions(-) create mode 100644 content/canvas/src/WebGLBuffer.h create mode 100644 content/canvas/src/WebGLObjectModel.cpp create mode 100644 content/canvas/src/WebGLObjectModel.h diff --git a/content/canvas/src/Makefile.in b/content/canvas/src/Makefile.in index 20791bfc9e1c..847d01e747ad 100644 --- a/content/canvas/src/Makefile.in +++ b/content/canvas/src/Makefile.in @@ -55,6 +55,7 @@ CPPSRCS += \ WebGLExtensionTextureFilterAnisotropic.cpp \ WebGLExtensionTextureFloat.cpp \ WebGLFramebuffer.cpp \ + WebGLObjectModel.cpp \ WebGLProgram.cpp \ WebGLRenderbuffer.cpp \ WebGLShader.cpp \ diff --git a/content/canvas/src/WebGLBuffer.cpp b/content/canvas/src/WebGLBuffer.cpp index 0d73be148484..f1592d8557d6 100644 --- a/content/canvas/src/WebGLBuffer.cpp +++ b/content/canvas/src/WebGLBuffer.cpp @@ -3,11 +3,57 @@ * 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 "WebGLBuffer.h" #include "WebGLContext.h" #include "mozilla/dom/WebGLRenderingContextBinding.h" using namespace mozilla; +WebGLBuffer::WebGLBuffer(WebGLContext *context) + : WebGLContextBoundObject(context) + , mHasEverBeenBound(false) + , mByteLength(0) + , mTarget(LOCAL_GL_NONE) +{ + SetIsDOMBinding(); + mContext->MakeContextCurrent(); + mContext->gl->fGenBuffers(1, &mGLName); + mContext->mBuffers.insertBack(this); +} + +WebGLBuffer::~WebGLBuffer() { + DeleteOnce(); +} + +void +WebGLBuffer::Delete() { + mContext->MakeContextCurrent(); + mContext->gl->fDeleteBuffers(1, &mGLName); + mByteLength = 0; + mCache = nullptr; + LinkedListElement::remove(); // remove from mContext->mBuffers +} + +void +WebGLBuffer::SetTarget(GLenum target) { + mTarget = target; + if (!mCache && mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER) + mCache = new WebGLElementArrayCache; +} + +bool +WebGLBuffer::ElementArrayCacheBufferData(const void* ptr, size_t buffer_size_in_bytes) { + if (mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER) + return mCache->BufferData(ptr, buffer_size_in_bytes); + return true; +} + +void +WebGLBuffer::ElementArrayCacheBufferSubData(size_t pos, const void* ptr, size_t update_size_in_bytes) { + if (mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER) + mCache->BufferSubData(pos, ptr, update_size_in_bytes); +} + JSObject* WebGLBuffer::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap) { return dom::WebGLBufferBinding::Wrap(cx, scope, this, triedToWrap); diff --git a/content/canvas/src/WebGLBuffer.h b/content/canvas/src/WebGLBuffer.h new file mode 100644 index 000000000000..f0b9fa6a8180 --- /dev/null +++ b/content/canvas/src/WebGLBuffer.h @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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 WEBGLBUFFER_H_ +#define WEBGLBUFFER_H_ + +#include "WebGLElementArrayCache.h" +#include "WebGLObjectModel.h" + +#include "nsWrapperCache.h" + +#include "mozilla/LinkedList.h" + +namespace mozilla { + +class WebGLBuffer MOZ_FINAL + : public nsISupports + , public WebGLRefCountedObject + , public LinkedListElement + , public WebGLContextBoundObject + , public nsWrapperCache +{ +public: + WebGLBuffer(WebGLContext *context); + + ~WebGLBuffer(); + + void Delete(); + + size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const { + size_t sizeOfCache = mCache ? mCache->SizeOfIncludingThis(aMallocSizeOf) : 0; + return aMallocSizeOf(this) + sizeOfCache; + } + + bool HasEverBeenBound() { return mHasEverBeenBound; } + void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; } + GLuint GLName() const { return mGLName; } + GLuint ByteLength() const { return mByteLength; } + GLenum Target() const { return mTarget; } + + void SetByteLength(GLuint byteLength) { mByteLength = byteLength; } + + void SetTarget(GLenum target); + + bool ElementArrayCacheBufferData(const void* ptr, size_t buffer_size_in_bytes); + + void ElementArrayCacheBufferSubData(size_t pos, const void* ptr, size_t update_size_in_bytes); + + bool Validate(WebGLenum type, uint32_t max_allowed, size_t first, size_t count) { + return mCache->Validate(type, max_allowed, first, count); + } + + WebGLContext *GetParentObject() const { + return Context(); + } + + virtual JSObject* WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap); + + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLBuffer) + +protected: + + WebGLuint mGLName; + bool mHasEverBeenBound; + GLuint mByteLength; + GLenum mTarget; + + nsAutoPtr mCache; +}; +} +#endif //WEBGLBUFFER_H_ diff --git a/content/canvas/src/WebGLContext.cpp b/content/canvas/src/WebGLContext.cpp index 1e850eeb297d..975d5d4c6bf3 100644 --- a/content/canvas/src/WebGLContext.cpp +++ b/content/canvas/src/WebGLContext.cpp @@ -4,6 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "WebGLContext.h" +#include "WebGLObjectModel.h" #include "WebGLExtensions.h" #include "WebGLContextUtils.h" diff --git a/content/canvas/src/WebGLContext.h b/content/canvas/src/WebGLContext.h index 4758b4eb1e3b..74c8a59dd2d6 100644 --- a/content/canvas/src/WebGLContext.h +++ b/content/canvas/src/WebGLContext.h @@ -6,6 +6,10 @@ #ifndef WEBGLCONTEXT_H_ #define WEBGLCONTEXT_H_ +#include "WebGLElementArrayCache.h" +#include "WebGLObjectModel.h" +#include "WebGLBuffer.h" + #include #include @@ -42,8 +46,6 @@ #include "mozilla/ErrorResult.h" #include "mozilla/dom/BindingUtils.h" -#include "WebGLElementArrayCache.h" - /* * Minimum value constants defined in 6.2 State Tables of OpenGL ES - 2.0.25 * https://bugzilla.mozilla.org/show_bug.cgi?id=686732 @@ -62,30 +64,16 @@ #define MINVALUE_GL_MAX_RENDERBUFFER_SIZE 1024 // Different from the spec, which sets it to 1 on page 164 #define MINVALUE_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 8 // Page 164 -// Manual reflection of WebIDL typedefs -typedef uint32_t WebGLenum; -typedef uint32_t WebGLbitfield; -typedef int32_t WebGLint; -typedef int32_t WebGLsizei; -typedef int64_t WebGLsizeiptr; -typedef int64_t WebGLintptr; -typedef uint32_t WebGLuint; -typedef float WebGLfloat; -typedef float WebGLclampf; -typedef bool WebGLboolean; - class nsIPropertyBag; namespace mozilla { class WebGLTexture; -class WebGLBuffer; class WebGLProgram; class WebGLShader; class WebGLFramebuffer; -class WebGLRenderbuffer; class WebGLUniformLocation; -class WebGLContext; +class WebGLRenderbuffer; struct WebGLVertexAttribData; class WebGLMemoryPressureObserver; class WebGLRectangleObject; @@ -163,246 +151,6 @@ inline bool is_pot_assuming_nonnegative(WebGLsizei x) return x && (x & (x-1)) == 0; } -/* Each WebGL object class WebGLFoo wants to: - * - inherit WebGLRefCountedObject - * - implement a Delete() method - * - have its destructor call DeleteOnce() - * - * This base class provides two features to WebGL object types: - * 1. support for OpenGL object reference counting - * 2. support for OpenGL deletion statuses - * - ***** 1. OpenGL object reference counting ***** - * - * WebGL objects such as WebGLTexture's really have two different refcounts: - * the XPCOM refcount, that is directly exposed to JavaScript, and the OpenGL - * refcount. - * - * For example, when in JavaScript one does: var newname = existingTexture; - * that increments the XPCOM refcount, but doesn't affect the OpenGL refcount. - * When one attaches the texture to a framebuffer object, that does increment - * its OpenGL refcount (and also its XPCOM refcount, to prevent the regular - * XPCOM refcounting mechanism from destroying objects prematurely). - * - * The actual OpenGL refcount is opaque to us (it's internal to the OpenGL - * implementation) but is affects the WebGL semantics that we have to implement: - * for example, a WebGLTexture that is attached to a WebGLFramebuffer must not - * be actually deleted, even if deleteTexture has been called on it, and even - * if JavaScript doesn't have references to it anymore. We can't just rely on - * OpenGL to keep alive the underlying OpenGL texture for us, for a variety of - * reasons, most importantly: we'd need to know when OpenGL objects are actually - * deleted, and OpenGL doesn't notify us about that, so we would have to query - * status very often with glIsXxx calls which isn't practical. - * - * This means that we have to keep track of the OpenGL refcount ourselves, - * in addition to the XPCOM refcount. - * - * This class implements such a refcount, see the mWebGLRefCnt - * member. In order to avoid name clashes (with regular XPCOM refcounting) - * in the derived class, we prefix members with 'WebGL', whence the names - * WebGLAddRef, WebGLRelease, etc. - * - * In practice, WebGLAddRef and WebGLRelease are only called from the - * WebGLRefPtr class. - * - ***** 2. OpenGL deletion statuses ***** - * - * In OpenGL, an object can go through 3 different deletion statuses during its - * lifetime, which correspond to the 3 enum values for DeletionStatus in this class: - * - the Default status, which it has from its creation to when the - * suitable glDeleteXxx function is called on it; - * - the DeleteRequested status, which is has from when the suitable glDeleteXxx - * function is called on it to when it is no longer referenced by other OpenGL - * objects. For example, a texture that is attached to a non-current FBO - * will enter that status when glDeleteTexture is called on it. For objects - * with that status, GL_DELETE_STATUS queries return true, but glIsXxx - * functions still return true. - * - the Deleted status, which is the status of objects on which the - * suitable glDeleteXxx function has been called, and that are not referenced - * by other OpenGL objects. - * - * This state is stored in the mDeletionStatus member of this class. - * - * When the GL refcount hits zero, if the status is DeleteRequested then we call - * the Delete() method on the derived class and the status becomes Deleted. This is - * what the MaybeDelete() function does. - * - * The DeleteOnce() function implemented here is a helper to ensure that we don't - * call Delete() twice on the same object. Since the derived class' destructor - * needs to call DeleteOnce() which calls Delete(), we can't allow either to be - * virtual. Strictly speaking, we could let them be virtual if the derived class - * were final, but that would be impossible to enforce and would lead to strange - * bugs if it were subclassed. - * - * This WebGLRefCountedObject class takes the Derived type - * as template parameter, as a means to allow DeleteOnce to call Delete() - * on the Derived class, without either method being virtual. This is a common - * C++ pattern known as the "curiously recursive template pattern (CRTP)". - */ -template -class WebGLRefCountedObject -{ -public: - enum DeletionStatus { Default, DeleteRequested, Deleted }; - - WebGLRefCountedObject() - : mDeletionStatus(Default) - { } - - ~WebGLRefCountedObject() { - NS_ABORT_IF_FALSE(mWebGLRefCnt == 0, "destroying WebGL object still referenced by other WebGL objects"); - NS_ABORT_IF_FALSE(mDeletionStatus == Deleted, "Derived class destructor must call DeleteOnce()"); - } - - // called by WebGLRefPtr - void WebGLAddRef() { - ++mWebGLRefCnt; - } - - // called by WebGLRefPtr - void WebGLRelease() { - NS_ABORT_IF_FALSE(mWebGLRefCnt > 0, "releasing WebGL object with WebGL refcnt already zero"); - --mWebGLRefCnt; - MaybeDelete(); - } - - // this is the function that WebGL.deleteXxx() functions want to call - void RequestDelete() { - if (mDeletionStatus == Default) - mDeletionStatus = DeleteRequested; - MaybeDelete(); - } - - bool IsDeleted() const { - return mDeletionStatus == Deleted; - } - - bool IsDeleteRequested() const { - return mDeletionStatus != Default; - } - - void DeleteOnce() { - if (mDeletionStatus != Deleted) { - static_cast(this)->Delete(); - mDeletionStatus = Deleted; - } - } - -private: - void MaybeDelete() { - if (mWebGLRefCnt == 0 && - mDeletionStatus == DeleteRequested) - { - DeleteOnce(); - } - } - -protected: - nsAutoRefCnt mWebGLRefCnt; - DeletionStatus mDeletionStatus; -}; - -/* This WebGLRefPtr class is meant to be used for references between WebGL objects. - * For example, a WebGLProgram holds WebGLRefPtr's to the WebGLShader's attached - * to it. - * - * Why the need for a separate refptr class? The only special thing that WebGLRefPtr - * does is that it increments and decrements the WebGL refcount of - * WebGLRefCountedObject's, in addition to incrementing and decrementing the - * usual XPCOM refcount. - * - * This means that by using a WebGLRefPtr instead of a nsRefPtr, you ensure that - * the WebGL refcount is incremented, which means that the object will be kept - * alive by this reference even if the matching webgl.deleteXxx() function is - * called on it. - */ -template -class WebGLRefPtr -{ -public: - WebGLRefPtr() - : mRawPtr(0) - { } - - WebGLRefPtr(const WebGLRefPtr& aSmartPtr) - : mRawPtr(aSmartPtr.mRawPtr) - { - AddRefOnPtr(mRawPtr); - } - - WebGLRefPtr(T *aRawPtr) - : mRawPtr(aRawPtr) - { - AddRefOnPtr(mRawPtr); - } - - ~WebGLRefPtr() { - ReleasePtr(mRawPtr); - } - - WebGLRefPtr& - operator=(const WebGLRefPtr& rhs) - { - assign_with_AddRef(rhs.mRawPtr); - return *this; - } - - WebGLRefPtr& - operator=(T* rhs) - { - assign_with_AddRef(rhs); - return *this; - } - - T* get() const { - return static_cast(mRawPtr); - } - - operator T*() const { - return get(); - } - - T* operator->() const { - NS_ABORT_IF_FALSE(mRawPtr != 0, "You can't dereference a NULL WebGLRefPtr with operator->()!"); - return get(); - } - - T& operator*() const { - NS_ABORT_IF_FALSE(mRawPtr != 0, "You can't dereference a NULL WebGLRefPtr with operator*()!"); - return *get(); - } - -private: - - static void AddRefOnPtr(T* rawPtr) { - if (rawPtr) { - rawPtr->WebGLAddRef(); - rawPtr->AddRef(); - } - } - - static void ReleasePtr(T* rawPtr) { - if (rawPtr) { - rawPtr->WebGLRelease(); // must be done first before Release(), as Release() might actually destroy the object - rawPtr->Release(); - } - } - - void assign_with_AddRef(T* rawPtr) { - AddRefOnPtr(rawPtr); - assign_assuming_AddRef(rawPtr); - } - - void assign_assuming_AddRef(T* newPtr) { - T* oldPtr = mRawPtr; - mRawPtr = newPtr; - ReleasePtr(oldPtr); - } - -protected: - T *mRawPtr; -}; - // this class is a mixin for GL objects that have dimensions // that we need to track. class WebGLRectangleObject @@ -1463,29 +1211,6 @@ ToSupports(WebGLContext* context) return static_cast(context); } -// This class is a mixin for objects that are tied to a specific -// context (which is to say, all of them). They provide initialization -// as well as comparison with the current context. -class WebGLContextBoundObject -{ -public: - WebGLContextBoundObject(WebGLContext *context) { - mContext = context; - mContextGeneration = context->Generation(); - } - - bool IsCompatibleWithContext(WebGLContext *other) { - return mContext == other && - mContextGeneration == other->Generation(); - } - - WebGLContext *Context() const { return mContext; } - -protected: - WebGLContext *mContext; - uint32_t mContextGeneration; -}; - struct WebGLVertexAttribData { // note that these initial values are what GL initializes vertex attribs to WebGLVertexAttribData() @@ -1531,90 +1256,6 @@ struct WebGLVertexAttribData { } }; -class WebGLBuffer MOZ_FINAL - : public nsISupports - , public WebGLRefCountedObject - , public LinkedListElement - , public WebGLContextBoundObject - , public nsWrapperCache -{ -public: - WebGLBuffer(WebGLContext *context) - : WebGLContextBoundObject(context) - , mHasEverBeenBound(false) - , mByteLength(0) - , mTarget(LOCAL_GL_NONE) - { - SetIsDOMBinding(); - mContext->MakeContextCurrent(); - mContext->gl->fGenBuffers(1, &mGLName); - mContext->mBuffers.insertBack(this); - } - - ~WebGLBuffer() { - DeleteOnce(); - } - - void Delete() { - mContext->MakeContextCurrent(); - mContext->gl->fDeleteBuffers(1, &mGLName); - mByteLength = 0; - mCache = nullptr; - LinkedListElement::removeFrom(mContext->mBuffers); - } - - size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const { - size_t sizeOfCache = mCache ? mCache->SizeOfIncludingThis(aMallocSizeOf) : 0; - return aMallocSizeOf(this) + sizeOfCache; - } - - bool HasEverBeenBound() { return mHasEverBeenBound; } - void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; } - GLuint GLName() const { return mGLName; } - GLuint ByteLength() const { return mByteLength; } - GLenum Target() const { return mTarget; } - - void SetByteLength(GLuint byteLength) { mByteLength = byteLength; } - - void SetTarget(GLenum target) { - mTarget = target; - if (!mCache && mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER) - mCache = new WebGLElementArrayCache; - } - - bool ElementArrayCacheBufferData(const void* ptr, size_t buffer_size_in_bytes) { - if (mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER) - return mCache->BufferData(ptr, buffer_size_in_bytes); - return true; - } - - void ElementArrayCacheBufferSubData(size_t pos, const void* ptr, size_t update_size_in_bytes) { - if (mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER) - mCache->BufferSubData(pos, ptr, update_size_in_bytes); - } - - bool Validate(WebGLenum type, uint32_t max_allowed, size_t first, size_t count) { - return mCache->Validate(type, max_allowed, first, count); - } - - WebGLContext *GetParentObject() const { - return Context(); - } - - virtual JSObject* WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap); - - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLBuffer) - -protected: - - WebGLuint mGLName; - bool mHasEverBeenBound; - GLuint mByteLength; - GLenum mTarget; - - nsAutoPtr mCache; -}; // NOTE: When this class is switched to new DOM bindings, update the (then-slow) // WrapObject calls in GetParameter and GetFramebufferAttachmentParameter. @@ -3467,22 +3108,4 @@ ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, aCallback.NoteXPCOMChild(aField.buf); } -template -inline void -ImplCycleCollectionUnlink(mozilla::WebGLRefPtr& aField) -{ - aField = nullptr; -} - -template -inline void -ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, - mozilla::WebGLRefPtr& aField, - const char* aName, - uint32_t aFlags = 0) -{ - CycleCollectionNoteEdgeName(aCallback, aName, aFlags); - aCallback.NoteXPCOMChild(aField); -} - #endif diff --git a/content/canvas/src/WebGLObjectModel.cpp b/content/canvas/src/WebGLObjectModel.cpp new file mode 100644 index 000000000000..eb640a3f56cf --- /dev/null +++ b/content/canvas/src/WebGLObjectModel.cpp @@ -0,0 +1,19 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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 "WebGLObjectModel.h" +#include "WebGLContext.h" + +using namespace mozilla; + +WebGLContextBoundObject::WebGLContextBoundObject(WebGLContext *context) { + mContext = context; + mContextGeneration = context->Generation(); +} +bool +WebGLContextBoundObject::IsCompatibleWithContext(WebGLContext *other) { + return mContext == other && + mContextGeneration == other->Generation(); +} diff --git a/content/canvas/src/WebGLObjectModel.h b/content/canvas/src/WebGLObjectModel.h new file mode 100644 index 000000000000..d895a9312856 --- /dev/null +++ b/content/canvas/src/WebGLObjectModel.h @@ -0,0 +1,306 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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 WEBGLOBJECTMODEL_H_ +#define WEBGLOBJECTMODEL_H_ + +#include "nsCycleCollectionNoteChild.h" +#include "nsICanvasRenderingContextInternal.h" + +// Manual reflection of WebIDL typedefs +typedef uint32_t WebGLenum; +typedef uint32_t WebGLbitfield; +typedef int32_t WebGLint; +typedef int32_t WebGLsizei; +typedef int64_t WebGLsizeiptr; +typedef int64_t WebGLintptr; +typedef uint32_t WebGLuint; +typedef float WebGLfloat; +typedef float WebGLclampf; +typedef bool WebGLboolean; + +namespace mozilla { + +class WebGLBuffer; +class WebGLContext; + +/* Each WebGL object class WebGLFoo wants to: + * - inherit WebGLRefCountedObject + * - implement a Delete() method + * - have its destructor call DeleteOnce() + * + * This base class provides two features to WebGL object types: + * 1. support for OpenGL object reference counting + * 2. support for OpenGL deletion statuses + * + ***** 1. OpenGL object reference counting ***** + * + * WebGL objects such as WebGLTexture's really have two different refcounts: + * the XPCOM refcount, that is directly exposed to JavaScript, and the OpenGL + * refcount. + * + * For example, when in JavaScript one does: var newname = existingTexture; + * that increments the XPCOM refcount, but doesn't affect the OpenGL refcount. + * When one attaches the texture to a framebuffer object, that does increment + * its OpenGL refcount (and also its XPCOM refcount, to prevent the regular + * XPCOM refcounting mechanism from destroying objects prematurely). + * + * The actual OpenGL refcount is opaque to us (it's internal to the OpenGL + * implementation) but is affects the WebGL semantics that we have to implement: + * for example, a WebGLTexture that is attached to a WebGLFramebuffer must not + * be actually deleted, even if deleteTexture has been called on it, and even + * if JavaScript doesn't have references to it anymore. We can't just rely on + * OpenGL to keep alive the underlying OpenGL texture for us, for a variety of + * reasons, most importantly: we'd need to know when OpenGL objects are actually + * deleted, and OpenGL doesn't notify us about that, so we would have to query + * status very often with glIsXxx calls which isn't practical. + * + * This means that we have to keep track of the OpenGL refcount ourselves, + * in addition to the XPCOM refcount. + * + * This class implements such a refcount, see the mWebGLRefCnt + * member. In order to avoid name clashes (with regular XPCOM refcounting) + * in the derived class, we prefix members with 'WebGL', whence the names + * WebGLAddRef, WebGLRelease, etc. + * + * In practice, WebGLAddRef and WebGLRelease are only called from the + * WebGLRefPtr class. + * + ***** 2. OpenGL deletion statuses ***** + * + * In OpenGL, an object can go through 3 different deletion statuses during its + * lifetime, which correspond to the 3 enum values for DeletionStatus in this class: + * - the Default status, which it has from its creation to when the + * suitable glDeleteXxx function is called on it; + * - the DeleteRequested status, which is has from when the suitable glDeleteXxx + * function is called on it to when it is no longer referenced by other OpenGL + * objects. For example, a texture that is attached to a non-current FBO + * will enter that status when glDeleteTexture is called on it. For objects + * with that status, GL_DELETE_STATUS queries return true, but glIsXxx + * functions still return true. + * - the Deleted status, which is the status of objects on which the + * suitable glDeleteXxx function has been called, and that are not referenced + * by other OpenGL objects. + * + * This state is stored in the mDeletionStatus member of this class. + * + * When the GL refcount hits zero, if the status is DeleteRequested then we call + * the Delete() method on the derived class and the status becomes Deleted. This is + * what the MaybeDelete() function does. + * + * The DeleteOnce() function implemented here is a helper to ensure that we don't + * call Delete() twice on the same object. Since the derived class' destructor + * needs to call DeleteOnce() which calls Delete(), we can't allow either to be + * virtual. Strictly speaking, we could let them be virtual if the derived class + * were final, but that would be impossible to enforce and would lead to strange + * bugs if it were subclassed. + * + * This WebGLRefCountedObject class takes the Derived type + * as template parameter, as a means to allow DeleteOnce to call Delete() + * on the Derived class, without either method being virtual. This is a common + * C++ pattern known as the "curiously recursive template pattern (CRTP)". + */ +template +class WebGLRefCountedObject +{ +public: + enum DeletionStatus { Default, DeleteRequested, Deleted }; + + WebGLRefCountedObject() + : mDeletionStatus(Default) + { } + + ~WebGLRefCountedObject() { + NS_ABORT_IF_FALSE(mWebGLRefCnt == 0, "destroying WebGL object still referenced by other WebGL objects"); + NS_ABORT_IF_FALSE(mDeletionStatus == Deleted, "Derived class destructor must call DeleteOnce()"); + } + + // called by WebGLRefPtr + void WebGLAddRef() { + ++mWebGLRefCnt; + } + + // called by WebGLRefPtr + void WebGLRelease() { + NS_ABORT_IF_FALSE(mWebGLRefCnt > 0, "releasing WebGL object with WebGL refcnt already zero"); + --mWebGLRefCnt; + MaybeDelete(); + } + + // this is the function that WebGL.deleteXxx() functions want to call + void RequestDelete() { + if (mDeletionStatus == Default) + mDeletionStatus = DeleteRequested; + MaybeDelete(); + } + + bool IsDeleted() const { + return mDeletionStatus == Deleted; + } + + bool IsDeleteRequested() const { + return mDeletionStatus != Default; + } + + void DeleteOnce() { + if (mDeletionStatus != Deleted) { + static_cast(this)->Delete(); + mDeletionStatus = Deleted; + } + } + +private: + void MaybeDelete() { + if (mWebGLRefCnt == 0 && + mDeletionStatus == DeleteRequested) + { + DeleteOnce(); + } + } + +protected: + nsAutoRefCnt mWebGLRefCnt; + DeletionStatus mDeletionStatus; +}; + +/* This WebGLRefPtr class is meant to be used for references between WebGL objects. + * For example, a WebGLProgram holds WebGLRefPtr's to the WebGLShader's attached + * to it. + * + * Why the need for a separate refptr class? The only special thing that WebGLRefPtr + * does is that it increments and decrements the WebGL refcount of + * WebGLRefCountedObject's, in addition to incrementing and decrementing the + * usual XPCOM refcount. + * + * This means that by using a WebGLRefPtr instead of a nsRefPtr, you ensure that + * the WebGL refcount is incremented, which means that the object will be kept + * alive by this reference even if the matching webgl.deleteXxx() function is + * called on it. + */ +template +class WebGLRefPtr +{ +public: + WebGLRefPtr() + : mRawPtr(0) + { } + + WebGLRefPtr(const WebGLRefPtr& aSmartPtr) + : mRawPtr(aSmartPtr.mRawPtr) + { + AddRefOnPtr(mRawPtr); + } + + WebGLRefPtr(T *aRawPtr) + : mRawPtr(aRawPtr) + { + AddRefOnPtr(mRawPtr); + } + + ~WebGLRefPtr() { + ReleasePtr(mRawPtr); + } + + WebGLRefPtr& + operator=(const WebGLRefPtr& rhs) + { + assign_with_AddRef(rhs.mRawPtr); + return *this; + } + + WebGLRefPtr& + operator=(T* rhs) + { + assign_with_AddRef(rhs); + return *this; + } + + T* get() const { + return static_cast(mRawPtr); + } + + operator T*() const { + return get(); + } + + T* operator->() const { + NS_ABORT_IF_FALSE(mRawPtr != 0, "You can't dereference a NULL WebGLRefPtr with operator->()!"); + return get(); + } + + T& operator*() const { + NS_ABORT_IF_FALSE(mRawPtr != 0, "You can't dereference a NULL WebGLRefPtr with operator*()!"); + return *get(); + } + +private: + + static void AddRefOnPtr(T* rawPtr) { + if (rawPtr) { + rawPtr->WebGLAddRef(); + rawPtr->AddRef(); + } + } + + static void ReleasePtr(T* rawPtr) { + if (rawPtr) { + rawPtr->WebGLRelease(); // must be done first before Release(), as Release() might actually destroy the object + rawPtr->Release(); + } + } + + void assign_with_AddRef(T* rawPtr) { + AddRefOnPtr(rawPtr); + assign_assuming_AddRef(rawPtr); + } + + void assign_assuming_AddRef(T* newPtr) { + T* oldPtr = mRawPtr; + mRawPtr = newPtr; + ReleasePtr(oldPtr); + } + +protected: + T *mRawPtr; +}; + +// This class is a mixin for objects that are tied to a specific +// context (which is to say, all of them). They provide initialization +// as well as comparison with the current context. +class WebGLContextBoundObject +{ +public: + WebGLContextBoundObject(WebGLContext *context); + + bool IsCompatibleWithContext(WebGLContext *other); + + WebGLContext *Context() const { return mContext; } + +protected: + WebGLContext *mContext; + uint32_t mContextGeneration; +}; + +}// namespace mozilla + +template +inline void +ImplCycleCollectionUnlink(mozilla::WebGLRefPtr& aField) +{ + aField = nullptr; +} + +template +inline void +ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, + mozilla::WebGLRefPtr& aField, + const char* aName, + uint32_t aFlags = 0) +{ + CycleCollectionNoteEdgeName(aCallback, aName, aFlags); + aCallback.NoteXPCOMChild(aField); +} + +#endif From f6e498e705b77f1fcd1dfd43c2352a9ed7c9d67d Mon Sep 17 00:00:00 2001 From: Jason Orendorff Date: Fri, 16 Nov 2012 15:59:26 -0600 Subject: [PATCH 73/75] Bug 812314 part 1 - Use fewer namespace js {...} blocks in .cpp files in js/src, js/src/builtin, js/src/vm. r=luke. --HG-- rename : browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after.js => browser/components/privatebrowsing/test/browser/global/browser_privatebrowsing_localStorage_before_after.js rename : browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after_page.html => browser/components/privatebrowsing/test/browser/global/browser_privatebrowsing_localStorage_before_after_page.html rename : browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_localStorage_before_after_page2.html => browser/components/privatebrowsing/test/browser/global/browser_privatebrowsing_localStorage_before_after_page2.html rename : browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_placestitle.js => browser/components/privatebrowsing/test/browser/global/browser_privatebrowsing_placestitle.js rename : browser/components/privatebrowsing/test/browser/perwindow/title.sjs => browser/components/privatebrowsing/test/browser/global/title.sjs extra : rebase_source : d1d1c39b490ae33fb9e8417ed72c2b77ee631416 --- js/src/TraceLogging.cpp | 20 ++--- js/src/builtin/TestingFunctions.cpp | 7 +- js/src/jsalloc.cpp | 4 +- js/src/jsanalyze.cpp | 12 +-- js/src/jsapi.cpp | 38 +++----- js/src/jsarray.cpp | 49 ++++------- js/src/jsatom.cpp | 6 +- js/src/jsatominlines.h | 4 +- js/src/jsbool.cpp | 11 +-- js/src/jsboolinlines.h | 3 +- js/src/jsclone.cpp | 19 ++-- js/src/jscntxt.cpp | 18 +--- js/src/jscntxtinlines.h | 2 - js/src/jscrashreport.cpp | 22 ++--- js/src/jsdbgapi.cpp | 8 +- js/src/jsexn.cpp | 6 +- js/src/jsfriendapi.cpp | 86 +++++++++--------- js/src/jsfun.cpp | 26 ++---- js/src/jsfun.h | 5 ++ js/src/jsfuninlines.h | 2 - js/src/jsgc.cpp | 132 ++++++++++------------------ js/src/jsgc.h | 4 - js/src/jsgcinlines.h | 4 +- js/src/jsinfer.cpp | 14 ++- js/src/jsinferinlines.h | 10 +-- js/src/jsiter.cpp | 20 ++--- js/src/jslock.h | 1 + js/src/jsmemorymetrics.cpp | 21 ++--- js/src/jsnativestack.cpp | 14 ++- js/src/jsnum.cpp | 44 +++------- js/src/jsobj.cpp | 114 ++++++++---------------- js/src/json.cpp | 8 +- js/src/jsopcode.cpp | 14 ++- js/src/jsreflect.cpp | 17 ++-- js/src/jsreflect.h | 1 - js/src/jsscript.cpp | 14 +-- js/src/jsstr.cpp | 46 +++------- js/src/jsweakmap.cpp | 4 - js/src/jswrapper.cpp | 8 +- js/src/jsxml.cpp | 10 +-- js/src/vm/GlobalObject.cpp | 14 ++- js/src/vm/ScopeObject.cpp | 4 - js/src/vm/Unicode.cpp | 12 ++- js/src/vm/Xdr.cpp | 9 +- js/src/vm/make_unicode.py | 10 +-- 45 files changed, 305 insertions(+), 592 deletions(-) diff --git a/js/src/TraceLogging.cpp b/js/src/TraceLogging.cpp index 9c57700cba56..49fe2d3e8ace 100644 --- a/js/src/TraceLogging.cpp +++ b/js/src/TraceLogging.cpp @@ -12,6 +12,8 @@ #include #include +using namespace js; + #ifndef TRACE_LOG_DIR # if defined(_WIN32) # define TRACE_LOG_DIR "" @@ -20,11 +22,9 @@ # endif #endif -namespace js { - #if defined(__i386__) static __inline__ uint64_t -rdtsc(void) +js::rdtsc(void) { uint64_t x; __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); @@ -32,7 +32,7 @@ rdtsc(void) } #elif defined(__x86_64__) static __inline__ uint64_t -rdtsc(void) +js::rdtsc(void) { unsigned hi, lo; __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); @@ -40,7 +40,7 @@ rdtsc(void) } #elif defined(__powerpc__) static __inline__ uint64_t -rdtsc(void) +js::rdtsc(void) { uint64_t result=0; uint32_t upper, lower,tmp; @@ -242,19 +242,19 @@ TraceLogging::releaseDefaultLogger() /* Helper functions for asm calls */ void -TraceLog(TraceLogging* logger, TraceLogging::Type type, JSScript* script) +js::TraceLog(TraceLogging* logger, TraceLogging::Type type, JSScript* script) { logger->log(type, script); } + void -TraceLog(TraceLogging* logger, const char* log) +js::TraceLog(TraceLogging* logger, const char* log) { logger->log(log); } + void -TraceLog(TraceLogging* logger, TraceLogging::Type type) +js::TraceLog(TraceLogging* logger, TraceLogging::Type type) { logger->log(type); } - -} /* namespace js */ diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index 46fd34809873..7021c9dcf178 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -14,6 +14,7 @@ #include "jsprf.h" #include "jswrapper.h" +#include "builtin/TestingFunctions.h" #include "methodjit/MethodJIT.h" #include "vm/Stack-inl.h" @@ -925,12 +926,8 @@ static JSFunctionSpecWithHelp TestingFunctions[] = { JS_FS_HELP_END }; -namespace js { - bool -DefineTestingFunctions(JSContext *cx, HandleObject obj) +js::DefineTestingFunctions(JSContext *cx, HandleObject obj) { return JS_DefineFunctionsWithHelp(cx, obj, TestingFunctions); } - -} /* namespace js */ diff --git a/js/src/jsalloc.cpp b/js/src/jsalloc.cpp index 45806eb9264f..71c036a5e0f8 100644 --- a/js/src/jsalloc.cpp +++ b/js/src/jsalloc.cpp @@ -8,7 +8,7 @@ #include "jsalloc.h" #include "jscntxt.h" -namespace js { +using namespace js; void * TempAllocPolicy::onOutOfMemory(void *p, size_t nbytes) @@ -21,5 +21,3 @@ TempAllocPolicy::reportAllocOverflow() const { js_ReportAllocationOverflow(cx); } - -} /* namespace js */ diff --git a/js/src/jsanalyze.cpp b/js/src/jsanalyze.cpp index 5abdb44367ea..d89f108f59f0 100644 --- a/js/src/jsanalyze.cpp +++ b/js/src/jsanalyze.cpp @@ -13,9 +13,8 @@ #include "jsobjinlines.h" using mozilla::DebugOnly; - -namespace js { -namespace analyze { +using namespace js; +using namespace js::analyze; ///////////////////////////////////////////////////////////////////// // Bytecode @@ -23,7 +22,7 @@ namespace analyze { #ifdef DEBUG void -PrintBytecode(JSContext *cx, JSScript *scriptArg, jsbytecode *pc) +analyze::PrintBytecode(JSContext *cx, JSScript *scriptArg, jsbytecode *pc) { RootedScript script(cx, scriptArg); @@ -36,7 +35,7 @@ PrintBytecode(JSContext *cx, JSScript *scriptArg, jsbytecode *pc) } #endif -inline bool +static inline bool IsJumpOpcode(JSOp op) { uint32_t type = JOF_TYPE(js_CodeSpec[op].format); @@ -2129,6 +2128,3 @@ ScriptAnalysis::assertMatchingDebugMode() } #endif /* DEBUG */ - -} /* namespace analyze */ -} /* namespace js */ diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 74e8a3bd442d..c43515d065ab 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -680,49 +680,43 @@ static JSBool js_NewRuntimeWasCalled = JS_FALSE; /* * Thread Local Storage slot for storing the runtime for a thread. */ -namespace js { -mozilla::ThreadLocal TlsPerThreadData; -} - -namespace JS { +mozilla::ThreadLocal js::TlsPerThreadData; #ifdef DEBUG JS_FRIEND_API(void) -EnterAssertNoGCScope() +JS::EnterAssertNoGCScope() { ++TlsPerThreadData.get()->gcAssertNoGCDepth; } JS_FRIEND_API(void) -LeaveAssertNoGCScope() +JS::LeaveAssertNoGCScope() { --TlsPerThreadData.get()->gcAssertNoGCDepth; JS_ASSERT(TlsPerThreadData.get()->gcAssertNoGCDepth >= 0); } JS_FRIEND_API(bool) -InNoGCScope() +JS::InNoGCScope() { return TlsPerThreadData.get()->gcAssertNoGCDepth > 0; } JS_FRIEND_API(bool) -NeedRelaxedRootChecks() +JS::NeedRelaxedRootChecks() { return TlsPerThreadData.get()->gcRelaxRootChecks; } #else -JS_FRIEND_API(void) EnterAssertNoGCScope() {} -JS_FRIEND_API(void) LeaveAssertNoGCScope() {} -JS_FRIEND_API(bool) InNoGCScope() { return false; } -JS_FRIEND_API(bool) NeedRelaxedRootChecks() { return false; } +JS_FRIEND_API(void) JS::EnterAssertNoGCScope() {} +JS_FRIEND_API(void) JS::LeaveAssertNoGCScope() {} +JS_FRIEND_API(bool) JS::InNoGCScope() { return false; } +JS_FRIEND_API(bool) JS::NeedRelaxedRootChecks() { return false; } #endif -} /* namespace JS */ - static const JSSecurityCallbacks NullSecurityCallbacks = { }; -js::PerThreadData::PerThreadData(JSRuntime *runtime) +PerThreadData::PerThreadData(JSRuntime *runtime) : runtime_(runtime) #ifdef DEBUG , gcRelaxRootChecks(false) @@ -5770,10 +5764,8 @@ JS_CallFunctionValue(JSContext *cx, JSObject *objArg, jsval fval, unsigned argc, return Invoke(cx, ObjectOrNullValue(obj), fval, argc, argv, rval); } -namespace JS { - JS_PUBLIC_API(bool) -Call(JSContext *cx, jsval thisv, jsval fval, unsigned argc, jsval *argv, jsval *rval) +JS::Call(JSContext *cx, jsval thisv, jsval fval, unsigned argc, jsval *argv, jsval *rval) { AssertHeapIsIdle(cx); CHECK_REQUEST(cx); @@ -5783,8 +5775,6 @@ Call(JSContext *cx, jsval thisv, jsval fval, unsigned argc, jsval *argv, jsval * return Invoke(cx, thisv, fval, argc, argv, rval); } -} // namespace JS - JS_PUBLIC_API(JSObject *) JS_New(JSContext *cx, JSObject *ctorArg, unsigned argc, jsval *argv) { @@ -7106,8 +7096,6 @@ JS_CallOnce(JSCallOnceType *once, JSInitCallback func) #endif } -namespace JS { - AutoGCRooter::AutoGCRooter(JSContext *cx, ptrdiff_t tag) : down(cx->runtime->autoGCRooters), tag(tag), stackTop(&cx->runtime->autoGCRooters) { @@ -7117,7 +7105,7 @@ AutoGCRooter::AutoGCRooter(JSContext *cx, ptrdiff_t tag) #ifdef DEBUG JS_PUBLIC_API(void) -AssertArgumentsAreSane(JSContext *cx, const JS::Value &value) +JS::AssertArgumentsAreSane(JSContext *cx, const JS::Value &value) { AssertHeapIsIdle(cx); CHECK_REQUEST(cx); @@ -7125,8 +7113,6 @@ AssertArgumentsAreSane(JSContext *cx, const JS::Value &value) } #endif /* DEBUG */ -} // namespace JS - JS_PUBLIC_API(void *) JS_EncodeScript(JSContext *cx, JSRawScript scriptArg, uint32_t *lengthp) { diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp index 331986d85038..cd909d915eb5 100644 --- a/js/src/jsarray.cpp +++ b/js/src/jsarray.cpp @@ -120,10 +120,8 @@ using mozilla::ArrayLength; using mozilla::DebugOnly; using mozilla::PointerRangeSize; -namespace js { - JSBool -GetLengthProperty(JSContext *cx, HandleObject obj, uint32_t *lengthp) +js::GetLengthProperty(JSContext *cx, HandleObject obj, uint32_t *lengthp) { if (obj->isArray()) { *lengthp = obj->getArrayLength(); @@ -170,7 +168,7 @@ GetLengthProperty(JSContext *cx, HandleObject obj, uint32_t *lengthp) * */ JS_FRIEND_API(bool) -StringIsArrayIndex(JSLinearString *str, uint32_t *indexp) +js::StringIsArrayIndex(JSLinearString *str, uint32_t *indexp) { const jschar *s = str->chars(); uint32_t length = str->length(); @@ -207,7 +205,7 @@ StringIsArrayIndex(JSLinearString *str, uint32_t *indexp) } Shape * -GetDenseArrayShape(JSContext *cx, HandleObject globalObj) +js::GetDenseArrayShape(JSContext *cx, HandleObject globalObj) { JS_ASSERT(globalObj); @@ -219,8 +217,6 @@ GetDenseArrayShape(JSContext *cx, HandleObject globalObj) gc::FINALIZE_OBJECT0); } -} - bool JSObject::willBeSparseDenseArray(unsigned requiredCapacity, unsigned newElementsHint) { @@ -364,8 +360,6 @@ GetElement(JSContext *cx, HandleObject obj, IndexType index, JSBool *hole, Mutab return DoGetElement(cx, obj, index, hole, vp); } -namespace js { - static bool GetElementsSlow(JSContext *cx, HandleObject aobj, uint32_t length, Value *vp) { @@ -378,7 +372,7 @@ GetElementsSlow(JSContext *cx, HandleObject aobj, uint32_t length, Value *vp) } bool -GetElements(JSContext *cx, HandleObject aobj, uint32_t length, Value *vp) +js::GetElements(JSContext *cx, HandleObject aobj, uint32_t length, Value *vp) { if (aobj->isDenseArray() && length <= aobj->getDenseArrayInitializedLength() && !js_PrototypeHasIndexedProperties(aobj)) { @@ -402,8 +396,6 @@ GetElements(JSContext *cx, HandleObject aobj, uint32_t length, Value *vp) return GetElementsSlow(cx, aobj, length, vp); } -} - /* * Set the value of the property at the given index to v assuming v is rooted. */ @@ -984,12 +976,10 @@ array_defineProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, H return array_defineGeneric(cx, obj, id, value, getter, setter, attrs); } -namespace js { - /* non-static for direct definition of array elements within the engine */ JSBool -array_defineElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue value, - PropertyOp getter, StrictPropertyOp setter, unsigned attrs) +js::array_defineElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue value, + PropertyOp getter, StrictPropertyOp setter, unsigned attrs) { if (!obj->isDenseArray()) return baseops::DefineElement(cx, obj, index, value, getter, setter, attrs); @@ -1023,8 +1013,6 @@ array_defineElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue return baseops::DefineElement(cx, obj, index, value, getter, setter, attrs); } -} // namespace js - static JSBool array_defineSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, HandleValue value, PropertyOp getter, StrictPropertyOp setter, unsigned attrs) @@ -1108,12 +1096,10 @@ array_deleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, return true; } -namespace js { - /* non-static for direct deletion of array elements within the engine */ JSBool -array_deleteElement(JSContext *cx, HandleObject obj, uint32_t index, - MutableHandleValue rval, JSBool strict) +js::array_deleteElement(JSContext *cx, HandleObject obj, uint32_t index, MutableHandleValue rval, + JSBool strict) { if (!obj->isDenseArray()) return baseops::DeleteElement(cx, obj, index, rval, strict); @@ -1130,8 +1116,6 @@ array_deleteElement(JSContext *cx, HandleObject obj, uint32_t index, return true; } -} // namespace js - static JSBool array_deleteSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, MutableHandleValue rval, JSBool strict) @@ -3615,7 +3599,6 @@ js_InitArrayClass(JSContext *cx, HandleObject obj) /* * Array allocation functions. */ -namespace js { static inline bool EnsureNewArrayElements(JSContext *cx, JSObject *obj, uint32_t length) @@ -3692,19 +3675,19 @@ NewArray(JSContext *cx, uint32_t length, RawObject protoArg) } JSObject * JS_FASTCALL -NewDenseEmptyArray(JSContext *cx, RawObject proto /* = NULL */) +js::NewDenseEmptyArray(JSContext *cx, RawObject proto /* = NULL */) { return NewArray(cx, 0, proto); } JSObject * JS_FASTCALL -NewDenseAllocatedArray(JSContext *cx, uint32_t length, RawObject proto /* = NULL */) +js::NewDenseAllocatedArray(JSContext *cx, uint32_t length, RawObject proto /* = NULL */) { return NewArray(cx, length, proto); } JSObject * JS_FASTCALL -NewDenseUnallocatedArray(JSContext *cx, uint32_t length, RawObject proto /* = NULL */) +js::NewDenseUnallocatedArray(JSContext *cx, uint32_t length, RawObject proto /* = NULL */) { return NewArray(cx, length, proto); } @@ -3722,7 +3705,8 @@ mjit::stubs::NewDenseUnallocatedArray(VMFrame &f, uint32_t length) #endif JSObject * -NewDenseCopiedArray(JSContext *cx, uint32_t length, HandleObject src, uint32_t elementOffset, RawObject proto /* = NULL */) +js::NewDenseCopiedArray(JSContext *cx, uint32_t length, HandleObject src, uint32_t elementOffset, + RawObject proto /* = NULL */) { JSObject* obj = NewArray(cx, length, proto); if (!obj) @@ -3741,7 +3725,8 @@ NewDenseCopiedArray(JSContext *cx, uint32_t length, HandleObject src, uint32_t e // values must point at already-rooted Value objects JSObject * -NewDenseCopiedArray(JSContext *cx, uint32_t length, const Value *values, RawObject proto /* = NULL */) +js::NewDenseCopiedArray(JSContext *cx, uint32_t length, const Value *values, + RawObject proto /* = NULL */) { JSObject* obj = NewArray(cx, length, proto); if (!obj) @@ -3758,7 +3743,7 @@ NewDenseCopiedArray(JSContext *cx, uint32_t length, const Value *values, RawObje } JSObject * -NewSlowEmptyArray(JSContext *cx) +js::NewSlowEmptyArray(JSContext *cx) { RootedObject obj(cx, NewBuiltinClassInstance(cx, &SlowArrayClass)); if (!obj || !AddLengthProperty(cx, obj)) @@ -3768,8 +3753,6 @@ NewSlowEmptyArray(JSContext *cx) return obj; } -} // namespace js - #ifdef DEBUG JSBool js_ArrayInfo(JSContext *cx, unsigned argc, Value *vp) diff --git a/js/src/jsatom.cpp b/js/src/jsatom.cpp index cccf4a2c9605..d12c3b8016b5 100644 --- a/js/src/jsatom.cpp +++ b/js/src/jsatom.cpp @@ -371,10 +371,8 @@ js::AtomizeChars(JSContext *cx, const jschar *chars, size_t length, InternBehavi return AtomizeInline(cx, &chars, length, ib); } -namespace js { - bool -IndexToIdSlow(JSContext *cx, uint32_t index, jsid *idp) +js::IndexToIdSlow(JSContext *cx, uint32_t index, jsid *idp) { JS_ASSERT(index > JSID_INT_MAX); @@ -390,8 +388,6 @@ IndexToIdSlow(JSContext *cx, uint32_t index, jsid *idp) return true; } -} /* namespace js */ - bool js::InternNonIntElementId(JSContext *cx, JSObject *obj, const Value &idval, jsid *idp, MutableHandleValue vp) diff --git a/js/src/jsatominlines.h b/js/src/jsatominlines.h index 12da31a66df2..ec2eed027925 100644 --- a/js/src/jsatominlines.h +++ b/js/src/jsatominlines.h @@ -94,6 +94,9 @@ BackfillIndexInCharBuffer(uint32_t index, mozilla::RangedPtr end) return end; } +bool +IndexToIdSlow(JSContext *cx, uint32_t index, jsid *idp); + inline bool IndexToId(JSContext *cx, uint32_t index, jsid *idp) { @@ -104,7 +107,6 @@ IndexToId(JSContext *cx, uint32_t index, jsid *idp) return true; } - extern bool IndexToIdSlow(JSContext *cx, uint32_t index, jsid *idp); return IndexToIdSlow(cx, index, idp); } diff --git a/js/src/jsbool.cpp b/js/src/jsbool.cpp index d24765b511d4..aecaad544ce4 100644 --- a/js/src/jsbool.cpp +++ b/js/src/jsbool.cpp @@ -26,6 +26,7 @@ #include "vm/GlobalObject.h" #include "vm/StringBuffer.h" +#include "jsboolinlines.h" #include "jsinferinlines.h" #include "jsobjinlines.h" @@ -192,17 +193,15 @@ js_BooleanToString(JSContext *cx, JSBool b) return b ? cx->runtime->atomState.true_ : cx->runtime->atomState.false_; } -namespace js { - JS_PUBLIC_API(bool) -ToBooleanSlow(const Value &v) +js::ToBooleanSlow(const Value &v) { JS_ASSERT(v.isString()); return v.toString()->length() != 0; } bool -BooleanGetPrimitiveValueSlow(JSContext *cx, JSObject &obj, Value *vp) +js::BooleanGetPrimitiveValueSlow(JSContext *cx, JSObject &obj, Value *vp) { InvokeArgsGuard ag; if (!cx->stack.pushInvokeArgs(cx, 0, &ag)) @@ -214,7 +213,3 @@ BooleanGetPrimitiveValueSlow(JSContext *cx, JSObject &obj, Value *vp) *vp = ag.rval(); return true; } - -} /* namespace js */ - - diff --git a/js/src/jsboolinlines.h b/js/src/jsboolinlines.h index 5c57f9c724dc..b1e4a10b4445 100644 --- a/js/src/jsboolinlines.h +++ b/js/src/jsboolinlines.h @@ -13,6 +13,8 @@ namespace js { +bool BooleanGetPrimitiveValueSlow(JSContext *, JSObject &, Value *); + inline bool BooleanGetPrimitiveValue(JSContext *cx, JSObject &obj, Value *vp) { @@ -21,7 +23,6 @@ BooleanGetPrimitiveValue(JSContext *cx, JSObject &obj, Value *vp) return true; } - extern bool BooleanGetPrimitiveValueSlow(JSContext *, JSObject &, Value *); return BooleanGetPrimitiveValueSlow(cx, obj, vp); } diff --git a/js/src/jsclone.cpp b/js/src/jsclone.cpp index ccfcfe7bbb8c..2d94b293b377 100644 --- a/js/src/jsclone.cpp +++ b/js/src/jsclone.cpp @@ -120,12 +120,10 @@ SwapBytes(uint64_t u) #endif } -namespace js { - bool -WriteStructuredClone(JSContext *cx, const Value &v, uint64_t **bufp, size_t *nbytesp, - const JSStructuredCloneCallbacks *cb, void *cbClosure, - jsval transferable) +js::WriteStructuredClone(JSContext *cx, const Value &v, uint64_t **bufp, size_t *nbytesp, + const JSStructuredCloneCallbacks *cb, void *cbClosure, + jsval transferable) { SCOutput out(cx); JSStructuredCloneWriter w(out, cb, cbClosure, transferable); @@ -133,8 +131,8 @@ WriteStructuredClone(JSContext *cx, const Value &v, uint64_t **bufp, size_t *nby } bool -ReadStructuredClone(JSContext *cx, uint64_t *data, size_t nbytes, Value *vp, - const JSStructuredCloneCallbacks *cb, void *cbClosure) +js::ReadStructuredClone(JSContext *cx, uint64_t *data, size_t nbytes, Value *vp, + const JSStructuredCloneCallbacks *cb, void *cbClosure) { SCInput in(cx, data, nbytes); @@ -146,7 +144,7 @@ ReadStructuredClone(JSContext *cx, uint64_t *data, size_t nbytes, Value *vp, } bool -ClearStructuredClone(const uint64_t *data, size_t nbytes) +js::ClearStructuredClone(const uint64_t *data, size_t nbytes) { const uint64_t *point = data; const uint64_t *end = data + nbytes / 8; @@ -171,8 +169,7 @@ ClearStructuredClone(const uint64_t *data, size_t nbytes) } bool -StructuredCloneHasTransferObjects(const uint64_t *data, size_t nbytes, - bool *hasTransferable) +js::StructuredCloneHasTransferObjects(const uint64_t *data, size_t nbytes, bool *hasTransferable) { *hasTransferable = false; @@ -187,8 +184,6 @@ StructuredCloneHasTransferObjects(const uint64_t *data, size_t nbytes, return true; } -} /* namespace js */ - static inline uint64_t PairToUInt64(uint32_t tag, uint32_t data) { diff --git a/js/src/jscntxt.cpp b/js/src/jscntxt.cpp index 92f2446e14f7..daba5f0d589c 100644 --- a/js/src/jscntxt.cpp +++ b/js/src/jscntxt.cpp @@ -541,8 +541,6 @@ js::DestroyContext(JSContext *cx, DestroyContextMode mode) js_delete(cx); } -namespace js { - bool AutoResolving::alreadyStartedSlow() const { @@ -556,8 +554,6 @@ AutoResolving::alreadyStartedSlow() const return false; } -} /* namespace js */ - static void ReportError(JSContext *cx, const char *message, JSErrorReport *reportp, JSErrorCallback callback, void *userRef) @@ -754,11 +750,9 @@ js_ReportErrorVA(JSContext *cx, unsigned flags, const char *format, va_list ap) return warning; } -namespace js { - /* |callee| requires a usage string provided by JS_DefineFunctionsWithHelp. */ void -ReportUsageError(JSContext *cx, HandleObject callee, const char *msg) +js::ReportUsageError(JSContext *cx, HandleObject callee, const char *msg) { const char *usageStr = "usage"; PropertyName *usageAtom = Atomize(cx, usageStr, strlen(usageStr))->asPropertyName(); @@ -784,8 +778,8 @@ ReportUsageError(JSContext *cx, HandleObject callee, const char *msg) } bool -PrintError(JSContext *cx, FILE *file, const char *message, JSErrorReport *report, - bool reportWarnings) +js::PrintError(JSContext *cx, FILE *file, const char *message, JSErrorReport *report, + bool reportWarnings) { if (!report) { fprintf(file, "%s\n", message); @@ -855,8 +849,6 @@ PrintError(JSContext *cx, FILE *file, const char *message, JSErrorReport *report return true; } -} /* namespace js */ - /* * The arguments from ap need to be packaged up into an array and stored * into the report struct. @@ -1610,8 +1602,6 @@ JSContext::mark(JSTracer *trc) MarkValueRoot(trc, &iterValue, "iterValue"); } -namespace JS { - #if defined JS_THREADSAFE && defined DEBUG AutoCheckRequestDepth::AutoCheckRequestDepth(JSContext *cx) @@ -1629,5 +1619,3 @@ AutoCheckRequestDepth::~AutoCheckRequestDepth() } #endif - -} // namespace JS diff --git a/js/src/jscntxtinlines.h b/js/src/jscntxtinlines.h index 5184abe78390..437fe49a393e 100644 --- a/js/src/jscntxtinlines.h +++ b/js/src/jscntxtinlines.h @@ -385,8 +385,6 @@ CallNativeImpl(JSContext *cx, NativeImpl impl, const CallArgs &args) return ok; } -extern JSBool CallOrConstructBoundFunction(JSContext *, unsigned, js::Value *); - STATIC_PRECONDITION(ubound(args.argv_) >= argc) JS_ALWAYS_INLINE bool CallJSNativeConstructor(JSContext *cx, Native native, const CallArgs &args) diff --git a/js/src/jscrashreport.cpp b/js/src/jscrashreport.cpp index 0414af6d50d7..6cb415aeb716 100644 --- a/js/src/jscrashreport.cpp +++ b/js/src/jscrashreport.cpp @@ -12,8 +12,8 @@ #include -namespace js { -namespace crash { +using namespace js; +using namespace js::crash; const static int stack_snapshot_max_size = 32768; @@ -139,6 +139,9 @@ GetStack(uint64_t *stack, uint64_t *stack_len, CrashRegisters *regs, char *buffe #endif +namespace js { +namespace crash { + class Stack : private CrashStack { public: @@ -206,6 +209,9 @@ Ring::copyBytes(void *data, size_t size) } } +} /* namespace crash */ +} /* namespace js */ + static bool gInitialized; static Stack gGCStack(JS_CRASH_STACK_GC); @@ -213,32 +219,26 @@ static Stack gErrorStack(JS_CRASH_STACK_ERROR); static Ring gRingBuffer(JS_CRASH_RING); void -SnapshotGCStack() +js::crash::SnapshotGCStack() { if (gInitialized) gGCStack.snapshot(); } void -SnapshotErrorStack() +js::crash::SnapshotErrorStack() { if (gInitialized) gErrorStack.snapshot(); } void -SaveCrashData(uint64_t tag, void *ptr, size_t size) +js::crash::SaveCrashData(uint64_t tag, void *ptr, size_t size) { if (gInitialized) gRingBuffer.push(tag, ptr, size); } -} /* namespace crash */ -} /* namespace js */ - -using namespace js; -using namespace js::crash; - JS_PUBLIC_API(void) JS_EnumerateDiagnosticMemoryRegions(JSEnumerateDiagnosticMemoryCallback callback) { diff --git a/js/src/jsdbgapi.cpp b/js/src/jsdbgapi.cpp index c8e5c638dde7..0b588ce7e92b 100644 --- a/js/src/jsdbgapi.cpp +++ b/js/src/jsdbgapi.cpp @@ -70,10 +70,8 @@ JS_SetRuntimeDebugMode(JSRuntime *rt, JSBool debug) rt->debugMode = !!debug; } -namespace js { - JSTrapStatus -ScriptDebugPrologue(JSContext *cx, StackFrame *fp) +js::ScriptDebugPrologue(JSContext *cx, StackFrame *fp) { JS_ASSERT(fp == cx->fp()); @@ -106,7 +104,7 @@ ScriptDebugPrologue(JSContext *cx, StackFrame *fp) } bool -ScriptDebugEpilogue(JSContext *cx, StackFrame *fp, bool okArg) +js::ScriptDebugEpilogue(JSContext *cx, StackFrame *fp, bool okArg) { JS_ASSERT(fp == cx->fp()); JSBool ok = okArg; @@ -124,8 +122,6 @@ ScriptDebugEpilogue(JSContext *cx, StackFrame *fp, bool okArg) return Debugger::onLeaveFrame(cx, ok); } -} /* namespace js */ - JS_FRIEND_API(JSBool) JS_SetDebugModeForAllCompartments(JSContext *cx, JSBool debug) { diff --git a/js/src/jsexn.cpp b/js/src/jsexn.cpp index f2b00722ae4f..07224e520f19 100644 --- a/js/src/jsexn.cpp +++ b/js/src/jsexn.cpp @@ -875,10 +875,8 @@ js_GetLocalizedErrorMessage(JSContext* cx, void *userRef, const char *locale, return errorString; } -namespace js { - JS_FRIEND_API(const jschar*) -GetErrorTypeName(JSContext* cx, int16_t exnType) +js::GetErrorTypeName(JSContext* cx, int16_t exnType) { /* * JSEXN_INTERNALERR returns null to prevent that "InternalError: " @@ -893,8 +891,6 @@ GetErrorTypeName(JSContext* cx, int16_t exnType) return ClassName(key, cx)->chars(); } -} /* namespace js */ - #if defined ( DEBUG_mccabe ) && defined ( PRINTNAMES ) /* For use below... get character strings for error name and exception name */ static struct exnname { char *name; char *exception; } errortoexnname[] = { diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index e6e3018220d1..8be51dfae81f 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -502,6 +502,7 @@ js::SetPreserveWrapperCallback(JSRuntime *rt, PreserveWrapperCallback callback) * sufficient data has been harvested. */ +// Defined in jsxml.cpp. extern size_t sE4XObjectsCreated; JS_FRIEND_API(size_t) @@ -511,6 +512,7 @@ JS_GetE4XObjectsCreated(JSContext *) } namespace js { +// Defined in vm/GlobalObject.cpp. extern size_t sSetProtoCalled; } @@ -520,6 +522,7 @@ JS_SetProtoCalled(JSContext *) return sSetProtoCalled; } +// Defined in jsiter.cpp. extern size_t sCustomIteratorCount; JS_FRIEND_API(size_t) @@ -717,29 +720,27 @@ js::DumpHeapComplete(JSRuntime *rt, FILE *fp) fflush(dtrc.output); } -namespace js { - JS_FRIEND_API(const JSStructuredCloneCallbacks *) -GetContextStructuredCloneCallbacks(JSContext *cx) +js::GetContextStructuredCloneCallbacks(JSContext *cx) { return cx->runtime->structuredCloneCallbacks; } JS_FRIEND_API(JSVersion) -VersionSetMoarXML(JSVersion version, bool enable) +js::VersionSetMoarXML(JSVersion version, bool enable) { return enable ? JSVersion(uint32_t(version) | VersionFlags::MOAR_XML) : JSVersion(uint32_t(version) & ~VersionFlags::MOAR_XML); } JS_FRIEND_API(bool) -CanCallContextDebugHandler(JSContext *cx) +js::CanCallContextDebugHandler(JSContext *cx) { return !!cx->runtime->debugHooks.debuggerHandler; } JS_FRIEND_API(JSTrapStatus) -CallContextDebugHandler(JSContext *cx, JSScript *script, jsbytecode *bc, Value *rval) +js::CallContextDebugHandler(JSContext *cx, JSScript *script, jsbytecode *bc, Value *rval) { if (!cx->runtime->debugHooks.debuggerHandler) return JSTRAP_RETURN; @@ -750,51 +751,51 @@ CallContextDebugHandler(JSContext *cx, JSScript *script, jsbytecode *bc, Value * #ifdef JS_THREADSAFE void * -GetOwnerThread(const JSContext *cx) +js::GetOwnerThread(const JSContext *cx) { return cx->runtime->ownerThread(); } JS_FRIEND_API(bool) -ContextHasOutstandingRequests(const JSContext *cx) +js::ContextHasOutstandingRequests(const JSContext *cx) { return cx->outstandingRequests > 0; } #endif JS_FRIEND_API(JSCompartment *) -GetContextCompartment(const JSContext *cx) +js::GetContextCompartment(const JSContext *cx) { return cx->compartment; } JS_FRIEND_API(bool) -HasUnrootedGlobal(const JSContext *cx) +js::HasUnrootedGlobal(const JSContext *cx) { return cx->hasRunOption(JSOPTION_UNROOTED_GLOBAL); } JS_FRIEND_API(void) -SetActivityCallback(JSRuntime *rt, ActivityCallback cb, void *arg) +js::SetActivityCallback(JSRuntime *rt, ActivityCallback cb, void *arg) { rt->activityCallback = cb; rt->activityCallbackArg = arg; } JS_FRIEND_API(bool) -IsContextRunningJS(JSContext *cx) +js::IsContextRunningJS(JSContext *cx) { return !cx->stack.empty(); } JS_FRIEND_API(const CompartmentVector&) -GetRuntimeCompartments(JSRuntime *rt) +js::GetRuntimeCompartments(JSRuntime *rt) { return rt->compartments; } JS_FRIEND_API(GCSliceCallback) -SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback) +js::SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback) { GCSliceCallback old = rt->gcSliceCallback; rt->gcSliceCallback = callback; @@ -802,7 +803,7 @@ SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback) } JS_FRIEND_API(bool) -WasIncrementalGC(JSRuntime *rt) +js::WasIncrementalGC(JSRuntime *rt) { return rt->gcIsIncremental; } @@ -820,7 +821,7 @@ GCDescription::formatJSON(JSRuntime *rt, uint64_t timestamp) const } JS_FRIEND_API(AnalysisPurgeCallback) -SetAnalysisPurgeCallback(JSRuntime *rt, AnalysisPurgeCallback callback) +js::SetAnalysisPurgeCallback(JSRuntime *rt, AnalysisPurgeCallback callback) { AnalysisPurgeCallback old = rt->analysisPurgeCallback; rt->analysisPurgeCallback = callback; @@ -828,7 +829,7 @@ SetAnalysisPurgeCallback(JSRuntime *rt, AnalysisPurgeCallback callback) } JS_FRIEND_API(void) -NotifyDidPaint(JSRuntime *rt) +js::NotifyDidPaint(JSRuntime *rt) { if (rt->gcZeal() == gc::ZealFrameVerifierPreValue) { gc::VerifyBarriers(rt, gc::PreBarrierVerifier); @@ -854,50 +855,50 @@ NotifyDidPaint(JSRuntime *rt) rt->gcInterFrameGC = false; } -extern JS_FRIEND_API(bool) -IsIncrementalGCEnabled(JSRuntime *rt) +JS_FRIEND_API(bool) +js::IsIncrementalGCEnabled(JSRuntime *rt) { return rt->gcIncrementalEnabled && rt->gcMode == JSGC_MODE_INCREMENTAL; } JS_FRIEND_API(bool) -IsIncrementalGCInProgress(JSRuntime *rt) +js::IsIncrementalGCInProgress(JSRuntime *rt) { return (rt->gcIncrementalState != gc::NO_INCREMENTAL && !rt->gcVerifyPreData); } -extern JS_FRIEND_API(void) -DisableIncrementalGC(JSRuntime *rt) +JS_FRIEND_API(void) +js::DisableIncrementalGC(JSRuntime *rt) { rt->gcIncrementalEnabled = false; } JS_FRIEND_API(bool) -IsIncrementalBarrierNeeded(JSRuntime *rt) +js::IsIncrementalBarrierNeeded(JSRuntime *rt) { return (rt->gcIncrementalState == gc::MARK && !rt->isHeapBusy()); } JS_FRIEND_API(bool) -IsIncrementalBarrierNeeded(JSContext *cx) +js::IsIncrementalBarrierNeeded(JSContext *cx) { return IsIncrementalBarrierNeeded(cx->runtime); } JS_FRIEND_API(bool) -IsIncrementalBarrierNeededOnObject(RawObject obj) +js::IsIncrementalBarrierNeededOnObject(RawObject obj) { return obj->compartment()->needsBarrier(); } JS_FRIEND_API(bool) -IsIncrementalBarrierNeededOnScript(JSScript *script) +js::IsIncrementalBarrierNeededOnScript(JSScript *script) { return script->compartment()->needsBarrier(); } -extern JS_FRIEND_API(void) -IncrementalReferenceBarrier(void *ptr) +JS_FRIEND_API(void) +js::IncrementalReferenceBarrier(void *ptr) { if (!ptr) return; @@ -924,20 +925,20 @@ IncrementalReferenceBarrier(void *ptr) JS_NOT_REACHED("invalid trace kind"); } -extern JS_FRIEND_API(void) -IncrementalValueBarrier(const Value &v) +JS_FRIEND_API(void) +js::IncrementalValueBarrier(const Value &v) { HeapValue::writeBarrierPre(v); } -extern JS_FRIEND_API(void) -PokeGC(JSRuntime *rt) +JS_FRIEND_API(void) +js::PokeGC(JSRuntime *rt) { rt->gcPoke = true; } JS_FRIEND_API(JSObject *) -GetTestingFunctions(JSContext *cx) +js::GetTestingFunctions(JSContext *cx) { RootedObject obj(cx, JS_NewObject(cx, NULL, NULL, NULL)); if (!obj) @@ -950,32 +951,31 @@ GetTestingFunctions(JSContext *cx) } JS_FRIEND_API(void) -SetRuntimeProfilingStack(JSRuntime *rt, ProfileEntry *stack, uint32_t *size, - uint32_t max) +js::SetRuntimeProfilingStack(JSRuntime *rt, ProfileEntry *stack, uint32_t *size, uint32_t max) { rt->spsProfiler.setProfilingStack(stack, size, max); } JS_FRIEND_API(void) -EnableRuntimeProfilingStack(JSRuntime *rt, bool enabled) +js::EnableRuntimeProfilingStack(JSRuntime *rt, bool enabled) { rt->spsProfiler.enable(enabled); } JS_FRIEND_API(jsbytecode*) -ProfilingGetPC(JSRuntime *rt, JSScript *script, void *ip) +js::ProfilingGetPC(JSRuntime *rt, JSScript *script, void *ip) { return rt->spsProfiler.ipToPC(script, size_t(ip)); } JS_FRIEND_API(void) -SetDOMCallbacks(JSRuntime *rt, const DOMCallbacks *callbacks) +js::SetDOMCallbacks(JSRuntime *rt, const DOMCallbacks *callbacks) { rt->DOMcallbacks = callbacks; } JS_FRIEND_API(const DOMCallbacks *) -GetDOMCallbacks(JSRuntime *rt) +js::GetDOMCallbacks(JSRuntime *rt) { return rt->DOMcallbacks; } @@ -984,22 +984,20 @@ static void *gListBaseHandlerFamily = NULL; static uint32_t gListBaseExpandoSlot = 0; JS_FRIEND_API(void) -SetListBaseInformation(void *listBaseHandlerFamily, uint32_t listBaseExpandoSlot) +js::SetListBaseInformation(void *listBaseHandlerFamily, uint32_t listBaseExpandoSlot) { gListBaseHandlerFamily = listBaseHandlerFamily; gListBaseExpandoSlot = listBaseExpandoSlot; } void * -GetListBaseHandlerFamily() +js::GetListBaseHandlerFamily() { return gListBaseHandlerFamily; } uint32_t -GetListBaseExpandoSlot() +js::GetListBaseExpandoSlot() { return gListBaseExpandoSlot; } - -} // namespace js diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index e0983606c61b..5e3d379bc90c 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -966,13 +966,6 @@ js_fun_apply(JSContext *cx, unsigned argc, Value *vp) return true; } -namespace js { - -JSBool -CallOrConstructBoundFunction(JSContext *cx, unsigned argc, Value *vp); - -} - static const uint32_t JSSLOT_BOUND_FUNCTION_THIS = 0; static const uint32_t JSSLOT_BOUND_FUNCTION_ARGS_COUNT = 1; @@ -1046,11 +1039,9 @@ JSFunction::getBoundFunctionArgumentCount() const return getSlot(JSSLOT_BOUND_FUNCTION_ARGS_COUNT).toPrivateUint32(); } -namespace js { - /* ES5 15.3.4.5.1 and 15.3.4.5.2. */ JSBool -CallOrConstructBoundFunction(JSContext *cx, unsigned argc, Value *vp) +js::CallOrConstructBoundFunction(JSContext *cx, unsigned argc, Value *vp) { JSFunction *fun = vp[0].toObject().toFunction(); JS_ASSERT(fun->isBoundFunction()); @@ -1093,8 +1084,6 @@ CallOrConstructBoundFunction(JSContext *cx, unsigned argc, Value *vp) return true; } -} - #if JS_HAS_GENERATORS static JSBool fun_isGenerator(JSContext *cx, unsigned argc, Value *vp) @@ -1200,9 +1189,7 @@ OnBadFormal(JSContext *cx, TokenKind tt) return false; } -namespace js { - -JSFunctionSpec function_methods[] = { +JSFunctionSpec js::function_methods[] = { #if JS_HAS_TOSOURCE JS_FN(js_toSource_str, fun_toSource, 0,0), #endif @@ -1217,7 +1204,7 @@ JSFunctionSpec function_methods[] = { }; JSBool -Function(JSContext *cx, unsigned argc, Value *vp) +js::Function(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedString arg(cx); // used multiple times below @@ -1412,16 +1399,15 @@ Function(JSContext *cx, unsigned argc, Value *vp) } bool -IsBuiltinFunctionConstructor(JSFunction *fun) +js::IsBuiltinFunctionConstructor(JSFunction *fun) { return fun->maybeNative() == Function; } -} /* namespace js */ - JSFunction * js_NewFunction(JSContext *cx, HandleObject funobjArg, Native native, unsigned nargs, - JSFunction::Flags flags, HandleObject parent, HandleAtom atom, js::gc::AllocKind kind) + JSFunction::Flags flags, HandleObject parent, HandleAtom atom, + js::gc::AllocKind kind) { JS_ASSERT(kind == JSFunction::FinalizeKind || kind == JSFunction::ExtendedFinalizeKind); JS_ASSERT(sizeof(JSFunction) <= gc::Arena::thingSize(JSFunction::FinalizeKind)); diff --git a/js/src/jsfun.h b/js/src/jsfun.h index 033f8ab1916a..6e9614a73d8b 100644 --- a/js/src/jsfun.h +++ b/js/src/jsfun.h @@ -349,6 +349,11 @@ ReportIncompatibleMethod(JSContext *cx, CallReceiver call, Class *clasp); extern void ReportIncompatible(JSContext *cx, CallReceiver call); +JSBool +CallOrConstructBoundFunction(JSContext *, unsigned, js::Value *); + +extern JSFunctionSpec function_methods[]; + } /* namespace js */ extern JSBool diff --git a/js/src/jsfuninlines.h b/js/src/jsfuninlines.h index 1910c0d899a6..1b0230eadc4d 100644 --- a/js/src/jsfuninlines.h +++ b/js/src/jsfuninlines.h @@ -206,8 +206,6 @@ GetFunctionNameBytes(JSContext *cx, JSFunction *fun, JSAutoByteString *bytes) return js_anonymous_str; } -extern JSFunctionSpec function_methods[]; - extern JSBool Function(JSContext *cx, unsigned argc, Value *vp); diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 18fa641cd78b..ea61a5eee754 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -85,6 +85,7 @@ #include "ion/IonFrameIterator.h" #endif +#include "jsgcinlines.h" #include "jsinterpinlines.h" #include "jsobjinlines.h" @@ -115,15 +116,11 @@ using mozilla::ArrayEnd; using mozilla::DebugOnly; using mozilla::Maybe; -namespace js { - -namespace gc { - /* Perform a Full GC every 20 seconds if MaybeGC is called */ static const uint64_t GC_IDLE_FULL_SPAN = 20 * 1000 * 1000; /* Increase the IGC marking slice time if we are in highFrequencyGC mode. */ -const int IGC_MARK_SLICE_MULTIPLIER = 2; +static const int IGC_MARK_SLICE_MULTIPLIER = 2; #ifdef JS_GC_ZEAL static void @@ -138,12 +135,12 @@ StartVerifyPostBarriers(JSRuntime *rt); static void EndVerifyPostBarriers(JSRuntime *rt); -void +static void FinishVerifier(JSRuntime *rt); #endif /* This array should be const, but that doesn't link right under GCC. */ -AllocKind slotsToThingKind[] = { +AllocKind gc::slotsToThingKind[] = { /* 0 */ FINALIZE_OBJECT0, FINALIZE_OBJECT2, FINALIZE_OBJECT2, FINALIZE_OBJECT4, /* 4 */ FINALIZE_OBJECT4, FINALIZE_OBJECT8, FINALIZE_OBJECT8, FINALIZE_OBJECT8, /* 8 */ FINALIZE_OBJECT8, FINALIZE_OBJECT12, FINALIZE_OBJECT12, FINALIZE_OBJECT12, @@ -417,7 +414,7 @@ void ArenaList::insert(ArenaHeader *a) } template -inline bool +static inline bool FinalizeTypedArenas(FreeOp *fop, ArenaHeader **src, ArenaList &dest, @@ -694,7 +691,7 @@ Chunk::init() /* The rest of info fields are initialized in PickChunk. */ } -inline Chunk ** +static inline Chunk ** GetAvailableChunkList(JSCompartment *comp) { JSRuntime *rt = comp->rt; @@ -864,9 +861,6 @@ Chunk::releaseArena(ArenaHeader *aheader) } } -} /* namespace gc */ -} /* namespace js */ - /* The caller must hold the GC lock. */ static Chunk * PickChunk(JSCompartment *comp) @@ -937,9 +931,7 @@ js_InitGC(JSRuntime *rt, uint32_t maxbytes) return true; } -namespace js { - -inline bool +static inline bool InFreeList(ArenaHeader *aheader, uintptr_t addr) { if (!aheader->hasFreeThings()) @@ -1030,7 +1022,7 @@ enum ConservativeGCTest * Tests whether w is a (possibly dead) GC thing. Returns CGCT_VALID and * details about the thing if so. On failure, returns the reason for rejection. */ -inline ConservativeGCTest +static inline ConservativeGCTest IsAddressableGCThing(JSRuntime *rt, uintptr_t w, bool skipUncollectedCompartments, gc::AllocKind *thingKindPtr, @@ -1108,7 +1100,7 @@ IsAddressableGCThing(JSRuntime *rt, uintptr_t w, * Returns CGCT_VALID and mark it if the w can be a live GC thing and sets * thingKind accordingly. Otherwise returns the reason for rejection. */ -inline ConservativeGCTest +static inline ConservativeGCTest MarkIfGCThingWord(JSTracer *trc, uintptr_t w) { void *thing; @@ -1244,7 +1236,7 @@ MarkConservativeStackRoots(JSTracer *trc, bool useSavedRoots) #endif /* JSGC_USE_EXACT_ROOTING */ void -MarkStackRangeConservatively(JSTracer *trc, Value *beginv, Value *endv) +js::MarkStackRangeConservatively(JSTracer *trc, Value *beginv, Value *endv) { const uintptr_t *begin = beginv->payloadUIntPtr(); const uintptr_t *end = endv->payloadUIntPtr(); @@ -1295,8 +1287,6 @@ RecordNativeStackTopForGC(JSRuntime *rt) cgcd->recordStackTop(); } -} /* namespace js */ - void js_FinishGC(JSRuntime *rt) { @@ -1450,9 +1440,6 @@ JSCompartment::reduceGCTriggerBytes(size_t amount) gcTriggerBytes -= amount; } -namespace js { -namespace gc { - inline void ArenaLists::prepareForIncrementalGC(JSRuntime *rt) { @@ -1809,9 +1796,6 @@ ArenaLists::refillFreeList(JSContext *cx, AllocKind thingKind) return NULL; } -} /* namespace gc */ -} /* namespace js */ - JSGCTraceKind js_GetGCThingTraceKind(void *thing) { @@ -1854,10 +1838,8 @@ js_UnlockGCThingRT(JSRuntime *rt, void *thing) } } -namespace js { - void -InitTracer(JSTracer *trc, JSRuntime *rt, JSTraceCallback callback) +js::InitTracer(JSTracer *trc, JSRuntime *rt, JSTraceCallback callback) { trc->runtime = rt; trc->callback = callback; @@ -2178,24 +2160,18 @@ GCMarker::sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const } void -SetMarkStackLimit(JSRuntime *rt, size_t limit) +js::SetMarkStackLimit(JSRuntime *rt, size_t limit) { JS_ASSERT(!rt->isHeapBusy()); rt->gcMarker.setSizeLimit(limit); } -} /* namespace js */ - -namespace js { - void -MarkCompartmentActive(StackFrame *fp) +js::MarkCompartmentActive(StackFrame *fp) { fp->script()->compartment()->active = true; } -} /* namespace js */ - void AutoIdArray::trace(JSTracer *trc) { @@ -2477,8 +2453,6 @@ HashableValue::AutoRooter::trace(JSTracer *trc) MarkValueRoot(trc, reinterpret_cast(&v->value), "HashableValue::AutoRooter"); } -namespace js { - static void MarkRuntime(JSTracer *trc, bool useSavedRoots = false) { @@ -2615,7 +2589,7 @@ TriggerOperationCallback(JSRuntime *rt, gcreason::Reason reason) } void -TriggerGC(JSRuntime *rt, gcreason::Reason reason) +js::TriggerGC(JSRuntime *rt, gcreason::Reason reason) { rt->assertValidThread(); @@ -2627,7 +2601,7 @@ TriggerGC(JSRuntime *rt, gcreason::Reason reason) } void -TriggerCompartmentGC(JSCompartment *comp, gcreason::Reason reason) +js::TriggerCompartmentGC(JSCompartment *comp, gcreason::Reason reason) { JSRuntime *rt = comp->rt; rt->assertValidThread(); @@ -2651,7 +2625,7 @@ TriggerCompartmentGC(JSCompartment *comp, gcreason::Reason reason) } void -MaybeGC(JSContext *cx) +js::MaybeGC(JSContext *cx) { JSRuntime *rt = cx->runtime; rt->assertValidThread(); @@ -2874,7 +2848,7 @@ AssertBackgroundSweepingFinished(JSRuntime *rt) } unsigned -GetCPUCount() +js::GetCPUCount() { static unsigned ncpus = 0; if (ncpus == 0) { @@ -3167,8 +3141,6 @@ GCHelperThread::doSweep() } #endif /* JS_THREADSAFE */ -} /* namespace js */ - static bool ReleaseObservedTypes(JSRuntime *rt) { @@ -4714,17 +4686,15 @@ Collect(JSRuntime *rt, bool incremental, int64_t budget, } while (rt->gcPoke && rt->gcShouldCleanUpEverything); } -namespace js { - void -GC(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason) +js::GC(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason) { AssertCanGC(); Collect(rt, false, SliceBudget::Unlimited, gckind, reason); } void -GCSlice(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason, int64_t millis) +js::GCSlice(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason, int64_t millis) { AssertCanGC(); int64_t sliceBudget; @@ -4739,14 +4709,14 @@ GCSlice(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason, int64 } void -GCFinalSlice(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason) +js::GCFinalSlice(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason) { AssertCanGC(); Collect(rt, true, SliceBudget::Unlimited, gckind, reason); } void -GCDebugSlice(JSRuntime *rt, bool limit, int64_t objCount) +js::GCDebugSlice(JSRuntime *rt, bool limit, int64_t objCount) { AssertCanGC(); int64_t budget = limit ? SliceBudget::WorkBudget(objCount) : SliceBudget::Unlimited; @@ -4756,7 +4726,7 @@ GCDebugSlice(JSRuntime *rt, bool limit, int64_t objCount) /* Schedule a full GC unless a compartment will already be collected. */ void -PrepareForDebugGC(JSRuntime *rt) +js::PrepareForDebugGC(JSRuntime *rt) { for (CompartmentsIter c(rt); !c.done(); c.next()) { if (c->isGCScheduled()) @@ -4767,7 +4737,7 @@ PrepareForDebugGC(JSRuntime *rt) } void -ShrinkGCBuffers(JSRuntime *rt) +js::ShrinkGCBuffers(JSRuntime *rt) { AutoLockGC lock(rt); JS_ASSERT(!rt->isHeapBusy()); @@ -4804,7 +4774,7 @@ struct AutoPrepareForTracing }; void -TraceRuntime(JSTracer *trc) +js::TraceRuntime(JSTracer *trc) { JS_ASSERT(!IS_GC_MARKING_TRACER(trc)); @@ -4842,10 +4812,10 @@ struct IterateCellCallbackOp }; void -IterateCompartmentsArenasCells(JSRuntime *rt, void *data, - JSIterateCompartmentCallback compartmentCallback, - IterateArenaCallback arenaCallback, - IterateCellCallback cellCallback) +js::IterateCompartmentsArenasCells(JSRuntime *rt, void *data, + JSIterateCompartmentCallback compartmentCallback, + IterateArenaCallback arenaCallback, + IterateCellCallback cellCallback) { AutoPrepareForTracing prop(rt); @@ -4863,7 +4833,7 @@ IterateCompartmentsArenasCells(JSRuntime *rt, void *data, } void -IterateChunks(JSRuntime *rt, void *data, IterateChunkCallback chunkCallback) +js::IterateChunks(JSRuntime *rt, void *data, IterateChunkCallback chunkCallback) { AutoPrepareForTracing prep(rt); @@ -4872,8 +4842,8 @@ IterateChunks(JSRuntime *rt, void *data, IterateChunkCallback chunkCallback) } void -IterateCells(JSRuntime *rt, JSCompartment *compartment, AllocKind thingKind, - void *data, IterateCellCallback cellCallback) +js::IterateCells(JSRuntime *rt, JSCompartment *compartment, AllocKind thingKind, + void *data, IterateCellCallback cellCallback) { AutoPrepareForTracing prep(rt); @@ -4892,7 +4862,7 @@ IterateCells(JSRuntime *rt, JSCompartment *compartment, AllocKind thingKind, } void -IterateGrayObjects(JSCompartment *compartment, GCThingCallback *cellCallback, void *data) +js::IterateGrayObjects(JSCompartment *compartment, GCThingCallback *cellCallback, void *data) { JS_ASSERT(compartment); AutoPrepareForTracing prep(compartment->rt); @@ -4906,10 +4876,8 @@ IterateGrayObjects(JSCompartment *compartment, GCThingCallback *cellCallback, vo } } -namespace gc { - JSCompartment * -NewCompartment(JSContext *cx, JSPrincipals *principals) +gc::NewCompartment(JSContext *cx, JSPrincipals *principals) { JSRuntime *rt = cx->runtime; JS_AbortIfWrongThread(rt); @@ -4939,7 +4907,7 @@ NewCompartment(JSContext *cx, JSPrincipals *principals) } void -RunDebugGC(JSContext *cx) +gc::RunDebugGC(JSContext *cx) { #ifdef JS_GC_ZEAL JSRuntime *rt = cx->runtime; @@ -4990,7 +4958,7 @@ RunDebugGC(JSContext *cx) } void -SetDeterministicGC(JSContext *cx, bool enabled) +gc::SetDeterministicGC(JSContext *cx, bool enabled) { #ifdef JS_GC_ZEAL JSRuntime *rt = cx->runtime; @@ -4999,15 +4967,12 @@ SetDeterministicGC(JSContext *cx, bool enabled) } void -SetValidateGC(JSContext *cx, bool enabled) +gc::SetValidateGC(JSContext *cx, bool enabled) { JSRuntime *rt = cx->runtime; rt->gcValidate = enabled; } -} /* namespace gc */ -} /* namespace js */ - #if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE) JS_ALWAYS_INLINE bool @@ -5197,9 +5162,6 @@ JS::CheckStackRoots(JSContext *cx) #endif /* DEBUG && JS_GC_ZEAL && JSGC_ROOT_ANALYSIS && !JS_THREADSAFE */ -namespace js { -namespace gc { - #ifdef JS_GC_ZEAL /* @@ -5324,8 +5286,7 @@ MakeNode(VerifyPreTracer *trc, void *thing, JSGCTraceKind kind) return NULL; } -static -VerifyNode * +static VerifyNode * NextNode(VerifyNode *node) { if (node->count == 0) @@ -5700,7 +5661,7 @@ VerifyPostBarriers(JSRuntime *rt) } void -VerifyBarriers(JSRuntime *rt, VerifierType type) +gc::VerifyBarriers(JSRuntime *rt, VerifierType type) { if (type == PreBarrierVerifier) VerifyPreBarriers(rt); @@ -5739,7 +5700,7 @@ MaybeVerifyPostBarriers(JSRuntime *rt, bool always) } void -MaybeVerifyBarriers(JSContext *cx, bool always) +gc::MaybeVerifyBarriers(JSContext *cx, bool always) { MaybeVerifyPreBarriers(cx->runtime, always); MaybeVerifyPostBarriers(cx->runtime, always); @@ -5766,9 +5727,8 @@ FinishVerifier(JSRuntime *rt) #endif /* JS_GC_ZEAL */ -} /* namespace gc */ - -void ReleaseAllJITCode(FreeOp *fop) +void +js::ReleaseAllJITCode(FreeOp *fop) { #ifdef JS_METHODJIT for (CompartmentsIter c(fop->runtime()); !c.done(); c.next()) { @@ -5828,7 +5788,7 @@ ReleaseScriptCounts(FreeOp *fop) } JS_FRIEND_API(void) -StartPCCountProfiling(JSContext *cx) +js::StartPCCountProfiling(JSContext *cx) { JSRuntime *rt = cx->runtime; @@ -5844,7 +5804,7 @@ StartPCCountProfiling(JSContext *cx) } JS_FRIEND_API(void) -StopPCCountProfiling(JSContext *cx) +js::StopPCCountProfiling(JSContext *cx) { JSRuntime *rt = cx->runtime; @@ -5876,7 +5836,7 @@ StopPCCountProfiling(JSContext *cx) } JS_FRIEND_API(void) -PurgePCCounts(JSContext *cx) +js::PurgePCCounts(JSContext *cx) { JSRuntime *rt = cx->runtime; @@ -5888,7 +5848,7 @@ PurgePCCounts(JSContext *cx) } void -PurgeJITCaches(JSCompartment *c) +js::PurgeJITCaches(JSCompartment *c) { #ifdef JS_METHODJIT mjit::ClearAllFrames(c); @@ -5937,8 +5897,6 @@ AutoMaybeTouchDeadCompartments::~AutoMaybeTouchDeadCompartments() runtime->gcManipulatingDeadCompartments = manipulatingDeadCompartments; } -} /* namespace js */ - JS_PUBLIC_API(void) JS_IterateCompartments(JSRuntime *rt, void *data, JSIterateCompartmentCallback compartmentCallback) diff --git a/js/src/jsgc.h b/js/src/jsgc.h index 1c6d2cc65de1..59b9edca309b 100644 --- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -545,10 +545,6 @@ GCDebugSlice(JSRuntime *rt, bool limit, int64_t objCount); extern void PrepareForDebugGC(JSRuntime *rt); -} /* namespace js */ - -namespace js { - void InitTracer(JSTracer *trc, JSRuntime *rt, JSTraceCallback callback); diff --git a/js/src/jsgcinlines.h b/js/src/jsgcinlines.h index 4127756cc050..8c6e66ce691a 100644 --- a/js/src/jsgcinlines.h +++ b/js/src/jsgcinlines.h @@ -64,12 +64,12 @@ GetGCThingTraceKind(const void *thing) /* Capacity for slotsToThingKind */ const size_t SLOTS_TO_THING_KIND_LIMIT = 17; +extern AllocKind slotsToThingKind[]; + /* Get the best kind to use when making an object with the given slot count. */ static inline AllocKind GetGCObjectKind(size_t numSlots) { - extern AllocKind slotsToThingKind[]; - AutoAssertNoGC nogc; if (numSlots >= SLOTS_TO_THING_KIND_LIMIT) return FINALIZE_OBJECT16; diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index 125b9aa65262..63c030be2cbc 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -5133,11 +5133,8 @@ ScriptAnalysis::printTypes(JSContext *cx) // Interface functions ///////////////////////////////////////////////////////////////////// -namespace js { -namespace types { - void -MarkIteratorUnknownSlow(JSContext *cx) +types::MarkIteratorUnknownSlow(JSContext *cx) { /* Check whether we are actually at an ITER opcode. */ @@ -5197,7 +5194,8 @@ MarkIteratorUnknownSlow(JSContext *cx) } void -TypeMonitorCallSlow(JSContext *cx, HandleObject callee, const CallArgs &args, bool constructing) +types::TypeMonitorCallSlow(JSContext *cx, HandleObject callee, const CallArgs &args, + bool constructing) { unsigned nargs = callee->toFunction()->nargs; RootedScript script(cx, callee->toFunction()->script()); @@ -5230,7 +5228,7 @@ IsAboutToBeFinalized(TypeObjectKey *key) } void -TypeDynamicResult(JSContext *cx, HandleScript script, jsbytecode *pc, Type type) +types::TypeDynamicResult(JSContext *cx, HandleScript script, jsbytecode *pc, Type type) { JS_ASSERT(cx->typeInferenceEnabled()); AutoEnterTypeInference enter(cx); @@ -5332,7 +5330,7 @@ TypeDynamicResult(JSContext *cx, HandleScript script, jsbytecode *pc, Type type) } void -TypeMonitorResult(JSContext *cx, HandleScript script, jsbytecode *pc, const js::Value &rval) +types::TypeMonitorResult(JSContext *cx, HandleScript script, jsbytecode *pc, const js::Value &rval) { /* Allow the non-TYPESET scenario to simplify stubs used in compound opcodes. */ if (!(js_CodeSpec[*pc].format & JOF_TYPESET)) @@ -5355,8 +5353,6 @@ TypeMonitorResult(JSContext *cx, HandleScript script, jsbytecode *pc, const js:: types->addType(cx, type); } -} } /* namespace js::types */ - ///////////////////////////////////////////////////////////////////// // TypeScript ///////////////////////////////////////////////////////////////////// diff --git a/js/src/jsinferinlines.h b/js/src/jsinferinlines.h index b28454fb6e94..fa875412575b 100644 --- a/js/src/jsinferinlines.h +++ b/js/src/jsinferinlines.h @@ -505,6 +505,8 @@ GetTypeCallerInitObject(JSContext *cx, JSProtoKey key) return GetTypeNewObject(cx, key); } +void MarkIteratorUnknownSlow(JSContext *cx); + /* * When using a custom iterator within the initialization of a 'for in' loop, * mark the iterator values as unknown. @@ -512,12 +514,13 @@ GetTypeCallerInitObject(JSContext *cx, JSProtoKey key) inline void MarkIteratorUnknown(JSContext *cx) { - extern void MarkIteratorUnknownSlow(JSContext *cx); - if (cx->typeInferenceEnabled()) MarkIteratorUnknownSlow(cx); } +void TypeMonitorCallSlow(JSContext *cx, HandleObject callee, const CallArgs &args, + bool constructing); + /* * Monitor a javascript call, either on entry to the interpreter or made * from within the interpreter. @@ -525,9 +528,6 @@ MarkIteratorUnknown(JSContext *cx) inline bool TypeMonitorCall(JSContext *cx, const js::CallArgs &args, bool constructing) { - extern void TypeMonitorCallSlow(JSContext *cx, HandleObject callee, - const CallArgs &args, bool constructing); - js::RootedObject callee(cx, &args.callee()); if (callee->isFunction()) { JSFunction *fun = callee->toFunction(); diff --git a/js/src/jsiter.cpp b/js/src/jsiter.cpp index 930d83df635f..a3f16494e8b3 100644 --- a/js/src/jsiter.cpp +++ b/js/src/jsiter.cpp @@ -517,18 +517,16 @@ VectorToKeyIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVecto return true; } -namespace js { - bool -VectorToKeyIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVector &props, - MutableHandleValue vp) +js::VectorToKeyIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVector &props, + MutableHandleValue vp) { return VectorToKeyIterator(cx, obj, flags, props, 0, 0, vp); } bool -VectorToValueIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVector &keys, - MutableHandleValue vp) +js::VectorToValueIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVector &keys, + MutableHandleValue vp) { JS_ASSERT(flags & JSITER_FOREACH); @@ -555,8 +553,8 @@ VectorToValueIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVec } bool -EnumeratedIdVectorToIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVector &props, - MutableHandleValue vp) +js::EnumeratedIdVectorToIterator(JSContext *cx, HandleObject obj, unsigned flags, + AutoIdVector &props, MutableHandleValue vp) { if (!(flags & JSITER_FOREACH)) return VectorToKeyIterator(cx, obj, flags, props, vp); @@ -573,7 +571,7 @@ UpdateNativeIterator(NativeIterator *ni, RawObject obj) } bool -GetIterator(JSContext *cx, HandleObject obj, unsigned flags, MutableHandleValue vp) +js::GetIterator(JSContext *cx, HandleObject obj, unsigned flags, MutableHandleValue vp) { if (flags == JSITER_FOR_OF) { // for-of loop. The iterator is simply |obj.iterator()|. @@ -729,7 +727,7 @@ GetIterator(JSContext *cx, HandleObject obj, unsigned flags, MutableHandleValue } JSObject * -GetIteratorObject(JSContext *cx, HandleObject obj, uint32_t flags) +js::GetIteratorObject(JSContext *cx, HandleObject obj, uint32_t flags) { RootedValue value(cx); if (!GetIterator(cx, obj, flags, &value)) @@ -737,8 +735,6 @@ GetIteratorObject(JSContext *cx, HandleObject obj, uint32_t flags) return &value.toObject(); } -} /* namespace js */ - JSBool js_ThrowStopIteration(JSContext *cx) { diff --git a/js/src/jslock.h b/js/src/jslock.h index aa5e1c83e70e..025aaea0af82 100644 --- a/js/src/jslock.h +++ b/js/src/jslock.h @@ -22,6 +22,7 @@ # define JS_ATOMIC_SET(p,v) PR_ATOMIC_SET((int32_t *)(p), (int32_t)(v)) namespace js { + // Defined in jsgc.cpp. unsigned GetCPUCount(); } diff --git a/js/src/jsmemorymetrics.cpp b/js/src/jsmemorymetrics.cpp index 8325c3b2cee8..03cef2b2b2b5 100644 --- a/js/src/jsmemorymetrics.cpp +++ b/js/src/jsmemorymetrics.cpp @@ -22,21 +22,16 @@ #include "ion/IonCode.h" #include "ion/Ion.h" -namespace js { +using namespace js; -size_t MemoryReportingSundriesThreshold() +JS_FRIEND_API(size_t) +js::MemoryReportingSundriesThreshold() { return 8 * 1024; } -} // namespace js - #ifdef JS_THREADSAFE -namespace JS { - -using namespace js; - typedef HashSet, SystemAllocPolicy> SourceSet; struct IteratorClosure @@ -275,7 +270,7 @@ StatsCellCallback(JSRuntime *rt, void *data, void *thing, JSGCTraceKind traceKin } JS_PUBLIC_API(bool) -CollectRuntimeStats(JSRuntime *rt, RuntimeStats *rtStats, ObjectPrivateVisitor *opv) +JS::CollectRuntimeStats(JSRuntime *rt, RuntimeStats *rtStats, ObjectPrivateVisitor *opv) { if (!rtStats->compartmentStatsVector.reserve(rt->compartments.length())) return false; @@ -328,7 +323,7 @@ CollectRuntimeStats(JSRuntime *rt, RuntimeStats *rtStats, ObjectPrivateVisitor * } JS_PUBLIC_API(int64_t) -GetExplicitNonHeapForRuntime(JSRuntime *rt, JSMallocSizeOfFun mallocSizeOf) +JS::GetExplicitNonHeapForRuntime(JSRuntime *rt, JSMallocSizeOfFun mallocSizeOf) { // explicit//gc-heap/* size_t n = size_t(JS_GetGCParameter(rt, JSGC_TOTAL_CHUNKS)) * gc::ChunkSize; @@ -343,7 +338,7 @@ GetExplicitNonHeapForRuntime(JSRuntime *rt, JSMallocSizeOfFun mallocSizeOf) } JS_PUBLIC_API(size_t) -SystemCompartmentCount(const JSRuntime *rt) +JS::SystemCompartmentCount(const JSRuntime *rt) { size_t n = 0; for (size_t i = 0; i < rt->compartments.length(); i++) { @@ -354,7 +349,7 @@ SystemCompartmentCount(const JSRuntime *rt) } JS_PUBLIC_API(size_t) -UserCompartmentCount(const JSRuntime *rt) +JS::UserCompartmentCount(const JSRuntime *rt) { size_t n = 0; for (size_t i = 0; i < rt->compartments.length(); i++) { @@ -364,6 +359,4 @@ UserCompartmentCount(const JSRuntime *rt) return n; } -} // namespace JS - #endif // JS_THREADSAFE diff --git a/js/src/jsnativestack.cpp b/js/src/jsnativestack.cpp index b1240bd2dcd8..29cc77f4591e 100644 --- a/js/src/jsnativestack.cpp +++ b/js/src/jsnativestack.cpp @@ -28,12 +28,10 @@ #endif -namespace js { - #if defined(XP_WIN) void * -GetNativeStackBaseImpl() +js::GetNativeStackBaseImpl() { # if defined(_M_IX86) && defined(_MSC_VER) /* @@ -66,7 +64,7 @@ GetNativeStackBaseImpl() JS_STATIC_ASSERT(JS_STACK_GROWTH_DIRECTION < 0); void * -GetNativeStackBaseImpl() +js::GetNativeStackBaseImpl() { stack_t st; stack_getbounds(&st); @@ -80,7 +78,7 @@ GetNativeStackBaseImpl() JS_STATIC_ASSERT(JS_STACK_GROWTH_DIRECTION < 0); void * -GetNativeStackBaseImpl() +js::GetNativeStackBaseImpl() { ucontext_t context; getcontext(&context); @@ -91,7 +89,7 @@ GetNativeStackBaseImpl() #elif defined(XP_OS2) void * -GetNativeStackBaseImpl() +js::GetNativeStackBaseImpl() { PTIB ptib; PPIB ppib; @@ -103,7 +101,7 @@ GetNativeStackBaseImpl() #else /* XP_UNIX */ void * -GetNativeStackBaseImpl() +js::GetNativeStackBaseImpl() { pthread_t thread = pthread_self(); # if defined(XP_MACOSX) || defined(DARWIN) @@ -150,5 +148,3 @@ GetNativeStackBaseImpl() } #endif /* !XP_WIN */ - -} /* namespace js */ diff --git a/js/src/jsnum.cpp b/js/src/jsnum.cpp index 7ec1d43bf3ca..566423c8778b 100644 --- a/js/src/jsnum.cpp +++ b/js/src/jsnum.cpp @@ -180,11 +180,9 @@ ComputeAccurateBinaryBaseInteger(const jschar *start, const jschar *end, int bas return value; } -namespace js { - bool -GetPrefixInteger(JSContext *cx, const jschar *start, const jschar *end, int base, - const jschar **endp, double *dp) +js::GetPrefixInteger(JSContext *cx, const jschar *start, const jschar *end, int base, + const jschar **endp, double *dp) { JS_ASSERT(start <= end); JS_ASSERT(2 <= base && base <= 36); @@ -227,8 +225,6 @@ GetPrefixInteger(JSContext *cx, const jschar *start, const jschar *end, int base return true; } -} // namespace js - static JSBool num_isNaN(JSContext *cx, unsigned argc, Value *vp) { @@ -1037,10 +1033,8 @@ inline void FIX_FPU() { #endif -namespace js { - bool -InitRuntimeNumberState(JSRuntime *rt) +js::InitRuntimeNumberState(JSRuntime *rt) { FIX_FPU(); @@ -1111,7 +1105,7 @@ InitRuntimeNumberState(JSRuntime *rt) } void -FinishRuntimeNumberState(JSRuntime *rt) +js::FinishRuntimeNumberState(JSRuntime *rt) { /* * The free also releases the memory for decimalSeparator and numGrouping @@ -1121,8 +1115,6 @@ FinishRuntimeNumberState(JSRuntime *rt) js_free(storage); } -} /* namespace js */ - JSObject * js_InitNumberClass(JSContext *cx, HandleObject obj) { @@ -1179,8 +1171,6 @@ js_InitNumberClass(JSContext *cx, HandleObject obj) return numberProto; } -namespace js { - static char * FracNumberToCString(JSContext *cx, ToCStringBuf *cbuf, double d, int base = 10) { @@ -1212,7 +1202,7 @@ FracNumberToCString(JSContext *cx, ToCStringBuf *cbuf, double d, int base = 10) } char * -NumberToCString(JSContext *cx, ToCStringBuf *cbuf, double d, int base/* = 10*/) +js::NumberToCString(JSContext *cx, ToCStringBuf *cbuf, double d, int base/* = 10*/) { int32_t i; return MOZ_DOUBLE_IS_INT32(d, &i) @@ -1220,8 +1210,6 @@ NumberToCString(JSContext *cx, ToCStringBuf *cbuf, double d, int base/* = 10*/) : FracNumberToCString(cx, cbuf, d, base); } -} - static JSString * JS_FASTCALL js_NumberToStringWithBase(JSContext *cx, double d, int base) { @@ -1281,10 +1269,8 @@ js_NumberToString(JSContext *cx, double d) return js_NumberToStringWithBase(cx, d, 10); } -namespace js { - JSFlatString * -NumberToString(JSContext *cx, double d) +js::NumberToString(JSContext *cx, double d) { if (JSString *str = js_NumberToStringWithBase(cx, d, 10)) return &str->asFlat(); @@ -1292,7 +1278,7 @@ NumberToString(JSContext *cx, double d) } JSFlatString * -IndexToString(JSContext *cx, uint32_t index) +js::IndexToString(JSContext *cx, uint32_t index) { if (StaticStrings::hasUint(index)) return cx->runtime->staticStrings.getUint(index); @@ -1319,7 +1305,7 @@ IndexToString(JSContext *cx, uint32_t index) } bool JS_FASTCALL -NumberValueToStringBuffer(JSContext *cx, const Value &v, StringBuffer &sb) +js::NumberValueToStringBuffer(JSContext *cx, const Value &v, StringBuffer &sb) { /* Convert to C-string. */ ToCStringBuf cbuf; @@ -1344,7 +1330,7 @@ NumberValueToStringBuffer(JSContext *cx, const Value &v, StringBuffer &sb) } JS_PUBLIC_API(bool) -ToNumberSlow(JSContext *cx, Value v, double *out) +js::ToNumberSlow(JSContext *cx, Value v, double *out) { AssertCanGC(); #ifdef DEBUG @@ -1407,7 +1393,7 @@ ToNumberSlow(JSContext *cx, Value v, double *out) * conversion. Return converted value in *out on success, false on failure. */ JS_PUBLIC_API(bool) -ToInt64Slow(JSContext *cx, const Value &v, int64_t *out) +js::ToInt64Slow(JSContext *cx, const Value &v, int64_t *out) { JS_ASSERT(!v.isInt32()); double d; @@ -1426,7 +1412,7 @@ ToInt64Slow(JSContext *cx, const Value &v, int64_t *out) * conversion. Return converted value in *out on success, false on failure. */ JS_PUBLIC_API(bool) -ToUint64Slow(JSContext *cx, const Value &v, uint64_t *out) +js::ToUint64Slow(JSContext *cx, const Value &v, uint64_t *out) { JS_ASSERT(!v.isInt32()); double d; @@ -1441,7 +1427,7 @@ ToUint64Slow(JSContext *cx, const Value &v, uint64_t *out) } JS_PUBLIC_API(bool) -ToInt32Slow(JSContext *cx, const Value &v, int32_t *out) +js::ToInt32Slow(JSContext *cx, const Value &v, int32_t *out) { JS_ASSERT(!v.isInt32()); double d; @@ -1456,7 +1442,7 @@ ToInt32Slow(JSContext *cx, const Value &v, int32_t *out) } JS_PUBLIC_API(bool) -ToUint32Slow(JSContext *cx, const Value &v, uint32_t *out) +js::ToUint32Slow(JSContext *cx, const Value &v, uint32_t *out) { JS_ASSERT(!v.isInt32()); double d; @@ -1471,7 +1457,7 @@ ToUint32Slow(JSContext *cx, const Value &v, uint32_t *out) } JS_PUBLIC_API(bool) -ToUint16Slow(JSContext *cx, const Value &v, uint16_t *out) +js::ToUint16Slow(JSContext *cx, const Value &v, uint16_t *out) { JS_ASSERT(!v.isInt32()); double d; @@ -1503,8 +1489,6 @@ ToUint16Slow(JSContext *cx, const Value &v, uint16_t *out) return true; } -} /* namespace js */ - JSBool js_strtod(JSContext *cx, const jschar *s, const jschar *send, const jschar **ep, double *dp) diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 5e83ef141c2a..e7989f4c5fd3 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -289,10 +289,8 @@ obj_toSource(JSContext *cx, unsigned argc, Value *vp) } #endif /* JS_HAS_TOSOURCE */ -namespace js { - JSString * -obj_toStringHelper(JSContext *cx, JSObject *obj) +js::obj_toStringHelper(JSContext *cx, JSObject *obj) { if (obj->isProxy()) return Proxy::obj_toString(cx, obj); @@ -308,7 +306,7 @@ obj_toStringHelper(JSContext *cx, JSObject *obj) } JSObject * -NonNullObject(JSContext *cx, const Value &v) +js::NonNullObject(JSContext *cx, const Value &v) { if (v.isPrimitive()) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_NONNULL_OBJECT); @@ -318,7 +316,7 @@ NonNullObject(JSContext *cx, const Value &v) } const char * -InformalValueTypeName(const Value &v) +js::InformalValueTypeName(const Value &v) { if (v.isObject()) return v.toObject().getClass()->name; @@ -335,8 +333,6 @@ InformalValueTypeName(const Value &v) return "value"; } -} /* namespace js */ - /* ES5 15.2.4.2. Note steps 1 and 2 are errata. */ static JSBool obj_toString(JSContext *cx, unsigned argc, Value *vp) @@ -802,10 +798,8 @@ obj_getPrototypeOf(JSContext *cx, unsigned argc, Value *vp) return true; } -namespace js { - bool -NewPropertyDescriptorObject(JSContext *cx, const PropertyDescriptor *desc, Value *vp) +js::NewPropertyDescriptorObject(JSContext *cx, const PropertyDescriptor *desc, Value *vp) { if (!desc->obj) { vp->setUndefined(); @@ -889,7 +883,8 @@ PropDesc::makeObject(JSContext *cx) } bool -GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id, PropertyDescriptor *desc) +js::GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id, + PropertyDescriptor *desc) { // FIXME: Call TrapGetOwnProperty directly once ScriptedIndirectProxies is removed if (obj->isProxy()) @@ -929,7 +924,7 @@ GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id, PropertyD } bool -GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id, Value *vp) +js::GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id, Value *vp) { AutoPropertyDescriptorRooter desc(cx); return GetOwnPropertyDescriptor(cx, obj, id, &desc) && @@ -937,8 +932,8 @@ GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id, Value *vp } bool -GetFirstArgumentAsObject(JSContext *cx, unsigned argc, Value *vp, const char *method, - MutableHandleObject objp) +js::GetFirstArgumentAsObject(JSContext *cx, unsigned argc, Value *vp, const char *method, + MutableHandleObject objp) { if (argc == 0) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_MORE_ARGS_NEEDED, @@ -961,8 +956,6 @@ GetFirstArgumentAsObject(JSContext *cx, unsigned argc, Value *vp, const char *me return true; } -} /* namespace js */ - static JSBool obj_getOwnPropertyDescriptor(JSContext *cx, unsigned argc, Value *vp) { @@ -1165,10 +1158,8 @@ PropDesc::complete() } } -namespace js { - bool -Throw(JSContext *cx, jsid id, unsigned errorNumber) +js::Throw(JSContext *cx, jsid id, unsigned errorNumber) { JS_ASSERT(js_ErrorFormatString[errorNumber].argCount == 1); @@ -1183,7 +1174,7 @@ Throw(JSContext *cx, jsid id, unsigned errorNumber) } bool -Throw(JSContext *cx, JSObject *obj, unsigned errorNumber) +js::Throw(JSContext *cx, JSObject *obj, unsigned errorNumber) { if (js_ErrorFormatString[errorNumber].argCount == 1) { RootedValue val(cx, ObjectValue(*obj)); @@ -1197,8 +1188,6 @@ Throw(JSContext *cx, JSObject *obj, unsigned errorNumber) return false; } -} /* namespace js */ - static JSBool Reject(JSContext *cx, unsigned errorNumber, bool throwError, jsid id, bool *rval) { @@ -1608,11 +1597,9 @@ DefinePropertyOnArray(JSContext *cx, HandleObject obj, HandleId id, const PropDe return DefinePropertyOnObject(cx, obj, id, desc, throwError, rval); } -namespace js { - bool -DefineProperty(JSContext *cx, HandleObject obj, HandleId id, const PropDesc &desc, bool throwError, - bool *rval) +js::DefineProperty(JSContext *cx, HandleObject obj, HandleId id, const PropDesc &desc, + bool throwError, bool *rval) { if (obj->isArray()) return DefinePropertyOnArray(cx, obj, id, desc, throwError, rval); @@ -1630,10 +1617,9 @@ DefineProperty(JSContext *cx, HandleObject obj, HandleId id, const PropDesc &des return DefinePropertyOnObject(cx, obj, id, desc, throwError, rval); } -} /* namespace js */ - JSBool -js_DefineOwnProperty(JSContext *cx, HandleObject obj, HandleId id, const Value &descriptor, JSBool *bp) +js_DefineOwnProperty(JSContext *cx, HandleObject obj, HandleId id, const Value &descriptor, + JSBool *bp) { AutoPropDescArrayRooter descs(cx); PropDesc *desc = descs.append(); @@ -1669,11 +1655,9 @@ obj_defineProperty(JSContext *cx, unsigned argc, Value *vp) return true; } -namespace js { - bool -ReadPropertyDescriptors(JSContext *cx, HandleObject props, bool checkAccessors, - AutoIdVector *ids, AutoPropDescArrayRooter *descs) +js::ReadPropertyDescriptors(JSContext *cx, HandleObject props, bool checkAccessors, + AutoIdVector *ids, AutoPropDescArrayRooter *descs) { if (!GetPropertyNames(cx, props, JSITER_OWNONLY, ids)) return false; @@ -1693,8 +1677,6 @@ ReadPropertyDescriptors(JSContext *cx, HandleObject props, bool checkAccessors, return true; } -} /* namespace js */ - static bool DefineProperties(JSContext *cx, HandleObject obj, HandleObject props) { @@ -2990,8 +2972,6 @@ DefineStandardSlot(JSContext *cx, HandleObject obj, JSProtoKey key, JSAtom *atom return named; } -namespace js { - static void SetClassObject(JSObject *obj, JSProtoKey key, JSObject *cobj, JSObject *proto) { @@ -3015,12 +2995,12 @@ ClearClassObject(JSObject *obj, JSProtoKey key) } JSObject * -DefineConstructorAndPrototype(JSContext *cx, HandleObject obj, JSProtoKey key, HandleAtom atom, - JSObject *protoProto, Class *clasp, - Native constructor, unsigned nargs, - JSPropertySpec *ps, JSFunctionSpec *fs, - JSPropertySpec *static_ps, JSFunctionSpec *static_fs, - JSObject **ctorp, AllocKind ctorKind) +js::DefineConstructorAndPrototype(JSContext *cx, HandleObject obj, JSProtoKey key, HandleAtom atom, + JSObject *protoProto, Class *clasp, + Native constructor, unsigned nargs, + JSPropertySpec *ps, JSFunctionSpec *fs, + JSPropertySpec *static_ps, JSFunctionSpec *static_fs, + JSObject **ctorp, AllocKind ctorKind) { /* * Create a prototype object for this class. @@ -3166,7 +3146,7 @@ bad: * whether a class is initialized by calling IsStandardClassResolved(). */ bool -IsStandardClassResolved(JSObject *obj, js::Class *clasp) +js::IsStandardClassResolved(JSObject *obj, js::Class *clasp) { JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(clasp); @@ -3175,7 +3155,7 @@ IsStandardClassResolved(JSObject *obj, js::Class *clasp) } void -MarkStandardClassInitializedNoProto(JSObject *obj, js::Class *clasp) +js::MarkStandardClassInitializedNoProto(JSObject *obj, js::Class *clasp) { JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(clasp); @@ -3187,8 +3167,6 @@ MarkStandardClassInitializedNoProto(JSObject *obj, js::Class *clasp) obj->setSlot(key, BooleanValue(true)); } -} - JSObject * js_InitClass(JSContext *cx, HandleObject obj, JSObject *protoProto_, Class *clasp, Native constructor, unsigned nargs, @@ -3523,10 +3501,8 @@ static JSClassInitializerOp lazy_prototype_init[JSProto_LIMIT] = { #undef LAZY_PROTOTYPE_INIT }; -namespace js { - bool -SetProto(JSContext *cx, HandleObject obj, Handle proto, bool checkForCycles) +js::SetProto(JSContext *cx, HandleObject obj, Handle proto, bool checkForCycles) { JS_ASSERT_IF(!checkForCycles, obj.get() != proto.raw()); @@ -3616,13 +3592,9 @@ SetProto(JSContext *cx, HandleObject obj, Handle proto, bool ch return true; } -} - bool -js_GetClassObject(JSContext *cx, RawObject obj, JSProtoKey key, - MutableHandleObject objp) +js_GetClassObject(JSContext *cx, RawObject obj, JSProtoKey key, MutableHandleObject objp) { - RootedObject global(cx, &obj->global()); if (!global->isGlobal()) { objp.set(NULL); @@ -3906,12 +3878,10 @@ CallAddPropertyHook(JSContext *cx, Class *clasp, HandleObject obj, HandleShape s return true; } -namespace js { - Shape * -DefineNativeProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue value, - PropertyOp getter, StrictPropertyOp setter, unsigned attrs, - unsigned flags, int shortid, unsigned defineHow /* = 0 */) +js::DefineNativeProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue value, + PropertyOp getter, StrictPropertyOp setter, unsigned attrs, + unsigned flags, int shortid, unsigned defineHow /* = 0 */) { JS_ASSERT((defineHow & ~(DNP_CACHE_RESULT | DNP_DONT_PURGE | DNP_SKIP_TYPE)) == 0); @@ -4004,8 +3974,6 @@ DefineNativeProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v return shape; } -} /* namespace js */ - /* * Call obj's resolve hook. * @@ -4838,10 +4806,8 @@ baseops::DeleteSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, return baseops::DeleteGeneric(cx, obj, id, rval, strict); } -namespace js { - bool -HasDataProperty(JSContext *cx, HandleObject obj, jsid id, Value *vp) +js::HasDataProperty(JSContext *cx, HandleObject obj, jsid id, Value *vp) { if (Shape *shape = obj->nativeLookup(cx, id)) { if (shape->hasDefaultGetter() && shape->hasSlot()) { @@ -4874,7 +4840,7 @@ MaybeCallMethod(JSContext *cx, HandleObject obj, Handle id, MutableHandleV } JSBool -DefaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp) +js::DefaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp) { JS_ASSERT(hint == JSTYPE_NUMBER || hint == JSTYPE_STRING || hint == JSTYPE_VOID); #if JS_HAS_XML_SUPPORT @@ -4954,8 +4920,6 @@ DefaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp return false; } -} /* namespace js */ - JS_FRIEND_API(JSBool) JS_EnumerateState(JSContext *cx, JSHandleObject obj, JSIterateOp enum_op, JSMutableHandleValue statep, JSMutableHandleId idp) @@ -4977,11 +4941,9 @@ JS_EnumerateState(JSContext *cx, JSHandleObject obj, JSIterateOp enum_op, return true; } -namespace js { - JSBool -CheckAccess(JSContext *cx, JSObject *obj_, HandleId id, JSAccessMode mode, - MutableHandleValue vp, unsigned *attrsp) +js::CheckAccess(JSContext *cx, JSObject *obj_, HandleId id, JSAccessMode mode, + MutableHandleValue vp, unsigned *attrsp) { JSBool writing; RootedObject obj(cx, obj_), pobj(cx); @@ -5051,8 +5013,6 @@ CheckAccess(JSContext *cx, JSObject *obj_, HandleId id, JSAccessMode mode, return !check || check(cx, pobj, id, mode, vp); } -} - JSType baseops::TypeOf(JSContext *cx, HandleObject obj) { @@ -5156,11 +5116,9 @@ js_ValueToObjectOrNull(JSContext *cx, const Value &v, MutableHandleObject objp) return true; } -namespace js { - /* Callers must handle the already-object case . */ JSObject * -ToObjectSlow(JSContext *cx, HandleValue val, bool reportScanStack) +js::ToObjectSlow(JSContext *cx, HandleValue val, bool reportScanStack) { JS_ASSERT(!val.isMagic()); JS_ASSERT(!val.isObject()); @@ -5178,8 +5136,6 @@ ToObjectSlow(JSContext *cx, HandleValue val, bool reportScanStack) return PrimitiveToObject(cx, val); } -} - JSObject * js_ValueToNonNullObject(JSContext *cx, const Value &v) { diff --git a/js/src/json.cpp b/js/src/json.cpp index 59423a02610e..3da852d1aa51 100644 --- a/js/src/json.cpp +++ b/js/src/json.cpp @@ -862,11 +862,9 @@ Revive(JSContext *cx, HandleValue reviver, MutableHandleValue vp) return Walk(cx, obj, id, reviver, vp); } -namespace js { - JSBool -ParseJSONWithReviver(JSContext *cx, StableCharPtr chars, size_t length, HandleValue reviver, - MutableHandleValue vp, DecodingMode decodingMode /* = STRICT */) +js::ParseJSONWithReviver(JSContext *cx, StableCharPtr chars, size_t length, HandleValue reviver, + MutableHandleValue vp, DecodingMode decodingMode /* = STRICT */) { /* 15.12.2 steps 2-3. */ JSONParser parser(cx, chars, length, @@ -880,8 +878,6 @@ ParseJSONWithReviver(JSContext *cx, StableCharPtr chars, size_t length, HandleVa return true; } -} /* namespace js */ - #if JS_HAS_TOSOURCE static JSBool json_toSource(JSContext *cx, unsigned argc, Value *vp) diff --git a/js/src/jsopcode.cpp b/js/src/jsopcode.cpp index 8999df4e8417..99a6fda6b01b 100644 --- a/js/src/jsopcode.cpp +++ b/js/src/jsopcode.cpp @@ -6548,10 +6548,8 @@ ReconstructPCStack(JSContext *cx, JSScript *script, jsbytecode *target, jsbyteco #undef LOCAL_ASSERT #undef LOCAL_ASSERT_RV -namespace js { - bool -CallResultEscapes(jsbytecode *pc) +js::CallResultEscapes(jsbytecode *pc) { /* * If we see any of these sequences, the result is unused: @@ -6577,7 +6575,7 @@ CallResultEscapes(jsbytecode *pc) } extern bool -IsValidBytecodeOffset(JSContext *cx, JSScript *script, size_t offset) +js::IsValidBytecodeOffset(JSContext *cx, JSScript *script, size_t offset) { // This could be faster (by following jump instructions if the target is <= offset). for (BytecodeRange r(script); !r.empty(); r.popFront()) { @@ -6589,7 +6587,7 @@ IsValidBytecodeOffset(JSContext *cx, JSScript *script, size_t offset) } JS_FRIEND_API(size_t) -GetPCCountScriptCount(JSContext *cx) +js::GetPCCountScriptCount(JSContext *cx) { JSRuntime *rt = cx->runtime; @@ -6626,7 +6624,7 @@ AppendArrayJSONProperties(JSContext *cx, StringBuffer &buf, } JS_FRIEND_API(JSString *) -GetPCCountScriptSummary(JSContext *cx, size_t index) +js::GetPCCountScriptSummary(JSContext *cx, size_t index) { JSRuntime *rt = cx->runtime; @@ -6919,7 +6917,7 @@ GetPCCountJSON(JSContext *cx, const ScriptAndCounts &sac, StringBuffer &buf) } JS_FRIEND_API(JSString *) -GetPCCountScriptContents(JSContext *cx, size_t index) +js::GetPCCountScriptContents(JSContext *cx, size_t index) { JSRuntime *rt = cx->runtime; @@ -6944,5 +6942,3 @@ GetPCCountScriptContents(JSContext *cx, size_t index) return buf.finishString(); } - -} // namespace js diff --git a/js/src/jsreflect.cpp b/js/src/jsreflect.cpp index bb80ab698002..f6416cbc89d9 100644 --- a/js/src/jsreflect.cpp +++ b/js/src/jsreflect.cpp @@ -37,9 +37,7 @@ using namespace js::frontend; using mozilla::DebugOnly; using mozilla::ArrayLength; -namespace js { - -char const *aopNames[] = { +char const *js::aopNames[] = { "=", /* AOP_ASSIGN */ "+=", /* AOP_PLUS */ "-=", /* AOP_MINUS */ @@ -54,7 +52,7 @@ char const *aopNames[] = { "&=" /* AOP_BITAND */ }; -char const *binopNames[] = { +char const *js::binopNames[] = { "==", /* BINOP_EQ */ "!=", /* BINOP_NE */ "===", /* BINOP_STRICTEQ */ @@ -79,7 +77,7 @@ char const *binopNames[] = { "..", /* BINOP_DBLDOT */ }; -char const *unopNames[] = { +char const *js::unopNames[] = { "delete", /* UNOP_DELETE */ "-", /* UNOP_NEG */ "+", /* UNOP_POS */ @@ -89,14 +87,14 @@ char const *unopNames[] = { "void" /* UNOP_VOID */ }; -char const *nodeTypeNames[] = { +char const *js::nodeTypeNames[] = { #define ASTDEF(ast, str, method) str, #include "jsast.tbl" #undef ASTDEF NULL }; -char const *callbackNames[] = { +static char const *callbackNames[] = { #define ASTDEF(ast, str, method) method, #include "jsast.tbl" #undef ASTDEF @@ -1685,13 +1683,11 @@ NodeBuilder::xmlPI(HandleValue target, HandleValue contents, TokenPos *pos, Muta dst); } - /* * Serialization of parse nodes to JavaScript objects. * * All serialization methods take a non-nullable ParseNode pointer. */ - class ASTSerializer { JSContext *cx; @@ -3386,8 +3382,6 @@ ASTSerializer::functionBody(ParseNode *pn, TokenPos *pos, MutableHandleValue dst return builder.blockStatement(elts, pos, dst); } -} /* namespace js */ - static JSBool reflect_parse(JSContext *cx, uint32_t argc, jsval *vp) { @@ -3515,7 +3509,6 @@ static JSFunctionSpec static_methods[] = { JS_FS_END }; - JS_PUBLIC_API(JSObject *) JS_InitReflect(JSContext *cx, JSObject *objArg) { diff --git a/js/src/jsreflect.h b/js/src/jsreflect.h index 2d875f10a81e..4cd7519bc32b 100644 --- a/js/src/jsreflect.h +++ b/js/src/jsreflect.h @@ -98,5 +98,4 @@ extern char const *nodeTypeNames[]; } /* namespace js */ - #endif /* jsreflect_h___ */ diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index 37e2839a9845..20de1be46c9f 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -1938,8 +1938,6 @@ JSScript::finalize(FreeOp *fop) } } -namespace js { - static const uint32_t GSN_CACHE_THRESHOLD = 100; static const uint32_t GSN_CACHE_MAP_INIT_SIZE = 20; @@ -1951,8 +1949,6 @@ GSNCache::purge() map.finish(); } -} /* namespace js */ - jssrcnote * js_GetSrcNote(JSContext *cx, RawScript script, jsbytecode *pc) { @@ -2133,18 +2129,16 @@ js_GetScriptLineExtent(RawScript script) return 1 + lineno - script->lineno; } -namespace js { - unsigned -CurrentLine(JSContext *cx) +js::CurrentLine(JSContext *cx) { AutoAssertNoGC nogc; return PCToLineNumber(cx->fp()->script().get(nogc), cx->regs().pc); } void -CurrentScriptFileLineOriginSlow(JSContext *cx, const char **file, unsigned *linenop, - JSPrincipals **origin) +js::CurrentScriptFileLineOriginSlow(JSContext *cx, const char **file, unsigned *linenop, + JSPrincipals **origin) { AutoAssertNoGC nogc; NonBuiltinScriptFrameIter iter(cx); @@ -2162,8 +2156,6 @@ CurrentScriptFileLineOriginSlow(JSContext *cx, const char **file, unsigned *line *origin = script->originPrincipals; } -} /* namespace js */ - template static inline T * Rebase(RawScript dst, RawScript src, T *srcp) diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index 1fea29469342..4563396e743d 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -3460,10 +3460,8 @@ js_ValueToSource(JSContext *cx, const Value &v) return ToString(cx, rval); } -namespace js { - bool -EqualStrings(JSContext *cx, JSString *str1, JSString *str2, bool *result) +js::EqualStrings(JSContext *cx, JSString *str1, JSString *str2, bool *result) { if (str1 == str2) { *result = true; @@ -3488,7 +3486,7 @@ EqualStrings(JSContext *cx, JSString *str1, JSString *str2, bool *result) } bool -EqualStrings(JSLinearString *str1, JSLinearString *str2) +js::EqualStrings(JSLinearString *str1, JSLinearString *str2) { if (str1 == str2) return true; @@ -3500,10 +3498,6 @@ EqualStrings(JSLinearString *str1, JSLinearString *str2) return PodEqual(str1->chars(), str2->chars(), length1); } -} /* namespace js */ - -namespace js { - static bool CompareStringsImpl(JSContext *cx, JSString *str1, JSString *str2, int32_t *result) { @@ -3527,17 +3521,13 @@ CompareStringsImpl(JSContext *cx, JSString *str1, JSString *str2, int32_t *resul } bool -CompareStrings(JSContext *cx, JSString *str1, JSString *str2, int32_t *result) +js::CompareStrings(JSContext *cx, JSString *str1, JSString *str2, int32_t *result) { return CompareStringsImpl(cx, str1, str2, result); } -} /* namespace js */ - -namespace js { - bool -StringEqualsAscii(JSLinearString *str, const char *asciiBytes) +js::StringEqualsAscii(JSLinearString *str, const char *asciiBytes) { size_t length = strlen(asciiBytes); #ifdef DEBUG @@ -3554,8 +3544,6 @@ StringEqualsAscii(JSLinearString *str, const char *asciiBytes) return true; } -} /* namespacejs */ - size_t js_strlen(const jschar *s) { @@ -3600,10 +3588,8 @@ js_strchr_limit(const jschar *s, jschar c, const jschar *limit) return NULL; } -namespace js { - jschar * -InflateString(JSContext *cx, const char *bytes, size_t *lengthp) +js::InflateString(JSContext *cx, const char *bytes, size_t *lengthp) { AssertCanGC(); size_t nchars; @@ -3630,7 +3616,7 @@ InflateString(JSContext *cx, const char *bytes, size_t *lengthp) } jschar * -InflateUTF8String(JSContext *cx, const char *bytes, size_t *lengthp) +js::InflateUTF8String(JSContext *cx, const char *bytes, size_t *lengthp) { AssertCanGC(); size_t nchars; @@ -3663,7 +3649,7 @@ InflateUTF8String(JSContext *cx, const char *bytes, size_t *lengthp) * May be called with null cx. */ char * -DeflateString(JSContext *maybecx, const jschar *chars, size_t nchars) +js::DeflateString(JSContext *maybecx, const jschar *chars, size_t nchars) { AutoAssertNoGC nogc; size_t nbytes = nchars; @@ -3679,13 +3665,13 @@ DeflateString(JSContext *maybecx, const jschar *chars, size_t nchars) } size_t -GetDeflatedStringLength(JSContext *cx, const jschar *chars, size_t nchars) +js::GetDeflatedStringLength(JSContext *cx, const jschar *chars, size_t nchars) { return nchars; } bool -DeflateStringToBuffer(JSContext *maybecx, const jschar *src, size_t srclen, +js::DeflateStringToBuffer(JSContext *maybecx, const jschar *src, size_t srclen, char *dst, size_t *dstlenp) { size_t dstlen = *dstlenp; @@ -3704,9 +3690,8 @@ DeflateStringToBuffer(JSContext *maybecx, const jschar *src, size_t srclen, return JS_TRUE; } - bool -InflateStringToBuffer(JSContext *maybecx, const char *src, size_t srclen, +js::InflateStringToBuffer(JSContext *maybecx, const char *src, size_t srclen, jschar *dst, size_t *dstlenp) { if (dst) { @@ -3728,7 +3713,7 @@ InflateStringToBuffer(JSContext *maybecx, const char *src, size_t srclen, } bool -InflateUTF8StringToBuffer(JSContext *cx, const char *src, size_t srclen, +js::InflateUTF8StringToBuffer(JSContext *cx, const char *src, size_t srclen, jschar *dst, size_t *dstlenp) { size_t dstlen, origDstlen, offset, j, n; @@ -3808,8 +3793,6 @@ bufferTooSmall: return JS_FALSE; } -} /* namepsace js */ - const jschar js_uriReservedPlusPound_ucstr[] = {';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '#', 0}; const jschar js_uriUnescaped_ucstr[] = @@ -4184,10 +4167,9 @@ Utf8ToOneUcs4Char(const uint8_t *utf8Buffer, int utf8Length) return ucs4Char; } -namespace js { - size_t -PutEscapedStringImpl(char *buffer, size_t bufferSize, FILE *fp, JSLinearString *str, uint32_t quote) +js::PutEscapedStringImpl(char *buffer, size_t bufferSize, FILE *fp, JSLinearString *str, + uint32_t quote) { enum { STOP, FIRST_QUOTE, LAST_QUOTE, CHARS, ESCAPE_START, ESCAPE_MORE @@ -4296,5 +4278,3 @@ PutEscapedStringImpl(char *buffer, size_t bufferSize, FILE *fp, JSLinearString * buffer[n] = '\0'; return n; } - -} /* namespace js */ diff --git a/js/src/jsweakmap.cpp b/js/src/jsweakmap.cpp index 94c6bd0997c6..7f38aeefb2d3 100644 --- a/js/src/jsweakmap.cpp +++ b/js/src/jsweakmap.cpp @@ -21,8 +21,6 @@ using namespace js; -namespace js { - bool WeakMapBase::markAllIteratively(JSTracer *tracer) { @@ -89,8 +87,6 @@ WeakMapBase::restoreWeakMapList(JSRuntime *rt, WeakMapVector &vector) } } -} /* namespace js */ - typedef WeakMap ObjectValueMap; static ObjectValueMap * diff --git a/js/src/jswrapper.cpp b/js/src/jswrapper.cpp index 9a7c1f605fa5..14bc2d3b33f8 100644 --- a/js/src/jswrapper.cpp +++ b/js/src/jswrapper.cpp @@ -29,9 +29,7 @@ using namespace js; using namespace js::gc; -namespace js { -int sWrapperFamily; -} +int js::sWrapperFamily; void * Wrapper::getWrapperFamily() @@ -825,8 +823,6 @@ SecurityWrapper::regexp_toShared(JSContext *cx, JSObject *obj, RegExpGuard template class js::SecurityWrapper; template class js::SecurityWrapper; -namespace js { - DeadObjectProxy::DeadObjectProxy() : BaseProxyHandler(&sDeadObjectFamily) { @@ -969,8 +965,6 @@ DeadObjectProxy::getPrototypeOf(JSContext *cx, JSObject *proxy, JSObject **proto DeadObjectProxy DeadObjectProxy::singleton; int DeadObjectProxy::sDeadObjectFamily; -} // namespace js - JSObject * js::NewDeadProxyObject(JSContext *cx, JSObject *parent) { diff --git a/js/src/jsxml.cpp b/js/src/jsxml.cpp index bacc8ecf3d35..feeab9eadad7 100644 --- a/js/src/jsxml.cpp +++ b/js/src/jsxml.cpp @@ -2833,10 +2833,8 @@ ReportBadXMLName(JSContext *cx, const Value &idval) js_ReportValueError(cx, JSMSG_BAD_XML_NAME, JSDVG_IGNORE_STACK, val, NullPtr()); } -namespace js { - bool -GetLocalNameFromFunctionQName(JSObject *qn, JSAtom **namep, JSContext *cx) +js::GetLocalNameFromFunctionQName(JSObject *qn, JSAtom **namep, JSContext *cx) { JSAtom *atom = cx->names().functionNamespaceURI; JSLinearString *uri = qn->getNameURI(); @@ -2847,8 +2845,6 @@ GetLocalNameFromFunctionQName(JSObject *qn, JSAtom **namep, JSContext *cx) return false; } -} /* namespace js */ - bool js_GetLocalNameFromFunctionQName(JSObject *obj, jsid *funidp, JSContext *cx) { @@ -7467,8 +7463,6 @@ js_InitXMLClasses(JSContext *cx, HandleObject obj) return js_InitXMLClass(cx, obj); } -namespace js { - bool GlobalObject::getFunctionNamespace(JSContext *cx, Value *vp) { @@ -7498,8 +7492,6 @@ GlobalObject::getFunctionNamespace(JSContext *cx, Value *vp) return true; } -} // namespace js - /* * Note the asymmetry between js_GetDefaultXMLNamespace and js_SetDefaultXML- * Namespace. Get searches fp->scopeChain for JS_DEFAULT_XML_NAMESPACE_ID, diff --git a/js/src/vm/GlobalObject.cpp b/js/src/vm/GlobalObject.cpp index 7de47c77f0a0..7208274b1743 100644 --- a/js/src/vm/GlobalObject.cpp +++ b/js/src/vm/GlobalObject.cpp @@ -57,8 +57,6 @@ ThrowTypeError(JSContext *cx, unsigned argc, Value *vp) return false; } -namespace js { - static bool TestProtoGetterThis(const Value &v) { @@ -92,7 +90,9 @@ ProtoGetter(JSContext *cx, unsigned argc, Value *vp) return CallNonGenericMethod(cx, TestProtoGetterThis, ProtoGetterImpl, args); } +namespace js { size_t sSetProtoCalled = 0; +} // namespace js static bool TestProtoSetterThis(const Value &v) @@ -533,7 +533,7 @@ GlobalObject::createBlankPrototypeInheriting(JSContext *cx, Class *clasp, JSObje } bool -LinkConstructorAndPrototype(JSContext *cx, JSObject *ctor_, JSObject *proto_) +js::LinkConstructorAndPrototype(JSContext *cx, JSObject *ctor_, JSObject *proto_) { RootedObject ctor(cx, ctor_), proto(cx, proto_); @@ -548,8 +548,8 @@ LinkConstructorAndPrototype(JSContext *cx, JSObject *ctor_, JSObject *proto_) } bool -DefinePropertiesAndBrand(JSContext *cx, JSObject *obj_, - const JSPropertySpec *ps, const JSFunctionSpec *fs) +js::DefinePropertiesAndBrand(JSContext *cx, JSObject *obj_, + const JSPropertySpec *ps, const JSFunctionSpec *fs) { RootedObject obj(cx, obj_); @@ -560,7 +560,7 @@ DefinePropertiesAndBrand(JSContext *cx, JSObject *obj_, return true; } -void +static void GlobalDebuggees_finalize(FreeOp *fop, RawObject obj) { fop->delete_((GlobalObject::DebuggerVector *) obj->getPrivate()); @@ -620,5 +620,3 @@ GlobalObject::addDebugger(JSContext *cx, Handle global, Debugger } return true; } - -} // namespace js diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index 6a866ce8d1ac..79903c2a7eb4 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -1068,8 +1068,6 @@ ScopeIterKey::match(ScopeIterKey si1, ScopeIterKey si2) /*****************************************************************************/ -namespace js { - /* * DebugScopeProxy is the handler for DebugScopeObject proxy objects. Having a * custom handler (rather than trying to reuse js::Wrapper) gives us several @@ -1461,8 +1459,6 @@ class DebugScopeProxy : public BaseProxyHandler } }; -} /* namespace js */ - int DebugScopeProxy::family = 0; DebugScopeProxy DebugScopeProxy::singleton; diff --git a/js/src/vm/Unicode.cpp b/js/src/vm/Unicode.cpp index 8d92a0678262..e61916eb1a52 100644 --- a/js/src/vm/Unicode.cpp +++ b/js/src/vm/Unicode.cpp @@ -6,8 +6,8 @@ */ #include "Unicode.h" -namespace js { -namespace unicode { +using namespace js; +using namespace js::unicode; /* * So how does indexing work? @@ -53,7 +53,7 @@ namespace unicode { * increase shift * stop if you found the best shift */ -const CharacterInfo js_charinfo[] = { +const CharacterInfo unicode::js_charinfo[] = { {0, 0, 0}, {0, 0, 1}, {0, 0, 4}, @@ -197,7 +197,7 @@ const CharacterInfo js_charinfo[] = { {58272, 0, 2}, }; -const uint8_t index1[] = { +const uint8_t unicode::index1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, @@ -257,7 +257,7 @@ const uint8_t index1[] = { 26, 26, 26, 26, 165, 166, 167, 168, 169, 170, 26, 171, 172, 173, 174, 175, }; -const uint8_t index2[] = { +const uint8_t unicode::index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, @@ -886,6 +886,4 @@ const uint8_t index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; -} /* namespace unicode */ -} /* namespace js */ diff --git a/js/src/vm/Xdr.cpp b/js/src/vm/Xdr.cpp index 8b6b88ac07d4..4edc242c72a6 100644 --- a/js/src/vm/Xdr.cpp +++ b/js/src/vm/Xdr.cpp @@ -28,8 +28,6 @@ using namespace js; using mozilla::DebugOnly; -namespace js { - void XDRBuffer::freeBuffer() { @@ -167,8 +165,5 @@ XDRDecoder::XDRDecoder(JSContext *cx, const void *data, uint32_t length, this->originPrincipals = JSScript::normalizeOriginPrincipals(principals, originPrincipals); } -template class XDRState; -template class XDRState; - -} /* namespace js */ - +template class js::XDRState; +template class js::XDRState; diff --git a/js/src/vm/make_unicode.py b/js/src/vm/make_unicode.py index 3edf1a758761..3537b09058d6 100644 --- a/js/src/vm/make_unicode.py +++ b/js/src/vm/make_unicode.py @@ -255,10 +255,10 @@ if (typeof reportCompare === "function") data_file.write('/* Generated by make_unicode.py DO NOT MODIFY */\n') data_file.write(public_domain) data_file.write('#include "Unicode.h"\n\n') - data_file.write('namespace js {\n') - data_file.write('namespace unicode {\n') + data_file.write('using namespace js;\n') + data_file.write('using namespace js::unicode;\n') data_file.write(comment) - data_file.write('const CharacterInfo js_charinfo[] = {\n') + data_file.write('const CharacterInfo unicode::js_charinfo[] = {\n') for d in table: data_file.write(' {') data_file.write(', '.join((str(e) for e in d))) @@ -267,7 +267,7 @@ if (typeof reportCompare === "function") data_file.write('\n') def dump(data, name, file): - file.write('const uint8_t ' + name + '[] = {\n') + file.write('const uint8_t unicode::' + name + '[] = {\n') line = pad = ' ' * 4 lines = [] @@ -291,8 +291,6 @@ if (typeof reportCompare === "function") dump(index2, 'index2', data_file) data_file.write('\n') - data_file.write('} /* namespace unicode */\n') - data_file.write('} /* namespace js */\n') data_file.write('\n') def getsize(data): From 3514c55e3518bebb448589927e4d2299406ea3d5 Mon Sep 17 00:00:00 2001 From: Jason Orendorff Date: Fri, 16 Nov 2012 16:00:02 -0600 Subject: [PATCH 74/75] Bug 812314 part 2 - User fewer namespace js {...} blocks in .cpp files in js/src/gc. r=terrence. --HG-- extra : rebase_source : 821757d2ac77c66ce42c3db42d9dcaa99e6ae637 --- js/src/gc/Marking.cpp | 139 ++++++++++++++++++++++---------------- js/src/gc/Memory.cpp | 62 ++++++++--------- js/src/gc/Statistics.cpp | 9 +-- js/src/gc/StoreBuffer.cpp | 6 +- 4 files changed, 114 insertions(+), 102 deletions(-) diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index 60c8faa5b317..884a3cbef89d 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -19,6 +19,9 @@ #include "ion/IonCode.h" #include "vm/String-inl.h" +using namespace js; +using namespace js::gc; + using mozilla::DebugOnly; void * const js::NullPtr::constNullValue = NULL; @@ -53,9 +56,6 @@ void * const js::NullPtr::constNullValue = NULL; * scanning functions, but they don't push onto an explicit stack. */ -namespace js { -namespace gc { - #if JS_HAS_XML_SUPPORT static inline void PushMarkStack(GCMarker *gcmarker, JSXML *thing); @@ -79,6 +79,22 @@ PushMarkStack(GCMarker *gcmarker, JSString *thing); static inline void PushMarkStack(GCMarker *gcmarker, types::TypeObject *thing); +namespace js { +namespace gc { + +static void MarkChildren(JSTracer *trc, JSString *str); +static void MarkChildren(JSTracer *trc, JSScript *script); +static void MarkChildren(JSTracer *trc, Shape *shape); +static void MarkChildren(JSTracer *trc, BaseShape *base); +static void MarkChildren(JSTracer *trc, types::TypeObject *type); +static void MarkChildren(JSTracer *trc, ion::IonCode *code); +#if JS_HAS_XML_SUPPORT +static void MarkChildren(JSTracer *trc, JSXML *xml); +#endif + +} /* namespace gc */ +} /* namespace js */ + /*** Object Marking ***/ template @@ -104,7 +120,7 @@ CheckMarkedThing(JSTracer *trc, T *thing) } template -void +static void MarkInternal(JSTracer *trc, T **thingp) { JS_ASSERT(thingp); @@ -143,6 +159,9 @@ MarkUnbarriered(JSTracer *trc, T **thingp, const char *name) MarkInternal(trc, thingp); } +namespace js { +namespace gc { + template static void Mark(JSTracer *trc, EncapsulatedPtr *thing, const char *name) @@ -151,6 +170,9 @@ Mark(JSTracer *trc, EncapsulatedPtr *thing, const char *name) MarkInternal(trc, thing->unsafeGet()); } +} /* namespace gc */ +} /* namespace js */ + template static void MarkRoot(JSTracer *trc, T **thingp, const char *name) @@ -185,6 +207,9 @@ MarkRootRange(JSTracer *trc, size_t len, T **vec, const char *name) } } +namespace js { +namespace gc { + template static bool IsMarked(T **thingp) @@ -215,22 +240,26 @@ Mark##base##Unbarriered(JSTracer *trc, type **thingp, const char *name) MarkUnbarriered(trc, thingp, name); \ } \ \ -void Mark##base##Range(JSTracer *trc, size_t len, HeapPtr *vec, const char *name) \ +void \ +Mark##base##Range(JSTracer *trc, size_t len, HeapPtr *vec, const char *name) \ { \ MarkRange(trc, len, vec, name); \ } \ \ -void Mark##base##RootRange(JSTracer *trc, size_t len, type **vec, const char *name) \ +void \ +Mark##base##RootRange(JSTracer *trc, size_t len, type **vec, const char *name) \ { \ MarkRootRange(trc, len, vec, name); \ } \ \ -bool Is##base##Marked(type **thingp) \ +bool \ +Is##base##Marked(type **thingp) \ { \ return IsMarked(thingp); \ } \ \ -bool Is##base##Marked(EncapsulatedPtr *thingp) \ +bool \ +Is##base##Marked(EncapsulatedPtr *thingp) \ { \ return IsMarked(thingp->unsafeGet()); \ } @@ -251,15 +280,18 @@ DeclMarkerImpl(String, JSString) DeclMarkerImpl(String, JSFlatString) DeclMarkerImpl(String, JSLinearString) DeclMarkerImpl(String, PropertyName) -DeclMarkerImpl(TypeObject, types::TypeObject) +DeclMarkerImpl(TypeObject, js::types::TypeObject) #if JS_HAS_XML_SUPPORT DeclMarkerImpl(XML, JSXML) #endif +} /* namespace gc */ +} /* namespace js */ + /*** Externally Typed Marking ***/ void -MarkKind(JSTracer *trc, void **thingp, JSGCTraceKind kind) +gc::MarkKind(JSTracer *trc, void **thingp, JSGCTraceKind kind) { JS_ASSERT(thingp); JS_ASSERT(*thingp); @@ -294,7 +326,7 @@ MarkKind(JSTracer *trc, void **thingp, JSGCTraceKind kind) } } -void +static void MarkGCThingInternal(JSTracer *trc, void **thingp, const char *name) { JS_SET_TRACING_NAME(trc, name); @@ -305,14 +337,14 @@ MarkGCThingInternal(JSTracer *trc, void **thingp, const char *name) } void -MarkGCThingRoot(JSTracer *trc, void **thingp, const char *name) +gc::MarkGCThingRoot(JSTracer *trc, void **thingp, const char *name) { JS_ROOT_MARKING_ASSERT(trc); MarkGCThingInternal(trc, thingp, name); } void -MarkGCThingUnbarriered(JSTracer *trc, void **thingp, const char *name) +gc::MarkGCThingUnbarriered(JSTracer *trc, void **thingp, const char *name) { MarkGCThingInternal(trc, thingp, name); } @@ -339,14 +371,14 @@ MarkIdInternal(JSTracer *trc, jsid *id) } void -MarkId(JSTracer *trc, EncapsulatedId *id, const char *name) +gc::MarkId(JSTracer *trc, EncapsulatedId *id, const char *name) { JS_SET_TRACING_NAME(trc, name); MarkIdInternal(trc, id->unsafeGet()); } void -MarkIdRoot(JSTracer *trc, jsid *id, const char *name) +gc::MarkIdRoot(JSTracer *trc, jsid *id, const char *name) { JS_ROOT_MARKING_ASSERT(trc); JS_SET_TRACING_NAME(trc, name); @@ -354,14 +386,14 @@ MarkIdRoot(JSTracer *trc, jsid *id, const char *name) } void -MarkIdUnbarriered(JSTracer *trc, jsid *id, const char *name) +gc::MarkIdUnbarriered(JSTracer *trc, jsid *id, const char *name) { JS_SET_TRACING_NAME(trc, name); MarkIdInternal(trc, id); } void -MarkIdRange(JSTracer *trc, size_t len, HeapId *vec, const char *name) +gc::MarkIdRange(JSTracer *trc, size_t len, HeapId *vec, const char *name) { for (size_t i = 0; i < len; ++i) { JS_SET_TRACING_INDEX(trc, name, i); @@ -370,7 +402,7 @@ MarkIdRange(JSTracer *trc, size_t len, HeapId *vec, const char *name) } void -MarkIdRootRange(JSTracer *trc, size_t len, jsid *vec, const char *name) +gc::MarkIdRootRange(JSTracer *trc, size_t len, jsid *vec, const char *name) { JS_ROOT_MARKING_ASSERT(trc); for (size_t i = 0; i < len; ++i) { @@ -400,14 +432,14 @@ MarkValueInternal(JSTracer *trc, Value *v) } void -MarkValue(JSTracer *trc, EncapsulatedValue *v, const char *name) +gc::MarkValue(JSTracer *trc, EncapsulatedValue *v, const char *name) { JS_SET_TRACING_NAME(trc, name); MarkValueInternal(trc, v->unsafeGet()); } void -MarkValueRoot(JSTracer *trc, Value *v, const char *name) +gc::MarkValueRoot(JSTracer *trc, Value *v, const char *name) { JS_ROOT_MARKING_ASSERT(trc); JS_SET_TRACING_NAME(trc, name); @@ -415,7 +447,7 @@ MarkValueRoot(JSTracer *trc, Value *v, const char *name) } void -MarkTypeRoot(JSTracer *trc, types::Type *v, const char *name) +gc::MarkTypeRoot(JSTracer *trc, types::Type *v, const char *name) { JS_ROOT_MARKING_ASSERT(trc); JS_SET_TRACING_NAME(trc, name); @@ -431,7 +463,7 @@ MarkTypeRoot(JSTracer *trc, types::Type *v, const char *name) } void -MarkValueRange(JSTracer *trc, size_t len, EncapsulatedValue *vec, const char *name) +gc::MarkValueRange(JSTracer *trc, size_t len, EncapsulatedValue *vec, const char *name) { for (size_t i = 0; i < len; ++i) { JS_SET_TRACING_INDEX(trc, name, i); @@ -440,7 +472,7 @@ MarkValueRange(JSTracer *trc, size_t len, EncapsulatedValue *vec, const char *na } void -MarkValueRootRange(JSTracer *trc, size_t len, Value *vec, const char *name) +gc::MarkValueRootRange(JSTracer *trc, size_t len, Value *vec, const char *name) { JS_ROOT_MARKING_ASSERT(trc); for (size_t i = 0; i < len; ++i) { @@ -450,7 +482,7 @@ MarkValueRootRange(JSTracer *trc, size_t len, Value *vec, const char *name) } bool -IsValueMarked(Value *v) +gc::IsValueMarked(Value *v) { JS_ASSERT(v->isMarkable()); bool rv; @@ -469,14 +501,14 @@ IsValueMarked(Value *v) /*** Slot Marking ***/ void -MarkSlot(JSTracer *trc, HeapSlot *s, const char *name) +gc::MarkSlot(JSTracer *trc, HeapSlot *s, const char *name) { JS_SET_TRACING_NAME(trc, name); MarkValueInternal(trc, s->unsafeGet()); } void -MarkArraySlots(JSTracer *trc, size_t len, HeapSlot *vec, const char *name) +gc::MarkArraySlots(JSTracer *trc, size_t len, HeapSlot *vec, const char *name) { for (size_t i = 0; i < len; ++i) { JS_SET_TRACING_INDEX(trc, name, i); @@ -485,7 +517,7 @@ MarkArraySlots(JSTracer *trc, size_t len, HeapSlot *vec, const char *name) } void -MarkObjectSlots(JSTracer *trc, JSObject *obj, uint32_t start, uint32_t nslots) +gc::MarkObjectSlots(JSTracer *trc, JSObject *obj, uint32_t start, uint32_t nslots) { JS_ASSERT(obj->isNative()); for (uint32_t i = start; i < (start + nslots); ++i) { @@ -495,7 +527,7 @@ MarkObjectSlots(JSTracer *trc, JSObject *obj, uint32_t start, uint32_t nslots) } void -MarkCrossCompartmentObjectUnbarriered(JSTracer *trc, JSObject **obj, const char *name) +gc::MarkCrossCompartmentObjectUnbarriered(JSTracer *trc, JSObject **obj, const char *name) { if (IS_GC_MARKING_TRACER(trc) && !(*obj)->compartment()->isCollecting()) return; @@ -504,7 +536,7 @@ MarkCrossCompartmentObjectUnbarriered(JSTracer *trc, JSObject **obj, const char } void -MarkCrossCompartmentScriptUnbarriered(JSTracer *trc, JSScript **script, const char *name) +gc::MarkCrossCompartmentScriptUnbarriered(JSTracer *trc, JSScript **script, const char *name) { if (IS_GC_MARKING_TRACER(trc) && !(*script)->compartment()->isCollecting()) return; @@ -513,7 +545,7 @@ MarkCrossCompartmentScriptUnbarriered(JSTracer *trc, JSScript **script, const ch } void -MarkCrossCompartmentSlot(JSTracer *trc, HeapSlot *s, const char *name) +gc::MarkCrossCompartmentSlot(JSTracer *trc, HeapSlot *s, const char *name) { if (s->isMarkable()) { Cell *cell = (Cell *)s->toGCThing(); @@ -527,21 +559,21 @@ MarkCrossCompartmentSlot(JSTracer *trc, HeapSlot *s, const char *name) /*** Special Marking ***/ void -MarkObject(JSTracer *trc, HeapPtr *thingp, const char *name) +gc::MarkObject(JSTracer *trc, HeapPtr *thingp, const char *name) { JS_SET_TRACING_NAME(trc, name); MarkInternal(trc, thingp->unsafeGet()); } void -MarkValueUnbarriered(JSTracer *trc, Value *v, const char *name) +gc::MarkValueUnbarriered(JSTracer *trc, Value *v, const char *name) { JS_SET_TRACING_NAME(trc, name); MarkValueInternal(trc, v); } bool -IsCellMarked(Cell **thingp) +gc::IsCellMarked(Cell **thingp) { return IsMarked(thingp); } @@ -593,9 +625,6 @@ PushMarkStack(GCMarker *gcmarker, types::TypeObject *thing) gcmarker->pushType(thing); } -static void -MarkChildren(JSTracer *trc, JSScript *script); - static void PushMarkStack(GCMarker *gcmarker, JSScript *thing) { @@ -623,7 +652,7 @@ PushMarkStack(GCMarker *gcmarker, Shape *thing) ScanShape(gcmarker, thing); } -void +static void PushMarkStack(GCMarker *gcmarker, ion::IonCode *thing) { JS_COMPARTMENT_ASSERT(gcmarker->runtime, thing); @@ -789,13 +818,13 @@ PushMarkStack(GCMarker *gcmarker, JSString *str) } void -MarkChildren(JSTracer *trc, JSObject *obj) +gc::MarkChildren(JSTracer *trc, JSObject *obj) { obj->markChildren(trc); } static void -MarkChildren(JSTracer *trc, JSString *str) +gc::MarkChildren(JSTracer *trc, JSString *str) { if (str->hasBase()) str->markBase(trc); @@ -804,19 +833,19 @@ MarkChildren(JSTracer *trc, JSString *str) } static void -MarkChildren(JSTracer *trc, JSScript *script) +gc::MarkChildren(JSTracer *trc, JSScript *script) { script->markChildren(trc); } static void -MarkChildren(JSTracer *trc, Shape *shape) +gc::MarkChildren(JSTracer *trc, Shape *shape) { shape->markChildren(trc); } static void -MarkChildren(JSTracer *trc, BaseShape *base) +gc::MarkChildren(JSTracer *trc, BaseShape *base) { base->markChildren(trc); } @@ -829,7 +858,7 @@ MarkChildren(JSTracer *trc, BaseShape *base) * marked only if it isn't the same as prevParent, which will be * updated to the current shape's parent. */ -inline void +static inline void MarkCycleCollectorChildren(JSTracer *trc, BaseShape *base, JSObject **prevParent) { JS_ASSERT(base); @@ -870,7 +899,7 @@ MarkCycleCollectorChildren(JSTracer *trc, BaseShape *base, JSObject **prevParent * parent pointer will only be marked once. */ void -MarkCycleCollectorChildren(JSTracer *trc, Shape *shape) +gc::MarkCycleCollectorChildren(JSTracer *trc, Shape *shape) { JSObject *prevParent = NULL; do { @@ -909,7 +938,7 @@ ScanTypeObject(GCMarker *gcmarker, types::TypeObject *type) } static void -MarkChildren(JSTracer *trc, types::TypeObject *type) +gc::MarkChildren(JSTracer *trc, types::TypeObject *type) { unsigned count = type->getPropertyCount(); for (unsigned i = 0; i < count; i++) { @@ -933,8 +962,8 @@ MarkChildren(JSTracer *trc, types::TypeObject *type) MarkObject(trc, &type->interpretedFunction, "type_function"); } -void -MarkChildren(JSTracer *trc, ion::IonCode *code) +static void +gc::MarkChildren(JSTracer *trc, ion::IonCode *code) { #ifdef JS_ION code->trace(trc); @@ -943,14 +972,14 @@ MarkChildren(JSTracer *trc, ion::IonCode *code) #if JS_HAS_XML_SUPPORT static void -MarkChildren(JSTracer *trc, JSXML *xml) +gc::MarkChildren(JSTracer *trc, JSXML *xml) { js_TraceXML(trc, xml); } #endif template -void +static void PushArenaTyped(GCMarker *gcmarker, ArenaHeader *aheader) { for (CellIterUnderGC i(aheader); !i.done(); i.next()) @@ -958,7 +987,7 @@ PushArenaTyped(GCMarker *gcmarker, ArenaHeader *aheader) } void -PushArena(GCMarker *gcmarker, ArenaHeader *aheader) +gc::PushArena(GCMarker *gcmarker, ArenaHeader *aheader) { switch (MapAllocToTraceKind(aheader->getAllocKind())) { case JSTRACE_OBJECT: @@ -997,10 +1026,6 @@ PushArena(GCMarker *gcmarker, ArenaHeader *aheader) } } -} /* namespace gc */ - -using namespace js::gc; - struct SlotArrayLayout { union { @@ -1325,7 +1350,7 @@ GCMarker::drainMarkStack(SliceBudget &budget) } void -TraceChildren(JSTracer *trc, void *thing, JSGCTraceKind kind) +js::TraceChildren(JSTracer *trc, void *thing, JSGCTraceKind kind) { switch (kind) { case JSTRACE_OBJECT: @@ -1365,12 +1390,10 @@ TraceChildren(JSTracer *trc, void *thing, JSGCTraceKind kind) } void -CallTracer(JSTracer *trc, void *thing, JSGCTraceKind kind) +js::CallTracer(JSTracer *trc, void *thing, JSGCTraceKind kind) { JS_ASSERT(thing); void *tmp = thing; MarkKind(trc, &tmp, kind); JS_ASSERT(tmp == thing); } - -} /* namespace js */ diff --git a/js/src/gc/Memory.cpp b/js/src/gc/Memory.cpp index 0868bd9962c5..e2bec9717391 100644 --- a/js/src/gc/Memory.cpp +++ b/js/src/gc/Memory.cpp @@ -7,17 +7,16 @@ #include "mozilla/Assertions.h" -#include "jstypes.h" +#include "jsapi.h" +#include "js/HeapAPI.h" #include "js/Utility.h" #include "gc/Memory.h" -namespace js { -namespace gc { +using namespace js; +using namespace js::gc; /* Unused memory decommiting requires the arena size match the page size. */ -extern const size_t PageSize; -extern const size_t ArenaSize; static bool DecommitEnabled() { @@ -31,7 +30,7 @@ DecommitEnabled() static size_t AllocationGranularity = 0; void -InitMemorySubsystem() +gc::InitMemorySubsystem() { SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); @@ -43,7 +42,7 @@ InitMemorySubsystem() } void * -MapAlignedPages(size_t size, size_t alignment) +gc::MapAlignedPages(size_t size, size_t alignment) { JS_ASSERT(size >= alignment); JS_ASSERT(size % alignment == 0); @@ -86,13 +85,13 @@ MapAlignedPages(size_t size, size_t alignment) } void -UnmapPages(void *p, size_t size) +gc::UnmapPages(void *p, size_t size) { JS_ALWAYS_TRUE(VirtualFree(p, 0, MEM_RELEASE)); } bool -MarkPagesUnused(void *p, size_t size) +gc::MarkPagesUnused(void *p, size_t size) { if (!DecommitEnabled()) return false; @@ -103,14 +102,14 @@ MarkPagesUnused(void *p, size_t size) } bool -MarkPagesInUse(void *p, size_t size) +gc::MarkPagesInUse(void *p, size_t size) { JS_ASSERT(uintptr_t(p) % PageSize == 0); return true; } size_t -GetPageFaultCount() +gc::GetPageFaultCount() { PROCESS_MEMORY_COUNTERS pmc; if (!GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) @@ -127,12 +126,12 @@ GetPageFaultCount() #define OS2_MAX_RECURSIONS 16 void -InitMemorySubsystem() +gc::InitMemorySubsystem() { } void -UnmapPages(void *addr, size_t size) +gc::UnmapPages(void *addr, size_t size) { if (!DosFreeMem(addr)) return; @@ -153,7 +152,7 @@ UnmapPages(void *addr, size_t size) } static void * -MapAlignedPagesRecursively(size_t size, size_t alignment, int& recursions) +gc::MapAlignedPagesRecursively(size_t size, size_t alignment, int& recursions) { if (++recursions >= OS2_MAX_RECURSIONS) return NULL; @@ -194,7 +193,7 @@ MapAlignedPagesRecursively(size_t size, size_t alignment, int& recursions) } void * -MapAlignedPages(size_t size, size_t alignment) +gc::MapAlignedPages(size_t size, size_t alignment) { JS_ASSERT(size >= alignment); JS_ASSERT(size % alignment == 0); @@ -230,21 +229,21 @@ MapAlignedPages(size_t size, size_t alignment) } bool -MarkPagesUnused(void *p, size_t size) +gc::MarkPagesUnused(void *p, size_t size) { JS_ASSERT(uintptr_t(p) % PageSize == 0); return true; } bool -MarkPagesInUse(void *p, size_t size) +gc::MarkPagesInUse(void *p, size_t size) { JS_ASSERT(uintptr_t(p) % PageSize == 0); return true; } size_t -GetPageFaultCount() +gc::GetPageFaultCount() { return 0; } @@ -259,12 +258,12 @@ GetPageFaultCount() #endif void -InitMemorySubsystem() +gc::InitMemorySubsystem() { } void * -MapAlignedPages(size_t size, size_t alignment) +gc::MapAlignedPages(size_t size, size_t alignment) { JS_ASSERT(size >= alignment); JS_ASSERT(size % alignment == 0); @@ -281,27 +280,27 @@ MapAlignedPages(size_t size, size_t alignment) } void -UnmapPages(void *p, size_t size) +gc::UnmapPages(void *p, size_t size) { JS_ALWAYS_TRUE(0 == munmap((caddr_t)p, size)); } bool -MarkPagesUnused(void *p, size_t size) +gc::MarkPagesUnused(void *p, size_t size) { JS_ASSERT(uintptr_t(p) % PageSize == 0); return true; } bool -MarkPagesInUse(void *p, size_t size) +gc::MarkPagesInUse(void *p, size_t size) { JS_ASSERT(uintptr_t(p) % PageSize == 0); return true; } size_t -GetPageFaultCount() +gc::GetPageFaultCount() { return 0; } @@ -314,7 +313,7 @@ GetPageFaultCount() #include void -InitMemorySubsystem() +gc::InitMemorySubsystem() { if (size_t(sysconf(_SC_PAGESIZE)) != PageSize) { fprintf(stderr,"SpiderMonkey compiled with incorrect page size; please update js/public/HeapAPI.h.\n"); @@ -323,7 +322,7 @@ InitMemorySubsystem() } void * -MapAlignedPages(size_t size, size_t alignment) +gc::MapAlignedPages(size_t size, size_t alignment) { JS_ASSERT(size >= alignment); JS_ASSERT(size % alignment == 0); @@ -360,13 +359,13 @@ MapAlignedPages(size_t size, size_t alignment) } void -UnmapPages(void *p, size_t size) +gc::UnmapPages(void *p, size_t size) { JS_ALWAYS_TRUE(0 == munmap(p, size)); } bool -MarkPagesUnused(void *p, size_t size) +gc::MarkPagesUnused(void *p, size_t size) { if (!DecommitEnabled()) return false; @@ -377,14 +376,14 @@ MarkPagesUnused(void *p, size_t size) } bool -MarkPagesInUse(void *p, size_t size) +gc::MarkPagesInUse(void *p, size_t size) { JS_ASSERT(uintptr_t(p) % PageSize == 0); return true; } size_t -GetPageFaultCount() +gc::GetPageFaultCount() { struct rusage usage; int err = getrusage(RUSAGE_SELF, &usage); @@ -396,6 +395,3 @@ GetPageFaultCount() #else #error "Memory mapping functions are not defined for your OS." #endif - -} /* namespace gc */ -} /* namespace js */ diff --git a/js/src/gc/Statistics.cpp b/js/src/gc/Statistics.cpp index f83f3dbc4a49..a1dd2797790f 100644 --- a/js/src/gc/Statistics.cpp +++ b/js/src/gc/Statistics.cpp @@ -22,13 +22,13 @@ #include "gc/Barrier-inl.h" -namespace js { -namespace gcstats { +using namespace js; +using namespace js::gcstats; /* Except for the first and last, slices of less than 42ms are not reported. */ static const int64_t SLICE_MIN_REPORT_TIME = 42 * PRMJ_USEC_PER_MSEC; -class StatisticsSerializer +class gcstats::StatisticsSerializer { typedef Vector CharBuffer; CharBuffer buf_; @@ -682,6 +682,3 @@ Statistics::computeMMU(int64_t window) return double(window - gcMax) / window; } - -} /* namespace gcstats */ -} /* namespace js */ diff --git a/js/src/gc/StoreBuffer.cpp b/js/src/gc/StoreBuffer.cpp index 3a8eeff2e9ca..4a57b8d1da49 100644 --- a/js/src/gc/StoreBuffer.cpp +++ b/js/src/gc/StoreBuffer.cpp @@ -13,8 +13,7 @@ #include "gc/StoreBuffer.h" #include "vm/ObjectImpl-inl.h" -namespace js { -namespace gc { +using namespace js::gc; /*** MonoTypeBuffer ***/ @@ -265,7 +264,4 @@ template class StoreBuffer::MonoTypeBuffer; template class StoreBuffer::RelocatableMonoTypeBuffer; template class StoreBuffer::RelocatableMonoTypeBuffer; -} /* namespace gc */ -} /* namespace js */ - #endif /* JSGC_GENERATIONAL */ From 40e3eba86b1f58bcda1e6dc2c38dd6a182891ee3 Mon Sep 17 00:00:00 2001 From: Srinath N Date: Tue, 20 Nov 2012 17:52:22 -0500 Subject: [PATCH 75/75] Bug 809884 - Add 'spelt' and 'spelled' the en-US dictionary; r=ehsan DONTBUILD --- .../dictionary-sources/upstream-hunspell.diff | 48 ++++++++++--------- .../locales/en-US/hunspell/en-US.dic | 4 +- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/upstream-hunspell.diff b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/upstream-hunspell.diff index 1a2a53b5fb52..c2d0da6fd001 100644 --- a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/upstream-hunspell.diff +++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/upstream-hunspell.diff @@ -9503,69 +9503,73 @@ < sonofabitch --- > sonofabitch/! -44371a50184 +44346a50159 +> spelled +44348a50162 +> spelt +44371a50186 > spick/S! -44383c50196 +44383c50198 < spik/S --- > spik/S! -46106a51920 +46106a51922 > syllabi -46160c51974 +46160c51976 < synch/GMD --- > synch/GMDS -46167d51980 +46167d51982 < synchs -46203,46204c52016,52017 +46203,46204c52018,52019 < sysadmin/S < sysop/S --- > sysadmin/MS > sysop/MS -46752a52566 +46752a52568 > terabit/MS -46753a52568,52569 +46753a52570,52571 > terahertz/M > terapixel/MS -46817a52634 +46817a52636 > testcase/MS -46831a52649 +46831a52651 > testsuite/MS -46925a52744 +46925a52746 > theremin/MS -47755a53575 +47755a53577 > transfect/DSMG -47774a53595,53596 +47774a53597,53598 > transgenderism > transgene/MS -47951c53773 +47951c53775 < triage/M --- > triage/MG -48869a54692 +48869a54694 > unlikeable -49211c55034 +49211c55036 < vagina/M --- > vagina/MS -49368,49369c55191 +49368,49369c55193 < velour's < velours's --- > velour/MS -49478a55301 +49478a55303 > vertices -50148a55972 +50148a55974 > weaponize/DSG -50260,50261d56083 +50260,50261d56085 < werwolf/M < werwolves -50728c56550 +50728c56552 < women --- > women/M -50794c56616 +50794c56618 < wop/S! --- > wop/MS! diff --git a/extensions/spellcheck/locales/en-US/hunspell/en-US.dic b/extensions/spellcheck/locales/en-US/hunspell/en-US.dic index e424e219ada7..9a8d7d081d52 100644 --- a/extensions/spellcheck/locales/en-US/hunspell/en-US.dic +++ b/extensions/spellcheck/locales/en-US/hunspell/en-US.dic @@ -1,4 +1,4 @@ -57438 +57440 0/nm 0th/pt 1/n1 @@ -50500,8 +50500,10 @@ spellbinder/M spellbound spellchecker/S spelldown/SM +spelled speller/M spelling/M +spelt spelunker/MS spelunking/M spend/BSRZG