Commit message: None
CVE: CVE-2018-6048
CWE: CWE-20
Vulnerability description: Insufficient policy enforcement in Blink in Google Chrome prior to 64.0.3282.119 allowed a remote attacker to potentially leak referrer information via a crafted HTML page.

Project: Chrome

void Document::AddConsoleMessage(ConsoleMessage* console_message) {
  if (!IsContextThread()) {
    TaskRunnerHelper::Get(TaskType::kUnthrottled, this)
        ->PostTask(BLINK_FROM_HERE,
                   CrossThreadBind(
                       &RunAddConsoleMessageTask, console_message->Source(),
                       console_message->Level(), console_message->Message(),
                       WrapCrossThreadPersistent(this)));
    return;
  }

  if (!frame_)
    return;

  if (console_message->Location()->IsUnknown()) {
    unsigned line_number = 0;
    if (!IsInDocumentWrite() && GetScriptableDocumentParser()) {
      ScriptableDocumentParser* parser = GetScriptableDocumentParser();
      if (parser->IsParsingAtLineNumber())
        line_number = parser->LineNumber().OneBasedInt();
    }
    Vector<DOMNodeId> nodes(console_message->Nodes());
    console_message = ConsoleMessage::Create(
        console_message->Source(), console_message->Level(),
        console_message->Message(),
        SourceLocation::Create(Url().GetString(), line_number, 0, nullptr));
    console_message->SetNodes(frame_, std::move(nodes));
  }
  frame_->Console().AddMessage(console_message);
}

Project: Chrome

void Document::AdjustFloatQuadsForScrollAndAbsoluteZoom(
    Vector<FloatQuad>& quads,
    const LayoutObject& layout_object) const {
  if (!View())
    return;

  LayoutRect visible_content_rect(View()->VisibleContentRect());
  for (size_t i = 0; i < quads.size(); ++i) {
    quads[i].Move(-FloatSize(visible_content_rect.X().ToFloat(),
                             visible_content_rect.Y().ToFloat()));
    AdjustFloatQuadForAbsoluteZoom(quads[i], layout_object);
  }
}

Project: Chrome

AXObjectCache* Document::AxObjectCache() const {
  Settings* settings = GetSettings();
  if (!settings || !settings->GetAccessibilityEnabled())
    return nullptr;

  Document& cache_owner = AxObjectCacheOwner();

  if (!cache_owner.GetLayoutView())
    return nullptr;

  DCHECK(&cache_owner == this || !ax_object_cache_);
  if (!cache_owner.ax_object_cache_)
    cache_owner.ax_object_cache_ = AXObjectCache::Create(cache_owner);
  return cache_owner.ax_object_cache_.Get();
}

Project: Chrome

void Document::CheckCompleted() {
  if (!ShouldComplete())
    return;

  if (frame_) {
    frame_->Client()->RunScriptsAtDocumentIdle();

    if (!frame_)
      return;

    if (!ShouldComplete())
      return;
  }

  SetReadyState(kComplete);
  if (LoadEventStillNeeded())
    ImplicitClose();

  if (!frame_ || !frame_->IsAttached())
    return;
  if (frame_->GetSettings()->GetSavePreviousDocumentResources() ==
      SavePreviousDocumentResources::kUntilOnLoad) {
    fetcher_->ClearResourcesFromPreviousFetcher();
  }
  frame_->GetNavigationScheduler().StartTimer();
  View()->HandleLoadCompleted();
  if (!AllDescendantsAreComplete(frame_))
    return;

  if (!Loader()->SentDidFinishLoad()) {
    if (frame_->IsMainFrame())
      ViewportDescription().ReportMobilePageStats(frame_);
    Loader()->SetSentDidFinishLoad();
    frame_->Client()->DispatchDidFinishLoad();
    if (!frame_)
      return;
  }

  frame_->Loader().DidFinishNavigation();
}

Project: Chrome

void Document::DidLoadAllScriptBlockingResources() {
  execute_scripts_waiting_for_resources_task_handle_ =
      TaskRunnerHelper::Get(TaskType::kNetworking, this)
          ->PostCancellableTask(
              BLINK_FROM_HERE,
              WTF::Bind(&Document::ExecuteScriptsWaitingForResources,
                        WrapWeakPersistent(this)));

  if (IsHTMLDocument() && body()) {
    BeginLifecycleUpdatesIfRenderingReady();
  } else if (!IsHTMLDocument() && documentElement()) {
    BeginLifecycleUpdatesIfRenderingReady();
  }
}

