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/core/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 blink {
     68 
     69 using namespace HTMLNames;
     70 
     71 HTMLDocument::HTMLDocument(const DocumentInit& initializer, DocumentClassFlags extendedDocumentClasses)
     72     : Document(initializer, HTMLDocumentClass | extendedDocumentClasses)
     73 {
     74     clearXMLVersion();
     75     if (isSrcdocDocument() || initializer.importsController()) {
     76         ASSERT(inNoQuirksMode());
     77         lockCompatibilityMode();
     78     }
     79 }
     80 
     81 HTMLDocument::~HTMLDocument()
     82 {
     83 }
     84 
     85 HTMLBodyElement* HTMLDocument::htmlBodyElement() const
     86 {
     87     HTMLElement* body = this->body();
     88     return isHTMLBodyElement(body) ? toHTMLBodyElement(body) : 0;
     89 }
     90 
     91 const AtomicString& HTMLDocument::bodyAttributeValue(const QualifiedName& name) const
     92 {
     93     if (HTMLBodyElement* body = htmlBodyElement())
     94         return body->fastGetAttribute(name);
     95     return nullAtom;
     96 }
     97 
     98 void HTMLDocument::setBodyAttribute(const QualifiedName& name, const AtomicString& value)
     99 {
    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);
    107     }
    108 }
    109 
    110 const AtomicString& HTMLDocument::bgColor() const
    111 {
    112     return bodyAttributeValue(bgcolorAttr);
    113 }
    114 
    115 void HTMLDocument::setBgColor(const AtomicString& value)
    116 {
    117     setBodyAttribute(bgcolorAttr, value);
    118 }
    119 
    120 const AtomicString& HTMLDocument::fgColor() const
    121 {
    122     return bodyAttributeValue(textAttr);
    123 }
    124 
    125 void HTMLDocument::setFgColor(const AtomicString& value)
    126 {
    127     setBodyAttribute(textAttr, value);
    128 }
    129 
    130 const AtomicString& HTMLDocument::alinkColor() const
    131 {
    132     return bodyAttributeValue(alinkAttr);
    133 }
    134 
    135 void HTMLDocument::setAlinkColor(const AtomicString& value)
    136 {
    137     setBodyAttribute(alinkAttr, value);
    138 }
    139 
    140 const AtomicString& HTMLDocument::linkColor() const
    141 {
    142     return bodyAttributeValue(linkAttr);
    143 }
    144 
    145 void HTMLDocument::setLinkColor(const AtomicString& value)
    146 {
    147     setBodyAttribute(linkAttr, value);
    148 }
    149 
    150 const AtomicString& HTMLDocument::vlinkColor() const
    151 {
    152     return bodyAttributeValue(vlinkAttr);
    153 }
    154 
    155 void HTMLDocument::setVlinkColor(const AtomicString& value)
    156 {
    157     setBodyAttribute(vlinkAttr, value);
    158 }
    159 
    160 PassRefPtrWillBeRawPtr<Document> HTMLDocument::cloneDocumentWithoutChildren()
    161 {
    162     return create(DocumentInit(url()).withRegistrationContext(registrationContext()));
    163 }
    164 
    165 // --------------------------------------------------------------------------
    166 // not part of the DOM
    167 // --------------------------------------------------------------------------
    168 
    169 void HTMLDocument::addItemToMap(HashCountedSet<AtomicString>& map, const AtomicString& name)
    170 {
    171     if (name.isEmpty())
    172         return;
    173     map.add(name);
    174     if (LocalFrame* f = frame())
    175         f->script().namedItemAdded(this, name);
    176 }
    177 
    178 void HTMLDocument::removeItemFromMap(HashCountedSet<AtomicString>& map, const AtomicString& name)
    179 {
    180     if (name.isEmpty())
    181         return;
    182     map.remove(name);
    183     if (LocalFrame* f = frame())
    184         f->script().namedItemRemoved(this, name);
    185 }
    186 
    187 void HTMLDocument::addNamedItem(const AtomicString& name)
    188 {
    189     addItemToMap(m_namedItemCounts, name);
    190 }
    191 
    192 void HTMLDocument::removeNamedItem(const AtomicString& name)
    193 {
    194     removeItemFromMap(m_namedItemCounts, name);
    195 }
    196 
    197 void HTMLDocument::addExtraNamedItem(const AtomicString& name)
    198 {
    199     addItemToMap(m_extraNamedItemCounts, name);
    200 }
    201 
    202 void HTMLDocument::removeExtraNamedItem(const AtomicString& name)
    203 {
    204     removeItemFromMap(m_extraNamedItemCounts, name);
    205 }
    206 
    207 static void addLocalNameToSet(HashSet<StringImpl*>* set, const QualifiedName& qName)
    208 {
    209     set->add(qName.localName().impl());
    210 }
    211 
    212 static HashSet<StringImpl*>* createHtmlCaseInsensitiveAttributesSet()
    213 {
    214     // This is the list of attributes in HTML 4.01 with values marked as "[CI]" or case-insensitive
    215     // Mozilla treats all other values as case-sensitive, thus so do we.
    216     HashSet<StringImpl*>* attrSet = new HashSet<StringImpl*>;
    217 
    218     addLocalNameToSet(attrSet, accept_charsetAttr);
    219     addLocalNameToSet(attrSet, acceptAttr);
    220     addLocalNameToSet(attrSet, alignAttr);
    221     addLocalNameToSet(attrSet, alinkAttr);
    222     addLocalNameToSet(attrSet, axisAttr);
    223     addLocalNameToSet(attrSet, bgcolorAttr);
    224     addLocalNameToSet(attrSet, charsetAttr);
    225     addLocalNameToSet(attrSet, checkedAttr);
    226     addLocalNameToSet(attrSet, clearAttr);
    227     addLocalNameToSet(attrSet, codetypeAttr);
    228     addLocalNameToSet(attrSet, colorAttr);
    229     addLocalNameToSet(attrSet, compactAttr);
    230     addLocalNameToSet(attrSet, declareAttr);
    231     addLocalNameToSet(attrSet, deferAttr);
    232     addLocalNameToSet(attrSet, dirAttr);
    233     addLocalNameToSet(attrSet, disabledAttr);
    234     addLocalNameToSet(attrSet, enctypeAttr);
    235     addLocalNameToSet(attrSet, faceAttr);
    236     addLocalNameToSet(attrSet, frameAttr);
    237     addLocalNameToSet(attrSet, hreflangAttr);
    238     addLocalNameToSet(attrSet, http_equivAttr);
    239     addLocalNameToSet(attrSet, langAttr);
    240     addLocalNameToSet(attrSet, languageAttr);
    241     addLocalNameToSet(attrSet, linkAttr);
    242     addLocalNameToSet(attrSet, mediaAttr);
    243     addLocalNameToSet(attrSet, methodAttr);
    244     addLocalNameToSet(attrSet, multipleAttr);
    245     addLocalNameToSet(attrSet, nohrefAttr);
    246     addLocalNameToSet(attrSet, noresizeAttr);
    247     addLocalNameToSet(attrSet, noshadeAttr);
    248     addLocalNameToSet(attrSet, nowrapAttr);
    249     addLocalNameToSet(attrSet, readonlyAttr);
    250     addLocalNameToSet(attrSet, relAttr);
    251     addLocalNameToSet(attrSet, revAttr);
    252     addLocalNameToSet(attrSet, rulesAttr);
    253     addLocalNameToSet(attrSet, scopeAttr);
    254     addLocalNameToSet(attrSet, scrollingAttr);
    255     addLocalNameToSet(attrSet, selectedAttr);
    256     addLocalNameToSet(attrSet, shapeAttr);
    257     addLocalNameToSet(attrSet, targetAttr);
    258     addLocalNameToSet(attrSet, textAttr);
    259     addLocalNameToSet(attrSet, typeAttr);
    260     addLocalNameToSet(attrSet, valignAttr);
    261     addLocalNameToSet(attrSet, valuetypeAttr);
    262     addLocalNameToSet(attrSet, vlinkAttr);
    263 
    264     return attrSet;
    265 }
    266 
    267 bool HTMLDocument::isCaseSensitiveAttribute(const QualifiedName& attributeName)
    268 {
    269     static HashSet<StringImpl*>* htmlCaseInsensitiveAttributesSet = createHtmlCaseInsensitiveAttributesSet();
    270     bool isPossibleHTMLAttr = !attributeName.hasPrefix() && (attributeName.namespaceURI() == nullAtom);
    271     return !isPossibleHTMLAttr || !htmlCaseInsensitiveAttributesSet->contains(attributeName.localName().impl());
    272 }
    273 
    274 void HTMLDocument::write(LocalDOMWindow* callingWindow, const Vector<String>& text, ExceptionState& exceptionState)
    275 {
    276     ASSERT(callingWindow);
    277     StringBuilder builder;
    278     for (size_t i = 0; i < text.size(); ++i)
    279         builder.append(text[i]);
    280     write(builder.toString(), callingWindow->document(), exceptionState);
    281 }
    282 
    283 void HTMLDocument::writeln(LocalDOMWindow* callingWindow, const Vector<String>& text, ExceptionState& exceptionState)
    284 {
    285     ASSERT(callingWindow);
    286     StringBuilder builder;
    287     for (size_t i = 0; i < text.size(); ++i)
    288         builder.append(text[i]);
    289     writeln(builder.toString(), callingWindow->document(), exceptionState);
    290 }
    291 
    292 }
    293