#include "config.h"
#include "core/dom/Document.h"
-#include "bindings/v8/CustomElementConstructorBuilder.h"
-#include "bindings/v8/Dictionary.h"
-#include "bindings/v8/ExceptionMessages.h"
-#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/ExceptionStatePlaceholder.h"
-#include "bindings/v8/ScriptController.h"
+#include "bindings/core/v8/CustomElementConstructorBuilder.h"
+#include "bindings/core/v8/Dictionary.h"
+#include "bindings/core/v8/ExceptionMessages.h"
+#include "bindings/core/v8/ExceptionState.h"
+#include "bindings/core/v8/ExceptionStatePlaceholder.h"
+#include "bindings/core/v8/ScriptController.h"
#include "core/HTMLElementFactory.h"
#include "core/HTMLNames.h"
#include "core/SVGElementFactory.h"
#include "core/dom/ExecutionContextTask.h"
#include "core/dom/MainThreadTaskRunner.h"
#include "core/dom/MutationObserver.h"
-#include "core/dom/NoEventDispatchAssertion.h"
#include "core/dom/NodeChildRemovalTracker.h"
#include "core/dom/NodeFilter.h"
#include "core/dom/NodeIterator.h"
#include "core/dom/NodeWithIndex.h"
#include "core/dom/ProcessingInstruction.h"
#include "core/dom/RequestAnimationFrameCallback.h"
-#include "core/dom/ScriptForbiddenScope.h"
#include "core/dom/ScriptRunner.h"
#include "core/dom/ScriptedAnimationController.h"
#include "core/dom/SelectorQuery.h"
+#include "core/dom/StaticNodeList.h"
#include "core/dom/StyleEngine.h"
#include "core/dom/TouchList.h"
#include "core/dom/TransformSource.h"
#include "core/dom/TreeWalker.h"
#include "core/dom/VisitedLinkState.h"
#include "core/dom/XMLDocument.h"
+#include "core/dom/custom/CustomElementMicrotaskRunQueue.h"
#include "core/dom/custom/CustomElementRegistrationContext.h"
#include "core/dom/shadow/ElementShadow.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/editing/Editor.h"
#include "core/editing/FrameSelection.h"
#include "core/editing/SpellChecker.h"
+#include "core/editing/markup.h"
#include "core/events/BeforeUnloadEvent.h"
#include "core/events/Event.h"
#include "core/events/EventFactory.h"
#include "core/events/PageTransitionEvent.h"
#include "core/events/ScopedEventQueue.h"
#include "core/fetch/ResourceFetcher.h"
+#include "core/frame/EventHandlerRegistry.h"
#include "core/frame/LocalDOMWindow.h"
#include "core/frame/FrameConsole.h"
#include "core/frame/FrameHost.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/parser/NestingLevelIncrementer.h"
#include "core/html/parser/TextResourceDecoder.h"
+#include "core/inspector/ConsoleMessage.h"
#include "core/inspector/InspectorCounters.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/inspector/InspectorTraceEvents.h"
#include "core/page/Chrome.h"
#include "core/page/ChromeClient.h"
#include "core/page/EventHandler.h"
+#include "core/page/EventWithHitTestResults.h"
#include "core/page/FocusController.h"
#include "core/page/FrameTree.h"
-#include "core/page/MouseEventWithHitTestResults.h"
#include "core/page/Page.h"
#include "core/page/PointerLockController.h"
#include "core/page/scrolling/ScrollingCoordinator.h"
-#include "core/rendering/FastTextAutosizer.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/RenderView.h"
+#include "core/rendering/RenderWidget.h"
#include "core/rendering/TextAutosizer.h"
#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "core/svg/SVGDocumentExtensions.h"
#include "core/xml/XSLTProcessor.h"
#include "core/xml/parser/XMLDocumentParser.h"
#include "platform/DateComponents.h"
+#include "platform/EventDispatchForbiddenScope.h"
#include "platform/Language.h"
#include "platform/RuntimeEnabledFeatures.h"
+#include "platform/ScriptForbiddenScope.h"
#include "platform/TraceEvent.h"
#include "platform/network/ContentSecurityPolicyParsers.h"
#include "platform/network/HTTPParsers.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "public/platform/Platform.h"
#include "wtf/CurrentTime.h"
+#include "wtf/DateMath.h"
#include "wtf/HashFunctions.h"
#include "wtf/MainThread.h"
#include "wtf/StdLibExtras.h"
using namespace WTF;
using namespace Unicode;
-namespace WebCore {
+namespace blink {
using namespace HTMLNames;
static bool acceptsEditingFocus(const Element& element)
{
- ASSERT(element.rendererIsEditable());
+ ASSERT(element.hasEditableStyle());
return element.document().frame() && element.rootEditableElement();
}
uint64_t Document::s_globalTreeVersion = 0;
+#ifndef NDEBUG
+typedef WillBeHeapHashSet<RawPtrWillBeWeakMember<Document> > WeakDocumentSet;
+static WeakDocumentSet& liveDocumentSet()
+{
+ DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<WeakDocumentSet>, set, (adoptPtrWillBeNoop(new WeakDocumentSet())));
+ return *set;
+}
+#endif
+
// This class doesn't work with non-Document ExecutionContext.
class AutofocusTask FINAL : public ExecutionContextTask {
public:
, m_taskRunner(MainThreadTaskRunner::create(this))
, m_registrationContext(initializer.registrationContext(this))
, m_elementDataCacheClearTimer(this, &Document::elementDataCacheClearTimerFired)
-#ifndef NDEBUG
- , m_didDispatchViewportPropertiesChanged(false)
-#endif
, m_timeline(AnimationTimeline::create(this))
, m_templateDocumentHost(nullptr)
, m_didAssociateFormControlsTimer(this, &Document::didAssociateFormControlsTimerFired)
// CSSFontSelector, need to initialize m_styleEngine after initializing
// m_fetcher.
m_styleEngine = StyleEngine::create(*this);
+
+#ifndef NDEBUG
+ liveDocumentSet().add(this);
+#endif
}
Document::~Document()
for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); ++i)
ASSERT(!m_nodeListCounts[i]);
+
+#ifndef NDEBUG
+ liveDocumentSet().remove(this);
+#endif
#endif
setClient(0);
MediaQueryMatcher& Document::mediaQueryMatcher()
{
if (!m_mediaQueryMatcher)
- m_mediaQueryMatcher = MediaQueryMatcher::create(this);
+ m_mediaQueryMatcher = MediaQueryMatcher::create(*this);
return *m_mediaQueryMatcher;
}
return &domWindow()->location();
}
-void Document::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+void Document::childrenChanged(const ChildrenChange& change)
{
- ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+ ContainerNode::childrenChanged(change);
m_documentElement = ElementTraversal::firstWithin(*this);
}
+AtomicString Document::convertLocalName(const AtomicString& name)
+{
+ return isHTMLDocument() ? name.lower() : name;
+}
+
PassRefPtrWillBeRawPtr<Element> Document::createElement(const AtomicString& name, ExceptionState& exceptionState)
{
if (!isValidName(name)) {
}
if (isXHTMLDocument() || isHTMLDocument())
- return HTMLElementFactory::createHTMLElement(isHTMLDocument() ? name.lower() : name, *this, 0, false);
+ return HTMLElementFactory::createHTMLElement(convertLocalName(name), *this, 0, false);
return Element::create(QualifiedName(nullAtom, name, nullAtom), this);
}
RefPtrWillBeRawPtr<Element> element;
if (CustomElement::isValidName(localName) && registrationContext()) {
- element = registrationContext()->createCustomTagElement(*this, QualifiedName(nullAtom, localName, xhtmlNamespaceURI));
+ element = registrationContext()->createCustomTagElement(*this, QualifiedName(nullAtom, convertLocalName(localName), xhtmlNamespaceURI));
} else {
element = createElement(localName, exceptionState);
if (exceptionState.hadException())
return element.release();
}
-ScriptValue Document::registerElement(WebCore::ScriptState* scriptState, const AtomicString& name, ExceptionState& exceptionState)
+ScriptValue Document::registerElement(ScriptState* scriptState, const AtomicString& name, ExceptionState& exceptionState)
{
return registerElement(scriptState, name, Dictionary(), exceptionState);
}
-ScriptValue Document::registerElement(WebCore::ScriptState* scriptState, const AtomicString& name, const Dictionary& options, ExceptionState& exceptionState, CustomElement::NameSet validNames)
+ScriptValue Document::registerElement(ScriptState* scriptState, const AtomicString& name, const Dictionary& options, ExceptionState& exceptionState, CustomElement::NameSet validNames)
{
if (!registrationContext()) {
exceptionState.throwDOMException(NotSupportedError, "No element registration context is available.");
return constructorBuilder.bindingsReturnValue();
}
+CustomElementMicrotaskRunQueue* Document::customElementMicrotaskRunQueue()
+{
+ if (!m_customElementMicrotaskRunQueue)
+ m_customElementMicrotaskRunQueue = CustomElementMicrotaskRunQueue::create();
+ return m_customElementMicrotaskRunQueue.get();
+}
+
void Document::setImportsController(HTMLImportsController* controller)
{
ASSERT(!m_importsController || !controller);
return true;
}
-PassRefPtrWillBeRawPtr<Node> Document::importNode(Node* importedNode, ExceptionState& ec)
-{
- UseCounter::countDeprecation(this, UseCounter::DocumentImportNodeOptionalArgument);
- return importNode(importedNode, true, ec);
-}
-
PassRefPtrWillBeRawPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionState& exceptionState)
{
- if (!importedNode) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
- return nullptr;
- }
-
switch (importedNode->nodeType()) {
case TEXT_NODE:
return createTextNode(importedNode->nodeValue());
PassRefPtrWillBeRawPtr<Node> Document::adoptNode(PassRefPtrWillBeRawPtr<Node> source, ExceptionState& exceptionState)
{
- if (!source) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
- return nullptr;
- }
-
EventQueueScope scope;
switch (source->nodeType()) {
case DOCUMENT_NODE:
- case DOCUMENT_TYPE_NODE:
exceptionState.throwDOMException(NotSupportedError, "The node provided is of type '" + source->nodeName() + "', which may not be adopted.");
return nullptr;
case ATTRIBUTE_NODE: {
return Range::create(*this, container, offset, container, offset);
}
- PositionWithAffinity positionWithAffinity = renderer->positionForPoint(result.localPoint());
+ PositionWithAffinity positionWithAffinity = result.position();
if (positionWithAffinity.position().isNull())
return nullptr;
return Range::create(*this);
}
-PassRefPtrWillBeRawPtr<NodeIterator> Document::createNodeIterator(Node* root, ExceptionState& exceptionState)
-{
- // FIXME: Probably this should be handled within the bindings layer and TypeError should be thrown.
- if (!root) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
- return nullptr;
- }
- return NodeIterator::create(root, NodeFilter::SHOW_ALL, nullptr);
-}
-
-PassRefPtrWillBeRawPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> filter, ExceptionState& exceptionState)
{
- if (!root) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
- return nullptr;
- }
// FIXME: It might be a good idea to emit a warning if |whatToShow| contains a bit that is not defined in
// NodeFilter.
- return NodeIterator::create(root, whatToShow, nullptr);
-}
-
-PassRefPtrWillBeRawPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> filter, ExceptionState& exceptionState)
-{
- if (!root) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
- return nullptr;
- }
- // FIXME: Ditto.
return NodeIterator::create(root, whatToShow, filter);
}
-PassRefPtrWillBeRawPtr<TreeWalker> Document::createTreeWalker(Node* root, ExceptionState& exceptionState)
-{
- if (!root) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
- return nullptr;
- }
- return TreeWalker::create(root, NodeFilter::SHOW_ALL, nullptr);
-}
-
-PassRefPtrWillBeRawPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, ExceptionState& exceptionState)
-{
- if (!root) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
- return nullptr;
- }
- return TreeWalker::create(root, whatToShow, nullptr);
-}
-
PassRefPtrWillBeRawPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> filter, ExceptionState& exceptionState)
{
- if (!root) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
- return nullptr;
- }
return TreeWalker::create(root, whatToShow, filter);
}
if (!childNeedsDistributionRecalc())
return;
- TRACE_EVENT0("webkit", "Document::updateDistributionIfNeeded");
+ TRACE_EVENT0("blink", "Document::updateDistributionIfNeeded");
recalcDistribution();
}
return;
if (!childNeedsStyleInvalidation())
return;
- TRACE_EVENT0("webkit", "Document::updateStyleInvalidationIfNeeded");
+ TRACE_EVENT0("blink", "Document::updateStyleInvalidationIfNeeded");
ASSERT(styleResolver());
styleResolver()->ruleFeatureSet().styleInvalidator().invalidate(*this);
{
ASSERT(isMainThread());
+ ScriptForbiddenScope forbidScript;
+
if (!view() || !isActive())
return;
RELEASE_ASSERT(!view()->isPainting());
// Script can run below in WidgetUpdates, so protect the LocalFrame.
+ // FIXME: Can this still happen? How does script run inside
+ // UpdateSuspendScope::performDeferredWidgetTreeOperations() ?
RefPtr<LocalFrame> protect(m_frame);
- TRACE_EVENT0("webkit", "Document::updateRenderTree");
- TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "UpdateRenderTree");
+ TRACE_EVENT_BEGIN0("blink", "Document::updateRenderTree");
+ TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "UpdateRenderTree");
+ // FIXME: Remove m_styleRecalcElementCounter, we should just use the accessCount() on the resolver.
m_styleRecalcElementCounter = 0;
TRACE_EVENT_BEGIN1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "RecalculateStyles", "frame", frame());
TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRecalculateStyle(this);
DocumentAnimations::updateOutdatedAnimationPlayersIfNeeded(*this);
-
- // FIXME: This executes media query listeners which runs script, instead the script
- // should run at raf timing in ScriptedAnimationController just like resize events.
evaluateMediaQueryListIfNeeded();
-
updateUseShadowTreesIfNeeded();
updateDistributionIfNeeded();
updateStyleInvalidationIfNeeded();
ASSERT(!m_timeline->hasOutdatedAnimationPlayer());
TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "RecalculateStyles", "elementCount", m_styleRecalcElementCounter);
+ TRACE_EVENT_END1("blink", "Document::updateRenderTree", "elementCount", m_styleRecalcElementCounter);
// FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::didRecalculateStyle(cookie, m_styleRecalcElementCounter);
}
void Document::updateStyle(StyleRecalcChange change)
{
- TRACE_EVENT0("webkit", "Document::updateStyle");
+ TRACE_EVENT0("blink", "Document::updateStyle");
- ScriptForbiddenScope forbidScript;
HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates;
m_lifecycle.advanceTo(DocumentLifecycle::InStyleRecalc);
ensureStyleResolver().printStats();
view()->recalcOverflowAfterStyleChange();
- renderView()->compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
clearChildNeedsStyleRecalc();
{
ASSERT(isMainThread());
+ ScriptForbiddenScope forbidScript;
+
RefPtr<FrameView> frameView = view();
if (frameView && frameView->isInPerformLayout()) {
// View layout should not be re-entrant.
PassRefPtr<RenderStyle> Document::styleForPage(int pageIndex)
{
+ updateDistributionIfNeeded();
return ensureStyleResolver().styleForPage(pageIndex);
}
ContainerNode::attach(context);
- // FastTextAutosizer can't update render view info while the Document is detached, so update now in case anything changed.
- if (FastTextAutosizer* textAutosizer = fastTextAutosizer())
- textAutosizer->updatePageInfo();
+ // The TextAutosizer can't update render view info while the Document is detached, so update now in case anything changed.
+ if (TextAutosizer* autosizer = textAutosizer())
+ autosizer->updatePageInfo();
m_lifecycle.advanceTo(DocumentLifecycle::StyleClean);
}
m_styleEngine->didDetach();
- if (Document* parentDoc = parentDocument())
- parentDoc->didClearTouchEventHandlers(this);
+ frameHost()->eventHandlerRegistry().documentDetached(*this);
// This is required, as our LocalFrame might delete itself as soon as it detaches
// us. However, this violates Node::detach() semantics, as it's never
m_frame = 0;
if (m_mediaQueryMatcher)
- m_mediaQueryMatcher->documentDestroyed();
+ m_mediaQueryMatcher->documentDetached();
lifecycleNotifier().notifyDocumentWasDetached();
m_lifecycle.advanceTo(DocumentLifecycle::Stopped);
#if ENABLE(OILPAN)
- // This mirrors the clearing of the document object's touch
- // handlers that happens when the LocalDOMWindow is destructed in a
- // non-Oilpan setting (LocalDOMWindow::removeAllEventListeners()),
- // except that it is now done during detach instead.
- didClearTouchEventHandlers(this);
-
// Done with the window, explicitly clear to hasten its
// destruction.
clearDOMWindow();
if (!documentElement())
return 0;
- for (HTMLElement* child = Traversal<HTMLElement>::firstWithin(*documentElement()); child; child = Traversal<HTMLElement>::nextSibling(*child)) {
+ for (HTMLElement* child = Traversal<HTMLElement>::firstChild(*documentElement()); child; child = Traversal<HTMLElement>::nextSibling(*child)) {
if (isHTMLFrameSetElement(*child) || isHTMLBodyElement(*child))
return child;
}
return true;
if (didAllowNavigation) {
- addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Blocked attempt to show multiple 'beforeunload' confirmation panels for a single navigation.");
+ addConsoleMessage(ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, "Blocked attempt to show multiple 'beforeunload' confirmation panels for a single navigation."));
return true;
}
bool hasInsertionPoint = m_parser && m_parser->hasInsertionPoint();
if (!hasInsertionPoint && m_ignoreDestructiveWriteCount) {
- addConsoleMessage(JSMessageSource, WarningMessageLevel, ExceptionMessages::failedToExecute("write", "Document", "It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened."));
+ addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, ExceptionMessages::failedToExecute("write", "Document", "It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.")));
return;
}
void Document::logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack)
{
- internalAddMessage(JSMessageSource, ErrorMessageLevel, errorMessage, sourceURL, lineNumber, callStack, 0);
+ RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorMessage, sourceURL, lineNumber);
+ consoleMessage->setCallStack(callStack);
+ addMessage(consoleMessage.release());
}
void Document::setURL(const KURL& url)
{
m_executeScriptsWaitingForResourcesTimer.startOneShot(0, FROM_HERE);
+ if (frame())
+ frame()->loader().client()->didRemoveAllPendingStylesheet();
+
if (m_gotoAnchorNeededAfterStylesheetsLoad && view())
view()->scrollToFragment(m_url);
}
if (protocolIsJavaScript(refreshURL)) {
String message = "Refused to refresh " + m_url.elidedString() + " to a javascript: URL";
- addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message);
+ addConsoleMessage(ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, message));
return;
}
if (httpRefreshType == HttpRefreshFromMetaTag && isSandboxed(SandboxAutomaticFeatures)) {
String message = "Refused to execute the redirect specified via '<meta http-equiv='refresh' content='...'>'. The document is sandboxed, and the 'allow-scripts' keyword is not set.";
- addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message);
+ addConsoleMessage(ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, message));
return;
}
m_frame->navigationScheduler().scheduleRedirect(delay, refreshURL);
// intent, we must navigate away from the possibly partially-rendered document to a location that
// doesn't inherit the parent's SecurityOrigin.
frame->navigationScheduler().scheduleLocationChange(this, SecurityOrigin::urlWithUniqueSecurityOrigin(), Referrer());
- addConsoleMessageWithRequestIdentifier(SecurityMessageSource, ErrorMessageLevel, message, requestIdentifier);
+ RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, message);
+ consoleMessage->setRequestIdentifier(requestIdentifier);
+ addMessage(consoleMessage.release());
}
}
void Document::updateViewportDescription()
{
if (frame() && frame()->isMainFrame()) {
-#ifndef NDEBUG
- m_didDispatchViewportPropertiesChanged = true;
-#endif
frameHost()->chrome().dispatchViewportPropertiesDidChange(m_viewportDescription);
}
}
} else if (equalIgnoringCase(policy, "default")) {
setReferrerPolicy(ReferrerPolicyDefault);
} else {
- addConsoleMessage(RenderingMessageSource, ErrorMessageLevel, "Failed to set referrer policy: The value '" + policy + "' is not one of 'always', 'default', 'never', or 'origin'. Defaulting to 'never'.");
+ addConsoleMessage(ConsoleMessage::create(RenderingMessageSource, ErrorMessageLevel, "Failed to set referrer policy: The value '" + policy + "' is not one of 'always', 'default', 'never', or 'origin'. Defaulting to 'never'."));
setReferrerPolicy(ReferrerPolicyNever);
}
}
void Document::evaluateMediaQueryList()
{
if (m_mediaQueryMatcher)
- m_mediaQueryMatcher->styleResolverChanged();
+ m_mediaQueryMatcher->mediaFeaturesChanged();
}
void Document::notifyResizeForViewportUnits()
{
+ if (m_mediaQueryMatcher)
+ m_mediaQueryMatcher->viewportChanged();
if (!hasViewportUnits())
return;
ensureStyleResolver().notifyResizeForViewportUnits();
ASSERT(renderView() || importsController());
if (renderView())
- renderView()->repaintViewAndCompositedLayers();
+ renderView()->invalidatePaintForViewAndCompositedLayers();
}
}
if (!m_activeHoverElement)
return;
- if (node != m_activeHoverElement && (!m_activeHoverElement->isTextNode() || node != NodeRenderingTraversal::parent(m_activeHoverElement.get())))
+ if (node != m_activeHoverElement)
return;
Node* activeNode = NodeRenderingTraversal::parent(node);
void Document::nodeChildrenWillBeRemoved(ContainerNode& container)
{
- NoEventDispatchAssertion assertNoEventDispatch;
+ EventDispatchForbiddenScope assertNoEventDispatch;
if (!m_ranges.isEmpty()) {
AttachedRangeSet::const_iterator end = m_ranges.end();
for (AttachedRangeSet::const_iterator it = m_ranges.begin(); it != end; ++it)
ensureScriptedAnimationController().enqueuePerFrameEvent(event.release());
}
+void Document::enqueueMediaQueryChangeListeners(WillBeHeapVector<RefPtrWillBeMember<MediaQueryListListener> >& listeners)
+{
+ ensureScriptedAnimationController().enqueueMediaQueryChangeListeners(listeners);
+}
+
+
Document::EventFactorySet& Document::eventFactories()
{
DEFINE_STATIC_LOCAL(EventFactorySet, s_eventFactory, ());
if (DocumentLoader* documentLoader = loader()) {
const AtomicString& httpLastModified = documentLoader->response().httpHeaderField("Last-Modified");
if (!httpLastModified.isEmpty()) {
- date.setMillisecondsSinceEpochForDateTime(parseDate(httpLastModified));
+ date.setMillisecondsSinceEpochForDateTime(convertToLocalTime(parseDate(httpLastModified)));
foundDate = true;
}
}
// specificiation tells us to read the last modification date from the file
// system.
if (!foundDate)
- date.setMillisecondsSinceEpochForDateTime(currentTimeMS());
+ date.setMillisecondsSinceEpochForDateTime(convertToLocalTime(currentTimeMS()));
return String::format("%02d/%02d/%04d %02d:%02d:%02d", date.month() + 1, date.monthDay(), date.fullYear(), date.hour(), date.minute(), date.second());
}
static bool inExecCommand = false;
if (inExecCommand) {
String message = "We don't execute document.execCommand() this time, because it is called recursively.";
- addConsoleMessage(JSMessageSource, WarningMessageLevel, message);
+ addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message));
return false;
}
TemporaryChange<bool> executeScope(inExecCommand, true);
// DOM tree against implementation assumption.
EventQueueScope eventQueueScope;
Editor::Command editorCommand = command(this, commandName, userInterface);
- blink::Platform::current()->histogramSparse("WebCore.Document.execCommand", editorCommand.idForHistogram());
+ Platform::current()->histogramSparse("WebCore.Document.execCommand", editorCommand.idForHistogram());
return editorCommand.execute(value);
}
// FIXME: Not clear what topDocument() should do in the OOPI case--should it return the topmost
// available Document, or something else?
Document* doc = const_cast<Document*>(this);
- Element* element;
- while ((element = doc->ownerElement()))
+ for (Element* element = doc->ownerElement(); element; element = doc->ownerElement())
doc = &element->document();
ASSERT(doc);
return isSVGSVGElement(documentElement());
}
-PassRefPtrWillBeRawPtr<HTMLCollection> Document::ensureCachedCollection(CollectionType type)
-{
- return ensureRareData().ensureNodeLists().addCache<HTMLCollection>(*this, type);
-}
-
PassRefPtrWillBeRawPtr<HTMLCollection> Document::images()
{
- return ensureCachedCollection(DocImages);
+ return ensureCachedCollection<HTMLCollection>(DocImages);
}
PassRefPtrWillBeRawPtr<HTMLCollection> Document::applets()
{
- return ensureCachedCollection(DocApplets);
+ return ensureCachedCollection<HTMLCollection>(DocApplets);
}
PassRefPtrWillBeRawPtr<HTMLCollection> Document::embeds()
{
- return ensureCachedCollection(DocEmbeds);
+ return ensureCachedCollection<HTMLCollection>(DocEmbeds);
}
PassRefPtrWillBeRawPtr<HTMLCollection> Document::scripts()
{
- return ensureCachedCollection(DocScripts);
+ return ensureCachedCollection<HTMLCollection>(DocScripts);
}
PassRefPtrWillBeRawPtr<HTMLCollection> Document::links()
{
- return ensureCachedCollection(DocLinks);
+ return ensureCachedCollection<HTMLCollection>(DocLinks);
}
PassRefPtrWillBeRawPtr<HTMLCollection> Document::forms()
{
- return ensureCachedCollection(DocForms);
+ return ensureCachedCollection<HTMLCollection>(DocForms);
}
PassRefPtrWillBeRawPtr<HTMLCollection> Document::anchors()
{
- return ensureCachedCollection(DocAnchors);
+ return ensureCachedCollection<HTMLCollection>(DocAnchors);
}
PassRefPtrWillBeRawPtr<HTMLAllCollection> Document::allForBinding()
PassRefPtrWillBeRawPtr<HTMLAllCollection> Document::all()
{
- return ensureRareData().ensureNodeLists().addCache<HTMLAllCollection>(*this, DocAll);
+ return ensureCachedCollection<HTMLAllCollection>(DocAll);
}
PassRefPtrWillBeRawPtr<HTMLCollection> Document::windowNamedItems(const AtomicString& name)
{
- return ensureRareData().ensureNodeLists().addCache<WindowNameCollection>(*this, WindowNamedItems, name);
+ return ensureCachedCollection<WindowNameCollection>(WindowNamedItems, name);
}
PassRefPtrWillBeRawPtr<HTMLCollection> Document::documentNamedItems(const AtomicString& name)
{
- return ensureRareData().ensureNodeLists().addCache<DocumentNameCollection>(*this, DocumentNamedItems, name);
+ return ensureCachedCollection<DocumentNameCollection>(DocumentNamedItems, name);
}
void Document::finishedParsing()
if (!m_documentTiming.domContentLoadedEventEnd)
m_documentTiming.domContentLoadedEventEnd = monotonicallyIncreasingTime();
- if (frame() && frame()->isMainFrame()) {
- // Reset the text autosizing multipliers on main frame when DOM is loaded.
- // This is to allow for a fresh text autosizing pass when the page layout
- // changes significantly in the end.
- if (TextAutosizer* textAutosizer = this->textAutosizer())
- textAutosizer->recalculateMultipliers();
- }
-
// The loader's finishedParsing() method may invoke script that causes this object to
// be dereferenced (when this document is in an iframe and the onload causes the iframe's src to change).
// Keep it alive until we are done.
return Color();
for (HTMLMetaElement* metaElement = head() ? Traversal<HTMLMetaElement>::firstChild(*head()) : 0; metaElement; metaElement = Traversal<HTMLMetaElement>::nextSibling(*metaElement)) {
- RGBA32 rgb;
+ RGBA32 rgb = Color::transparent;
if (equalIgnoringCase(metaElement->name(), "theme-color") && BisonCSSParser::parseColor(rgb, metaElement->content().string().stripWhiteSpace(), true))
return Color(rgb);
}
m_ranges.remove(range);
}
-void Document::getCSSCanvasContext(const String& type, const String& name, int width, int height, bool& is2d, RefPtrWillBeRawPtr<CanvasRenderingContext2D>& context2d, bool& is3d, RefPtrWillBeRawPtr<WebGLRenderingContext>& context3d)
+void Document::getCSSCanvasContext(const String& type, const String& name, int width, int height, RefPtrWillBeRawPtr<CanvasRenderingContext2D>& context2d, RefPtrWillBeRawPtr<WebGLRenderingContext>& context3d)
{
HTMLCanvasElement& element = getCSSCanvasElement(name);
element.setSize(IntSize(width, height));
return;
if (context->is2d()) {
- is2d = true;
context2d = toCanvasRenderingContext2D(context);
} else if (context->is3d()) {
- is3d = true;
context3d = toWebGLRenderingContext(context);
}
}
InspectorInstrumentation::scriptExecutionBlockedByCSP(this, directiveText);
}
-void Document::addMessage(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, ScriptState* scriptState)
-{
- internalAddMessage(source, level, message, sourceURL, lineNumber, nullptr, scriptState);
-}
-
-void Document::internalAddMessage(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack, ScriptState* scriptState)
+void Document::addMessage(PassRefPtrWillBeRawPtr<ConsoleMessage> consoleMessage)
{
if (!isContextThread()) {
- m_taskRunner->postTask(AddConsoleMessageTask::create(source, level, message));
+ m_taskRunner->postTask(AddConsoleMessageTask::create(consoleMessage->source(), consoleMessage->level(), consoleMessage->message()));
return;
}
if (!m_frame)
return;
- String messageURL = sourceURL;
- if (!scriptState && sourceURL.isNull() && !lineNumber) {
- messageURL = url().string();
+ if (!consoleMessage->scriptState() && consoleMessage->url().isNull() && !consoleMessage->lineNumber()) {
+ consoleMessage->setURL(url().string());
if (parsing() && !isInDocumentWrite() && scriptableDocumentParser()) {
ScriptableDocumentParser* parser = scriptableDocumentParser();
if (!parser->isWaitingForScripts() && !parser->isExecutingScript())
- lineNumber = parser->lineNumber().oneBasedInt();
+ consoleMessage->setLineNumber(parser->lineNumber().oneBasedInt());
}
}
- m_frame->console().addMessage(source, level, message, messageURL, lineNumber, 0, callStack, scriptState, 0);
-}
-
-void Document::addConsoleMessageWithRequestIdentifier(MessageSource source, MessageLevel level, const String& message, unsigned long requestIdentifier)
-{
- if (!isContextThread()) {
- m_taskRunner->postTask(AddConsoleMessageTask::create(source, level, message));
- return;
- }
-
- if (m_frame)
- m_frame->console().addMessage(source, level, message, String(), 0, 0, nullptr, 0, requestIdentifier);
+ m_frame->console().addMessage(consoleMessage);
}
// FIXME(crbug.com/305497): This should be removed after ExecutionContext-LocalDOMWindow migration.
m_taskRunner->postTask(task);
}
+void Document::postInspectorTask(PassOwnPtr<ExecutionContextTask> task)
+{
+ m_taskRunner->postInspectorTask(task);
+}
+
void Document::tasksWereSuspended()
{
scriptRunner()->suspend();
return TouchList::create(touches);
}
-void Document::didAddTouchEventHandler(Node* handler)
-{
- // The node should either be in this document, or be the Document node of a child
- // of this document.
- ASSERT(&handler->document() == this
- || (handler->isDocumentNode() && toDocument(handler)->parentDocument() == this));
- if (!m_touchEventTargets.get())
- m_touchEventTargets = adoptPtr(new TouchEventTargetSet);
- bool isFirstHandler = m_touchEventTargets->isEmpty();
-
- if (!m_touchEventTargets->add(handler).isNewEntry) {
- // Just incremented refcount, no real change.
- // If this is a child document node, then the count should never go above 1.
- ASSERT(!handler->isDocumentNode() || &handler->document() == this);
- return;
- }
-
- if (isFirstHandler) {
- if (Document* parent = parentDocument()) {
- parent->didAddTouchEventHandler(this);
- } else {
- // This is the first touch handler on the whole page.
- if (FrameHost* frameHost = this->frameHost())
- frameHost->chrome().client().needTouchEvents(true);
- }
- }
-
- // When we're all done with all frames, ensure touch hit rects are marked as dirty.
- if (!handler->isDocumentNode() || handler == this) {
- if (Page* page = this->page()) {
- if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
- scrollingCoordinator->touchEventTargetRectsDidChange();
- }
- }
-}
-
-void Document::didRemoveTouchEventHandler(Node* handler, bool clearAll)
-{
- // Note that we can't assert that |handler| is in this document because it might be in
- // the process of moving out of it.
- ASSERT(clearAll || m_touchEventTargets->contains(handler));
- if (!m_touchEventTargets.get())
- return;
-
- if (clearAll) {
- if (!m_touchEventTargets->contains(handler))
- return;
- m_touchEventTargets->removeAll(handler);
- } else {
- if (!m_touchEventTargets->remove(handler))
- // Just decremented refcount, no real update.
- return;
- }
-
- if (m_touchEventTargets->isEmpty()) {
- if (Document* parent = parentDocument()) {
- // This was the last handler in this document, update the parent document too.
- parent->didRemoveTouchEventHandler(this, clearAll);
- } else {
- // We just removed the last touch handler on the whole page.
- if (FrameHost* frameHost = this->frameHost())
- frameHost->chrome().client().needTouchEvents(false);
- }
- }
-
- // When we're all done with all frames, ensure touch hit rects are marked as dirty.
- if (!handler->isDocumentNode() || handler == this) {
- if (Page* page = this->page()) {
- if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
- scrollingCoordinator->touchEventTargetRectsDidChange();
- }
- }
-}
-
DocumentLoader* Document::loader() const
{
if (!m_frame)
--m_activeParserCount;
if (!frame())
return;
- // FIXME: This should always be enabled, but it seems to cause
- // http/tests/security/feed-urls-from-remote.html to timeout on Mac WK1
- // see http://webkit.org/b/110554 and http://webkit.org/b/110401
frame()->loader().checkLoadComplete();
}
Element* oldActiveElement = activeHoverElement();
if (oldActiveElement && !request.active()) {
- // We are clearing the :active chain because the mouse has been released.
- for (RenderObject* curr = oldActiveElement->renderer(); curr; curr = curr->parent()) {
- if (curr->node()) {
- ASSERT(!curr->node()->isTextNode());
- curr->node()->setActive(false);
- m_userActionElements.setInActiveChain(curr->node(), false);
- }
+ // The oldActiveElement renderer is null, dropped on :active by setting display: none,
+ // for instance. We still need to clear the ActiveChain as the mouse is released.
+ for (Node* node = oldActiveElement; node; node = NodeRenderingTraversal::parent(node)) {
+ ASSERT(!node->isTextNode());
+ node->setActive(false);
+ m_userActionElements.setInActiveChain(node, false);
}
setActiveHoverElement(nullptr);
} else {
if (!oldActiveElement && newActiveElement && !newActiveElement->isDisabledFormControl() && request.active() && !request.touchMove()) {
// We are setting the :active chain and freezing it. If future moves happen, they
// will need to reference this chain.
- for (RenderObject* curr = newActiveElement->renderer(); curr; curr = curr->parent()) {
- if (curr->node() && !curr->isText())
- m_userActionElements.setInActiveChain(curr->node(), true);
+ for (Node* node = newActiveElement; node; node = NodeRenderingTraversal::parent(node)) {
+ ASSERT(!node->isTextNode());
+ m_userActionElements.setInActiveChain(node, true);
}
-
setActiveHoverElement(newActiveElement);
}
}
TextAutosizer* Document::textAutosizer()
{
- if (!m_textAutosizer && !RuntimeEnabledFeatures::fastTextAutosizingEnabled())
+ if (!m_textAutosizer)
m_textAutosizer = TextAutosizer::create(this);
return m_textAutosizer.get();
}
-FastTextAutosizer* Document::fastTextAutosizer()
-{
- if (!m_fastTextAutosizer && RuntimeEnabledFeatures::fastTextAutosizingEnabled())
- m_fastTextAutosizer = FastTextAutosizer::create(this);
- return m_fastTextAutosizer.get();
-}
-
void Document::setAutofocusElement(Element* element)
{
if (!element) {
return body();
}
+void Document::getTransitionElementData(Vector<TransitionElementData>& elementData)
+{
+ if (!head())
+ return;
+
+ for (HTMLMetaElement* metaElement = Traversal<HTMLMetaElement>::firstChild(*head()); metaElement; metaElement = Traversal<HTMLMetaElement>::nextSibling(*metaElement)) {
+ if (metaElement->name() != "transition-elements")
+ continue;
+
+ const String& metaElementContents = metaElement->content().string();
+ size_t firstSemicolon = metaElementContents.find(';');
+ if (firstSemicolon == kNotFound)
+ continue;
+
+ TrackExceptionState exceptionState;
+ AtomicString selector(metaElementContents.substring(0, firstSemicolon));
+ RefPtrWillBeRawPtr<StaticElementList> elementList = querySelectorAll(selector, exceptionState);
+ if (!elementList || exceptionState.hadException())
+ continue;
+
+ unsigned nodeListLength = elementList->length();
+ if (!nodeListLength)
+ continue;
+
+ StringBuilder markup;
+ for (unsigned nodeIndex = 0; nodeIndex < nodeListLength; ++nodeIndex) {
+ Element* element = elementList->item(nodeIndex);
+ markup.append(createStyledMarkupForNavigationTransition(element));
+ }
+
+ TransitionElementData newElements;
+ newElements.scope = metaElementContents.substring(firstSemicolon + 1).stripWhiteSpace();
+ newElements.selector = selector;
+ newElements.markup = markup.toString();
+ elementData.append(newElements);
+ }
+}
+
+void Document::hideTransitionElements(const AtomicString& cssSelector)
+{
+ TrackExceptionState exceptionState;
+ RefPtrWillBeRawPtr<StaticElementList> elementList = querySelectorAll(cssSelector, exceptionState);
+ if (elementList && !exceptionState.hadException()) {
+ unsigned nodeListLength = elementList->length();
+
+ for (unsigned nodeIndex = 0; nodeIndex < nodeListLength; ++nodeIndex) {
+ Element* element = elementList->item(nodeIndex);
+ element->setInlineStyleProperty(CSSPropertyOpacity, 0.0, CSSPrimitiveValue::CSS_NUMBER);
+ }
+ }
+}
+
bool Document::hasFocus() const
{
Page* page = this->page();
{
if (m_axObjectCache)
m_axObjectCache->clearWeakMembers(visitor);
-
- // FIXME: Oilpan: Use a weak counted set instead.
- if (m_touchEventTargets) {
- Vector<Node*> deadNodes;
- for (TouchEventTargetSet::iterator it = m_touchEventTargets->begin(); it != m_touchEventTargets->end(); ++it) {
- if (!visitor->isAlive(it->key))
- deadNodes.append(it->key);
- }
- for (unsigned i = 0; i < deadNodes.size(); ++i)
- didClearTouchEventHandlers(deadNodes[i]);
- }
}
void Document::trace(Visitor* visitor)
{
+#if ENABLE(OILPAN)
visitor->trace(m_importsController);
visitor->trace(m_docType);
visitor->trace(m_implementation);
visitor->trace(m_scriptRunner);
visitor->trace(m_transformSourceDocument);
visitor->trace(m_listsInvalidatedAtDocument);
-#if ENABLE(OILPAN)
for (int i = 0; i < numNodeListInvalidationTypes; ++i)
visitor->trace(m_nodeLists[i]);
-#endif
visitor->trace(m_cssCanvasElements);
visitor->trace(m_topLayerElements);
visitor->trace(m_elemSheet);
visitor->trace(m_ranges);
visitor->trace(m_styleEngine);
visitor->trace(m_formController);
+ visitor->trace(m_visitedLinkState);
visitor->trace(m_domWindow);
visitor->trace(m_fetcher);
visitor->trace(m_parser);
visitor->trace(m_styleSheetList);
visitor->trace(m_mediaQueryMatcher);
visitor->trace(m_scriptedAnimationController);
+ visitor->trace(m_textAutosizer);
visitor->trace(m_registrationContext);
+ visitor->trace(m_customElementMicrotaskRunQueue);
+ visitor->trace(m_elementDataCache);
visitor->trace(m_associatedFormControls);
visitor->trace(m_useElementsNeedingUpdate);
visitor->trace(m_layerUpdateSVGFilterElements);
visitor->trace(m_compositorPendingAnimations);
visitor->trace(m_contextDocument);
visitor->registerWeakMembers<Document, &Document::clearWeakMembers>(this);
+#endif
DocumentSupplementable::trace(visitor);
TreeScope::trace(visitor);
ContainerNode::trace(visitor);
ExecutionContext::trace(visitor);
+ LifecycleContext<Document>::trace(visitor);
}
-} // namespace WebCore
+} // namespace blink
+
+#ifndef NDEBUG
+using namespace blink;
+void showLiveDocumentInstances()
+{
+ WeakDocumentSet& set = liveDocumentSet();
+ fprintf(stderr, "There are %u documents currently alive:\n", set.size());
+ for (WeakDocumentSet::const_iterator it = set.begin(); it != set.end(); ++it) {
+ fprintf(stderr, "- Document %p URL: %s\n", *it, (*it)->url().string().utf8().data());
+ }
+}
+#endif