Project: Chrome

void Document::DispatchUnloadEvents() {
  PluginScriptForbiddenScope forbid_plugin_destructor_scripting;
  if (parser_)
    parser_->StopParsing();

  if (load_event_progress_ == kLoadEventNotRun)
    return;

  if (load_event_progress_ <= kUnloadEventInProgress) {
    Element* current_focused_element = FocusedElement();
    if (auto* input = ToHTMLInputElementOrNull(current_focused_element))
      input->EndEditing();
    if (load_event_progress_ < kPageHideInProgress) {
      load_event_progress_ = kPageHideInProgress;
      if (LocalDOMWindow* window = domWindow()) {
        const double pagehide_event_start = MonotonicallyIncreasingTime();
        window->DispatchEvent(
            PageTransitionEvent::Create(EventTypeNames::pagehide, false), this);
        const double pagehide_event_end = MonotonicallyIncreasingTime();
        DEFINE_STATIC_LOCAL(
            CustomCountHistogram, pagehide_histogram,
            ("DocumentEventTiming.PageHideDuration", 0, 10000000, 50));
        pagehide_histogram.Count((pagehide_event_end - pagehide_event_start) *
                                 1000000.0);
      }
      if (!frame_)
        return;

      PageVisibilityState visibility_state = GetPageVisibilityState();
      load_event_progress_ = kUnloadVisibilityChangeInProgress;
      if (visibility_state != kPageVisibilityStateHidden) {
        const double pagevisibility_hidden_event_start =
            MonotonicallyIncreasingTime();
        DispatchEvent(Event::CreateBubble(EventTypeNames::visibilitychange));
        const double pagevisibility_hidden_event_end =
            MonotonicallyIncreasingTime();
        DEFINE_STATIC_LOCAL(CustomCountHistogram, pagevisibility_histogram,
                            ("DocumentEventTiming.PageVibilityHiddenDuration",
                             0, 10000000, 50));
        pagevisibility_histogram.Count((pagevisibility_hidden_event_end -
                                        pagevisibility_hidden_event_start) *
                                       1000000.0);
        DispatchEvent(
            Event::CreateBubble(EventTypeNames::webkitvisibilitychange));
      }
      if (!frame_)
        return;

      DocumentLoader* document_loader =
          frame_->Loader().GetProvisionalDocumentLoader();
      load_event_progress_ = kUnloadEventInProgress;
      Event* unload_event(Event::Create(EventTypeNames::unload));
      if (document_loader && !document_loader->GetTiming().UnloadEventStart() &&
          !document_loader->GetTiming().UnloadEventEnd()) {
        DocumentLoadTiming& timing = document_loader->GetTiming();
        DCHECK(timing.NavigationStart());
        const double unload_event_start = MonotonicallyIncreasingTime();
        timing.MarkUnloadEventStart(unload_event_start);
        frame_->DomWindow()->DispatchEvent(unload_event, this);
        const double unload_event_end = MonotonicallyIncreasingTime();
        DEFINE_STATIC_LOCAL(
            CustomCountHistogram, unload_histogram,
            ("DocumentLoadTiming.UnloadDuration", 0, 10000000, 50));
        unload_histogram.Count((unload_event_end - unload_event_start) *
                               1000000.0);
        timing.MarkUnloadEventEnd(unload_event_end);
      } else {
        frame_->DomWindow()->DispatchEvent(unload_event, frame_->GetDocument());
      }
    }
    load_event_progress_ = kUnloadEventHandled;
  }

  if (!frame_)
    return;

  bool keep_event_listeners =
      frame_->Loader().GetProvisionalDocumentLoader() &&
      frame_->ShouldReuseDefaultView(
          frame_->Loader().GetProvisionalDocumentLoader()->Url());
  if (!keep_event_listeners)
    RemoveAllEventListenersRecursively();
}

Project: Chrome

