tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

CloseWatcherManager.cpp (2919B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "CloseWatcherManager.h"
      8 
      9 #include "CloseWatcher.h"
     10 
     11 namespace mozilla::dom {
     12 
     13 NS_IMPL_CYCLE_COLLECTION(CloseWatcherManager, mGroups)
     14 NS_IMPL_CYCLE_COLLECTING_ADDREF(CloseWatcherManager)
     15 NS_IMPL_CYCLE_COLLECTING_RELEASE(CloseWatcherManager)
     16 
     17 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CloseWatcherManager)
     18  NS_INTERFACE_MAP_ENTRY(nsISupports)
     19 NS_INTERFACE_MAP_END
     20 
     21 // https://html.spec.whatwg.org/multipage/interaction.html#notify-the-close-watcher-manager-about-user-activation
     22 void CloseWatcherManager::NotifyUserInteraction() {
     23  if (mNextUserInteractionAllowsNewGroup) {
     24    mAllowedNumberOfGroups += 1;
     25    mNextUserInteractionAllowsNewGroup = false;
     26  }
     27 }
     28 
     29 bool CloseWatcherManager::CanGrow() const {
     30  return mGroups.Length() < mAllowedNumberOfGroups;
     31 }
     32 
     33 // https://html.spec.whatwg.org/multipage/interaction.html#process-close-watchers
     34 MOZ_CAN_RUN_SCRIPT bool CloseWatcherManager::ProcessCloseRequest() {
     35  bool processedACloseWatcher = false;
     36  if (mGroups.IsEmpty()) {
     37    return processedACloseWatcher;
     38  }
     39  auto i = mGroups.Length() - 1;
     40  auto group = mGroups.ElementAt(i).Clone();
     41  for (RefPtr<CloseWatcher> watcher : group.BackwardRange()) {
     42    processedACloseWatcher = true;
     43    // TODO:(keithamus): https://github.com/whatwg/html/issues/10240 ?
     44    if (!watcher->RequestToClose(true)) {
     45      break;
     46    }
     47  }
     48  if (mAllowedNumberOfGroups > 1) {
     49    mAllowedNumberOfGroups -= 1;
     50  }
     51  return processedACloseWatcher;
     52 }
     53 
     54 // https://html.spec.whatwg.org/multipage/interaction.html#establish-a-close-watcher
     55 // step 4-6
     56 void CloseWatcherManager::Add(CloseWatcher& aWatcher) {
     57  if (CanGrow()) {
     58    mGroups.AppendElement()->AppendElement(&aWatcher);
     59  } else {
     60    MOZ_ASSERT(!mGroups.IsEmpty(),
     61               "CloseWatcherManager groups must be at least 1");
     62    auto i = mGroups.Length() - 1;
     63    MOZ_ASSERT(!mGroups.ElementAt(i).Contains(&aWatcher));
     64    mGroups.ElementAt(i).AppendElement(&aWatcher);
     65  }
     66  mNextUserInteractionAllowsNewGroup = true;
     67 }
     68 
     69 // https://html.spec.whatwg.org/multipage/interaction.html#close-watcher-destroy
     70 void CloseWatcherManager::Remove(CloseWatcher& aWatcher) {
     71  CloseWatcherArray::ForwardIterator iter(mGroups);
     72  while (iter.HasMore()) {
     73    auto& group = iter.GetNext();
     74    group.RemoveElement(&aWatcher);
     75    if (group.IsEmpty()) {
     76      iter.Remove();
     77    }
     78  }
     79  mGroups.Compact();
     80 }
     81 
     82 bool CloseWatcherManager::Contains(const CloseWatcher& aWatcher) const {
     83  for (const auto& group : mGroups.BackwardRange()) {
     84    if (group.Contains(&aWatcher)) {
     85      return true;
     86    }
     87  }
     88  return false;
     89 }
     90 
     91 }  // namespace mozilla::dom