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();
}
示例#2
0
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;
}
示例#3
0
// 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;
}
示例#5
0
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());
}