Document::Document(const DocumentInit& initializer,
                   DocumentClassFlags document_classes)
    : ContainerNode(nullptr, kCreateDocument),
      TreeScope(*this),
      has_nodes_with_placeholder_style_(false),
      evaluate_media_queries_on_style_recalc_(false),
      pending_sheet_layout_(kNoLayoutWithPendingSheets),
      frame_(initializer.GetFrame()),
      dom_window_(frame_ ? frame_->DomWindow() : nullptr),
      imports_controller_(initializer.ImportsController()),
      context_document_(initializer.ContextDocument()),
      context_features_(ContextFeatures::DefaultSwitch()),
      well_formed_(false),
      printing_(kNotPrinting),
      paginated_for_screen_(false),
      compatibility_mode_(kNoQuirksMode),
      compatibility_mode_locked_(false),
      has_autofocused_(false),
      clear_focused_element_timer_(
          TaskRunnerHelper::Get(TaskType::kUnspecedTimer, this),
          this,
          &Document::ClearFocusedElementTimerFired),
      dom_tree_version_(++global_tree_version_),
      style_version_(0),
      listener_types_(0),
      mutation_observer_types_(0),
      visited_link_state_(VisitedLinkState::Create(*this)),
      visually_ordered_(false),
      ready_state_(kComplete),
      parsing_state_(kFinishedParsing),
      goto_anchor_needed_after_stylesheets_load_(false),
      contains_validity_style_rules_(false),
      contains_plugins_(false),
      ignore_destructive_write_count_(0),
      throw_on_dynamic_markup_insertion_count_(0),
      markers_(new DocumentMarkerController(*this)),
      update_focus_appearance_timer_(
          TaskRunnerHelper::Get(TaskType::kUnspecedTimer, this),
          this,
          &Document::UpdateFocusAppearanceTimerFired),
      css_target_(nullptr),
      load_event_progress_(kLoadEventCompleted),
      start_time_(CurrentTime()),
      script_runner_(ScriptRunner::Create(this)),
      xml_version_("1.0"),
      xml_standalone_(kStandaloneUnspecified),
      has_xml_declaration_(0),
      design_mode_(false),
      is_running_exec_command_(false),
      has_annotated_regions_(false),
      annotated_regions_dirty_(false),
      document_classes_(document_classes),
      is_view_source_(false),
      saw_elements_in_known_namespaces_(false),
      is_srcdoc_document_(initializer.ShouldTreatURLAsSrcdocDocument()),
      is_mobile_document_(false),
      layout_view_(nullptr),
      has_fullscreen_supplement_(false),
      load_event_delay_count_(0),
      load_event_delay_timer_(
          TaskRunnerHelper::Get(TaskType::kNetworking, this),
          this,
          &Document::LoadEventDelayTimerFired),
      plugin_loading_timer_(
          TaskRunnerHelper::Get(TaskType::kUnspecedLoading, this),
          this,
          &Document::PluginLoadingTimerFired),
      document_timing_(*this),
      write_recursion_is_too_deep_(false),
      write_recursion_depth_(0),
      registration_context_(initializer.RegistrationContext(this)),
      element_data_cache_clear_timer_(
          TaskRunnerHelper::Get(TaskType::kUnspecedTimer, this),
          this,
          &Document::ElementDataCacheClearTimerFired),
      timeline_(DocumentTimeline::Create(this)),
      pending_animations_(new PendingAnimations(*this)),
      worklet_animation_controller_(new WorkletAnimationController),
      template_document_host_(nullptr),
      did_associate_form_controls_timer_(
          TaskRunnerHelper::Get(TaskType::kUnspecedLoading, this),
          this,
          &Document::DidAssociateFormControlsTimerFired),
      timers_(TaskRunnerHelper::Get(TaskType::kJavascriptTimer, this)),
      has_viewport_units_(false),
      parser_sync_policy_(kAllowAsynchronousParsing),
      node_count_(0),
      would_load_reason_(WouldLoadReason::kInvalid),
      password_count_(0),
      logged_field_edit_(false),
      engagement_level_(mojom::blink::EngagementLevel::NONE) {
  if (frame_) {
    DCHECK(frame_->GetPage());
    ProvideContextFeaturesToDocumentFrom(*this, *frame_->GetPage());

    fetcher_ = frame_->Loader().GetDocumentLoader()->Fetcher();
    FrameFetchContext::ProvideDocumentToContext(fetcher_->Context(), this);

    CustomElementRegistry* registry =
        frame_->DomWindow() ? frame_->DomWindow()->MaybeCustomElements()
                            : nullptr;
    if (registry && registration_context_)
      registry->Entangle(registration_context_);
  } else if (imports_controller_) {
    fetcher_ = FrameFetchContext::CreateFetcherFromDocument(this);
  } else {
    fetcher_ = ResourceFetcher::Create(nullptr);
  }
  DCHECK(fetcher_);

  root_scroller_controller_ = RootScrollerController::Create(*this);

  if (initializer.ShouldSetURL()) {
    SetURL(initializer.Url());
  } else {
    UpdateBaseURL();
  }

  InitSecurityContext(initializer);

  InitDNSPrefetch();

  InstanceCounters::IncrementCounter(InstanceCounters::kDocumentCounter);

  lifecycle_.AdvanceTo(DocumentLifecycle::kInactive);

  style_engine_ = StyleEngine::Create(*this);

  DCHECK(!ParentDocument() || !ParentDocument()->IsContextSuspended());

#ifndef NDEBUG
  liveDocumentSet().insert(this);
#endif
}

