• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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.
5  *
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.
10  *
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.
15  *
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.
20  *
21  * Portions are Copyright (C) 2002 Netscape Communications Corporation.
22  * Other contributors: David Baron <dbaron@fas.harvard.edu>
23  *
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.
28  *
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.
33  *
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
37  *
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.
51  */
52 
53 #include "config.h"
54 #include "core/html/HTMLDocument.h"
55 
56 #include "bindings/v8/ScriptController.h"
57 #include "core/HTMLNames.h"
58 #include "core/frame/LocalDOMWindow.h"
59 #include "core/frame/FrameView.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"
66 
67 namespace WebCore {
68 
69 using namespace HTMLNames;
70 
HTMLDocument(const DocumentInit & initializer,DocumentClassFlags extendedDocumentClasses)71 HTMLDocument::HTMLDocument(const DocumentInit& initializer, DocumentClassFlags extendedDocumentClasses)
72     : Document(initializer, HTMLDocumentClass | extendedDocumentClasses)
73 {
74     ScriptWrappable::init(this);
75     clearXMLVersion();
76     if (isSrcdocDocument() || initializer.importsController()) {
77         ASSERT(inNoQuirksMode());
78         lockCompatibilityMode();
79     }
80 }
81 
~HTMLDocument()82 HTMLDocument::~HTMLDocument()
83 {
84 }
85 
htmlBodyElement() const86 HTMLBodyElement* HTMLDocument::htmlBodyElement() const
87 {
88     HTMLElement* body = this->body();
89     return isHTMLBodyElement(body) ? toHTMLBodyElement(body) : 0;
90 }
91 
bodyAttributeValue(const QualifiedName & name) const92 const AtomicString& HTMLDocument::bodyAttributeValue(const QualifiedName& name) const
93 {
94     if (HTMLBodyElement* body = htmlBodyElement())
95         return body->fastGetAttribute(name);
96     return nullAtom;
97 }
98 
setBodyAttribute(const QualifiedName & name,const AtomicString & value)99 void HTMLDocument::setBodyAttribute(const QualifiedName& name, const AtomicString& value)
100 {
101     if (HTMLBodyElement* body = htmlBodyElement()) {
102         // FIXME: This check is apparently for benchmarks that set the same value repeatedly.
103         // It's not clear what benchmarks though, it's also not clear why we don't avoid
104         // causing a style recalc when setting the same value to a presentational attribute
105         // in the common case.
106         if (body->fastGetAttribute(name) != value)
107             body->setAttribute(name, value);
108     }
109 }
110 
bgColor() const111 const AtomicString& HTMLDocument::bgColor() const
112 {
113     return bodyAttributeValue(bgcolorAttr);
114 }
115 
setBgColor(const AtomicString & value)116 void HTMLDocument::setBgColor(const AtomicString& value)
117 {
118     setBodyAttribute(bgcolorAttr, value);
119 }
120 
fgColor() const121 const AtomicString& HTMLDocument::fgColor() const
122 {
123     return bodyAttributeValue(textAttr);
124 }
125 
setFgColor(const AtomicString & value)126 void HTMLDocument::setFgColor(const AtomicString& value)
127 {
128     setBodyAttribute(textAttr, value);
129 }
130 
alinkColor() const131 const AtomicString& HTMLDocument::alinkColor() const
132 {
133     return bodyAttributeValue(alinkAttr);
134 }
135 
setAlinkColor(const AtomicString & value)136 void HTMLDocument::setAlinkColor(const AtomicString& value)
137 {
138     setBodyAttribute(alinkAttr, value);
139 }
140 
linkColor() const141 const AtomicString& HTMLDocument::linkColor() const
142 {
143     return bodyAttributeValue(linkAttr);
144 }
145 
setLinkColor(const AtomicString & value)146 void HTMLDocument::setLinkColor(const AtomicString& value)
147 {
148     setBodyAttribute(linkAttr, value);
149 }
150 
vlinkColor() const151 const AtomicString& HTMLDocument::vlinkColor() const
152 {
153     return bodyAttributeValue(vlinkAttr);
154 }
155 
setVlinkColor(const AtomicString & value)156 void HTMLDocument::setVlinkColor(const AtomicString& value)
157 {
158     setBodyAttribute(vlinkAttr, value);
159 }
160 
cloneDocumentWithoutChildren()161 PassRefPtrWillBeRawPtr<Document> HTMLDocument::cloneDocumentWithoutChildren()
162 {
163     return create(DocumentInit(url()).withRegistrationContext(registrationContext()));
164 }
165 
166 // --------------------------------------------------------------------------
167 // not part of the DOM
168 // --------------------------------------------------------------------------
169 
addItemToMap(HashCountedSet<AtomicString> & map,const AtomicString & name)170 void HTMLDocument::addItemToMap(HashCountedSet<AtomicString>& map, const AtomicString& name)
171 {
172     if (name.isEmpty())
173         return;
174     map.add(name);
175     if (LocalFrame* f = frame())
176         f->script().namedItemAdded(this, name);
177 }
178 
removeItemFromMap(HashCountedSet<AtomicString> & map,const AtomicString & name)179 void HTMLDocument::removeItemFromMap(HashCountedSet<AtomicString>& map, const AtomicString& name)
180 {
181     if (name.isEmpty())
182         return;
183     map.remove(name);
184     if (LocalFrame* f = frame())
185         f->script().namedItemRemoved(this, name);
186 }
187 
addNamedItem(const AtomicString & name)188 void HTMLDocument::addNamedItem(const AtomicString& name)
189 {
190     addItemToMap(m_namedItemCounts, name);
191 }
192 
removeNamedItem(const AtomicString & name)193 void HTMLDocument::removeNamedItem(const AtomicString& name)
194 {
195     removeItemFromMap(m_namedItemCounts, name);
196 }
197 
addExtraNamedItem(const AtomicString & name)198 void HTMLDocument::addExtraNamedItem(const AtomicString& name)
199 {
200     addItemToMap(m_extraNamedItemCounts, name);
201 }
202 
removeExtraNamedItem(const AtomicString & name)203 void HTMLDocument::removeExtraNamedItem(const AtomicString& name)
204 {
205     removeItemFromMap(m_extraNamedItemCounts, name);
206 }
207 
addLocalNameToSet(HashSet<StringImpl * > * set,const QualifiedName & qName)208 static void addLocalNameToSet(HashSet<StringImpl*>* set, const QualifiedName& qName)
209 {
210     set->add(qName.localName().impl());
211 }
212 
createHtmlCaseInsensitiveAttributesSet()213 static HashSet<StringImpl*>* createHtmlCaseInsensitiveAttributesSet()
214 {
215     // This is the list of attributes in HTML 4.01 with values marked as "[CI]" or case-insensitive
216     // Mozilla treats all other values as case-sensitive, thus so do we.
217     HashSet<StringImpl*>* attrSet = new HashSet<StringImpl*>;
218 
219     addLocalNameToSet(attrSet, accept_charsetAttr);
220     addLocalNameToSet(attrSet, acceptAttr);
221     addLocalNameToSet(attrSet, alignAttr);
222     addLocalNameToSet(attrSet, alinkAttr);
223     addLocalNameToSet(attrSet, axisAttr);
224     addLocalNameToSet(attrSet, bgcolorAttr);
225     addLocalNameToSet(attrSet, charsetAttr);
226     addLocalNameToSet(attrSet, checkedAttr);
227     addLocalNameToSet(attrSet, clearAttr);
228     addLocalNameToSet(attrSet, codetypeAttr);
229     addLocalNameToSet(attrSet, colorAttr);
230     addLocalNameToSet(attrSet, compactAttr);
231     addLocalNameToSet(attrSet, declareAttr);
232     addLocalNameToSet(attrSet, deferAttr);
233     addLocalNameToSet(attrSet, dirAttr);
234     addLocalNameToSet(attrSet, disabledAttr);
235     addLocalNameToSet(attrSet, enctypeAttr);
236     addLocalNameToSet(attrSet, faceAttr);
237     addLocalNameToSet(attrSet, frameAttr);
238     addLocalNameToSet(attrSet, hreflangAttr);
239     addLocalNameToSet(attrSet, http_equivAttr);
240     addLocalNameToSet(attrSet, langAttr);
241     addLocalNameToSet(attrSet, languageAttr);
242     addLocalNameToSet(attrSet, linkAttr);
243     addLocalNameToSet(attrSet, mediaAttr);
244     addLocalNameToSet(attrSet, methodAttr);
245     addLocalNameToSet(attrSet, multipleAttr);
246     addLocalNameToSet(attrSet, nohrefAttr);
247     addLocalNameToSet(attrSet, noresizeAttr);
248     addLocalNameToSet(attrSet, noshadeAttr);
249     addLocalNameToSet(attrSet, nowrapAttr);
250     addLocalNameToSet(attrSet, readonlyAttr);
251     addLocalNameToSet(attrSet, relAttr);
252     addLocalNameToSet(attrSet, revAttr);
253     addLocalNameToSet(attrSet, rulesAttr);
254     addLocalNameToSet(attrSet, scopeAttr);
255     addLocalNameToSet(attrSet, scrollingAttr);
256     addLocalNameToSet(attrSet, selectedAttr);
257     addLocalNameToSet(attrSet, shapeAttr);
258     addLocalNameToSet(attrSet, targetAttr);
259     addLocalNameToSet(attrSet, textAttr);
260     addLocalNameToSet(attrSet, typeAttr);
261     addLocalNameToSet(attrSet, valignAttr);
262     addLocalNameToSet(attrSet, valuetypeAttr);
263     addLocalNameToSet(attrSet, vlinkAttr);
264 
265     return attrSet;
266 }
267 
isCaseSensitiveAttribute(const QualifiedName & attributeName)268 bool HTMLDocument::isCaseSensitiveAttribute(const QualifiedName& attributeName)
269 {
270     static HashSet<StringImpl*>* htmlCaseInsensitiveAttributesSet = createHtmlCaseInsensitiveAttributesSet();
271     bool isPossibleHTMLAttr = !attributeName.hasPrefix() && (attributeName.namespaceURI() == nullAtom);
272     return !isPossibleHTMLAttr || !htmlCaseInsensitiveAttributesSet->contains(attributeName.localName().impl());
273 }
274 
write(LocalDOMWindow * callingWindow,const Vector<String> & text,ExceptionState & exceptionState)275 void HTMLDocument::write(LocalDOMWindow* callingWindow, const Vector<String>& text, ExceptionState& exceptionState)
276 {
277     ASSERT(callingWindow);
278     StringBuilder builder;
279     for (size_t i = 0; i < text.size(); ++i)
280         builder.append(text[i]);
281     write(builder.toString(), callingWindow->document(), exceptionState);
282 }
283 
writeln(LocalDOMWindow * callingWindow,const Vector<String> & text,ExceptionState & exceptionState)284 void HTMLDocument::writeln(LocalDOMWindow* callingWindow, const Vector<String>& text, ExceptionState& exceptionState)
285 {
286     ASSERT(callingWindow);
287     StringBuilder builder;
288     for (size_t i = 0; i < text.size(); ++i)
289         builder.append(text[i]);
290     writeln(builder.toString(), callingWindow->document(), exceptionState);
291 }
292 
293 }
294