Document.cpp 141 KB
Newer Older
1
/*
kocienda's avatar
kocienda committed
2 3
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4
 *           (C) 2001 Dirk Mueller (mueller@kde.org)
ap's avatar
ap committed
5
 *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
6
 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
7
 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
levin@chromium.org's avatar
levin@chromium.org committed
8
 * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
kocienda's avatar
kocienda committed
9 10 11 12 13 14 15 16 17 18 19 20 21
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
ddkilzer's avatar
ddkilzer committed
22 23
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
kocienda's avatar
kocienda committed
24 25
 */

mjs's avatar
mjs committed
26
#include "config.h"
darin's avatar
darin committed
27
#include "Document.h"
darin's avatar
darin committed
28

29
#include "AXObjectCache.h"
weinig@apple.com's avatar
weinig@apple.com committed
30
#include "AnimationController.h"
darin@apple.com's avatar
darin@apple.com committed
31
#include "Attr.h"
darin's avatar
darin committed
32
#include "CDATASection.h"
weinig's avatar
weinig committed
33 34
#include "CSSHelper.h"
#include "CSSStyleSelector.h"
35
#include "CSSStyleSheet.h"
darin's avatar
darin committed
36
#include "CSSValueKeywords.h"
weinig@apple.com's avatar
weinig@apple.com committed
37
#include "CString.h"
weinig@apple.com's avatar
weinig@apple.com committed
38
#include "CachedCSSStyleSheet.h"
darin's avatar
darin committed
39
#include "Comment.h"
ap@webkit.org's avatar
ap@webkit.org committed
40
#include "Console.h"
oliver's avatar
oliver committed
41
#include "CookieJar.h"
darin's avatar
darin committed
42
#include "DOMImplementation.h"
weinig@apple.com's avatar
weinig@apple.com committed
43
#include "DOMWindow.h"
darin's avatar
darin committed
44
#include "DocLoader.h"
darin's avatar
darin committed
45
#include "DocumentFragment.h"
darin's avatar
darin committed
46
#include "DocumentLoader.h"
darin's avatar
darin committed
47 48
#include "DocumentType.h"
#include "EditingText.h"
andersca's avatar
andersca committed
49
#include "Editor.h"
50
#include "EntityReference.h"
weinig's avatar
 
weinig committed
51
#include "Event.h"
darin's avatar
darin committed
52
#include "EventHandler.h"
darin's avatar
darin committed
53
#include "EventListener.h"
darin's avatar
darin committed
54
#include "EventNames.h"
darin's avatar
darin committed
55
#include "ExceptionCode.h"
56
#include "FocusController.h"
mjs's avatar
mjs committed
57
#include "Frame.h"
ggaren's avatar
ggaren committed
58
#include "FrameLoader.h"
mjs's avatar
mjs committed
59
#include "FrameTree.h"
darin's avatar
darin committed
60
#include "FrameView.h"
61
#include "HTMLAnchorElement.h"
62
#include "HTMLBodyElement.h"
63
#include "HTMLCanvasElement.h"
darin@apple.com's avatar
darin@apple.com committed
64
#include "HTMLCollection.h"
darin's avatar
darin committed
65 66
#include "HTMLDocument.h"
#include "HTMLElementFactory.h"
darin's avatar
darin committed
67
#include "HTMLFrameOwnerElement.h"
darin's avatar
darin committed
68
#include "HTMLHeadElement.h"
darin's avatar
darin committed
69
#include "HTMLInputElement.h"
70
#include "HTMLLinkElement.h"
71
#include "HTMLMapElement.h"
darin's avatar
darin committed
72
#include "HTMLNameCollection.h"
darin's avatar
darin committed
73
#include "HTMLNames.h"
74
#include "HTMLParser.h"
75
#include "HTMLStyleElement.h"
bdash's avatar
bdash committed
76
#include "HTMLTitleElement.h"
ap's avatar
ap committed
77
#include "HTTPParsers.h"
weinig@apple.com's avatar
weinig@apple.com committed
78
#include "HistoryItem.h"
weinig's avatar
weinig committed
79 80
#include "HitTestRequest.h"
#include "HitTestResult.h"
zimmermann@webkit.org's avatar
zimmermann@webkit.org committed
81
#include "ImageLoader.h"
82
#include "InspectorController.h"
weinig's avatar
 
weinig committed
83
#include "KeyboardEvent.h"
darin's avatar
darin committed
84
#include "Logging.h"
darin@apple.com's avatar
darin@apple.com committed
85
#include "MappedAttribute.h"
weinig@apple.com's avatar
weinig@apple.com committed
86
#include "MessageEvent.h"
weinig's avatar
 
weinig committed
87
#include "MouseEvent.h"
darin's avatar
darin committed
88
#include "MouseEventWithHitTestResults.h"
weinig's avatar
 