Project: Chrome

AXObjectCache* Document::ExistingAXObjectCache() const {
  auto& cache_owner = AxObjectCacheOwner();

  if (!cache_owner.GetLayoutView())
    return nullptr;

  return cache_owner.ax_object_cache_.Get();
}

Project: Chrome

void Document::FinishedParsing() {
  DCHECK(!GetScriptableDocumentParser() || !parser_->IsParsing());
  DCHECK(!GetScriptableDocumentParser() || ready_state_ != kLoading);
  SetParsingState(kInDOMContentLoaded);
  DocumentParserTiming::From(*this).MarkParserStop();

  if (!document_timing_.DomContentLoadedEventStart())
    document_timing_.MarkDomContentLoadedEventStart();
  DispatchEvent(Event::CreateBubble(EventTypeNames::DOMContentLoaded));
  if (!document_timing_.DomContentLoadedEventEnd())
    document_timing_.MarkDomContentLoadedEventEnd();
  SetParsingState(kFinishedParsing);

  Microtask::PerformCheckpoint(V8PerIsolateData::MainThreadIsolate());

  ScriptableDocumentParser* parser = GetScriptableDocumentParser();
  well_formed_ = parser && parser->WellFormed();

  if (LocalFrame* frame = GetFrame()) {
    const bool main_resource_was_already_requested =
        frame->Loader().StateMachine()->CommittedFirstRealDocumentLoad();

    if (main_resource_was_already_requested)
      UpdateStyleAndLayoutTree();

    BeginLifecycleUpdatesIfRenderingReady();

    frame->Loader().FinishedParsing();

    TRACE_EVENT_INSTANT1("devtools.timeline", "MarkDOMContent",
                         TRACE_EVENT_SCOPE_THREAD, "data",
                         InspectorMarkLoadEvent::Data(frame));
    probe::domContentLoadedEventFired(frame);
    frame->GetIdlenessDetector()->DomContentLoadedEventFired();
  }

  element_data_cache_clear_timer_.StartOneShot(10, BLINK_FROM_HERE);

  fetcher_->ClearPreloads(ResourceFetcher::kClearSpeculativeMarkupPreloads);
  if (!frame_ || frame_->GetSettings()->GetSavePreviousDocumentResources() ==
                     SavePreviousDocumentResources::kUntilOnDOMContentLoaded) {
    fetcher_->ClearResourcesFromPreviousFetcher();
  }

  if (IsPrefetchOnly())
    WebPrerenderingSupport::Current()->PrefetchFinished();
}

Project: Chrome

