Changeset 259930 in webkit
- Timestamp:
- Apr 11, 2020 8:35:04 AM (4 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r259922 r259930 1 2020-04-08 Darin Adler <darin@apple.com> 2 3 Use Node::length to replace Node::maxCharacterOffset and lastOffsetInNode; switch more offsets from int to unsigned 4 https://bugs.webkit.org/show_bug.cgi?id=210246 5 6 Reviewed by Antti Koivisto. 7 8 - The recently-added Node::length, which matches the DOM specification terminology 9 for node offsets as used in ranges, is the same as the existing maxCharacterOffset 10 and lastOffsetInNode functions. Deleted all uses of those and replaced them 11 with calls to Node::length. One of the benefits of this is that Node::length is 12 implemented more efficiently and is not a virtual function. Another is consistently 13 matching the DOM specification terminology. 14 - Many offsets, including the ones in live ranges, are currently implemented as signed 15 in WebKit, but are specified as unsigned in the DOM and HTML specifications. This 16 has very little observable effect from JavaScript that can affect website compatibility, 17 but it's still helpful to be consistent both with the specification and internally. 18 Accordingly, changed some of these to unsigned; more to come later. 19 20 * accessibility/AXObjectCache.cpp: 21 (WebCore::AXObjectCache::previousBoundary): Use length instead of 22 maxCharacterOffset. 23 24 * dom/CharacterData.cpp: 25 (WebCore::CharacterData::maxCharacterOffset const): Deleted. 26 * dom/CharacterData.h: Deleted maxCharacterOffset override. 27 28 * dom/DocumentMarkerController.cpp: 29 (WebCore::DocumentMarkerController::shiftMarkers): Use length instead of 30 maxCharacterOffset. 31 32 * dom/Node.cpp: 33 (WebCore::Node::maxCharacterOffset const): Deleted. 34 * dom/Node.h: Deleted maxCharacterOffset. 35 36 * dom/Position.cpp: 37 (WebCore::Position::computeOffsetInContainerNode const): Use length instead 38 of lastOffsetInNode. 39 40 * dom/Position.h: 41 (WebCore::lastOffsetInNode): Deleted. 42 (WebCore::lastPositionInNode): Use length instead of lastOffsetInNode. 43 (WebCore::minOffsetForNode): Use length instead of maxCharacterOffset. 44 (WebCore::offsetIsBeforeLastNodeOffset): Ditto. 45 46 * dom/RangeBoundaryPoint.h: 47 (WebCore::RangeBoundaryPoint::setToEndOfNode): Use length instead of 48 maxCharacterOffset. 49 50 * editing/ApplyBlockElementCommand.cpp: 51 (WebCore::isNewLineAtPosition): Use length instead of maxCharacterOffset. 52 (WebCore::ApplyBlockElementCommand::rangeForParagraphSplittingTextNodesIfNeeded): 53 Ditto. 54 55 * editing/ApplyStyleCommand.cpp: 56 (WebCore::ApplyStyleCommand::removeInlineStyle): Use length instead of 57 maxCharacterOffset. 58 59 * editing/Editing.cpp: 60 (WebCore::lastOffsetForEditing): Use length instead of mmaxCharacterOffset 61 and countChildNodes. Also improved the comment here. 62 63 * editing/EditingStyle.cpp: 64 (WebCore::EditingStyle::styleAtSelectionStart): Use length instead of 65 maxCharacterOffset. 66 67 * editing/InsertListCommand.cpp: 68 (WebCore::InsertListCommand::doApplyForSingleParagraph): Use length instead 69 of lastOffsetInNode. 70 71 * editing/TextIterator.cpp: 72 (WebCore::SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator): 73 USe length instead of lastOffsetInNode. 74 75 * editing/VisibleUnits.cpp: 76 (WebCore::previousBoundary): Use length instead of maxCharacterOffset. 77 1 78 2020-04-10 Alex Christensen <achristensen@webkit.org> 2 79 -
trunk/Source/WebCore/accessibility/AXObjectCache.cpp
r259633 r259930 2665 2665 return startOrEndCharacterOffsetForRange(rangeForNodeContents(nextSibling), false); 2666 2666 2667 if ((!suffixLength && node.isTextNode() && static_cast<int>(next) <= node.maxCharacterOffset()) || (node.renderer() && node.renderer()->isBR() && !next)) {2667 if ((!suffixLength && node.isTextNode() && next <= node.length()) || (node.renderer() && node.renderer()->isBR() && !next)) { 2668 2668 // The next variable contains a usable index into a text node 2669 2669 if (node.isTextNode()) -
trunk/Source/WebCore/accessibility/atk/WebKitAccessibleUtil.cpp
r258871 r259930 169 169 auto& node = *coreObject->node(); 170 170 auto* lastDescendant = node.lastDescendant(); 171 unsigned lastOffset = last OffsetInNode(lastDescendant);171 unsigned lastOffset = lastDescendant->length(); 172 172 auto intersectsResult = range->intersectsNode(node); 173 173 return !intersectsResult.hasException() -
trunk/Source/WebCore/dom/CharacterData.cpp
r240237 r259930 240 240 } 241 241 242 int CharacterData::maxCharacterOffset() const243 {244 return static_cast<int>(length());245 }246 247 242 } // namespace WebCore -
trunk/Source/WebCore/dom/CharacterData.h
r259575 r259930 64 64 ExceptionOr<void> setNodeValue(const String&) final; 65 65 bool virtualIsCharacterData() const final { return true; } 66 int maxCharacterOffset() const final;67 66 void setDataAndUpdate(const String&, unsigned offsetOfReplacedData, unsigned oldLength, unsigned newLength); 68 67 void notifyParentAfterChange(ContainerNode::ChildChangeSource); -
trunk/Source/WebCore/dom/DocumentMarkerController.cpp
r259575 r259930 598 598 int targetStartOffset = marker.startOffset() + delta; 599 599 int targetEndOffset = marker.endOffset() + delta; 600 if ( targetStartOffset >= node.maxCharacterOffset() || targetEndOffset <= 0) {600 if (static_cast<unsigned>(targetStartOffset) >= node.length() || targetEndOffset <= 0) { 601 601 list->remove(i); 602 602 continue; … … 616 616 continue; 617 617 } 618 marker.setEndOffset( targetEndOffset < node.maxCharacterOffset() ? targetEndOffset : node.maxCharacterOffset());618 marker.setEndOffset(std::min<unsigned>(targetEndOffset, node.length())); 619 619 didShiftMarker = true; 620 620 } -
trunk/Source/WebCore/dom/Node.cpp
r259581 r259930 1103 1103 } 1104 1104 1105 int Node::maxCharacterOffset() const1106 {1107 ASSERT_NOT_REACHED();1108 return 0;1109 }1110 1111 1105 // FIXME: Shouldn't these functions be in the editing code? Code that asks questions about HTML in the core DOM class 1112 1106 // is obviously misplaced. -
trunk/Source/WebCore/dom/Node.h
r259575 r259930 378 378 bool containsIncludingShadowDOM(const Node*) const; 379 379 380 // Number of DOM 16-bit units contained in node. Note that rendered text length can be different - e.g. because of381 // css-transform:capitalize breaking up precomposed characters and ligatures.382 virtual int maxCharacterOffset() const;383 384 380 // Whether or not a selection can be started in this object 385 381 virtual bool canStartSelection() const; -
trunk/Source/WebCore/dom/Position.cpp
r258609 r259930 208 208 return 0; 209 209 case PositionIsAfterChildren: 210 return lastOffsetInNode(m_anchorNode.get());210 return m_anchorNode->length(); 211 211 case PositionIsOffsetInAnchor: 212 212 return minOffsetForNode(m_anchorNode.get(), m_offset); -
trunk/Source/WebCore/dom/Position.h
r259184 r259930 26 26 #pragma once 27 27 28 #include "CharacterData.h" 28 29 #include "ContainerNode.h" 29 30 #include "EditingBoundary.h" … … 238 239 Position positionAfterNode(Node* anchorNode); 239 240 240 int lastOffsetInNode(Node*);241 242 241 // firstPositionInNode and lastPositionInNode return parent-anchored positions, lastPositionInNode construction is O(n) due to countChildNodes() 243 242 Position firstPositionInNode(Node* anchorNode); … … 307 306 } 308 307 309 inline int lastOffsetInNode(Node* node)310 {311 return node->isCharacterDataNode() ? node->maxCharacterOffset() : node->countChildNodes();312 }313 314 308 // firstPositionInNode and lastPositionInNode return parent-anchored positions, lastPositionInNode construction is O(n) due to countChildNodes() 315 309 inline Position firstPositionInNode(Node* anchorNode) … … 323 317 { 324 318 if (anchorNode->isTextNode()) 325 return Position(anchorNode, lastOffsetInNode(anchorNode), Position::PositionIsOffsetInAnchor);319 return Position(anchorNode, anchorNode->length(), Position::PositionIsOffsetInAnchor); 326 320 return Position(anchorNode, Position::PositionIsAfterChildren); 327 321 } … … 329 323 inline int minOffsetForNode(Node* anchorNode, unsigned offset) 330 324 { 331 if ( anchorNode->isCharacterDataNode())332 return std::min <unsigned>(offset, anchorNode->maxCharacterOffset());325 if (is<CharacterData>(*anchorNode)) 326 return std::min(offset, downcast<CharacterData>(*anchorNode).length()); 333 327 334 328 unsigned newOffset = 0; 335 329 for (Node* node = anchorNode->firstChild(); node && newOffset < offset; node = node->nextSibling()) 336 330 newOffset++; 337 338 331 return newOffset; 339 332 } … … 341 334 inline bool offsetIsBeforeLastNodeOffset(unsigned offset, Node* anchorNode) 342 335 { 343 if ( anchorNode->isCharacterDataNode())344 return offset < static_cast<unsigned>(anchorNode->maxCharacterOffset());336 if (is<CharacterData>(*anchorNode)) 337 return offset < downcast<CharacterData>(*anchorNode).length(); 345 338 346 339 unsigned currentOffset = 0; 347 340 for (Node* node = anchorNode->firstChild(); node && currentOffset < offset; node = node->nextSibling()) 348 341 currentOffset++; 349 350 351 342 return offset < currentOffset; 352 343 } -
trunk/Source/WebCore/dom/RangeBoundaryPoint.h
r258250 r259930 148 148 { 149 149 m_containerNode = WTFMove(container); 150 if ( m_containerNode->isCharacterDataNode()) {151 m_offsetInContainer = m_containerNode->maxCharacterOffset();150 if (is<CharacterData>(*m_containerNode)) { 151 m_offsetInContainer = downcast<CharacterData>(*m_containerNode).length(); 152 152 m_childBeforeBoundary = nullptr; 153 153 } else { -
trunk/Source/WebCore/editing/ApplyBlockElementCommand.cpp
r259619 r259930 176 176 { 177 177 Node* textNode = position.containerNode(); 178 intoffset = position.offsetInContainerNode();179 if (!is<Text>(textNode) || offset < 0 || offset >= textNode->maxCharacterOffset())178 unsigned offset = position.offsetInContainerNode(); 179 if (!is<Text>(textNode) || offset >= downcast<Text>(*textNode).length()) 180 180 return false; 181 181 return downcast<Text>(*textNode).data()[offset] == '\n'; … … 233 233 bool isEndAndEndOfLastParagraphOnSameNode = renderStyleOfEnclosingTextNode(m_endOfLastParagraph) && end.deprecatedNode() == m_endOfLastParagraph.deprecatedNode(); 234 234 // Include \n at the end of line if we're at an empty paragraph 235 if (endStyle->preserveNewline() && start == end && end.offsetInContainerNode() < end.containerNode()->maxCharacterOffset()) {236 int endOffset = end.offsetInContainerNode();235 unsigned endOffset = end.offsetInContainerNode(); 236 if (endStyle->preserveNewline() && start == end && endOffset < end.containerNode()->length()) { 237 237 if (!isNewLineAtPosition(end.previous()) && isNewLineAtPosition(end)) 238 end = Position(end.containerText(), endOffset + 1);238 end = Position(end.containerText(), ++endOffset); 239 239 if (isEndAndEndOfLastParagraphOnSameNode && end.offsetInContainerNode() >= m_endOfLastParagraph.offsetInContainerNode()) 240 240 m_endOfLastParagraph = end; … … 242 242 243 243 // If end is in the middle of a text node and the text node is editable, split. 244 if (endStyle->userModify() != UserModify::ReadOnly && !endStyle->collapseWhiteSpace() && end .offsetInContainerNode() && end.offsetInContainerNode() < end.containerNode()->maxCharacterOffset()) {244 if (endStyle->userModify() != UserModify::ReadOnly && !endStyle->collapseWhiteSpace() && endOffset && endOffset < end.containerNode()->length()) { 245 245 RefPtr<Text> endContainer = end.containerText(); 246 splitTextNode(*endContainer, end .offsetInContainerNode());246 splitTextNode(*endContainer, endOffset); 247 247 if (is<Text>(endContainer) && !endContainer->previousSibling()) { 248 248 start = { }; … … 253 253 start = firstPositionInOrBeforeNode(endContainer->previousSibling()); 254 254 if (isEndAndEndOfLastParagraphOnSameNode) { 255 if ( m_endOfLastParagraph.offsetInContainerNode() == end.offsetInContainerNode())255 if (static_cast<unsigned>(m_endOfLastParagraph.offsetInContainerNode()) == endOffset) 256 256 m_endOfLastParagraph = lastPositionInOrAfterNode(endContainer->previousSibling()); 257 257 else 258 m_endOfLastParagraph = Position(endContainer.get(), m_endOfLastParagraph.offsetInContainerNode() - end .offsetInContainerNode());258 m_endOfLastParagraph = Position(endContainer.get(), m_endOfLastParagraph.offsetInContainerNode() - endOffset); 259 259 } 260 260 end = lastPositionInNode(endContainer->previousSibling()); -
trunk/Source/WebCore/editing/ApplyStyleCommand.cpp
r259184 r259930 1092 1092 // e.g. if pushDownStart was at Position("hello", 5) in <b>hello<div>world</div></b>, we want Position("world", 0) instead. 1093 1093 auto* pushDownStartContainer = pushDownStart.containerNode(); 1094 if (is<Text>(pushDownStartContainer) && pushDownStart.computeOffsetInContainerNode() == pushDownStartContainer->maxCharacterOffset())1094 if (is<Text>(pushDownStartContainer) && static_cast<unsigned>(pushDownStart.computeOffsetInContainerNode()) == downcast<Text>(*pushDownStartContainer).length()) 1095 1095 pushDownStart = nextVisuallyDistinctCandidate(pushDownStart); 1096 1096 // If pushDownEnd is at the start of a text node, then this node is not fully selected. -
trunk/Source/WebCore/editing/Editing.cpp
r259575 r259930 378 378 int lastOffsetForEditing(const Node& node) 379 379 { 380 if (node.isCharacterDataNode()) 381 return node.maxCharacterOffset(); 382 383 if (node.hasChildNodes()) 384 return node.countChildNodes(); 385 386 // NOTE: This should preempt the countChildNodes() for, e.g., select nodes. 387 // FIXME: What does the comment above mean? 388 if (editingIgnoresContent(node)) 389 return 1; 390 391 return 0; 380 if (node.isCharacterDataNode() || node.hasChildNodes()) 381 return node.length(); 382 383 // FIXME: Might be more helpful to return 1 for any node where editingIgnoresContent is true, even one that happens to have child nodes, like a select element with option node children. 384 return editingIgnoresContent(node) ? 1 : 0; 392 385 } 393 386 -
trunk/Source/WebCore/editing/EditingStyle.cpp
r256580 r259930 1498 1498 // We only do this for range because caret at Position("hello", 5) in <b>hello</b>world should give you font-weight: bold. 1499 1499 Node* positionNode = position.containerNode(); 1500 if (selection.isRange() && positionNode && positionNode->isTextNode() && position.computeOffsetInContainerNode() == positionNode->maxCharacterOffset())1501 position = nextVisuallyDistinctCandidate(position); 1500 if (selection.isRange() && is<Text>(positionNode) && static_cast<unsigned>(position.computeOffsetInContainerNode()) == downcast<Text>(*positionNode).length()) 1501 position = nextVisuallyDistinctCandidate(position); 1502 1502 1503 1503 Element* element = position.element(); -
trunk/Source/WebCore/editing/InsertListCommand.cpp
r259899 r259930 257 257 currentSelection->setStart(*newList, 0); 258 258 if (rangeEndIsInList && newList) 259 currentSelection->setEnd(*newList, lastOffsetInNode(newList.get()));259 currentSelection->setEnd(*newList, newList->length()); 260 260 261 261 setEndingSelection(VisiblePosition(firstPositionInNode(newList.get()))); -
trunk/Source/WebCore/editing/TextIterator.cpp
r259401 r259930 1135 1135 if (endOffset > 0 && endOffset <= endNode->countChildNodes()) { 1136 1136 endNode = endNode->traverseToChildAt(endOffset - 1); 1137 endOffset = lastOffsetInNode(endNode);1137 endOffset = endNode->length(); 1138 1138 } 1139 1139 } -
trunk/Source/WebCore/editing/VisibleUnits.cpp
r259401 r259930 638 638 639 639 auto& node = it.atEnd() ? searchRange->startContainer() : it.range().start.container.get(); 640 if ((!suffixLength && node.isTextNode() && static_cast<int>(next) <= node.maxCharacterOffset()) || (node.renderer() && node.renderer()->isBR() && !next)) {640 if ((!suffixLength && is<Text>(node) && next <= downcast<Text>(node).length()) || (node.renderer() && node.renderer()->isBR() && !next)) { 641 641 // The next variable contains a usable index into a text node 642 642 return VisiblePosition(createLegacyEditingPosition(&node, next), DOWNSTREAM); -
trunk/Source/WebCore/html/HTMLTextFormControlElement.cpp
r257839 r259930 469 469 ASSERT(!node->firstChild()); 470 470 ASSERT(node->isTextNode() || node->hasTagName(brTag)); 471 int length = node->isTextNode() ? lastOffsetInNode(node.get()) : 1;471 int length = is<Text>(*node) ? downcast<Text>(*node).length() : 1; 472 472 473 473 if (offset <= start && start <= offset + length)
Note: See TracChangeset
for help on using the changeset viewer.