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