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

📄 element.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 1999 Lars Knoll (knoll@kde.org) *           (C) 1999 Antti Koivisto (koivisto@kde.org) *           (C) 2001 Peter Kelly (pmk@post.com) *           (C) 2001 Dirk Mueller (mueller@kde.org) *           (C) 2007 David Smith (catfish.man@gmail.com) * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. *           (C) 2007 Eric Seidel (eric@webkit.org) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB.  If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */#include "config.h"#include "Element.h"#include "AXObjectCache.h"#include "CSSStyleSelector.h"#include "CString.h"#include "ClientRect.h"#include "ClientRectList.h"#include "Document.h"#include "Editor.h"#include "ElementRareData.h"#include "ExceptionCode.h"#include "FocusController.h"#include "Frame.h"#include "FrameView.h"#include "HTMLElement.h"#include "HTMLNames.h"#include "NamedAttrMap.h"#include "NodeList.h"#include "NodeRenderStyle.h"#include "Page.h"#include "PlatformString.h"#include "RenderBlock.h"#if ENABLE(SVG)#include "SVGNames.h"#endif#include "SelectionController.h"#include "TextIterator.h"#include "XMLNames.h"namespace WebCore {using namespace HTMLNames;using namespace XMLNames;    Element::Element(const QualifiedName& tagName, Document* doc)    : ContainerNode(doc, true)    , m_tagName(tagName){}Element::~Element(){    if (namedAttrMap)        namedAttrMap->detachFromElement();}inline ElementRareData* Element::rareData() const{    ASSERT(hasRareData());    return static_cast<ElementRareData*>(NodeRareData::rareDataFromMap(this));}    inline ElementRareData* Element::ensureRareData(){    return static_cast<ElementRareData*>(Node::ensureRareData());}    NodeRareData* Element::createRareData(){    return new ElementRareData;}    PassRefPtr<Node> Element::cloneNode(bool deep){    RefPtr<Element> clone = document()->createElement(tagQName(), false);    // This will catch HTML elements in the wrong namespace that are not correctly copied.    // This is a sanity check as HTML overloads some of the DOM methods.    ASSERT(isHTMLElement() == clone->isHTMLElement());    // Clone attributes.    if (namedAttrMap)        clone->attributes()->setAttributes(*namedAttrMap);    clone->copyNonAttributeProperties(this);        if (deep)        cloneChildNodes(clone.get());    return clone.release();}PassRefPtr<Element> Element::cloneElement(){    return static_pointer_cast<Element>(cloneNode(false));}void Element::removeAttribute(const QualifiedName& name, ExceptionCode& ec){    if (namedAttrMap) {        namedAttrMap->removeNamedItem(name, ec);        if (ec == NOT_FOUND_ERR)            ec = 0;    }}void Element::setAttribute(const QualifiedName& name, const AtomicString& value){    ExceptionCode ec;    setAttribute(name, value, ec);}void Element::setBooleanAttribute(const QualifiedName& name, bool b){    if (b)        setAttribute(name, name.localName());    else {        ExceptionCode ex;        removeAttribute(name, ex);    }}// Virtual function, defined in base class.NamedAttrMap* Element::attributes() const{    return attributes(false);}NamedAttrMap* Element::attributes(bool readonly) const{    if (!m_isStyleAttributeValid)        updateStyleAttribute();#if ENABLE(SVG)    if (!m_areSVGAttributesValid)        updateAnimatedSVGAttribute(String());#endif    if (!readonly && !namedAttrMap)        createAttributeMap();    return namedAttrMap.get();}Node::NodeType Element::nodeType() const{    return ELEMENT_NODE;}const AtomicString& Element::getIDAttribute() const{    return namedAttrMap ? namedAttrMap->id() : nullAtom;}bool Element::hasAttribute(const QualifiedName& name) const{    return hasAttributeNS(name.namespaceURI(), name.localName());}const AtomicString& Element::getAttribute(const QualifiedName& name) const{    if (name == styleAttr && !m_isStyleAttributeValid)        updateStyleAttribute();#if ENABLE(SVG)    if (!m_areSVGAttributesValid)        updateAnimatedSVGAttribute(name.localName());#endif    if (namedAttrMap)        if (Attribute* a = namedAttrMap->getAttributeItem(name))            return a->value();    return nullAtom;}void Element::scrollIntoView(bool alignToTop) {    document()->updateLayoutIgnorePendingStylesheets();    IntRect bounds = getRect();        if (renderer()) {        // Align to the top / bottom and to the closest edge.        if (alignToTop)            renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);        else            renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignBottomAlways);    }}void Element::scrollIntoViewIfNeeded(bool centerIfNeeded){    document()->updateLayoutIgnorePendingStylesheets();    IntRect bounds = getRect();        if (renderer()) {        if (centerIfNeeded)            renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeeded);        else            renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);    }}void Element::scrollByUnits(int units, ScrollGranularity granularity){    document()->updateLayoutIgnorePendingStylesheets();    if (RenderObject *rend = renderer()) {        if (rend->hasOverflowClip()) {            ScrollDirection direction = ScrollDown;            if (units < 0) {                direction = ScrollUp;                units = -units;            }            toRenderBox(rend)->layer()->scroll(direction, granularity, units);        }    }}void Element::scrollByLines(int lines){    scrollByUnits(lines, ScrollByLine);}void Element::scrollByPages(int pages){    scrollByUnits(pages, ScrollByPage);}static float localZoomForRenderer(RenderObject* renderer){    // FIXME: This does the wrong thing if two opposing zooms are in effect and canceled each    // other out, but the alternative is that we'd have to crawl up the whole render tree every    // time (or store an additional bit in the RenderStyle to indicate that a zoom was specified).    float zoomFactor = 1.0f;    if (renderer->style()->effectiveZoom() != 1.0f) {        // Need to find the nearest enclosing RenderObject that set up        // a differing zoom, and then we divide our result by it to eliminate the zoom.        RenderObject* prev = renderer;        for (RenderObject* curr = prev->parent(); curr; curr = curr->parent()) {            if (curr->style()->effectiveZoom() != prev->style()->effectiveZoom()) {                zoomFactor = prev->style()->zoom();                break;            }            prev = curr;        }        if (prev->isRenderView())            zoomFactor = prev->style()->zoom();    }    return zoomFactor;}static int adjustForLocalZoom(int value, RenderObject* renderer){    float zoomFactor = localZoomForRenderer(renderer);    if (zoomFactor == 1.0f)        return value;    return static_cast<int>(value / zoomFactor);}static int adjustForAbsoluteZoom(int value, RenderObject* renderer){    float zoomFactor = renderer->style()->effectiveZoom();    if (zoomFactor == 1.0f)        return value;    return static_cast<int>(value / zoomFactor);}int Element::offsetLeft(){    document()->updateLayoutIgnorePendingStylesheets();    if (RenderBoxModelObject* rend = renderBoxModelObject())        return adjustForLocalZoom(rend->offsetLeft(), rend);    return 0;}int Element::offsetTop(){    document()->updateLayoutIgnorePendingStylesheets();    if (RenderBoxModelObject* rend = renderBoxModelObject())        return adjustForLocalZoom(rend->offsetTop(), rend);    return 0;}int Element::offsetWidth(){    document()->updateLayoutIgnorePendingStylesheets();    if (RenderBoxModelObject* rend = renderBoxModelObject())        return adjustForAbsoluteZoom(rend->offsetWidth(), rend);    return 0;}int Element::offsetHeight(){    document()->updateLayoutIgnorePendingStylesheets();    if (RenderBoxModelObject* rend = renderBoxModelObject())        return adjustForAbsoluteZoom(rend->offsetHeight(), rend);    return 0;}Element* Element::offsetParent(){    document()->updateLayoutIgnorePendingStylesheets();    if (RenderObject* rend = renderer())        if (RenderObject* offsetParent = rend->offsetParent())            return static_cast<Element*>(offsetParent->node());    return 0;}int Element::clientLeft(){    document()->updateLayoutIgnorePendingStylesheets();    if (RenderBox* rend = renderBox())        return adjustForAbsoluteZoom(rend->clientLeft(), rend);    return 0;}int Element::clientTop(){    document()->updateLayoutIgnorePendingStylesheets();    if (RenderBox* rend = renderBox())        return adjustForAbsoluteZoom(rend->clientTop(), rend);    return 0;}int Element::clientWidth(){    document()->updateLayoutIgnorePendingStylesheets();    // When in strict mode, clientWidth for the document element should return the width of the containing frame.    // When in quirks mode, clientWidth for the body element should return the width of the containing frame.    bool inCompatMode = document()->inCompatMode();    if ((!inCompatMode && document()->documentElement() == this) ||        (inCompatMode && isHTMLElement() && document()->body() == this)) {        if (FrameView* view = document()->view())            return adjustForAbsoluteZoom(view->layoutWidth(), document()->renderer());    }        if (RenderBox* rend = renderBox())        return adjustForAbsoluteZoom(rend->clientWidth(), rend);    return 0;}int Element::clientHeight(){    document()->updateLayoutIgnorePendingStylesheets();    // When in strict mode, clientHeight for the document element should return the height of the containing frame.    // When in quirks mode, clientHeight for the body element should return the height of the containing frame.    bool inCompatMode = document()->inCompatMode();         if ((!inCompatMode && document()->documentElement() == this) ||        (inCompatMode && isHTMLElement() && document()->body() == this)) {        if (FrameView* view = document()->view())            return adjustForAbsoluteZoom(view->layoutHeight(), document()->renderer());    }        if (RenderBox* rend = renderBox())        return adjustForAbsoluteZoom(rend->clientHeight(), rend);    return 0;}int Element::scrollLeft(){    document()->updateLayoutIgnorePendingStylesheets();    if (RenderBox* rend = renderBox())        return adjustForAbsoluteZoom(rend->scrollLeft(), rend);    return 0;}int Element::scrollTop(){    document()->updateLayoutIgnorePendingStylesheets();    if (RenderBox* rend = renderBox())        return adjustForAbsoluteZoom(rend->scrollTop(), rend);    return 0;}void Element::setScrollLeft(int newLeft){    document()->updateLayoutIgnorePendingStylesheets();    if (RenderBox* rend = renderBox())        rend->setScrollLeft(static_cast<int>(newLeft * rend->style()->effectiveZoom()));}void Element::setScrollTop(int newTop){    document()->updateLayoutIgnorePendingStylesheets();    if (RenderBox* rend = renderBox())        rend->setScrollTop(static_cast<int>(newTop * rend->style()->effectiveZoom()));}int Element::scrollWidth(){    document()->updateLayoutIgnorePendingStylesheets();    if (RenderBox* rend = renderBox())        return adjustForAbsoluteZoom(rend->scrollWidth(), rend);    return 0;}int Element::scrollHeight(){    document()->updateLayoutIgnorePendingStylesheets();    if (RenderBox* rend = renderBox())        return adjustForAbsoluteZoom(rend->scrollHeight(), rend);    return 0;}PassRefPtr<ClientRectList> Element::getClientRects() const{    document()->updateLayoutIgnorePendingStylesheets();    RenderBoxModelObject* renderBoxModelObject = this->renderBoxModelObject();    if (!renderBoxModelObject)        return ClientRectList::create();    // FIXME: Handle SVG elements.    // FIXME: Handle table/inline-table with a caption.    Vector<FloatQuad> quads;    renderBoxModelObject->absoluteQuads(quads);

⌨️ 快捷键说明

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