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"
83
#include "ScriptEventListener.h"
weinig's avatar
 
weinig committed
84
#include "KeyboardEvent.h"
darin's avatar
darin committed
85
#include "Logging.h"
darin@apple.com's avatar
darin@apple.com committed
86
#include "MappedAttribute.h"
weinig@apple.com's avatar
weinig@apple.com committed
87
#include "MessageEvent.h"
weinig's avatar
 
weinig committed
88
#include "MouseEvent.h"
darin's avatar
darin committed
89
#include "MouseEventWithHitTestResults.h"
weinig's avatar
 
weinig committed
90
#include "MutationEvent.h"
darin's avatar
darin committed
91
#include "NameNodeList.h"
92 93
#include "NodeFilter.h"
#include "NodeIterator.h"
darin@apple.com's avatar
darin@apple.com committed
94
#include "NodeWithIndex.h"
darin's avatar
darin committed
95
#include "OverflowEvent.h"
96
#include "Page.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"
weinig's avatar
weinig committed
107
#include "SecurityOrigin.h"
darin's avatar
darin committed
108
#include "SegmentedString.h"
darin's avatar
darin committed
109
#include "SelectionController.h"
ggaren's avatar
ggaren committed
110
#include "Settings.h"
111
#include "StyleSheetList.h"
darin's avatar
darin committed
112
#include "TextEvent.h"
darin's avatar
darin committed
113
#include "TextIterator.h"
darin's avatar
darin committed
114
#include "TextResourceDecoder.h"
115
#include "Timer.h"
weinig@apple.com's avatar
weinig@apple.com committed
116
#include "TreeWalker.h"
weinig's avatar
 
weinig committed
117
#include "UIEvent.h"
118 119
#include "WebKitAnimationEvent.h"
#include "WebKitTransitionEvent.h"
darin's avatar
darin committed
120
#include "WheelEvent.h"
weinig's avatar
weinig committed
121
#include "XMLHttpRequest.h"
eric@webkit.org's avatar
eric@webkit.org committed
122
#include "XMLNames.h"
darin's avatar
darin committed
123
#include "XMLTokenizer.h"
ap@webkit.org's avatar
ap@webkit.org committed
124
#include <wtf/CurrentTime.h>
dsmith@webkit.org's avatar
dsmith@webkit.org committed
125
#include <wtf/HashFunctions.h>
126 127
#include <wtf/MainThread.h>
#include <wtf/PassRefPtr.h>
weinig@apple.com's avatar
weinig@apple.com committed
128
#include <wtf/StdLibExtras.h>
129

130
#if ENABLE(DATABASE)
131
#include "Database.h"
132 133 134
#include "DatabaseThread.h"
#endif

135 136 137 138
#if ENABLE(DOM_STORAGE)
#include "StorageEvent.h"
#endif

mjs's avatar
mjs committed
139
#if ENABLE(XPATH)
140 141 142 143
#include "XPathEvaluator.h"
#include "XPathExpression.h"
#include "XPathNSResolver.h"
#include "XPathResult.h"
144
#endif
kocienda's avatar
kocienda committed
145

mjs's avatar
mjs committed
146
#if ENABLE(XSLT)
darin's avatar
darin committed
147
#include "XSLTProcessor.h"
148 149
#endif

mjs's avatar
mjs committed
150
#if ENABLE(XBL)
151
#include "XBLBindingManager.h"
152 153
#endif

mjs's avatar
mjs committed
154
#if ENABLE(SVG)
155
#include "SVGDocumentExtensions.h"
eseidel's avatar
eseidel committed
156
#include "SVGElementFactory.h"
darin's avatar
darin committed
157 158
#include "SVGZoomEvent.h"
#include "SVGStyleElement.h"
eseidel's avatar
eseidel committed
159 160
#endif

161
#if ENABLE(WML)
162
#include "WMLDocument.h"
163 164 165 166 167
#include "WMLElement.h"
#include "WMLElementFactory.h"
#include "WMLNames.h"
#endif

168 169 170 171
#if ENABLE(XHTMLMP)
#include "HTMLNoScriptElement.h"
#endif

darin's avatar
darin committed
172
using namespace std;
darin's avatar
darin committed
173 174
using namespace WTF;
using namespace Unicode;
darin's avatar
darin committed
175

darin's avatar
darin committed
176 177
namespace WebCore {

178
using namespace HTMLNames;
kocienda's avatar
kocienda committed
179

180
// #define INSTRUMENT_LAYOUT_SCHEDULING 1
hyatt's avatar
hyatt committed
181

182 183 184
// 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
185
static const int cLayoutScheduleThreshold = 250;
186

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

eseidel's avatar
eseidel committed
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
// 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
216 217
    const uint32_t nameStartMask = Letter_Lowercase | Letter_Uppercase | Letter_Other | Letter_Titlecase | Number_Letter;
    if (!(Unicode::category(c) & nameStartMask))
eseidel's avatar
eseidel committed
218 219 220 221 222 223 224
        return false;

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

    // rule (d) above
darin's avatar
darin committed
225 226
    DecompositionType decompType = decompositionType(c);
    if (decompType == DecompositionFont || decompType == DecompositionCompat)
eseidel's avatar
eseidel committed
227 228 229 230 231 232
        return false;

    return true;
}

static inline bool isValidNamePart(UChar32 c)
darin's avatar
darin committed
233
{
eseidel's avatar
eseidel committed
234 235 236 237 238 239 240 241 242 243 244 245 246
    // 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
247 248
    const uint32_t otherNamePartMask = Mark_NonSpacing | Mark_Enclosing | Mark_SpacingCombining | Letter_Modifier | Number_DecimalDigit;
    if (!(Unicode::category(c) & otherNamePartMask))
eseidel's avatar
eseidel committed
249 250 251 252
        return false;

    // rule (c) above
    if (c >= 0xF900 && c < 0xFFFE)
darin's avatar
darin committed
253
        return false;
eseidel's avatar
eseidel committed
254 255

    // rule (d) above
darin's avatar
darin committed
256 257
    DecompositionType decompType = decompositionType(c);
    if (decompType == DecompositionFont || decompType == DecompositionCompat)
eseidel's avatar
eseidel committed
258 259
        return false;

darin's avatar
darin committed
260 261 262
    return true;
}

ggaren's avatar
ggaren committed
263
static Widget* widgetForNode(Node* focusedNode)
darin@apple.com's avatar
darin@apple.com committed
264
{
ggaren's avatar
ggaren committed
265 266 267 268 269 270 271 272 273 274
    if (!focusedNode)
        return 0;
    RenderObject* renderer = focusedNode->renderer();
    if (!renderer || !renderer->isWidget())
        return 0;
    return static_cast<RenderWidget*>(renderer)->widget();
}

