⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 applystylecommand.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        Node *prevNode = text->previousSibling();        ASSERT(prevNode);        Node *startNode = start.node() == end.node() ? prevNode : start.node();        ASSERT(startNode);        updateStartEnd(Position(startNode, start.offset()), Position(prevNode, caretMaxOffset(prevNode)));        return true;    }    return false;}bool ApplyStyleCommand::splitTextElementAtStartIfNeeded(const Position &start, const Position &end){    if (start.node()->isTextNode() && start.offset() > caretMinOffset(start.node()) && start.offset() < caretMaxOffset(start.node())) {        int endOffsetAdjustment = start.node() == end.node() ? start.offset() : 0;        Text *text = static_cast<Text *>(start.node());        splitTextNodeContainingElement(text, start.offset());        updateStartEnd(Position(start.node()->parentNode(), start.node()->nodeIndex()), Position(end.node(), end.offset() - endOffsetAdjustment));        return true;    }    return false;}bool ApplyStyleCommand::splitTextElementAtEndIfNeeded(const Position &start, const Position &end){    if (end.node()->isTextNode() && end.offset() > caretMinOffset(end.node()) && end.offset() < caretMaxOffset(end.node())) {        Text *text = static_cast<Text *>(end.node());        splitTextNodeContainingElement(text, end.offset());        Node *prevNode = text->parent()->previousSibling()->lastChild();        ASSERT(prevNode);        Node *startNode = start.node() == end.node() ? prevNode : start.node();        ASSERT(startNode);        updateStartEnd(Position(startNode, start.offset()), Position(prevNode->parent(), prevNode->nodeIndex() + 1));        return true;    }    return false;}static bool areIdenticalElements(Node *first, Node *second){    // check that tag name and all attribute names and values are identical    if (!first->isElementNode())        return false;        if (!second->isElementNode())        return false;    Element *firstElement = static_cast<Element *>(first);    Element *secondElement = static_cast<Element *>(second);        if (!firstElement->tagQName().matches(secondElement->tagQName()))        return false;    NamedAttrMap *firstMap = firstElement->attributes();    NamedAttrMap *secondMap = secondElement->attributes();    unsigned firstLength = firstMap->length();    if (firstLength != secondMap->length())        return false;    for (unsigned i = 0; i < firstLength; i++) {        Attribute *attribute = firstMap->attributeItem(i);        Attribute *secondAttribute = secondMap->getAttributeItem(attribute->name());        if (!secondAttribute || attribute->value() != secondAttribute->value())            return false;    }        return true;}bool ApplyStyleCommand::mergeStartWithPreviousIfIdentical(const Position &start, const Position &end){    Node *startNode = start.node();    int startOffset = start.offset();    if (isAtomicNode(start.node())) {        if (start.offset() != 0)            return false;        // note: prior siblings could be unrendered elements. it's silly to miss the        // merge opportunity just for that.        if (start.node()->previousSibling())            return false;        startNode = start.node()->parent();        startOffset = 0;    }    if (!startNode->isElementNode())        return false;    if (startOffset != 0)        return false;    Node *previousSibling = startNode->previousSibling();    if (previousSibling && areIdenticalElements(startNode, previousSibling)) {        Element *previousElement = static_cast<Element *>(previousSibling);        Element *element = static_cast<Element *>(startNode);        Node *startChild = element->firstChild();        ASSERT(startChild);        mergeIdenticalElements(previousElement, element);        int startOffsetAdjustment = startChild->nodeIndex();        int endOffsetAdjustment = startNode == end.node() ? startOffsetAdjustment : 0;        updateStartEnd(Position(startNode, startOffsetAdjustment), Position(end.node(), end.offset() + endOffsetAdjustment));         return true;    }    return false;}bool ApplyStyleCommand::mergeEndWithNextIfIdentical(const Position &start, const Position &end){    Node *endNode = end.node();    int endOffset = end.offset();    if (isAtomicNode(endNode)) {        if (endOffset < caretMaxOffset(endNode))            return false;        unsigned parentLastOffset = end.node()->parent()->childNodes()->length() - 1;        if (end.node()->nextSibling())            return false;        endNode = end.node()->parent();        endOffset = parentLastOffset;    }    if (!endNode->isElementNode() || endNode->hasTagName(brTag))        return false;    Node *nextSibling = endNode->nextSibling();    if (nextSibling && areIdenticalElements(endNode, nextSibling)) {        Element *nextElement = static_cast<Element *>(nextSibling);        Element *element = static_cast<Element *>(endNode);        Node *nextChild = nextElement->firstChild();        mergeIdenticalElements(element, nextElement);        Node *startNode = start.node() == endNode ? nextElement : start.node();        ASSERT(startNode);        int endOffset = nextChild ? nextChild->nodeIndex() : nextElement->childNodes()->length();        updateStartEnd(Position(startNode, start.offset()), Position(nextElement, endOffset));        return true;    }    return false;}void ApplyStyleCommand::surroundNodeRangeWithElement(Node* startNode, Node* endNode, PassRefPtr<Element> elementToInsert){    ASSERT(startNode);    ASSERT(endNode);    ASSERT(elementToInsert);    RefPtr<Element> element = elementToInsert;    insertNodeBefore(element, startNode);        Node* node = startNode;    while (1) {        Node* next = node->traverseNextNode();        if (node->childNodeCount() == 0 && node->renderer() && node->renderer()->isInline()) {            removeNode(node);            appendNode(node, element);        }        if (node == endNode)            break;        node = next;    }    // FIXME: We should probably call updateStartEnd if the start or end was in the node    // range so that the endingSelection() is canonicalized.  See the comments at the end of    // VisibleSelection::validate().}void ApplyStyleCommand::addBlockStyle(const StyleChange& styleChange, HTMLElement* block){    // Do not check for legacy styles here. Those styles, like <B> and <I>, only apply for    // inline content.    if (!block)        return;            String cssText = styleChange.cssStyle();    CSSMutableStyleDeclaration* decl = block->inlineStyleDecl();    if (decl)        cssText += decl->cssText();    setNodeAttribute(block, styleAttr, cssText);}static bool fontColorChangesComputedStyle(RenderStyle* computedStyle, StyleChange styleChange){    if (styleChange.applyFontColor()) {        if (Color(styleChange.fontColor()) != computedStyle->color())            return true;    }    return false;}static bool fontSizeChangesComputedStyle(RenderStyle* computedStyle, StyleChange styleChange){    if (styleChange.applyFontSize()) {        if (styleChange.fontSize().toInt() != computedStyle->fontSize())            return true;    }    return false;}static bool fontFaceChangesComputedStyle(RenderStyle* computedStyle, StyleChange styleChange){    if (styleChange.applyFontFace()) {        if (computedStyle->fontDescription().family().family().string() != styleChange.fontFace())            return true;    }    return false;}void ApplyStyleCommand::addInlineStyleIfNeeded(CSSMutableStyleDeclaration *style, Node *startNode, Node *endNode){    if (m_removeOnly)        return;    StyleChange styleChange(style, Position(startNode, 0));    //    // Font tags need to go outside of CSS so that CSS font sizes override leagcy font sizes.    //    if (styleChange.applyFontColor() || styleChange.applyFontFace() || styleChange.applyFontSize()) {        RefPtr<Element> fontElement = createFontElement(document());        RenderStyle* computedStyle = startNode->computedStyle();        // We only want to insert a font element if it will end up changing the style of the        // text somehow. Otherwise it will be a garbage node that will create problems for us        // most notably when we apply a blockquote style for a message reply.        if (fontColorChangesComputedStyle(computedStyle, styleChange)                || fontFaceChangesComputedStyle(computedStyle, styleChange)                || fontSizeChangesComputedStyle(computedStyle, styleChange)) {            if (styleChange.applyFontColor())                fontElement->setAttribute(colorAttr, styleChange.fontColor());            if (styleChange.applyFontFace())                fontElement->setAttribute(faceAttr, styleChange.fontFace());            if (styleChange.applyFontSize())                fontElement->setAttribute(sizeAttr, styleChange.fontSize());            surroundNodeRangeWithElement(startNode, endNode, fontElement.get());        }    }    if (styleChange.cssStyle().length() > 0) {        RefPtr<Element> styleElement = createStyleSpanElement(document());        styleElement->setAttribute(styleAttr, styleChange.cssStyle());        surroundNodeRangeWithElement(startNode, endNode, styleElement.release());    }    if (styleChange.applyBold())        surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(document(), bTag));    if (styleChange.applyItalic())        surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(document(), iTag));    if (styleChange.applySubscript())        surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(document(), subTag));    else if (styleChange.applySuperscript())        surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(document(), supTag));    if (m_styledInlineElement)        surroundNodeRangeWithElement(startNode, endNode, m_styledInlineElement->cloneElement());}float ApplyStyleCommand::computedFontSize(const Node *node){    if (!node)        return 0;        Position pos(const_cast<Node *>(node), 0);    RefPtr<CSSComputedStyleDeclaration> computedStyle = pos.computedStyle();    if (!computedStyle)        return 0;    RefPtr<CSSPrimitiveValue> value = static_pointer_cast<CSSPrimitiveValue>(computedStyle->getPropertyCSSValue(CSSPropertyFontSize));    if (!value)        return 0;    return value->getFloatValue(CSSPrimitiveValue::CSS_PX);}void ApplyStyleCommand::joinChildTextNodes(Node *node, const Position &start, const Position &end){    if (!node)        return;    Position newStart = start;    Position newEnd = end;        Node *child = node->firstChild();    while (child) {        Node *next = child->nextSibling();        if (child->isTextNode() && next && next->isTextNode()) {            Text *childText = static_cast<Text *>(child);            Text *nextText = static_cast<Text *>(next);            if (next == start.node())                newStart = Position(childText, childText->length() + start.offset());            if (next == end.node())                newEnd = Position(childText, childText->length() + end.offset());            String textToMove = nextText->data();            insertTextIntoNode(childText, childText->length(), textToMove);            removeNode(next);            // don't move child node pointer. it may want to merge with more text nodes.        }        else {            child = child->nextSibling();        }    }    updateStartEnd(newStart, newEnd);}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -