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

📄 applystylecommand.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            CSSMutableStyleDeclaration::const_iterator end = style->end();    for (CSSMutableStyleDeclaration::const_iterator it = style->begin(); it != end; ++it) {        switch ((*it).id()) {            case CSSPropertyColor:                removeNodeAttribute(elem, colorAttr);                break;            case CSSPropertyFontFamily:                removeNodeAttribute(elem, faceAttr);                break;            case CSSPropertyFontSize:                removeNodeAttribute(elem, sizeAttr);                break;        }    }    if (isEmptyFontTag(elem))        removeNodePreservingChildren(elem);}void ApplyStyleCommand::removeHTMLBidiEmbeddingStyle(CSSMutableStyleDeclaration *style, HTMLElement *elem){    ASSERT(style);    ASSERT(elem);    if (!elem->hasAttribute(dirAttr))        return;    if (!style->getPropertyCSSValue(CSSPropertyUnicodeBidi) && !style->getPropertyCSSValue(CSSPropertyDirection))        return;    removeNodeAttribute(elem, dirAttr);    // FIXME: should this be isSpanWithoutAttributesOrUnstyleStyleSpan?  Need a test.    if (isUnstyledStyleSpan(elem))        removeNodePreservingChildren(elem);}void ApplyStyleCommand::removeCSSStyle(CSSMutableStyleDeclaration* style, HTMLElement* elem){    ASSERT(style);    ASSERT(elem);    CSSMutableStyleDeclaration* decl = elem->inlineStyleDecl();    if (!decl)        return;    CSSMutableStyleDeclaration::const_iterator end = style->end();    for (CSSMutableStyleDeclaration::const_iterator it = style->begin(); it != end; ++it) {        CSSPropertyID propertyID = static_cast<CSSPropertyID>((*it).id());        RefPtr<CSSValue> value = decl->getPropertyCSSValue(propertyID);        if (value && (propertyID != CSSPropertyWhiteSpace || !isTabSpanNode(elem))) {            removeCSSProperty(decl, propertyID);            if (propertyID == CSSPropertyUnicodeBidi && !decl->getPropertyValue(CSSPropertyDirection).isEmpty())                removeCSSProperty(decl, CSSPropertyDirection);        }    }    // No need to serialize <foo style=""> if we just removed the last css property    if (decl->length() == 0)        removeNodeAttribute(elem, styleAttr);    if (isSpanWithoutAttributesOrUnstyleStyleSpan(elem))        removeNodePreservingChildren(elem);}static bool hasTextDecorationProperty(Node *node){    if (!node->isElementNode())        return false;    RefPtr<CSSValue> value = computedStyle(node)->getPropertyCSSValue(CSSPropertyTextDecoration, DoNotUpdateLayout);    return value && !equalIgnoringCase(value->cssText(), "none");}static Node* highestAncestorWithTextDecoration(Node *node){    Node *result = NULL;    for (Node *n = node; n; n = n->parentNode()) {        if (hasTextDecorationProperty(n))            result = n;    }    return result;}PassRefPtr<CSSMutableStyleDeclaration> ApplyStyleCommand::extractTextDecorationStyle(Node* node){    ASSERT(node);    ASSERT(node->isElementNode());        // non-html elements not handled yet    if (!node->isHTMLElement())        return 0;    HTMLElement *element = static_cast<HTMLElement *>(node);    RefPtr<CSSMutableStyleDeclaration> style = element->inlineStyleDecl();    if (!style)        return 0;    int properties[1] = { CSSPropertyTextDecoration };    RefPtr<CSSMutableStyleDeclaration> textDecorationStyle = style->copyPropertiesInSet(properties, 1);    RefPtr<CSSValue> property = style->getPropertyCSSValue(CSSPropertyTextDecoration);    if (property && !equalIgnoringCase(property->cssText(), "none"))        removeCSSProperty(style.get(), CSSPropertyTextDecoration);    return textDecorationStyle.release();}PassRefPtr<CSSMutableStyleDeclaration> ApplyStyleCommand::extractAndNegateTextDecorationStyle(Node* node){    ASSERT(node);    ASSERT(node->isElementNode());        // non-html elements not handled yet    if (!node->isHTMLElement())        return 0;    RefPtr<CSSComputedStyleDeclaration> nodeStyle = computedStyle(node);    ASSERT(nodeStyle);    int properties[1] = { CSSPropertyTextDecoration };    RefPtr<CSSMutableStyleDeclaration> textDecorationStyle = nodeStyle->copyPropertiesInSet(properties, 1);    RefPtr<CSSValue> property = nodeStyle->getPropertyCSSValue(CSSPropertyTextDecoration);    if (property && !equalIgnoringCase(property->cssText(), "none")) {        RefPtr<CSSMutableStyleDeclaration> newStyle = textDecorationStyle->copy();        newStyle->setProperty(CSSPropertyTextDecoration, "none");        applyTextDecorationStyle(node, newStyle.get());    }    return textDecorationStyle.release();}void ApplyStyleCommand::applyTextDecorationStyle(Node *node, CSSMutableStyleDeclaration *style){    ASSERT(node);    if (!style || !style->cssText().length())        return;    if (node->isTextNode()) {        RefPtr<HTMLElement> styleSpan = createStyleSpanElement(document());        surroundNodeRangeWithElement(node, node, styleSpan.get());        node = styleSpan.get();    }    if (!node->isElementNode())        return;    HTMLElement *element = static_cast<HTMLElement *>(node);            StyleChange styleChange(style, Position(element, 0));    if (styleChange.cssStyle().length() > 0) {        String cssText = styleChange.cssStyle();        CSSMutableStyleDeclaration *decl = element->inlineStyleDecl();        if (decl)            cssText += decl->cssText();        setNodeAttribute(element, styleAttr, cssText);    }}void ApplyStyleCommand::pushDownTextDecorationStyleAroundNode(Node* node, bool force){    Node *highestAncestor = highestAncestorWithTextDecoration(node);        if (highestAncestor) {        Node *nextCurrent;        Node *nextChild;        for (Node *current = highestAncestor; current != node; current = nextCurrent) {            ASSERT(current);                        nextCurrent = NULL;                        RefPtr<CSSMutableStyleDeclaration> decoration = force ? extractAndNegateTextDecorationStyle(current) : extractTextDecorationStyle(current);            for (Node *child = current->firstChild(); child; child = nextChild) {                nextChild = child->nextSibling();                if (node == child) {                    nextCurrent = child;                } else if (node->isDescendantOf(child)) {                    applyTextDecorationStyle(child, decoration.get());                    nextCurrent = child;                } else {                    applyTextDecorationStyle(child, decoration.get());                }            }        }    }}void ApplyStyleCommand::pushDownTextDecorationStyleAtBoundaries(const Position &start, const Position &end){    // We need to work in two passes. First we push down any inline    // styles that set text decoration. Then we look for any remaining    // styles (caused by stylesheets) and explicitly negate text    // decoration while pushing down.    pushDownTextDecorationStyleAroundNode(start.node(), false);    updateLayout();    pushDownTextDecorationStyleAroundNode(start.node(), true);    pushDownTextDecorationStyleAroundNode(end.node(), false);    updateLayout();    pushDownTextDecorationStyleAroundNode(end.node(), true);}static int maxRangeOffset(Node *n){    if (n->offsetInCharacters())        return n->maxCharacterOffset();    if (n->isElementNode())        return n->childNodeCount();    return 1;}void ApplyStyleCommand::removeInlineStyle(PassRefPtr<CSSMutableStyleDeclaration> style, const Position &start, const Position &end){    ASSERT(start.isNotNull());    ASSERT(end.isNotNull());    ASSERT(start.node()->inDocument());    ASSERT(end.node()->inDocument());    ASSERT(Range::compareBoundaryPoints(start, end) <= 0);        RefPtr<CSSValue> textDecorationSpecialProperty = style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);    if (textDecorationSpecialProperty) {        pushDownTextDecorationStyleAtBoundaries(start.downstream(), end.upstream());        style = style->copy();        style->setProperty(CSSPropertyTextDecoration, textDecorationSpecialProperty->cssText(), style->getPropertyPriority(CSSPropertyWebkitTextDecorationsInEffect));    }    // The s and e variables store the positions used to set the ending selection after style removal    // takes place. This will help callers to recognize when either the start node or the end node    // are removed from the document during the work of this function.    Position s = start;    Position e = end;    Node *node = start.node();    while (node) {        Node *next = node->traverseNextNode();        if (node->isHTMLElement() && nodeFullySelected(node, start, end)) {            HTMLElement *elem = static_cast<HTMLElement *>(node);            Node *prev = elem->traversePreviousNodePostOrder();            Node *next = elem->traverseNextNode();            if (m_styledInlineElement && elem->hasTagName(m_styledInlineElement->tagQName()))                removeNodePreservingChildren(elem);            if (isHTMLStyleNode(style.get(), elem))                removeHTMLStyleNode(elem);            else {                removeHTMLFontStyle(style.get(), elem);                removeHTMLBidiEmbeddingStyle(style.get(), elem);                removeCSSStyle(style.get(), elem);            }            if (!elem->inDocument()) {                if (s.node() == elem) {                    // Since elem must have been fully selected, and it is at the start                    // of the selection, it is clear we can set the new s offset to 0.                    ASSERT(s.offset() <= caretMinOffset(s.node()));                    s = Position(next, 0);                }                if (e.node() == elem) {                    // Since elem must have been fully selected, and it is at the end                    // of the selection, it is clear we can set the new e offset to                    // the max range offset of prev.                    ASSERT(e.offset() >= maxRangeOffset(e.node()));                    e = Position(prev, maxRangeOffset(prev));                }            }        }        if (node == end.node())            break;        node = next;    }        ASSERT(s.node()->inDocument());    ASSERT(e.node()->inDocument());    updateStartEnd(s, e);}bool ApplyStyleCommand::nodeFullySelected(Node *node, const Position &start, const Position &end) const{    ASSERT(node);    ASSERT(node->isElementNode());    Position pos = Position(node, node->childNodeCount()).upstream();    return Range::compareBoundaryPoints(node, 0, start.node(), start.offset()) >= 0 &&        Range::compareBoundaryPoints(pos, end) <= 0;}bool ApplyStyleCommand::nodeFullyUnselected(Node *node, const Position &start, const Position &end) const{    ASSERT(node);    ASSERT(node->isElementNode());    Position pos = Position(node, node->childNodeCount()).upstream();    bool isFullyBeforeStart = Range::compareBoundaryPoints(pos, start) < 0;    bool isFullyAfterEnd = Range::compareBoundaryPoints(node, 0, end.node(), end.offset()) > 0;    return isFullyBeforeStart || isFullyAfterEnd;}bool ApplyStyleCommand::splitTextAtStartIfNeeded(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());        splitTextNode(text, start.offset());        updateStartEnd(Position(start.node(), 0), Position(end.node(), end.offset() - endOffsetAdjustment));        return true;    }    return false;}bool ApplyStyleCommand::splitTextAtEndIfNeeded(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());        splitTextNode(text, end.offset());        

⌨️ 快捷键说明

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