void Document::ImplicitClose() {
  DCHECK(!InStyleRecalc());
  DCHECK(parser_);

  load_event_progress_ = kLoadEventInProgress;

  DetachParser();


  if (SvgExtensions())
    AccessSVGExtensions().DispatchSVGLoadEventToOutermostSVGElements();

  if (domWindow())
    domWindow()->DocumentWasClosed();

  if (GetFrame()) {
    GetFrame()->Client()->DispatchDidHandleOnloadEvents();
    Loader()->GetApplicationCacheHost()->StopDeferringEvents();
  }

  if (!GetFrame()) {
    load_event_progress_ = kLoadEventCompleted;
    return;
  }


  if (GetFrame()->GetNavigationScheduler().LocationChangePending() &&
      ElapsedTime() < kCLayoutScheduleThreshold) {
    load_event_progress_ = kLoadEventCompleted;
    return;
  }

  if (!LocalOwner() || (LocalOwner()->GetLayoutObject() &&
                        !LocalOwner()->GetLayoutObject()->NeedsLayout())) {
    UpdateStyleAndLayoutTree();

    if (View() && !GetLayoutViewItem().IsNull() &&
        (!GetLayoutViewItem().FirstChild() ||
         GetLayoutViewItem().NeedsLayout()))
      View()->UpdateLayout();
  }

  load_event_progress_ = kLoadEventCompleted;

  if (GetFrame() && !GetLayoutViewItem().IsNull() &&
      GetSettings()->GetAccessibilityEnabled()) {
    if (AXObjectCache* cache = AxObjectCache()) {
      if (this == &AxObjectCacheOwner())
        cache->HandleLoadComplete(this);
      else
        cache->HandleLayoutComplete(this);
    }
  }

  if (SvgExtensions())
    AccessSVGExtensions().StartAnimations();
}

Project: Chrome

HTMLLinkElement* Document::LinkManifest() const {
  HTMLHeadElement* head = this->head();
  if (!head)
    return nullptr;

  for (HTMLLinkElement* link_element =
           Traversal<HTMLLinkElement>::FirstChild(*head);
       link_element;
       link_element = Traversal<HTMLLinkElement>::NextSibling(*link_element)) {
    if (!link_element->RelAttribute().IsManifest())
      continue;
    return link_element;
  }

  return nullptr;
}

Project: Chrome

  explicit NetworkStateObserver(Document& document)
      : ContextLifecycleObserver(&document) {
    online_observer_handle_ = GetNetworkStateNotifier().AddOnLineObserver(
        this,
        TaskRunnerHelper::Get(TaskType::kNetworking, GetExecutionContext()));
  }

Project: Chrome