static bool acceptsEditingFocus(Node *node)
{
ggaren's avatar
ggaren committed
275 276
    ASSERT(node);
    ASSERT(node->isContentEditable());
ggaren's avatar
ggaren committed
277 278 279 280 281 282 283 284 285

    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
286 287
static bool disableRangeMutation(Page* page)
{
288
#if PLATFORM(MAC)
adele@apple.com's avatar
adele@apple.com committed
289 290 291
    // Disable Range mutation on document modifications in Tiger and Leopard Mail
    // See <rdar://problem/5865171>
    return page && (page->settings()->needsLeopardMailQuirks() || page->settings()->needsTigerMailQuirks());
292 293 294
#else
    return false;
#endif
adele@apple.com's avatar
adele@apple.com committed
295 296
}

297
static HashSet<Document*>* documentsThatNeedStyleRecalc = 0;
298

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

344
    m_printing = false;
adele@apple.com's avatar
adele@apple.com committed
345 346
    
    m_ignoreAutofocus = false;
kocienda's avatar
kocienda committed
347

mjs's avatar
mjs committed
348
    m_frame = frame;
349
    m_renderArena = 0;
350

351
    m_axObjectCache = 0;
352
    
eric@webkit.org's avatar
eric@webkit.org committed
353
    m_docLoader = new DocLoader(this);
kocienda's avatar
kocienda committed
354 355

    visuallyOrdered = false;
356
    m_bParsing = false;
kocienda's avatar
kocienda committed
357
    m_tokenizer = 0;
ap's avatar
ap committed
358
    m_wellFormed = false;
359

360 361
    setParseMode(Strict);

362
    m_textColor = Color::black;
kocienda's avatar
kocienda committed
363
    m_listenerTypes = 0;
364
    m_inDocument = true;
365
    m_inStyleRecalc = false;
366
    m_closeAfterStyleRecalc = false;
hyatt@apple.com's avatar
hyatt@apple.com committed
367

368
    m_usesDescendantRules = false;
369
    m_usesSiblingRules = false;
370
    m_usesFirstLineRules = false;
weinig's avatar
weinig committed
371
    m_usesFirstLetterRules = false;
372
    m_usesBeforeAfterRules = false;
hyatt@apple.com's avatar
hyatt@apple.com committed
373 374
    m_usesRemUnits = false;

thatcher's avatar
thatcher committed
375
    m_gotoAnchorNeededAfterStylesheetsLoad = false;
376 377
 
    m_styleSelector = 0;
ddkilzer's avatar
ddkilzer committed
378
    m_didCalculateStyleSelector = false;
hyatt's avatar
hyatt committed
379
    m_pendingStylesheets = 0;
mjs's avatar
mjs committed
380
    m_ignorePendingStylesheets = false;
antti's avatar
antti committed
381
    m_hasNodesWithPlaceholderStyle = false;
382
    m_pendingSheetLayout = NoLayoutWithPendingSheets;
383 384

    m_cssTarget = 0;
385

386 387 388 389
    resetLinkColor();
    resetVisitedLinkColor();
    resetActiveLinkColor();

390
    m_processingLoadEvent = false;
darin's avatar
darin committed
391
    m_startTime = currentTime();
392
    m_overMinimumLayoutThreshold = false;
kocienda's avatar
kocienda committed
393
    
abarth@webkit.org's avatar
abarth@webkit.org committed
394
    initSecurityContext();
collinj@webkit.org's avatar
 
collinj@webkit.org committed
395
    initDNSPrefetch();
weinig's avatar
weinig committed
396

397 398
    static int docID = 0;
    m_docID = docID++;
399 400 401
#if ENABLE(XHTMLMP)
    m_shouldProcessNoScriptElement = settings() && !settings()->isJavaScriptEnabled();
#endif
kocienda's avatar
kocienda committed
402 403
}

darin's avatar
darin committed
404
void Document::removedLastRef()
mjs's avatar
mjs committed
405
{
darin's avatar
darin committed
406
    ASSERT(!m_deletionHasBegun);
mjs's avatar
mjs committed
407
    if (m_selfOnlyRefCount) {
darin's avatar
darin committed
408
        // If removing a child removes the last self-only ref, we don't
mjs's avatar
mjs committed
409 410
        // want the document to be destructed until after
        // removeAllChildren returns, so we guard ourselves with an
darin's avatar
darin committed
411
        // extra self-only ref.
mjs's avatar
mjs committed
412

darin's avatar
darin committed
413
        DocPtr<Document> guard(this);
mjs's avatar
mjs committed
414

darin's avatar
darin committed
415 416
        // 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
417
        m_docType = 0;
ggaren's avatar
ggaren committed
418
        m_focusedNode = 0;
mjs's avatar
mjs committed
419 420 421
        m_hoverNode = 0;
        m_activeNode = 0;
        m_titleElement = 0;
thatcher's avatar
thatcher committed
422
        m_documentElement = 0;
mjs's avatar
mjs committed
423 424

        removeAllChildren();
mjs's avatar
mjs committed
425

darin's avatar
darin committed
426
        deleteAllValues(m_markers);
mjs's avatar
mjs committed
427
        m_markers.clear();
mjs's avatar
mjs committed
428 429 430

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

432 433
        m_cssCanvasElements.clear();

darin's avatar
darin committed
434 435 436
#ifndef NDEBUG
        m_inRemovedLastRefFunction = false;
#endif
harrison's avatar
harrison committed
437 438
    } else {
#ifndef NDEBUG
darin's avatar
darin committed
439
        m_deletionHasBegun = true;
harrison's avatar
harrison committed
440
#endif
mjs's avatar
mjs committed
441
        delete this;
harrison's avatar
harrison committed
442
    }
mjs's avatar
mjs committed
443 444
}

