예제 #1
0
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;
    }
}
예제 #2
0
bool HTMLElement::rendererIsNeeded(const NodeRenderingContext& context)
{
    if (hasLocalName(noscriptTag)) {
        Frame* frame = document()->frame();
        if (frame && frame->script()->canExecuteScripts(NotAboutToExecuteScript))
            return false;
    } else if (hasLocalName(noembedTag)) {
        Frame* frame = document()->frame();
        if (frame && frame->loader()->subframeLoader()->allowPlugins(NotAboutToInstantiatePlugin))
            return false;
    }
    return StyledElement::rendererIsNeeded(context);
}
예제 #3
0
bool HTMLElement::rendererIsNeeded(const RenderStyle& style)
{
    if (hasLocalName(noscriptTag)) {
        Frame* frame = document().frame();
        if (frame && frame->script().canExecuteScripts(NotAboutToExecuteScript))
            return false;
    } else if (hasLocalName(noembedTag)) {
        Frame* frame = document().frame();
        if (frame && frame->loader().allowPlugins(NotAboutToInstantiatePlugin))
            return false;
    }
    return Element::rendererIsNeeded(style);
}
예제 #4
0
void HTMLElement::setInnerText(const String& text, ExceptionCode& ec)
{
    if (ieForbidsInsertHTML()) {
        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 updateStyleIfNeeded?
    // 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 = textToFragment(text, ec);
    if (!ec)
        replaceChildrenWithFragment(this, fragment.release(), ec);
}
예제 #5
0
void HTMLElement::setInnerHTML(const String& html, ExceptionCode& ec)
{
    if (hasLocalName(scriptTag) || hasLocalName(styleTag)) {
        // Script and CSS source shouldn't be parsed as HTML.
        removeChildren();
        appendChild(document()->createTextNode(html), ec);
        return;
    }

    RefPtr<DocumentFragment> fragment = createContextualFragment(html);
    if (!fragment) {
        ec = NO_MODIFICATION_ALLOWED_ERR;
        return;
    }

    replaceChildrenWithFragment(this, fragment.release(), ec);
}
예제 #6
0
void HTMLElement::setOuterText(const String &text, ExceptionState& exceptionState)
{
    if (ieForbidsInsertHTML()) {
        exceptionState.throwDOMException(NoModificationAllowedError, "The '" + localName() + "' element does not support text insertion.");
        return;
    }
    if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(framesetTag) ||
        hasLocalName(headTag) || hasLocalName(htmlTag) || hasLocalName(tableTag) ||
        hasLocalName(tbodyTag) || hasLocalName(tfootTag) || hasLocalName(theadTag) ||
        hasLocalName(trTag)) {
        exceptionState.throwDOMException(NoModificationAllowedError, "The '" + localName() + "' element does not support text insertion.");
        return;
    }

    ContainerNode* parent = parentNode();
    if (!parent) {
        exceptionState.throwDOMException(NoModificationAllowedError, "The element has no parent.");
        return;
    }

    RefPtr<Node> prev = previousSibling();
    RefPtr<Node> next = nextSibling();
    RefPtr<Node> newChild;

    // Convert text to fragment with <br> tags instead of linebreaks if needed.
    if (text.contains('\r') || text.contains('\n'))
        newChild = textToFragment(text, exceptionState);
    else
        newChild = Text::create(document(), text);

    // textToFragment might cause mutation events.
    if (!this || !parentNode())
        exceptionState.throwDOMException(HierarchyRequestError, "The element has no parent.");

    if (exceptionState.hadException())
        return;

    parent->replaceChild(newChild.release(), this, exceptionState);

    RefPtr<Node> node = next ? next->previousSibling() : 0;
    if (!exceptionState.hadException() && node && node->isTextNode())
        mergeWithNextTextNode(node.release(), exceptionState);

    if (!exceptionState.hadException() && prev && prev->isTextNode())
        mergeWithNextTextNode(prev.release(), exceptionState);
}
예제 #7
0
void HTMLElement::setInnerHTML(const String& html, ExceptionState& es)
{
    if (RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, this, AllowScriptingContent, es)) {
        ContainerNode* container = this;
        if (hasLocalName(templateTag))
            container = toHTMLTemplateElement(this)->content();
        replaceChildrenWithFragment(container, fragment.release(), es);
    }
}
예제 #8
0
void HTMLElement::setOuterText(const String &text, ExceptionCode& ec)
{
    if (ieForbidsInsertHTML()) {
        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;
    }

    ContainerNode* parent = parentNode();
    if (!parent) {
        ec = NO_MODIFICATION_ALLOWED_ERR;
        return;
    }

    RefPtr<Node> prev = previousSibling();
    RefPtr<Node> next = nextSibling();
    RefPtr<Node> newChild;
    ec = 0;
    
    // Convert text to fragment with <br> tags instead of linebreaks if needed.
    if (text.contains('\r') || text.contains('\n'))
        newChild = textToFragment(text, ec);
    else
        newChild = Text::create(document(), text);

    if (!this || !parentNode())
        ec = HIERARCHY_REQUEST_ERR;
    if (ec)
        return;
    parent->replaceChild(newChild.release(), this, ec);

    RefPtr<Node> node = next ? next->previousSibling() : 0;
    if (!ec && node && node->isTextNode())
        mergeWithNextTextNode(node.release(), ec);

    if (!ec && prev && prev->isTextNode())
        mergeWithNextTextNode(prev.release(), ec);
}
예제 #9
0
bool HTMLElement::rendererIsNeeded(RenderStyle *style)
{
#if !ENABLE(XHTMLMP)
    if (hasLocalName(noscriptTag)) {
        Settings* settings = document()->settings();
        if (settings && settings->isJavaScriptEnabled())
            return false;
    }
#endif
    return StyledElement::rendererIsNeeded(style);
}
예제 #10
0
void HTMLElement::setInnerHTML(const String& html, ExceptionCode& ec)
{
    if (RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, this, AllowScriptingContent, ec)) {
        ContainerNode* container = this;
#if ENABLE(TEMPLATE_ELEMENT)
        if (hasLocalName(templateTag))
            container = toHTMLTemplateElement(this)->content();
#endif
        replaceChildrenWithFragment(container, fragment.release(), ec);
    }
}
예제 #11
0
bool HTMLElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
{
    if (attrName == alignAttr ||
        attrName == contenteditableAttr) {
        result = eUniversal;
        return false;
    }
    if (attrName == dirAttr) {
        result = hasLocalName(bdoTag) ? eBDO : eUniversal;
        return false;
    }

    return StyledElement::mapToEntry(attrName, result);
}
예제 #12
0
PassRefPtr<DocumentFragment> HTMLElement::createContextualFragment(const String& markup, FragmentScriptingPermission scriptingPermission)
{
    // The following is in accordance with the definition as used by IE.
    if (endTagRequirement() == TagStatusForbidden)
        return 0;

    if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(framesetTag) ||
        hasLocalName(headTag) || hasLocalName(styleTag) || hasLocalName(titleTag))
        return 0;

    return Element::createContextualFragment(markup, scriptingPermission);
}
예제 #13
0
PassRefPtr<DocumentFragment> HTMLElement::createContextualFragment(const String &html)
{
    // the following is in accordance with the definition as used by IE
    if (endTagRequirement() == TagStatusForbidden)
        return 0;

    if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(framesetTag) ||
        hasLocalName(headTag) || hasLocalName(styleTag) || hasLocalName(titleTag))
        return 0;

    RefPtr<DocumentFragment> fragment = new DocumentFragment(document());
    
    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 0;
    }

    // Exceptions are ignored because none ought to happen here.
    int ignoredExceptionCode;

    // we need to pop <html> and <body> elements and remove <head> to
    // accommodate folks passing complete HTML documents to make the
    // child of an element.

    RefPtr<Node> nextNode;
    for (RefPtr<Node> node = fragment->firstChild(); node; node = nextNode) {
        nextNode = node->nextSibling();
        if (node->hasTagName(htmlTag) || node->hasTagName(bodyTag)) {
            Node *firstChild = node->firstChild();
            if (firstChild)
                nextNode = firstChild;
            RefPtr<Node> nextChild;
            for (RefPtr<Node> child = firstChild; child; child = nextChild) {
                nextChild = child->nextSibling();
                node->removeChild(child.get(), ignoredExceptionCode);
                ASSERT(!ignoredExceptionCode);
                fragment->insertBefore(child, node.get(), ignoredExceptionCode);
                ASSERT(!ignoredExceptionCode);
            }
            fragment->removeChild(node.get(), ignoredExceptionCode);
            ASSERT(!ignoredExceptionCode);
        } else if (node->hasTagName(headTag)) {
            fragment->removeChild(node.get(), ignoredExceptionCode);
            ASSERT(!ignoredExceptionCode);
        }
    }

    return fragment.release();
}
예제 #14
0
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);
}
예제 #15
0
void HTMLElement::parseMappedAttribute(MappedAttribute *attr)
{
    if (attr->name() == idAttr || attr->name() == classAttr || attr->name() == styleAttr)
        return StyledElement::parseMappedAttribute(attr);

    String indexstring;
    if (attr->name() == alignAttr) {
        if (equalIgnoringCase(attr->value(), "middle"))
            addCSSProperty(attr, CSSPropertyTextAlign, "center");
        else
            addCSSProperty(attr, CSSPropertyTextAlign, attr->value());
    } else if (attr->name() == contenteditableAttr) {
        setContentEditable(attr);
    } else if (attr->name() == tabindexAttr) {
        indexstring = getAttribute(tabindexAttr);
        if (indexstring.length()) {
            bool parsedOK;
            int tabindex = indexstring.toIntStrict(&parsedOK);
            if (parsedOK)
                // Clamp tabindex to the range of 'short' to match Firefox's behavior.
                setTabIndexExplicitly(max(static_cast<int>(std::numeric_limits<short>::min()), min(tabindex, static_cast<int>(std::numeric_limits<short>::max()))));
        }
    } else if (attr->name() == langAttr) {
        // FIXME: Implement
    } else if (attr->name() == dirAttr) {
        addCSSProperty(attr, CSSPropertyDirection, attr->value());
        addCSSProperty(attr, CSSPropertyUnicodeBidi, hasLocalName(bdoTag) ? CSSValueBidiOverride : CSSValueEmbed);
    }
// standard events
    else if (attr->name() == onclickAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().clickEvent, attr);
    } else if (attr->name() == oncontextmenuAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().contextmenuEvent, attr);
    } else if (attr->name() == ondblclickAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().dblclickEvent, attr);
    } else if (attr->name() == onmousedownAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().mousedownEvent, attr);
    } else if (attr->name() == onmousemoveAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().mousemoveEvent, attr);
    } else if (attr->name() == onmouseoutAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().mouseoutEvent, attr);
    } else if (attr->name() == onmouseoverAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().mouseoverEvent, attr);
    } else if (attr->name() == onmouseupAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().mouseupEvent, attr);
    } else if (attr->name() == onmousewheelAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().mousewheelEvent, attr);
    } else if (attr->name() == onfocusAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().focusEvent, attr);
    } else if (attr->name() == onblurAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().blurEvent, attr);
    } else if (attr->name() == onkeydownAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().keydownEvent, attr);
    } else if (attr->name() == onkeypressAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().keypressEvent, attr);
    } else if (attr->name() == onkeyupAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().keyupEvent, attr);
    } else if (attr->name() == onscrollAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().scrollEvent, attr);
    } else if (attr->name() == onbeforecutAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().beforecutEvent, attr);
    } else if (attr->name() == oncutAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().cutEvent, attr);
    } else if (attr->name() == onbeforecopyAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().beforecopyEvent, attr);
    } else if (attr->name() == oncopyAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().copyEvent, attr);
    } else if (attr->name() == onbeforepasteAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().beforepasteEvent, attr);
    } else if (attr->name() == onpasteAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().pasteEvent, attr);
    } else if (attr->name() == ondragenterAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().dragenterEvent, attr);
    } else if (attr->name() == ondragoverAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().dragoverEvent, attr);
    } else if (attr->name() == ondragleaveAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().dragleaveEvent, attr);
    } else if (attr->name() == ondropAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().dropEvent, attr);
    } else if (attr->name() == ondragstartAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().dragstartEvent, attr);
    } else if (attr->name() == ondragAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().dragEvent, attr);
    } else if (attr->name() == ondragendAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().dragendEvent, attr);
    } else if (attr->name() == onselectstartAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().selectstartEvent, attr);
    } else if (attr->name() == onsubmitAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().submitEvent, attr);
    } else if (attr->name() == onerrorAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().errorEvent, attr);
    } else if (attr->name() == onwebkitanimationstartAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().webkitAnimationStartEvent, attr);
    } else if (attr->name() == onwebkitanimationiterationAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().webkitAnimationIterationEvent, attr);
    } else if (attr->name() == onwebkitanimationendAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().webkitAnimationEndEvent, attr);
    } else if (attr->name() == onwebkittransitionendAttr) {
        setInlineEventListenerForTypeAndAttribute(eventNames().webkitTransitionEndEvent, attr);
    }
}
예제 #16
0
RenderObject* HTMLElement::createRenderer(RenderArena* arena, RenderStyle* style)
{
    if (hasLocalName(wbrTag))
        return new (arena) RenderWordBreak(this);
    return RenderObject::createObject(this, style);
}
예제 #17
0
bool HTMLElement::checkDTD(const Node* newChild)
{
    if (hasLocalName(addressTag) && newChild->hasTagName(pTag))
        return true;
    return inEitherTagList(newChild);
}