void Document::PropagateStyleToViewport() {
  DCHECK(InStyleRecalc());
  DCHECK(documentElement());

  HTMLElement* body = this->body();

  const ComputedStyle* body_style =
      body ? body->EnsureComputedStyle() : nullptr;
  const ComputedStyle* document_element_style =
      documentElement()->EnsureComputedStyle();

  WritingMode root_writing_mode = document_element_style->GetWritingMode();
  TextDirection root_direction = document_element_style->Direction();
  if (body_style) {
    root_writing_mode = body_style->GetWritingMode();
    root_direction = body_style->Direction();
  }

  const ComputedStyle* background_style = document_element_style;
  if (IsHTMLHtmlElement(documentElement()) && IsHTMLBodyElement(body) &&
      !background_style->HasBackground())
    background_style = body_style;

  Node& root_scroller = GetRootScrollerController().EffectiveRootScroller();
  if (this != &root_scroller)
    background_style = ToElement(root_scroller).EnsureComputedStyle();

  Color background_color =
      background_style->VisitedDependentColor(CSSPropertyBackgroundColor);
  FillLayer background_layers = background_style->BackgroundLayers();
  for (auto current_layer = &background_layers; current_layer;
       current_layer = current_layer->Next()) {
    current_layer->SetClip(kBorderFillBox);

    if (current_layer->Attachment() == kScrollBackgroundAttachment)
      current_layer->SetAttachment(kLocalBackgroundAttachment);
  }
  EImageRendering image_rendering = background_style->ImageRendering();

  const ComputedStyle* overflow_style = nullptr;
  if (Element* element = ViewportDefiningElement(document_element_style)) {
    if (element == body) {
      overflow_style = body_style;
    } else {
      DCHECK_EQ(element, documentElement());
      overflow_style = document_element_style;

      if (body_style && !body_style->IsOverflowVisible())
        UseCounter::Count(*this, WebFeature::kBodyScrollsInAdditionToViewport);
    }
  }

  EOverflowAnchor overflow_anchor = EOverflowAnchor::kAuto;
  EOverflow overflow_x = EOverflow::kAuto;
  EOverflow overflow_y = EOverflow::kAuto;
  bool column_gap_normal = true;
  float column_gap = 0;
  if (overflow_style) {
    overflow_anchor = overflow_style->OverflowAnchor();
    overflow_x = overflow_style->OverflowX();
    overflow_y = overflow_style->OverflowY();
    if (overflow_x == EOverflow::kVisible)
      overflow_x = EOverflow::kAuto;
    if (overflow_y == EOverflow::kVisible)
      overflow_y = EOverflow::kAuto;
    if (overflow_anchor == EOverflowAnchor::kVisible)
      overflow_anchor = EOverflowAnchor::kAuto;
    if (!overflow_style->HasNormalColumnGap()) {
      column_gap_normal = false;
      column_gap = overflow_style->ColumnGap();
    }
  }

  ScrollSnapType snap_type = overflow_style->GetScrollSnapType();
  ScrollBehavior scroll_behavior = document_element_style->GetScrollBehavior();

  EScrollBoundaryBehavior scroll_boundary_behavior_x =
      overflow_style->ScrollBoundaryBehaviorX();
  EScrollBoundaryBehavior scroll_boundary_behavior_y =
      overflow_style->ScrollBoundaryBehaviorY();
  using ScrollBoundaryBehaviorType =
      WebScrollBoundaryBehavior::ScrollBoundaryBehaviorType;
  if (RuntimeEnabledFeatures::CSSScrollBoundaryBehaviorEnabled() &&
      IsInMainFrame()) {
    GetPage()->GetOverscrollController().SetScrollBoundaryBehavior(
        WebScrollBoundaryBehavior(
            static_cast<ScrollBoundaryBehaviorType>(scroll_boundary_behavior_x),
            static_cast<ScrollBoundaryBehaviorType>(
                scroll_boundary_behavior_y)));
  }

  scoped_refptr<ComputedStyle> viewport_style =
      GetLayoutViewItem().MutableStyle();
  if (viewport_style->GetWritingMode() != root_writing_mode ||
      viewport_style->Direction() != root_direction ||
      viewport_style->VisitedDependentColor(CSSPropertyBackgroundColor) !=
          background_color ||
      viewport_style->BackgroundLayers() != background_layers ||
      viewport_style->ImageRendering() != image_rendering ||
      viewport_style->OverflowAnchor() != overflow_anchor ||
      viewport_style->OverflowX() != overflow_x ||
      viewport_style->OverflowY() != overflow_y ||
      viewport_style->HasNormalColumnGap() != column_gap_normal ||
      viewport_style->ColumnGap() != column_gap ||
      viewport_style->GetScrollSnapType() != snap_type ||
      viewport_style->GetScrollBehavior() != scroll_behavior ||
      viewport_style->ScrollBoundaryBehaviorX() != scroll_boundary_behavior_x ||
      viewport_style->ScrollBoundaryBehaviorY() != scroll_boundary_behavior_y) {
    scoped_refptr<ComputedStyle> new_style =
        ComputedStyle::Clone(*viewport_style);
    new_style->SetWritingMode(root_writing_mode);
    new_style->SetDirection(root_direction);
    new_style->SetBackgroundColor(background_color);
    new_style->AccessBackgroundLayers() = background_layers;
    new_style->SetImageRendering(image_rendering);
    new_style->SetOverflowAnchor(overflow_anchor);
    new_style->SetOverflowX(overflow_x);
    new_style->SetOverflowY(overflow_y);
    if (column_gap_normal)
      new_style->SetHasNormalColumnGap();
    else
      new_style->SetColumnGap(column_gap);
    new_style->SetScrollSnapType(snap_type);
    new_style->SetScrollBehavior(scroll_behavior);
    new_style->SetScrollBoundaryBehaviorX(scroll_boundary_behavior_x);
    new_style->SetScrollBoundaryBehaviorY(scroll_boundary_behavior_y);
    GetLayoutViewItem().SetStyle(new_style);
    SetupFontBuilder(*new_style);
  }
}

