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 "SharedWorkerRepository.h"
112
#include "StyleSheetList.h"
darin's avatar
darin committed
113
#include "TextEvent.h"
darin's avatar
darin committed
114
#include "TextIterator.h"
darin's avatar
darin committed
115
#include "TextResourceDecoder.h"
116
#include "Timer.h"
weinig@apple.com's avatar
weinig@apple.com committed
117
#include "TreeWalker.h"
weinig's avatar
 
weinig committed
118
#include "UIEvent.h"
119 120
#include "WebKitAnimationEvent.h"
#include "WebKitTransitionEvent.h"
darin's avatar
darin committed
121
#include "WheelEvent.h"
weinig's avatar
weinig committed
122
#include "XMLHttpRequest.h"
eric@webkit.org's avatar
eric@webkit.org committed
123
#include "XMLNames.h"
darin's avatar
darin committed
124
#include "XMLTokenizer.h"
ap@webkit.org's avatar
ap@webkit.org committed
125
#include <wtf/CurrentTime.h>
dsmith@webkit.org's avatar
dsmith@webkit.org committed
126
#include <wtf/HashFunctions.h>
127 128
#include <wtf/MainThread.h>
#include <wtf/PassRefPtr.h>
weinig@apple.com's avatar
weinig@apple.com committed
129
#include <wtf/StdLibExtras.h>
130

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

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

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

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

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

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

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

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

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

darin's avatar
darin committed
177 178
namespace WebCore {

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

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

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

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

eseidel's avatar
eseidel committed
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 216
// 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
217 218
    const uint32_t nameStartMask = Letter_Lowercase | Letter_Uppercase | Letter_Other | Letter_Titlecase | Number_Letter;
    if (!(Unicode::category(c) & nameStartMask))
eseidel's avatar
eseidel committed
219 220 221 222 223 224 225
        return false;

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

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

    return true;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

361 362
    setParseMode(Strict);

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

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

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

    m_cssTarget = 0;
386

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

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

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

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

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

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

        removeAllChildren();
mjs's avatar
mjs committed
426

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

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

433 434
        m_cssCanvasElements.clear();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

671 672
            newElement->copyNonAttributeProperties(oldElement);

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

darin's avatar
darin committed
684
            return newElement.release();
darin's avatar
darin committed
685
        }
ap's avatar
ap committed
686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706
        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
707
        case ENTITY_NODE:
ap's avatar
ap committed
708 709 710
        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
711 712
        case DOCUMENT_NODE:
        case DOCUMENT_TYPE_NODE:
713
        case XPATH_NAMESPACE_NODE:
darin's avatar
darin committed
714
            break;
darin's avatar
darin committed
715 716
    }

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

721

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

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

734
    switch (source->nodeType()) {
darin's avatar
darin committed
735 736 737 738
        case ENTITY_NODE:
        case NOTATION_NODE:
        case DOCUMENT_NODE:
        case DOCUMENT_TYPE_NODE:
739
        case XPATH_NAMESPACE_NODE:
darin's avatar
darin committed
740
            ec = NOT_SUPPORTED_ERR;
741
            return 0;            
darin's avatar
darin committed
742