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 "HTMLNames.h"
     57 #include "bindings/v8/ScriptController.h"
     58 #include "core/html/HTMLBodyElement.h"
     59 #include "core/page/FocusController.h"
     60 #include "core/page/Frame.h"
     61 #include "core/page/FrameTree.h"
     62 #include "core/page/FrameView.h"
     63 #include "core/page/Page.h"
     64 
     65 namespace WebCore {
     66 
     67 using namespace HTMLNames;
     68 
     69 HTMLDocument::HTMLDocument(const DocumentInit& initializer, DocumentClassFlags extendedDocumentClasses)
     70     : Document(initializer, HTMLDocumentClass | extendedDocumentClasses)
     71 {
     72     ScriptWrappable::init(this);
     73     clearXMLVersion();
     74 }
     75 
     76 HTMLDocument::~HTMLDocument()
     77 {
     78 }
     79 
     80 int HTMLDocument::width()
     81 {
     82     updateLayoutIgnorePendingStylesheets();
     83     FrameView* frameView = view();
     84     return frameView ? frameView->contentsWidth() : 0;
     85 }
     86 
     87 int HTMLDocument::height()
     88 {
     89     updateLayoutIgnorePendingStylesheets();
     90     FrameView* frameView = view();
     91     return frameView ? frameView->contentsHeight() : 0;
     92 }
     93 
     94 String HTMLDocument::dir()
     95 {
     96     HTMLElement* b = body();
     97     if (!b)
     98         return String();
     99     return b->getAttribute(dirAttr);
    100 }
    101 
    102 void HTMLDocument::setDir(const String& value)
    103 {
    104     HTMLElement* b = body();
    105     if (b)
    106         b->setAttribute(dirAttr, value);
    107 }
    108 
    109 String HTMLDocument::designMode() const
    110 {
    111     return inDesignMode() ? "on" : "off";
    112 }
    113 
    114 void HTMLDocument::setDesignMode(const String& value)
    115 {
    116     InheritedBool mode;
    117     if (equalIgnoringCase(value, "on"))
    118         mode = on;
    119     else if (equalIgnoringCase(value, "off"))
    120         mode = off;
    121     else
    122         mode = inherit;
    123     Document::setDesignMode(mode);
    124 }
    125 
    126 Element* HTMLDocument::activeElement()
    127 {
    128     if (Element* element = treeScope()->adjustedFocusedElement())
    129         return element;
    130     return body();
    131 }
    132 
    133 bool HTMLDocument::hasFocus()
    134 {
    135     Page* page = this->page();
    136     if (!page)
    137         return false;
    138     if (!page->focusController().isActive() || !page->focusController().isFocused())
    139         return false;
    140     if (Frame* focusedFrame = page->focusController().focusedFrame()) {
    141         if (focusedFrame->tree()->isDescendantOf(frame()))
    142             return true;
    143     }
    144     return false;
    145 }
    146 
    147 inline HTMLBodyElement* HTMLDocument::bodyAsHTMLBodyElement() const
    148 {
    149     HTMLElement* element = body();
    150     return (element && element->hasTagName(bodyTag)) ? toHTMLBodyElement(element) : 0;
    151 }
    152 
    153 String HTMLDocument::bgColor()
    154 {
    155     if (HTMLBodyElement* bodyElement = bodyAsHTMLBodyElement())
    156         return bodyElement->bgColor();
    157     return String();
    158 }
    159 
    160 void HTMLDocument::setBgColor(const String& value)
    161 {
    162     if (HTMLBodyElement* bodyElement = bodyAsHTMLBodyElement())
    163         bodyElement->setBgColor(value);
    164 }
    165 
    166 String HTMLDocument::fgColor()
    167 {
    168     if (HTMLBodyElement* bodyElement = bodyAsHTMLBodyElement())
    169         return bodyElement->text();
    170     return String();
    171 }
    172 
    173 void HTMLDocument::setFgColor(const String& value)
    174 {
    175     if (HTMLBodyElement* bodyElement = bodyAsHTMLBodyElement())
    176         bodyElement->setText(value);
    177 }
    178 
    179 String HTMLDocument::alinkColor()
    180 {
    181     if (HTMLBodyElement* bodyElement = bodyAsHTMLBodyElement())
    182         return bodyElement->aLink();
    183     return String();
    184 }
    185 
    186 void HTMLDocument::setAlinkColor(const String& value)
    187 {
    188     if (HTMLBodyElement* bodyElement = bodyAsHTMLBodyElement()) {
    189         // This check is a bit silly, but some benchmarks like to set the
    190         // document's link colors over and over to the same value and we
    191         // don't want to incur a style update each time.
    192         if (bodyElement->aLink() != value)
    193             bodyElement->setALink(value);
    194     }
    195 }
    196 
    197 String HTMLDocument::linkColor()
    198 {
    199     if (HTMLBodyElement* bodyElement = bodyAsHTMLBodyElement())
    200         return bodyElement->link();
    201     return String();
    202 }
    203 
    204 void HTMLDocument::setLinkColor(const String& value)
    205 {
    206     if (HTMLBodyElement* bodyElement = bodyAsHTMLBodyElement()) {
    207         // This check is a bit silly, but some benchmarks like to set the
    208         // document's link colors over and over to the same value and we
    209         // don't want to incur a style update each time.
    210         if (bodyElement->link() != value)
    211             bodyElement->setLink(value);
    212     }
    213 }
    214 
    215 String HTMLDocument::vlinkColor()
    216 {
    217     if (HTMLBodyElement* bodyElement = bodyAsHTMLBodyElement())
    218         return bodyElement->vLink();
    219     return String();
    220 }
    221 
    222 void HTMLDocument::setVlinkColor(const String& value)
    223 {
    224     if (HTMLBodyElement* bodyElement = bodyAsHTMLBodyElement()) {
    225         // This check is a bit silly, but some benchmarks like to set the
    226         // document's link colors over and over to the same value and we
    227         // don't want to incur a style update each time.
    228         if (bodyElement->vLink() != value)
    229             bodyElement->setVLink(value);
    230     }
    231 }
    232 
    233 // --------------------------------------------------------------------------
    234 // not part of the DOM
    235 // --------------------------------------------------------------------------
    236 
    237 void HTMLDocument::addItemToMap(HashCountedSet<StringImpl*>& map, const AtomicString& name)
    238 {
    239     if (name.isEmpty())
    240         return;
    241     map.add(name.impl());
    242     if (Frame* f = frame())
    243         f->script()->namedItemAdded(this, name);
    244 }
    245 
    246 void HTMLDocument::removeItemFromMap(HashCountedSet<StringImpl*>& map, const AtomicString& name)
    247 {
    248     if (name.isEmpty())
    249         return;
    250     map.remove(name.impl());
    251     if (Frame* f = frame())
    252         f->script()->namedItemRemoved(this, name);
    253 }
    254 
    255 void HTMLDocument::addNamedItem(const AtomicString& name)
    256 {
    257     addItemToMap(m_namedItemCounts, name);
    258 }
    259 
    260 void HTMLDocument::removeNamedItem(const AtomicString& name)
    261 {
    262     removeItemFromMap(m_namedItemCounts, name);
    263 }
    264 
    265 void HTMLDocument::addExtraNamedItem(const AtomicString& name)
    266 {
    267     addItemToMap(m_extraNamedItemCounts, name);
    268 }
    269 
    270 void HTMLDocument::removeExtraNamedItem(const AtomicString& name)
    271 {
    272     removeItemFromMap(m_extraNamedItemCounts, name);
    273 }
    274 
    275 static void addLocalNameToSet(HashSet<StringImpl*>* set, const QualifiedName& qName)
    276 {
    277     set->add(qName.localName().impl());
    278 }
    279 
    280 static HashSet<StringImpl*>* createHtmlCaseInsensitiveAttributesSet()
    281 {
    282     // This is the list of attributes in HTML 4.01 with values marked as "[CI]" or case-insensitive
    283     // Mozilla treats all other values as case-sensitive, thus so do we.
    284     HashSet<StringImpl*>* attrSet = new HashSet<StringImpl*>;
    285 
    286     addLocalNameToSet(attrSet, accept_charsetAttr);
    287     addLocalNameToSet(attrSet, acceptAttr);
    288     addLocalNameToSet(attrSet, alignAttr);
    289     addLocalNameToSet(attrSet, alinkAttr);
    290     addLocalNameToSet(attrSet, axisAttr);
    291     addLocalNameToSet(attrSet, bgcolorAttr);
    292     addLocalNameToSet(attrSet, charsetAttr);
    293     addLocalNameToSet(attrSet, checkedAttr);
    294     addLocalNameToSet(attrSet, clearAttr);
    295     addLocalNameToSet(attrSet, codetypeAttr);
    296     addLocalNameToSet(attrSet, colorAttr);
    297     addLocalNameToSet(attrSet, compactAttr);
    298     addLocalNameToSet(attrSet, declareAttr);
    299     addLocalNameToSet(attrSet, deferAttr);
    300     addLocalNameToSet(attrSet, dirAttr);
    301     addLocalNameToSet(attrSet, disabledAttr);
    302     addLocalNameToSet(attrSet, enctypeAttr);
    303     addLocalNameToSet(attrSet, faceAttr);
    304     addLocalNameToSet(attrSet, frameAttr);
    305     addLocalNameToSet(attrSet, hreflangAttr);
    306     addLocalNameToSet(attrSet, http_equivAttr);
    307     addLocalNameToSet(attrSet, langAttr);
    308     addLocalNameToSet(attrSet, languageAttr);
    309     addLocalNameToSet(attrSet, linkAttr);
    310     addLocalNameToSet(attrSet, mediaAttr);
    311     addLocalNameToSet(attrSet, methodAttr);
    312     addLocalNameToSet(attrSet, multipleAttr);
    313     addLocalNameToSet(attrSet, nohrefAttr);
    314     addLocalNameToSet(attrSet, noresizeAttr);
    315     addLocalNameToSet(attrSet, noshadeAttr);
    316     addLocalNameToSet(attrSet, nowrapAttr);
    317     addLocalNameToSet(attrSet, readonlyAttr);
    318     addLocalNameToSet(attrSet, relAttr);
    319     addLocalNameToSet(attrSet, revAttr);
    320     addLocalNameToSet(attrSet, rulesAttr);
    321     addLocalNameToSet(attrSet, scopeAttr);
    322     addLocalNameToSet(attrSet, scrollingAttr);
    323     addLocalNameToSet(attrSet, selectedAttr);
    324     addLocalNameToSet(attrSet, shapeAttr);
    325     addLocalNameToSet(attrSet, targetAttr);
    326     addLocalNameToSet(attrSet, textAttr);
    327     addLocalNameToSet(attrSet, typeAttr);
    328     addLocalNameToSet(attrSet, valignAttr);
    329     addLocalNameToSet(attrSet, valuetypeAttr);
    330     addLocalNameToSet(attrSet, vlinkAttr);
    331 
    332     return attrSet;
    333 }
    334 
    335 bool HTMLDocument::isCaseSensitiveAttribute(const QualifiedName& attributeName)
    336 {
    337     static HashSet<StringImpl*>* htmlCaseInsensitiveAttributesSet = createHtmlCaseInsensitiveAttributesSet();
    338     bool isPossibleHTMLAttr = !attributeName.hasPrefix() && (attributeName.namespaceURI() == nullAtom);
    339     return !isPossibleHTMLAttr || !htmlCaseInsensitiveAttributesSet->contains(attributeName.localName().impl());
    340 }
    341 
    342 void HTMLDocument::clear()
    343 {
    344     // FIXME: This does nothing, and that seems unlikely to be correct.
    345     // We've long had a comment saying that IE doesn't support this.
    346     // But I do see it in the documentation for Mozilla.
    347 }
    348 
    349 }
    350