darin's avatar
darin committed
445
Document::~Document()
kocienda's avatar
kocienda committed
446
{
447 448 449
    ASSERT(!renderer());
    ASSERT(!m_inPageCache);
    ASSERT(!m_savedRenderer);
darin@apple.com's avatar
darin@apple.com committed
450
    ASSERT(m_ranges.isEmpty());
451
    ASSERT(!m_styleRecalcTimer.isActive());
452

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

456
    removeAllEventListeners();
darin's avatar
darin committed
457

458
#if USE(JSC)
darin@apple.com's avatar
darin@apple.com committed
459
    forgetAllDOMNodesForDocument(this);
460
#endif
mjs's avatar
mjs committed
461

darin's avatar
darin committed
462
    delete m_tokenizer;
ggaren's avatar
ggaren committed
463
    m_document.resetSkippingRef(0);
kocienda's avatar
kocienda committed
464 465
    delete m_styleSelector;
    delete m_docLoader;
adele's avatar
adele committed
466
    
darin's avatar
darin committed
467
    if (m_renderArena) {
468 469 470
        delete m_renderArena;
        m_renderArena = 0;
    }
471

mjs's avatar
mjs committed
472
#if ENABLE(XSLT)
473
    xmlFreeDoc((xmlDocPtr)m_transformSource);
474 475
#endif

mjs's avatar
mjs committed
476
#if ENABLE(XBL)
477 478 479
    delete m_bindingManager;
#endif

darin's avatar
darin committed
480 481
    deleteAllValues(m_markers);

harrison@apple.com's avatar
harrison@apple.com committed
482 483
    clearAXObjectCache();

eseidel's avatar
eseidel committed
484
    m_decoder = 0;
kocienda's avatar
kocienda committed
485
    
andersca's avatar
andersca committed
486 487 488
    unsigned count = sizeof(m_nameCollectionInfo) / sizeof(m_nameCollectionInfo[0]);
    for (unsigned i = 0; i < count; i++)
        deleteAllValues(m_nameCollectionInfo[i]);
489

490
#if ENABLE(DATABASE)
beidson's avatar
beidson committed
491
    if (m_databaseThread) {
beidson@apple.com's avatar
beidson@apple.com committed
492
        ASSERT(m_databaseThread->terminationRequested());
beidson's avatar
beidson committed
493 494
        m_databaseThread = 0;
    }
495
#endif
beidson's avatar
beidson committed
496

497 498
    if (m_styleSheets)
        m_styleSheets->documentDestroyed();
weinig@apple.com's avatar
weinig@apple.com committed
499 500

    m_document = 0;
kocienda's avatar
kocienda committed
501 502
}

darin's avatar
darin committed
503
void Document::resetLinkColor()
504
{
505
    m_linkColor = Color(0, 0, 238);
506 507
}

darin's avatar
darin committed
508
void Document::resetVisitedLinkColor()
509
{
510
    m_visitedLinkColor = Color(85, 26, 139);    
511 512
}

darin's avatar
darin committed
513
void Document::resetActiveLinkColor()
514
{
515
    m_activeLinkColor.setNamedColor("red");
516
}
517

darin's avatar
darin committed
518
void Document::setDocType(PassRefPtr<DocumentType> docType)
519
{
520 521 522 523 524
    // 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;
525
    m_docType = docType;
526 527 528
    if (m_docType)
        m_docType->setDocument(this);
    determineParseMode();
kocienda's avatar
kocienda committed
529 530
}

darin's avatar
darin committed
531
DOMImplementation* Document::implementation() const
kocienda's avatar
kocienda committed
532
{
weinig@apple.com's avatar
weinig@apple.com committed
533 534
    if (!m_implementation)
        m_implementation = DOMImplementation::create();
darin's avatar
darin committed
535
    return m_implementation.get();
kocienda's avatar
kocienda committed
536 537
}

