From 2124f457f190a4f345264ff92f3edc4dc5c16921 Mon Sep 17 00:00:00 2001 From: Kushan Joshi <0o3ko0@gmail.com> Date: Tue, 30 Dec 2014 14:07:57 -0500 Subject: [PATCH 01/41] Bug 1116008 - Make FrameMetrics::mCriticalDisplayPort private. r=kats --- gfx/layers/FrameMetrics.h | 33 +++++++++++-------- gfx/layers/LayersLogging.cpp | 2 +- gfx/layers/apz/src/AsyncPanZoomController.cpp | 4 +-- gfx/layers/client/ClientLayerManager.cpp | 4 +-- gfx/layers/client/ClientTiledPaintedLayer.cpp | 4 +-- gfx/layers/client/TiledContentClient.cpp | 4 +-- .../composite/AsyncCompositionManager.cpp | 8 ++--- .../composite/LayerManagerComposite.cpp | 4 +-- .../gtest/TestAsyncPanZoomController.cpp | 2 +- layout/base/nsDisplayList.cpp | 2 +- 10 files changed, 36 insertions(+), 31 deletions(-) diff --git a/gfx/layers/FrameMetrics.h b/gfx/layers/FrameMetrics.h index 1547c611eba..a204e4b41cd 100644 --- a/gfx/layers/FrameMetrics.h +++ b/gfx/layers/FrameMetrics.h @@ -40,9 +40,9 @@ public: FrameMetrics() : mCompositionBounds(0, 0, 0, 0) - , mCriticalDisplayPort(0, 0, 0, 0) , mPresShellResolution(1) , mDisplayPort(0, 0, 0, 0) + , mCriticalDisplayPort(0, 0, 0, 0) , mScrollableRect(0, 0, 0, 0) , mCumulativeResolution(1) , mDevPixelsPerCSSPixel(1) @@ -251,19 +251,6 @@ public: // layout/paint time. ParentLayerRect mCompositionBounds; - // --------------------------------------------------------------------------- - // The following metrics are all in CSS pixels. They are not in any uniform - // space, so each is explained separately. - // - - // If non-empty, the area of a frame's contents that is considered critical - // to paint. Area outside of this area (i.e. area inside mDisplayPort, but - // outside of mCriticalDisplayPort) is considered low-priority, and may be - // painted with lower precision, or not painted at all. - // - // The same restrictions for mDisplayPort apply here. - CSSRect mCriticalDisplayPort; - // --------------------------------------------------------------------------- // The following metrics are dimensionless. // @@ -288,6 +275,16 @@ public: return mDisplayPort; } + void SetCriticalDisplayPort(const CSSRect& aCriticalDisplayPort) + { + mCriticalDisplayPort = aCriticalDisplayPort; + } + + CSSRect GetCriticalDisplayPort() const + { + return mCriticalDisplayPort; + } + void SetCumulativeResolution(const LayoutDeviceToLayerScale& aCumulativeResolution) { mCumulativeResolution = aCumulativeResolution; @@ -539,6 +536,14 @@ private: // width = window.innerWidth + 200, height = window.innerHeight + 200 } CSSRect mDisplayPort; + // If non-empty, the area of a frame's contents that is considered critical + // to paint. Area outside of this area (i.e. area inside mDisplayPort, but + // outside of mCriticalDisplayPort) is considered low-priority, and may be + // painted with lower precision, or not painted at all. + // + // The same restrictions for mDisplayPort apply here. + CSSRect mCriticalDisplayPort; + // The scrollable bounds of a frame. This is determined by reflow. // Ordinarily the x and y will be 0 and the width and height will be the // size of the element being scrolled. However for RTL pages or elements diff --git a/gfx/layers/LayersLogging.cpp b/gfx/layers/LayersLogging.cpp index fa90eef33d4..2c97537ce48 100644 --- a/gfx/layers/LayersLogging.cpp +++ b/gfx/layers/LayersLogging.cpp @@ -176,7 +176,7 @@ AppendToString(std::stringstream& aStream, const FrameMetrics& m, AppendToString(aStream, m.GetSmoothScrollOffset(), "] [ss="); } AppendToString(aStream, m.GetDisplayPort(), "] [dp="); - AppendToString(aStream, m.mCriticalDisplayPort, "] [cdp="); + AppendToString(aStream, m.GetCriticalDisplayPort(), "] [cdp="); AppendToString(aStream, m.GetBackgroundColor(), "] [color="); if (!detailed) { AppendToString(aStream, m.GetScrollId(), "] [scrollId="); diff --git a/gfx/layers/apz/src/AsyncPanZoomController.cpp b/gfx/layers/apz/src/AsyncPanZoomController.cpp index 6e0334a5017..51e346a604b 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.cpp +++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp @@ -2707,9 +2707,9 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri LogRendertraceRect(GetGuid(), "page", "brown", aLayerMetrics.GetScrollableRect()); LogRendertraceRect(GetGuid(), "painted displayport", "lightgreen", aLayerMetrics.GetDisplayPort() + aLayerMetrics.GetScrollOffset()); - if (!aLayerMetrics.mCriticalDisplayPort.IsEmpty()) { + if (!aLayerMetrics.GetCriticalDisplayPort().IsEmpty()) { LogRendertraceRect(GetGuid(), "painted critical displayport", "darkgreen", - aLayerMetrics.mCriticalDisplayPort + aLayerMetrics.GetScrollOffset()); + aLayerMetrics.GetCriticalDisplayPort() + aLayerMetrics.GetScrollOffset()); } mPaintThrottler.TaskComplete(GetFrameTime()); diff --git a/gfx/layers/client/ClientLayerManager.cpp b/gfx/layers/client/ClientLayerManager.cpp index d266e34adad..b1c52387ad1 100644 --- a/gfx/layers/client/ClientLayerManager.cpp +++ b/gfx/layers/client/ClientLayerManager.cpp @@ -752,8 +752,8 @@ ClientLayerManager::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, // gfx/layers/ipc/CompositorParent.cpp::TransformShadowTree. CSSToLayerScale paintScale = aMetrics.LayersPixelsPerCSSPixel(); const CSSRect& metricsDisplayPort = - (aDrawingCritical && !aMetrics.mCriticalDisplayPort.IsEmpty()) ? - aMetrics.mCriticalDisplayPort : aMetrics.GetDisplayPort(); + (aDrawingCritical && !aMetrics.GetCriticalDisplayPort().IsEmpty()) ? + aMetrics.GetCriticalDisplayPort() : aMetrics.GetDisplayPort(); LayerRect displayPort = (metricsDisplayPort + aMetrics.GetScrollOffset()) * paintScale; ParentLayerPoint scrollOffset; diff --git a/gfx/layers/client/ClientTiledPaintedLayer.cpp b/gfx/layers/client/ClientTiledPaintedLayer.cpp index d3190b20986..c219fa354a1 100644 --- a/gfx/layers/client/ClientTiledPaintedLayer.cpp +++ b/gfx/layers/client/ClientTiledPaintedLayer.cpp @@ -152,7 +152,7 @@ ClientTiledPaintedLayer::BeginPaint() // Compute the critical display port that applies to this layer in the // LayoutDevice space of this layer. ParentLayerRect criticalDisplayPort = - (displayportMetrics.mCriticalDisplayPort * displayportMetrics.GetZoom()) + (displayportMetrics.GetCriticalDisplayPort() * displayportMetrics.GetZoom()) + displayportMetrics.mCompositionBounds.TopLeft(); mPaintData.mCriticalDisplayPort = RoundedOut( ApplyParentLayerToLayerTransform(transformDisplayPortToLayer, criticalDisplayPort)); @@ -189,7 +189,7 @@ ClientTiledPaintedLayer::UseFastPath() bool multipleTransactionsNeeded = gfxPlatform::GetPlatform()->UseProgressivePaint() || gfxPrefs::UseLowPrecisionBuffer() - || !parentMetrics.mCriticalDisplayPort.IsEmpty(); + || !parentMetrics.GetCriticalDisplayPort().IsEmpty(); bool isFixed = GetIsFixedPosition() || GetParent()->GetIsFixedPosition(); return !multipleTransactionsNeeded || isFixed || parentMetrics.GetDisplayPort().IsEmpty(); } diff --git a/gfx/layers/client/TiledContentClient.cpp b/gfx/layers/client/TiledContentClient.cpp index e7bb13b6033..7dc70ed31f6 100644 --- a/gfx/layers/client/TiledContentClient.cpp +++ b/gfx/layers/client/TiledContentClient.cpp @@ -257,9 +257,9 @@ SharedFrameMetricsHelper::AboutToCheckerboard(const FrameMetrics& aContentMetric // converted to app units and then back to CSS pixels before being put in the FrameMetrics. // This process can introduce some rounding error, so we inflate the rect by one app unit // to account for that. - CSSRect painted = (aContentMetrics.mCriticalDisplayPort.IsEmpty() + CSSRect painted = (aContentMetrics.GetCriticalDisplayPort().IsEmpty() ? aContentMetrics.GetDisplayPort() - : aContentMetrics.mCriticalDisplayPort) + : aContentMetrics.GetCriticalDisplayPort()) + aContentMetrics.GetScrollOffset(); painted.Inflate(CSSMargin::FromAppUnits(nsMargin(1, 1, 1, 1))); diff --git a/gfx/layers/composite/AsyncCompositionManager.cpp b/gfx/layers/composite/AsyncCompositionManager.cpp index 4bc35e454fe..876f010ccd6 100644 --- a/gfx/layers/composite/AsyncCompositionManager.cpp +++ b/gfx/layers/composite/AsyncCompositionManager.cpp @@ -604,8 +604,8 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer) const FrameMetrics& metrics = aLayer->GetFrameMetrics(i); CSSToLayerScale paintScale = metrics.LayersPixelsPerCSSPixel(); - CSSRect displayPort(metrics.mCriticalDisplayPort.IsEmpty() ? - metrics.GetDisplayPort() : metrics.mCriticalDisplayPort); + CSSRect displayPort(metrics.GetCriticalDisplayPort().IsEmpty() ? + metrics.GetDisplayPort() : metrics.GetCriticalDisplayPort()); ScreenPoint offset(0, 0); // XXX this call to SyncFrameMetrics is not currently being used. It will be cleaned // up as part of bug 776030 or one of its dependencies. @@ -859,9 +859,9 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer) // notifications, so that Java can take these into account in its response. // Calculate the absolute display port to send to Java LayerIntRect displayPort = RoundedToInt( - (metrics.mCriticalDisplayPort.IsEmpty() + (metrics.GetCriticalDisplayPort().IsEmpty() ? metrics.GetDisplayPort() - : metrics.mCriticalDisplayPort + : metrics.GetCriticalDisplayPort() ) * geckoZoom); displayPort += scrollOffsetLayerPixels; diff --git a/gfx/layers/composite/LayerManagerComposite.cpp b/gfx/layers/composite/LayerManagerComposite.cpp index 8e19491533e..4b1768e8830 100644 --- a/gfx/layers/composite/LayerManagerComposite.cpp +++ b/gfx/layers/composite/LayerManagerComposite.cpp @@ -928,10 +928,10 @@ LayerManagerComposite::ComputeRenderIntegrity() // Work out how much of the critical display-port covers the screen bool hasLowPrecision = false; - if (!metrics.mCriticalDisplayPort.IsEmpty()) { + if (!metrics.GetCriticalDisplayPort().IsEmpty()) { hasLowPrecision = true; highPrecisionMultiplier = - GetDisplayportCoverage(metrics.mCriticalDisplayPort, transform, screenRect); + GetDisplayportCoverage(metrics.GetCriticalDisplayPort(), transform, screenRect); } // Work out how much of the display-port covers the screen diff --git a/gfx/tests/gtest/TestAsyncPanZoomController.cpp b/gfx/tests/gtest/TestAsyncPanZoomController.cpp index c2931074570..1204401dd2b 100644 --- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp +++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp @@ -225,7 +225,7 @@ TestFrameMetrics() fm.SetDisplayPort(CSSRect(0, 0, 10, 10)); fm.mCompositionBounds = ParentLayerRect(0, 0, 10, 10); - fm.mCriticalDisplayPort = CSSRect(0, 0, 10, 10); + fm.SetCriticalDisplayPort(CSSRect(0, 0, 10, 10)); fm.SetScrollableRect(CSSRect(0, 0, 100, 100)); return fm; diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 9e021d45e3b..f5431403daf 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -721,7 +721,7 @@ nsDisplayScrollLayer::ComputeFrameMetrics(nsIFrame* aForFrame, metrics.GetDisplayPort()); } if (nsLayoutUtils::GetCriticalDisplayPort(content, &dp)) { - metrics.mCriticalDisplayPort = CSSRect::FromAppUnits(dp); + metrics.SetCriticalDisplayPort(CSSRect::FromAppUnits(dp)); } DisplayPortMarginsPropertyData* marginsData = static_cast(content->GetProperty(nsGkAtoms::DisplayPortMargins)); From 8c483075ea862d069965bf6f5b6d10701b84a91a Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Thu, 25 Dec 2014 16:21:34 -0500 Subject: [PATCH 02/41] Bug 1116358 - Directly call Release() on |this| when closing a GMP encoder/decoder proxies; r=cpearce This is needed in order to avoid calling Release() on a smart pointer. --- dom/media/gmp/GMPAudioDecoderParent.cpp | 2 +- dom/media/gmp/GMPVideoDecoderParent.cpp | 2 +- dom/media/gmp/GMPVideoEncoderParent.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dom/media/gmp/GMPAudioDecoderParent.cpp b/dom/media/gmp/GMPAudioDecoderParent.cpp index 55b9fde9f8b..b8a72922d50 100644 --- a/dom/media/gmp/GMPAudioDecoderParent.cpp +++ b/dom/media/gmp/GMPAudioDecoderParent.cpp @@ -149,7 +149,7 @@ GMPAudioDecoderParent::Close() // In case this is the last reference nsRefPtr kungfudeathgrip(this); - NS_RELEASE(kungfudeathgrip); + Release(); Shutdown(); return NS_OK; diff --git a/dom/media/gmp/GMPVideoDecoderParent.cpp b/dom/media/gmp/GMPVideoDecoderParent.cpp index 319f78d4228..33690f0438e 100644 --- a/dom/media/gmp/GMPVideoDecoderParent.cpp +++ b/dom/media/gmp/GMPVideoDecoderParent.cpp @@ -76,7 +76,7 @@ GMPVideoDecoderParent::Close() // In case this is the last reference nsRefPtr kungfudeathgrip(this); - NS_RELEASE(kungfudeathgrip); + Release(); Shutdown(); } diff --git a/dom/media/gmp/GMPVideoEncoderParent.cpp b/dom/media/gmp/GMPVideoEncoderParent.cpp index 6f2af86d9d6..f17190dab6c 100644 --- a/dom/media/gmp/GMPVideoEncoderParent.cpp +++ b/dom/media/gmp/GMPVideoEncoderParent.cpp @@ -91,7 +91,7 @@ GMPVideoEncoderParent::Close() // In case this is the last reference nsRefPtr kungfudeathgrip(this); - NS_RELEASE(kungfudeathgrip); + Release(); Shutdown(); } From cbe75bc86de1ad8068e35dc7f4d488efafea57b9 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Tue, 30 Dec 2014 12:22:45 -0800 Subject: [PATCH 03/41] Bug 1116355 - Throw when setting SourceBuffer mode to 'sequence'. r=karlt,rs=Ms2ger --- dom/media/mediasource/SourceBuffer.cpp | 4 +++ dom/media/mediasource/test/mochitest.ini | 1 + .../mediasource/test/test_SetModeThrows.html | 34 +++++++++++++++++++ .../mediasource-sourcebuffer-mode.html.ini | 2 ++ 4 files changed, 41 insertions(+) create mode 100644 dom/media/mediasource/test/test_SetModeThrows.html diff --git a/dom/media/mediasource/SourceBuffer.cpp b/dom/media/mediasource/SourceBuffer.cpp index 838e02c56ba..88b352b42f9 100644 --- a/dom/media/mediasource/SourceBuffer.cpp +++ b/dom/media/mediasource/SourceBuffer.cpp @@ -49,6 +49,10 @@ SourceBuffer::SetMode(SourceBufferAppendMode aMode, ErrorResult& aRv) aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return; } + if (aMode == SourceBufferAppendMode::Sequence) { + aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); + return; + } MOZ_ASSERT(mMediaSource->ReadyState() != MediaSourceReadyState::Closed); if (mMediaSource->ReadyState() == MediaSourceReadyState::Ended) { mMediaSource->SetReadyState(MediaSourceReadyState::Open); diff --git a/dom/media/mediasource/test/mochitest.ini b/dom/media/mediasource/test/mochitest.ini index fa80aa756b8..fa06f72d2c7 100644 --- a/dom/media/mediasource/test/mochitest.ini +++ b/dom/media/mediasource/test/mochitest.ini @@ -19,6 +19,7 @@ skip-if = (toolkit == 'android' || buildapp == 'mulet') #timeout android/mulet o [test_SeekableAfterEndOfStreamSplit.html] [test_SeekableBeforeEndOfStream.html] [test_SeekableBeforeEndOfStreamSplit.html] +[test_SetModeThrows.html] [test_SplitAppendDelay.html] [test_SplitAppend.html] [test_WaitingOnMissingData.html] diff --git a/dom/media/mediasource/test/test_SetModeThrows.html b/dom/media/mediasource/test/test_SetModeThrows.html new file mode 100644 index 00000000000..8254b8ca050 --- /dev/null +++ b/dom/media/mediasource/test/test_SetModeThrows.html @@ -0,0 +1,34 @@ + + + + MSE: append initialization only + + + + + +
+
+
+ + diff --git a/testing/web-platform/meta/media-source/mediasource-sourcebuffer-mode.html.ini b/testing/web-platform/meta/media-source/mediasource-sourcebuffer-mode.html.ini index 85f1f83353d..527f68c3a45 100644 --- a/testing/web-platform/meta/media-source/mediasource-sourcebuffer-mode.html.ini +++ b/testing/web-platform/meta/media-source/mediasource-sourcebuffer-mode.html.ini @@ -2,4 +2,6 @@ type: testharness [Test setting SourceBuffer.mode and SourceBuffer.timestampOffset while parsing media segment.] expected: FAIL + [Test setting SourceBuffer.mode] + expected: FAIL # Not supported yet - see bug 1116353 From 742d62599d06ae8a24d77f874269c6c22aef9f2c Mon Sep 17 00:00:00 2001 From: Alexander Surkov Date: Tue, 30 Dec 2014 15:43:49 -0500 Subject: [PATCH 04/41] Bug 1113389 - loading google creates accessibles without firing show events, r=tbsaunde --- accessible/generic/Accessible-inl.h | 8 - accessible/generic/Accessible.cpp | 15 +- accessible/generic/Accessible.h | 28 ++- accessible/generic/DocAccessible.cpp | 220 ++++++++++-------- accessible/generic/DocAccessible.h | 14 +- accessible/html/HTMLSelectAccessible.cpp | 1 + .../tests/mochitest/events/test_mutation.html | 28 +++ .../tests/mochitest/tree/test_select.html | 2 +- .../mochitest/treeupdate/test_optgroup.html | 3 +- .../mochitest/treeupdate/test_select.html | 3 +- 10 files changed, 184 insertions(+), 138 deletions(-) diff --git a/accessible/generic/Accessible-inl.h b/accessible/generic/Accessible-inl.h index ec92e9e6f2f..cfe4eece79f 100644 --- a/accessible/generic/Accessible-inl.h +++ b/accessible/generic/Accessible-inl.h @@ -67,14 +67,6 @@ Accessible::ScrollTo(uint32_t aHow) const nsCoreUtils::ScrollTo(mDoc->PresShell(), mContent, aHow); } -inline bool -Accessible::UpdateChildren() -{ - AutoTreeMutation mut(this); - InvalidateChildren(); - return EnsureChildren(); -} - } // namespace a11y } // namespace mozilla diff --git a/accessible/generic/Accessible.cpp b/accessible/generic/Accessible.cpp index 07ab7fc2930..8ee79e62995 100644 --- a/accessible/generic/Accessible.cpp +++ b/accessible/generic/Accessible.cpp @@ -2012,8 +2012,7 @@ Accessible::InvalidateChildren() { int32_t childCount = mChildren.Length(); for (int32_t childIdx = 0; childIdx < childCount; childIdx++) { - Accessible* child = mChildren.ElementAt(childIdx); - child->UnbindFromParent(); + mChildren.ElementAt(childIdx)->UnbindFromParent(); } mEmbeddedObjCollector = nullptr; @@ -2446,23 +2445,17 @@ Accessible::TestChildCache(Accessible* aCachedChild) const #endif } -// Accessible public -bool +void Accessible::EnsureChildren() { - if (IsDefunct()) { - SetChildrenFlag(eChildrenUninitialized); - return true; - } + NS_ASSERTION(!IsDefunct(), "Caching children for defunct accessible!"); if (!IsChildrenFlag(eChildrenUninitialized)) - return false; + return; // State is embedded children until text leaf accessible is appended. SetChildrenFlag(eEmbeddedChildren); // Prevent reentry - CacheChildren(); - return false; } Accessible* diff --git a/accessible/generic/Accessible.h b/accessible/generic/Accessible.h index b1009074b78..bb235b85f43 100644 --- a/accessible/generic/Accessible.h +++ b/accessible/generic/Accessible.h @@ -366,14 +366,9 @@ public: { mRoleMapEntry = aRoleMapEntry; } /** - * Update the children cache. + * Cache children if necessary. */ - bool UpdateChildren(); - - /** - * Cache children if necessary. Return true if the accessible is defunct. - */ - bool EnsureChildren(); + void EnsureChildren(); /** * Set the child count to -1 (unknown) and null out cached child pointers. @@ -587,6 +582,7 @@ public: HyperTextAccessible* AsHyperText(); bool IsHTMLBr() const { return mType == eHTMLBRType; } + bool IsHTMLCombobox() const { return mType == eHTMLComboboxType; } bool IsHTMLFileInput() const { return mType == eHTMLFileInputType; } bool IsHTMLListItem() const { return mType == eHTMLLiType; } @@ -870,6 +866,19 @@ public: bool NeedsDOMUIEvent() const { return !(mStateFlags & eIgnoreDOMUIEvent); } + /** + * Get/set survivingInUpdate bit on child indicating that parent recollects + * its children. + */ + bool IsSurvivingInUpdate() const { return mStateFlags & eSurvivingInUpdate; } + void SetSurvivingInUpdate(bool aIsSurviving) + { + if (aIsSurviving) + mStateFlags |= eSurvivingInUpdate; + else + mStateFlags &= ~eSurvivingInUpdate; + } + /** * Return true if this accessible has a parent whose name depends on this * accessible. @@ -953,8 +962,9 @@ protected: eGroupInfoDirty = 1 << 5, // accessible needs to update group info eSubtreeMutating = 1 << 6, // subtree is being mutated eIgnoreDOMUIEvent = 1 << 7, // don't process DOM UI events for a11y events + eSurvivingInUpdate = 1 << 8, // parent drops children to recollect them - eLastStateFlag = eIgnoreDOMUIEvent + eLastStateFlag = eSurvivingInUpdate }; /** @@ -1068,7 +1078,7 @@ protected: int32_t mIndexInParent; static const uint8_t kChildrenFlagsBits = 2; - static const uint8_t kStateFlagsBits = 8; + static const uint8_t kStateFlagsBits = 9; static const uint8_t kContextFlagsBits = 1; static const uint8_t kTypeBits = 6; static const uint8_t kGenericTypesBits = 13; diff --git a/accessible/generic/DocAccessible.cpp b/accessible/generic/DocAccessible.cpp index 2dcb0a66669..7c72a7390ec 100644 --- a/accessible/generic/DocAccessible.cpp +++ b/accessible/generic/DocAccessible.cpp @@ -1308,19 +1308,10 @@ DocAccessible::ProcessInvalidationList() // children are recached. for (uint32_t idx = 0; idx < mInvalidationList.Length(); idx++) { nsIContent* content = mInvalidationList[idx]; - Accessible* accessible = GetAccessible(content); - if (!accessible) { + if (!HasAccessible(content)) { Accessible* container = GetContainerAccessible(content); - if (container) { - container->UpdateChildren(); - accessible = GetAccessible(content); - } - } - - // Make sure the subtree is created. - if (accessible) { - AutoTreeMutation mut(accessible); - CacheChildrenInSubtree(accessible); + if (container) + UpdateTreeOnInsertion(container); } } @@ -1633,8 +1624,6 @@ DocAccessible::ProcessContentInserted(Accessible* aContainer, if (!HasAccessible(aContainer->GetNode())) return; - bool containerNotUpdated = true; - for (uint32_t idx = 0; idx < aInsertedContent->Length(); idx++) { // The container might be changed, for example, because of the subsequent // overlapping content insertion (i.e. other content was inserted between @@ -1644,108 +1633,73 @@ DocAccessible::ProcessContentInserted(Accessible* aContainer, // Note, the inserted content might be not in tree at all at this point what // means there's no container. Ignore the insertion too. - Accessible* presentContainer = + Accessible* container = GetContainerAccessible(aInsertedContent->ElementAt(idx)); - if (presentContainer != aContainer) + if (container != aContainer) continue; - if (containerNotUpdated) { - containerNotUpdated = false; - - if (aContainer == this) { - // If new root content has been inserted then update it. - nsIContent* rootContent = nsCoreUtils::GetRoleContent(mDocumentNode); - if (rootContent != mContent) { - mContent = rootContent; - SetRoleMapEntry(aria::GetRoleMap(mContent)); - } - - // Continue to update the tree even if we don't have root content. - // For example, elements may be inserted under the document element while - // there is no HTML body element. + if (container == this) { + // If new root content has been inserted then update it. + nsIContent* rootContent = nsCoreUtils::GetRoleContent(mDocumentNode); + if (rootContent != mContent) { + mContent = rootContent; + SetRoleMapEntry(aria::GetRoleMap(mContent)); } - // XXX: Invalidate parent-child relations for container accessible and its - // children because there's no good way to find insertion point of new child - // accessibles into accessible tree. We need to invalidate children even - // there's no inserted accessibles in the end because accessible children - // are created while parent recaches child accessibles. - // XXX Group invalidation here may be redundant with invalidation in - // UpdateTree. - AutoTreeMutation mut(aContainer); - aContainer->InvalidateChildren(); - CacheChildrenInSubtree(aContainer); + // Continue to update the tree even if we don't have root content. + // For example, elements may be inserted under the document element while + // there is no HTML body element. } - UpdateTree(aContainer, aInsertedContent->ElementAt(idx), true); + // HTML comboboxes have no-content list accessible as an intermidiate + // containing all options. + if (container->IsHTMLCombobox()) + container = container->FirstChild(); + + // We have a DOM/layout change under the container accessible, and its tree + // might need an update. Since DOM/layout change of the element may affect + // on the accessibleness of adjacent elements (for example, insertion of + // extra HTML:body make the old body accessible) then we have to recache + // children of the container, and then fire show/hide events for a change. + UpdateTreeOnInsertion(container); + break; } } void -DocAccessible::UpdateTree(Accessible* aContainer, nsIContent* aChildNode, - bool aIsInsert) +DocAccessible::UpdateTreeOnInsertion(Accessible* aContainer) { - uint32_t updateFlags = eNoAccessible; + for (uint32_t idx = 0; idx < aContainer->ContentChildCount(); idx++) { + Accessible* child = aContainer->ContentChildAt(idx); + child->SetSurvivingInUpdate(true); + } - // If child node is not accessible then look for its accessible children. - Accessible* child = GetAccessible(aChildNode); -#ifdef A11Y_LOG - if (logging::IsEnabled(logging::eTree)) { - logging::MsgBegin("TREE", "process content %s", - (aIsInsert ? "insertion" : "removal")); - logging::Node("container", aContainer->GetNode()); - logging::Node("child", aChildNode); - if (child) - logging::Address("child", child); - else - logging::MsgEntry("child accessible: null"); - - logging::MsgEnd(); - } -#endif + AutoTreeMutation mut(aContainer); + aContainer->InvalidateChildren(); + aContainer->EnsureChildren(); nsRefPtr reorderEvent = new AccReorderEvent(aContainer); - AutoTreeMutation mut(aContainer); - if (child) { - updateFlags |= UpdateTreeInternal(child, aIsInsert, reorderEvent); - } else { - if (aIsInsert) { - TreeWalker walker(aContainer, aChildNode, TreeWalker::eWalkCache); - - while ((child = walker.NextChild())) - updateFlags |= UpdateTreeInternal(child, aIsInsert, reorderEvent); - } else { - // aChildNode may not coorespond to a particular accessible, to handle - // this we go through all the children of aContainer. Then if a child - // has aChildNode as an ancestor, or does not have the node for - // aContainer as an ancestor remove that child of aContainer. Note that - // when we are called aChildNode may already have been removed - // from the DOM so we can't expect it to have a parent or what was it's - // parent to have it as a child. - nsINode* containerNode = aContainer->GetNode(); - for (uint32_t idx = 0; idx < aContainer->ContentChildCount();) { - Accessible* child = aContainer->ContentChildAt(idx); - - // If accessible doesn't have its own content then we assume parent - // will handle its update. If child is DocAccessible then we don't - // handle updating it here either. - if (!child->HasOwnContent() || child->IsDoc()) { - idx++; - continue; - } - - nsINode* childNode = child->GetContent(); - while (childNode != aChildNode && childNode != containerNode && - (childNode = childNode->GetParentNode())); - - if (childNode != containerNode) { - updateFlags |= UpdateTreeInternal(child, false, reorderEvent); - } else { - idx++; - } - } + uint32_t updateFlags = eNoAccessible; + for (uint32_t idx = 0; idx < aContainer->ContentChildCount(); idx++) { + Accessible* child = aContainer->ContentChildAt(idx); + if (child->IsSurvivingInUpdate()) { + child->SetSurvivingInUpdate(false); + continue; } + + // A new child has been created, update its tree. +#ifdef A11Y_LOG + if (logging::IsEnabled(logging::eTree)) { + logging::MsgBegin("TREE", "process content insertion"); + logging::Node("container", aContainer->GetNode()); + logging::Node("child", child->GetContent()); + logging::Address("child", child); + logging::MsgEnd(); + } +#endif + + updateFlags |= UpdateTreeInternal(child, true, reorderEvent); } // Content insertion/removal is not cause of accessible tree change. @@ -1754,7 +1708,7 @@ DocAccessible::UpdateTree(Accessible* aContainer, nsIContent* aChildNode, // Check to see if change occurred inside an alert, and fire an EVENT_ALERT // if it did. - if (aIsInsert && !(updateFlags & eAlertAccessible)) { + if (!(updateFlags & eAlertAccessible)) { // XXX: tree traversal is perf issue, accessible should know if they are // children of alert accessible to avoid this. Accessible* ancestor = aContainer; @@ -1773,9 +1727,71 @@ DocAccessible::UpdateTree(Accessible* aContainer, nsIContent* aChildNode, } MaybeNotifyOfValueChange(aContainer); + FireDelayedEvent(reorderEvent); +} - // Fire reorder event so the MSAA clients know the children have changed. Also - // the event is used internally by MSAA layer. +void +DocAccessible::UpdateTreeOnRemoval(Accessible* aContainer, nsIContent* aChildNode) +{ + // If child node is not accessible then look for its accessible children. + Accessible* child = GetAccessible(aChildNode); +#ifdef A11Y_LOG + if (logging::IsEnabled(logging::eTree)) { + logging::MsgBegin("TREE", "process content removal"); + logging::Node("container", aContainer->GetNode()); + logging::Node("child", aChildNode); + if (child) + logging::Address("child", child); + else + logging::MsgEntry("child accessible: null"); + + logging::MsgEnd(); + } +#endif + + uint32_t updateFlags = eNoAccessible; + nsRefPtr reorderEvent = new AccReorderEvent(aContainer); + AutoTreeMutation mut(aContainer); + + if (child) { + updateFlags |= UpdateTreeInternal(child, false, reorderEvent); + } else { + // aChildNode may not coorespond to a particular accessible, to handle + // this we go through all the children of aContainer. Then if a child + // has aChildNode as an ancestor, or does not have the node for + // aContainer as an ancestor remove that child of aContainer. Note that + // when we are called aChildNode may already have been removed from the DOM + // so we can't expect it to have a parent or what was it's parent to have + // it as a child. + nsINode* containerNode = aContainer->GetNode(); + for (uint32_t idx = 0; idx < aContainer->ContentChildCount();) { + Accessible* child = aContainer->ContentChildAt(idx); + + // If accessible doesn't have its own content then we assume parent + // will handle its update. If child is DocAccessible then we don't + // handle updating it here either. + if (!child->HasOwnContent() || child->IsDoc()) { + idx++; + continue; + } + + nsINode* childNode = child->GetContent(); + while (childNode != aChildNode && childNode != containerNode && + (childNode = childNode->GetParentNode())); + + if (childNode != containerNode) { + updateFlags |= UpdateTreeInternal(child, false, reorderEvent); + } else { + idx++; + } + } + } + + // Content insertion/removal is not cause of accessible tree change. + if (updateFlags == eNoAccessible) + return; + + MaybeNotifyOfValueChange(aContainer); FireDelayedEvent(reorderEvent); } diff --git a/accessible/generic/DocAccessible.h b/accessible/generic/DocAccessible.h index d75a41e7330..8c007b8378f 100644 --- a/accessible/generic/DocAccessible.h +++ b/accessible/generic/DocAccessible.h @@ -321,7 +321,7 @@ public: { // Update the whole tree of this document accessible when the container is // null (document element is removed). - UpdateTree((aContainer ? aContainer : this), aChildNode, false); + UpdateTreeOnRemoval((aContainer ? aContainer : this), aChildNode); } void ContentRemoved(nsIContent* aContainerNode, nsIContent* aChildNode) { @@ -465,13 +465,17 @@ protected: void ProcessInvalidationList(); /** - * Update the accessible tree for content insertion or removal. + * Update the tree on content insertion. */ - void UpdateTree(Accessible* aContainer, nsIContent* aChildNode, - bool aIsInsert); + void UpdateTreeOnInsertion(Accessible* aContainer); /** - * Helper for UpdateTree() method. Go down to DOM subtree and updates + * Update the accessible tree for content removal. + */ + void UpdateTreeOnRemoval(Accessible* aContainer, nsIContent* aChildNode); + + /** + * Helper for UpdateTreeOn methods. Go down to DOM subtree and updates * accessible tree. Return one of these flags. */ enum EUpdateTreeFlags { diff --git a/accessible/html/HTMLSelectAccessible.cpp b/accessible/html/HTMLSelectAccessible.cpp index 97e06d4429b..3a7447d6a9d 100644 --- a/accessible/html/HTMLSelectAccessible.cpp +++ b/accessible/html/HTMLSelectAccessible.cpp @@ -359,6 +359,7 @@ HTMLComboboxAccessible:: HTMLComboboxAccessible(nsIContent* aContent, DocAccessible* aDoc) : AccessibleWrap(aContent, aDoc) { + mType = eHTMLComboboxType; mGenericTypes |= eCombobox; } diff --git a/accessible/tests/mochitest/events/test_mutation.html b/accessible/tests/mochitest/events/test_mutation.html index ac2143f4c75..8eadd521ccb 100644 --- a/accessible/tests/mochitest/events/test_mutation.html +++ b/accessible/tests/mochitest/events/test_mutation.html @@ -336,6 +336,28 @@ } } + function insertReferredElm(aContainerID) + { + this.containerNode = getNode(aContainerID); + + this.eventSeq = [ + new invokerChecker(EVENT_SHOW, function(aNode) { return aNode.lastChild; }, this.containerNode), + new invokerChecker(EVENT_SHOW, function(aNode) { return aNode.firstChild; }, this.containerNode), + new invokerChecker(EVENT_REORDER, this.containerNode) + ]; + + this.invoke = function insertReferredElm_invoke() + { + this.containerNode.innerHTML = + ""; + } + + this.getID = function insertReferredElm_getID() + { + return "insert inaccessible element and then insert referring element to make it accessible"; + } + } + /** * Target getters. */ @@ -343,6 +365,10 @@ { return [aNode.firstChild]; } + function getLastChild(aNode) + { + return [aNode.lastChild]; + } function getNEnsureFirstChild(aNode) { @@ -457,6 +483,7 @@ gQueue.push(new test2("testContainer", "testContainer2")); gQueue.push(new test2("testContainer", "testNestedContainer")); gQueue.push(new test3("testContainer")); + gQueue.push(new insertReferredElm("testContainer3")); gQueue.invoke(); // Will call SimpleTest.finish(); } @@ -516,5 +543,6 @@
+
diff --git a/accessible/tests/mochitest/tree/test_select.html b/accessible/tests/mochitest/tree/test_select.html index 45a1b48e65d..15198562263 100644 --- a/accessible/tests/mochitest/tree/test_select.html +++ b/accessible/tests/mochitest/tree/test_select.html @@ -86,7 +86,7 @@ ] }, ] -}, + }, { role: ROLE_COMBOBOX_OPTION, children: [ diff --git a/accessible/tests/mochitest/treeupdate/test_optgroup.html b/accessible/tests/mochitest/treeupdate/test_optgroup.html index 360e1bbc08f..999a253ddec 100644 --- a/accessible/tests/mochitest/treeupdate/test_optgroup.html +++ b/accessible/tests/mochitest/treeupdate/test_optgroup.html @@ -21,6 +21,7 @@ { this.selectNode = getNode(aID); this.select = getAccessible(this.selectNode); + this.selectList = this.select.firstChild; this.invoke = function addOptGroup_invoke() { @@ -39,7 +40,7 @@ } this.eventSeq = [ - new invokerChecker(EVENT_REORDER, this.select) + new invokerChecker(EVENT_REORDER, this.selectList) ]; this.finalCheck = function addOptGroup_finalCheck() diff --git a/accessible/tests/mochitest/treeupdate/test_select.html b/accessible/tests/mochitest/treeupdate/test_select.html index 520b8dab20d..006618b80fb 100644 --- a/accessible/tests/mochitest/treeupdate/test_select.html +++ b/accessible/tests/mochitest/treeupdate/test_select.html @@ -21,6 +21,7 @@ { this.selectNode = getNode(aID); this.select = getAccessible(this.selectNode); + this.selectList = this.select.firstChild; this.invoke = function addOptions_invoke() { @@ -34,7 +35,7 @@ } this.eventSeq = [ - new invokerChecker(EVENT_REORDER, this.select) + new invokerChecker(EVENT_REORDER, this.selectList) ]; this.finalCheck = function addOptions_finalCheck() From 9aebb420fbac8594070edec6847795ec6093778c Mon Sep 17 00:00:00 2001 From: Geoff Brown Date: Tue, 30 Dec 2014 14:27:42 -0700 Subject: [PATCH 05/41] Bug 1113754 - Wait for view in robocop getToolbarView; r=mcomella --- mobile/android/base/tests/components/ToolbarComponent.java | 1 + 1 file changed, 1 insertion(+) diff --git a/mobile/android/base/tests/components/ToolbarComponent.java b/mobile/android/base/tests/components/ToolbarComponent.java index e92e145292c..3b795b606ad 100644 --- a/mobile/android/base/tests/components/ToolbarComponent.java +++ b/mobile/android/base/tests/components/ToolbarComponent.java @@ -83,6 +83,7 @@ public class ToolbarComponent extends BaseComponent { * Returns the root View for the browser toolbar. */ private View getToolbarView() { + mSolo.waitForView(R.id.browser_toolbar); return mSolo.getView(R.id.browser_toolbar); } From 5f23ee5c3e034fe12eb629e59cf1628563f74a8c Mon Sep 17 00:00:00 2001 From: Geoff Brown Date: Tue, 30 Dec 2014 14:27:44 -0700 Subject: [PATCH 06/41] Bug 1114655 - Increase robocop WaitHelper default wait time; r=mcomella --- mobile/android/base/tests/helpers/WaitHelper.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mobile/android/base/tests/helpers/WaitHelper.java b/mobile/android/base/tests/helpers/WaitHelper.java index e74be045047..32eee8ed37c 100644 --- a/mobile/android/base/tests/helpers/WaitHelper.java +++ b/mobile/android/base/tests/helpers/WaitHelper.java @@ -25,7 +25,9 @@ import com.jayway.android.robotium.solo.Solo; public final class WaitHelper { // TODO: Make public for when Solo.waitForCondition is used directly (i.e. do not want // assertion from waitFor)? - private static final int DEFAULT_MAX_WAIT_MS = 5000; + // DEFAULT_MAX_WAIT_MS of 5000 was intermittently insufficient during + // initialization on Android 2.3 emulator -- bug 1114655 + private static final int DEFAULT_MAX_WAIT_MS = 15000; private static final int PAGE_LOAD_WAIT_MS = 10000; private static final int CHANGE_WAIT_MS = 15000; From 6efbee378c365f6e1c8e50ba93b8757adfe95edd Mon Sep 17 00:00:00 2001 From: Aaron Klotz Date: Tue, 30 Dec 2014 14:52:39 -0700 Subject: [PATCH 07/41] Bug 1100360: Convert ChromeHang annotations to use UniquePtr; r=vladan --HG-- extra : rebase_source : 5c2ae8645b927c4d73a649beb573cfe2e242c146 --- toolkit/components/telemetry/Telemetry.cpp | 68 +++++++++++++--------- toolkit/components/telemetry/Telemetry.h | 3 +- xpcom/threads/HangMonitor.cpp | 13 ++--- 3 files changed, 47 insertions(+), 37 deletions(-) diff --git a/toolkit/components/telemetry/Telemetry.cpp b/toolkit/components/telemetry/Telemetry.cpp index fd47c602400..de5d88e437f 100644 --- a/toolkit/components/telemetry/Telemetry.cpp +++ b/toolkit/components/telemetry/Telemetry.cpp @@ -234,26 +234,37 @@ public: */ struct AnnotationInfo { AnnotationInfo(uint32_t aHangIndex, - HangAnnotations* aAnnotations) + UniquePtr aAnnotations) : mHangIndex(aHangIndex) - , mAnnotations(aAnnotations) + , mAnnotations(Move(aAnnotations)) {} - AnnotationInfo(const AnnotationInfo& aOther) + AnnotationInfo(AnnotationInfo&& aOther) : mHangIndex(aOther.mHangIndex) - , mAnnotations(aOther.mAnnotations) + , mAnnotations(Move(aOther.mAnnotations)) {} ~AnnotationInfo() {} + AnnotationInfo& operator=(AnnotationInfo&& aOther) + { + mHangIndex = aOther.mHangIndex; + mAnnotations = Move(aOther.mAnnotations); + return *this; + } uint32_t mHangIndex; - mutable nsAutoPtr mAnnotations; + UniquePtr mAnnotations; + + private: + // Force move constructor + AnnotationInfo(const AnnotationInfo& aOther) MOZ_DELETE; + void operator=(const AnnotationInfo& aOther) MOZ_DELETE; }; size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; void AddHang(const Telemetry::ProcessedStack& aStack, uint32_t aDuration, int32_t aSystemUptime, int32_t aFirefoxUptime, - HangAnnotations* aAnnotations); + UniquePtr aAnnotations); uint32_t GetDuration(unsigned aIndex) const; int32_t GetSystemUptime(unsigned aIndex) const; int32_t GetFirefoxUptime(unsigned aIndex) const; - const std::vector& GetAnnotationInfo() const; + const nsTArray& GetAnnotationInfo() const; const CombinedStacks& GetStacks() const; private: /** @@ -269,7 +280,7 @@ private: int32_t mFirefoxUptime; }; std::vector mHangInfo; - std::vector mAnnotationInfo; + nsTArray mAnnotationInfo; CombinedStacks mStacks; }; @@ -278,13 +289,13 @@ HangReports::AddHang(const Telemetry::ProcessedStack& aStack, uint32_t aDuration, int32_t aSystemUptime, int32_t aFirefoxUptime, - HangAnnotations* aAnnotations) { + UniquePtr aAnnotations) { HangInfo info = { aDuration, aSystemUptime, aFirefoxUptime }; mHangInfo.push_back(info); if (aAnnotations) { AnnotationInfo ainfo(static_cast(mHangInfo.size() - 1), - aAnnotations); - mAnnotationInfo.push_back(ainfo); + Move(aAnnotations)); + mAnnotationInfo.AppendElement(Move(ainfo)); } mStacks.AddStack(aStack); } @@ -296,10 +307,9 @@ HangReports::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { // This is a crude approximation. See comment on // CombinedStacks::SizeOfExcludingThis. n += mHangInfo.capacity() * sizeof(HangInfo); - n += mAnnotationInfo.capacity() * sizeof(AnnotationInfo); - for (std::vector::const_iterator i = mAnnotationInfo.begin(), - e = mAnnotationInfo.end(); i != e; ++i) { - n += i->mAnnotations->SizeOfIncludingThis(aMallocSizeOf); + n += mAnnotationInfo.Capacity() * sizeof(AnnotationInfo); + for (int32_t i = 0, l = mAnnotationInfo.Length(); i < l; ++i) { + n += mAnnotationInfo[i].mAnnotations->SizeOfIncludingThis(aMallocSizeOf); } return n; } @@ -324,7 +334,7 @@ HangReports::GetFirefoxUptime(unsigned aIndex) const { return mHangInfo[aIndex].mFirefoxUptime; } -const std::vector& +const nsTArray& HangReports::GetAnnotationInfo() const { return mAnnotationInfo; } @@ -816,7 +826,7 @@ public: Telemetry::ProcessedStack &aStack, int32_t aSystemUptime, int32_t aFirefoxUptime, - HangAnnotations* aAnnotations); + UniquePtr aAnnotations); #endif static void RecordThreadHangStats(Telemetry::ThreadHangStats& aStats); static nsresult GetHistogramEnumId(const char *name, Telemetry::ID *id); @@ -2405,18 +2415,16 @@ TelemetryImpl::GetChromeHangs(JSContext *cx, JS::MutableHandle ret) if (!JS_SetElement(cx, firefoxUptimeArray, i, mHangReports.GetFirefoxUptime(i))) { return NS_ERROR_FAILURE; } - const std::vector& annotationInfo = + const nsTArray& annotationInfo = mHangReports.GetAnnotationInfo(); - uint32_t annotationsArrayIndex = 0; - for (std::vector::const_iterator - ai = annotationInfo.begin(), e = annotationInfo.end(); ai != e; - ++ai, ++annotationsArrayIndex) { + for (uint32_t iterIndex = 0, arrayLen = annotationInfo.Length(); + iterIndex < arrayLen; ++iterIndex) { JS::Rooted keyValueArray(cx, JS_NewArrayObject(cx, 0)); if (!keyValueArray) { return NS_ERROR_FAILURE; } JS::RootedValue indexValue(cx); - indexValue.setNumber(ai->mHangIndex); + indexValue.setNumber(annotationInfo[iterIndex].mHangIndex); if (!JS_SetElement(cx, keyValueArray, 0, indexValue)) { return NS_ERROR_FAILURE; } @@ -2427,7 +2435,8 @@ TelemetryImpl::GetChromeHangs(JSContext *cx, JS::MutableHandle ret) return NS_ERROR_FAILURE; } nsAutoPtr annotationsEnum; - if (!ai->mAnnotations->GetEnumerator(annotationsEnum.StartAssignment())) { + if (!annotationInfo[iterIndex].mAnnotations->GetEnumerator( + annotationsEnum.StartAssignment())) { return NS_ERROR_FAILURE; } nsAutoString key; @@ -2443,7 +2452,7 @@ TelemetryImpl::GetChromeHangs(JSContext *cx, JS::MutableHandle ret) if (!JS_SetElement(cx, keyValueArray, 1, jsAnnotation)) { return NS_ERROR_FAILURE; } - if (!JS_SetElement(cx, annotationsArray, annotationsArrayIndex, + if (!JS_SetElement(cx, annotationsArray, iterIndex, keyValueArray)) { return NS_ERROR_FAILURE; } @@ -3200,7 +3209,7 @@ TelemetryImpl::RecordChromeHang(uint32_t aDuration, Telemetry::ProcessedStack &aStack, int32_t aSystemUptime, int32_t aFirefoxUptime, - HangAnnotations* aAnnotations) + UniquePtr aAnnotations) { if (!sTelemetry || !sTelemetry->mCanRecord) return; @@ -3209,7 +3218,7 @@ TelemetryImpl::RecordChromeHang(uint32_t aDuration, sTelemetry->mHangReports.AddHang(aStack, aDuration, aSystemUptime, aFirefoxUptime, - aAnnotations); + Move(aAnnotations)); } #endif @@ -3473,10 +3482,11 @@ void RecordChromeHang(uint32_t duration, ProcessedStack &aStack, int32_t aSystemUptime, int32_t aFirefoxUptime, - HangAnnotations* aAnnotations) + UniquePtr aAnnotations) { TelemetryImpl::RecordChromeHang(duration, aStack, - aSystemUptime, aFirefoxUptime, aAnnotations); + aSystemUptime, aFirefoxUptime, + Move(aAnnotations)); } #endif diff --git a/toolkit/components/telemetry/Telemetry.h b/toolkit/components/telemetry/Telemetry.h index ae30fd7d553..f572ef0e61e 100644 --- a/toolkit/components/telemetry/Telemetry.h +++ b/toolkit/components/telemetry/Telemetry.h @@ -238,7 +238,8 @@ void RecordChromeHang(uint32_t aDuration, ProcessedStack &aStack, int32_t aSystemUptime, int32_t aFirefoxUptime, - mozilla::HangMonitor::HangAnnotations* aAnnotations = nullptr); + mozilla::UniquePtr + aAnnotations); #endif class ThreadHangStats; diff --git a/xpcom/threads/HangMonitor.cpp b/xpcom/threads/HangMonitor.cpp index 58805c56755..a2e3d7b4f81 100644 --- a/xpcom/threads/HangMonitor.cpp +++ b/xpcom/threads/HangMonitor.cpp @@ -8,14 +8,14 @@ #include +#include "mozilla/Atomics.h" #include "mozilla/BackgroundHangMonitor.h" #include "mozilla/Monitor.h" #include "mozilla/Preferences.h" -#include "mozilla/Telemetry.h" #include "mozilla/ProcessedStack.h" -#include "mozilla/Atomics.h" +#include "mozilla/Telemetry.h" #include "mozilla/StaticPtr.h" -#include "nsAutoPtr.h" +#include "mozilla/UniquePtr.h" #include "nsReadableUtils.h" #include "nsStackWalk.h" #include "nsThreadUtils.h" @@ -363,7 +363,7 @@ ThreadMain(void*) Telemetry::ProcessedStack stack; int32_t systemUptime = -1; int32_t firefoxUptime = -1; - nsAutoPtr annotations = new ChromeHangAnnotations(); + auto annotations = MakeUnique(); #endif while (true) { @@ -410,10 +410,9 @@ ThreadMain(void*) if (waitCount >= 2) { uint32_t hangDuration = PR_IntervalToSeconds(now - lastTimestamp); Telemetry::RecordChromeHang(hangDuration, stack, systemUptime, - firefoxUptime, annotations->IsEmpty() ? - nullptr : annotations.forget()); + firefoxUptime, Move(annotations)); stack.Clear(); - annotations = new ChromeHangAnnotations(); + annotations = MakeUnique(); } #endif lastTimestamp = timestamp; From e2cd335ec4683b98079f9dde986e7e388c08f3f6 Mon Sep 17 00:00:00 2001 From: Jeff Gilbert Date: Mon, 17 Nov 2014 17:02:19 -0800 Subject: [PATCH 08/41] Bug 1100699 - Use OriginPos instead of isInverted. - r=mattwoodrow,snorp --- .../fmp4/android/AndroidDecoderModule.cpp | 4 +- dom/plugins/base/android/ANPNativeWindow.cpp | 8 ++- dom/plugins/base/android/ANPOpenGL.cpp | 8 ++- dom/plugins/base/nsNPAPIPluginInstance.cpp | 10 +--- dom/plugins/base/nsNPAPIPluginInstance.h | 8 +-- dom/plugins/base/nsPluginInstanceOwner.cpp | 7 +-- gfx/gl/GLBlitHelper.cpp | 50 ++++++++----------- gfx/gl/GLBlitHelper.h | 20 ++++---- gfx/gl/GLContextTypes.h | 7 ++- gfx/gl/GLScreenBuffer.cpp | 2 +- gfx/gl/GLTextureImage.cpp | 6 +-- gfx/gl/GLTextureImage.h | 5 +- gfx/layers/CompositorTypes.h | 4 +- gfx/layers/CopyableCanvasLayer.cpp | 7 +-- gfx/layers/CopyableCanvasLayer.h | 2 +- gfx/layers/GLImages.cpp | 2 +- gfx/layers/GLImages.h | 8 +-- gfx/layers/LayersLogging.cpp | 2 +- gfx/layers/LayersTypes.h | 6 +-- gfx/layers/basic/BasicCanvasLayer.cpp | 6 ++- gfx/layers/client/CanvasClient.cpp | 4 +- gfx/layers/client/ClientCanvasLayer.cpp | 6 +-- gfx/layers/client/ImageClient.cpp | 2 +- gfx/layers/composite/ImageHost.cpp | 4 +- gfx/layers/d3d10/CanvasLayerD3D10.cpp | 16 +++--- gfx/layers/d3d10/CanvasLayerD3D10.h | 4 +- gfx/layers/d3d9/CanvasLayerD3D9.cpp | 13 +++-- gfx/layers/d3d9/CanvasLayerD3D9.h | 4 +- gfx/layers/opengl/GrallocTextureClient.cpp | 2 +- gfx/layers/opengl/GrallocTextureHost.cpp | 4 +- gfx/layers/opengl/TextureClientOGL.cpp | 10 ++-- gfx/layers/opengl/TextureClientOGL.h | 2 +- gfx/layers/opengl/TextureHostOGL.cpp | 4 +- widget/gonk/HwcComposer2D.cpp | 10 +++- 34 files changed, 134 insertions(+), 123 deletions(-) diff --git a/dom/media/fmp4/android/AndroidDecoderModule.cpp b/dom/media/fmp4/android/AndroidDecoderModule.cpp index a252f953eef..ada7c3eda7c 100644 --- a/dom/media/fmp4/android/AndroidDecoderModule.cpp +++ b/dom/media/fmp4/android/AndroidDecoderModule.cpp @@ -79,7 +79,7 @@ public: layers::SurfaceTextureImage::Data data; data.mSurfTex = mSurfaceTexture.get(); data.mSize = gfx::IntSize(mConfig.display_width, mConfig.display_height); - data.mInverted = true; + data.mOriginPos = gl::OriginPos::BottomLeft; layers::SurfaceTextureImage* stImg = static_cast(img.get()); stImg->SetData(data); @@ -138,7 +138,7 @@ public: data.mSync = eglSync; data.mOwns = true; data.mSize = gfx::IntSize(mConfig.display_width, mConfig.display_height); - data.mInverted = false; + data.mOriginPos = gl::OriginPos::TopLeft; layers::EGLImageImage* typedImg = static_cast(img.get()); typedImg->SetData(data); diff --git a/dom/plugins/base/android/ANPNativeWindow.cpp b/dom/plugins/base/android/ANPNativeWindow.cpp index 4579c7ae7b5..0de5518c721 100644 --- a/dom/plugins/base/android/ANPNativeWindow.cpp +++ b/dom/plugins/base/android/ANPNativeWindow.cpp @@ -12,7 +12,6 @@ #include "nsNPAPIPluginInstance.h" #include "gfxRect.h" -using namespace mozilla; using namespace mozilla; #define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args) @@ -24,8 +23,13 @@ static ANPNativeWindow anp_native_window_acquireNativeWindow(NPP instance) { } static void anp_native_window_invertPluginContent(NPP instance, bool isContentInverted) { + // NativeWindow is TopLeft if uninverted. + gl::OriginPos newOriginPos = gl::OriginPos::TopLeft; + if (isContentInverted) + newOriginPos = gl::OriginPos::BottomLeft; + nsNPAPIPluginInstance* pinst = static_cast(instance->ndata); - pinst->SetInverted(isContentInverted); + pinst->SetOriginPos(newOriginPos); pinst->RedrawPlugin(); } diff --git a/dom/plugins/base/android/ANPOpenGL.cpp b/dom/plugins/base/android/ANPOpenGL.cpp index 71fa201d9f5..60c53250551 100644 --- a/dom/plugins/base/android/ANPOpenGL.cpp +++ b/dom/plugins/base/android/ANPOpenGL.cpp @@ -60,10 +60,14 @@ static void anp_opengl_releaseTexture(NPP instance, const ANPTextureInfo* info) } static void anp_opengl_invertPluginContent(NPP instance, bool isContentInverted) { + // OpenGL is BottomLeft if uninverted. + gl::OriginPos newOriginPos = gl::OriginPos::BottomLeft; + if (isContentInverted) + newOriginPos = gl::OriginPos::TopLeft; + nsNPAPIPluginInstance* pinst = static_cast(instance->ndata); - // Our definition of inverted is the opposite of the plugin's - pinst->SetInverted(!isContentInverted); + pinst->SetOriginPos(newOriginPos); pinst->RedrawPlugin(); } diff --git a/dom/plugins/base/nsNPAPIPluginInstance.cpp b/dom/plugins/base/nsNPAPIPluginInstance.cpp index cf16dce7a33..7b47fee5cc7 100644 --- a/dom/plugins/base/nsNPAPIPluginInstance.cpp +++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp @@ -179,7 +179,7 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance() , mFullScreenOrientation(dom::eScreenOrientation_LandscapePrimary) , mWakeLocked(false) , mFullScreen(false) - , mInverted(false) + , mOriginPos(gl::OriginPos::TopLeft) #endif , mRunning(NOT_STARTED) , mWindowless(false) @@ -1056,14 +1056,6 @@ void nsNPAPIPluginInstance::GetVideos(nsTArray& aVideos) aVideos.AppendElement(it->second); } -void nsNPAPIPluginInstance::SetInverted(bool aInverted) -{ - if (aInverted == mInverted) - return; - - mInverted = aInverted; -} - nsNPAPIPluginInstance* nsNPAPIPluginInstance::GetFromNPP(NPP npp) { std::map::iterator it; diff --git a/dom/plugins/base/nsNPAPIPluginInstance.h b/dom/plugins/base/nsNPAPIPluginInstance.h index 1c9f8ae016d..c0a4d904031 100644 --- a/dom/plugins/base/nsNPAPIPluginInstance.h +++ b/dom/plugins/base/nsNPAPIPluginInstance.h @@ -220,8 +220,10 @@ public: void GetVideos(nsTArray& aVideos); - void SetInverted(bool aInverted); - bool Inverted() { return mInverted; } + void SetOriginPos(mozilla::gl::OriginPos aOriginPos) { + mOriginPos = aOriginPos; + } + mozilla::gl::OriginPos OriginPos() const { return mOriginPos; } static nsNPAPIPluginInstance* GetFromNPP(NPP npp); #endif @@ -328,7 +330,7 @@ protected: uint32_t mFullScreenOrientation; bool mWakeLocked; bool mFullScreen; - bool mInverted; + mozilla::gl::OriginPos mOriginPos; mozilla::RefPtr mContentTexture; mozilla::RefPtr mContentSurface; diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index 1e6e3f233f3..9adadcb9f85 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -176,7 +176,7 @@ AttachToContainerAsEGLImage(ImageContainer* container, EGLImageImage::Data data; data.mImage = image; data.mSize = gfx::IntSize(rect.width, rect.height); - data.mInverted = instance->Inverted(); + data.mOriginPos = instance->OriginPos(); EGLImageImage* typedImg = static_cast(img.get()); typedImg->SetData(data); @@ -203,7 +203,7 @@ AttachToContainerAsSurfaceTexture(ImageContainer* container, SurfaceTextureImage::Data data; data.mSurfTex = surfTex; data.mSize = gfx::IntSize(rect.width, rect.height); - data.mInverted = instance->Inverted(); + data.mOriginPos = instance->OriginPos(); SurfaceTextureImage* typedImg = static_cast(img.get()); typedImg->SetData(data); @@ -1386,7 +1386,8 @@ nsPluginInstanceOwner::GetImageContainerForVideo(nsNPAPIPluginInstance::VideoInf // The logic below for Honeycomb is just a guess, but seems to work. We don't have a separate // inverted flag for video. - data.mInverted = AndroidBridge::Bridge()->IsHoneycomb() ? true : mInstance->Inverted(); + data.mOriginPos = AndroidBridge::Bridge()->IsHoneycomb() ? gl::OriginPos::BottomLeft + : mInstance->OriginPos(); data.mSize = gfx::IntSize(aVideoInfo->mDimensions.width, aVideoInfo->mDimensions.height); SurfaceTextureImage* typedImg = static_cast(img.get()); diff --git a/gfx/gl/GLBlitHelper.cpp b/gfx/gl/GLBlitHelper.cpp index a05076f5200..d1b27b8514f 100644 --- a/gfx/gl/GLBlitHelper.cpp +++ b/gfx/gl/GLBlitHelper.cpp @@ -690,7 +690,7 @@ GLBlitHelper::BindAndUploadEGLImage(EGLImage image, GLuint target) #ifdef MOZ_WIDGET_GONK bool -GLBlitHelper::BlitGrallocImage(layers::GrallocImage* grallocImage, bool yFlip) +GLBlitHelper::BlitGrallocImage(layers::GrallocImage* grallocImage, bool yflip) { ScopedBindTextureUnit boundTU(mGL, LOCAL_GL_TEXTURE0); mGL->fClear(LOCAL_GL_COLOR_BUFFER_BIT); @@ -711,7 +711,7 @@ GLBlitHelper::BlitGrallocImage(layers::GrallocImage* grallocImage, bool yFlip) BindAndUploadEGLImage(image, LOCAL_GL_TEXTURE_EXTERNAL_OES); - mGL->fUniform1f(mYFlipLoc, yFlip ? (float)1.0f : (float)0.0f); + mGL->fUniform1f(mYFlipLoc, yflip ? (float)1.0f : (float)0.0f); mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4); @@ -724,18 +724,14 @@ GLBlitHelper::BlitGrallocImage(layers::GrallocImage* grallocImage, bool yFlip) #ifdef MOZ_WIDGET_ANDROID bool -GLBlitHelper::BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage, bool yFlip) +GLBlitHelper::BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage, bool yflip) { AndroidSurfaceTexture* surfaceTexture = stImage->GetData()->mSurfTex; - if (stImage->GetData()->mInverted) { - yFlip = !yFlip; - } ScopedBindTextureUnit boundTU(mGL, LOCAL_GL_TEXTURE0); - if (NS_FAILED(surfaceTexture->Attach(mGL))) { + if (NS_FAILED(surfaceTexture->Attach(mGL))) return false; - } // UpdateTexImage() changes the EXTERNAL binding, so save it here // so we can restore it after. @@ -748,7 +744,7 @@ GLBlitHelper::BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage, bool surfaceTexture->GetTransformMatrix(transform); mGL->fUniformMatrix4fv(mTextureTransformLoc, 1, false, &transform._11); - mGL->fUniform1f(mYFlipLoc, yFlip ? 1.0f : 0.0f); + mGL->fUniform1f(mYFlipLoc, yflip ? 1.0f : 0.0f); mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4); surfaceTexture->Detach(); @@ -758,15 +754,11 @@ GLBlitHelper::BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage, bool } bool -GLBlitHelper::BlitEGLImageImage(layers::EGLImageImage* image, bool yFlip) +GLBlitHelper::BlitEGLImageImage(layers::EGLImageImage* image, bool yflip) { EGLImage eglImage = image->GetData()->mImage; EGLSync eglSync = image->GetData()->mSync; - if (image->GetData()->mInverted) { - yFlip = !yFlip; - } - if (eglSync) { EGLint status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(), eglSync, 0, LOCAL_EGL_FOREVER); if (status != LOCAL_EGL_CONDITION_SATISFIED) { @@ -781,7 +773,7 @@ GLBlitHelper::BlitEGLImageImage(layers::EGLImageImage* image, bool yFlip) BindAndUploadEGLImage(eglImage, LOCAL_GL_TEXTURE_2D); - mGL->fUniform1f(mYFlipLoc, yFlip ? 1.0f : 0.0f); + mGL->fUniform1f(mYFlipLoc, yflip ? 1.0f : 0.0f); mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4); @@ -792,7 +784,7 @@ GLBlitHelper::BlitEGLImageImage(layers::EGLImageImage* image, bool yFlip) #endif bool -GLBlitHelper::BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage, bool yFlip) +GLBlitHelper::BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage, bool yflip) { ScopedBindTextureUnit boundTU(mGL, LOCAL_GL_TEXTURE0); const PlanarYCbCrData* yuvData = yuvImage->GetData(); @@ -813,7 +805,7 @@ GLBlitHelper::BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage, bool yFli BindAndUploadYUVTexture(Channel_Cb, yuvData->mCbCrStride, yuvData->mCbCrSize.height, yuvData->mCbChannel, needsAllocation); BindAndUploadYUVTexture(Channel_Cr, yuvData->mCbCrStride, yuvData->mCbCrSize.height, yuvData->mCrChannel, needsAllocation); - mGL->fUniform1f(mYFlipLoc, yFlip ? (float)1.0 : (float)0.0); + mGL->fUniform1f(mYFlipLoc, yflip ? (float)1.0 : (float)0.0); if (needsAllocation) { mGL->fUniform2f(mYTexScaleLoc, (float)yuvData->mYSize.width/yuvData->mYStride, 1.0f); @@ -832,7 +824,7 @@ bool GLBlitHelper::BlitImageToFramebuffer(layers::Image* srcImage, const gfx::IntSize& destSize, GLuint destFB, - bool yFlip, + bool yflip, GLuint xoffset, GLuint yoffset, GLuint cropWidth, @@ -878,22 +870,22 @@ GLBlitHelper::BlitImageToFramebuffer(layers::Image* srcImage, #ifdef MOZ_WIDGET_GONK if (type == ConvertGralloc) { layers::GrallocImage* grallocImage = static_cast(srcImage); - return BlitGrallocImage(grallocImage, yFlip); + return BlitGrallocImage(grallocImage, yflip); } #endif if (type == ConvertPlanarYCbCr) { mGL->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 1); PlanarYCbCrImage* yuvImage = static_cast(srcImage); - return BlitPlanarYCbCrImage(yuvImage, yFlip); + return BlitPlanarYCbCrImage(yuvImage, yflip); } #ifdef MOZ_WIDGET_ANDROID if (type == ConvertSurfaceTexture) { layers::SurfaceTextureImage* stImage = static_cast(srcImage); - return BlitSurfaceTextureImage(stImage, yFlip); + return BlitSurfaceTextureImage(stImage, yflip); } if (type == ConvertEGLImage) { layers::EGLImageImage* eglImage = static_cast(srcImage); - return BlitEGLImageImage(eglImage, yFlip); + return BlitEGLImageImage(eglImage, yflip); } #endif @@ -905,7 +897,7 @@ GLBlitHelper::BlitImageToTexture(layers::Image* srcImage, const gfx::IntSize& destSize, GLuint destTex, GLenum destTarget, - bool yFlip, + bool yflip, GLuint xoffset, GLuint yoffset, GLuint cropWidth, @@ -913,13 +905,13 @@ GLBlitHelper::BlitImageToTexture(layers::Image* srcImage, { ScopedGLDrawState autoStates(mGL); - if (!mFBO) { + if (!mFBO) mGL->fGenFramebuffers(1, &mFBO); - } ScopedBindFramebuffer boundFB(mGL, mFBO); - mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0, destTarget, destTex, 0); - return BlitImageToFramebuffer(srcImage, destSize, mFBO, yFlip, xoffset, yoffset, + mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0, + destTarget, destTex, 0); + return BlitImageToFramebuffer(srcImage, destSize, mFBO, yflip, xoffset, yoffset, cropWidth, cropHeight); } @@ -1027,5 +1019,5 @@ GLBlitHelper::BlitTextureToTexture(GLuint srcTex, GLuint destTex, srcSize, destSize, destTarget); } -} -} +} // namespace gl +} // namespace mozilla diff --git a/gfx/gl/GLBlitHelper.h b/gfx/gl/GLBlitHelper.h index 4df7a0089aa..2814e76267f 100644 --- a/gfx/gl/GLBlitHelper.h +++ b/gfx/gl/GLBlitHelper.h @@ -145,12 +145,13 @@ class GLBlitHelper MOZ_FINAL void BindAndUploadEGLImage(EGLImage image, GLuint target); #ifdef MOZ_WIDGET_GONK - bool BlitGrallocImage(layers::GrallocImage* grallocImage, bool yFlip = false); + bool BlitGrallocImage(layers::GrallocImage* grallocImage, bool yflip); #endif - bool BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage, bool yFlip = false); + bool BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage, bool yflip); #ifdef MOZ_WIDGET_ANDROID - bool BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage, bool yFlip = false); - bool BlitEGLImageImage(layers::EGLImageImage* eglImage, bool yFlip = false); + // Blit onto the current FB. + bool BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage, bool yflip); + bool BlitEGLImageImage(layers::EGLImageImage* eglImage, bool yflip); #endif public: @@ -186,14 +187,15 @@ public: GLenum srcTarget = LOCAL_GL_TEXTURE_2D, GLenum destTarget = LOCAL_GL_TEXTURE_2D); bool BlitImageToFramebuffer(layers::Image* srcImage, const gfx::IntSize& destSize, - GLuint destFB, bool yFlip = false, GLuint xoffset = 0, + GLuint destFB, bool yflip = false, GLuint xoffset = 0, GLuint yoffset = 0, GLuint width = 0, GLuint height = 0); bool BlitImageToTexture(layers::Image* srcImage, const gfx::IntSize& destSize, - GLuint destTex, GLenum destTarget, bool yFlip = false, GLuint xoffset = 0, - GLuint yoffset = 0, GLuint width = 0, GLuint height = 0); + GLuint destTex, GLenum destTarget, bool yflip = false, + GLuint xoffset = 0, GLuint yoffset = 0, GLuint width = 0, + GLuint height = 0); }; -} -} +} // namespace gl +} // namespace mozilla #endif // GLBLITHELPER_H_ diff --git a/gfx/gl/GLContextTypes.h b/gfx/gl/GLContextTypes.h index 27ae4813d75..1cdc12aeb22 100644 --- a/gfx/gl/GLContextTypes.h +++ b/gfx/gl/GLContextTypes.h @@ -22,6 +22,11 @@ MOZ_BEGIN_ENUM_CLASS(GLContextType) EGL MOZ_END_ENUM_CLASS(GLContextType) +MOZ_BEGIN_ENUM_CLASS(OriginPos, uint8_t) + TopLeft, + BottomLeft +MOZ_END_ENUM_CLASS(OriginPos) + struct GLFormats { // Constructs a zeroed object: @@ -39,7 +44,6 @@ struct GLFormats GLsizei samples; }; - struct PixelBufferFormat { // Constructs a zeroed object: @@ -53,7 +57,6 @@ struct PixelBufferFormat int ColorBits() const { return red + green + blue; } }; - } /* namespace gl */ } /* namespace mozilla */ diff --git a/gfx/gl/GLScreenBuffer.cpp b/gfx/gl/GLScreenBuffer.cpp index 01751a9bdc2..0f36523ff60 100755 --- a/gfx/gl/GLScreenBuffer.cpp +++ b/gfx/gl/GLScreenBuffer.cpp @@ -49,7 +49,7 @@ GLScreenBuffer::Create(GLContext* gl, XRE_GetProcessType() != GeckoProcessType_Default) { layers::TextureFlags flags = layers::TextureFlags::DEALLOCATE_CLIENT | - layers::TextureFlags::NEEDS_Y_FLIP; + layers::TextureFlags::ORIGIN_BOTTOM_LEFT; if (!caps.premultAlpha) { flags |= layers::TextureFlags::NON_PREMULTIPLIED; } diff --git a/gfx/gl/GLTextureImage.cpp b/gfx/gl/GLTextureImage.cpp index 61358a4d556..8dd8f2f5a31 100644 --- a/gfx/gl/GLTextureImage.cpp +++ b/gfx/gl/GLTextureImage.cpp @@ -597,9 +597,9 @@ gfx::IntRect TiledTextureImage::GetTileRect() gfx::IntRect TiledTextureImage::GetSrcTileRect() { gfx::IntRect rect = GetTileRect(); - unsigned int srcY = mFlags & NeedsYFlip - ? mSize.height - rect.height - rect.y - : rect.y; + const bool needsYFlip = mFlags & OriginBottomLeft; + unsigned int srcY = needsYFlip ? mSize.height - rect.height - rect.y + : rect.y; return gfx::IntRect(rect.x, srcY, rect.width, rect.height); } diff --git a/gfx/gl/GLTextureImage.h b/gfx/gl/GLTextureImage.h index f204a456955..dc67f1028d0 100644 --- a/gfx/gl/GLTextureImage.h +++ b/gfx/gl/GLTextureImage.h @@ -58,7 +58,7 @@ public: enum Flags { NoFlags = 0x0, UseNearestFilter = 0x1, - NeedsYFlip = 0x2, + OriginBottomLeft = 0x2, DisallowBigImage = 0x4 }; @@ -381,7 +381,8 @@ CreateBasicTextureImage(GLContext* aGL, * |aWrapMode| (usually GL_CLAMP_TO_EDGE or GL_REPEAT) and by * default, GL_LINEAR filtering. Specify * |aFlags=UseNearestFilter| for GL_NEAREST filtering. Specify - * |aFlags=NeedsYFlip| if the image is flipped. Return + * |aFlags=OriginBottomLeft| if the image is origin-bottom-left, instead of the + * default origin-top-left. Return * nullptr if creating the TextureImage fails. * * The returned TextureImage may only be used with this GLContext. diff --git a/gfx/layers/CompositorTypes.h b/gfx/layers/CompositorTypes.h index 9642f00058b..b2cd511dae9 100644 --- a/gfx/layers/CompositorTypes.h +++ b/gfx/layers/CompositorTypes.h @@ -29,8 +29,8 @@ MOZ_BEGIN_ENUM_CLASS(TextureFlags, uint32_t) NO_FLAGS = 0, // Use nearest-neighbour texture filtering (as opposed to linear filtering). USE_NEAREST_FILTER = 1 << 0, - // The texture should be flipped along the y-axis when composited. - NEEDS_Y_FLIP = 1 << 1, + // The compositor assumes everything is origin-top-left by default. + ORIGIN_BOTTOM_LEFT = 1 << 1, // Force the texture to be represented using a single tile (note that this means // tiled textures, not tiled layers). DISALLOW_BIGIMAGE = 1 << 2, diff --git a/gfx/layers/CopyableCanvasLayer.cpp b/gfx/layers/CopyableCanvasLayer.cpp index bdf3f067285..3889920faac 100644 --- a/gfx/layers/CopyableCanvasLayer.cpp +++ b/gfx/layers/CopyableCanvasLayer.cpp @@ -32,6 +32,7 @@ CopyableCanvasLayer::CopyableCanvasLayer(LayerManager* aLayerManager, void *aImp CanvasLayer(aLayerManager, aImplData) , mGLFrontbuffer(nullptr) , mIsAlphaPremultiplied(true) + , mOriginPos(gl::OriginPos::TopLeft) { MOZ_COUNT_CTOR(CopyableCanvasLayer); } @@ -49,7 +50,8 @@ CopyableCanvasLayer::Initialize(const Data& aData) if (aData.mGLContext) { mGLContext = aData.mGLContext; mIsAlphaPremultiplied = aData.mIsGLAlphaPremult; - mNeedsYFlip = true; + mOriginPos = gl::OriginPos::BottomLeft; + MOZ_ASSERT(mGLContext->IsOffscreen(), "canvas gl context isn't offscreen"); if (aData.mFrontbufferGLTex) { @@ -63,9 +65,8 @@ CopyableCanvasLayer::Initialize(const Data& aData) } else if (aData.mDrawTarget) { mDrawTarget = aData.mDrawTarget; mSurface = mDrawTarget->Snapshot(); - mNeedsYFlip = false; } else { - NS_ERROR("CanvasLayer created without mSurface, mDrawTarget or mGLContext?"); + MOZ_CRASH("CanvasLayer created without mSurface, mDrawTarget or mGLContext?"); } mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height); diff --git a/gfx/layers/CopyableCanvasLayer.h b/gfx/layers/CopyableCanvasLayer.h index c8c4df1a9ee..4f6125efb46 100644 --- a/gfx/layers/CopyableCanvasLayer.h +++ b/gfx/layers/CopyableCanvasLayer.h @@ -55,7 +55,7 @@ protected: UniquePtr mGLFrontbuffer; bool mIsAlphaPremultiplied; - bool mNeedsYFlip; + gl::OriginPos mOriginPos; RefPtr mCachedTempSurface; diff --git a/gfx/layers/GLImages.cpp b/gfx/layers/GLImages.cpp index 5a6f780fc70..ee519a1a6c0 100644 --- a/gfx/layers/GLImages.cpp +++ b/gfx/layers/GLImages.cpp @@ -40,7 +40,6 @@ GLImage::GetAsSourceSurface() if (!sSnapshotContext) { sSnapshotContext = GLContextProvider::CreateHeadless(); - if (!sSnapshotContext) { NS_WARNING("Failed to create snapshot GLContext"); return nullptr; @@ -63,6 +62,7 @@ GLImage::GetAsSourceSurface() GLBlitHelper helper(sSnapshotContext); helper.BlitImageToFramebuffer(this, size, fb.FB(), false); + ScopedBindFramebuffer bind(sSnapshotContext, fb.FB()); RefPtr source = diff --git a/gfx/layers/GLImages.h b/gfx/layers/GLImages.h index fc6d86a4c22..e1861263649 100644 --- a/gfx/layers/GLImages.h +++ b/gfx/layers/GLImages.h @@ -6,6 +6,7 @@ #ifndef GFX_GLIMAGES_H #define GFX_GLIMAGES_H +#include "GLContextTypes.h" #include "GLTypes.h" #include "ImageContainer.h" // for Image #include "ImageTypes.h" // for ImageFormat::SHARED_GLTEXTURE @@ -31,10 +32,11 @@ public: EGLImage mImage; EGLSync mSync; gfx::IntSize mSize; - bool mInverted; + gl::OriginPos mOriginPos; bool mOwns; - Data() : mImage(nullptr), mSync(nullptr), mSize(0, 0), mInverted(false), mOwns(false) + Data() : mImage(nullptr), mSync(nullptr), mSize(0, 0), + mOriginPos(gl::OriginPos::TopLeft), mOwns(false) { } }; @@ -60,7 +62,7 @@ public: struct Data { mozilla::gl::AndroidSurfaceTexture* mSurfTex; gfx::IntSize mSize; - bool mInverted; + gl::OriginPos mOriginPos; }; void SetData(const Data& aData) { mData = aData; } diff --git a/gfx/layers/LayersLogging.cpp b/gfx/layers/LayersLogging.cpp index 2c97537ce48..7d68e8f692f 100644 --- a/gfx/layers/LayersLogging.cpp +++ b/gfx/layers/LayersLogging.cpp @@ -289,7 +289,7 @@ AppendToString(std::stringstream& aStream, TextureFlags flags, } bool previous = false; AppendFlag(TextureFlags::USE_NEAREST_FILTER); - AppendFlag(TextureFlags::NEEDS_Y_FLIP); + AppendFlag(TextureFlags::ORIGIN_BOTTOM_LEFT); AppendFlag(TextureFlags::DISALLOW_BIGIMAGE); #undef AppendFlag diff --git a/gfx/layers/LayersTypes.h b/gfx/layers/LayersTypes.h index 23ab87522e0..ddcbb2dea68 100644 --- a/gfx/layers/LayersTypes.h +++ b/gfx/layers/LayersTypes.h @@ -79,7 +79,7 @@ MOZ_END_ENUM_CLASS(SurfaceMode) // by other surfaces we will need a more generic LayerRenderState. MOZ_BEGIN_ENUM_CLASS(LayerRenderStateFlags, int8_t) LAYER_RENDER_STATE_DEFAULT = 0, - Y_FLIPPED = 1 << 0, + ORIGIN_BOTTOM_LEFT = 1 << 0, BUFFER_ROTATION = 1 << 1, // Notify Composer2D to swap the RB pixels of gralloc buffer FORMAT_RB_SWAP = 1 << 2, @@ -116,8 +116,8 @@ struct LayerRenderState { , mTexture(aTexture) {} - bool YFlipped() const - { return bool(mFlags & LayerRenderStateFlags::Y_FLIPPED); } + bool OriginBottomLeft() const + { return bool(mFlags & LayerRenderStateFlags::ORIGIN_BOTTOM_LEFT); } bool BufferRotated() const { return bool(mFlags & LayerRenderStateFlags::BUFFER_ROTATION); } diff --git a/gfx/layers/basic/BasicCanvasLayer.cpp b/gfx/layers/basic/BasicCanvasLayer.cpp index 25ab6865e07..656a770b0cc 100644 --- a/gfx/layers/basic/BasicCanvasLayer.cpp +++ b/gfx/layers/basic/BasicCanvasLayer.cpp @@ -40,8 +40,10 @@ BasicCanvasLayer::Paint(DrawTarget* aDT, return; } + const bool needsYFlip = (mOriginPos == gl::OriginPos::BottomLeft); + Matrix oldTM; - if (mNeedsYFlip) { + if (needsYFlip) { oldTM = aDT->GetTransform(); aDT->SetTransform(Matrix(oldTM). PreTranslate(0.0f, mBounds.height). @@ -54,7 +56,7 @@ BasicCanvasLayer::Paint(DrawTarget* aDT, DrawOptions(GetEffectiveOpacity(), GetEffectiveOperator(this)), aMaskLayer); - if (mNeedsYFlip) { + if (needsYFlip) { aDT->SetTransform(oldTM); } } diff --git a/gfx/layers/client/CanvasClient.cpp b/gfx/layers/client/CanvasClient.cpp index a4435c2b7a9..a01da3feb9e 100644 --- a/gfx/layers/client/CanvasClient.cpp +++ b/gfx/layers/client/CanvasClient.cpp @@ -72,8 +72,8 @@ CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) gfxImageFormat format = gfxPlatform::GetPlatform()->OptimalFormatForContent(contentType); TextureFlags flags = TextureFlags::DEFAULT; - if (mTextureFlags & TextureFlags::NEEDS_Y_FLIP) { - flags |= TextureFlags::NEEDS_Y_FLIP; + if (mTextureFlags & TextureFlags::ORIGIN_BOTTOM_LEFT) { + flags |= TextureFlags::ORIGIN_BOTTOM_LEFT; } gfx::SurfaceFormat surfaceFormat = gfx::ImageFormatToSurfaceFormat(format); diff --git a/gfx/layers/client/ClientCanvasLayer.cpp b/gfx/layers/client/ClientCanvasLayer.cpp index 8aaa4aeff75..fadfd5d230b 100644 --- a/gfx/layers/client/ClientCanvasLayer.cpp +++ b/gfx/layers/client/ClientCanvasLayer.cpp @@ -78,7 +78,7 @@ ClientCanvasLayer::Initialize(const Data& aData) if (mGLContext->GetContextType() == GLContextType::EGL) { #ifdef MOZ_WIDGET_GONK TextureFlags flags = TextureFlags::DEALLOCATE_CLIENT | - TextureFlags::NEEDS_Y_FLIP; + TextureFlags::ORIGIN_BOTTOM_LEFT; if (!aData.mIsGLAlphaPremult) { flags |= TextureFlags::NON_PREMULTIPLIED; } @@ -153,8 +153,8 @@ ClientCanvasLayer::RenderLayer() if (!mCanvasClient) { TextureFlags flags = TextureFlags::IMMEDIATE_UPLOAD; - if (mNeedsYFlip) { - flags |= TextureFlags::NEEDS_Y_FLIP; + if (mOriginPos == gl::OriginPos::BottomLeft) { + flags |= TextureFlags::ORIGIN_BOTTOM_LEFT; } if (!mGLContext) { diff --git a/gfx/layers/client/ImageClient.cpp b/gfx/layers/client/ImageClient.cpp index ec6b438d79e..05aa876cbe6 100644 --- a/gfx/layers/client/ImageClient.cpp +++ b/gfx/layers/client/ImageClient.cpp @@ -202,7 +202,7 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlag const SurfaceTextureImage::Data* data = typedImage->GetData(); texture = new SurfaceTextureClient(GetForwarder(), mTextureFlags, data->mSurfTex, size, - data->mInverted); + data->mOriginPos); #endif } else { MOZ_ASSERT(false, "Bad ImageFormat."); diff --git a/gfx/layers/composite/ImageHost.cpp b/gfx/layers/composite/ImageHost.cpp index c9a267553c4..f9f247b0907 100644 --- a/gfx/layers/composite/ImageHost.cpp +++ b/gfx/layers/composite/ImageHost.cpp @@ -151,7 +151,7 @@ ImageHost::Composite(EffectChain& aEffectChain, } else { effect->mTextureCoords = Rect(0, 0, 1, 1); } - if (mFrontBuffer->GetFlags() & TextureFlags::NEEDS_Y_FLIP) { + if (mFrontBuffer->GetFlags() & TextureFlags::ORIGIN_BOTTOM_LEFT) { effect->mTextureCoords.y = effect->mTextureCoords.YMost(); effect->mTextureCoords.height = -effect->mTextureCoords.height; } @@ -179,7 +179,7 @@ ImageHost::Composite(EffectChain& aEffectChain, rect = gfx::Rect(0, 0, textureSize.width, textureSize.height); } - if (mFrontBuffer->GetFlags() & TextureFlags::NEEDS_Y_FLIP) { + if (mFrontBuffer->GetFlags() & TextureFlags::ORIGIN_BOTTOM_LEFT) { effect->mTextureCoords.y = effect->mTextureCoords.YMost(); effect->mTextureCoords.height = -effect->mTextureCoords.height; } diff --git a/gfx/layers/d3d10/CanvasLayerD3D10.cpp b/gfx/layers/d3d10/CanvasLayerD3D10.cpp index b0c3d008153..bfb11bea2a9 100644 --- a/gfx/layers/d3d10/CanvasLayerD3D10.cpp +++ b/gfx/layers/d3d10/CanvasLayerD3D10.cpp @@ -23,8 +23,8 @@ using namespace mozilla::gfx; CanvasLayerD3D10::CanvasLayerD3D10(LayerManagerD3D10 *aManager) : CanvasLayer(aManager, nullptr) , LayerD3D10(aManager) - , mDataIsPremultiplied(false) - , mNeedsYFlip(false) + , mDataIsPremultiplied(true) + , mOriginPos(gl::OriginPos::TopLeft) , mHasAlpha(true) { mImplData = static_cast(this); @@ -43,7 +43,7 @@ CanvasLayerD3D10::Initialize(const Data& aData) mGLContext = aData.mGLContext; NS_ASSERTION(mGLContext->IsOffscreen(), "Canvas GLContext must be offscreen."); mDataIsPremultiplied = aData.mIsGLAlphaPremult; - mNeedsYFlip = true; + mOriginPos = gl::OriginPos::TopLeft; GLScreenBuffer* screen = mGLContext->Screen(); @@ -60,8 +60,6 @@ CanvasLayerD3D10::Initialize(const Data& aData) } } else if (aData.mDrawTarget) { mDrawTarget = aData.mDrawTarget; - mNeedsYFlip = false; - mDataIsPremultiplied = true; void *texture = mDrawTarget->GetNativeSurface(NativeSurfaceType::D3D10_TEXTURE); if (texture) { @@ -79,7 +77,7 @@ CanvasLayerD3D10::Initialize(const Data& aData) // bypassing Thebes mSurface = mDrawTarget->Snapshot(); } else { - NS_ERROR("CanvasLayer created without mSurface, mDrawTarget or mGLContext?"); + MOZ_CRASH("CanvasLayer created without mSurface, mDrawTarget or mGLContext?"); } mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height); @@ -213,7 +211,9 @@ CanvasLayerD3D10::RenderLayer() (float)mBounds.height) ); - if (mNeedsYFlip) { + const bool needsYFlip = (mOriginPos == gl::OriginPos::BottomLeft); + + if (needsYFlip) { effect()->GetVariableByName("vTextureCoords")->AsVector()->SetFloatVector( ShaderConstantRectD3D10( 0, @@ -226,7 +226,7 @@ CanvasLayerD3D10::RenderLayer() technique->GetPassByIndex(0)->Apply(0); device()->Draw(4, 0); - if (mNeedsYFlip) { + if (needsYFlip) { effect()->GetVariableByName("vTextureCoords")->AsVector()-> SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f)); } diff --git a/gfx/layers/d3d10/CanvasLayerD3D10.h b/gfx/layers/d3d10/CanvasLayerD3D10.h index e8066519cd9..34733f0d37b 100644 --- a/gfx/layers/d3d10/CanvasLayerD3D10.h +++ b/gfx/layers/d3d10/CanvasLayerD3D10.h @@ -6,8 +6,8 @@ #ifndef GFX_CANVASLAYERD3D10_H #define GFX_CANVASLAYERD3D10_H +#include "GLContextTypes.h" #include "LayerManagerD3D10.h" - #include "mozilla/Preferences.h" namespace mozilla { @@ -45,7 +45,7 @@ private: nsRefPtr mSRView; bool mDataIsPremultiplied; - bool mNeedsYFlip; + gl::OriginPos mOriginPos; bool mIsD2DTexture; bool mHasAlpha; diff --git a/gfx/layers/d3d9/CanvasLayerD3D9.cpp b/gfx/layers/d3d9/CanvasLayerD3D9.cpp index 70b4250bf10..f8ce2e67df1 100644 --- a/gfx/layers/d3d9/CanvasLayerD3D9.cpp +++ b/gfx/layers/d3d9/CanvasLayerD3D9.cpp @@ -22,8 +22,8 @@ namespace layers { CanvasLayerD3D9::CanvasLayerD3D9(LayerManagerD3D9 *aManager) : CanvasLayer(aManager, nullptr) , LayerD3D9(aManager) - , mDataIsPremultiplied(false) - , mNeedsYFlip(false) + , mDataIsPremultiplied(true) + , mOriginPos(gl::OriginPos::TopLeft) , mHasAlpha(true) { mImplData = static_cast(this); @@ -44,13 +44,11 @@ CanvasLayerD3D9::Initialize(const Data& aData) if (aData.mDrawTarget) { mDrawTarget = aData.mDrawTarget; - mNeedsYFlip = false; - mDataIsPremultiplied = true; } else if (aData.mGLContext) { mGLContext = aData.mGLContext; NS_ASSERTION(mGLContext->IsOffscreen(), "Canvas GLContext must be offscreen."); mDataIsPremultiplied = aData.mIsGLAlphaPremult; - mNeedsYFlip = true; + mOriginPos = gl::OriginPos::BottomLeft; } else { NS_ERROR("CanvasLayer created without mGLContext or mDrawTarget?"); } @@ -137,9 +135,10 @@ CanvasLayerD3D9::RenderLayer() * We flip the Y axis here, note we can only do this because we are in * CULL_NONE mode! */ - ShaderConstantRect quad(0, 0, mBounds.width, mBounds.height); - if (mNeedsYFlip) { + + const bool needsYFlip = (mOriginPos == gl::OriginPos::BottomLeft); + if (needsYFlip) { quad.mHeight = (float)-mBounds.height; quad.mY = (float)mBounds.height; } diff --git a/gfx/layers/d3d9/CanvasLayerD3D9.h b/gfx/layers/d3d9/CanvasLayerD3D9.h index 602d2f0720b..3a4234ea043 100644 --- a/gfx/layers/d3d9/CanvasLayerD3D9.h +++ b/gfx/layers/d3d9/CanvasLayerD3D9.h @@ -6,8 +6,8 @@ #ifndef GFX_CANVASLAYERD3D9_H #define GFX_CANVASLAYERD3D9_H -#include "LayerManagerD3D9.h" #include "GLContextTypes.h" +#include "LayerManagerD3D9.h" namespace mozilla { namespace layers { @@ -42,7 +42,7 @@ protected: RefPtr mDrawTarget; bool mDataIsPremultiplied; - bool mNeedsYFlip; + gl::OriginPos mOriginPos; bool mHasAlpha; nsAutoArrayPtr mCachedTempBlob; diff --git a/gfx/layers/opengl/GrallocTextureClient.cpp b/gfx/layers/opengl/GrallocTextureClient.cpp index 4f5fa6a30d3..769c5459d04 100644 --- a/gfx/layers/opengl/GrallocTextureClient.cpp +++ b/gfx/layers/opengl/GrallocTextureClient.cpp @@ -348,7 +348,7 @@ GrallocTextureClientOGL::FromSharedSurface(gl::SharedSurface* abstractSurf, RefPtr ret = surf->GetTextureClient(); - TextureFlags mask = TextureFlags::NEEDS_Y_FLIP | + TextureFlags mask = TextureFlags::ORIGIN_BOTTOM_LEFT | TextureFlags::RB_SWAPPED | TextureFlags::NON_PREMULTIPLIED; TextureFlags required = flags & mask; diff --git a/gfx/layers/opengl/GrallocTextureHost.cpp b/gfx/layers/opengl/GrallocTextureHost.cpp index ee1f60822f9..849205ef748 100644 --- a/gfx/layers/opengl/GrallocTextureHost.cpp +++ b/gfx/layers/opengl/GrallocTextureHost.cpp @@ -212,8 +212,8 @@ GrallocTextureHostOGL::GetRenderState() if (mIsOpaque) { flags |= LayerRenderStateFlags::OPAQUE; } - if (mFlags & TextureFlags::NEEDS_Y_FLIP) { - flags |= LayerRenderStateFlags::Y_FLIPPED; + if (mFlags & TextureFlags::ORIGIN_BOTTOM_LEFT) { + flags |= LayerRenderStateFlags::ORIGIN_BOTTOM_LEFT; } if (mFlags & TextureFlags::RB_SWAPPED) { flags |= LayerRenderStateFlags::FORMAT_RB_SWAP; diff --git a/gfx/layers/opengl/TextureClientOGL.cpp b/gfx/layers/opengl/TextureClientOGL.cpp index 8aa64ed7345..d6b35eb7678 100644 --- a/gfx/layers/opengl/TextureClientOGL.cpp +++ b/gfx/layers/opengl/TextureClientOGL.cpp @@ -34,8 +34,8 @@ EGLImageTextureClient::EGLImageTextureClient(ISurfaceAllocator* aAllocator, AddFlags(TextureFlags::DEALLOCATE_CLIENT); - if (aImage->GetData()->mInverted) { - AddFlags(TextureFlags::NEEDS_Y_FLIP); + if (aImage->GetData()->mOriginPos == gl::OriginPos::BottomLeft) { + AddFlags(TextureFlags::ORIGIN_BOTTOM_LEFT); } } @@ -77,7 +77,7 @@ SurfaceTextureClient::SurfaceTextureClient(ISurfaceAllocator* aAllocator, TextureFlags aFlags, AndroidSurfaceTexture* aSurfTex, gfx::IntSize aSize, - bool aInverted) + gl::OriginPos aOriginPos) : TextureClient(aAllocator, aFlags) , mSurfTex(aSurfTex) , mSize(aSize) @@ -89,8 +89,8 @@ SurfaceTextureClient::SurfaceTextureClient(ISurfaceAllocator* aAllocator, // Our data is always owned externally. AddFlags(TextureFlags::DEALLOCATE_CLIENT); - if (aInverted) { - AddFlags(TextureFlags::NEEDS_Y_FLIP); + if (aOriginPos == gl::OriginPos::BottomLeft) { + AddFlags(TextureFlags::ORIGIN_BOTTOM_LEFT); } } diff --git a/gfx/layers/opengl/TextureClientOGL.h b/gfx/layers/opengl/TextureClientOGL.h index 3130a0008e4..15c8cad9e12 100644 --- a/gfx/layers/opengl/TextureClientOGL.h +++ b/gfx/layers/opengl/TextureClientOGL.h @@ -77,7 +77,7 @@ public: TextureFlags aFlags, gl::AndroidSurfaceTexture* aSurfTex, gfx::IntSize aSize, - bool aInverted); + gl::OriginPos aOriginPos); ~SurfaceTextureClient(); diff --git a/gfx/layers/opengl/TextureHostOGL.cpp b/gfx/layers/opengl/TextureHostOGL.cpp index d98eb93021f..3a445c1ac1d 100644 --- a/gfx/layers/opengl/TextureHostOGL.cpp +++ b/gfx/layers/opengl/TextureHostOGL.cpp @@ -103,8 +103,8 @@ FlagsToGLFlags(TextureFlags aFlags) if (aFlags & TextureFlags::USE_NEAREST_FILTER) result |= TextureImage::UseNearestFilter; - if (aFlags & TextureFlags::NEEDS_Y_FLIP) - result |= TextureImage::NeedsYFlip; + if (aFlags & TextureFlags::ORIGIN_BOTTOM_LEFT) + result |= TextureImage::OriginBottomLeft; if (aFlags & TextureFlags::DISALLOW_BIGIMAGE) result |= TextureImage::DisallowBigImage; diff --git a/widget/gonk/HwcComposer2D.cpp b/widget/gonk/HwcComposer2D.cpp index 2474de48e85..bc161f649c9 100644 --- a/widget/gonk/HwcComposer2D.cpp +++ b/widget/gonk/HwcComposer2D.cpp @@ -426,13 +426,16 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer, return false; } + const bool needsYFlip = state.OriginBottomLeft() ? true + : false; + hwc_rect_t sourceCrop, displayFrame; if(!HwcUtils::PrepareLayerRects(visibleRect, layerTransform, layerBufferTransform, clip, bufferRect, - state.YFlipped(), + needsYFlip, &(sourceCrop), &(displayFrame))) { @@ -609,7 +612,10 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer, } } - if (state.YFlipped()) { + const bool needsYFlip = state.OriginBottomLeft() ? true + : false; + + if (needsYFlip) { // Invert vertical reflection flag if it was already set hwcLayer.transform ^= HWC_TRANSFORM_FLIP_V; } From a2a49258e5d7098a9dfce23ca5a1dff9792bab04 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Wed, 31 Dec 2014 12:18:12 +1100 Subject: [PATCH 09/41] Bug 649142 - Part 1: Add macros and flags for defining logical properties and don't allocate storage for them in nsRuleData. r=dbaron We define a new flag CSS_PROPERTY_LOGICAL to be used for logical longhand properties and a new CSS_PROP_LOGICAL macro in nsCSSPropList.h to define them. When using CSS_PROP to capture all properties, includers must now explicitly indicate whether logical properties are included or not, by defining CSS_PROP_LIST_EXCLUDE_LOGICAL (to exclude them), CSS_PROP_LIST_INCLUDE_LOGICAL (to include them), or CSS_PROP_LOGICAL (to capture them separately from other properties). --- dom/webidl/CSS2PropertiesProps.h | 2 + layout/style/nsCSSParser.cpp | 2 + layout/style/nsCSSPropList.h | 65 +++++++++++++++++++++++-- layout/style/nsCSSProperty.h | 2 + layout/style/nsCSSProps.cpp | 40 +++++++++++++++ layout/style/nsCSSProps.h | 3 ++ layout/style/nsComputedDOMStyle.cpp | 4 ++ layout/style/nsDOMCSSDeclaration.h | 2 + layout/style/nsRuleData.h | 2 + layout/style/test/ListCSSProperties.cpp | 4 ++ 10 files changed, 122 insertions(+), 4 deletions(-) diff --git a/dom/webidl/CSS2PropertiesProps.h b/dom/webidl/CSS2PropertiesProps.h index f0dd534bcc2..978dfd45c18 100644 --- a/dom/webidl/CSS2PropertiesProps.h +++ b/dom/webidl/CSS2PropertiesProps.h @@ -17,9 +17,11 @@ DO_PROP(name, method, id, flags, pref) #define CSS_PROP_PUBLIC_OR_PRIVATE(publicname_, privatename_) publicname_ #define CSS_PROP_LIST_EXCLUDE_INTERNAL +#define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" +#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP_LIST_EXCLUDE_INTERNAL #undef CSS_PROP_PUBLIC_OR_PRIVATE #undef CSS_PROP_SHORTHAND diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 19e5b9aea2e..26e02e7e7d4 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -59,7 +59,9 @@ nsCSSProps::kParserVariantTable[eCSSProperty_COUNT_no_shorthands] = { #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \ stylestruct_, stylestructoffset_, animtype_) \ parsevariant_, +#define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" +#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP }; diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index ac0915d7bf7..e7f59f6cb2b 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -17,7 +17,7 @@ It is recommended (but not strictly necessary) to keep all entries in alphabetical order. - The arguments to CSS_PROP and CSS_PROP_* are: + The arguments to CSS_PROP, CSS_PROP_LOGICAL and CSS_PROP_* are: -. 'name' entries represent a CSS property name and *must* use only lowercase characters. @@ -51,9 +51,9 @@ keyword table member of class nsCSSProps, for use in nsCSSProps::LookupPropertyValue. - -. 'stylestruct_' [used only for CSS_PROP, not CSS_PROP_*] gives the - name of the style struct. Can be used to make nsStyle##stylestruct_ - and eStyleStruct_##stylestruct_ + -. 'stylestruct_' [used only for CSS_PROP and CSS_PROP_LOGICAL, not + CSS_PROP_*] gives the name of the style struct. Can be used to make + nsStyle##stylestruct_ and eStyleStruct_##stylestruct_ -. 'stylestructoffset_' [not used for CSS_PROP_BACKENDONLY] gives the result of offsetof(nsStyle*, member). Ignored (and generally @@ -65,6 +65,11 @@ CSS_PROP_SHORTHAND only takes 1-5. + CSS_PROP_LOGICAL should be used instead of CSS_PROP_struct when + defining logical properties (which also must be defined with the + CSS_PROPERTY_LOGICAL flag). Logical shorthand properties should still + be defined with CSS_PROP_SHORTHAND. + ******/ @@ -87,6 +92,26 @@ // exclude internal properties that are not represented in the DOM (only // the DOM style code defines this). +// When capturing all properties by defining CSS_PROP, callers must also +// define one of the following three macros: +// +// CSS_PROP_LIST_EXCLUDE_LOGICAL +// Does not include logical properties (defined with CSS_PROP_LOGICAL, +// such as -moz-margin-start) when capturing properties to CSS_PROP. +// +// CSS_PROP_LIST_INCLUDE_LOGICAL +// Does include logical properties when capturing properties to +// CSS_PROP. +// +// CSS_PROP_LOGICAL +// Captures logical properties separately to CSS_PROP_LOGICAL. +// +// (CSS_PROP_LIST_EXCLUDE_LOGICAL is used for example to ensure +// gPropertyCountInStruct and gPropertyIndexInStruct do not allocate any +// storage to logical properties, since the result of the cascade, stored +// in an nsRuleData, does not need to store both logical and physical +// property values.) + // Callers may also define CSS_PROP_LIST_ONLY_COMPONENTS_OF_ALL_SHORTHAND // to exclude properties that are not considered to be components of the 'all' // shorthand property. Currently this excludes 'direction' and 'unicode-bidi', @@ -134,12 +159,36 @@ #define DEFINED_CSS_PROP_BACKENDONLY #endif +// And similarly for logical properties. An includer can define +// CSS_PROP_LOGICAL to capture all logical properties, but otherwise they +// are included in CSS_PROP (as long as CSS_PROP_LIST_INCLUDE_LOGICAL is +// defined). +#if defined(CSS_PROP_LOGICAL) && defined(CSS_PROP_LIST_EXCLUDE_LOGICAL) || defined(CSS_PROP_LOGICAL) && defined(CSS_PROP_LIST_INCLUDE_LOGICAL) || defined(CSS_PROP_LIST_EXCLUDE_LOGICAL) && defined(CSS_PROP_LIST_INCLUDE_LOGICAL) +#error Do not define more than one of CSS_PROP_LOGICAL, CSS_PROP_LIST_EXCLUDE_LOGICAL and CSS_PROP_LIST_INCLUDE_LOGICAL when capturing properties using CSS_PROP. +#endif + +#ifndef CSS_PROP_LOGICAL +#ifdef CSS_PROP_LIST_INCLUDE_LOGICAL +#define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, struct_, stylestructoffset_, animtype_) CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, struct_, stylestructoffset_, animtype_) +#else +#ifndef CSS_PROP_LIST_EXCLUDE_LOGICAL +#error Must define exactly one of CSS_PROP_LOGICAL, CSS_PROP_LIST_EXCLUDE_LOGICAL and CSS_PROP_LIST_INCLUDE_LOGICAL when capturing properties using CSS_PROP. +#endif +#define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, struct_, stylestructoffset_, animtype_) /* nothing */ +#endif +#define DEFINED_CSS_PROP_LOGICAL +#endif + #else /* !defined(CSS_PROP) */ // An includer who does not define CSS_PROP can define any or all of the // per-struct macros that are equivalent to it, and the rest will be // ignored. +#if defined(CSS_PROP_LIST_EXCLUDE_LOGICAL) || defined(CSS_PROP_LIST_INCLUDE_LOGICAL) +#error Do not define CSS_PROP_LIST_EXCLUDE_LOGICAL or CSS_PROP_LIST_INCLUDE_LOGICAL when not capturing properties using CSS_PROP. +#endif + #ifndef CSS_PROP_FONT #define CSS_PROP_FONT(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, stylestructoffset_, animtype_) /* nothing */ #define DEFINED_CSS_PROP_FONT @@ -241,6 +290,10 @@ #define CSS_PROP_BACKENDONLY(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_) /* nothing */ #define DEFINED_CSS_PROP_BACKENDONLY #endif +#ifndef CSS_PROP_LOGICAL +#define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, struct_, stylestructoffset_, animtype_) /* nothing */ +#define DEFINED_CSS_PROP_LOGICAL +#endif #endif /* !defined(CSS_PROP) */ @@ -4189,5 +4242,9 @@ CSS_PROP_FONT( #undef CSS_PROP_SHORTHAND #undef DEFINED_CSS_PROP_SHORTHAND #endif +#ifdef DEFINED_CSS_PROP_LOGICAL +#undef CSS_PROP_LOGICAL +#undef DEFINED_CSS_PROP_LOGICAL +#endif #undef CSS_PROP_DOMPROP_PREFIXED diff --git a/layout/style/nsCSSProperty.h b/layout/style/nsCSSProperty.h index b29ffdd4acc..36d67d7106f 100644 --- a/layout/style/nsCSSProperty.h +++ b/layout/style/nsCSSProperty.h @@ -21,7 +21,9 @@ enum nsCSSProperty { #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \ kwtable_, stylestruct_, stylestructoffset_, animtype_) \ eCSSProperty_##id_, + #define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" + #undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP eCSSProperty_COUNT_no_shorthands, diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp index a9408be01e9..41caf5930bb 100644 --- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -36,7 +36,9 @@ const char* const kCSSRawProperties[eCSSProperty_COUNT_with_aliases] = { #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \ stylestruct_, stylestructoffset_, animtype_) \ #name_, +#define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" +#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) #name_, #include "nsCSSPropList.h" @@ -169,7 +171,9 @@ nsCSSProps::AddRefTable(void) #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \ kwtable_, stylestruct_, stylestructoffset_, animtype_) \ OBSERVE_PROP(pref_, eCSSProperty_##id_) + #define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" + #undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) \ @@ -2119,7 +2123,9 @@ nsCSSProps::kKeywordTableTable[eCSSProperty_COUNT_no_shorthands] = { #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \ kwtable_, stylestruct_, stylestructoffset_, animtype_) \ kwtable_, + #define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" + #undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP }; @@ -2165,9 +2171,11 @@ const nsStyleStructID nsCSSProps::kSIDTable[eCSSProperty_COUNT_no_shorthands] = #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \ kwtable_, stylestruct_, stylestructoffset_, animtype_) \ eStyleStruct_##stylestruct_, + #define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" + #undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP }; @@ -2176,7 +2184,9 @@ nsCSSProps::kAnimTypeTable[eCSSProperty_COUNT_no_shorthands] = { #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \ stylestruct_, stylestructoffset_, animtype_) \ animtype_, +#define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" +#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP }; @@ -2185,7 +2195,9 @@ nsCSSProps::kStyleStructOffsetTable[eCSSProperty_COUNT_no_shorthands] = { #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \ stylestruct_, stylestructoffset_, animtype_) \ stylestructoffset_, +#define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" +#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP }; @@ -2193,7 +2205,9 @@ const uint32_t nsCSSProps::kFlagsTable[eCSSProperty_COUNT] = { #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \ stylestruct_, stylestructoffset_, animtype_) \ flags_, +#define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" +#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) flags_, #include "nsCSSPropList.h" @@ -2202,11 +2216,13 @@ const uint32_t nsCSSProps::kFlagsTable[eCSSProperty_COUNT] = { static const nsCSSProperty gAllSubpropTable[] = { #define CSS_PROP_LIST_ONLY_COMPONENTS_OF_ALL_SHORTHAND +#define CSS_PROP_LIST_INCLUDE_LOGICAL #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \ stylestruct_, stylestructoffset_, animtype_) \ eCSSProperty_##id_, #include "nsCSSPropList.h" #undef CSS_PROP +#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP_LIST_ONLY_COMPONENTS_OF_ALL_SHORTHAND eCSSProperty_UNKNOWN }; @@ -2975,11 +2991,16 @@ nsCSSProps::gPropertyIndexInStruct[eCSSProperty_COUNT_no_shorthands] = { #define CSS_PROP_BACKENDONLY(name_, id_, method_, flags_, pref_, \ parsevariant_, kwtable_) \ size_t(-1), + #define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, \ + kwtable_, stylestruct_, stylestructoffset_, \ + animtype_) \ + size_t(-1), #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \ kwtable_, stylestruct_, stylestructoffset_, animtype_) \ ePropertyIndex_for_##id_, #include "nsCSSPropList.h" #undef CSS_PROP + #undef CSS_PROP_LOGICAL #undef CSS_PROP_BACKENDONLY }; @@ -2989,7 +3010,9 @@ nsCSSProps::gPropertyEnabled[eCSSProperty_COUNT_with_aliases] = { #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \ kwtable_, stylestruct_, stylestructoffset_, animtype_) \ true, + #define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" + #undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) \ @@ -3002,3 +3025,20 @@ nsCSSProps::gPropertyEnabled[eCSSProperty_COUNT_with_aliases] = { #include "nsCSSPropAliasList.h" #undef CSS_PROP_ALIAS }; + +// Check that all properties defined using CSS_PROP_*_LOGICAL macros use +// the CSS_PROPERTY_LOGICAL flag. +#define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \ + kwtable_, stylestruct_, stylestructoffset_, animtype_) \ + static_assert(!((flags_) & CSS_PROPERTY_LOGICAL), \ + "only properties defined with CSS_PROP_LOGICAL can use " \ + "the CSS_PROPERTY_LOGICAL flag"); +#define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, \ + kwtable_, stylestruct_, stylestructoffset_, \ + animtype_) \ + static_assert((flags_) & CSS_PROPERTY_LOGICAL, \ + "properties defined with CSS_PROP_LOGICAL must also use " \ + "the CSS_PROPERTY_LOGICAL flag"); +#include "nsCSSPropList.h" +#undef CSS_PROP_LOGICAL +#undef CSS_PROP diff --git a/layout/style/nsCSSProps.h b/layout/style/nsCSSProps.h index 5613a0507b6..2feec741c14 100644 --- a/layout/style/nsCSSProps.h +++ b/layout/style/nsCSSProps.h @@ -216,6 +216,9 @@ static_assert((CSS_PROPERTY_PARSE_PROPERTY_MASK & // This property's unitless values are pixels. #define CSS_PROPERTY_NUMBERS_ARE_PIXELS (1<<24) +// This property is a logical property (such as padding-inline-start). +#define CSS_PROPERTY_LOGICAL (1<<25) + /** * Types of animatable values. */ diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index c772ee0d560..de6df5def34 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -5868,7 +5868,9 @@ nsComputedDOMStyle::RegisterPrefChangeCallbacks() #define CSS_PROP(prop_, id_, method_, flags_, pref_, parsevariant_, \ kwtable_, stylestruct_, stylestructoffset_, animtype_) \ REGISTER_CALLBACK(pref_) +#define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" +#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP #undef REGISTER_CALLBACK } @@ -5884,7 +5886,9 @@ nsComputedDOMStyle::UnregisterPrefChangeCallbacks() #define CSS_PROP(prop_, id_, method_, flags_, pref_, parsevariant_, \ kwtable_, stylestruct_, stylestructoffset_, animtype_) \ UNREGISTER_CALLBACK(pref_) +#define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" +#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP #undef UNREGISTER_CALLBACK } diff --git a/layout/style/nsDOMCSSDeclaration.h b/layout/style/nsDOMCSSDeclaration.h index eed8389b55a..329cfb99f4e 100644 --- a/layout/style/nsDOMCSSDeclaration.h +++ b/layout/style/nsDOMCSSDeclaration.h @@ -79,6 +79,7 @@ public: } #define CSS_PROP_LIST_EXCLUDE_INTERNAL +#define CSS_PROP_LIST_INCLUDE_LOGICAL #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) \ CSS_PROP(name_, id_, method_, flags_, pref_, X, X, X, X, X) #include "nsCSSPropList.h" @@ -89,6 +90,7 @@ public: #undef CSS_PROP_ALIAS #undef CSS_PROP_SHORTHAND +#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP_LIST_EXCLUDE_INTERNAL #undef CSS_PROP #undef CSS_PROP_PUBLIC_OR_PRIVATE diff --git a/layout/style/nsRuleData.h b/layout/style/nsRuleData.h index 53d6f777ccb..abbd54a6356 100644 --- a/layout/style/nsRuleData.h +++ b/layout/style/nsRuleData.h @@ -116,7 +116,9 @@ struct nsRuleData #define CSS_PROP_BACKENDONLY(name_, id_, method_, flags_, pref_, \ parsevariant_, kwtable_) \ /* empty; backend-only structs are not in nsRuleData */ + #define CSS_PROP_LIST_EXCLUDE_LOGICAL #include "nsCSSPropList.h" + #undef CSS_PROP_LIST_EXCLUDE_LOGICAL #undef CSS_PROP #undef CSS_PROP_PUBLIC_OR_PRIVATE #undef CSS_PROP_BACKENDONLY diff --git a/layout/style/test/ListCSSProperties.cpp b/layout/style/test/ListCSSProperties.cpp index e213e25377d..9f93b8505a7 100644 --- a/layout/style/test/ListCSSProperties.cpp +++ b/layout/style/test/ListCSSProperties.cpp @@ -21,9 +21,11 @@ const PropertyInfo gLonghandProperties[] = { #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \ stylestruct_, stylestructoffset_, animtype_) \ { #name_, #method_, pref_ }, +#define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" +#undef CSS_PROP_LIST_EXCLUDE_LOGICAL #undef CSS_PROP #undef CSS_PROP_PUBLIC_OR_PRIVATE @@ -40,9 +42,11 @@ const char* gLonghandPropertiesWithDOMProp[] = { #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \ stylestruct_, stylestructoffset_, animtype_) \ #name_, +#define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" +#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP #undef CSS_PROP_LIST_EXCLUDE_INTERNAL From 3c21668a0abe50867301aa8ce4099cc055b723c0 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Wed, 31 Dec 2014 12:18:13 +1100 Subject: [PATCH 10/41] Bug 649142 - Part 2: Convert logical properties to their physical equivalents during the cascade. r=dbaron We will add cases to EnsurePhysicalProperty's switch statement as we convert the existing shorthand-implemented logical properties to the new, CSS_PROPERTY_LOGICAL-bearing properties. --- layout/style/nsCSSDataBlock.cpp | 41 ++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/layout/style/nsCSSDataBlock.cpp b/layout/style/nsCSSDataBlock.cpp index 2191bf513a3..c0fc73854a8 100644 --- a/layout/style/nsCSSDataBlock.cpp +++ b/layout/style/nsCSSDataBlock.cpp @@ -163,6 +163,25 @@ MapSinglePropertyInto(nsCSSProperty aProp, } } +/** + * If aProperty is a logical property, converts it to the equivalent physical + * property based on writing mode information obtained from aRuleData's + * style context. Returns true if aProperty was changed. + */ +static inline void +EnsurePhysicalProperty(nsCSSProperty& aProperty, nsRuleData* aRuleData) +{ + uint8_t direction = aRuleData->mStyleContext->StyleVisibility()->mDirection; + bool ltr = direction == NS_STYLE_DIRECTION_LTR; + + switch (aProperty) { + default: + NS_ABORT_IF_FALSE(nsCSSProps::PropHasFlags(aProperty, + CSS_PROPERTY_LOGICAL), + "unhandled logical property"); + } +} + void nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const { @@ -173,10 +192,20 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const if (!(aRuleData->mSIDs & mStyleBits)) return; - for (uint32_t i = 0; i < mNumProps; i++) { + // We process these in reverse order so that we end up mapping the + // right property when one can be expressed using both logical and + // physical property names. + for (uint32_t i = mNumProps; i-- > 0; ) { nsCSSProperty iProp = PropertyAtIndex(i); if (nsCachedStyleData::GetBitForSID(nsCSSProps::kSIDTable[iProp]) & aRuleData->mSIDs) { + if (nsCSSProps::PropHasFlags(iProp, CSS_PROPERTY_LOGICAL)) { + EnsurePhysicalProperty(iProp, aRuleData); + // We can't cache anything on the rule tree if we use any data from + // the style context, since data cached in the rule tree could be + // used with a style context with a different value. + aRuleData->mCanStoreInRuleTree = false; + } nsCSSValue* target = aRuleData->ValueFor(iProp); if (target->GetUnit() == eCSSUnit_Null) { const nsCSSValue *val = ValueAtIndex(i); @@ -605,11 +634,17 @@ nsCSSExpandedDataBlock::MapRuleInfoInto(nsCSSProperty aPropID, const nsCSSValue* src = PropertyAt(aPropID); MOZ_ASSERT(src->GetUnit() != eCSSUnit_Null); - nsCSSValue* dest = aRuleData->ValueFor(aPropID); + nsCSSProperty physicalProp = aPropID; + if (nsCSSProps::PropHasFlags(aPropID, CSS_PROPERTY_LOGICAL)) { + EnsurePhysicalProperty(physicalProp, aRuleData); + aRuleData->mCanStoreInRuleTree = false; + } + + nsCSSValue* dest = aRuleData->ValueFor(physicalProp); MOZ_ASSERT(dest->GetUnit() == eCSSUnit_TokenStream && dest->GetTokenStreamValue()->mPropertyID == aPropID); - MapSinglePropertyInto(aPropID, src, dest, aRuleData); + MapSinglePropertyInto(physicalProp, src, dest, aRuleData); } #ifdef DEBUG From f2d31a76695194bd7094b1409505c840e103612d Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Wed, 31 Dec 2014 12:18:13 +1100 Subject: [PATCH 11/41] Bug 649142 - Part 2.1: Test that logical properties in property_database.js are longhands. r=dbaron --- layout/style/test/property_database.js | 2 ++ layout/style/test/test_property_database.html | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index 34049760d6f..36909d205c8 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -22,6 +22,8 @@ const CSS_TYPE_SHORTHAND_AND_LONGHAND = 2; // alias_for: optional, indicates that the property is an alias for // some other property that is the preferred serialization. (Type // must not be CSS_TYPE_LONGHAND.) +// logical: optional, indicates that the property is a logical directional +// property. (Type must be CSS_TYPE_LONGHAND.) // get_computed: if present, the property's computed value shows up on // another property, and this is a function used to get it // initial_values: Values whose computed value should be the same as the diff --git a/layout/style/test/test_property_database.html b/layout/style/test/test_property_database.html index 7b550afa0e8..aa5e5b2b6b8 100644 --- a/layout/style/test/test_property_database.html +++ b/layout/style/test/test_property_database.html @@ -122,6 +122,17 @@ for (var prop in gCSSProperties) { "must have non-initial values for property '" + prop + "'"); } +/* + * Test that only longhand properties are listed as logical properties. + */ +for (var prop in gCSSProperties) { + var info = gCSSProperties[prop]; + if (info.logical) { + is(info.type, CSS_TYPE_LONGHAND, + "property '" + prop + "' is listed as CSS_TYPE_LONGHAND due to its " + + "being a logical property"); + } +} From fc345d527c70981b128d08c04dfcaedbbf63207c Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Wed, 31 Dec 2014 12:18:14 +1100 Subject: [PATCH 12/41] Bug 649142 - Part 3: Convert logical padding properties. r=dbaron Here we convert the logical padding properties into their new resolved-at- cascade-time implementations. This involves: * converting -moz-padding-{start,end} into logical longhand properties * adding padding-inline-{start,end} aliases for -moz-padding-{start,end} * converting padding-{left,right} into longhand properties * removing padding-{left,right}-value and padding-{left,right}-{ltr,rtl}-source internal properties The CSS parser and various tests are simplified a bit as a result. --- browser/devtools/layoutview/view.js | 4 - dom/html/HTMLTableElement.cpp | 4 +- layout/inspector/tests/test_bug1006595.html | 6 +- layout/style/Declaration.cpp | 4 - layout/style/nsCSSDataBlock.cpp | 6 + layout/style/nsCSSParser.cpp | 25 +-- layout/style/nsCSSPropAliasList.h | 8 + layout/style/nsCSSPropList.h | 154 ++++-------------- layout/style/nsCSSProps.cpp | 45 +---- layout/style/nsRuleData.h | 2 +- layout/style/nsRuleNode.cpp | 31 +--- layout/style/test/ListCSSProperties.cpp | 8 - .../test/css_properties_like_longhand.js | 4 - layout/style/test/property_database.js | 72 ++++++-- layout/style/test/test_value_computation.html | 2 + 15 files changed, 127 insertions(+), 248 deletions(-) diff --git a/browser/devtools/layoutview/view.js b/browser/devtools/layoutview/view.js index b1ea551f0bf..cb0b365a3ce 100644 --- a/browser/devtools/layoutview/view.js +++ b/browser/devtools/layoutview/view.js @@ -192,15 +192,11 @@ LayoutView.prototype = { paddingBottom: {selector: ".padding.bottom > span", property: "padding-bottom", value: undefined}, - // padding-left behaves the same as margin-left paddingLeft: {selector: ".padding.left > span", property: "padding-left", - realProperty: "padding-left-value", value: undefined}, - // padding-right behaves the same as margin-left paddingRight: {selector: ".padding.right > span", property: "padding-right", - realProperty: "padding-right-value", value: undefined}, borderTop: {selector: ".border.top > span", property: "border-top-width", diff --git a/dom/html/HTMLTableElement.cpp b/dom/html/HTMLTableElement.cpp index 18cd16f5f63..493d02421cb 100644 --- a/dom/html/HTMLTableElement.cpp +++ b/dom/html/HTMLTableElement.cpp @@ -854,12 +854,12 @@ MapInheritedTableAttributesIntoRule(const nsMappedAttributes* aAttributes, // don't have any set. nsCSSValue padVal(float(value->GetIntegerValue()), eCSSUnit_Pixel); - nsCSSValue* paddingLeft = aData->ValueForPaddingLeftValue(); + nsCSSValue* paddingLeft = aData->ValueForPaddingLeft(); if (paddingLeft->GetUnit() == eCSSUnit_Null) { *paddingLeft = padVal; } - nsCSSValue* paddingRight = aData->ValueForPaddingRightValue(); + nsCSSValue* paddingRight = aData->ValueForPaddingRight(); if (paddingRight->GetUnit() == eCSSUnit_Null) { *paddingRight = padVal; } diff --git a/layout/inspector/tests/test_bug1006595.html b/layout/inspector/tests/test_bug1006595.html index 2e9e237adc6..0ad713858e4 100644 --- a/layout/inspector/tests/test_bug1006595.html +++ b/layout/inspector/tests/test_bug1006595.html @@ -23,11 +23,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1006595 var paddingSubProps = utils.getSubpropertiesForCSSProperty("padding"); arraysEqual(paddingSubProps, [ "padding-top", - "padding-right-value", + "padding-right", "padding-bottom", - "padding-left-value", - "padding-left-ltr-source", "padding-left-rtl-source", - "padding-right-ltr-source", "padding-right-rtl-source" ], + "padding-left" ], "'padding' subproperties"); var displaySubProps = utils.getSubpropertiesForCSSProperty("color"); diff --git a/layout/style/Declaration.cpp b/layout/style/Declaration.cpp index 3685b7a8da0..883d51b6557 100644 --- a/layout/style/Declaration.cpp +++ b/layout/style/Declaration.cpp @@ -400,10 +400,6 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue, case eCSSProperty_margin_right: case eCSSProperty_margin_start: case eCSSProperty_margin_end: - case eCSSProperty_padding_left: - case eCSSProperty_padding_right: - case eCSSProperty_padding_start: - case eCSSProperty_padding_end: case eCSSProperty_border_left_color: case eCSSProperty_border_left_style: case eCSSProperty_border_left_width: diff --git a/layout/style/nsCSSDataBlock.cpp b/layout/style/nsCSSDataBlock.cpp index c0fc73854a8..638eb283435 100644 --- a/layout/style/nsCSSDataBlock.cpp +++ b/layout/style/nsCSSDataBlock.cpp @@ -175,6 +175,12 @@ EnsurePhysicalProperty(nsCSSProperty& aProperty, nsRuleData* aRuleData) bool ltr = direction == NS_STYLE_DIRECTION_LTR; switch (aProperty) { + case eCSSProperty_padding_end: + aProperty = ltr ? eCSSProperty_padding_right : eCSSProperty_padding_left; + break; + case eCSSProperty_padding_start: + aProperty = ltr ? eCSSProperty_padding_left : eCSSProperty_padding_right; + break; default: NS_ABORT_IF_FALSE(nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_LOGICAL), diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 26e02e7e7d4..653ee864ae1 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -9907,18 +9907,6 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSProperty aPropID) return ParseOverflow(); case eCSSProperty_padding: return ParsePadding(); - case eCSSProperty_padding_end: - return ParseDirectionalBoxProperty(eCSSProperty_padding_end, - NS_BOXPROP_SOURCE_LOGICAL); - case eCSSProperty_padding_left: - return ParseDirectionalBoxProperty(eCSSProperty_padding_left, - NS_BOXPROP_SOURCE_PHYSICAL); - case eCSSProperty_padding_right: - return ParseDirectionalBoxProperty(eCSSProperty_padding_right, - NS_BOXPROP_SOURCE_PHYSICAL); - case eCSSProperty_padding_start: - return ParseDirectionalBoxProperty(eCSSProperty_padding_start, - NS_BOXPROP_SOURCE_LOGICAL); case eCSSProperty_quotes: return ParseQuotes(); case eCSSProperty_size: @@ -13085,20 +13073,11 @@ CSSParserImpl::ParsePadding() { static const nsCSSProperty kPaddingSideIDs[] = { eCSSProperty_padding_top, - eCSSProperty_padding_right_value, + eCSSProperty_padding_right, eCSSProperty_padding_bottom, - eCSSProperty_padding_left_value - }; - static const nsCSSProperty kPaddingSources[] = { - eCSSProperty_padding_left_ltr_source, - eCSSProperty_padding_left_rtl_source, - eCSSProperty_padding_right_ltr_source, - eCSSProperty_padding_right_rtl_source, - eCSSProperty_UNKNOWN + eCSSProperty_padding_left }; - // do this now, in case 4 values weren't specified - InitBoxPropsAsPhysical(kPaddingSources); return ParseBoxProperties(kPaddingSideIDs); } diff --git a/layout/style/nsCSSPropAliasList.h b/layout/style/nsCSSPropAliasList.h index 78605295e6d..d2ba9544049 100644 --- a/layout/style/nsCSSPropAliasList.h +++ b/layout/style/nsCSSPropAliasList.h @@ -139,3 +139,11 @@ CSS_PROP_ALIAS(-moz-text-decoration-style, text_decoration_style, MozTextDecorationStyle, "") +CSS_PROP_ALIAS(padding-inline-end, + padding_end, + PaddingInlineEnd, + "layout.css.vertical-text.enabled") +CSS_PROP_ALIAS(padding-inline-start, + padding_start, + PaddingInlineStart, + "layout.css.vertical-text.enabled") diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index e7f59f6cb2b..b6df55fed93 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -2752,158 +2752,76 @@ CSS_PROP_PADDING( nullptr, offsetof(nsStylePadding, mPadding), eStyleAnimType_Sides_Bottom) -CSS_PROP_SHORTHAND( +CSS_PROP_LOGICAL( -moz-padding-end, padding_end, CSS_PROP_DOMPROP_PREFIXED(PaddingEnd), - CSS_PROPERTY_PARSE_FUNCTION, - "") -#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL -CSS_PROP_PADDING( - padding-end-value, - padding_end_value, - PaddingEndValue, - CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_VALUE_NONNEGATIVE | CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | // This is required by the UA stylesheet and can't be overridden. CSS_PROPERTY_APPLIES_TO_PLACEHOLDER | - CSS_PROPERTY_STORES_CALC, + CSS_PROPERTY_STORES_CALC | + CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH | + CSS_PROPERTY_LOGICAL, "", - VARIANT_HLP | VARIANT_CALC, // for internal use + VARIANT_HLP | VARIANT_CALC, nullptr, + Padding, CSS_PROP_NO_OFFSET, eStyleAnimType_None) -#endif -CSS_PROP_SHORTHAND( +CSS_PROP_LOGICAL( + -moz-padding-start, + padding_start, + CSS_PROP_DOMPROP_PREFIXED(PaddingStart), + CSS_PROPERTY_PARSE_VALUE | + CSS_PROPERTY_VALUE_NONNEGATIVE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + // This is required by the UA stylesheet and can't be overridden. + CSS_PROPERTY_APPLIES_TO_PLACEHOLDER | + CSS_PROPERTY_STORES_CALC | + CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH | + CSS_PROPERTY_LOGICAL, + "", + VARIANT_HLP | VARIANT_CALC, + nullptr, + Padding, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +CSS_PROP_PADDING( padding-left, padding_left, PaddingLeft, - CSS_PROPERTY_PARSE_FUNCTION | - CSS_PROPERTY_UNITLESS_LENGTH_QUIRK | - CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, - "") -#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL -CSS_PROP_PADDING( - padding-left-value, - padding_left_value, - PaddingLeftValue, - CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_VALUE_NONNEGATIVE | + CSS_PROPERTY_UNITLESS_LENGTH_QUIRK | CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | // This is required by the UA stylesheet and can't be overridden. CSS_PROPERTY_APPLIES_TO_PLACEHOLDER | - CSS_PROPERTY_REPORT_OTHER_NAME | - CSS_PROPERTY_STORES_CALC, + CSS_PROPERTY_STORES_CALC | + CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, "", - VARIANT_HLP | VARIANT_CALC, // for internal use + VARIANT_HLP | VARIANT_CALC, nullptr, offsetof(nsStylePadding, mPadding), eStyleAnimType_Sides_Left) CSS_PROP_PADDING( - padding-left-ltr-source, - padding_left_ltr_source, - PaddingLeftLTRSource, - CSS_PROPERTY_PARSE_INACCESSIBLE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - // This is required by the UA stylesheet and can't be overridden. - CSS_PROPERTY_APPLIES_TO_PLACEHOLDER | - CSS_PROPERTY_DIRECTIONAL_SOURCE, - "", - 0, - kBoxPropSourceKTable, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) -CSS_PROP_PADDING( - padding-left-rtl-source, - padding_left_rtl_source, - PaddingLeftRTLSource, - CSS_PROPERTY_PARSE_INACCESSIBLE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - // This is required by the UA stylesheet and can't be overridden. - CSS_PROPERTY_APPLIES_TO_PLACEHOLDER | - CSS_PROPERTY_DIRECTIONAL_SOURCE, - "", - 0, - kBoxPropSourceKTable, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) -#endif -CSS_PROP_SHORTHAND( padding-right, padding_right, PaddingRight, - CSS_PROPERTY_PARSE_FUNCTION | - CSS_PROPERTY_UNITLESS_LENGTH_QUIRK | - CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, - "") -#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL -CSS_PROP_PADDING( - padding-right-value, - padding_right_value, - PaddingRightValue, - CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_VALUE_NONNEGATIVE | + CSS_PROPERTY_UNITLESS_LENGTH_QUIRK | CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | // This is required by the UA stylesheet and can't be overridden. CSS_PROPERTY_APPLIES_TO_PLACEHOLDER | - CSS_PROPERTY_REPORT_OTHER_NAME | - CSS_PROPERTY_STORES_CALC, + CSS_PROPERTY_STORES_CALC | + CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, "", - VARIANT_HLP | VARIANT_CALC, // for internal use + VARIANT_HLP | VARIANT_CALC, nullptr, offsetof(nsStylePadding, mPadding), eStyleAnimType_Sides_Right) -CSS_PROP_PADDING( - padding-right-ltr-source, - padding_right_ltr_source, - PaddingRightLTRSource, - CSS_PROPERTY_PARSE_INACCESSIBLE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - // This is required by the UA stylesheet and can't be overridden. - CSS_PROPERTY_APPLIES_TO_PLACEHOLDER | - CSS_PROPERTY_DIRECTIONAL_SOURCE, - "", - 0, - kBoxPropSourceKTable, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) -CSS_PROP_PADDING( - padding-right-rtl-source, - padding_right_rtl_source, - PaddingRightRTLSource, - CSS_PROPERTY_PARSE_INACCESSIBLE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - CSS_PROPERTY_DIRECTIONAL_SOURCE, - "", - 0, - kBoxPropSourceKTable, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) -#endif -CSS_PROP_SHORTHAND( - -moz-padding-start, - padding_start, - CSS_PROP_DOMPROP_PREFIXED(PaddingStart), - CSS_PROPERTY_PARSE_FUNCTION, - "") -#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL -CSS_PROP_PADDING( - padding-start-value, - padding_start_value, - PaddingStartValue, - CSS_PROPERTY_PARSE_INACCESSIBLE | - CSS_PROPERTY_VALUE_NONNEGATIVE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - // This is required by the UA stylesheet and can't be overridden. - CSS_PROPERTY_APPLIES_TO_PLACEHOLDER | - CSS_PROPERTY_STORES_CALC, - "", - VARIANT_HLP | VARIANT_CALC, // for internal use - nullptr, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) -#endif CSS_PROP_PADDING( padding-top, padding_top, diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp index 41caf5930bb..fa15b40858c 100644 --- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -578,10 +578,6 @@ nsCSSProps::OtherNameFor(nsCSSProperty aProperty) return eCSSProperty_margin_left; case eCSSProperty_margin_right_value: return eCSSProperty_margin_right; - case eCSSProperty_padding_left_value: - return eCSSProperty_padding_left; - case eCSSProperty_padding_right_value: - return eCSSProperty_padding_right; default: NS_ABORT_IF_FALSE(false, "bad caller"); } @@ -2704,46 +2700,9 @@ static const nsCSSProperty gOverflowSubpropTable[] = { static const nsCSSProperty gPaddingSubpropTable[] = { // Code relies on these being in top-right-bottom-left order. eCSSProperty_padding_top, - eCSSProperty_padding_right_value, + eCSSProperty_padding_right, eCSSProperty_padding_bottom, - eCSSProperty_padding_left_value, - // extras: - eCSSProperty_padding_left_ltr_source, - eCSSProperty_padding_left_rtl_source, - eCSSProperty_padding_right_ltr_source, - eCSSProperty_padding_right_rtl_source, - eCSSProperty_UNKNOWN -}; - -static const nsCSSProperty gPaddingLeftSubpropTable[] = { - // nsCSSParser::ParseDirectionalBoxProperty depends on this order - eCSSProperty_padding_left_value, - eCSSProperty_padding_left_ltr_source, - eCSSProperty_padding_left_rtl_source, - eCSSProperty_UNKNOWN -}; - -static const nsCSSProperty gPaddingRightSubpropTable[] = { - // nsCSSParser::ParseDirectionalBoxProperty depends on this order - eCSSProperty_padding_right_value, - eCSSProperty_padding_right_ltr_source, - eCSSProperty_padding_right_rtl_source, - eCSSProperty_UNKNOWN -}; - -static const nsCSSProperty gPaddingStartSubpropTable[] = { - // nsCSSParser::ParseDirectionalBoxProperty depends on this order - eCSSProperty_padding_start_value, - eCSSProperty_padding_left_ltr_source, - eCSSProperty_padding_right_rtl_source, - eCSSProperty_UNKNOWN -}; - -static const nsCSSProperty gPaddingEndSubpropTable[] = { - // nsCSSParser::ParseDirectionalBoxProperty depends on this order - eCSSProperty_padding_end_value, - eCSSProperty_padding_right_ltr_source, - eCSSProperty_padding_left_rtl_source, + eCSSProperty_padding_left, eCSSProperty_UNKNOWN }; diff --git a/layout/style/nsRuleData.h b/layout/style/nsRuleData.h index abbd54a6356..7b9d7ec0ac3 100644 --- a/layout/style/nsRuleData.h +++ b/layout/style/nsRuleData.h @@ -77,7 +77,7 @@ struct nsRuleData "calling nsRuleData::ValueFor on property not in mSIDs"); NS_ABORT_IF_FALSE(sid != eStyleStruct_BackendOnly && indexInStruct != size_t(-1), - "backend-only property"); + "backend-only or logical property"); return mValueStorage + mValueOffsets[sid] + indexInStruct; } diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 29c3d7de994..23bab2542a3 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -7013,28 +7013,13 @@ nsRuleNode::ComputePaddingData(void* aStartStruct, { COMPUTE_START_RESET(Padding, (), padding, parentPadding) - // padding: length, percent, inherit - nsStyleCoord coord; - nsCSSRect ourPadding; - ourPadding.mTop = *aRuleData->ValueForPaddingTop(); - ourPadding.mRight = *aRuleData->ValueForPaddingRightValue(); - ourPadding.mBottom = *aRuleData->ValueForPaddingBottom(); - ourPadding.mLeft = *aRuleData->ValueForPaddingLeftValue(); - AdjustLogicalBoxProp(aContext, - *aRuleData->ValueForPaddingLeftLTRSource(), - *aRuleData->ValueForPaddingLeftRTLSource(), - *aRuleData->ValueForPaddingStartValue(), - *aRuleData->ValueForPaddingEndValue(), - NS_SIDE_LEFT, ourPadding, canStoreInRuleTree); - AdjustLogicalBoxProp(aContext, - *aRuleData->ValueForPaddingRightLTRSource(), - *aRuleData->ValueForPaddingRightRTLSource(), - *aRuleData->ValueForPaddingEndValue(), - *aRuleData->ValueForPaddingStartValue(), - NS_SIDE_RIGHT, ourPadding, canStoreInRuleTree); + // padding: length, percent, calc, inherit + const nsCSSProperty* subprops = + nsCSSProps::SubpropertyEntryFor(eCSSProperty_padding); + nsStyleCoord coord; NS_FOR_CSS_SIDES(side) { nsStyleCoord parentCoord = parentPadding->mPadding.Get(side); - if (SetCoord(ourPadding.*(nsCSSRect::sides[side]), + if (SetCoord(*aRuleData->ValueFor(subprops[side]), coord, parentCoord, SETCOORD_LPH | SETCOORD_INITIAL_ZERO | SETCOORD_STORE_CALC | SETCOORD_UNSET_INITIAL, @@ -9512,11 +9497,9 @@ nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext, static const nsCSSProperty paddingValues[] = { eCSSProperty_padding_top, - eCSSProperty_padding_right_value, + eCSSProperty_padding_right, eCSSProperty_padding_bottom, - eCSSProperty_padding_left_value, - eCSSProperty_padding_start_value, - eCSSProperty_padding_end_value, + eCSSProperty_padding_left, }; static const nsCSSProperty textShadowValues[] = { diff --git a/layout/style/test/ListCSSProperties.cpp b/layout/style/test/ListCSSProperties.cpp index 9f93b8505a7..f8a7c6b6302 100644 --- a/layout/style/test/ListCSSProperties.cpp +++ b/layout/style/test/ListCSSProperties.cpp @@ -140,14 +140,6 @@ const char *gInaccessibleProperties[] = { "margin-left-rtl-source", "margin-right-ltr-source", "margin-right-rtl-source", - "padding-end-value", - "padding-left-value", - "padding-right-value", - "padding-start-value", - "padding-left-ltr-source", - "padding-left-rtl-source", - "padding-right-ltr-source", - "padding-right-rtl-source", "-moz-control-character-visibility", "-moz-script-level", // parsed by UA sheets only "-moz-script-size-multiplier", diff --git a/layout/style/test/css_properties_like_longhand.js b/layout/style/test/css_properties_like_longhand.js index 1a6ee0e6a3d..55e9082db79 100644 --- a/layout/style/test/css_properties_like_longhand.js +++ b/layout/style/test/css_properties_like_longhand.js @@ -4,8 +4,4 @@ var gShorthandPropertiesLikeLonghand = [ { name: "margin-right", prop: "marginRight"}, { name: "-moz-margin-start", prop: "MozMarginStart"}, { name: "overflow", prop: "overflow"}, - { name: "-moz-padding-end", prop: "MozPaddingEnd"}, - { name: "padding-left", prop: "paddingLeft"}, - { name: "padding-right", prop: "paddingRight"}, - { name: "-moz-padding-start", prop: "MozPaddingStart"}, ]; diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index 36909d205c8..fd3b5f0d2d6 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -1566,7 +1566,8 @@ var gCSSProperties = { "-moz-padding-end": { domProp: "MozPaddingEnd", inherited: false, - type: CSS_TYPE_SHORTHAND_AND_LONGHAND, + type: CSS_TYPE_LONGHAND, + logical: true, get_computed: logical_box_prop_get_computed, /* no subproperties */ initial_values: [ "0", "0px", "0%", "0em", "0ex", "calc(0pt)", "calc(0% + 0px)", "calc(-3px)", "calc(-1%)" ], @@ -1582,7 +1583,8 @@ var gCSSProperties = { "-moz-padding-start": { domProp: "MozPaddingStart", inherited: false, - type: CSS_TYPE_SHORTHAND_AND_LONGHAND, + type: CSS_TYPE_LONGHAND, + logical: true, get_computed: logical_box_prop_get_computed, /* no subproperties */ initial_values: [ "0", "0px", "0%", "0em", "0ex", "calc(0pt)", "calc(0% + 0px)", "calc(-3px)", "calc(-1%)" ], @@ -3122,8 +3124,7 @@ var gCSSProperties = { "padding-left": { domProp: "paddingLeft", inherited: false, - type: CSS_TYPE_SHORTHAND_AND_LONGHAND, - /* no subproperties */ + type: CSS_TYPE_LONGHAND, initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)", "calc(-3px)", "calc(-1%)" ], other_values: [ "1px", "2em", "5%", "calc(2px)", @@ -3138,8 +3139,7 @@ var gCSSProperties = { "padding-right": { domProp: "paddingRight", inherited: false, - type: CSS_TYPE_SHORTHAND_AND_LONGHAND, - /* no subproperties */ + type: CSS_TYPE_LONGHAND, initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)", "calc(-3px)", "calc(-1%)" ], other_values: [ "1px", "2em", "5%", "calc(2px)", @@ -4520,13 +4520,27 @@ var gCSSProperties = { function logical_box_prop_get_computed(cs, property) { - if (! /^-moz-/.test(property)) + var ltr = cs.getPropertyValue("direction") == "ltr"; + if (/^-moz-/.test(property)) { + property = property.substring(5); + if (ltr) { + property = property.replace("-start", "-left") + .replace("-end", "-right"); + } else { + property = property.replace("-start", "-right") + .replace("-end", "-left"); + } + } else if (/-inline-(start|end)/.test(property)) { + if (ltr) { + property = property.replace("-inline-start", "-left") + .replace("-inline-end", "-right"); + } else { + property = property.replace("-inline-start", "-right") + .replace("-inline-end", "-left"); + } + } else { throw "Unexpected property"; - property = property.substring(5); - if (cs.getPropertyValue("direction") == "ltr") - property = property.replace("-start", "-left").replace("-end", "-right"); - else - property = property.replace("-start", "-right").replace("-end", "-left"); + } return cs.getPropertyValue(property); } @@ -4597,7 +4611,39 @@ if (SpecialPowers.getBoolPref("layout.css.vertical-text.enabled")) { invalid_values: [ "auto", "all 2", "none all", "digits -3", "digits 0", "digits 12", "none 3", "digits 3.1415", "digits3", "digits 1", "digits 3 all", "digits foo", "digits all", "digits 3.0" ] - } + }, + "padding-inline-end": { + domProp: "paddingInlineEnd", + inherited: false, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, + alias_for: "-moz-padding-end", + get_computed: logical_box_prop_get_computed, + initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)", "calc(-3px)", "calc(-1%)" ], + other_values: [ "1px", "2em", "5%", + "calc(2px)", + "calc(50%)", + "calc(3*25px)", + "calc(25px*3)", + "calc(3*25px + 50%)", + ], + invalid_values: [ ], + }, + "padding-inline-start": { + domProp: "paddingInlineStart", + inherited: false, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, + alias_for: "-moz-padding-start", + get_computed: logical_box_prop_get_computed, + initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)", "calc(-3px)", "calc(-1%)" ], + other_values: [ "1px", "2em", "5%", + "calc(2px)", + "calc(50%)", + "calc(3*25px)", + "calc(25px*3)", + "calc(3*25px + 50%)", + ], + invalid_values: [ ], + }, }; for (var prop in verticalTextProperties) { gCSSProperties[prop] = verticalTextProperties[prop]; diff --git a/layout/style/test/test_value_computation.html b/layout/style/test/test_value_computation.html index c0240e53f22..a9214c98b89 100644 --- a/layout/style/test/test_value_computation.html +++ b/layout/style/test/test_value_computation.html @@ -75,6 +75,8 @@ var gBadComputedNoFrame = { "min-width": [ "calc(-1%)" ], "padding": [ "0% 0px 0em 0pt", "calc(0px) calc(0em) calc(-2px) calc(-1%)" ], "padding-bottom": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], + "padding-inline-end": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], + "padding-inline-start": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], "padding-left": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], "padding-right": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], "padding-top": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], From 6399b44e53ddf8fdd9c75229b0ae7f46b383f2e1 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Wed, 31 Dec 2014 12:18:14 +1100 Subject: [PATCH 13/41] Bug 649142 - Part 4: Convert logical margin properties. r=dbaron --- browser/devtools/layoutview/view.js | 12 +- dom/html/HTMLBodyElement.cpp | 12 +- dom/html/HTMLHRElement.cpp | 4 +- dom/html/HTMLTableElement.cpp | 8 +- dom/html/nsGenericHTMLElement.cpp | 4 +- layout/style/Declaration.cpp | 4 - layout/style/nsCSSDataBlock.cpp | 6 + layout/style/nsCSSParser.cpp | 25 +-- layout/style/nsCSSPropAliasList.h | 8 + layout/style/nsCSSPropList.h | 146 ++++-------------- layout/style/nsCSSProps.cpp | 45 +----- layout/style/nsRuleNode.cpp | 25 +-- layout/style/test/ListCSSProperties.cpp | 8 - .../test/css_properties_like_longhand.js | 4 - layout/style/test/property_database.js | 48 +++++- layout/style/test/test_page_parser.html | 30 +--- layout/style/test/test_value_computation.html | 13 +- 17 files changed, 127 insertions(+), 275 deletions(-) diff --git a/browser/devtools/layoutview/view.js b/browser/devtools/layoutview/view.js index cb0b365a3ce..36584e63e00 100644 --- a/browser/devtools/layoutview/view.js +++ b/browser/devtools/layoutview/view.js @@ -174,17 +174,11 @@ LayoutView.prototype = { marginBottom: {selector: ".margin.bottom > span", property: "margin-bottom", value: undefined}, - // margin-left is a shorthand for some internal properties, - // margin-left-ltr-source and margin-left-rtl-source for example. The - // real margin value we want is in margin-left-value marginLeft: {selector: ".margin.left > span", property: "margin-left", - realProperty: "margin-left-value", value: undefined}, - // margin-right behaves the same as margin-left marginRight: {selector: ".margin.right > span", property: "margin-right", - realProperty: "margin-right-value", value: undefined}, paddingTop: {selector: ".padding.top > span", property: "padding-top", @@ -261,11 +255,9 @@ LayoutView.prototype = { * Called when the user clicks on one of the editable values in the layoutview */ initEditor: function(element, event, dimension) { - let { property, realProperty } = dimension; - if (!realProperty) - realProperty = property; + let { property } = dimension; let session = new EditingSession(document, this.elementRules); - let initialValue = session.getProperty(realProperty); + let initialValue = session.getProperty(property); let editor = new InplaceEditor({ element: element, diff --git a/dom/html/HTMLBodyElement.cpp b/dom/html/HTMLBodyElement.cpp index 191db08d75f..f62217beb98 100644 --- a/dom/html/HTMLBodyElement.cpp +++ b/dom/html/HTMLBodyElement.cpp @@ -62,10 +62,10 @@ BodyRule::MapRuleInfoInto(nsRuleData* aData) if (value && value->Type() == nsAttrValue::eInteger) { bodyMarginWidth = value->GetIntegerValue(); if (bodyMarginWidth < 0) bodyMarginWidth = 0; - nsCSSValue* marginLeft = aData->ValueForMarginLeftValue(); + nsCSSValue* marginLeft = aData->ValueForMarginLeft(); if (marginLeft->GetUnit() == eCSSUnit_Null) marginLeft->SetFloatValue((float)bodyMarginWidth, eCSSUnit_Pixel); - nsCSSValue* marginRight = aData->ValueForMarginRightValue(); + nsCSSValue* marginRight = aData->ValueForMarginRight(); if (marginRight->GetUnit() == eCSSUnit_Null) marginRight->SetFloatValue((float)bodyMarginWidth, eCSSUnit_Pixel); } @@ -107,7 +107,7 @@ BodyRule::MapRuleInfoInto(nsRuleData* aData) if (value && value->Type() == nsAttrValue::eInteger) { bodyLeftMargin = value->GetIntegerValue(); if (bodyLeftMargin < 0) bodyLeftMargin = 0; - nsCSSValue* marginLeft = aData->ValueForMarginLeftValue(); + nsCSSValue* marginLeft = aData->ValueForMarginLeft(); if (marginLeft->GetUnit() == eCSSUnit_Null) marginLeft->SetFloatValue((float)bodyLeftMargin, eCSSUnit_Pixel); } @@ -117,7 +117,7 @@ BodyRule::MapRuleInfoInto(nsRuleData* aData) if (value && value->Type() == nsAttrValue::eInteger) { bodyRightMargin = value->GetIntegerValue(); if (bodyRightMargin < 0) bodyRightMargin = 0; - nsCSSValue* marginRight = aData->ValueForMarginRightValue(); + nsCSSValue* marginRight = aData->ValueForMarginRight(); if (marginRight->GetUnit() == eCSSUnit_Null) marginRight->SetFloatValue((float)bodyRightMargin, eCSSUnit_Pixel); } @@ -147,10 +147,10 @@ BodyRule::MapRuleInfoInto(nsRuleData* aData) } if ((bodyMarginWidth == -1) && (frameMarginWidth >= 0)) { - nsCSSValue* marginLeft = aData->ValueForMarginLeftValue(); + nsCSSValue* marginLeft = aData->ValueForMarginLeft(); if (marginLeft->GetUnit() == eCSSUnit_Null) marginLeft->SetFloatValue((float)frameMarginWidth, eCSSUnit_Pixel); - nsCSSValue* marginRight = aData->ValueForMarginRightValue(); + nsCSSValue* marginRight = aData->ValueForMarginRight(); if (marginRight->GetUnit() == eCSSUnit_Null) marginRight->SetFloatValue((float)frameMarginWidth, eCSSUnit_Pixel); } diff --git a/dom/html/HTMLHRElement.cpp b/dom/html/HTMLHRElement.cpp index 42670386940..552917750c6 100644 --- a/dom/html/HTMLHRElement.cpp +++ b/dom/html/HTMLHRElement.cpp @@ -88,8 +88,8 @@ HTMLHRElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes, const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align); if (value && value->Type() == nsAttrValue::eEnum) { // Map align attribute into auto side margins - nsCSSValue* marginLeft = aData->ValueForMarginLeftValue(); - nsCSSValue* marginRight = aData->ValueForMarginRightValue(); + nsCSSValue* marginLeft = aData->ValueForMarginLeft(); + nsCSSValue* marginRight = aData->ValueForMarginRight(); switch (value->GetEnumValue()) { case NS_STYLE_TEXT_ALIGN_LEFT: if (marginLeft->GetUnit() == eCSSUnit_Null) diff --git a/dom/html/HTMLTableElement.cpp b/dom/html/HTMLTableElement.cpp index 493d02421cb..14dbff0eb0d 100644 --- a/dom/html/HTMLTableElement.cpp +++ b/dom/html/HTMLTableElement.cpp @@ -705,10 +705,10 @@ HTMLTableElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes, if (value && value->Type() == nsAttrValue::eEnum) { if (value->GetEnumValue() == NS_STYLE_TEXT_ALIGN_CENTER || value->GetEnumValue() == NS_STYLE_TEXT_ALIGN_MOZ_CENTER) { - nsCSSValue* marginLeft = aData->ValueForMarginLeftValue(); + nsCSSValue* marginLeft = aData->ValueForMarginLeft(); if (marginLeft->GetUnit() == eCSSUnit_Null) marginLeft->SetAutoValue(); - nsCSSValue* marginRight = aData->ValueForMarginRightValue(); + nsCSSValue* marginRight = aData->ValueForMarginRight(); if (marginRight->GetUnit() == eCSSUnit_Null) marginRight->SetAutoValue(); } @@ -721,10 +721,10 @@ HTMLTableElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes, value = aAttributes->GetAttr(nsGkAtoms::hspace); if (value && value->Type() == nsAttrValue::eInteger) { - nsCSSValue* marginLeft = aData->ValueForMarginLeftValue(); + nsCSSValue* marginLeft = aData->ValueForMarginLeft(); if (marginLeft->GetUnit() == eCSSUnit_Null) marginLeft->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel); - nsCSSValue* marginRight = aData->ValueForMarginRightValue(); + nsCSSValue* marginRight = aData->ValueForMarginRight(); if (marginRight->GetUnit() == eCSSUnit_Null) marginRight->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel); } diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp index 0d5cf78873d..19ee7a5012b 100644 --- a/dom/html/nsGenericHTMLElement.cpp +++ b/dom/html/nsGenericHTMLElement.cpp @@ -1444,10 +1444,10 @@ nsGenericHTMLElement::MapImageMarginAttributeInto(const nsMappedAttributes* aAtt hval.SetPercentValue(value->GetPercentValue()); if (hval.GetUnit() != eCSSUnit_Null) { - nsCSSValue* left = aData->ValueForMarginLeftValue(); + nsCSSValue* left = aData->ValueForMarginLeft(); if (left->GetUnit() == eCSSUnit_Null) *left = hval; - nsCSSValue* right = aData->ValueForMarginRightValue(); + nsCSSValue* right = aData->ValueForMarginRight(); if (right->GetUnit() == eCSSUnit_Null) *right = hval; } diff --git a/layout/style/Declaration.cpp b/layout/style/Declaration.cpp index 883d51b6557..c957ec6c905 100644 --- a/layout/style/Declaration.cpp +++ b/layout/style/Declaration.cpp @@ -396,10 +396,6 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue, } break; } - case eCSSProperty_margin_left: - case eCSSProperty_margin_right: - case eCSSProperty_margin_start: - case eCSSProperty_margin_end: case eCSSProperty_border_left_color: case eCSSProperty_border_left_style: case eCSSProperty_border_left_width: diff --git a/layout/style/nsCSSDataBlock.cpp b/layout/style/nsCSSDataBlock.cpp index 638eb283435..02c53028e7f 100644 --- a/layout/style/nsCSSDataBlock.cpp +++ b/layout/style/nsCSSDataBlock.cpp @@ -175,6 +175,12 @@ EnsurePhysicalProperty(nsCSSProperty& aProperty, nsRuleData* aRuleData) bool ltr = direction == NS_STYLE_DIRECTION_LTR; switch (aProperty) { + case eCSSProperty_margin_end: + aProperty = ltr ? eCSSProperty_margin_right : eCSSProperty_margin_left; + break; + case eCSSProperty_margin_start: + aProperty = ltr ? eCSSProperty_margin_left : eCSSProperty_margin_right; + break; case eCSSProperty_padding_end: aProperty = ltr ? eCSSProperty_padding_right : eCSSProperty_padding_left; break; diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 653ee864ae1..93ad260dded 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -9887,18 +9887,6 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSProperty aPropID) return ParseListStyle(); case eCSSProperty_margin: return ParseMargin(); - case eCSSProperty_margin_end: - return ParseDirectionalBoxProperty(eCSSProperty_margin_end, - NS_BOXPROP_SOURCE_LOGICAL); - case eCSSProperty_margin_left: - return ParseDirectionalBoxProperty(eCSSProperty_margin_left, - NS_BOXPROP_SOURCE_PHYSICAL); - case eCSSProperty_margin_right: - return ParseDirectionalBoxProperty(eCSSProperty_margin_right, - NS_BOXPROP_SOURCE_PHYSICAL); - case eCSSProperty_margin_start: - return ParseDirectionalBoxProperty(eCSSProperty_margin_start, - NS_BOXPROP_SOURCE_LOGICAL); case eCSSProperty_object_position: return ParseObjectPosition(); case eCSSProperty_outline: @@ -12955,20 +12943,11 @@ CSSParserImpl::ParseMargin() { static const nsCSSProperty kMarginSideIDs[] = { eCSSProperty_margin_top, - eCSSProperty_margin_right_value, + eCSSProperty_margin_right, eCSSProperty_margin_bottom, - eCSSProperty_margin_left_value - }; - static const nsCSSProperty kMarginSources[] = { - eCSSProperty_margin_left_ltr_source, - eCSSProperty_margin_left_rtl_source, - eCSSProperty_margin_right_ltr_source, - eCSSProperty_margin_right_rtl_source, - eCSSProperty_UNKNOWN + eCSSProperty_margin_left }; - // do this now, in case 4 values weren't specified - InitBoxPropsAsPhysical(kMarginSources); return ParseBoxProperties(kMarginSideIDs); } diff --git a/layout/style/nsCSSPropAliasList.h b/layout/style/nsCSSPropAliasList.h index d2ba9544049..ffde58e2369 100644 --- a/layout/style/nsCSSPropAliasList.h +++ b/layout/style/nsCSSPropAliasList.h @@ -147,3 +147,11 @@ CSS_PROP_ALIAS(padding-inline-start, padding_start, PaddingInlineStart, "layout.css.vertical-text.enabled") +CSS_PROP_ALIAS(margin-inline-end, + margin_end, + MarginInlineEnd, + "layout.css.vertical-text.enabled") +CSS_PROP_ALIAS(margin-inline-start, + margin_start, + MarginInlineStart, + "layout.css.vertical-text.enabled") diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index b6df55fed93..5a19128bf89 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -2331,152 +2331,66 @@ CSS_PROP_MARGIN( nullptr, offsetof(nsStyleMargin, mMargin), eStyleAnimType_Sides_Bottom) -CSS_PROP_SHORTHAND( +CSS_PROP_LOGICAL( -moz-margin-end, margin_end, CSS_PROP_DOMPROP_PREFIXED(MarginEnd), - CSS_PROPERTY_PARSE_FUNCTION | - CSS_PROPERTY_APPLIES_TO_PAGE_RULE, - "") -#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL -CSS_PROP_MARGIN( - margin-end-value, - margin_end_value, - MarginEndValue, - CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | CSS_PROPERTY_STORES_CALC | - CSS_PROPERTY_APPLIES_TO_PAGE_RULE, + CSS_PROPERTY_APPLIES_TO_PAGE_RULE | + CSS_PROPERTY_LOGICAL, "", - VARIANT_AHLP | VARIANT_CALC, // for internal use + VARIANT_AHLP | VARIANT_CALC, nullptr, + Margin, CSS_PROP_NO_OFFSET, eStyleAnimType_None) -#endif -CSS_PROP_SHORTHAND( +CSS_PROP_LOGICAL( + -moz-margin-start, + margin_start, + CSS_PROP_DOMPROP_PREFIXED(MarginStart), + CSS_PROPERTY_PARSE_VALUE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_STORES_CALC | + CSS_PROPERTY_APPLIES_TO_PAGE_RULE | + CSS_PROPERTY_LOGICAL, + "", + VARIANT_AHLP | VARIANT_CALC, + nullptr, + Margin, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +CSS_PROP_MARGIN( margin-left, margin_left, MarginLeft, - CSS_PROPERTY_PARSE_FUNCTION | + CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_UNITLESS_LENGTH_QUIRK | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_STORES_CALC | CSS_PROPERTY_APPLIES_TO_PAGE_RULE | CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, - "") -#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL -CSS_PROP_MARGIN( - margin-left-value, - margin_left_value, - MarginLeftValue, - CSS_PROPERTY_PARSE_INACCESSIBLE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - CSS_PROPERTY_REPORT_OTHER_NAME | - CSS_PROPERTY_STORES_CALC | - CSS_PROPERTY_APPLIES_TO_PAGE_RULE, "", - VARIANT_AHLP | VARIANT_CALC, // for internal use + VARIANT_AHLP | VARIANT_CALC, nullptr, offsetof(nsStyleMargin, mMargin), eStyleAnimType_Sides_Left) CSS_PROP_MARGIN( - margin-left-ltr-source, - margin_left_ltr_source, - MarginLeftLTRSource, - CSS_PROPERTY_PARSE_INACCESSIBLE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - CSS_PROPERTY_DIRECTIONAL_SOURCE | - CSS_PROPERTY_APPLIES_TO_PAGE_RULE, - "", - 0, - kBoxPropSourceKTable, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) -CSS_PROP_MARGIN( - margin-left-rtl-source, - margin_left_rtl_source, - MarginLeftRTLSource, - CSS_PROPERTY_PARSE_INACCESSIBLE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - CSS_PROPERTY_DIRECTIONAL_SOURCE | - CSS_PROPERTY_APPLIES_TO_PAGE_RULE, - "", - 0, - kBoxPropSourceKTable, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) -#endif -CSS_PROP_SHORTHAND( margin-right, margin_right, MarginRight, - CSS_PROPERTY_PARSE_FUNCTION | + CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_UNITLESS_LENGTH_QUIRK | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_STORES_CALC | CSS_PROPERTY_APPLIES_TO_PAGE_RULE | CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, - "") -#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL -CSS_PROP_MARGIN( - margin-right-value, - margin_right_value, - MarginRightValue, - CSS_PROPERTY_PARSE_INACCESSIBLE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - CSS_PROPERTY_REPORT_OTHER_NAME | - CSS_PROPERTY_STORES_CALC | - CSS_PROPERTY_APPLIES_TO_PAGE_RULE, "", - VARIANT_AHLP | VARIANT_CALC, // for internal use + VARIANT_AHLP | VARIANT_CALC, nullptr, offsetof(nsStyleMargin, mMargin), eStyleAnimType_Sides_Right) -CSS_PROP_MARGIN( - margin-right-ltr-source, - margin_right_ltr_source, - MarginRightLTRSource, - CSS_PROPERTY_PARSE_INACCESSIBLE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - CSS_PROPERTY_DIRECTIONAL_SOURCE | - CSS_PROPERTY_APPLIES_TO_PAGE_RULE, - "", - 0, - kBoxPropSourceKTable, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) -CSS_PROP_MARGIN( - margin-right-rtl-source, - margin_right_rtl_source, - MarginRightRTLSource, - CSS_PROPERTY_PARSE_INACCESSIBLE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - CSS_PROPERTY_DIRECTIONAL_SOURCE | - CSS_PROPERTY_APPLIES_TO_PAGE_RULE, - "", - 0, - kBoxPropSourceKTable, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) -#endif -CSS_PROP_SHORTHAND( - -moz-margin-start, - margin_start, - CSS_PROP_DOMPROP_PREFIXED(MarginStart), - CSS_PROPERTY_PARSE_FUNCTION | - CSS_PROPERTY_APPLIES_TO_PAGE_RULE, - "") -#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL -CSS_PROP_MARGIN( - margin-start-value, - margin_start_value, - MarginStartValue, - CSS_PROPERTY_PARSE_INACCESSIBLE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - CSS_PROPERTY_STORES_CALC | - CSS_PROPERTY_APPLIES_TO_PAGE_RULE, - "", - VARIANT_AHLP | VARIANT_CALC, // for internal use - nullptr, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) -#endif CSS_PROP_MARGIN( margin-top, margin_top, diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp index fa15b40858c..2d3937ae151 100644 --- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -574,10 +574,6 @@ nsCSSProps::OtherNameFor(nsCSSProperty aProperty) return eCSSProperty_border_right_style; case eCSSProperty_border_right_width_value: return eCSSProperty_border_right_width; - case eCSSProperty_margin_left_value: - return eCSSProperty_margin_left; - case eCSSProperty_margin_right_value: - return eCSSProperty_margin_right; default: NS_ABORT_IF_FALSE(false, "bad caller"); } @@ -2573,46 +2569,9 @@ static const nsCSSProperty gListStyleSubpropTable[] = { static const nsCSSProperty gMarginSubpropTable[] = { // Code relies on these being in top-right-bottom-left order. eCSSProperty_margin_top, - eCSSProperty_margin_right_value, + eCSSProperty_margin_right, eCSSProperty_margin_bottom, - eCSSProperty_margin_left_value, - // extras: - eCSSProperty_margin_left_ltr_source, - eCSSProperty_margin_left_rtl_source, - eCSSProperty_margin_right_ltr_source, - eCSSProperty_margin_right_rtl_source, - eCSSProperty_UNKNOWN -}; - -static const nsCSSProperty gMarginLeftSubpropTable[] = { - // nsCSSParser::ParseDirectionalBoxProperty depends on this order - eCSSProperty_margin_left_value, - eCSSProperty_margin_left_ltr_source, - eCSSProperty_margin_left_rtl_source, - eCSSProperty_UNKNOWN -}; - -static const nsCSSProperty gMarginRightSubpropTable[] = { - // nsCSSParser::ParseDirectionalBoxProperty depends on this order - eCSSProperty_margin_right_value, - eCSSProperty_margin_right_ltr_source, - eCSSProperty_margin_right_rtl_source, - eCSSProperty_UNKNOWN -}; - -static const nsCSSProperty gMarginStartSubpropTable[] = { - // nsCSSParser::ParseDirectionalBoxProperty depends on this order - eCSSProperty_margin_start_value, - eCSSProperty_margin_left_ltr_source, - eCSSProperty_margin_right_rtl_source, - eCSSProperty_UNKNOWN -}; - -static const nsCSSProperty gMarginEndSubpropTable[] = { - // nsCSSParser::ParseDirectionalBoxProperty depends on this order - eCSSProperty_margin_end_value, - eCSSProperty_margin_right_ltr_source, - eCSSProperty_margin_left_rtl_source, + eCSSProperty_margin_left, eCSSProperty_UNKNOWN }; diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 23bab2542a3..cad21c6d952 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -6502,28 +6502,13 @@ nsRuleNode::ComputeMarginData(void* aStartStruct, { COMPUTE_START_RESET(Margin, (), margin, parentMargin) - // margin: length, percent, auto, inherit - nsStyleCoord coord; - nsCSSRect ourMargin; - ourMargin.mTop = *aRuleData->ValueForMarginTop(); - ourMargin.mRight = *aRuleData->ValueForMarginRightValue(); - ourMargin.mBottom = *aRuleData->ValueForMarginBottom(); - ourMargin.mLeft = *aRuleData->ValueForMarginLeftValue(); - AdjustLogicalBoxProp(aContext, - *aRuleData->ValueForMarginLeftLTRSource(), - *aRuleData->ValueForMarginLeftRTLSource(), - *aRuleData->ValueForMarginStartValue(), - *aRuleData->ValueForMarginEndValue(), - NS_SIDE_LEFT, ourMargin, canStoreInRuleTree); - AdjustLogicalBoxProp(aContext, - *aRuleData->ValueForMarginRightLTRSource(), - *aRuleData->ValueForMarginRightRTLSource(), - *aRuleData->ValueForMarginEndValue(), - *aRuleData->ValueForMarginStartValue(), - NS_SIDE_RIGHT, ourMargin, canStoreInRuleTree); + // margin: length, percent, calc, inherit + const nsCSSProperty* subprops = + nsCSSProps::SubpropertyEntryFor(eCSSProperty_margin); + nsStyleCoord coord; NS_FOR_CSS_SIDES(side) { nsStyleCoord parentCoord = parentMargin->mMargin.Get(side); - if (SetCoord(ourMargin.*(nsCSSRect::sides[side]), + if (SetCoord(*aRuleData->ValueFor(subprops[side]), coord, parentCoord, SETCOORD_LPAH | SETCOORD_INITIAL_ZERO | SETCOORD_STORE_CALC | SETCOORD_UNSET_INITIAL, diff --git a/layout/style/test/ListCSSProperties.cpp b/layout/style/test/ListCSSProperties.cpp index f8a7c6b6302..007e82b2933 100644 --- a/layout/style/test/ListCSSProperties.cpp +++ b/layout/style/test/ListCSSProperties.cpp @@ -132,14 +132,6 @@ const char *gInaccessibleProperties[] = { "border-start-color-value", "border-start-style-value", "border-start-width-value", - "margin-end-value", - "margin-left-value", - "margin-right-value", - "margin-start-value", - "margin-left-ltr-source", - "margin-left-rtl-source", - "margin-right-ltr-source", - "margin-right-rtl-source", "-moz-control-character-visibility", "-moz-script-level", // parsed by UA sheets only "-moz-script-size-multiplier", diff --git a/layout/style/test/css_properties_like_longhand.js b/layout/style/test/css_properties_like_longhand.js index 55e9082db79..60b8fd5832c 100644 --- a/layout/style/test/css_properties_like_longhand.js +++ b/layout/style/test/css_properties_like_longhand.js @@ -1,7 +1,3 @@ var gShorthandPropertiesLikeLonghand = [ - { name: "-moz-margin-end", prop: "MozMarginEnd"}, - { name: "margin-left", prop: "marginLeft"}, - { name: "margin-right", prop: "marginRight"}, - { name: "-moz-margin-start", prop: "MozMarginStart"}, { name: "overflow", prop: "overflow"}, ]; diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index fd3b5f0d2d6..e6332e58aed 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -1432,7 +1432,8 @@ var gCSSProperties = { "-moz-margin-end": { domProp: "MozMarginEnd", inherited: false, - type: CSS_TYPE_SHORTHAND_AND_LONGHAND, + type: CSS_TYPE_LONGHAND, + logical: true, get_computed: logical_box_prop_get_computed, /* no subproperties */ /* auto may or may not be initial */ @@ -1450,7 +1451,8 @@ var gCSSProperties = { "-moz-margin-start": { domProp: "MozMarginStart", inherited: false, - type: CSS_TYPE_SHORTHAND_AND_LONGHAND, + type: CSS_TYPE_LONGHAND, + logical: true, get_computed: logical_box_prop_get_computed, /* no subproperties */ /* auto may or may not be initial */ @@ -2851,8 +2853,7 @@ var gCSSProperties = { "margin-left": { domProp: "marginLeft", inherited: false, - type: CSS_TYPE_SHORTHAND_AND_LONGHAND, - /* no subproperties */ + type: CSS_TYPE_LONGHAND, /* XXX testing auto has prerequisites */ initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)" ], other_values: [ "1px", "2em", "5%", ".5px", "+32px", "+.789px", "-.328px", "+0.56px", "-0.974px", "237px", "-289px", "-056px", "1987.45px", "-84.32px", @@ -2869,8 +2870,7 @@ var gCSSProperties = { "margin-right": { domProp: "marginRight", inherited: false, - type: CSS_TYPE_SHORTHAND_AND_LONGHAND, - /* no subproperties */ + type: CSS_TYPE_LONGHAND, /* XXX testing auto has prerequisites */ initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)" ], other_values: [ "1px", "2em", "5%", @@ -4612,6 +4612,42 @@ if (SpecialPowers.getBoolPref("layout.css.vertical-text.enabled")) { "digits 12", "none 3", "digits 3.1415", "digits3", "digits 1", "digits 3 all", "digits foo", "digits all", "digits 3.0" ] }, + "margin-inline-end": { + domProp: "marginInlineEnd", + inherited: false, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, + alias_for: "-moz-margin-end", + get_computed: logical_box_prop_get_computed, + /* XXX testing auto has prerequisites */ + initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)" ], + other_values: [ "1px", "2em", "5%", + "calc(2px)", + "calc(-2px)", + "calc(50%)", + "calc(3*25px)", + "calc(25px*3)", + "calc(3*25px + 50%)", + ], + invalid_values: [ "..25px", ".+5px", ".px", "-.px", "++5px", "-+4px", "+-3px", "--7px", "+-.6px", "-+.5px", "++.7px", "--.4px" ], + }, + "margin-inline-start": { + domProp: "marginInlineStart", + inherited: false, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, + alias_for: "-moz-margin-start", + get_computed: logical_box_prop_get_computed, + /* XXX testing auto has prerequisites */ + initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)" ], + other_values: [ "1px", "2em", "5%", + "calc(2px)", + "calc(-2px)", + "calc(50%)", + "calc(3*25px)", + "calc(25px*3)", + "calc(3*25px + 50%)", + ], + invalid_values: [ "..25px", ".+5px", ".px", "-.px", "++5px", "-+4px", "+-3px", "--7px", "+-.6px", "-+.5px", "++.7px", "--.4px" ], + }, "padding-inline-end": { domProp: "paddingInlineEnd", inherited: false, diff --git a/layout/style/test/test_page_parser.html b/layout/style/test/test_page_parser.html index d887cc090c0..8c94be0bf17 100644 --- a/layout/style/test/test_page_parser.html +++ b/layout/style/test/test_page_parser.html @@ -26,13 +26,9 @@ // Check good properties with invalid units. { rule: _("margin: 2in; margin: 2vw;"), expected: { "margin-top": "2in", - "margin-right-value": "2in", + "margin-right": "2in", "margin-bottom": "2in", - "margin-left-value": "2in", - "margin-left-ltr-source": "physical", - "margin-left-rtl-source": "physical", - "margin-right-ltr-source": "physical", - "margin-right-rtl-source": "physical" + "margin-left": "2in" }}, { rule: _("margin-top: 2in; margin-top: 2vw;"), expected: {"margin-top": "2in"}}, { rule: _("margin-top: 2in; margin-top: 2vh;"), expected: {"margin-top": "2in"}}, @@ -40,30 +36,16 @@ { rule: _("margin-top: 2in; margin-top: 2vmin;"), expected: {"margin-top": "2in"}}, // Check good properties. - // NOTE: The margin-*-value and margin-*-source properties are not really - // expected and will need to be removed once bug 241234 is addressed. { rule: _("margin: 2in;"), expected: { "margin-top": "2in", - "margin-right-value": "2in", + "margin-right": "2in", "margin-bottom": "2in", - "margin-left-value": "2in", - "margin-left-ltr-source": "physical", - "margin-left-rtl-source": "physical", - "margin-right-ltr-source": "physical", - "margin-right-rtl-source": "physical" + "margin-left": "2in" }}, { rule: _("margin-top: 2in;"), expected: {"margin-top": "2in"}}, - { rule: _("margin-left: 2in;"), expected: { - "margin-left-value": "2in", - "margin-left-ltr-source": "physical", - "margin-left-rtl-source": "physical", - }}, + { rule: _("margin-left: 2in;"), expected: {"margin-left": "2in"}}, { rule: _("margin-bottom: 2in;"), expected: {"margin-bottom": "2in"}}, - { rule: _("margin-right: 2in;"), expected: { - "margin-right-value": "2in", - "margin-right-ltr-source": "physical", - "margin-right-rtl-source": "physical", - }} + { rule: _("margin-right: 2in;"), expected: {"margin-right": "2in"}} ]; var display = document.getElementById("display"); diff --git a/layout/style/test/test_value_computation.html b/layout/style/test/test_value_computation.html index a9214c98b89..cd48dfe6bf8 100644 --- a/layout/style/test/test_value_computation.html +++ b/layout/style/test/test_value_computation.html @@ -13,7 +13,12 @@ + + +
+ + From 265386ac329933c6471cda922b5e8235c74c819c Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 30 Dec 2014 14:54:01 +1300 Subject: [PATCH 18/41] Bug 1109644. Part 1: Create SourceMediaStream::GetEndOfAppendedData to reliably track how much data has been appended to a SourceMediaStream's track. r=jesup --HG-- extra : rebase_source : 385ad9b704d35df7b70a75afe807e363e0929476 --- dom/media/MediaStreamGraph.cpp | 15 +++++++++++++++ dom/media/MediaStreamGraph.h | 15 ++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/dom/media/MediaStreamGraph.cpp b/dom/media/MediaStreamGraph.cpp index 2a18c14fb67..47ee1c0baf3 100644 --- a/dom/media/MediaStreamGraph.cpp +++ b/dom/media/MediaStreamGraph.cpp @@ -206,6 +206,7 @@ MediaStreamGraphImpl::ExtractPendingInput(SourceMediaStream* aStream, aStream, data->mID, int64_t(data->mStart), int64_t(segment->GetDuration()))); + data->mEndOfFlushedData += segment->GetDuration(); aStream->mBuffer.AddTrack(data->mID, data->mStart, segment); // The track has taken ownership of data->mData, so let's replace // data->mData with an empty clone. @@ -217,6 +218,7 @@ MediaStreamGraphImpl::ExtractPendingInput(SourceMediaStream* aStream, aStream, data->mID, int64_t(dest->GetDuration()), int64_t(dest->GetDuration() + data->mData->GetDuration()))); + data->mEndOfFlushedData += data->mData->GetDuration(); dest->AppendFrom(data->mData); } if (data->mCommands & SourceMediaStream::TRACK_END) { @@ -2279,6 +2281,7 @@ SourceMediaStream::AddTrackInternal(TrackID aID, TrackRate aRate, StreamTime aSt data->mID = aID; data->mInputRate = aRate; data->mStart = aStart; + data->mEndOfFlushedData = aStart; data->mCommands = TRACK_CREATE; data->mData = aSegment; data->mHaveEnough = false; @@ -2437,6 +2440,18 @@ SourceMediaStream::HaveEnoughBuffered(TrackID aID) return false; } +StreamTime +SourceMediaStream::GetEndOfAppendedData(TrackID aID) +{ + MutexAutoLock lock(mMutex); + TrackData *track = FindDataForTrack(aID); + if (track) { + return track->mEndOfFlushedData + track->mData->GetDuration(); + } + NS_ERROR("Track not found"); + return 0; +} + void SourceMediaStream::DispatchWhenNotEnoughBuffered(TrackID aID, nsIEventTarget* aSignalThread, nsIRunnable* aSignalRunnable) diff --git a/dom/media/MediaStreamGraph.h b/dom/media/MediaStreamGraph.h index 7ac84eb5487..e38e11379e3 100644 --- a/dom/media/MediaStreamGraph.h +++ b/dom/media/MediaStreamGraph.h @@ -750,6 +750,13 @@ public: * Returns false if there isn't enough data or if no such track exists. */ bool HaveEnoughBuffered(TrackID aID); + /** + * Get the stream time of the end of the data that has been appended so far. + * Can be called from any thread but won't be useful if it can race with + * an AppendToTrack call, so should probably just be called from the thread + * that also calls AppendToTrack. + */ + StreamTime GetEndOfAppendedData(TrackID aID); /** * Ensures that aSignalRunnable will be dispatched to aSignalThread * when we don't have enough buffered data in the track (which could be @@ -848,13 +855,15 @@ protected: int mResamplerChannelCount; #endif StreamTime mStart; - // Each time the track updates are flushed to the media graph thread, - // this is cleared. - uint32_t mCommands; + // End-time of data already flushed to the track (excluding mData) + StreamTime mEndOfFlushedData; // Each time the track updates are flushed to the media graph thread, // the segment buffer is emptied. nsAutoPtr mData; nsTArray mDispatchWhenNotEnough; + // Each time the track updates are flushed to the media graph thread, + // this is cleared. + uint32_t mCommands; bool mHaveEnough; }; From 88cf3c7e137e51043f629fa4d896a8dec1559510 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 30 Dec 2014 14:54:02 +1300 Subject: [PATCH 19/41] Bug 1109644. Part 2: Make MediaEngineWebRTCVideoSource use GetEndOfAppendedData instead of aLastEndTime. r=jesup --HG-- extra : rebase_source : a1b716900bba01b5af1057e03bdc6360e327174b --- dom/media/webrtc/MediaEngineWebRTCVideo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom/media/webrtc/MediaEngineWebRTCVideo.cpp b/dom/media/webrtc/MediaEngineWebRTCVideo.cpp index 14d9a95fb57..7558557e4f5 100644 --- a/dom/media/webrtc/MediaEngineWebRTCVideo.cpp +++ b/dom/media/webrtc/MediaEngineWebRTCVideo.cpp @@ -134,7 +134,7 @@ MediaEngineWebRTCVideoSource::NotifyPull(MediaStreamGraph* aGraph, // So mState could be kReleased here. We really don't care about the state, // though. - StreamTime delta = aDesiredTime - aLastEndTime; + StreamTime delta = aDesiredTime - aSource->GetEndOfAppendedData(aID); LOGFRAME(("NotifyPull, desired = %ld, delta = %ld %s", (int64_t) aDesiredTime, (int64_t) delta, mImage.get() ? "" : "")); From 720b09430e31dff6fd76279f940319ba5f6fb21c Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 30 Dec 2014 14:54:02 +1300 Subject: [PATCH 20/41] Bug 1109644. Part 3: Make MediaEngineDefaultVideoSource use GetEndOfAppendedData instead of aLastEndTime. r=jesup --HG-- extra : rebase_source : d2285dad46e5b089b49e5ddce12564d5518c45a3 --- dom/media/webrtc/MediaEngineDefault.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom/media/webrtc/MediaEngineDefault.cpp b/dom/media/webrtc/MediaEngineDefault.cpp index a7a8cfadb74..b0025a82ab8 100644 --- a/dom/media/webrtc/MediaEngineDefault.cpp +++ b/dom/media/webrtc/MediaEngineDefault.cpp @@ -256,7 +256,7 @@ MediaEngineDefaultVideoSource::NotifyPull(MediaStreamGraph* aGraph, // Note: we're not giving up mImage here nsRefPtr image = mImage; - StreamTime delta = aDesiredTime - aLastEndTime; + StreamTime delta = aDesiredTime - aSource->GetEndOfAppendedData(aID); if (delta > 0) { // nullptr images are allowed From b0225d40504b45440568490f32ff379ad8393926 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 30 Dec 2014 14:54:02 +1300 Subject: [PATCH 21/41] Bug 1109644. Part 4: Make MediaEngineGonkVideoSource use GetEndOfAppendedData instead of aLastEndTime. r=jesup --HG-- extra : rebase_source : 0899d9e42cd42b2ab4ef1d0d4cf600ccc7f49a3f --- dom/media/webrtc/MediaEngineGonkVideoSource.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom/media/webrtc/MediaEngineGonkVideoSource.cpp b/dom/media/webrtc/MediaEngineGonkVideoSource.cpp index 4dcc4a39ee5..be01b334396 100644 --- a/dom/media/webrtc/MediaEngineGonkVideoSource.cpp +++ b/dom/media/webrtc/MediaEngineGonkVideoSource.cpp @@ -82,7 +82,7 @@ MediaEngineGonkVideoSource::NotifyPull(MediaStreamGraph* aGraph, // Note: we're not giving up mImage here nsRefPtr image = mImage; - StreamTime delta = aDesiredTime - aLastEndTime; + StreamTime delta = aDesiredTime - aSource->GetEndOfAppendedData(aID); LOGFRAME(("NotifyPull, desired = %ld, delta = %ld %s", (int64_t) aDesiredTime, (int64_t) delta, image ? "" : "")); From a9f4b728622334a2b9803ec4cd766da4f446bfe7 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 30 Dec 2014 14:54:02 +1300 Subject: [PATCH 22/41] Bug 1109644. Part 5: Make MediaEngineTabVideoSource use GetEndOfAppendedData instead of aLastEndTime. r=jesup --HG-- extra : rebase_source : ee34171ed4297afa90fb14c7cf655a8d22a30dca --- dom/media/webrtc/MediaEngineTabVideoSource.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom/media/webrtc/MediaEngineTabVideoSource.cpp b/dom/media/webrtc/MediaEngineTabVideoSource.cpp index 0b0a44aaa11..2519a12fda7 100644 --- a/dom/media/webrtc/MediaEngineTabVideoSource.cpp +++ b/dom/media/webrtc/MediaEngineTabVideoSource.cpp @@ -200,7 +200,7 @@ MediaEngineTabVideoSource::NotifyPull(MediaStreamGraph*, // Note: we're not giving up mImage here nsRefPtr image = mImage; - StreamTime delta = aDesiredTime - aLastEndTime; + StreamTime delta = aDesiredTime - aSource->GetEndOfAppendedData(aID); if (delta > 0) { // nullptr images are allowed gfx::IntSize size = image ? image->GetSize() : IntSize(0, 0); From 11ba996bc661ec14acb0bcd244e56ce09617dd9f Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 30 Dec 2014 14:54:03 +1300 Subject: [PATCH 23/41] Bug 1109644. Part 6: Remove aLastEndTime parameter from NotifyPull. r=jesup --HG-- extra : rebase_source : 47c950d1b1d03a8de279f2ac361b8dcd4ab0f801 --- dom/media/MediaManager.h | 8 ++------ dom/media/webrtc/MediaEngine.h | 3 +-- dom/media/webrtc/MediaEngineDefault.cpp | 7 ++----- dom/media/webrtc/MediaEngineDefault.h | 6 ++---- dom/media/webrtc/MediaEngineGonkVideoSource.cpp | 3 +-- dom/media/webrtc/MediaEngineGonkVideoSource.h | 3 +-- dom/media/webrtc/MediaEngineTabVideoSource.cpp | 7 ++----- dom/media/webrtc/MediaEngineTabVideoSource.h | 2 +- dom/media/webrtc/MediaEngineWebRTC.h | 6 ++---- dom/media/webrtc/MediaEngineWebRTCAudio.cpp | 10 ++-------- dom/media/webrtc/MediaEngineWebRTCVideo.cpp | 7 ++----- 11 files changed, 18 insertions(+), 44 deletions(-) diff --git a/dom/media/MediaManager.h b/dom/media/MediaManager.h index b82c2cda775..74bbe06fe05 100644 --- a/dom/media/MediaManager.h +++ b/dom/media/MediaManager.h @@ -89,8 +89,6 @@ public: mStream = aStream; mAudioSource = aAudioSource; mVideoSource = aVideoSource; - mLastEndTimeAudio = 0; - mLastEndTimeVideo = 0; mStream->AddListener(this); } @@ -187,10 +185,10 @@ public: // Currently audio sources ignore NotifyPull, but they could // watch it especially for fake audio. if (mAudioSource) { - mAudioSource->NotifyPull(aGraph, mStream, kAudioTrack, aDesiredTime, mLastEndTimeAudio); + mAudioSource->NotifyPull(aGraph, mStream, kAudioTrack, aDesiredTime); } if (mVideoSource) { - mVideoSource->NotifyPull(aGraph, mStream, kVideoTrack, aDesiredTime, mLastEndTimeVideo); + mVideoSource->NotifyPull(aGraph, mStream, kVideoTrack, aDesiredTime); } } @@ -239,8 +237,6 @@ private: nsRefPtr mAudioSource; // threadsafe refcnt nsRefPtr mVideoSource; // threadsafe refcnt nsRefPtr mStream; // threadsafe refcnt - StreamTime mLastEndTimeAudio; - StreamTime mLastEndTimeVideo; bool mFinished; // Accessed from MainThread and MSG thread diff --git a/dom/media/webrtc/MediaEngine.h b/dom/media/webrtc/MediaEngine.h index cb62def6aad..b7c33405b9c 100644 --- a/dom/media/webrtc/MediaEngine.h +++ b/dom/media/webrtc/MediaEngine.h @@ -110,8 +110,7 @@ public: virtual void NotifyPull(MediaStreamGraph* aGraph, SourceMediaStream *aSource, TrackID aId, - StreamTime aDesiredTime, - StreamTime &aLastEndTime) = 0; + StreamTime aDesiredTime) = 0; /* Stop the device and release the corresponding MediaStream */ virtual nsresult Stop(SourceMediaStream *aSource, TrackID aID) = 0; diff --git a/dom/media/webrtc/MediaEngineDefault.cpp b/dom/media/webrtc/MediaEngineDefault.cpp index b0025a82ab8..bb0015da25b 100644 --- a/dom/media/webrtc/MediaEngineDefault.cpp +++ b/dom/media/webrtc/MediaEngineDefault.cpp @@ -244,8 +244,7 @@ void MediaEngineDefaultVideoSource::NotifyPull(MediaStreamGraph* aGraph, SourceMediaStream *aSource, TrackID aID, - StreamTime aDesiredTime, - StreamTime &aLastEndTime) + StreamTime aDesiredTime) { // AddTrack takes ownership of segment VideoSegment segment; @@ -264,9 +263,7 @@ MediaEngineDefaultVideoSource::NotifyPull(MediaStreamGraph* aGraph, segment.AppendFrame(image.forget(), delta, size); // This can fail if either a) we haven't added the track yet, or b) // we've removed or finished the track. - if (aSource->AppendToTrack(aID, &segment)) { - aLastEndTime = aDesiredTime; - } + aSource->AppendToTrack(aID, &segment); // Generate null data for fake tracks. if (mHasFakeTracks) { for (int i = 0; i < kFakeVideoTrackCount; ++i) { diff --git a/dom/media/webrtc/MediaEngineDefault.h b/dom/media/webrtc/MediaEngineDefault.h index e64863855f6..efb6b05eb78 100644 --- a/dom/media/webrtc/MediaEngineDefault.h +++ b/dom/media/webrtc/MediaEngineDefault.h @@ -53,8 +53,7 @@ public: virtual void NotifyPull(MediaStreamGraph* aGraph, SourceMediaStream *aSource, TrackID aId, - StreamTime aDesiredTime, - StreamTime &aLastEndTime); + StreamTime aDesiredTime) MOZ_OVERRIDE; virtual bool SatisfiesConstraintSets( const nsTArray& aConstraintSets) { @@ -122,8 +121,7 @@ public: virtual void NotifyPull(MediaStreamGraph* aGraph, SourceMediaStream *aSource, TrackID aId, - StreamTime aDesiredTime, - StreamTime &aLastEndTime) {} + StreamTime aDesiredTime) MOZ_OVERRIDE {} virtual bool IsFake() { return true; diff --git a/dom/media/webrtc/MediaEngineGonkVideoSource.cpp b/dom/media/webrtc/MediaEngineGonkVideoSource.cpp index be01b334396..b204f19858f 100644 --- a/dom/media/webrtc/MediaEngineGonkVideoSource.cpp +++ b/dom/media/webrtc/MediaEngineGonkVideoSource.cpp @@ -70,8 +70,7 @@ void MediaEngineGonkVideoSource::NotifyPull(MediaStreamGraph* aGraph, SourceMediaStream* aSource, TrackID aID, - StreamTime aDesiredTime, - StreamTime& aLastEndTime) + StreamTime aDesiredTime) { VideoSegment segment; diff --git a/dom/media/webrtc/MediaEngineGonkVideoSource.h b/dom/media/webrtc/MediaEngineGonkVideoSource.h index 2d361705b8d..c03a9d4a049 100644 --- a/dom/media/webrtc/MediaEngineGonkVideoSource.h +++ b/dom/media/webrtc/MediaEngineGonkVideoSource.h @@ -68,8 +68,7 @@ public: virtual void NotifyPull(MediaStreamGraph* aGraph, SourceMediaStream* aSource, TrackID aId, - StreamTime aDesiredTime, - StreamTime &aLastEndTime) MOZ_OVERRIDE; + StreamTime aDesiredTime) MOZ_OVERRIDE; virtual bool SatisfiesConstraintSets( const nsTArray& aConstraintSets) { diff --git a/dom/media/webrtc/MediaEngineTabVideoSource.cpp b/dom/media/webrtc/MediaEngineTabVideoSource.cpp index 2519a12fda7..32fb303df0d 100644 --- a/dom/media/webrtc/MediaEngineTabVideoSource.cpp +++ b/dom/media/webrtc/MediaEngineTabVideoSource.cpp @@ -192,8 +192,7 @@ MediaEngineTabVideoSource::Start(SourceMediaStream* aStream, TrackID aID) void MediaEngineTabVideoSource::NotifyPull(MediaStreamGraph*, SourceMediaStream* aSource, - TrackID aID, StreamTime aDesiredTime, - StreamTime& aLastEndTime) + TrackID aID, StreamTime aDesiredTime) { VideoSegment segment; MonitorAutoLock mon(mMonitor); @@ -207,9 +206,7 @@ MediaEngineTabVideoSource::NotifyPull(MediaStreamGraph*, segment.AppendFrame(image.forget().downcast(), delta, size); // This can fail if either a) we haven't added the track yet, or b) // we've removed or finished the track. - if (aSource->AppendToTrack(aID, &(segment))) { - aLastEndTime = aDesiredTime; - } + aSource->AppendToTrack(aID, &(segment)); } } diff --git a/dom/media/webrtc/MediaEngineTabVideoSource.h b/dom/media/webrtc/MediaEngineTabVideoSource.h index 6820788663f..ae4b3abb979 100644 --- a/dom/media/webrtc/MediaEngineTabVideoSource.h +++ b/dom/media/webrtc/MediaEngineTabVideoSource.h @@ -25,7 +25,7 @@ class MediaEngineTabVideoSource : public MediaEngineVideoSource, nsIDOMEventList virtual nsresult Deallocate(); virtual nsresult Start(mozilla::SourceMediaStream*, mozilla::TrackID); virtual void SetDirectListeners(bool aHasDirectListeners) {}; - virtual void NotifyPull(mozilla::MediaStreamGraph*, mozilla::SourceMediaStream*, mozilla::TrackID, mozilla::StreamTime, mozilla::StreamTime&); + virtual void NotifyPull(mozilla::MediaStreamGraph*, mozilla::SourceMediaStream*, mozilla::TrackID, mozilla::StreamTime) MOZ_OVERRIDE; virtual nsresult Stop(mozilla::SourceMediaStream*, mozilla::TrackID); virtual nsresult Config(bool, uint32_t, bool, uint32_t, bool, uint32_t, int32_t); virtual bool IsFake(); diff --git a/dom/media/webrtc/MediaEngineWebRTC.h b/dom/media/webrtc/MediaEngineWebRTC.h index 0954380e247..7ebb9d99992 100644 --- a/dom/media/webrtc/MediaEngineWebRTC.h +++ b/dom/media/webrtc/MediaEngineWebRTC.h @@ -97,8 +97,7 @@ public: virtual void NotifyPull(MediaStreamGraph* aGraph, SourceMediaStream* aSource, TrackID aId, - StreamTime aDesiredTime, - StreamTime &aLastEndTime); + StreamTime aDesiredTime) MOZ_OVERRIDE; virtual const MediaSourceType GetMediaSource() { return mMediaSource; @@ -180,8 +179,7 @@ public: virtual void NotifyPull(MediaStreamGraph* aGraph, SourceMediaStream* aSource, TrackID aId, - StreamTime aDesiredTime, - StreamTime &aLastEndTime); + StreamTime aDesiredTime) MOZ_OVERRIDE; virtual bool IsFake() { return false; diff --git a/dom/media/webrtc/MediaEngineWebRTCAudio.cpp b/dom/media/webrtc/MediaEngineWebRTCAudio.cpp index b95fea5641b..ba5378ab966 100644 --- a/dom/media/webrtc/MediaEngineWebRTCAudio.cpp +++ b/dom/media/webrtc/MediaEngineWebRTCAudio.cpp @@ -398,16 +398,10 @@ void MediaEngineWebRTCAudioSource::NotifyPull(MediaStreamGraph* aGraph, SourceMediaStream *aSource, TrackID aID, - StreamTime aDesiredTime, - StreamTime &aLastEndTime) + StreamTime aDesiredTime) { // Ignore - we push audio data -#ifdef DEBUG - StreamTime delta = aDesiredTime - aLastEndTime; - LOG(("Audio: NotifyPull: aDesiredTime %ld, delta %ld",(int64_t) aDesiredTime, - (int64_t) delta)); - aLastEndTime = aDesiredTime; -#endif + LOG_FRAMES(("NotifyPull, desired = %ld", (int64_t) aDesiredTime)); } void diff --git a/dom/media/webrtc/MediaEngineWebRTCVideo.cpp b/dom/media/webrtc/MediaEngineWebRTCVideo.cpp index 7558557e4f5..b2c73861c51 100644 --- a/dom/media/webrtc/MediaEngineWebRTCVideo.cpp +++ b/dom/media/webrtc/MediaEngineWebRTCVideo.cpp @@ -124,8 +124,7 @@ void MediaEngineWebRTCVideoSource::NotifyPull(MediaStreamGraph* aGraph, SourceMediaStream* aSource, TrackID aID, - StreamTime aDesiredTime, - StreamTime &aLastEndTime) + StreamTime aDesiredTime) { VideoSegment segment; @@ -150,9 +149,7 @@ MediaEngineWebRTCVideoSource::NotifyPull(MediaStreamGraph* aGraph, // Doing so means a negative delta and thus messes up handling of the graph if (delta > 0) { // nullptr images are allowed - if (AppendToTrack(aSource, mImage, aID, delta)) { - aLastEndTime = aDesiredTime; - } + AppendToTrack(aSource, mImage, aID, delta); } } From 1dd7d2a39d7a625393a26749e7379403b673356f Mon Sep 17 00:00:00 2001 From: Paolo Amadini Date: Tue, 30 Dec 2014 16:42:27 +0000 Subject: [PATCH 24/41] Bug 1115791 - Developer Edition profile switching feature broken when in-content preferences are disabled. r=jaws --- browser/components/preferences/main.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/browser/components/preferences/main.js b/browser/components/preferences/main.js index 14ed970ac6e..700c824d4ff 100644 --- a/browser/components/preferences/main.js +++ b/browser/components/preferences/main.js @@ -69,7 +69,7 @@ var gMainPane = { let syncListener = gMainPane.onGetStarted.bind(gMainPane); getStartedLink.addEventListener("click", syncListener); - Cu.import("resource://gre/modules/osfile.jsm"); + Components.utils.import("resource://gre/modules/osfile.jsm"); let uAppData = OS.Constants.Path.userApplicationDataDir; let ignoreSeparateProfile = OS.Path.join(uAppData, "ignore-dev-edition-profile"); @@ -87,12 +87,13 @@ var gMainPane = { separateProfileModeChange: function () { function quitApp() { - Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestartNotSameProfile); + Services.startup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit | + Components.interfaces.nsIAppStartup.eRestartNotSameProfile); } function revertCheckbox(error) { separateProfileModeCheckbox.checked = !separateProfileModeCheckbox.checked; if (error) { - Cu.reportError("Failed to toggle separate profile mode: " + error); + Components.utils.reportError("Failed to toggle separate profile mode: " + error); } } @@ -106,13 +107,13 @@ var gMainPane = { let shouldProceed = Services.prompt.confirm(window, title, msg) if (shouldProceed) { let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"] - .createInstance(Ci.nsISupportsPRBool); + .createInstance(Components.interfaces.nsISupportsPRBool); Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart"); shouldProceed = !cancelQuit.data; if (shouldProceed) { - Cu.import("resource://gre/modules/osfile.jsm"); + Components.utils.import("resource://gre/modules/osfile.jsm"); let uAppData = OS.Constants.Path.userApplicationDataDir; let ignoreSeparateProfile = OS.Path.join(uAppData, "ignore-dev-edition-profile"); @@ -131,7 +132,7 @@ var gMainPane = { onGetStarted: function (aEvent) { const Cc = Components.classes, Ci = Components.interfaces; let wm = Cc["@mozilla.org/appshell/window-mediator;1"] - .getService(Ci.nsIWindowMediator); + .getService(Components.interfaces.nsIWindowMediator); let win = wm.getMostRecentWindow("navigator:browser"); if (win) { @@ -254,7 +255,7 @@ var gMainPane = { const Cc = Components.classes, Ci = Components.interfaces; // If we're in instant-apply mode, use the most recent browser window var wm = Cc["@mozilla.org/appshell/window-mediator;1"] - .getService(Ci.nsIWindowMediator); + .getService(Components.interfaces.nsIWindowMediator); win = wm.getMostRecentWindow("navigator:browser"); } else { From b618ac9265266dc325e9d09a704e1ff7039c4c24 Mon Sep 17 00:00:00 2001 From: Mark Finkle Date: Tue, 30 Dec 2014 12:34:55 -0500 Subject: [PATCH 25/41] Bug 1072997 - Check for a disabled System Download Manager before trying to use it r=margaret --- mobile/android/base/DownloadsIntegration.java | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/mobile/android/base/DownloadsIntegration.java b/mobile/android/base/DownloadsIntegration.java index 5e5b48032fb..8c65835b17f 100644 --- a/mobile/android/base/DownloadsIntegration.java +++ b/mobile/android/base/DownloadsIntegration.java @@ -12,16 +12,19 @@ import org.mozilla.gecko.util.EventCallback; import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; import java.io.File; +import java.lang.IllegalArgumentException; import java.util.ArrayList; import java.util.List; import android.app.DownloadManager; import android.content.Context; +import android.content.pm.PackageManager; import android.database.Cursor; import android.media.MediaScannerConnection; import android.media.MediaScannerConnection.MediaScannerConnectionClient; import android.net.Uri; import android.text.TextUtils; +import android.util.Log; public class DownloadsIntegration implements NativeEventListener { @@ -88,6 +91,23 @@ public class DownloadsIntegration implements NativeEventListener } } + private static boolean useSystemDownloadManager() { + if (!AppConstants.ANDROID_DOWNLOADS_INTEGRATION) { + return false; + } + + int state = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; + try { + state = GeckoAppShell.getContext().getPackageManager().getApplicationEnabledSetting("com.android.providers.downloads"); + } catch (IllegalArgumentException e) { + // Download Manager package does not exist + return false; + } + + return (PackageManager.COMPONENT_ENABLED_STATE_ENABLED == state || + PackageManager.COMPONENT_ENABLED_STATE_DEFAULT == state); + } + @WrapElementForJNI public static void scanMedia(final String aFile, String aMimeType) { String mimeType = aMimeType; @@ -115,7 +135,7 @@ public class DownloadsIntegration implements NativeEventListener } } - if (AppConstants.ANDROID_DOWNLOADS_INTEGRATION) { + if (useSystemDownloadManager()) { final File f = new File(aFile); final DownloadManager dm = (DownloadManager) GeckoAppShell.getContext().getSystemService(Context.DOWNLOAD_SERVICE); dm.addCompletedDownload(f.getName(), @@ -133,7 +153,7 @@ public class DownloadsIntegration implements NativeEventListener } public static void removeDownload(final Download download) { - if (!AppConstants.ANDROID_DOWNLOADS_INTEGRATION) { + if (!useSystemDownloadManager()) { return; } From 53fcd11a27b15fc3385560439fc959bb5fa6dade Mon Sep 17 00:00:00 2001 From: Michael Comella Date: Tue, 30 Dec 2014 09:48:55 -0800 Subject: [PATCH 26/41] Bug 1116369 - Remove new tablet toggle settings strings. r=margaret --- mobile/android/base/locales/en-US/android_strings.dtd | 6 ------ mobile/android/base/strings.xml.in | 4 ---- 2 files changed, 10 deletions(-) diff --git a/mobile/android/base/locales/en-US/android_strings.dtd b/mobile/android/base/locales/en-US/android_strings.dtd index 0b1d1ac2885..6ccbb425d26 100644 --- a/mobile/android/base/locales/en-US/android_strings.dtd +++ b/mobile/android/base/locales/en-US/android_strings.dtd @@ -529,12 +529,6 @@ just addresses the organization to follow, e.g. "This site is run by " --> - - - - - - diff --git a/mobile/android/base/strings.xml.in b/mobile/android/base/strings.xml.in index 3bdafa30dbd..ec813ea4779 100644 --- a/mobile/android/base/strings.xml.in +++ b/mobile/android/base/strings.xml.in @@ -447,10 +447,6 @@ &updater_apply_title2; &updater_apply_select2; - - &new_tablet_restart; - &new_tablet_pref; - &suggestions_prompt3; From ff401675b0cb69f67b5da2045e6aaed44a9ca6c1 Mon Sep 17 00:00:00 2001 From: Marco Bonardo Date: Tue, 30 Dec 2014 21:33:14 +0100 Subject: [PATCH 27/41] Bug 1081108 - Implement reorder in Bookmarks.jsm. r=Mano --HG-- extra : rebase_source : d9327202388828855c8579646ace390887eadaf6 --- toolkit/components/places/Bookmarks.jsm | 124 +++++++++++++++++- .../bookmarks/test_bookmarks_notifications.js | 52 ++++++++ .../tests/bookmarks/test_bookmarks_reorder.js | 110 ++++++++++++++++ .../places/tests/bookmarks/xpcshell.ini | 1 + 4 files changed, 283 insertions(+), 4 deletions(-) create mode 100644 toolkit/components/places/tests/bookmarks/test_bookmarks_reorder.js diff --git a/toolkit/components/places/Bookmarks.jsm b/toolkit/components/places/Bookmarks.jsm index 70137511d1b..6977e380fe1 100644 --- a/toolkit/components/places/Bookmarks.jsm +++ b/toolkit/components/places/Bookmarks.jsm @@ -654,14 +654,39 @@ let Bookmarks = Object.freeze({ * @rejects if an error happens while reordering. * @throws if the arguments are invalid. */ - // TODO must implement these methods yet: - // void setItemIndex(in long long aItemId, in long aNewIndex); reorder(parentGuid, orderedChildrenGuids) { - throw new Error("Not yet implemented"); + let info = { guid: parentGuid }; + info = validateBookmarkObject(info, { guid: { required: true } }); + + if (!Array.isArray(orderedChildrenGuids) || !orderedChildrenGuids.length) + throw new Error("Must provide a sorted array of children GUIDs."); + try { + orderedChildrenGuids.forEach(VALIDATORS.guid); + } catch (ex) { + throw new Error("Invalid GUID found in the sorted children array."); + } + + return Task.spawn(function* () { + let parent = yield fetchBookmark(info); + if (!parent || parent.type != this.TYPE_FOLDER) + throw new Error("No folder found for the provided GUID."); + + let sortedChildren = yield reorderChildren(parent, orderedChildrenGuids); + + let observers = PlacesUtils.bookmarks.getObservers(); + // Note that child.index is the old index. + for (let i = 0; i < sortedChildren.length; ++i) { + let child = sortedChildren[i]; + notify(observers, "onItemMoved", [ child._id, child._parentId, + child.index, child._parentId, + i, child.type, + child.guid, child.parentGuid, + child.parentGuid ]); + } + }.bind(this)); } }); - //////////////////////////////////////////////////////////////////////////////// // Globals. @@ -949,6 +974,26 @@ function* fetchBookmarksByKeyword(info) { return rows.length ? rowsToItemsArray(rows) : null; } +function* fetchBookmarksByParent(info) { + let db = yield DBConnPromised; + + let rows = yield db.executeCached( + `SELECT b.guid, IFNULL(p.guid, "") AS parentGuid, b.position AS 'index', + b.dateAdded, b.lastModified, b.type, b.title, h.url AS url, + keyword, b.id AS _id, b.parent AS _parentId, + (SELECT count(*) FROM moz_bookmarks WHERE parent = b.id) AS _childCount, + p.parent AS _grandParentId + FROM moz_bookmarks b + LEFT JOIN moz_bookmarks p ON p.id = b.parent + LEFT JOIN moz_keywords k ON k.id = b.keyword_id + LEFT JOIN moz_places h ON h.id = b.fk + WHERE p.guid = :parentGuid + ORDER BY b.position ASC + `, { parentGuid: info.parentGuid }); + + return rowsToItemsArray(rows); +} + //////////////////////////////////////////////////////////////////////////////// // Remove implementation. @@ -996,6 +1041,77 @@ function* removeBookmark(item) { return item; } +//////////////////////////////////////////////////////////////////////////////// +// Reorder implementation. + +function* reorderChildren(parent, orderedChildrenGuids) { + let db = yield DBConnPromised; + + return db.executeTransaction(function* () { + // Select all of the direct children for the given parent. + let children = yield fetchBookmarksByParent({ parentGuid: parent.guid }); + if (!children.length) + return; + + // Reorder the children array according to the specified order, provided + // GUIDs come first, others are appended in somehow random order. + children.sort((a, b) => { + let i = orderedChildrenGuids.indexOf(a.guid); + let j = orderedChildrenGuids.indexOf(b.guid); + // This works provided fetchBookmarksByParent returns sorted children. + return (i == -1 && j == -1) ? 0 : + (i != -1 && j != -1 && i < j) || (i != -1 && j == -1) ? -1 : 1; + }); + + // Update the bookmarks position now. If any unknown guid have been + // inserted meanwhile, its position will be set to -position, and we'll + // handle it later. + // To do the update in a single step, we build a VALUES (guid, position) + // table. We then use count() in the sorting table to avoid skipping values + // when no more existing GUIDs have been provided. + let valuesTable = children.map((child, i) => `("${child.guid}", ${i})`) + .join(); + yield db.execute( + `WITH sorting(g, p) AS ( + VALUES ${valuesTable} + ) + UPDATE moz_bookmarks SET position = ( + SELECT CASE count(a.g) WHEN 0 THEN -position + ELSE count(a.g) - 1 + END + FROM sorting a + JOIN sorting b ON b.p <= a.p + WHERE a.g = guid + AND parent = :parentId + )`, { parentId: parent._id}); + + // Update position of items that could have been inserted in the meanwhile. + // Since this can happen rarely and it's only done for schema coherence + // resonds, we won't notify about these changes. + yield db.executeCached( + `CREATE TEMP TRIGGER moz_bookmarks_reorder_trigger + AFTER UPDATE OF position ON moz_bookmarks + WHEN NEW.position = -1 + BEGIN + UPDATE moz_bookmarks + SET position = (SELECT MAX(position) FROM moz_bookmarks + WHERE parent = NEW.parent) + + (SELECT count(*) FROM moz_bookmarks + WHERE parent = NEW.parent + AND position BETWEEN OLD.position AND -1) + WHERE guid = NEW.guid; + END + `); + + yield db.executeCached( + `UPDATE moz_bookmarks SET position = -1 WHERE position < 0`); + + yield db.executeCached(`DROP TRIGGER moz_bookmarks_reorder_trigger`); + + return children; + }.bind(this)); +} + //////////////////////////////////////////////////////////////////////////////// // Helpers. diff --git a/toolkit/components/places/tests/bookmarks/test_bookmarks_notifications.js b/toolkit/components/places/tests/bookmarks/test_bookmarks_notifications.js index b4390ae2cf7..791b21d6131 100644 --- a/toolkit/components/places/tests/bookmarks/test_bookmarks_notifications.js +++ b/toolkit/components/places/tests/bookmarks/test_bookmarks_notifications.js @@ -414,6 +414,58 @@ add_task(function* eraseEverything_notification() { ]); }); +add_task(function* reorder_notification() { + let bookmarks = [ + { type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + url: "http://example1.com/", + parentGuid: PlacesUtils.bookmarks.unfiledGuid + }, + { type: PlacesUtils.bookmarks.TYPE_FOLDER, + parentGuid: PlacesUtils.bookmarks.unfiledGuid + }, + { type: PlacesUtils.bookmarks.TYPE_SEPARATOR, + parentGuid: PlacesUtils.bookmarks.unfiledGuid + }, + { type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + url: "http://example2.com/", + parentGuid: PlacesUtils.bookmarks.unfiledGuid + }, + { type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + url: "http://example3.com/", + parentGuid: PlacesUtils.bookmarks.unfiledGuid + }, + ]; + let sorted = []; + for (let bm of bookmarks){ + sorted.push(yield PlacesUtils.bookmarks.insert(bm)); + } + + // Randomly reorder the array. + sorted.sort(() => 0.5 - Math.random()); + + let observer = expectNotifications(); + yield PlacesUtils.bookmarks.reorder(PlacesUtils.bookmarks.unfiledGuid, + sorted.map(bm => bm.guid)); + + let expectedNotifications = []; + for (let i = 0; i < sorted.length; ++i) { + let child = sorted[i]; + let childId = yield PlacesUtils.promiseItemId(child.guid); + expectedNotifications.push({ name: "onItemMoved", + arguments: [ childId, + PlacesUtils.unfiledBookmarksFolderId, + child.index, + PlacesUtils.unfiledBookmarksFolderId, + i, + child.type, + child.guid, + child.parentGuid, + child.parentGuid + ] }); + } + observer.check(expectedNotifications); +}); + function expectNotifications() { let notifications = []; let observer = new Proxy(NavBookmarkObserver, { diff --git a/toolkit/components/places/tests/bookmarks/test_bookmarks_reorder.js b/toolkit/components/places/tests/bookmarks/test_bookmarks_reorder.js new file mode 100644 index 00000000000..c12c581f4b0 --- /dev/null +++ b/toolkit/components/places/tests/bookmarks/test_bookmarks_reorder.js @@ -0,0 +1,110 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +add_task(function* invalid_input_throws() { + Assert.throws(() => PlacesUtils.bookmarks.reorder(), + /Invalid value for property 'guid'/); + Assert.throws(() => PlacesUtils.bookmarks.reorder(null), + /Invalid value for property 'guid'/); + + Assert.throws(() => PlacesUtils.bookmarks.reorder("test"), + /Invalid value for property 'guid'/); + Assert.throws(() => PlacesUtils.bookmarks.reorder(123), + /Invalid value for property 'guid'/); + + Assert.throws(() => PlacesUtils.bookmarks.reorder({ guid: "test" }), + /Invalid value for property 'guid'/); + + Assert.throws(() => PlacesUtils.bookmarks.reorder("123456789012"), + /Must provide a sorted array of children GUIDs./); + Assert.throws(() => PlacesUtils.bookmarks.reorder("123456789012", {}), + /Must provide a sorted array of children GUIDs./); + Assert.throws(() => PlacesUtils.bookmarks.reorder("123456789012", null), + /Must provide a sorted array of children GUIDs./); + Assert.throws(() => PlacesUtils.bookmarks.reorder("123456789012", []), + /Must provide a sorted array of children GUIDs./); + + Assert.throws(() => PlacesUtils.bookmarks.reorder("123456789012", [ null ]), + /Invalid GUID found in the sorted children array/); + Assert.throws(() => PlacesUtils.bookmarks.reorder("123456789012", [ "" ]), + /Invalid GUID found in the sorted children array/); + Assert.throws(() => PlacesUtils.bookmarks.reorder("123456789012", [ {} ]), + /Invalid GUID found in the sorted children array/); + Assert.throws(() => PlacesUtils.bookmarks.reorder("123456789012", [ "012345678901" , null ]), + /Invalid GUID found in the sorted children array/); +}); + +add_task(function* reorder_nonexistent_guid() { + yield Assert.rejects(PlacesUtils.bookmarks.reorder("123456789012", [ "012345678901" ]), + /No folder found for the provided GUID/, + "Should throw for nonexisting guid"); +}); + +add_task(function* reorder() { + let bookmarks = [ + { type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + url: "http://example1.com/", + parentGuid: PlacesUtils.bookmarks.unfiledGuid + }, + { type: PlacesUtils.bookmarks.TYPE_FOLDER, + parentGuid: PlacesUtils.bookmarks.unfiledGuid + }, + { type: PlacesUtils.bookmarks.TYPE_SEPARATOR, + parentGuid: PlacesUtils.bookmarks.unfiledGuid + }, + { type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + url: "http://example2.com/", + parentGuid: PlacesUtils.bookmarks.unfiledGuid + }, + { type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + url: "http://example3.com/", + parentGuid: PlacesUtils.bookmarks.unfiledGuid + } + ]; + let sorted = [for (bm of bookmarks) yield PlacesUtils.bookmarks.insert(bm)] + + // Check the initial append sorting. + Assert.ok(sorted.every((bm, i) => bm.index == i), + "Initial bookmarks sorting is correct"); + + // Apply random sorting and run multiple tests. + for (let t = 0; t < 4; t++) { + sorted.sort(() => 0.5 - Math.random()); + let sortedGuids = sorted.map(child => child.guid); + dump("Expected order: " + sortedGuids.join() + "\n"); + // Add a nonexisting guid to the array, to ensure nothing will break. + sortedGuids.push("123456789012"); + yield PlacesUtils.bookmarks.reorder(PlacesUtils.bookmarks.unfiledGuid, + sortedGuids); + for (let i = 0; i < sorted.length; ++i) { + let item = yield PlacesUtils.bookmarks.fetch(sorted[i].guid); + Assert.equal(item.index, i); + } + } + + do_print("Test partial sorting"); + // Try a partial sorting by passing only 2 entries. + // The unspecified entries should retain the original order. + sorted = [ sorted[1], sorted[0] ].concat(sorted.slice(2)); + let sortedGuids = [ sorted[0].guid, sorted[1].guid ]; + dump("Expected order: " + [b.guid for (b of sorted)].join() + "\n"); + yield PlacesUtils.bookmarks.reorder(PlacesUtils.bookmarks.unfiledGuid, + sortedGuids); + for (let i = 0; i < sorted.length; ++i) { + let item = yield PlacesUtils.bookmarks.fetch(sorted[i].guid); + Assert.equal(item.index, i); + } + + // Use triangular numbers to detect skipped position. + let db = yield PlacesUtils.promiseDBConnection(); + let rows = yield db.execute( + `SELECT parent + FROM moz_bookmarks + GROUP BY parent + HAVING (SUM(DISTINCT position + 1) - (count(*) * (count(*) + 1) / 2)) <> 0`); + Assert.equal(rows.length, 0, "All the bookmarks should have consistent positions"); +}); + +function run_test() { + run_next_test(); +} diff --git a/toolkit/components/places/tests/bookmarks/xpcshell.ini b/toolkit/components/places/tests/bookmarks/xpcshell.ini index 864521cfe7d..0f0af1bc2a6 100644 --- a/toolkit/components/places/tests/bookmarks/xpcshell.ini +++ b/toolkit/components/places/tests/bookmarks/xpcshell.ini @@ -34,6 +34,7 @@ skip-if = toolkit == 'android' || toolkit == 'gonk' [test_bookmarks_insert.js] [test_bookmarks_notifications.js] [test_bookmarks_remove.js] +[test_bookmarks_reorder.js] [test_bookmarks_update.js] [test_changeBookmarkURI.js] [test_getBookmarkedURIFor.js] From 5a4af1158c39a16f680e971fda5ca1b14560de7f Mon Sep 17 00:00:00 2001 From: Paolo Amadini Date: Tue, 30 Dec 2014 21:05:12 +0000 Subject: [PATCH 28/41] Bug 480169 - Remove unused tree view test for the Clear Recent History dialog. r=mak --- browser/base/content/test/general/browser.ini | 4 - .../browser_sanitizeDialog_treeView.js | 632 ------------------ 2 files changed, 636 deletions(-) delete mode 100644 browser/base/content/test/general/browser_sanitizeDialog_treeView.js diff --git a/browser/base/content/test/general/browser.ini b/browser/base/content/test/general/browser.ini index c781c7668a9..1a3095cc28c 100644 --- a/browser/base/content/test/general/browser.ini +++ b/browser/base/content/test/general/browser.ini @@ -384,10 +384,6 @@ skip-if = true # bug 432425 skip-if = buildapp == 'mulet' [browser_sanitizeDialog.js] skip-if = buildapp == 'mulet' -[browser_sanitizeDialog_treeView.js] -skip-if = true # disabled until the tree view is added - # back to the clear recent history dialog (sanitize.xul), if - # it ever is (bug 480169) [browser_save_link-perwindowpb.js] skip-if = buildapp == 'mulet' || e10s # Bug 933103 - mochitest's EventUtils.synthesizeMouse functions not e10s friendly [browser_save_private_link_perwindowpb.js] diff --git a/browser/base/content/test/general/browser_sanitizeDialog_treeView.js b/browser/base/content/test/general/browser_sanitizeDialog_treeView.js deleted file mode 100644 index 011f9703a9b..00000000000 --- a/browser/base/content/test/general/browser_sanitizeDialog_treeView.js +++ /dev/null @@ -1,632 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et: */ -/* 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/. */ - -/** - * Tests the sanitize dialog (a.k.a. the clear recent history dialog). - * See bug 480169. - * - * The purpose of this test is not to fully flex the sanitize timespan code; - * browser/base/content/test/general/browser_sanitize-timespans.js does that. This - * test checks the UI of the dialog and makes sure it's correctly connected to - * the sanitize timespan code. - * - * Some of this code, especially the history creation parts, was taken from - * browser/base/content/test/general/browser_sanitize-timespans.js. - */ - -Cc["@mozilla.org/moz/jssubscript-loader;1"]. - getService(Ci.mozIJSSubScriptLoader). - loadSubScript("chrome://browser/content/sanitize.js"); - -const dm = Cc["@mozilla.org/download-manager;1"]. - getService(Ci.nsIDownloadManager); -const formhist = Cc["@mozilla.org/satchel/form-history;1"]. - getService(Ci.nsIFormHistory2); - -// Add tests here. Each is a function that's called by doNextTest(). -var gAllTests = [ - - /** - * Moves the grippy around, makes sure it works OK. - */ - function () { - // Add history (within the past hour) to get some rows in the tree. - let uris = []; - let places = []; - let pURI; - for (let i = 0; i < 30; i++) { - pURI = makeURI("http://" + i + "-minutes-ago.com/"); - places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(i)}); - uris.push(pURI); - } - - addVisits(places, function() { - // Open the dialog and do our tests. - openWindow(function (aWin) { - let wh = new WindowHelper(aWin); - wh.selectDuration(Sanitizer.TIMESPAN_HOUR); - wh.checkGrippy("Grippy should be at last row after selecting HOUR " + - "duration", - wh.getRowCount() - 1); - - // Move the grippy around. - let row = wh.getGrippyRow(); - while (row !== 0) { - row--; - wh.moveGrippyBy(-1); - wh.checkGrippy("Grippy should be moved up one row", row); - } - wh.moveGrippyBy(-1); - wh.checkGrippy("Grippy should remain at first row after trying to move " + - "it up", - 0); - while (row !== wh.getRowCount() - 1) { - row++; - wh.moveGrippyBy(1); - wh.checkGrippy("Grippy should be moved down one row", row); - } - wh.moveGrippyBy(1); - wh.checkGrippy("Grippy should remain at last row after trying to move " + - "it down", - wh.getRowCount() - 1); - - // Cancel the dialog, make sure history visits are not cleared. - wh.checkPrefCheckbox("history", false); - - wh.cancelDialog(); - yield promiseHistoryClearedState(uris, false); - - // OK, done, cleanup after ourselves. - blankSlate(); - yield promiseHistoryClearedState(uris, true); - }); - }); - }, - - /** - * Ensures that the combined history-downloads checkbox clears both history - * visits and downloads when checked; the dialog respects simple timespan. - */ - function () { - // Add history (within the past hour). - let uris = []; - let places = []; - let pURI; - for (let i = 0; i < 30; i++) { - pURI = makeURI("http://" + i + "-minutes-ago.com/"); - places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(i)}); - uris.push(pURI); - } - // Add history (over an hour ago). - let olderURIs = []; - for (let i = 0; i < 5; i++) { - pURI = makeURI("http://" + (60 + i) + "-minutes-ago.com/"); - places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(60 + i)}); - olderURIs.push(pURI); - } - - addVisits(places, function() { - // Add downloads (within the past hour). - let downloadIDs = []; - for (let i = 0; i < 5; i++) { - downloadIDs.push(addDownloadWithMinutesAgo(i)); - } - // Add downloads (over an hour ago). - let olderDownloadIDs = []; - for (let i = 0; i < 5; i++) { - olderDownloadIDs.push(addDownloadWithMinutesAgo(61 + i)); - } - let totalHistoryVisits = uris.length + olderURIs.length; - - // Open the dialog and do our tests. - openWindow(function (aWin) { - let wh = new WindowHelper(aWin); - wh.selectDuration(Sanitizer.TIMESPAN_HOUR); - wh.checkGrippy("Grippy should be at proper row after selecting HOUR " + - "duration", - uris.length); - - // Accept the dialog, make sure history visits and downloads within one - // hour are cleared. - wh.checkPrefCheckbox("history", true); - wh.acceptDialog(); - yield promiseHistoryClearedState(uris, true); - ensureDownloadsClearedState(downloadIDs, true); - - // Make sure visits and downloads > 1 hour still exist. - yield promiseHistoryClearedState(olderURIs, false); - ensureDownloadsClearedState(olderDownloadIDs, false); - - // OK, done, cleanup after ourselves. - blankSlate(); - yield promiseHistoryClearedState(olderURIs, true); - ensureDownloadsClearedState(olderDownloadIDs, true); - }); - }); - }, - - /** - * Ensures that the combined history-downloads checkbox removes neither - * history visits nor downloads when not checked. - */ - function () { - // Add history, downloads, form entries (within the past hour). - let uris = []; - let places = []; - let pURI; - for (let i = 0; i < 5; i++) { - pURI = makeURI("http://" + i + "-minutes-ago.com/"); - places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(i)}); - uris.push(pURI); - } - - addVisits(places, function() { - let downloadIDs = []; - for (let i = 0; i < 5; i++) { - downloadIDs.push(addDownloadWithMinutesAgo(i)); - } - let formEntries = []; - for (let i = 0; i < 5; i++) { - formEntries.push(addFormEntryWithMinutesAgo(i)); - } - - // Open the dialog and do our tests. - openWindow(function (aWin) { - let wh = new WindowHelper(aWin); - wh.selectDuration(Sanitizer.TIMESPAN_HOUR); - wh.checkGrippy("Grippy should be at last row after selecting HOUR " + - "duration", - wh.getRowCount() - 1); - - // Remove only form entries, leave history (including downloads). - wh.checkPrefCheckbox("history", false); - wh.checkPrefCheckbox("formdata", true); - wh.acceptDialog(); - - // Of the three only form entries should be cleared. - yield promiseHistoryClearedState(uris, false); - ensureDownloadsClearedState(downloadIDs, false); - ensureFormEntriesClearedState(formEntries, true); - - // OK, done, cleanup after ourselves. - blankSlate(); - yield promiseHistoryClearedState(uris, true); - ensureDownloadsClearedState(downloadIDs, true); - }); - }); - }, - - /** - * Ensures that the "Everything" duration option works. - */ - function () { - // Add history. - let uris = []; - let places = []; - let pURI; - // within past hour, within past two hours, within past four hours and - // outside past four hours - [10, 70, 130, 250].forEach(function(aValue) { - pURI = makeURI("http://" + aValue + "-minutes-ago.com/"); - places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(aValue)}); - uris.push(pURI); - }); - addVisits(places, function() { - - // Open the dialog and do our tests. - openWindow(function (aWin) { - let wh = new WindowHelper(aWin); - wh.selectDuration(Sanitizer.TIMESPAN_EVERYTHING); - wh.checkPrefCheckbox("history", true); - wh.acceptDialog(); - yield promiseHistoryClearedState(uris, true); - }); - }); - } -]; - -// Used as the download database ID for a new download. Incremented for each -// new download. See addDownloadWithMinutesAgo(). -var gDownloadId = 5555551; - -// Index in gAllTests of the test currently being run. Incremented for each -// test run. See doNextTest(). -var gCurrTest = 0; - -var now_uSec = Date.now() * 1000; - -/////////////////////////////////////////////////////////////////////////////// - -/** - * This wraps the dialog and provides some convenience methods for interacting - * with it. - * - * A warning: Before you call any function that uses the tree (or any function - * that calls a function that uses the tree), you must set a non-everything - * duration by calling selectDuration(). The dialog does not initialize the - * tree if it does not yet need to be shown. - * - * @param aWin - * The dialog's nsIDOMWindow - */ -function WindowHelper(aWin) { - this.win = aWin; -} - -WindowHelper.prototype = { - /** - * "Presses" the dialog's OK button. - */ - acceptDialog: function () { - is(this.win.document.documentElement.getButton("accept").disabled, false, - "Dialog's OK button should not be disabled"); - this.win.document.documentElement.acceptDialog(); - }, - - /** - * "Presses" the dialog's Cancel button. - */ - cancelDialog: function () { - this.win.document.documentElement.cancelDialog(); - }, - - /** - * Ensures that the grippy row is in the right place, tree selection is OK, - * and that the grippy's visible. - * - * @param aMsg - * Passed to is() when checking grippy location - * @param aExpectedRow - * The row that the grippy should be at - */ - checkGrippy: function (aMsg, aExpectedRow) { - is(this.getGrippyRow(), aExpectedRow, aMsg); - this.checkTreeSelection(); - this.ensureGrippyIsVisible(); - }, - - /** - * (Un)checks a history scope checkbox (browser & download history, - * form history, etc.). - * - * @param aPrefName - * The final portion of the checkbox's privacy.cpd.* preference name - * @param aCheckState - * True if the checkbox should be checked, false otherwise - */ - checkPrefCheckbox: function (aPrefName, aCheckState) { - var pref = "privacy.cpd." + aPrefName; - var cb = this.win.document.querySelectorAll( - "#itemList > [preference='" + pref + "']"); - is(cb.length, 1, "found checkbox for " + pref + " preference"); - if (cb[0].checked != aCheckState) - cb[0].click(); - }, - - /** - * Ensures that the tree selection is appropriate to the grippy row. (A - * single, contiguous selection should exist from the first row all the way - * to the grippy.) - */ - checkTreeSelection: function () { - let grippyRow = this.getGrippyRow(); - let sel = this.getTree().view.selection; - if (grippyRow === 0) { - is(sel.getRangeCount(), 0, - "Grippy row is 0, so no tree selection should exist"); - } - else { - is(sel.getRangeCount(), 1, - "Grippy row > 0, so only one tree selection range should exist"); - let min = {}; - let max = {}; - sel.getRangeAt(0, min, max); - is(min.value, 0, "Tree selection should start at first row"); - is(max.value, grippyRow - 1, - "Tree selection should end at row before grippy"); - } - }, - - /** - * The grippy should always be visible when it's moved directly. This method - * ensures that. - */ - ensureGrippyIsVisible: function () { - let tbo = this.getTree().treeBoxObject; - let firstVis = tbo.getFirstVisibleRow(); - let lastVis = tbo.getLastVisibleRow(); - let grippyRow = this.getGrippyRow(); - ok(firstVis <= grippyRow && grippyRow <= lastVis, - "Grippy row should be visible; this inequality should be true: " + - firstVis + " <= " + grippyRow + " <= " + lastVis); - }, - - /** - * @return The dialog's duration dropdown - */ - getDurationDropdown: function () { - return this.win.document.getElementById("sanitizeDurationChoice"); - }, - - /** - * @return The grippy row index - */ - getGrippyRow: function () { - return this.win.gContiguousSelectionTreeHelper.getGrippyRow(); - }, - - /** - * @return The tree's row count (includes the grippy row) - */ - getRowCount: function () { - return this.getTree().view.rowCount; - }, - - /** - * @return The tree - */ - getTree: function () { - return this.win.gContiguousSelectionTreeHelper.tree; - }, - - /** - * @return True if the "Everything" warning panel is visible (as opposed to - * the tree) - */ - isWarningPanelVisible: function () { - return this.win.document.getElementById("durationDeck").selectedIndex == 1; - }, - - /** - * @return True if the tree is visible (as opposed to the warning panel) - */ - isTreeVisible: function () { - return this.win.document.getElementById("durationDeck").selectedIndex == 0; - }, - - /** - * Moves the grippy one row at a time in the direction and magnitude specified. - * If aDelta < 0, moves the grippy up; if aDelta > 0, moves it down. - * - * @param aDelta - * The amount and direction to move - */ - moveGrippyBy: function (aDelta) { - if (aDelta === 0) - return; - let key = aDelta < 0 ? "UP" : "DOWN"; - let abs = Math.abs(aDelta); - let treechildren = this.getTree().treeBoxObject.treeBody; - treechildren.focus(); - for (let i = 0; i < abs; i++) { - EventUtils.sendKey(key); - } - }, - - /** - * Selects a duration in the duration dropdown. - * - * @param aDurVal - * One of the Sanitizer.TIMESPAN_* values - */ - selectDuration: function (aDurVal) { - this.getDurationDropdown().value = aDurVal; - if (aDurVal === Sanitizer.TIMESPAN_EVERYTHING) { - is(this.isTreeVisible(), false, - "Tree should not be visible for TIMESPAN_EVERYTHING"); - is(this.isWarningPanelVisible(), true, - "Warning panel should be visible for TIMESPAN_EVERYTHING"); - } - else { - is(this.isTreeVisible(), true, - "Tree should be visible for non-TIMESPAN_EVERYTHING"); - is(this.isWarningPanelVisible(), false, - "Warning panel should not be visible for non-TIMESPAN_EVERYTHING"); - } - } -}; - -/** - * Adds a download to history. - * - * @param aMinutesAgo - * The download will be downloaded this many minutes ago - */ -function addDownloadWithMinutesAgo(aMinutesAgo) { - let name = "fakefile-" + aMinutesAgo + "-minutes-ago"; - let data = { - id: gDownloadId, - name: name, - source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169", - target: name, - startTime: now_uSec - (aMinutesAgo * 60 * 1000000), - endTime: now_uSec - ((aMinutesAgo + 1) *60 * 1000000), - state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED, - currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0, - guid: "a1bcD23eF4g5" - }; - - let db = dm.DBConnection; - let stmt = db.createStatement( - "INSERT INTO moz_downloads (id, name, source, target, startTime, endTime, " + - "state, currBytes, maxBytes, preferredAction, autoResume, guid) " + - "VALUES (:id, :name, :source, :target, :startTime, :endTime, :state, " + - ":currBytes, :maxBytes, :preferredAction, :autoResume, :guid)"); - try { - for (let prop in data) { - stmt.params[prop] = data[prop]; - } - stmt.execute(); - } - finally { - stmt.reset(); - } - - is(downloadExists(gDownloadId), true, - "Sanity check: download " + gDownloadId + - " should exist after creating it"); - - return gDownloadId++; -} - -/** - * Adds a form entry to history. - * - * @param aMinutesAgo - * The entry will be added this many minutes ago - */ -function addFormEntryWithMinutesAgo(aMinutesAgo) { - let name = aMinutesAgo + "-minutes-ago"; - formhist.addEntry(name, "dummy"); - - // Artifically age the entry to the proper vintage. - let db = formhist.DBConnection; - let timestamp = now_uSec - (aMinutesAgo * 60 * 1000000); - db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " + - timestamp + " WHERE fieldname = '" + name + "'"); - - is(formhist.nameExists(name), true, - "Sanity check: form entry " + name + " should exist after creating it"); - return name; -} - -/** - * Removes all history visits, downloads, and form entries. - */ -function blankSlate() { - PlacesUtils.bhistory.removeAllPages(); - dm.cleanUp(); - formhist.removeAllEntries(); -} - -/** - * Checks to see if the download with the specified ID exists. - * - * @param aID - * The ID of the download to check - * @return True if the download exists, false otherwise - */ -function downloadExists(aID) -{ - let db = dm.DBConnection; - let stmt = db.createStatement( - "SELECT * " + - "FROM moz_downloads " + - "WHERE id = :id" - ); - stmt.params.id = aID; - let rows = stmt.executeStep(); - stmt.finalize(); - return !!rows; -} - -/** - * Runs the next test in the gAllTests array. If all tests have been run, - * finishes the entire suite. - */ -function doNextTest() { - if (gAllTests.length <= gCurrTest) { - blankSlate(); - waitForAsyncUpdates(finish); - } - else { - let ct = gCurrTest; - gCurrTest++; - gAllTests[ct](); - } -} - -/** - * Ensures that the specified downloads are either cleared or not. - * - * @param aDownloadIDs - * Array of download database IDs - * @param aShouldBeCleared - * True if each download should be cleared, false otherwise - */ -function ensureDownloadsClearedState(aDownloadIDs, aShouldBeCleared) { - let niceStr = aShouldBeCleared ? "no longer" : "still"; - aDownloadIDs.forEach(function (id) { - is(downloadExists(id), !aShouldBeCleared, - "download " + id + " should " + niceStr + " exist"); - }); -} - -/** - * Ensures that the specified form entries are either cleared or not. - * - * @param aFormEntries - * Array of form entry names - * @param aShouldBeCleared - * True if each form entry should be cleared, false otherwise - */ -function ensureFormEntriesClearedState(aFormEntries, aShouldBeCleared) { - let niceStr = aShouldBeCleared ? "no longer" : "still"; - aFormEntries.forEach(function (entry) { - is(formhist.nameExists(entry), !aShouldBeCleared, - "form entry " + entry + " should " + niceStr + " exist"); - }); -} - -/** - * Opens the sanitize dialog and runs a callback once it's finished loading. - * - * @param aOnloadCallback - * A function that will be called once the dialog has loaded - */ -function openWindow(aOnloadCallback) { - function windowObserver(aSubject, aTopic, aData) { - if (aTopic != "domwindowopened") - return; - - Services.ww.unregisterNotification(windowObserver); - let win = aSubject.QueryInterface(Ci.nsIDOMWindow); - win.addEventListener("load", function onload(event) { - win.removeEventListener("load", onload, false); - executeSoon(function () { - // Some exceptions that reach here don't reach the test harness, but - // ok()/is() do... - try { - Task.spawn(function() { - aOnloadCallback(win); - }).then(function() { - waitForAsyncUpdates(doNextTest); - }); - } - catch (exc) { - win.close(); - ok(false, "Unexpected exception: " + exc + "\n" + exc.stack); - finish(); - } - }); - }, false); - } - Services.ww.registerNotification(windowObserver); - Services.ww.openWindow(null, - "chrome://browser/content/sanitize.xul", - "Sanitize", - "chrome,titlebar,dialog,centerscreen,modal", - null); -} - -/** - * Creates a visit time. - * - * @param aMinutesAgo - * The visit will be visited this many minutes ago - */ -function visitTimeForMinutesAgo(aMinutesAgo) { - return now_uSec - (aMinutesAgo * 60 * 1000000); -} - -/////////////////////////////////////////////////////////////////////////////// - -function test() { - blankSlate(); - waitForExplicitFinish(); - // Kick off all the tests in the gAllTests array. - waitForAsyncUpdates(doNextTest); -} From 17634166b8482df8de52a3fadf917c0af73777ba Mon Sep 17 00:00:00 2001 From: Paolo Amadini Date: Tue, 30 Dec 2014 21:05:12 +0000 Subject: [PATCH 29/41] Bug 432425 - Remove unused test for downloads in the Clear Recent History dialog. r=gavin --- browser/base/content/test/general/browser.ini | 2 - .../browser_sanitize-download-history.js | 142 ------------------ 2 files changed, 144 deletions(-) delete mode 100644 browser/base/content/test/general/browser_sanitize-download-history.js diff --git a/browser/base/content/test/general/browser.ini b/browser/base/content/test/general/browser.ini index 1a3095cc28c..072c446204e 100644 --- a/browser/base/content/test/general/browser.ini +++ b/browser/base/content/test/general/browser.ini @@ -376,8 +376,6 @@ support-files = [browser_removeUnsafeProtocolsFromURLBarPaste.js] skip-if = e10s [browser_restore_isAppTab.js] -[browser_sanitize-download-history.js] -skip-if = true # bug 432425 [browser_sanitize-passwordDisabledHosts.js] [browser_sanitize-sitepermissions.js] [browser_sanitize-timespans.js] diff --git a/browser/base/content/test/general/browser_sanitize-download-history.js b/browser/base/content/test/general/browser_sanitize-download-history.js deleted file mode 100644 index 186b02167c8..00000000000 --- a/browser/base/content/test/general/browser_sanitize-download-history.js +++ /dev/null @@ -1,142 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - -function test() -{ - ////////////////////////////////////////////////////////////////////////////// - //// Tests (defined locally for scope's sake) - - function test_checkedAndDisabledAtStart(aWin) - { - let doc = aWin.document; - let downloads = doc.getElementById("downloads-checkbox"); - let history = doc.getElementById("history-checkbox"); - - ok(history.checked, "history checkbox is checked"); - ok(downloads.disabled, "downloads checkbox is disabled"); - ok(downloads.checked, "downloads checkbox is checked"); - } - - function test_checkedAndDisabledOnHistoryToggle(aWin) - { - let doc = aWin.document; - let downloads = doc.getElementById("downloads-checkbox"); - let history = doc.getElementById("history-checkbox"); - - EventUtils.synthesizeMouse(history, 0, 0, {}, aWin); - ok(!history.checked, "history checkbox is not checked"); - ok(downloads.disabled, "downloads checkbox is disabled"); - ok(downloads.checked, "downloads checkbox is checked"); - } - - function test_checkedAfterAddingDownload(aWin) - { - let doc = aWin.document; - let downloads = doc.getElementById("downloads-checkbox"); - let history = doc.getElementById("history-checkbox"); - - // Add download to DB - let file = Cc["@mozilla.org/file/directory_service;1"]. - getService(Ci.nsIProperties).get("TmpD", Ci.nsIFile); - file.append("sanitize-dm-test.file"); - file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666); - let testPath = Services.io.newFileURI(file).spec; - let data = { - name: "381603.patch", - source: "https://bugzilla.mozilla.org/attachment.cgi?id=266520", - target: testPath, - startTime: 1180493839859230, - endTime: 1180493839859239, - state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED, - currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0, - guid: "a1bcD23eF4g5" - }; - let db = Cc["@mozilla.org/download-manager;1"]. - getService(Ci.nsIDownloadManager).DBConnection; - let stmt = db.createStatement( - "INSERT INTO moz_downloads (name, source, target, startTime, endTime, " + - "state, currBytes, maxBytes, preferredAction, autoResume, guid) " + - "VALUES (:name, :source, :target, :startTime, :endTime, :state, " + - ":currBytes, :maxBytes, :preferredAction, :autoResume, :guid)"); - try { - for (let prop in data) - stmt.params[prop] = data[prop]; - stmt.execute(); - } - finally { - stmt.finalize(); - } - - // Toggle history to get everything to update - EventUtils.synthesizeMouse(history, 0, 0, {}, aWin); - EventUtils.synthesizeMouse(history, 0, 0, {}, aWin); - - ok(!history.checked, "history checkbox is not checked"); - ok(!downloads.disabled, "downloads checkbox is not disabled"); - ok(downloads.checked, "downloads checkbox is checked"); - } - - function test_checkedAndDisabledWithHistoryChecked(aWin) - { - let doc = aWin.document; - let downloads = doc.getElementById("downloads-checkbox"); - let history = doc.getElementById("history-checkbox"); - - EventUtils.synthesizeMouse(history, 0, 0, {}, aWin); - ok(history.checked, "history checkbox is checked"); - ok(downloads.disabled, "downloads checkbox is disabled"); - ok(downloads.checked, "downloads checkbox is checked"); - } - - let tests = [ - test_checkedAndDisabledAtStart, - test_checkedAndDisabledOnHistoryToggle, - test_checkedAfterAddingDownload, - test_checkedAndDisabledWithHistoryChecked, - ]; - - ////////////////////////////////////////////////////////////////////////////// - //// Run the tests - - let dm = Cc["@mozilla.org/download-manager;1"]. - getService(Ci.nsIDownloadManager); - let db = dm.DBConnection; - - // Empty any old downloads - db.executeSimpleSQL("DELETE FROM moz_downloads"); - - // Close the UI if necessary - let win = Services.ww.getWindowByName("Sanitize", null); - if (win && (win instanceof Ci.nsIDOMWindow)) - win.close(); - - // Start the test when the sanitize window loads - Services.ww.registerNotification(function (aSubject, aTopic, aData) { - Services.ww.unregisterNotification(arguments.callee); - aSubject.QueryInterface(Ci.nsIDOMEventTarget) - .addEventListener("DOMContentLoaded", doTest, false); - }); - - // Let the methods that run onload finish before we test - let doTest = function() setTimeout(function() { - let win = Services.ww.getWindowByName("Sanitize", null) - .QueryInterface(Ci.nsIDOMWindow); - - for (let i = 0; i < tests.length; i++) - tests[i](win); - - win.close(); - finish(); - }, 0); - - // Show the UI - Services.ww.openWindow(window, - "chrome://browser/content/sanitize.xul", - "Sanitize", - "chrome,titlebar,centerscreen", - null); - - waitForExplicitFinish(); -} From 116aa524b83c2a6c3d10e308b5e700b0db3354b8 Mon Sep 17 00:00:00 2001 From: Mark Capella Date: Tue, 30 Dec 2014 16:42:16 -0500 Subject: [PATCH 30/41] Bug 1115370 - TextSelection lost abruptly on unrelated Tab:pagehide messages, r=margaret * * * Bug 1115370 - Update SelectionHandler test for Tab:pagehide messages, r=margaret --- .../base/tests/roboextender/testSelectionHandler.html | 5 ++++- mobile/android/chrome/content/SelectionHandler.js | 10 +++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/mobile/android/base/tests/roboextender/testSelectionHandler.html b/mobile/android/base/tests/roboextender/testSelectionHandler.html index 5b6de0acade..fb2e4a36c4d 100644 --- a/mobile/android/base/tests/roboextender/testSelectionHandler.html +++ b/mobile/android/base/tests/roboextender/testSelectionHandler.html @@ -207,7 +207,10 @@ function testCloseSelection() { }).then(function() { sh.startSelection(inputNode); - sh.handleEvent({ type: "pagehide" }); + sh.handleEvent({ type: "pagehide", originalTarget: {} }); + return ok(sh.isSelectionActive(), "unrelated pagehide should not close active selection"); + }).then(function() { + sh.handleEvent({ type: "pagehide", originalTarget: document }); return ok(!sh.isSelectionActive(), "pagehide should close active selection"); }).then(function() { diff --git a/mobile/android/chrome/content/SelectionHandler.js b/mobile/android/chrome/content/SelectionHandler.js index c83cb693f44..0f900b015bc 100644 --- a/mobile/android/chrome/content/SelectionHandler.js +++ b/mobile/android/chrome/content/SelectionHandler.js @@ -222,7 +222,15 @@ var SelectionHandler = { this._positionHandlesOnChange(); break; - case "pagehide": + case "pagehide": { + // We only care about events on the selected tab. + let tab = BrowserApp.getTabForWindow(aEvent.originalTarget.defaultView); + if (tab == BrowserApp.selectedTab) { + this._closeSelection(); + } + break; + } + case "blur": this._closeSelection(); break; From a9b0fed124a7a9ae8ec175a8f2170bde5393b7ec Mon Sep 17 00:00:00 2001 From: Mark Capella Date: Tue, 30 Dec 2014 16:42:17 -0500 Subject: [PATCH 31/41] Bug 1106800 - Refactor out string constants in favor of existing Enums, r=margaret --- mobile/android/base/TextSelection.java | 16 ++++++++++------ mobile/android/base/TextSelectionHandle.java | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/mobile/android/base/TextSelection.java b/mobile/android/base/TextSelection.java index b4613c7db77..440c8ba76f4 100644 --- a/mobile/android/base/TextSelection.java +++ b/mobile/android/base/TextSelection.java @@ -110,12 +110,16 @@ class TextSelection extends Layer implements GeckoEventListener { } private TextSelectionHandle getHandle(String name) { - if (name.equals("START")) { - return mStartHandle; - } else if (name.equals("MIDDLE")) { - return mMiddleHandle; - } else { - return mEndHandle; + switch (TextSelectionHandle.HandleType.valueOf(name)) { + case START: + return mStartHandle; + case MIDDLE: + return mMiddleHandle; + case END: + return mEndHandle; + + default: + throw new IllegalArgumentException("TextSelectionHandle is invalid type."); } } diff --git a/mobile/android/base/TextSelectionHandle.java b/mobile/android/base/TextSelectionHandle.java index bd71fe005f0..2c0924cc196 100644 --- a/mobile/android/base/TextSelectionHandle.java +++ b/mobile/android/base/TextSelectionHandle.java @@ -22,7 +22,7 @@ import android.widget.RelativeLayout; class TextSelectionHandle extends ImageView implements View.OnTouchListener { private static final String LOGTAG = "GeckoTextSelectionHandle"; - private enum HandleType { START, MIDDLE, END }; + public enum HandleType { START, MIDDLE, END }; private final HandleType mHandleType; private final int mWidth; From 08c7fe5948c1a9bb16bb2b365ba4fc8a6893fe4e Mon Sep 17 00:00:00 2001 From: Mark Capella Date: Tue, 30 Dec 2014 16:42:17 -0500 Subject: [PATCH 32/41] Bug 1106800 - Rename Selection Handle Names, r=margaret --HG-- rename : mobile/android/base/resources/drawable/handle_start_level.xml => mobile/android/base/resources/drawable/handle_anchor_level.xml rename : mobile/android/base/resources/drawable/handle_end_level.xml => mobile/android/base/resources/drawable/handle_focus_level.xml --- mobile/android/base/GeckoApp.java | 6 +-- mobile/android/base/TextSelection.java | 54 +++++++++---------- mobile/android/base/TextSelectionHandle.java | 34 +++++++++--- ...tart_level.xml => handle_anchor_level.xml} | 0 ...e_end_level.xml => handle_focus_level.xml} | 0 .../layout/text_selection_handles.xml | 10 ++-- .../chrome/content/SelectionHandler.js | 20 +++---- 7 files changed, 72 insertions(+), 52 deletions(-) rename mobile/android/base/resources/drawable/{handle_start_level.xml => handle_anchor_level.xml} (100%) rename mobile/android/base/resources/drawable/{handle_end_level.xml => handle_focus_level.xml} (100%) diff --git a/mobile/android/base/GeckoApp.java b/mobile/android/base/GeckoApp.java index 339d90871c6..3c1cafb6ff7 100644 --- a/mobile/android/base/GeckoApp.java +++ b/mobile/android/base/GeckoApp.java @@ -1586,9 +1586,9 @@ public abstract class GeckoApp mPromptService = new PromptService(this); - mTextSelection = new TextSelection((TextSelectionHandle) findViewById(R.id.start_handle), - (TextSelectionHandle) findViewById(R.id.middle_handle), - (TextSelectionHandle) findViewById(R.id.end_handle), + mTextSelection = new TextSelection((TextSelectionHandle) findViewById(R.id.anchor_handle), + (TextSelectionHandle) findViewById(R.id.caret_handle), + (TextSelectionHandle) findViewById(R.id.focus_handle), EventDispatcher.getInstance(), this); diff --git a/mobile/android/base/TextSelection.java b/mobile/android/base/TextSelection.java index 440c8ba76f4..4819397c214 100644 --- a/mobile/android/base/TextSelection.java +++ b/mobile/android/base/TextSelection.java @@ -36,10 +36,10 @@ import android.view.View; class TextSelection extends Layer implements GeckoEventListener { private static final String LOGTAG = "GeckoTextSelection"; - private final TextSelectionHandle mStartHandle; - private final TextSelectionHandle mMiddleHandle; - private final TextSelectionHandle mEndHandle; - private final EventDispatcher mEventDispatcher; + private final TextSelectionHandle anchorHandle; + private final TextSelectionHandle caretHandle; + private final TextSelectionHandle focusHandle; + private final EventDispatcher eventDispatcher; private final DrawListener mDrawListener; private boolean mDraggingHandles; @@ -68,15 +68,15 @@ class TextSelection extends Layer implements GeckoEventListener { }; private ActionModeTimerTask mActionModeTimerTask; - TextSelection(TextSelectionHandle startHandle, - TextSelectionHandle middleHandle, - TextSelectionHandle endHandle, + TextSelection(TextSelectionHandle anchorHandle, + TextSelectionHandle caretHandle, + TextSelectionHandle focusHandle, EventDispatcher eventDispatcher, GeckoApp activity) { - mStartHandle = startHandle; - mMiddleHandle = middleHandle; - mEndHandle = endHandle; - mEventDispatcher = eventDispatcher; + this.anchorHandle = anchorHandle; + this.caretHandle = caretHandle; + this.focusHandle = focusHandle; + this.eventDispatcher = eventDispatcher; mDrawListener = new DrawListener() { @Override @@ -88,7 +88,7 @@ class TextSelection extends Layer implements GeckoEventListener { }; // Only register listeners if we have valid start/middle/end handles - if (mStartHandle == null || mMiddleHandle == null || mEndHandle == null) { + if (anchorHandle == null || caretHandle == null || focusHandle == null) { Log.e(LOGTAG, "Failed to initialize text selection because at least one handle is null"); } else { EventDispatcher.getInstance().registerGeckoThreadListener(this, @@ -111,12 +111,12 @@ class TextSelection extends Layer implements GeckoEventListener { private TextSelectionHandle getHandle(String name) { switch (TextSelectionHandle.HandleType.valueOf(name)) { - case START: - return mStartHandle; - case MIDDLE: - return mMiddleHandle; - case END: - return mEndHandle; + case ANCHOR: + return anchorHandle; + case CARET: + return caretHandle; + case FOCUS: + return focusHandle; default: throw new IllegalArgumentException("TextSelectionHandle is invalid type."); @@ -169,9 +169,9 @@ class TextSelection extends Layer implements GeckoEventListener { mActionModeTimerTask = new ActionModeTimerTask(); mActionModeTimer.schedule(mActionModeTimerTask, 250); - mStartHandle.setVisibility(View.GONE); - mMiddleHandle.setVisibility(View.GONE); - mEndHandle.setVisibility(View.GONE); + anchorHandle.setVisibility(View.GONE); + caretHandle.setVisibility(View.GONE); + focusHandle.setVisibility(View.GONE); } else if (event.equals("TextSelection:PositionHandles")) { final boolean rtl = message.getBoolean("rtl"); final JSONArray positions = message.getJSONArray("positions"); @@ -204,7 +204,7 @@ class TextSelection extends Layer implements GeckoEventListener { return; } - final Context context = mStartHandle.getContext(); + final Context context = anchorHandle.getContext(); if (context instanceof ActionModeCompat.Presenter) { final ActionModeCompat.Presenter presenter = (ActionModeCompat.Presenter) context; mCallback = new TextSelectionActionModeCallback(items); @@ -213,7 +213,7 @@ class TextSelection extends Layer implements GeckoEventListener { } private void endActionMode() { - Context context = mStartHandle.getContext(); + Context context = anchorHandle.getContext(); if (context instanceof ActionModeCompat.Presenter) { final ActionModeCompat.Presenter presenter = (ActionModeCompat.Presenter) context; presenter.endActionModeCompat(); @@ -242,9 +242,9 @@ class TextSelection extends Layer implements GeckoEventListener { ThreadUtils.postToUiThread(new Runnable() { @Override public void run() { - mStartHandle.repositionWithViewport(viewLeft, viewTop, viewZoom); - mMiddleHandle.repositionWithViewport(viewLeft, viewTop, viewZoom); - mEndHandle.repositionWithViewport(viewLeft, viewTop, viewZoom); + anchorHandle.repositionWithViewport(viewLeft, viewTop, viewZoom); + caretHandle.repositionWithViewport(viewLeft, viewTop, viewZoom); + focusHandle.repositionWithViewport(viewLeft, viewTop, viewZoom); } }); } @@ -280,7 +280,7 @@ class TextSelection extends Layer implements GeckoEventListener { final int actionEnum = obj.optBoolean("showAsAction") ? GeckoMenuItem.SHOW_AS_ACTION_ALWAYS : GeckoMenuItem.SHOW_AS_ACTION_NEVER; menuitem.setShowAsAction(actionEnum, R.attr.menuItemActionModeStyle); - BitmapUtils.getDrawable(mStartHandle.getContext(), obj.optString("icon"), new BitmapLoader() { + BitmapUtils.getDrawable(anchorHandle.getContext(), obj.optString("icon"), new BitmapLoader() { @Override public void onBitmapFound(Drawable d) { if (d != null) { diff --git a/mobile/android/base/TextSelectionHandle.java b/mobile/android/base/TextSelectionHandle.java index 2c0924cc196..165c4c839f8 100644 --- a/mobile/android/base/TextSelectionHandle.java +++ b/mobile/android/base/TextSelectionHandle.java @@ -19,10 +19,30 @@ import android.view.View; import android.widget.ImageView; import android.widget.RelativeLayout; +/** + * Text selection handles enable a user to change position of selected text in + * Gecko's DOM structure. + * + * A text "Selection" or nsISelection object, has start and end positions, + * referred to as Anchor and Focus objects. + * + * If the Anchor and Focus objects are at the same point, it represents a text + * selection Caret, commonly diplayed as a blinking, vertical |. + * + * Anchor and Focus objects each represent a DOM node, and character offset + * from the start of the node. The Anchor always refers to the start of the + * Selection, and the Focus refers to its end. + * + * In LTR languages such as English, the Anchor is to the left of the Focus. + * In RTL languages such as Hebrew, the Anchor is to the right of the Focus. + * + * For multi-line Selections, in both LTR and RTL languages, the Anchor starts + * above the Focus. + */ class TextSelectionHandle extends ImageView implements View.OnTouchListener { private static final String LOGTAG = "GeckoTextSelectionHandle"; - public enum HandleType { START, MIDDLE, END }; + public enum HandleType { ANCHOR, CARET, FOCUS }; private final HandleType mHandleType; private final int mWidth; @@ -51,11 +71,11 @@ class TextSelectionHandle extends ImageView implements View.OnTouchListener { int handleType = a.getInt(R.styleable.TextSelectionHandle_handleType, 0x01); if (handleType == 0x01) - mHandleType = HandleType.START; + mHandleType = HandleType.ANCHOR; else if (handleType == 0x02) - mHandleType = HandleType.MIDDLE; + mHandleType = HandleType.CARET; else - mHandleType = HandleType.END; + mHandleType = HandleType.FOCUS; mGeckoPoint = new PointF(0.0f, 0.0f); @@ -132,7 +152,7 @@ class TextSelectionHandle extends ImageView implements View.OnTouchListener { // will tell us the position of the caret, so we set the handle // position then. This allows us to lock the handle to wherever the // caret appears. - if (mHandleType != HandleType.MIDDLE) { + if (mHandleType != HandleType.CARET) { setLayoutPosition(); } } @@ -166,9 +186,9 @@ class TextSelectionHandle extends ImageView implements View.OnTouchListener { } private float adjustLeftForHandle() { - if (mHandleType == HandleType.START) { + if (mHandleType == HandleType.ANCHOR) { return mIsRTL ? mShadow : mWidth - mShadow; - } else if (mHandleType == HandleType.MIDDLE) { + } else if (mHandleType == HandleType.CARET) { return mWidth / 2; } else { return mIsRTL ? mWidth - mShadow : mShadow; diff --git a/mobile/android/base/resources/drawable/handle_start_level.xml b/mobile/android/base/resources/drawable/handle_anchor_level.xml similarity index 100% rename from mobile/android/base/resources/drawable/handle_start_level.xml rename to mobile/android/base/resources/drawable/handle_anchor_level.xml diff --git a/mobile/android/base/resources/drawable/handle_end_level.xml b/mobile/android/base/resources/drawable/handle_focus_level.xml similarity index 100% rename from mobile/android/base/resources/drawable/handle_end_level.xml rename to mobile/android/base/resources/drawable/handle_focus_level.xml diff --git a/mobile/android/base/resources/layout/text_selection_handles.xml b/mobile/android/base/resources/layout/text_selection_handles.xml index c31cfa05567..c8343dcb74f 100644 --- a/mobile/android/base/resources/layout/text_selection_handles.xml +++ b/mobile/android/base/resources/layout/text_selection_handles.xml @@ -6,24 +6,24 @@ - - - diff --git a/mobile/android/chrome/content/SelectionHandler.js b/mobile/android/chrome/content/SelectionHandler.js index 0f900b015bc..314e9d46c4c 100644 --- a/mobile/android/chrome/content/SelectionHandler.js +++ b/mobile/android/chrome/content/SelectionHandler.js @@ -8,9 +8,9 @@ const PHONE_NUMBER_CONTAINERS = "td,div"; var SelectionHandler = { - HANDLE_TYPE_START: "START", - HANDLE_TYPE_MIDDLE: "MIDDLE", - HANDLE_TYPE_END: "END", + HANDLE_TYPE_ANCHOR: "ANCHOR", + HANDLE_TYPE_CARET: "CARET", + HANDLE_TYPE_FOCUS: "FOCUS", TYPE_NONE: 0, TYPE_CURSOR: 1, @@ -133,7 +133,7 @@ var SelectionHandler = { let data = JSON.parse(aData); if (this._activeType == this.TYPE_SELECTION) { this._startDraggingHandles(); - this._moveSelection(data.handleType == this.HANDLE_TYPE_START, data.x, data.y); + this._moveSelection(data.handleType == this.HANDLE_TYPE_ANCHOR, data.x, data.y); } else if (this._activeType == this.TYPE_CURSOR) { this._startDraggingHandles(); @@ -152,7 +152,7 @@ var SelectionHandler = { this._startDraggingHandles(); // Check to see if the handles should be reversed. - let isStartHandle = JSON.parse(aData).handleType == this.HANDLE_TYPE_START; + let isStartHandle = JSON.parse(aData).handleType == this.HANDLE_TYPE_ANCHOR; try { let selectionReversed = this._updateCacheForSelection(isStartHandle); if (selectionReversed) { @@ -345,7 +345,7 @@ var SelectionHandler = { this._positionHandles(positions); Messaging.sendRequest({ type: "TextSelection:ShowHandles", - handles: [this.HANDLE_TYPE_START, this.HANDLE_TYPE_END] + handles: [this.HANDLE_TYPE_ANCHOR, this.HANDLE_TYPE_FOCUS] }); this._updateMenu(); return true; @@ -724,7 +724,7 @@ var SelectionHandler = { this._positionHandles(); Messaging.sendRequest({ type: "TextSelection:ShowHandles", - handles: [this.HANDLE_TYPE_MIDDLE] + handles: [this.HANDLE_TYPE_CARET] }); this._updateMenu(); @@ -1097,7 +1097,7 @@ var SelectionHandler = { // divide by the pixel ratio let x = cursor.left / window.devicePixelRatio; let y = (cursor.top + cursor.height) / window.devicePixelRatio; - return [{ handle: this.HANDLE_TYPE_MIDDLE, + return [{ handle: this.HANDLE_TYPE_CARET, left: x + scroll.X, top: y + scroll.Y, hidden: checkHidden(x, y) }]; @@ -1111,11 +1111,11 @@ var SelectionHandler = { // this because the top-level page may have scrolled since selection started. let offset = this._getViewOffset(); - return [{ handle: this.HANDLE_TYPE_START, + return [{ handle: this.HANDLE_TYPE_ANCHOR, left: sx + offset.x + scroll.X, top: sy + offset.y + scroll.Y, hidden: checkHidden(sx, sy) }, - { handle: this.HANDLE_TYPE_END, + { handle: this.HANDLE_TYPE_FOCUS, left: ex + offset.x + scroll.X, top: ey + offset.y + scroll.Y, hidden: checkHidden(ex, ey) }]; From 5b0331e5e6f39cdb4d8da3c80c37668b5afd4fe3 Mon Sep 17 00:00:00 2001 From: Mark Capella Date: Tue, 30 Dec 2014 16:42:17 -0500 Subject: [PATCH 33/41] Bug 1106800 - Rename Selection Cache Handle Names, r=margaret --- .../chrome/content/SelectionHandler.js | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/mobile/android/chrome/content/SelectionHandler.js b/mobile/android/chrome/content/SelectionHandler.js index 314e9d46c4c..ef7d7420dc5 100644 --- a/mobile/android/chrome/content/SelectionHandler.js +++ b/mobile/android/chrome/content/SelectionHandler.js @@ -327,7 +327,7 @@ var SelectionHandler = { this._activeType = this.TYPE_SELECTION; // Initialize the cache - this._cache = { start: {}, end: {}}; + this._cache = { anchorPt: {}, focusPt: {}}; this._updateCacheForSelection(); let scroll = this._getScrollPos(); @@ -851,11 +851,11 @@ var SelectionHandler = { // Update the cache as the handle is dragged (keep the cache in client coordinates). if (aIsStartHandle) { - this._cache.start.x = aX; - this._cache.start.y = aY; + this._cache.anchorPt.x = aX; + this._cache.anchorPt.y = aY; } else { - this._cache.end.x = aX; - this._cache.end.y = aY; + this._cache.focusPt.x = aX; + this._cache.focusPt.y = aY; } let selection = this._getSelection(); @@ -864,7 +864,7 @@ var SelectionHandler = { // are reversed, so we need to reverse the logic to extend the selection. if ((aIsStartHandle && !this._isRTL) || (!aIsStartHandle && this._isRTL)) { if (targetIsEditable) { - let anchorX = this._isRTL ? this._cache.start.x : this._cache.end.x; + let anchorX = this._isRTL ? this._cache.anchorPt.x : this._cache.focusPt.x; this._moveSelectionInEditable(anchorX, aX, caretPos); } else { let focusNode = selection.focusNode; @@ -874,7 +874,7 @@ var SelectionHandler = { } } else { if (targetIsEditable) { - let anchorX = this._isRTL ? this._cache.end.x : this._cache.start.x; + let anchorX = this._isRTL ? this._cache.focusPt.x : this._cache.anchorPt.x; this._moveSelectionInEditable(anchorX, aX, caretPos); } else { selection.extend(caretPos.offsetNode, caretPos.offset); @@ -1060,14 +1060,14 @@ var SelectionHandler = { let end = { x: this._isRTL ? rects[rects.length - 1].left : rects[rects.length - 1].right, y: rects[rects.length - 1].bottom }; let selectionReversed = false; - if (this._cache.start) { + if (this._cache.anchorPt) { // If the end moved past the old end, but we're dragging the start handle, then that handle should become the end handle (and vice versa) - selectionReversed = (aIsStartHandle && (end.y > this._cache.end.y || (end.y == this._cache.end.y && end.x > this._cache.end.x))) || - (!aIsStartHandle && (start.y < this._cache.start.y || (start.y == this._cache.start.y && start.x < this._cache.start.x))); + selectionReversed = (aIsStartHandle && (end.y > this._cache.focusPt.y || (end.y == this._cache.focusPt.y && end.x > this._cache.focusPt.x))) || + (!aIsStartHandle && (start.y < this._cache.anchorPt.y || (start.y == this._cache.anchorPt.y && start.x < this._cache.anchorPt.x))); } - this._cache.start = start; - this._cache.end = end; + this._cache.anchorPt = start; + this._cache.focusPt = end; return selectionReversed; }, @@ -1102,23 +1102,23 @@ var SelectionHandler = { top: y + scroll.Y, hidden: checkHidden(x, y) }]; } else { - let sx = this._cache.start.x; - let sy = this._cache.start.y; - let ex = this._cache.end.x; - let ey = this._cache.end.y; + let anchorX = this._cache.anchorPt.x; + let anchorY = this._cache.anchorPt.y; + let focusX = this._cache.focusPt.x; + let focusY = this._cache.focusPt.y; // Translate coordinates to account for selections in sub-frames. We can't cache // this because the top-level page may have scrolled since selection started. let offset = this._getViewOffset(); return [{ handle: this.HANDLE_TYPE_ANCHOR, - left: sx + offset.x + scroll.X, - top: sy + offset.y + scroll.Y, - hidden: checkHidden(sx, sy) }, + left: anchorX + offset.x + scroll.X, + top: anchorY + offset.y + scroll.Y, + hidden: checkHidden(anchorX, anchorY) }, { handle: this.HANDLE_TYPE_FOCUS, - left: ex + offset.x + scroll.X, - top: ey + offset.y + scroll.Y, - hidden: checkHidden(ex, ey) }]; + left: focusX + offset.x + scroll.X, + top: focusY + offset.y + scroll.Y, + hidden: checkHidden(focusX, focusY) }]; } }, From 8e9731d8d6fa32ddf35927450fac39a0fb4484c1 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 31 Dec 2014 15:44:00 +1300 Subject: [PATCH 34/41] Bug 1109644. Fix bustage on a CLOSED TREE --- dom/media/webrtc/MediaEngineGonkVideoSource.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dom/media/webrtc/MediaEngineGonkVideoSource.cpp b/dom/media/webrtc/MediaEngineGonkVideoSource.cpp index b204f19858f..dbc2a390def 100644 --- a/dom/media/webrtc/MediaEngineGonkVideoSource.cpp +++ b/dom/media/webrtc/MediaEngineGonkVideoSource.cpp @@ -101,9 +101,7 @@ MediaEngineGonkVideoSource::NotifyPull(MediaStreamGraph* aGraph, segment.AppendFrame(image.forget(), delta, size); // This can fail if either a) we haven't added the track yet, or b) // we've removed or finished the track. - if (aSource->AppendToTrack(aID, &(segment))) { - aLastEndTime = aDesiredTime; - } + aSource->AppendToTrack(aID, &(segment)); } } From 5cc5a1f24c2e74c1488d987d9dfb334fa0628cab Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Tue, 30 Dec 2014 20:04:20 -0800 Subject: [PATCH 35/41] Back out 9 changesets (bug 649142) Backed out changeset 936703c75200 (bug 649142) Backed out changeset b0252d2620d8 (bug 649142) Backed out changeset 69ddb2036c50 (bug 649142) Backed out changeset 67748675e669 (bug 649142) Backed out changeset 15ed55c61f4e (bug 649142) Backed out changeset 35c42cd138e1 (bug 649142) Backed out changeset 1335630cf287 (bug 649142) Backed out changeset b5725cd39a31 (bug 649142) Backed out changeset b0eb691d6695 (bug 649142) --- browser/devtools/layoutview/view.js | 16 +- dom/base/nsDOMWindowUtils.cpp | 10 +- dom/html/HTMLBodyElement.cpp | 12 +- dom/html/HTMLHRElement.cpp | 12 +- dom/html/HTMLIFrameElement.cpp | 4 +- dom/html/HTMLTableElement.cpp | 20 +- dom/html/nsGenericHTMLElement.cpp | 16 +- dom/webidl/CSS2PropertiesProps.h | 2 - layout/inspector/inDOMUtils.cpp | 2 +- layout/inspector/tests/test_bug1006595.html | 6 +- layout/style/Declaration.cpp | 38 +- layout/style/StyleAnimationValue.cpp | 14 +- layout/style/nsCSSDataBlock.cpp | 77 +- layout/style/nsCSSParser.cpp | 243 ++++- layout/style/nsCSSPropAliasList.h | 48 - layout/style/nsCSSPropList.h | 869 ++++++++++++------ layout/style/nsCSSProperty.h | 2 - layout/style/nsCSSProps.cpp | 369 ++++++-- layout/style/nsCSSProps.h | 17 +- layout/style/nsComputedDOMStyle.cpp | 4 - layout/style/nsDOMCSSDeclaration.h | 2 - layout/style/nsRuleData.h | 4 +- layout/style/nsRuleNode.cpp | 206 ++++- layout/style/nsRuleNode.h | 9 + layout/style/nsStyleConsts.h | 4 + layout/style/nsStyleContext.cpp | 4 +- layout/style/nsTransitionManager.cpp | 4 + layout/style/test/ListCSSProperties.cpp | 44 +- .../test/css_properties_like_longhand.js | 8 + layout/style/test/mochitest.ini | 1 - layout/style/test/property_database.js | 254 +---- .../style/test/test_logical_properties.html | 273 ------ layout/style/test/test_page_parser.html | 30 +- layout/style/test/test_property_database.html | 11 - layout/style/test/test_value_computation.html | 15 +- 35 files changed, 1551 insertions(+), 1099 deletions(-) delete mode 100644 layout/style/test/test_logical_properties.html diff --git a/browser/devtools/layoutview/view.js b/browser/devtools/layoutview/view.js index 36584e63e00..b1ea551f0bf 100644 --- a/browser/devtools/layoutview/view.js +++ b/browser/devtools/layoutview/view.js @@ -174,11 +174,17 @@ LayoutView.prototype = { marginBottom: {selector: ".margin.bottom > span", property: "margin-bottom", value: undefined}, + // margin-left is a shorthand for some internal properties, + // margin-left-ltr-source and margin-left-rtl-source for example. The + // real margin value we want is in margin-left-value marginLeft: {selector: ".margin.left > span", property: "margin-left", + realProperty: "margin-left-value", value: undefined}, + // margin-right behaves the same as margin-left marginRight: {selector: ".margin.right > span", property: "margin-right", + realProperty: "margin-right-value", value: undefined}, paddingTop: {selector: ".padding.top > span", property: "padding-top", @@ -186,11 +192,15 @@ LayoutView.prototype = { paddingBottom: {selector: ".padding.bottom > span", property: "padding-bottom", value: undefined}, + // padding-left behaves the same as margin-left paddingLeft: {selector: ".padding.left > span", property: "padding-left", + realProperty: "padding-left-value", value: undefined}, + // padding-right behaves the same as margin-left paddingRight: {selector: ".padding.right > span", property: "padding-right", + realProperty: "padding-right-value", value: undefined}, borderTop: {selector: ".border.top > span", property: "border-top-width", @@ -255,9 +265,11 @@ LayoutView.prototype = { * Called when the user clicks on one of the editable values in the layoutview */ initEditor: function(element, event, dimension) { - let { property } = dimension; + let { property, realProperty } = dimension; + if (!realProperty) + realProperty = property; let session = new EditingSession(document, this.elementRules); - let initialValue = session.getProperty(property); + let initialValue = session.getProperty(realProperty); let editor = new InplaceEditor({ element: element, diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 7429662d406..db387831c0a 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -2754,10 +2754,18 @@ nsDOMWindowUtils::ComputeAnimationDistance(nsIDOMElement* aElement, nsCOMPtr content = do_QueryInterface(aElement, &rv); NS_ENSURE_SUCCESS(rv, rv); + // Convert direction-dependent properties as appropriate, e.g., + // border-left to border-left-value. nsCSSProperty property = nsCSSProps::LookupProperty(aProperty, nsCSSProps::eIgnoreEnabledState); if (property != eCSSProperty_UNKNOWN && nsCSSProps::IsShorthand(property)) { - property = eCSSProperty_UNKNOWN; + nsCSSProperty subprop0 = *nsCSSProps::SubpropertyEntryFor(property); + if (nsCSSProps::PropHasFlags(subprop0, CSS_PROPERTY_REPORT_OTHER_NAME) && + nsCSSProps::OtherNameFor(subprop0) == property) { + property = subprop0; + } else { + property = eCSSProperty_UNKNOWN; + } } NS_ABORT_IF_FALSE(property == eCSSProperty_UNKNOWN || diff --git a/dom/html/HTMLBodyElement.cpp b/dom/html/HTMLBodyElement.cpp index f62217beb98..191db08d75f 100644 --- a/dom/html/HTMLBodyElement.cpp +++ b/dom/html/HTMLBodyElement.cpp @@ -62,10 +62,10 @@ BodyRule::MapRuleInfoInto(nsRuleData* aData) if (value && value->Type() == nsAttrValue::eInteger) { bodyMarginWidth = value->GetIntegerValue(); if (bodyMarginWidth < 0) bodyMarginWidth = 0; - nsCSSValue* marginLeft = aData->ValueForMarginLeft(); + nsCSSValue* marginLeft = aData->ValueForMarginLeftValue(); if (marginLeft->GetUnit() == eCSSUnit_Null) marginLeft->SetFloatValue((float)bodyMarginWidth, eCSSUnit_Pixel); - nsCSSValue* marginRight = aData->ValueForMarginRight(); + nsCSSValue* marginRight = aData->ValueForMarginRightValue(); if (marginRight->GetUnit() == eCSSUnit_Null) marginRight->SetFloatValue((float)bodyMarginWidth, eCSSUnit_Pixel); } @@ -107,7 +107,7 @@ BodyRule::MapRuleInfoInto(nsRuleData* aData) if (value && value->Type() == nsAttrValue::eInteger) { bodyLeftMargin = value->GetIntegerValue(); if (bodyLeftMargin < 0) bodyLeftMargin = 0; - nsCSSValue* marginLeft = aData->ValueForMarginLeft(); + nsCSSValue* marginLeft = aData->ValueForMarginLeftValue(); if (marginLeft->GetUnit() == eCSSUnit_Null) marginLeft->SetFloatValue((float)bodyLeftMargin, eCSSUnit_Pixel); } @@ -117,7 +117,7 @@ BodyRule::MapRuleInfoInto(nsRuleData* aData) if (value && value->Type() == nsAttrValue::eInteger) { bodyRightMargin = value->GetIntegerValue(); if (bodyRightMargin < 0) bodyRightMargin = 0; - nsCSSValue* marginRight = aData->ValueForMarginRight(); + nsCSSValue* marginRight = aData->ValueForMarginRightValue(); if (marginRight->GetUnit() == eCSSUnit_Null) marginRight->SetFloatValue((float)bodyRightMargin, eCSSUnit_Pixel); } @@ -147,10 +147,10 @@ BodyRule::MapRuleInfoInto(nsRuleData* aData) } if ((bodyMarginWidth == -1) && (frameMarginWidth >= 0)) { - nsCSSValue* marginLeft = aData->ValueForMarginLeft(); + nsCSSValue* marginLeft = aData->ValueForMarginLeftValue(); if (marginLeft->GetUnit() == eCSSUnit_Null) marginLeft->SetFloatValue((float)frameMarginWidth, eCSSUnit_Pixel); - nsCSSValue* marginRight = aData->ValueForMarginRight(); + nsCSSValue* marginRight = aData->ValueForMarginRightValue(); if (marginRight->GetUnit() == eCSSUnit_Null) marginRight->SetFloatValue((float)frameMarginWidth, eCSSUnit_Pixel); } diff --git a/dom/html/HTMLHRElement.cpp b/dom/html/HTMLHRElement.cpp index 9257a3c9b8b..42670386940 100644 --- a/dom/html/HTMLHRElement.cpp +++ b/dom/html/HTMLHRElement.cpp @@ -88,8 +88,8 @@ HTMLHRElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes, const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align); if (value && value->Type() == nsAttrValue::eEnum) { // Map align attribute into auto side margins - nsCSSValue* marginLeft = aData->ValueForMarginLeft(); - nsCSSValue* marginRight = aData->ValueForMarginRight(); + nsCSSValue* marginLeft = aData->ValueForMarginLeftValue(); + nsCSSValue* marginRight = aData->ValueForMarginRightValue(); switch (value->GetEnumValue()) { case NS_STYLE_TEXT_ALIGN_LEFT: if (marginLeft->GetUnit() == eCSSUnit_Null) @@ -165,7 +165,7 @@ HTMLHRElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes, borderTopWidth->SetFloatValue(sizePerSide, eCSSUnit_Pixel); } if (allSides) { - nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidth(); + nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidthValue(); if (borderRightWidth->GetUnit() == eCSSUnit_Null) { borderRightWidth->SetFloatValue(sizePerSide, eCSSUnit_Pixel); } @@ -173,7 +173,7 @@ HTMLHRElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes, if (borderBottomWidth->GetUnit() == eCSSUnit_Null) { borderBottomWidth->SetFloatValue(sizePerSide, eCSSUnit_Pixel); } - nsCSSValue* borderLeftWidth = aData->ValueForBorderLeftWidth(); + nsCSSValue* borderLeftWidth = aData->ValueForBorderLeftWidthValue(); if (borderLeftWidth->GetUnit() == eCSSUnit_Null) { borderLeftWidth->SetFloatValue(sizePerSide, eCSSUnit_Pixel); } @@ -185,7 +185,7 @@ HTMLHRElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes, eCSSUnit_Enumerated); } if (allSides) { - nsCSSValue* borderRightStyle = aData->ValueForBorderRightStyle(); + nsCSSValue* borderRightStyle = aData->ValueForBorderRightStyleValue(); if (borderRightStyle->GetUnit() == eCSSUnit_Null) { borderRightStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID, eCSSUnit_Enumerated); @@ -195,7 +195,7 @@ HTMLHRElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes, borderBottomStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID, eCSSUnit_Enumerated); } - nsCSSValue* borderLeftStyle = aData->ValueForBorderLeftStyle(); + nsCSSValue* borderLeftStyle = aData->ValueForBorderLeftStyleValue(); if (borderLeftStyle->GetUnit() == eCSSUnit_Null) { borderLeftStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID, eCSSUnit_Enumerated); diff --git a/dom/html/HTMLIFrameElement.cpp b/dom/html/HTMLIFrameElement.cpp index 60f200d695f..030200dc666 100644 --- a/dom/html/HTMLIFrameElement.cpp +++ b/dom/html/HTMLIFrameElement.cpp @@ -121,10 +121,10 @@ HTMLIFrameElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes, if (NS_STYLE_FRAME_0 == frameborder || NS_STYLE_FRAME_NO == frameborder || NS_STYLE_FRAME_OFF == frameborder) { - nsCSSValue* borderLeftWidth = aData->ValueForBorderLeftWidth(); + nsCSSValue* borderLeftWidth = aData->ValueForBorderLeftWidthValue(); if (borderLeftWidth->GetUnit() == eCSSUnit_Null) borderLeftWidth->SetFloatValue(0.0f, eCSSUnit_Pixel); - nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidth(); + nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidthValue(); if (borderRightWidth->GetUnit() == eCSSUnit_Null) borderRightWidth->SetFloatValue(0.0f, eCSSUnit_Pixel); nsCSSValue* borderTopWidth = aData->ValueForBorderTopWidth(); diff --git a/dom/html/HTMLTableElement.cpp b/dom/html/HTMLTableElement.cpp index 29dd6e95b9b..18cd16f5f63 100644 --- a/dom/html/HTMLTableElement.cpp +++ b/dom/html/HTMLTableElement.cpp @@ -705,10 +705,10 @@ HTMLTableElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes, if (value && value->Type() == nsAttrValue::eEnum) { if (value->GetEnumValue() == NS_STYLE_TEXT_ALIGN_CENTER || value->GetEnumValue() == NS_STYLE_TEXT_ALIGN_MOZ_CENTER) { - nsCSSValue* marginLeft = aData->ValueForMarginLeft(); + nsCSSValue* marginLeft = aData->ValueForMarginLeftValue(); if (marginLeft->GetUnit() == eCSSUnit_Null) marginLeft->SetAutoValue(); - nsCSSValue* marginRight = aData->ValueForMarginRight(); + nsCSSValue* marginRight = aData->ValueForMarginRightValue(); if (marginRight->GetUnit() == eCSSUnit_Null) marginRight->SetAutoValue(); } @@ -721,10 +721,10 @@ HTMLTableElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes, value = aAttributes->GetAttr(nsGkAtoms::hspace); if (value && value->Type() == nsAttrValue::eInteger) { - nsCSSValue* marginLeft = aData->ValueForMarginLeft(); + nsCSSValue* marginLeft = aData->ValueForMarginLeftValue(); if (marginLeft->GetUnit() == eCSSUnit_Null) marginLeft->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel); - nsCSSValue* marginRight = aData->ValueForMarginRight(); + nsCSSValue* marginRight = aData->ValueForMarginRightValue(); if (marginRight->GetUnit() == eCSSUnit_Null) marginRight->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel); } @@ -768,10 +768,10 @@ HTMLTableElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes, nscolor color; if (value && presContext->UseDocumentColors() && value->GetColorValue(color)) { - nsCSSValue* borderLeftColor = aData->ValueForBorderLeftColor(); + nsCSSValue* borderLeftColor = aData->ValueForBorderLeftColorValue(); if (borderLeftColor->GetUnit() == eCSSUnit_Null) borderLeftColor->SetColorValue(color); - nsCSSValue* borderRightColor = aData->ValueForBorderRightColor(); + nsCSSValue* borderRightColor = aData->ValueForBorderRightColorValue(); if (borderRightColor->GetUnit() == eCSSUnit_Null) borderRightColor->SetColorValue(color); nsCSSValue* borderTopColor = aData->ValueForBorderTopColor(); @@ -792,10 +792,10 @@ HTMLTableElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes, borderThickness = borderValue->GetIntegerValue(); // by default, set all border sides to the specified width - nsCSSValue* borderLeftWidth = aData->ValueForBorderLeftWidth(); + nsCSSValue* borderLeftWidth = aData->ValueForBorderLeftWidthValue(); if (borderLeftWidth->GetUnit() == eCSSUnit_Null) borderLeftWidth->SetFloatValue((float)borderThickness, eCSSUnit_Pixel); - nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidth(); + nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidthValue(); if (borderRightWidth->GetUnit() == eCSSUnit_Null) borderRightWidth->SetFloatValue((float)borderThickness, eCSSUnit_Pixel); nsCSSValue* borderTopWidth = aData->ValueForBorderTopWidth(); @@ -854,12 +854,12 @@ MapInheritedTableAttributesIntoRule(const nsMappedAttributes* aAttributes, // don't have any set. nsCSSValue padVal(float(value->GetIntegerValue()), eCSSUnit_Pixel); - nsCSSValue* paddingLeft = aData->ValueForPaddingLeft(); + nsCSSValue* paddingLeft = aData->ValueForPaddingLeftValue(); if (paddingLeft->GetUnit() == eCSSUnit_Null) { *paddingLeft = padVal; } - nsCSSValue* paddingRight = aData->ValueForPaddingRight(); + nsCSSValue* paddingRight = aData->ValueForPaddingRightValue(); if (paddingRight->GetUnit() == eCSSUnit_Null) { *paddingRight = padVal; } diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp index d3d40fdc6cc..0d5cf78873d 100644 --- a/dom/html/nsGenericHTMLElement.cpp +++ b/dom/html/nsGenericHTMLElement.cpp @@ -1444,10 +1444,10 @@ nsGenericHTMLElement::MapImageMarginAttributeInto(const nsMappedAttributes* aAtt hval.SetPercentValue(value->GetPercentValue()); if (hval.GetUnit() != eCSSUnit_Null) { - nsCSSValue* left = aData->ValueForMarginLeft(); + nsCSSValue* left = aData->ValueForMarginLeftValue(); if (left->GetUnit() == eCSSUnit_Null) *left = hval; - nsCSSValue* right = aData->ValueForMarginRight(); + nsCSSValue* right = aData->ValueForMarginRightValue(); if (right->GetUnit() == eCSSUnit_Null) *right = hval; } @@ -1517,39 +1517,39 @@ nsGenericHTMLElement::MapImageBorderAttributeInto(const nsMappedAttributes* aAtt if (value->Type() == nsAttrValue::eInteger) val = value->GetIntegerValue(); - nsCSSValue* borderLeftWidth = aData->ValueForBorderLeftWidth(); + nsCSSValue* borderLeftWidth = aData->ValueForBorderLeftWidthValue(); if (borderLeftWidth->GetUnit() == eCSSUnit_Null) borderLeftWidth->SetFloatValue((float)val, eCSSUnit_Pixel); nsCSSValue* borderTopWidth = aData->ValueForBorderTopWidth(); if (borderTopWidth->GetUnit() == eCSSUnit_Null) borderTopWidth->SetFloatValue((float)val, eCSSUnit_Pixel); - nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidth(); + nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidthValue(); if (borderRightWidth->GetUnit() == eCSSUnit_Null) borderRightWidth->SetFloatValue((float)val, eCSSUnit_Pixel); nsCSSValue* borderBottomWidth = aData->ValueForBorderBottomWidth(); if (borderBottomWidth->GetUnit() == eCSSUnit_Null) borderBottomWidth->SetFloatValue((float)val, eCSSUnit_Pixel); - nsCSSValue* borderLeftStyle = aData->ValueForBorderLeftStyle(); + nsCSSValue* borderLeftStyle = aData->ValueForBorderLeftStyleValue(); if (borderLeftStyle->GetUnit() == eCSSUnit_Null) borderLeftStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID, eCSSUnit_Enumerated); nsCSSValue* borderTopStyle = aData->ValueForBorderTopStyle(); if (borderTopStyle->GetUnit() == eCSSUnit_Null) borderTopStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID, eCSSUnit_Enumerated); - nsCSSValue* borderRightStyle = aData->ValueForBorderRightStyle(); + nsCSSValue* borderRightStyle = aData->ValueForBorderRightStyleValue(); if (borderRightStyle->GetUnit() == eCSSUnit_Null) borderRightStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID, eCSSUnit_Enumerated); nsCSSValue* borderBottomStyle = aData->ValueForBorderBottomStyle(); if (borderBottomStyle->GetUnit() == eCSSUnit_Null) borderBottomStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID, eCSSUnit_Enumerated); - nsCSSValue* borderLeftColor = aData->ValueForBorderLeftColor(); + nsCSSValue* borderLeftColor = aData->ValueForBorderLeftColorValue(); if (borderLeftColor->GetUnit() == eCSSUnit_Null) borderLeftColor->SetIntValue(NS_STYLE_COLOR_MOZ_USE_TEXT_COLOR, eCSSUnit_Enumerated); nsCSSValue* borderTopColor = aData->ValueForBorderTopColor(); if (borderTopColor->GetUnit() == eCSSUnit_Null) borderTopColor->SetIntValue(NS_STYLE_COLOR_MOZ_USE_TEXT_COLOR, eCSSUnit_Enumerated); - nsCSSValue* borderRightColor = aData->ValueForBorderRightColor(); + nsCSSValue* borderRightColor = aData->ValueForBorderRightColorValue(); if (borderRightColor->GetUnit() == eCSSUnit_Null) borderRightColor->SetIntValue(NS_STYLE_COLOR_MOZ_USE_TEXT_COLOR, eCSSUnit_Enumerated); nsCSSValue* borderBottomColor = aData->ValueForBorderBottomColor(); diff --git a/dom/webidl/CSS2PropertiesProps.h b/dom/webidl/CSS2PropertiesProps.h index 978dfd45c18..f0dd534bcc2 100644 --- a/dom/webidl/CSS2PropertiesProps.h +++ b/dom/webidl/CSS2PropertiesProps.h @@ -17,11 +17,9 @@ DO_PROP(name, method, id, flags, pref) #define CSS_PROP_PUBLIC_OR_PRIVATE(publicname_, privatename_) publicname_ #define CSS_PROP_LIST_EXCLUDE_INTERNAL -#define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" -#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP_LIST_EXCLUDE_INTERNAL #undef CSS_PROP_PUBLIC_OR_PRIVATE #undef CSS_PROP_SHORTHAND diff --git a/layout/inspector/inDOMUtils.cpp b/layout/inspector/inDOMUtils.cpp index 3a5a608924f..11e959a5b24 100644 --- a/layout/inspector/inDOMUtils.cpp +++ b/layout/inspector/inDOMUtils.cpp @@ -522,7 +522,7 @@ static void GetKeywordsForProperty(const nsCSSProperty aProperty, } const nsCSSProps::KTableValue *keywordTable = nsCSSProps::kKeywordTableTable[aProperty]; - if (keywordTable) { + if (keywordTable && keywordTable != nsCSSProps::kBoxPropSourceKTable) { size_t i = 0; while (nsCSSKeyword(keywordTable[i]) != eCSSKeyword_UNKNOWN) { nsCSSKeyword word = nsCSSKeyword(keywordTable[i]); diff --git a/layout/inspector/tests/test_bug1006595.html b/layout/inspector/tests/test_bug1006595.html index 0ad713858e4..2e9e237adc6 100644 --- a/layout/inspector/tests/test_bug1006595.html +++ b/layout/inspector/tests/test_bug1006595.html @@ -23,9 +23,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1006595 var paddingSubProps = utils.getSubpropertiesForCSSProperty("padding"); arraysEqual(paddingSubProps, [ "padding-top", - "padding-right", + "padding-right-value", "padding-bottom", - "padding-left" ], + "padding-left-value", + "padding-left-ltr-source", "padding-left-rtl-source", + "padding-right-ltr-source", "padding-right-rtl-source" ], "'padding' subproperties"); var displaySubProps = utils.getSubpropertiesForCSSProperty("color"); diff --git a/layout/style/Declaration.cpp b/layout/style/Declaration.cpp index 847dfd2b0e6..3685b7a8da0 100644 --- a/layout/style/Declaration.cpp +++ b/layout/style/Declaration.cpp @@ -169,8 +169,9 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue, initialCount = 0, inheritCount = 0, unsetCount = 0, matchingTokenStreamCount = 0, nonMatchingTokenStreamCount = 0; CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p, aProperty) { - if (*p == eCSSProperty__x_system_font) { - // The system-font subproperty doesn't count. + if (*p == eCSSProperty__x_system_font || + nsCSSProps::PropHasFlags(*p, CSS_PROPERTY_DIRECTIONAL_SOURCE)) { + // The system-font subproperty and the *-source properties don't count. continue; } ++totalCount; @@ -348,6 +349,8 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue, for (const nsCSSProperty** subprops = subproptables, **subprops_end = ArrayEnd(subproptables); subprops < subprops_end; ++subprops) { + // Check only the first four subprops in each table, since the + // others are extras for dimensional box properties. const nsCSSValue *firstSide = data->ValueFor((*subprops)[0]); for (int32_t side = 1; side < 4; ++side) { const nsCSSValue *otherSide = @@ -374,7 +377,9 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue, const nsCSSProperty* subprops = nsCSSProps::SubpropertyEntryFor(aProperty); NS_ABORT_IF_FALSE(StringEndsWith(nsCSSProps::GetStringValue(subprops[2]), - NS_LITERAL_CSTRING("-color")), + NS_LITERAL_CSTRING("-color")) || + StringEndsWith(nsCSSProps::GetStringValue(subprops[2]), + NS_LITERAL_CSTRING("-color-value")), "third subprop must be the color property"); const nsCSSValue *colorValue = data->ValueFor(subprops[2]); bool isMozUseTextColor = @@ -391,6 +396,33 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue, } break; } + case eCSSProperty_margin_left: + case eCSSProperty_margin_right: + case eCSSProperty_margin_start: + case eCSSProperty_margin_end: + case eCSSProperty_padding_left: + case eCSSProperty_padding_right: + case eCSSProperty_padding_start: + case eCSSProperty_padding_end: + case eCSSProperty_border_left_color: + case eCSSProperty_border_left_style: + case eCSSProperty_border_left_width: + case eCSSProperty_border_right_color: + case eCSSProperty_border_right_style: + case eCSSProperty_border_right_width: + case eCSSProperty_border_start_color: + case eCSSProperty_border_start_style: + case eCSSProperty_border_start_width: + case eCSSProperty_border_end_color: + case eCSSProperty_border_end_style: + case eCSSProperty_border_end_width: { + const nsCSSProperty* subprops = + nsCSSProps::SubpropertyEntryFor(aProperty); + NS_ABORT_IF_FALSE(subprops[3] == eCSSProperty_UNKNOWN, + "not box property with physical vs. logical cascading"); + AppendValueToString(subprops[0], aValue, aSerialization); + break; + } case eCSSProperty_background: { // We know from above that all subproperties were specified. // However, we still can't represent that in the shorthand unless diff --git a/layout/style/StyleAnimationValue.cpp b/layout/style/StyleAnimationValue.cpp index 796d2d4cc50..d06f844be3d 100644 --- a/layout/style/StyleAnimationValue.cpp +++ b/layout/style/StyleAnimationValue.cpp @@ -2539,9 +2539,13 @@ StyleAnimationValue::ComputeValue(nsCSSProperty aProperty, "we should only be able to actively animate nodes that " "are in a document"); + nsCSSProperty propToParse = + nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_REPORT_OTHER_NAME) + ? nsCSSProps::OtherNameFor(aProperty) : aProperty; + // Parse specified value into a temporary css::StyleRule nsRefPtr styleRule = - BuildStyleRule(aProperty, aTargetElement, aSpecifiedValue, aUseSVGMode); + BuildStyleRule(propToParse, aTargetElement, aSpecifiedValue, aUseSVGMode); if (!styleRule) { return false; } @@ -2923,8 +2927,8 @@ StyleAnimationValue::ExtractComputedValue(nsCSSProperty aProperty, GetComputedBorder().side_); \ break; BORDER_WIDTH_CASE(eCSSProperty_border_bottom_width, bottom) - BORDER_WIDTH_CASE(eCSSProperty_border_left_width, left) - BORDER_WIDTH_CASE(eCSSProperty_border_right_width, right) + BORDER_WIDTH_CASE(eCSSProperty_border_left_width_value, left) + BORDER_WIDTH_CASE(eCSSProperty_border_right_width_value, right) BORDER_WIDTH_CASE(eCSSProperty_border_top_width, top) #undef BORDER_WIDTH_CASE @@ -2938,11 +2942,11 @@ StyleAnimationValue::ExtractComputedValue(nsCSSProperty aProperty, ExtractBorderColor(aStyleContext, styleStruct, NS_SIDE_BOTTOM, aComputedValue); break; - case eCSSProperty_border_left_color: + case eCSSProperty_border_left_color_value: ExtractBorderColor(aStyleContext, styleStruct, NS_SIDE_LEFT, aComputedValue); break; - case eCSSProperty_border_right_color: + case eCSSProperty_border_right_color_value: ExtractBorderColor(aStyleContext, styleStruct, NS_SIDE_RIGHT, aComputedValue); break; diff --git a/layout/style/nsCSSDataBlock.cpp b/layout/style/nsCSSDataBlock.cpp index 69cf4dd7166..2191bf513a3 100644 --- a/layout/style/nsCSSDataBlock.cpp +++ b/layout/style/nsCSSDataBlock.cpp @@ -163,61 +163,6 @@ MapSinglePropertyInto(nsCSSProperty aProp, } } -/** - * If aProperty is a logical property, converts it to the equivalent physical - * property based on writing mode information obtained from aRuleData's - * style context. Returns true if aProperty was changed. - */ -static inline void -EnsurePhysicalProperty(nsCSSProperty& aProperty, nsRuleData* aRuleData) -{ - uint8_t direction = aRuleData->mStyleContext->StyleVisibility()->mDirection; - bool ltr = direction == NS_STYLE_DIRECTION_LTR; - - switch (aProperty) { - case eCSSProperty_margin_end: - aProperty = ltr ? eCSSProperty_margin_right : eCSSProperty_margin_left; - break; - case eCSSProperty_margin_start: - aProperty = ltr ? eCSSProperty_margin_left : eCSSProperty_margin_right; - break; - case eCSSProperty_padding_end: - aProperty = ltr ? eCSSProperty_padding_right : eCSSProperty_padding_left; - break; - case eCSSProperty_padding_start: - aProperty = ltr ? eCSSProperty_padding_left : eCSSProperty_padding_right; - break; - case eCSSProperty_border_end_color: - aProperty = ltr ? eCSSProperty_border_right_color : - eCSSProperty_border_left_color; - break; - case eCSSProperty_border_end_style: - aProperty = ltr ? eCSSProperty_border_right_style : - eCSSProperty_border_left_style; - break; - case eCSSProperty_border_end_width: - aProperty = ltr ? eCSSProperty_border_right_width : - eCSSProperty_border_left_width; - break; - case eCSSProperty_border_start_color: - aProperty = ltr ? eCSSProperty_border_left_color : - eCSSProperty_border_right_color; - break; - case eCSSProperty_border_start_style: - aProperty = ltr ? eCSSProperty_border_left_style : - eCSSProperty_border_right_style; - break; - case eCSSProperty_border_start_width: - aProperty = ltr ? eCSSProperty_border_left_width : - eCSSProperty_border_right_width; - break; - default: - NS_ABORT_IF_FALSE(nsCSSProps::PropHasFlags(aProperty, - CSS_PROPERTY_LOGICAL), - "unhandled logical property"); - } -} - void nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const { @@ -228,20 +173,10 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const if (!(aRuleData->mSIDs & mStyleBits)) return; - // We process these in reverse order so that we end up mapping the - // right property when one can be expressed using both logical and - // physical property names. - for (uint32_t i = mNumProps; i-- > 0; ) { + for (uint32_t i = 0; i < mNumProps; i++) { nsCSSProperty iProp = PropertyAtIndex(i); if (nsCachedStyleData::GetBitForSID(nsCSSProps::kSIDTable[iProp]) & aRuleData->mSIDs) { - if (nsCSSProps::PropHasFlags(iProp, CSS_PROPERTY_LOGICAL)) { - EnsurePhysicalProperty(iProp, aRuleData); - // We can't cache anything on the rule tree if we use any data from - // the style context, since data cached in the rule tree could be - // used with a style context with a different value. - aRuleData->mCanStoreInRuleTree = false; - } nsCSSValue* target = aRuleData->ValueFor(iProp); if (target->GetUnit() == eCSSUnit_Null) { const nsCSSValue *val = ValueAtIndex(i); @@ -670,17 +605,11 @@ nsCSSExpandedDataBlock::MapRuleInfoInto(nsCSSProperty aPropID, const nsCSSValue* src = PropertyAt(aPropID); MOZ_ASSERT(src->GetUnit() != eCSSUnit_Null); - nsCSSProperty physicalProp = aPropID; - if (nsCSSProps::PropHasFlags(aPropID, CSS_PROPERTY_LOGICAL)) { - EnsurePhysicalProperty(physicalProp, aRuleData); - aRuleData->mCanStoreInRuleTree = false; - } - - nsCSSValue* dest = aRuleData->ValueFor(physicalProp); + nsCSSValue* dest = aRuleData->ValueFor(aPropID); MOZ_ASSERT(dest->GetUnit() == eCSSUnit_TokenStream && dest->GetTokenStreamValue()->mPropertyID == aPropID); - MapSinglePropertyInto(physicalProp, src, dest, aRuleData); + MapSinglePropertyInto(aPropID, src, dest, aRuleData); } #ifdef DEBUG diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index daef422a508..19e5b9aea2e 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -59,9 +59,7 @@ nsCSSProps::kParserVariantTable[eCSSProperty_COUNT_no_shorthands] = { #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \ stylestruct_, stylestructoffset_, animtype_) \ parsevariant_, -#define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" -#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP }; @@ -630,6 +628,8 @@ protected: bool ParseTreePseudoElement(nsAtomList **aPseudoElementArgs); #endif + void InitBoxPropsAsPhysical(const nsCSSProperty *aSourceProperties); + // Property specific parsing routines bool ParseBackground(); @@ -686,6 +686,8 @@ protected: bool ParseBorderSpacing(); bool ParseBorderSide(const nsCSSProperty aPropIDs[], bool aSetAllSides); + bool ParseDirectionalBorderSide(const nsCSSProperty aPropIDs[], + int32_t aSourceType); bool ParseBorderStyle(); bool ParseBorderWidth(); @@ -885,6 +887,8 @@ protected: bool ParseBoxProperties(const nsCSSProperty aPropIDs[]); bool ParseGroupedBoxProperty(int32_t aVariantMask, nsCSSValue& aValue); + bool ParseDirectionalBoxProperty(nsCSSProperty aProperty, + int32_t aSourceType); bool ParseBoxCornerRadius(const nsCSSProperty aPropID); bool ParseBoxCornerRadiiInternals(nsCSSValue array[]); bool ParseBoxCornerRadii(const nsCSSProperty aPropIDs[]); @@ -6608,6 +6612,9 @@ static const nsCSSProperty kBorderTopIDs[] = { eCSSProperty_border_top_color }; static const nsCSSProperty kBorderRightIDs[] = { + eCSSProperty_border_right_width_value, + eCSSProperty_border_right_style_value, + eCSSProperty_border_right_color_value, eCSSProperty_border_right_width, eCSSProperty_border_right_style, eCSSProperty_border_right_color @@ -6618,16 +6625,25 @@ static const nsCSSProperty kBorderBottomIDs[] = { eCSSProperty_border_bottom_color }; static const nsCSSProperty kBorderLeftIDs[] = { + eCSSProperty_border_left_width_value, + eCSSProperty_border_left_style_value, + eCSSProperty_border_left_color_value, eCSSProperty_border_left_width, eCSSProperty_border_left_style, eCSSProperty_border_left_color }; static const nsCSSProperty kBorderStartIDs[] = { + eCSSProperty_border_start_width_value, + eCSSProperty_border_start_style_value, + eCSSProperty_border_start_color_value, eCSSProperty_border_start_width, eCSSProperty_border_start_style, eCSSProperty_border_start_color }; static const nsCSSProperty kBorderEndIDs[] = { + eCSSProperty_border_end_width_value, + eCSSProperty_border_end_style_value, + eCSSProperty_border_end_color_value, eCSSProperty_border_end_width, eCSSProperty_border_end_style, eCSSProperty_border_end_color @@ -9313,6 +9329,25 @@ CSSParserImpl::ParseGroupedBoxProperty(int32_t aVariantMask, return true; } +bool +CSSParserImpl::ParseDirectionalBoxProperty(nsCSSProperty aProperty, + int32_t aSourceType) +{ + const nsCSSProperty* subprops = nsCSSProps::SubpropertyEntryFor(aProperty); + NS_ASSERTION(subprops[3] == eCSSProperty_UNKNOWN, + "not box property with physical vs. logical cascading"); + nsCSSValue value; + if (!ParseSingleValueProperty(value, subprops[0])) { + return false; + } + + AppendValue(subprops[0], value); + nsCSSValue typeVal(aSourceType, eCSSUnit_Enumerated); + AppendValue(subprops[1], typeVal); + AppendValue(subprops[2], typeVal); + return true; +} + bool CSSParserImpl::ParseBoxCornerRadius(nsCSSProperty aPropID) { @@ -9429,21 +9464,21 @@ CSSParserImpl::ParseBoxCornerRadii(const nsCSSProperty aPropIDs[]) // These must be in CSS order (top,right,bottom,left) for indexing to work static const nsCSSProperty kBorderStyleIDs[] = { eCSSProperty_border_top_style, - eCSSProperty_border_right_style, + eCSSProperty_border_right_style_value, eCSSProperty_border_bottom_style, - eCSSProperty_border_left_style + eCSSProperty_border_left_style_value }; static const nsCSSProperty kBorderWidthIDs[] = { eCSSProperty_border_top_width, - eCSSProperty_border_right_width, + eCSSProperty_border_right_width_value, eCSSProperty_border_bottom_width, - eCSSProperty_border_left_width + eCSSProperty_border_left_width_value }; static const nsCSSProperty kBorderColorIDs[] = { eCSSProperty_border_top_color, - eCSSProperty_border_right_color, + eCSSProperty_border_right_color_value, eCSSProperty_border_bottom_color, - eCSSProperty_border_left_color + eCSSProperty_border_left_color_value }; static const nsCSSProperty kBorderRadiusIDs[] = { eCSSProperty_border_top_left_radius, @@ -9709,13 +9744,17 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSProperty aPropID) case eCSSProperty_border_bottom: return ParseBorderSide(kBorderBottomIDs, false); case eCSSProperty_border_end: - return ParseBorderSide(kBorderEndIDs, false); - case eCSSProperty_border_start: - return ParseBorderSide(kBorderStartIDs, false); + return ParseDirectionalBorderSide(kBorderEndIDs, + NS_BOXPROP_SOURCE_LOGICAL); case eCSSProperty_border_left: - return ParseBorderSide(kBorderLeftIDs, false); + return ParseDirectionalBorderSide(kBorderLeftIDs, + NS_BOXPROP_SOURCE_PHYSICAL); case eCSSProperty_border_right: - return ParseBorderSide(kBorderRightIDs, false); + return ParseDirectionalBorderSide(kBorderRightIDs, + NS_BOXPROP_SOURCE_PHYSICAL); + case eCSSProperty_border_start: + return ParseDirectionalBorderSide(kBorderStartIDs, + NS_BOXPROP_SOURCE_LOGICAL); case eCSSProperty_border_top: return ParseBorderSide(kBorderTopIDs, false); case eCSSProperty_border_bottom_colors: @@ -9735,6 +9774,42 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSProperty aPropID) return ParseBorderImage(); case eCSSProperty_border_width: return ParseBorderWidth(); + case eCSSProperty_border_end_color: + return ParseDirectionalBoxProperty(eCSSProperty_border_end_color, + NS_BOXPROP_SOURCE_LOGICAL); + case eCSSProperty_border_left_color: + return ParseDirectionalBoxProperty(eCSSProperty_border_left_color, + NS_BOXPROP_SOURCE_PHYSICAL); + case eCSSProperty_border_right_color: + return ParseDirectionalBoxProperty(eCSSProperty_border_right_color, + NS_BOXPROP_SOURCE_PHYSICAL); + case eCSSProperty_border_start_color: + return ParseDirectionalBoxProperty(eCSSProperty_border_start_color, + NS_BOXPROP_SOURCE_LOGICAL); + case eCSSProperty_border_end_width: + return ParseDirectionalBoxProperty(eCSSProperty_border_end_width, + NS_BOXPROP_SOURCE_LOGICAL); + case eCSSProperty_border_left_width: + return ParseDirectionalBoxProperty(eCSSProperty_border_left_width, + NS_BOXPROP_SOURCE_PHYSICAL); + case eCSSProperty_border_right_width: + return ParseDirectionalBoxProperty(eCSSProperty_border_right_width, + NS_BOXPROP_SOURCE_PHYSICAL); + case eCSSProperty_border_start_width: + return ParseDirectionalBoxProperty(eCSSProperty_border_start_width, + NS_BOXPROP_SOURCE_LOGICAL); + case eCSSProperty_border_end_style: + return ParseDirectionalBoxProperty(eCSSProperty_border_end_style, + NS_BOXPROP_SOURCE_LOGICAL); + case eCSSProperty_border_left_style: + return ParseDirectionalBoxProperty(eCSSProperty_border_left_style, + NS_BOXPROP_SOURCE_PHYSICAL); + case eCSSProperty_border_right_style: + return ParseDirectionalBoxProperty(eCSSProperty_border_right_style, + NS_BOXPROP_SOURCE_PHYSICAL); + case eCSSProperty_border_start_style: + return ParseDirectionalBoxProperty(eCSSProperty_border_start_style, + NS_BOXPROP_SOURCE_LOGICAL); case eCSSProperty_border_radius: return ParseBoxCornerRadii(kBorderRadiusIDs); case eCSSProperty__moz_outline_radius: @@ -9810,6 +9885,18 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSProperty aPropID) return ParseListStyle(); case eCSSProperty_margin: return ParseMargin(); + case eCSSProperty_margin_end: + return ParseDirectionalBoxProperty(eCSSProperty_margin_end, + NS_BOXPROP_SOURCE_LOGICAL); + case eCSSProperty_margin_left: + return ParseDirectionalBoxProperty(eCSSProperty_margin_left, + NS_BOXPROP_SOURCE_PHYSICAL); + case eCSSProperty_margin_right: + return ParseDirectionalBoxProperty(eCSSProperty_margin_right, + NS_BOXPROP_SOURCE_PHYSICAL); + case eCSSProperty_margin_start: + return ParseDirectionalBoxProperty(eCSSProperty_margin_start, + NS_BOXPROP_SOURCE_LOGICAL); case eCSSProperty_object_position: return ParseObjectPosition(); case eCSSProperty_outline: @@ -9818,6 +9905,18 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSProperty aPropID) return ParseOverflow(); case eCSSProperty_padding: return ParsePadding(); + case eCSSProperty_padding_end: + return ParseDirectionalBoxProperty(eCSSProperty_padding_end, + NS_BOXPROP_SOURCE_LOGICAL); + case eCSSProperty_padding_left: + return ParseDirectionalBoxProperty(eCSSProperty_padding_left, + NS_BOXPROP_SOURCE_PHYSICAL); + case eCSSProperty_padding_right: + return ParseDirectionalBoxProperty(eCSSProperty_padding_right, + NS_BOXPROP_SOURCE_PHYSICAL); + case eCSSProperty_padding_start: + return ParseDirectionalBoxProperty(eCSSProperty_padding_start, + NS_BOXPROP_SOURCE_LOGICAL); case eCSSProperty_quotes: return ParseQuotes(); case eCSSProperty_size: @@ -10027,6 +10126,16 @@ CSSParserImpl::ParseFontDescriptorValue(nsCSSFontDesc aDescID, return false; } +void +CSSParserImpl::InitBoxPropsAsPhysical(const nsCSSProperty *aSourceProperties) +{ + nsCSSValue physical(NS_BOXPROP_SOURCE_PHYSICAL, eCSSUnit_Enumerated); + for (const nsCSSProperty *prop = aSourceProperties; + *prop != eCSSProperty_UNKNOWN; ++prop) { + AppendValue(*prop, physical); + } +} + static nsCSSValue BoxPositionMaskToCSSValue(int32_t aMask, bool isX) { @@ -10769,6 +10878,16 @@ bool CSSParserImpl::ParseBackgroundSizeValues(nsCSSValuePair &aOut) bool CSSParserImpl::ParseBorderColor() { + static const nsCSSProperty kBorderColorSources[] = { + eCSSProperty_border_left_color_ltr_source, + eCSSProperty_border_left_color_rtl_source, + eCSSProperty_border_right_color_ltr_source, + eCSSProperty_border_right_color_rtl_source, + eCSSProperty_UNKNOWN + }; + + // do this now, in case 4 values weren't specified + InitBoxPropsAsPhysical(kBorderColorSources); return ParseBoxProperties(kBorderColorIDs); } @@ -11075,6 +11194,24 @@ CSSParserImpl::ParseBorderSide(const nsCSSProperty aPropIDs[], } if (aSetAllSides) { + static const nsCSSProperty kBorderSources[] = { + eCSSProperty_border_left_color_ltr_source, + eCSSProperty_border_left_color_rtl_source, + eCSSProperty_border_right_color_ltr_source, + eCSSProperty_border_right_color_rtl_source, + eCSSProperty_border_left_style_ltr_source, + eCSSProperty_border_left_style_rtl_source, + eCSSProperty_border_right_style_ltr_source, + eCSSProperty_border_right_style_rtl_source, + eCSSProperty_border_left_width_ltr_source, + eCSSProperty_border_left_width_rtl_source, + eCSSProperty_border_right_width_ltr_source, + eCSSProperty_border_right_width_rtl_source, + eCSSProperty_UNKNOWN + }; + + InitBoxPropsAsPhysical(kBorderSources); + // Parsing "border" shorthand; set all four sides to the same thing for (int32_t index = 0; index < 4; index++) { NS_ASSERTION(numProps == 3, "This code needs updating"); @@ -11123,15 +11260,69 @@ CSSParserImpl::ParseBorderSide(const nsCSSProperty aPropIDs[], return true; } +bool +CSSParserImpl::ParseDirectionalBorderSide(const nsCSSProperty aPropIDs[], + int32_t aSourceType) +{ + const int32_t numProps = 3; + nsCSSValue values[numProps]; + + int32_t found = ParseChoice(values, aPropIDs, numProps); + if (found < 1) { + return false; + } + + if ((found & 1) == 0) { // Provide default border-width + values[0].SetIntValue(NS_STYLE_BORDER_WIDTH_MEDIUM, eCSSUnit_Enumerated); + } + if ((found & 2) == 0) { // Provide default border-style + values[1].SetIntValue(NS_STYLE_BORDER_STYLE_NONE, eCSSUnit_Enumerated); + } + if ((found & 4) == 0) { // text color will be used + values[2].SetIntValue(NS_STYLE_COLOR_MOZ_USE_TEXT_COLOR, eCSSUnit_Enumerated); + } + for (int32_t index = 0; index < numProps; index++) { + const nsCSSProperty* subprops = + nsCSSProps::SubpropertyEntryFor(aPropIDs[index + numProps]); + NS_ASSERTION(subprops[3] == eCSSProperty_UNKNOWN, + "not box property with physical vs. logical cascading"); + AppendValue(subprops[0], values[index]); + nsCSSValue typeVal(aSourceType, eCSSUnit_Enumerated); + AppendValue(subprops[1], typeVal); + AppendValue(subprops[2], typeVal); + } + return true; +} + bool CSSParserImpl::ParseBorderStyle() { + static const nsCSSProperty kBorderStyleSources[] = { + eCSSProperty_border_left_style_ltr_source, + eCSSProperty_border_left_style_rtl_source, + eCSSProperty_border_right_style_ltr_source, + eCSSProperty_border_right_style_rtl_source, + eCSSProperty_UNKNOWN + }; + + // do this now, in case 4 values weren't specified + InitBoxPropsAsPhysical(kBorderStyleSources); return ParseBoxProperties(kBorderStyleIDs); } bool CSSParserImpl::ParseBorderWidth() { + static const nsCSSProperty kBorderWidthSources[] = { + eCSSProperty_border_left_width_ltr_source, + eCSSProperty_border_left_width_rtl_source, + eCSSProperty_border_right_width_ltr_source, + eCSSProperty_border_right_width_rtl_source, + eCSSProperty_UNKNOWN + }; + + // do this now, in case 4 values weren't specified + InitBoxPropsAsPhysical(kBorderWidthSources); return ParseBoxProperties(kBorderWidthIDs); } @@ -12774,11 +12965,20 @@ CSSParserImpl::ParseMargin() { static const nsCSSProperty kMarginSideIDs[] = { eCSSProperty_margin_top, - eCSSProperty_margin_right, + eCSSProperty_margin_right_value, eCSSProperty_margin_bottom, - eCSSProperty_margin_left + eCSSProperty_margin_left_value + }; + static const nsCSSProperty kMarginSources[] = { + eCSSProperty_margin_left_ltr_source, + eCSSProperty_margin_left_rtl_source, + eCSSProperty_margin_right_ltr_source, + eCSSProperty_margin_right_rtl_source, + eCSSProperty_UNKNOWN }; + // do this now, in case 4 values weren't specified + InitBoxPropsAsPhysical(kMarginSources); return ParseBoxProperties(kMarginSideIDs); } @@ -12883,11 +13083,20 @@ CSSParserImpl::ParsePadding() { static const nsCSSProperty kPaddingSideIDs[] = { eCSSProperty_padding_top, - eCSSProperty_padding_right, + eCSSProperty_padding_right_value, eCSSProperty_padding_bottom, - eCSSProperty_padding_left + eCSSProperty_padding_left_value + }; + static const nsCSSProperty kPaddingSources[] = { + eCSSProperty_padding_left_ltr_source, + eCSSProperty_padding_left_rtl_source, + eCSSProperty_padding_right_ltr_source, + eCSSProperty_padding_right_rtl_source, + eCSSProperty_UNKNOWN }; + // do this now, in case 4 values weren't specified + InitBoxPropsAsPhysical(kPaddingSources); return ParseBoxProperties(kPaddingSideIDs); } diff --git a/layout/style/nsCSSPropAliasList.h b/layout/style/nsCSSPropAliasList.h index 64a1c9d6d88..78605295e6d 100644 --- a/layout/style/nsCSSPropAliasList.h +++ b/layout/style/nsCSSPropAliasList.h @@ -139,51 +139,3 @@ CSS_PROP_ALIAS(-moz-text-decoration-style, text_decoration_style, MozTextDecorationStyle, "") -CSS_PROP_ALIAS(padding-inline-end, - padding_end, - PaddingInlineEnd, - "layout.css.vertical-text.enabled") -CSS_PROP_ALIAS(padding-inline-start, - padding_start, - PaddingInlineStart, - "layout.css.vertical-text.enabled") -CSS_PROP_ALIAS(margin-inline-end, - margin_end, - MarginInlineEnd, - "layout.css.vertical-text.enabled") -CSS_PROP_ALIAS(margin-inline-start, - margin_start, - MarginInlineStart, - "layout.css.vertical-text.enabled") -CSS_PROP_ALIAS(border-inline-end, - border_end, - BorderInlineEnd, - "layout.css.vertical-text.enabled") -CSS_PROP_ALIAS(border-inline-end-color, - border_end_color, - BorderInlineEndColor, - "layout.css.vertical-text.enabled") -CSS_PROP_ALIAS(border-inline-end-style, - border_end_style, - BorderInlineEndStyle, - "layout.css.vertical-text.enabled") -CSS_PROP_ALIAS(border-inline-end-width, - border_end_width, - BorderInlineEndWidth, - "layout.css.vertical-text.enabled") -CSS_PROP_ALIAS(border-inline-start, - border_start, - BorderInlineStart, - "layout.css.vertical-text.enabled") -CSS_PROP_ALIAS(border-inline-start-color, - border_start_color, - BorderInlineStartColor, - "layout.css.vertical-text.enabled") -CSS_PROP_ALIAS(border-inline-start-style, - border_start_style, - BorderInlineStartStyle, - "layout.css.vertical-text.enabled") -CSS_PROP_ALIAS(border-inline-start-width, - border_start_width, - BorderInlineStartWidth, - "layout.css.vertical-text.enabled") diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index bf6a59f6593..ac0915d7bf7 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -17,7 +17,7 @@ It is recommended (but not strictly necessary) to keep all entries in alphabetical order. - The arguments to CSS_PROP, CSS_PROP_LOGICAL and CSS_PROP_* are: + The arguments to CSS_PROP and CSS_PROP_* are: -. 'name' entries represent a CSS property name and *must* use only lowercase characters. @@ -51,9 +51,9 @@ keyword table member of class nsCSSProps, for use in nsCSSProps::LookupPropertyValue. - -. 'stylestruct_' [used only for CSS_PROP and CSS_PROP_LOGICAL, not - CSS_PROP_*] gives the name of the style struct. Can be used to make - nsStyle##stylestruct_ and eStyleStruct_##stylestruct_ + -. 'stylestruct_' [used only for CSS_PROP, not CSS_PROP_*] gives the + name of the style struct. Can be used to make nsStyle##stylestruct_ + and eStyleStruct_##stylestruct_ -. 'stylestructoffset_' [not used for CSS_PROP_BACKENDONLY] gives the result of offsetof(nsStyle*, member). Ignored (and generally @@ -65,11 +65,6 @@ CSS_PROP_SHORTHAND only takes 1-5. - CSS_PROP_LOGICAL should be used instead of CSS_PROP_struct when - defining logical properties (which also must be defined with the - CSS_PROPERTY_LOGICAL flag). Logical shorthand properties should still - be defined with CSS_PROP_SHORTHAND. - ******/ @@ -92,26 +87,6 @@ // exclude internal properties that are not represented in the DOM (only // the DOM style code defines this). -// When capturing all properties by defining CSS_PROP, callers must also -// define one of the following three macros: -// -// CSS_PROP_LIST_EXCLUDE_LOGICAL -// Does not include logical properties (defined with CSS_PROP_LOGICAL, -// such as -moz-margin-start) when capturing properties to CSS_PROP. -// -// CSS_PROP_LIST_INCLUDE_LOGICAL -// Does include logical properties when capturing properties to -// CSS_PROP. -// -// CSS_PROP_LOGICAL -// Captures logical properties separately to CSS_PROP_LOGICAL. -// -// (CSS_PROP_LIST_EXCLUDE_LOGICAL is used for example to ensure -// gPropertyCountInStruct and gPropertyIndexInStruct do not allocate any -// storage to logical properties, since the result of the cascade, stored -// in an nsRuleData, does not need to store both logical and physical -// property values.) - // Callers may also define CSS_PROP_LIST_ONLY_COMPONENTS_OF_ALL_SHORTHAND // to exclude properties that are not considered to be components of the 'all' // shorthand property. Currently this excludes 'direction' and 'unicode-bidi', @@ -159,36 +134,12 @@ #define DEFINED_CSS_PROP_BACKENDONLY #endif -// And similarly for logical properties. An includer can define -// CSS_PROP_LOGICAL to capture all logical properties, but otherwise they -// are included in CSS_PROP (as long as CSS_PROP_LIST_INCLUDE_LOGICAL is -// defined). -#if defined(CSS_PROP_LOGICAL) && defined(CSS_PROP_LIST_EXCLUDE_LOGICAL) || defined(CSS_PROP_LOGICAL) && defined(CSS_PROP_LIST_INCLUDE_LOGICAL) || defined(CSS_PROP_LIST_EXCLUDE_LOGICAL) && defined(CSS_PROP_LIST_INCLUDE_LOGICAL) -#error Do not define more than one of CSS_PROP_LOGICAL, CSS_PROP_LIST_EXCLUDE_LOGICAL and CSS_PROP_LIST_INCLUDE_LOGICAL when capturing properties using CSS_PROP. -#endif - -#ifndef CSS_PROP_LOGICAL -#ifdef CSS_PROP_LIST_INCLUDE_LOGICAL -#define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, struct_, stylestructoffset_, animtype_) CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, struct_, stylestructoffset_, animtype_) -#else -#ifndef CSS_PROP_LIST_EXCLUDE_LOGICAL -#error Must define exactly one of CSS_PROP_LOGICAL, CSS_PROP_LIST_EXCLUDE_LOGICAL and CSS_PROP_LIST_INCLUDE_LOGICAL when capturing properties using CSS_PROP. -#endif -#define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, struct_, stylestructoffset_, animtype_) /* nothing */ -#endif -#define DEFINED_CSS_PROP_LOGICAL -#endif - #else /* !defined(CSS_PROP) */ // An includer who does not define CSS_PROP can define any or all of the // per-struct macros that are equivalent to it, and the rest will be // ignored. -#if defined(CSS_PROP_LIST_EXCLUDE_LOGICAL) || defined(CSS_PROP_LIST_INCLUDE_LOGICAL) -#error Do not define CSS_PROP_LIST_EXCLUDE_LOGICAL or CSS_PROP_LIST_INCLUDE_LOGICAL when not capturing properties using CSS_PROP. -#endif - #ifndef CSS_PROP_FONT #define CSS_PROP_FONT(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, stylestructoffset_, animtype_) /* nothing */ #define DEFINED_CSS_PROP_FONT @@ -290,10 +241,6 @@ #define CSS_PROP_BACKENDONLY(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_) /* nothing */ #define DEFINED_CSS_PROP_BACKENDONLY #endif -#ifndef CSS_PROP_LOGICAL -#define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, struct_, stylestructoffset_, animtype_) /* nothing */ -#define DEFINED_CSS_PROP_LOGICAL -#endif #endif /* !defined(CSS_PROP) */ @@ -743,6 +690,70 @@ CSS_PROP_SHORTHAND( CSS_PROPERTY_PARSE_FUNCTION | CSS_PROPERTY_HASHLESS_COLOR_QUIRK, "") +CSS_PROP_SHORTHAND( + -moz-border-end, + border_end, + CSS_PROP_DOMPROP_PREFIXED(BorderEnd), + CSS_PROPERTY_PARSE_FUNCTION, + "") +CSS_PROP_SHORTHAND( + -moz-border-end-color, + border_end_color, + CSS_PROP_DOMPROP_PREFIXED(BorderEndColor), + CSS_PROPERTY_PARSE_FUNCTION, + "") +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_BORDER( + border-end-color-value, + border_end_color_value, + BorderEndColorValue, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER, + "", + VARIANT_HCK, // used only internally + kBorderColorKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +#endif +CSS_PROP_SHORTHAND( + -moz-border-end-style, + border_end_style, + CSS_PROP_DOMPROP_PREFIXED(BorderEndStyle), + CSS_PROPERTY_PARSE_FUNCTION, + "") +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_BORDER( + border-end-style-value, + border_end_style_value, + BorderEndStyleValue, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER, + "", + VARIANT_HK, // used only internally + kBorderStyleKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +#endif +CSS_PROP_SHORTHAND( + -moz-border-end-width, + border_end_width, + CSS_PROP_DOMPROP_PREFIXED(BorderEndWidth), + CSS_PROPERTY_PARSE_FUNCTION, + "") +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_BORDER( + border-end-width-value, + border_end_width_value, + BorderEndWidthValue, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_VALUE_NONNEGATIVE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER, + "", + VARIANT_HKL | VARIANT_CALC, + kBorderWidthKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +#endif CSS_PROP_SHORTHAND( border-image, border_image, @@ -805,117 +816,60 @@ CSS_PROP_BORDER( kBorderImageRepeatKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_None) -CSS_PROP_SHORTHAND( - -moz-border-end, - border_end, - CSS_PROP_DOMPROP_PREFIXED(BorderEnd), - CSS_PROPERTY_PARSE_FUNCTION, - "") -CSS_PROP_LOGICAL( - -moz-border-end-color, - border_end_color, - CSS_PROP_DOMPROP_PREFIXED(BorderEndColor), - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - CSS_PROPERTY_LOGICAL, - "", - VARIANT_HCK, - kBorderColorKTable, - Border, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) -CSS_PROP_LOGICAL( - -moz-border-end-style, - border_end_style, - CSS_PROP_DOMPROP_PREFIXED(BorderEndStyle), - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - CSS_PROPERTY_LOGICAL, - "", - VARIANT_HK, - kBorderStyleKTable, - Border, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) -CSS_PROP_LOGICAL( - -moz-border-end-width, - border_end_width, - CSS_PROP_DOMPROP_PREFIXED(BorderEndWidth), - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_VALUE_NONNEGATIVE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - CSS_PROPERTY_LOGICAL, - "", - VARIANT_HKL | VARIANT_CALC, - kBorderWidthKTable, - Border, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) -CSS_PROP_SHORTHAND( - -moz-border-start, - border_start, - CSS_PROP_DOMPROP_PREFIXED(BorderStart), - CSS_PROPERTY_PARSE_FUNCTION, - "") -CSS_PROP_LOGICAL( - -moz-border-start-color, - border_start_color, - CSS_PROP_DOMPROP_PREFIXED(BorderStartColor), - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - CSS_PROPERTY_LOGICAL, - "", - VARIANT_HCK, - kBorderColorKTable, - Border, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) -CSS_PROP_LOGICAL( - -moz-border-start-style, - border_start_style, - CSS_PROP_DOMPROP_PREFIXED(BorderStartStyle), - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - CSS_PROPERTY_LOGICAL, - "", - VARIANT_HK, - kBorderStyleKTable, - Border, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) -CSS_PROP_LOGICAL( - -moz-border-start-width, - border_start_width, - CSS_PROP_DOMPROP_PREFIXED(BorderStartWidth), - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_VALUE_NONNEGATIVE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - CSS_PROPERTY_LOGICAL, - "", - VARIANT_HKL | VARIANT_CALC, - kBorderWidthKTable, - Border, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) CSS_PROP_SHORTHAND( border-left, border_left, BorderLeft, CSS_PROPERTY_PARSE_FUNCTION, "") -CSS_PROP_BORDER( +CSS_PROP_SHORTHAND( border-left-color, border_left_color, BorderLeftColor, - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_HASHLESS_COLOR_QUIRK | + CSS_PROPERTY_PARSE_FUNCTION | + CSS_PROPERTY_HASHLESS_COLOR_QUIRK, + "") +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_BORDER( + border-left-color-value, + border_left_color_value, + BorderLeftColorValue, + CSS_PROPERTY_PARSE_INACCESSIBLE | CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED, + CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED | + CSS_PROPERTY_REPORT_OTHER_NAME, "", - VARIANT_HCK, + VARIANT_HCK, // used only internally kBorderColorKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_Custom) +CSS_PROP_BORDER( + border-left-color-ltr-source, + border_left_color_ltr_source, + BorderLeftColorLTRSource, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_DIRECTIONAL_SOURCE | + CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED, + "", + 0, + kBoxPropSourceKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +CSS_PROP_BORDER( + border-left-color-rtl-source, + border_left_color_rtl_source, + BorderLeftColorRTLSource, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_DIRECTIONAL_SOURCE | + CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED, + "", + 0, + kBoxPropSourceKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +#endif CSS_PROP_BORDER( -moz-border-left-colors, border_left_colors, @@ -928,50 +882,151 @@ CSS_PROP_BORDER( nullptr, CSS_PROP_NO_OFFSET, eStyleAnimType_None) -CSS_PROP_BORDER( +CSS_PROP_SHORTHAND( border-left-style, border_left_style, BorderLeftStyle, - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER, + CSS_PROPERTY_PARSE_FUNCTION, + "") // on/off will need reflow +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_BORDER( + border-left-style-value, + border_left_style_value, + BorderLeftStyleValue, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_REPORT_OTHER_NAME, "", - VARIANT_HK, + VARIANT_HK, // used only internally kBorderStyleKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_None) CSS_PROP_BORDER( + border-left-style-ltr-source, + border_left_style_ltr_source, + BorderLeftStyleLTRSource, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_DIRECTIONAL_SOURCE, + "", + 0, + kBoxPropSourceKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +CSS_PROP_BORDER( + border-left-style-rtl-source, + border_left_style_rtl_source, + BorderLeftStyleRTLSource, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_DIRECTIONAL_SOURCE, + "", + 0, + kBoxPropSourceKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +#endif +CSS_PROP_SHORTHAND( border-left-width, border_left_width, BorderLeftWidth, - CSS_PROPERTY_PARSE_VALUE | + CSS_PROPERTY_PARSE_FUNCTION | CSS_PROPERTY_UNITLESS_LENGTH_QUIRK | + CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, + "") +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_BORDER( + border-left-width-value, + border_left_width_value, + BorderLeftWidthValue, + CSS_PROPERTY_PARSE_INACCESSIBLE | CSS_PROPERTY_VALUE_NONNEGATIVE | - CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER, + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_REPORT_OTHER_NAME, "", VARIANT_HKL | VARIANT_CALC, kBorderWidthKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_Custom) +CSS_PROP_BORDER( + border-left-width-ltr-source, + border_left_width_ltr_source, + BorderLeftWidthLTRSource, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_DIRECTIONAL_SOURCE, + "", + 0, + kBoxPropSourceKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +CSS_PROP_BORDER( + border-left-width-rtl-source, + border_left_width_rtl_source, + BorderLeftWidthRTLSource, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_DIRECTIONAL_SOURCE, + "", + 0, + kBoxPropSourceKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +#endif CSS_PROP_SHORTHAND( border-right, border_right, BorderRight, CSS_PROPERTY_PARSE_FUNCTION, "") -CSS_PROP_BORDER( +CSS_PROP_SHORTHAND( border-right-color, border_right_color, BorderRightColor, - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_HASHLESS_COLOR_QUIRK | + CSS_PROPERTY_PARSE_FUNCTION | + CSS_PROPERTY_HASHLESS_COLOR_QUIRK, + "") +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_BORDER( + border-right-color-value, + border_right_color_value, + BorderRightColorValue, + CSS_PROPERTY_PARSE_INACCESSIBLE | CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED, + CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED | + CSS_PROPERTY_REPORT_OTHER_NAME, "", - VARIANT_HCK, + VARIANT_HCK, // used only internally kBorderColorKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_Custom) +CSS_PROP_BORDER( + border-right-color-ltr-source, + border_right_color_ltr_source, + BorderRightColorLTRSource, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_DIRECTIONAL_SOURCE | + CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED, + "", + 0, + kBoxPropSourceKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +CSS_PROP_BORDER( + border-right-color-rtl-source, + border_right_color_rtl_source, + BorderRightColorRTLSource, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_DIRECTIONAL_SOURCE | + CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED, + "", + 0, + kBoxPropSourceKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +#endif CSS_PROP_BORDER( -moz-border-right-colors, border_right_colors, @@ -984,31 +1039,97 @@ CSS_PROP_BORDER( nullptr, CSS_PROP_NO_OFFSET, eStyleAnimType_None) -CSS_PROP_BORDER( +CSS_PROP_SHORTHAND( border-right-style, border_right_style, BorderRightStyle, - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER, + CSS_PROPERTY_PARSE_FUNCTION, + "") // on/off will need reflow +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_BORDER( + border-right-style-value, + border_right_style_value, + BorderRightStyleValue, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_REPORT_OTHER_NAME, "", - VARIANT_HK, + VARIANT_HK, // used only internally kBorderStyleKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_None) CSS_PROP_BORDER( + border-right-style-ltr-source, + border_right_style_ltr_source, + BorderRightStyleLTRSource, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_DIRECTIONAL_SOURCE, + "", + 0, + kBoxPropSourceKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +CSS_PROP_BORDER( + border-right-style-rtl-source, + border_right_style_rtl_source, + BorderRightStyleRTLSource, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_DIRECTIONAL_SOURCE, + "", + 0, + kBoxPropSourceKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +#endif +CSS_PROP_SHORTHAND( border-right-width, border_right_width, BorderRightWidth, - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_VALUE_NONNEGATIVE | + CSS_PROPERTY_PARSE_FUNCTION | CSS_PROPERTY_UNITLESS_LENGTH_QUIRK | - CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER, + CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, + "") +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_BORDER( + border-right-width-value, + border_right_width_value, + BorderRightWidthValue, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_VALUE_NONNEGATIVE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_REPORT_OTHER_NAME, "", VARIANT_HKL | VARIANT_CALC, kBorderWidthKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_Custom) +CSS_PROP_BORDER( + border-right-width-ltr-source, + border_right_width_ltr_source, + BorderRightWidthLTRSource, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_DIRECTIONAL_SOURCE, + "", + 0, + kBoxPropSourceKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +CSS_PROP_BORDER( + border-right-width-rtl-source, + border_right_width_rtl_source, + BorderRightWidthRTLSource, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_DIRECTIONAL_SOURCE, + "", + 0, + kBoxPropSourceKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +#endif CSS_PROP_TABLEBORDER( border-spacing, border_spacing, @@ -1020,6 +1141,70 @@ CSS_PROP_TABLEBORDER( nullptr, CSS_PROP_NO_OFFSET, eStyleAnimType_Custom) +CSS_PROP_SHORTHAND( + -moz-border-start, + border_start, + CSS_PROP_DOMPROP_PREFIXED(BorderStart), + CSS_PROPERTY_PARSE_FUNCTION, + "") +CSS_PROP_SHORTHAND( + -moz-border-start-color, + border_start_color, + CSS_PROP_DOMPROP_PREFIXED(BorderStartColor), + CSS_PROPERTY_PARSE_FUNCTION, + "") +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_BORDER( + border-start-color-value, + border_start_color_value, + BorderStartColorValue, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER, + "", + VARIANT_HCK, // used only internally + kBorderColorKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +#endif +CSS_PROP_SHORTHAND( + -moz-border-start-style, + border_start_style, + CSS_PROP_DOMPROP_PREFIXED(BorderStartStyle), + CSS_PROPERTY_PARSE_FUNCTION, + "") +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_BORDER( + border-start-style-value, + border_start_style_value, + BorderStartStyleValue, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER, + "", + VARIANT_HK, // used only internally + kBorderStyleKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +#endif +CSS_PROP_SHORTHAND( + -moz-border-start-width, + border_start_width, + CSS_PROP_DOMPROP_PREFIXED(BorderStartWidth), + CSS_PROPERTY_PARSE_FUNCTION, + "") +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_BORDER( + border-start-width-value, + border_start_width_value, + BorderStartWidthValue, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_VALUE_NONNEGATIVE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER, + "", + VARIANT_HKL | VARIANT_CALC, + kBorderWidthKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +#endif CSS_PROP_SHORTHAND( border-style, border_style, @@ -2093,66 +2278,152 @@ CSS_PROP_MARGIN( nullptr, offsetof(nsStyleMargin, mMargin), eStyleAnimType_Sides_Bottom) -CSS_PROP_LOGICAL( +CSS_PROP_SHORTHAND( -moz-margin-end, margin_end, CSS_PROP_DOMPROP_PREFIXED(MarginEnd), - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - CSS_PROPERTY_STORES_CALC | - CSS_PROPERTY_APPLIES_TO_PAGE_RULE | - CSS_PROPERTY_LOGICAL, - "", - VARIANT_AHLP | VARIANT_CALC, - nullptr, - Margin, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) -CSS_PROP_LOGICAL( - -moz-margin-start, - margin_start, - CSS_PROP_DOMPROP_PREFIXED(MarginStart), - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - CSS_PROPERTY_STORES_CALC | - CSS_PROPERTY_APPLIES_TO_PAGE_RULE | - CSS_PROPERTY_LOGICAL, - "", - VARIANT_AHLP | VARIANT_CALC, - nullptr, - Margin, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) + CSS_PROPERTY_PARSE_FUNCTION | + CSS_PROPERTY_APPLIES_TO_PAGE_RULE, + "") +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL CSS_PROP_MARGIN( + margin-end-value, + margin_end_value, + MarginEndValue, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_STORES_CALC | + CSS_PROPERTY_APPLIES_TO_PAGE_RULE, + "", + VARIANT_AHLP | VARIANT_CALC, // for internal use + nullptr, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +#endif +CSS_PROP_SHORTHAND( margin-left, margin_left, MarginLeft, - CSS_PROPERTY_PARSE_VALUE | + CSS_PROPERTY_PARSE_FUNCTION | CSS_PROPERTY_UNITLESS_LENGTH_QUIRK | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - CSS_PROPERTY_STORES_CALC | CSS_PROPERTY_APPLIES_TO_PAGE_RULE | CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, + "") +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_MARGIN( + margin-left-value, + margin_left_value, + MarginLeftValue, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_REPORT_OTHER_NAME | + CSS_PROPERTY_STORES_CALC | + CSS_PROPERTY_APPLIES_TO_PAGE_RULE, "", - VARIANT_AHLP | VARIANT_CALC, + VARIANT_AHLP | VARIANT_CALC, // for internal use nullptr, offsetof(nsStyleMargin, mMargin), eStyleAnimType_Sides_Left) CSS_PROP_MARGIN( + margin-left-ltr-source, + margin_left_ltr_source, + MarginLeftLTRSource, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_DIRECTIONAL_SOURCE | + CSS_PROPERTY_APPLIES_TO_PAGE_RULE, + "", + 0, + kBoxPropSourceKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +CSS_PROP_MARGIN( + margin-left-rtl-source, + margin_left_rtl_source, + MarginLeftRTLSource, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_DIRECTIONAL_SOURCE | + CSS_PROPERTY_APPLIES_TO_PAGE_RULE, + "", + 0, + kBoxPropSourceKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +#endif +CSS_PROP_SHORTHAND( margin-right, margin_right, MarginRight, - CSS_PROPERTY_PARSE_VALUE | + CSS_PROPERTY_PARSE_FUNCTION | CSS_PROPERTY_UNITLESS_LENGTH_QUIRK | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - CSS_PROPERTY_STORES_CALC | CSS_PROPERTY_APPLIES_TO_PAGE_RULE | CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, + "") +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_MARGIN( + margin-right-value, + margin_right_value, + MarginRightValue, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_REPORT_OTHER_NAME | + CSS_PROPERTY_STORES_CALC | + CSS_PROPERTY_APPLIES_TO_PAGE_RULE, "", - VARIANT_AHLP | VARIANT_CALC, + VARIANT_AHLP | VARIANT_CALC, // for internal use nullptr, offsetof(nsStyleMargin, mMargin), eStyleAnimType_Sides_Right) +CSS_PROP_MARGIN( + margin-right-ltr-source, + margin_right_ltr_source, + MarginRightLTRSource, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_DIRECTIONAL_SOURCE | + CSS_PROPERTY_APPLIES_TO_PAGE_RULE, + "", + 0, + kBoxPropSourceKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +CSS_PROP_MARGIN( + margin-right-rtl-source, + margin_right_rtl_source, + MarginRightRTLSource, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_DIRECTIONAL_SOURCE | + CSS_PROPERTY_APPLIES_TO_PAGE_RULE, + "", + 0, + kBoxPropSourceKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +#endif +CSS_PROP_SHORTHAND( + -moz-margin-start, + margin_start, + CSS_PROP_DOMPROP_PREFIXED(MarginStart), + CSS_PROPERTY_PARSE_FUNCTION | + CSS_PROPERTY_APPLIES_TO_PAGE_RULE, + "") +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_MARGIN( + margin-start-value, + margin_start_value, + MarginStartValue, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_STORES_CALC | + CSS_PROPERTY_APPLIES_TO_PAGE_RULE, + "", + VARIANT_AHLP | VARIANT_CALC, // for internal use + nullptr, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +#endif CSS_PROP_MARGIN( margin-top, margin_top, @@ -2428,76 +2699,158 @@ CSS_PROP_PADDING( nullptr, offsetof(nsStylePadding, mPadding), eStyleAnimType_Sides_Bottom) -CSS_PROP_LOGICAL( +CSS_PROP_SHORTHAND( -moz-padding-end, padding_end, CSS_PROP_DOMPROP_PREFIXED(PaddingEnd), - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_VALUE_NONNEGATIVE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - // This is required by the UA stylesheet and can't be overridden. - CSS_PROPERTY_APPLIES_TO_PLACEHOLDER | - CSS_PROPERTY_STORES_CALC | - CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH | - CSS_PROPERTY_LOGICAL, - "", - VARIANT_HLP | VARIANT_CALC, - nullptr, - Padding, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) -CSS_PROP_LOGICAL( - -moz-padding-start, - padding_start, - CSS_PROP_DOMPROP_PREFIXED(PaddingStart), - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_VALUE_NONNEGATIVE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | - // This is required by the UA stylesheet and can't be overridden. - CSS_PROPERTY_APPLIES_TO_PLACEHOLDER | - CSS_PROPERTY_STORES_CALC | - CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH | - CSS_PROPERTY_LOGICAL, - "", - VARIANT_HLP | VARIANT_CALC, - nullptr, - Padding, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) + CSS_PROPERTY_PARSE_FUNCTION, + "") +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL CSS_PROP_PADDING( + padding-end-value, + padding_end_value, + PaddingEndValue, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_VALUE_NONNEGATIVE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + // This is required by the UA stylesheet and can't be overridden. + CSS_PROPERTY_APPLIES_TO_PLACEHOLDER | + CSS_PROPERTY_STORES_CALC, + "", + VARIANT_HLP | VARIANT_CALC, // for internal use + nullptr, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +#endif +CSS_PROP_SHORTHAND( padding-left, padding_left, PaddingLeft, - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_VALUE_NONNEGATIVE | + CSS_PROPERTY_PARSE_FUNCTION | CSS_PROPERTY_UNITLESS_LENGTH_QUIRK | + CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, + "") +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_PADDING( + padding-left-value, + padding_left_value, + PaddingLeftValue, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_VALUE_NONNEGATIVE | CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | // This is required by the UA stylesheet and can't be overridden. CSS_PROPERTY_APPLIES_TO_PLACEHOLDER | - CSS_PROPERTY_STORES_CALC | - CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, + CSS_PROPERTY_REPORT_OTHER_NAME | + CSS_PROPERTY_STORES_CALC, "", - VARIANT_HLP | VARIANT_CALC, + VARIANT_HLP | VARIANT_CALC, // for internal use nullptr, offsetof(nsStylePadding, mPadding), eStyleAnimType_Sides_Left) CSS_PROP_PADDING( - padding-right, - padding_right, - PaddingRight, - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_VALUE_NONNEGATIVE | - CSS_PROPERTY_UNITLESS_LENGTH_QUIRK | + padding-left-ltr-source, + padding_left_ltr_source, + PaddingLeftLTRSource, + CSS_PROPERTY_PARSE_INACCESSIBLE | CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | // This is required by the UA stylesheet and can't be overridden. CSS_PROPERTY_APPLIES_TO_PLACEHOLDER | - CSS_PROPERTY_STORES_CALC | - CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, + CSS_PROPERTY_DIRECTIONAL_SOURCE, "", - VARIANT_HLP | VARIANT_CALC, + 0, + kBoxPropSourceKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +CSS_PROP_PADDING( + padding-left-rtl-source, + padding_left_rtl_source, + PaddingLeftRTLSource, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + // This is required by the UA stylesheet and can't be overridden. + CSS_PROPERTY_APPLIES_TO_PLACEHOLDER | + CSS_PROPERTY_DIRECTIONAL_SOURCE, + "", + 0, + kBoxPropSourceKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +#endif +CSS_PROP_SHORTHAND( + padding-right, + padding_right, + PaddingRight, + CSS_PROPERTY_PARSE_FUNCTION | + CSS_PROPERTY_UNITLESS_LENGTH_QUIRK | + CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, + "") +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_PADDING( + padding-right-value, + padding_right_value, + PaddingRightValue, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_VALUE_NONNEGATIVE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + // This is required by the UA stylesheet and can't be overridden. + CSS_PROPERTY_APPLIES_TO_PLACEHOLDER | + CSS_PROPERTY_REPORT_OTHER_NAME | + CSS_PROPERTY_STORES_CALC, + "", + VARIANT_HLP | VARIANT_CALC, // for internal use nullptr, offsetof(nsStylePadding, mPadding), eStyleAnimType_Sides_Right) +CSS_PROP_PADDING( + padding-right-ltr-source, + padding_right_ltr_source, + PaddingRightLTRSource, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + // This is required by the UA stylesheet and can't be overridden. + CSS_PROPERTY_APPLIES_TO_PLACEHOLDER | + CSS_PROPERTY_DIRECTIONAL_SOURCE, + "", + 0, + kBoxPropSourceKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +CSS_PROP_PADDING( + padding-right-rtl-source, + padding_right_rtl_source, + PaddingRightRTLSource, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_DIRECTIONAL_SOURCE, + "", + 0, + kBoxPropSourceKTable, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +#endif +CSS_PROP_SHORTHAND( + -moz-padding-start, + padding_start, + CSS_PROP_DOMPROP_PREFIXED(PaddingStart), + CSS_PROPERTY_PARSE_FUNCTION, + "") +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_PADDING( + padding-start-value, + padding_start_value, + PaddingStartValue, + CSS_PROPERTY_PARSE_INACCESSIBLE | + CSS_PROPERTY_VALUE_NONNEGATIVE | + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + // This is required by the UA stylesheet and can't be overridden. + CSS_PROPERTY_APPLIES_TO_PLACEHOLDER | + CSS_PROPERTY_STORES_CALC, + "", + VARIANT_HLP | VARIANT_CALC, // for internal use + nullptr, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +#endif CSS_PROP_PADDING( padding-top, padding_top, @@ -3836,9 +4189,5 @@ CSS_PROP_FONT( #undef CSS_PROP_SHORTHAND #undef DEFINED_CSS_PROP_SHORTHAND #endif -#ifdef DEFINED_CSS_PROP_LOGICAL -#undef CSS_PROP_LOGICAL -#undef DEFINED_CSS_PROP_LOGICAL -#endif #undef CSS_PROP_DOMPROP_PREFIXED diff --git a/layout/style/nsCSSProperty.h b/layout/style/nsCSSProperty.h index 36d67d7106f..b29ffdd4acc 100644 --- a/layout/style/nsCSSProperty.h +++ b/layout/style/nsCSSProperty.h @@ -21,9 +21,7 @@ enum nsCSSProperty { #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \ kwtable_, stylestruct_, stylestructoffset_, animtype_) \ eCSSProperty_##id_, - #define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" - #undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP eCSSProperty_COUNT_no_shorthands, diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp index d410ba7bb31..a9408be01e9 100644 --- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -36,9 +36,7 @@ const char* const kCSSRawProperties[eCSSProperty_COUNT_with_aliases] = { #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \ stylestruct_, stylestructoffset_, animtype_) \ #name_, -#define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" -#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) #name_, #include "nsCSSPropList.h" @@ -171,9 +169,7 @@ nsCSSProps::AddRefTable(void) #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \ kwtable_, stylestruct_, stylestructoffset_, animtype_) \ OBSERVE_PROP(pref_, eCSSProperty_##id_) - #define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" - #undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) \ @@ -558,6 +554,36 @@ nsCSSProps::GetStringValue(nsCSSCounterDesc aCounterDesc) } } +nsCSSProperty +nsCSSProps::OtherNameFor(nsCSSProperty aProperty) +{ + switch (aProperty) { + case eCSSProperty_border_left_color_value: + return eCSSProperty_border_left_color; + case eCSSProperty_border_left_style_value: + return eCSSProperty_border_left_style; + case eCSSProperty_border_left_width_value: + return eCSSProperty_border_left_width; + case eCSSProperty_border_right_color_value: + return eCSSProperty_border_right_color; + case eCSSProperty_border_right_style_value: + return eCSSProperty_border_right_style; + case eCSSProperty_border_right_width_value: + return eCSSProperty_border_right_width; + case eCSSProperty_margin_left_value: + return eCSSProperty_margin_left; + case eCSSProperty_margin_right_value: + return eCSSProperty_margin_right; + case eCSSProperty_padding_left_value: + return eCSSProperty_padding_left; + case eCSSProperty_padding_right_value: + return eCSSProperty_padding_right; + default: + NS_ABORT_IF_FALSE(false, "bad caller"); + } + return eCSSProperty_UNKNOWN; +} + /***************************************************************************/ const KTableValue nsCSSProps::kAnimationDirectionKTable[] = { @@ -835,6 +861,12 @@ const KTableValue nsCSSProps::kBorderWidthKTable[] = { eCSSKeyword_UNKNOWN,-1 }; +const KTableValue nsCSSProps::kBoxPropSourceKTable[] = { + eCSSKeyword_physical, NS_BOXPROP_SOURCE_PHYSICAL, + eCSSKeyword_logical, NS_BOXPROP_SOURCE_LOGICAL, + eCSSKeyword_UNKNOWN,-1 +}; + const KTableValue nsCSSProps::kBoxDecorationBreakKTable[] = { eCSSKeyword_slice, NS_STYLE_BOX_DECORATION_BREAK_SLICE, eCSSKeyword_clone, NS_STYLE_BOX_DECORATION_BREAK_CLONE, @@ -2087,9 +2119,7 @@ nsCSSProps::kKeywordTableTable[eCSSProperty_COUNT_no_shorthands] = { #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \ kwtable_, stylestruct_, stylestructoffset_, animtype_) \ kwtable_, - #define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" - #undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP }; @@ -2135,11 +2165,9 @@ const nsStyleStructID nsCSSProps::kSIDTable[eCSSProperty_COUNT_no_shorthands] = #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \ kwtable_, stylestruct_, stylestructoffset_, animtype_) \ eStyleStruct_##stylestruct_, - #define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" - #undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP }; @@ -2148,9 +2176,7 @@ nsCSSProps::kAnimTypeTable[eCSSProperty_COUNT_no_shorthands] = { #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \ stylestruct_, stylestructoffset_, animtype_) \ animtype_, -#define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" -#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP }; @@ -2159,9 +2185,7 @@ nsCSSProps::kStyleStructOffsetTable[eCSSProperty_COUNT_no_shorthands] = { #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \ stylestruct_, stylestructoffset_, animtype_) \ stylestructoffset_, -#define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" -#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP }; @@ -2169,9 +2193,7 @@ const uint32_t nsCSSProps::kFlagsTable[eCSSProperty_COUNT] = { #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \ stylestruct_, stylestructoffset_, animtype_) \ flags_, -#define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" -#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) flags_, #include "nsCSSPropList.h" @@ -2180,13 +2202,11 @@ const uint32_t nsCSSProps::kFlagsTable[eCSSProperty_COUNT] = { static const nsCSSProperty gAllSubpropTable[] = { #define CSS_PROP_LIST_ONLY_COMPONENTS_OF_ALL_SHORTHAND -#define CSS_PROP_LIST_INCLUDE_LOGICAL #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \ stylestruct_, stylestructoffset_, animtype_) \ eCSSProperty_##id_, #include "nsCSSPropList.h" #undef CSS_PROP -#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP_LIST_ONLY_COMPONENTS_OF_ALL_SHORTHAND eCSSProperty_UNKNOWN }; @@ -2240,17 +2260,29 @@ static const nsCSSProperty gBackgroundSubpropTable[] = { static const nsCSSProperty gBorderSubpropTable[] = { eCSSProperty_border_top_width, - eCSSProperty_border_right_width, + eCSSProperty_border_right_width_value, + eCSSProperty_border_right_width_ltr_source, + eCSSProperty_border_right_width_rtl_source, eCSSProperty_border_bottom_width, - eCSSProperty_border_left_width, + eCSSProperty_border_left_width_value, + eCSSProperty_border_left_width_ltr_source, + eCSSProperty_border_left_width_rtl_source, eCSSProperty_border_top_style, - eCSSProperty_border_right_style, + eCSSProperty_border_right_style_value, + eCSSProperty_border_right_style_ltr_source, + eCSSProperty_border_right_style_rtl_source, eCSSProperty_border_bottom_style, - eCSSProperty_border_left_style, + eCSSProperty_border_left_style_value, + eCSSProperty_border_left_style_ltr_source, + eCSSProperty_border_left_style_rtl_source, eCSSProperty_border_top_color, - eCSSProperty_border_right_color, + eCSSProperty_border_right_color_value, + eCSSProperty_border_right_color_ltr_source, + eCSSProperty_border_right_color_rtl_source, eCSSProperty_border_bottom_color, - eCSSProperty_border_left_color, + eCSSProperty_border_left_color_value, + eCSSProperty_border_left_color_ltr_source, + eCSSProperty_border_left_color_rtl_source, eCSSProperty_border_top_colors, eCSSProperty_border_right_colors, eCSSProperty_border_bottom_colors, @@ -2264,7 +2296,7 @@ static const nsCSSProperty gBorderSubpropTable[] = { }; static const nsCSSProperty gBorderBottomSubpropTable[] = { - // Declaration.cpp outputs the subproperties in this order. + // nsCSSDeclaration.cpp outputs the subproperties in this order. // It also depends on the color being third. eCSSProperty_border_bottom_width, eCSSProperty_border_bottom_style, @@ -2279,59 +2311,161 @@ static const nsCSSProperty gBorderColorSubpropTable[] = { // Code relies on these being in top-right-bottom-left order. // Code relies on these matching the NS_SIDE_* constants. eCSSProperty_border_top_color, - eCSSProperty_border_right_color, + eCSSProperty_border_right_color_value, eCSSProperty_border_bottom_color, - eCSSProperty_border_left_color, + eCSSProperty_border_left_color_value, + // extras: + eCSSProperty_border_left_color_ltr_source, + eCSSProperty_border_left_color_rtl_source, + eCSSProperty_border_right_color_ltr_source, + eCSSProperty_border_right_color_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gBorderEndColorSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_border_end_color_value, + eCSSProperty_border_right_color_ltr_source, + eCSSProperty_border_left_color_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gBorderLeftColorSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_border_left_color_value, + eCSSProperty_border_left_color_ltr_source, + eCSSProperty_border_left_color_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gBorderRightColorSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_border_right_color_value, + eCSSProperty_border_right_color_ltr_source, + eCSSProperty_border_right_color_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gBorderStartColorSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_border_start_color_value, + eCSSProperty_border_left_color_ltr_source, + eCSSProperty_border_right_color_rtl_source, eCSSProperty_UNKNOWN }; static const nsCSSProperty gBorderEndSubpropTable[] = { - // Declaration.cpp output the subproperties in this order. + // nsCSSDeclaration.cpp output the subproperties in this order. // It also depends on the color being third. - eCSSProperty_border_end_width, - eCSSProperty_border_end_style, - eCSSProperty_border_end_color, + eCSSProperty_border_end_width_value, + eCSSProperty_border_end_style_value, + eCSSProperty_border_end_color_value, + // extras: + eCSSProperty_border_right_width_ltr_source, + eCSSProperty_border_left_width_rtl_source, + eCSSProperty_border_right_style_ltr_source, + eCSSProperty_border_left_style_rtl_source, + eCSSProperty_border_right_color_ltr_source, + eCSSProperty_border_left_color_rtl_source, eCSSProperty_UNKNOWN }; static const nsCSSProperty gBorderLeftSubpropTable[] = { - // Declaration.cpp outputs the subproperties in this order. + // nsCSSDeclaration.cpp outputs the subproperties in this order. // It also depends on the color being third. - eCSSProperty_border_left_width, - eCSSProperty_border_left_style, - eCSSProperty_border_left_color, + eCSSProperty_border_left_width_value, + eCSSProperty_border_left_style_value, + eCSSProperty_border_left_color_value, + // extras: + eCSSProperty_border_left_width_ltr_source, + eCSSProperty_border_left_width_rtl_source, + eCSSProperty_border_left_style_ltr_source, + eCSSProperty_border_left_style_rtl_source, + eCSSProperty_border_left_color_ltr_source, + eCSSProperty_border_left_color_rtl_source, eCSSProperty_UNKNOWN }; static const nsCSSProperty gBorderRightSubpropTable[] = { - // Declaration.cpp outputs the subproperties in this order. + // nsCSSDeclaration.cpp outputs the subproperties in this order. // It also depends on the color being third. - eCSSProperty_border_right_width, - eCSSProperty_border_right_style, - eCSSProperty_border_right_color, + eCSSProperty_border_right_width_value, + eCSSProperty_border_right_style_value, + eCSSProperty_border_right_color_value, + // extras: + eCSSProperty_border_right_width_ltr_source, + eCSSProperty_border_right_width_rtl_source, + eCSSProperty_border_right_style_ltr_source, + eCSSProperty_border_right_style_rtl_source, + eCSSProperty_border_right_color_ltr_source, + eCSSProperty_border_right_color_rtl_source, eCSSProperty_UNKNOWN }; static const nsCSSProperty gBorderStartSubpropTable[] = { - // Declaration.cpp outputs the subproperties in this order. + // nsCSSDeclaration.cpp outputs the subproperties in this order. // It also depends on the color being third. - eCSSProperty_border_start_width, - eCSSProperty_border_start_style, - eCSSProperty_border_start_color, + eCSSProperty_border_start_width_value, + eCSSProperty_border_start_style_value, + eCSSProperty_border_start_color_value, + // extras: + eCSSProperty_border_left_width_ltr_source, + eCSSProperty_border_right_width_rtl_source, + eCSSProperty_border_left_style_ltr_source, + eCSSProperty_border_right_style_rtl_source, + eCSSProperty_border_left_color_ltr_source, + eCSSProperty_border_right_color_rtl_source, eCSSProperty_UNKNOWN }; static const nsCSSProperty gBorderStyleSubpropTable[] = { // Code relies on these being in top-right-bottom-left order. eCSSProperty_border_top_style, - eCSSProperty_border_right_style, + eCSSProperty_border_right_style_value, eCSSProperty_border_bottom_style, - eCSSProperty_border_left_style, + eCSSProperty_border_left_style_value, + // extras: + eCSSProperty_border_left_style_ltr_source, + eCSSProperty_border_left_style_rtl_source, + eCSSProperty_border_right_style_ltr_source, + eCSSProperty_border_right_style_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gBorderLeftStyleSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_border_left_style_value, + eCSSProperty_border_left_style_ltr_source, + eCSSProperty_border_left_style_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gBorderRightStyleSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_border_right_style_value, + eCSSProperty_border_right_style_ltr_source, + eCSSProperty_border_right_style_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gBorderStartStyleSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_border_start_style_value, + eCSSProperty_border_left_style_ltr_source, + eCSSProperty_border_right_style_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gBorderEndStyleSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_border_end_style_value, + eCSSProperty_border_right_style_ltr_source, + eCSSProperty_border_left_style_rtl_source, eCSSProperty_UNKNOWN }; static const nsCSSProperty gBorderTopSubpropTable[] = { - // Declaration.cpp outputs the subproperties in this order. + // nsCSSDeclaration.cpp outputs the subproperties in this order. // It also depends on the color being third. eCSSProperty_border_top_width, eCSSProperty_border_top_style, @@ -2342,9 +2476,46 @@ static const nsCSSProperty gBorderTopSubpropTable[] = { static const nsCSSProperty gBorderWidthSubpropTable[] = { // Code relies on these being in top-right-bottom-left order. eCSSProperty_border_top_width, - eCSSProperty_border_right_width, + eCSSProperty_border_right_width_value, eCSSProperty_border_bottom_width, - eCSSProperty_border_left_width, + eCSSProperty_border_left_width_value, + // extras: + eCSSProperty_border_left_width_ltr_source, + eCSSProperty_border_left_width_rtl_source, + eCSSProperty_border_right_width_ltr_source, + eCSSProperty_border_right_width_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gBorderLeftWidthSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_border_left_width_value, + eCSSProperty_border_left_width_ltr_source, + eCSSProperty_border_left_width_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gBorderRightWidthSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_border_right_width_value, + eCSSProperty_border_right_width_ltr_source, + eCSSProperty_border_right_width_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gBorderStartWidthSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_border_start_width_value, + eCSSProperty_border_left_width_ltr_source, + eCSSProperty_border_right_width_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gBorderEndWidthSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_border_end_width_value, + eCSSProperty_border_right_width_ltr_source, + eCSSProperty_border_left_width_rtl_source, eCSSProperty_UNKNOWN }; @@ -2390,9 +2561,46 @@ static const nsCSSProperty gListStyleSubpropTable[] = { static const nsCSSProperty gMarginSubpropTable[] = { // Code relies on these being in top-right-bottom-left order. eCSSProperty_margin_top, - eCSSProperty_margin_right, + eCSSProperty_margin_right_value, eCSSProperty_margin_bottom, - eCSSProperty_margin_left, + eCSSProperty_margin_left_value, + // extras: + eCSSProperty_margin_left_ltr_source, + eCSSProperty_margin_left_rtl_source, + eCSSProperty_margin_right_ltr_source, + eCSSProperty_margin_right_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gMarginLeftSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_margin_left_value, + eCSSProperty_margin_left_ltr_source, + eCSSProperty_margin_left_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gMarginRightSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_margin_right_value, + eCSSProperty_margin_right_ltr_source, + eCSSProperty_margin_right_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gMarginStartSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_margin_start_value, + eCSSProperty_margin_left_ltr_source, + eCSSProperty_margin_right_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gMarginEndSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_margin_end_value, + eCSSProperty_margin_right_ltr_source, + eCSSProperty_margin_left_rtl_source, eCSSProperty_UNKNOWN }; @@ -2480,9 +2688,46 @@ static const nsCSSProperty gOverflowSubpropTable[] = { static const nsCSSProperty gPaddingSubpropTable[] = { // Code relies on these being in top-right-bottom-left order. eCSSProperty_padding_top, - eCSSProperty_padding_right, + eCSSProperty_padding_right_value, eCSSProperty_padding_bottom, - eCSSProperty_padding_left, + eCSSProperty_padding_left_value, + // extras: + eCSSProperty_padding_left_ltr_source, + eCSSProperty_padding_left_rtl_source, + eCSSProperty_padding_right_ltr_source, + eCSSProperty_padding_right_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gPaddingLeftSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_padding_left_value, + eCSSProperty_padding_left_ltr_source, + eCSSProperty_padding_left_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gPaddingRightSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_padding_right_value, + eCSSProperty_padding_right_ltr_source, + eCSSProperty_padding_right_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gPaddingStartSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_padding_start_value, + eCSSProperty_padding_left_ltr_source, + eCSSProperty_padding_right_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gPaddingEndSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_padding_end_value, + eCSSProperty_padding_right_ltr_source, + eCSSProperty_padding_left_rtl_source, eCSSProperty_UNKNOWN }; @@ -2730,16 +2975,11 @@ nsCSSProps::gPropertyIndexInStruct[eCSSProperty_COUNT_no_shorthands] = { #define CSS_PROP_BACKENDONLY(name_, id_, method_, flags_, pref_, \ parsevariant_, kwtable_) \ size_t(-1), - #define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, \ - kwtable_, stylestruct_, stylestructoffset_, \ - animtype_) \ - size_t(-1), #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \ kwtable_, stylestruct_, stylestructoffset_, animtype_) \ ePropertyIndex_for_##id_, #include "nsCSSPropList.h" #undef CSS_PROP - #undef CSS_PROP_LOGICAL #undef CSS_PROP_BACKENDONLY }; @@ -2749,9 +2989,7 @@ nsCSSProps::gPropertyEnabled[eCSSProperty_COUNT_with_aliases] = { #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \ kwtable_, stylestruct_, stylestructoffset_, animtype_) \ true, - #define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" - #undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) \ @@ -2764,20 +3002,3 @@ nsCSSProps::gPropertyEnabled[eCSSProperty_COUNT_with_aliases] = { #include "nsCSSPropAliasList.h" #undef CSS_PROP_ALIAS }; - -// Check that all properties defined using CSS_PROP_*_LOGICAL macros use -// the CSS_PROPERTY_LOGICAL flag. -#define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \ - kwtable_, stylestruct_, stylestructoffset_, animtype_) \ - static_assert(!((flags_) & CSS_PROPERTY_LOGICAL), \ - "only properties defined with CSS_PROP_LOGICAL can use " \ - "the CSS_PROPERTY_LOGICAL flag"); -#define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, \ - kwtable_, stylestruct_, stylestructoffset_, \ - animtype_) \ - static_assert((flags_) & CSS_PROPERTY_LOGICAL, \ - "properties defined with CSS_PROP_LOGICAL must also use " \ - "the CSS_PROPERTY_LOGICAL flag"); -#include "nsCSSPropList.h" -#undef CSS_PROP_LOGICAL -#undef CSS_PROP diff --git a/layout/style/nsCSSProps.h b/layout/style/nsCSSProps.h index 39e2e8b87c2..5613a0507b6 100644 --- a/layout/style/nsCSSProps.h +++ b/layout/style/nsCSSProps.h @@ -103,8 +103,9 @@ // Flags for the kFlagsTable bitfield (flags_ in nsCSSPropList.h) -// This property is a logical property (such as padding-inline-start). -#define CSS_PROPERTY_LOGICAL (1<<0) +// A property that is a *-ltr-source or *-rtl-source property for one of +// the directional pseudo-shorthand properties. +#define CSS_PROPERTY_DIRECTIONAL_SOURCE (1<<0) #define CSS_PROPERTY_VALUE_LIST_USES_COMMAS (1<<1) /* otherwise spaces */ @@ -130,7 +131,12 @@ // list. #define CSS_PROPERTY_IMAGE_IS_IN_ARRAY_0 (1<<6) -// Flag (1<<7) is currently free. +// This is a property for which the computed value should generally be +// reported as the computed value of a property of a different name. In +// particular, the directional box properties (margin-left-value, etc.) +// should be reported as being margin-left, etc. Call +// nsCSSProps::OtherNameFor to get the other property. +#define CSS_PROPERTY_REPORT_OTHER_NAME (1<<7) // This property allows calc() between lengths and percentages and // stores such calc() expressions in its style structs (typically in an @@ -320,6 +326,11 @@ public: static const nsAFlatCString& GetStringValue(nsCSSFontDesc aFontDesc); static const nsAFlatCString& GetStringValue(nsCSSCounterDesc aCounterDesc); + // Get the property to report the computed value of aProperty as being + // the computed value of. aProperty must have the + // CSS_PROPERTY_REPORT_OTHER_NAME bit set. + static nsCSSProperty OtherNameFor(nsCSSProperty aProperty); + // Given a CSS Property and a Property Enum Value // Return back a const nsString& representation of the // value. Return back nullstr if no value is found diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index de6df5def34..c772ee0d560 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -5868,9 +5868,7 @@ nsComputedDOMStyle::RegisterPrefChangeCallbacks() #define CSS_PROP(prop_, id_, method_, flags_, pref_, parsevariant_, \ kwtable_, stylestruct_, stylestructoffset_, animtype_) \ REGISTER_CALLBACK(pref_) -#define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" -#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP #undef REGISTER_CALLBACK } @@ -5886,9 +5884,7 @@ nsComputedDOMStyle::UnregisterPrefChangeCallbacks() #define CSS_PROP(prop_, id_, method_, flags_, pref_, parsevariant_, \ kwtable_, stylestruct_, stylestructoffset_, animtype_) \ UNREGISTER_CALLBACK(pref_) -#define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" -#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP #undef UNREGISTER_CALLBACK } diff --git a/layout/style/nsDOMCSSDeclaration.h b/layout/style/nsDOMCSSDeclaration.h index 329cfb99f4e..eed8389b55a 100644 --- a/layout/style/nsDOMCSSDeclaration.h +++ b/layout/style/nsDOMCSSDeclaration.h @@ -79,7 +79,6 @@ public: } #define CSS_PROP_LIST_EXCLUDE_INTERNAL -#define CSS_PROP_LIST_INCLUDE_LOGICAL #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) \ CSS_PROP(name_, id_, method_, flags_, pref_, X, X, X, X, X) #include "nsCSSPropList.h" @@ -90,7 +89,6 @@ public: #undef CSS_PROP_ALIAS #undef CSS_PROP_SHORTHAND -#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP_LIST_EXCLUDE_INTERNAL #undef CSS_PROP #undef CSS_PROP_PUBLIC_OR_PRIVATE diff --git a/layout/style/nsRuleData.h b/layout/style/nsRuleData.h index 7b9d7ec0ac3..53d6f777ccb 100644 --- a/layout/style/nsRuleData.h +++ b/layout/style/nsRuleData.h @@ -77,7 +77,7 @@ struct nsRuleData "calling nsRuleData::ValueFor on property not in mSIDs"); NS_ABORT_IF_FALSE(sid != eStyleStruct_BackendOnly && indexInStruct != size_t(-1), - "backend-only or logical property"); + "backend-only property"); return mValueStorage + mValueOffsets[sid] + indexInStruct; } @@ -116,9 +116,7 @@ struct nsRuleData #define CSS_PROP_BACKENDONLY(name_, id_, method_, flags_, pref_, \ parsevariant_, kwtable_) \ /* empty; backend-only structs are not in nsRuleData */ - #define CSS_PROP_LIST_EXCLUDE_LOGICAL #include "nsCSSPropList.h" - #undef CSS_PROP_LIST_EXCLUDE_LOGICAL #undef CSS_PROP #undef CSS_PROP_PUBLIC_OR_PRIVATE #undef CSS_PROP_BACKENDONLY diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 5c8425ad680..29c3d7de994 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -2572,6 +2572,65 @@ nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, nsStyleContext* aContex return nullptr; } +/* + * This function handles cascading of *-left or *-right box properties + * against *-start (which is L for LTR and R for RTL) or *-end (which is + * R for LTR and L for RTL). + * + * Cascading these properties correctly is hard because we need to + * cascade two properties as one, but which two properties depends on a + * third property ('direction'). We solve this by treating each of + * these properties (say, 'margin-start') as a shorthand that sets a + * property containing the value of the property specified + * ('margin-start-value') and sets a pair of properties + * ('margin-left-ltr-source' and 'margin-right-rtl-source') saying which + * of the properties we use. Thus, when we want to compute the value of + * 'margin-left' when 'direction' is 'ltr', we look at the value of + * 'margin-left-ltr-source', which tells us whether to use the highest + * 'margin-left' in the cascade or the highest 'margin-start'. + * + * Finally, since we can compute the normal (*-left and *-right) + * properties in a loop, this function works by modifying the data we + * will use in that loop (which the caller must copy from the const + * input). + */ +void +nsRuleNode::AdjustLogicalBoxProp(nsStyleContext* aContext, + const nsCSSValue& aLTRSource, + const nsCSSValue& aRTLSource, + const nsCSSValue& aLTRLogicalValue, + const nsCSSValue& aRTLLogicalValue, + mozilla::css::Side aSide, + nsCSSRect& aValueRect, + bool& aCanStoreInRuleTree) +{ + bool LTRlogical = aLTRSource.GetUnit() == eCSSUnit_Enumerated && + aLTRSource.GetIntValue() == NS_BOXPROP_SOURCE_LOGICAL; + bool RTLlogical = aRTLSource.GetUnit() == eCSSUnit_Enumerated && + aRTLSource.GetIntValue() == NS_BOXPROP_SOURCE_LOGICAL; + if (LTRlogical || RTLlogical) { + // We can't cache anything on the rule tree if we use any data from + // the style context, since data cached in the rule tree could be + // used with a style context with a different value. + aCanStoreInRuleTree = false; + uint8_t dir = aContext->StyleVisibility()->mDirection; + + if (dir == NS_STYLE_DIRECTION_LTR) { + if (LTRlogical) + aValueRect.*(nsCSSRect::sides[aSide]) = aLTRLogicalValue; + } else { + if (RTLlogical) + aValueRect.*(nsCSSRect::sides[aSide]) = aRTLLogicalValue; + } + } else if (aLTRLogicalValue.GetUnit() == eCSSUnit_Inherit || + aRTLLogicalValue.GetUnit() == eCSSUnit_Inherit) { + // It actually is valid to store this in the ruletree, since + // LTRlogical and RTLlogical are both false, but doing that will + // trigger asserts. Silence those. + aCanStoreInRuleTree = false; + } +} + /** * Begin an nsRuleNode::Compute*Data function for an inherited struct. * @@ -6443,13 +6502,28 @@ nsRuleNode::ComputeMarginData(void* aStartStruct, { COMPUTE_START_RESET(Margin, (), margin, parentMargin) - // margin: length, percent, calc, inherit - const nsCSSProperty* subprops = - nsCSSProps::SubpropertyEntryFor(eCSSProperty_margin); - nsStyleCoord coord; + // margin: length, percent, auto, inherit + nsStyleCoord coord; + nsCSSRect ourMargin; + ourMargin.mTop = *aRuleData->ValueForMarginTop(); + ourMargin.mRight = *aRuleData->ValueForMarginRightValue(); + ourMargin.mBottom = *aRuleData->ValueForMarginBottom(); + ourMargin.mLeft = *aRuleData->ValueForMarginLeftValue(); + AdjustLogicalBoxProp(aContext, + *aRuleData->ValueForMarginLeftLTRSource(), + *aRuleData->ValueForMarginLeftRTLSource(), + *aRuleData->ValueForMarginStartValue(), + *aRuleData->ValueForMarginEndValue(), + NS_SIDE_LEFT, ourMargin, canStoreInRuleTree); + AdjustLogicalBoxProp(aContext, + *aRuleData->ValueForMarginRightLTRSource(), + *aRuleData->ValueForMarginRightRTLSource(), + *aRuleData->ValueForMarginEndValue(), + *aRuleData->ValueForMarginStartValue(), + NS_SIDE_RIGHT, ourMargin, canStoreInRuleTree); NS_FOR_CSS_SIDES(side) { nsStyleCoord parentCoord = parentMargin->mMargin.Get(side); - if (SetCoord(*aRuleData->ValueFor(subprops[side]), + if (SetCoord(ourMargin.*(nsCSSRect::sides[side]), coord, parentCoord, SETCOORD_LPAH | SETCOORD_INITIAL_ZERO | SETCOORD_STORE_CALC | SETCOORD_UNSET_INITIAL, @@ -6586,12 +6660,27 @@ nsRuleNode::ComputeBorderData(void* aStartStruct, } // border-width, border-*-width: length, enum, inherit - nsStyleCoord coord; - { - const nsCSSProperty* subprops = - nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_width); + nsStyleCoord coord; + nsCSSRect ourBorderWidth; + ourBorderWidth.mTop = *aRuleData->ValueForBorderTopWidth(); + ourBorderWidth.mRight = *aRuleData->ValueForBorderRightWidthValue(); + ourBorderWidth.mBottom = *aRuleData->ValueForBorderBottomWidth(); + ourBorderWidth.mLeft = *aRuleData->ValueForBorderLeftWidthValue(); + AdjustLogicalBoxProp(aContext, + *aRuleData->ValueForBorderLeftWidthLTRSource(), + *aRuleData->ValueForBorderLeftWidthRTLSource(), + *aRuleData->ValueForBorderStartWidthValue(), + *aRuleData->ValueForBorderEndWidthValue(), + NS_SIDE_LEFT, ourBorderWidth, canStoreInRuleTree); + AdjustLogicalBoxProp(aContext, + *aRuleData->ValueForBorderRightWidthLTRSource(), + *aRuleData->ValueForBorderRightWidthRTLSource(), + *aRuleData->ValueForBorderEndWidthValue(), + *aRuleData->ValueForBorderStartWidthValue(), + NS_SIDE_RIGHT, ourBorderWidth, canStoreInRuleTree); + { // scope for compilers with broken |for| loop scoping NS_FOR_CSS_SIDES(side) { - const nsCSSValue& value = *aRuleData->ValueFor(subprops[side]); + const nsCSSValue &value = ourBorderWidth.*(nsCSSRect::sides[side]); NS_ASSERTION(eCSSUnit_Percent != value.GetUnit(), "Percentage borders not implemented yet " "If implementing, make sure to fix all consumers of " @@ -6634,11 +6723,26 @@ nsRuleNode::ComputeBorderData(void* aStartStruct, } // border-style, border-*-style: enum, inherit - { - const nsCSSProperty* subprops = - nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_style); + nsCSSRect ourBorderStyle; + ourBorderStyle.mTop = *aRuleData->ValueForBorderTopStyle(); + ourBorderStyle.mRight = *aRuleData->ValueForBorderRightStyleValue(); + ourBorderStyle.mBottom = *aRuleData->ValueForBorderBottomStyle(); + ourBorderStyle.mLeft = *aRuleData->ValueForBorderLeftStyleValue(); + AdjustLogicalBoxProp(aContext, + *aRuleData->ValueForBorderLeftStyleLTRSource(), + *aRuleData->ValueForBorderLeftStyleRTLSource(), + *aRuleData->ValueForBorderStartStyleValue(), + *aRuleData->ValueForBorderEndStyleValue(), + NS_SIDE_LEFT, ourBorderStyle, canStoreInRuleTree); + AdjustLogicalBoxProp(aContext, + *aRuleData->ValueForBorderRightStyleLTRSource(), + *aRuleData->ValueForBorderRightStyleRTLSource(), + *aRuleData->ValueForBorderEndStyleValue(), + *aRuleData->ValueForBorderStartStyleValue(), + NS_SIDE_RIGHT, ourBorderStyle, canStoreInRuleTree); + { // scope for compilers with broken |for| loop scoping NS_FOR_CSS_SIDES(side) { - const nsCSSValue& value = *aRuleData->ValueFor(subprops[side]); + const nsCSSValue &value = ourBorderStyle.*(nsCSSRect::sides[side]); nsCSSUnit unit = value.GetUnit(); NS_ABORT_IF_FALSE(eCSSUnit_None != unit, "'none' should be handled as enumerated value"); @@ -6718,12 +6822,27 @@ nsRuleNode::ComputeBorderData(void* aStartStruct, } // border-color, border-*-color: color, string, enum, inherit - { - const nsCSSProperty* subprops = - nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_color); - bool foreground; + bool foreground; + nsCSSRect ourBorderColor; + ourBorderColor.mTop = *aRuleData->ValueForBorderTopColor(); + ourBorderColor.mRight = *aRuleData->ValueForBorderRightColorValue(); + ourBorderColor.mBottom = *aRuleData->ValueForBorderBottomColor(); + ourBorderColor.mLeft = *aRuleData->ValueForBorderLeftColorValue(); + AdjustLogicalBoxProp(aContext, + *aRuleData->ValueForBorderLeftColorLTRSource(), + *aRuleData->ValueForBorderLeftColorRTLSource(), + *aRuleData->ValueForBorderStartColorValue(), + *aRuleData->ValueForBorderEndColorValue(), + NS_SIDE_LEFT, ourBorderColor, canStoreInRuleTree); + AdjustLogicalBoxProp(aContext, + *aRuleData->ValueForBorderRightColorLTRSource(), + *aRuleData->ValueForBorderRightColorRTLSource(), + *aRuleData->ValueForBorderEndColorValue(), + *aRuleData->ValueForBorderStartColorValue(), + NS_SIDE_RIGHT, ourBorderColor, canStoreInRuleTree); + { // scope for compilers with broken |for| loop scoping NS_FOR_CSS_SIDES(side) { - const nsCSSValue& value = *aRuleData->ValueFor(subprops[side]); + const nsCSSValue &value = ourBorderColor.*(nsCSSRect::sides[side]); if (eCSSUnit_Inherit == value.GetUnit()) { canStoreInRuleTree = false; if (parentContext) { @@ -6894,13 +7013,28 @@ nsRuleNode::ComputePaddingData(void* aStartStruct, { COMPUTE_START_RESET(Padding, (), padding, parentPadding) - // padding: length, percent, calc, inherit - const nsCSSProperty* subprops = - nsCSSProps::SubpropertyEntryFor(eCSSProperty_padding); - nsStyleCoord coord; + // padding: length, percent, inherit + nsStyleCoord coord; + nsCSSRect ourPadding; + ourPadding.mTop = *aRuleData->ValueForPaddingTop(); + ourPadding.mRight = *aRuleData->ValueForPaddingRightValue(); + ourPadding.mBottom = *aRuleData->ValueForPaddingBottom(); + ourPadding.mLeft = *aRuleData->ValueForPaddingLeftValue(); + AdjustLogicalBoxProp(aContext, + *aRuleData->ValueForPaddingLeftLTRSource(), + *aRuleData->ValueForPaddingLeftRTLSource(), + *aRuleData->ValueForPaddingStartValue(), + *aRuleData->ValueForPaddingEndValue(), + NS_SIDE_LEFT, ourPadding, canStoreInRuleTree); + AdjustLogicalBoxProp(aContext, + *aRuleData->ValueForPaddingRightLTRSource(), + *aRuleData->ValueForPaddingRightRTLSource(), + *aRuleData->ValueForPaddingEndValue(), + *aRuleData->ValueForPaddingStartValue(), + NS_SIDE_RIGHT, ourPadding, canStoreInRuleTree); NS_FOR_CSS_SIDES(side) { nsStyleCoord parentCoord = parentPadding->mPadding.Get(side); - if (SetCoord(*aRuleData->ValueFor(subprops[side]), + if (SetCoord(ourPadding.*(nsCSSRect::sides[side]), coord, parentCoord, SETCOORD_LPH | SETCOORD_INITIAL_ZERO | SETCOORD_STORE_CALC | SETCOORD_UNSET_INITIAL, @@ -9355,15 +9489,21 @@ nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext, eCSSProperty_border_top_color, eCSSProperty_border_top_style, eCSSProperty_border_top_width, - eCSSProperty_border_right_color, - eCSSProperty_border_right_style, - eCSSProperty_border_right_width, + eCSSProperty_border_right_color_value, + eCSSProperty_border_right_style_value, + eCSSProperty_border_right_width_value, eCSSProperty_border_bottom_color, eCSSProperty_border_bottom_style, eCSSProperty_border_bottom_width, - eCSSProperty_border_left_color, - eCSSProperty_border_left_style, - eCSSProperty_border_left_width, + eCSSProperty_border_left_color_value, + eCSSProperty_border_left_style_value, + eCSSProperty_border_left_width_value, + eCSSProperty_border_start_color_value, + eCSSProperty_border_start_style_value, + eCSSProperty_border_start_width_value, + eCSSProperty_border_end_color_value, + eCSSProperty_border_end_style_value, + eCSSProperty_border_end_width_value, eCSSProperty_border_top_left_radius, eCSSProperty_border_top_right_radius, eCSSProperty_border_bottom_right_radius, @@ -9372,9 +9512,11 @@ nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext, static const nsCSSProperty paddingValues[] = { eCSSProperty_padding_top, - eCSSProperty_padding_right, + eCSSProperty_padding_right_value, eCSSProperty_padding_bottom, - eCSSProperty_padding_left, + eCSSProperty_padding_left_value, + eCSSProperty_padding_start_value, + eCSSProperty_padding_end_value, }; static const nsCSSProperty textShadowValues[] = { diff --git a/layout/style/nsRuleNode.h b/layout/style/nsRuleNode.h index 075c9e1e10f..7ffa327f892 100644 --- a/layout/style/nsRuleNode.h +++ b/layout/style/nsRuleNode.h @@ -643,6 +643,15 @@ protected: uint8_t aGenericFontID, nsStyleFont* aFont); + void AdjustLogicalBoxProp(nsStyleContext* aContext, + const nsCSSValue& aLTRSource, + const nsCSSValue& aRTLSource, + const nsCSSValue& aLTRLogicalValue, + const nsCSSValue& aRTLLogicalValue, + mozilla::css::Side aSide, + nsCSSRect& aValueRect, + bool& aCanStoreInRuleTree); + inline RuleDetail CheckSpecifiedProperties(const nsStyleStructID aSID, const nsRuleData* aRuleData); diff --git a/layout/style/nsStyleConsts.h b/layout/style/nsStyleConsts.h index 6e572b8b59b..a6de27d3e22 100644 --- a/layout/style/nsStyleConsts.h +++ b/layout/style/nsStyleConsts.h @@ -56,6 +56,10 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) { #define NS_SIDE_TO_HALF_CORNER(side_, second_, parallel_) \ ((((side_) + !!(second_))*2 + ((side_) + !(parallel_))%2) % 8) +// {margin,border-{width,style,color},padding}-{left,right}-{ltr,rtl}-source +#define NS_BOXPROP_SOURCE_PHYSICAL 0 +#define NS_BOXPROP_SOURCE_LOGICAL 1 + // box-sizing #define NS_STYLE_BOX_SIZING_CONTENT 0 #define NS_STYLE_BOX_SIZING_PADDING 1 diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp index b296f646cb1..9990af2d387 100644 --- a/layout/style/nsStyleContext.cpp +++ b/layout/style/nsStyleContext.cpp @@ -1004,9 +1004,9 @@ nsStyleContext::GetVisitedDependentColor(nsCSSProperty aProperty) NS_ASSERTION(aProperty == eCSSProperty_color || aProperty == eCSSProperty_background_color || aProperty == eCSSProperty_border_top_color || - aProperty == eCSSProperty_border_right_color || + aProperty == eCSSProperty_border_right_color_value || aProperty == eCSSProperty_border_bottom_color || - aProperty == eCSSProperty_border_left_color || + aProperty == eCSSProperty_border_left_color_value || aProperty == eCSSProperty_outline_color || aProperty == eCSSProperty__moz_column_rule_color || aProperty == eCSSProperty_text_decoration_color || diff --git a/layout/style/nsTransitionManager.cpp b/layout/style/nsTransitionManager.cpp index 121c436d281..c128c095453 100644 --- a/layout/style/nsTransitionManager.cpp +++ b/layout/style/nsTransitionManager.cpp @@ -695,6 +695,10 @@ nsTransitionManager::FlushTransitions(FlushFlags aFlags) MOZ_ASSERT(player->GetSource()->Properties().Length() == 1, "Should have one animation property for a transition"); nsCSSProperty prop = player->GetSource()->Properties()[0].mProperty; + if (nsCSSProps::PropHasFlags(prop, CSS_PROPERTY_REPORT_OTHER_NAME)) + { + prop = nsCSSProps::OtherNameFor(prop); + } TimeDuration duration = player->GetSource()->Timing().mIterationDuration; events.AppendElement( diff --git a/layout/style/test/ListCSSProperties.cpp b/layout/style/test/ListCSSProperties.cpp index 12e6e0c8c17..e213e25377d 100644 --- a/layout/style/test/ListCSSProperties.cpp +++ b/layout/style/test/ListCSSProperties.cpp @@ -21,11 +21,9 @@ const PropertyInfo gLonghandProperties[] = { #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \ stylestruct_, stylestructoffset_, animtype_) \ { #name_, #method_, pref_ }, -#define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" -#undef CSS_PROP_LIST_EXCLUDE_LOGICAL #undef CSS_PROP #undef CSS_PROP_PUBLIC_OR_PRIVATE @@ -42,11 +40,9 @@ const char* gLonghandPropertiesWithDOMProp[] = { #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \ stylestruct_, stylestructoffset_, animtype_) \ #name_, -#define CSS_PROP_LIST_INCLUDE_LOGICAL #include "nsCSSPropList.h" -#undef CSS_PROP_LIST_INCLUDE_LOGICAL #undef CSS_PROP #undef CSS_PROP_LIST_EXCLUDE_INTERNAL @@ -108,6 +104,46 @@ const char *gInaccessibleProperties[] = { "-x-span", "-x-system-font", "-x-text-zoom", + "border-end-color-value", + "border-end-style-value", + "border-end-width-value", + "border-left-color-value", + "border-left-color-ltr-source", + "border-left-color-rtl-source", + "border-left-style-value", + "border-left-style-ltr-source", + "border-left-style-rtl-source", + "border-left-width-value", + "border-left-width-ltr-source", + "border-left-width-rtl-source", + "border-right-color-value", + "border-right-color-ltr-source", + "border-right-color-rtl-source", + "border-right-style-value", + "border-right-style-ltr-source", + "border-right-style-rtl-source", + "border-right-width-value", + "border-right-width-ltr-source", + "border-right-width-rtl-source", + "border-start-color-value", + "border-start-style-value", + "border-start-width-value", + "margin-end-value", + "margin-left-value", + "margin-right-value", + "margin-start-value", + "margin-left-ltr-source", + "margin-left-rtl-source", + "margin-right-ltr-source", + "margin-right-rtl-source", + "padding-end-value", + "padding-left-value", + "padding-right-value", + "padding-start-value", + "padding-left-ltr-source", + "padding-left-rtl-source", + "padding-right-ltr-source", + "padding-right-rtl-source", "-moz-control-character-visibility", "-moz-script-level", // parsed by UA sheets only "-moz-script-size-multiplier", diff --git a/layout/style/test/css_properties_like_longhand.js b/layout/style/test/css_properties_like_longhand.js index 60b8fd5832c..1a6ee0e6a3d 100644 --- a/layout/style/test/css_properties_like_longhand.js +++ b/layout/style/test/css_properties_like_longhand.js @@ -1,3 +1,11 @@ var gShorthandPropertiesLikeLonghand = [ + { name: "-moz-margin-end", prop: "MozMarginEnd"}, + { name: "margin-left", prop: "marginLeft"}, + { name: "margin-right", prop: "marginRight"}, + { name: "-moz-margin-start", prop: "MozMarginStart"}, { name: "overflow", prop: "overflow"}, + { name: "-moz-padding-end", prop: "MozPaddingEnd"}, + { name: "padding-left", prop: "paddingLeft"}, + { name: "padding-right", prop: "paddingRight"}, + { name: "-moz-padding-start", prop: "MozPaddingStart"}, ]; diff --git a/layout/style/test/mochitest.ini b/layout/style/test/mochitest.ini index b9847682288..f852e43c2ba 100644 --- a/layout/style/test/mochitest.ini +++ b/layout/style/test/mochitest.ini @@ -243,7 +243,6 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(bug 870262, skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(bug 870262, :visited support) b2g-debug(bug 870262, :visited support) b2g-desktop(bug 870262, :visited support) [test_bug525952.html] [test_load_events_on_stylesheets.html] -[test_logical_properties.html] [test_page_parser.html] [test_bug732153.html] [test_bug732209.html] diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index 713e88acb90..34049760d6f 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -22,8 +22,6 @@ const CSS_TYPE_SHORTHAND_AND_LONGHAND = 2; // alias_for: optional, indicates that the property is an alias for // some other property that is the preferred serialization. (Type // must not be CSS_TYPE_LONGHAND.) -// logical: optional, indicates that the property is a logical directional -// property. (Type must be CSS_TYPE_LONGHAND.) // get_computed: if present, the property's computed value shows up on // another property, and this is a function used to get it // initial_values: Values whose computed value should be the same as the @@ -697,8 +695,7 @@ var gCSSProperties = { "-moz-border-end-color": { domProp: "MozBorderEndColor", inherited: false, - type: CSS_TYPE_LONGHAND, - logical: true, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, get_computed: logical_box_prop_get_computed, initial_values: [ "currentColor" ], other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ], @@ -707,8 +704,7 @@ var gCSSProperties = { "-moz-border-end-style": { domProp: "MozBorderEndStyle", inherited: false, - type: CSS_TYPE_LONGHAND, - logical: true, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, get_computed: logical_box_prop_get_computed, /* XXX hidden is sometimes the same as initial */ initial_values: [ "none" ], @@ -718,8 +714,7 @@ var gCSSProperties = { "-moz-border-end-width": { domProp: "MozBorderEndWidth", inherited: false, - type: CSS_TYPE_LONGHAND, - logical: true, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, get_computed: logical_box_prop_get_computed, prerequisites: { "-moz-border-end-style": "solid" }, initial_values: [ "medium", "3px", "calc(4px - 1px)" ], @@ -943,8 +938,7 @@ var gCSSProperties = { "-moz-border-start-color": { domProp: "MozBorderStartColor", inherited: false, - type: CSS_TYPE_LONGHAND, - logical: true, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, get_computed: logical_box_prop_get_computed, initial_values: [ "currentColor" ], other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ], @@ -953,8 +947,7 @@ var gCSSProperties = { "-moz-border-start-style": { domProp: "MozBorderStartStyle", inherited: false, - type: CSS_TYPE_LONGHAND, - logical: true, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, get_computed: logical_box_prop_get_computed, /* XXX hidden is sometimes the same as initial */ initial_values: [ "none" ], @@ -964,8 +957,7 @@ var gCSSProperties = { "-moz-border-start-width": { domProp: "MozBorderStartWidth", inherited: false, - type: CSS_TYPE_LONGHAND, - logical: true, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, get_computed: logical_box_prop_get_computed, prerequisites: { "-moz-border-start-style": "solid" }, initial_values: [ "medium", "3px", "calc(4px - 1px)" ], @@ -1438,8 +1430,7 @@ var gCSSProperties = { "-moz-margin-end": { domProp: "MozMarginEnd", inherited: false, - type: CSS_TYPE_LONGHAND, - logical: true, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, get_computed: logical_box_prop_get_computed, /* no subproperties */ /* auto may or may not be initial */ @@ -1457,8 +1448,7 @@ var gCSSProperties = { "-moz-margin-start": { domProp: "MozMarginStart", inherited: false, - type: CSS_TYPE_LONGHAND, - logical: true, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, get_computed: logical_box_prop_get_computed, /* no subproperties */ /* auto may or may not be initial */ @@ -1574,8 +1564,7 @@ var gCSSProperties = { "-moz-padding-end": { domProp: "MozPaddingEnd", inherited: false, - type: CSS_TYPE_LONGHAND, - logical: true, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, get_computed: logical_box_prop_get_computed, /* no subproperties */ initial_values: [ "0", "0px", "0%", "0em", "0ex", "calc(0pt)", "calc(0% + 0px)", "calc(-3px)", "calc(-1%)" ], @@ -1591,8 +1580,7 @@ var gCSSProperties = { "-moz-padding-start": { domProp: "MozPaddingStart", inherited: false, - type: CSS_TYPE_LONGHAND, - logical: true, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, get_computed: logical_box_prop_get_computed, /* no subproperties */ initial_values: [ "0", "0px", "0%", "0em", "0ex", "calc(0pt)", "calc(0% + 0px)", "calc(-3px)", "calc(-1%)" ], @@ -2145,7 +2133,7 @@ var gCSSProperties = { "border-left-color": { domProp: "borderLeftColor", inherited: false, - type: CSS_TYPE_LONGHAND, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, prerequisites: { "color": "black" }, initial_values: [ "currentColor", "-moz-use-text-color" ], other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ], @@ -2155,7 +2143,7 @@ var gCSSProperties = { "border-left-style": { domProp: "borderLeftStyle", inherited: false, - type: CSS_TYPE_LONGHAND, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, /* XXX hidden is sometimes the same as initial */ initial_values: [ "none" ], other_values: [ "solid", "dashed", "dotted", "double", "outset", "inset", "groove", "ridge" ], @@ -2164,7 +2152,7 @@ var gCSSProperties = { "border-left-width": { domProp: "borderLeftWidth", inherited: false, - type: CSS_TYPE_LONGHAND, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, prerequisites: { "border-left-style": "solid" }, initial_values: [ "medium", "3px", "calc(4px - 1px)" ], other_values: [ "thin", "thick", "1px", "2em", @@ -2192,7 +2180,7 @@ var gCSSProperties = { "border-right-color": { domProp: "borderRightColor", inherited: false, - type: CSS_TYPE_LONGHAND, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, prerequisites: { "color": "black" }, initial_values: [ "currentColor", "-moz-use-text-color" ], other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ], @@ -2202,7 +2190,7 @@ var gCSSProperties = { "border-right-style": { domProp: "borderRightStyle", inherited: false, - type: CSS_TYPE_LONGHAND, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, /* XXX hidden is sometimes the same as initial */ initial_values: [ "none" ], other_values: [ "solid", "dashed", "dotted", "double", "outset", "inset", "groove", "ridge" ], @@ -2211,7 +2199,7 @@ var gCSSProperties = { "border-right-width": { domProp: "borderRightWidth", inherited: false, - type: CSS_TYPE_LONGHAND, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, prerequisites: { "border-right-style": "solid" }, initial_values: [ "medium", "3px", "calc(4px - 1px)" ], other_values: [ "thin", "thick", "1px", "2em", @@ -2859,7 +2847,8 @@ var gCSSProperties = { "margin-left": { domProp: "marginLeft", inherited: false, - type: CSS_TYPE_LONGHAND, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, + /* no subproperties */ /* XXX testing auto has prerequisites */ initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)" ], other_values: [ "1px", "2em", "5%", ".5px", "+32px", "+.789px", "-.328px", "+0.56px", "-0.974px", "237px", "-289px", "-056px", "1987.45px", "-84.32px", @@ -2876,7 +2865,8 @@ var gCSSProperties = { "margin-right": { domProp: "marginRight", inherited: false, - type: CSS_TYPE_LONGHAND, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, + /* no subproperties */ /* XXX testing auto has prerequisites */ initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)" ], other_values: [ "1px", "2em", "5%", @@ -3130,7 +3120,8 @@ var gCSSProperties = { "padding-left": { domProp: "paddingLeft", inherited: false, - type: CSS_TYPE_LONGHAND, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, + /* no subproperties */ initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)", "calc(-3px)", "calc(-1%)" ], other_values: [ "1px", "2em", "5%", "calc(2px)", @@ -3145,7 +3136,8 @@ var gCSSProperties = { "padding-right": { domProp: "paddingRight", inherited: false, - type: CSS_TYPE_LONGHAND, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, + /* no subproperties */ initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)", "calc(-3px)", "calc(-1%)" ], other_values: [ "1px", "2em", "5%", "calc(2px)", @@ -4526,27 +4518,13 @@ var gCSSProperties = { function logical_box_prop_get_computed(cs, property) { - var ltr = cs.getPropertyValue("direction") == "ltr"; - if (/^-moz-/.test(property)) { - property = property.substring(5); - if (ltr) { - property = property.replace("-start", "-left") - .replace("-end", "-right"); - } else { - property = property.replace("-start", "-right") - .replace("-end", "-left"); - } - } else if (/-inline-(start|end)/.test(property)) { - if (ltr) { - property = property.replace("-inline-start", "-left") - .replace("-inline-end", "-right"); - } else { - property = property.replace("-inline-start", "-right") - .replace("-inline-end", "-left"); - } - } else { + if (! /^-moz-/.test(property)) throw "Unexpected property"; - } + property = property.substring(5); + if (cs.getPropertyValue("direction") == "ltr") + property = property.replace("-start", "-left").replace("-end", "-right"); + else + property = property.replace("-start", "-right").replace("-end", "-left"); return cs.getPropertyValue(property); } @@ -4617,177 +4595,7 @@ if (SpecialPowers.getBoolPref("layout.css.vertical-text.enabled")) { invalid_values: [ "auto", "all 2", "none all", "digits -3", "digits 0", "digits 12", "none 3", "digits 3.1415", "digits3", "digits 1", "digits 3 all", "digits foo", "digits all", "digits 3.0" ] - }, - "border-inline-end": { - domProp: "borderInlineEnd", - inherited: false, - type: CSS_TYPE_TRUE_SHORTHAND, - alias_for: "-moz-border-end", - subproperties: [ "border-inline-end-color", "border-inline-end-style", "border-inline-end-width" ], - initial_values: [ "none", "medium", "currentColor", "thin", "none medium currentcolor" ], - other_values: [ "solid", "green", "medium solid", "green solid", "10px solid", "thick solid", "5px green none" ], - invalid_values: [ "5%", "5", "5 green none" ] - }, - "border-inline-end-color": { - domProp: "borderInlineEndColor", - inherited: false, - type: CSS_TYPE_SHORTHAND_AND_LONGHAND, - alias_for: "-moz-border-end-color", - get_computed: logical_box_prop_get_computed, - initial_values: [ "currentColor" ], - other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ], - invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000", "000000" ] - }, - "border-inline-end-style": { - domProp: "borderInlineEndStyle", - inherited: false, - type: CSS_TYPE_SHORTHAND_AND_LONGHAND, - alias_for: "-moz-border-end-style", - get_computed: logical_box_prop_get_computed, - /* XXX hidden is sometimes the same as initial */ - initial_values: [ "none" ], - other_values: [ "solid", "dashed", "dotted", "double", "outset", "inset", "groove", "ridge" ], - invalid_values: [] - }, - "border-inline-end-width": { - domProp: "borderInlineEndWidth", - inherited: false, - type: CSS_TYPE_SHORTHAND_AND_LONGHAND, - alias_for: "-moz-border-end-width", - get_computed: logical_box_prop_get_computed, - prerequisites: { "border-inline-end-style": "solid" }, - initial_values: [ "medium", "3px", "calc(4px - 1px)" ], - other_values: [ "thin", "thick", "1px", "2em", - "calc(2px)", - "calc(-2px)", - "calc(0em)", - "calc(0px)", - "calc(5em)", - "calc(3*25px)", - "calc(25px*3)", - "calc(3*25px + 5em)", - ], - invalid_values: [ "5%", "5" ] - }, - "border-inline-start": { - domProp: "borderInlineStart", - inherited: false, - type: CSS_TYPE_TRUE_SHORTHAND, - alias_for: "-moz-border-start", - subproperties: [ "border-inline-start-color", "border-inline-start-style", "border-inline-start-width" ], - initial_values: [ "none", "medium", "currentColor", "thin", "none medium currentcolor" ], - other_values: [ "solid", "green", "medium solid", "green solid", "10px solid", "thick solid", "5px green none" ], - invalid_values: [ "5%", "5", "5 green solid" ] - }, - "border-inline-start-color": { - domProp: "borderInlineStartColor", - inherited: false, - type: CSS_TYPE_SHORTHAND_AND_LONGHAND, - alias_for: "-moz-border-start-color", - get_computed: logical_box_prop_get_computed, - initial_values: [ "currentColor" ], - other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ], - invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000", "000000" ] - }, - "border-inline-start-style": { - domProp: "borderInlineStartStyle", - inherited: false, - type: CSS_TYPE_SHORTHAND_AND_LONGHAND, - alias_for: "-moz-border-start-style", - get_computed: logical_box_prop_get_computed, - /* XXX hidden is sometimes the same as initial */ - initial_values: [ "none" ], - other_values: [ "solid", "dashed", "dotted", "double", "outset", "inset", "groove", "ridge" ], - invalid_values: [] - }, - "border-inline-start-width": { - domProp: "borderInlineStartWidth", - inherited: false, - type: CSS_TYPE_SHORTHAND_AND_LONGHAND, - alias_for: "-moz-border-start-width", - get_computed: logical_box_prop_get_computed, - prerequisites: { "border-inline-start-style": "solid" }, - initial_values: [ "medium", "3px", "calc(4px - 1px)" ], - other_values: [ "thin", "thick", "1px", "2em", - "calc(2px)", - "calc(-2px)", - "calc(0em)", - "calc(0px)", - "calc(5em)", - "calc(3*25px)", - "calc(25px*3)", - "calc(3*25px + 5em)", - ], - invalid_values: [ "5%", "5" ] - }, - "margin-inline-end": { - domProp: "marginInlineEnd", - inherited: false, - type: CSS_TYPE_SHORTHAND_AND_LONGHAND, - alias_for: "-moz-margin-end", - get_computed: logical_box_prop_get_computed, - /* XXX testing auto has prerequisites */ - initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)" ], - other_values: [ "1px", "2em", "5%", - "calc(2px)", - "calc(-2px)", - "calc(50%)", - "calc(3*25px)", - "calc(25px*3)", - "calc(3*25px + 50%)", - ], - invalid_values: [ "..25px", ".+5px", ".px", "-.px", "++5px", "-+4px", "+-3px", "--7px", "+-.6px", "-+.5px", "++.7px", "--.4px" ], - }, - "margin-inline-start": { - domProp: "marginInlineStart", - inherited: false, - type: CSS_TYPE_SHORTHAND_AND_LONGHAND, - alias_for: "-moz-margin-start", - get_computed: logical_box_prop_get_computed, - /* XXX testing auto has prerequisites */ - initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)" ], - other_values: [ "1px", "2em", "5%", - "calc(2px)", - "calc(-2px)", - "calc(50%)", - "calc(3*25px)", - "calc(25px*3)", - "calc(3*25px + 50%)", - ], - invalid_values: [ "..25px", ".+5px", ".px", "-.px", "++5px", "-+4px", "+-3px", "--7px", "+-.6px", "-+.5px", "++.7px", "--.4px" ], - }, - "padding-inline-end": { - domProp: "paddingInlineEnd", - inherited: false, - type: CSS_TYPE_SHORTHAND_AND_LONGHAND, - alias_for: "-moz-padding-end", - get_computed: logical_box_prop_get_computed, - initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)", "calc(-3px)", "calc(-1%)" ], - other_values: [ "1px", "2em", "5%", - "calc(2px)", - "calc(50%)", - "calc(3*25px)", - "calc(25px*3)", - "calc(3*25px + 50%)", - ], - invalid_values: [ ], - }, - "padding-inline-start": { - domProp: "paddingInlineStart", - inherited: false, - type: CSS_TYPE_SHORTHAND_AND_LONGHAND, - alias_for: "-moz-padding-start", - get_computed: logical_box_prop_get_computed, - initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)", "calc(-3px)", "calc(-1%)" ], - other_values: [ "1px", "2em", "5%", - "calc(2px)", - "calc(50%)", - "calc(3*25px)", - "calc(25px*3)", - "calc(3*25px + 50%)", - ], - invalid_values: [ ], - }, + } }; for (var prop in verticalTextProperties) { gCSSProperties[prop] = verticalTextProperties[prop]; diff --git a/layout/style/test/test_logical_properties.html b/layout/style/test/test_logical_properties.html deleted file mode 100644 index 4e194ae3ab7..00000000000 --- a/layout/style/test/test_logical_properties.html +++ /dev/null @@ -1,273 +0,0 @@ - - -Test for handling of logical and physical properties - - - - -
- - diff --git a/layout/style/test/test_page_parser.html b/layout/style/test/test_page_parser.html index 8c94be0bf17..d887cc090c0 100644 --- a/layout/style/test/test_page_parser.html +++ b/layout/style/test/test_page_parser.html @@ -26,9 +26,13 @@ // Check good properties with invalid units. { rule: _("margin: 2in; margin: 2vw;"), expected: { "margin-top": "2in", - "margin-right": "2in", + "margin-right-value": "2in", "margin-bottom": "2in", - "margin-left": "2in" + "margin-left-value": "2in", + "margin-left-ltr-source": "physical", + "margin-left-rtl-source": "physical", + "margin-right-ltr-source": "physical", + "margin-right-rtl-source": "physical" }}, { rule: _("margin-top: 2in; margin-top: 2vw;"), expected: {"margin-top": "2in"}}, { rule: _("margin-top: 2in; margin-top: 2vh;"), expected: {"margin-top": "2in"}}, @@ -36,16 +40,30 @@ { rule: _("margin-top: 2in; margin-top: 2vmin;"), expected: {"margin-top": "2in"}}, // Check good properties. + // NOTE: The margin-*-value and margin-*-source properties are not really + // expected and will need to be removed once bug 241234 is addressed. { rule: _("margin: 2in;"), expected: { "margin-top": "2in", - "margin-right": "2in", + "margin-right-value": "2in", "margin-bottom": "2in", - "margin-left": "2in" + "margin-left-value": "2in", + "margin-left-ltr-source": "physical", + "margin-left-rtl-source": "physical", + "margin-right-ltr-source": "physical", + "margin-right-rtl-source": "physical" }}, { rule: _("margin-top: 2in;"), expected: {"margin-top": "2in"}}, - { rule: _("margin-left: 2in;"), expected: {"margin-left": "2in"}}, + { rule: _("margin-left: 2in;"), expected: { + "margin-left-value": "2in", + "margin-left-ltr-source": "physical", + "margin-left-rtl-source": "physical", + }}, { rule: _("margin-bottom: 2in;"), expected: {"margin-bottom": "2in"}}, - { rule: _("margin-right: 2in;"), expected: {"margin-right": "2in"}} + { rule: _("margin-right: 2in;"), expected: { + "margin-right-value": "2in", + "margin-right-ltr-source": "physical", + "margin-right-rtl-source": "physical", + }} ]; var display = document.getElementById("display"); diff --git a/layout/style/test/test_property_database.html b/layout/style/test/test_property_database.html index aa5e5b2b6b8..7b550afa0e8 100644 --- a/layout/style/test/test_property_database.html +++ b/layout/style/test/test_property_database.html @@ -122,17 +122,6 @@ for (var prop in gCSSProperties) { "must have non-initial values for property '" + prop + "'"); } -/* - * Test that only longhand properties are listed as logical properties. - */ -for (var prop in gCSSProperties) { - var info = gCSSProperties[prop]; - if (info.logical) { - is(info.type, CSS_TYPE_LONGHAND, - "property '" + prop + "' is listed as CSS_TYPE_LONGHAND due to its " + - "being a logical property"); - } -} diff --git a/layout/style/test/test_value_computation.html b/layout/style/test/test_value_computation.html index cd48dfe6bf8..c0240e53f22 100644 --- a/layout/style/test/test_value_computation.html +++ b/layout/style/test/test_value_computation.html @@ -13,12 +13,7 @@