Document.cpp 142 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 "InspectorTimelineAgent.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"
ap@apple.com's avatar
ap@apple.com committed
97
#include "PageTransitionEvent.h"
darin's avatar
darin committed
98
#include "PlatformKeyboardEvent.h"
99
#include "ProcessingInstruction.h"
antti's avatar
antti committed
100
#include "ProgressEvent.h"
weinig's avatar
 
weinig committed
101
#include "RegisteredEventListener.h"
darin's avatar
darin committed
102
#include "RenderArena.h"
103
#include "RenderTextControl.h"
104
#include "RenderView.h"
105
#include "RenderWidget.h"
106
#include "ScriptController.h"
mitz@apple.com's avatar
mitz@apple.com committed
107
#include "ScriptElement.h"
108
#include "ScriptEventListener.h"
weinig's avatar
weinig committed
109
#include "SecurityOrigin.h"
darin's avatar
darin committed
110
#include "SegmentedString.h"
darin's avatar
darin committed
111
#include "SelectionController.h"
ggaren's avatar
ggaren committed
112
#include "Settings.h"
kov@webkit.org's avatar
kov@webkit.org committed
113 114

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

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

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

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

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

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

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

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

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

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

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

darin's avatar
darin committed
184 185
namespace WebCore {

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

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

190 191 192
// 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
193
static const int cLayoutScheduleThreshold = 250;
194

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

eseidel's avatar
eseidel committed
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 223
// 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
224 225
    const uint32_t nameStartMask = Letter_Lowercase | Letter_Uppercase | Letter_Other | Letter_Titlecase | Number_Letter;
    if (!(Unicode::category(c) & nameStartMask))
eseidel's avatar
eseidel committed
226 227 228 229 230 231 232
        return false;

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

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

    return true;
}

static inline bool isValidNamePart(UChar32 c)
darin's avatar
darin committed
241
{
eseidel's avatar
eseidel committed
242 243 244 245 246 247 248 249 250 251 252 253 254
    // 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
255 256
    const uint32_t otherNamePartMask = Mark_NonSpacing | Mark_Enclosing | Mark_SpacingCombining | Letter_Modifier | Number_DecimalDigit;
    if (!(Unicode::category(c) & otherNamePartMask))
eseidel's avatar
eseidel committed
257 258 259 260
        return false;

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

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

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

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

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

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

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

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

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

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

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

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

368 369
    setParseMode(Strict);

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

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

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

    m_cssTarget = 0;
393

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

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

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

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

darin's avatar
darin committed
422 423
        // 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
424
        m_docType = 0;
ggaren's avatar
ggaren committed
425
        m_focusedNode = 0;
mjs's avatar
mjs committed
426 427 428
        m_hoverNode = 0;
        m_activeNode = 0;
        m_titleElement = 0;
thatcher's avatar
thatcher committed
429
        m_documentElement = 0;
mjs's avatar
mjs committed
430 431

        removeAllChildren();
mjs's avatar
mjs committed
432

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

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

439 440
        m_cssCanvasElements.clear();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

darin's avatar
darin committed
525
void Document::setDocType(PassRefPtr<DocumentType> docType)
526
{
527 528 529 530 531
    // 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;
532
    m_docType = docType;
533 534 535
    if (m_docType)
        m_docType->setDocument(this);
    determineParseMode();
kocienda's avatar
kocienda committed
536 537
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

677 678
            newElement->copyNonAttributeProperties(oldElement);

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

darin's avatar
darin committed
690
            return newElement.release();
darin's avatar
darin committed
691
        }
692 693
        case ATTRIBUTE_NODE:
            return Attr::create(0, this, static_cast<Attr*>(importedNode)->attr()->clone());
ap's avatar
ap committed
694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709
        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
710
        case ENTITY_NODE:
ap's avatar
ap committed
711 712 713
        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
714 715
        case DOCUMENT_NODE:
        case DOCUMENT_TYPE_NODE:
716
        case XPATH_NAMESPACE_NODE:
darin's avatar
darin committed
717
            break;
darin's avatar
darin committed
718 719
    }

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

724

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

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

737
    switch (source->nodeType()) {