538
void Document::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
thatcher's avatar
thatcher committed
539
{
540 541 542
    ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
    
    // Invalidate the document element we have cached in case it was replaced.
thatcher's avatar
thatcher committed
543 544 545
    m_documentElement = 0;
}

546
void Document::cacheDocumentElement() const
kocienda's avatar
kocienda committed
547
{
548 549 550 551 552
    ASSERT(!m_documentElement);
    Node* n = firstChild();
    while (n && !n->isElementNode())
        n = n->nextSibling();
    m_documentElement = static_cast<Element*>(n);
kocienda's avatar
kocienda committed
553 554
}

555
PassRefPtr<Element> Document::createElement(const AtomicString& name, ExceptionCode& ec)
kocienda's avatar
kocienda committed
556
{
eric@webkit.org's avatar
eric@webkit.org committed
557 558 559 560 561 562
    if (!isValidName(name)) {
        ec = INVALID_CHARACTER_ERR;
        return 0;
    }

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

jchaffraix@webkit.org's avatar
jchaffraix@webkit.org committed
565
    return createElement(QualifiedName(nullAtom, name, nullAtom), false);
kocienda's avatar
kocienda committed
566 567
}

darin's avatar
darin committed
568
PassRefPtr<DocumentFragment> Document::createDocumentFragment()
569
{
ggaren's avatar
ggaren committed
570
    return new DocumentFragment(document());
571 572
}

darin@apple.com's avatar
darin@apple.com committed
573
PassRefPtr<Text> Document::createTextNode(const String& data)
574
{
darin's avatar
darin committed
575
    return new Text(this, data);
576 577
}

darin@apple.com's avatar
darin@apple.com committed
578
PassRefPtr<Comment> Document::createComment(const String& data)
579
{
darin's avatar
darin committed
580
    return new Comment(this, data);
581 582
}

darin@apple.com's avatar
darin@apple.com committed
583
PassRefPtr<CDATASection> Document::createCDATASection(const String& data, ExceptionCode& ec)
584
{
darin's avatar
darin committed
585
    if (isHTMLDocument()) {
darin's avatar
darin committed
586
        ec = NOT_SUPPORTED_ERR;
darin's avatar
darin committed
587
        return 0;
darin's avatar
darin committed
588
    }
darin's avatar
darin committed
589
    return new CDATASection(this, data);
590 591
}

darin@apple.com's avatar
darin@apple.com committed
592
PassRefPtr<ProcessingInstruction> Document::createProcessingInstruction(const String& target, const String& data, ExceptionCode& ec)
593
{
darin's avatar
darin committed
594
    if (!isValidName(target)) {
darin's avatar
darin committed
595
        ec = INVALID_CHARACTER_ERR;
596
        return 0;
darin's avatar
darin committed
597 598
    }
    if (isHTMLDocument()) {
darin's avatar
darin committed
599
        ec = NOT_SUPPORTED_ERR;
600
        return 0;
darin's avatar
darin committed
601
    }
darin's avatar
darin committed
602
    return new ProcessingInstruction(this, target, data);
603 604
}

darin@apple.com's avatar
darin@apple.com committed
605
PassRefPtr<EntityReference> Document::createEntityReference(const String& name, ExceptionCode& ec)
606
{
darin's avatar
darin committed
607
    if (!isValidName(name)) {
darin's avatar
darin committed
608
        ec = INVALID_CHARACTER_ERR;
darin's avatar
darin committed
609
        return 0;
darin's avatar
darin committed
610 611
    }
    if (isHTMLDocument()) {
darin's avatar
darin committed
612
        ec = NOT_SUPPORTED_ERR;
darin's avatar
darin committed
613
        return 0;
darin's avatar
darin committed
614
    }
615
    return new EntityReference(this, name);
616 617
}

darin@apple.com's avatar
darin@apple.com committed
618
PassRefPtr<EditingText> Document::createEditingTextNode(const String& text)
kocienda's avatar
kocienda committed
619
{
darin's avatar
darin committed
620
    return new EditingText(this, text);
kocienda's avatar
kocienda committed
621 622
}

