Diff
Modified: trunk/LayoutTests/ChangeLog (133223 => 133224)
--- trunk/LayoutTests/ChangeLog 2012-11-01 20:50:43 UTC (rev 133223)
+++ trunk/LayoutTests/ChangeLog 2012-11-01 20:54:20 UTC (rev 133224)
@@ -1,3 +1,24 @@
+2012-11-01 Enrica Casucci <enr...@apple.com>
+
+ Part2 of: Extend -webkit-user-select with new value "all"
+ <rdar://problem/10161404>
+ https://bugs.webkit.org/show_bug.cgi?id=91912
+
+ Reviewed by Ryosuke Niwa.
+
+ Testing moving and extending selections with the new CSS propertyvalue, with mouse movements
+ and with the keyboard.
+ Updated test expectations for all the platforms, since this is only enabled for the Mac port.
+
+ * editing/selection/user-select-all-selection-expected.txt: Added.
+ * editing/selection/user-select-all-selection.html: Added.
+ * platform/chromium/TestExpectations:
+ * platform/qt/TestExpectations:
+ * platform/gtk/TestExpectations:
+ * platform/win/TestExpectations:
+ * platform/efl/TestExpectations:
+
+
2012-11-01 David Barton <dbar...@mathscribe.com>
REGRESSION (r128837): mathml/presentation/subsup.xhtml became flaky
Added: trunk/LayoutTests/editing/selection/user-select-all-selection-expected.txt (0 => 133224)
--- trunk/LayoutTests/editing/selection/user-select-all-selection-expected.txt (rev 0)
+++ trunk/LayoutTests/editing/selection/user-select-all-selection-expected.txt 2012-11-01 20:54:20 UTC (rev 133224)
@@ -0,0 +1,34 @@
+Test -webkit-user-select all user select all area Test -webkit-user-select all
+Test -webkit-user-select all selection movements and extensions (left right forward backward)
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+placeCaretBeforeUserSelectAllElement()
+window.getSelection().modify('extend', 'forward', 'character')
+PASS Selection is the entire user-select-all element
+window.getSelection().modify('extend', 'backward', 'character')
+PASS Selection is right before user-select-all element
+window.getSelection().modify('extend', 'right', 'character')
+PASS Selection is the entire user-select-all element
+window.getSelection().modify('extend', 'left', 'character')
+PASS Selection is right before user-select-all element
+window.getSelection().modify('move', 'forward', 'character')
+PASS Selection is right after user-select-all element
+window.getSelection().modify('move', 'backward', 'character')
+PASS Selection is right before user-select-all element
+window.getSelection().modify('move', 'right', 'character')
+PASS Selection is right after user-select-all element
+window.getSelection().modify('move', 'left', 'character')
+PASS Selection is right before user-select-all element
+clickAt(descendant.offsetLeft + 10 , descendant.offsetTop + 10)
+PASS Selection is the entire user-select-all element
+mouseMoveFromTo(leftTarget.offsetLeft, descendant.offsetLeft + 20)
+PASS Selection is the entire user-select-all element plus everything on its left
+mouseMoveFromTo(userSelectAllElement.offsetLeft + userSelectAllElement.offsetWidth + rightTarget.offsetWidth, descendant.offsetLeft + 10)
+PASS Selection is the entire user-select-all element plus everything on its right
+PASS Selection is only the text in bold
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/editing/selection/user-select-all-selection.html (0 => 133224)
--- trunk/LayoutTests/editing/selection/user-select-all-selection.html (rev 0)
+++ trunk/LayoutTests/editing/selection/user-select-all-selection.html 2012-11-01 20:54:20 UTC (rev 133224)
@@ -0,0 +1,136 @@
+<!DOCTYPE html>
+<head>
+<style>
+.userSelectAll {-webkit-user-select: all; }
+</style>
+<script src=""
+<script src=""
+<script src=""
+<script>
+function log(str) {
+ var div = document.createElement("div");
+ div.appendChild(document.createTextNode(str));
+ document.getElementById("console").appendChild(div);
+}
+
+function testSelectionAt(anchorNode, anchorOffset, optFocusNode, optFocusOffset, str) {
+ var focusNode = optFocusNode || anchorNode;
+ var focusOffset = (optFocusOffset === undefined) ? anchorOffset : optFocusOffset;
+
+ var sel = window.getSelection();
+ if (sel.anchorNode == anchorNode
+ && sel.focusNode == focusNode
+ && sel.anchorOffset == anchorOffset
+ && sel.focusOffset == focusOffset) {
+ testPassed("Selection is " + str);
+ } else {
+ testFailed("Selection should be " + str +
+ " at anchorNode: " + sel.anchorNode + " anchorOffset: " + sel.anchorOffset +
+ " focusNode: " + sel.focusNode + " focusOffset: " + sel.focusOffset);
+ }
+}
+
+function selectionShouldBeRelativeToUserSelectAllElement(str) {
+ var userSelectAllElement = document.getElementById("allArea");
+ var userSelectAllNodeIndex = 1;
+ if (str == "around")
+ testSelectionAt(userSelectAllElement.previousSibling.firstChild, userSelectAllElement.previousSibling.textContent.length,
+ userSelectAllElement.nextSibling, 0,
+ "the entire user-select-all element");
+ else if ( str == "before")
+ testSelectionAt(userSelectAllElement.previousSibling.firstChild, userSelectAllElement.previousSibling.textContent.length,
+ userSelectAllElement.previousSibling.firstChild, userSelectAllElement.previousSibling.textContent.length,
+ "right before user-select-all element");
+ else if (str == "after")
+ testSelectionAt(userSelectAllElement.nextSibling.firstChild, 0,
+ userSelectAllElement.nextSibling.firstChild, 0,
+ "right after user-select-all element");
+}
+
+function placeCaretBeforeUserSelectAllElement(){
+ var userSelectAllElement = document.getElementById("allArea");
+ execSetSelectionCommand(userSelectAllElement.previousSibling.firstChild, userSelectAllElement.previousSibling.textContent.length, userSelectAllElement.previousSibling, userSelectAllElement.previousSibling.textContent.length);
+}
+
+function mouseMoveFromTo(fromX, toX){
+ var userSelectAllElement = document.getElementById("allArea");
+ var y = userSelectAllElement.offsetTop + 10;
+ eventSender.dragMode = false;
+ // Clear click count
+ eventSender.mouseMoveTo(0, 0);
+ eventSender.mouseDown();
+ eventSender.mouseUp();
+
+ eventSender.mouseMoveTo(fromX, y);
+ eventSender.mouseDown();
+ eventSender.mouseMoveTo(toX, y);
+ eventSender.mouseUp();
+}
+
+function testKeyboard(){
+ var userSelectAllElement = document.getElementById("allArea");
+
+ evalAndLog("placeCaretBeforeUserSelectAllElement()");
+ evalAndLog("window.getSelection().modify('extend', 'forward', 'character')");
+ selectionShouldBeRelativeToUserSelectAllElement("around");
+
+ evalAndLog("window.getSelection().modify('extend', 'backward', 'character')");
+ selectionShouldBeRelativeToUserSelectAllElement("before");
+
+ evalAndLog("window.getSelection().modify('extend', 'right', 'character')");
+ selectionShouldBeRelativeToUserSelectAllElement("around");
+
+ evalAndLog("window.getSelection().modify('extend', 'left', 'character')");
+ selectionShouldBeRelativeToUserSelectAllElement("before");
+
+ evalAndLog("window.getSelection().modify('move', 'forward', 'character')");
+ selectionShouldBeRelativeToUserSelectAllElement("after");
+
+ evalAndLog("window.getSelection().modify('move', 'backward', 'character')");
+ selectionShouldBeRelativeToUserSelectAllElement("before");
+
+ evalAndLog("window.getSelection().modify('move', 'right', 'character')");
+ selectionShouldBeRelativeToUserSelectAllElement("after");
+
+ evalAndLog("window.getSelection().modify('move', 'left', 'character')");
+ selectionShouldBeRelativeToUserSelectAllElement("before");
+}
+
+function testMouse(){
+ var userSelectAllElement = document.getElementById("allArea");
+ var descendant = document.getElementById("descendant");
+ evalAndLog("clickAt(descendant.offsetLeft + 10 , descendant.offsetTop + 10)");
+ selectionShouldBeRelativeToUserSelectAllElement("around");
+
+ // mouse extending from left
+ var leftTarget = userSelectAllElement.previousSibling;
+ log("mouseMoveFromTo(leftTarget.offsetLeft, descendant.offsetLeft + 20)");
+ mouseMoveFromTo(leftTarget.offsetLeft, descendant.offsetLeft + 20);
+ testSelectionAt(leftTarget.firstChild, 0, userSelectAllElement.nextSibling, 0, "the entire user-select-all element plus everything on its left");
+
+ // mouse extending from right
+ var rightTarget = userSelectAllElement.nextSibling;
+ var textLength = rightTarget.textContent.length;
+ log("mouseMoveFromTo(userSelectAllElement.offsetLeft + userSelectAllElement.offsetWidth + rightTarget.offsetWidth, descendant.offsetLeft + 10)");
+ mouseMoveFromTo(userSelectAllElement.offsetLeft + userSelectAllElement.offsetWidth + rightTarget.offsetWidth, descendant.offsetLeft + 10);
+ testSelectionAt(rightTarget.firstChild, textLength, leftTarget.firstChild, leftTarget.textContent.textLength, "the entire user-select-all element plus everything on its right");
+}
+
+function testProgrammaticSelection(){
+ var boldElement = document.querySelector('b');
+ getSelection().selectAllChildren(boldElement);
+ testSelectionAt(boldElement.firstChild, 0, boldElement.firstChild, 10, "only the text in bold");
+}
+</script>
+</head>
+<body><div contenteditable><span>Test -webkit-user-select all </span><span class="userSelectAll" id="allArea"><span style="border: solid red 1px" id="descendant">user <b>select all</b> area</span></span><span> Test -webkit-user-select all</span></div>
+<div id="console"></div>
+<script>
+description(" Test -webkit-user-select all selection movements and extensions (left right forward backward) ");
+testKeyboard();
+testMouse();
+testProgrammaticSelection();
+</script>
+<script src=""
+</body>
+</html>
Modified: trunk/LayoutTests/platform/chromium/TestExpectations (133223 => 133224)
--- trunk/LayoutTests/platform/chromium/TestExpectations 2012-11-01 20:50:43 UTC (rev 133223)
+++ trunk/LayoutTests/platform/chromium/TestExpectations 2012-11-01 20:54:20 UTC (rev 133224)
@@ -4141,6 +4141,7 @@
webkit.org/b/100478 [ Mac ] css3/filters/custom/effect-custom.html [ Pass ImageOnlyFailure ]
+webkit.org/b/100424 editing/selection/user-select-all-selection.html [ Failure ]
webkit.org/b/100475 compositing/tiling/tile-cache-zoomed.html [ Failure ]
webkit.org/b/100475 platform/chromium/virtual/softwarecompositing/tiling/tile-cache-zoomed.html [ Failure ]
webkit.org/b/100477 [ Win ] platform/chromium/fast/forms/suggestion-picker/date-suggestion-picker-key-operations.html [ Failure ]
Modified: trunk/LayoutTests/platform/efl/TestExpectations (133223 => 133224)
--- trunk/LayoutTests/platform/efl/TestExpectations 2012-11-01 20:50:43 UTC (rev 133223)
+++ trunk/LayoutTests/platform/efl/TestExpectations 2012-11-01 20:54:20 UTC (rev 133224)
@@ -1670,6 +1670,8 @@
# Resource Timing is not enable yet, skip it.
webkit.org/b/61138 http/tests/w3c/webperf/submission/Intel/resource-timing [ Skip ]
+webkit.org/b/100424 editing/selection/user-select-all-selection.html [ Failure ]
+
# Entering into full screen playback mode fails when triggered by context menu
Bug(EFL) media/context-menu-actions.html [ Failure ]
Modified: trunk/LayoutTests/platform/gtk/TestExpectations (133223 => 133224)
--- trunk/LayoutTests/platform/gtk/TestExpectations 2012-11-01 20:50:43 UTC (rev 133223)
+++ trunk/LayoutTests/platform/gtk/TestExpectations 2012-11-01 20:54:20 UTC (rev 133224)
@@ -1429,6 +1429,8 @@
webkit.org/b/98718 svg/animations/animate-css-xml-attributeType.html [ Failure ]
+webkit.org/b/100424 editing/selection/user-select-all-selection.html [ Failure ]
+
webkit.org/b/100846 inspector-protocol/debugger-pause-dedicated-worker.html [ Skip ]
webkit.org/b/95299 fast/images/exif-orientation.html [ Failure ]
Modified: trunk/LayoutTests/platform/qt/TestExpectations (133223 => 133224)
--- trunk/LayoutTests/platform/qt/TestExpectations 2012-11-01 20:50:43 UTC (rev 133223)
+++ trunk/LayoutTests/platform/qt/TestExpectations 2012-11-01 20:54:20 UTC (rev 133224)
@@ -2508,6 +2508,8 @@
# [Qt] New http/tests/inspector/network/image-as-text-loading-data-url.html fails
webkit.org/b/100196 http/tests/inspector/network/image-as-text-loading-data-url.html
+webkit.org/b/100424 editing/selection/user-select-all-selection.html [ Failure ]
+
# REGRESSION(r132757): It made 2 jquery tests assert
webkit.org/b/100636 jquery/manipulation.html
webkit.org/b/100636 jquery/traversing.html
Modified: trunk/LayoutTests/platform/win/TestExpectations (133223 => 133224)
--- trunk/LayoutTests/platform/win/TestExpectations 2012-11-01 20:50:43 UTC (rev 133223)
+++ trunk/LayoutTests/platform/win/TestExpectations 2012-11-01 20:54:20 UTC (rev 133224)
@@ -2378,6 +2378,8 @@
# Resource Timing is not enable yet, skip it.
webkit.org/b/61138 http/tests/w3c/webperf/submission/Intel/resource-timing
+webkit.org/b/100424 editing/selection/user-select-all-selection.html [ Failure ]
+
# https://bugs.webkit.org/show_bug.cgi?id=99567
# Not supported on Mac or Windows ports
inspector/elements/update-shadowdom.html
Modified: trunk/Source/WebCore/ChangeLog (133223 => 133224)
--- trunk/Source/WebCore/ChangeLog 2012-11-01 20:50:43 UTC (rev 133223)
+++ trunk/Source/WebCore/ChangeLog 2012-11-01 20:54:20 UTC (rev 133224)
@@ -1,3 +1,75 @@
+2012-11-01 Enrica Casucci <enr...@apple.com>
+
+ Part2 of: Extend -webkit-user-select with new value "all"
+ <rdar://problem/10161404>
+ https://bugs.webkit.org/show_bug.cgi?id=91912
+
+ Reviewed by Ryosuke Niwa.
+
+ The new value "all" for -webkit-user-select property gives content none-or-all selection option.
+ The patch was originally prepared by Alice Cheng but the approach has been changed.
+ The idea is to treat these elements like non editable, meaning that we should skip over them entirely
+ when moving the cursor and a deletion should delete the element and all its descentants at once.
+ The key change is in Node::rendererIsEditable where we now return false if the element style is
+ userSelect: all. The other change is in the way we create the selection on mouse click and dragging
+ over the element. In both cases we force the selection to extend over the entire element with
+ the user-select: all attribute.
+ This is currently enabled only for the Mac port.
+
+ Test: editing/selection/user-select-all-selection.html
+
+ * dom/Node.cpp: Added a parameter to isContentEditable to behave differently
+ when called from _javascript_. Internally isContentEditable returns false on
+ nodes with user-select: all style.
+ (WebCore::Node::isContentEditable):
+ (WebCore::Node::isContentRichlyEditable):
+ (WebCore::Node::rendererIsEditable):
+ (WebCore::Node::shouldUseInputMethod):
+ (WebCore::Node::willRespondToMouseClickEvents):
+ * dom/Node.h:
+ (WebCore::Node::rendererIsEditable):
+ (WebCore::Node::rendererIsRichlyEditable):
+ * dom/Position.cpp:
+ (WebCore::Position::nodeIsUserSelectAll): Added.
+ (WebCore::Position::rootUserSelectAllForNode): Added.
+ * dom/Position.h: Added static functions described above.
+ * editing/ApplyStyleCommand.cpp:
+ (WebCore::ApplyStyleCommand::removeInlineStyleFromElement): Added parameter to
+ isContentEditable() call.
+ (WebCore::ApplyStyleCommand::surroundNodeRangeWithElement): Added parameter to
+ isContentEditable() call.
+ * editing/DeleteFromTextNodeCommand.cpp:
+ (WebCore::DeleteFromTextNodeCommand::doApply): Added parameter to
+ isContentEditable() call.
+ * editing/FrameSelection.cpp:
+ (WebCore::adjustForwardPositionForUserSelectAll): New helper function.
+ (WebCore::adjustBackwardPositionForUserSelectAll): New helper function.
+ (WebCore::FrameSelection::modifyExtendingRight):
+ (WebCore::FrameSelection::modifyExtendingForward):
+ (WebCore::FrameSelection::modifyExtendingLeft):
+ (WebCore::FrameSelection::modifyExtendingBackward):
+ (WebCore::FrameSelection::modify):
+ (WebCore::CaretBase::invalidateCaretRect): Added parameter to
+ isContentEditable() call.
+ * editing/InsertNodeBeforeCommand.cpp:
+ (WebCore::InsertNodeBeforeCommand::doApply): Ditto.
+ (WebCore::InsertNodeBeforeCommand::doUnapply): Ditto.
+ * editing/RemoveNodeCommand.cpp:
+ (WebCore::RemoveNodeCommand::doApply): Ditto.
+ * editing/visible_units.cpp:
+ (WebCore::startOfParagraph): We should not consider a paragraph break and element
+ with user-select: all style, like we do at the border of editability.
+ (WebCore::endOfParagraph): Ditto.
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::updateSelectionForMouseDownDispatchingSelectStart): Create a selection
+ around the element whose style is user-select: all.
+ (WebCore::EventHandler::updateSelectionForMouseDrag): Ditto.
+ * rendering/RootInlineBox.cpp:
+ (WebCore::RootInlineBox::selectionState): Fixed a bug uncovered during this work.
+ If the selection starts in one of the leaf boxes and after we encounter one with SelectionNone,
+ we should return the selection state as SelectionBoth, assuming we went past the end selection.
+ This avoids doing an incorrect gap filling for the selection highlighting.
+
2012-11-01 Alec Flett <alecfl...@chromium.org>
IndexedDB: Fix Windows build by re-adding a #include
Modified: trunk/Source/WebCore/dom/Node.cpp (133223 => 133224)
--- trunk/Source/WebCore/dom/Node.cpp 2012-11-01 20:50:43 UTC (rev 133223)
+++ trunk/Source/WebCore/dom/Node.cpp 2012-11-01 20:54:20 UTC (rev 133224)
@@ -717,16 +717,16 @@
return nullAtom;
}
-bool Node::isContentEditable()
+bool Node::isContentEditable(UserSelectAllTreatment treatment)
{
document()->updateStyleIfNeeded();
- return rendererIsEditable(Editable);
+ return rendererIsEditable(Editable, treatment);
}
bool Node::isContentRichlyEditable()
{
document()->updateStyleIfNeeded();
- return rendererIsEditable(RichlyEditable);
+ return rendererIsEditable(RichlyEditable, UserSelectAllIsAlwaysNonEditable);
}
void Node::inspect()
@@ -737,7 +737,7 @@
#endif
}
-bool Node::rendererIsEditable(EditableLevel editableLevel) const
+bool Node::rendererIsEditable(EditableLevel editableLevel, UserSelectAllTreatment treatment) const
{
if (document()->frame() && document()->frame()->page() && document()->frame()->page()->isEditable() && !shadowRoot())
return true;
@@ -748,6 +748,12 @@
for (const Node* node = this; node; node = node->parentNode()) {
if ((node->isHTMLElement() || node->isDocumentNode()) && node->renderer()) {
+#if ENABLE(USERSELECT_ALL)
+ // Elements with user-select: all style are considered atomic
+ // therefore non editable.
+ if (node->renderer()->style()->userSelect() == SELECT_ALL && treatment == UserSelectAllIsAlwaysNonEditable)
+ return false;
+#endif
switch (node->renderer()->style()->userModify()) {
case READ_ONLY:
return false;
@@ -785,7 +791,7 @@
bool Node::shouldUseInputMethod()
{
- return isContentEditable();
+ return isContentEditable(UserSelectAllIsAlwaysNonEditable);
}
RenderBox* Node::renderBox() const
@@ -2746,7 +2752,7 @@
{
if (disabled())
return false;
- return isContentEditable() || hasEventListeners(eventNames().mouseupEvent) || hasEventListeners(eventNames().mousedownEvent) || hasEventListeners(eventNames().clickEvent) || hasEventListeners(eventNames().DOMActivateEvent);
+ return isContentEditable(UserSelectAllIsAlwaysNonEditable) || hasEventListeners(eventNames().mouseupEvent) || hasEventListeners(eventNames().mousedownEvent) || hasEventListeners(eventNames().clickEvent) || hasEventListeners(eventNames().DOMActivateEvent);
}
bool Node::willRespondToTouchEvents()
Modified: trunk/Source/WebCore/dom/Node.h (133223 => 133224)
--- trunk/Source/WebCore/dom/Node.h 2012-11-01 20:50:43 UTC (rev 133223)
+++ trunk/Source/WebCore/dom/Node.h 2012-11-01 20:54:20 UTC (rev 133224)
@@ -375,16 +375,20 @@
virtual bool isMouseFocusable() const;
virtual Node* focusDelegate();
- bool isContentEditable();
+ enum UserSelectAllTreatment {
+ UserSelectAllDoesNotAffectEditability,
+ UserSelectAllIsAlwaysNonEditable
+ };
+ bool isContentEditable(UserSelectAllTreatment = UserSelectAllDoesNotAffectEditability);
bool isContentRichlyEditable();
void inspect();
- bool rendererIsEditable(EditableType editableType = ContentIsEditable) const
+ bool rendererIsEditable(EditableType editableType = ContentIsEditable, UserSelectAllTreatment treatment = UserSelectAllIsAlwaysNonEditable) const
{
switch (editableType) {
case ContentIsEditable:
- return rendererIsEditable(Editable);
+ return rendererIsEditable(Editable, treatment);
case HasEditableAXRole:
return isEditableToAccessibility(Editable);
}
@@ -396,7 +400,7 @@
{
switch (editableType) {
case ContentIsEditable:
- return rendererIsEditable(RichlyEditable);
+ return rendererIsEditable(RichlyEditable, UserSelectAllIsAlwaysNonEditable);
case HasEditableAXRole:
return isEditableToAccessibility(RichlyEditable);
}
@@ -768,7 +772,7 @@
void setDocument(Document*);
enum EditableLevel { Editable, RichlyEditable };
- bool rendererIsEditable(EditableLevel) const;
+ bool rendererIsEditable(EditableLevel, UserSelectAllTreatment = UserSelectAllIsAlwaysNonEditable) const;
bool isEditableToAccessibility(EditableLevel) const;
void setStyleChange(StyleChangeType);
Modified: trunk/Source/WebCore/dom/Position.cpp (133223 => 133224)
--- trunk/Source/WebCore/dom/Position.cpp 2012-11-01 20:50:43 UTC (rev 133223)
+++ trunk/Source/WebCore/dom/Position.cpp 2012-11-01 20:54:20 UTC (rev 133224)
@@ -865,6 +865,35 @@
return node->nonShadowBoundaryParentNode();
}
+#if ENABLE(USERSELECT_ALL)
+bool Position::nodeIsUserSelectAll(const Node* node)
+{
+ return node && node->renderer() && node->renderer()->style()->userSelect() == SELECT_ALL;
+}
+
+Node* Position::rootUserSelectAllForNode(Node* node)
+{
+ if (!node || !nodeIsUserSelectAll(node))
+ return 0;
+ Node* parent = node->parentNode();
+ if (!parent)
+ return node;
+
+ Node* candidateRoot = node;
+ while (parent) {
+ if (!parent->renderer()) {
+ parent = parent->parentNode();
+ continue;
+ }
+ if (!nodeIsUserSelectAll(parent))
+ break;
+ candidateRoot = parent;
+ parent = candidateRoot->parentNode();
+ }
+ return candidateRoot;
+}
+#endif
+
bool Position::isCandidate() const
{
if (isNull())
Modified: trunk/Source/WebCore/dom/Position.h (133223 => 133224)
--- trunk/Source/WebCore/dom/Position.h 2012-11-01 20:50:43 UTC (rev 133223)
+++ trunk/Source/WebCore/dom/Position.h 2012-11-01 20:54:20 UTC (rev 133224)
@@ -189,7 +189,10 @@
static bool hasRenderedNonAnonymousDescendantsWithHeight(RenderObject*);
static bool nodeIsUserSelectNone(Node*);
-
+#if ENABLE(USERSELECT_ALL)
+ static bool nodeIsUserSelectAll(const Node*);
+ static Node* rootUserSelectAllForNode(Node*);
+#endif
static ContainerNode* findParent(const Node*);
void debugPosition(const char* msg = "") const;
Modified: trunk/Source/WebCore/editing/ApplyStyleCommand.cpp (133223 => 133224)
--- trunk/Source/WebCore/editing/ApplyStyleCommand.cpp 2012-11-01 20:50:43 UTC (rev 133223)
+++ trunk/Source/WebCore/editing/ApplyStyleCommand.cpp 2012-11-01 20:54:20 UTC (rev 133224)
@@ -825,7 +825,7 @@
{
ASSERT(element);
- if (!element->parentNode() || !element->parentNode()->isContentEditable())
+ if (!element->parentNode() || !element->parentNode()->isContentEditable(Node::UserSelectAllIsAlwaysNonEditable))
return false;
if (isStyledInlineElementToRemove(element.get())) {
@@ -1288,7 +1288,7 @@
RefPtr<Node> node = startNode;
while (node) {
RefPtr<Node> next = node->nextSibling();
- if (node->isContentEditable()) {
+ if (node->isContentEditable(Node::UserSelectAllIsAlwaysNonEditable)) {
removeNode(node);
appendNode(node, element);
}
Modified: trunk/Source/WebCore/editing/DeleteFromTextNodeCommand.cpp (133223 => 133224)
--- trunk/Source/WebCore/editing/DeleteFromTextNodeCommand.cpp 2012-11-01 20:50:43 UTC (rev 133223)
+++ trunk/Source/WebCore/editing/DeleteFromTextNodeCommand.cpp 2012-11-01 20:54:20 UTC (rev 133224)
@@ -47,7 +47,7 @@
{
ASSERT(m_node);
- if (!m_node->isContentEditable())
+ if (!m_node->isContentEditable(Node::UserSelectAllIsAlwaysNonEditable))
return;
ExceptionCode ec = 0;
Modified: trunk/Source/WebCore/editing/FrameSelection.cpp (133223 => 133224)
--- trunk/Source/WebCore/editing/FrameSelection.cpp 2012-11-01 20:50:43 UTC (rev 133223)
+++ trunk/Source/WebCore/editing/FrameSelection.cpp 2012-11-01 20:54:20 UTC (rev 133224)
@@ -556,6 +556,14 @@
return positionForPlatform(false);
}
+#if ENABLE(USERSELECT_ALL)
+static void adjustPositionForUserSelectAll(VisiblePosition& pos, bool isForward)
+{
+ if (Node* rootUserSelectAll = Position::rootUserSelectAllForNode(pos.deepEquivalent().anchorNode()))
+ pos = isForward ? positionAfterNode(rootUserSelectAll).downstream(CanCrossEditingBoundary) : positionBeforeNode(rootUserSelectAll).upstream(CanCrossEditingBoundary);
+}
+#endif
+
VisiblePosition FrameSelection::modifyExtendingRight(TextGranularity granularity)
{
VisiblePosition pos(m_selection.extent(), m_selection.affinity());
@@ -594,6 +602,9 @@
pos = modifyExtendingForward(granularity);
break;
}
+#if ENABLE(USERSELECT_ALL)
+ adjustPositionForUserSelectAll(pos, directionOfEnclosingBlock() == LTR);
+#endif
return pos;
}
@@ -633,7 +644,9 @@
pos = endOfDocument(pos);
break;
}
-
+#if ENABLE(USERSELECT_ALL)
+ adjustPositionForUserSelectAll(pos, directionOfEnclosingBlock() == LTR);
+#endif
return pos;
}
@@ -760,6 +773,9 @@
pos = modifyExtendingBackward(granularity);
break;
}
+#if ENABLE(USERSELECT_ALL)
+ adjustPositionForUserSelectAll(pos, !(directionOfEnclosingBlock() == LTR));
+#endif
return pos;
}
@@ -804,6 +820,9 @@
pos = startOfDocument(pos);
break;
}
+#if ENABLE(USERSELECT_ALL)
+ adjustPositionForUserSelectAll(pos, !(directionOfEnclosingBlock() == LTR));
+#endif
return pos;
}
@@ -956,6 +975,7 @@
moveTo(position, userTriggered);
break;
case AlterationExtend:
+
if (!m_selection.isCaret()
&& (granularity == WordGranularity || granularity == ParagraphGranularity || granularity == LineGranularity)
&& m_frame && !m_frame->editor()->behavior().shouldExtendSelectionByWordOrLineAcrossCaret()) {
@@ -1365,7 +1385,7 @@
if (!caretRectChanged) {
RenderView* view = toRenderView(node->document()->renderer());
- if (view && shouldRepaintCaret(view, node->isContentEditable()))
+ if (view && shouldRepaintCaret(view, node->isContentEditable(Node::UserSelectAllIsAlwaysNonEditable)))
view->repaintRectangleInViewAndCompositedLayers(caretRepaintRect(node), false);
}
}
Modified: trunk/Source/WebCore/editing/InsertNodeBeforeCommand.cpp (133223 => 133224)
--- trunk/Source/WebCore/editing/InsertNodeBeforeCommand.cpp 2012-11-01 20:50:43 UTC (rev 133223)
+++ trunk/Source/WebCore/editing/InsertNodeBeforeCommand.cpp 2012-11-01 20:54:20 UTC (rev 133224)
@@ -48,7 +48,7 @@
void InsertNodeBeforeCommand::doApply()
{
ContainerNode* parent = m_refChild->parentNode();
- if (!parent || !parent->isContentEditable())
+ if (!parent || !parent->isContentEditable(Node::UserSelectAllIsAlwaysNonEditable))
return;
ExceptionCode ec;
@@ -60,7 +60,7 @@
void InsertNodeBeforeCommand::doUnapply()
{
- if (!m_insertChild->isContentEditable())
+ if (!m_insertChild->isContentEditable(Node::UserSelectAllIsAlwaysNonEditable))
return;
// Need to notify this before actually deleting the text
Modified: trunk/Source/WebCore/editing/RemoveNodeCommand.cpp (133223 => 133224)
--- trunk/Source/WebCore/editing/RemoveNodeCommand.cpp 2012-11-01 20:50:43 UTC (rev 133223)
+++ trunk/Source/WebCore/editing/RemoveNodeCommand.cpp 2012-11-01 20:54:20 UTC (rev 133224)
@@ -42,7 +42,7 @@
void RemoveNodeCommand::doApply()
{
ContainerNode* parent = m_node->parentNode();
- if (!parent || !parent->isContentEditable())
+ if (!parent || !parent->isContentEditable(Node::UserSelectAllIsAlwaysNonEditable))
return;
m_parent = parent;
Modified: trunk/Source/WebCore/editing/visible_units.cpp (133223 => 133224)
--- trunk/Source/WebCore/editing/visible_units.cpp 2012-11-01 20:50:43 UTC (rev 133223)
+++ trunk/Source/WebCore/editing/visible_units.cpp 2012-11-01 20:54:20 UTC (rev 133224)
@@ -1108,7 +1108,11 @@
Node* n = startNode;
while (n) {
+#if ENABLE(USERSELECT_ALL)
+ if (boundaryCrossingRule == CannotCrossEditingBoundary && !Position::nodeIsUserSelectAll(n) && n->rendererIsEditable() != startNode->rendererIsEditable())
+#else
if (boundaryCrossingRule == CannotCrossEditingBoundary && n->rendererIsEditable() != startNode->rendererIsEditable())
+#endif
break;
if (boundaryCrossingRule == CanSkipOverEditingBoundary) {
while (n && n->rendererIsEditable() != startNode->rendererIsEditable())
@@ -1184,7 +1188,11 @@
Node* n = startNode;
while (n) {
+#if ENABLE(USERSELECT_ALL)
+ if (boundaryCrossingRule == CannotCrossEditingBoundary && !Position::nodeIsUserSelectAll(n) && n->rendererIsEditable() != startNode->rendererIsEditable())
+#else
if (boundaryCrossingRule == CannotCrossEditingBoundary && n->rendererIsEditable() != startNode->rendererIsEditable())
+#endif
break;
if (boundaryCrossingRule == CanSkipOverEditingBoundary) {
while (n && n->rendererIsEditable() != startNode->rendererIsEditable())
Modified: trunk/Source/WebCore/page/EventHandler.cpp (133223 => 133224)
--- trunk/Source/WebCore/page/EventHandler.cpp 2012-11-01 20:50:43 UTC (rev 133223)
+++ trunk/Source/WebCore/page/EventHandler.cpp 2012-11-01 20:54:20 UTC (rev 133224)
@@ -418,14 +418,21 @@
if (!dispatchSelectStart(targetNode))
return false;
- if (newSelection.isRange())
+ VisibleSelection selection(newSelection);
+#if ENABLE(USERSELECT_ALL)
+ if (Node* rootUserSelectAll = Position::rootUserSelectAllForNode(targetNode)) {
+ selection.setBase(positionBeforeNode(rootUserSelectAll).upstream(CanCrossEditingBoundary));
+ selection.setExtent(positionAfterNode(rootUserSelectAll).downstream(CanCrossEditingBoundary));
+ }
+#endif
+ if (selection.isRange())
m_selectionInitiationState = ExtendedSelection;
else {
granularity = CharacterGranularity;
m_selectionInitiationState = PlacedCaret;
}
- m_frame->selection()->setNonDirectionalSelectionIfNeeded(newSelection, granularity);
+ m_frame->selection()->setNonDirectionalSelectionIfNeeded(selection, granularity);
return true;
}
@@ -844,7 +851,25 @@
newSelection = VisibleSelection(targetPosition);
}
- newSelection.setExtent(targetPosition);
+#if ENABLE(USERSELECT_ALL)
+ Node* rootUserSelectAllForMousePressNode = Position::rootUserSelectAllForNode(m_mousePressNode.get());
+ if (rootUserSelectAllForMousePressNode && rootUserSelectAllForMousePressNode == Position::rootUserSelectAllForNode(target)) {
+ newSelection.setBase(positionBeforeNode(rootUserSelectAllForMousePressNode).upstream(CanCrossEditingBoundary));
+ newSelection.setExtent(positionAfterNode(rootUserSelectAllForMousePressNode).downstream(CanCrossEditingBoundary));
+ } else {
+ // Reset base for user select all when base is inside user-select-all area and extent < base.
+ if (rootUserSelectAllForMousePressNode && comparePositions(target->renderer()->positionForPoint(hitTestResult.localPoint()), m_mousePressNode->renderer()->positionForPoint(m_dragStartPos)) < 0)
+ newSelection.setBase(positionAfterNode(rootUserSelectAllForMousePressNode).downstream(CanCrossEditingBoundary));
+
+ Node* rootUserSelectAllForTarget = Position::rootUserSelectAllForNode(target);
+ if (rootUserSelectAllForTarget && m_mousePressNode->renderer() && comparePositions(target->renderer()->positionForPoint(hitTestResult.localPoint()), m_mousePressNode->renderer()->positionForPoint(m_dragStartPos)) < 0)
+ newSelection.setExtent(positionBeforeNode(rootUserSelectAllForTarget).upstream(CanCrossEditingBoundary));
+ else if (rootUserSelectAllForTarget && m_mousePressNode->renderer())
+ newSelection.setExtent(positionAfterNode(rootUserSelectAllForTarget).downstream(CanCrossEditingBoundary));
+ else
+ newSelection.setExtent(targetPosition);
+ }
+#endif
if (m_frame->selection()->granularity() != CharacterGranularity)
newSelection.expandUsingGranularity(m_frame->selection()->granularity());
Modified: trunk/Source/WebCore/rendering/RootInlineBox.cpp (133223 => 133224)
--- trunk/Source/WebCore/rendering/RootInlineBox.cpp 2012-11-01 20:50:43 UTC (rev 133223)
+++ trunk/Source/WebCore/rendering/RootInlineBox.cpp 2012-11-01 20:54:20 UTC (rev 133224)
@@ -499,6 +499,10 @@
((boxState == RenderObject::SelectionStart || boxState == RenderObject::SelectionEnd) &&
(state == RenderObject::SelectionNone || state == RenderObject::SelectionInside)))
state = boxState;
+ else if (boxState == RenderObject::SelectionNone && state == RenderObject::SelectionStart) {
+ // We are past the end of the selection.
+ state = RenderObject::SelectionBoth;
+ }
if (state == RenderObject::SelectionBoth)
break;
}