Project: Chrome

bool Document::SetFocusedElement(Element* new_focused_element,
                                 const FocusParams& params) {
  DCHECK(!lifecycle_.InDetach());

  clear_focused_element_timer_.Stop();

  if (new_focused_element && (new_focused_element->GetDocument() != this))
    return true;

  if (NodeChildRemovalTracker::IsBeingRemoved(new_focused_element))
    return true;

  if (focused_element_ == new_focused_element)
    return true;

  bool focus_change_blocked = false;
  Element* old_focused_element = focused_element_;
  focused_element_ = nullptr;

  UpdateDistribution();
  Node* ancestor = (old_focused_element && old_focused_element->isConnected() &&
                    new_focused_element)
                       ? FlatTreeTraversal::CommonAncestor(*old_focused_element,
                                                           *new_focused_element)
                       : nullptr;

  if (old_focused_element) {
    old_focused_element->SetFocused(false, params.type);
    old_focused_element->SetHasFocusWithinUpToAncestor(false, ancestor);

    if (GetPage() && (GetPage()->GetFocusController().IsFocused())) {
      old_focused_element->DispatchBlurEvent(new_focused_element, params.type,
                                             params.source_capabilities);
      if (focused_element_) {
        focus_change_blocked = true;
        new_focused_element = nullptr;
      }

      old_focused_element->DispatchFocusOutEvent(EventTypeNames::focusout,
                                                 new_focused_element,
                                                 params.source_capabilities);
      old_focused_element->DispatchFocusOutEvent(EventTypeNames::DOMFocusOut,
                                                 new_focused_element,
                                                 params.source_capabilities);

      if (focused_element_) {
        focus_change_blocked = true;
        new_focused_element = nullptr;
      }
    }
  }

  if (new_focused_element)
    UpdateStyleAndLayoutTreeForNode(new_focused_element);
  if (new_focused_element && new_focused_element->IsFocusable()) {
    if (IsRootEditableElement(*new_focused_element) &&
        !AcceptsEditingFocus(*new_focused_element)) {
      focus_change_blocked = true;
      goto SetFocusedElementDone;
    }
    focused_element_ = new_focused_element;
    SetSequentialFocusNavigationStartingPoint(focused_element_.Get());

    focused_element_->SetFocused(true, params.type);
    focused_element_->SetHasFocusWithinUpToAncestor(true, ancestor);

    if (focused_element_ != new_focused_element) {
      focus_change_blocked = true;
      goto SetFocusedElementDone;
    }
    CancelFocusAppearanceUpdate();
    focused_element_->UpdateFocusAppearance(params.selection_behavior);

    if (GetPage() && (GetPage()->GetFocusController().IsFocused())) {
      focused_element_->DispatchFocusEvent(old_focused_element, params.type,
                                           params.source_capabilities);

      if (focused_element_ != new_focused_element) {
        focus_change_blocked = true;
        goto SetFocusedElementDone;
      }
      focused_element_->DispatchFocusInEvent(EventTypeNames::focusin,
                                             old_focused_element, params.type,
                                             params.source_capabilities);

      if (focused_element_ != new_focused_element) {
        focus_change_blocked = true;
        goto SetFocusedElementDone;
      }

      focused_element_->DispatchFocusInEvent(EventTypeNames::DOMFocusIn,
                                             old_focused_element, params.type,
                                             params.source_capabilities);

      if (focused_element_ != new_focused_element) {
        focus_change_blocked = true;
        goto SetFocusedElementDone;
      }
    }
  }

  if (!focus_change_blocked && focused_element_) {
    if (AXObjectCache* cache = AxObjectCache())
      cache->HandleFocusedUIElementChanged(old_focused_element,
                                           new_focused_element);
  }

  if (!focus_change_blocked && GetPage()) {
    GetPage()->GetChromeClient().FocusedNodeChanged(old_focused_element,
                                                    focused_element_.Get());
  }

SetFocusedElementDone:
  UpdateStyleAndLayoutTree();
  if (LocalFrame* frame = GetFrame())
    frame->Selection().DidChangeFocus();
  return !focus_change_blocked;
}

Project: Chrome

