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

📄 htmlelement.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
}void HTMLElement::setOuterHTML(const String& html, ExceptionCode& ec){    Node* p = parent();    if (!p || !p->isHTMLElement()) {        ec = NO_MODIFICATION_ALLOWED_ERR;        return;    }    HTMLElement* parent = static_cast<HTMLElement*>(p);    RefPtr<DocumentFragment> fragment = parent->createContextualFragment(html);    if (!fragment) {        ec = NO_MODIFICATION_ALLOWED_ERR;        return;    }    // FIXME: Why doesn't this have code to merge neighboring text nodes the way setOuterText does?    parent->replaceChild(fragment.release(), this, ec);}void HTMLElement::setInnerText(const String& text, ExceptionCode& ec){    // follow the IE specs about when this is allowed    if (endTagRequirement() == TagStatusForbidden) {        ec = NO_MODIFICATION_ALLOWED_ERR;        return;    }    if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(framesetTag) ||        hasLocalName(headTag) || hasLocalName(htmlTag) || hasLocalName(tableTag) ||         hasLocalName(tbodyTag) || hasLocalName(tfootTag) || hasLocalName(theadTag) ||        hasLocalName(trTag)) {        ec = NO_MODIFICATION_ALLOWED_ERR;        return;    }    // FIXME: This doesn't take whitespace collapsing into account at all.    if (!text.contains('\n') && !text.contains('\r')) {        if (text.isEmpty()) {            removeChildren();            return;        }        replaceChildrenWithText(this, text, ec);        return;    }    // FIXME: Do we need to be able to detect preserveNewline style even when there's no renderer?    // FIXME: Can the renderer be out of date here? Do we need to call updateRendering?    // For example, for the contents of textarea elements that are display:none?    RenderObject* r = renderer();    if (r && r->style()->preserveNewline()) {        if (!text.contains('\r')) {            replaceChildrenWithText(this, text, ec);            return;        }        String textWithConsistentLineBreaks = text;        textWithConsistentLineBreaks.replace("\r\n", "\n");        textWithConsistentLineBreaks.replace('\r', '\n');        replaceChildrenWithText(this, textWithConsistentLineBreaks, ec);        return;    }    // Add text nodes and <br> elements.    ec = 0;    RefPtr<DocumentFragment> fragment = new DocumentFragment(document());    int lineStart = 0;    UChar prev = 0;    int length = text.length();    for (int i = 0; i < length; ++i) {        UChar c = text[i];        if (c == '\n' || c == '\r') {            if (i > lineStart) {                fragment->appendChild(new Text(document(), text.substring(lineStart, i - lineStart)), ec);                if (ec)                    return;            }            if (!(c == '\n' && i != 0 && prev == '\r')) {                fragment->appendChild(new HTMLBRElement(brTag, document()), ec);                if (ec)                    return;            }            lineStart = i + 1;        }        prev = c;    }    if (length > lineStart)        fragment->appendChild(new Text(document(), text.substring(lineStart, length - lineStart)), ec);    replaceChildrenWithFragment(this, fragment.release(), ec);}void HTMLElement::setOuterText(const String &text, ExceptionCode& ec){    // follow the IE specs about when this is allowed    if (endTagRequirement() == TagStatusForbidden) {        ec = NO_MODIFICATION_ALLOWED_ERR;        return;    }    if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(framesetTag) ||        hasLocalName(headTag) || hasLocalName(htmlTag) || hasLocalName(tableTag) ||         hasLocalName(tbodyTag) || hasLocalName(tfootTag) || hasLocalName(theadTag) ||        hasLocalName(trTag)) {        ec = NO_MODIFICATION_ALLOWED_ERR;        return;    }    Node* parent = parentNode();    if (!parent) {        ec = NO_MODIFICATION_ALLOWED_ERR;        return;    }    // FIXME: This creates a new text node even when the text is empty.    // FIXME: This creates a single text node even when the text has CR and LF    // characters in it. Instead it should create <br> elements.    RefPtr<Text> t = new Text(document(), text);    ec = 0;    parent->replaceChild(t, this, ec);    if (ec)        return;    // is previous node a text node? if so, merge into it    Node* prev = t->previousSibling();    if (prev && prev->isTextNode()) {        Text* textPrev = static_cast<Text*>(prev);        textPrev->appendData(t->data(), ec);        if (ec)            return;        t->remove(ec);        if (ec)            return;        t = textPrev;    }    // is next node a text node? if so, merge it in    Node* next = t->nextSibling();    if (next && next->isTextNode()) {        Text* textNext = static_cast<Text*>(next);        t->appendData(textNext->data(), ec);        if (ec)            return;        textNext->remove(ec);        if (ec)            return;    }}Node* HTMLElement::insertAdjacent(const String& where, Node* newChild, ExceptionCode& ec){    // In Internet Explorer if the element has no parent and where is "beforeBegin" or "afterEnd",    // a document fragment is created and the elements appended in the correct order. This document    // fragment isn't returned anywhere.    //    // This is impossible for us to implement as the DOM tree does not allow for such structures,    // Opera also appears to disallow such usage.    if (equalIgnoringCase(where, "beforeBegin")) {        if (Node* p = parent())            return p->insertBefore(newChild, this, ec) ? newChild : 0;        return 0;    }    if (equalIgnoringCase(where, "afterBegin"))        return insertBefore(newChild, firstChild(), ec) ? newChild : 0;    if (equalIgnoringCase(where, "beforeEnd"))        return appendChild(newChild, ec) ? newChild : 0;    if (equalIgnoringCase(where, "afterEnd")) {        if (Node* p = parent())            return p->insertBefore(newChild, nextSibling(), ec) ? newChild : 0;        return 0;    }        // IE throws COM Exception E_INVALIDARG; this is the best DOM exception alternative    ec = NOT_SUPPORTED_ERR;    return 0;}Element* HTMLElement::insertAdjacentElement(const String& where, Element* newChild, ExceptionCode& ec){    if (!newChild) {        // IE throws COM Exception E_INVALIDARG; this is the best DOM exception alternative        ec = TYPE_MISMATCH_ERR;        return 0;    }    Node* returnValue = insertAdjacent(where, newChild, ec);    ASSERT(!returnValue || returnValue->isElementNode());    return static_cast<Element*>(returnValue); }void HTMLElement::insertAdjacentHTML(const String& where, const String& html, ExceptionCode& ec){    RefPtr<DocumentFragment> fragment = document()->createDocumentFragment();    if (document()->isHTMLDocument())         parseHTMLDocumentFragment(html, fragment.get());    else {        if (!parseXMLDocumentFragment(html, fragment.get(), this))            // FIXME: We should propagate a syntax error exception out here.            return;    }    insertAdjacent(where, fragment.get(), ec);}void HTMLElement::insertAdjacentText(const String& where, const String& text, ExceptionCode& ec){    RefPtr<Text> textNode = document()->createTextNode(text);    insertAdjacent(where, textNode.get(), ec);}void HTMLElement::addHTMLAlignment(MappedAttribute* attr){    addHTMLAlignmentToStyledElement(this, attr);}void HTMLElement::addHTMLAlignmentToStyledElement(StyledElement* element, MappedAttribute* attr){    // vertical alignment with respect to the current baseline of the text    // right or left means floating images    int floatValue = CSSValueInvalid;    int verticalAlignValue = CSSValueInvalid;    const AtomicString& alignment = attr->value();    if (equalIgnoringCase(alignment, "absmiddle"))        verticalAlignValue = CSSValueMiddle;    else if (equalIgnoringCase(alignment, "absbottom"))        verticalAlignValue = CSSValueBottom;    else if (equalIgnoringCase(alignment, "left")) {        floatValue = CSSValueLeft;        verticalAlignValue = CSSValueTop;    } else if (equalIgnoringCase(alignment, "right")) {        floatValue = CSSValueRight;        verticalAlignValue = CSSValueTop;    } else if (equalIgnoringCase(alignment, "top"))        verticalAlignValue = CSSValueTop;    else if (equalIgnoringCase(alignment, "middle"))        verticalAlignValue = CSSValueWebkitBaselineMiddle;    else if (equalIgnoringCase(alignment, "center"))        verticalAlignValue = CSSValueMiddle;    else if (equalIgnoringCase(alignment, "bottom"))        verticalAlignValue = CSSValueBaseline;    else if (equalIgnoringCase(alignment, "texttop"))        verticalAlignValue = CSSValueTextTop;    if (floatValue != CSSValueInvalid)        element->addCSSProperty(attr, CSSPropertyFloat, floatValue);    if (verticalAlignValue != CSSValueInvalid)        element->addCSSProperty(attr, CSSPropertyVerticalAlign, verticalAlignValue);}bool HTMLElement::isFocusable() const{    return Element::isFocusable() || (isContentEditable() && parent() && !parent()->isContentEditable());}bool HTMLElement::isContentEditable() const {    if (document()->frame() && document()->frame()->isContentEditable())        return true;    // FIXME: this is a terrible thing to do here:    // https://bugs.webkit.org/show_bug.cgi?id=21834    document()->updateRendering();    if (!renderer()) {        if (parentNode())            return parentNode()->isContentEditable();        else            return false;    }        return renderer()->style()->userModify() == READ_WRITE || renderer()->style()->userModify() == READ_WRITE_PLAINTEXT_ONLY;}bool HTMLElement::isContentRichlyEditable() const{    if (document()->frame() && document()->frame()->isContentEditable())        return true;    document()->updateRendering();    if (!renderer()) {        if (parentNode())            return parentNode()->isContentEditable();        else            return false;    }        return renderer()->style()->userModify() == READ_WRITE;}String HTMLElement::contentEditable() const {    document()->updateRendering();    if (!renderer())        return "false";        switch (renderer()->style()->userModify()) {        case READ_WRITE:            return "true";        case READ_ONLY:            return "false";        case READ_WRITE_PLAINTEXT_ONLY:            return "plaintext-only";        default:            return "inherit";    }}void HTMLElement::setContentEditable(MappedAttribute* attr) {    const AtomicString& enabled = attr->value();    if (enabled.isEmpty() || equalIgnoringCase(enabled, "true")) {        addCSSProperty(attr, CSSPropertyWebkitUserModify, CSSValueReadWrite);        addCSSProperty(attr, CSSPropertyWordWrap, CSSValueBreakWord);        addCSSProperty(attr, CSSPropertyWebkitNbspMode, CSSValueSpace);        addCSSProperty(attr, CSSPropertyWebkitLineBreak, CSSValueAfterWhiteSpace);    } else if (equalIgnoringCase(enabled, "false")) {        addCSSProperty(attr, CSSPropertyWebkitUserModify, CSSValueReadOnly);        attr->decl()->removeProperty(CSSPropertyWordWrap, false);        attr->decl()->removeProperty(CSSPropertyWebkitNbspMode, false);        attr->decl()->removeProperty(CSSPropertyWebkitLineBreak, false);    } else if (equalIgnoringCase(enabled, "inherit")) {        addCSSProperty(attr, CSSPropertyWebkitUserModify, CSSValueInherit);        attr->decl()->removeProperty(CSSPropertyWordWrap, false);        attr->decl()->removeProperty(CSSPropertyWebkitNbspMode, false);        attr->decl()->removeProperty(CSSPropertyWebkitLineBreak, false);    } else if (equalIgnoringCase(enabled, "plaintext-only")) {        addCSSProperty(attr, CSSPropertyWebkitUserModify, CSSValueReadWritePlaintextOnly);        addCSSProperty(attr, CSSPropertyWordWrap, CSSValueBreakWord);        addCSSProperty(attr, CSSPropertyWebkitNbspMode, CSSValueSpace);        addCSSProperty(attr, CSSPropertyWebkitLineBreak, CSSValueAfterWhiteSpace);

⌨️ 快捷键说明

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