darin's avatar
darin committed
623
PassRefPtr<CSSStyleDeclaration> Document::createCSSStyleDeclaration()
kocienda's avatar
kocienda committed
624
{
darin@apple.com's avatar
darin@apple.com committed
625
    return CSSMutableStyleDeclaration::create();
kocienda's avatar
kocienda committed
626 627
}

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

darin's avatar
darin committed
641
    switch (importedNode->nodeType()) {
darin's avatar
darin committed
642
        case TEXT_NODE:
darin's avatar
darin committed
643
            return createTextNode(importedNode->nodeValue());
darin's avatar
darin committed
644 645 646 647 648 649 650
        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
651
            return createComment(importedNode->nodeValue());
darin's avatar
darin committed
652
        case ELEMENT_NODE: {
ap's avatar
ap committed
653
            Element* oldElement = static_cast<Element*>(importedNode);
mjs's avatar
mjs committed
654
            RefPtr<Element> newElement = createElementNS(oldElement->namespaceURI(), oldElement->tagQName().toString(), ec);
darin's avatar
darin committed
655
                        
ap's avatar
ap committed
656
            if (ec)
darin's avatar
darin committed
657
                return 0;
darin's avatar
darin committed
658

659
            NamedNodeMap* attrs = oldElement->attributes(true);
darin's avatar
darin committed
660 661 662
            if (attrs) {
                unsigned length = attrs->length();
                for (unsigned i = 0; i < length; i++) {
darin's avatar
darin committed
663
                    Attribute* attr = attrs->attributeItem(i);
darin's avatar
darin committed
664
                    newElement->setAttribute(attr->name(), attr->value().impl(), ec);
ap's avatar
ap committed
665
                    if (ec)
darin's avatar
darin committed
666 667 668 669
                        return 0;
                }
            }

670 671
            newElement->copyNonAttributeProperties(oldElement);

darin's avatar
darin committed
672
            if (deep) {
darin's avatar
darin committed
673 674
                for (Node* oldChild = oldElement->firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
                    RefPtr<Node> newChild = importNode(oldChild, true, ec);
ap's avatar
ap committed
675
                    if (ec)
darin's avatar
darin committed
676
                        return 0;
darin's avatar
darin committed
677
                    newElement->appendChild(newChild.release(), ec);
ap's avatar
ap committed
678
                    if (ec)
darin's avatar
darin committed
679 680 681 682
                        return 0;
                }
            }

darin's avatar
darin committed
683
            return newElement.release();
darin's avatar
darin committed
684
        }
ap's avatar
ap committed
685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705
        case ATTRIBUTE_NODE: {
            RefPtr<Attr> newAttr = new Attr(0, this, static_cast<Attr*>(importedNode)->attr()->clone());
            newAttr->createTextChild();
            return newAttr.release();
        }
        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
706
        case ENTITY_NODE:
ap's avatar
ap committed
707 708 709
        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
710 711
        case DOCUMENT_NODE:
        case DOCUMENT_TYPE_NODE:
712
        case XPATH_NAMESPACE_NODE:
darin's avatar
darin committed
713
            break;
darin's avatar
darin committed
714 715
    }

darin's avatar
darin committed
716
    ec = NOT_SUPPORTED_ERR;
darin's avatar
darin committed
717
    return 0;
718 719
}

720

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

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

733
    switch (source->nodeType()) {
darin's avatar
darin committed
734 735 736 737
        case ENTITY_NODE:
        case NOTATION_NODE:
        case DOCUMENT_NODE:
        case DOCUMENT_TYPE_NODE:
738
        case XPATH_NAMESPACE_NODE:
darin's avatar
darin committed
739
            ec = NOT_SUPPORTED_ERR;
740
            return 0;            
darin's avatar
darin committed
741
        case ATTRIBUTE_NODE: {                   
darin's avatar
darin committed
742
            Attr* attr = static_cast<Attr*>(source.get());
743
            if (attr->ownerElement())