weinig committed
89
#include "MutationEvent.h"
darin's avatar
darin committed
90
#include "NameNodeList.h"
91 92
#include "NodeFilter.h"
#include "NodeIterator.h"
darin@apple.com's avatar
darin@apple.com committed
93
#include "NodeWithIndex.h"
darin's avatar
darin committed
94
#include "OverflowEvent.h"
95
#include "Page.h"
ap@apple.com's avatar
ap@apple.com committed
96
#include "PageTransitionEvent.h"
darin's avatar
darin committed
97
#include "PlatformKeyboardEvent.h"
98
#include "ProcessingInstruction.h"
antti's avatar
antti committed
99
#include "ProgressEvent.h"
weinig's avatar
 
weinig committed
100
#include "RegisteredEventListener.h"
darin's avatar
darin committed
101
#include "RenderArena.h"
102
#include "RenderTextControl.h"
103
#include "RenderView.h"
104
#include "RenderWidget.h"
105
#include "ScriptController.h"
mitz@apple.com's avatar
mitz@apple.com committed
106
#include "ScriptElement.h"
107
#include "ScriptEventListener.h"
weinig's avatar
weinig committed
108
#include "SecurityOrigin.h"
darin's avatar
darin committed
109
#include "SegmentedString.h"
darin's avatar
darin committed
110
#include "SelectionController.h"
ggaren's avatar
ggaren committed
111
#include "Settings.h"
kov@webkit.org's avatar
kov@webkit.org committed
112 113

#if ENABLE(SHARED_WORKERS)
114
#include "SharedWorkerRepository.h"
kov@webkit.org's avatar
kov@webkit.org committed
115 116
#endif

117
#include "StyleSheetList.h"
darin's avatar
darin committed
118
#include "TextEvent.h"
darin's avatar
darin committed
119
#include "TextIterator.h"
darin's avatar
darin committed
120
#include "TextResourceDecoder.h"
121
#include "Timer.h"
weinig@apple.com's avatar
weinig@apple.com committed
122
#include "TreeWalker.h"
weinig's avatar
 
weinig committed
123
#include "UIEvent.h"
124 125
#include "WebKitAnimationEvent.h"
#include "WebKitTransitionEvent.h"
darin's avatar
darin committed
126
#include "WheelEvent.h"
weinig's avatar
weinig committed
127
#include "XMLHttpRequest.h"
eric@webkit.org's avatar
eric@webkit.org committed
128
#include "XMLNames.h"
darin's avatar
darin committed
129
#include "XMLTokenizer.h"
ap@webkit.org's avatar
ap@webkit.org committed
130
#include <wtf/CurrentTime.h>
dsmith@webkit.org's avatar
dsmith@webkit.org committed
131
#include <wtf/HashFunctions.h>
132 133
#include <wtf/MainThread.h>
#include <wtf/PassRefPtr.h>
weinig@apple.com's avatar
weinig@apple.com committed
134
#include <wtf/StdLibExtras.h>
135

136
#if ENABLE(DATABASE)
137
#include "Database.h"
138 139 140
#include "DatabaseThread.h"
#endif

141 142 143 144
#if ENABLE(DOM_STORAGE)
#include "StorageEvent.h"
#endif

mjs's avatar
mjs committed
145
#if ENABLE(XPATH)
146 147 148 149
#include "XPathEvaluator.h"
#include "XPathExpression.h"
#include "XPathNSResolver.h"
#include "XPathResult.h"
150
#endif
kocienda's avatar
kocienda committed
151

mjs's avatar
mjs committed
152
#if ENABLE(XSLT)
darin's avatar
darin committed
153
#include "XSLTProcessor.h"
154 155
#endif

mjs's avatar
mjs committed
156
#if ENABLE(XBL)
157
#include "XBLBindingManager.h"
158 159
#endif

mjs's avatar
mjs committed
160
#if ENABLE(SVG)
161
#include "SVGDocumentExtensions.h"
eseidel's avatar
eseidel committed
162
#include "SVGElementFactory.h"
163
#include "SVGNames.h"
darin's avatar
darin committed
164 165
#include "SVGZoomEvent.h"
#include "SVGStyleElement.h"
eseidel's avatar
eseidel committed
166 167
#endif

168
#if ENABLE(WML)
169
#include "WMLDocument.h"
170 171 172 173 174
#include "WMLElement.h"
#include "WMLElementFactory.h"
#include "WMLNames.h"
#endif

175 176 177 178
#if ENABLE(XHTMLMP)
#include "HTMLNoScriptElement.h"
#endif

darin's avatar
darin committed
179
using namespace std;
darin's avatar
darin committed
180 181
using namespace WTF;
using namespace Unicode;
darin's avatar
darin committed
182

