tor-browser

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

PermissionStatus.cpp (3380B)


      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 "mozilla/dom/PermissionStatus.h"
      8 
      9 #include "PermissionStatusSink.h"
     10 #include "PermissionUtils.h"
     11 #include "mozilla/AsyncEventDispatcher.h"
     12 #include "mozilla/Permission.h"
     13 #include "mozilla/Services.h"
     14 #include "nsGlobalWindowInner.h"
     15 #include "nsIPermissionManager.h"
     16 
     17 namespace mozilla::dom {
     18 
     19 PermissionStatus::PermissionStatus(nsIGlobalObject* aGlobal,
     20                                   PermissionName aName)
     21    : DOMEventTargetHelper(aGlobal),
     22      mName(aName),
     23      mState(PermissionState::Denied) {
     24  KeepAliveIfHasListenersFor(nsGkAtoms::onchange);
     25 }
     26 
     27 // https://w3c.github.io/permissions/#onchange-attribute and
     28 // https://w3c.github.io/permissions/#query-method
     29 RefPtr<PermissionStatus::SimplePromise> PermissionStatus::Init() {
     30  mSink = CreateSink();
     31  MOZ_ASSERT(mSink);
     32 
     33  return mSink->Init()->Then(
     34      GetCurrentSerialEventTarget(), __func__,
     35      [self = RefPtr(this)](const PermissionStatusSink::PermissionStatePromise::
     36                                ResolveOrRejectValue& aResult) {
     37        if (aResult.IsResolve()) {
     38          self->mState = self->ComputeStateFromAction(aResult.ResolveValue());
     39          return SimplePromise::CreateAndResolve(NS_OK, __func__);
     40        }
     41 
     42        return SimplePromise::CreateAndReject(aResult.RejectValue(), __func__);
     43      });
     44 }
     45 
     46 PermissionStatus::~PermissionStatus() {
     47  if (mSink) {
     48    mSink->Disentangle();
     49    mSink = nullptr;
     50  }
     51 }
     52 
     53 JSObject* PermissionStatus::WrapObject(JSContext* aCx,
     54                                       JS::Handle<JSObject*> aGivenProto) {
     55  return PermissionStatus_Binding::Wrap(aCx, this, aGivenProto);
     56 }
     57 
     58 nsLiteralCString PermissionStatus::GetPermissionType() const {
     59  return PermissionNameToType(mName);
     60 }
     61 
     62 // https://w3c.github.io/permissions/#dfn-permissionstatus-update-steps
     63 void PermissionStatus::PermissionChanged(uint32_t aAction) {
     64  PermissionState newState = ComputeStateFromAction(aAction);
     65  if (mState == newState) {
     66    return;
     67  }
     68 
     69  mState = newState;
     70 
     71  // Step 4: Queue a task on the permissions task source to fire an
     72  // event named change at status.
     73  RefPtr<AsyncEventDispatcher> eventDispatcher =
     74      new AsyncEventDispatcher(this, u"change"_ns, CanBubble::eNo);
     75  eventDispatcher->PostDOMEvent();
     76 }
     77 
     78 void PermissionStatus::DisconnectFromOwner() {
     79  IgnoreKeepAliveIfHasListenersFor(nsGkAtoms::onchange);
     80 
     81  if (mSink) {
     82    mSink->Disentangle();
     83    mSink = nullptr;
     84  }
     85 
     86  DOMEventTargetHelper::DisconnectFromOwner();
     87 }
     88 
     89 void PermissionStatus::GetType(nsACString& aName) const {
     90  aName.Assign(GetPermissionType());
     91 }
     92 
     93 already_AddRefed<PermissionStatusSink> PermissionStatus::CreateSink() {
     94  RefPtr<PermissionStatusSink> sink =
     95      new PermissionStatusSink(this, mName, GetPermissionType());
     96  return sink.forget();
     97 }
     98 
     99 PermissionState PermissionStatus::ComputeStateFromAction(uint32_t aAction) {
    100  nsCOMPtr<nsIGlobalObject> global = GetOwnerGlobal();
    101  if (NS_WARN_IF(!global)) {
    102    return PermissionState::Denied;
    103  }
    104 
    105  return ActionToPermissionState(aAction, mName, global);
    106 }
    107 
    108 }  // namespace mozilla::dom