Home | History | Annotate | Download | only in html
      1 /*
      2  * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org)
      3  *           (C) 1999 Antti Koivisto (koivisto (at) 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 (at) 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 
     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 
     82 HTMLDocument::~HTMLDocument()
     83 {
     84 }
     85 
     86 HTMLBodyElement* HTMLDocument::htmlBodyElement() const
     87 {
     88     HTMLElement* body = this->body();
     89     return isHTMLBodyElement(body) ? toHTMLBodyElement(body) : 0;
     90 }
     91 
     92 const AtomicString& HTMLDocument::bodyAttributeValue(const QualifiedName& name) const
     93 {
     94     if (HTMLBodyElement* body = htmlBodyElement())
     95         return body->fastGetAttribute(name);
     96     return nullAtom;
     97 }
     98 
     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 
    111 const AtomicString& HTMLDocument::bgColor() const
    112 {
    113     return bodyAttributeValue(bgcolorAttr);
    114 }
    115 
    116 void HTMLDocument::setBgColor(const AtomicString& value)
    117 {
    118     setBodyAttribute(bgcolorAttr, value);
    119 }
    120 
    121 const AtomicString& HTMLDocument::fgColor() const
    122 {
    123     return bodyAttributeValue(textAttr);
    124 }
    125 
    126 void HTMLDocument::setFgColor(const AtomicString& value)
    127 {
    128     setBodyAttribute(textAttr, value);
    129 }
    130 
    131 const AtomicString& HTMLDocument::alinkColor() const
    132 {
    133     return bodyAttributeValue(alinkAttr);
    134 }
    135 
    136 void HTMLDocument::setAlinkColor(const AtomicString& value)
    137 {
    138     setBodyAttribute(alinkAttr, value);
    139 }
    140 
    141 const AtomicString& HTMLDocument::linkColor() const
    142 {
    143     return bodyAttributeValue(linkAttr);
    144 }
    145 
    146 void HTMLDocument::setLinkColor(const AtomicString& value)
    147 {
    148     setBodyAttribute(linkAttr, value);
    149 }
    150 
    151 const AtomicString& HTMLDocument::vlinkColor() const
    152 {
    153     return bodyAttributeValue(vlinkAttr);
    154 }
    155 
    156 void HTMLDocument::setVlinkColor(const AtomicString& value)
    157 {
    158     setBodyAttribute(vlinkAttr, value);
    159 }
    160 
    161 PassRefPtrWillBeRawPtr<Document> HTMLDocument::cloneDocumentWithoutChildren()
    162 {
    163     return create(DocumentInit(url()).withRegistrationContext(registrationContext()));
    164 }
    165 
    166 // --------------------------------------------------------------------------
    167 // not part of the DOM
    168 // --------------------------------------------------------------------------
    169 
    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 
    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 
    188 void HTMLDocument::addNamedItem(const AtomicString& name)
    189 {
    190     addItemToMap(m_namedItemCounts, name);
    191 }
    192 
    193 void HTMLDocument::removeNamedItem(const AtomicString& name)
    194 {
    195     removeItemFromMap(m_namedItemCounts, name);
    196 }
    197 
    198 void HTMLDocument::addExtraNamedItem(const AtomicString& name)
    199 {
    200     addItemToMap(m_extraNamedItemCounts, name);
    201 }
    202 
    203 void HTMLDocument::removeExtraNamedItem(const AtomicString& name)
    204 {
    205     removeItemFromMap(m_extraNamedItemCounts, name);
    206 }
    207 
    208 static void addLocalNameToSet(HashSet<StringImpl*>* set, const QualifiedName& qName)
    209 {
    210     set->add(qName.localName().impl());
    211 }
    212 
    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 
    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 
    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 
    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