void EditingStyle::init(Node* node, PropertiesToInclude propertiesToInclude) { if (isTabSpanTextNode(node)) node = tabSpanNode(node)->parentNode(); else if (isTabSpanNode(node)) node = node->parentNode(); RefPtr<CSSComputedStyleDeclaration> computedStyleAtPosition = computedStyle(node); m_mutableStyle = propertiesToInclude == AllProperties && computedStyleAtPosition ? computedStyleAtPosition->copy() : editingStyleFromComputedStyle(computedStyleAtPosition); if (node && node->computedStyle()) { RenderStyle* renderStyle = node->computedStyle(); removeTextFillAndStrokeColorsIfNeeded(renderStyle); replaceFontSizeByKeywordIfPossible(renderStyle, computedStyleAtPosition.get()); //SISO_HTMLComposer start if(node->document() && node->document()->frame() && (node->document()->frame()->textZoomFactor() > 1.0 || node->document()->frame()->pageZoomFactor() > 1.0)) { replaceComputedFontSizeBySpecifiedSize(computedStyleAtPosition.get()); } //SISO_HTMLComposer end } m_shouldUseFixedDefaultFontSize = computedStyleAtPosition->useFixedFontDefaultSize(); extractFontSizeDelta(); }
Position InsertTextCommand::prepareForTextInsertion(const Position& pos) { // Prepare for text input by looking at the specified position. // It may be necessary to insert a text node to receive characters. // FIXME: What is the rootEditable() check about? Seems like it // assumes that the content before (or after) pos.node() is editable // (i.e. pos is at an editable/non-editable boundary). That seems // like a bad assumption. if (!pos.node()->isTextNode()) { RefPtr<Node> textNode = document()->createEditingTextNode(""); // Now insert the node in the right place if (pos.node()->rootEditableElement() != NULL) { insertNodeAt(textNode.get(), pos.node(), pos.offset()); } else if (pos.node()->caretMinOffset() == pos.offset()) { insertNodeBefore(textNode.get(), pos.node()); } else if (pos.node()->caretMaxOffset() == pos.offset()) { insertNodeAfter(textNode.get(), pos.node()); } else ASSERT_NOT_REACHED(); return Position(textNode.get(), 0); } if (isTabSpanTextNode(pos.node())) { RefPtr<Node> textNode = document()->createEditingTextNode(""); insertNodeAtTabSpanPosition(textNode.get(), pos); return Position(textNode.get(), 0); } return pos; }
// This avoids the expense of a full fledged delete operation, and avoids a layout that typically results // from text removal. bool InsertTextCommand::performTrivialReplace(const String& text, bool selectInsertedText) { if (!endingSelection().isRange()) return false; if (text.contains('\t') || text.contains(' ') || text.contains('\n')) return false; Position start = endingSelection().start(); Position end = endingSelection().end(); if (start.node() != end.node() || !start.node()->isTextNode() || isTabSpanTextNode(start.node())) return false; replaceTextInNode(static_cast<Text*>(start.node()), start.offset(), end.offset() - start.offset(), text); Position endPosition(start.node(), start.offset() + text.length()); // We could have inserted a part of composed character sequence, // so we are basically treating ending selection as a range to avoid validation. // <http://bugs.webkit.org/show_bug.cgi?id=15781> Selection forcedEndingSelection; forcedEndingSelection.setWithoutValidation(start, endPosition); setEndingSelection(forcedEndingSelection); if (!selectInsertedText) setEndingSelection(Selection(endingSelection().visibleEnd())); return true; }
Position InsertTextCommand::positionInsideTextNode(const Position& p) { Position pos = p; if (isTabSpanTextNode(pos.anchorNode())) { RefPtrWillBeRawPtr<Node> textNode = document().createEditingTextNode(""); insertNodeAtTabSpanPosition(textNode.get(), pos); return firstPositionInNode(textNode.get()); } // Prepare for text input by looking at the specified position. // It may be necessary to insert a text node to receive characters. if (!pos.containerNode()->isTextNode()) { RefPtrWillBeRawPtr<Node> textNode = document().createEditingTextNode(""); insertNodeAt(textNode.get(), pos); return firstPositionInNode(textNode.get()); } return pos; }
Position InsertTextCommand::prepareForTextInsertion(const Position& p) { Position pos = p; // Prepare for text input by looking at the specified position. // It may be necessary to insert a text node to receive characters. if (!pos.node()->isTextNode()) { RefPtr<Node> textNode = document()->createEditingTextNode(""); insertNodeAt(textNode.get(), pos); return Position(textNode.get(), 0); } if (isTabSpanTextNode(pos.node())) { RefPtr<Node> textNode = document()->createEditingTextNode(""); insertNodeAtTabSpanPosition(textNode.get(), pos); return Position(textNode.get(), 0); } return pos; }
void EditingStyle::init(Node* node, PropertiesToInclude propertiesToInclude) { if (isTabSpanTextNode(node)) node = tabSpanNode(node)->parentNode(); else if (isTabSpanNode(node)) node = node->parentNode(); RefPtr<CSSComputedStyleDeclaration> computedStyleAtPosition = computedStyle(node); m_mutableStyle = propertiesToInclude == AllProperties && computedStyleAtPosition ? computedStyleAtPosition->copy() : editingStyleFromComputedStyle(computedStyleAtPosition); if (node && node->computedStyle()) { RenderStyle* renderStyle = node->computedStyle(); removeTextFillAndStrokeColorsIfNeeded(renderStyle); replaceFontSizeByKeywordIfPossible(renderStyle, computedStyleAtPosition.get()); } m_shouldUseFixedDefaultFontSize = computedStyleAtPosition->useFixedFontDefaultSize(); extractFontSizeDelta(); }
Position InsertTextCommand::insertTab(const Position& pos) { Position insertPos = VisiblePosition(pos, DOWNSTREAM).deepEquivalent(); if (insertPos.isNull()) return pos; Node* node = insertPos.containerNode(); unsigned offset = node->isTextNode() ? insertPos.offsetInContainerNode() : 0; // keep tabs coalesced in tab span if (isTabSpanTextNode(node)) { RefPtrWillBeRawPtr<Text> textNode = toText(node); insertTextIntoNode(textNode, offset, "\t"); return Position(textNode.release(), offset + 1); } // create new tab span RefPtrWillBeRawPtr<Element> spanNode = createTabSpanElement(document()); // place it if (!node->isTextNode()) { insertNodeAt(spanNode.get(), insertPos); } else { RefPtrWillBeRawPtr<Text> textNode = toText(node); if (offset >= textNode->length()) insertNodeAfter(spanNode, textNode.release()); else { // split node to make room for the span // NOTE: splitTextNode uses textNode for the // second node in the split, so we need to // insert the span before it. if (offset > 0) splitTextNode(textNode, offset); insertNodeBefore(spanNode, textNode.release()); } } // return the position following the new tab return lastPositionInNode(spanNode.get()); }
Position InsertTextCommand::insertTab(const Position& pos) { Position insertPos = VisiblePosition(pos, DOWNSTREAM).deepEquivalent(); Node *node = insertPos.node(); unsigned int offset = insertPos.offset(); // keep tabs coalesced in tab span if (isTabSpanTextNode(node)) { insertTextIntoNode(static_cast<Text *>(node), offset, "\t"); return Position(node, offset + 1); } // create new tab span RefPtr<Element> spanNode = createTabSpanElement(document()); // place it if (!node->isTextNode()) { insertNodeAt(spanNode.get(), node, offset); } else { Text *textNode = static_cast<Text *>(node); if (offset >= textNode->length()) { insertNodeAfter(spanNode.get(), textNode); } else { // split node to make room for the span // NOTE: splitTextNode uses textNode for the // second node in the split, so we need to // insert the span before it. if (offset > 0) splitTextNode(textNode, offset); insertNodeBefore(spanNode.get(), textNode); } } // return the position following the new tab return Position(spanNode->lastChild(), spanNode->lastChild()->caretMaxOffset()); }