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

📄 element.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    if (FrameView* view = document()->view()) {        IntRect visibleContentRect = view->visibleContentRect();        for (size_t i = 0; i < quads.size(); ++i)            quads[i].move(-visibleContentRect.x(), -visibleContentRect.y());    }    return ClientRectList::create(quads);}PassRefPtr<ClientRect> Element::getBoundingClientRect() const{    document()->updateLayoutIgnorePendingStylesheets();    RenderBoxModelObject* renderBoxModelObject = this->renderBoxModelObject();    if (!renderBoxModelObject)        return ClientRect::create();    Vector<FloatQuad> quads;    renderBoxModelObject->absoluteQuads(quads);    if (quads.isEmpty())        return ClientRect::create();    IntRect result = quads[0].enclosingBoundingBox();    for (size_t i = 1; i < quads.size(); ++i)        result.unite(quads[i].enclosingBoundingBox());    if (FrameView* view = document()->view()) {        IntRect visibleContentRect = view->visibleContentRect();        result.move(-visibleContentRect.x(), -visibleContentRect.y());    }    return ClientRect::create(result);}static inline bool shouldIgnoreAttributeCase(const Element* e){    return e && e->document()->isHTMLDocument() && e->isHTMLElement();}const AtomicString& Element::getAttribute(const String& name) const{    String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;    if (localName == styleAttr.localName() && !m_isStyleAttributeValid)        updateStyleAttribute();#if ENABLE(SVG)    if (!m_areSVGAttributesValid)        updateAnimatedSVGAttribute(name);#endif    if (namedAttrMap)        if (Attribute* a = namedAttrMap->getAttributeItem(name, shouldIgnoreAttributeCase(this)))            return a->value();        return nullAtom;}const AtomicString& Element::getAttributeNS(const String& namespaceURI, const String& localName) const{    return getAttribute(QualifiedName(nullAtom, localName, namespaceURI));}void Element::setAttribute(const AtomicString& name, const AtomicString& value, ExceptionCode& ec){    if (!Document::isValidName(name)) {        ec = INVALID_CHARACTER_ERR;        return;    }    const AtomicString& localName = (shouldIgnoreAttributeCase(this) && !name.string().impl()->isLower()) ? AtomicString(name.string().lower()) : name;    // allocate attributemap if necessary    Attribute* old = attributes(false)->getAttributeItem(localName, false);    document()->incDOMTreeVersion();    if (localName == idAttr.localName())        updateId(old ? old->value() : nullAtom, value);        if (old && value.isNull())        namedAttrMap->removeAttribute(old->name());    else if (!old && !value.isNull())        namedAttrMap->addAttribute(createAttribute(QualifiedName(nullAtom, localName, nullAtom), value));    else if (old && !value.isNull()) {        old->setValue(value);        attributeChanged(old);    }}void Element::setAttribute(const QualifiedName& name, const AtomicString& value, ExceptionCode&){    document()->incDOMTreeVersion();    // allocate attributemap if necessary    Attribute* old = attributes(false)->getAttributeItem(name);    if (name == idAttr)        updateId(old ? old->value() : nullAtom, value);        if (old && value.isNull())        namedAttrMap->removeAttribute(name);    else if (!old && !value.isNull())        namedAttrMap->addAttribute(createAttribute(name, value));    else if (old) {        old->setValue(value);        attributeChanged(old);    }}PassRefPtr<Attribute> Element::createAttribute(const QualifiedName& name, const AtomicString& value){    return Attribute::create(name, value);}void Element::attributeChanged(Attribute* attr, bool){    if (!document()->axObjectCache()->accessibilityEnabled())        return;    const QualifiedName& attrName = attr->name();    if (attrName == aria_activedescendantAttr) {        // any change to aria-activedescendant attribute triggers accessibility focus change, but document focus remains intact        document()->axObjectCache()->handleActiveDescendantChanged(renderer());    } else if (attrName == roleAttr) {        // the role attribute can change at any time, and the AccessibilityObject must pick up these changes        document()->axObjectCache()->handleAriaRoleChanged(renderer());    }}void Element::setAttributeMap(PassRefPtr<NamedAttrMap> list){    document()->incDOMTreeVersion();    // If setting the whole map changes the id attribute, we need to call updateId.    Attribute* oldId = namedAttrMap ? namedAttrMap->getAttributeItem(idAttr) : 0;    Attribute* newId = list ? list->getAttributeItem(idAttr) : 0;    if (oldId || newId)        updateId(oldId ? oldId->value() : nullAtom, newId ? newId->value() : nullAtom);    if (namedAttrMap)        namedAttrMap->m_element = 0;    namedAttrMap = list;    if (namedAttrMap) {        namedAttrMap->m_element = this;        unsigned len = namedAttrMap->length();        for (unsigned i = 0; i < len; i++)            attributeChanged(namedAttrMap->m_attributes[i].get());        // FIXME: What about attributes that were in the old map that are not in the new map?    }}bool Element::hasAttributes() const{    if (!m_isStyleAttributeValid)        updateStyleAttribute();#if ENABLE(SVG)    if (!m_areSVGAttributesValid)        updateAnimatedSVGAttribute(String());#endif    return namedAttrMap && namedAttrMap->length() > 0;}String Element::nodeName() const{    return m_tagName.toString();}String Element::nodeNamePreservingCase() const{    return m_tagName.toString();}void Element::setPrefix(const AtomicString &_prefix, ExceptionCode& ec){    ec = 0;    checkSetPrefix(_prefix, ec);    if (ec)        return;    m_tagName.setPrefix(_prefix);}KURL Element::baseURI() const{    KURL base(getAttribute(baseAttr));    if (!base.protocol().isEmpty())        return base;    Node* parent = parentNode();    if (!parent)        return base;    const KURL& parentBase = parent->baseURI();    if (parentBase.isNull())        return base;    return KURL(parentBase, base.string());}void Element::createAttributeMap() const{    namedAttrMap = NamedAttrMap::create(const_cast<Element*>(this));}bool Element::isURLAttribute(Attribute*) const{    return false;}const QualifiedName& Element::imageSourceAttributeName() const{    return srcAttr;}RenderObject* Element::createRenderer(RenderArena* arena, RenderStyle* style){    if (document()->documentElement() == this && style->display() == NONE) {        // Ignore display: none on root elements.  Force a display of block in that case.        RenderBlock* result = new (arena) RenderBlock(this);        if (result)            result->setAnimatableStyle(style);        return result;    }    return RenderObject::createObject(this, style);}void Element::insertedIntoDocument(){    // need to do superclass processing first so inDocument() is true    // by the time we reach updateId    ContainerNode::insertedIntoDocument();    if (hasID()) {        if (NamedAttrMap* attrs = namedAttrMap.get()) {            Attribute* idItem = attrs->getAttributeItem(idAttr);            if (idItem && !idItem->isNull())                updateId(nullAtom, idItem->value());        }    }}void Element::removedFromDocument(){    if (hasID()) {        if (NamedAttrMap* attrs = namedAttrMap.get()) {            Attribute* idItem = attrs->getAttributeItem(idAttr);            if (idItem && !idItem->isNull())                updateId(idItem->value(), nullAtom);        }    }    ContainerNode::removedFromDocument();}void Element::attach(){    createRendererIfNeeded();    ContainerNode::attach();    if (hasRareData()) {           ElementRareData* data = rareData();        if (data->needsFocusAppearanceUpdateSoonAfterAttach()) {            if (isFocusable() && document()->focusedNode() == this)                document()->updateFocusAppearanceSoon();            data->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);        }    }}void Element::detach(){    cancelFocusAppearanceUpdate();    if (hasRareData())        rareData()->resetComputedStyle();    ContainerNode::detach();}void Element::recalcStyle(StyleChange change){    RenderStyle* currentStyle = renderStyle();    bool hasParentStyle = parentNode() ? parentNode()->renderStyle() : false;    bool hasPositionalRules = changed() && currentStyle && currentStyle->childrenAffectedByPositionalRules();    bool hasDirectAdjacentRules = currentStyle && currentStyle->childrenAffectedByDirectAdjacentRules();#if ENABLE(SVG)    if (!hasParentStyle && isShadowNode() && isSVGElement())        hasParentStyle = true;#endif    if ((change > NoChange || changed())) {        if (hasRareData())            rareData()->resetComputedStyle();    }    if (hasParentStyle && (change >= Inherit || changed())) {        RefPtr<RenderStyle> newStyle = document()->styleSelector()->styleForElement(this);        StyleChange ch = diff(currentStyle, newStyle.get());        if (ch == Detach || !currentStyle) {            if (attached())                detach();            attach(); // FIXME: The style gets computed twice by calling attach. We could do better if we passed the style along.            // attach recalulates the style for all children. No need to do it twice.            setChanged(NoStyleChange);            setHasChangedChild(false);            return;        }        if (currentStyle) {            // Preserve "affected by" bits that were propagated to us from descendants in the case where we didn't do a full            // style change (e.g., only inline style changed).            if (currentStyle->affectedByHoverRules())                newStyle->setAffectedByHoverRules(true);            if (currentStyle->affectedByActiveRules())                newStyle->setAffectedByActiveRules(true);            if (currentStyle->affectedByDragRules())                newStyle->setAffectedByDragRules(true);            if (currentStyle->childrenAffectedByForwardPositionalRules())                newStyle->setChildrenAffectedByForwardPositionalRules();            if (currentStyle->childrenAffectedByBackwardPositionalRules())                newStyle->setChildrenAffectedByBackwardPositionalRules();            if (currentStyle->childrenAffectedByFirstChildRules())                newStyle->setChildrenAffectedByFirstChildRules();            if (currentStyle->childrenAffectedByLastChildRules())                newStyle->setChildrenAffectedByLastChildRules();            if (currentStyle->childrenAffectedByDirectAdjacentRules())                newStyle->setChildrenAffectedByDirectAdjacentRules();        }        if (ch != NoChange) {            setRenderStyle(newStyle);        } else if (changed() && (styleChangeType() != AnimationStyleChange) && (document()->usesSiblingRules() || document()->usesDescendantRules())) {            // Although no change occurred, we use the new style so that the cousin style sharing code won't get            // fooled into believing this style is the same.  This is only necessary if the document actually uses            // sibling/descendant rules, since otherwise it isn't possible for ancestor styles to affect sharing of            // descendants.            if (renderer())                renderer()->setStyleInternal(newStyle.get());            else                setRenderStyle(newStyle);        } else if (styleChangeType() == AnimationStyleChange)             setRenderStyle(newStyle);        if (change != Force) {            if ((document()->usesDescendantRules() || hasPositionalRules) && styleChangeType() >= FullStyleChange)                change = Force;            else                change = ch;        }    }    // FIXME: This check is good enough for :hover + foo, but it is not good enough for :hover + foo + bar.    // For now we will just worry about the common case, since it's a lot trickier to get the second case right    // without doing way too much re-resolution.    bool forceCheckOfNextElementSibling = false;    for (Node *n = firstChild(); n; n = n->nextSibling()) {        bool childRulesChanged = n->changed() && n->styleChangeType() == FullStyleChange;        if (forceCheckOfNextElementSibling && n->isElementNode())            n->setChanged();        if (change >= Inherit || n->isTextNode() || n->hasChangedChild() || n->changed())            n->recalcStyle(change);        if (n->isElementNode())            forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules;    }    setChanged(NoStyleChange);    setHasChangedChild(false);}bool Element::childTypeAllowed(NodeType type){    switch (type) {        case ELEMENT_NODE:        case TEXT_NODE:        case COMMENT_NODE:        case PROCESSING_INSTRUCTION_NODE:        case CDATA_SECTION_NODE:        case ENTITY_REFERENCE_NODE:            return true;            break;        default:            return false;    }}static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool finishedParsingCallback,                                        Node* beforeChange, Node* afterChange, int childCountDelta){    if (!style || (e->changed() && style->childrenAffectedByPositionalRules()))        return;    // :first-child.  In the parser callback case, we don't have to check anything, since we were right the first time.    // In the DOM case, we only need to do something if |afterChange| is not 0.    // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.    if (style->childrenAffectedByFirstChildRules() && afterChange) {        // Find our new first child.        Node* newFirstChild = 0;        for (newFirstChild = e->firstChild(); newFirstChild && !newFirstChild->isElementNode(); newFirstChild = newFirstChild->nextSibling()) {};                // Find the first element node following |afterChange|        Node* firstElementAfterInsertion = 0;        for (firstElementAfterInsertion = afterChange;             firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();             firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};                // This is the insert/append case.        if (newFirstChild != firstElementAfterInsertion && firstElementAfterInsertion && firstElementAfterInsertion->attached() &&            firstElementAfterInsertion->renderStyle() && firstElementAfterInsertion->renderStyle()->firstChildState())            firstElementAfterInsertion->setChanged();                    // We also have to handle node removal.        if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion && newFirstChild && newFirstChild->renderStyle() && !newFirstChild->renderStyle()->firstChildState())            newFirstChild->setChanged();    }    // :last-child.  In the parser callback case, we don't have to check anything, since we were right the first time.    // In the DOM case, we only need to do something if |afterChange| is not 0.    if (style->childrenAffectedByLastChildRules() && beforeChange) {        // Find our new last child.        Node* newLastChild = 0;        for (newLastChild = e->lastChild(); newLastChild && !newLastChild->isElementNode(); newLastChild = newLastChild->previousSibling()) {};                // Find the last element node going backwards from |beforeChange|        Node* lastElementBeforeInsertion = 0;        for (lastElementBeforeInsertion = beforeChange;             lastElementBeforeInsertion && !lastElementBeforeInsertion->isElementNode();             lastElementBeforeInsertion = lastElementBeforeInsertion->previousSibling()) {};                if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInsertion && lastElementBeforeInsertion->attached() &&

⌨️ 快捷键说明

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