Put date into field that was used to activate DatePicker instead of currectly focused...
[framework/web/webkit-efl.git] / Source / WebCore / dom / Document.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2001 Dirk Mueller (mueller@kde.org)
5  *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
6  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All rights reserved.
7  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
8  * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved.
9  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
10  * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Library General Public
14  * License as published by the Free Software Foundation; either
15  * version 2 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Library General Public License for more details.
21  *
22  * You should have received a copy of the GNU Library General Public License
23  * along with this library; see the file COPYING.LIB.  If not, write to
24  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25  * Boston, MA 02110-1301, USA.
26  */
27
28 #include "config.h"
29 #include "Document.h"
30
31 #include "AXObjectCache.h"
32 #include "AnimationController.h"
33 #include "Attr.h"
34 #include "Attribute.h"
35 #include "CDATASection.h"
36 #include "CSSParser.h"
37 #include "CSSStyleDeclaration.h"
38 #include "CSSStyleSheet.h"
39 #include "CSSValueKeywords.h"
40 #include "CachedCSSStyleSheet.h"
41 #include "CachedResourceLoader.h"
42 #include "Chrome.h"
43 #include "ChromeClient.h"
44 #include "Comment.h"
45 #include "Console.h"
46 #include "ContentSecurityPolicy.h"
47 #include "ContextFeatures.h"
48 #include "CookieJar.h"
49 #include "DOMImplementation.h"
50 #include "DOMSelection.h"
51 #include "DOMWindow.h"
52 #include "DateComponents.h"
53 #include "DeviceMotionController.h"
54 #include "DeviceMotionEvent.h"
55 #include "DeviceOrientationController.h"
56 #include "DeviceOrientationEvent.h"
57 #include "DocumentEventQueue.h"
58 #include "DocumentFragment.h"
59 #include "DocumentLoader.h"
60 #include "DocumentMarkerController.h"
61 #include "DocumentType.h"
62 #include "EditingText.h"
63 #include "Editor.h"
64 #include "Element.h"
65 #include "ElementShadow.h"
66 #include "EntityReference.h"
67 #include "Event.h"
68 #include "EventFactory.h"
69 #include "EventHandler.h"
70 #include "EventListener.h"
71 #include "EventNames.h"
72 #include "ExceptionCode.h"
73 #include "FlowThreadController.h"
74 #include "FocusController.h"
75 #include "FormController.h"
76 #include "Frame.h"
77 #include "FrameLoader.h"
78 #include "FrameLoaderClient.h"
79 #include "FrameSelection.h"
80 #include "FrameTree.h"
81 #include "FrameView.h"
82 #include "GeolocationController.h"
83 #include "HashChangeEvent.h"
84 #include "HistogramSupport.h"
85 #include "History.h"
86 #include "HTMLAllCollection.h"
87 #include "HTMLAnchorElement.h"
88 #include "HTMLBodyElement.h"
89 #include "HTMLCanvasElement.h"
90 #include "HTMLCollection.h"
91 #include "HTMLDocument.h"
92 #include "HTMLElementFactory.h"
93 #include "HTMLFrameOwnerElement.h"
94 #include "HTMLHeadElement.h"
95 #include "HTMLIFrameElement.h"
96 #include "HTMLLinkElement.h"
97 #include "HTMLMapElement.h"
98 #include "HTMLNameCollection.h"
99 #include "HTMLNames.h"
100 #include "HTMLParserIdioms.h"
101 #include "HTMLStyleElement.h"
102 #include "HTMLTitleElement.h"
103 #include "HTTPParsers.h"
104 #include "HitTestRequest.h"
105 #include "HitTestResult.h"
106 #include "ImageLoader.h"
107 #include "InspectorCounters.h"
108 #include "InspectorInstrumentation.h"
109 #include "Logging.h"
110 #include "MediaQueryList.h"
111 #include "MediaQueryMatcher.h"
112 #include "MemoryInstrumentation.h"
113 #include "MouseEventWithHitTestResults.h"
114 #include "NameNodeList.h"
115 #include "NestingLevelIncrementer.h"
116 #include "NewXMLDocumentParser.h"
117 #include "NodeFilter.h"
118 #include "NodeIterator.h"
119 #include "NodeRareData.h"
120 #include "NodeWithIndex.h"
121 #include "Page.h"
122 #include "PageGroup.h"
123 #include "PageTransitionEvent.h"
124 #include "PlatformKeyboardEvent.h"
125 #include "PluginDocument.h"
126 #include "PointerLockController.h"
127 #include "PopStateEvent.h"
128 #include "ProcessingInstruction.h"
129 #include "RegisteredEventListener.h"
130 #include "RenderArena.h"
131 #include "RenderLayerCompositor.h"
132 #include "RenderNamedFlowThread.h"
133 #include "RenderTextControl.h"
134 #include "RenderView.h"
135 #include "RenderWidget.h"
136 #include "SchemeRegistry.h"
137 #include "ScopedEventQueue.h"
138 #include "ScriptCallStack.h"
139 #include "ScriptController.h"
140 #include "ScriptElement.h"
141 #include "ScriptEventListener.h"
142 #include "ScriptRunner.h"
143 #include "ScrollingCoordinator.h"
144 #include "SecurityOrigin.h"
145 #include "SecurityPolicy.h"
146 #include "SegmentedString.h"
147 #include "SelectorQuery.h"
148 #include "Settings.h"
149 #include "ShadowRoot.h"
150 #include "StaticHashSetNodeList.h"
151 #include "StyleResolver.h"
152 #include "StyleSheetContents.h"
153 #include "StyleSheetList.h"
154 #include "TextResourceDecoder.h"
155 #include "Timer.h"
156 #include "TransformSource.h"
157 #include "TreeWalker.h"
158 #include "UndoManager.h"
159 #include "UserContentURLPattern.h"
160 #include "WebKitNamedFlow.h"
161 #include "WebKitNamedFlowCollection.h"
162 #include "XMLDocumentParser.h"
163 #include "XMLHttpRequest.h"
164 #include "XMLNSNames.h"
165 #include "XMLNames.h"
166 #include "XPathEvaluator.h"
167 #include "XPathExpression.h"
168 #include "XPathNSResolver.h"
169 #include "XPathResult.h"
170 #include "htmlediting.h"
171 #include <wtf/CurrentTime.h>
172 #include <wtf/HashFunctions.h>
173 #include <wtf/MainThread.h>
174 #include <wtf/PassRefPtr.h>
175 #include <wtf/StdLibExtras.h>
176 #include <wtf/text/StringBuffer.h>
177
178 #if ENABLE(SHARED_WORKERS)
179 #include "SharedWorkerRepository.h"
180 #endif
181
182 #if ENABLE(XSLT)
183 #include "XSLTProcessor.h"
184 #endif
185
186 #if ENABLE(SVG)
187 #include "SVGDocumentExtensions.h"
188 #include "SVGElementFactory.h"
189 #include "SVGNames.h"
190 #include "SVGSVGElement.h"
191 #include "SVGStyleElement.h"
192 #endif
193
194 #if ENABLE(TOUCH_EVENTS)
195 #include "TouchList.h"
196 #endif
197
198 #if ENABLE(MATHML)
199 #include "MathMLElement.h"
200 #include "MathMLElementFactory.h"
201 #include "MathMLNames.h"
202 #endif
203
204 #if ENABLE(FULLSCREEN_API)
205 #include "RenderFullScreen.h"
206 #endif
207
208 #if ENABLE(REQUEST_ANIMATION_FRAME)
209 #include "RequestAnimationFrameCallback.h"
210 #include "ScriptedAnimationController.h"
211 #endif
212
213 #if ENABLE(MICRODATA)
214 #include "MicroDataItemList.h"
215 #include "NodeRareData.h"
216 #endif
217
218 #if ENABLE(LINK_PRERENDER)
219 #include "Prerenderer.h"
220 #endif
221
222 #if ENABLE(TEXT_AUTOSIZING)
223 #include "TextAutosizer.h"
224 #endif
225
226 #if ENABLE(CSP_NEXT)
227 #include "DOMSecurityPolicy.h"
228 #endif
229
230 #if ENABLE(TIZEN_EXTENSIBLE_API)
231 #include "TizenExtensibleAPI.h"
232 #endif
233
234 #if ENABLE(TIZEN_GSTREAMER_AUDIO)
235 #include "AudioSessionManagerGStreamerTizen.h"
236 #endif
237
238 using namespace std;
239 using namespace WTF;
240 using namespace Unicode;
241
242 namespace WebCore {
243
244 using namespace HTMLNames;
245
246 // #define INSTRUMENT_LAYOUT_SCHEDULING 1
247
248 static const unsigned cMaxWriteRecursionDepth = 21;
249
250 // This amount of time must have elapsed before we will even consider scheduling a layout without a delay.
251 // FIXME: For faster machines this value can really be lowered to 200.  250 is adequate, but a little high
252 // for dual G5s. :)
253 static const int cLayoutScheduleThreshold = 250;
254
255 // DOM Level 2 says (letters added):
256 //
257 // a) Name start characters must have one of the categories Ll, Lu, Lo, Lt, Nl.
258 // b) Name characters other than Name-start characters must have one of the categories Mc, Me, Mn, Lm, or Nd.
259 // c) Characters in the compatibility area (i.e. with character code greater than #xF900 and less than #xFFFE) are not allowed in XML names.
260 // 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.
261 // 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.
262 // f) Characters #x20DD-#x20E0 are excluded (in accordance with Unicode, section 5.14).
263 // g) Character #x00B7 is classified as an extender, because the property list so identifies it.
264 // h) Character #x0387 is added as a name character, because #x00B7 is its canonical equivalent.
265 // i) Characters ':' and '_' are allowed as name-start characters.
266 // j) Characters '-' and '.' are allowed as name characters.
267 //
268 // It also contains complete tables. If we decide it's better, we could include those instead of the following code.
269
270 static inline bool isValidNameStart(UChar32 c)
271 {
272     // rule (e) above
273     if ((c >= 0x02BB && c <= 0x02C1) || c == 0x559 || c == 0x6E5 || c == 0x6E6)
274         return true;
275
276     // rule (i) above
277     if (c == ':' || c == '_')
278         return true;
279
280     // rules (a) and (f) above
281     const uint32_t nameStartMask = Letter_Lowercase | Letter_Uppercase | Letter_Other | Letter_Titlecase | Number_Letter;
282     if (!(Unicode::category(c) & nameStartMask))
283         return false;
284
285     // rule (c) above
286     if (c >= 0xF900 && c < 0xFFFE)
287         return false;
288
289     // rule (d) above
290     DecompositionType decompType = decompositionType(c);
291     if (decompType == DecompositionFont || decompType == DecompositionCompat)
292         return false;
293
294     return true;
295 }
296
297 static inline bool isValidNamePart(UChar32 c)
298 {
299     // rules (a), (e), and (i) above
300     if (isValidNameStart(c))
301         return true;
302
303     // rules (g) and (h) above
304     if (c == 0x00B7 || c == 0x0387)
305         return true;
306
307     // rule (j) above
308     if (c == '-' || c == '.')
309         return true;
310
311     // rules (b) and (f) above
312     const uint32_t otherNamePartMask = Mark_NonSpacing | Mark_Enclosing | Mark_SpacingCombining | Letter_Modifier | Number_DecimalDigit;
313     if (!(Unicode::category(c) & otherNamePartMask))
314         return false;
315
316     // rule (c) above
317     if (c >= 0xF900 && c < 0xFFFE)
318         return false;
319
320     // rule (d) above
321     DecompositionType decompType = decompositionType(c);
322     if (decompType == DecompositionFont || decompType == DecompositionCompat)
323         return false;
324
325     return true;
326 }
327
328 static bool shouldInheritSecurityOriginFromOwner(const KURL& url)
329 {
330     // http://www.whatwg.org/specs/web-apps/current-work/#origin-0
331     //
332     // If a Document has the address "about:blank"
333     //     The origin of the Document is the origin it was assigned when its browsing context was created.
334     //
335     // Note: We generalize this to all "blank" URLs and invalid URLs because we
336     // treat all of these URLs as about:blank.
337     //
338     return !url.isValid() || url.isBlankURL();
339 }
340
341 static Widget* widgetForNode(Node* focusedNode)
342 {
343     if (!focusedNode)
344         return 0;
345     RenderObject* renderer = focusedNode->renderer();
346     if (!renderer || !renderer->isWidget())
347         return 0;
348     return toRenderWidget(renderer)->widget();
349 }
350
351 static bool acceptsEditingFocus(Node* node)
352 {
353     ASSERT(node);
354     ASSERT(node->rendererIsEditable());
355
356     Node* root = node->rootEditableElement();
357     Frame* frame = node->document()->frame();
358     if (!frame || !root)
359         return false;
360
361     return frame->editor()->shouldBeginEditing(rangeOfContents(root).get());
362 }
363
364 static bool canAccessAncestor(const SecurityOrigin* activeSecurityOrigin, Frame* targetFrame)
365 {
366     // targetFrame can be 0 when we're trying to navigate a top-level frame
367     // that has a 0 opener.
368     if (!targetFrame)
369         return false;
370
371     const bool isLocalActiveOrigin = activeSecurityOrigin->isLocal();
372     for (Frame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame = ancestorFrame->tree()->parent()) {
373         Document* ancestorDocument = ancestorFrame->document();
374         // FIXME: Should be an ASSERT? Frames should alway have documents.
375         if (!ancestorDocument)
376             return true;
377
378         const SecurityOrigin* ancestorSecurityOrigin = ancestorDocument->securityOrigin();
379         if (activeSecurityOrigin->canAccess(ancestorSecurityOrigin))
380             return true;
381         
382         // Allow file URL descendant navigation even when allowFileAccessFromFileURLs is false.
383         // FIXME: It's a bit strange to special-case local origins here. Should we be doing
384         // something more general instead?
385         if (isLocalActiveOrigin && ancestorSecurityOrigin->isLocal())
386             return true;
387     }
388
389     return false;
390 }
391
392 static void printNavigationErrorMessage(Frame* frame, const KURL& activeURL)
393 {
394     // FIXME: this error message should contain more specifics of why the navigation change is not allowed.
395     String message = "Unsafe JavaScript attempt to initiate a navigation change for frame with URL " +
396                      frame->document()->url().string() + " from frame with URL " + activeURL.string() + ".\n";
397
398     // FIXME: should we print to the console of the document performing the navigation instead?
399     frame->domWindow()->printErrorMessage(message);
400 }
401
402 static HashSet<Document*>* documentsThatNeedStyleRecalc = 0;
403
404 class DocumentWeakReference : public ThreadSafeRefCounted<DocumentWeakReference> {
405 public:
406     static PassRefPtr<DocumentWeakReference> create(Document* document)
407     {
408         return adoptRef(new DocumentWeakReference(document));
409     }
410
411     Document* document()
412     {
413         ASSERT(isMainThread());
414         return m_document;
415     }
416
417     void clear()
418     {
419         ASSERT(isMainThread());
420         m_document = 0;
421     }
422
423 private:
424     DocumentWeakReference(Document* document)
425         : m_document(document)
426     {
427         ASSERT(isMainThread());
428     }
429
430     Document* m_document;
431 };
432
433 uint64_t Document::s_globalTreeVersion = 0;
434
435 Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
436     : ContainerNode(0, CreateDocument)
437     , TreeScope(this)
438     , m_guardRefCount(0)
439     , m_contextFeatures(ContextFeatures::defaultSwitch())
440     , m_compatibilityMode(NoQuirksMode)
441     , m_compatibilityModeLocked(false)
442     , m_domTreeVersion(++s_globalTreeVersion)
443 #if ENABLE(MUTATION_OBSERVERS)
444     , m_mutationObserverTypes(0)
445 #endif
446     , m_styleSheets(StyleSheetList::create(this))
447     , m_hadActiveLoadingStylesheet(false)
448     , m_readyState(Complete)
449     , m_styleRecalcTimer(this, &Document::styleRecalcTimerFired)
450     , m_pendingStyleRecalcShouldForce(false)
451     , m_frameElementsShouldIgnoreScrolling(false)
452     , m_containsValidityStyleRules(false)
453     , m_updateFocusAppearanceRestoresSelection(false)
454     , m_ignoreDestructiveWriteCount(0)
455     , m_titleSetExplicitly(false)
456     , m_updateFocusAppearanceTimer(this, &Document::updateFocusAppearanceTimerFired)
457     , m_loadEventFinished(false)
458     , m_startTime(currentTime())
459     , m_overMinimumLayoutThreshold(false)
460     , m_scriptRunner(ScriptRunner::create(this))
461     , m_xmlVersion("1.0")
462     , m_xmlStandalone(StandaloneUnspecified)
463     , m_hasXMLDeclaration(0)
464     , m_savedRenderer(0)
465     , m_designMode(inherit)
466 #if ENABLE(DASHBOARD_SUPPORT)
467     , m_hasDashboardRegions(false)
468     , m_dashboardRegionsDirty(false)
469 #endif
470     , m_createRenderers(true)
471     , m_inPageCache(false)
472     , m_accessKeyMapValid(false)
473     , m_useSecureKeyboardEntryWhenActive(false)
474     , m_isXHTML(isXHTML)
475     , m_isHTML(isHTML)
476     , m_isViewSource(false)
477     , m_sawElementsInKnownNamespaces(false)
478     , m_isSrcdocDocument(false)
479     , m_documentRareData(0)
480     , m_eventQueue(DocumentEventQueue::create(this))
481     , m_weakReference(DocumentWeakReference::create(this))
482     , m_idAttributeName(idAttr)
483 #if ENABLE(FULLSCREEN_API)
484     , m_areKeysEnabledInFullScreen(0)
485     , m_fullScreenRenderer(0)
486     , m_fullScreenChangeDelayTimer(this, &Document::fullScreenChangeDelayTimerFired)
487     , m_isAnimatingFullScreen(false)
488 #if ENABLE(TIZEN_FULLSCREEN_API)
489     , m_exitFullScreenByHwBackKey(false)
490 #endif
491 #endif
492     , m_loadEventDelayCount(0)
493     , m_loadEventDelayTimer(this, &Document::loadEventDelayTimerFired)
494     , m_referrerPolicy(ReferrerPolicyDefault)
495     , m_directionSetOnDocumentElement(false)
496     , m_writingModeSetOnDocumentElement(false)
497     , m_writeRecursionIsTooDeep(false)
498     , m_writeRecursionDepth(0)
499     , m_wheelEventHandlerCount(0)
500 #if ENABLE(TOUCH_EVENTS)
501     , m_touchEventHandlerCount(0)
502 #endif
503 #if ENABLE(UNDO_MANAGER)
504     , m_undoManager(0)
505 #endif
506     , m_pendingTasksTimer(this, &Document::pendingTasksTimerFired)
507     , m_scheduledTasksAreSuspended(false)
508     , m_visualUpdatesAllowed(true)
509     , m_visualUpdatesSuppressionTimer(this, &Document::visualUpdatesSuppressionTimerFired)
510 #ifndef NDEBUG
511     , m_didDispatchViewportPropertiesChanged(false)
512 #endif
513 #if ENABLE(TIZEN_GSTREAMER_AUDIO)
514     , m_activeMediaObjectCount(0)
515 #endif
516 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
517     , m_currentTargetNode(0)
518 #endif
519 {
520     m_document = this;
521
522     m_pageGroupUserSheetCacheValid = false;
523
524     m_printing = false;
525     m_paginatedForScreen = false;
526
527     m_ignoreAutofocus = false;
528
529     m_frame = frame;
530     if (m_frame)
531         provideContextFeaturesToDocumentFrom(this, m_frame->page());
532
533     // We depend on the url getting immediately set in subframes, but we
534     // also depend on the url NOT getting immediately set in opened windows.
535     // See fast/dom/early-frame-url.html
536     // and fast/dom/location-new-window-no-crash.html, respectively.
537     // FIXME: Can/should we unify this behavior?
538     if ((frame && frame->ownerElement()) || !url.isEmpty())
539         setURL(url);
540
541     m_axObjectCache = 0;
542
543     m_markers = adoptPtr(new DocumentMarkerController);
544
545     m_cachedResourceLoader = adoptPtr(new CachedResourceLoader(this));
546 #if ENABLE(LINK_PRERENDER)
547     m_prerenderer = Prerenderer::create(this);
548 #endif
549 #if ENABLE(TEXT_AUTOSIZING)
550     m_textAutosizer = TextAutosizer::create(this);
551 #endif
552     m_visuallyOrdered = false;
553     m_bParsing = false;
554     m_wellFormed = false;
555
556     m_textColor = Color::black;
557     m_listenerTypes = 0;
558     m_inStyleRecalc = false;
559     m_closeAfterStyleRecalc = false;
560
561     m_usesSiblingRules = false;
562     m_usesSiblingRulesOverride = false;
563     m_usesFirstLineRules = false;
564     m_usesFirstLetterRules = false;
565     m_usesBeforeAfterRules = false;
566     m_usesBeforeAfterRulesOverride = false;
567     m_usesRemUnits = false;
568     m_usesLinkRules = false;
569
570     m_gotoAnchorNeededAfterStylesheetsLoad = false;
571
572     m_didCalculateStyleResolver = false;
573     m_hasDirtyStyleResolver = false;
574     m_pendingStylesheets = 0;
575     m_ignorePendingStylesheets = false;
576     m_hasNodesWithPlaceholderStyle = false;
577     m_pendingSheetLayout = NoLayoutWithPendingSheets;
578
579     m_cssTarget = 0;
580
581     resetLinkColor();
582     resetVisitedLinkColor();
583     resetActiveLinkColor();
584
585     m_processingLoadEvent = false;
586     
587     initSecurityContext();
588     initDNSPrefetch();
589
590     static int docID = 0;
591     m_docID = docID++;
592
593     for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); i++)
594         m_nodeListCounts[i] = 0;
595
596     for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_collections); i++)
597         m_collections[i] = 0;
598
599     InspectorCounters::incrementCounter(InspectorCounters::DocumentCounter);
600 }
601
602 static void histogramMutationEventUsage(const unsigned short& listenerTypes)
603 {
604     HistogramSupport::histogramEnumeration("DOMAPI.PerDocumentMutationEventUsage.DOMSubtreeModified", static_cast<bool>(listenerTypes & Document::DOMSUBTREEMODIFIED_LISTENER), 2);
605     HistogramSupport::histogramEnumeration("DOMAPI.PerDocumentMutationEventUsage.DOMNodeInserted", static_cast<bool>(listenerTypes & Document::DOMNODEINSERTED_LISTENER), 2);
606     HistogramSupport::histogramEnumeration("DOMAPI.PerDocumentMutationEventUsage.DOMNodeRemoved", static_cast<bool>(listenerTypes & Document::DOMNODEREMOVED_LISTENER), 2);
607     HistogramSupport::histogramEnumeration("DOMAPI.PerDocumentMutationEventUsage.DOMNodeRemovedFromDocument", static_cast<bool>(listenerTypes & Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER), 2);
608     HistogramSupport::histogramEnumeration("DOMAPI.PerDocumentMutationEventUsage.DOMNodeInsertedIntoDocument", static_cast<bool>(listenerTypes & Document::DOMNODEINSERTEDINTODOCUMENT_LISTENER), 2);
609     HistogramSupport::histogramEnumeration("DOMAPI.PerDocumentMutationEventUsage.DOMCharacterDataModified", static_cast<bool>(listenerTypes & Document::DOMCHARACTERDATAMODIFIED_LISTENER), 2);
610 }
611
612 #if ENABLE(FULLSCREEN_API)
613 static bool isAttributeOnAllOwners(const WebCore::QualifiedName& attribute, const HTMLFrameOwnerElement* owner)
614 {
615     if (!owner)
616         return true;
617     do {
618         if (!owner->hasAttribute(attribute))
619             return false;
620     } while ((owner = owner->document()->ownerElement()));
621     return true;
622 }
623 #endif
624
625 Document::~Document()
626 {
627     ASSERT(!renderer());
628     ASSERT(!m_inPageCache);
629     ASSERT(!m_savedRenderer);
630     ASSERT(m_ranges.isEmpty());
631     ASSERT(!m_styleRecalcTimer.isActive());
632     ASSERT(!m_parentTreeScope);
633     ASSERT(!m_guardRefCount);
634
635     m_scriptRunner.clear();
636
637     histogramMutationEventUsage(m_listenerTypes);
638
639     removeAllEventListeners();
640
641     // Currently we believe that Document can never outlive the parser.
642     // Although the Document may be replaced synchronously, DocumentParsers
643     // generally keep at least one reference to an Element which would in turn
644     // has a reference to the Document.  If you hit this ASSERT, then that
645     // assumption is wrong.  DocumentParser::detach() should ensure that even
646     // if the DocumentParser outlives the Document it won't cause badness.
647     ASSERT(!m_parser || m_parser->refCount() == 1);
648     detachParser();
649
650     m_renderArena.clear();
651
652     clearAXObjectCache();
653
654     m_decoder = 0;
655
656     if (m_styleSheets)
657         m_styleSheets->documentDestroyed();
658
659     if (m_namedFlows)
660         m_namedFlows->documentDestroyed();
661
662     if (m_elemSheet)
663         m_elemSheet->clearOwnerNode();
664     if (m_pageUserSheet)
665         m_pageUserSheet->clearOwnerNode();
666     if (m_pageGroupUserSheets) {
667         for (size_t i = 0; i < m_pageGroupUserSheets->size(); ++i)
668             (*m_pageGroupUserSheets)[i]->clearOwnerNode();
669     }
670     if (m_userSheets) {
671         for (size_t i = 0; i < m_userSheets->size(); ++i)
672             (*m_userSheets)[i]->clearOwnerNode();
673     }
674
675     deleteCustomFonts();
676
677     m_weakReference->clear();
678
679     if (m_mediaQueryMatcher)
680         m_mediaQueryMatcher->documentDestroyed();
681
682     clearStyleResolver(); // We need to destory CSSFontSelector before destroying m_cachedResourceLoader.
683     m_cachedResourceLoader.clear();
684
685 #if ENABLE(UNDO_MANAGER)
686     if (m_undoManager)
687         m_undoManager->disconnect();
688 #endif
689
690     // We must call clearRareData() here since a Document class inherits TreeScope
691     // as well as Node. See a comment on TreeScope.h for the reason.
692     if (hasRareData())
693         clearRareData();
694
695     ASSERT(!m_listsInvalidatedAtDocument.size());
696
697     for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); i++)
698         ASSERT(!m_nodeListCounts[i]);
699
700     for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_collections); i++)
701         ASSERT(!m_collections[i]);
702
703     m_document = 0;
704
705     InspectorCounters::decrementCounter(InspectorCounters::DocumentCounter);
706 }
707
708 void Document::removedLastRef()
709 {
710     ASSERT(!m_deletionHasBegun);
711     if (m_guardRefCount) {
712         // If removing a child removes the last self-only ref, we don't
713         // want the scope to be destructed until after
714         // removeAllChildren returns, so we guard ourselves with an
715         // extra self-only ref.
716         guardRef();
717
718         // We must make sure not to be retaining any of our children through
719         // these extra pointers or we will create a reference cycle.
720         m_docType = 0;
721         m_focusedNode = 0;
722         m_hoverNode = 0;
723         m_activeNode = 0;
724         m_titleElement = 0;
725         m_documentElement = 0;
726 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
727         m_currentTargetNode = 0;
728 #endif
729         m_contextFeatures = ContextFeatures::defaultSwitch();
730 #if ENABLE(FULLSCREEN_API)
731         m_fullScreenElement = 0;
732         m_fullScreenElementStack.clear();
733 #endif
734
735         detachParser();
736
737         // removeAllChildren() doesn't always unregister IDs,
738         // so tear down scope information upfront to avoid having stale references in the map.
739         destroyTreeScopeData();
740         removeAllChildren();
741
742         m_markers->detach();
743
744         m_cssCanvasElements.clear();
745
746 #if ENABLE(REQUEST_ANIMATION_FRAME)
747         // FIXME: consider using ActiveDOMObject.
748         if (m_scriptedAnimationController)
749             m_scriptedAnimationController->clearDocumentPointer();
750         m_scriptedAnimationController.clear();
751 #endif
752
753 #ifndef NDEBUG
754         m_inRemovedLastRefFunction = false;
755 #endif
756
757         guardDeref();
758     } else {
759 #ifndef NDEBUG 
760         m_deletionHasBegun = true; 
761 #endif 
762         delete this;
763     }
764 }
765
766 Element* Document::getElementById(const AtomicString& id) const
767 {
768     return TreeScope::getElementById(id);
769 }
770
771 Element* Document::getElementByAccessKey(const String& key)
772 {
773     if (key.isEmpty())
774         return 0;
775     if (!m_accessKeyMapValid) {
776         buildAccessKeyMap(this);
777         m_accessKeyMapValid = true;
778     }
779     return m_elementsByAccessKey.get(key.impl());
780 }
781
782 void Document::buildAccessKeyMap(TreeScope* scope)
783 {
784     ASSERT(scope);
785     Node* rootNode = scope->rootNode();
786     for (Node* node = rootNode; node; node = node->traverseNextNode(rootNode)) {
787         if (!node->isElementNode())
788             continue;
789         Element* element = static_cast<Element*>(node);
790         const AtomicString& accessKey = element->getAttribute(accesskeyAttr);
791         if (!accessKey.isEmpty())
792             m_elementsByAccessKey.set(accessKey.impl(), element);
793
794         for (ShadowRoot* root = node->youngestShadowRoot(); root; root = root->olderShadowRoot())
795             buildAccessKeyMap(root);
796     }
797 }
798
799 void Document::invalidateAccessKeyMap()
800 {
801     m_accessKeyMapValid = false;
802     m_elementsByAccessKey.clear();
803 }
804
805 SelectorQueryCache* Document::selectorQueryCache()
806 {
807     if (!m_selectorQueryCache)
808         m_selectorQueryCache = adoptPtr(new SelectorQueryCache());
809     return m_selectorQueryCache.get();
810 }
811
812 MediaQueryMatcher* Document::mediaQueryMatcher()
813 {
814     if (!m_mediaQueryMatcher)
815         m_mediaQueryMatcher = MediaQueryMatcher::create(this);
816     return m_mediaQueryMatcher.get();
817 }
818
819 void Document::setCompatibilityMode(CompatibilityMode mode)
820 {
821     if (m_compatibilityModeLocked || mode == m_compatibilityMode)
822         return;
823     ASSERT(!m_styleSheets->length());
824     bool wasInQuirksMode = inQuirksMode();
825     m_compatibilityMode = mode;
826     selectorQueryCache()->invalidate();
827     if (inQuirksMode() != wasInQuirksMode) {
828         // All user stylesheets have to reparse using the different mode.
829         clearPageUserSheet();
830         clearPageGroupUserSheets();
831     }
832 }
833
834 String Document::compatMode() const
835 {
836     return inQuirksMode() ? "BackCompat" : "CSS1Compat";
837 }
838
839 void Document::resetLinkColor()
840 {
841     m_linkColor = Color(0, 0, 238);
842 }
843
844 void Document::resetVisitedLinkColor()
845 {
846     m_visitedLinkColor = Color(85, 26, 139);    
847 }
848
849 void Document::resetActiveLinkColor()
850 {
851     m_activeLinkColor.setNamedColor("red");
852 }
853
854 void Document::setDocType(PassRefPtr<DocumentType> docType)
855 {
856     // This should never be called more than once.
857     ASSERT(!m_docType || !docType);
858     m_docType = docType;
859     if (m_docType) {
860         this->adoptIfNeeded(m_docType.get());
861 #if ENABLE(LEGACY_VIEWPORT_ADAPTION)
862         if (m_docType->publicId().startsWith("-//wapforum//dtd xhtml mobile 1.", /* caseSensitive */ false))
863             processViewport("width=device-width, height=device-height", ViewportArguments::XHTMLMobileProfile);
864 #endif
865     }
866     // Doctype affects the interpretation of the stylesheets.
867     clearStyleResolver();
868 }
869
870 DOMImplementation* Document::implementation()
871 {
872     if (!m_implementation)
873         m_implementation = DOMImplementation::create(this);
874     return m_implementation.get();
875 }
876
877 void Document::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
878 {
879     ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
880     
881     Element* newDocumentElement = firstElementChild(this);
882     if (newDocumentElement == m_documentElement)
883         return;
884     m_documentElement = newDocumentElement;
885     // The root style used for media query matching depends on the document element.
886     clearStyleResolver();
887 }
888
889 PassRefPtr<Element> Document::createElement(const AtomicString& name, ExceptionCode& ec)
890 {
891     if (!isValidName(name)) {
892         ec = INVALID_CHARACTER_ERR;
893         return 0;
894     }
895
896     if (m_isXHTML)
897         return HTMLElementFactory::createHTMLElement(QualifiedName(nullAtom, name, xhtmlNamespaceURI), this, 0, false);
898
899     return createElement(QualifiedName(nullAtom, name, nullAtom), false);
900 }
901
902 PassRefPtr<DocumentFragment> Document::createDocumentFragment()
903 {
904     return DocumentFragment::create(document());
905 }
906
907 PassRefPtr<Text> Document::createTextNode(const String& data)
908 {
909     return Text::create(this, data);
910 }
911
912 PassRefPtr<Comment> Document::createComment(const String& data)
913 {
914     return Comment::create(this, data);
915 }
916
917 PassRefPtr<CDATASection> Document::createCDATASection(const String& data, ExceptionCode& ec)
918 {
919     if (isHTMLDocument()) {
920         ec = NOT_SUPPORTED_ERR;
921         return 0;
922     }
923     return CDATASection::create(this, data);
924 }
925
926 PassRefPtr<ProcessingInstruction> Document::createProcessingInstruction(const String& target, const String& data, ExceptionCode& ec)
927 {
928     if (!isValidName(target)) {
929         ec = INVALID_CHARACTER_ERR;
930         return 0;
931     }
932     if (isHTMLDocument()) {
933         ec = NOT_SUPPORTED_ERR;
934         return 0;
935     }
936     return ProcessingInstruction::create(this, target, data);
937 }
938
939 PassRefPtr<EntityReference> Document::createEntityReference(const String& name, ExceptionCode& ec)
940 {
941     if (!isValidName(name)) {
942         ec = INVALID_CHARACTER_ERR;
943         return 0;
944     }
945     if (isHTMLDocument()) {
946         ec = NOT_SUPPORTED_ERR;
947         return 0;
948     }
949     return EntityReference::create(this, name);
950 }
951
952 PassRefPtr<EditingText> Document::createEditingTextNode(const String& text)
953 {
954     return EditingText::create(this, text);
955 }
956
957 PassRefPtr<CSSStyleDeclaration> Document::createCSSStyleDeclaration()
958 {
959     return StylePropertySet::create()->ensureCSSStyleDeclaration();
960 }
961
962 PassRefPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionCode& ec)
963 {
964     ec = 0;
965     
966     if (!importedNode) {
967         ec = NOT_SUPPORTED_ERR;
968         return 0;
969     }
970
971     switch (importedNode->nodeType()) {
972     case TEXT_NODE:
973         return createTextNode(importedNode->nodeValue());
974     case CDATA_SECTION_NODE:
975         return createCDATASection(importedNode->nodeValue(), ec);
976     case ENTITY_REFERENCE_NODE:
977         return createEntityReference(importedNode->nodeName(), ec);
978     case PROCESSING_INSTRUCTION_NODE:
979         return createProcessingInstruction(importedNode->nodeName(), importedNode->nodeValue(), ec);
980     case COMMENT_NODE:
981         return createComment(importedNode->nodeValue());
982     case ELEMENT_NODE: {
983         Element* oldElement = static_cast<Element*>(importedNode);
984         // FIXME: The following check might be unnecessary. Is it possible that
985         // oldElement has mismatched prefix/namespace?
986         if (!hasValidNamespaceForElements(oldElement->tagQName())) {
987             ec = NAMESPACE_ERR;
988             return 0;
989         }
990         RefPtr<Element> newElement = createElement(oldElement->tagQName(), ec);
991         if (ec)
992             return 0;
993
994         newElement->cloneDataFromElement(*oldElement);
995
996         if (deep) {
997             for (Node* oldChild = oldElement->firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
998                 RefPtr<Node> newChild = importNode(oldChild, true, ec);
999                 if (ec)
1000                     return 0;
1001                 newElement->appendChild(newChild.release(), ec);
1002                 if (ec)
1003                     return 0;
1004             }
1005         }
1006
1007         return newElement.release();
1008     }
1009     case ATTRIBUTE_NODE:
1010         return Attr::create(this, QualifiedName(nullAtom, static_cast<Attr*>(importedNode)->name(), nullAtom), static_cast<Attr*>(importedNode)->value());
1011     case DOCUMENT_FRAGMENT_NODE: {
1012         if (importedNode->isShadowRoot()) {
1013             // ShadowRoot nodes should not be explicitly importable.
1014             // Either they are imported along with their host node, or created implicitly.
1015             break;
1016         }
1017         DocumentFragment* oldFragment = static_cast<DocumentFragment*>(importedNode);
1018         RefPtr<DocumentFragment> newFragment = createDocumentFragment();
1019         if (deep) {
1020             for (Node* oldChild = oldFragment->firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
1021                 RefPtr<Node> newChild = importNode(oldChild, true, ec);
1022                 if (ec)
1023                     return 0;
1024                 newFragment->appendChild(newChild.release(), ec);
1025                 if (ec)
1026                     return 0;
1027             }
1028         }
1029         
1030         return newFragment.release();
1031     }
1032     case ENTITY_NODE:
1033     case NOTATION_NODE:
1034         // 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.
1035         // Ability to add these imported nodes to a DocumentType will be considered for addition to a future release of the DOM.
1036     case DOCUMENT_NODE:
1037     case DOCUMENT_TYPE_NODE:
1038     case XPATH_NAMESPACE_NODE:
1039         break;
1040     }
1041     ec = NOT_SUPPORTED_ERR;
1042     return 0;
1043 }
1044
1045
1046 PassRefPtr<Node> Document::adoptNode(PassRefPtr<Node> source, ExceptionCode& ec)
1047 {
1048     if (!source) {
1049         ec = NOT_SUPPORTED_ERR;
1050         return 0;
1051     }
1052
1053     if (source->isReadOnlyNode()) {
1054         ec = NO_MODIFICATION_ALLOWED_ERR;
1055         return 0;
1056     }
1057
1058     EventQueueScope scope;
1059
1060     switch (source->nodeType()) {
1061     case ENTITY_NODE:
1062     case NOTATION_NODE:
1063     case DOCUMENT_NODE:
1064     case DOCUMENT_TYPE_NODE:
1065     case XPATH_NAMESPACE_NODE:
1066         ec = NOT_SUPPORTED_ERR;
1067         return 0;            
1068     case ATTRIBUTE_NODE: {                   
1069         Attr* attr = static_cast<Attr*>(source.get());
1070         if (attr->ownerElement())
1071             attr->ownerElement()->removeAttributeNode(attr, ec);
1072         attr->setSpecified(true);
1073         break;
1074     }       
1075     default:
1076         if (source->isShadowRoot()) {
1077             // ShadowRoot cannot disconnect itself from the host node.
1078             ec = HIERARCHY_REQUEST_ERR;
1079             return 0;
1080         }
1081
1082         // FIXME: What about <frame> and <object>?
1083         if (source->hasTagName(iframeTag)) {
1084             HTMLIFrameElement* iframe = static_cast<HTMLIFrameElement*>(source.get());
1085             if (frame() && frame()->tree()->isDescendantOf(iframe->contentFrame())) {
1086                 ec = HIERARCHY_REQUEST_ERR;
1087                 return 0;
1088             }
1089         }
1090         if (source->parentNode())
1091             source->parentNode()->removeChild(source.get(), ec);
1092     }
1093
1094     this->adoptIfNeeded(source.get());
1095
1096     return source;
1097 }
1098
1099 bool Document::hasValidNamespaceForElements(const QualifiedName& qName)
1100 {
1101     // These checks are from DOM Core Level 2, createElementNS
1102     // http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-DocCrElNS
1103     if (!qName.prefix().isEmpty() && qName.namespaceURI().isNull()) // createElementNS(null, "html:div")
1104         return false;
1105     if (qName.prefix() == xmlAtom && qName.namespaceURI() != XMLNames::xmlNamespaceURI) // createElementNS("http://www.example.com", "xml:lang")
1106         return false;
1107
1108     // Required by DOM Level 3 Core and unspecified by DOM Level 2 Core:
1109     // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-DocCrElNS
1110     // createElementNS("http://www.w3.org/2000/xmlns/", "foo:bar"), createElementNS(null, "xmlns:bar")
1111     if ((qName.prefix() == xmlnsAtom && qName.namespaceURI() != XMLNSNames::xmlnsNamespaceURI) || (qName.prefix() != xmlnsAtom && qName.namespaceURI() == XMLNSNames::xmlnsNamespaceURI))
1112         return false;
1113
1114     return true;
1115 }
1116
1117 bool Document::hasValidNamespaceForAttributes(const QualifiedName& qName)
1118 {
1119     // Spec: DOM Level 2 Core: http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-ElSetAttrNS
1120     if (qName.prefix().isEmpty() && qName.localName() == xmlnsAtom) {
1121         // Note: The case of an "xmlns" qualified name with a namespace of
1122         // xmlnsNamespaceURI is specifically allowed (See <http://www.w3.org/2000/xmlns/>).
1123         return qName.namespaceURI() == XMLNSNames::xmlnsNamespaceURI;
1124     }
1125     return hasValidNamespaceForElements(qName);
1126 }
1127
1128 // FIXME: This should really be in a possible ElementFactory class
1129 PassRefPtr<Element> Document::createElement(const QualifiedName& qName, bool createdByParser)
1130 {
1131     RefPtr<Element> e;
1132
1133     // FIXME: Use registered namespaces and look up in a hash to find the right factory.
1134     if (qName.namespaceURI() == xhtmlNamespaceURI)
1135         e = HTMLElementFactory::createHTMLElement(qName, this, 0, createdByParser);
1136 #if ENABLE(SVG)
1137     else if (qName.namespaceURI() == SVGNames::svgNamespaceURI)
1138         e = SVGElementFactory::createSVGElement(qName, this, createdByParser);
1139 #endif
1140 #if ENABLE(MATHML)
1141     else if (qName.namespaceURI() == MathMLNames::mathmlNamespaceURI)
1142         e = MathMLElementFactory::createMathMLElement(qName, this, createdByParser);
1143 #endif
1144
1145     if (e)
1146         m_sawElementsInKnownNamespaces = true;
1147     else
1148         e = Element::create(qName, document());
1149
1150     // <image> uses imgTag so we need a special rule.
1151     ASSERT((qName.matches(imageTag) && e->tagQName().matches(imgTag) && e->tagQName().prefix() == qName.prefix()) || qName == e->tagQName());
1152
1153     return e.release();
1154 }
1155
1156 bool Document::regionBasedColumnsEnabled() const
1157 {
1158     return settings() && settings()->regionBasedColumnsEnabled(); 
1159 }
1160
1161 bool Document::cssRegionsEnabled() const
1162 {
1163     return settings() && settings()->cssRegionsEnabled(); 
1164 }
1165
1166 bool Document::cssGridLayoutEnabled() const
1167 {
1168     return settings() && settings()->cssGridLayoutEnabled();
1169 }
1170
1171 #if ENABLE(CSS_REGIONS)
1172
1173 PassRefPtr<WebKitNamedFlow> Document::webkitGetFlowByName(const String& flowName)
1174 {
1175     if (!cssRegionsEnabled() || !renderer())
1176         return 0;
1177
1178     // It's possible to have pending styles not applied that affect the existing flows.
1179     updateStyleIfNeeded();
1180
1181     return namedFlows()->flowByName(flowName);
1182 }
1183 #endif
1184
1185 WebKitNamedFlowCollection* Document::namedFlows()
1186 {
1187     if (!m_namedFlows)
1188         m_namedFlows = WebKitNamedFlowCollection::create(this);
1189
1190     return m_namedFlows.get();
1191 }
1192
1193 PassRefPtr<Element> Document::createElementNS(const String& namespaceURI, const String& qualifiedName, ExceptionCode& ec)
1194 {
1195     String prefix, localName;
1196     if (!parseQualifiedName(qualifiedName, prefix, localName, ec))
1197         return 0;
1198
1199     QualifiedName qName(prefix, localName, namespaceURI);
1200     if (!hasValidNamespaceForElements(qName)) {
1201         ec = NAMESPACE_ERR;
1202         return 0;
1203     }
1204
1205     return createElement(qName, false);
1206 }
1207
1208 String Document::readyState() const
1209 {
1210     DEFINE_STATIC_LOCAL(const String, loading, ("loading"));
1211     DEFINE_STATIC_LOCAL(const String, interactive, ("interactive"));
1212     DEFINE_STATIC_LOCAL(const String, complete, ("complete"));
1213
1214     switch (m_readyState) {
1215     case Loading:
1216         return loading;
1217     case Interactive:
1218         return interactive;
1219     case Complete:
1220         return complete;
1221     }
1222
1223     ASSERT_NOT_REACHED();
1224     return String();
1225 }
1226
1227 void Document::setReadyState(ReadyState readyState)
1228 {
1229     if (readyState == m_readyState)
1230         return;
1231
1232     switch (readyState) {
1233     case Loading:
1234         if (!m_documentTiming.domLoading)
1235             m_documentTiming.domLoading = monotonicallyIncreasingTime();
1236         break;
1237     case Interactive:
1238         if (!m_documentTiming.domInteractive)
1239             m_documentTiming.domInteractive = monotonicallyIncreasingTime();
1240         break;
1241     case Complete:
1242         if (!m_documentTiming.domComplete)
1243             m_documentTiming.domComplete = monotonicallyIncreasingTime();
1244         break;
1245     }
1246
1247     m_readyState = readyState;
1248     dispatchEvent(Event::create(eventNames().readystatechangeEvent, false, false));
1249     
1250     if (settings() && settings()->suppressesIncrementalRendering())
1251         setVisualUpdatesAllowed(readyState);
1252 }
1253
1254 void Document::setVisualUpdatesAllowed(ReadyState readyState)
1255 {
1256     ASSERT(settings() && settings()->suppressesIncrementalRendering());
1257     switch (readyState) {
1258     case Loading:
1259         ASSERT(!m_visualUpdatesSuppressionTimer.isActive());
1260         ASSERT(m_visualUpdatesAllowed);
1261         m_visualUpdatesSuppressionTimer.startOneShot(settings()->incrementalRenderingSuppressionTimeoutInSeconds());
1262         setVisualUpdatesAllowed(false);
1263         break;
1264     case Interactive:
1265         ASSERT(m_visualUpdatesSuppressionTimer.isActive() || m_visualUpdatesAllowed);
1266         break;
1267     case Complete:
1268         if (m_visualUpdatesSuppressionTimer.isActive()) {
1269             ASSERT(!m_visualUpdatesAllowed);
1270             m_visualUpdatesSuppressionTimer.stop();
1271             setVisualUpdatesAllowed(true);
1272         } else
1273             ASSERT(m_visualUpdatesAllowed);
1274         break;
1275     }
1276 }
1277     
1278 void Document::setVisualUpdatesAllowed(bool visualUpdatesAllowed)
1279 {
1280     if (m_visualUpdatesAllowed == visualUpdatesAllowed)
1281         return;
1282
1283     m_visualUpdatesAllowed = visualUpdatesAllowed;
1284
1285     if (!visualUpdatesAllowed)
1286         return;
1287
1288 #if USE(ACCELERATED_COMPOSITING)
1289     if (view())
1290         view()->updateCompositingLayersAfterLayout();
1291 #endif
1292
1293     if (renderer())
1294         renderer()->repaint();
1295 }
1296
1297 void Document::visualUpdatesSuppressionTimerFired(Timer<Document>*)
1298 {
1299     ASSERT(!m_visualUpdatesAllowed);
1300     setVisualUpdatesAllowed(true);
1301 }
1302
1303 String Document::encoding() const
1304 {
1305     if (TextResourceDecoder* d = decoder())
1306         return d->encoding().domName();
1307     return String();
1308 }
1309
1310 String Document::defaultCharset() const
1311 {
1312     if (Settings* settings = this->settings())
1313         return settings->defaultTextEncodingName();
1314     return String();
1315 }
1316
1317 void Document::setCharset(const String& charset)
1318 {
1319     if (!decoder())
1320         return;
1321     decoder()->setEncoding(charset, TextResourceDecoder::UserChosenEncoding);
1322 }
1323
1324 void Document::setContentLanguage(const String& language)
1325 {
1326     if (m_contentLanguage == language)
1327         return;
1328     m_contentLanguage = language;
1329
1330     // Recalculate style so language is used when selecting the initial font.
1331     styleResolverChanged(DeferRecalcStyle);
1332 }
1333
1334 void Document::setXMLVersion(const String& version, ExceptionCode& ec)
1335 {
1336     if (!implementation()->hasFeature("XML", String())) {
1337         ec = NOT_SUPPORTED_ERR;
1338         return;
1339     }
1340
1341     if (!XMLDocumentParser::supportsXMLVersion(version)) {
1342         ec = NOT_SUPPORTED_ERR;
1343         return;
1344     }
1345
1346     m_xmlVersion = version;
1347 }
1348
1349 void Document::setXMLStandalone(bool standalone, ExceptionCode& ec)
1350 {
1351     if (!implementation()->hasFeature("XML", String())) {
1352         ec = NOT_SUPPORTED_ERR;
1353         return;
1354     }
1355
1356     m_xmlStandalone = standalone ? Standalone : NotStandalone;
1357 }
1358
1359 void Document::setDocumentURI(const String& uri)
1360 {
1361     // This property is read-only from JavaScript, but writable from Objective-C.
1362     m_documentURI = uri;
1363     updateBaseURL();
1364 }
1365
1366 KURL Document::baseURI() const
1367 {
1368     return m_baseURL;
1369 }
1370
1371 void Document::setContent(const String& content)
1372 {
1373     open();
1374     m_parser->append(content);
1375     close();
1376 }
1377
1378 String Document::suggestedMIMEType() const
1379 {
1380     if (m_document->isXHTMLDocument())
1381         return "application/xhtml+xml";
1382     if (m_document->isSVGDocument())
1383         return "image/svg+xml";
1384     if (m_document->xmlStandalone())
1385         return "text/xml";
1386     if (m_document->isHTMLDocument())
1387         return "text/html";
1388
1389     if (DocumentLoader* documentLoader = loader())
1390         return documentLoader->responseMIMEType();
1391     return String();
1392 }
1393
1394 // FIXME: We need to discuss the DOM API here at some point. Ideas:
1395 // * making it receive a rect as parameter, i.e. nodesFromRect(x, y, w, h);
1396 // * making it receive the expading size of each direction separately,
1397 //   i.e. nodesFromRect(x, y, topSize, rightSize, bottomSize, leftSize);
1398 PassRefPtr<NodeList> Document::nodesFromRect(int centerX, int centerY, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent) const
1399 {
1400     // FIXME: Share code between this, elementFromPoint and caretRangeFromPoint.
1401     if (!renderer())
1402         return 0;
1403     Frame* frame = this->frame();
1404     if (!frame)
1405         return 0;
1406     FrameView* frameView = frame->view();
1407     if (!frameView)
1408         return 0;
1409
1410     float zoomFactor = frame->pageZoomFactor();
1411     LayoutPoint point = roundedLayoutPoint(FloatPoint(centerX * zoomFactor + view()->scrollX(), centerY * zoomFactor + view()->scrollY()));
1412
1413     int type = HitTestRequest::ReadOnly | HitTestRequest::Active;
1414
1415     // When ignoreClipping is false, this method returns null for coordinates outside of the viewport.
1416     if (ignoreClipping)
1417         type |= HitTestRequest::IgnoreClipping;
1418     else if (!frameView->visibleContentRect().intersects(HitTestResult::rectForPoint(point, topPadding, rightPadding, bottomPadding, leftPadding)))
1419         return 0;
1420
1421     HitTestRequest request(type);
1422
1423     // Passing a zero padding will trigger a rect hit test, however for the purposes of nodesFromRect,
1424     // we special handle this case in order to return a valid NodeList.
1425     if (!topPadding && !rightPadding && !bottomPadding && !leftPadding) {
1426         HitTestResult result(point);
1427         return handleZeroPadding(request, result);
1428     }
1429
1430     enum ShadowContentFilterPolicy shadowContentFilterPolicy = allowShadowContent ? AllowShadowContent : DoNotAllowShadowContent;
1431     HitTestResult result(point, topPadding, rightPadding, bottomPadding, leftPadding, shadowContentFilterPolicy);
1432     renderView()->hitTest(request, result);
1433
1434     return StaticHashSetNodeList::adopt(result.rectBasedTestResult());
1435 }
1436
1437 PassRefPtr<NodeList> Document::handleZeroPadding(const HitTestRequest& request, HitTestResult& result) const
1438 {
1439     renderView()->hitTest(request, result);
1440
1441     Node* node = result.innerNode();
1442     if (!node)
1443         return 0;
1444
1445     node = node->shadowAncestorNode();
1446     ListHashSet<RefPtr<Node> > list;
1447     list.add(node);
1448     return StaticHashSetNodeList::adopt(list);
1449 }
1450
1451 static Node* nodeFromPoint(Frame* frame, RenderView* renderView, int x, int y, LayoutPoint* localPoint = 0)
1452 {
1453     if (!frame)
1454         return 0;
1455     FrameView* frameView = frame->view();
1456     if (!frameView)
1457         return 0;
1458
1459     float zoomFactor = frame->pageZoomFactor();
1460     IntPoint point = roundedIntPoint(FloatPoint(x * zoomFactor  + frameView->scrollX(), y * zoomFactor + frameView->scrollY()));
1461
1462     if (!frameView->visibleContentRect().contains(point))
1463         return 0;
1464
1465     HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
1466     HitTestResult result(point);
1467
1468     renderView->hitTest(request, result);
1469
1470     if (localPoint)
1471         *localPoint = result.localPoint();
1472
1473     return result.innerNode();
1474 }
1475
1476 Element* Document::elementFromPoint(int x, int y) const
1477 {
1478     if (!renderer())
1479         return 0;
1480     Node* node = nodeFromPoint(frame(), renderView(), x, y);
1481     while (node && !node->isElementNode())
1482         node = node->parentNode();
1483     if (node)
1484         node = ancestorInThisScope(node);
1485     return static_cast<Element*>(node);
1486 }
1487
1488 PassRefPtr<Range> Document::caretRangeFromPoint(int x, int y)
1489 {
1490     if (!renderer())
1491         return 0;
1492     LayoutPoint localPoint;
1493     Node* node = nodeFromPoint(frame(), renderView(), x, y, &localPoint);
1494     if (!node)
1495         return 0;
1496
1497     Node* shadowAncestorNode = ancestorInThisScope(node);
1498     if (shadowAncestorNode != node) {
1499         unsigned offset = shadowAncestorNode->nodeIndex();
1500         ContainerNode* container = shadowAncestorNode->parentNode();
1501         return Range::create(this, container, offset, container, offset);
1502     }
1503
1504     RenderObject* renderer = node->renderer();
1505     if (!renderer)
1506         return 0;
1507     VisiblePosition visiblePosition = renderer->positionForPoint(localPoint);
1508     if (visiblePosition.isNull())
1509         return 0;
1510
1511     Position rangeCompliantPosition = visiblePosition.deepEquivalent().parentAnchoredEquivalent();
1512     return Range::create(this, rangeCompliantPosition, rangeCompliantPosition);
1513 }
1514
1515 /*
1516  * Performs three operations:
1517  *  1. Convert control characters to spaces
1518  *  2. Trim leading and trailing spaces
1519  *  3. Collapse internal whitespace.
1520  */
1521 static inline StringWithDirection canonicalizedTitle(Document* document, const StringWithDirection& titleWithDirection)
1522 {
1523     const String& title = titleWithDirection.string();
1524     const UChar* characters = title.characters();
1525     unsigned length = title.length();
1526     unsigned i;
1527
1528     StringBuffer<UChar> buffer(length);
1529     unsigned builderIndex = 0;
1530
1531     // Skip leading spaces and leading characters that would convert to spaces
1532     for (i = 0; i < length; ++i) {
1533         UChar c = characters[i];
1534         if (!(c <= 0x20 || c == 0x7F))
1535             break;
1536     }
1537
1538     if (i == length)
1539         return StringWithDirection();
1540
1541     // Replace control characters with spaces, and backslashes with currency symbols, and collapse whitespace.
1542     bool previousCharWasWS = false;
1543     for (; i < length; ++i) {
1544         UChar c = characters[i];
1545         if (c <= 0x20 || c == 0x7F || (WTF::Unicode::category(c) & (WTF::Unicode::Separator_Line | WTF::Unicode::Separator_Paragraph))) {
1546             if (previousCharWasWS)
1547                 continue;
1548             buffer[builderIndex++] = ' ';
1549             previousCharWasWS = true;
1550         } else {
1551             buffer[builderIndex++] = c;
1552             previousCharWasWS = false;
1553         }
1554     }
1555
1556     // Strip trailing spaces
1557     while (builderIndex > 0) {
1558         --builderIndex;
1559         if (buffer[builderIndex] != ' ')
1560             break;
1561     }
1562
1563     if (!builderIndex && buffer[builderIndex] == ' ')
1564         return StringWithDirection();
1565
1566     buffer.shrink(builderIndex + 1);
1567
1568     // Replace the backslashes with currency symbols if the encoding requires it.
1569     document->displayBufferModifiedByEncoding(buffer.characters(), buffer.length());
1570     
1571     return StringWithDirection(String::adopt(buffer), titleWithDirection.direction());
1572 }
1573
1574 void Document::updateTitle(const StringWithDirection& title)
1575 {
1576     if (m_rawTitle == title)
1577         return;
1578
1579     m_rawTitle = title;
1580     m_title = canonicalizedTitle(this, m_rawTitle);
1581     if (Frame* f = frame())
1582         f->loader()->setTitle(m_title);
1583 }
1584
1585 void Document::setTitle(const String& title)
1586 {
1587     // Title set by JavaScript -- overrides any title elements.
1588     m_titleSetExplicitly = true;
1589     if (!isHTMLDocument() && !isXHTMLDocument())
1590         m_titleElement = 0;
1591     else if (!m_titleElement) {
1592         if (HTMLElement* headElement = head()) {
1593             m_titleElement = createElement(titleTag, false);
1594             ExceptionCode ec = 0;
1595             headElement->appendChild(m_titleElement, ec);
1596             ASSERT(!ec);
1597         }
1598     }
1599
1600     // The DOM API has no method of specifying direction, so assume LTR.
1601     updateTitle(StringWithDirection(title, LTR));
1602
1603     if (m_titleElement) {
1604         ASSERT(m_titleElement->hasTagName(titleTag));
1605         if (m_titleElement->hasTagName(titleTag))
1606             static_cast<HTMLTitleElement*>(m_titleElement.get())->setText(title);
1607     }
1608 }
1609
1610 void Document::setTitleElement(const StringWithDirection& title, Element* titleElement)
1611 {
1612     if (titleElement != m_titleElement) {
1613         if (m_titleElement || m_titleSetExplicitly)
1614             // Only allow the first title element to change the title -- others have no effect.
1615             return;
1616         m_titleElement = titleElement;
1617     }
1618
1619     updateTitle(title);
1620 }
1621
1622 void Document::removeTitle(Element* titleElement)
1623 {
1624     if (m_titleElement != titleElement)
1625         return;
1626
1627     m_titleElement = 0;
1628     m_titleSetExplicitly = false;
1629
1630     // Update title based on first title element in the head, if one exists.
1631     if (HTMLElement* headElement = head()) {
1632         for (Node* e = headElement->firstChild(); e; e = e->nextSibling())
1633             if (e->hasTagName(titleTag)) {
1634                 HTMLTitleElement* titleElement = static_cast<HTMLTitleElement*>(e);
1635                 setTitleElement(titleElement->textWithDirection(), titleElement);
1636                 break;
1637             }
1638     }
1639
1640     if (!m_titleElement)
1641         updateTitle(StringWithDirection());
1642 }
1643
1644 #if ENABLE(PAGE_VISIBILITY_API)
1645 PageVisibilityState Document::visibilityState() const
1646 {
1647     // The visibility of the document is inherited from the visibility of the
1648     // page. If there is no page associated with the document, we will assume
1649     // that the page is hidden, as specified by the spec:
1650     // http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html#dom-document-hidden
1651     if (!m_frame || !m_frame->page())
1652         return PageVisibilityStateHidden;
1653     return m_frame->page()->visibilityState();
1654 }
1655
1656 String Document::webkitVisibilityState() const
1657 {
1658     return pageVisibilityStateString(visibilityState());
1659 }
1660
1661 bool Document::webkitHidden() const
1662 {
1663     return visibilityState() != PageVisibilityStateVisible;
1664 }
1665
1666 void Document::dispatchVisibilityStateChangeEvent()
1667 {
1668 #if ENABLE(TIZEN_GSTREAMER_AUDIO)
1669     if (m_activeMediaObjectCount) {
1670         if (!webkitHidden())
1671             AudioSessionManagerGStreamerTizen::setVolumeSessionToMediaType();
1672         else
1673             AudioSessionManagerGStreamerTizen::clearVolumeSessionFromMediaType();
1674     }
1675 #endif
1676     dispatchEvent(Event::create(eventNames().webkitvisibilitychangeEvent, false, false));
1677 }
1678 #endif
1679
1680 #if ENABLE(CSP_NEXT)
1681 DOMSecurityPolicy* Document::securityPolicy()
1682 {
1683     if (!m_domSecurityPolicy)
1684         m_domSecurityPolicy = DOMSecurityPolicy::create(this);
1685     return m_domSecurityPolicy.get();
1686 }
1687 #endif
1688
1689 String Document::nodeName() const
1690 {
1691     return "#document";
1692 }
1693
1694 Node::NodeType Document::nodeType() const
1695 {
1696     return DOCUMENT_NODE;
1697 }
1698
1699 FormController* Document::formController()
1700 {
1701     if (!m_formController)
1702         m_formController = FormController::create();
1703     return m_formController.get();
1704 }
1705
1706 Vector<String> Document::formElementsState() const
1707 {
1708     if (!m_formController)
1709         return Vector<String>();
1710     return m_formController->formElementsState();
1711 }
1712
1713 void Document::setStateForNewFormElements(const Vector<String>& stateVector)
1714 {
1715     if (!stateVector.size() && !m_formController)
1716         return;
1717     formController()->setStateForNewFormElements(stateVector);
1718 }
1719
1720 FrameView* Document::view() const
1721 {
1722     return m_frame ? m_frame->view() : 0;
1723 }
1724
1725 Page* Document::page() const
1726 {
1727     return m_frame ? m_frame->page() : 0;    
1728 }
1729
1730 Settings* Document::settings() const
1731 {
1732     return m_frame ? m_frame->settings() : 0;
1733 }
1734
1735 PassRefPtr<Range> Document::createRange()
1736 {
1737     return Range::create(this);
1738 }
1739
1740 PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, 
1741     PassRefPtr<NodeFilter> filter, bool expandEntityReferences, ExceptionCode& ec)
1742 {
1743     if (!root) {
1744         ec = NOT_SUPPORTED_ERR;
1745         return 0;
1746     }
1747     return NodeIterator::create(root, whatToShow, filter, expandEntityReferences);
1748 }
1749
1750 PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, 
1751     PassRefPtr<NodeFilter> filter, bool expandEntityReferences, ExceptionCode& ec)
1752 {
1753     if (!root) {
1754         ec = NOT_SUPPORTED_ERR;
1755         return 0;
1756     }
1757     return TreeWalker::create(root, whatToShow, filter, expandEntityReferences);
1758 }
1759
1760 void Document::scheduleForcedStyleRecalc()
1761 {
1762     m_pendingStyleRecalcShouldForce = true;
1763     scheduleStyleRecalc();
1764 }
1765
1766 void Document::scheduleStyleRecalc()
1767 {
1768     if (shouldDisplaySeamlesslyWithParent()) {
1769         // When we're seamless, our parent document manages our style recalcs.
1770         ownerElement()->setNeedsStyleRecalc();
1771         ownerElement()->document()->scheduleStyleRecalc();
1772         return;
1773     }
1774
1775     if (m_styleRecalcTimer.isActive() || inPageCache())
1776         return;
1777
1778     ASSERT(childNeedsStyleRecalc() || m_pendingStyleRecalcShouldForce);
1779
1780     if (!documentsThatNeedStyleRecalc)
1781         documentsThatNeedStyleRecalc = new HashSet<Document*>;
1782     documentsThatNeedStyleRecalc->add(this);
1783     
1784     // FIXME: Why on earth is this here? This is clearly misplaced.
1785     invalidateAccessKeyMap();
1786     
1787     m_styleRecalcTimer.startOneShot(0);
1788
1789     InspectorInstrumentation::didScheduleStyleRecalculation(this);
1790 }
1791
1792 void Document::unscheduleStyleRecalc()
1793 {
1794     ASSERT(!childNeedsStyleRecalc());
1795
1796     if (documentsThatNeedStyleRecalc)
1797         documentsThatNeedStyleRecalc->remove(this);
1798
1799     m_styleRecalcTimer.stop();
1800     m_pendingStyleRecalcShouldForce = false;
1801 }
1802
1803 bool Document::isPendingStyleRecalc() const
1804 {
1805     return m_styleRecalcTimer.isActive() && !m_inStyleRecalc;
1806 }
1807
1808 void Document::styleRecalcTimerFired(Timer<Document>*)
1809 {
1810     updateStyleIfNeeded();
1811 }
1812
1813 bool Document::childNeedsAndNotInStyleRecalc()
1814 {
1815     return childNeedsStyleRecalc() && !m_inStyleRecalc;
1816 }
1817
1818 void Document::recalcStyle(StyleChange change)
1819 {
1820     // we should not enter style recalc while painting
1821     if (view() && view()->isPainting()) {
1822         ASSERT(!view()->isPainting());
1823         return;
1824     }
1825     
1826     if (m_inStyleRecalc)
1827         return; // Guard against re-entrancy. -dwh
1828
1829     // FIXME: We should update style on our ancestor chain before proceeding (especially for seamless),
1830     // however doing so currently causes several tests to crash, as Frame::setDocument calls Document::attach
1831     // before setting the DOMWindow on the Frame, or the SecurityOrigin on the document. The attach, in turn
1832     // resolves style (here) and then when we resolve style on the parent chain, we may end up
1833     // re-attaching our containing iframe, which when asked HTMLFrameElementBase::isURLAllowed
1834     // hits a null-dereference due to security code always assuming the document has a SecurityOrigin.
1835
1836     if (m_hasDirtyStyleResolver)
1837         updateActiveStylesheets(RecalcStyleImmediately);
1838
1839     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRecalculateStyle(this);
1840
1841     if (m_elemSheet && m_elemSheet->contents()->usesRemUnits())
1842         m_usesRemUnits = true;
1843
1844     m_inStyleRecalc = true;
1845     suspendPostAttachCallbacks();
1846     RenderWidget::suspendWidgetHierarchyUpdates();
1847     
1848     RefPtr<FrameView> frameView = view();
1849     if (frameView) {
1850         frameView->pauseScheduledEvents();
1851         frameView->beginDeferredRepaints();
1852     }
1853
1854     ASSERT(!renderer() || renderArena());
1855     if (!renderer() || !renderArena())
1856         goto bail_out;
1857
1858     if (m_pendingStyleRecalcShouldForce)
1859         change = Force;
1860
1861     // Recalculating the root style (on the document) is not needed in the common case.
1862     if ((change == Force) || (shouldDisplaySeamlesslyWithParent() && (change >= Inherit))) {
1863         // style selector may set this again during recalc
1864         m_hasNodesWithPlaceholderStyle = false;
1865         
1866         RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(this, m_styleResolver ? m_styleResolver->fontSelector() : 0);
1867         StyleChange ch = Node::diff(documentStyle.get(), renderer()->style(), this);
1868         if (ch != NoChange)
1869             renderer()->setStyle(documentStyle.release());
1870     }
1871
1872     for (Node* n = firstChild(); n; n = n->nextSibling()) {
1873         if (!n->isElementNode())
1874             continue;
1875         Element* element = static_cast<Element*>(n);
1876         if (change >= Inherit || element->childNeedsStyleRecalc() || element->needsStyleRecalc())
1877             element->recalcStyle(change);
1878     }
1879
1880 #if USE(ACCELERATED_COMPOSITING)
1881     if (view()) {
1882         bool layoutPending = view()->layoutPending() || renderer()->needsLayout();
1883         // If we didn't update compositing layers because of layout(), we need to do so here.
1884         if (!layoutPending)
1885             view()->updateCompositingLayersAfterStyleChange();
1886     }
1887 #endif
1888
1889 bail_out:
1890     clearNeedsStyleRecalc();
1891     clearChildNeedsStyleRecalc();
1892     unscheduleStyleRecalc();
1893
1894     m_inStyleRecalc = false;
1895     
1896     // Pseudo element removal and similar may only work with these flags still set. Reset them after the style recalc.
1897     if (m_styleResolver)
1898         resetCSSFeatureFlags();
1899
1900     if (frameView) {
1901         frameView->resumeScheduledEvents();
1902         frameView->endDeferredRepaints();
1903     }
1904     RenderWidget::resumeWidgetHierarchyUpdates();
1905     resumePostAttachCallbacks();
1906
1907     // If we wanted to call implicitClose() during recalcStyle, do so now that we're finished.
1908     if (m_closeAfterStyleRecalc) {
1909         m_closeAfterStyleRecalc = false;
1910         implicitClose();
1911     }
1912
1913     InspectorInstrumentation::didRecalculateStyle(cookie);
1914 }
1915
1916 void Document::updateStyleIfNeeded()
1917 {
1918     ASSERT(isMainThread());
1919     ASSERT(!view() || (!view()->isInLayout() && !view()->isPainting()));
1920     
1921     if ((!m_pendingStyleRecalcShouldForce && !childNeedsStyleRecalc()) || inPageCache())
1922         return;
1923
1924     AnimationUpdateBlock animationUpdateBlock(m_frame ? m_frame->animation() : 0);
1925     recalcStyle(NoChange);
1926 }
1927
1928 void Document::updateStyleForAllDocuments()
1929 {
1930     ASSERT(isMainThread());
1931     if (!documentsThatNeedStyleRecalc)
1932         return;
1933
1934     while (documentsThatNeedStyleRecalc->size()) {
1935         HashSet<Document*>::iterator it = documentsThatNeedStyleRecalc->begin();
1936         Document* doc = *it;
1937         documentsThatNeedStyleRecalc->remove(doc);
1938         doc->updateStyleIfNeeded();
1939     }
1940 }
1941
1942 void Document::updateLayout()
1943 {
1944     ASSERT(isMainThread());
1945     if (Element* oe = ownerElement())
1946         oe->document()->updateLayout();
1947
1948     updateStyleIfNeeded();
1949
1950     // Only do a layout if changes have occurred that make it necessary.      
1951     FrameView* v = view();
1952     if (v && renderer() && (v->layoutPending() || renderer()->needsLayout()))
1953         v->layout();
1954 }
1955
1956 // FIXME: This is a bad idea and needs to be removed eventually.
1957 // Other browsers load stylesheets before they continue parsing the web page.
1958 // Since we don't, we can run JavaScript code that needs answers before the
1959 // stylesheets are loaded. Doing a layout ignoring the pending stylesheets
1960 // lets us get reasonable answers. The long term solution to this problem is
1961 // to instead suspend JavaScript execution.
1962 void Document::updateLayoutIgnorePendingStylesheets()
1963 {
1964     bool oldIgnore = m_ignorePendingStylesheets;
1965     
1966     if (!haveStylesheetsLoaded()) {
1967         m_ignorePendingStylesheets = true;
1968         // FIXME: We are willing to attempt to suppress painting with outdated style info only once.  Our assumption is that it would be
1969         // dangerous to try to stop it a second time, after page content has already been loaded and displayed
1970         // with accurate style information.  (Our suppression involves blanking the whole page at the
1971         // moment.  If it were more refined, we might be able to do something better.)
1972         // It's worth noting though that this entire method is a hack, since what we really want to do is
1973         // suspend JS instead of doing a layout with inaccurate information.
1974         HTMLElement* bodyElement = body();
1975         if (bodyElement && !bodyElement->renderer() && m_pendingSheetLayout == NoLayoutWithPendingSheets) {
1976             m_pendingSheetLayout = DidLayoutWithPendingSheets;
1977             styleResolverChanged(RecalcStyleImmediately);
1978         } else if (m_hasNodesWithPlaceholderStyle)
1979             // If new nodes have been added or style recalc has been done with style sheets still pending, some nodes 
1980             // may not have had their real style calculated yet. Normally this gets cleaned when style sheets arrive 
1981             // but here we need up-to-date style immediately.
1982             recalcStyle(Force);
1983     }
1984
1985     updateLayout();
1986
1987     m_ignorePendingStylesheets = oldIgnore;
1988 }
1989
1990 PassRefPtr<RenderStyle> Document::styleForElementIgnoringPendingStylesheets(Element* element)
1991 {
1992     ASSERT_ARG(element, element->document() == this);
1993
1994     bool oldIgnore = m_ignorePendingStylesheets;
1995     m_ignorePendingStylesheets = true;
1996     RefPtr<RenderStyle> style = styleResolver()->styleForElement(element, element->parentNode() ? element->parentNode()->computedStyle() : 0);
1997     m_ignorePendingStylesheets = oldIgnore;
1998     return style.release();
1999 }
2000
2001 PassRefPtr<RenderStyle> Document::styleForPage(int pageIndex)
2002 {
2003     RefPtr<RenderStyle> style = styleResolver()->styleForPage(pageIndex);
2004     return style.release();
2005 }
2006
2007 void Document::registerCustomFont(PassOwnPtr<FontData> fontData)
2008 {
2009     m_customFonts.append(fontData);
2010 }
2011
2012 void Document::deleteCustomFonts()
2013 {
2014     size_t size = m_customFonts.size();
2015     for (size_t i = 0; i < size; ++i)
2016         GlyphPageTreeNode::pruneTreeCustomFontData(m_customFonts[i].get());
2017
2018     m_customFonts.clear();
2019 }
2020
2021 bool Document::isPageBoxVisible(int pageIndex)
2022 {
2023     RefPtr<RenderStyle> style = styleForPage(pageIndex);
2024     return style->visibility() != HIDDEN; // display property doesn't apply to @page.
2025 }
2026
2027 void Document::pageSizeAndMarginsInPixels(int pageIndex, IntSize& pageSize, int& marginTop, int& marginRight, int& marginBottom, int& marginLeft)
2028 {
2029     RefPtr<RenderStyle> style = styleForPage(pageIndex);
2030     RenderView* view = renderView();
2031
2032     int width = pageSize.width();
2033     int height = pageSize.height();
2034     switch (style->pageSizeType()) {
2035     case PAGE_SIZE_AUTO:
2036         break;
2037     case PAGE_SIZE_AUTO_LANDSCAPE:
2038         if (width < height)
2039             std::swap(width, height);
2040         break;
2041     case PAGE_SIZE_AUTO_PORTRAIT:
2042         if (width > height)
2043             std::swap(width, height);
2044         break;
2045     case PAGE_SIZE_RESOLVED: {
2046         LengthSize size = style->pageSize();
2047         ASSERT(size.width().isFixed());
2048         ASSERT(size.height().isFixed());
2049         width = valueForLength(size.width(), 0, view);
2050         height = valueForLength(size.height(), 0, view);
2051         break;
2052     }
2053     default:
2054         ASSERT_NOT_REACHED();
2055     }
2056     pageSize = IntSize(width, height);
2057
2058     // The percentage is calculated with respect to the width even for margin top and bottom.
2059     // http://www.w3.org/TR/CSS2/box.html#margin-properties
2060     marginTop = style->marginTop().isAuto() ? marginTop : intValueForLength(style->marginTop(), width, view);
2061     marginRight = style->marginRight().isAuto() ? marginRight : intValueForLength(style->marginRight(), width, view);
2062     marginBottom = style->marginBottom().isAuto() ? marginBottom : intValueForLength(style->marginBottom(), width, view);
2063     marginLeft = style->marginLeft().isAuto() ? marginLeft : intValueForLength(style->marginLeft(), width, view);
2064 }
2065
2066 void Document::setDocumentRareData(NodeRareData* rareData)
2067 {
2068     m_documentRareData = rareData;
2069 }
2070
2071 void Document::setIsViewSource(bool isViewSource)
2072 {
2073     m_isViewSource = isViewSource;
2074     if (!m_isViewSource)
2075         return;
2076
2077     setSecurityOrigin(SecurityOrigin::createUnique());
2078 }
2079
2080 void Document::combineCSSFeatureFlags()
2081 {
2082     // Delay resetting the flags until after next style recalc since unapplying the style may not work without these set (this is true at least with before/after).
2083     m_usesSiblingRules = m_usesSiblingRules || m_styleResolver->usesSiblingRules();
2084     m_usesFirstLineRules = m_usesFirstLineRules || m_styleResolver->usesFirstLineRules();
2085     m_usesBeforeAfterRules = m_usesBeforeAfterRules || m_styleResolver->usesBeforeAfterRules();
2086     m_usesLinkRules = m_usesLinkRules || m_styleResolver->usesLinkRules();
2087 }
2088
2089 void Document::resetCSSFeatureFlags()
2090 {
2091     m_usesSiblingRules = m_styleResolver->usesSiblingRules();
2092     m_usesFirstLineRules = m_styleResolver->usesFirstLineRules();
2093     m_usesBeforeAfterRules = m_styleResolver->usesBeforeAfterRules();
2094     m_usesLinkRules = m_styleResolver->usesLinkRules();
2095 }
2096
2097 void Document::createStyleResolver()
2098 {
2099     bool matchAuthorAndUserStyles = true;
2100     if (Settings* docSettings = settings())
2101         matchAuthorAndUserStyles = docSettings->authorAndUserStylesEnabled();
2102     m_styleResolver = adoptPtr(new StyleResolver(this, matchAuthorAndUserStyles));
2103     combineCSSFeatureFlags();
2104 }
2105
2106 inline void Document::clearStyleResolver()
2107 {
2108     m_styleResolver.clear();
2109 }
2110
2111 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
2112 void Document::setCurrentTargetNode(PassRefPtr<Node> prpNode)
2113 {
2114     m_currentTargetNode = prpNode;
2115 }
2116 #endif
2117
2118 void Document::attach()
2119 {
2120     ASSERT(!attached());
2121     ASSERT(!m_inPageCache);
2122     ASSERT(!m_axObjectCache || this != topDocument());
2123
2124     if (!m_renderArena)
2125         m_renderArena = adoptPtr(new RenderArena);
2126     
2127     // Create the rendering tree
2128     setRenderer(new (m_renderArena.get()) RenderView(this, view()));
2129 #if USE(ACCELERATED_COMPOSITING)
2130     renderView()->didMoveOnscreen();
2131 #endif
2132
2133     recalcStyle(Force);
2134
2135     RenderObject* render = renderer();
2136     setRenderer(0);
2137
2138     ContainerNode::attach();
2139
2140     setRenderer(render);
2141 }
2142
2143 void Document::detach()
2144 {
2145     ASSERT(attached());
2146     ASSERT(!m_inPageCache);
2147
2148 #if ENABLE(POINTER_LOCK)
2149     if (page())
2150         page()->pointerLockController()->documentDetached(this);
2151 #endif
2152
2153     if (this == topDocument())
2154         clearAXObjectCache();
2155
2156     stopActiveDOMObjects();
2157     m_eventQueue->close();
2158 #if ENABLE(FULLSCREEN_API)
2159     m_fullScreenChangeEventTargetQueue.clear();
2160     m_fullScreenErrorEventTargetQueue.clear();
2161 #endif
2162
2163 #if ENABLE(REQUEST_ANIMATION_FRAME)
2164     // FIXME: consider using ActiveDOMObject.
2165     if (m_scriptedAnimationController)
2166         m_scriptedAnimationController->clearDocumentPointer();
2167     m_scriptedAnimationController.clear();
2168 #endif
2169
2170     RenderObject* render = renderer();
2171
2172     documentWillBecomeInactive();
2173
2174 #if ENABLE(SHARED_WORKERS)
2175     SharedWorkerRepository::documentDetached(this);
2176 #endif
2177
2178     if (m_frame) {
2179         FrameView* view = m_frame->view();
2180         if (view)
2181             view->detachCustomScrollbars();
2182
2183     }
2184
2185     // indicate destruction mode,  i.e. attached() but renderer == 0
2186     setRenderer(0);
2187     
2188 #if ENABLE(FULLSCREEN_API)
2189     if (m_fullScreenRenderer)
2190         setFullScreenRenderer(0);
2191 #endif
2192
2193     m_hoverNode = 0;
2194     m_focusedNode = 0;
2195     m_activeNode = 0;
2196 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
2197     m_currentTargetNode = 0;
2198 #endif
2199
2200     ContainerNode::detach();
2201
2202     unscheduleStyleRecalc();
2203
2204     if (render)
2205         render->destroy();
2206     
2207     // This is required, as our Frame might delete itself as soon as it detaches
2208     // us. However, this violates Node::detach() semantics, as it's never
2209     // possible to re-attach. Eventually Document::detach() should be renamed,
2210     // or this setting of the frame to 0 could be made explicit in each of the
2211     // callers of Document::detach().
2212     m_frame = 0;
2213     m_renderArena.clear();
2214 }
2215
2216 void Document::prepareForDestruction()
2217 {
2218     disconnectDescendantFrames();
2219     if (DOMWindow* window = this->domWindow())
2220         window->willDetachDocumentFromFrame();
2221     detach();
2222 }
2223
2224 void Document::removeAllEventListeners()
2225 {
2226     EventTarget::removeAllEventListeners();
2227
2228     if (DOMWindow* domWindow = this->domWindow())
2229         domWindow->removeAllEventListeners();
2230     for (Node* node = firstChild(); node; node = node->traverseNextNode())
2231         node->removeAllEventListeners();
2232 }
2233
2234 void Document::suspendActiveDOMObjects(ActiveDOMObject::ReasonForSuspension why)
2235 {
2236     ScriptExecutionContext::suspendActiveDOMObjects(why);
2237
2238 #if ENABLE(DEVICE_ORIENTATION)
2239     if (!page())
2240         return;
2241
2242     if (DeviceMotionController* controller = DeviceMotionController::from(page()))
2243         controller->suspendEventsForAllListeners(domWindow());
2244     if (DeviceOrientationController* controller = DeviceOrientationController::from(page()))
2245         controller->suspendEventsForAllListeners(domWindow());
2246
2247 #endif
2248
2249 #if ENABLE(TIZEN_WEBKIT2_NOTIFY_SUSPEND_BY_REMOTE_WEB_INSPECTOR)
2250     if (why == ActiveDOMObject::JavaScriptDebuggerPaused)
2251         page()->chrome()->setContentSuspendedByInspector(true);
2252 #endif
2253 }
2254
2255 void Document::resumeActiveDOMObjects()
2256 {
2257     ScriptExecutionContext::resumeActiveDOMObjects();
2258
2259 #if ENABLE(DEVICE_ORIENTATION)
2260     if (!page())
2261         return;
2262
2263     if (DeviceMotionController* controller = DeviceMotionController::from(page()))
2264         controller->resumeEventsForAllListeners(domWindow());
2265     if (DeviceOrientationController* controller = DeviceOrientationController::from(page()))
2266         controller->resumeEventsForAllListeners(domWindow());
2267 #endif
2268
2269 #if ENABLE(TIZEN_WEBKIT2_NOTIFY_SUSPEND_BY_REMOTE_WEB_INSPECTOR)
2270     page()->chrome()->setContentSuspendedByInspector(false);
2271 #endif
2272 }
2273
2274 RenderView* Document::renderView() const
2275 {
2276     return toRenderView(renderer());
2277 }
2278
2279 void Document::clearAXObjectCache()
2280 {
2281     // clear cache in top document
2282     if (m_axObjectCache) {
2283         // Clear the cache member variable before calling delete because attempts
2284         // are made to access it during destruction.
2285         AXObjectCache* axObjectCache = m_axObjectCache;
2286         m_axObjectCache = 0;
2287         delete axObjectCache;
2288         return;
2289     }
2290     
2291     // ask the top-level document to clear its cache
2292     Document* doc = topDocument();
2293     if (doc != this)
2294         doc->clearAXObjectCache();
2295 }
2296
2297 bool Document::axObjectCacheExists() const
2298 {
2299     if (m_axObjectCache)
2300         return true;
2301     
2302     Document* doc = topDocument();
2303     if (doc != this)
2304         return doc->axObjectCacheExists();
2305     
2306     return false;
2307 }
2308     
2309 AXObjectCache* Document::axObjectCache() const
2310 {
2311     // The only document that actually has a AXObjectCache is the top-level
2312     // document.  This is because we need to be able to get from any WebCoreAXObject
2313     // to any other WebCoreAXObject on the same page.  Using a single cache allows
2314     // lookups across nested webareas (i.e. multiple documents).
2315     
2316     if (m_axObjectCache) {
2317         // return already known top-level cache
2318         if (!ownerElement())
2319             return m_axObjectCache;
2320         
2321         // In some pages with frames, the cache is created before the sub-webarea is
2322         // inserted into the tree.  Here, we catch that case and just toss the old
2323         // cache and start over.
2324         // NOTE: This recovery may no longer be needed. I have been unable to trigger
2325         // it again. See rdar://5794454
2326         // FIXME: Can this be fixed when inserting the subframe instead of now?
2327         // FIXME: If this function was called to get the cache in order to remove
2328         // an AXObject, we are now deleting the cache as a whole and returning a
2329         // new empty cache that does not contain the AXObject! That should actually
2330         // be OK. I am concerned about other cases like this where accessing the
2331         // cache blows away the AXObject being operated on.
2332         delete m_axObjectCache;
2333         m_axObjectCache = 0;
2334     }
2335
2336     // ask the top-level document for its cache
2337     Document* doc = topDocument();
2338     if (doc != this)
2339         return doc->axObjectCache();
2340     
2341     // this is the top-level document, so install a new cache
2342     m_axObjectCache = new AXObjectCache(this);
2343     return m_axObjectCache;
2344 }
2345
2346 void Document::setVisuallyOrdered()
2347 {
2348     m_visuallyOrdered = true;
2349     if (renderer())
2350         renderer()->style()->setRTLOrdering(VisualOrder);
2351 }
2352
2353 PassRefPtr<DocumentParser> Document::createParser()
2354 {
2355     // FIXME: this should probably pass the frame instead
2356 #if ENABLE(NEW_XML)
2357     return NewXMLDocumentParser::create(this);
2358 #else
2359     return XMLDocumentParser::create(this, view());
2360 #endif
2361 }
2362
2363 ScriptableDocumentParser* Document::scriptableDocumentParser() const
2364 {
2365     return parser() ? parser()->asScriptableDocumentParser() : 0;
2366 }
2367
2368 void Document::open(Document* ownerDocument)
2369 {
2370     if (ownerDocument) {
2371         setURL(ownerDocument->url());
2372         m_cookieURL = ownerDocument->cookieURL();
2373         setSecurityOrigin(ownerDocument->securityOrigin());
2374     }
2375
2376     if (m_frame) {
2377         if (ScriptableDocumentParser* parser = scriptableDocumentParser()) {
2378             if (parser->isParsing()) {
2379                 // FIXME: HTML5 doesn't tell us to check this, it might not be correct.
2380                 if (parser->isExecutingScript())
2381                     return;
2382
2383                 if (!parser->wasCreatedByScript() && parser->hasInsertionPoint())
2384                     return;
2385             }
2386         }
2387
2388         if (m_frame->loader()->state() == FrameStateProvisional)
2389             m_frame->loader()->stopAllLoaders();
2390     }
2391
2392     removeAllEventListeners();
2393     implicitOpen();
2394     if (ScriptableDocumentParser* parser = scriptableDocumentParser())
2395         parser->setWasCreatedByScript(true);
2396
2397     if (DOMWindow* domWindow = this->domWindow())
2398         domWindow->removeAllEventListeners();
2399
2400     if (m_frame)
2401         m_frame->loader()->didExplicitOpen();
2402 }
2403
2404 void Document::detachParser()
2405 {
2406     if (!m_parser)
2407         return;
2408     m_parser->detach();
2409     m_parser.clear();
2410 }
2411
2412 void Document::cancelParsing()
2413 {
2414     if (!m_parser)
2415         return;
2416
2417     // We have to clear the parser to avoid possibly triggering
2418     // the onload handler when closing as a side effect of a cancel-style
2419     // change, such as opening a new document or closing the window while
2420     // still parsing
2421     detachParser();
2422     explicitClose();
2423 }
2424
2425 void Document::implicitOpen()
2426 {
2427     cancelParsing();
2428
2429     removeChildren();
2430
2431     setCompatibilityMode(NoQuirksMode);
2432
2433     m_parser = createParser();
2434     setParsing(true);
2435     setReadyState(Loading);
2436 }
2437
2438 HTMLElement* Document::body() const
2439 {
2440     Node* de = documentElement();
2441     if (!de)
2442         return 0;
2443     
2444     // try to prefer a FRAMESET element over BODY
2445     Node* body = 0;
2446     for (Node* i = de->firstChild(); i; i = i->nextSibling()) {
2447         if (i->hasTagName(framesetTag))
2448             return toHTMLElement(i);
2449         
2450         if (i->hasTagName(bodyTag) && !body)
2451             body = i;
2452     }
2453     return toHTMLElement(body);
2454 }
2455
2456 void Document::setBody(PassRefPtr<HTMLElement> prpNewBody, ExceptionCode& ec)
2457 {
2458     RefPtr<HTMLElement> newBody = prpNewBody;
2459
2460     if (!newBody || !documentElement() || !newBody->hasTagName(bodyTag)) { 
2461         ec = HIERARCHY_REQUEST_ERR;
2462         return;
2463     }
2464
2465     if (newBody->document() && newBody->document() != this) {
2466         ec = 0;
2467         RefPtr<Node> node = importNode(newBody.get(), true, ec);
2468         if (ec)
2469             return;
2470         
2471         newBody = toHTMLElement(node.get());
2472     }
2473
2474     HTMLElement* b = body();
2475     if (!b)
2476         documentElement()->appendChild(newBody.release(), ec);
2477     else
2478         documentElement()->replaceChild(newBody.release(), b, ec);
2479 }
2480
2481 HTMLHeadElement* Document::head()
2482 {
2483     Node* de = documentElement();
2484     if (!de)
2485         return 0;
2486
2487     for (Node* e = de->firstChild(); e; e = e->nextSibling())
2488         if (e->hasTagName(headTag))
2489             return static_cast<HTMLHeadElement*>(e);
2490
2491     return 0;
2492 }
2493
2494 void Document::close()
2495 {
2496     // FIXME: We should follow the specification more closely:
2497     //        http://www.whatwg.org/specs/web-apps/current-work/#dom-document-close
2498
2499     if (!scriptableDocumentParser() || !scriptableDocumentParser()->wasCreatedByScript() || !scriptableDocumentParser()->isParsing())
2500         return;
2501
2502     explicitClose();
2503 }
2504
2505 void Document::explicitClose()
2506 {
2507     if (m_parser)
2508         m_parser->finish();
2509
2510     if (!m_frame) {
2511         // Because we have no frame, we don't know if all loading has completed,
2512         // so we just call implicitClose() immediately. FIXME: This might fire
2513         // the load event prematurely <http://bugs.webkit.org/show_bug.cgi?id=14568>.
2514         implicitClose();
2515         return;
2516     }
2517
2518     m_frame->loader()->checkCompleted();
2519 }
2520
2521 void Document::implicitClose()
2522 {
2523     // If we're in the middle of recalcStyle, we need to defer the close until the style information is accurate and all elements are re-attached.
2524     if (m_inStyleRecalc) {
2525         m_closeAfterStyleRecalc = true;
2526         return;
2527     }
2528
2529     bool wasLocationChangePending = frame() && frame()->navigationScheduler()->locationChangePending();
2530     bool doload = !parsing() && m_parser && !m_processingLoadEvent && !wasLocationChangePending;
2531     
2532     if (!doload)
2533         return;
2534
2535     m_processingLoadEvent = true;
2536
2537     ScriptableDocumentParser* parser = scriptableDocumentParser();
2538     m_wellFormed = parser && parser->wellFormed();
2539
2540     // We have to clear the parser, in case someone document.write()s from the
2541     // onLoad event handler, as in Radar 3206524.
2542     detachParser();
2543
2544     // Parser should have picked up all preloads by now
2545     m_cachedResourceLoader->clearPreloads();
2546
2547     // FIXME: We kick off the icon loader when the Document is done parsing.
2548     // There are earlier opportunities we could start it:
2549     //  -When the <head> finishes parsing
2550     //  -When any new HTMLLinkElement is inserted into the document
2551     // But those add a dynamic component to the favicon that has UI 
2552     // ramifications, and we need to decide what is the Right Thing To Do(tm)
2553     Frame* f = frame();
2554     if (f) {
2555         f->loader()->icon()->startLoader();
2556         f->animation()->resumeAnimationsForDocument(this);
2557     }
2558
2559     ImageLoader::dispatchPendingBeforeLoadEvents();
2560     ImageLoader::dispatchPendingLoadEvents();
2561     ImageLoader::dispatchPendingErrorEvents();
2562
2563     HTMLLinkElement::dispatchPendingLoadEvents();
2564     HTMLStyleElement::dispatchPendingLoadEvents();
2565
2566 #if ENABLE(SVG)
2567     // To align the HTML load event and the SVGLoad event for the outermost <svg> element, fire it from
2568     // here, instead of doing it from SVGElement::finishedParsingChildren (if externalResourcesRequired="false",
2569     // which is the default, for ='true' its fired at a later time, once all external resources finished loading).
2570     if (svgExtensions())
2571         accessSVGExtensions()->dispatchSVGLoadEventToOutermostSVGElements();
2572 #endif
2573
2574     dispatchWindowLoadEvent();
2575     enqueuePageshowEvent(PageshowEventNotPersisted);
2576     enqueuePopstateEvent(m_pendingStateObject ? m_pendingStateObject.release() : SerializedScriptValue::nullValue());
2577     
2578     if (f)
2579         f->loader()->handledOnloadEvents();
2580 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2581     if (!ownerElement())
2582         printf("onload fired at %d\n", elapsedTime());
2583 #endif
2584
2585     // An event handler may have removed the frame
2586     if (!frame()) {
2587         m_processingLoadEvent = false;
2588         return;
2589     }
2590
2591     // Make sure both the initial layout and reflow happen after the onload
2592     // fires. This will improve onload scores, and other browsers do it.
2593     // If they wanna cheat, we can too. -dwh
2594
2595     if (frame()->navigationScheduler()->locationChangePending() && elapsedTime() < cLayoutScheduleThreshold) {
2596         // Just bail out. Before or during the onload we were shifted to another page.
2597         // The old i-Bench suite does this. When this happens don't bother painting or laying out.        
2598         m_processingLoadEvent = false;
2599         view()->unscheduleRelayout();
2600         return;
2601     }
2602
2603     frame()->loader()->checkCallImplicitClose();
2604     RenderObject* renderObject = renderer();
2605     
2606     // We used to force a synchronous display and flush here.  This really isn't
2607     // necessary and can in fact be actively harmful if pages are loading at a rate of > 60fps
2608     // (if your platform is syncing flushes and limiting them to 60fps).
2609     m_overMinimumLayoutThreshold = true;
2610     if (!ownerElement() || (ownerElement()->renderer() && !ownerElement()->renderer()->needsLayout())) {
2611         updateStyleIfNeeded();
2612         
2613         // Always do a layout after loading if needed.
2614         if (view() && renderObject && (!renderObject->firstChild() || renderObject->needsLayout()))
2615             view()->layout();
2616     }
2617
2618     m_processingLoadEvent = false;
2619
2620 #if PLATFORM(MAC) || PLATFORM(CHROMIUM)
2621     if (f && renderObject && AXObjectCache::accessibilityEnabled()) {
2622         // The AX cache may have been cleared at this point, but we need to make sure it contains an
2623         // AX object to send the notification to. getOrCreate will make sure that an valid AX object
2624         // exists in the cache (we ignore the return value because we don't need it here). This is 
2625         // only safe to call when a layout is not in progress, so it can not be used in postNotification.    
2626         axObjectCache()->getOrCreate(renderObject);
2627         if (this == topDocument())
2628             axObjectCache()->postNotification(renderObject, AXObjectCache::AXLoadComplete, true);
2629         else {
2630             // AXLoadComplete can only be posted on the top document, so if it's a document
2631             // in an iframe that just finished loading, post AXLayoutComplete instead.
2632             axObjectCache()->postNotification(renderObject, AXObjectCache::AXLayoutComplete, true);
2633         }
2634     }
2635 #endif
2636
2637 #if ENABLE(SVG)
2638     if (svgExtensions())
2639         accessSVGExtensions()->startAnimations();
2640 #endif
2641 }
2642
2643 void Document::setParsing(bool b)
2644 {
2645     m_bParsing = b;
2646     if (!m_bParsing && view())
2647         view()->scheduleRelayout();
2648
2649 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2650     if (!ownerElement() && !m_bParsing)
2651         printf("Parsing finished at %d\n", elapsedTime());
2652 #endif
2653 }
2654
2655 bool Document::shouldScheduleLayout()
2656 {
2657     // This function will only be called when FrameView thinks a layout is needed.
2658     // This enforces a couple extra rules.
2659     //
2660     //    (a) Only schedule a layout once the stylesheets are loaded.
2661     //    (b) Only schedule layout once we have a body element.
2662
2663     return (haveStylesheetsLoaded() && body())
2664         || (documentElement() && !documentElement()->hasTagName(htmlTag));
2665 }
2666     
2667 bool Document::isLayoutTimerActive()
2668 {
2669     return view() && view()->layoutPending() && !minimumLayoutDelay();
2670 }
2671
2672 int Document::minimumLayoutDelay()
2673 {
2674     if (m_overMinimumLayoutThreshold)
2675         return 0;
2676     
2677     int elapsed = elapsedTime();
2678     m_overMinimumLayoutThreshold = elapsed > cLayoutScheduleThreshold;
2679     
2680     // We'll want to schedule the timer to fire at the minimum layout threshold.
2681     return max(0, cLayoutScheduleThreshold - elapsed);
2682 }
2683
2684 int Document::elapsedTime() const
2685 {
2686     return static_cast<int>((currentTime() - m_startTime) * 1000);
2687 }
2688
2689 void Document::write(const SegmentedString& text, Document* ownerDocument)
2690 {
2691     NestingLevelIncrementer nestingLevelIncrementer(m_writeRecursionDepth);
2692
2693     m_writeRecursionIsTooDeep = (m_writeRecursionDepth > 1) && m_writeRecursionIsTooDeep;
2694     m_writeRecursionIsTooDeep = (m_writeRecursionDepth > cMaxWriteRecursionDepth) || m_writeRecursionIsTooDeep;
2695
2696     if (m_writeRecursionIsTooDeep)
2697        return;
2698
2699 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2700     if (!ownerElement())
2701         printf("Beginning a document.write at %d\n", elapsedTime());
2702 #endif
2703
2704     bool hasInsertionPoint = m_parser && m_parser->hasInsertionPoint();
2705     if (!hasInsertionPoint && m_ignoreDestructiveWriteCount)
2706         return;
2707
2708     if (!hasInsertionPoint)
2709         open(ownerDocument);
2710
2711     ASSERT(m_parser);
2712     m_parser->insert(text);
2713
2714 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2715     if (!ownerElement())
2716         printf("Ending a document.write at %d\n", elapsedTime());
2717 #endif    
2718 }
2719
2720 void Document::write(const String& text, Document* ownerDocument)
2721 {
2722     write(SegmentedString(text), ownerDocument);
2723 }
2724
2725 void Document::writeln(const String& text, Document* ownerDocument)
2726 {
2727     write(text, ownerDocument);
2728     write("\n", ownerDocument);
2729 }
2730
2731 const KURL& Document::virtualURL() const
2732 {
2733     return m_url;
2734 }
2735
2736 KURL Document::virtualCompleteURL(const String& url) const
2737 {
2738     return completeURL(url);
2739 }
2740
2741 double Document::minimumTimerInterval() const
2742 {
2743     Page* p = page();
2744     if (!p)
2745         return ScriptExecutionContext::minimumTimerInterval();
2746     return p->settings()->minDOMTimerInterval();
2747 }
2748
2749 EventTarget* Document::errorEventTarget()
2750 {
2751     return domWindow();
2752 }
2753
2754 void Document::logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, PassRefPtr<ScriptCallStack> callStack)
2755 {
2756     addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, errorMessage, sourceURL, lineNumber, callStack);
2757 }
2758
2759 void Document::setURL(const KURL& url)
2760 {
2761     const KURL& newURL = url.isEmpty() ? blankURL() : url;
2762     if (newURL == m_url)
2763         return;
2764
2765     m_url = newURL;
2766     m_documentURI = m_url.string();
2767     updateBaseURL();
2768     contextFeatures()->urlDidChange(this);
2769 }
2770
2771 void Document::updateBaseURL()
2772 {
2773     KURL oldBaseURL = m_baseURL;
2774     // DOM 3 Core: When the Document supports the feature "HTML" [DOM Level 2 HTML], the base URI is computed using
2775     // first the value of the href attribute of the HTML BASE element if any, and the value of the documentURI attribute
2776     // from the Document interface otherwise.
2777     if (!m_baseElementURL.isEmpty())
2778         m_baseURL = m_baseElementURL;
2779     else if (!m_baseURLOverride.isEmpty())
2780         m_baseURL = m_baseURLOverride;
2781     else {
2782         // The documentURI attribute is read-only from JavaScript, but writable from Objective C, so we need to retain
2783         // this fallback behavior. We use a null base URL, since the documentURI attribute is an arbitrary string
2784         // and DOM 3 Core does not specify how it should be resolved.
2785         m_baseURL = KURL(KURL(), documentURI());
2786     }
2787     selectorQueryCache()->invalidate();
2788
2789     if (!m_baseURL.isValid())
2790         m_baseURL = KURL();
2791
2792     if (m_elemSheet) {
2793         // Element sheet is silly. It never contains anything.
2794         ASSERT(!m_elemSheet->contents()->ruleCount());
2795         bool usesRemUnits = m_elemSheet->contents()->usesRemUnits();
2796         m_elemSheet = CSSStyleSheet::createInline(this, m_baseURL);
2797         // FIXME: So we are not really the parser. The right fix is to eliminate the element sheet completely.
2798         m_elemSheet->contents()->parserSetUsesRemUnits(usesRemUnits);
2799     }
2800
2801     if (!equalIgnoringFragmentIdentifier(oldBaseURL, m_baseURL)) {
2802         // Base URL change changes any relative visited links.
2803         // FIXME: There are other URLs in the tree that would need to be re-evaluated on dynamic base URL change. Style should be invalidated too.
2804         for (Node* node = firstChild(); node; node = node->traverseNextNode()) {
2805             if (node->hasTagName(aTag))
2806                 static_cast<HTMLAnchorElement*>(node)->invalidateCachedVisitedLinkHash();
2807         }
2808     }
2809 }
2810
2811 void Document::setBaseURLOverride(const KURL& url)
2812 {
2813     m_baseURLOverride = url;
2814     updateBaseURL();
2815 }
2816
2817 void Document::processBaseElement()
2818 {
2819     // Find the first href attribute in a base element and the first target attribute in a base element.
2820     const AtomicString* href = 0;
2821     const AtomicString* target = 0;
2822     for (Node* node = document()->firstChild(); node && (!href || !target); node = node->traverseNextNode()) {
2823         if (node->hasTagName(baseTag)) {
2824             if (!href) {
2825                 const AtomicString& value = static_cast<Element*>(node)->fastGetAttribute(hrefAttr);
2826                 if (!value.isNull())
2827                     href = &value;
2828             }
2829             if (!target) {
2830                 const AtomicString& value = static_cast<Element*>(node)->fastGetAttribute(targetAttr);
2831                 if (!value.isNull())
2832                     target = &value;
2833             }
2834         }
2835     }
2836
2837     // FIXME: Since this doesn't share code with completeURL it may not handle encodings correctly.
2838     KURL baseElementURL;
2839     if (href) {
2840         String strippedHref = stripLeadingAndTrailingHTMLSpaces(*href);
2841         if (!strippedHref.isEmpty())
2842             baseElementURL = KURL(url(), strippedHref);
2843     }
2844     if (m_baseElementURL != baseElementURL) {
2845         m_baseElementURL = baseElementURL;
2846         updateBaseURL();
2847     }
2848
2849     m_baseTarget = target ? *target : nullAtom;
2850 }
2851
2852 String Document::userAgent(const KURL& url) const
2853 {
2854     return frame() ? frame()->loader()->userAgent(url) : String();
2855 }
2856
2857 void Document::disableEval()
2858 {
2859     if (!frame())
2860         return;
2861
2862     frame()->script()->disableEval();
2863 }
2864
2865 bool Document::canNavigate(Frame* targetFrame)
2866 {
2867     if (!m_frame)
2868         return false;
2869
2870     // FIXME: We shouldn't call this function without a target frame, but
2871     // fast/forms/submit-to-blank-multiple-times.html depends on this function
2872     // returning true when supplied with a 0 targetFrame.
2873     if (!targetFrame)
2874         return true;
2875
2876     // Frame-busting is generally allowed (unless we're sandboxed and prevent from frame-busting).
2877     if (!isSandboxed(SandboxTopNavigation) && targetFrame == m_frame->tree()->top())
2878         return true;
2879
2880     if (isSandboxed(SandboxNavigation)) {
2881         if (targetFrame->tree()->isDescendantOf(m_frame))
2882             return true;
2883
2884         printNavigationErrorMessage(targetFrame, url());
2885         return false;
2886     }
2887
2888     // This is the normal case. A document can navigate its decendant frames,
2889     // or, more generally, a document can navigate a frame if the document is
2890     // in the same origin as any of that frame's ancestors (in the frame
2891     // hierarchy).
2892     //
2893     // See http://www.adambarth.com/papers/2008/barth-jackson-mitchell.pdf for
2894     // historical information about this security check.
2895     if (canAccessAncestor(securityOrigin(), targetFrame))
2896         return true;
2897
2898     // Top-level frames are easier to navigate than other frames because they
2899     // display their URLs in the address bar (in most browsers). However, there
2900     // are still some restrictions on navigation to avoid nuisance attacks.
2901     // Specifically, a document can navigate a top-level frame if that frame
2902     // opened the document or if the document is the same-origin with any of
2903     // the top-level frame's opener's ancestors (in the frame hierarchy).
2904     //
2905     // In both of these cases, the document performing the navigation is in
2906     // some way related to the frame being navigate (e.g., by the "opener"
2907     // and/or "parent" relation). Requiring some sort of relation prevents a
2908     // document from navigating arbitrary, unrelated top-level frames.
2909     if (!targetFrame->tree()->parent()) {
2910         if (targetFrame == m_frame->loader()->opener())
2911             return true;
2912
2913         if (canAccessAncestor(securityOrigin(), targetFrame->loader()->opener()))
2914             return true;
2915     }
2916
2917     printNavigationErrorMessage(targetFrame, url());
2918     return false;
2919 }
2920
2921 Frame* Document::findUnsafeParentScrollPropagationBoundary()
2922 {
2923     Frame* currentFrame = m_frame;
2924     Frame* ancestorFrame = currentFrame->tree()->parent(); 
2925
2926     while (ancestorFrame) {
2927         if (!ancestorFrame->document()->securityOrigin()->canAccess(securityOrigin()))
2928             return currentFrame;
2929         currentFrame = ancestorFrame;
2930         ancestorFrame = ancestorFrame->tree()->parent();
2931     }
2932     return 0;
2933 }
2934
2935 CSSStyleSheet* Document::pageUserSheet()
2936 {
2937     if (m_pageUserSheet)
2938         return m_pageUserSheet.get();
2939     
2940     Page* owningPage = page();
2941     if (!owningPage)
2942         return 0;
2943     
2944     String userSheetText = owningPage->userStyleSheet();
2945     if (userSheetText.isEmpty())
2946         return 0;
2947     
2948     // Parse the sheet and cache it.
2949     m_pageUserSheet = CSSStyleSheet::createInline(this, settings()->userStyleSheetLocation());
2950     m_pageUserSheet->contents()->setIsUserStyleSheet(true);
2951     m_pageUserSheet->contents()->parseString(userSheetText);
2952     return m_pageUserSheet.get();
2953 }
2954
2955 void Document::clearPageUserSheet()
2956 {
2957     if (m_pageUserSheet) {
2958         m_pageUserSheet = 0;
2959         styleResolverChanged(DeferRecalcStyle);
2960     }
2961 }
2962
2963 void Document::updatePageUserSheet()
2964 {
2965     clearPageUserSheet();
2966     if (pageUserSheet())
2967         styleResolverChanged(RecalcStyleImmediately);
2968 }
2969
2970 const Vector<RefPtr<CSSStyleSheet> >* Document::pageGroupUserSheets() const
2971 {
2972     if (m_pageGroupUserSheetCacheValid)
2973         return m_pageGroupUserSheets.get();
2974     
2975     m_pageGroupUserSheetCacheValid = true;
2976     
2977     Page* owningPage = page();
2978     if (!owningPage)
2979         return 0;
2980         
2981     const PageGroup& pageGroup = owningPage->group();
2982     const UserStyleSheetMap* sheetsMap = pageGroup.userStyleSheets();
2983     if (!sheetsMap)
2984         return 0;
2985
2986     UserStyleSheetMap::const_iterator end = sheetsMap->end();
2987     for (UserStyleSheetMap::const_iterator it = sheetsMap->begin(); it != end; ++it) {
2988         const UserStyleSheetVector* sheets = it->second.get();
2989         for (unsigned i = 0; i < sheets->size(); ++i) {
2990             const UserStyleSheet* sheet = sheets->at(i).get();
2991             if (sheet->injectedFrames() == InjectInTopFrameOnly && ownerElement())
2992                 continue;
2993             if (!UserContentURLPattern::matchesPatterns(url(), sheet->whitelist(), sheet->blacklist()))
2994                 continue;
2995             RefPtr<CSSStyleSheet> groupSheet = CSSStyleSheet::createInline(const_cast<Document*>(this), sheet->url());
2996             if (!m_pageGroupUserSheets)
2997                 m_pageGroupUserSheets = adoptPtr(new Vector<RefPtr<CSSStyleSheet> >);
2998             m_pageGroupUserSheets->append(groupSheet);
2999             groupSheet->contents()->setIsUserStyleSheet(sheet->level() == UserStyleUserLevel);
3000             groupSheet->contents()->parseString(sheet->source());
3001         }
3002     }
3003
3004     return m_pageGroupUserSheets.get();
3005 }
3006
3007 void Document::clearPageGroupUserSheets()
3008 {
3009     m_pageGroupUserSheetCacheValid = false;
3010     if (m_pageGroupUserSheets && m_pageGroupUserSheets->size()) {
3011         m_pageGroupUserSheets->clear();
3012         styleResolverChanged(DeferRecalcStyle);
3013     }
3014 }
3015
3016 void Document::updatePageGroupUserSheets()
3017 {
3018     clearPageGroupUserSheets();
3019     if (pageGroupUserSheets() && pageGroupUserSheets()->size())
3020         styleResolverChanged(RecalcStyleImmediately);
3021 }
3022
3023 void Document::addUserSheet(PassRefPtr<StyleSheetContents> userSheet)
3024 {
3025     if (!m_userSheets)
3026         m_userSheets = adoptPtr(new Vector<RefPtr<CSSStyleSheet> >);
3027     m_userSheets->append(CSSStyleSheet::create(userSheet, this));
3028     styleResolverChanged(RecalcStyleImmediately);
3029 }
3030
3031 void Document::seamlessParentUpdatedStylesheets()
3032 {
3033     styleResolverChanged(RecalcStyleImmediately);
3034 }
3035
3036 CSSStyleSheet* Document::elementSheet()
3037 {
3038     if (!m_elemSheet)
3039         m_elemSheet = CSSStyleSheet::createInline(this, m_baseURL);
3040     return m_elemSheet.get();
3041 }
3042
3043 int Document::nodeAbsIndex(Node *node)
3044 {
3045     ASSERT(node->document() == this);
3046
3047     int absIndex = 0;
3048     for (Node* n = node; n && n != this; n = n->traversePreviousNode())
3049         absIndex++;
3050     return absIndex;
3051 }
3052
3053 Node* Document::nodeWithAbsIndex(int absIndex)
3054 {
3055     Node* n = this;
3056     for (int i = 0; n && (i < absIndex); i++)
3057         n = n->traverseNextNode();
3058     return n;
3059 }
3060
3061 void Document::processHttpEquiv(const String& equiv, const String& content)
3062 {
3063     ASSERT(!equiv.isNull() && !content.isNull());
3064
3065     Frame* frame = this->frame();
3066
3067     if (equalIgnoringCase(equiv, "default-style")) {
3068         // The preferred style set has been overridden as per section 
3069         // 14.3.2 of the HTML4.0 specification.  We need to update the
3070         // sheet used variable and then update our style selector. 
3071         // For more info, see the test at:
3072         // http://www.hixie.ch/tests/evil/css/import/main/preferred.html
3073         // -dwh
3074         m_selectedStylesheetSet = content;
3075         m_preferredStylesheetSet = content;
3076         styleResolverChanged(DeferRecalcStyle);
3077     } else if (equalIgnoringCase(equiv, "refresh")) {
3078         double delay;
3079         String url;
3080         if (frame && parseHTTPRefresh(content, true, delay, url)) {
3081             if (url.isEmpty())
3082                 url = m_url.string();
3083             else
3084                 url = completeURL(url).string();
3085             frame->navigationScheduler()->scheduleRedirect(delay, url);
3086         }
3087     } else if (equalIgnoringCase(equiv, "set-cookie")) {
3088         // FIXME: make setCookie work on XML documents too; e.g. in case of <html:meta .....>
3089         if (isHTMLDocument()) {
3090             ExceptionCode ec; // Exception (for sandboxed documents) ignored.
3091             static_cast<HTMLDocument*>(this)->setCookie(content, ec);
3092         }
3093     } else if (equalIgnoringCase(equiv, "content-language"))
3094         setContentLanguage(content);
3095     else if (equalIgnoringCase(equiv, "x-dns-prefetch-control"))
3096         parseDNSPrefetchControlHeader(content);
3097     else if (equalIgnoringCase(equiv, "x-frame-options")) {
3098         if (frame) {
3099             FrameLoader* frameLoader = frame->loader();
3100             if (frameLoader->shouldInterruptLoadForXFrameOptions(content, url())) {
3101                 frameLoader->stopAllLoaders();
3102                 frame->navigationScheduler()->scheduleLocationChange(securityOrigin(), blankURL(), String());
3103
3104                 DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to display document because display forbidden by X-Frame-Options.\n"));
3105                 addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage);
3106             }
3107         }
3108     } else if (equalIgnoringCase(equiv, "x-webkit-csp"))
3109         contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::EnforcePolicy);
3110     else if (equalIgnoringCase(equiv, "x-webkit-csp-report-only"))
3111         contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::ReportOnly);
3112 }
3113
3114 // Though isspace() considers \t and \v to be whitespace, Win IE doesn't.
3115 static bool isSeparator(UChar c)
3116 {
3117     return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '=' || c == ',' || c == '\0';
3118 }
3119
3120 void Document::processArguments(const String& features, void* data, ArgumentsCallback callback)
3121 {
3122     // Tread lightly in this code -- it was specifically designed to mimic Win IE's parsing behavior.
3123     int keyBegin, keyEnd;
3124     int valueBegin, valueEnd;
3125
3126     int i = 0;
3127     int length = features.length();
3128     String buffer = features.lower();
3129     while (i < length) {
3130         // skip to first non-separator, but don't skip past the end of the string
3131         while (isSeparator(buffer[i])) {
3132             if (i >= length)
3133                 break;
3134             i++;
3135         }
3136         keyBegin = i;
3137
3138         // skip to first separator
3139         while (!isSeparator(buffer[i]))
3140             i++;
3141         keyEnd = i;
3142
3143         // skip to first '=', but don't skip past a ',' or the end of the string
3144         while (buffer[i] != '=') {
3145             if (buffer[i] == ',' || i >= length)
3146                 break;
3147             i++;
3148         }
3149
3150         // skip to first non-separator, but don't skip past a ',' or the end of the string
3151         while (isSeparator(buffer[i])) {
3152             if (buffer[i] == ',' || i >= length)
3153                 break;
3154             i++;
3155         }
3156         valueBegin = i;
3157
3158         // skip to first separator
3159         while (!isSeparator(buffer[i]))
3160             i++;
3161         valueEnd = i;
3162
3163         ASSERT(i <= length);
3164
3165         String keyString = buffer.substring(keyBegin, keyEnd - keyBegin);
3166         String valueString = buffer.substring(valueBegin, valueEnd - valueBegin);
3167         callback(keyString, valueString, this, data);
3168     }
3169 }
3170
3171 void Document::processViewport(const String& features, ViewportArguments::Type origin)
3172 {
3173     ASSERT(!features.isNull());
3174
3175     if (origin < m_viewportArguments.type)
3176         return;
3177
3178     m_viewportArguments = ViewportArguments(origin);
3179     processArguments(features, (void*)&m_viewportArguments, &setViewportFeature);
3180
3181     updateViewportArguments();
3182 }
3183
3184 void Document::updateViewportArguments()
3185 {
3186     if (page() && page()->mainFrame() == frame()) {
3187 #ifndef NDEBUG
3188         m_didDispatchViewportPropertiesChanged = true;
3189 #endif
3190         page()->chrome()->dispatchViewportPropertiesDidChange(m_viewportArguments);
3191     }
3192 }
3193
3194 void Document::processReferrerPolicy(const String& policy)
3195 {
3196     ASSERT(!policy.isNull());
3197
3198     m_referrerPolicy = ReferrerPolicyDefault;
3199
3200     if (equalIgnoringCase(policy, "never"))
3201         m_referrerPolicy = ReferrerPolicyNever;
3202     else if (equalIgnoringCase(policy, "always"))
3203         m_referrerPolicy = ReferrerPolicyAlways;
3204     else if (equalIgnoringCase(policy, "origin"))
3205         m_referrerPolicy = ReferrerPolicyOrigin;
3206 }
3207
3208 MouseEventWithHitTestResults Document::prepareMouseEvent(const HitTestRequest& request, const LayoutPoint& documentPoint, const PlatformMouseEvent& event)
3209 {
3210     ASSERT(!renderer() || renderer()->isRenderView());
3211
3212     if (!renderer())
3213         return MouseEventWithHitTestResults(event, HitTestResult(LayoutPoint()));
3214
3215     HitTestResult result(documentPoint);
3216     renderView()->hitTest(request, result);
3217
3218     if (!request.readOnly())
3219         updateStyleIfNeeded();
3220
3221     return MouseEventWithHitTestResults(event, result);
3222 }
3223
3224 // DOM Section 1.1.1
3225 bool Document::childTypeAllowed(NodeType type) const
3226 {
3227     switch (type) {
3228     case ATTRIBUTE_NODE:
3229     case CDATA_SECTION_NODE:
3230     case DOCUMENT_FRAGMENT_NODE:
3231     case DOCUMENT_NODE:
3232     case ENTITY_NODE:
3233     case ENTITY_REFERENCE_NODE:
3234     case NOTATION_NODE:
3235     case TEXT_NODE:
3236     case XPATH_NAMESPACE_NODE:
3237         return false;
3238     case COMMENT_NODE:
3239     case PROCESSING_INSTRUCTION_NODE:
3240         return true;
3241     case DOCUMENT_TYPE_NODE:
3242     case ELEMENT_NODE:
3243         // Documents may contain no more than one of each of these.
3244         // (One Element and one DocumentType.)
3245         for (Node* c = firstChild(); c; c = c->nextSibling())
3246             if (c->nodeType() == type)
3247                 return false;
3248         return true;
3249     }
3250     return false;
3251 }
3252
3253 bool Document::canReplaceChild(Node* newChild, Node* oldChild)
3254 {
3255     if (!oldChild)
3256         // ContainerNode::replaceChild will raise a NOT_FOUND_ERR.
3257         return true;
3258
3259     if (oldChild->nodeType() == newChild->nodeType())
3260         return true;
3261
3262     int numDoctypes = 0;
3263     int numElements = 0;
3264
3265     // First, check how many doctypes and elements we have, not counting
3266     // the child we're about to remove.
3267     for (Node* c = firstChild(); c; c = c->nextSibling()) {
3268         if (c == oldChild)
3269             continue;
3270         
3271         switch (c->nodeType()) {
3272         case DOCUMENT_TYPE_NODE:
3273             numDoctypes++;
3274             break;
3275         case ELEMENT_NODE:
3276             numElements++;
3277             break;
3278         default:
3279             break;
3280         }
3281     }
3282     
3283     // Then, see how many doctypes and elements might be added by the new child.
3284     if (newChild->nodeType() == DOCUMENT_FRAGMENT_NODE) {
3285         for (Node* c = newChild->firstChild(); c; c = c->nextSibling()) {
3286             switch (c->nodeType()) {
3287             case ATTRIBUTE_NODE:
3288             case CDATA_SECTION_NODE:
3289             case DOCUMENT_FRAGMENT_NODE:
3290             case DOCUMENT_NODE:
3291             case ENTITY_NODE:
3292             case ENTITY_REFERENCE_NODE:
3293             case NOTATION_NODE:
3294             case TEXT_NODE:
3295             case XPATH_NAMESPACE_NODE:
3296                 return false;
3297             case COMMENT_NODE:
3298             case PROCESSING_INSTRUCTION_NODE:
3299                 break;
3300             case DOCUMENT_TYPE_NODE:
3301                 numDoctypes++;
3302                 break;
3303             case ELEMENT_NODE:
3304                 numElements++;
3305                 break;
3306             }
3307         }
3308     } else {
3309         switch (newChild->nodeType()) {
3310         case ATTRIBUTE_NODE:
3311         case CDATA_SECTION_NODE:
3312         case DOCUMENT_FRAGMENT_NODE:
3313         case DOCUMENT_NODE:
3314         case ENTITY_NODE:
3315         case ENTITY_REFERENCE_NODE:
3316         case NOTATION_NODE:
3317         case TEXT_NODE:
3318         case XPATH_NAMESPACE_NODE:
3319             return false;
3320         case COMMENT_NODE:
3321         case PROCESSING_INSTRUCTION_NODE:
3322             return true;
3323         case DOCUMENT_TYPE_NODE:
3324             numDoctypes++;
3325             break;
3326         case ELEMENT_NODE:
3327             numElements++;
3328             break;
3329         }                
3330     }
3331         
3332     if (numElements > 1 || numDoctypes > 1)
3333         return false;
3334     
3335     return true;
3336 }
3337
3338 PassRefPtr<Node> Document::cloneNode(bool /*deep*/)
3339 {
3340     // Spec says cloning Document nodes is "implementation dependent"
3341     // so we do not support it...
3342     return 0;
3343 }
3344
3345 StyleSheetList* Document::styleSheets()
3346 {
3347     return m_styleSheets.get();
3348 }
3349
3350 String Document::preferredStylesheetSet() const
3351 {
3352     return m_preferredStylesheetSet;
3353 }
3354
3355 String Document::selectedStylesheetSet() const
3356 {
3357     return m_selectedStylesheetSet;
3358 }
3359
3360 void Document::setSelectedStylesheetSet(const String& aString)
3361 {
3362     m_selectedStylesheetSet = aString;
3363     styleResolverChanged(DeferRecalcStyle);
3364 }
3365
3366 // This method is called whenever a top-level stylesheet has finished loading.
3367 void Document::removePendingSheet()
3368 {
3369     // Make sure we knew this sheet was pending, and that our count isn't out of sync.
3370     ASSERT(m_pendingStylesheets > 0);
3371
3372     m_pendingStylesheets--;
3373     
3374 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
3375     if (!ownerElement())
3376         printf("Stylesheet loaded at time %d. %d stylesheets still remain.\n", elapsedTime(), m_pendingStylesheets);
3377 #endif
3378
3379     if (m_pendingStylesheets)
3380         return;
3381
3382     styleResolverChanged(RecalcStyleIfNeeded);
3383
3384     if (ScriptableDocumentParser* parser = scriptableDocumentParser())
3385         parser->executeScriptsWaitingForStylesheets();
3386
3387     if (m_gotoAnchorNeededAfterStylesheetsLoad && view())
3388         view()->scrollToFragment(m_url);
3389 }
3390
3391 void Document::evaluateMediaQueryList()
3392 {
3393     if (m_mediaQueryMatcher)
3394         m_mediaQueryMatcher->styleResolverChanged();
3395 }
3396
3397 void Document::styleResolverChanged(StyleResolverUpdateFlag updateFlag)
3398 {
3399     // Don't bother updating, since we haven't loaded all our style info yet
3400     // and haven't calculated the style selector for the first time.
3401     if (!attached() || (!m_didCalculateStyleResolver && !haveStylesheetsLoaded())) {
3402         m_styleResolver.clear();
3403         return;
3404     }
3405
3406 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
3407     if (!ownerElement())
3408         printf("Beginning update of style selector at time %d.\n", elapsedTime());
3409 #endif
3410
3411     bool stylesheetChangeRequiresStyleRecalc = updateActiveStylesheets(updateFlag);
3412
3413     if (updateFlag == DeferRecalcStyle) {
3414         scheduleForcedStyleRecalc();
3415         return;
3416     }
3417
3418     if (didLayoutWithPendingStylesheets() && m_pendingStylesheets <= 0) {
3419         m_pendingSheetLayout = IgnoreLayoutWithPendingSheets;
3420         if (renderer())
3421             renderer()->repaint();
3422     }
3423
3424     if (!stylesheetChangeRequiresStyleRecalc)
3425         return;
3426
3427     // This recalcStyle initiates a new recalc cycle. We need to bracket it to
3428     // make sure animations get the correct update time
3429     {
3430         AnimationUpdateBlock animationUpdateBlock(m_frame ? m_frame->animation() : 0);
3431         recalcStyle(Force);
3432     }
3433
3434 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
3435     if (!ownerElement())
3436         printf("Finished update of style selector at time %d\n", elapsedTime());
3437 #endif
3438
3439     if (renderer()) {
3440         renderer()->setNeedsLayoutAndPrefWidthsRecalc();
3441         if (view())
3442             view()->scheduleRelayout();
3443     }
3444
3445     evaluateMediaQueryList();
3446 }
3447
3448 void Document::addStyleSheetCandidateNode(Node* node, bool createdByParser)
3449 {
3450     if (!node->inDocument())
3451         return;
3452     
3453     // Until the <body> exists, we have no choice but to compare document positions,
3454     // since styles outside of the body and head continue to be shunted into the head
3455     // (and thus can shift to end up before dynamically added DOM content that is also
3456     // outside the body).
3457     if ((createdByParser && body()) || m_styleSheetCandidateNodes.isEmpty()) {
3458         m_styleSheetCandidateNodes.add(node);
3459         return;
3460     }
3461
3462     // Determine an appropriate insertion point.
3463     StyleSheetCandidateListHashSet::iterator begin = m_styleSheetCandidateNodes.begin();
3464     StyleSheetCandidateListHashSet::iterator end = m_styleSheetCandidateNodes.end();
3465     StyleSheetCandidateListHashSet::iterator it = end;
3466     Node* followingNode = 0;
3467     do {
3468         --it;
3469         Node* n = *it;
3470         unsigned short position = n->compareDocumentPosition(node);
3471         if (position == DOCUMENT_POSITION_FOLLOWING) {
3472             m_styleSheetCandidateNodes.insertBefore(followingNode, node);
3473             return;
3474         }
3475         followingNode = n;
3476     } while (it != begin);
3477     
3478     m_styleSheetCandidateNodes.insertBefore(followingNode, node);
3479 }
3480
3481 void Document::removeStyleSheetCandidateNode(Node* node)
3482 {
3483     m_styleSheetCandidateNodes.remove(node);
3484 }
3485
3486 void Document::collectActiveStylesheets(Vector<RefPtr<StyleSheet> >& sheets)
3487 {
3488     if (settings() && !settings()->authorAndUserStylesEnabled())
3489         return;
3490
3491     StyleSheetCandidateListHashSet::iterator begin = m_styleSheetCandidateNodes.begin();
3492     StyleSheetCandidateListHashSet::iterator end = m_styleSheetCandidateNodes.end();
3493     for (StyleSheetCandidateListHashSet::iterator it = begin; it != end; ++it) {
3494         Node* n = *it;
3495         StyleSheet* sheet = 0;
3496         if (n->nodeType() == PROCESSING_INSTRUCTION_NODE) {
3497             // Processing instruction (XML documents only).
3498             // We don't support linking to embedded CSS stylesheets, see <https://bugs.webkit.org/show_bug.cgi?id=49281> for discussion.
3499             ProcessingInstruction* pi = static_cast<ProcessingInstruction*>(n);
3500             sheet = pi->sheet();
3501 #if ENABLE(XSLT)
3502             // Don't apply XSL transforms to already transformed documents -- <rdar://problem/4132806>
3503             if (pi->isXSL() && !transformSourceDocument()) {
3504                 // Don't apply XSL transforms until loading is finished.
3505                 if (!parsing())
3506                     applyXSLTransform(pi);
3507                 return;
3508             }
3509 #endif
3510         } else if ((n->isHTMLElement() && (n->hasTagName(linkTag) || n->hasTagName(styleTag)))
3511 #if ENABLE(SVG)
3512                    ||  (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))
3513 #endif
3514                    ) {
3515             Element* e = static_cast<Element*>(n);
3516             AtomicString title = e->getAttribute(titleAttr);
3517             bool enabledViaScript = false;
3518             if (e->hasLocalName(linkTag)) {
3519                 // <LINK> element
3520                 HTMLLinkElement* linkElement = static_cast<HTMLLinkElement*>(n);
3521                 if (linkElement->isDisabled())
3522                     continue;
3523                 enabledViaScript = linkElement->isEnabledViaScript();
3524                 if (linkElement->styleSheetIsLoading()) {
3525                     // it is loading but we should still decide which style sheet set to use
3526                     if (!enabledViaScript && !title.isEmpty() && m_preferredStylesheetSet.isEmpty()) {
3527                         const AtomicString& rel = e->getAttribute(relAttr);
3528                         if (!rel.contains("alternate")) {
3529                             m_preferredStylesheetSet = title;
3530                             m_selectedStylesheetSet = title;
3531                         }
3532                     }
3533                     continue;
3534                 }
3535                 if (!linkElement->sheet())
3536                     title = nullAtom;
3537             }
3538             // Get the current preferred styleset.  This is the
3539             // set of sheets that will be enabled.
3540 #if ENABLE(SVG)
3541             if (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))
3542                 sheet = static_cast<SVGStyleElement*>(n)->sheet();
3543             else
3544 #endif
3545             if (e->hasLocalName(linkTag))
3546                 sheet = static_cast<HTMLLinkElement*>(n)->sheet();
3547             else
3548                 // <STYLE> element
3549                 sheet = static_cast<HTMLStyleElement*>(n)->sheet();
3550             // Check to see if this sheet belongs to a styleset
3551             // (thus making it PREFERRED or ALTERNATE rather than
3552             // PERSISTENT).
3553             AtomicString rel = e->getAttribute(relAttr);
3554             if (!enabledViaScript && !title.isEmpty()) {
3555                 // Yes, we have a title.
3556                 if (m_preferredStylesheetSet.isEmpty()) {
3557                     // No preferred set has been established.  If
3558                     // we are NOT an alternate sheet, then establish
3559                     // us as the preferred set.  Otherwise, just ignore
3560                     // this sheet.
3561                     if (e->hasLocalName(styleTag) || !rel.contains("alternate"))
3562                         m_preferredStylesheetSet = m_selectedStylesheetSet = title;
3563                 }
3564                 if (title != m_preferredStylesheetSet)
3565                     sheet = 0;
3566             }
3567
3568             if (rel.contains("alternate") && title.isEmpty())
3569                 sheet = 0;
3570         }
3571         if (sheet)
3572             sheets.append(sheet);
3573     }
3574 }
3575
3576 bool Document::testAddedStylesheetRequiresStyleRecalc(StyleSheetContents* stylesheet)
3577 {
3578     // See if all rules on the sheet are scoped to some specific ids or classes.
3579     // Then test if we actually have any of those in the tree at the moment.
3580     HashSet<AtomicStringImpl*> idScopes; 
3581     HashSet<AtomicStringImpl*> classScopes;
3582     if (!StyleResolver::determineStylesheetSelectorScopes(stylesheet, idScopes, classScopes))
3583         return true;
3584     // Invalidate the subtrees that match the scopes.
3585     Node* node = firstChild();
3586     while (node) {
3587         if (!node->isStyledElement()) {
3588             node = node->traverseNextNode();
3589             continue;
3590         }
3591         StyledElement* element = static_cast<StyledElement*>(node);
3592         if (SelectorChecker::elementMatchesSelectorScopes(element, idScopes, classScopes)) {
3593             element->setNeedsStyleRecalc();
3594             // The whole subtree is now invalidated, we can skip to the next sibling.
3595             node = node->traverseNextSibling();
3596             continue;
3597         }
3598         node = node->traverseNextNode();
3599     }
3600     return false;
3601 }
3602
3603 void Document::analyzeStylesheetChange(StyleResolverUpdateFlag updateFlag, const Vector<RefPtr<StyleSheet> >& newStylesheets, bool& requiresStyleResolverReset, bool& requiresFullStyleRecalc)
3604 {
3605     requiresStyleResolverReset = true;
3606     requiresFullStyleRecalc = true;
3607     
3608     // Stylesheets of <style> elements that @import stylesheets are active but loading. We need to trigger a full recalc when such loads are done.
3609     bool hasActiveLoadingStylesheet = false;
3610     unsigned newStylesheetCount = newStylesheets.size();
3611     for (unsigned i = 0; i < newStylesheetCount; ++i) {
3612         if (newStylesheets[i]->isLoading())
3613             hasActiveLoadingStylesheet = true;
3614     }
3615     if (m_hadActiveLoadingStylesheet && !hasActiveLoadingStylesheet) {
3616         m_hadActiveLoadingStylesheet = false;
3617         return;
3618     }
3619     m_hadActiveLoadingStylesheet = hasActiveLoadingStylesheet;
3620
3621     if (updateFlag != RecalcStyleIfNeeded)
3622         return;
3623     if (!m_styleResolver)
3624         return;
3625
3626     // See if we are just adding stylesheets.
3627     unsigned oldStylesheetCount = m_styleSheets->length();
3628     if (newStylesheetCount < oldStylesheetCount)
3629         return;
3630     for (unsigned i = 0; i < oldStylesheetCount; ++i) {
3631         if (m_styleSheets->item(i) != newStylesheets[i])
3632             return;
3633     }
3634     requiresStyleResolverReset = false;
3635
3636     // If we are already parsing the body and so may have significant amount of elements, put some effort into trying to avoid style recalcs.
3637     if (!body() || m_hasNodesWithPlaceholderStyle)
3638         return;
3639     for (unsigned i = oldStylesheetCount; i < newStylesheetCount; ++i) {
3640         if (!newStylesheets[i]->isCSSStyleSheet())
3641             return;
3642         if (newStylesheets[i]->disabled())
3643             continue;
3644         if (testAddedStylesheetRequiresStyleRecalc(static_cast<CSSStyleSheet*>(newStylesheets[i].get())->contents()))
3645             return;
3646     }
3647     requiresFullStyleRecalc = false;
3648 }
3649
3650 static bool styleSheetsUseRemUnits(const Vector<RefPtr<StyleSheet> >& sheets)
3651 {
3652     for (unsigned i = 0; i < sheets.size(); ++i) {
3653         if (!sheets[i]->isCSSStyleSheet())
3654             continue;
3655         if (static_cast<CSSStyleSheet*>(sheets[i].get())->contents()->usesRemUnits())
3656             return true;
3657     }
3658     return false;
3659 }
3660
3661 void Document::notifySeamlessChildDocumentsOfStylesheetUpdate() const
3662 {
3663     // If we're not in a frame yet any potential child documents won't have a StyleResolver to update.
3664     if (!frame())
3665         return;
3666
3667     // Seamless child frames are expected to notify their seamless children recursively, so we only do direct children.
3668     for (Frame* child = frame()->tree()->firstChild(); child; child = child->tree()->nextSibling()) {
3669         Document* childDocument = child->document();
3670         if (childDocument->shouldDisplaySeamlesslyWithParent()) {
3671             ASSERT(childDocument->seamlessParentIFrame()->document() == this);
3672             childDocument->seamlessParentUpdatedStylesheets();
3673         }
3674     }
3675 }
3676
3677 bool Document::updateActiveStylesheets(StyleResolverUpdateFlag updateFlag)
3678 {
3679     if (m_inStyleRecalc) {
3680         // SVG <use> element may manage to invalidate style selector in the middle of a style recalc.
3681         // https://bugs.webkit.org/show_bug.cgi?id=54344
3682         // FIXME: This should be fixed in SVG and this code replaced with ASSERT(!m_inStyleRecalc).
3683         m_hasDirtyStyleResolver = true;
3684         scheduleForcedStyleRecalc();
3685         return false;
3686     }
3687     if (!renderer() || !attached())
3688         return false;
3689
3690     StyleSheetVector newStylesheets;
3691     collectActiveStylesheets(newStylesheets);
3692
3693     bool requiresStyleResolverReset;
3694     bool requiresFullStyleRecalc;
3695     analyzeStylesheetChange(updateFlag, newStylesheets, requiresStyleResolverReset, requiresFullStyleRecalc);
3696
3697     if (requiresStyleResolverReset)
3698         clearStyleResolver();
3699     else {
3700         m_styleResolver->appendAuthorStylesheets(m_styleSheets->length(), newStylesheets);
3701         resetCSSFeatureFlags();
3702     }
3703     m_styleSheets->swap(newStylesheets);
3704
3705     m_usesRemUnits = styleSheetsUseRemUnits(m_styleSheets->vector());
3706     m_didCalculateStyleResolver = true;
3707     m_hasDirtyStyleResolver = false;
3708
3709     notifySeamlessChildDocumentsOfStylesheetUpdate();
3710
3711     return requiresFullStyleRecalc;
3712 }
3713
3714 void Document::setHoverNode(PassRefPtr<Node> newHoverNode)
3715 {
3716     m_hoverNode = newHoverNode;
3717 }
3718
3719 void Document::setActiveNode(PassRefPtr<Node> newActiveNode)
3720 {
3721     m_activeNode = newActiveNode;
3722 }
3723
3724 void Document::focusedNodeRemoved()
3725 {
3726     setFocusedNode(0);
3727 }
3728
3729 void Document::removeFocusedNodeOfSubtree(Node* node, bool amongChildrenOnly)
3730 {
3731     if (!m_focusedNode || this->inPageCache()) // If the document is in the page cache, then we don't need to clear out the focused node.
3732         return;
3733         
3734     bool nodeInSubtree = false;
3735     if (amongChildrenOnly)
3736         nodeInSubtree = m_focusedNode->isDescendantOf(node);
3737     else
3738         nodeInSubtree = (m_focusedNode == node) || m_focusedNode->isDescendantOf(node);
3739     
3740     if (nodeInSubtree)
3741         document()->focusedNodeRemoved();
3742 }
3743
3744 void Document::hoveredNodeDetached(Node* node)
3745 {
3746     if (!m_hoverNode || (node != m_hoverNode && (!m_hoverNode->isTextNode() || node != m_hoverNode->parentNode())))
3747         return;
3748
3749     m_hoverNode = node->parentNode();
3750     while (m_hoverNode && !m_hoverNode->renderer())
3751         m_hoverNode = m_hoverNode->parentNode();
3752     if (frame())
3753         frame()->eventHandler()->scheduleHoverStateUpdate();
3754 }
3755
3756 void Document::activeChainNodeDetached(Node* node)
3757 {
3758     if (!m_activeNode || (node != m_activeNode && (!m_activeNode->isTextNode() || node != m_activeNode->parentNode())))
3759         return;
3760
3761     m_activeNode = node->parentNode();
3762     while (m_activeNode && !m_activeNode->renderer())
3763         m_activeNode = m_activeNode->parentNode();
3764 }
3765
3766 #if ENABLE(DASHBOARD_SUPPORT)
3767 const Vector<DashboardRegionValue>& Document::dashboardRegions() const
3768 {
3769     return m_dashboardRegions;
3770 }
3771
3772 void Document::setDashboardRegions(const Vector<DashboardRegionValue>& regions)
3773 {
3774     m_dashboardRegions = regions;
3775     setDashboardRegionsDirty(false);
3776 }
3777 #endif
3778
3779 bool Document::setFocusedNode(PassRefPtr<Node> prpNewFocusedNode)
3780 {
3781     RefPtr<Node> newFocusedNode = prpNewFocusedNode;
3782
3783     // Make sure newFocusedNode is actually in this document
3784     if (newFocusedNode && (newFocusedNode->document() != this))
3785         return true;
3786
3787     if (m_focusedNode == newFocusedNode) {
3788 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
3789         page()->chrome()->focusedNodeChanged(m_focusedNode.get());
3790 #endif
3791         return true;
3792     }
3793
3794     if (m_inPageCache)
3795         return false;
3796
3797     bool focusChangeBlocked = false;
3798     RefPtr<Node> oldFocusedNode = m_focusedNode;
3799     m_focusedNode = 0;
3800
3801     // Remove focus from the existing focus node (if any)
3802     if (oldFocusedNode) {
3803         ASSERT(!oldFocusedNode->inDetach());
3804
3805         if (oldFocusedNode->active())
3806             oldFocusedNode->setActive(false);
3807
3808         oldFocusedNode->setFocus(false);
3809
3810         // Dispatch a change event for text fields or textareas that have been edited
3811         if (oldFocusedNode->isElementNode()) {
3812             Element* element = static_cast<Element*>(oldFocusedNode.get());
3813             if (element->wasChangedSinceLastFormControlChangeEvent())
3814                 element->dispatchFormControlChangeEvent();
3815         }
3816
3817         // Dispatch the blur event and let the node do any other blur related activities (important for text fields)
3818         oldFocusedNode->dispatchBlurEvent(newFocusedNode);
3819
3820         if (m_focusedNode) {
3821             // handler shifted focus
3822             focusChangeBlocked = true;
3823             newFocusedNode = 0;
3824         }
3825         
3826         oldFocusedNode->dispatchFocusOutEvent(eventNames().focusoutEvent, newFocusedNode); // DOM level 3 name for the bubbling blur event.
3827         // FIXME: We should remove firing DOMFocusOutEvent event when we are sure no content depends
3828         // on it, probably when <rdar://problem/8503958> is resolved.
3829         oldFocusedNode->dispatchFocusOutEvent(eventNames().DOMFocusOutEvent, newFocusedNode); // DOM level 2 name for compatibility.
3830
3831         if (m_focusedNode) {
3832             // handler shifted focus
3833             focusChangeBlocked = true;
3834             newFocusedNode = 0;
3835         }
3836         if (oldFocusedNode == this && oldFocusedNode->hasOneRef())
3837             return true;
3838             
3839         if (oldFocusedNode->isRootEditableElement())
3840             frame()->editor()->didEndEditing();
3841
3842         if (view()) {
3843             Widget* oldWidget = widgetForNode(oldFocusedNode.get());
3844             if (oldWidget)
3845                 oldWidget->setFocus(false);
3846             else
3847                 view()->setFocus(false);
3848         }
3849     }
3850
3851     if (newFocusedNode) {
3852         if (newFocusedNode->isRootEditableElement() && !acceptsEditingFocus(newFocusedNode.get())) {
3853             // delegate blocks focus change
3854             focusChangeBlocked = true;
3855             goto SetFocusedNodeDone;
3856         }
3857         // Set focus on the new node
3858         m_focusedNode = newFocusedNode;
3859
3860         // Dispatch the focus event and let the node do any other focus related activities (important for text fields)
3861         m_focusedNode->dispatchFocusEvent(oldFocusedNode);
3862
3863         if (m_focusedNode != newFocusedNode) {
3864             // handler shifted focus
3865             focusChangeBlocked = true;
3866             goto SetFocusedNodeDone;
3867         }
3868
3869         m_focusedNode->dispatchFocusInEvent(eventNames().focusinEvent, oldFocusedNode); // DOM level 3 bubbling focus event.
3870
3871         if (m_focusedNode != newFocusedNode) {
3872             // handler shifted focus
3873             focusChangeBlocked = true;
3874             goto SetFocusedNodeDone;
3875         }
3876
3877         // FIXME: We should remove firing DOMFocusInEvent event when we are sure no content depends
3878         // on it, probably when <rdar://problem/8503958> is m.
3879         m_focusedNode->dispatchFocusInEvent(eventNames().DOMFocusInEvent, oldFocusedNode); // DOM level 2 for compatibility.
3880
3881         if (m_focusedNode != newFocusedNode) { 
3882             // handler shifted focus
3883             focusChangeBlocked = true;
3884             goto SetFocusedNodeDone;
3885         }
3886         m_focusedNode->setFocus(true);
3887
3888         if (m_focusedNode->isRootEditableElement())
3889             frame()->editor()->didBeginEditing();
3890
3891         // eww, I suck. set the qt focus correctly
3892         // ### find a better place in the code for this
3893         if (view()) {
3894             Widget* focusWidget = widgetForNode(m_focusedNode.get());
3895             if (focusWidget) {
3896                 // Make sure a widget has the right size before giving it focus.
3897                 // Otherwise, we are testing edge cases of the Widget code.
3898                 // Specifically, in WebCore this does not work well for text fields.
3899                 updateLayout();
3900                 // Re-get the widget in case updating the layout changed things.
3901                 focusWidget = widgetForNode(m_focusedNode.get());
3902             }
3903             if (focusWidget)
3904                 focusWidget->setFocus(true);
3905             else
3906                 view()->setFocus(true);
3907         }
3908     }
3909
3910 #if PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(CHROMIUM)
3911     if (!focusChangeBlocked && m_focusedNode && AXObjectCache::accessibilityEnabled()) {
3912         RenderObject* oldFocusedRenderer = 0;
3913         RenderObject* newFocusedRenderer = 0;
3914
3915         if (oldFocusedNode)
3916             oldFocusedRenderer = oldFocusedNode->renderer();
3917         if (newFocusedNode)
3918             newFocusedRenderer = newFocusedNode->renderer();
3919
3920         axObjectCache()->handleFocusedUIElementChanged(oldFocusedRenderer, newFocusedRenderer);
3921     }
3922 #endif
3923     if (!focusChangeBlocked)
3924         page()->chrome()->focusedNodeChanged(m_focusedNode.get());
3925
3926 SetFocusedNodeDone:
3927     updateStyleIfNeeded();
3928     return !focusChangeBlocked;
3929 }
3930     
3931 void Document::getFocusableNodes(Vector<RefPtr<Node> >& nodes)
3932 {
3933     updateLayout();
3934
3935     for (Node* node = firstChild(); node; node = node->traverseNextNode()) {
3936         if (node->isFocusable())
3937             nodes.append(node);
3938     }
3939 }
3940   
3941 void Document::setCSSTarget(Element* n)
3942 {
3943     if (m_cssTarget)
3944         m_cssTarget->setNeedsStyleRecalc();
3945     m_cssTarget = n;
3946     if (n)
3947         n->setNeedsStyleRecalc();
3948 }
3949
3950 void Document::registerNodeListCache(DynamicNodeListCacheBase* list)
3951 {
3952     if (list->type() != NodeListCollectionType)
3953         m_nodeListCounts[InvalidateOnIdNameAttrChange]++;
3954     m_nodeListCounts[list->invalidationType()]++;
3955     if (list->isRootedAtDocument())
3956         m_listsInvalidatedAtDocument.add(list);
3957 }
3958
3959 void Document::unregisterNodeListCache(DynamicNodeListCacheBase* list)
3960 {
3961     if (list->type() != NodeListCollectionType)
3962         m_nodeListCounts[InvalidateOnIdNameAttrChange]--;
3963     m_nodeListCounts[list->invalidationType()]--;
3964     if (list->isRootedAtDocument()) {
3965         ASSERT(m_listsInvalidatedAtDocument.contains(list));
3966         m_listsInvalidatedAtDocument.remove(list);
3967     }
3968 }
3969
3970 void Document::attachNodeIterator(NodeIterator* ni)
3971 {
3972     m_nodeIterators.add(ni);
3973 }
3974
3975 void Document::detachNodeIterator(NodeIterator* ni)
3976 {
3977     // The node iterator can be detached without having been attached if its root node didn't have a document
3978     // when the iterator was created, but has it now.
3979     m_nodeIterators.remove(ni);
3980 }
3981
3982 void Document::moveNodeIteratorsToNewDocument(Node* node, Document* newDocument)
3983 {
3984     HashSet<NodeIterator*> nodeIteratorsList = m_nodeIterators;
3985     HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = nodeIteratorsList.end();
3986     for (HashSet<NodeIterator*>::const_iterator it = nodeIteratorsList.begin(); it != nodeIteratorsEnd; ++it) {
3987         if ((*it)->root() == node) {
3988             detachNodeIterator(*it);
3989             newDocument->attachNodeIterator(*it);
3990         }
3991     }
3992 }
3993
3994 void Document::updateRangesAfterChildrenChanged(ContainerNode* container)
3995 {
3996     if (!m_ranges.isEmpty()) {
3997         HashSet<Range*>::const_iterator end = m_ranges.end();
3998         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
3999             (*it)->nodeChildrenChanged(container);
4000     }
4001 }
4002
4003 void Document::nodeChildrenWillBeRemoved(ContainerNode* container)
4004 {
4005     if (!m_ranges.isEmpty()) {
4006         HashSet<Range*>::const_iterator end = m_ranges.end();
4007         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
4008             (*it)->nodeChildrenWillBeRemoved(container);
4009     }
4010
4011     HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
4012     for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it) {
4013         for (Node* n = container->firstChild(); n; n = n->nextSibling())
4014             (*it)->nodeWillBeRemoved(n);
4015     }
4016
4017     if (Frame* frame = this->frame()) {
4018         for (Node* n = container->firstChild(); n; n = n->nextSibling()) {
4019             frame->eventHandler()->nodeWillBeRemoved(n);
4020             frame->selection()->nodeWillBeRemoved(n);
4021             frame->page()->dragCaretController()->nodeWillBeRemoved(n);
4022         }
4023     }
4024 }
4025
4026 void Document::nodeWillBeRemoved(Node* n)
4027 {
4028     HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
4029     for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it)
4030         (*it)->nodeWillBeRemoved(n);
4031
4032     if (!m_ranges.isEmpty()) {
4033         HashSet<Range*>::const_iterator rangesEnd = m_ranges.end();
4034         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != rangesEnd; ++it)
4035             (*it)->nodeWillBeRemoved(n);
4036     }
4037
4038     if (Frame* frame = this->frame()) {
4039         frame->eventHandler()->nodeWillBeRemoved(n);
4040         frame->selection()->nodeWillBeRemoved(n);
4041         frame->page()->dragCaretController()->nodeWillBeRemoved(n);
4042     }
4043 }
4044
4045 void Document::textInserted(Node* text, unsigned offset, unsigned length)
4046 {
4047     if (!m_ranges.isEmpty()) {
4048         HashSet<Range*>::const_iterator end = m_ranges.end();
4049         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
4050             (*it)->textInserted(text, offset, length);
4051     }
4052
4053     // Update the markers for spelling and grammar checking.
4054     m_markers->shiftMarkers(text, offset, length);
4055 }
4056
4057 void Document::textRemoved(Node* text, unsigned offset, unsigned length)
4058 {
4059     if (!m_ranges.isEmpty()) {
4060         HashSet<Range*>::const_iterator end = m_ranges.end();
4061         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
4062             (*it)->textRemoved(text, offset, length);
4063     }
4064
4065     // Update the markers for spelling and grammar checking.
4066     m_markers->removeMarkers(text, offset, length);
4067     m_markers->shiftMarkers(text, offset + length, 0 - length);
4068 }
4069
4070 void Document::textNodesMerged(Text* oldNode, unsigned offset)
4071 {
4072     if (!m_ranges.isEmpty()) {
4073         NodeWithIndex oldNodeWithIndex(oldNode);
4074         HashSet<Range*>::const_iterator end = m_ranges.end();
4075         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
4076             (*it)->textNodesMerged(oldNodeWithIndex, offset);
4077     }
4078
4079     // FIXME: This should update markers for spelling and grammar checking.
4080 }
4081
4082 void Document::textNodeSplit(Text* oldNode)
4083 {
4084     if (!m_ranges.isEmpty()) {
4085         HashSet<Range*>::const_iterator end = m_ranges.end();
4086         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
4087             (*it)->textNodeSplit(oldNode);
4088     }
4089
4090     // FIXME: This should update markers for spelling and grammar checking.
4091 }
4092
4093 // FIXME: eventually, this should return a DOMWindow stored in the document.
4094 DOMWindow* Document::domWindow() const
4095 {
4096     if (!frame())
4097         return 0;
4098
4099     // The m_frame pointer is not (not always?) zeroed out when the document is put into b/f cache, so the frame can hold an unrelated document/window pair.
4100     // FIXME: We should always zero out the frame pointer on navigation to avoid accidentally accessing the new frame content.
4101     if (m_frame->document() != this)
4102         return 0;
4103
4104     return frame()->domWindow();
4105 }
4106
4107 void Document::setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener)
4108 {
4109     DOMWindow* domWindow = this->domWindow();
4110     if (!domWindow)
4111         return;
4112     domWindow->setAttributeEventListener(eventType, listener);
4113 }
4114
4115 EventListener* Document::getWindowAttributeEventListener(const AtomicString& eventType)
4116 {
4117     DOMWindow* domWindow = this->domWindow();
4118     if (!domWindow)
4119         return 0;
4120     return domWindow->getAttributeEventListener(eventType);
4121 }
4122
4123 void Document::dispatchWindowEvent(PassRefPtr<Event> event,  PassRefPtr<EventTarget> target)
4124 {
4125     ASSERT(!eventDispatchForbidden());
4126     DOMWindow* domWindow = this->domWindow();
4127     if (!domWindow)
4128         return;
4129     domWindow->dispatchEvent(event, target);
4130 }
4131
4132 void Document::dispatchWindowLoadEvent()
4133 {
4134     ASSERT(!eventDispatchForbidden());
4135     DOMWindow* domWindow = this->domWindow();
4136     if (!domWindow)
4137         return;
4138     domWindow->dispatchLoadEvent();
4139     m_loadEventFinished = true;
4140 }
4141
4142 void Document::enqueueWindowEvent(PassRefPtr<Event> event)
4143 {
4144     event->setTarget(domWindow());
4145     m_eventQueue->enqueueEvent(event);
4146 }
4147
4148 void Document::enqueueDocumentEvent(PassRefPtr<Event> event)
4149 {
4150     event->setTarget(this);
4151     m_eventQueue->enqueueEvent(event);
4152 }
4153
4154 PassRefPtr<Event> Document::createEvent(const String& eventType, ExceptionCode& ec)
4155 {
4156     RefPtr<Event> event = EventFactory::create(eventType);
4157     if (event)
4158         return event.release();
4159
4160     ec = NOT_SUPPORTED_ERR;
4161     return 0;
4162 }
4163
4164 void Document::addListenerTypeIfNeeded(const AtomicString& eventType)
4165 {
4166     if (eventType == eventNames().DOMSubtreeModifiedEvent)
4167         addListenerType(DOMSUBTREEMODIFIED_LISTENER);
4168     else if (eventType == eventNames().DOMNodeInsertedEvent)
4169         addListenerType(DOMNODEINSERTED_LISTENER);
4170     else if (eventType == eventNames().DOMNodeRemovedEvent)
4171         addListenerType(DOMNODEREMOVED_LISTENER);
4172     else if (eventType == eventNames().DOMNodeRemovedFromDocumentEvent)
4173         addListenerType(DOMNODEREMOVEDFROMDOCUMENT_LISTENER);
4174     else if (eventType == eventNames().DOMNodeInsertedIntoDocumentEvent)
4175         addListenerType(DOMNODEINSERTEDINTODOCUMENT_LISTENER);
4176     else if (eventType == eventNames().DOMAttrModifiedEvent)
4177         addListenerType(DOMATTRMODIFIED_LISTENER);
4178     else if (eventType == eventNames().DOMCharacterDataModifiedEvent)
4179         addListenerType(DOMCHARACTERDATAMODIFIED_LISTENER);
4180     else if (eventType == eventNames().overflowchangedEvent)
4181         addListenerType(OVERFLOWCHANGED_LISTENER);
4182     else if (eventType == eventNames().webkitAnimationStartEvent)
4183         addListenerType(ANIMATIONSTART_LISTENER);
4184     else if (eventType == eventNames().webkitAnimationEndEvent)
4185         addListenerType(ANIMATIONEND_LISTENER);
4186     else if (eventType == eventNames().webkitAnimationIterationEvent)
4187         addListenerType(ANIMATIONITERATION_LISTENER);
4188     else if (eventType == eventNames().webkitTransitionEndEvent)
4189         addListenerType(TRANSITIONEND_LISTENER);
4190     else if (eventType == eventNames().beforeloadEvent)
4191         addListenerType(BEFORELOAD_LISTENER);
4192 #if ENABLE(TOUCH_EVENTS)
4193     else if (eventType == eventNames().touchstartEvent
4194              || eventType == eventNames().touchmoveEvent
4195              || eventType == eventNames().touchendEvent
4196              || eventType == eventNames().touchcancelEvent) {
4197         addListenerType(TOUCH_LISTENER);
4198         if (Page* page = this->page())
4199             page->chrome()->client()->needTouchEvents(true);
4200     }
4201 #endif
4202     else if (eventType == eventNames().scrollEvent)
4203         addListenerType(SCROLL_LISTENER);
4204     else if (eventType == eventNames().webkitRegionLayoutUpdateEvent)
4205         addListenerType(REGIONLAYOUTUPDATE_LISTENER);
4206 }
4207
4208 #if ENABLE(TIZEN_PLUGIN_TOUCH_EVENT)
4209 void Document::removeListenerType(const AtomicString& eventType)
4210 {
4211     if (eventType == eventNames().touchstartEvent
4212              || eventType == eventNames().touchmoveEvent
4213              || eventType == eventNames().touchendEvent
4214              || eventType == eventNames().touchcancelEvent) {
4215         if (!m_touchEventHandlerCount) {
4216             m_listenerTypes = m_listenerTypes & ~TOUCH_LISTENER;
4217             if (Page* page = this->page())
4218                 page->chrome()->client()->needTouchEvents(false);
4219         }
4220     }
4221 }
4222 #endif
4223
4224 CSSStyleDeclaration* Document::getOverrideStyle(Element*, const String&)
4225 {
4226     return 0;
4227 }
4228
4229 HTMLFrameOwnerElement* Document::ownerElement() const
4230 {
4231     if (!frame())
4232         return 0;
4233     return frame()->ownerElement();
4234 }
4235
4236 String Document::cookie(ExceptionCode& ec) const
4237 {
4238     if (page() && !page()->settings()->cookieEnabled())
4239         return String();
4240
4241     // FIXME: The HTML5 DOM spec states that this attribute can raise an
4242     // INVALID_STATE_ERR exception on getting if the Document has no
4243     // browsing context.
4244
4245     if (!securityOrigin()->canAccessCookies()) {
4246         ec = SECURITY_ERR;
4247         return String();
4248     }
4249
4250     KURL cookieURL = this->cookieURL();
4251     if (cookieURL.isEmpty())
4252         return String();
4253
4254     return cookies(this, cookieURL);
4255 }
4256
4257 void Document::setCookie(const String& value, ExceptionCode& ec)
4258 {
4259     if (page() && !page()->settings()->cookieEnabled())
4260         return;
4261
4262     // FIXME: The HTML5 DOM spec states that this attribute can raise an
4263     // INVALID_STATE_ERR exception on setting if the Document has no
4264     // browsing context.
4265
4266     if (!securityOrigin()->canAccessCookies()) {
4267         ec = SECURITY_ERR;
4268         return;
4269     }
4270
4271     KURL cookieURL = this->cookieURL();
4272     if (cookieURL.isEmpty())
4273         return;
4274
4275     setCookies(this, cookieURL, value);
4276 }
4277
4278 String Document::referrer() const
4279 {
4280     if (frame())
4281         return frame()->loader()->referrer();
4282     return String();
4283 }
4284
4285 String Document::domain() const
4286 {
4287     return securityOrigin()->domain();
4288 }
4289
4290 void Document::setDomain(const String& newDomain, ExceptionCode& ec)
4291 {
4292     if (SchemeRegistry::isDomainRelaxationForbiddenForURLScheme(securityOrigin()->protocol())) {
4293         ec = SECURITY_ERR;
4294         return;
4295     }
4296
4297     // Both NS and IE specify that changing the domain is only allowed when
4298     // the new domain is a suffix of the old domain.
4299
4300     // FIXME: We should add logging indicating why a domain was not allowed.
4301
4302     // If the new domain is the same as the old domain, still call
4303     // securityOrigin()->setDomainForDOM. This will change the
4304     // security check behavior. For example, if a page loaded on port 8000
4305     // assigns its current domain using document.domain, the page will
4306     // allow other pages loaded on different ports in the same domain that
4307     // have also assigned to access this page.
4308     if (equalIgnoringCase(domain(), newDomain)) {
4309         securityOrigin()->setDomainFromDOM(newDomain);
4310         if (m_frame)
4311             m_frame->script()->updateSecurityOrigin();
4312         return;
4313     }
4314
4315     int oldLength = domain().length();
4316     int newLength = newDomain.length();
4317     // e.g. newDomain = webkit.org (10) and domain() = www.webkit.org (14)
4318     if (newLength >= oldLength) {
4319         ec = SECURITY_ERR;
4320         return;
4321     }
4322
4323     String test = domain();
4324     // Check that it's a subdomain, not e.g. "ebkit.org"
4325     if (test[oldLength - newLength - 1] != '.') {
4326         ec = SECURITY_ERR;
4327         return;
4328     }
4329
4330     // Now test is "webkit.org" from domain()
4331     // and we check that it's the same thing as newDomain
4332     test.remove(0, oldLength - newLength);
4333     if (test != newDomain) {
4334         ec = SECURITY_ERR;
4335         return;
4336     }
4337
4338     securityOrigin()->setDomainFromDOM(newDomain);
4339     if (m_frame)
4340         m_frame->script()->updateSecurityOrigin();
4341 }
4342
4343 // http://www.whatwg.org/specs/web-apps/current-work/#dom-document-lastmodified
4344 String Document::lastModified() const
4345 {
4346     DateComponents date;
4347     bool foundDate = false;
4348     if (m_frame) {
4349         String httpLastModified;
4350         if (DocumentLoader* documentLoader = loader()) 
4351             httpLastModified = documentLoader->response().httpHeaderField("Last-Modified");
4352         if (!httpLastModified.isEmpty()) {
4353             date.setMillisecondsSinceEpochForDateTime(parseDate(httpLastModified));
4354             foundDate = true;
4355         }
4356     }
4357     // FIXME: If this document came from the file system, the HTML5
4358     // specificiation tells us to read the last modification date from the file
4359     // system.
4360     if (!foundDate)
4361         date.setMillisecondsSinceEpochForDateTime(currentTimeMS());
4362     return String::format("%02d/%02d/%04d %02d:%02d:%02d", date.month() + 1, date.monthDay(), date.fullYear(), date.hour(), date.minute(), date.second());
4363 }
4364
4365 static bool isValidNameNonASCII(const UChar* characters, unsigned length)
4366 {
4367     unsigned i = 0;
4368
4369     UChar32 c;
4370     U16_NEXT(characters, i, length, c)
4371     if (!isValidNameStart(c))
4372         return false;
4373
4374     while (i < length) {
4375         U16_NEXT(characters, i, length, c)
4376         if (!isValidNamePart(c))
4377             return false;
4378     }
4379
4380     return true;
4381 }
4382
4383 template<typename CharType>
4384 static inline bool isValidNameASCII(const CharType* characters, unsigned length)
4385 {
4386     CharType c = characters[0];
4387     if (!(isASCIIAlpha(c) || c == ':' || c == '_'))
4388         return false;
4389
4390     for (unsigned i = 1; i < length; ++i) {
4391         c = characters[i];
4392         if (!(isASCIIAlphanumeric(c) || c == ':' || c == '_' || c == '-' || c == '.'))
4393             return false;
4394     }
4395
4396     return true;
4397 }
4398
4399 bool Document::isValidName(const String& name)
4400 {
4401     unsigned length = name.length();
4402     if (!length)
4403         return false;
4404
4405     const UChar* characters;
4406     if (name.is8Bit()) {
4407         if (isValidNameASCII(name.characters8(), length))
4408             return true;
4409         characters = name.characters();
4410     } else {
4411         characters = name.characters16();
4412         if (isValidNameASCII(characters, length))
4413             return true;
4414     }
4415     return isValidNameNonASCII(characters, length);
4416 }
4417
4418 bool Document::parseQualifiedName(const String& qualifiedName, String& prefix, String& localName, ExceptionCode& ec)
4419 {
4420     unsigned length = qualifiedName.length();
4421
4422     if (!length) {
4423         ec = INVALID_CHARACTER_ERR;
4424         return false;
4425     }
4426
4427     bool nameStart = true;
4428     bool sawColon = false;
4429     int colonPos = 0;
4430
4431     const UChar* s = qualifiedName.characters();
4432     for (unsigned i = 0; i < length;) {
4433         UChar32 c;
4434         U16_NEXT(s, i, length, c)
4435         if (c == ':') {
4436             if (sawColon) {
4437                 ec = NAMESPACE_ERR;
4438                 return false; // multiple colons: not allowed
4439             }
4440             nameStart = true;
4441             sawColon = true;
4442             colonPos = i - 1;
4443         } else if (nameStart) {
4444             if (!isValidNameStart(c)) {
4445                 ec = INVALID_CHARACTER_ERR;
4446                 return false;
4447             }
4448             nameStart = false;
4449         } else {
4450             if (!isValidNamePart(c)) {
4451                 ec = INVALID_CHARACTER_ERR;
4452                 return false;
4453             }
4454         }
4455     }
4456
4457     if (!sawColon) {
4458         prefix = String();
4459         localName = qualifiedName;
4460     } else {
4461         prefix = qualifiedName.substring(0, colonPos);
4462         if (prefix.isEmpty()) {
4463             ec = NAMESPACE_ERR;
4464             return false;
4465         }
4466         localName = qualifiedName.substring(colonPos + 1);
4467     }
4468
4469     if (localName.isEmpty()) {
4470         ec = NAMESPACE_ERR;
4471         return false;
4472     }
4473
4474     return true;
4475 }
4476
4477 void Document::setDecoder(PassRefPtr<TextResourceDecoder> decoder)
4478 {
4479     m_decoder = decoder;
4480 }
4481
4482 KURL Document::completeURL(const String& url, const KURL& baseURLOverride) const
4483 {
4484     // Always return a null URL when passed a null string.
4485     // FIXME: Should we change the KURL constructor to have this behavior?
4486     // See also [CSS]StyleSheet::completeURL(const String&)
4487     if (url.isNull())
4488         return KURL();
4489     const KURL& baseURL = ((baseURLOverride.isEmpty() || baseURLOverride == blankURL()) && parentDocument()) ? parentDocument()->baseURL() : baseURLOverride;
4490     if (!m_decoder)
4491         return KURL(baseURL, url);
4492     return KURL(baseURL, url, m_decoder->encoding());
4493 }
4494
4495 KURL Document::completeURL(const String& url) const
4496 {
4497     return completeURL(url, m_baseURL);
4498 }
4499
4500 void Document::setInPageCache(bool flag)
4501 {
4502     if (m_inPageCache == flag)
4503         return;
4504
4505     m_inPageCache = flag;
4506
4507     FrameView* v = view();
4508     if (flag) {
4509         ASSERT(!m_savedRenderer);
4510         m_savedRenderer = renderer();
4511         if (v) {
4512             v->cacheCurrentScrollPosition();
4513             if (page() && page()->mainFrame() == m_frame)
4514                 v->resetScrollbarsAndClearContentsSize();
4515             else
4516                 v->resetScrollbars();
4517         }
4518         m_styleRecalcTimer.stop();
4519     } else {
4520         ASSERT(!renderer() || renderer() == m_savedRenderer);
4521         ASSERT(m_renderArena);
4522         setRenderer(m_savedRenderer);
4523         m_savedRenderer = 0;
4524
4525         if (childNeedsStyleRecalc())
4526             scheduleStyleRecalc();
4527     }
4528 }
4529
4530 void Document::documentWillBecomeInactive()
4531 {
4532 #if USE(ACCELERATED_COMPOSITING)
4533     if (renderer())
4534         renderView()->willMoveOffscreen();
4535 #endif
4536 }
4537
4538 void Document::documentWillSuspendForPageCache()
4539 {
4540     documentWillBecomeInactive();
4541
4542     HashSet<Element*>::iterator end = m_documentSuspensionCallbackElements.end();
4543     for (HashSet<Element*>::iterator i = m_documentSuspensionCallbackElements.begin(); i != end; ++i)
4544         (*i)->documentWillSuspendForPageCache();
4545
4546 #ifndef NDEBUG
4547     // Clear the update flag to be able to check if the viewport arguments update
4548     // is dispatched, after the document is restored from the page cache.
4549     m_didDispatchViewportPropertiesChanged = false;
4550 #endif
4551 }
4552
4553 void Document::documentDidResumeFromPageCache() 
4554 {
4555     Vector<Element*> elements;
4556     copyToVector(m_documentSuspensionCallbackElements, elements);
4557     Vector<Element*>::iterator end = elements.end();
4558     for (Vector<Element*>::iterator i = elements.begin(); i != end; ++i)
4559         (*i)->documentDidResumeFromPageCache();
4560
4561 #if USE(ACCELERATED_COMPOSITING)
4562     if (renderer())
4563         renderView()->didMoveOnscreen();
4564 #endif
4565
4566     if (FrameView* frameView = view())
4567         frameView->setAnimatorsAreActive();
4568
4569     ASSERT(m_frame);
4570     m_frame->loader()->client()->dispatchDidBecomeFrameset(isFrameSet());
4571 }
4572
4573 void Document::registerForPageCacheSuspensionCallbacks(Element* e)
4574 {
4575     m_documentSuspensionCallbackElements.add(e);
4576 }
4577
4578 void Document::unregisterForPageCacheSuspensionCallbacks(Element* e)
4579 {
4580     m_documentSuspensionCallbackElements.remove(e);
4581 }
4582
4583 void Document::mediaVolumeDidChange() 
4584 {
4585     HashSet<Element*>::iterator end = m_mediaVolumeCallbackElements.end();
4586     for (HashSet<Element*>::iterator i = m_mediaVolumeCallbackElements.begin(); i != end; ++i)
4587         (*i)->mediaVolumeDidChange();
4588 }
4589
4590 void Document::registerForMediaVolumeCallbacks(Element* e)
4591 {
4592     m_mediaVolumeCallbackElements.add(e);
4593 }
4594
4595 void Document::unregisterForMediaVolumeCallbacks(Element* e)
4596 {
4597     m_mediaVolumeCallbackElements.remove(e);
4598 }
4599
4600 void Document::privateBrowsingStateDidChange() 
4601 {
4602     HashSet<Element*>::iterator end = m_privateBrowsingStateChangedElements.end();
4603     for (HashSet<Element*>::iterator it = m_privateBrowsingStateChangedElements.begin(); it != end; ++it)
4604         (*it)->privateBrowsingStateDidChange();
4605 }
4606
4607 void Document::registerForPrivateBrowsingStateChangedCallbacks(Element* e)
4608 {
4609     m_privateBrowsingStateChangedElements.add(e);
4610 }
4611
4612 void Document::unregisterForPrivateBrowsingStateChangedCallbacks(Element* e)
4613 {
4614     m_privateBrowsingStateChangedElements.remove(e);
4615 }
4616
4617 void Document::setShouldCreateRenderers(bool f)
4618 {
4619     m_createRenderers = f;
4620 }
4621
4622 bool Document::shouldCreateRenderers()
4623 {
4624     return m_createRenderers;
4625 }
4626
4627 // Support for Javascript execCommand, and related methods
4628
4629 static Editor::Command command(Document* document, const String& commandName, bool userInterface = false)
4630 {
4631     Frame* frame = document->frame();
4632     if (!frame || frame->document() != document)
4633         return Editor::Command();
4634
4635     document->updateStyleIfNeeded();
4636
4637     return frame->editor()->command(commandName,
4638         userInterface ? CommandFromDOMWithUserInterface : CommandFromDOM);
4639 }
4640
4641 bool Document::execCommand(const String& commandName, bool userInterface, const String& value)
4642 {
4643     return command(this, commandName, userInterface).execute(value);
4644 }
4645
4646 bool Document::queryCommandEnabled(const String& commandName)
4647 {
4648     return command(this, commandName).isEnabled();
4649 }
4650
4651 bool Document::queryCommandIndeterm(const String& commandName)
4652 {
4653     return command(this, commandName).state() == MixedTriState;
4654 }
4655
4656 bool Document::queryCommandState(const String& commandName)
4657 {
4658     return command(this, commandName).state() == TrueTriState;
4659 }
4660
4661 bool Document::queryCommandSupported(const String& commandName)
4662 {
4663     return command(this, commandName).isSupported();
4664 }
4665
4666 String Document::queryCommandValue(const String& commandName)
4667 {
4668     return command(this, commandName).value();
4669 }
4670
4671 KURL Document::openSearchDescriptionURL()
4672 {
4673     static const char* const openSearchMIMEType = "application/opensearchdescription+xml";
4674     static const char* const openSearchRelation = "search";
4675
4676     // FIXME: Why do only top-level frames have openSearchDescriptionURLs?
4677     if (!frame() || frame()->tree()->parent())
4678         return KURL();
4679
4680     // FIXME: Why do we need to wait for FrameStateComplete?
4681     if (frame()->loader()->state() != FrameStateComplete)
4682         return KURL();
4683
4684     if (!head())
4685         return KURL();
4686
4687     RefPtr<HTMLCollection> children = head()->children();
4688     for (unsigned i = 0; Node* child = children->item(i); i++) {
4689         if (!child->hasTagName(linkTag))
4690             continue;
4691         HTMLLinkElement* linkElement = static_cast<HTMLLinkElement*>(child);
4692         if (!equalIgnoringCase(linkElement->type(), openSearchMIMEType) || !equalIgnoringCase(linkElement->rel(), openSearchRelation))
4693             continue;
4694         if (linkElement->href().isEmpty())
4695             continue;
4696         return linkElement->href();
4697     }
4698
4699     return KURL();
4700 }
4701
4702 #if ENABLE(XSLT)
4703
4704 void Document::applyXSLTransform(ProcessingInstruction* pi)
4705 {
4706     RefPtr<XSLTProcessor> processor = XSLTProcessor::create();
4707     processor->setXSLStyleSheet(static_cast<XSLStyleSheet*>(pi->sheet()));
4708     String resultMIMEType;
4709     String newSource;
4710     String resultEncoding;
4711     if (!processor->transformToString(this, resultMIMEType, newSource, resultEncoding))
4712         return;
4713     // FIXME: If the transform failed we should probably report an error (like Mozilla does).
4714     processor->createDocumentFromSource(newSource, resultEncoding, resultMIMEType, this, frame());
4715 }
4716
4717 void Document::setTransformSource(PassOwnPtr<TransformSource> source)
4718 {
4719     m_transformSource = source;
4720 }
4721
4722 #endif
4723
4724 void Document::setDesignMode(InheritedBool value)
4725 {
4726     m_designMode = value;
4727     for (Frame* frame = m_frame; frame && frame->document(); frame = frame->tree()->traverseNext(m_frame))
4728         frame->document()->scheduleForcedStyleRecalc();
4729 }
4730
4731 Document::InheritedBool Document::getDesignMode() const
4732 {
4733     return m_designMode;
4734 }
4735
4736 bool Document::inDesignMode() const
4737 {
4738     for (const Document* d = this; d; d = d->parentDocument()) {
4739         if (d->m_designMode != inherit)
4740             return d->m_designMode;
4741     }
4742     return false;
4743 }
4744
4745 Document* Document::parentDocument() const
4746 {
4747     if (!m_frame)
4748         return 0;
4749     Frame* parent = m_frame->tree()->parent();
4750     if (!parent)
4751         return 0;
4752     return parent->document();
4753 }
4754
4755 Document* Document::topDocument() const
4756 {
4757     Document* doc = const_cast<Document *>(this);
4758     Element* element;
4759     while ((element = doc->ownerElement()))
4760         doc = element->document();
4761     
4762     return doc;
4763 }
4764
4765 PassRefPtr<Attr> Document::createAttribute(const String& name, ExceptionCode& ec)
4766 {
4767     return createAttributeNS(String(), name, ec, true);
4768 }
4769
4770 PassRefPtr<Attr> Document::createAttributeNS(const String& namespaceURI, const String& qualifiedName, ExceptionCode& ec, bool shouldIgnoreNamespaceChecks)
4771 {
4772     String prefix, localName;
4773     if (!parseQualifiedName(qualifiedName, prefix, localName, ec))
4774         return 0;
4775
4776     QualifiedName qName(prefix, localName, namespaceURI);
4777
4778     if (!shouldIgnoreNamespaceChecks && !hasValidNamespaceForAttributes(qName)) {
4779         ec = NAMESPACE_ERR;
4780         return 0;
4781     }
4782
4783     return Attr::create(this, qName, emptyString());
4784 }
4785
4786 #if ENABLE(SVG)
4787 const SVGDocumentExtensions* Document::svgExtensions()
4788 {
4789     return m_svgExtensions.get();
4790 }
4791
4792 SVGDocumentExtensions* Document::accessSVGExtensions()
4793 {
4794     if (!m_svgExtensions)
4795         m_svgExtensions = adoptPtr(new SVGDocumentExtensions(this));
4796     return m_svgExtensions.get();
4797 }
4798
4799 bool Document::hasSVGRootNode() const
4800 {
4801     return documentElement() && documentElement()->hasTagName(SVGNames::svgTag);
4802 }
4803 #endif
4804
4805 // FIXME: This caching mechanism should be merged that of DynamicNodeList in NodeRareData.
4806 PassRefPtr<HTMLCollection> Document::cachedCollection(CollectionType type)
4807 {
4808     ASSERT(static_cast<unsigned>(type) < NumUnnamedDocumentCachedTypes);
4809     if (m_collections[type])
4810         return m_collections[type];
4811
4812     RefPtr<HTMLCollection> collection;
4813     if (type == DocAll)
4814         collection = HTMLAllCollection::create(this);
4815     else
4816         collection = HTMLCollection::create(this, type);
4817     m_collections[type] = collection.get();
4818
4819     return collection.release();
4820 }
4821
4822 void Document::removeCachedHTMLCollection(HTMLCollection* collection, CollectionType type)
4823 {
4824     ASSERT_UNUSED(collection, m_collections[type] == collection);
4825     m_collections[type] = 0;
4826 }
4827
4828 PassRefPtr<HTMLCollection> Document::images()
4829 {
4830     return cachedCollection(DocImages);
4831 }
4832
4833 PassRefPtr<HTMLCollection> Document::applets()
4834 {
4835     return cachedCollection(DocApplets);
4836 }
4837
4838 PassRefPtr<HTMLCollection> Document::embeds()
4839 {
4840     return cachedCollection(DocEmbeds);
4841 }
4842
4843 PassRefPtr<HTMLCollection> Document::plugins()
4844 {
4845     // This is an alias for embeds() required for the JS DOM bindings.
4846     return cachedCollection(DocEmbeds);
4847 }
4848
4849 PassRefPtr<HTMLCollection> Document::objects()
4850 {
4851     return cachedCollection(DocObjects);
4852 }
4853
4854 PassRefPtr<HTMLCollection> Document::scripts()
4855 {
4856     return cachedCollection(DocScripts);
4857 }
4858
4859 PassRefPtr<HTMLCollection> Document::links()
4860 {
4861     return cachedCollection(DocLinks);
4862 }
4863
4864 PassRefPtr<HTMLCollection> Document::forms()
4865 {
4866     return cachedCollection(DocForms);
4867 }
4868
4869 PassRefPtr<HTMLCollection> Document::anchors()
4870 {
4871     return cachedCollection(DocAnchors);
4872 }
4873
4874 PassRefPtr<HTMLCollection> Document::all()
4875 {
4876     return cachedCollection(DocAll);
4877 }
4878
4879 PassRefPtr<HTMLCollection> Document::windowNamedItems(const AtomicString& name)
4880 {
4881     NamedCollectionMap::AddResult result = m_windowNamedItemCollections.add(name, 0);
4882     if (!result.isNewEntry)
4883         return result.iterator->second;
4884
4885     RefPtr<HTMLNameCollection> collection = HTMLNameCollection::create(this, WindowNamedItems, name);
4886     result.iterator->second = collection.get();
4887     return collection.release();
4888 }
4889
4890 PassRefPtr<HTMLCollection> Document::documentNamedItems(const AtomicString& name)
4891 {
4892     NamedCollectionMap::AddResult result = m_documentNamedItemCollections.add(name, 0);
4893     if (!result.isNewEntry)
4894         return result.iterator->second;
4895
4896     RefPtr<HTMLNameCollection> collection = HTMLNameCollection::create(this, DocumentNamedItems, name);
4897     result.iterator->second = collection.get();
4898     return collection.release();
4899 }
4900
4901 // FIXME: This caching mechanism should be merged that of DynamicNodeList in NodeRareData.
4902 void Document::removeWindowNamedItemCache(HTMLCollection* collection, const AtomicString& name)
4903 {
4904     ASSERT_UNUSED(collection, m_windowNamedItemCollections.get(name) == collection);
4905     m_windowNamedItemCollections.remove(name);
4906 }
4907
4908 void Document::removeDocumentNamedItemCache(HTMLCollection* collection, const AtomicString& name)
4909 {
4910     ASSERT_UNUSED(collection, m_documentNamedItemCollections.get(name) == collection);
4911     m_documentNamedItemCollections.remove(name);
4912 }
4913
4914 void Document::finishedParsing()
4915 {
4916     ASSERT(!scriptableDocumentParser() || !m_parser->isParsing());
4917     ASSERT(!scriptableDocumentParser() || m_readyState != Loading);
4918     setParsing(false);
4919     if (!m_documentTiming.domContentLoadedEventStart)
4920         m_documentTiming.domContentLoadedEventStart = monotonicallyIncreasingTime();
4921     dispatchEvent(Event::create(eventNames().DOMContentLoadedEvent, true, false));
4922     if (!m_documentTiming.domContentLoadedEventEnd)
4923         m_documentTiming.domContentLoadedEventEnd = monotonicallyIncreasingTime();
4924
4925     if (RefPtr<Frame> f = frame()) {
4926         // FrameLoader::finishedParsing() might end up calling Document::implicitClose() if all
4927         // resource loads are complete. HTMLObjectElements can start loading their resources from
4928         // post attach callbacks triggered by recalcStyle().  This means if we parse out an <object>
4929         // tag and then reach the end of the document without updating styles, we might not have yet
4930         // started the resource load and might fire the window load event too early.  To avoid this
4931         // we force the styles to be up to date before calling FrameLoader::finishedParsing().
4932         // See https://bugs.webkit.org/show_bug.cgi?id=36864 starting around comment 35.
4933         updateStyleIfNeeded();
4934
4935         f->loader()->finishedParsing();
4936
4937         InspectorInstrumentation::domContentLoadedEventFired(f.get());
4938     }
4939 }
4940
4941 PassRefPtr<XPathExpression> Document::createExpression(const String& expression,
4942                                                        XPathNSResolver* resolver,
4943                                                        ExceptionCode& ec)
4944 {
4945     if (!m_xpathEvaluator)
4946         m_xpathEvaluator = XPathEvaluator::create();
4947     return m_xpathEvaluator->createExpression(expression, resolver, ec);
4948 }
4949
4950 PassRefPtr<XPathNSResolver> Document::createNSResolver(Node* nodeResolver)
4951 {
4952     if (!m_xpathEvaluator)
4953         m_xpathEvaluator = XPathEvaluator::create();
4954     return m_xpathEvaluator->createNSResolver(nodeResolver);
4955 }
4956
4957 PassRefPtr<XPathResult> Document::evaluate(const String& expression,
4958                                            Node* contextNode,
4959                                            XPathNSResolver* resolver,
4960                                            unsigned short type,
4961                                            XPathResult* result,
4962                                            ExceptionCode& ec)
4963 {
4964     if (!m_xpathEvaluator)
4965         m_xpathEvaluator = XPathEvaluator::create();
4966     return m_xpathEvaluator->evaluate(expression, contextNode, resolver, type, result, ec);
4967 }
4968
4969 const Vector<IconURL>& Document::iconURLs()
4970 {
4971     m_iconURLs.clear();
4972
4973     if (!head() || !(head()->children()))
4974         return m_iconURLs;
4975
4976     // Include any icons where type = link, rel = "shortcut icon".
4977     RefPtr<HTMLCollection> children = head()->children();
4978     unsigned int length = children->length();
4979     for (unsigned int i = 0; i < length; ++i) {
4980         Node* child = children->item(i);
4981         if (!child->hasTagName(linkTag))
4982             continue;
4983         HTMLLinkElement* linkElement = static_cast<HTMLLinkElement*>(child);
4984         if (linkElement->iconType() != Favicon)
4985             continue;
4986         if (linkElement->href().isEmpty())
4987             continue;
4988
4989         // Put it at the front to ensure that icons seen later take precedence as required by the spec.
4990         IconURL newURL(linkElement->href(), linkElement->iconSizes(), linkElement->type(), linkElement->iconType());
4991         m_iconURLs.prepend(newURL);
4992     }
4993
4994     return m_iconURLs;
4995 }
4996
4997 void Document::addIconURL(const String& url, const String& mimeType, const String& sizes, IconType iconType)
4998 {
4999     if (url.isEmpty())
5000         return;
5001
5002     // FIXME - <rdar://problem/4727645> - At some point in the future, we might actually honor the "mimeType"
5003     IconURL newURL(KURL(ParsedURLString, url), sizes, mimeType, iconType);
5004
5005     if (Frame* f = frame()) {
5006         IconURL iconURL = f->loader()->icon()->iconURL(iconType);
5007         if (iconURL == newURL)
5008             f->loader()->didChangeIcons(iconType);
5009     }
5010 }
5011
5012 void Document::setUseSecureKeyboardEntryWhenActive(bool usesSecureKeyboard)
5013 {
5014     if (m_useSecureKeyboardEntryWhenActive == usesSecureKeyboard)
5015         return;
5016
5017     m_useSecureKeyboardEntryWhenActive = usesSecureKeyboard;
5018     m_frame->selection()->updateSecureKeyboardEntryIfActive();
5019 }
5020
5021 bool Document::useSecureKeyboardEntryWhenActive() const
5022 {
5023     return m_useSecureKeyboardEntryWhenActive;
5024 }
5025
5026 static bool isEligibleForSeamless(Document* parent, Document* child)
5027 {
5028     // It should not matter what we return for the top-most document.
5029     if (!parent)
5030         return false;
5031     if (parent->isSandboxed(SandboxSeamlessIframes))
5032         return false;
5033     if (child->isSrcdocDocument())
5034         return true;
5035     if (parent->securityOrigin()->canAccess(child->securityOrigin()))
5036         return true;
5037     return parent->securityOrigin()->canRequest(child->url());
5038 }
5039
5040 void Document::initSecurityContext()
5041 {
5042     if (haveInitializedSecurityOrigin()) {
5043         ASSERT(securityOrigin());
5044         return;
5045     }
5046
5047     if (!m_frame) {
5048         // No source for a security context.
5049         // This can occur via document.implementation.createDocument().
5050         m_cookieURL = KURL(ParsedURLString, emptyString());
5051         setSecurityOrigin(SecurityOrigin::createUnique());
5052         setContentSecurityPolicy(ContentSecurityPolicy::create(this));
5053         return;
5054     }
5055
5056     // In the common case, create the security context from the currently
5057     // loading URL with a fresh content security policy.
5058     m_cookieURL = m_url;
5059     enforceSandboxFlags(m_frame->loader()->effectiveSandboxFlags());
5060     setSecurityOrigin(isSandboxed(SandboxOrigin) ? SecurityOrigin::createUnique() : SecurityOrigin::create(m_url));
5061     setContentSecurityPolicy(ContentSecurityPolicy::create(this));
5062
5063     if (SecurityPolicy::allowSubstituteDataAccessToLocal()) {
5064         // If this document was loaded with substituteData, then the document can
5065         // load local resources.  See https://bugs.webkit.org/show_bug.cgi?id=16756
5066         // and https://bugs.webkit.org/show_bug.cgi?id=19760 for further
5067         // discussion.
5068         
5069         DocumentLoader* documentLoader = loader();
5070         if (documentLoader && documentLoader->substituteData().isValid())
5071             securityOrigin()->grantLoadLocalResources();
5072     }
5073
5074     if (Settings* settings = this->settings()) {
5075         if (!settings->isWebSecurityEnabled()) {
5076             // Web security is turned off. We should let this document access every other document. This is used primary by testing
5077             // harnesses for web sites.
5078             securityOrigin()->grantUniversalAccess();
5079         } else if (securityOrigin()->isLocal()) {
5080             if (settings->allowUniversalAccessFromFileURLs() || m_frame->loader()->client()->shouldForceUniversalAccessFromLocalURL(m_url)) {
5081                 // Some clients want local URLs to have universal access, but that setting is dangerous for other clients.
5082                 securityOrigin()->grantUniversalAccess();
5083             } else if (!settings->allowFileAccessFromFileURLs()) {
5084                 // Some clients want local URLs to have even tighter restrictions by default, and not be able to access other local files.
5085                 // FIXME 81578: The naming of this is confusing. Files with restricted access to other local files
5086                 // still can have other privileges that can be remembered, thereby not making them unique origins.
5087                 securityOrigin()->enforceFilePathSeparation();
5088             }
5089         }
5090     }
5091
5092     Document* parentDocument = ownerElement() ? ownerElement()->document() : 0;
5093     if (parentDocument && m_frame->loader()->shouldTreatURLAsSrcdocDocument(url())) {
5094         m_isSrcdocDocument = true;
5095         setBaseURLOverride(parentDocument->baseURL());
5096     }
5097
5098     // FIXME: What happens if we inherit the security origin? This check may need to be later.
5099     // <iframe seamless src="about:blank"> likely won't work as-is.
5100     m_mayDisplaySeamlessWithParent = isEligibleForSeamless(parentDocument, this);
5101
5102     if (!shouldInheritSecurityOriginFromOwner(m_url))
5103         return;
5104
5105     // If we do not obtain a meaningful origin from the URL, then we try to
5106     // find one via the frame hierarchy.
5107
5108     Frame* ownerFrame = m_frame->tree()->parent();
5109     if (!ownerFrame)
5110         ownerFrame = m_frame->loader()->opener();
5111
5112     if (!ownerFrame) {
5113         didFailToInitializeSecurityOrigin();
5114         return;
5115     }
5116
5117     if (isSandboxed(SandboxOrigin)) {
5118         // If we're supposed to inherit our security origin from our owner,
5119         // but we're also sandboxed, the only thing we inherit is the ability
5120         // to load local resources. This lets about:blank iframes in file://
5121         // URL documents load images and other resources from the file system.
5122         if (ownerFrame->document()->securityOrigin()->canLoadLocalResources())
5123             securityOrigin()->grantLoadLocalResources();
5124         return;
5125     }
5126
5127     m_cookieURL = ownerFrame->document()->cookieURL();
5128     // We alias the SecurityOrigins to match Firefox, see Bug 15313
5129     // https://bugs.webkit.org/show_bug.cgi?id=15313
5130     setSecurityOrigin(ownerFrame->document()->securityOrigin());
5131 }
5132
5133 void Document::initContentSecurityPolicy()
5134 {
5135     if (!m_frame->tree()->parent() || !shouldInheritSecurityOriginFromOwner(m_url))
5136         return;
5137     contentSecurityPolicy()->copyStateFrom(m_frame->tree()->parent()->document()->contentSecurityPolicy());
5138 }
5139
5140 #if ENABLE(TIZEN_CSP)
5141 void Document::copyContentSecurityPolicy(Document* other)
5142 {
5143     contentSecurityPolicy()->copyStateFrom(other->contentSecurityPolicy());
5144 }
5145 #endif
5146
5147 void Document::didUpdateSecurityOrigin()
5148 {
5149     if (!m_frame)
5150         return;
5151     // FIXME: We should remove DOMWindow::m_securityOrigin so that we don't need to keep them in sync.
5152     // See <https://bugs.webkit.org/show_bug.cgi?id=75793>.
5153     m_frame->domWindow()->setSecurityOrigin(securityOrigin());
5154     m_frame->script()->updateSecurityOrigin();
5155 }
5156
5157 bool Document::isContextThread() const
5158 {
5159     return isMainThread();
5160 }
5161
5162 void Document::updateURLForPushOrReplaceState(const KURL& url)
5163 {
5164     Frame* f = frame();
5165     if (!f)
5166         return;
5167
5168     setURL(url);
5169     f->loader()->setOutgoingReferrer(url);
5170
5171     if (DocumentLoader* documentLoader = loader())
5172         documentLoader->replaceRequestURLForSameDocumentNavigation(url);
5173 }
5174
5175 void Document::statePopped(PassRefPtr<SerializedScriptValue> stateObject)
5176 {
5177     if (!frame())
5178         return;
5179     
5180     // Per step 11 of section 6.5.9 (history traversal) of the HTML5 spec, we 
5181     // defer firing of popstate until we're in the complete state.
5182     if (m_readyState == Complete)
5183         enqueuePopstateEvent(stateObject);
5184     else
5185         m_pendingStateObject = stateObject;
5186 }
5187
5188 void Document::updateFocusAppearanceSoon(bool restorePreviousSelection)
5189 {
5190     m_updateFocusAppearanceRestoresSelection = restorePreviousSelection;
5191     if (!m_updateFocusAppearanceTimer.isActive())
5192         m_updateFocusAppearanceTimer.startOneShot(0);
5193 }
5194
5195 void Document::cancelFocusAppearanceUpdate()
5196 {
5197     m_updateFocusAppearanceTimer.stop();
5198 }
5199
5200 void Document::updateFocusAppearanceTimerFired(Timer<Document>*)
5201 {
5202     Node* node = focusedNode();
5203     if (!node)
5204         return;
5205     if (!node->isElementNode())
5206         return;
5207
5208     updateLayout();
5209
5210     Element* element = static_cast<Element*>(node);
5211     if (element->isFocusable())
5212         element->updateFocusAppearance(m_updateFocusAppearanceRestoresSelection);
5213 }
5214
5215 void Document::attachRange(Range* range)
5216 {
5217     ASSERT(!m_ranges.contains(range));
5218     m_ranges.add(range);
5219 }
5220
5221 void Document::detachRange(Range* range)
5222 {
5223     // We don't ASSERT m_ranges.contains(range) to allow us to call this
5224     // unconditionally to fix: https://bugs.webkit.org/show_bug.cgi?id=26044
5225     m_ranges.remove(range);
5226 }
5227
5228 CanvasRenderingContext* Document::getCSSCanvasContext(const String& type, const String& name, int width, int height)
5229 {
5230     HTMLCanvasElement* element = getCSSCanvasElement(name);
5231     if (!element)
5232         return 0;
5233     element->setSize(IntSize(width, height));
5234     return element->getContext(type);
5235 }
5236
5237 HTMLCanvasElement* Document::getCSSCanvasElement(const String& name)
5238 {
5239     RefPtr<HTMLCanvasElement>& element = m_cssCanvasElements.add(name, 0).iterator->second;
5240     if (!element)
5241         element = HTMLCanvasElement::create(this);
5242     return element.get();
5243 }
5244
5245 void Document::initDNSPrefetch()
5246 {
5247     Settings* settings = this->settings();
5248
5249     m_haveExplicitlyDisabledDNSPrefetch = false;
5250     m_isDNSPrefetchEnabled = settings && settings->dnsPrefetchingEnabled() && securityOrigin()->protocol() == "http";
5251
5252     // Inherit DNS prefetch opt-out from parent frame    
5253     if (Document* parent = parentDocument()) {
5254         if (!parent->isDNSPrefetchEnabled())
5255             m_isDNSPrefetchEnabled = false;
5256     }
5257 }
5258
5259 void Document::parseDNSPrefetchControlHeader(const String& dnsPrefetchControl)
5260 {
5261     if (equalIgnoringCase(dnsPrefetchControl, "on") && !m_haveExplicitlyDisabledDNSPrefetch) {
5262         m_isDNSPrefetchEnabled = true;
5263         return;
5264     }
5265
5266     m_isDNSPrefetchEnabled = false;
5267     m_haveExplicitlyDisabledDNSPrefetch = true;
5268 }
5269
5270 void Document::addMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtr<ScriptCallStack> callStack)
5271 {
5272     if (!isContextThread()) {
5273         postTask(AddConsoleMessageTask::create(source, type, level, message));
5274         return;
5275     }
5276
5277     if (DOMWindow* window = domWindow())
5278         window->console()->addMessage(source, type, level, message, sourceURL, lineNumber, callStack);
5279 }
5280
5281 struct PerformTaskContext {
5282     WTF_MAKE_NONCOPYABLE(PerformTaskContext); WTF_MAKE_FAST_ALLOCATED;
5283 public:
5284     PerformTaskContext(PassRefPtr<DocumentWeakReference> documentReference, PassOwnPtr<ScriptExecutionContext::Task> task)
5285         : documentReference(documentReference)
5286         , task(task)
5287     {
5288     }
5289
5290     RefPtr<DocumentWeakReference> documentReference;
5291     OwnPtr<ScriptExecutionContext::Task> task;
5292 };
5293
5294 void Document::didReceiveTask(void* untypedContext)
5295 {
5296     ASSERT(isMainThread());
5297
5298     OwnPtr<PerformTaskContext> context = adoptPtr(static_cast<PerformTaskContext*>(untypedContext));
5299     ASSERT(context);
5300
5301     Document* document = context->documentReference->document();
5302     if (!document)
5303         return;
5304
5305     Page* page = document->page();
5306     if ((page && page->defersLoading()) || !document->m_pendingTasks.isEmpty()) {
5307         document->m_pendingTasks.append(context->task.release());
5308         return;
5309     }
5310
5311     context->task->performTask(document);
5312 }
5313
5314 void Document::postTask(PassOwnPtr<Task> task)
5315 {
5316     callOnMainThread(didReceiveTask, new PerformTaskContext(m_weakReference, task));
5317 }
5318
5319 void Document::pendingTasksTimerFired(Timer<Document>*)
5320 {
5321     while (!m_pendingTasks.isEmpty()) {
5322         OwnPtr<Task> task = m_pendingTasks[0].release();
5323         m_pendingTasks.remove(0);
5324         task->performTask(this);
5325     }
5326 }
5327
5328 void Document::suspendScheduledTasks(ActiveDOMObject::ReasonForSuspension reason)
5329 {
5330     ASSERT(!m_scheduledTasksAreSuspended);
5331
5332     suspendScriptedAnimationControllerCallbacks();
5333     suspendActiveDOMObjects(reason);
5334     scriptRunner()->suspend();
5335     m_pendingTasksTimer.stop();
5336     if (m_parser)
5337         m_parser->suspendScheduledTasks();
5338
5339     m_scheduledTasksAreSuspended = true;
5340 }
5341
5342 void Document::resumeScheduledTasks()
5343 {
5344     ASSERT(m_scheduledTasksAreSuspended);
5345
5346     if (m_parser)
5347         m_parser->resumeScheduledTasks();
5348     if (!m_pendingTasks.isEmpty())
5349         m_pendingTasksTimer.startOneShot(0);
5350     scriptRunner()->resume();
5351     resumeActiveDOMObjects();
5352     resumeScriptedAnimationControllerCallbacks();
5353     
5354     m_scheduledTasksAreSuspended = false;
5355 }
5356
5357 void Document::suspendScriptedAnimationControllerCallbacks()
5358 {
5359 #if ENABLE(REQUEST_ANIMATION_FRAME)
5360     if (m_scriptedAnimationController)
5361         m_scriptedAnimationController->suspend();
5362 #endif
5363 }
5364
5365 void Document::resumeScriptedAnimationControllerCallbacks()
5366 {
5367 #if ENABLE(REQUEST_ANIMATION_FRAME)
5368     if (m_scriptedAnimationController)
5369         m_scriptedAnimationController->resume();
5370 #endif
5371 }
5372
5373 void Document::windowScreenDidChange(PlatformDisplayID displayID)
5374 {
5375     UNUSED_PARAM(displayID);
5376
5377 #if ENABLE(REQUEST_ANIMATION_FRAME)
5378     if (m_scriptedAnimationController)
5379         m_scriptedAnimationController->windowScreenDidChange(displayID);
5380 #endif
5381
5382 #if USE(ACCELERATED_COMPOSITING)
5383     if (renderView()->usesCompositing())
5384         renderView()->compositor()->windowScreenDidChange(displayID);
5385 #endif
5386 }
5387
5388 String Document::displayStringModifiedByEncoding(const String& str) const
5389 {
5390     if (m_decoder)
5391         return m_decoder->encoding().displayString(str.impl());
5392     return str;
5393 }
5394
5395 PassRefPtr<StringImpl> Document::displayStringModifiedByEncoding(PassRefPtr<StringImpl> str) const
5396 {
5397     if (m_decoder)
5398         return m_decoder->encoding().displayString(str);
5399     return str;
5400 }
5401
5402 void Document::displayBufferModifiedByEncoding(UChar* buffer, unsigned len) const
5403 {
5404     if (m_decoder)
5405         m_decoder->encoding().displayBuffer(buffer, len);
5406 }
5407
5408 void Document::enqueuePageshowEvent(PageshowEventPersistence persisted)
5409 {
5410     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=36334 Pageshow event needs to fire asynchronously.
5411     dispatchWindowEvent(PageTransitionEvent::create(eventNames().pageshowEvent, persisted), this);
5412 }
5413
5414 void Document::enqueueHashchangeEvent(const String& oldURL, const String& newURL)
5415 {
5416     enqueueWindowEvent(HashChangeEvent::create(oldURL, newURL));
5417 }
5418
5419 void Document::enqueuePopstateEvent(PassRefPtr<SerializedScriptValue> stateObject)
5420 {
5421     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=36202 Popstate event needs to fire asynchronously
5422     dispatchWindowEvent(PopStateEvent::create(stateObject, domWindow() ? domWindow()->history() : 0));
5423 }
5424
5425 void Document::addMediaCanStartListener(MediaCanStartListener* listener)
5426 {
5427     ASSERT(!m_mediaCanStartListeners.contains(listener));
5428     m_mediaCanStartListeners.add(listener);
5429 }
5430
5431 void Document::removeMediaCanStartListener(MediaCanStartListener* listener)
5432 {
5433     ASSERT(m_mediaCanStartListeners.contains(listener));
5434     m_mediaCanStartListeners.remove(listener);
5435 }
5436
5437 MediaCanStartListener* Document::takeAnyMediaCanStartListener()
5438 {
5439     HashSet<MediaCanStartListener*>::iterator slot = m_mediaCanStartListeners.begin();
5440     if (slot == m_mediaCanStartListeners.end())
5441         return 0;
5442     MediaCanStartListener* listener = *slot;
5443     m_mediaCanStartListeners.remove(slot);
5444     return listener;
5445 }
5446
5447 #if ENABLE(FULLSCREEN_API)
5448 bool Document::fullScreenIsAllowedForElement(Element* element) const
5449 {
5450     ASSERT(element);
5451     return isAttributeOnAllOwners(webkitallowfullscreenAttr, element->document()->ownerElement());
5452 }
5453
5454 void Document::requestFullScreenForElement(Element* element, unsigned short flags, FullScreenCheckType checkType)
5455 {
5456     // The Mozilla Full Screen API <https://wiki.mozilla.org/Gecko:FullScreenAPI> has different requirements
5457     // for full screen mode, and do not have the concept of a full screen element stack.
5458     bool inLegacyMozillaMode = (flags & Element::LEGACY_MOZILLA_REQUEST);
5459
5460     do {
5461         if (!element)
5462             element = documentElement();
5463  
5464         // 1. If any of the following conditions are true, terminate these steps and queue a task to fire
5465         // an event named fullscreenerror with its bubbles attribute set to true on the context object's 
5466         // node document:
5467
5468         // The context object is not in a document.
5469         if (!element->inDocument())
5470             break;
5471
5472         // The context object's node document, or an ancestor browsing context's document does not have
5473         // the fullscreen enabled flag set.
5474         if (checkType == EnforceIFrameAllowFullScreenRequirement && !fullScreenIsAllowedForElement(element))
5475             break;
5476
5477         // The context object's node document fullscreen element stack is not empty and its top element
5478         // is not an ancestor of the context object. (NOTE: Ignore this requirement if the request was
5479         // made via the legacy Mozilla-style API.)
5480         if (!m_fullScreenElementStack.isEmpty() && !m_fullScreenElementStack.first()->contains(element) && !inLegacyMozillaMode)
5481             break;
5482
5483         // A descendant browsing context's document has a non-empty fullscreen element stack.
5484         bool descendentHasNonEmptyStack = false;
5485         for (Frame* descendant = frame() ? frame()->tree()->traverseNext() : 0; descendant; descendant = descendant->tree()->traverseNext()) {
5486             if (descendant->document()->webkitFullscreenElement()) {
5487                 descendentHasNonEmptyStack = true;
5488                 break;
5489             }
5490         }
5491         if (descendentHasNonEmptyStack && !inLegacyMozillaMode)
5492             break;
5493
5494         // This algorithm is not allowed to show a pop-up:
5495         //   An algorithm is allowed to show a pop-up if, in the task in which the algorithm is running, either:
5496         //   - an activation behavior is currently being processed whose click event was trusted, or
5497         //   - the event listener for a trusted click event is being handled.
5498 #if ENABLE(TIZEN_EXTENSIBLE_API)
5499         if (!TizenExtensibleAPI::extensibleAPI().fullScreen())
5500             if (!ScriptController::processingUserGesture())
5501                 break;
5502 #else
5503         if (!ScriptController::processingUserGesture())
5504             break;
5505 #endif
5506
5507         // There is a previously-established user preference, security risk, or platform limitation.
5508         if (!page() || !page()->settings()->fullScreenEnabled())
5509             break;
5510         
5511         if (!page()->chrome()->client()->supportsFullScreenForElement(element, flags & Element::ALLOW_KEYBOARD_INPUT))
5512             break;
5513
5514         // 2. Let doc be element's node document. (i.e. "this")
5515         Document* currentDoc = this;
5516
5517         // 3. Let docs be all doc's ancestor browsing context's documents (if any) and doc.
5518         Deque<Document*> docs;
5519
5520         do {
5521             docs.prepend(currentDoc);
5522             currentDoc = currentDoc->ownerElement() ? currentDoc->ownerElement()->document() : 0;
5523         } while (currentDoc);
5524
5525         // 4. For each document in docs, run these substeps:
5526         Deque<Document*>::iterator current = docs.begin(), following = docs.begin();
5527
5528         do {
5529             ++following;
5530
5531             // 1. Let following document be the document after document in docs, or null if there is no
5532             // such document.
5533             Document* currentDoc = *current;
5534             Document* followingDoc = following != docs.end() ? *following : 0;
5535
5536             // 2. If following document is null, push context object on document's fullscreen element
5537             // stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute
5538             // set to true on the document.
5539             if (!followingDoc) {
5540                 currentDoc->pushFullscreenElementStack(element);
5541                 addDocumentToFullScreenChangeEventQueue(currentDoc);
5542                 continue;
5543             }
5544
5545             // 3. Otherwise, if document's fullscreen element stack is either empty or its top element
5546             // is not following document's browsing context container,
5547             Element* topElement = currentDoc->webkitFullscreenElement();
5548             if (!topElement || topElement != followingDoc->ownerElement()) {
5549                 // ...push following document's browsing context container on document's fullscreen element
5550                 // stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute
5551                 // set to true on document.
5552                 currentDoc->pushFullscreenElementStack(followingDoc->ownerElement());
5553                 addDocumentToFullScreenChangeEventQueue(currentDoc);
5554                 continue;
5555             }
5556
5557             // 4. Otherwise, do nothing for this document. It stays the same.
5558         } while (++current != docs.end());
5559
5560         // 5. Return, and run the remaining steps asynchronously.
5561         // 6. Optionally, perform some animation.
5562         m_areKeysEnabledInFullScreen = flags & Element::ALLOW_KEYBOARD_INPUT;
5563 #if ENABLE(TIZEN_FULLSCREEN_API)
5564         m_exitFullScreenByHwBackKey = flags & Element::HARDWARE_BACKKEY_EXIT;
5565 #endif
5566         page()->chrome()->client()->enterFullScreenForElement(element);
5567
5568         // 7. Optionally, display a message indicating how the user can exit displaying the context object fullscreen.
5569         return;
5570     } while (0);
5571
5572     m_fullScreenErrorEventTargetQueue.append(element ? element : documentElement());
5573     m_fullScreenChangeDelayTimer.startOneShot(0);
5574 }
5575
5576 void Document::webkitCancelFullScreen()
5577 {
5578     // The Mozilla "cancelFullScreen()" API behaves like the W3C "fully exit fullscreen" behavior, which
5579     // is defined as: 
5580     // "To fully exit fullscreen act as if the exitFullscreen() method was invoked on the top-level browsing
5581     // context's document and subsequently empty that document's fullscreen element stack."
5582     if (!topDocument()->webkitFullscreenElement())
5583         return;
5584
5585     // To achieve that aim, remove all the elements from the top document's stack except for the first before
5586     // calling webkitExitFullscreen():
5587     Deque<RefPtr<Element> > replacementFullscreenElementStack;
5588     replacementFullscreenElementStack.prepend(topDocument()->webkitFullscreenElement());
5589     topDocument()->m_fullScreenElementStack.swap(replacementFullscreenElementStack);
5590
5591     topDocument()->webkitExitFullscreen();
5592 }
5593
5594 void Document::webkitExitFullscreen()
5595 {
5596     // The exitFullscreen() method must run these steps:
5597     
5598     // 1. Let doc be the context object. (i.e. "this")
5599     Document* currentDoc = this;
5600
5601     // 2. If doc's fullscreen element stack is empty, terminate these steps.
5602     if (m_fullScreenElementStack.isEmpty())
5603         return;
5604     
5605     // 3. Let descendants be all the doc's descendant browsing context's documents with a non-empty fullscreen
5606     // element stack (if any), ordered so that the child of the doc is last and the document furthest
5607     // away from the doc is first.
5608     Deque<RefPtr<Document> > descendants;
5609     for (Frame* descendant = frame() ? frame()->tree()->traverseNext() : 0; descendant; descendant = descendant->tree()->traverseNext()) {
5610         if (descendant->document()->webkitFullscreenElement())
5611             descendants.prepend(descendant->document());
5612     }
5613         
5614     // 4. For each descendant in descendants, empty descendant's fullscreen element stack, and queue a
5615     // task to fire an event named fullscreenchange with its bubbles attribute set to true on descendant.
5616     for (Deque<RefPtr<Document> >::iterator i = descendants.begin(); i != descendants.end(); ++i) {
5617         (*i)->clearFullscreenElementStack();
5618         addDocumentToFullScreenChangeEventQueue(i->get());
5619     }
5620
5621     // 5. While doc is not null, run these substeps:
5622     Element* newTop = 0;
5623     while (currentDoc) {
5624         // 1. Pop the top element of doc's fullscreen element stack.
5625         currentDoc->popFullscreenElementStack();
5626
5627         //    If doc's fullscreen element stack is non-empty and the element now at the top is either
5628         //    not in a document or its node document is not doc, repeat this substep.
5629         newTop = currentDoc->webkitFullscreenElement();
5630         if (newTop && (!newTop->inDocument() || newTop->document() != currentDoc))
5631             continue;
5632
5633         // 2. Queue a task to fire an event named fullscreenchange with its bubbles attribute set to true
5634         // on doc.
5635         addDocumentToFullScreenChangeEventQueue(currentDoc);
5636
5637         // 3. If doc's fullscreen element stack is empty and doc's browsing context has a browsing context
5638         // container, set doc to that browsing context container's node document.
5639         if (!newTop && currentDoc->ownerElement()) {
5640             currentDoc = currentDoc->ownerElement()->document();
5641             continue;
5642         }
5643
5644         // 4. Otherwise, set doc to null.
5645         currentDoc = 0;
5646     }
5647
5648     // 6. Return, and run the remaining steps asynchronously.
5649     // 7. Optionally, perform some animation.
5650
5651     // Only exit out of full screen window mode if there are no remaining elements in the 
5652     // full screen stack.
5653     if (!newTop) {
5654         page()->chrome()->client()->exitFullScreenForElement(m_fullScreenElement.get());
5655         return;
5656     }
5657
5658     // Otherwise, notify the chrome of the new full screen element.
5659     page()->chrome()->client()->enterFullScreenForElement(newTop);      
5660 }
5661
5662 bool Document::webkitFullscreenEnabled() const
5663 {
5664     // 4. The fullscreenEnabled attribute must return true if the context object and all ancestor
5665     // browsing context's documents have their fullscreen enabled flag set, or false otherwise.
5666
5667     // Top-level browsing contexts are implied to have their allowFullScreen attribute set.
5668     return isAttributeOnAllOwners(webkitallowfullscreenAttr, ownerElement());
5669 }
5670
5671 void Document::webkitWillEnterFullScreenForElement(Element* element)
5672 {
5673     if (!attached() || inPageCache())
5674         return;
5675
5676     ASSERT(element);
5677
5678     // Protect against being called after the document has been removed from the page.
5679     if (!page())
5680         return;
5681
5682     ASSERT(page()->settings()->fullScreenEnabled());
5683
5684     if (m_fullScreenRenderer)
5685         m_fullScreenRenderer->unwrapRenderer();
5686
5687     m_fullScreenElement = element;
5688
5689 #if USE(NATIVE_FULLSCREEN_VIDEO)
5690     if (element && element->isMediaElement())
5691         return;
5692 #endif
5693
5694     // Create a placeholder block for a the full-screen element, to keep the page from reflowing
5695     // when the element is removed from the normal flow.  Only do this for a RenderBox, as only 
5696     // a box will have a frameRect.  The placeholder will be created in setFullScreenRenderer()
5697     // during layout.
5698     RenderObject* renderer = m_fullScreenElement->renderer();
5699     bool shouldCreatePlaceholder = renderer && renderer->isBox();
5700     if (shouldCreatePlaceholder) {
5701         m_savedPlaceholderFrameRect = toRenderBox(renderer)->frameRect();
5702         m_savedPlaceholderRenderStyle = RenderStyle::clone(renderer->style());
5703     }
5704
5705     if (m_fullScreenElement != documentElement())
5706         RenderFullScreen::wrapRenderer(renderer, this);
5707
5708     m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
5709     
5710     recalcStyle(Force);
5711 }
5712
5713 void Document::webkitDidEnterFullScreenForElement(Element*)
5714 {
5715     if (!m_fullScreenElement)
5716         return;
5717
5718     if (!attached() || inPageCache())
5719         return;
5720
5721     m_fullScreenElement->didBecomeFullscreenElement();
5722
5723     m_fullScreenChangeDelayTimer.startOneShot(0);
5724 }
5725
5726 void Document::webkitWillExitFullScreenForElement(Element*)
5727 {
5728     if (!m_fullScreenElement)
5729         return;
5730
5731     if (!attached() || inPageCache())
5732         return;
5733
5734     m_fullScreenElement->willStopBeingFullscreenElement();
5735 }
5736
5737 void Document::webkitDidExitFullScreenForElement(Element*)
5738 {
5739     if (!m_fullScreenElement)
5740         return;
5741
5742     if (!attached() || inPageCache())
5743         return;
5744
5745     m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
5746
5747     m_areKeysEnabledInFullScreen = false;
5748 #if ENABLE(TIZEN_FULLSCREEN_API)
5749     m_exitFullScreenByHwBackKey = false;
5750 #endif
5751
5752     if (m_fullScreenRenderer)
5753         m_fullScreenRenderer->unwrapRenderer();
5754
5755     m_fullScreenElement = 0;
5756     scheduleForcedStyleRecalc();
5757     
5758     // When webkitCancelFullScreen is called, we call webkitExitFullScreen on the topDocument(). That
5759     // means that the events will be queued there. So if we have no events here, start the timer on
5760     // the exiting document.
5761     Document* exitingDocument = this;
5762     if (m_fullScreenChangeEventTargetQueue.isEmpty() && m_fullScreenErrorEventTargetQueue.isEmpty())
5763         exitingDocument = topDocument();
5764     exitingDocument->m_fullScreenChangeDelayTimer.startOneShot(0);
5765 }
5766     
5767 void Document::setFullScreenRenderer(RenderFullScreen* renderer)
5768 {
5769     if (renderer == m_fullScreenRenderer)
5770         return;
5771
5772     if (renderer && m_savedPlaceholderRenderStyle) 
5773         renderer->createPlaceholder(m_savedPlaceholderRenderStyle.release(), m_savedPlaceholderFrameRect);
5774     else if (renderer && m_fullScreenRenderer && m_fullScreenRenderer->placeholder()) {
5775         RenderBlock* placeholder = m_fullScreenRenderer->placeholder();
5776         renderer->createPlaceholder(RenderStyle::clone(placeholder->style()), placeholder->frameRect());
5777     }
5778
5779     if (m_fullScreenRenderer)
5780         m_fullScreenRenderer->destroy();
5781     ASSERT(!m_fullScreenRenderer);
5782
5783     m_fullScreenRenderer = renderer;
5784     
5785     // This notification can come in after the page has been destroyed.
5786     if (page())
5787         page()->chrome()->client()->fullScreenRendererChanged(m_fullScreenRenderer);
5788 }
5789
5790 void Document::fullScreenRendererDestroyed()
5791 {
5792     m_fullScreenRenderer = 0;
5793
5794     if (page())
5795         page()->chrome()->client()->fullScreenRendererChanged(0);
5796 }
5797
5798 void Document::setFullScreenRendererSize(const IntSize& size)
5799 {
5800     ASSERT(m_fullScreenRenderer);
5801     if (!m_fullScreenRenderer)
5802         return;
5803     
5804     if (m_fullScreenRenderer) {
5805         RefPtr<RenderStyle> newStyle = RenderStyle::clone(m_fullScreenRenderer->style());
5806         newStyle->setWidth(Length(size.width(), WebCore::Fixed));
5807         newStyle->setHeight(Length(size.height(), WebCore::Fixed));
5808         newStyle->setTop(Length(0, WebCore::Fixed));
5809         newStyle->setLeft(Length(0, WebCore::Fixed));
5810         m_fullScreenRenderer->setStyle(newStyle);
5811         updateLayout();
5812     }
5813 }
5814     
5815 void Document::setFullScreenRendererBackgroundColor(Color backgroundColor)
5816 {
5817     if (!m_fullScreenRenderer)
5818         return;
5819     
5820     RefPtr<RenderStyle> newStyle = RenderStyle::clone(m_fullScreenRenderer->style());
5821     newStyle->setBackgroundColor(backgroundColor);
5822     m_fullScreenRenderer->setStyle(newStyle);
5823 }
5824     
5825 void Document::fullScreenChangeDelayTimerFired(Timer<Document>*)
5826 {
5827     Deque<RefPtr<Node> > changeQueue;
5828     m_fullScreenChangeEventTargetQueue.swap(changeQueue);
5829
5830     while (!changeQueue.isEmpty()) {
5831         RefPtr<Node> node = changeQueue.takeFirst();
5832         if (!node)
5833             node = documentElement();
5834
5835         // If the element was removed from our tree, also message the documentElement. Since we may
5836         // have a document hierarchy, check that node isn't in another document.
5837         if (!contains(node.get()) && !node->inDocument())
5838             changeQueue.append(documentElement());
5839         
5840         node->dispatchEvent(Event::create(eventNames().webkitfullscreenchangeEvent, true, false));
5841     }
5842
5843     Deque<RefPtr<Node> > errorQueue;
5844     m_fullScreenErrorEventTargetQueue.swap(errorQueue);
5845     
5846     while (!errorQueue.isEmpty()) {
5847         RefPtr<Node> node = errorQueue.takeFirst();
5848         if (!node)
5849             node = documentElement();
5850         
5851         // If the element was removed from our tree, also message the documentElement. Since we may
5852         // have a document hierarchy, check that node isn't in another document.
5853         if (!contains(node.get()) && !node->inDocument())
5854             errorQueue.append(documentElement());
5855         
5856         node->dispatchEvent(Event::create(eventNames().webkitfullscreenerrorEvent, true, false));
5857     }
5858 }
5859
5860 void Document::fullScreenElementRemoved()
5861 {
5862     m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
5863     webkitCancelFullScreen();
5864 }
5865
5866 void Document::removeFullScreenElementOfSubtree(Node* node, bool amongChildrenOnly)
5867 {
5868     if (!m_fullScreenElement)
5869         return;
5870     
5871     bool elementInSubtree = false;
5872     if (amongChildrenOnly)
5873         elementInSubtree = m_fullScreenElement->isDescendantOf(node);
5874     else
5875         elementInSubtree = (m_fullScreenElement == node) || m_fullScreenElement->isDescendantOf(node);
5876     
5877     if (elementInSubtree)
5878         fullScreenElementRemoved();
5879 }
5880
5881 bool Document::isAnimatingFullScreen() const
5882 {
5883     return m_isAnimatingFullScreen;
5884 }
5885
5886 void Document::setAnimatingFullScreen(bool flag)
5887 {
5888     if (m_isAnimatingFullScreen == flag)
5889         return;
5890     m_isAnimatingFullScreen = flag;
5891
5892     if (m_fullScreenElement && m_fullScreenElement->isDescendantOf(this)) {
5893         m_fullScreenElement->setNeedsStyleRecalc();
5894         scheduleForcedStyleRecalc();
5895     }
5896 }
5897
5898 void Document::clearFullscreenElementStack()
5899 {
5900     m_fullScreenElementStack.clear();
5901 }
5902
5903 void Document::popFullscreenElementStack()
5904 {
5905     if (m_fullScreenElementStack.isEmpty())
5906         return;
5907
5908     m_fullScreenElementStack.removeFirst();
5909 }
5910
5911 void Document::pushFullscreenElementStack(Element* element)
5912 {
5913     m_fullScreenElementStack.prepend(element);
5914 }
5915
5916 void Document::addDocumentToFullScreenChangeEventQueue(Document* doc)
5917 {
5918     ASSERT(doc);
5919     Node* target = doc->webkitFullscreenElement();
5920     if (!target)
5921         target = doc->webkitCurrentFullScreenElement();
5922     if (!target)
5923         target = doc;
5924     m_fullScreenChangeEventTargetQueue.append(target);
5925 }
5926 #endif
5927
5928 #if ENABLE(POINTER_LOCK)
5929 void Document::webkitExitPointerLock()
5930 {
5931     if (page())
5932         page()->pointerLockController()->requestPointerUnlock();
5933 }
5934
5935 Element* Document::webkitPointerLockElement() const
5936 {
5937     if (!page())
5938         return 0;
5939     if (Element* element = page()->pointerLockController()->element()) {
5940         if (element->document() == this)
5941             return element;
5942     }
5943     return 0;
5944 }
5945 #endif
5946
5947 void Document::decrementLoadEventDelayCount()
5948 {
5949     ASSERT(m_loadEventDelayCount);
5950     --m_loadEventDelayCount;
5951
5952     if (frame() && !m_loadEventDelayCount && !m_loadEventDelayTimer.isActive())
5953         m_loadEventDelayTimer.startOneShot(0);
5954 }
5955
5956 void Document::loadEventDelayTimerFired(Timer<Document>*)
5957 {
5958     if (frame())
5959         frame()->loader()->checkCompleted();
5960 }
5961
5962 #if ENABLE(REQUEST_ANIMATION_FRAME)
5963 int Document::webkitRequestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback> callback)
5964 {
5965     if (!m_scriptedAnimationController) {
5966 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
5967         m_scriptedAnimationController = ScriptedAnimationController::create(this, page() ? page()->displayID() : 0);
5968 #else
5969         m_scriptedAnimationController = ScriptedAnimationController::create(this, 0);
5970 #endif
5971         // It's possible that the Page may have suspended scripted animations before
5972         // we were created. We need to make sure that we don't start up the animation
5973         // controller on a background tab, for example.
5974         if (!page() || page()->scriptedAnimationsSuspended())
5975             m_scriptedAnimationController->suspend();
5976     }
5977
5978     return m_scriptedAnimationController->registerCallback(callback);
5979 }
5980
5981 void Document::webkitCancelAnimationFrame(int id)
5982 {
5983     if (!m_scriptedAnimationController)
5984         return;
5985     m_scriptedAnimationController->cancelCallback(id);
5986 }
5987
5988 void Document::serviceScriptedAnimations(DOMTimeStamp time)
5989 {
5990     if (!m_scriptedAnimationController)
5991         return;
5992     m_scriptedAnimationController->serviceScriptedAnimations(time);
5993 }
5994 #endif
5995
5996 #if ENABLE(TOUCH_EVENTS)
5997 PassRefPtr<Touch> Document::createTouch(DOMWindow* window, EventTarget* target, int identifier, int pageX, int pageY, int screenX, int screenY, int radiusX, int radiusY, float rotationAngle, float force, ExceptionCode&) const
5998 {
5999     // FIXME: It's not clear from the documentation at
6000     // http://developer.apple.com/library/safari/#documentation/UserExperience/Reference/DocumentAdditionsReference/DocumentAdditions/DocumentAdditions.html
6001     // when this method should throw and nor is it by inspection of iOS behavior. It would be nice to verify any cases where it throws under iOS
6002     // and implement them here. See https://bugs.webkit.org/show_bug.cgi?id=47819
6003     Frame* frame = window ? window->frame() : this->frame();
6004     return Touch::create(frame, target, identifier, screenX, screenY, pageX, pageY, radiusX, radiusY, rotationAngle, force);
6005 }
6006 #endif
6007
6008 static void wheelEventHandlerCountChanged(Document* document)
6009 {
6010     Page* page = document->page();
6011     if (!page)
6012         return;
6013
6014     ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator();
6015     if (!scrollingCoordinator)
6016         return;
6017
6018     FrameView* frameView = document->view();
6019     if (!frameView)
6020         return;
6021
6022     scrollingCoordinator->frameViewWheelEventHandlerCountChanged(frameView);
6023 }
6024
6025 void Document::didAddWheelEventHandler()
6026 {
6027     ++m_wheelEventHandlerCount;
6028     Frame* mainFrame = page() ? page()->mainFrame() : 0;
6029     if (mainFrame)
6030         mainFrame->notifyChromeClientWheelEventHandlerCountChanged();
6031
6032     wheelEventHandlerCountChanged(this);
6033 }
6034
6035 void Document::didRemoveWheelEventHandler()
6036 {
6037     ASSERT(m_wheelEventHandlerCount > 0);
6038     --m_wheelEventHandlerCount;
6039     Frame* mainFrame = page() ? page()->mainFrame() : 0;
6040     if (mainFrame)
6041         mainFrame->notifyChromeClientWheelEventHandlerCountChanged();
6042
6043     wheelEventHandlerCountChanged(this);
6044 }
6045
6046 void Document::didAddTouchEventHandler()
6047 {
6048 #if ENABLE(TOUCH_EVENTS)
6049     ++m_touchEventHandlerCount;
6050     if (m_touchEventHandlerCount > 1)
6051         return;
6052     if (Page* page = this->page())
6053         page->chrome()->client()->needTouchEvents(true);
6054 #endif
6055 }
6056
6057 void Document::didRemoveTouchEventHandler()
6058 {
6059 #if ENABLE(TOUCH_EVENTS)
6060     ASSERT(m_touchEventHandlerCount);
6061     --m_touchEventHandlerCount;
6062     if (m_touchEventHandlerCount)
6063         return;
6064
6065     m_listenerTypes &= ~TOUCH_LISTENER;
6066     Page* page = this->page();
6067     if (!page)
6068         return;
6069     for (const Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
6070         if (frame->document() && frame->document()->touchEventHandlerCount())
6071             return;
6072     }
6073     page->chrome()->client()->needTouchEvents(false);
6074 #endif
6075 }
6076
6077 HTMLIFrameElement* Document::seamlessParentIFrame() const
6078 {
6079     if (!shouldDisplaySeamlesslyWithParent())
6080         return 0;
6081
6082     HTMLFrameOwnerElement* ownerElement = this->ownerElement();
6083     ASSERT(ownerElement->hasTagName(iframeTag));
6084     return static_cast<HTMLIFrameElement*>(ownerElement);
6085 }
6086
6087 bool Document::shouldDisplaySeamlesslyWithParent() const
6088 {
6089 #if ENABLE(IFRAME_SEAMLESS)
6090     HTMLFrameOwnerElement* ownerElement = this->ownerElement();
6091     if (!ownerElement)
6092         return false;
6093     return m_mayDisplaySeamlessWithParent && ownerElement->hasTagName(iframeTag) && ownerElement->fastHasAttribute(seamlessAttr);
6094 #else
6095     return false;
6096 #endif
6097 }
6098
6099 DocumentLoader* Document::loader() const
6100 {
6101     if (!m_frame)
6102         return 0;
6103     
6104     DocumentLoader* loader = m_frame->loader()->documentLoader();
6105     if (!loader)
6106         return 0;
6107     
6108     if (m_frame->document() != this)
6109         return 0;
6110     
6111     return loader;
6112 }
6113
6114 #if ENABLE(MICRODATA)
6115 PassRefPtr<NodeList> Document::getItems(const String& typeNames)
6116 {
6117     // Since documet.getItem() is allowed for microdata, typeNames will be null string.
6118     // In this case we need to create an unique string identifier to map such request in the cache.
6119     String localTypeNames = typeNames.isNull() ? MicroDataItemList::undefinedItemType() : typeNames;
6120
6121     return ensureRareData()->ensureNodeLists()->addCacheWithName<MicroDataItemList>(this, DynamicNodeList::MicroDataItemListType, localTypeNames);
6122 }
6123 #endif
6124
6125 IntSize Document::viewportSize() const
6126 {
6127     if (!view())
6128         return IntSize();
6129     return view()->visibleContentRect(/* includeScrollbars */ true).size();
6130 }
6131
6132 Node* eventTargetNodeForDocument(Document* doc)
6133 {
6134     if (!doc)
6135         return 0;
6136     Node* node = doc->focusedNode();
6137     if (!node && doc->isPluginDocument()) {
6138         PluginDocument* pluginDocument = static_cast<PluginDocument*>(doc);
6139         node =  pluginDocument->pluginNode();
6140     }
6141     if (!node && doc->isHTMLDocument())
6142         node = doc->body();
6143     if (!node)
6144         node = doc->documentElement();
6145     return node;
6146 }
6147
6148 void Document::adjustFloatQuadsForScrollAndAbsoluteZoomAndFrameScale(Vector<FloatQuad>& quads, RenderObject* renderer)
6149 {
6150     if (!view())
6151         return;
6152
6153     float inverseFrameScale = 1;
6154     if (frame())
6155         inverseFrameScale = 1 / frame()->frameScaleFactor();
6156
6157     LayoutRect visibleContentRect = view()->visibleContentRect();
6158     for (size_t i = 0; i < quads.size(); ++i) {
6159         quads[i].move(-visibleContentRect.x(), -visibleContentRect.y());
6160         adjustFloatQuadForAbsoluteZoom(quads[i], renderer);
6161         if (inverseFrameScale != 1)
6162             quads[i].scale(inverseFrameScale, inverseFrameScale);
6163     }
6164 }
6165
6166 void Document::adjustFloatRectForScrollAndAbsoluteZoomAndFrameScale(FloatRect& rect, RenderObject* renderer)
6167 {
6168     if (!view())
6169         return;
6170
6171     float inverseFrameScale = 1;
6172     if (frame())
6173         inverseFrameScale = 1 / frame()->frameScaleFactor();
6174
6175     LayoutRect visibleContentRect = view()->visibleContentRect();
6176     rect.move(-visibleContentRect.x(), -visibleContentRect.y());
6177     adjustFloatRectForAbsoluteZoom(rect, renderer);
6178     if (inverseFrameScale != 1)
6179         rect.scale(inverseFrameScale);
6180 }
6181
6182 void Document::setContextFeatures(PassRefPtr<ContextFeatures> features)
6183 {
6184     m_contextFeatures = features;
6185 }
6186
6187 void Document::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
6188 {
6189     MemoryClassInfo<Document> info(memoryObjectInfo, this, MemoryInstrumentation::DOM);
6190     info.addInstrumentedMember(m_styleResolver);
6191     info.visitBaseClass<ContainerNode>(this);
6192     info.addVector(m_customFonts);
6193     info.addString(m_documentURI);
6194     info.addString(m_baseTarget);
6195     if (m_pageGroupUserSheets)
6196         info.addVector(*m_pageGroupUserSheets.get());
6197     if (m_userSheets)
6198         info.addVector(*m_userSheets.get());
6199     info.addHashSet(m_nodeIterators);
6200     info.addHashSet(m_ranges);
6201     info.addListHashSet(m_styleSheetCandidateNodes);
6202     info.addString(m_preferredStylesheetSet);
6203     info.addString(m_selectedStylesheetSet);
6204     info.addString(m_title.string());
6205     info.addString(m_rawTitle.string());
6206     info.addString(m_xmlEncoding);
6207     info.addString(m_xmlVersion);
6208     info.addString(m_contentLanguage);
6209     info.addHashMap(m_documentNamedItemCollections);
6210     info.addHashMap(m_windowNamedItemCollections);
6211 #if ENABLE(DASHBOARD_SUPPORT)
6212     info.addVector(m_dashboardRegions);
6213 #endif
6214     info.addHashMap(m_cssCanvasElements);
6215     info.addVector(m_iconURLs);
6216     info.addHashSet(m_documentSuspensionCallbackElements);
6217     info.addHashSet(m_mediaVolumeCallbackElements);
6218     info.addHashSet(m_privateBrowsingStateChangedElements);
6219     info.addHashMap(m_elementsByAccessKey);
6220     info.addHashSet(m_mediaCanStartListeners);
6221     info.addVector(m_pendingTasks);
6222 }
6223
6224 #if ENABLE(UNDO_MANAGER)
6225 PassRefPtr<UndoManager> Document::undoManager()
6226 {
6227     if (!m_undoManager)
6228         m_undoManager = UndoManager::create(this);
6229     return m_undoManager;
6230 }
6231 #endif
6232
6233 #if ENABLE(TIZEN_GSTREAMER_AUDIO)
6234 void Document::incrementActiveMediaObjectCount()
6235 {
6236     if (!m_activeMediaObjectCount)
6237         AudioSessionManagerGStreamerTizen::setVolumeSessionToMediaType();
6238     atomicIncrement(&m_activeMediaObjectCount);
6239 }
6240
6241 void Document::decrementActiveMediaObjectCount()
6242 {
6243     atomicDecrement(&m_activeMediaObjectCount);
6244     if (!m_activeMediaObjectCount)
6245         AudioSessionManagerGStreamerTizen::clearVolumeSessionFromMediaType();
6246 }
6247 #endif
6248 } // namespace WebCore