darin's avatar
darin committed
183 184
namespace WebCore {

185
using namespace HTMLNames;
kocienda's avatar
kocienda committed
186

187
// #define INSTRUMENT_LAYOUT_SCHEDULING 1
hyatt's avatar
hyatt committed
188

189 190 191
// This amount of time must have elapsed before we will even consider scheduling a layout without a delay.
// FIXME: For faster machines this value can really be lowered to 200.  250 is adequate, but a little high
// for dual G5s. :)
darin's avatar
darin committed
192
static const int cLayoutScheduleThreshold = 250;
193

adele's avatar
adele committed
194
// Use 1 to represent the document's default form.
darin's avatar
darin committed
195
static HTMLFormElement* const defaultForm = reinterpret_cast<HTMLFormElement*>(1);
adele's avatar
adele committed
196

eseidel's avatar
eseidel committed
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
// DOM Level 2 says (letters added):
//
// a) Name start characters must have one of the categories Ll, Lu, Lo, Lt, Nl.
// b) Name characters other than Name-start characters must have one of the categories Mc, Me, Mn, Lm, or Nd.
// c) Characters in the compatibility area (i.e. with character code greater than #xF900 and less than #xFFFE) are not allowed in XML names.
// d) Characters which have a font or compatibility decomposition (i.e. those with a "compatibility formatting tag" in field 5 of the database -- marked by field 5 beginning with a "<") are not allowed.
// e) The following characters are treated as name-start characters rather than name characters, because the property file classifies them as Alphabetic: [#x02BB-#x02C1], #x0559, #x06E5, #x06E6.
// f) Characters #x20DD-#x20E0 are excluded (in accordance with Unicode, section 5.14).
// g) Character #x00B7 is classified as an extender, because the property list so identifies it.
// h) Character #x0387 is added as a name character, because #x00B7 is its canonical equivalent.
// i) Characters ':' and '_' are allowed as name-start characters.
// j) Characters '-' and '.' are allowed as name characters.
//
// It also contains complete tables. If we decide it's better, we could include those instead of the following code.

static inline bool isValidNameStart(UChar32 c)
{
    // rule (e) above
    if ((c >= 0x02BB && c <= 0x02C1) || c == 0x559 || c == 0x6E5 || c == 0x6E6)
        return true;

    // rule (i) above
    if (c == ':' || c == '_')
        return true;

    // rules (a) and (f) above
darin's avatar
darin committed
223 224
    const uint32_t nameStartMask = Letter_Lowercase | Letter_Uppercase | Letter_Other | Letter_Titlecase | Number_Letter;
    if (!(Unicode::category(c) & nameStartMask))
eseidel's avatar
eseidel committed
225 226 227 228 229 230 231
        return false;

    // rule (c) above
    if (c >= 0xF900 && c < 0xFFFE)
        return false;

    // rule (d) above
darin's avatar
darin committed
232 233
    DecompositionType decompType = decompositionType(c);
    if (decompType == DecompositionFont || decompType == DecompositionCompat)
eseidel's avatar
eseidel committed
234 235 236 237 238 239
        return false;

    return true;
}

static inline bool isValidNamePart(UChar32 c)
darin's avatar
darin committed
240
{
eseidel's avatar
eseidel committed
241 242 243 244 245 246 247 248 249 250 251 252 253
    // rules (a), (e), and (i) above
    if (isValidNameStart(c))
        return true;

    // rules (g) and (h) above
    if (c == 0x00B7 || c == 0x0387)
        return true;

    // rule (j) above
    if (c == '-' || c == '.')
        return true;

    // rules (b) and (f) above
darin's avatar
darin committed
254 255
    const uint32_t otherNamePartMask = Mark_NonSpacing | Mark_Enclosing | Mark_SpacingCombining | Letter_Modifier | Number_DecimalDigit;
    if (!(Unicode::category(c) & otherNamePartMask))
eseidel's avatar
eseidel committed
256 257 258 259
        return false;

    // rule (c) above
    if (c >= 0xF900 && c < 0xFFFE)
darin's avatar
darin committed
260
        return false;
eseidel's avatar
eseidel committed
261 262

    // rule (d) above
darin's avatar
darin committed
263 264
    DecompositionType decompType = decompositionType(c);
    if (decompType == DecompositionFont || decompType == DecompositionCompat)
eseidel's avatar
eseidel committed
265 266
        return false;

darin's avatar
darin committed
267 268 269
    return true;
}

ggaren's avatar
ggaren committed
270
static Widget* widgetForNode(Node* focusedNode)
darin@apple.com's avatar
darin@apple.com committed
271
{
ggaren's avatar
ggaren committed
272 273 274 275 276
    if (!focusedNode)
        return 0;
    RenderObject* renderer = focusedNode->renderer();
    if (!renderer || !renderer->isWidget())
        return 0;
277
    return toRenderWidget(renderer)->widget();
ggaren's avatar
ggaren committed
278 279 280 281
}

static bool acceptsEditingFocus(Node *node)
{
ggaren's avatar
ggaren committed
282 283
    ASSERT(node);
    ASSERT(node->isContentEditable());
ggaren's avatar
ggaren committed
284 285 286 287 288 289 290 291 292

    Node *root = node->rootEditableElement();
    Frame* frame = node->document()->frame();
    if (!frame || !root)
        return false;

    return frame->editor()->shouldBeginEditing(rangeOfContents(root).get());
}

adele@apple.com's avatar
adele@apple.com committed
293 294
static bool disableRangeMutation(Page* page)
{
295
#if PLATFORM(MAC)
adele@apple.com's avatar
adele@apple.com committed
296 297 298
    // Disable Range mutation on document modifications in Tiger and Leopard Mail
    // See <rdar://problem/5865171>
    return page && (page->settings()->needsLeopardMailQuirks() || page->settings()->needsTigerMailQuirks());
299 300 301
#else
    return false;
#endif
adele@apple.com's avatar
adele@apple.com committed
302 303
}

304
static HashSet<Document*>* documentsThatNeedStyleRecalc = 0;
305

weinig@apple.com's avatar
weinig@apple.com committed
306
Document::Document(Frame* frame, bool isXHTML)
darin's avatar
darin committed
307
    : ContainerNode(0)
darin's avatar
darin committed
308
    , m_domtree_version(0)
309
    , m_styleSheets(StyleSheetList::create(this))
310
    , m_styleRecalcTimer(this, &Document::styleRecalcTimerFired)
darin@apple.com's avatar
darin@apple.com committed
311
    , m_frameElementsShouldIgnoreScrolling(false)
darin's avatar
darin committed
312 313
    , m_title("")
    , m_titleSetExplicitly(false)
darin's avatar
darin committed
314
    , m_updateFocusAppearanceTimer(this, &Document::updateFocusAppearanceTimerFired)
mitz@apple.com's avatar
mitz@apple.com committed
315
    , m_executeScriptSoonTimer(this, &Document::executeScriptSoonTimerFired)
mjs's avatar
mjs committed
316
#if ENABLE(XSLT)
eseidel's avatar
eseidel committed
317
    , m_transformSource(0)
ap's avatar
ap committed
318 319 320
#endif
    , m_xmlVersion("1.0")
    , m_xmlStandalone(false)
mjs's avatar
mjs committed
321
#if ENABLE(XBL)
ap's avatar
ap committed
322
    , m_bindingManager(new XBLBindingManager(this))
323
#endif
adele's avatar
adele committed
324 325 326
    , m_savedRenderer(0)
    , m_secureForms(0)
    , m_designMode(inherit)
327
    , m_selfOnlyRefCount(0)
mjs's avatar
mjs committed
328
#if ENABLE(SVG)
darin's avatar
darin committed
329 330
    , m_svgExtensions(0)
#endif
ddkilzer@apple.com's avatar
ddkilzer@apple.com committed
331
#if ENABLE(DASHBOARD_SUPPORT)
rjw's avatar
rjw committed
332
    , m_hasDashboardRegions(false)
rjw's avatar
rjw committed
333
    , m_dashboardRegionsDirty(false)
ddkilzer@apple.com's avatar
ddkilzer@apple.com committed
334
#endif
335 336 337
    , m_accessKeyMapValid(false)
    , m_createRenderers(true)
    , m_inPageCache(false)
beidson's avatar
beidson committed
338
    , m_useSecureKeyboardEntryWhenActive(false)
339
    , m_isXHTML(isXHTML)
weinig@apple.com's avatar
weinig@apple.com committed
340
    , m_numNodeListCaches(0)
mjs@apple.com's avatar
mjs@apple.com committed
341 342 343
#if ENABLE(DATABASE)
    , m_hasOpenDatabases(false)
#endif
ddkilzer@apple.com's avatar
ddkilzer@apple.com committed
344
    , m_usingGeolocation(false)
345 346 347
#if ENABLE(WML)
    , m_containsWMLContent(false)
#endif
kocienda's avatar
kocienda committed
348
{
349
    m_document = this;
350

351
    m_printing = false;
adele@apple.com's avatar
adele@apple.com committed
352 353
    
    m_ignoreAutofocus = false;
kocienda's avatar
kocienda committed
354

mjs's avatar
mjs committed
355
    m_frame = frame;
356
    m_renderArena = 0;
357

358
    m_axObjectCache = 0;
359
    
eric@webkit.org's avatar
eric@webkit.org committed
360
    m_docLoader = new DocLoader(this);
kocienda's avatar
kocienda committed
361 362

    visuallyOrdered = false;
363
    m_bParsing = false;
kocienda's avatar
kocienda committed
364
    m_tokenizer = 0;
ap's avatar
ap committed
365
    m_wellFormed = false;
366

367 368
    setParseMode(Strict);

369
    m_textColor = Color::black;
kocienda's avatar
kocienda committed
370
    m_listenerTypes = 0;
371
    m_inDocument = true;
372
    m_inStyleRecalc = false;
373
    m_closeAfterStyleRecalc = false;
hyatt@apple.com's avatar
hyatt@apple.com committed
374

375
    m_usesDescendantRules = false;
376
    m_usesSiblingRules = false;
377
    m_usesFirstLineRules = false;
weinig's avatar
weinig committed
378
    m_usesFirstLetterRules = false;
379
    m_usesBeforeAfterRules = false;
hyatt@apple.com's avatar
hyatt@apple.com committed
380 381
    m_usesRemUnits = false;

thatcher's avatar
thatcher committed
382
    m_gotoAnchorNeededAfterStylesheetsLoad = false;
383 384
 
    m_styleSelector = 0;
ddkilzer's avatar
ddkilzer committed
385
    m_didCalculateStyleSelector = false;
hyatt's avatar
hyatt committed
386
    m_pendingStylesheets = 0;
mjs's avatar
mjs committed
387
    m_ignorePendingStylesheets = false;
antti's avatar
antti committed
388
    m_hasNodesWithPlaceholderStyle = false;
389
    m_pendingSheetLayout = NoLayoutWithPendingSheets;
390 391

    m_cssTarget = 0;
392

393 394 395 396
    resetLinkColor();
    resetVisitedLinkColor();
    resetActiveLinkColor();

397
    m_processingLoadEvent = false;
darin's avatar
darin committed
398
    m_startTime = currentTime();
399
    m_overMinimumLayoutThreshold = false;
kocienda's avatar
kocienda committed
400
    
abarth@webkit.org's avatar
abarth@webkit.org committed
401
    initSecurityContext();
collinj@webkit.org's avatar
 
collinj@webkit.org committed
402
    initDNSPrefetch();
weinig's avatar
weinig committed
403

404 405
    static int docID = 0;
    m_docID = docID++;
406 407 408
#if ENABLE(XHTMLMP)
    m_shouldProcessNoScriptElement = settings() && !settings()->isJavaScriptEnabled();
#endif
kocienda's avatar
kocienda committed
409 410
}

darin's avatar
darin committed
411
void Document::removedLastRef()
mjs's avatar
mjs committed
412
{
darin's avatar
darin committed
413
    ASSERT(!m_deletionHasBegun);
mjs's avatar
mjs committed
414
    if (m_selfOnlyRefCount) {
darin's avatar
darin committed
415
        // If removing a child removes the last self-only ref, we don't
mjs's avatar
mjs committed
416 417
        // want the document to be destructed until after
        // removeAllChildren returns, so we guard ourselves with an
darin's avatar
darin committed
418
        // extra self-only ref.
419
        selfOnlyRef();
mjs's avatar
mjs committed
420

darin's avatar
darin committed
421 422
        // We must make sure not to be retaining any of our children through
        // these extra pointers or we will create a reference cycle.
mjs's avatar
mjs committed
423
        m_docType = 0;
ggaren's avatar
ggaren committed
424
        m_focusedNode = 0;
mjs's avatar
mjs committed
425 426 427
        m_hoverNode = 0;
        m_activeNode = 0;
        m_titleElement = 0;
thatcher's avatar
thatcher committed
428
        m_documentElement = 0;
mjs's avatar
mjs committed
429 430

        removeAllChildren();
mjs's avatar
mjs committed
431

darin's avatar
darin committed
432
        deleteAllValues(m_markers);
mjs's avatar
mjs committed
433
        m_markers.clear();
mjs's avatar
mjs committed
434 435 436

        delete m_tokenizer;
        m_tokenizer = 0;
darin's avatar
darin committed
437

438 439
        m_cssCanvasElements.clear();

darin's avatar
darin committed
440 441 442
#ifndef NDEBUG
        m_inRemovedLastRefFunction = false;
#endif
443 444

        selfOnlyDeref();
harrison's avatar
harrison committed
445 446
    } else {
#ifndef NDEBUG
darin's avatar
darin committed
447
        m_deletionHasBegun = true;
harrison's avatar
harrison committed
448
#endif
mjs's avatar
mjs committed
449
        delete this;
harrison's avatar
harrison committed
450
    }
mjs's avatar
mjs committed
451 452
}

darin's avatar
darin committed
453
Document::~Document()
kocienda's avatar
kocienda committed
454
{
455 456 457
    ASSERT(!renderer());
    ASSERT(!m_inPageCache);
    ASSERT(!m_savedRenderer);
darin@apple.com's avatar
darin@apple.com committed
458
    ASSERT(m_ranges.isEmpty());
459
    ASSERT(!m_styleRecalcTimer.isActive());
460

mitz@apple.com's avatar
mitz@apple.com committed
461 462 463
    for (size_t i = 0; i < m_scriptsToExecuteSoon.size(); ++i)
        m_scriptsToExecuteSoon[i].first->element()->deref(); // Balances ref() in executeScriptSoon().

464
    removeAllEventListeners();
darin's avatar
darin committed
465

466
#if USE(JSC)
darin@apple.com's avatar
darin@apple.com committed
467
    forgetAllDOMNodesForDocument(this);
468
#endif
mjs's avatar
mjs committed
469

darin's avatar
darin committed
470
    delete m_tokenizer;
471
    m_document = 0;
kocienda's avatar
kocienda committed
472 473
    delete m_styleSelector;
    delete m_docLoader;
adele's avatar
adele committed
474
    
darin's avatar
darin committed
475
    if (m_renderArena) {
476 477 478
        delete m_renderArena;
        m_renderArena = 0;
    }
479

mjs's avatar
mjs committed
480
#if ENABLE(XSLT)
481
    xmlFreeDoc((xmlDocPtr)m_transformSource);
482 483
#endif

mjs's avatar
mjs committed
484
#if ENABLE(XBL)
485 486 487
    delete m_bindingManager;
#endif

darin's avatar
darin committed
488 489
    deleteAllValues(m_markers);

harrison@apple.com's avatar
harrison@apple.com committed
490 491
    clearAXObjectCache();

eseidel's avatar
eseidel committed
492
    m_decoder = 0;
kocienda's avatar
kocienda committed
493
    
andersca's avatar
andersca committed
494 495 496
    unsigned count = sizeof(m_nameCollectionInfo) / sizeof(m_nameCollectionInfo[0]);
    for (unsigned i = 0; i < count; i++)
        deleteAllValues(m_nameCollectionInfo[i]);
497

498
#if ENABLE(DATABASE)
beidson's avatar
beidson committed
499
    if (m_databaseThread) {
beidson@apple.com's avatar
beidson@apple.com committed
500
        ASSERT(m_databaseThread->terminationRequested());
beidson's avatar
beidson committed
501 502
        m_databaseThread = 0;
    }
503
#endif
beidson's avatar
beidson committed
504

505 506
    if (m_styleSheets)
        m_styleSheets->documentDestroyed();
kocienda's avatar
kocienda committed
507 508
}

darin's avatar
darin committed
509
void Document::resetLinkColor()
510
{
511
    m_linkColor = Color(0, 0, 238);
512 513
}

darin's avatar
darin committed
514
void Document::resetVisitedLinkColor()
515
{
516
    m_visitedLinkColor = Color(85, 26, 139);    
517 518
}

darin's avatar
darin committed
519
void Document::resetActiveLinkColor()
520
{
521
    m_activeLinkColor.setNamedColor("red");
522
}
523

darin's avatar
darin committed
524
void Document::setDocType(PassRefPtr<DocumentType> docType)
525
{
526 527 528 529 530
    // This should never be called more than once.
    // Note: This is not a public DOM method and can only be called by the parser.
    ASSERT(!m_docType || !docType);
    if (m_docType && docType)
        return;
531
    m_docType = docType;
532 533 534
    if (m_docType)
        m_docType->setDocument(this);
    determineParseMode();
kocienda's avatar
kocienda committed
535 536
}

darin's avatar
darin committed
537
DOMImplementation* Document::implementation() const
kocienda's avatar
kocienda committed
538
{
weinig@apple.com's avatar
weinig@apple.com committed
539 540
    if (!m_implementation)
        m_implementation = DOMImplementation::create();
darin's avatar
darin committed
541
    return m_implementation.get();
kocienda's avatar
kocienda committed
542 543
}

544
void Document::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
thatcher's avatar
thatcher committed
545
{
546 547 548
    ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
    
    // Invalidate the document element we have cached in case it was replaced.
thatcher's avatar
thatcher committed
549 550 551
    m_documentElement = 0;
}

552
void Document::cacheDocumentElement() const
kocienda's avatar
kocienda committed
553
{
554 555 556 557 558
    ASSERT(!m_documentElement);
    Node* n = firstChild();
    while (n && !n->isElementNode())
        n = n->nextSibling();
    m_documentElement = static_cast<Element*>(n);
kocienda's avatar
kocienda committed
559 560
}

561
PassRefPtr<Element> Document::createElement(const AtomicString& name, ExceptionCode& ec)
kocienda's avatar
kocienda committed
562
{
eric@webkit.org's avatar
eric@webkit.org committed
563 564 565 566 567 568
    if (!isValidName(name)) {
        ec = INVALID_CHARACTER_ERR;
        return 0;
    }

    if (m_isXHTML)
569
        return HTMLElementFactory::createHTMLElement(QualifiedName(nullAtom, name, xhtmlNamespaceURI), this, 0, false);
kmccullo's avatar
kmccullo committed
570

jchaffraix@webkit.org's avatar
jchaffraix@webkit.org committed
571
    return createElement(QualifiedName(nullAtom, name, nullAtom), false);
kocienda's avatar
kocienda committed
572 573
}

darin's avatar
darin committed
574
PassRefPtr<DocumentFragment> Document::createDocumentFragment()
575
{
576
    return DocumentFragment::create(document());
577 578
}

darin@apple.com's avatar
darin@apple.com committed
579
PassRefPtr<Text> Document::createTextNode(const String& data)
580
{
581
    return Text::create(this, data);
582 583
}

darin@apple.com's avatar
darin@apple.com committed
584
PassRefPtr<Comment> Document::createComment(const String& data)
585
{
586
    return Comment::create(this, data);
587 588
}

darin@apple.com's avatar
darin@apple.com committed
589
PassRefPtr<CDATASection> Document::createCDATASection(const String& data, ExceptionCode& ec)
590
{
darin's avatar
darin committed
591
    if (isHTMLDocument()) {
darin's avatar
darin committed
592
        ec = NOT_SUPPORTED_ERR;
darin's avatar
darin committed
593
        return 0;
darin's avatar
darin committed
594
    }
595
    return CDATASection::create(this, data);
596 597
}

darin@apple.com's avatar
darin@apple.com committed
598
PassRefPtr<ProcessingInstruction> Document::createProcessingInstruction(const String& target, const String& data, ExceptionCode& ec)
599
{
darin's avatar
darin committed
600
    if (!isValidName(target)) {
darin's avatar
darin committed
601
        ec = INVALID_CHARACTER_ERR;
602
        return 0;
darin's avatar
darin committed
603 604
    }
    if (isHTMLDocument()) {
darin's avatar
darin committed
605
        ec = NOT_SUPPORTED_ERR;
606
        return 0;
darin's avatar
darin committed
607
    }
608
    return ProcessingInstruction::create(this, target, data);
609 610
}

darin@apple.com's avatar
darin@apple.com committed
611
PassRefPtr<EntityReference> Document::createEntityReference(const String& name, ExceptionCode& ec)
612
{
darin's avatar
darin committed
613
    if (!isValidName(name)) {
darin's avatar
darin committed
614
        ec = INVALID_CHARACTER_ERR;
darin's avatar
darin committed
615
        return 0;
darin's avatar
darin committed
616 617
    }
    if (isHTMLDocument()) {
darin's avatar
darin committed
618
        ec = NOT_SUPPORTED_ERR;
darin's avatar
darin committed
619
        return 0;
darin's avatar
darin committed
620
    }
621
    return EntityReference::create(this, name);
622 623
}

darin@apple.com's avatar
darin@apple.com committed
624
PassRefPtr<EditingText> Document::createEditingTextNode(const String& text)
kocienda's avatar
kocienda committed
625
{
626
    return EditingText::create(this, text);
kocienda's avatar
kocienda committed
627 628
}

darin's avatar
darin committed
629
PassRefPtr<CSSStyleDeclaration> Document::createCSSStyleDeclaration()
kocienda's avatar
kocienda committed
630
{
darin@apple.com's avatar
darin@apple.com committed
631
    return CSSMutableStyleDeclaration::create();
kocienda's avatar
kocienda committed
632 633
}

darin's avatar
darin committed
634
PassRefPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionCode& ec)
635
{
darin's avatar
darin committed
636
    ec = 0;
ggaren's avatar
ggaren committed
637
    
oliver's avatar
oliver committed
638
    if (!importedNode
ddkilzer@apple.com's avatar
ddkilzer@apple.com committed
639
#if ENABLE(SVG) && ENABLE(DASHBOARD_SUPPORT)
oliver's avatar
oliver committed
640 641 642
        || (importedNode->isSVGElement() && page() && page()->settings()->usesDashboardBackwardCompatibilityMode())
#endif
        ) {
ggaren's avatar
ggaren committed
643 644 645
        ec = NOT_SUPPORTED_ERR;
        return 0;
    }
darin's avatar
darin committed
646

darin's avatar
darin committed
647
    switch (importedNode->nodeType()) {
darin's avatar
darin committed
648
        case TEXT_NODE:
darin's avatar
darin committed
649
            return createTextNode(importedNode->nodeValue());
darin's avatar
darin committed
650 651 652 653 654 655 656
        case CDATA_SECTION_NODE:
            return createCDATASection(importedNode->nodeValue(), ec);
        case ENTITY_REFERENCE_NODE:
            return createEntityReference(importedNode->nodeName(), ec);
        case PROCESSING_INSTRUCTION_NODE:
            return createProcessingInstruction(importedNode->nodeName(), importedNode->nodeValue(), ec);
        case COMMENT_NODE:
darin's avatar
darin committed
657
            return createComment(importedNode->nodeValue());
darin's avatar
darin committed
658
        case ELEMENT_NODE: {
ap's avatar
ap committed
659
            Element* oldElement = static_cast<Element*>(importedNode);
mjs's avatar
mjs committed
660
            RefPtr<Element> newElement = createElementNS(oldElement->namespaceURI(), oldElement->tagQName().toString(), ec);
darin's avatar
darin committed
661
                        
ap's avatar
ap committed
662
            if (ec)
darin's avatar
darin committed
663
                return 0;
darin's avatar
darin committed
664

665
            NamedNodeMap* attrs = oldElement->attributes(true);
darin's avatar
darin committed
666 667 668
            if (attrs) {
                unsigned length = attrs->length();
                for (unsigned i = 0; i < length; i++) {
darin's avatar
darin committed
669
                    Attribute* attr = attrs->attributeItem(i);
darin's avatar
darin committed
670
                    newElement->setAttribute(attr->name(), attr->value().impl(), ec);
ap's avatar
ap committed
671
                    if (ec)
darin's avatar
darin committed
672 673 674 675
                        return 0;
                }
            }

676 677
            newElement->copyNonAttributeProperties(oldElement);

darin's avatar
darin committed
678
            if (deep) {
darin's avatar
darin committed
679 680
                for (Node* oldChild = oldElement->firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
                    RefPtr<Node> newChild = importNode(oldChild, true, ec);
ap's avatar
ap committed
681
                    if (ec)
darin's avatar
darin committed
682
                        return 0;
darin's avatar
darin committed
683
                    newElement->appendChild(newChild.release(), ec);
ap's avatar
ap committed
684
                    if (ec)
darin's avatar
darin committed
685 686 687 688
                        return 0;
                }
            }

darin's avatar
darin committed
689
            return newElement.release();
darin's avatar
darin committed
690
        }
691 692
        case ATTRIBUTE_NODE:
            return Attr::create(0, this, static_cast<Attr*>(importedNode)->attr()->clone());
ap's avatar
ap committed
693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708
        case DOCUMENT_FRAGMENT_NODE: {
            DocumentFragment* oldFragment = static_cast<DocumentFragment*>(importedNode);
            RefPtr<DocumentFragment> newFragment = createDocumentFragment();
            if (deep) {
                for (Node* oldChild = oldFragment->firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
                    RefPtr<Node> newChild = importNode(oldChild, true, ec);
                    if (ec)
                        return 0;
                    newFragment->appendChild(newChild.release(), ec);
                    if (ec)
                        return 0;
                }
            }
            
            return newFragment.release();
        }
darin's avatar
darin committed
709
        case ENTITY_NODE:
ap's avatar
ap committed
710 711 712
        case NOTATION_NODE:
            // FIXME: It should be possible to import these node types, however in DOM3 the DocumentType is readonly, so there isn't much sense in doing that.
            // Ability to add these imported nodes to a DocumentType will be considered for addition to a future release of the DOM.
darin's avatar
darin committed
713 714
        case DOCUMENT_NODE:
        case DOCUMENT_TYPE_NODE:
715
        case XPATH_NAMESPACE_NODE:
darin's avatar
darin committed
716
            break;
darin's avatar
darin committed
717 718
    }

darin's avatar
darin committed
719
    ec = NOT_SUPPORTED_ERR;
darin's avatar
darin committed
720
    return 0;
721 722
}

723

darin's avatar
darin committed
724
PassRefPtr<Node> Document::adoptNode(PassRefPtr<Node> source, ExceptionCode& ec)
725
{
ggaren's avatar
ggaren committed
726 727
    if (!source) {
        ec = NOT_SUPPORTED_ERR;
728
        return 0;
ggaren's avatar
ggaren committed
729
    }
eric@webkit.org's avatar
eric@webkit.org committed
730 731 732 733 734 735

    if (source->isReadOnlyNode()) {
        ec = NO_MODIFICATION_ALLOWED_ERR;
        return 0;
    }

736
    switch (source->nodeType()) {
darin's avatar
darin committed
737 738 739 740
        case ENTITY_NODE:
        case NOTATION_NODE: