Bug 1612510 - Remove IsChromeOrXBL*. r=bzbarsky

XBL is no longer a thing... Also, should we rename AllowContentXBLScope?

Differential Revision: https://phabricator.services.mozilla.com/D61359

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Emilio Cobos Álvarez 2020-02-04 21:28:57 +00:00
Родитель 2727cf28b8
Коммит 322cec0c5e
33 изменённых файлов: 66 добавлений и 114 удалений

Просмотреть файл

@ -1259,8 +1259,7 @@ nsScriptSecurityManager::PrincipalWithOA(
return NS_ERROR_INVALID_ARG;
}
RefPtr<ContentPrincipal> copy = new ContentPrincipal();
ContentPrincipal* contentPrincipal =
static_cast<ContentPrincipal*>(aPrincipal);
auto* contentPrincipal = static_cast<ContentPrincipal*>(aPrincipal);
nsresult rv = copy->Init(contentPrincipal, attrs);
NS_ENSURE_SUCCESS(rv, rv);
copy.forget(aReturnPrincipal);

Просмотреть файл

@ -35,7 +35,6 @@ void IntlUtils::GetDisplayNames(const Sequence<nsString>& aLocales,
DisplayNameResult& aResult,
ErrorResult& aError) {
MOZ_ASSERT(nsContentUtils::IsCallerChrome() ||
nsContentUtils::IsCallerContentXBL() ||
nsContentUtils::IsCallerUAWidget());
nsCOMPtr<mozIMozIntl> mozIntl = do_GetService("@mozilla.org/mozintl;1");
@ -90,7 +89,6 @@ void IntlUtils::GetDisplayNames(const Sequence<nsString>& aLocales,
void IntlUtils::GetLocaleInfo(const Sequence<nsString>& aLocales,
LocaleInfo& aResult, ErrorResult& aError) {
MOZ_ASSERT(nsContentUtils::IsCallerChrome() ||
nsContentUtils::IsCallerContentXBL() ||
nsContentUtils::IsCallerUAWidget());
nsCOMPtr<mozIMozIntl> mozIntl = do_GetService("@mozilla.org/mozintl;1");

Просмотреть файл

@ -2141,24 +2141,6 @@ bool nsContentUtils::ThreadsafeIsCallerChrome() {
: IsCurrentThreadRunningChromeWorker();
}
bool nsContentUtils::IsCallerContentXBL() {
JSContext* cx = GetCurrentJSContext();
if (!cx) return false;
JS::Realm* realm = JS::GetCurrentRealmOrNull(cx);
if (!realm) return false;
// For remote XUL, we run XBL in the XUL scope. Given that we care about
// compat and not security for remote XUL, just always claim to be XBL.
if (!xpc::AllowContentXBLScope(realm)) {
MOZ_ASSERT(
nsContentUtils::AllowXULXBLForPrincipal(xpc::GetRealmPrincipal(realm)));
return true;
}
return false;
}
bool nsContentUtils::IsCallerUAWidget() {
JSContext* cx = GetCurrentJSContext();
if (!cx) {
@ -6001,7 +5983,7 @@ bool nsContentUtils::CheckMayLoad(nsIPrincipal* aPrincipal,
/* static */
bool nsContentUtils::CanAccessNativeAnon() {
return LegacyIsCallerChromeOrNativeCode() || IsCallerContentXBL();
return LegacyIsCallerChromeOrNativeCode();
}
/* static */

Просмотреть файл

@ -224,7 +224,6 @@ class nsContentUtils {
static bool IsCallerChrome();
static bool ThreadsafeIsCallerChrome();
static bool IsCallerContentXBL();
static bool IsCallerUAWidget();
static bool IsFuzzingEnabled()
#ifndef FUZZING

Просмотреть файл

@ -2605,9 +2605,9 @@ nsNPAPIPluginInstance* nsObjectLoadingContent::ScriptRequestPluginInstance(
// sort out what the SetupProtoChain callers look like.
MOZ_ASSERT_IF(nsContentUtils::GetCurrentJSContext(),
aCx == nsContentUtils::GetCurrentJSContext());
// FIXME(emilio): Doesn't account for UA widgets, but probably doesn't matter?
bool callerIsContentJS = (nsContentUtils::GetCurrentJSContext() &&
!nsContentUtils::IsCallerChrome() &&
!nsContentUtils::IsCallerContentXBL());
!nsContentUtils::IsCallerChrome());
nsCOMPtr<nsIContent> thisContent =
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));

Просмотреть файл

@ -100,14 +100,14 @@ class Configuration(DescriptorProvider):
iface = thing
if not iface.isExternal():
if not (iface.getExtendedAttribute("ChromeOnly") or
iface.getExtendedAttribute("Func") == ["IsChromeOrXBL"] or
iface.getExtendedAttribute("Func") == ["nsContentUtils::IsCallerChromeOrFuzzingEnabled"] or
not iface.hasInterfaceObject() or
isInWebIDLRoot(iface.filename())):
raise TypeError(
"Interfaces which are exposed to the web may only be "
"defined in a DOM WebIDL root %r. Consider marking "
"the interface [ChromeOnly] or [Func='IsChromeOrXBL'] "
"the interface [ChromeOnly] or "
"[Func='nsContentUtils::IsCallerChromeOrFuzzingEnabled'] "
"if you do not want it exposed to the web.\n"
"%s" %
(webRoots, iface.location))

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -6,7 +6,7 @@
interface nsIDocShell;
interface nsIWebNavigation;
[Func="IsChromeOrXBL",
[ChromeOnly,
Exposed=Window]
interface XULFrameElement : XULElement
{

Просмотреть файл

@ -1,11 +1,10 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
[Func="IsChromeOrXBL",
[ChromeOnly,
Exposed=Window]
interface XULMenuElement : XULElement {
[HTMLConstructor] constructor();

Просмотреть файл

@ -1,11 +1,10 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
[Func="IsChromeOrXBL",
[ChromeOnly,
Exposed=Window]
interface XULTextElement : XULElement {
[HTMLConstructor] constructor();

Просмотреть файл

@ -13,7 +13,7 @@ dictionary TreeCellInfo {
DOMString childElt = "";
};
[Func="IsChromeOrXBL",
[ChromeOnly,
Exposed=Window]
interface XULTreeElement : XULElement
{

Просмотреть файл

@ -4,7 +4,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
[Func="IsChromeOrXBL",
[ChromeOnly,
Exposed=Window]
interface ChromeNodeList : NodeList {
constructor();

Просмотреть файл

@ -4,8 +4,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
[Func="IsChromeOrXBL",
Exposed=Window]
[ChromeOnly, Exposed=Window]
interface CommandEvent : Event {
readonly attribute DOMString? command;
};

Просмотреть файл

@ -44,7 +44,7 @@ interface DOMParser {
// Can be used to allow a DOMParser to load DTDs from URLs that
// normally would not be allowed based on the document principal.
[Func="IsChromeOrXBLOrUAWidget"]
void forceEnableDTD();
[Func="IsChromeOrUAWidget"]
void forceEnableDTD();
};

Просмотреть файл

@ -197,7 +197,7 @@ partial interface Document {
* True if this document is synthetic : stand alone image, video, audio file,
* etc.
*/
[Func="IsChromeOrXBLOrUAWidget"] readonly attribute boolean mozSyntheticDocument;
[Func="IsChromeOrUAWidget"] readonly attribute boolean mozSyntheticDocument;
/**
* Returns the script element whose script is currently being processed.
*
@ -379,7 +379,7 @@ partial interface Document {
// Mozilla extensions of various sorts
partial interface Document {
// Creates a new XUL element regardless of the document's default type.
[CEReactions, NewObject, Throws, Func="IsChromeOrXBL"]
[ChromeOnly, CEReactions, NewObject, Throws]
Element createXULElement(DOMString localName, optional (ElementCreationOptions or DOMString) options = {});
// Wether the document was loaded using a nsXULPrototypeDocument.
[ChromeOnly]

Просмотреть файл

@ -14,7 +14,7 @@
dictionary EventListenerOptions {
boolean capture = false;
/* Setting to true make the listener be added to the system group. */
[Func="ThreadSafeIsChromeOrXBLOrUAWidget"]
[Func="ThreadSafeIsChromeOrUAWidget"]
boolean mozSystemGroup = false;
};

Просмотреть файл

@ -201,13 +201,13 @@ interface mixin MozEditableElement {
// This is set to true if "input" event should be fired with InputEvent on
// the element. Otherwise, i.e., if "input" event should be fired with
// Event, set to false.
[Func="IsChromeOrXBLOrUAWidget"]
[ChromeOnly]
readonly attribute boolean isInputEventTarget;
// This is similar to set .value on nsIDOMInput/TextAreaElements, but handling
// of the value change is closer to the normal user input, so 'change' event
// for example will be dispatched when focusing out the element.
[Func="IsChromeOrXBLOrUAWidget", NeedsSubjectPrincipal]
[Func="IsChromeOrUAWidget", NeedsSubjectPrincipal]
void setUserInput(DOMString input);
};
@ -264,26 +264,26 @@ partial interface HTMLInputElement {
BinaryName="getMaximumAsDouble"]
double getMaximum();
[Pref="dom.forms.datetime", Func="IsChromeOrXBLOrUAWidget"]
[Pref="dom.forms.datetime", Func="IsChromeOrUAWidget"]
void openDateTimePicker(optional DateTimeValue initialValue = {});
[Pref="dom.forms.datetime", Func="IsChromeOrXBLOrUAWidget"]
[Pref="dom.forms.datetime", Func="IsChromeOrUAWidget"]
void updateDateTimePicker(optional DateTimeValue value = {});
[Pref="dom.forms.datetime", Func="IsChromeOrXBLOrUAWidget"]
[Pref="dom.forms.datetime", Func="IsChromeOrUAWidget"]
void closeDateTimePicker();
[Pref="dom.forms.datetime", Func="IsChromeOrXBLOrUAWidget"]
[Pref="dom.forms.datetime", Func="IsChromeOrUAWidget"]
void setFocusState(boolean aIsFocused);
[Pref="dom.forms.datetime", Func="IsChromeOrXBLOrUAWidget"]
[Pref="dom.forms.datetime", Func="IsChromeOrUAWidget"]
void updateValidityState();
[Pref="dom.forms.datetime", Func="IsChromeOrXBLOrUAWidget",
[Pref="dom.forms.datetime", Func="IsChromeOrUAWidget",
BinaryName="getStepAsDouble"]
double getStep();
[Pref="dom.forms.datetime", Func="IsChromeOrXBLOrUAWidget",
[Pref="dom.forms.datetime", Func="IsChromeOrUAWidget",
BinaryName="getStepBaseAsDouble"]
double getStepBase();
};

Просмотреть файл

@ -116,8 +116,8 @@ partial interface HTMLMediaElement {
attribute boolean mozPreservesPitch;
// NB: for internal use with the video controls:
[Func="IsChromeOrXBLOrUAWidget"] attribute boolean mozAllowCasting;
[Func="IsChromeOrXBLOrUAWidget"] attribute boolean mozIsCasting;
[Func="IsChromeOrUAWidget"] attribute boolean mozAllowCasting;
[Func="IsChromeOrUAWidget"] attribute boolean mozIsCasting;
// Mozilla extension: stream capture
[Throws]

Просмотреть файл

@ -50,10 +50,10 @@ partial interface HTMLVideoElement {
// Attributes for builtin video controls to lock screen orientation.
// True if video controls should lock orientation when fullscreen.
[Pref="media.videocontrols.lock-video-orientation", Func="IsChromeOrXBLOrUAWidget"]
[Pref="media.videocontrols.lock-video-orientation", Func="IsChromeOrUAWidget"]
readonly attribute boolean mozOrientationLockEnabled;
// True if screen orientation is locked by video controls.
[Pref="media.videocontrols.lock-video-orientation", Func="IsChromeOrXBLOrUAWidget"]
[Pref="media.videocontrols.lock-video-orientation", Func="IsChromeOrUAWidget"]
attribute boolean mozIsOrientationLocked;
// Clones the frames playing in this <video> to the target. Cloning ends
@ -63,17 +63,17 @@ partial interface HTMLVideoElement {
// installed in this <video>'s MediaDecoder, or selected video
// MediaStreamTrack, whichever is available first. Note that it might never
// resolve.
[Throws, Func="IsChromeOrXBLOrUAWidget"]
[Throws, Func="IsChromeOrUAWidget"]
Promise<void> cloneElementVisually(HTMLVideoElement target);
// Stops a <video> from cloning visually. Does nothing if the <video>
// wasn't cloning in the first place.
[Func="IsChromeOrXBLOrUAWidget"]
[Func="IsChromeOrUAWidget"]
void stopCloningElementVisually();
// Returns true if the <video> is being cloned visually to another
// <video> element (see cloneElementVisually).
[Func="IsChromeOrXBLOrUAWidget"]
[Func="IsChromeOrUAWidget"]
readonly attribute boolean isCloningElementVisually;
};

Просмотреть файл

@ -115,7 +115,7 @@ interface Node : EventTarget {
readonly attribute boolean isNativeAnonymous;
// Maybe this would be useful to authors? https://github.com/whatwg/dom/issues/826
[Func="IsChromeOrXBLOrUAWidget", Pure, BinaryName="containingShadow"]
[Func="IsChromeOrUAWidget", Pure, BinaryName="containingShadow"]
readonly attribute ShadowRoot? containingShadowRoot;
// Mozilla devtools-specific stuff

Просмотреть файл

@ -17,10 +17,10 @@ interface mixin ParentNode {
[Pure]
readonly attribute unsigned long childElementCount;
[Func="IsChromeOrXBL"]
[ChromeOnly]
HTMLCollection getElementsByAttribute(DOMString name,
[TreatNullAs=EmptyString] DOMString value);
[Throws, Func="IsChromeOrXBL"]
[ChromeOnly, Throws]
HTMLCollection getElementsByAttributeNS(DOMString? namespaceURI, DOMString name,
[TreatNullAs=EmptyString] DOMString value);

Просмотреть файл

@ -37,10 +37,10 @@ interface ShadowRoot : DocumentFragment
// As such, these methods allow UA widget code to simultaneously create nodes
// and associate them with the UA widget tree, so that the reflectors get
// created in the right scope.
[CEReactions, Throws, Func="IsChromeOrXBLOrUAWidget"]
[CEReactions, Throws, Func="IsChromeOrUAWidget"]
Node importNodeAndAppendChildAt(Node parentNode, Node node, optional boolean deep = false);
[CEReactions, Throws, Func="IsChromeOrXBLOrUAWidget"]
[CEReactions, Throws, Func="IsChromeOrUAWidget"]
Node createElementAndAppendChildAt(Node parentNode, DOMString localName);
// For triggering UA Widget scope in tests.

Просмотреть файл

@ -102,7 +102,7 @@
* consuming events.
*/
[Func="IsChromeOrXBL",
[ChromeOnly,
Exposed=Window]
interface SimpleGestureEvent : MouseEvent
{

Просмотреть файл

@ -2,8 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
[Func="IsChromeOrXBL",
Exposed=Window]
[ChromeOnly, Exposed=Window]
interface TreeColumn {
readonly attribute Element element;

Просмотреть файл

@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
[Func="IsChromeOrXBL",
Exposed=Window]
[ChromeOnly,
Exposed=Window]
interface TreeColumns {
/**
* The tree widget for these columns.

Просмотреть файл

@ -1,9 +1,9 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
[Func="IsChromeOrXBL",
[ChromeOnly,
Exposed=Window]
interface TreeContentView
{

Просмотреть файл

@ -696,7 +696,7 @@ partial interface Window {
[Throws, Func="nsGlobalWindowInner::IsPrivilegedChromeWindow"]
Promise<any> promiseDocumentFlushed(PromiseDocumentFlushedCallback callback);
[Func="IsChromeOrXBL"]
[ChromeOnly]
readonly attribute boolean isChromeWindow;
};
@ -751,7 +751,7 @@ partial interface Window {
*
* Example: ["en-US", "de", "pl", "sr-Cyrl", "zh-Hans-HK"]
*/
[Func="IsChromeOrXBLOrUAWidget"]
[Func="IsChromeOrUAWidget"]
sequence<DOMString> getRegionalPrefsLocales();
/**
@ -768,14 +768,14 @@ partial interface Window {
*
* Example: ["en-US"]
*/
[Func="IsChromeOrXBLOrUAWidget"]
[Func="IsChromeOrUAWidget"]
sequence<DOMString> getWebExposedLocales();
/**
* Getter funcion for IntlUtils, which provides helper functions for
* localization.
*/
[Throws, Func="IsChromeOrXBLOrUAWidget"]
[Throws, Func="IsChromeOrUAWidget"]
readonly attribute IntlUtils intlUtils;
};

Просмотреть файл

@ -8,7 +8,7 @@
* This interface is supported by command events, which are dispatched to
* XUL elements as a result of mouse or keyboard activation.
*/
[Func="IsChromeOrXBL",
[ChromeOnly,
Exposed=Window]
interface XULCommandEvent : UIEvent
{

Просмотреть файл

@ -6,7 +6,7 @@
interface XULControllers;
[Func="IsChromeOrXBL",
[ChromeOnly,
Exposed=Window]
interface XULElement : Element {
[HTMLConstructor] constructor();

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -20,7 +20,7 @@ dictionary OpenPopupOptions {
typedef (DOMString or OpenPopupOptions) StringOrOpenPopupOptions;
[Func="IsChromeOrXBL",
[ChromeOnly,
Exposed=Window]
interface XULPopupElement : XULElement
{

Просмотреть файл

@ -83,8 +83,11 @@ XPCWrappedNativeScope::XPCWrappedNativeScope(JS::Compartment* aCompartment,
// remote XUL domains, _except_ if we have an additional pref override set.
//
// Note that we can't quite remove this yet, even though we never actually
// use XBL scopes, because some code (including the security manager) uses
// this boolean to make decisions that we rely on in our test infrastructure.
// use XBL scopes, because the security manager uses this boolean to make
// decisions that we rely on in our test infrastructure.
//
// FIXME(emilio): Now that the security manager is the only caller probably
// should be renamed, but what's a good name for this?
mAllowContentXBLScope = !RemoteXULForbidsXBLScope(aFirstGlobal);
}

Просмотреть файл

@ -1093,19 +1093,13 @@ bool IsXrayWrapper(JSObject* obj) { return WrapperFactory::IsXrayWrapper(obj); }
namespace mozilla {
namespace dom {
bool IsChromeOrXBL(JSContext* cx, JSObject* /* unused */) {
bool IsChromeOrUAWidget(JSContext* cx, JSObject* /* unused */) {
MOZ_ASSERT(NS_IsMainThread());
JS::Realm* realm = JS::GetCurrentRealmOrNull(cx);
MOZ_ASSERT(realm);
JS::Compartment* c = JS::GetCompartmentForRealm(realm);
// For remote XUL, we run XBL in the XUL scope. Given that we care about
// compat and not security for remote XUL, we just always claim to be XBL.
//
// Note that, for performance, we don't check AllowXULXBLForPrincipal here,
// and instead rely on the fact that AllowContentXBLScope() only returns false
// in remote XUL situations.
return AccessCheck::isChrome(c) || !AllowContentXBLScope(realm);
return AccessCheck::isChrome(c) || IsUAWidgetCompartment(c);
}
bool IsNotUAWidget(JSContext* cx, JSObject* /* unused */) {
@ -1117,24 +1111,11 @@ bool IsNotUAWidget(JSContext* cx, JSObject* /* unused */) {
return !IsUAWidgetCompartment(c);
}
bool IsChromeOrXBLOrUAWidget(JSContext* cx, JSObject* /* unused */) {
if (IsChromeOrXBL(cx, nullptr)) {
return true;
}
MOZ_ASSERT(NS_IsMainThread());
JS::Realm* realm = JS::GetCurrentRealmOrNull(cx);
MOZ_ASSERT(realm);
JS::Compartment* c = JS::GetCompartmentForRealm(realm);
return IsUAWidgetCompartment(c);
}
extern bool IsCurrentThreadRunningChromeWorker();
bool ThreadSafeIsChromeOrXBLOrUAWidget(JSContext* cx, JSObject* obj) {
bool ThreadSafeIsChromeOrUAWidget(JSContext* cx, JSObject* obj) {
if (NS_IsMainThread()) {
return IsChromeOrXBLOrUAWidget(cx, obj);
return IsChromeOrUAWidget(cx, obj);
}
return IsCurrentThreadRunningChromeWorker();
}

Просмотреть файл

@ -743,12 +743,6 @@ bool AppendCrossOriginWhitelistedPropNames(JSContext* cx,
namespace mozilla {
namespace dom {
/**
* A test for whether WebIDL methods that should only be visible to
* chrome or XBL scopes should be exposed.
*/
bool IsChromeOrXBL(JSContext* cx, JSObject* /* unused */);
/**
* This is used to prevent UA widget code from directly creating and adopting
* nodes via the content document, since they should use the special
@ -760,12 +754,12 @@ bool IsNotUAWidget(JSContext* cx, JSObject* /* unused */);
* A test for whether WebIDL methods that should only be visible to
* chrome, XBL scopes, or UA Widget scopes.
*/
bool IsChromeOrXBLOrUAWidget(JSContext* cx, JSObject* /* unused */);
bool IsChromeOrUAWidget(JSContext* cx, JSObject* /* unused */);
/**
* Same as IsChromeOrXBLOrUAWidget but can be used in worker threads as well.
* Same as IsChromeOrUAWidget but can be used in worker threads as well.
*/
bool ThreadSafeIsChromeOrXBLOrUAWidget(JSContext* cx, JSObject* obj);
bool ThreadSafeIsChromeOrUAWidget(JSContext* cx, JSObject* obj);
} // namespace dom

Просмотреть файл

@ -45,7 +45,7 @@ The sandboxes created for UA Widgets are per-origin and set to the expanded prin
While the closed shadow root technically prevents content from accessing the contents, we want a stronger guarantee to protect against accidental leakage of references to the UA Widget shadow tree into content script. Access to the UA Widget DOM is restricted by having their reflectors set in the UA Widgets scope, as opposed to the normal scope. To accomplish this, we avoid having any script (UA Widget script included) getting a hold of the reference of any created DOM element before appending to the Shadow DOM. Once the element is in the Shadow DOM, the binding mechanism will put the reflector in the desired scope as it is being accessed.
To avoid creating reflectors before DOM insertion, the available DOM interfaces is limited. For example, instead of ``createElement()`` and ``appendChild()``, the script would have to call ``createElementAndAppendChildAt()`` available on the UA Widget Shadow Root instance, to avoid receiving a reference to the DOM element and thus triggering the creation of its reflector in the wrong scope, before the element is properly associated with the UA Widget shadow tree. To find out the differences, search for ``Func="IsChromeOrXBLOrUAWidget"`` and ``Func="IsNotUAWidget"`` in in-tree WebIDL files.
To avoid creating reflectors before DOM insertion, the available DOM interfaces are limited. For example, instead of ``createElement()`` and ``appendChild()``, the script would have to call ``createElementAndAppendChildAt()`` available on the UA Widget Shadow Root instance, to avoid receiving a reference to the DOM element and thus triggering the creation of its reflector in the wrong scope, before the element is properly associated with the UA Widget shadow tree. To find out the differences, search for ``Func="IsChromeOrUAWidget"`` and ``Func="IsNotUAWidget"`` in in-tree WebIDL files.
Other things to watch out for
-----------------------------