tor-browser

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

HTMLEmbedElement.cpp (8975B)


      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/HTMLEmbedElement.h"
      8 
      9 #include "mozilla/dom/BindContext.h"
     10 #include "mozilla/dom/Document.h"
     11 #include "mozilla/dom/ElementInlines.h"
     12 #include "mozilla/dom/HTMLEmbedElementBinding.h"
     13 #include "nsContentUtils.h"
     14 #include "nsFrameLoader.h"
     15 #include "nsIWidget.h"
     16 #include "nsObjectLoadingContent.h"
     17 #include "nsThreadUtils.h"
     18 #ifdef XP_MACOSX
     19 #  include "mozilla/EventDispatcher.h"
     20 #  include "mozilla/dom/Event.h"
     21 #endif
     22 
     23 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Embed)
     24 
     25 namespace mozilla::dom {
     26 
     27 HTMLEmbedElement::HTMLEmbedElement(
     28    already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
     29    FromParser aFromParser)
     30    : nsGenericHTMLElement(std::move(aNodeInfo)) {
     31  SetIsNetworkCreated(aFromParser == FROM_PARSER_NETWORK);
     32 }
     33 
     34 HTMLEmbedElement::~HTMLEmbedElement() = default;
     35 
     36 NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLEmbedElement)
     37 
     38 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLEmbedElement,
     39                                                  nsGenericHTMLElement)
     40  nsObjectLoadingContent::Traverse(tmp, cb);
     41 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     42 
     43 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLEmbedElement,
     44                                                nsGenericHTMLElement)
     45  nsObjectLoadingContent::Unlink(tmp);
     46 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     47 
     48 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(
     49    HTMLEmbedElement, nsGenericHTMLElement, nsIRequestObserver,
     50    nsIStreamListener, nsFrameLoaderOwner, nsIObjectLoadingContent,
     51    nsIChannelEventSink)
     52 
     53 NS_IMPL_ELEMENT_CLONE(HTMLEmbedElement)
     54 
     55 nsresult HTMLEmbedElement::BindToTree(BindContext& aContext, nsINode& aParent) {
     56  nsresult rv = nsGenericHTMLElement::BindToTree(aContext, aParent);
     57  NS_ENSURE_SUCCESS(rv, rv);
     58 
     59  if (IsInComposedDoc()) {
     60    void (HTMLEmbedElement::*start)() = &HTMLEmbedElement::StartObjectLoad;
     61    nsContentUtils::AddScriptRunner(
     62        NewRunnableMethod("dom::HTMLEmbedElement::BindToTree", this, start));
     63  }
     64 
     65  return NS_OK;
     66 }
     67 
     68 void HTMLEmbedElement::UnbindFromTree(UnbindContext& aContext) {
     69  nsObjectLoadingContent::UnbindFromTree();
     70  nsGenericHTMLElement::UnbindFromTree(aContext);
     71 }
     72 
     73 void HTMLEmbedElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
     74                                    const nsAttrValue* aValue,
     75                                    const nsAttrValue* aOldValue,
     76                                    nsIPrincipal* aSubjectPrincipal,
     77                                    bool aNotify) {
     78  if (aValue) {
     79    AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
     80  }
     81 
     82  if (aName == nsGkAtoms::src) {
     83    RefreshFeaturePolicy();
     84  }
     85 
     86  if (aNamespaceID == kNameSpaceID_None &&
     87      aName == nsGkAtoms::allowfullscreen && mFrameLoader) {
     88    if (auto* bc = mFrameLoader->GetExtantBrowsingContext()) {
     89      MOZ_ALWAYS_SUCCEEDS(bc->SetFullscreenAllowedByOwner(AllowFullscreen()));
     90    }
     91  }
     92 
     93  return nsGenericHTMLElement::AfterSetAttr(
     94      aNamespaceID, aName, aValue, aOldValue, aSubjectPrincipal, aNotify);
     95 }
     96 
     97 void HTMLEmbedElement::OnAttrSetButNotChanged(int32_t aNamespaceID,
     98                                              nsAtom* aName,
     99                                              const nsAttrValueOrString& aValue,
    100                                              bool aNotify) {
    101  AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
    102  return nsGenericHTMLElement::OnAttrSetButNotChanged(aNamespaceID, aName,
    103                                                      aValue, aNotify);
    104 }
    105 
    106 void HTMLEmbedElement::AfterMaybeChangeAttr(int32_t aNamespaceID, nsAtom* aName,
    107                                            bool aNotify) {
    108  if (aNamespaceID != kNameSpaceID_None || aName != nsGkAtoms::src) {
    109    return;
    110  }
    111  // If aNotify is false, we are coming from the parser or some such place;
    112  // we'll get bound after all the attributes have been set, so we'll do the
    113  // object load from BindToTree.
    114  // Skip the LoadObject call in that case.
    115  // We also don't want to start loading the object when we're not yet in
    116  // a document, just in case that the caller wants to set additional
    117  // attributes before inserting the node into the document.
    118  if (!aNotify || !IsInComposedDoc() || BlockEmbedOrObjectContentLoading()) {
    119    return;
    120  }
    121  nsContentUtils::AddScriptRunner(NS_NewRunnableFunction(
    122      "HTMLEmbedElement::LoadObject",
    123      [self = RefPtr<HTMLEmbedElement>(this), aNotify]() {
    124        if (self->IsInComposedDoc()) {
    125          self->LoadObject(aNotify, true);
    126        }
    127      }));
    128 }
    129 
    130 int32_t HTMLEmbedElement::TabIndexDefault() {
    131  // Only when we loaded a sub-document, <embed> should be tabbable by default
    132  // because it's a navigable containers mentioned in 6.6.3 The tabindex
    133  // attribute in the standard (see "If the value is null" section).
    134  // https://html.spec.whatwg.org/#the-tabindex-attribute
    135  // Otherwise, the default tab-index of <embed> is expected as -1 in a WPT:
    136  // https://searchfox.org/mozilla-central/rev/7d98e651953f3135d91e98fa6d33efa131aec7ea/testing/web-platform/tests/html/interaction/focus/sequential-focus-navigation-and-the-tabindex-attribute/tabindex-getter.html#63
    137  return Type() == ObjectType::Document ? 0 : -1;
    138 }
    139 
    140 bool HTMLEmbedElement::IsHTMLFocusable(IsFocusableFlags aFlags,
    141                                       bool* aIsFocusable, int32_t* aTabIndex) {
    142  // Has non-plugin content: let the plugin decide what to do in terms of
    143  // internal focus from mouse clicks
    144  if (aTabIndex) {
    145    *aTabIndex = TabIndex();
    146  }
    147 
    148  *aIsFocusable = true;
    149 
    150  // Let the plugin decide, so override.
    151  return true;
    152 }
    153 
    154 bool HTMLEmbedElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
    155                                      const nsAString& aValue,
    156                                      nsIPrincipal* aMaybeScriptedPrincipal,
    157                                      nsAttrValue& aResult) {
    158  if (aNamespaceID == kNameSpaceID_None) {
    159    if (aAttribute == nsGkAtoms::align) {
    160      return ParseAlignValue(aValue, aResult);
    161    }
    162    if (aAttribute == nsGkAtoms::width || aAttribute == nsGkAtoms::height ||
    163        aAttribute == nsGkAtoms::hspace || aAttribute == nsGkAtoms::vspace) {
    164      return aResult.ParseHTMLDimension(aValue);
    165    }
    166  }
    167 
    168  return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
    169                                              aMaybeScriptedPrincipal, aResult);
    170 }
    171 
    172 static void MapAttributesIntoRuleBase(MappedDeclarationsBuilder& aBuilder) {
    173  nsGenericHTMLElement::MapImageMarginAttributeInto(aBuilder);
    174  nsGenericHTMLElement::MapImageSizeAttributesInto(aBuilder);
    175  nsGenericHTMLElement::MapImageAlignAttributeInto(aBuilder);
    176 }
    177 
    178 static void MapAttributesIntoRuleExceptHidden(
    179    MappedDeclarationsBuilder& aBuilder) {
    180  MapAttributesIntoRuleBase(aBuilder);
    181  nsGenericHTMLElement::MapCommonAttributesIntoExceptHidden(aBuilder);
    182 }
    183 
    184 void HTMLEmbedElement::MapAttributesIntoRule(
    185    MappedDeclarationsBuilder& aBuilder) {
    186  MapAttributesIntoRuleBase(aBuilder);
    187  nsGenericHTMLElement::MapCommonAttributesInto(aBuilder);
    188 }
    189 
    190 NS_IMETHODIMP_(bool)
    191 HTMLEmbedElement::IsAttributeMapped(const nsAtom* aAttribute) const {
    192  static const MappedAttributeEntry* const map[] = {
    193      sCommonAttributeMap,
    194      sImageMarginSizeAttributeMap,
    195      sImageBorderAttributeMap,
    196      sImageAlignAttributeMap,
    197  };
    198 
    199  return FindAttributeDependence(aAttribute, map);
    200 }
    201 
    202 nsMapRuleToAttributesFunc HTMLEmbedElement::GetAttributeMappingFunction()
    203    const {
    204  return &MapAttributesIntoRuleExceptHidden;
    205 }
    206 
    207 void HTMLEmbedElement::StartObjectLoad(bool aNotify, bool aForceLoad) {
    208  // BindToTree can call us asynchronously, and we may be removed from the tree
    209  // in the interim
    210  if (!IsInComposedDoc() || !OwnerDoc()->IsActive() ||
    211      BlockEmbedOrObjectContentLoading()) {
    212    return;
    213  }
    214 
    215  LoadObject(aNotify, aForceLoad);
    216  SetIsNetworkCreated(false);
    217 }
    218 
    219 uint32_t HTMLEmbedElement::GetCapabilities() const {
    220  return eAllowPluginSkipChannel | eSupportImages | eSupportDocuments;
    221 }
    222 
    223 void HTMLEmbedElement::DestroyContent() {
    224  nsObjectLoadingContent::Destroy();
    225  nsGenericHTMLElement::DestroyContent();
    226 }
    227 
    228 nsresult HTMLEmbedElement::CopyInnerTo(HTMLEmbedElement* aDest) {
    229  nsresult rv = nsGenericHTMLElement::CopyInnerTo(aDest);
    230  NS_ENSURE_SUCCESS(rv, rv);
    231 
    232  if (aDest->OwnerDoc()->IsStaticDocument()) {
    233    CreateStaticClone(aDest);
    234  }
    235 
    236  return rv;
    237 }
    238 
    239 JSObject* HTMLEmbedElement::WrapNode(JSContext* aCx,
    240                                     JS::Handle<JSObject*> aGivenProto) {
    241  return HTMLEmbedElement_Binding::Wrap(aCx, this, aGivenProto);
    242 }
    243 
    244 nsContentPolicyType HTMLEmbedElement::GetContentPolicyType() const {
    245  return nsIContentPolicy::TYPE_INTERNAL_EMBED;
    246 }
    247 
    248 }  // namespace mozilla::dom