WebKit Bugzilla
Attachment 356603 Details for
Bug 176914
: Allow control over child order when adding nodes to the scrolling tree
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch 327061, rebased on top of bug 192398 (untested)
0002-Bug-176914-Async-iframes-in-the-scrolling-tree-shoul.patch (text/plain), 19.97 KB, created by
Frédéric Wang (:fredw)
on 2018-12-05 07:23:38 PST
(
hide
)
Description:
Patch 327061, rebased on top of bug 192398 (untested)
Filename:
MIME Type:
Creator:
Frédéric Wang (:fredw)
Created:
2018-12-05 07:23:38 PST
Size:
19.97 KB
patch
obsolete
>From 98a3fb90a1054d05b136c699e0828c18c7edb632 Mon Sep 17 00:00:00 2001 >From: Frederic Wang <fwang@igalia.com> >Date: Wed, 5 Dec 2018 16:21:45 +0100 >Subject: [PATCH xserver 2/2] Bug 176914 - Async iframes in the scrolling tree > should be in the z-index order > >--- > .../scrolling/AsyncScrollingCoordinator.cpp | 6 ++--- > .../scrolling/AsyncScrollingCoordinator.h | 2 +- > .../page/scrolling/ScrollingCoordinator.h | 2 +- > .../page/scrolling/ScrollingStateNode.cpp | 27 +++++++++++++++++-- > .../page/scrolling/ScrollingStateNode.h | 7 ++++- > .../page/scrolling/ScrollingStateTree.cpp | 16 ++++++----- > .../page/scrolling/ScrollingStateTree.h | 4 +-- > .../rendering/RenderLayerCompositor.cpp | 21 ++++++++------- > .../WebCore/rendering/RenderLayerCompositor.h | 4 +-- > .../RemoteScrollingCoordinatorTransaction.cpp | 9 +++++-- > 10 files changed, 68 insertions(+), 30 deletions(-) > >diff --git a/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp b/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp >index 2638826b507..25513f2a74d 100644 >--- a/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp >+++ b/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp >@@ -474,9 +474,9 @@ void AsyncScrollingCoordinator::scrollableAreaScrollbarLayerDidChange(Scrollable > scrollableArea.horizontalScrollbarLayerDidChange(); > } > >-ScrollingNodeID AsyncScrollingCoordinator::attachToStateTree(ScrollingNodeType nodeType, ScrollingNodeID newNodeID, ScrollingNodeID parentID) >+ScrollingNodeID AsyncScrollingCoordinator::attachToStateTree(ScrollingNodeType nodeType, ScrollingNodeID newNodeID, ScrollingNodeID parentID, size_t childIndex) > { >- return m_scrollingStateTree->attachNode(nodeType, newNodeID, parentID); >+ return m_scrollingStateTree->attachNode(nodeType, newNodeID, parentID, childIndex); > } > > void AsyncScrollingCoordinator::detachFromStateTree(ScrollingNodeID nodeID) >@@ -509,7 +509,7 @@ void AsyncScrollingCoordinator::ensureRootStateNodeForFrameView(FrameView& frame > // For non-main frames, it is only possible to arrive in this function from > // RenderLayerCompositor::updateBacking where the node has already been created. > ASSERT(frameView.frame().isMainFrame()); >- attachToStateTree(MainFrameScrollingNode, frameView.scrollLayerID(), 0); >+ attachToStateTree(MainFrameScrollingNode, frameView.scrollLayerID(), 0, 0); > } > > void AsyncScrollingCoordinator::updateFrameScrollingNode(ScrollingNodeID nodeID, GraphicsLayer* layer, GraphicsLayer* scrolledContentsLayer, GraphicsLayer* counterScrollingLayer, GraphicsLayer* insetClipLayer, const ScrollingGeometry& scrollingGeometry) >diff --git a/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h b/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h >index 5d678e400e5..03ae58aa66e 100644 >--- a/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h >+++ b/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h >@@ -97,7 +97,7 @@ private: > > WEBCORE_EXPORT bool requestScrollPositionUpdate(FrameView&, const IntPoint&) override; > >- WEBCORE_EXPORT ScrollingNodeID attachToStateTree(ScrollingNodeType, ScrollingNodeID newNodeID, ScrollingNodeID parentID) override; >+ WEBCORE_EXPORT ScrollingNodeID attachToStateTree(ScrollingNodeType, ScrollingNodeID newNodeID, ScrollingNodeID parentID, size_t childIndex) override; > WEBCORE_EXPORT void detachFromStateTree(ScrollingNodeID) override; > WEBCORE_EXPORT void clearStateTree() override; > >diff --git a/Source/WebCore/page/scrolling/ScrollingCoordinator.h b/Source/WebCore/page/scrolling/ScrollingCoordinator.h >index 53a6918ec2e..995971f9f5d 100644 >--- a/Source/WebCore/page/scrolling/ScrollingCoordinator.h >+++ b/Source/WebCore/page/scrolling/ScrollingCoordinator.h >@@ -164,7 +164,7 @@ public: > virtual void commitTreeStateIfNeeded() { } > virtual bool requestScrollPositionUpdate(FrameView&, const IntPoint&) { return false; } > virtual bool handleWheelEvent(FrameView&, const PlatformWheelEvent&) { return true; } >- virtual ScrollingNodeID attachToStateTree(ScrollingNodeType, ScrollingNodeID newNodeID, ScrollingNodeID /*parentID*/) { return newNodeID; } >+ virtual ScrollingNodeID attachToStateTree(ScrollingNodeType, ScrollingNodeID newNodeID, ScrollingNodeID /*parentID*/, size_t /*childIndex*/) { return newNodeID; } > virtual void detachFromStateTree(ScrollingNodeID) { } > virtual void clearStateTree() { } > >diff --git a/Source/WebCore/page/scrolling/ScrollingStateNode.cpp b/Source/WebCore/page/scrolling/ScrollingStateNode.cpp >index d9bf7c5e680..464b6678f4b 100644 >--- a/Source/WebCore/page/scrolling/ScrollingStateNode.cpp >+++ b/Source/WebCore/page/scrolling/ScrollingStateNode.cpp >@@ -58,6 +58,15 @@ ScrollingStateNode::ScrollingStateNode(const ScrollingStateNode& stateNode, Scro > > ScrollingStateNode::~ScrollingStateNode() = default; > >+void ScrollingStateNode::setChildIndex(size_t childIndex) >+{ >+ ASSERT(m_parent); >+ ASSERT(m_parent->children()); >+ ASSERT(childIndex < m_parent->children()->size()); >+ ASSERT(m_parent->children()->at(childIndex).get() == this); >+ m_childIndex = childIndex; >+} >+ > void ScrollingStateNode::setPropertyChanged(unsigned propertyBit) > { > if (hasChangedProperty(propertyBit)) >@@ -88,13 +97,27 @@ void ScrollingStateNode::cloneAndResetChildren(ScrollingStateNode& clone, Scroll > clone.appendChild(child->cloneAndReset(adoptiveTree)); > } > >-void ScrollingStateNode::appendChild(Ref<ScrollingStateNode>&& childNode) >+void ScrollingStateNode::prepareNewChild(ScrollingStateNode& childNode) > { >- childNode->setParent(this); >+ childNode.setParent(this); > > if (!m_children) > m_children = std::make_unique<Vector<RefPtr<ScrollingStateNode>>>(); >+} >+ >+void ScrollingStateNode::appendChild(Ref<ScrollingStateNode>&& childNode) >+{ >+ prepareNewChild(childNode.get()); > m_children->append(WTFMove(childNode)); >+ m_children->last()->setChildIndex(m_children->size() - 1); >+} >+ >+void ScrollingStateNode::insertChild(size_t position, Ref<ScrollingStateNode>&& childNode) >+{ >+ prepareNewChild(childNode.get()); >+ m_children->insert(position, WTFMove(childNode)); >+ for (size_t i = position; i < m_children->size(); i++) >+ (*m_children)[i]->setChildIndex(i); > } > > void ScrollingStateNode::reconcileLayerPositionForViewportRect(const LayoutRect& viewportRect, ScrollingLayerPositionAction action) >diff --git a/Source/WebCore/page/scrolling/ScrollingStateNode.h b/Source/WebCore/page/scrolling/ScrollingStateNode.h >index f310487454f..1a44e53a052 100644 >--- a/Source/WebCore/page/scrolling/ScrollingStateNode.h >+++ b/Source/WebCore/page/scrolling/ScrollingStateNode.h >@@ -232,10 +232,12 @@ public: > ScrollingStateNode* parent() const { return m_parent; } > void setParent(ScrollingStateNode* parent) { m_parent = parent; } > ScrollingNodeID parentNodeID() const { return m_parent ? m_parent->scrollingNodeID() : 0; } >+ void setChildIndex(size_t); >+ size_t childIndex() const { return m_childIndex; } > > Vector<RefPtr<ScrollingStateNode>>* children() const { return m_children.get(); } > >- void appendChild(Ref<ScrollingStateNode>&&); >+ void insertChild(size_t position, Ref<ScrollingStateNode>&&); > > String scrollingStateTreeAsText(ScrollingStateTreeAsTextBehavior = ScrollingStateTreeAsTextBehaviorNormal) const; > >@@ -246,6 +248,8 @@ protected: > > private: > void dump(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const; >+ void prepareNewChild(ScrollingStateNode& childNode); >+ void appendChild(Ref<ScrollingStateNode>&&); > > const ScrollingNodeType m_nodeType; > const ScrollingNodeID m_nodeID; >@@ -254,6 +258,7 @@ private: > ScrollingStateTree& m_scrollingStateTree; > > ScrollingStateNode* m_parent { nullptr }; >+ size_t m_childIndex { 0 }; > std::unique_ptr<Vector<RefPtr<ScrollingStateNode>>> m_children; > > LayerRepresentation m_layer; >diff --git a/Source/WebCore/page/scrolling/ScrollingStateTree.cpp b/Source/WebCore/page/scrolling/ScrollingStateTree.cpp >index 70a95f47e68..9a71ca63d47 100644 >--- a/Source/WebCore/page/scrolling/ScrollingStateTree.cpp >+++ b/Source/WebCore/page/scrolling/ScrollingStateTree.cpp >@@ -82,7 +82,7 @@ Ref<ScrollingStateNode> ScrollingStateTree::createNode(ScrollingNodeType nodeTyp > return ScrollingStateFixedNode::create(*this, nodeID); > } > >-bool ScrollingStateTree::nodeTypeAndParentMatch(ScrollingStateNode& node, ScrollingNodeType nodeType, ScrollingNodeID parentID) const >+bool ScrollingStateTree::nodeTypeAndParentAndChildIndexMatch(ScrollingStateNode& node, ScrollingNodeType nodeType, ScrollingNodeID parentID, size_t childIndex) const > { > if (node.nodeType() != nodeType) > return false; >@@ -91,15 +91,15 @@ bool ScrollingStateTree::nodeTypeAndParentMatch(ScrollingStateNode& node, Scroll > if (!parent) > return true; > >- return node.parent() == parent; >+ return node.parent() == parent && node.childIndex() == childIndex; > } > >-ScrollingNodeID ScrollingStateTree::attachNode(ScrollingNodeType nodeType, ScrollingNodeID newNodeID, ScrollingNodeID parentID) >+ScrollingNodeID ScrollingStateTree::attachNode(ScrollingNodeType nodeType, ScrollingNodeID newNodeID, ScrollingNodeID parentID, size_t childIndex) > { > ASSERT(newNodeID); > > if (auto* node = stateNodeForID(newNodeID)) { >- if (nodeTypeAndParentMatch(*node, nodeType, parentID)) >+ if (nodeTypeAndParentAndChildIndexMatch(*node, nodeType, parentID, childIndex)) > return newNodeID; > > #if ENABLE(ASYNC_SCROLLING) >@@ -108,7 +108,8 @@ ScrollingNodeID ScrollingStateTree::attachNode(ScrollingNodeType nodeType, Scrol > newNodeID = m_scrollingCoordinator->uniqueScrollingNodeID(); > #endif > >- // The node is being re-parented. To do that, we'll remove it, and then create a new node. >+ // The node is being re-parented or its position in its parent's child list is being modified. >+ // To do that, we'll remove it, and then create a new node. > removeNodeAndAllDescendants(node, SubframeNodeRemoval::Orphan); > } > >@@ -117,6 +118,7 @@ ScrollingNodeID ScrollingStateTree::attachNode(ScrollingNodeType nodeType, Scrol > // If we're resetting the root node, we should clear the HashMap and destroy the current children. > clear(); > >+ ASSERT(!childIndex); > setRootStateNode(ScrollingStateFrameScrollingNode::create(*this, MainFrameScrollingNode, newNodeID)); > newNode = rootStateNode(); > m_hasNewRootStateNode = true; >@@ -128,14 +130,14 @@ ScrollingNodeID ScrollingStateTree::attachNode(ScrollingNodeType nodeType, Scrol > if (nodeType == SubframeScrollingNode && parentID) { > if (auto orphanedNode = m_orphanedSubframeNodes.take(newNodeID)) { > newNode = orphanedNode.get(); >- parent->appendChild(orphanedNode.releaseNonNull()); >+ parent->insertChild(childIndex, orphanedNode.releaseNonNull()); > } > } > > if (!newNode) { > auto stateNode = createNode(nodeType, newNodeID); > newNode = stateNode.ptr(); >- parent->appendChild(WTFMove(stateNode)); >+ parent->insertChild(childIndex, WTFMove(stateNode)); > } > } > >diff --git a/Source/WebCore/page/scrolling/ScrollingStateTree.h b/Source/WebCore/page/scrolling/ScrollingStateTree.h >index cc9e571abd8..01a2c60e405 100644 >--- a/Source/WebCore/page/scrolling/ScrollingStateTree.h >+++ b/Source/WebCore/page/scrolling/ScrollingStateTree.h >@@ -51,7 +51,7 @@ public: > ScrollingStateFrameScrollingNode* rootStateNode() const { return m_rootStateNode.get(); } > WEBCORE_EXPORT ScrollingStateNode* stateNodeForID(ScrollingNodeID) const; > >- WEBCORE_EXPORT ScrollingNodeID attachNode(ScrollingNodeType, ScrollingNodeID, ScrollingNodeID parentID); >+ WEBCORE_EXPORT ScrollingNodeID attachNode(ScrollingNodeType, ScrollingNodeID, ScrollingNodeID parentID, size_t childIndex); > void detachNode(ScrollingNodeID); > void clear(); > >@@ -81,7 +81,7 @@ private: > > Ref<ScrollingStateNode> createNode(ScrollingNodeType, ScrollingNodeID); > >- bool nodeTypeAndParentMatch(ScrollingStateNode&, ScrollingNodeType, ScrollingNodeID parentID) const; >+ bool nodeTypeAndParentAndChildIndexMatch(ScrollingStateNode&, ScrollingNodeType, ScrollingNodeID parentID, size_t childIndex) const; > > enum class SubframeNodeRemoval { Delete, Orphan }; > void removeNodeAndAllDescendants(ScrollingStateNode*, SubframeNodeRemoval = SubframeNodeRemoval::Delete); >diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp >index 77b0120fbae..1536d6c63b6 100644 >--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp >+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp >@@ -3803,8 +3803,9 @@ void RenderLayerCompositor::reattachSubframeScrollLayers() > ScrollingNodeID parentNodeID = scrollCoordinatedAncestorInParentOfFrame(*child); > if (!parentNodeID) > continue; >+ size_t childIndex = 0; // TODO > >- scrollingCoordinator->attachToStateTree(child->isMainFrame() ? MainFrameScrollingNode : SubframeScrollingNode, frameScrollingNodeID, parentNodeID); >+ scrollingCoordinator->attachToStateTree(child->isMainFrame() ? MainFrameScrollingNode : SubframeScrollingNode, frameScrollingNodeID, parentNodeID, childIndex); > } > } > >@@ -3823,7 +3824,7 @@ static inline LayerScrollCoordinationRole scrollCoordinationRoleForNodeType(Scro > return Scrolling; > } > >-ScrollingNodeID RenderLayerCompositor::attachScrollingNode(RenderLayer& layer, ScrollingNodeType nodeType, ScrollingNodeID parentNodeID) >+ScrollingNodeID RenderLayerCompositor::attachScrollingNode(RenderLayer& layer, ScrollingNodeType nodeType, ScrollingNodeID parentNodeID, size_t childIndex) > { > auto* scrollingCoordinator = this->scrollingCoordinator(); > auto* backing = layer.backing(); >@@ -3837,7 +3838,7 @@ ScrollingNodeID RenderLayerCompositor::attachScrollingNode(RenderLayer& layer, S > if (!nodeID) > nodeID = scrollingCoordinator->uniqueScrollingNodeID(); > >- nodeID = scrollingCoordinator->attachToStateTree(nodeType, nodeID, parentNodeID); >+ nodeID = scrollingCoordinator->attachToStateTree(nodeType, nodeID, parentNodeID, childIndex); > if (!nodeID) > return 0; > >@@ -3866,13 +3867,13 @@ void RenderLayerCompositor::detachScrollCoordinatedLayer(RenderLayer& layer, Opt > backing->detachFromScrollingCoordinator(roles); > } > >-void RenderLayerCompositor::updateScrollCoordinationForThisFrame(ScrollingNodeID parentNodeID) >+void RenderLayerCompositor::updateScrollCoordinationForThisFrame(ScrollingNodeID parentNodeID, size_t childIndex) > { > auto* scrollingCoordinator = this->scrollingCoordinator(); > FrameView& frameView = m_renderView.frameView(); > ASSERT(scrollingCoordinator->coordinatesScrollingForFrameView(frameView)); > >- ScrollingNodeID nodeID = attachScrollingNode(*m_renderView.layer(), m_renderView.frame().isMainFrame() ? MainFrameScrollingNode : SubframeScrollingNode, parentNodeID); >+ ScrollingNodeID nodeID = attachScrollingNode(*m_renderView.layer(), m_renderView.frame().isMainFrame() ? MainFrameScrollingNode : SubframeScrollingNode, parentNodeID, childIndex); > ScrollingCoordinator::ScrollingGeometry scrollingGeometry; > // FIXME(https://webkit.org/b/172917): Pass parentRelativeScrollableRect? > scrollingGeometry.scrollOrigin = frameView.scrollOrigin(); >@@ -3901,8 +3902,9 @@ void RenderLayerCompositor::updateScrollCoordinatedLayer(RenderLayer& layer, Opt > ScrollingNodeID parentDocumentHostingNodeID = scrollCoordinatedAncestorInParentOfFrame(m_renderView.frame()); > if (!parentDocumentHostingNodeID) > return; >+ size_t childIndex = 0; // TODO > >- updateScrollCoordinationForThisFrame(parentDocumentHostingNodeID); >+ updateScrollCoordinationForThisFrame(parentDocumentHostingNodeID, childIndex); > if (!(reasons & ViewportConstrained) && isRenderViewLayer) > return; > } >@@ -3910,6 +3912,7 @@ void RenderLayerCompositor::updateScrollCoordinatedLayer(RenderLayer& layer, Opt > ScrollingNodeID parentNodeID = enclosingScrollingNodeID(layer, ExcludeSelf); > if (!parentNodeID && !isRenderViewLayer) > return; >+ size_t childIndex = 0; // TODO > > auto* backing = layer.backing(); > >@@ -3924,7 +3927,7 @@ void RenderLayerCompositor::updateScrollCoordinatedLayer(RenderLayer& layer, Opt > else > ASSERT_NOT_REACHED(); > >- ScrollingNodeID nodeID = attachScrollingNode(layer, nodeType, parentNodeID); >+ ScrollingNodeID nodeID = attachScrollingNode(layer, nodeType, parentNodeID, childIndex); > if (!nodeID) > return; > >@@ -3954,10 +3957,10 @@ void RenderLayerCompositor::updateScrollCoordinatedLayer(RenderLayer& layer, Opt > > if (reasons & Scrolling) { > if (isRenderViewLayer) >- updateScrollCoordinationForThisFrame(parentNodeID); >+ updateScrollCoordinationForThisFrame(parentNodeID, childIndex); > else { > ScrollingNodeType nodeType = OverflowScrollingNode; >- ScrollingNodeID nodeID = attachScrollingNode(layer, nodeType, parentNodeID); >+ ScrollingNodeID nodeID = attachScrollingNode(layer, nodeType, parentNodeID, childIndex); > if (!nodeID) > return; > >diff --git a/Source/WebCore/rendering/RenderLayerCompositor.h b/Source/WebCore/rendering/RenderLayerCompositor.h >index 70dde532e9e..6e8db08294d 100644 >--- a/Source/WebCore/rendering/RenderLayerCompositor.h >+++ b/Source/WebCore/rendering/RenderLayerCompositor.h >@@ -444,8 +444,8 @@ private: > > void updateCustomLayersAfterFlush(); > >- void updateScrollCoordinationForThisFrame(ScrollingNodeID); >- ScrollingNodeID attachScrollingNode(RenderLayer&, ScrollingNodeType, ScrollingNodeID parentNodeID); >+ void updateScrollCoordinationForThisFrame(ScrollingNodeID, size_t childIndex); >+ ScrollingNodeID attachScrollingNode(RenderLayer&, ScrollingNodeType, ScrollingNodeID parentNodeID, size_t childIndex); > void updateScrollCoordinatedLayer(RenderLayer&, OptionSet<LayerScrollCoordinationRole>, OptionSet<ScrollingNodeChangeFlags>); > void detachScrollCoordinatedLayer(RenderLayer&, OptionSet<LayerScrollCoordinationRole>); > void reattachSubframeScrollLayers(); >diff --git a/Source/WebKit/Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp b/Source/WebKit/Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp >index 8d2d18c096e..63a9fc1a43d 100644 >--- a/Source/WebKit/Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp >+++ b/Source/WebKit/Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp >@@ -83,6 +83,7 @@ void ArgumentCoder<ScrollingStateNode>::encode(Encoder& encoder, const Scrolling > encoder.encodeEnum(node.nodeType()); > encoder << node.scrollingNodeID(); > encoder << node.parentNodeID(); >+ encoder << node.childIndex(); > encoder << node.changedProperties(); > > if (node.hasChangedProperty(ScrollingStateNode::ScrollLayer)) >@@ -91,7 +92,7 @@ void ArgumentCoder<ScrollingStateNode>::encode(Encoder& encoder, const Scrolling > > bool ArgumentCoder<ScrollingStateNode>::decode(Decoder& decoder, ScrollingStateNode& node) > { >- // nodeType, scrollingNodeID and parentNodeID have already been decoded by the caller in order to create the node. >+ // nodeType, scrollingNodeID, parentNodeID and childIndex have already been decoded by the caller in order to create the node. > ScrollingStateNode::ChangedProperties changedProperties; > if (!decoder.decode(changedProperties)) > return false; >@@ -413,7 +414,11 @@ bool RemoteScrollingCoordinatorTransaction::decode(IPC::Decoder& decoder) > if (!decoder.decode(parentNodeID)) > return false; > >- m_scrollingStateTree->attachNode(nodeType, nodeID, parentNodeID); >+ size_t childIndex; >+ if (!decoder.decode(childIndex)) >+ return false; >+ >+ m_scrollingStateTree->attachNode(nodeType, nodeID, parentNodeID, childIndex); > ScrollingStateNode* newNode = m_scrollingStateTree->stateNodeForID(nodeID); > ASSERT(newNode); > ASSERT(!parentNodeID || newNode->parent()); >-- >2.19.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
simon.fraser
:
review-
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 176914
:
320777
|
320782
|
320785
|
320787
|
320795
|
324232
|
324410
|
327061
| 356603 |
356615
|
356722