2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
21 * Portions are Copyright (C) 2002 Netscape Communications Corporation.
22 * Other contributors: David Baron <dbaron@fas.harvard.edu>
24 * This library is free software; you can redistribute it and/or
25 * modify it under the terms of the GNU Lesser General Public
26 * License as published by the Free Software Foundation; either
27 * version 2.1 of the License, or (at your option) any later version.
29 * This library is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
32 * Lesser General Public License for more details.
34 * You should have received a copy of the GNU Lesser General Public
35 * License along with this library; if not, write to the Free Software
36 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
38 * Alternatively, the document type parsing portions of this file may be used
39 * under the terms of either the Mozilla Public License Version 1.1, found at
40 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
41 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
42 * (the "GPL"), in which case the provisions of the MPL or the GPL are
43 * applicable instead of those above. If you wish to allow use of your
44 * version of this file only under the terms of one of those two
45 * licenses (the MPL or the GPL) and not to allow others to use your
46 * version of this file under the LGPL, indicate your decision by
47 * deleting the provisions above and replace them with the notice and
48 * other provisions required by the MPL or the GPL, as the case may be.
49 * If you do not delete the provisions above, a recipient may use your
50 * version of this file under any of the LGPL, the MPL or the GPL.
54 #include "core/html/HTMLDocument.h"
56 #include "bindings/core/v8/ScriptController.h"
57 #include "core/HTMLNames.h"
58 #include "core/frame/FrameView.h"
59 #include "core/frame/LocalDOMWindow.h"
60 #include "core/frame/LocalFrame.h"
61 #include "core/html/HTMLBodyElement.h"
62 #include "core/page/FocusController.h"
63 #include "core/page/FrameTree.h"
64 #include "core/page/Page.h"
65 #include "wtf/text/StringBuilder.h"
69 using namespace HTMLNames
;
71 HTMLDocument::HTMLDocument(const DocumentInit
& initializer
, DocumentClassFlags extendedDocumentClasses
)
72 : Document(initializer
, HTMLDocumentClass
| extendedDocumentClasses
)
75 if (isSrcdocDocument() || initializer
.importsController()) {
76 ASSERT(inNoQuirksMode());
77 lockCompatibilityMode();
81 HTMLDocument::~HTMLDocument()
85 HTMLBodyElement
* HTMLDocument::htmlBodyElement() const
87 HTMLElement
* body
= this->body();
88 return isHTMLBodyElement(body
) ? toHTMLBodyElement(body
) : 0;
91 const AtomicString
& HTMLDocument::bodyAttributeValue(const QualifiedName
& name
) const
93 if (HTMLBodyElement
* body
= htmlBodyElement())
94 return body
->fastGetAttribute(name
);
98 void HTMLDocument::setBodyAttribute(const QualifiedName
& name
, const AtomicString
& value
)
100 if (HTMLBodyElement
* body
= htmlBodyElement()) {
101 // FIXME: This check is apparently for benchmarks that set the same value repeatedly.
102 // It's not clear what benchmarks though, it's also not clear why we don't avoid
103 // causing a style recalc when setting the same value to a presentational attribute
104 // in the common case.
105 if (body
->fastGetAttribute(name
) != value
)
106 body
->setAttribute(name
, value
);
110 const AtomicString
& HTMLDocument::bgColor() const
112 return bodyAttributeValue(bgcolorAttr
);
115 void HTMLDocument::setBgColor(const AtomicString
& value
)
117 setBodyAttribute(bgcolorAttr
, value
);
120 const AtomicString
& HTMLDocument::fgColor() const
122 return bodyAttributeValue(textAttr
);
125 void HTMLDocument::setFgColor(const AtomicString
& value
)
127 setBodyAttribute(textAttr
, value
);
130 const AtomicString
& HTMLDocument::alinkColor() const
132 return bodyAttributeValue(alinkAttr
);
135 void HTMLDocument::setAlinkColor(const AtomicString
& value
)
137 setBodyAttribute(alinkAttr
, value
);
140 const AtomicString
& HTMLDocument::linkColor() const
142 return bodyAttributeValue(linkAttr
);
145 void HTMLDocument::setLinkColor(const AtomicString
& value
)
147 setBodyAttribute(linkAttr
, value
);
150 const AtomicString
& HTMLDocument::vlinkColor() const
152 return bodyAttributeValue(vlinkAttr
);
155 void HTMLDocument::setVlinkColor(const AtomicString
& value
)
157 setBodyAttribute(vlinkAttr
, value
);
160 PassRefPtrWillBeRawPtr
<Document
> HTMLDocument::cloneDocumentWithoutChildren()
162 return create(DocumentInit(url()).withRegistrationContext(registrationContext()));
165 // --------------------------------------------------------------------------
166 // not part of the DOM
167 // --------------------------------------------------------------------------
169 void HTMLDocument::addItemToMap(HashCountedSet
<AtomicString
>& map
, const AtomicString
& name
)
174 if (LocalFrame
* f
= frame())
175 f
->script().namedItemAdded(this, name
);
178 void HTMLDocument::removeItemFromMap(HashCountedSet
<AtomicString
>& map
, const AtomicString
& name
)
183 if (LocalFrame
* f
= frame())
184 f
->script().namedItemRemoved(this, name
);
187 void HTMLDocument::addNamedItem(const AtomicString
& name
)
189 addItemToMap(m_namedItemCounts
, name
);
192 void HTMLDocument::removeNamedItem(const AtomicString
& name
)
194 removeItemFromMap(m_namedItemCounts
, name
);
197 void HTMLDocument::addExtraNamedItem(const AtomicString
& name
)
199 addItemToMap(m_extraNamedItemCounts
, name
);
202 void HTMLDocument::removeExtraNamedItem(const AtomicString
& name
)
204 removeItemFromMap(m_extraNamedItemCounts
, name
);
207 static HashSet
<StringImpl
*>* createHtmlCaseInsensitiveAttributesSet()
209 // This is the list of attributes in HTML 4.01 with values marked as "[CI]" or case-insensitive
210 // Mozilla treats all other values as case-sensitive, thus so do we.
211 HashSet
<StringImpl
*>* attrSet
= new HashSet
<StringImpl
*>;
213 const QualifiedName
* caseInsesitiveAttributes
[] = {
214 &accept_charsetAttr
, &acceptAttr
, &alignAttr
, &alinkAttr
, &axisAttr
,
216 &charsetAttr
, &checkedAttr
, &clearAttr
, &codetypeAttr
, &colorAttr
, &compactAttr
,
217 &declareAttr
, &deferAttr
, &dirAttr
, &directionAttr
, &disabledAttr
,
219 &faceAttr
, &frameAttr
,
220 &hreflangAttr
, &http_equivAttr
,
221 &langAttr
, &languageAttr
, &linkAttr
,
222 &mediaAttr
, &methodAttr
, &multipleAttr
,
223 &nohrefAttr
, &noresizeAttr
, &noshadeAttr
, &nowrapAttr
,
224 &readonlyAttr
, &relAttr
, &revAttr
, &rulesAttr
,
225 &scopeAttr
, &scrollingAttr
, &selectedAttr
, &shapeAttr
,
226 &targetAttr
, &textAttr
, &typeAttr
,
227 &valignAttr
, &valuetypeAttr
, &vlinkAttr
};
229 attrSet
->reserveCapacityForSize(WTF_ARRAY_LENGTH(caseInsesitiveAttributes
));
230 for (const QualifiedName
* attr
: caseInsesitiveAttributes
)
231 attrSet
->add(attr
->localName().impl());
236 bool HTMLDocument::isCaseSensitiveAttribute(const QualifiedName
& attributeName
)
238 static HashSet
<StringImpl
*>* htmlCaseInsensitiveAttributesSet
= createHtmlCaseInsensitiveAttributesSet();
239 bool isPossibleHTMLAttr
= !attributeName
.hasPrefix() && (attributeName
.namespaceURI() == nullAtom
);
240 return !isPossibleHTMLAttr
|| !htmlCaseInsensitiveAttributesSet
->contains(attributeName
.localName().impl());