Diff
Modified: trunk/LayoutTests/ChangeLog (116507 => 116508)
--- trunk/LayoutTests/ChangeLog 2012-05-09 09:07:41 UTC (rev 116507)
+++ trunk/LayoutTests/ChangeLog 2012-05-09 09:26:57 UTC (rev 116508)
@@ -1,3 +1,28 @@
+2012-05-09 Shinya Kawanaka <[email protected]>
+
+ Position should be able to have ShadowRoot as a container.
+ https://bugs.webkit.org/show_bug.cgi?id=82021
+
+ Reviewed by Ryosuke Niwa.
+
+ Skipped non-chromium port since SHADOW_DOM flag is not enabled in those platforms.
+ We will add bunch of tests for editing in Shadow DOM into editing/shadow later,
+ so I added the whole directory name to the skipped list.
+
+ * editing/shadow/doubleclick-on-meter-in-shadow-crash-expected.txt: Added.
+ * editing/shadow/doubleclick-on-meter-in-shadow-crash.html: Added.
+ * editing/shadow/rightclick-on-meter-in-shadow-crash-expected.txt: Added.
+ * editing/shadow/rightclick-on-meter-in-shadow-crash.html: Added.
+ * editing/shadow/shadow-selection-not-exported-expected.txt: Added.
+ * editing/shadow/shadow-selection-not-exported.html: Added.
+ * platform/efl/Skipped:
+ * platform/gtk/test_expectations.txt:
+ * platform/mac/Skipped:
+ * platform/qt/Skipped:
+ * platform/win/Skipped:
+ * platform/wincairo/Skipped:
+ * platform/wk2/Skipped:
+
2012-05-09 Mikhail Pozdnyakov <[email protected]>
[EFL][DRT] LayoutTestController addUserScript implementation
Added: trunk/LayoutTests/editing/shadow/doubleclick-on-meter-in-shadow-crash-expected.txt (0 => 116508)
--- trunk/LayoutTests/editing/shadow/doubleclick-on-meter-in-shadow-crash-expected.txt (rev 0)
+++ trunk/LayoutTests/editing/shadow/doubleclick-on-meter-in-shadow-crash-expected.txt 2012-05-09 09:26:57 UTC (rev 116508)
@@ -0,0 +1,3 @@
+This test ensures context click around meter won't crash.
+
+PASS
Added: trunk/LayoutTests/editing/shadow/doubleclick-on-meter-in-shadow-crash.html (0 => 116508)
--- trunk/LayoutTests/editing/shadow/doubleclick-on-meter-in-shadow-crash.html (rev 0)
+++ trunk/LayoutTests/editing/shadow/doubleclick-on-meter-in-shadow-crash.html 2012-05-09 09:26:57 UTC (rev 116508)
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<p>This test ensures context click around meter won't crash.</p>
+<div id='container' style="width:100px; height: 100px"></div>
+<p>PASS</p>
+<script src=""
+<script src=""
+<script>
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+var container = document.getElementById('container');
+var shadowRoot = new WebKitShadowRoot(container);
+var meter = document.createElement('meter');
+shadowRoot.appendChild(meter);
+
+// Do doubleclick at various points.
+doubleClick(meter.offsetLeft, meter.offsetTop);
+doubleClick(meter.offsetLeft - 1, meter.offsetTop);
+doubleClick(meter.offsetLeft, meter.offsetTop - 1);
+doubleClick(meter.offsetLeft - 1, meter.offsetTop - 1);
+doubleClick(meter.offsetLeft + 1, meter.offsetTop);
+doubleClick(meter.offsetLeft, meter.offsetTop + 1);
+doubleClick(meter.offsetLeft + 1, meter.offsetTop + 1);
+doubleClick(meter.offsetLeft + meter.offsetWidth / 2, meter.offsetTop + meter.offsetHeight / 2);
+doubleClick(meter.offsetLeft + meter.offsetWidth - 1, meter.offsetTop + meter.offsetHeight - 1);
+doubleClick(meter.offsetLeft + meter.offsetWidth + 1, meter.offsetTop + meter.offsetHeight + 1);
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/editing/shadow/rightclick-on-meter-in-shadow-crash-expected.txt (0 => 116508)
--- trunk/LayoutTests/editing/shadow/rightclick-on-meter-in-shadow-crash-expected.txt (rev 0)
+++ trunk/LayoutTests/editing/shadow/rightclick-on-meter-in-shadow-crash-expected.txt 2012-05-09 09:26:57 UTC (rev 116508)
@@ -0,0 +1,3 @@
+This test ensures context click around meter won't crash.
+
+PASS
Added: trunk/LayoutTests/editing/shadow/rightclick-on-meter-in-shadow-crash.html (0 => 116508)
--- trunk/LayoutTests/editing/shadow/rightclick-on-meter-in-shadow-crash.html (rev 0)
+++ trunk/LayoutTests/editing/shadow/rightclick-on-meter-in-shadow-crash.html 2012-05-09 09:26:57 UTC (rev 116508)
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<p>This test ensures context click around meter won't crash.</p>
+<div id='container' style="width:100px; height: 100px"></div>
+<p>PASS</p>
+
+<script src=""
+<script src=""
+<script>
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+function contextClick(x, y) {
+ eventSender.mouseMoveTo(x, y);
+ eventSender.contextClick();
+}
+
+var container = document.getElementById('container');
+var shadowRoot = new WebKitShadowRoot(container);
+var meter = document.createElement('meter');
+shadowRoot.appendChild(meter);
+
+// Do context click at various points.
+contextClick(meter.offsetLeft, meter.offsetTop);
+contextClick(meter.offsetLeft - 1, meter.offsetTop);
+contextClick(meter.offsetLeft, meter.offsetTop - 1);
+contextClick(meter.offsetLeft - 1, meter.offsetTop - 1);
+contextClick(meter.offsetLeft + 1, meter.offsetTop);
+contextClick(meter.offsetLeft, meter.offsetTop + 1);
+contextClick(meter.offsetLeft + 1, meter.offsetTop + 1);
+contextClick(meter.offsetLeft + meter.offsetWidth / 2, meter.offsetTop + meter.offsetHeight / 2);
+contextClick(meter.offsetLeft + meter.offsetWidth - 1, meter.offsetTop + meter.offsetHeight - 1);
+contextClick(meter.offsetLeft + meter.offsetWidth + 1, meter.offsetTop + meter.offsetHeight + 1);
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/editing/shadow/shadow-selection-not-exported-expected.txt (0 => 116508)
--- trunk/LayoutTests/editing/shadow/shadow-selection-not-exported-expected.txt (rev 0)
+++ trunk/LayoutTests/editing/shadow/shadow-selection-not-exported-expected.txt 2012-05-09 09:26:57 UTC (rev 116508)
@@ -0,0 +1,13 @@
+PASS assertNotInShadow(selection.anchorNode) is true
+PASS assertNotInShadow(selection.focusNode) is true
+PASS assertNotInShadow(selection.anchorNode) is true
+PASS assertNotInShadow(selection.focusNode) is true
+PASS assertNotInShadow(selection.anchorNode) is true
+PASS assertNotInShadow(selection.focusNode) is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+This test ensures shadow root won't expose to JS layer.
+
+BEFORE
+AFTER
Added: trunk/LayoutTests/editing/shadow/shadow-selection-not-exported.html (0 => 116508)
--- trunk/LayoutTests/editing/shadow/shadow-selection-not-exported.html (rev 0)
+++ trunk/LayoutTests/editing/shadow/shadow-selection-not-exported.html 2012-05-09 09:26:57 UTC (rev 116508)
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html>
+<pre id="console"></pre>
+
+<p>This test ensures shadow root won't expose to JS layer.<p>
+<div id='div1'>BEFORE</div>
+<div id='container'>CONTAINER</div>
+<div id='div4'>AFTER</di>
+<script src=""
+<script src=""
+<script src=""
+<script>
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+var container = document.getElementById('container');
+var shadowRoot = new WebKitShadowRoot(container);
+
+var div2 = document.createElement('div');
+div2.appendChild(document.createTextNode('IN SHADOW TREE 1'));
+var div3 = document.createElement('div');
+div3.appendChild(document.createTextNode('IN SHADOW TREE 2'));
+
+shadowRoot.appendChild(div2);
+shadowRoot.appendChild(div3);
+
+function midX(element) {
+ return element.offsetLeft + element.offsetWidth / 2;
+}
+
+function midY(element) {
+ return element.offsetTop + element.offsetHeight / 2;
+}
+
+function assertNotInShadow(element) {
+ if (element == div2 || element == div2.firstChild)
+ return false;
+ if (element == div3 || element == div3.firstChild)
+ return false;
+ return true;
+}
+
+if (window.eventSender) {
+ // Try select from outside of a shadow subtree to inside of a shadow subtree.
+ eventSender.mouseMoveTo(midX(div1), midY(div1));
+ eventSender.mouseDown();
+ eventSender.mouseMoveTo(midX(div2), midY(div2));
+ eventSender.mouseUp();
+
+ var selection = window.getSelection();
+ shouldBe('assertNotInShadow(selection.anchorNode)', 'true');
+ shouldBe('assertNotInShadow(selection.focusNode)', 'true');
+
+ selection.removeAllRanges();
+
+ // Try select from inside of a shadow subtree to outside of a shadow subtree.
+ eventSender.mouseMoveTo(midX(div3), midY(div3));
+ eventSender.mouseDown();
+ eventSender.mouseMoveTo(midX(div4), midY(div4));
+ eventSender.mouseUp();
+
+ selection = window.getSelection();
+ shouldBe('assertNotInShadow(selection.anchorNode)', 'true');
+ shouldBe('assertNotInShadow(selection.focusNode)', 'true');
+ selection.removeAllRanges();
+
+ // Try select inside shadow subtrees.
+ eventSender.mouseMoveTo(midX(div2), midY(div2));
+ eventSender.mouseDown();
+ eventSender.mouseMoveTo(midX(div3), midY(div3));
+ eventSender.mouseUp();
+
+ selection = window.getSelection();
+ shouldBe('assertNotInShadow(selection.anchorNode)', 'true');
+ shouldBe('assertNotInShadow(selection.focusNode)', 'true');
+ selection.removeAllRanges();
+}
+
+var successfullyParsed = true;
+</script>
+<script src=""
+</html>
Modified: trunk/LayoutTests/platform/efl/Skipped (116507 => 116508)
--- trunk/LayoutTests/platform/efl/Skipped 2012-05-09 09:07:41 UTC (rev 116507)
+++ trunk/LayoutTests/platform/efl/Skipped 2012-05-09 09:26:57 UTC (rev 116508)
@@ -227,6 +227,7 @@
# ENABLE(SHADOW_DOM) is disabled
fast/dom/shadow
+editing/shadow
# ENABLE(DATALIST) is disabled
fast/forms/datalist
Modified: trunk/LayoutTests/platform/gtk/test_expectations.txt (116507 => 116508)
--- trunk/LayoutTests/platform/gtk/test_expectations.txt 2012-05-09 09:07:41 UTC (rev 116507)
+++ trunk/LayoutTests/platform/gtk/test_expectations.txt 2012-05-09 09:26:57 UTC (rev 116508)
@@ -236,6 +236,7 @@
// ENABLE(SHADOW_DOM) is disabled.
BUGWKGTK SKIP : fast/dom/shadow = FAIL
+BUGWKGTK SKIP : editing/shadow = FAIL
// CSS Regions support not yet enabled.
BUGWK57312 SKIP : fast/regions = FAIL
Modified: trunk/LayoutTests/platform/mac/Skipped (116507 => 116508)
--- trunk/LayoutTests/platform/mac/Skipped 2012-05-09 09:07:41 UTC (rev 116507)
+++ trunk/LayoutTests/platform/mac/Skipped 2012-05-09 09:26:57 UTC (rev 116508)
@@ -447,6 +447,7 @@
# ENABLE(SHADOW_DOM) is disabled.
fast/dom/shadow
+editing/shadow
# JSC does not support setIsolatedWorldSecurityOrigin (http://webkit.org/b/61540)
http/tests/security/isolatedWorld/cross-origin-xhr.html
Modified: trunk/LayoutTests/platform/qt/Skipped (116507 => 116508)
--- trunk/LayoutTests/platform/qt/Skipped 2012-05-09 09:07:41 UTC (rev 116507)
+++ trunk/LayoutTests/platform/qt/Skipped 2012-05-09 09:26:57 UTC (rev 116508)
@@ -169,6 +169,7 @@
fast/regions/style-scoped-in-flow.html
# ENABLE(SHADOW_DOM) is disabled.
+editing/shadow
fast/dom/shadow/access-key.html
fast/dom/shadow/adopt-node-with-shadow-root.html
fast/dom/shadow/composed-shadow-tree-walker.html
Modified: trunk/LayoutTests/platform/win/Skipped (116507 => 116508)
--- trunk/LayoutTests/platform/win/Skipped 2012-05-09 09:07:41 UTC (rev 116507)
+++ trunk/LayoutTests/platform/win/Skipped 2012-05-09 09:26:57 UTC (rev 116508)
@@ -1477,6 +1477,7 @@
fast/regions/style-scoped-in-flow.html
# ENABLE(SHADOW_DOM) is disabled.
+editing/shadow
fast/dom/shadow/content-element-api.html
fast/dom/shadow/content-element-outside-shadow.html
fast/dom/shadow/content-element-outside-shadow-style.html
Modified: trunk/LayoutTests/platform/wincairo/Skipped (116507 => 116508)
--- trunk/LayoutTests/platform/wincairo/Skipped 2012-05-09 09:07:41 UTC (rev 116507)
+++ trunk/LayoutTests/platform/wincairo/Skipped 2012-05-09 09:26:57 UTC (rev 116508)
@@ -1983,6 +1983,7 @@
fast/regions/style-scoped-in-flow.html
# ENABLE(SHADOW_DOM) is disabled.
+editing/shadow
fast/dom/shadow/content-element-api.html
fast/dom/shadow/content-element-outside-shadow.html
fast/dom/shadow/content-element-in-media-element.html
Modified: trunk/LayoutTests/platform/wk2/Skipped (116507 => 116508)
--- trunk/LayoutTests/platform/wk2/Skipped 2012-05-09 09:07:41 UTC (rev 116507)
+++ trunk/LayoutTests/platform/wk2/Skipped 2012-05-09 09:26:57 UTC (rev 116508)
@@ -1090,6 +1090,7 @@
fast/dom/shadow/create-content-element.html
# ENABLE(SHADOW_DOM) is disabled.
+editing/shadow
fast/dom/shadow/content-element-api.html
fast/dom/shadow/content-element-outside-shadow.html
fast/dom/shadow/content-element-outside-shadow-style.html
Modified: trunk/Source/WebCore/ChangeLog (116507 => 116508)
--- trunk/Source/WebCore/ChangeLog 2012-05-09 09:07:41 UTC (rev 116507)
+++ trunk/Source/WebCore/ChangeLog 2012-05-09 09:26:57 UTC (rev 116508)
@@ -1,3 +1,41 @@
+2012-05-09 Shinya Kawanaka <[email protected]>
+
+ Position should be able to have ShadowRoot as a container.
+ https://bugs.webkit.org/show_bug.cgi?id=82021
+
+ Reviewed by Ryosuke Niwa.
+
+ Since Position could not take a shadow root as a container node, pointing the direct children
+ of a shadow root was difficult.
+
+ This patch makes it enabled, and fixes a lot of crashes caused by that limitation.
+ Also, we confirm that ShadowRoot is not exposed to _javascript_ layer.
+
+ Currently this change is only enabled if shadow dom flag is enabled, since we cannot
+ prove this change does not destroy the existing behavior. However, this change is really required
+ to fix other editing bugs in Shadow DOM. A bunch of patches and tests will be added to
+ fix other editing bugs and they will check this patch does not break editing.
+ We will also add a fuzzer to check the stability of editing in Shadow DOM later, and it will
+ also help to confirm the patch will not break the editing.
+
+ Tests: editing/shadow/doubleclick-on-meter-in-shadow-crash.html
+ editing/shadow/rightclick-on-meter-in-shadow-crash.html
+ editing/shadow/shadow-selection-not-exported.html
+
+ * dom/Position.cpp:
+ (WebCore::Position::Position):
+ (WebCore::Position::containerNode):
+ (WebCore::Position::parentAnchoredEquivalent):
+ (WebCore::Position::previous):
+ (WebCore::Position::next):
+ (WebCore::Position::atStartOfTree):
+ (WebCore::Position::atEndOfTree):
+ (WebCore::Position::findParent):
+ * dom/Position.h:
+ (WebCore):
+ (WebCore::positionInParentBeforeNode):
+ (WebCore::positionInParentAfterNode):
+
2012-05-09 Zoltan Horvath <[email protected]>
[Qt] Build fix when using libpng version != 1.2
Modified: trunk/Source/WebCore/dom/Position.cpp (116507 => 116508)
--- trunk/Source/WebCore/dom/Position.cpp 2012-05-09 09:07:41 UTC (rev 116507)
+++ trunk/Source/WebCore/dom/Position.cpp 2012-05-09 09:26:57 UTC (rev 116508)
@@ -33,6 +33,7 @@
#include "PositionIterator.h"
#include "RenderBlock.h"
#include "RenderText.h"
+#include "RuntimeEnabledFeatures.h"
#include "Text.h"
#include "TextIterator.h"
#include "VisiblePosition.h"
@@ -80,7 +81,11 @@
, m_anchorType(anchorTypeForLegacyEditingPosition(m_anchorNode.get(), m_offset))
, m_isLegacyEditingPosition(true)
{
+#if ENABLE(SHADOW_DOM)
+ ASSERT(RuntimeEnabledFeatures::shadowDOMEnabled() || !m_anchorNode || !m_anchorNode->isShadowRoot());
+#else
ASSERT(!m_anchorNode || !m_anchorNode->isShadowRoot());
+#endif
}
Position::Position(PassRefPtr<Node> anchorNode, AnchorType anchorType)
@@ -89,7 +94,12 @@
, m_anchorType(anchorType)
, m_isLegacyEditingPosition(false)
{
+#if ENABLE(SHADOW_DOM)
+ ASSERT(RuntimeEnabledFeatures::shadowDOMEnabled() || !m_anchorNode || !m_anchorNode->isShadowRoot());
+#else
ASSERT(!m_anchorNode || !m_anchorNode->isShadowRoot());
+#endif
+
ASSERT(anchorType != PositionIsOffsetInAnchor);
ASSERT(!((anchorType == PositionIsBeforeChildren || anchorType == PositionIsAfterChildren)
&& (m_anchorNode->isTextNode() || editingIgnoresContent(m_anchorNode.get()))));
@@ -101,7 +111,12 @@
, m_anchorType(anchorType)
, m_isLegacyEditingPosition(false)
{
+#if ENABLE(SHADOW_DOM)
+ ASSERT(RuntimeEnabledFeatures::shadowDOMEnabled() || !m_anchorNode || !editingIgnoresContent(m_anchorNode.get()) || !m_anchorNode->isShadowRoot());
+#else
ASSERT(!m_anchorNode || !editingIgnoresContent(m_anchorNode.get()) || !m_anchorNode->isShadowRoot());
+#endif
+
ASSERT(anchorType == PositionIsOffsetInAnchor);
}
@@ -143,7 +158,7 @@
return m_anchorNode.get();
case PositionIsBeforeAnchor:
case PositionIsAfterAnchor:
- return m_anchorNode->nonShadowBoundaryParentNode();
+ return findParent(m_anchorNode.get());
}
ASSERT_NOT_REACHED();
return 0;
@@ -203,7 +218,7 @@
// FIXME: This should only be necessary for legacy positions, but is also needed for positions before and after Tables
if (m_offset <= 0 && (m_anchorType != PositionIsAfterAnchor && m_anchorType != PositionIsAfterChildren)) {
- if (m_anchorNode->nonShadowBoundaryParentNode() && (editingIgnoresContent(m_anchorNode.get()) || isTableElement(m_anchorNode.get())))
+ if (findParent(m_anchorNode.get()) && (editingIgnoresContent(m_anchorNode.get()) || isTableElement(m_anchorNode.get())))
return positionInParentBeforeNode(m_anchorNode.get());
return Position(m_anchorNode.get(), 0, PositionIsOffsetInAnchor);
}
@@ -316,7 +331,7 @@
}
}
- ContainerNode* parent = n->nonShadowBoundaryParentNode();
+ ContainerNode* parent = findParent(n);
if (!parent)
return *this;
@@ -348,7 +363,7 @@
return createLegacyEditingPosition(n, (moveType == Character) ? uncheckedNextOffset(n, o) : o + 1);
}
- ContainerNode* parent = n->nonShadowBoundaryParentNode();
+ ContainerNode* parent = findParent(n);
if (!parent)
return *this;
@@ -441,14 +456,14 @@
{
if (isNull())
return true;
- return !deprecatedNode()->nonShadowBoundaryParentNode() && m_offset <= 0;
+ return !findParent(deprecatedNode()) && m_offset <= 0;
}
bool Position::atEndOfTree() const
{
if (isNull())
return true;
- return !deprecatedNode()->nonShadowBoundaryParentNode() && m_offset >= lastOffsetForEditing(deprecatedNode());
+ return !findParent(deprecatedNode()) && m_offset >= lastOffsetForEditing(deprecatedNode());
}
int Position::renderedOffset() const
@@ -834,6 +849,18 @@
return node && node->renderer() && node->renderer()->style()->userSelect() == SELECT_NONE;
}
+ContainerNode* Position::findParent(const Node* node)
+{
+ // FIXME: See http://web.ug/82697
+
+#if ENABLE(SHADOW_DOM)
+ if (RuntimeEnabledFeatures::shadowDOMEnabled())
+ return node->parentNode();
+#endif
+
+ return node->nonShadowBoundaryParentNode();
+}
+
bool Position::isCandidate() const
{
if (isNull())
Modified: trunk/Source/WebCore/dom/Position.h (116507 => 116508)
--- trunk/Source/WebCore/dom/Position.h 2012-05-09 09:07:41 UTC (rev 116507)
+++ trunk/Source/WebCore/dom/Position.h 2012-05-09 09:26:57 UTC (rev 116508)
@@ -189,6 +189,8 @@
static bool hasRenderedNonAnonymousDescendantsWithHeight(RenderObject*);
static bool nodeIsUserSelectNone(Node*);
+
+ static ContainerNode* findParent(const Node*);
void debugPosition(const char* msg = "") const;
@@ -203,6 +205,7 @@
int renderedOffset() const;
+
Position previousCharacterPosition(EAffinity) const;
Position nextCharacterPosition(EAffinity) const;
@@ -244,13 +247,13 @@
// At least one caller currently hits this ASSERT though, which indicates
// that the caller is trying to make a position relative to a disconnected node (which is likely an error)
// Specifically, editing/deleting/delete-ligature-001.html crashes with ASSERT(node->parentNode())
- return Position(node->nonShadowBoundaryParentNode(), node->nodeIndex(), Position::PositionIsOffsetInAnchor);
+ return Position(Position::findParent(node), node->nodeIndex(), Position::PositionIsOffsetInAnchor);
}
inline Position positionInParentAfterNode(const Node* node)
{
- ASSERT(node->nonShadowBoundaryParentNode());
- return Position(node->nonShadowBoundaryParentNode(), node->nodeIndex() + 1, Position::PositionIsOffsetInAnchor);
+ ASSERT(Position::findParent(node));
+ return Position(Position::findParent(node), node->nodeIndex() + 1, Position::PositionIsOffsetInAnchor);
}
// positionBeforeNode and positionAfterNode return neighbor-anchored positions, construction is O(1)