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; } }
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); }
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); }
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); }
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); }
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); }
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); } }
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); }
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); }
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); } }
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); }
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); }
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(); }
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::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); } }
RenderObject* HTMLElement::createRenderer(RenderArena* arena, RenderStyle* style) { if (hasLocalName(wbrTag)) return new (arena) RenderWordBreak(this); return RenderObject::createObject(this, style); }
bool HTMLElement::checkDTD(const Node* newChild) { if (hasLocalName(addressTag) && newChild->hasTagName(pTag)) return true; return inEitherTagList(newChild); }