void Document::Shutdown() {
  TRACE_EVENT0("blink", "Document::shutdown");
  CHECK(!frame_ || frame_->Tree().ChildCount() == 0);
  if (!IsActive())
    return;

  FrameNavigationDisabler navigation_disabler(*frame_);
  HTMLFrameOwnerElement::PluginDisposeSuspendScope suspend_plugin_dispose;
  ScriptForbiddenScope forbid_script;

  lifecycle_.AdvanceTo(DocumentLifecycle::kStopping);
  View()->Dispose();
  CHECK(!View()->IsAttached());

  HTMLFrameOwnerElement* owner_element = frame_->DeprecatedLocalOwner();
  if (owner_element)
    owner_element->SetEmbeddedContentView(nullptr);

  markers_->PrepareForDestruction();

  if (GetPage())
    GetPage()->DocumentDetached(this);
  probe::documentDetached(this);

  if (frame_->Client()->GetSharedWorkerRepositoryClient())
    frame_->Client()->GetSharedWorkerRepositoryClient()->DocumentDetached(this);

  if (scripted_animation_controller_)
    scripted_animation_controller_->ClearDocumentPointer();
  scripted_animation_controller_.Clear();

  scripted_idle_task_controller_.Clear();

  if (SvgExtensions())
    AccessSVGExtensions().PauseAnimations();

  if (dom_window_)
    dom_window_->ClearEventQueue();

  if (layout_view_)
    layout_view_->SetIsInWindow(false);

  if (RegistrationContext())
    RegistrationContext()->DocumentWasDetached();

  MutationObserver::CleanSlotChangeList(*this);

  hover_element_ = nullptr;
  active_element_ = nullptr;
  autofocus_element_ = nullptr;

  if (focused_element_.Get()) {
    Element* old_focused_element = focused_element_;
    focused_element_ = nullptr;
    if (GetPage())
      GetPage()->GetChromeClient().FocusedNodeChanged(old_focused_element,
                                                      nullptr);
  }
  sequential_focus_navigation_starting_point_ = nullptr;

  if (this == &AxObjectCacheOwner())
    ClearAXObjectCache();

  layout_view_ = nullptr;
  ContainerNode::DetachLayoutTree();
  CHECK(!View()->IsAttached());

  if (this != &AxObjectCacheOwner()) {
    if (AXObjectCache* cache = ExistingAXObjectCache()) {
      for (Node& node : NodeTraversal::DescendantsOf(*this)) {
        cache->Remove(&node);
      }
    }
  }

  GetStyleEngine().DidDetach();

  GetPage()->GetEventHandlerRegistry().DocumentDetached(*this);

  DocumentShutdownNotifier::NotifyContextDestroyed();
  SynchronousMutationNotifier::NotifyContextDestroyed();

  if (!Loader())
    fetcher_->ClearContext();
  if (imports_controller_) {
    imports_controller_->Dispose();
    ClearImportsController();
  }

  timers_.SetTimerTaskRunner(
      Platform::Current()->CurrentThread()->Scheduler()->TimerTaskRunner());

  if (media_query_matcher_)
    media_query_matcher_->DocumentDetached();

  lifecycle_.AdvanceTo(DocumentLifecycle::kStopped);
  CHECK(!View()->IsAttached());

  ExecutionContext::NotifyContextDestroyed();
  CHECK(!View()->IsAttached());

  frame_ = nullptr;

  document_outlive_time_reporter_ =
      WTF::WrapUnique(new DocumentOutliveTimeReporter(this));
}

Project: Chrome

bool Document::TasksNeedSuspension() {
  Page* page = GetPage();
  return page && page->Paused();
}

Project: Chrome

ukm::UkmRecorder* Document::UkmRecorder() {
  if (ukm_recorder_)
    return ukm_recorder_.get();

  ukm::mojom::UkmRecorderInterfacePtr interface;
  Platform::Current()->GetInterfaceProvider()->GetInterface(
      mojo::MakeRequest(&interface));
  ukm_recorder_.reset(new ukm::MojoUkmRecorder(std::move(interface)));
  ukm_source_id_ = ukm_recorder_->GetNewSourceID();
  ukm_recorder_->UpdateSourceURL(ukm_source_id_, url_);
  return ukm_recorder_.get();
}