summaryrefslogtreecommitdiffstats
path: root/WebCore/html/HTMLElement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/html/HTMLElement.cpp')
-rw-r--r--WebCore/html/HTMLElement.cpp354
1 files changed, 51 insertions, 303 deletions
diff --git a/WebCore/html/HTMLElement.cpp b/WebCore/html/HTMLElement.cpp
index ff25e62..f40489b 100644
--- a/WebCore/html/HTMLElement.cpp
+++ b/WebCore/html/HTMLElement.cpp
@@ -61,68 +61,55 @@ PassRefPtr<HTMLElement> HTMLElement::create(const QualifiedName& tagName, Docume
String HTMLElement::nodeName() const
{
- // FIXME: Would be nice to have an atomicstring lookup based off uppercase chars that does not have to copy
- // the string on a hit in the hash.
+ // FIXME: Would be nice to have an atomicstring lookup based off uppercase
+ // chars that does not have to copy the string on a hit in the hash.
// FIXME: We should have a way to detect XHTML elements and replace the hasPrefix() check with it.
if (document()->isHTMLDocument() && !tagQName().hasPrefix())
return tagQName().localNameUpper();
return Element::nodeName();
}
-
-HTMLTagStatus HTMLElement::endTagRequirement() const
-{
- if (hasLocalName(wbrTag))
- return TagStatusForbidden;
- if (hasLocalName(dtTag) || hasLocalName(ddTag) || hasLocalName(rpTag) || hasLocalName(rtTag))
- return TagStatusOptional;
-
- // Same values as <span>. This way custom tag name elements will behave like inline spans.
- return TagStatusRequired;
-}
-struct Empty1IntHashTraits : HashTraits<int> {
- static const bool emptyValueIsZero = false;
- static int emptyValue() { return 1; }
-};
-typedef HashMap<AtomicStringImpl*, int, DefaultHash<AtomicStringImpl*>::Hash, HashTraits<AtomicStringImpl*>, Empty1IntHashTraits> TagPriorityMap;
-
-static const TagPriorityMap* createTagPriorityMap()
-{
- TagPriorityMap* map = new TagPriorityMap;
-
- map->add(wbrTag.localName().impl(), 0);
-
- map->add(addressTag.localName().impl(), 3);
- map->add(ddTag.localName().impl(), 3);
- map->add(dtTag.localName().impl(), 3);
- map->add(noscriptTag.localName().impl(), 3);
- map->add(rpTag.localName().impl(), 3);
- map->add(rtTag.localName().impl(), 3);
-
- // 5 is same as <div>'s priority.
- map->add(articleTag.localName().impl(), 5);
- map->add(asideTag.localName().impl(), 5);
- map->add(centerTag.localName().impl(), 5);
- map->add(footerTag.localName().impl(), 5);
- map->add(headerTag.localName().impl(), 5);
- map->add(hgroupTag.localName().impl(), 5);
- map->add(nobrTag.localName().impl(), 5);
- map->add(rubyTag.localName().impl(), 5);
- map->add(navTag.localName().impl(), 5);
- map->add(sectionTag.localName().impl(), 5);
-
- map->add(noembedTag.localName().impl(), 10);
- map->add(noframesTag.localName().impl(), 10);
-
- // TagPriorityMap returns 1 for unregistered tags. It's same as <span>.
- // This way custom tag name elements will behave like inline spans.
- return map;
-}
-
-int HTMLElement::tagPriority() const
-{
- static const TagPriorityMap* tagPriorityMap = createTagPriorityMap();
- return tagPriorityMap->get(localName().impl());
+bool HTMLElement::ieForbidsInsertHTML() const
+{
+ // FIXME: Supposedly IE disallows settting innerHTML, outerHTML
+ // and createContextualFragment on these tags. We have no tests to
+ // verify this however, so this list could be totally wrong.
+ // This list was moved from the previous endTagRequirement() implementation.
+ // This is also called from editing and assumed to be the list of tags
+ // for which no end tag should be serialized. It's unclear if the list for
+ // IE compat and the list for serialization sanity are the same.
+ if (hasLocalName(areaTag)
+ || hasLocalName(baseTag)
+ || hasLocalName(basefontTag)
+ || hasLocalName(brTag)
+ || hasLocalName(colTag)
+#if ENABLE(DATAGRID)
+ || hasLocalName(dcellTag)
+ || hasLocalName(dcolTag)
+#endif
+ || hasLocalName(embedTag)
+ || hasLocalName(frameTag)
+ || hasLocalName(hrTag)
+ || hasLocalName(imageTag)
+ || hasLocalName(imgTag)
+ || hasLocalName(inputTag)
+ || hasLocalName(isindexTag)
+ || hasLocalName(linkTag)
+ || hasLocalName(metaTag)
+ || hasLocalName(paramTag)
+ || hasLocalName(sourceTag)
+ || hasLocalName(wbrTag))
+ return true;
+ // FIXME: I'm not sure why dashboard mode would want to change the
+ // serialization of <canvas>, that seems like a bad idea.
+#if ENABLE(DASHBOARD_SUPPORT)
+ if (hasLocalName(canvasTag)) {
+ Settings* settings = document()->settings();
+ if (settings && settings->usesDashboardBackwardCompatibilityMode())
+ return true;
+ }
+#endif
+ return false;
}
bool HTMLElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
@@ -275,16 +262,16 @@ String HTMLElement::outerHTML() const
return createMarkup(this);
}
-static bool useLegacyTreeBuilder(Document* document)
+static bool useLegacyTreeBuilder(Document*)
{
- return !document || !document->settings() || !document->settings()->html5TreeBuilderEnabled();
+ return false;
}
// FIXME: This logic should move into Range::createContextualFragment
PassRefPtr<DocumentFragment> HTMLElement::deprecatedCreateContextualFragment(const String& markup, FragmentScriptingPermission scriptingPermission)
{
// The following is in accordance with the definition as used by IE.
- if (endTagRequirement() == TagStatusForbidden)
+ if (ieForbidsInsertHTML())
return 0;
if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(framesetTag)
@@ -404,8 +391,7 @@ void HTMLElement::setOuterHTML(const String& html, ExceptionCode& ec)
void HTMLElement::setInnerText(const String& text, ExceptionCode& ec)
{
- // Follow the IE specs about when this is allowed.
- if (endTagRequirement() == TagStatusForbidden) {
+ if (ieForbidsInsertHTML()) {
ec = NO_MODIFICATION_ALLOWED_ERR;
return;
}
@@ -474,8 +460,7 @@ void HTMLElement::setInnerText(const String& text, ExceptionCode& ec)
void HTMLElement::setOuterText(const String &text, ExceptionCode& ec)
{
- // Follow the IE specs about when this is allowed.
- if (endTagRequirement() == TagStatusForbidden) {
+ if (ieForbidsInsertHTML()) {
ec = NO_MODIFICATION_ALLOWED_ERR;
return;
}
@@ -666,9 +651,9 @@ 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()->updateStyleIfNeeded();
+ // Ideally we'd call ASSERT!needsStyleRecalc()) here, but
+ // ContainerNode::setFocus() calls setNeedsStyleRecalc(), so the assertion
+ // would fire in the middle of Document::setFocusedNode().
if (!renderer()) {
if (parentNode())
@@ -685,8 +670,6 @@ bool HTMLElement::isContentRichlyEditable() const
if (document()->frame() && document()->frame()->isContentEditable())
return true;
- document()->updateStyleIfNeeded();
-
if (!renderer()) {
if (parentNode())
return parentNode()->isContentEditable();
@@ -699,8 +682,6 @@ bool HTMLElement::isContentRichlyEditable() const
String HTMLElement::contentEditable() const
{
- document()->updateStyleIfNeeded();
-
if (!renderer())
return "false";
@@ -802,239 +783,6 @@ PassRefPtr<HTMLCollection> HTMLElement::children()
return HTMLCollection::create(this, NodeChildren);
}
-// DOM Section 1.1.1
-bool HTMLElement::childAllowed(Node *newChild)
-{
- if (!Element::childAllowed(newChild))
- return false;
-
- // For XML documents, we are non-validating and do not check against a DTD, even for HTML elements.
- if (!document()->isHTMLDocument())
- return true;
-
- // Future-proof for XML content inside HTML documents (we may allow this some day).
- if (newChild->isElementNode() && !newChild->isHTMLElement())
- return true;
-
- // Elements with forbidden tag status can never have children
- if (endTagRequirement() == TagStatusForbidden)
- return false;
-
- // Comment nodes are always allowed.
- if (newChild->isCommentNode())
- return true;
-
- // Now call checkDTD.
- return checkDTD(newChild);
-}
-
-// DTD Stuff
-// This unfortunate function is only needed when checking against the DTD. Other languages (like SVG) won't need this.
-bool HTMLElement::isRecognizedTagName(const QualifiedName& tagName)
-{
- DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, tagList, ());
- if (tagList.isEmpty()) {
- size_t tagCount = 0;
- WebCore::QualifiedName** tags = HTMLNames::getHTMLTags(&tagCount);
- for (size_t i = 0; i < tagCount; i++) {
- if (*tags[i] == bgsoundTag
- || *tags[i] == commandTag
- || *tags[i] == detailsTag
- || *tags[i] == figcaptionTag
- || *tags[i] == figureTag
- || *tags[i] == summaryTag
- || *tags[i] == trackTag) {
- // Even though we have atoms for these tags, we don't want to
- // treat them as "recognized tags" for the purpose of parsing
- // because that changes how we parse documents.
- continue;
- }
- tagList.add(tags[i]->localName().impl());
- }
- }
- return tagList.contains(tagName.localName().impl());
-}
-
-// The terms inline and block are used here loosely. Don't make the mistake of assuming all inlines or all blocks
-// need to be in these two lists.
-static HashSet<AtomicStringImpl*>* inlineTagList()
-{
- DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, tagList, ());
- if (tagList.isEmpty()) {
- tagList.add(ttTag.localName().impl());
- tagList.add(iTag.localName().impl());
- tagList.add(bTag.localName().impl());
- tagList.add(uTag.localName().impl());
- tagList.add(sTag.localName().impl());
- tagList.add(strikeTag.localName().impl());
- tagList.add(bigTag.localName().impl());
- tagList.add(smallTag.localName().impl());
- tagList.add(emTag.localName().impl());
- tagList.add(strongTag.localName().impl());
- tagList.add(dfnTag.localName().impl());
- tagList.add(codeTag.localName().impl());
- tagList.add(sampTag.localName().impl());
- tagList.add(kbdTag.localName().impl());
- tagList.add(varTag.localName().impl());
- tagList.add(citeTag.localName().impl());
- tagList.add(abbrTag.localName().impl());
- tagList.add(acronymTag.localName().impl());
- tagList.add(aTag.localName().impl());
- tagList.add(canvasTag.localName().impl());
- tagList.add(imgTag.localName().impl());
- tagList.add(appletTag.localName().impl());
- tagList.add(objectTag.localName().impl());
- tagList.add(embedTag.localName().impl());
- tagList.add(fontTag.localName().impl());
- tagList.add(basefontTag.localName().impl());
- tagList.add(brTag.localName().impl());
- tagList.add(scriptTag.localName().impl());
- tagList.add(styleTag.localName().impl());
- tagList.add(linkTag.localName().impl());
- tagList.add(mapTag.localName().impl());
- tagList.add(qTag.localName().impl());
- tagList.add(subTag.localName().impl());
- tagList.add(supTag.localName().impl());
- tagList.add(spanTag.localName().impl());
- tagList.add(bdoTag.localName().impl());
- tagList.add(iframeTag.localName().impl());
- tagList.add(inputTag.localName().impl());
- tagList.add(keygenTag.localName().impl());
- tagList.add(selectTag.localName().impl());
- tagList.add(datagridTag.localName().impl());
- tagList.add(textareaTag.localName().impl());
- tagList.add(labelTag.localName().impl());
- tagList.add(buttonTag.localName().impl());
- tagList.add(datalistTag.localName().impl());
- tagList.add(insTag.localName().impl());
- tagList.add(delTag.localName().impl());
- tagList.add(nobrTag.localName().impl());
- tagList.add(wbrTag.localName().impl());
-#if ENABLE(VIDEO)
- tagList.add(audioTag.localName().impl());
- tagList.add(videoTag.localName().impl());
-#endif
- tagList.add(rpTag.localName().impl());
- tagList.add(rtTag.localName().impl());
- tagList.add(rubyTag.localName().impl());
- tagList.add(progressTag.localName().impl());
- tagList.add(meterTag.localName().impl());
- tagList.add(markTag.localName().impl());
- }
- return &tagList;
-}
-
-static HashSet<AtomicStringImpl*>* blockTagList()
-{
- DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, tagList, ());
- if (tagList.isEmpty()) {
- tagList.add(addressTag.localName().impl());
- tagList.add(articleTag.localName().impl());
- tagList.add(asideTag.localName().impl());
- tagList.add(blockquoteTag.localName().impl());
- tagList.add(centerTag.localName().impl());
- tagList.add(ddTag.localName().impl());
- tagList.add(dirTag.localName().impl());
- tagList.add(divTag.localName().impl());
- tagList.add(dlTag.localName().impl());
- tagList.add(dtTag.localName().impl());
- tagList.add(fieldsetTag.localName().impl());
- tagList.add(footerTag.localName().impl());
- tagList.add(formTag.localName().impl());
- tagList.add(h1Tag.localName().impl());
- tagList.add(h2Tag.localName().impl());
- tagList.add(h3Tag.localName().impl());
- tagList.add(h4Tag.localName().impl());
- tagList.add(h5Tag.localName().impl());
- tagList.add(h6Tag.localName().impl());
- tagList.add(headerTag.localName().impl());
- tagList.add(hgroupTag.localName().impl());
- tagList.add(hrTag.localName().impl());
- tagList.add(isindexTag.localName().impl());
- tagList.add(layerTag.localName().impl());
- tagList.add(liTag.localName().impl());
- tagList.add(listingTag.localName().impl());
- tagList.add(marqueeTag.localName().impl());
- tagList.add(menuTag.localName().impl());
- tagList.add(navTag.localName().impl());
- tagList.add(noembedTag.localName().impl());
- tagList.add(noframesTag.localName().impl());
- tagList.add(nolayerTag.localName().impl());
- tagList.add(noscriptTag.localName().impl());
- tagList.add(olTag.localName().impl());
- tagList.add(pTag.localName().impl());
- tagList.add(plaintextTag.localName().impl());
- tagList.add(preTag.localName().impl());
- tagList.add(sectionTag.localName().impl());
- tagList.add(tableTag.localName().impl());
- tagList.add(ulTag.localName().impl());
- tagList.add(xmpTag.localName().impl());
- }
- return &tagList;
-}
-
-bool HTMLElement::inEitherTagList(const Node* newChild)
-{
- if (newChild->isTextNode())
- return true;
-
- if (newChild->isHTMLElement()) {
- const HTMLElement* child = static_cast<const HTMLElement*>(newChild);
- if (inlineTagList()->contains(child->tagQName().localName().impl())) {
-#if PLATFORM(MAC)
- if (child->tagQName().localName() == styleTag) {
- // Leopard Mail doesn't expect <style> to be in the body of the document, so don't allow it in that case.
- // See <rdar://problem/6621310>
- Settings* settings = newChild->document() ? newChild->document()->settings() : 0;
- if (settings && settings->needsLeopardMailQuirks())
- return false;
- }
-#endif
- return true;
- }
- if (blockTagList()->contains(child->tagQName().localName().impl()))
- return true;
- return !isRecognizedTagName(child->tagQName()); // Accept custom html tags
- }
-
- return false;
-}
-
-bool HTMLElement::inInlineTagList(const Node* newChild)
-{
- if (newChild->isTextNode())
- return true;
-
- if (newChild->isHTMLElement()) {
- const HTMLElement* child = static_cast<const HTMLElement*>(newChild);
- if (inlineTagList()->contains(child->tagQName().localName().impl()))
- return true;
- return !isRecognizedTagName(child->tagQName()); // Accept custom html tags
- }
-
- return false;
-}
-
-bool HTMLElement::inBlockTagList(const Node* newChild)
-{
- if (newChild->isTextNode())
- return true;
-
- if (newChild->isHTMLElement()) {
- const HTMLElement* child = static_cast<const HTMLElement*>(newChild);
- return (blockTagList()->contains(child->tagQName().localName().impl()));
- }
-
- return false;
-}
-
-bool HTMLElement::checkDTD(const Node* newChild)
-{
- if (hasLocalName(addressTag) && newChild->hasTagName(pTag))
- return true;
- return inEitherTagList(newChild);
-}
-
bool HTMLElement::rendererIsNeeded(RenderStyle *style)
{
#if !ENABLE(XHTMLMP)