diff options
Diffstat (limited to 'WebCore/editing/Editor.cpp')
-rw-r--r-- | WebCore/editing/Editor.cpp | 113 |
1 files changed, 70 insertions, 43 deletions
diff --git a/WebCore/editing/Editor.cpp b/WebCore/editing/Editor.cpp index c515bfc..24c1680 100644 --- a/WebCore/editing/Editor.cpp +++ b/WebCore/editing/Editor.cpp @@ -257,7 +257,7 @@ bool Editor::smartInsertDeleteEnabled() bool Editor::canSmartCopyOrDelete() { - return client() && client()->smartInsertDeleteEnabled() && m_frame->selectionGranularity() == WordGranularity; + return client() && client()->smartInsertDeleteEnabled() && m_frame->selection()->granularity() == WordGranularity; } bool Editor::isSelectTrailingWhitespaceEnabled() @@ -341,6 +341,7 @@ void Editor::pasteAsPlainTextWithPasteboard(Pasteboard* pasteboard) pasteAsPlainText(text, canSmartReplaceWithPasteboard(pasteboard)); } +#if !PLATFORM(MAC) void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText) { RefPtr<Range> range = selectedRange(); @@ -349,6 +350,7 @@ void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText) if (fragment && shouldInsertFragment(fragment, range, EditorInsertActionPasted)) pasteAsFragment(fragment, canSmartReplaceWithPasteboard(pasteboard), chosePlainText); } +#endif bool Editor::canSmartReplaceWithPasteboard(Pasteboard* pasteboard) { @@ -359,10 +361,12 @@ bool Editor::shouldInsertFragment(PassRefPtr<DocumentFragment> fragment, PassRef { if (!client()) return false; - - Node* child = fragment->firstChild(); - if (child && fragment->lastChild() == child && child->isCharacterDataNode()) - return client()->shouldInsertText(static_cast<CharacterData*>(child)->data(), replacingDOMRange.get(), givenAction); + + if (fragment) { + Node* child = fragment->firstChild(); + if (child && fragment->lastChild() == child && child->isCharacterDataNode()) + return client()->shouldInsertText(static_cast<CharacterData*>(child)->data(), replacingDOMRange.get(), givenAction); + } return client()->shouldInsertNode(fragment.get(), replacingDOMRange.get(), givenAction); } @@ -551,7 +555,7 @@ WritingDirection Editor::textDirectionForSelection(bool& hasNestedOrMultipleEmbe } if (m_frame->selection()->isCaret()) { - if (CSSMutableStyleDeclaration* typingStyle = m_frame->typingStyle()) { + if (CSSMutableStyleDeclaration* typingStyle = m_frame->selection()->typingStyle()) { RefPtr<CSSValue> unicodeBidi = typingStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi); if (unicodeBidi) { ASSERT(unicodeBidi->isPrimitiveValue()); @@ -947,12 +951,6 @@ String Editor::selectionStartCSSPropertyValue(int propertyID) String value = selectionStyle->getPropertyValue(propertyID); - if (nodeToRemove) { - ExceptionCode ec = 0; - nodeToRemove->remove(ec); - ASSERT(!ec); - } - // If background color is transparent, traverse parent nodes until we hit a different value or document root // Also, if the selection is a range, ignore the background color at the start of selection, // and find the background color of the common ancestor. @@ -969,11 +967,17 @@ String Editor::selectionStartCSSPropertyValue(int propertyID) } if (propertyID == CSSPropertyFontSize) { - RefPtr<CSSValue> value = selectionStyle->getPropertyCSSValue(CSSPropertyFontSize); - ASSERT(value->isPrimitiveValue()); - int fontPixelSize = static_cast<CSSPrimitiveValue*>(value.get())->getIntValue(CSSPrimitiveValue::CSS_PX); + RefPtr<CSSValue> cssValue = selectionStyle->getPropertyCSSValue(CSSPropertyFontSize); + ASSERT(cssValue->isPrimitiveValue()); + int fontPixelSize = static_cast<CSSPrimitiveValue*>(cssValue.get())->getIntValue(CSSPrimitiveValue::CSS_PX); int size = CSSStyleSelector::legacyFontSize(m_frame->document(), fontPixelSize, selectionStyle->useFixedFontDefaultSize()); - return String::number(size); + value = String::number(size); + } + + if (nodeToRemove) { + ExceptionCode ec = 0; + nodeToRemove->remove(ec); + ASSERT(!ec); } return value; @@ -1011,7 +1015,7 @@ void Editor::appliedEditing(PassRefPtr<EditCommand> cmd) changeSelectionAfterCommand(newSelection, false, false); if (!cmd->preservesTypingStyle()) - m_frame->setTypingStyle(0); + m_frame->selection()->clearTypingStyle(); // Command will be equal to last edit command only in the case of typing if (m_lastEditCommand.get() == cmd) @@ -1116,7 +1120,7 @@ bool Editor::insertTextWithoutSendingTextEvent(const String& text, bool selectIn // Reveal the current selection if (Frame* editedFrame = document->frame()) if (Page* page = editedFrame->page()) - page->focusController()->focusedOrMainFrame()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded); + page->focusController()->focusedOrMainFrame()->selection()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded); } } @@ -1193,8 +1197,6 @@ void Editor::copy() didWriteSelectionToPasteboard(); } -#if !PLATFORM(MAC) - void Editor::paste() { ASSERT(m_frame->document()); @@ -1211,8 +1213,6 @@ void Editor::paste() loader->setAllowStaleResources(false); } -#endif - void Editor::pasteAsPlainText() { if (tryDHTMLPaste()) @@ -1451,9 +1451,7 @@ void Editor::toggleUnderline() void Editor::setBaseWritingDirection(WritingDirection direction) { Node* focusedNode = frame()->document()->focusedNode(); - if (focusedNode && (focusedNode->hasTagName(textareaTag) - || (focusedNode->hasTagName(inputTag) && (static_cast<HTMLInputElement*>(focusedNode)->inputType() == HTMLInputElement::TEXT - || static_cast<HTMLInputElement*>(focusedNode)->inputType() == HTMLInputElement::SEARCH)))) { + if (focusedNode && (focusedNode->hasTagName(textareaTag) || (focusedNode->hasTagName(inputTag) && static_cast<HTMLInputElement*>(focusedNode)->isTextField()))) { if (direction == NaturalWritingDirection) return; static_cast<HTMLElement*>(focusedNode)->setAttribute(dirAttr, direction == LeftToRightWritingDirection ? "ltr" : "rtl"); @@ -2132,7 +2130,7 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection) // FIXME 4859190: This gets confused with doubled punctuation at the end of a paragraph RefPtr<Range> badGrammarRange = TextIterator::subrange(grammarSearchRange.get(), grammarPhraseOffset + grammarDetail.location, grammarDetail.length); frame()->selection()->setSelection(VisibleSelection(badGrammarRange.get(), SEL_DEFAULT_AFFINITY)); - frame()->revealSelection(); + frame()->selection()->revealSelection(); client()->updateSpellingUIWithGrammarString(badGrammarPhrase, grammarDetail); frame()->document()->markers()->addMarker(badGrammarRange.get(), DocumentMarker::Grammar, grammarDetail.userDescription); @@ -2143,7 +2141,7 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection) RefPtr<Range> misspellingRange = TextIterator::subrange(spellingSearchRange.get(), misspellingOffset, misspelledWord.length()); frame()->selection()->setSelection(VisibleSelection(misspellingRange.get(), DOWNSTREAM)); - frame()->revealSelection(); + frame()->selection()->revealSelection(); client()->updateSpellingUIWithMisspelledWord(misspelledWord); frame()->document()->markers()->addMarker(misspellingRange.get(), DocumentMarker::Spelling); @@ -2435,7 +2433,7 @@ void Editor::markMisspellingsAfterTypingToPosition(const VisiblePosition &p) if (!autocorrectedString.isEmpty()) { VisibleSelection newSelection(misspellingRange.get(), DOWNSTREAM); if (newSelection != frame()->selection()->selection()) { - if (!frame()->shouldChangeSelection(newSelection)) + if (!frame()->selection()->shouldChangeSelection(newSelection)) return; frame()->selection()->setSelection(newSelection); } @@ -2709,7 +2707,7 @@ void Editor::markAllMisspellingsAndBadGrammarInRanges(TextCheckingOptions textCh } } if (doReplacement && !shouldShowCorrectionPanel && selectionToReplace != m_frame->selection()->selection()) { - if (m_frame->shouldChangeSelection(selectionToReplace)) { + if (m_frame->selection()->shouldChangeSelection(selectionToReplace)) { m_frame->selection()->setSelection(selectionToReplace); selectionChanged = true; } else { @@ -2854,6 +2852,15 @@ void Editor::handleCancelOperation() #endif } +bool Editor::isShowingCorrectionPanel() +{ +#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) + if (client()) + return client()->isShowingCorrectionPanel(); +#endif + return false; +} + PassRefPtr<Range> Editor::rangeForPoint(const IntPoint& windowPoint) { Document* document = m_frame->documentAtPoint(windowPoint); @@ -2875,7 +2882,7 @@ void Editor::revealSelectionAfterEditingOperation() if (m_ignoreCompositionSelectionChange) return; - m_frame->revealSelection(ScrollAlignment::alignToEdgeIfNeeded); + m_frame->selection()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded); } void Editor::setIgnoreCompositionSelectionChange(bool ignore) @@ -2952,7 +2959,7 @@ void Editor::transpose() // Select the two characters. if (newSelection != m_frame->selection()->selection()) { - if (!m_frame->shouldChangeSelection(newSelection)) + if (!m_frame->selection()->shouldChangeSelection(newSelection)) return; m_frame->selection()->setSelection(newSelection); } @@ -3125,7 +3132,7 @@ void Editor::changeSelectionAfterCommand(const VisibleSelection& newSelection, b // The old selection can be invalid here and calling shouldChangeSelection can produce some strange calls. // See <rdar://problem/5729315> Some shouldChangeSelectedDOMRange contain Ranges for selections that are no longer valid bool selectionDidNotChangeDOMPosition = newSelection == m_frame->selection()->selection(); - if (selectionDidNotChangeDOMPosition || m_frame->shouldChangeSelection(newSelection)) + if (selectionDidNotChangeDOMPosition || m_frame->selection()->shouldChangeSelection(newSelection)) m_frame->selection()->setSelection(newSelection, closeTyping, clearTypingStyle); // Some editing operations change the selection visually without affecting its position within the DOM. @@ -3196,18 +3203,18 @@ bool Editor::shouldChangeSelection(const VisibleSelection& oldSelection, const V return client()->shouldChangeSelectedRange(oldSelection.toNormalizedRange().get(), newSelection.toNormalizedRange().get(), affinity, stillSelecting); } -void Editor::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction editingAction) +void Editor::computeAndSetTypingStyle(CSSStyleDeclaration* style, EditAction editingAction) { if (!style || !style->length()) { - m_frame->clearTypingStyle(); + m_frame->selection()->clearTypingStyle(); return; } // Calculate the current typing style. RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable(); - if (m_frame->typingStyle()) { - m_frame->typingStyle()->merge(mutableStyle.get()); - mutableStyle = m_frame->typingStyle(); + if (m_frame->selection()->typingStyle()) { + m_frame->selection()->typingStyle()->merge(mutableStyle.get()); + mutableStyle = m_frame->selection()->typingStyle(); } RefPtr<CSSValue> unicodeBidi; @@ -3236,7 +3243,7 @@ void Editor::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction edi applyCommand(ApplyStyleCommand::create(m_frame->document(), blockStyle.get(), editingAction)); // Set the remaining style as the typing style. - m_frame->setTypingStyle(mutableStyle.get()); + m_frame->selection()->setTypingStyle(mutableStyle.release()); } PassRefPtr<CSSComputedStyleDeclaration> Editor::selectionComputedStyle(Node*& nodeToRemove) const @@ -3264,10 +3271,10 @@ PassRefPtr<CSSComputedStyleDeclaration> Editor::selectionComputedStyle(Node*& no RefPtr<Element> styleElement = element; ExceptionCode ec = 0; - if (m_frame->typingStyle()) { + if (m_frame->selection()->typingStyle()) { styleElement = m_frame->document()->createElement(spanTag, false); - styleElement->setAttribute(styleAttr, m_frame->typingStyle()->cssText().impl(), ec); + styleElement->setAttribute(styleAttr, m_frame->selection()->typingStyle()->cssText(), ec); ASSERT(!ec); styleElement->appendChild(m_frame->document()->createEditingTextNode(""), ec); @@ -3368,13 +3375,13 @@ RenderStyle* Editor::styleForSelectionStart(Node *&nodeToRemove) const if (!position.node()) return 0; - if (!m_frame->typingStyle()) + if (!m_frame->selection()->typingStyle()) return position.node()->renderer()->style(); RefPtr<Element> styleElement = m_frame->document()->createElement(spanTag, false); ExceptionCode ec = 0; - String styleText = m_frame->typingStyle()->cssText() + " display: inline"; + String styleText = m_frame->selection()->typingStyle()->cssText() + " display: inline"; styleElement->setAttribute(styleAttr, styleText.impl(), ec); ASSERT(!ec); @@ -3471,7 +3478,7 @@ bool Editor::findString(const String& target, bool forward, bool caseFlag, bool return false; m_frame->selection()->setSelection(VisibleSelection(resultRange.get(), DOWNSTREAM)); - m_frame->revealSelection(); + m_frame->selection()->revealSelection(); return true; } @@ -3591,4 +3598,24 @@ void Editor::respondToChangedSelection(const VisibleSelection& oldSelection, boo respondToChangedSelection(oldSelection); } +bool Editor::selectionStartHasSpellingMarkerFor(int from, int length) const +{ + Node* node = m_frame->selection()->start().node(); + if (!node || !node->renderer()) + return false; + ASSERT(node->renderer()->isText()); + + unsigned int startOffset = static_cast<unsigned int>(from); + unsigned int endOffset = static_cast<unsigned int>(from + length); + Vector<DocumentMarker> markers = m_frame->document()->markers()->markersForNode(node); + for (size_t i = 0; i < markers.size(); ++i) { + DocumentMarker marker = markers[i]; + if (marker.startOffset <= startOffset && endOffset <= marker.endOffset && marker.type == DocumentMarker::Spelling) + return true; + } + + return false; +} + + } // namespace WebCore |