mirror of
https://github.com/Feodor2/Mypal68.git
synced 2025-06-18 14:55:44 -04:00
68.14.8 - dom
This commit is contained in:
parent
f9bcc75aaf
commit
4efeab7ecb
@ -44,11 +44,6 @@ const gMozillaSpecificProperties = {
|
||||
from: "1",
|
||||
to: "0"
|
||||
},
|
||||
"-moz-stack-sizing": {
|
||||
// https://developer.mozilla.org/en/docs/Web/CSS/-moz-stack-sizing
|
||||
from: "ignore",
|
||||
to: "stretch-to-fit"
|
||||
},
|
||||
"-moz-text-size-adjust": {
|
||||
// https://drafts.csswg.org/css-size-adjust/#propdef-text-size-adjust
|
||||
from: "none",
|
||||
|
@ -41,9 +41,6 @@ const testcases = [
|
||||
property: "-moz-osx-font-smoothing",
|
||||
pref: "layout.css.osx-font-smoothing.enabled"
|
||||
},
|
||||
{
|
||||
property: "-moz-stack-sizing"
|
||||
},
|
||||
{
|
||||
property: "-moz-text-size-adjust"
|
||||
},
|
||||
|
@ -28,8 +28,6 @@ mozilla::LazyLogModule gAudioChannelLog("AudioChannel");
|
||||
|
||||
namespace {
|
||||
|
||||
bool sAudioChannelCompeting = false;
|
||||
bool sAudioChannelCompetingAllAgents = false;
|
||||
bool sXPCOMShuttingDown = false;
|
||||
|
||||
class NotifyChannelActiveRunnable final : public Runnable {
|
||||
@ -117,20 +115,6 @@ class AudioPlaybackRunnable final : public Runnable {
|
||||
AudioChannelService::AudibleChangedReasons mReason;
|
||||
};
|
||||
|
||||
bool IsEnableAudioCompetingForAllAgents() {
|
||||
// In general, the audio competing should only be for audible media and it
|
||||
// helps user can focus on one media at the same time. However, we hope to
|
||||
// treat all media as the same in the mobile device. First reason is we have
|
||||
// media control on fennec and we just want to control one media at once time.
|
||||
// Second reason is to reduce the bandwidth, avoiding to play any non-audible
|
||||
// media in background which user doesn't notice about.
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
return true;
|
||||
#else
|
||||
return sAudioChannelCompetingAllAgents;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace mozilla {
|
||||
@ -250,12 +234,6 @@ void AudioChannelService::Shutdown() {
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool AudioChannelService::IsEnableAudioCompeting() {
|
||||
CreateServiceIfNeeded();
|
||||
return sAudioChannelCompeting;
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(AudioChannelService)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
@ -270,11 +248,6 @@ AudioChannelService::AudioChannelService() {
|
||||
obs->AddObserver(this, "xpcom-shutdown", false);
|
||||
obs->AddObserver(this, "outer-window-destroyed", false);
|
||||
}
|
||||
|
||||
Preferences::AddBoolVarCache(&sAudioChannelCompeting,
|
||||
"dom.audiochannel.audioCompeting");
|
||||
Preferences::AddBoolVarCache(&sAudioChannelCompetingAllAgents,
|
||||
"dom.audiochannel.audioCompeting.allAgents");
|
||||
}
|
||||
|
||||
AudioChannelService::~AudioChannelService() {}
|
||||
@ -334,9 +307,6 @@ AudioPlaybackConfig AudioChannelService::GetMediaConfig(
|
||||
if (winData) {
|
||||
config.mVolume *= winData->mConfig.mVolume;
|
||||
config.mMuted = config.mMuted || winData->mConfig.mMuted;
|
||||
config.mSuspend = winData->mOwningAudioFocus
|
||||
? config.mSuspend
|
||||
: nsISuspendedTypes::SUSPENDED_STOP_DISPOSABLE;
|
||||
config.mCapturedAudio = winData->mIsAudioCaptured;
|
||||
}
|
||||
|
||||
@ -532,20 +502,6 @@ bool AudioChannelService::IsWindowActive(nsPIDOMWindowOuter* aWindow) {
|
||||
return !winData->mAudibleAgents.IsEmpty();
|
||||
}
|
||||
|
||||
void AudioChannelService::RefreshAgentsAudioFocusChanged(
|
||||
AudioChannelAgent* aAgent) {
|
||||
MOZ_ASSERT(aAgent);
|
||||
|
||||
nsTObserverArray<nsAutoPtr<AudioChannelWindow>>::ForwardIterator iter(
|
||||
mWindows);
|
||||
while (iter.HasMore()) {
|
||||
AudioChannelWindow* winData = iter.GetNext();
|
||||
if (winData->mOwningAudioFocus) {
|
||||
winData->AudioFocusChanged(aAgent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AudioChannelService::NotifyMediaResumedFromBlock(
|
||||
nsPIDOMWindowOuter* aWindow) {
|
||||
MOZ_ASSERT(aWindow);
|
||||
@ -563,168 +519,13 @@ void AudioChannelService::NotifyMediaResumedFromBlock(
|
||||
winData->NotifyMediaBlockStop(aWindow);
|
||||
}
|
||||
|
||||
void AudioChannelService::AudioChannelWindow::RequestAudioFocus(
|
||||
AudioChannelAgent* aAgent) {
|
||||
MOZ_ASSERT(aAgent);
|
||||
|
||||
// Don't need to check audio focus for window-less agent.
|
||||
if (!aAgent->Window()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We already have the audio focus. No operation is needed.
|
||||
if (mOwningAudioFocus) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only foreground window can request audio focus, but it would still own the
|
||||
// audio focus even it goes to background. Audio focus would be abandoned
|
||||
// only when other foreground window starts audio competing.
|
||||
// One exception is if the pref "media.block-autoplay-until-in-foreground"
|
||||
// is on and the background page is the non-visited before. Because the media
|
||||
// in that page would be blocked until the page is going to foreground.
|
||||
mOwningAudioFocus = (!(aAgent->Window()->IsBackground()) ||
|
||||
aAgent->Window()->GetMediaSuspend() ==
|
||||
nsISuspendedTypes::SUSPENDED_BLOCK);
|
||||
|
||||
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
|
||||
("AudioChannelWindow, RequestAudioFocus, this = %p, "
|
||||
"agent = %p, owning audio focus = %s\n",
|
||||
this, aAgent, mOwningAudioFocus ? "true" : "false"));
|
||||
}
|
||||
|
||||
void AudioChannelService::AudioChannelWindow::NotifyAudioCompetingChanged(
|
||||
AudioChannelAgent* aAgent) {
|
||||
// This function may be called after RemoveAgentAndReduceAgentsNum(), so the
|
||||
// agent may be not contained in mAgent. In addition, the agent would still
|
||||
// be alive because we have kungFuDeathGrip in UnregisterAudioChannelAgent().
|
||||
MOZ_ASSERT(aAgent);
|
||||
|
||||
RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
|
||||
MOZ_ASSERT(service);
|
||||
|
||||
if (!service->IsEnableAudioCompeting()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsAgentInvolvingInAudioCompeting(aAgent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
|
||||
("AudioChannelWindow, NotifyAudioCompetingChanged, this = %p, "
|
||||
"agent = %p\n",
|
||||
this, aAgent));
|
||||
|
||||
service->RefreshAgentsAudioFocusChanged(aAgent);
|
||||
}
|
||||
|
||||
bool AudioChannelService::AudioChannelWindow::IsAgentInvolvingInAudioCompeting(
|
||||
AudioChannelAgent* aAgent) const {
|
||||
MOZ_ASSERT(aAgent);
|
||||
|
||||
if (!mOwningAudioFocus) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsAudioCompetingInSameTab()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO : add MediaSession::ambient kind, because it doens't interact with
|
||||
// other kinds.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AudioChannelService::AudioChannelWindow::IsAudioCompetingInSameTab()
|
||||
const {
|
||||
bool hasMultipleActiveAgents = IsEnableAudioCompetingForAllAgents()
|
||||
? mAgents.Length() > 1
|
||||
: mAudibleAgents.Length() > 1;
|
||||
return mOwningAudioFocus && hasMultipleActiveAgents;
|
||||
}
|
||||
|
||||
void AudioChannelService::AudioChannelWindow::AudioFocusChanged(
|
||||
AudioChannelAgent* aNewPlayingAgent) {
|
||||
// This agent isn't always known for the current window, because it can comes
|
||||
// from other window.
|
||||
MOZ_ASSERT(aNewPlayingAgent);
|
||||
|
||||
if (IsInactiveWindow()) {
|
||||
// These would happen in two situations,
|
||||
// (1) Audio in page A was ended, and another page B want to play audio.
|
||||
// Page A should abandon its focus.
|
||||
// (2) Audio was paused by remote-control, page should still own the focus.
|
||||
mOwningAudioFocus = IsContainingPlayingAgent(aNewPlayingAgent);
|
||||
} else {
|
||||
nsTObserverArray<AudioChannelAgent*>::ForwardIterator iter(
|
||||
IsEnableAudioCompetingForAllAgents() ? mAgents : mAudibleAgents);
|
||||
while (iter.HasMore()) {
|
||||
AudioChannelAgent* agent = iter.GetNext();
|
||||
MOZ_ASSERT(agent);
|
||||
|
||||
// Don't need to update the playing state of new playing agent.
|
||||
if (agent == aNewPlayingAgent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t type = GetCompetingBehavior(agent);
|
||||
|
||||
// If window will be suspended, it needs to abandon the audio focus
|
||||
// because only one window can own audio focus at a time. However, we
|
||||
// would support multiple audio focus at the same time in the future.
|
||||
mOwningAudioFocus = (type == nsISuspendedTypes::NONE_SUSPENDED);
|
||||
|
||||
// TODO : support other behaviors which are definded in MediaSession API.
|
||||
switch (type) {
|
||||
case nsISuspendedTypes::NONE_SUSPENDED:
|
||||
case nsISuspendedTypes::SUSPENDED_STOP_DISPOSABLE:
|
||||
agent->WindowSuspendChanged(type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
|
||||
("AudioChannelWindow, AudioFocusChanged, this = %p, "
|
||||
"OwningAudioFocus = %s\n",
|
||||
this, mOwningAudioFocus ? "true" : "false"));
|
||||
}
|
||||
|
||||
bool AudioChannelService::AudioChannelWindow::IsContainingPlayingAgent(
|
||||
AudioChannelAgent* aAgent) const {
|
||||
return (aAgent->WindowID() == mWindowID);
|
||||
}
|
||||
|
||||
uint32_t AudioChannelService::AudioChannelWindow::GetCompetingBehavior(
|
||||
AudioChannelAgent* aAgent) const {
|
||||
MOZ_ASSERT(aAgent);
|
||||
MOZ_ASSERT(IsEnableAudioCompetingForAllAgents()
|
||||
? mAgents.Contains(aAgent)
|
||||
: mAudibleAgents.Contains(aAgent));
|
||||
|
||||
uint32_t competingBehavior = nsISuspendedTypes::SUSPENDED_STOP_DISPOSABLE;
|
||||
|
||||
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
|
||||
("AudioChannelWindow, GetCompetingBehavior, this = %p, "
|
||||
"behavior = %s\n",
|
||||
this, SuspendTypeToStr(competingBehavior)));
|
||||
|
||||
return competingBehavior;
|
||||
}
|
||||
|
||||
void AudioChannelService::AudioChannelWindow::AppendAgent(
|
||||
AudioChannelAgent* aAgent, AudibleState aAudible) {
|
||||
MOZ_ASSERT(aAgent);
|
||||
|
||||
RequestAudioFocus(aAgent);
|
||||
AppendAgentAndIncreaseAgentsNum(aAgent);
|
||||
AudioAudibleChanged(aAgent, aAudible,
|
||||
AudibleChangedReasons::eDataAudibleChanged);
|
||||
if (IsEnableAudioCompetingForAllAgents() &&
|
||||
aAudible != AudibleState::eAudible) {
|
||||
NotifyAudioCompetingChanged(aAgent);
|
||||
}
|
||||
}
|
||||
|
||||
void AudioChannelService::AudioChannelWindow::RemoveAgent(
|
||||
@ -794,7 +595,6 @@ void AudioChannelService::AudioChannelWindow::AudioAudibleChanged(
|
||||
|
||||
if (aAudible == AudibleState::eAudible) {
|
||||
AppendAudibleAgentIfNotContained(aAgent, aReason);
|
||||
NotifyAudioCompetingChanged(aAgent);
|
||||
} else {
|
||||
RemoveAudibleAgentIfContained(aAgent, aReason);
|
||||
}
|
||||
@ -839,12 +639,6 @@ bool AudioChannelService::AudioChannelWindow::IsLastAudibleAgent() const {
|
||||
return mAudibleAgents.IsEmpty();
|
||||
}
|
||||
|
||||
bool AudioChannelService::AudioChannelWindow::IsInactiveWindow() const {
|
||||
return IsEnableAudioCompetingForAllAgents()
|
||||
? mAudibleAgents.IsEmpty() && mAgents.IsEmpty()
|
||||
: mAudibleAgents.IsEmpty();
|
||||
}
|
||||
|
||||
void AudioChannelService::AudioChannelWindow::NotifyAudioAudibleChanged(
|
||||
nsPIDOMWindowOuter* aWindow, AudibleState aAudible,
|
||||
AudibleChangedReasons aReason) {
|
||||
|
@ -183,10 +183,8 @@ class AudioChannelService final : public nsIObserver {
|
||||
explicit AudioChannelWindow(uint64_t aWindowID)
|
||||
: mWindowID(aWindowID),
|
||||
mIsAudioCaptured(false),
|
||||
mOwningAudioFocus(!AudioChannelService::IsEnableAudioCompeting()),
|
||||
mShouldSendActiveMediaBlockStopEvent(false) {}
|
||||
|
||||
void AudioFocusChanged(AudioChannelAgent* aNewPlayingAgent);
|
||||
void AudioAudibleChanged(AudioChannelAgent* aAgent, AudibleState aAudible,
|
||||
AudibleChangedReasons aReason);
|
||||
|
||||
@ -203,10 +201,6 @@ class AudioChannelService final : public nsIObserver {
|
||||
nsTObserverArray<AudioChannelAgent*> mAgents;
|
||||
nsTObserverArray<AudioChannelAgent*> mAudibleAgents;
|
||||
|
||||
// Owning audio focus when the window starts playing audible sound, and
|
||||
// lose audio focus when other windows starts playing.
|
||||
bool mOwningAudioFocus;
|
||||
|
||||
// If we've dispatched "activeMediaBlockStart" event, we must dispatch
|
||||
// another event "activeMediablockStop" when the window is resumed from
|
||||
// suspend-block.
|
||||
@ -230,18 +224,6 @@ class AudioChannelService final : public nsIObserver {
|
||||
|
||||
void NotifyChannelActive(uint64_t aWindowID, bool aActive);
|
||||
void MaybeNotifyMediaBlockStart(AudioChannelAgent* aAgent);
|
||||
|
||||
void RequestAudioFocus(AudioChannelAgent* aAgent);
|
||||
|
||||
// We need to do audio competing only when the new incoming agent started.
|
||||
void NotifyAudioCompetingChanged(AudioChannelAgent* aAgent);
|
||||
|
||||
uint32_t GetCompetingBehavior(AudioChannelAgent* aAgent) const;
|
||||
bool IsAgentInvolvingInAudioCompeting(AudioChannelAgent* aAgent) const;
|
||||
bool IsAudioCompetingInSameTab() const;
|
||||
bool IsContainingPlayingAgent(AudioChannelAgent* aAgent) const;
|
||||
|
||||
bool IsInactiveWindow() const;
|
||||
};
|
||||
|
||||
AudioChannelWindow* GetOrCreateWindowData(nsPIDOMWindowOuter* aWindow);
|
||||
|
@ -7,7 +7,6 @@
|
||||
#ifndef mozilla_dom_BindContext_h__
|
||||
#define mozilla_dom_BindContext_h__
|
||||
|
||||
#include "nsXBLBinding.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/AutoRestore.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
@ -46,17 +45,9 @@ struct MOZ_STACK_CLASS BindContext final {
|
||||
// Whether our subtree root is changing as a result of this operation.
|
||||
bool SubtreeRootChanges() const { return mSubtreeRootChanges; }
|
||||
|
||||
// Returns the binding parent of the subtree to be inserted.
|
||||
//
|
||||
// This can be null.
|
||||
Element* GetBindingParent() const { return mBindingParent; }
|
||||
|
||||
// This constructor should be used for regular appends to content.
|
||||
explicit BindContext(nsINode& aParent)
|
||||
: mDoc(*aParent.OwnerDoc()),
|
||||
mBindingParent(aParent.IsContent()
|
||||
? aParent.AsContent()->GetBindingParent()
|
||||
: nullptr),
|
||||
mInComposedDoc(aParent.IsInComposedDoc()),
|
||||
mInUncomposedDoc(aParent.IsInUncomposedDoc()),
|
||||
mSubtreeRootChanges(true) {}
|
||||
@ -69,7 +60,6 @@ struct MOZ_STACK_CLASS BindContext final {
|
||||
// This constructor is only meant to be used in that situation.
|
||||
explicit BindContext(ShadowRoot& aShadowRoot)
|
||||
: mDoc(*aShadowRoot.OwnerDoc()),
|
||||
mBindingParent(aShadowRoot.Host()),
|
||||
mInComposedDoc(aShadowRoot.IsInComposedDoc()),
|
||||
mInUncomposedDoc(false),
|
||||
mSubtreeRootChanges(false) {}
|
||||
@ -79,21 +69,12 @@ struct MOZ_STACK_CLASS BindContext final {
|
||||
enum ForNativeAnonymous { ForNativeAnonymous };
|
||||
BindContext(Element& aParentElement, enum ForNativeAnonymous)
|
||||
: mDoc(*aParentElement.OwnerDoc()),
|
||||
mBindingParent(&aParentElement),
|
||||
mInComposedDoc(aParentElement.IsInComposedDoc()),
|
||||
mInUncomposedDoc(aParentElement.IsInUncomposedDoc()),
|
||||
mSubtreeRootChanges(true) {
|
||||
MOZ_ASSERT(mInComposedDoc, "Binding NAC in a disconnected subtree?");
|
||||
}
|
||||
|
||||
// This is meant to be used to bind XBL anonymous content.
|
||||
BindContext(nsXBLBinding& aBinding, Element& aParentElement)
|
||||
: mDoc(*aParentElement.OwnerDoc()),
|
||||
mBindingParent(aBinding.GetBoundElement()),
|
||||
mInComposedDoc(aParentElement.IsInComposedDoc()),
|
||||
mInUncomposedDoc(aParentElement.IsInUncomposedDoc()),
|
||||
mSubtreeRootChanges(true) {}
|
||||
|
||||
private:
|
||||
static bool IsLikelyUndisplayed(const nsINode& aParent) {
|
||||
return aParent.IsAnyOfHTMLElements(nsGkAtoms::style, nsGkAtoms::script);
|
||||
@ -101,8 +82,6 @@ struct MOZ_STACK_CLASS BindContext final {
|
||||
|
||||
Document& mDoc;
|
||||
|
||||
Element* const mBindingParent;
|
||||
|
||||
const bool mInComposedDoc;
|
||||
const bool mInUncomposedDoc;
|
||||
|
||||
|
@ -506,7 +506,7 @@ void BodyConsumer::BeginConsumeBodyMainThread(ThreadSafeWorkerRef* aWorkerRef) {
|
||||
rv = GetBodyLocalFile(getter_AddRefs(file));
|
||||
if (!NS_WARN_IF(NS_FAILED(rv)) && file) {
|
||||
ChromeFilePropertyBag bag;
|
||||
bag.mType = NS_ConvertUTF8toUTF16(mBodyMimeType);
|
||||
CopyUTF8toUTF16(mBodyMimeType, bag.mType);
|
||||
|
||||
ErrorResult error;
|
||||
RefPtr<Promise> promise =
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include "nsChangeHint.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "mozilla/dom/DirectionalityUtils.h"
|
||||
#include "nsBindingManager.h"
|
||||
#include "nsCCUncollectableMarker.h"
|
||||
#include "mozAutoDocUpdate.h"
|
||||
#include "nsTextNode.h"
|
||||
@ -36,6 +35,10 @@
|
||||
#include "nsWindowSizes.h"
|
||||
#include "nsWrapperCacheInlines.h"
|
||||
|
||||
#if defined(ACCESSIBILITY) && defined(DEBUG)
|
||||
# include "nsAccessibilityService.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
@ -396,41 +399,16 @@ nsresult CharacterData::BindToTree(BindContext& aContext, nsINode& aParent) {
|
||||
// only assert if our parent is _changing_ while we have a parent.
|
||||
MOZ_ASSERT(!GetParentNode() || &aParent == GetParentNode(),
|
||||
"Already have a parent. Unbind first!");
|
||||
MOZ_ASSERT(
|
||||
!GetBindingParent() ||
|
||||
aContext.GetBindingParent() == GetBindingParent() ||
|
||||
(!aContext.GetBindingParent() && aParent.IsContent() &&
|
||||
aParent.AsContent()->GetBindingParent() == GetBindingParent()),
|
||||
"Already have a binding parent. Unbind first!");
|
||||
MOZ_ASSERT(!IsRootOfNativeAnonymousSubtree() ||
|
||||
aContext.GetBindingParent() == &aParent,
|
||||
"Native anonymous content must have its parent as its "
|
||||
"own binding parent");
|
||||
MOZ_ASSERT(aContext.GetBindingParent() || !aParent.IsContent() ||
|
||||
aContext.GetBindingParent() ==
|
||||
aParent.AsContent()->GetBindingParent(),
|
||||
"We should be passed the right binding parent");
|
||||
|
||||
// First set the binding parent
|
||||
if (Element* bindingParent = aContext.GetBindingParent()) {
|
||||
ExtendedContentSlots()->mBindingParent = bindingParent;
|
||||
}
|
||||
|
||||
const bool hadParent = !!GetParentNode();
|
||||
|
||||
NS_ASSERTION(!aContext.GetBindingParent() ||
|
||||
IsRootOfNativeAnonymousSubtree() ||
|
||||
!HasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE) ||
|
||||
aParent.IsInNativeAnonymousSubtree(),
|
||||
"Trying to re-bind content from native anonymous subtree to "
|
||||
"non-native anonymous parent!");
|
||||
if (aParent.IsInNativeAnonymousSubtree()) {
|
||||
SetFlags(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE);
|
||||
}
|
||||
if (aParent.HasFlag(NODE_HAS_BEEN_IN_UA_WIDGET)) {
|
||||
SetFlags(NODE_HAS_BEEN_IN_UA_WIDGET);
|
||||
}
|
||||
if (HasFlag(NODE_IS_ANONYMOUS_ROOT)) {
|
||||
if (IsRootOfNativeAnonymousSubtree()) {
|
||||
aParent.SetMayHaveAnonymousChildren();
|
||||
}
|
||||
|
||||
@ -486,8 +464,6 @@ nsresult CharacterData::BindToTree(BindContext& aContext, nsINode& aParent) {
|
||||
MOZ_ASSERT(IsInComposedDoc() == aContext.InComposedDoc());
|
||||
MOZ_ASSERT(IsInUncomposedDoc() == aContext.InUncomposedDoc());
|
||||
MOZ_ASSERT(&aParent == GetParentNode(), "Bound to wrong parent node");
|
||||
MOZ_ASSERT(aContext.GetBindingParent() == GetBindingParent(),
|
||||
"Bound to wrong binding parent");
|
||||
MOZ_ASSERT(aParent.IsInUncomposedDoc() == IsInUncomposedDoc());
|
||||
MOZ_ASSERT(aParent.IsInComposedDoc() == IsInComposedDoc());
|
||||
MOZ_ASSERT(aParent.IsInShadowTree() == IsInShadowTree());
|
||||
@ -501,8 +477,6 @@ void CharacterData::UnbindFromTree(bool aNullParent) {
|
||||
|
||||
HandleShadowDOMRelatedRemovalSteps(aNullParent);
|
||||
|
||||
Document* document = GetComposedDoc();
|
||||
|
||||
if (aNullParent) {
|
||||
if (IsRootOfNativeAnonymousSubtree()) {
|
||||
MutationObservers::NotifyNativeAnonymousChildListChange(this, true);
|
||||
@ -524,26 +498,18 @@ void CharacterData::UnbindFromTree(bool aNullParent) {
|
||||
SetSubtreeRootPointer(aNullParent ? this : mParent->SubtreeRoot());
|
||||
}
|
||||
|
||||
if (document && !GetContainingShadow()) {
|
||||
// Notify XBL- & nsIAnonymousContentCreator-generated
|
||||
// anonymous content that the document is changing.
|
||||
// Unlike XBL, bindings for web components shadow DOM
|
||||
// do not get uninstalled.
|
||||
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
|
||||
nsContentUtils::AddScriptRunner(new RemoveFromBindingManagerRunnable(
|
||||
document->BindingManager(), this, document));
|
||||
}
|
||||
}
|
||||
|
||||
nsExtendedContentSlots* slots = GetExistingExtendedContentSlots();
|
||||
if (slots) {
|
||||
slots->mBindingParent = nullptr;
|
||||
if (nsExtendedContentSlots* slots = GetExistingExtendedContentSlots()) {
|
||||
if (aNullParent || !mParent->IsInShadowTree()) {
|
||||
slots->mContainingShadow = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
MutationObservers::NotifyParentChainChanged(this);
|
||||
|
||||
#if defined(ACCESSIBILITY) && defined(DEBUG)
|
||||
MOZ_ASSERT(!GetAccService() || !GetAccService()->HasAccessible(this),
|
||||
"An accessible for this element still exists!");
|
||||
#endif
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -167,8 +167,6 @@ class CharacterData : public nsIContent {
|
||||
void DumpContent(FILE* out, int32_t aIndent, bool aDumpAll) const override {}
|
||||
#endif
|
||||
|
||||
nsXBLBinding* DoGetXBLBinding() const final { return nullptr; }
|
||||
|
||||
bool IsNodeOfType(uint32_t aFlags) const override { return false; }
|
||||
|
||||
bool IsLink(nsIURI** aURI) const final {
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "nsContentUtils.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/HTMLSlotElement.h"
|
||||
#include "mozilla/dom/XBLChildrenElement.h"
|
||||
#include "mozilla/dom/ShadowRoot.h"
|
||||
#include "nsIAnonymousContentCreator.h"
|
||||
#include "nsIFrame.h"
|
||||
@ -45,17 +44,10 @@ nsIContent* ExplicitChildIterator::GetNextChild() {
|
||||
return mChild;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mChild->IsActiveChildrenElement());
|
||||
auto* childrenElement = static_cast<XBLChildrenElement*>(mChild);
|
||||
if (mIndexInInserted < childrenElement->InsertedChildrenLength()) {
|
||||
return childrenElement->InsertedChild(mIndexInInserted++);
|
||||
}
|
||||
mIndexInInserted = 0;
|
||||
mChild = mChild->GetNextSibling();
|
||||
MOZ_ASSERT_UNREACHABLE("This needs to be revisited");
|
||||
} else if (mDefaultChild) {
|
||||
// If we're already in default content, check if there are more nodes there
|
||||
MOZ_ASSERT(mChild);
|
||||
MOZ_ASSERT(mChild->IsActiveChildrenElement());
|
||||
|
||||
mDefaultChild = mDefaultChild->GetNextSibling();
|
||||
if (mDefaultChild) {
|
||||
@ -83,89 +75,23 @@ nsIContent* ExplicitChildIterator::GetNextChild() {
|
||||
mChild = mChild->GetNextSibling();
|
||||
}
|
||||
|
||||
// Iterate until we find a non-insertion point, or an insertion point with
|
||||
// content.
|
||||
while (mChild) {
|
||||
if (mChild->IsActiveChildrenElement()) {
|
||||
// If the current child being iterated is a content insertion point
|
||||
// then the iterator needs to return the nodes distributed into
|
||||
// the content insertion point.
|
||||
auto* childrenElement = static_cast<XBLChildrenElement*>(mChild);
|
||||
if (childrenElement->HasInsertedChildren()) {
|
||||
// Iterate through elements projected on insertion point.
|
||||
mIndexInInserted = 1;
|
||||
return childrenElement->InsertedChild(0);
|
||||
}
|
||||
|
||||
// Insertion points inside fallback/default content
|
||||
// are considered inactive and do not get assigned nodes.
|
||||
mDefaultChild = mChild->GetFirstChild();
|
||||
if (mDefaultChild) {
|
||||
return mDefaultChild;
|
||||
}
|
||||
|
||||
// If we have an insertion point with no assigned nodes and
|
||||
// no default content, move on to the next node.
|
||||
mChild = mChild->GetNextSibling();
|
||||
} else {
|
||||
// mChild is not an insertion point, thus it is the next node to
|
||||
// return from this iterator.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return mChild;
|
||||
}
|
||||
|
||||
void FlattenedChildIterator::Init(bool aIgnoreXBL) {
|
||||
if (aIgnoreXBL) {
|
||||
mXBLInvolved = Some(false);
|
||||
void FlattenedChildIterator::Init() {
|
||||
if (!mParent->IsElement()) {
|
||||
// TODO(emilio): I think it probably makes sense to only allow constructing
|
||||
// FlattenedChildIterators with Element.
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(emilio): I think it probably makes sense to only allow constructing
|
||||
// FlattenedChildIterators with Element.
|
||||
if (mParent->IsElement()) {
|
||||
if (ShadowRoot* shadow = mParent->AsElement()->GetShadowRoot()) {
|
||||
mParent = shadow;
|
||||
mXBLInvolved = Some(true);
|
||||
return;
|
||||
}
|
||||
if (ShadowRoot* shadow = mParent->AsElement()->GetShadowRoot()) {
|
||||
mParent = shadow;
|
||||
mShadowDOMInvolved = true;
|
||||
return;
|
||||
}
|
||||
|
||||
nsXBLBinding* binding =
|
||||
mParent->OwnerDoc()->BindingManager()->GetBindingWithContent(mParent);
|
||||
|
||||
if (binding) {
|
||||
MOZ_ASSERT(binding->GetAnonymousContent());
|
||||
mParent = binding->GetAnonymousContent();
|
||||
mXBLInvolved = Some(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool FlattenedChildIterator::ComputeWhetherXBLIsInvolved() const {
|
||||
MOZ_ASSERT(mXBLInvolved.isNothing());
|
||||
// We set mXBLInvolved to true if either the node we're iterating has a
|
||||
// binding with content attached to it (in which case it is handled in Init),
|
||||
// the node is generated XBL content and has an <xbl:children> child, or the
|
||||
// node is a <slot> element.
|
||||
if (!mParent->GetBindingParent()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mParentAsSlot) {
|
||||
return true;
|
||||
mShadowDOMInvolved = true;
|
||||
}
|
||||
|
||||
for (nsIContent* child = mParent->GetFirstChild(); child;
|
||||
child = child->GetNextSibling()) {
|
||||
if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
|
||||
MOZ_ASSERT(child->GetBindingParent());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ExplicitChildIterator::Seek(const nsIContent* aChildToFind) {
|
||||
@ -177,7 +103,6 @@ bool ExplicitChildIterator::Seek(const nsIContent* aChildToFind) {
|
||||
mIndexInInserted = 0;
|
||||
mDefaultChild = nullptr;
|
||||
mIsFirst = false;
|
||||
MOZ_ASSERT(!mChild->IsActiveChildrenElement());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -198,9 +123,7 @@ nsIContent* ExplicitChildIterator::Get() const {
|
||||
}
|
||||
|
||||
if (mIndexInInserted) {
|
||||
MOZ_ASSERT(mChild->IsActiveChildrenElement());
|
||||
auto* childrenElement = static_cast<XBLChildrenElement*>(mChild);
|
||||
return childrenElement->InsertedChild(mIndexInInserted - 1);
|
||||
MOZ_ASSERT_UNREACHABLE("This needs to be revisited");
|
||||
}
|
||||
|
||||
return mDefaultChild ? mDefaultChild : mChild;
|
||||
@ -223,14 +146,7 @@ nsIContent* ExplicitChildIterator::GetPreviousChild() {
|
||||
return mChild;
|
||||
}
|
||||
|
||||
// NB: mIndexInInserted points one past the last returned child so we need
|
||||
// to look *two* indices back in order to return the previous child.
|
||||
MOZ_ASSERT(mChild->IsActiveChildrenElement());
|
||||
auto* childrenElement = static_cast<XBLChildrenElement*>(mChild);
|
||||
if (--mIndexInInserted) {
|
||||
return childrenElement->InsertedChild(mIndexInInserted - 1);
|
||||
}
|
||||
mChild = mChild->GetPreviousSibling();
|
||||
MOZ_ASSERT_UNREACHABLE("This needs to be revisited");
|
||||
} else if (mDefaultChild) {
|
||||
// If we're already in default content, check if there are more nodes there
|
||||
mDefaultChild = mDefaultChild->GetPreviousSibling();
|
||||
@ -259,32 +175,6 @@ nsIContent* ExplicitChildIterator::GetPreviousChild() {
|
||||
mChild = mParent->GetLastChild();
|
||||
}
|
||||
|
||||
// Iterate until we find a non-insertion point, or an insertion point with
|
||||
// content.
|
||||
while (mChild) {
|
||||
if (mChild->IsActiveChildrenElement()) {
|
||||
// If the current child being iterated is a content insertion point
|
||||
// then the iterator needs to return the nodes distributed into
|
||||
// the content insertion point.
|
||||
auto* childrenElement = static_cast<XBLChildrenElement*>(mChild);
|
||||
if (childrenElement->HasInsertedChildren()) {
|
||||
mIndexInInserted = childrenElement->InsertedChildrenLength();
|
||||
return childrenElement->InsertedChild(mIndexInInserted - 1);
|
||||
}
|
||||
|
||||
mDefaultChild = mChild->GetLastChild();
|
||||
if (mDefaultChild) {
|
||||
return mDefaultChild;
|
||||
}
|
||||
|
||||
mChild = mChild->GetPreviousSibling();
|
||||
} else {
|
||||
// mChild is not an insertion point, thus it is the next node to
|
||||
// return from this iterator.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mChild) {
|
||||
mIsFirst = true;
|
||||
}
|
||||
|
@ -34,22 +34,6 @@ class ExplicitChildIterator {
|
||||
explicit ExplicitChildIterator(const nsIContent* aParent,
|
||||
bool aStartAtBeginning = true);
|
||||
|
||||
ExplicitChildIterator(const ExplicitChildIterator& aOther)
|
||||
: mParent(aOther.mParent),
|
||||
mParentAsSlot(aOther.mParentAsSlot),
|
||||
mChild(aOther.mChild),
|
||||
mDefaultChild(aOther.mDefaultChild),
|
||||
mIsFirst(aOther.mIsFirst),
|
||||
mIndexInInserted(aOther.mIndexInInserted) {}
|
||||
|
||||
ExplicitChildIterator(ExplicitChildIterator&& aOther)
|
||||
: mParent(aOther.mParent),
|
||||
mParentAsSlot(aOther.mParentAsSlot),
|
||||
mChild(aOther.mChild),
|
||||
mDefaultChild(aOther.mDefaultChild),
|
||||
mIsFirst(aOther.mIsFirst),
|
||||
mIndexInInserted(aOther.mIndexInInserted) {}
|
||||
|
||||
nsIContent* GetNextChild();
|
||||
|
||||
// Looks for aChildToFind respecting insertion points until aChildToFind is
|
||||
@ -129,61 +113,30 @@ class FlattenedChildIterator : public ExplicitChildIterator {
|
||||
bool aStartAtBeginning = true)
|
||||
: ExplicitChildIterator(aParent, aStartAtBeginning),
|
||||
mOriginalContent(aParent) {
|
||||
Init(false);
|
||||
Init();
|
||||
}
|
||||
|
||||
FlattenedChildIterator(FlattenedChildIterator&& aOther)
|
||||
: ExplicitChildIterator(std::move(aOther)),
|
||||
mOriginalContent(aOther.mOriginalContent),
|
||||
mXBLInvolved(aOther.mXBLInvolved) {}
|
||||
|
||||
FlattenedChildIterator(const FlattenedChildIterator& aOther)
|
||||
: ExplicitChildIterator(aOther),
|
||||
mOriginalContent(aOther.mOriginalContent),
|
||||
mXBLInvolved(aOther.mXBLInvolved) {}
|
||||
|
||||
bool XBLInvolved() {
|
||||
if (mXBLInvolved.isNothing()) {
|
||||
mXBLInvolved = Some(ComputeWhetherXBLIsInvolved());
|
||||
}
|
||||
return *mXBLInvolved;
|
||||
}
|
||||
bool ShadowDOMInvolved() { return mShadowDOMInvolved; }
|
||||
|
||||
const nsIContent* Parent() const { return mOriginalContent; }
|
||||
|
||||
private:
|
||||
bool ComputeWhetherXBLIsInvolved() const;
|
||||
|
||||
void Init(bool aIgnoreXBL);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* This constructor is a hack to help AllChildrenIterator which sometimes
|
||||
* doesn't want to consider XBL.
|
||||
*/
|
||||
FlattenedChildIterator(const nsIContent* aParent, uint32_t aFlags,
|
||||
bool aStartAtBeginning = true)
|
||||
: ExplicitChildIterator(aParent, aStartAtBeginning),
|
||||
mOriginalContent(aParent) {
|
||||
bool ignoreXBL = aFlags & nsIContent::eAllButXBL;
|
||||
Init(ignoreXBL);
|
||||
}
|
||||
|
||||
const nsIContent* mOriginalContent;
|
||||
|
||||
private:
|
||||
void Init();
|
||||
|
||||
// For certain optimizations, nsCSSFrameConstructor needs to know if the child
|
||||
// list of the element that we're iterating matches its .childNodes.
|
||||
//
|
||||
// This is lazily computed when asked for it.
|
||||
Maybe<bool> mXBLInvolved;
|
||||
bool mShadowDOMInvolved = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* AllChildrenIterator traverses the children of an element including before /
|
||||
* after content and optionally XBL children. The iterator can be initialized
|
||||
* to start at the end by providing false for aStartAtBeginning in order to
|
||||
* start iterating in reverse from the last child.
|
||||
* after content and shadow DOM. The iterator can be initialized to start at
|
||||
* the end by providing false for aStartAtBeginning in order to start iterating
|
||||
* in reverse from the last child.
|
||||
*
|
||||
* Note: it assumes that no mutation of the DOM or frame tree takes place during
|
||||
* iteration, and will break horribly if that is not true.
|
||||
@ -192,31 +145,22 @@ class AllChildrenIterator : private FlattenedChildIterator {
|
||||
public:
|
||||
AllChildrenIterator(const nsIContent* aNode, uint32_t aFlags,
|
||||
bool aStartAtBeginning = true)
|
||||
: FlattenedChildIterator(aNode, aFlags, aStartAtBeginning),
|
||||
: FlattenedChildIterator(aNode, aStartAtBeginning),
|
||||
mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0),
|
||||
mFlags(aFlags),
|
||||
mPhase(aStartAtBeginning ? eAtBegin : eAtEnd) {}
|
||||
|
||||
AllChildrenIterator(AllChildrenIterator&& aOther)
|
||||
: FlattenedChildIterator(std::move(aOther)),
|
||||
mAnonKids(std::move(aOther.mAnonKids)),
|
||||
mAnonKidsIdx(aOther.mAnonKidsIdx),
|
||||
mFlags(aOther.mFlags),
|
||||
mPhase(aOther.mPhase)
|
||||
#ifdef DEBUG
|
||||
,
|
||||
mMutationGuard(aOther.mMutationGuard)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
AllChildrenIterator(AllChildrenIterator&&) = default;
|
||||
|
||||
AllChildrenIterator& operator=(AllChildrenIterator&& aOther) {
|
||||
// Explicitly call the destructor to ensure the assertion in the destructor
|
||||
// is checked.
|
||||
this->~AllChildrenIterator();
|
||||
new (this) AllChildrenIterator(std::move(aOther));
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
~AllChildrenIterator() { MOZ_ASSERT(!mMutationGuard.Mutated(0)); }
|
||||
#endif
|
||||
|
||||
@ -305,10 +249,7 @@ class MOZ_NEEDS_MEMMOVABLE_MEMBERS StyleChildrenIterator
|
||||
MOZ_COUNT_CTOR(StyleChildrenIterator);
|
||||
}
|
||||
|
||||
StyleChildrenIterator& operator=(StyleChildrenIterator&& aOther) {
|
||||
AllChildrenIterator::operator=(std::move(aOther));
|
||||
return *this;
|
||||
}
|
||||
StyleChildrenIterator& operator=(StyleChildrenIterator&& aOther) = default;
|
||||
|
||||
MOZ_COUNTED_DTOR(StyleChildrenIterator)
|
||||
|
||||
|
@ -385,16 +385,6 @@ class CustomElementRegistry final : public nsISupports, public nsWrapperCache {
|
||||
};
|
||||
|
||||
public:
|
||||
/**
|
||||
* Returns whether there's a definition that is likely to match this type
|
||||
* atom. This is not exact, so should only be used for optimization, but it's
|
||||
* good enough to prove that the chrome code doesn't need an XBL binding.
|
||||
*/
|
||||
bool IsLikelyToBeCustomElement(nsAtom* aTypeAtom) const {
|
||||
return mCustomDefinitions.GetWeak(aTypeAtom) ||
|
||||
mElementCreationCallbacks.GetWeak(aTypeAtom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looking up a custom element definition.
|
||||
* https://html.spec.whatwg.org/#look-up-a-custom-element-definition
|
||||
|
@ -172,7 +172,6 @@
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsBindingManager.h"
|
||||
#include "nsHTMLDocument.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "mozilla/dom/BlobURLProtocolHandler.h"
|
||||
@ -292,17 +291,17 @@
|
||||
#include "mozilla/dom/SVGSVGElement.h"
|
||||
#include "mozilla/dom/DocGroup.h"
|
||||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "mozilla/dom/ChromeObserver.h"
|
||||
#ifdef MOZ_XUL
|
||||
# include "mozilla/dom/XULBroadcastManager.h"
|
||||
# include "mozilla/dom/XULPersist.h"
|
||||
# include "nsIXULWindow.h"
|
||||
# include "nsIAppWindow.h"
|
||||
# include "nsIChromeRegistry.h"
|
||||
# include "nsXULPrototypeDocument.h"
|
||||
# include "nsXULCommandDispatcher.h"
|
||||
# include "nsXULPopupManager.h"
|
||||
# include "nsIDocShellTreeOwner.h"
|
||||
#endif
|
||||
#include "mozilla/dom/BoxObject.h"
|
||||
|
||||
#include "mozilla/DocLoadingTimelineMarker.h"
|
||||
|
||||
@ -829,19 +828,14 @@ nsresult ExternalResourceMap::AddExternalResource(nsIURI* aURI,
|
||||
doc = aViewer->GetDocument();
|
||||
NS_ASSERTION(doc, "Must have a document");
|
||||
|
||||
if (doc->IsXULDocument()) {
|
||||
// We don't handle XUL stuff here yet.
|
||||
rv = NS_ERROR_NOT_AVAILABLE;
|
||||
} else {
|
||||
doc->SetDisplayDocument(aDisplayDocument);
|
||||
doc->SetDisplayDocument(aDisplayDocument);
|
||||
|
||||
// Make sure that hiding our viewer will tear down its presentation.
|
||||
aViewer->SetSticky(false);
|
||||
// Make sure that hiding our viewer will tear down its presentation.
|
||||
aViewer->SetSticky(false);
|
||||
|
||||
rv = aViewer->Init(nullptr, nsIntRect(0, 0, 0, 0));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = aViewer->Open(nullptr, nullptr);
|
||||
}
|
||||
rv = aViewer->Init(nullptr, nsIntRect(0, 0, 0, 0));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = aViewer->Open(nullptr, nullptr);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
@ -1204,7 +1198,6 @@ Document::Document(const char* aContentType)
|
||||
mIsInitialDocumentInWindow(false),
|
||||
mIgnoreDocGroupMismatches(false),
|
||||
mLoadedAsData(false),
|
||||
mLoadedAsInteractiveData(false),
|
||||
mMayStartLayout(true),
|
||||
mHaveFiredTitleChange(false),
|
||||
mIsShowing(false),
|
||||
@ -1265,7 +1258,6 @@ Document::Document(const char* aContentType)
|
||||
mAutoFocusFired(false),
|
||||
mScrolledToRefAlready(false),
|
||||
mChangeScrollPosWhenScrollingToRef(false),
|
||||
mHasWarnedAboutBoxObjects(false),
|
||||
mDelayFrameLoaderInitialization(false),
|
||||
mSynchronousDOMContentLoaded(false),
|
||||
mMaybeServiceWorkerControlled(false),
|
||||
@ -1325,7 +1317,6 @@ Document::Document(const char* aContentType)
|
||||
mHeaderData(nullptr),
|
||||
mScrollAnchorAdjustmentLength(0),
|
||||
mScrollAnchorAdjustmentCount(0),
|
||||
mBoxObjectTable(nullptr),
|
||||
mCurrentOrientationAngle(0),
|
||||
mCurrentOrientationType(OrientationType::Portrait_primary),
|
||||
mServoRestyleRootDirtyBits(0),
|
||||
@ -1357,19 +1348,6 @@ Document::Document(const char* aContentType)
|
||||
mReferrerInfo = new dom::ReferrerInfo(nullptr);
|
||||
}
|
||||
|
||||
void Document::ClearAllBoxObjects() {
|
||||
if (mBoxObjectTable) {
|
||||
for (auto iter = mBoxObjectTable->Iter(); !iter.Done(); iter.Next()) {
|
||||
nsPIBoxObject* boxObject = iter.UserData();
|
||||
if (boxObject) {
|
||||
boxObject->Clear();
|
||||
}
|
||||
}
|
||||
delete mBoxObjectTable;
|
||||
mBoxObjectTable = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool Document::IsAboutPage() const {
|
||||
nsCOMPtr<nsIPrincipal> principal = NodePrincipal();
|
||||
return principal->SchemeIs("about");
|
||||
@ -1551,8 +1529,6 @@ Document::~Document() {
|
||||
|
||||
delete mHeaderData;
|
||||
|
||||
ClearAllBoxObjects();
|
||||
|
||||
mPendingTitleChangeEvent.Revoke();
|
||||
|
||||
mPlugins.Clear();
|
||||
@ -1658,13 +1634,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(Document)
|
||||
return NS_SUCCESS_INTERRUPTED_TRAVERSE;
|
||||
}
|
||||
|
||||
if (tmp->mMaybeEndOutermostXBLUpdateRunner) {
|
||||
// The cached runnable keeps a reference to the document object..
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(
|
||||
cb, "mMaybeEndOutermostXBLUpdateRunner.mObj");
|
||||
cb.NoteXPCOMChild(ToSupports(tmp));
|
||||
}
|
||||
|
||||
tmp->mExternalResourceMap.Traverse(&cb);
|
||||
|
||||
// Traverse all Document pointer members.
|
||||
@ -1683,15 +1652,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(Document)
|
||||
|
||||
DocumentOrShadowRoot::Traverse(tmp, cb);
|
||||
|
||||
// The boxobject for an element will only exist as long as it's in the
|
||||
// document, so we'll traverse the table here instead of from the element.
|
||||
if (tmp->mBoxObjectTable) {
|
||||
for (auto iter = tmp->mBoxObjectTable->Iter(); !iter.Done(); iter.Next()) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mBoxObjectTable entry");
|
||||
cb.NoteXPCOMChild(iter.UserData());
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChannel)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLayoutHistoryState)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOnloadBlocker)
|
||||
@ -1802,7 +1762,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Document)
|
||||
|
||||
tmp->mCachedRootElement = nullptr; // Avoid a dangling pointer
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDisplayDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMaybeEndOutermostXBLUpdateRunner)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMImplementation)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mImageMaps)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCachedEncoder)
|
||||
@ -1835,8 +1794,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Document)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIntersectionObservers)
|
||||
|
||||
tmp->ClearAllBoxObjects();
|
||||
|
||||
if (tmp->mListenerManager) {
|
||||
tmp->mListenerManager->Disconnect();
|
||||
tmp->UnsetFlags(NODE_HAS_LISTENERMANAGER);
|
||||
@ -1974,7 +1931,7 @@ void Document::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) {
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
nsCOMPtr<nsIPrincipal> storagePrincipal;
|
||||
if (aChannel) {
|
||||
// Note: this code is duplicated in XULDocument::StartDocumentLoad and
|
||||
// Note: this code is duplicated in PrototypeDocumentContentSink::Init and
|
||||
// nsScriptSecurityManager::GetChannelResultPrincipals.
|
||||
// Note: this should match nsDocShell::OnLoadingSite
|
||||
NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
|
||||
@ -2641,6 +2598,9 @@ nsresult Document::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
|
||||
IsSynthesized() && XRE_IsContentProcess()) {
|
||||
ContentChild::UpdateCookieStatus(mChannel);
|
||||
}
|
||||
|
||||
// Store the security info for future use.
|
||||
mChannel->GetSecurityInfo(getter_AddRefs(mSecurityInfo));
|
||||
}
|
||||
|
||||
// If this document is being loaded by a docshell, copy its sandbox flags
|
||||
@ -2866,11 +2826,12 @@ nsresult Document::InitCSP(nsIChannel* aChannel) {
|
||||
|
||||
// ----- if the doc is an addon, apply its CSP.
|
||||
if (addonPolicy) {
|
||||
nsAutoString addonCSP;
|
||||
Unused << ExtensionPolicyService::GetSingleton().GetBaseCSP(addonCSP);
|
||||
mCSP->AppendPolicy(addonCSP, false, false);
|
||||
nsAutoString extensionPageCSP;
|
||||
Unused << ExtensionPolicyService::GetSingleton().GetBaseCSP(
|
||||
extensionPageCSP);
|
||||
mCSP->AppendPolicy(extensionPageCSP, false, false);
|
||||
|
||||
mCSP->AppendPolicy(addonPolicy->ContentSecurityPolicy(), false, false);
|
||||
mCSP->AppendPolicy(addonPolicy->ExtensionPageCSP(), false, false);
|
||||
// Bug 1548468: Move CSP off ExpandedPrincipal
|
||||
// Currently the LoadInfo holds the source of truth for every resource load
|
||||
// because LoadInfo::GetCSP() queries the CSP from an ExpandedPrincipal
|
||||
@ -3503,7 +3464,7 @@ SVGSVGElement* Document::GetSVGRootElement() const {
|
||||
/* Return true if the document is in the focused top-level window, and is an
|
||||
* ancestor of the focused DOMWindow. */
|
||||
bool Document::HasFocus(ErrorResult& rv) const {
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (!fm) {
|
||||
rv.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||
return false;
|
||||
@ -5390,9 +5351,9 @@ Element* Document::GetActiveElement() {
|
||||
if (bodyElement) {
|
||||
return bodyElement;
|
||||
}
|
||||
// Special case to handle the transition to browser.xhtml where there is
|
||||
// currently not a body element, but we need to match the XUL behavior.
|
||||
// This should be removed when bug 1492582 is resolved.
|
||||
// Special case to handle the transition to XHTML from XUL documents
|
||||
// where there currently isn't a body element, but we need to match the
|
||||
// XUL behavior. This should be removed when bug 1540278 is resolved.
|
||||
if (nsContentUtils::IsChromeDoc(this)) {
|
||||
Element* docElement = GetDocumentElement();
|
||||
if (docElement && docElement->IsXULElement()) {
|
||||
@ -5604,20 +5565,6 @@ static inline void AssertNoStaleServoDataIn(nsINode& aSubtreeRoot) {
|
||||
continue;
|
||||
}
|
||||
MOZ_ASSERT(!element->HasServoData());
|
||||
if (nsXBLBinding* binding = element->GetXBLBinding()) {
|
||||
if (nsXBLBinding* bindingWithContent = binding->GetBindingWithContent()) {
|
||||
nsIContent* content = bindingWithContent->GetAnonymousContent();
|
||||
// Need to do this instead of just AssertNoStaleServoDataIn(*content),
|
||||
// because the parent of the children of the <content> element isn't the
|
||||
// <content> element, but the bound element, and that confuses
|
||||
// GetNextNode a lot.
|
||||
MOZ_ASSERT(!content->AsElement()->HasServoData());
|
||||
for (nsINode* child = content->GetFirstChild(); child;
|
||||
child = child->GetNextSibling()) {
|
||||
AssertNoStaleServoDataIn(*child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -6521,24 +6468,6 @@ bool Document::RemoveObserver(nsIDocumentObserver* aObserver) {
|
||||
return mObservers.Contains(aObserver);
|
||||
}
|
||||
|
||||
void Document::MaybeEndOutermostXBLUpdate() {
|
||||
// Only call BindingManager()->EndOutermostUpdate() when
|
||||
// we're not in an update and it is safe to run scripts.
|
||||
if (mUpdateNestLevel == 0 && mInXBLUpdate) {
|
||||
if (nsContentUtils::IsSafeToRunScript()) {
|
||||
mInXBLUpdate = false;
|
||||
BindingManager()->EndOutermostUpdate();
|
||||
} else if (!mInDestructor) {
|
||||
if (!mMaybeEndOutermostXBLUpdateRunner) {
|
||||
mMaybeEndOutermostXBLUpdateRunner =
|
||||
NewRunnableMethod("Document::MaybeEndOutermostXBLUpdate", this,
|
||||
&Document::MaybeEndOutermostXBLUpdate);
|
||||
}
|
||||
nsContentUtils::AddScriptRunner(mMaybeEndOutermostXBLUpdateRunner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Document::BeginUpdate() {
|
||||
// If the document is going away, then it's probably okay to do things to it
|
||||
// in the wrong DocGroup. We're unlikely to run JS or do anything else
|
||||
@ -6551,11 +6480,6 @@ void Document::BeginUpdate() {
|
||||
mDocGroup->ValidateAccess();
|
||||
}
|
||||
|
||||
if (mUpdateNestLevel == 0 && !mInXBLUpdate) {
|
||||
mInXBLUpdate = true;
|
||||
BindingManager()->BeginOutermostUpdate();
|
||||
}
|
||||
|
||||
++mUpdateNestLevel;
|
||||
nsContentUtils::AddScriptBlocker();
|
||||
NS_DOCUMENT_NOTIFY_OBSERVERS(BeginUpdate, (this));
|
||||
@ -6571,10 +6495,6 @@ void Document::EndUpdate() {
|
||||
|
||||
--mUpdateNestLevel;
|
||||
|
||||
// This set of updates may have created XBL bindings. Let the
|
||||
// binding manager know we're done.
|
||||
MaybeEndOutermostXBLUpdate();
|
||||
|
||||
MaybeInitializeFinalizeFrameLoaders();
|
||||
if (mXULBroadcastManager) {
|
||||
mXULBroadcastManager->MaybeBroadcast();
|
||||
@ -6772,10 +6692,9 @@ void Document::EndLoad() {
|
||||
bool turnOnEditing =
|
||||
mParser && (HasFlag(NODE_IS_EDITABLE) || mContentEditableCount > 0);
|
||||
|
||||
#if defined(DEBUG) && !defined(ANDROID)
|
||||
#if defined(DEBUG)
|
||||
// only assert if nothing stopped the load on purpose
|
||||
// TODO: we probably also want to check XUL documents here too
|
||||
if (!mParserAborted && !IsXULDocument()) {
|
||||
if (!mParserAborted) {
|
||||
nsContentSecurityUtils::AssertAboutPageHasCSP(this);
|
||||
}
|
||||
#endif
|
||||
@ -6799,6 +6718,14 @@ void Document::EndLoad() {
|
||||
mParser = nullptr;
|
||||
}
|
||||
|
||||
// Update the attributes on the PerformanceNavigationTiming before notifying
|
||||
// the onload observers.
|
||||
if (nsPIDOMWindowInner* window = GetInnerWindow()) {
|
||||
if (RefPtr<Performance> performance = window->GetPerformance()) {
|
||||
performance->UpdateNavigationTimingEntry();
|
||||
}
|
||||
}
|
||||
|
||||
NS_DOCUMENT_NOTIFY_OBSERVERS(EndLoad, (this));
|
||||
|
||||
// Part 2: Code that only executes when this EndLoad matches a BeginLoad.
|
||||
@ -7455,85 +7382,6 @@ already_AddRefed<nsINode> Document::ImportNode(nsINode& aNode, bool aDeep,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Document::LoadBindingDocument(const nsAString& aURI,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& rv) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = NS_NewURI(getter_AddRefs(uri), aURI, mCharacterSet, GetDocBaseURI());
|
||||
if (rv.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
BindingManager()->LoadBindingDocument(this, uri, &aSubjectPrincipal);
|
||||
}
|
||||
|
||||
Element* Document::GetBindingParent(nsINode& aNode) {
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(&aNode));
|
||||
if (!content) return nullptr;
|
||||
|
||||
nsIContent* bindingParent = content->GetBindingParent();
|
||||
return bindingParent ? bindingParent->AsElement() : nullptr;
|
||||
}
|
||||
|
||||
static Element* GetElementByAttribute(Element* aElement, nsAtom* aAttrName,
|
||||
const nsAString& aAttrValue,
|
||||
bool aUniversalMatch) {
|
||||
if (aUniversalMatch ? aElement->HasAttr(kNameSpaceID_None, aAttrName)
|
||||
: aElement->AttrValueIs(kNameSpaceID_None, aAttrName,
|
||||
aAttrValue, eCaseMatters)) {
|
||||
return aElement;
|
||||
}
|
||||
|
||||
for (nsIContent* child = aElement->GetFirstChild(); child;
|
||||
child = child->GetNextSibling()) {
|
||||
if (!child->IsElement()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Element* matchedElement = GetElementByAttribute(
|
||||
child->AsElement(), aAttrName, aAttrValue, aUniversalMatch);
|
||||
if (matchedElement) return matchedElement;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Element* Document::GetAnonymousElementByAttribute(
|
||||
nsIContent* aElement, nsAtom* aAttrName,
|
||||
const nsAString& aAttrValue) const {
|
||||
nsINodeList* nodeList = BindingManager()->GetAnonymousNodesFor(aElement);
|
||||
if (!nodeList) return nullptr;
|
||||
|
||||
uint32_t length = nodeList->Length();
|
||||
|
||||
bool universalMatch = aAttrValue.EqualsLiteral("*");
|
||||
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
Element* current = Element::FromNode(nodeList->Item(i));
|
||||
if (!current) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Element* matchedElm =
|
||||
GetElementByAttribute(current, aAttrName, aAttrValue, universalMatch);
|
||||
if (matchedElm) return matchedElm;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Element* Document::GetAnonymousElementByAttribute(Element& aElement,
|
||||
const nsAString& aAttrName,
|
||||
const nsAString& aAttrValue) {
|
||||
RefPtr<nsAtom> attribute = NS_Atomize(aAttrName);
|
||||
|
||||
return GetAnonymousElementByAttribute(&aElement, attribute, aAttrValue);
|
||||
}
|
||||
|
||||
nsINodeList* Document::GetAnonymousNodes(Element& aElement) {
|
||||
return BindingManager()->GetAnonymousNodesFor(&aElement);
|
||||
}
|
||||
|
||||
already_AddRefed<nsRange> Document::CreateRange(ErrorResult& rv) {
|
||||
return nsRange::Create(this, 0, this, 0, rv);
|
||||
}
|
||||
@ -7944,55 +7792,6 @@ void Document::DoNotifyPossibleTitleChange() {
|
||||
Cancelable::eYes);
|
||||
}
|
||||
|
||||
already_AddRefed<BoxObject> Document::GetBoxObjectFor(Element* aElement,
|
||||
ErrorResult& aRv) {
|
||||
if (!aElement) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Document* doc = aElement->OwnerDoc();
|
||||
if (doc != this) {
|
||||
aRv.Throw(NS_ERROR_DOM_WRONG_DOCUMENT_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!mHasWarnedAboutBoxObjects && !aElement->IsXULElement()) {
|
||||
mHasWarnedAboutBoxObjects = true;
|
||||
nsContentUtils::ReportToConsole(
|
||||
nsIScriptError::warningFlag, NS_LITERAL_CSTRING("BoxObjects"), this,
|
||||
nsContentUtils::eDOM_PROPERTIES, "UseOfGetBoxObjectForWarning");
|
||||
}
|
||||
|
||||
if (!mBoxObjectTable) {
|
||||
mBoxObjectTable =
|
||||
new nsRefPtrHashtable<nsPtrHashKey<nsIContent>, BoxObject>(6);
|
||||
}
|
||||
|
||||
RefPtr<BoxObject> boxObject;
|
||||
auto entry = mBoxObjectTable->LookupForAdd(aElement);
|
||||
if (entry) {
|
||||
boxObject = entry.Data();
|
||||
return boxObject.forget();
|
||||
}
|
||||
|
||||
boxObject = new BoxObject();
|
||||
boxObject->Init(aElement);
|
||||
entry.OrInsert([&boxObject]() { return boxObject; });
|
||||
|
||||
return boxObject.forget();
|
||||
}
|
||||
|
||||
void Document::ClearBoxObjectFor(nsIContent* aContent) {
|
||||
if (mBoxObjectTable) {
|
||||
if (auto entry = mBoxObjectTable->Lookup(aContent)) {
|
||||
nsPIBoxObject* boxObject = entry.Data();
|
||||
boxObject->Clear();
|
||||
entry.Remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<MediaQueryList> Document::MatchMedia(
|
||||
const nsACString& aMediaQueryList, CallerType aCallerType) {
|
||||
RefPtr<MediaQueryList> result =
|
||||
@ -8009,7 +7808,7 @@ void Document::SetMayStartLayout(bool aMayStartLayout) {
|
||||
// Before starting layout, check whether we're a toplevel chrome
|
||||
// window. If we are, setup some state so that we don't have to restyle
|
||||
// the whole tree after StartLayout.
|
||||
if (nsCOMPtr<nsIXULWindow> win = GetXULWindowIfToplevelChrome()) {
|
||||
if (nsCOMPtr<nsIAppWindow> win = GetAppWindowIfToplevelChrome()) {
|
||||
// We're the chrome document!
|
||||
win->BeforeStartLayout();
|
||||
}
|
||||
@ -8117,6 +7916,7 @@ void Document::TryCancelFrameLoaderInitialization(nsIDocShell* aShell) {
|
||||
|
||||
void Document::SetPrototypeDocument(nsXULPrototypeDocument* aPrototype) {
|
||||
mPrototypeDocument = aPrototype;
|
||||
mSynchronousDOMContentLoaded = true;
|
||||
}
|
||||
|
||||
Document* Document::RequestExternalResource(
|
||||
@ -8143,7 +7943,7 @@ SMILAnimationController* Document::GetAnimationController() {
|
||||
// one and only SVG documents and the like will call this
|
||||
if (mAnimationController) return mAnimationController;
|
||||
// Refuse to create an Animation Controller for data documents.
|
||||
if (mLoadedAsData || mLoadedAsInteractiveData) return nullptr;
|
||||
if (mLoadedAsData) return nullptr;
|
||||
|
||||
mAnimationController = new SMILAnimationController(this);
|
||||
|
||||
@ -8895,14 +8695,6 @@ nsINode* Document::AdoptNode(nsINode& aAdoptedNode, ErrorResult& rv) {
|
||||
parent->RemoveChildNode(adoptedNode->AsContent(), true);
|
||||
} else {
|
||||
MOZ_ASSERT(!adoptedNode->IsInUncomposedDoc());
|
||||
|
||||
// If we're adopting a node that's not in a document, it might still
|
||||
// have a binding applied. Remove the binding from the element now
|
||||
// that it's getting adopted into a new document.
|
||||
// TODO Fully tear down the binding.
|
||||
if (Element* element = Element::FromNode(adoptedNode)) {
|
||||
element->SetXBLBinding(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
@ -10749,14 +10541,15 @@ void Document::SetReadyStateInternal(ReadyState aReadyState,
|
||||
}
|
||||
// At the time of loading start, we don't have timing object, record time.
|
||||
|
||||
if (READYSTATE_INTERACTIVE == aReadyState) {
|
||||
if (NodePrincipal()->IsSystemPrincipal()) {
|
||||
Element* root = GetRootElement();
|
||||
if ((root && root->HasAttr(kNameSpaceID_None, nsGkAtoms::mozpersist)) ||
|
||||
IsXULDocument()) {
|
||||
mXULPersist = new XULPersist(this);
|
||||
mXULPersist->Init();
|
||||
}
|
||||
if (READYSTATE_INTERACTIVE == aReadyState &&
|
||||
NodePrincipal()->IsSystemPrincipal()) {
|
||||
if (!mXULPersist) {
|
||||
mXULPersist = new XULPersist(this);
|
||||
mXULPersist->Init();
|
||||
}
|
||||
if (!mChromeObserver) {
|
||||
mChromeObserver = new ChromeObserver(this);
|
||||
mChromeObserver->Init();
|
||||
}
|
||||
}
|
||||
|
||||
@ -10802,7 +10595,7 @@ void Document::SuppressEventHandling(uint32_t aIncrease) {
|
||||
|
||||
static void FireOrClearDelayedEvents(nsTArray<nsCOMPtr<Document>>& aDocuments,
|
||||
bool aFireEvents) {
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (!fm) return;
|
||||
|
||||
for (uint32_t i = 0; i < aDocuments.Length(); ++i) {
|
||||
@ -11077,14 +10870,14 @@ RefPtr<StyleSheet> Document::LoadChromeSheetSync(nsIURI* uri) {
|
||||
}
|
||||
|
||||
void Document::ResetDocumentDirection() {
|
||||
if (!(nsContentUtils::IsChromeDoc(this) || IsXULDocument())) {
|
||||
if (!nsContentUtils::IsChromeDoc(this)) {
|
||||
return;
|
||||
}
|
||||
UpdateDocumentStates(NS_DOCUMENT_STATE_RTL_LOCALE, true);
|
||||
}
|
||||
|
||||
bool Document::IsDocumentRightToLeft() {
|
||||
if (!(nsContentUtils::IsChromeDoc(this) || IsXULDocument())) {
|
||||
if (!nsContentUtils::IsChromeDoc(this)) {
|
||||
return false;
|
||||
}
|
||||
// setting the localedir attribute on the root element forces a
|
||||
@ -13858,13 +13651,6 @@ void Document::AddSizeOfNodeTree(nsINode& aNode, nsWindowSizes& aWindowSizes) {
|
||||
if (ShadowRoot* shadow = element->GetShadowRoot()) {
|
||||
AddSizeOfNodeTree(*shadow, aWindowSizes);
|
||||
}
|
||||
|
||||
for (nsXBLBinding* binding = element->GetXBLBinding(); binding;
|
||||
binding = binding->GetBaseBinding()) {
|
||||
if (nsIContent* anonContent = binding->GetAnonymousContent()) {
|
||||
AddSizeOfNodeTree(*anonContent, aWindowSizes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13933,23 +13719,23 @@ already_AddRefed<XPathResult> Document::Evaluate(
|
||||
aType, aResult, rv);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIXULWindow> Document::GetXULWindowIfToplevelChrome() const {
|
||||
already_AddRefed<nsIAppWindow> Document::GetAppWindowIfToplevelChrome() const {
|
||||
nsCOMPtr<nsIDocShellTreeItem> item = GetDocShell();
|
||||
if (!item) {
|
||||
return nullptr;
|
||||
}
|
||||
nsCOMPtr<nsIDocShellTreeOwner> owner;
|
||||
item->GetTreeOwner(getter_AddRefs(owner));
|
||||
nsCOMPtr<nsIXULWindow> xulWin = do_GetInterface(owner);
|
||||
if (!xulWin) {
|
||||
nsCOMPtr<nsIAppWindow> appWin = do_GetInterface(owner);
|
||||
if (!appWin) {
|
||||
return nullptr;
|
||||
}
|
||||
nsCOMPtr<nsIDocShell> xulWinShell;
|
||||
xulWin->GetDocShell(getter_AddRefs(xulWinShell));
|
||||
if (!SameCOMIdentity(xulWinShell, item)) {
|
||||
nsCOMPtr<nsIDocShell> appWinShell;
|
||||
appWin->GetDocShell(getter_AddRefs(appWinShell));
|
||||
if (!SameCOMIdentity(appWinShell, item)) {
|
||||
return nullptr;
|
||||
}
|
||||
return xulWin.forget();
|
||||
return appWin.forget();
|
||||
}
|
||||
|
||||
Document* Document::GetTopLevelContentDocument() {
|
||||
|
@ -79,7 +79,6 @@ class ElementCreationOptionsOrString;
|
||||
|
||||
class gfxUserFontSet;
|
||||
class imgIRequest;
|
||||
class nsBindingManager;
|
||||
class nsCachableElementsByNameNodeList;
|
||||
class nsContentList;
|
||||
class nsIDocShell;
|
||||
@ -124,7 +123,7 @@ class nsWindowSizes;
|
||||
class nsDOMCaretPosition;
|
||||
class nsViewportInfo;
|
||||
class nsIGlobalObject;
|
||||
class nsIXULWindow;
|
||||
class nsIAppWindow;
|
||||
class nsXULPrototypeDocument;
|
||||
class nsXULPrototypeElement;
|
||||
class PermissionDelegateHandler;
|
||||
@ -162,9 +161,9 @@ class Rule;
|
||||
namespace dom {
|
||||
class AnonymousContent;
|
||||
class Attr;
|
||||
class BoxObject;
|
||||
class XULBroadcastManager;
|
||||
class XULPersist;
|
||||
class ChromeObserver;
|
||||
class ClientInfo;
|
||||
class ClientState;
|
||||
class CDATASection;
|
||||
@ -218,7 +217,6 @@ class XPathEvaluator;
|
||||
class XPathExpression;
|
||||
class XPathNSResolver;
|
||||
class XPathResult;
|
||||
class XULDocument;
|
||||
template <typename>
|
||||
class Sequence;
|
||||
|
||||
@ -1019,9 +1017,6 @@ class Document : public nsINode,
|
||||
}
|
||||
|
||||
void SetLoadedAsData(bool aLoadedAsData) { mLoadedAsData = aLoadedAsData; }
|
||||
void SetLoadedAsInteractiveData(bool aLoadedAsInteractiveData) {
|
||||
mLoadedAsInteractiveData = aLoadedAsInteractiveData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normally we assert if a runnable labeled with one DocGroup touches data
|
||||
@ -1715,10 +1710,6 @@ class Document : public nsINode,
|
||||
|
||||
void DoUnblockOnload();
|
||||
|
||||
void ClearAllBoxObjects();
|
||||
|
||||
void MaybeEndOutermostXBLUpdate();
|
||||
|
||||
void RetrieveRelevantHeaders(nsIChannel* aChannel);
|
||||
|
||||
void TryChannelCharset(nsIChannel* aChannel, int32_t& aCharsetSource,
|
||||
@ -2304,10 +2295,6 @@ class Document : public nsINode,
|
||||
DoUpdateSVGUseElementShadowTrees();
|
||||
}
|
||||
|
||||
nsBindingManager* BindingManager() const {
|
||||
return mNodeInfoManager->GetBindingManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Only to be used inside Gecko, you can't really do anything with the
|
||||
* pointer outside Gecko anyway.
|
||||
@ -2372,14 +2359,8 @@ class Document : public nsINode,
|
||||
bool IsHTMLOrXHTML() const { return mType == eHTML || mType == eXHTML; }
|
||||
bool IsXMLDocument() const { return !IsHTMLDocument(); }
|
||||
bool IsSVGDocument() const { return mType == eSVG; }
|
||||
bool IsXULDocument() const { return mType == eXUL; }
|
||||
bool IsUnstyledDocument() {
|
||||
return IsLoadedAsData() || IsLoadedAsInteractiveData();
|
||||
}
|
||||
bool IsUnstyledDocument() { return IsLoadedAsData(); }
|
||||
bool LoadsFullXULStyleSheetUpFront() {
|
||||
if (IsXULDocument()) {
|
||||
return true;
|
||||
}
|
||||
if (IsSVGDocument()) {
|
||||
return false;
|
||||
}
|
||||
@ -2618,20 +2599,6 @@ class Document : public nsINode,
|
||||
// Refreshes the hrefs of all the links in the document.
|
||||
void RefreshLinkHrefs();
|
||||
|
||||
/**
|
||||
* Resets and removes a box object from the document's box object cache
|
||||
*
|
||||
* @param aElement canonical nsIContent pointer of the box object's element
|
||||
*/
|
||||
void ClearBoxObjectFor(nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* Get the box object for an element. This is not exposed through a
|
||||
* scriptable interface except for XUL documents.
|
||||
*/
|
||||
already_AddRefed<BoxObject> GetBoxObjectFor(Element* aElement,
|
||||
ErrorResult& aRv);
|
||||
|
||||
/**
|
||||
* Support for window.matchMedia()
|
||||
*/
|
||||
@ -2652,10 +2619,6 @@ class Document : public nsINode,
|
||||
*/
|
||||
bool HaveFiredDOMTitleChange() const { return mHaveFiredTitleChange; }
|
||||
|
||||
Element* GetAnonymousElementByAttribute(nsIContent* aElement,
|
||||
nsAtom* aAttrName,
|
||||
const nsAString& aAttrValue) const;
|
||||
|
||||
/**
|
||||
* To batch DOMSubtreeModified, document needs to be informed when
|
||||
* a mutation event might be dispatched, even if the event isn't actually
|
||||
@ -2703,8 +2666,6 @@ class Document : public nsINode,
|
||||
|
||||
bool IsLoadedAsData() { return mLoadedAsData; }
|
||||
|
||||
bool IsLoadedAsInteractiveData() { return mLoadedAsInteractiveData; }
|
||||
|
||||
bool MayStartLayout() { return mMayStartLayout; }
|
||||
|
||||
void SetMayStartLayout(bool aMayStartLayout);
|
||||
@ -3447,9 +3408,9 @@ class Document : public nsINode,
|
||||
Document* GetTopLevelContentDocument();
|
||||
const Document* GetTopLevelContentDocument() const;
|
||||
|
||||
// Returns the associated XUL window if this is a top-level chrome document,
|
||||
// Returns the associated app window if this is a top-level chrome document,
|
||||
// null otherwise.
|
||||
already_AddRefed<nsIXULWindow> GetXULWindowIfToplevelChrome() const;
|
||||
already_AddRefed<nsIAppWindow> GetAppWindowIfToplevelChrome() const;
|
||||
|
||||
already_AddRefed<Element> CreateElement(
|
||||
const nsAString& aTagName, const ElementCreationOptionsOrString& aOptions,
|
||||
@ -3640,13 +3601,7 @@ class Document : public nsINode,
|
||||
bool IsScrollingElement(Element* aElement);
|
||||
|
||||
// QuerySelector and QuerySelectorAll already defined on nsINode
|
||||
nsINodeList* GetAnonymousNodes(Element& aElement);
|
||||
Element* GetAnonymousElementByAttribute(Element& aElement,
|
||||
const nsAString& aAttrName,
|
||||
const nsAString& aAttrValue);
|
||||
Element* GetBindingParent(nsINode& aNode);
|
||||
void LoadBindingDocument(const nsAString& aURI,
|
||||
nsIPrincipal& aSubjectPrincipal, ErrorResult& rv);
|
||||
|
||||
XPathExpression* CreateExpression(const nsAString& aExpression,
|
||||
XPathNSResolver* aResolver,
|
||||
ErrorResult& rv);
|
||||
@ -3726,12 +3681,6 @@ class Document : public nsINode,
|
||||
inline SVGDocument* AsSVGDocument();
|
||||
inline const SVGDocument* AsSVGDocument() const;
|
||||
|
||||
/**
|
||||
* Asserts IsXULDocument, and can't return null.
|
||||
* Defined inline in XULDocument.h
|
||||
*/
|
||||
inline XULDocument* AsXULDocument();
|
||||
|
||||
/*
|
||||
* Given a node, get a weak reference to it and append that reference to
|
||||
* mBlockedNodesByClassifier. Can be used later on to look up a node in it.
|
||||
@ -4487,11 +4436,6 @@ class Document : public nsINode,
|
||||
// as scripts and plugins, disabled.
|
||||
bool mLoadedAsData : 1;
|
||||
|
||||
// This flag is only set in XMLDocument, for e.g. documents used in XBL. We
|
||||
// don't want animations to play in such documents, so we need to store the
|
||||
// flag here so that we can check it in Document::GetAnimationController.
|
||||
bool mLoadedAsInteractiveData : 1;
|
||||
|
||||
// If true, whoever is creating the document has gotten it to the
|
||||
// point where it's safe to start layout on it.
|
||||
bool mMayStartLayout : 1;
|
||||
@ -4668,8 +4612,6 @@ class Document : public nsINode,
|
||||
bool mScrolledToRefAlready : 1;
|
||||
bool mChangeScrollPosWhenScrollingToRef : 1;
|
||||
|
||||
bool mHasWarnedAboutBoxObjects : 1;
|
||||
|
||||
bool mDelayFrameLoaderInitialization : 1;
|
||||
|
||||
bool mSynchronousDOMContentLoaded : 1;
|
||||
@ -4777,8 +4719,7 @@ class Document : public nsINode,
|
||||
eHTML,
|
||||
eXHTML,
|
||||
eGenericXML,
|
||||
eSVG,
|
||||
eXUL
|
||||
eSVG
|
||||
};
|
||||
|
||||
Type mType;
|
||||
@ -5046,8 +4987,6 @@ class Document : public nsINode,
|
||||
|
||||
RefPtr<dom::ScriptLoader> mScriptLoader;
|
||||
|
||||
nsRefPtrHashtable<nsPtrHashKey<nsIContent>, BoxObject>* mBoxObjectTable;
|
||||
|
||||
// Tracker for animations that are waiting to start.
|
||||
// nullptr until GetOrCreatePendingAnimationTracker is called.
|
||||
RefPtr<PendingAnimationTracker> mPendingAnimationTracker;
|
||||
@ -5100,7 +5039,6 @@ class Document : public nsINode,
|
||||
|
||||
RefPtr<EventListenerManager> mListenerManager;
|
||||
|
||||
nsCOMPtr<nsIRunnable> mMaybeEndOutermostXBLUpdateRunner;
|
||||
nsCOMPtr<nsIRequest> mOnloadBlocker;
|
||||
|
||||
// Gecko-internal sheets used for extensions and such.
|
||||
@ -5147,6 +5085,7 @@ class Document : public nsINode,
|
||||
|
||||
RefPtr<XULBroadcastManager> mXULBroadcastManager;
|
||||
RefPtr<XULPersist> mXULPersist;
|
||||
RefPtr<ChromeObserver> mChromeObserver;
|
||||
|
||||
RefPtr<HTMLAllCollection> mAll;
|
||||
|
||||
@ -5308,12 +5247,6 @@ nsresult NS_NewDOMDocument(
|
||||
nsIURI* aDocumentURI, nsIURI* aBaseURI, nsIPrincipal* aPrincipal,
|
||||
bool aLoadedAsData, nsIGlobalObject* aEventObject, DocumentFlavor aFlavor);
|
||||
|
||||
// This is used only for xbl documents created from the startup cache.
|
||||
// Non-cached documents are created in the same manner as xml documents.
|
||||
nsresult NS_NewXBLDocument(mozilla::dom::Document** aInstancePtrResult,
|
||||
nsIURI* aDocumentURI, nsIURI* aBaseURI,
|
||||
nsIPrincipal* aPrincipal);
|
||||
|
||||
nsresult NS_NewPluginDocument(mozilla::dom::Document** aInstancePtrResult);
|
||||
|
||||
inline mozilla::dom::Document* nsINode::GetOwnerDocument() const {
|
||||
|
@ -46,7 +46,6 @@
|
||||
#include "nsContentList.h"
|
||||
#include "nsVariant.h"
|
||||
#include "nsDOMTokenList.h"
|
||||
#include "nsXBLPrototypeBinding.h"
|
||||
#include "nsError.h"
|
||||
#include "nsDOMString.h"
|
||||
#include "mozilla/dom/AnimatableBinding.h"
|
||||
@ -93,10 +92,7 @@
|
||||
# include "nsRange.h"
|
||||
#endif
|
||||
|
||||
#include "nsBindingManager.h"
|
||||
#include "nsXBLBinding.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsPIBoxObject.h"
|
||||
#include "mozilla/dom/DOMRect.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsGkAtoms.h"
|
||||
@ -128,7 +124,6 @@
|
||||
#include "mozilla/dom/NodeListBinding.h"
|
||||
|
||||
#include "nsStyledElement.h"
|
||||
#include "nsXBLService.h"
|
||||
#include "nsITextControlFrame.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "mozilla/dom/CSSPseudoElement.h"
|
||||
@ -166,6 +161,10 @@
|
||||
|
||||
#include "DOMMatrix.h"
|
||||
|
||||
#if defined(ACCESSIBILITY) && defined(DEBUG)
|
||||
# include "nsAccessibilityService.h"
|
||||
#endif
|
||||
|
||||
using mozilla::gfx::Matrix4x4;
|
||||
|
||||
namespace mozilla {
|
||||
@ -255,9 +254,7 @@ Element::QueryInterface(REFNSIID aIID, void** aInstancePtr) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Give the binding manager a chance to get an interface for this element.
|
||||
return OwnerDoc()->BindingManager()->GetBindingImplementation(this, aIID,
|
||||
aInstancePtr);
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
EventStates Element::IntrinsicState() const {
|
||||
@ -387,46 +384,6 @@ void Element::SetTabIndex(int32_t aTabIndex, mozilla::ErrorResult& aError) {
|
||||
SetAttr(nsGkAtoms::tabindex, value, aError);
|
||||
}
|
||||
|
||||
void Element::SetXBLBinding(nsXBLBinding* aBinding,
|
||||
nsBindingManager* aOldBindingManager) {
|
||||
nsBindingManager* bindingManager;
|
||||
if (aOldBindingManager) {
|
||||
MOZ_ASSERT(!aBinding,
|
||||
"aOldBindingManager should only be provided "
|
||||
"when removing a binding.");
|
||||
bindingManager = aOldBindingManager;
|
||||
} else {
|
||||
bindingManager = OwnerDoc()->BindingManager();
|
||||
}
|
||||
|
||||
// After this point, aBinding will be the most-derived binding for aContent.
|
||||
// If we already have a binding for aContent, make sure to
|
||||
// remove it from the attached stack. Otherwise we might end up firing its
|
||||
// constructor twice (if aBinding inherits from it) or firing its constructor
|
||||
// after aContent has been deleted (if aBinding is null and the content node
|
||||
// dies before we process mAttachedStack).
|
||||
RefPtr<nsXBLBinding> oldBinding = GetXBLBinding();
|
||||
if (oldBinding) {
|
||||
bindingManager->RemoveFromAttachedQueue(oldBinding);
|
||||
}
|
||||
|
||||
if (aBinding) {
|
||||
SetFlags(NODE_MAY_BE_IN_BINDING_MNGR);
|
||||
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
|
||||
slots->mXBLBinding = aBinding;
|
||||
bindingManager->AddBoundContent(this);
|
||||
} else {
|
||||
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
if (slots) {
|
||||
slots->mXBLBinding = nullptr;
|
||||
}
|
||||
bindingManager->RemoveBoundContent(this);
|
||||
if (oldBinding) {
|
||||
oldBinding->SetBoundElement(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Element::SetShadowRoot(ShadowRoot* aShadowRoot) {
|
||||
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
|
||||
slots->mShadowRoot = aShadowRoot;
|
||||
@ -443,7 +400,7 @@ void Element::Blur(mozilla::ErrorResult& aError) {
|
||||
}
|
||||
|
||||
nsPIDOMWindowOuter* win = doc->GetWindow();
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (win && fm) {
|
||||
aError = fm->ClearFocus(win);
|
||||
}
|
||||
@ -535,121 +492,6 @@ void Element::ClearStyleStateLocks() {
|
||||
NotifyStyleStateChange(locks.mLocks);
|
||||
}
|
||||
|
||||
static bool IsLikelyCustomElement(const nsXULElement& aElement) {
|
||||
const CustomElementData* data = aElement.GetCustomElementData();
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const CustomElementRegistry* registry =
|
||||
nsContentUtils::GetCustomElementRegistry(aElement.OwnerDoc());
|
||||
if (!registry) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return registry->IsLikelyToBeCustomElement(data->GetCustomElementType());
|
||||
}
|
||||
|
||||
static bool MayNeedToLoadXBLBinding(const Document& aDocument,
|
||||
const Element& aElement) {
|
||||
// If we have a frame, the frame has already loaded the binding.
|
||||
// Otherwise, don't do anything else here unless we're dealing with
|
||||
// XUL or an HTML element that may have a plugin-related overlay
|
||||
// (i.e. object or embed).
|
||||
if (!aDocument.GetPresShell() || aElement.GetPrimaryFrame()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (auto* xulElem = nsXULElement::FromNode(aElement)) {
|
||||
return !IsLikelyCustomElement(*xulElem);
|
||||
}
|
||||
|
||||
return aElement.IsAnyOfHTMLElements(nsGkAtoms::object, nsGkAtoms::embed);
|
||||
}
|
||||
|
||||
StyleUrlOrNone Element::GetBindingURL(Document* aDocument) {
|
||||
if (!MayNeedToLoadXBLBinding(*aDocument, *this)) {
|
||||
return StyleUrlOrNone::None();
|
||||
}
|
||||
|
||||
// Get the computed -moz-binding directly from the ComputedStyle
|
||||
RefPtr<ComputedStyle> style =
|
||||
nsComputedDOMStyle::GetComputedStyleNoFlush(this, nullptr);
|
||||
if (!style) {
|
||||
return StyleUrlOrNone::None();
|
||||
}
|
||||
|
||||
return style->StyleDisplay()->mBinding;
|
||||
}
|
||||
|
||||
JSObject* Element::WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) {
|
||||
JS::Rooted<JSObject*> obj(aCx, nsINode::WrapObject(aCx, aGivenProto));
|
||||
if (!obj) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (XRE_IsContentProcess() && !NodePrincipal()->IsSystemPrincipal()) {
|
||||
// We don't use XBL in content privileged content processes.
|
||||
return obj;
|
||||
}
|
||||
|
||||
Document* doc = GetComposedDoc();
|
||||
if (!doc) {
|
||||
// There's no baseclass that cares about this call so we just
|
||||
// return here.
|
||||
return obj;
|
||||
}
|
||||
|
||||
// We must ensure that the XBL Binding is installed before we hand
|
||||
// back this object.
|
||||
|
||||
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR) && GetXBLBinding()) {
|
||||
// There's already a binding for this element so nothing left to
|
||||
// be done here.
|
||||
|
||||
// In theory we could call ExecuteAttachedHandler here when it's safe to
|
||||
// run script if we also removed the binding from the PAQ queue, but that
|
||||
// seems like a scary change that would mosly just add more
|
||||
// inconsistencies.
|
||||
return obj;
|
||||
}
|
||||
|
||||
// Make sure the ComputedStyle goes away _before_ we load the binding
|
||||
// since that can destroy the relevant presshell.
|
||||
|
||||
{
|
||||
StyleUrlOrNone result = GetBindingURL(doc);
|
||||
if (result.IsUrl()) {
|
||||
auto& url = result.AsUrl();
|
||||
nsCOMPtr<nsIURI> uri = url.GetURI();
|
||||
nsCOMPtr<nsIPrincipal> principal = url.ExtraData().Principal();
|
||||
|
||||
// We have a binding that must be installed.
|
||||
nsXBLService* xblService = nsXBLService::GetInstance();
|
||||
if (!xblService) {
|
||||
dom::Throw(aCx, NS_ERROR_NOT_AVAILABLE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<nsXBLBinding> binding;
|
||||
xblService->LoadBindings(this, uri, principal, getter_AddRefs(binding));
|
||||
|
||||
if (binding) {
|
||||
if (nsContentUtils::IsSafeToRunScript()) {
|
||||
binding->ExecuteAttachedHandler();
|
||||
} else {
|
||||
nsContentUtils::AddScriptRunner(
|
||||
NewRunnableMethod("nsXBLBinding::ExecuteAttachedHandler", binding,
|
||||
&nsXBLBinding::ExecuteAttachedHandler));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
nsINode* Element::GetScopeChainParent() const { return OwnerDoc(); }
|
||||
|
||||
@ -1165,7 +1007,7 @@ bool Element::CanAttachShadowDOM() const {
|
||||
* XUL elements.
|
||||
*/
|
||||
if (!IsHTMLElement() &&
|
||||
!(XRE_IsParentProcess() && IsXULElement() &&
|
||||
!(IsXULElement() &&
|
||||
nsContentUtils::AllowXULXBLForPrincipal(NodePrincipal()))) {
|
||||
return false;
|
||||
}
|
||||
@ -1238,7 +1080,7 @@ already_AddRefed<ShadowRoot> Element::AttachShadow(const ShadowRootInit& aInit,
|
||||
* 4. If context object is a shadow host, then throw
|
||||
* an "NotSupportedError" DOMException.
|
||||
*/
|
||||
if (GetShadowRoot() || GetXBLBinding()) {
|
||||
if (GetShadowRoot()) {
|
||||
aError.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
@ -1259,12 +1101,19 @@ already_AddRefed<ShadowRoot> Element::AttachShadowWithoutNameChecks(
|
||||
nsGkAtoms::documentFragmentNodeName, nullptr, kNameSpaceID_None,
|
||||
DOCUMENT_FRAGMENT_NODE);
|
||||
|
||||
if (Document* doc = GetComposedDoc()) {
|
||||
if (PresShell* presShell = doc->GetPresShell()) {
|
||||
presShell->DestroyFramesForAndRestyle(this);
|
||||
// If there are no children, the flat tree is not changing due to the presence
|
||||
// of the shadow root, so we don't need to invalidate style / layout.
|
||||
//
|
||||
// This is a minor optimization, but also works around nasty stuff like
|
||||
// bug 1397876.
|
||||
if (HasChildren()) {
|
||||
if (Document* doc = GetComposedDoc()) {
|
||||
if (PresShell* presShell = doc->GetPresShell()) {
|
||||
presShell->DestroyFramesForAndRestyle(this);
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(!GetPrimaryFrame());
|
||||
}
|
||||
MOZ_ASSERT(!GetPrimaryFrame());
|
||||
|
||||
/**
|
||||
* 4. Let shadow be a new shadow root whose node document is
|
||||
@ -1655,50 +1504,16 @@ nsresult Element::BindToTree(BindContext& aContext, nsINode& aParent) {
|
||||
// only assert if our parent is _changing_ while we have a parent.
|
||||
MOZ_ASSERT(!GetParentNode() || &aParent == GetParentNode(),
|
||||
"Already have a parent. Unbind first!");
|
||||
MOZ_ASSERT(
|
||||
!GetBindingParent() ||
|
||||
aContext.GetBindingParent() == GetBindingParent() ||
|
||||
(!aContext.GetBindingParent() && aParent.IsContent() &&
|
||||
aParent.AsContent()->GetBindingParent() == GetBindingParent()),
|
||||
"Already have a binding parent. Unbind first!");
|
||||
MOZ_ASSERT(aContext.GetBindingParent() != this,
|
||||
"Content must not be its own binding parent");
|
||||
MOZ_ASSERT(!IsRootOfNativeAnonymousSubtree() ||
|
||||
aContext.GetBindingParent() == &aParent,
|
||||
"Native anonymous content must have its parent as its "
|
||||
"own binding parent");
|
||||
MOZ_ASSERT(aContext.GetBindingParent() || !aParent.IsContent() ||
|
||||
aContext.GetBindingParent() ==
|
||||
aParent.AsContent()->GetBindingParent(),
|
||||
"We should be passed the right binding parent");
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
// First set the binding parent
|
||||
if (nsXULElement* xulElem = nsXULElement::FromNode(this)) {
|
||||
xulElem->SetXULBindingParent(aContext.GetBindingParent());
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (Element* bindingParent = aContext.GetBindingParent()) {
|
||||
ExtendedDOMSlots()->mBindingParent = bindingParent;
|
||||
}
|
||||
}
|
||||
|
||||
const bool hadParent = !!GetParentNode();
|
||||
|
||||
NS_ASSERTION(!aContext.GetBindingParent() ||
|
||||
IsRootOfNativeAnonymousSubtree() ||
|
||||
!HasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE) ||
|
||||
aParent.IsInNativeAnonymousSubtree(),
|
||||
"Trying to re-bind content from native anonymous subtree to "
|
||||
"non-native anonymous parent!");
|
||||
if (aParent.IsInNativeAnonymousSubtree()) {
|
||||
SetFlags(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE);
|
||||
}
|
||||
if (aParent.HasFlag(NODE_HAS_BEEN_IN_UA_WIDGET)) {
|
||||
SetFlags(NODE_HAS_BEEN_IN_UA_WIDGET);
|
||||
}
|
||||
if (HasFlag(NODE_IS_ANONYMOUS_ROOT)) {
|
||||
if (IsRootOfNativeAnonymousSubtree()) {
|
||||
aParent.SetMayHaveAnonymousChildren();
|
||||
}
|
||||
|
||||
@ -1758,17 +1573,6 @@ nsresult Element::BindToTree(BindContext& aContext, nsINode& aParent) {
|
||||
|
||||
UpdateEditableState(false);
|
||||
|
||||
// If we had a pre-existing XBL binding, we might have anonymous children that
|
||||
// also need to be told that they are moving.
|
||||
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
|
||||
nsXBLBinding* binding =
|
||||
aContext.OwnerDoc().BindingManager()->GetBindingWithContent(this);
|
||||
|
||||
if (binding) {
|
||||
binding->BindAnonymousContent(binding->GetAnonymousContent(), this);
|
||||
}
|
||||
}
|
||||
|
||||
// Call BindToTree on shadow root children.
|
||||
nsresult rv;
|
||||
if (ShadowRoot* shadowRoot = GetShadowRoot()) {
|
||||
@ -1839,8 +1643,6 @@ nsresult Element::BindToTree(BindContext& aContext, nsINode& aParent) {
|
||||
MOZ_ASSERT(IsInComposedDoc() == aContext.InComposedDoc());
|
||||
MOZ_ASSERT(IsInUncomposedDoc() == aContext.InUncomposedDoc());
|
||||
MOZ_ASSERT(&aParent == GetParentNode(), "Bound to wrong parent node");
|
||||
MOZ_ASSERT(aContext.GetBindingParent() == GetBindingParent(),
|
||||
"Bound to wrong binding parent");
|
||||
MOZ_ASSERT(aParent.IsInUncomposedDoc() == IsInUncomposedDoc());
|
||||
MOZ_ASSERT(aParent.IsInComposedDoc() == IsInComposedDoc());
|
||||
MOZ_ASSERT(aParent.IsInShadowTree() == IsInShadowTree());
|
||||
@ -1848,32 +1650,6 @@ nsresult Element::BindToTree(BindContext& aContext, nsINode& aParent) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RemoveFromBindingManagerRunnable::RemoveFromBindingManagerRunnable(
|
||||
nsBindingManager* aManager, nsIContent* aContent, Document* aDoc)
|
||||
: mozilla::Runnable("dom::RemoveFromBindingManagerRunnable"),
|
||||
mManager(aManager),
|
||||
mContent(aContent),
|
||||
mDoc(aDoc) {}
|
||||
|
||||
RemoveFromBindingManagerRunnable::~RemoveFromBindingManagerRunnable() {}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RemoveFromBindingManagerRunnable::Run() {
|
||||
// It may be the case that the element was removed from the
|
||||
// DOM, causing this runnable to be created, then inserted back
|
||||
// into the document before the this runnable had a chance to
|
||||
// tear down the binding. Only tear down the binding if the element
|
||||
// is still no longer in the DOM. nsXBLService::LoadBinding tears
|
||||
// down the old binding if the element is inserted back into the
|
||||
// DOM and loads a different binding.
|
||||
if (!mContent->IsInComposedDoc()) {
|
||||
mManager->RemovedFromDocumentInternal(mContent, mDoc,
|
||||
nsBindingManager::eRunDtor);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool WillDetachFromShadowOnUnbind(const Element& aElement, bool aNullParent) {
|
||||
// If our parent still is in a shadow tree by now, and we're not removing
|
||||
// ourselves from it, then we're still going to be in a shadow tree after
|
||||
@ -1950,6 +1726,11 @@ void Element::UnbindFromTree(bool aNullParent) {
|
||||
"propagated scrollbar styles) - that's dangerous...");
|
||||
}
|
||||
}
|
||||
|
||||
# ifdef ACCESSIBILITY
|
||||
MOZ_ASSERT(!GetAccService() || !GetAccService()->HasAccessible(this),
|
||||
"An accessible for this element still exists!");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Ensure that CSS transitions don't continue on an element at a
|
||||
@ -1997,41 +1778,13 @@ void Element::UnbindFromTree(bool aNullParent) {
|
||||
SetSubtreeRootPointer(aNullParent ? this : mParent->SubtreeRoot());
|
||||
}
|
||||
|
||||
bool clearBindingParent = true;
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
if (nsXULElement* xulElem = nsXULElement::FromNode(this)) {
|
||||
xulElem->SetXULBindingParent(nullptr);
|
||||
clearBindingParent = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots()) {
|
||||
if (clearBindingParent) {
|
||||
slots->mBindingParent = nullptr;
|
||||
}
|
||||
if (aNullParent || !mParent->IsInShadowTree()) {
|
||||
slots->mContainingShadow = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (document) {
|
||||
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
|
||||
// Notify XBL- & nsIAnonymousContentCreator-generated anonymous content
|
||||
// that the document is changing.
|
||||
nsContentUtils::AddScriptRunner(new RemoveFromBindingManagerRunnable(
|
||||
document->BindingManager(), this, document));
|
||||
nsXBLBinding* binding =
|
||||
document->BindingManager()->GetBindingWithContent(this);
|
||||
if (binding) {
|
||||
nsXBLBinding::UnbindAnonymousContent(document,
|
||||
binding->GetAnonymousContent(),
|
||||
/* aNullParent */ false);
|
||||
}
|
||||
}
|
||||
|
||||
document->ClearBoxObjectFor(this);
|
||||
|
||||
// Disconnected must be enqueued whenever a connected custom element becomes
|
||||
// disconnected.
|
||||
CustomElementData* data = GetCustomElementData();
|
||||
@ -2553,13 +2306,6 @@ nsresult Element::SetAttrAndNotify(
|
||||
oldValue = aOldValue;
|
||||
}
|
||||
|
||||
if (aComposedDocument) {
|
||||
RefPtr<nsXBLBinding> binding = GetXBLBinding();
|
||||
if (binding) {
|
||||
binding->AttributeChanged(aName, aNamespaceID, false, aNotify);
|
||||
}
|
||||
}
|
||||
|
||||
if (HasElementCreatedFromPrototypeAndHasUnmodifiedL10n() &&
|
||||
aNamespaceID == kNameSpaceID_None &&
|
||||
(aName == nsGkAtoms::datal10nid || aName == nsGkAtoms::datal10nargs)) {
|
||||
@ -2874,13 +2620,6 @@ nsresult Element::UnsetAttr(int32_t aNameSpaceID, nsAtom* aName, bool aNotify) {
|
||||
|
||||
PostIdMaybeChange(aNameSpaceID, aName, nullptr);
|
||||
|
||||
if (document) {
|
||||
RefPtr<nsXBLBinding> binding = GetXBLBinding();
|
||||
if (binding) {
|
||||
binding->AttributeChanged(aName, aNameSpaceID, true, aNotify);
|
||||
}
|
||||
}
|
||||
|
||||
const CustomElementData* data = GetCustomElementData();
|
||||
if (data && data->mState == CustomElementData::State::eCustom) {
|
||||
CustomElementDefinition* definition = data->GetCustomElementDefinition();
|
||||
@ -3004,51 +2743,6 @@ void Element::List(FILE* out, int32_t aIndent, const nsCString& aPrefix) const {
|
||||
}
|
||||
|
||||
fputs(">\n", out);
|
||||
|
||||
Element* nonConstThis = const_cast<Element*>(this);
|
||||
|
||||
// XXX sXBL/XBL2 issue! Owner or current document?
|
||||
Document* document = OwnerDoc();
|
||||
|
||||
// Note: not listing nsIAnonymousContentCreator-created content...
|
||||
|
||||
nsBindingManager* bindingManager = document->BindingManager();
|
||||
nsINodeList* anonymousChildren =
|
||||
bindingManager->GetAnonymousNodesFor(nonConstThis);
|
||||
|
||||
if (anonymousChildren) {
|
||||
uint32_t length = anonymousChildren->Length();
|
||||
|
||||
for (indent = aIndent; --indent >= 0;) fputs(" ", out);
|
||||
fputs("anonymous-children<\n", out);
|
||||
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
nsIContent* child = anonymousChildren->Item(i);
|
||||
child->List(out, aIndent + 1);
|
||||
}
|
||||
|
||||
for (indent = aIndent; --indent >= 0;) fputs(" ", out);
|
||||
fputs(">\n", out);
|
||||
|
||||
bool outHeader = false;
|
||||
ExplicitChildIterator iter(nonConstThis);
|
||||
for (nsIContent* child = iter.GetNextChild(); child;
|
||||
child = iter.GetNextChild()) {
|
||||
if (!outHeader) {
|
||||
outHeader = true;
|
||||
|
||||
for (indent = aIndent; --indent >= 0;) fputs(" ", out);
|
||||
fputs("content-list<\n", out);
|
||||
}
|
||||
|
||||
child->List(out, aIndent + 1);
|
||||
}
|
||||
|
||||
if (outHeader) {
|
||||
for (indent = aIndent; --indent >= 0;) fputs(" ", out);
|
||||
fputs(">\n", out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Element::DumpContent(FILE* out, int32_t aIndent, bool aDumpAll) const {
|
||||
@ -3192,7 +2886,7 @@ nsresult Element::PostHandleEventForLinks(EventChainPostVisitor& aVisitor) {
|
||||
aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
|
||||
|
||||
if (IsInComposedDoc()) {
|
||||
if (nsIFocusManager* fm = nsFocusManager::GetFocusManager()) {
|
||||
if (nsFocusManager* fm = nsFocusManager::GetFocusManager()) {
|
||||
RefPtr<Element> kungFuDeathGrip(this);
|
||||
fm->SetFocus(kungFuDeathGrip, nsIFocusManager::FLAG_BYMOUSE |
|
||||
nsIFocusManager::FLAG_NOSCROLL);
|
||||
@ -4099,11 +3793,6 @@ void Element::GetCustomInterface(nsGetterAddRefs<T> aResult) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, check the binding manager to see if it implements the interface
|
||||
// for this element.
|
||||
OwnerDoc()->BindingManager()->GetBindingImplementation(
|
||||
this, NS_GET_TEMPLATE_IID(T), aResult);
|
||||
}
|
||||
|
||||
void Element::ClearServoData(Document* aDoc) {
|
||||
|
@ -222,22 +222,6 @@ class Element : public FragmentOrElement {
|
||||
*/
|
||||
void SetTabIndex(int32_t aTabIndex, mozilla::ErrorResult& aError);
|
||||
|
||||
/**
|
||||
* Sets or unsets an XBL binding for this element. Setting a
|
||||
* binding on an element that already has a binding will remove the
|
||||
* old binding.
|
||||
*
|
||||
* @param aBinding The binding to bind to this content. If nullptr is
|
||||
* provided as the argument, then existing binding will be
|
||||
* removed.
|
||||
*
|
||||
* @param aOldBindingManager The old binding manager that contains
|
||||
* this content if this content was adopted
|
||||
* to another document.
|
||||
*/
|
||||
void SetXBLBinding(nsXBLBinding* aBinding,
|
||||
nsBindingManager* aOldBindingManager = nullptr);
|
||||
|
||||
/**
|
||||
* Sets the ShadowRoot binding for this element. The contents of the
|
||||
* binding is rendered in place of this node's children.
|
||||
@ -456,8 +440,6 @@ class Element : public FragmentOrElement {
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::StyleUrlOrNone GetBindingURL(Document* aDocument);
|
||||
|
||||
Directionality GetComputedDirectionality() const;
|
||||
|
||||
static const uint32_t kAllServoDescendantBits =
|
||||
@ -1444,8 +1426,6 @@ class Element : public FragmentOrElement {
|
||||
*/
|
||||
static CORSMode AttrValueToCORSMode(const nsAttrValue* aValue);
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
|
||||
|
||||
nsINode* GetScopeChainParent() const override;
|
||||
|
||||
/**
|
||||
@ -1914,20 +1894,6 @@ class Element : public FragmentOrElement {
|
||||
AttrArray mAttrs;
|
||||
};
|
||||
|
||||
class RemoveFromBindingManagerRunnable : public mozilla::Runnable {
|
||||
public:
|
||||
RemoveFromBindingManagerRunnable(nsBindingManager* aManager,
|
||||
nsIContent* aContent, Document* aDoc);
|
||||
|
||||
NS_IMETHOD Run() override;
|
||||
|
||||
private:
|
||||
virtual ~RemoveFromBindingManagerRunnable();
|
||||
RefPtr<nsBindingManager> mManager;
|
||||
RefPtr<nsIContent> mContent;
|
||||
RefPtr<Document> mDoc;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(Element, NS_ELEMENT_IID)
|
||||
|
||||
inline bool Element::HasAttr(int32_t aNameSpaceID, const nsAtom* aName) const {
|
||||
|
@ -49,7 +49,6 @@
|
||||
#include "nsNameSpaceManager.h"
|
||||
#include "nsContentList.h"
|
||||
#include "nsDOMTokenList.h"
|
||||
#include "nsXBLPrototypeBinding.h"
|
||||
#include "nsError.h"
|
||||
#include "nsDOMString.h"
|
||||
#include "mozilla/InternalMutationEvent.h"
|
||||
@ -64,11 +63,8 @@
|
||||
# include "nsRange.h"
|
||||
#endif
|
||||
|
||||
#include "nsBindingManager.h"
|
||||
#include "nsFrameLoader.h"
|
||||
#include "nsXBLBinding.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsPIBoxObject.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsContentUtils.h"
|
||||
@ -154,11 +150,10 @@ NS_IMPL_MAIN_THREAD_ONLY_CYCLE_COLLECTING_RELEASE_WITH_LAST_RELEASE_AND_DESTROY(
|
||||
nsIContent* nsIContent::FindFirstNonChromeOnlyAccessContent() const {
|
||||
// This handles also nested native anonymous content.
|
||||
for (const nsIContent* content = this; content;
|
||||
content = content->GetBindingParent()) {
|
||||
content = content->GetChromeOnlyAccessSubtreeRootParent()) {
|
||||
if (!content->ChromeOnlyAccess()) {
|
||||
// Oops, this function signature allows casting const to
|
||||
// non-const. (Then again, so does
|
||||
// GetChildAt_Deprecated(0)->GetParent().)
|
||||
// non-const. (Then again, so does GetFirstChild()->GetParent().)
|
||||
return const_cast<nsIContent*>(content);
|
||||
}
|
||||
}
|
||||
@ -522,28 +517,20 @@ static_assert(sizeof(FragmentOrElement::nsDOMSlots) <= MaxDOMSlotSizeAllowed,
|
||||
"DOM slots cannot be grown without consideration");
|
||||
|
||||
void nsIContent::nsExtendedContentSlots::UnlinkExtendedSlots() {
|
||||
mBindingParent = nullptr;
|
||||
mXBLInsertionPoint = nullptr;
|
||||
mContainingShadow = nullptr;
|
||||
mAssignedSlot = nullptr;
|
||||
}
|
||||
|
||||
void nsIContent::nsExtendedContentSlots::TraverseExtendedSlots(
|
||||
nsCycleCollectionTraversalCallback& aCb) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mBindingParent");
|
||||
aCb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mBindingParent));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mContainingShadow");
|
||||
aCb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mContainingShadow));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mAssignedSlot");
|
||||
aCb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mAssignedSlot.get()));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mXBLInsertionPoint");
|
||||
aCb.NoteXPCOMChild(mXBLInsertionPoint.get());
|
||||
}
|
||||
|
||||
nsIContent::nsExtendedContentSlots::nsExtendedContentSlots() {}
|
||||
nsIContent::nsExtendedContentSlots::nsExtendedContentSlots() = default;
|
||||
|
||||
nsIContent::nsExtendedContentSlots::~nsExtendedContentSlots() = default;
|
||||
|
||||
@ -629,13 +616,12 @@ size_t FragmentOrElement::nsDOMSlots::SizeOfIncludingThis(
|
||||
|
||||
// The following member are not measured:
|
||||
// - mControllers: because it is non-owning
|
||||
// - mBindingParent: because it is some ancestor element.
|
||||
return n;
|
||||
}
|
||||
|
||||
FragmentOrElement::nsExtendedDOMSlots::nsExtendedDOMSlots() = default;
|
||||
|
||||
FragmentOrElement::nsExtendedDOMSlots::~nsExtendedDOMSlots() {}
|
||||
FragmentOrElement::nsExtendedDOMSlots::~nsExtendedDOMSlots() = default;
|
||||
|
||||
void FragmentOrElement::nsExtendedDOMSlots::UnlinkExtendedSlots() {
|
||||
nsIContent::nsExtendedContentSlots::UnlinkExtendedSlots();
|
||||
@ -670,10 +656,6 @@ void FragmentOrElement::nsExtendedDOMSlots::TraverseExtendedSlots(
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mShadowRoot");
|
||||
aCb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mShadowRoot));
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mXBLBinding");
|
||||
aCb.NoteNativeChild(mXBLBinding,
|
||||
NS_CYCLE_COLLECTION_PARTICIPANT(nsXBLBinding));
|
||||
|
||||
if (mCustomElementData) {
|
||||
mCustomElementData->Traverse(aCb);
|
||||
}
|
||||
@ -707,12 +689,6 @@ size_t FragmentOrElement::nsExtendedDOMSlots::SizeOfExcludingThis(
|
||||
// mShadowRoot should be handled during normal DOM tree memory reporting, just
|
||||
// like kids, siblings, etc.
|
||||
|
||||
// We don't seem to have memory reporting for nsXBLBinding. At least
|
||||
// report the memory it's using directly.
|
||||
if (mXBLBinding) {
|
||||
n += aMallocSizeOf(mXBLBinding);
|
||||
}
|
||||
|
||||
if (mCustomElementData) {
|
||||
n += mCustomElementData->SizeOfIncludingThis(aMallocSizeOf);
|
||||
}
|
||||
@ -878,23 +854,12 @@ void nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
|
||||
aVisitor.mEventTargetAtParent = parent;
|
||||
} else if (parent && aVisitor.mOriginalTargetIsInAnon) {
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aVisitor.mEvent->mTarget));
|
||||
if (content && content->GetBindingParent() == parent) {
|
||||
if (content &&
|
||||
content->GetClosestNativeAnonymousSubtreeRootParent() == parent) {
|
||||
aVisitor.mEventTargetAtParent = parent;
|
||||
}
|
||||
}
|
||||
|
||||
// check for an anonymous parent
|
||||
// XXX XBL2/sXBL issue
|
||||
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
|
||||
nsIContent* insertionParent = GetXBLInsertionParent();
|
||||
NS_ASSERTION(!(aVisitor.mEventTargetAtParent && insertionParent &&
|
||||
aVisitor.mEventTargetAtParent != insertionParent),
|
||||
"Retargeting and having insertion parent!");
|
||||
if (insertionParent) {
|
||||
parent = insertionParent;
|
||||
}
|
||||
}
|
||||
|
||||
if (!aVisitor.mEvent->mFlags.mComposedInNativeAnonymousContent &&
|
||||
IsRootOfNativeAnonymousSubtree() && OwnerDoc()->GetWindow()) {
|
||||
aVisitor.SetParentTarget(OwnerDoc()->GetWindow()->GetParentTarget(), true);
|
||||
@ -1067,58 +1032,11 @@ bool FragmentOrElement::IsLink(nsIURI** aURI) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsXBLBinding* FragmentOrElement::DoGetXBLBinding() const {
|
||||
MOZ_ASSERT(HasFlag(NODE_MAY_BE_IN_BINDING_MNGR));
|
||||
const nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
return slots ? slots->mXBLBinding.get() : nullptr;
|
||||
}
|
||||
|
||||
nsIContent* nsIContent::GetContainingShadowHost() const {
|
||||
if (mozilla::dom::ShadowRoot* shadow = GetContainingShadow()) {
|
||||
return shadow->GetHost();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void nsIContent::SetAssignedSlot(HTMLSlotElement* aSlot) {
|
||||
MOZ_ASSERT(aSlot || GetExistingExtendedContentSlots());
|
||||
ExtendedContentSlots()->mAssignedSlot = aSlot;
|
||||
}
|
||||
|
||||
void nsIContent::SetXBLInsertionPoint(nsIContent* aContent) {
|
||||
if (aContent) {
|
||||
nsExtendedContentSlots* slots = ExtendedContentSlots();
|
||||
SetFlags(NODE_MAY_BE_IN_BINDING_MNGR);
|
||||
slots->mXBLInsertionPoint = aContent;
|
||||
} else {
|
||||
if (nsExtendedContentSlots* slots = GetExistingExtendedContentSlots()) {
|
||||
slots->mXBLInsertionPoint = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void nsIContent::AssertAnonymousSubtreeRelatedInvariants() const {
|
||||
MOZ_ASSERT(!IsRootOfNativeAnonymousSubtree() ||
|
||||
(GetParent() && GetBindingParent() == GetParent()),
|
||||
"root of native anonymous subtree must have parent equal "
|
||||
"to binding parent");
|
||||
MOZ_ASSERT(!GetParent() || !IsInComposedDoc() ||
|
||||
((GetBindingParent() == GetParent()) ==
|
||||
HasFlag(NODE_IS_ANONYMOUS_ROOT)) ||
|
||||
// Unfortunately default content for XBL insertion points
|
||||
// is anonymous content that is bound with the parent of
|
||||
// the insertion point as the parent but the bound element
|
||||
// for the binding as the binding parent. So we have to
|
||||
// complicate the assert a bit here.
|
||||
(GetBindingParent() &&
|
||||
(GetBindingParent() == GetParent()->GetBindingParent()) ==
|
||||
HasFlag(NODE_IS_ANONYMOUS_ROOT)),
|
||||
"For connected nodes, flag and GetBindingParent() check "
|
||||
"should match");
|
||||
}
|
||||
#endif
|
||||
|
||||
void FragmentOrElement::GetTextContentInternal(nsAString& aTextContent,
|
||||
OOMReporter& aError) {
|
||||
if (!nsContentUtils::GetNodeTextContent(this, true, aTextContent, fallible)) {
|
||||
@ -1143,12 +1061,6 @@ void FragmentOrElement::DestroyContent() {
|
||||
AsElement()->ClearServoData();
|
||||
}
|
||||
|
||||
Document* document = OwnerDoc();
|
||||
|
||||
document->BindingManager()->RemovedFromDocument(this, document,
|
||||
nsBindingManager::eRunDtor);
|
||||
document->ClearBoxObjectFor(this);
|
||||
|
||||
#ifdef DEBUG
|
||||
uint32_t oldChildCount = GetChildCount();
|
||||
#endif
|
||||
@ -1354,9 +1266,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FragmentOrElement)
|
||||
tmp->ExtendedDOMSlots()->mShadowRoot = nullptr;
|
||||
}
|
||||
|
||||
Document* doc = tmp->OwnerDoc();
|
||||
doc->BindingManager()->RemovedFromDocument(tmp, doc,
|
||||
nsBindingManager::eDoNotRunDtor);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(FragmentOrElement)
|
||||
@ -1581,10 +1490,6 @@ bool NodeHasActiveFrame(Document* aCurrentDoc, nsINode* aNode) {
|
||||
aNode->AsElement()->GetPrimaryFrame();
|
||||
}
|
||||
|
||||
bool OwnedByBindingManager(Document* aCurrentDoc, nsINode* aNode) {
|
||||
return aNode->IsElement() && aNode->AsElement()->GetXBLBinding();
|
||||
}
|
||||
|
||||
// CanSkip checks if aNode is known-live, and if it is, returns true. If aNode
|
||||
// is in a known-live DOM tree, CanSkip may also remove other objects from
|
||||
// purple buffer and unmark event listeners and user data. If the root of the
|
||||
@ -1600,8 +1505,7 @@ bool FragmentOrElement::CanSkip(nsINode* aNode, bool aRemovingAllowed) {
|
||||
bool unoptimizable = aNode->UnoptimizableCCNode();
|
||||
Document* currentDoc = aNode->GetComposedDoc();
|
||||
if (currentDoc && IsCertainlyAliveNode(aNode, currentDoc) &&
|
||||
(!unoptimizable || NodeHasActiveFrame(currentDoc, aNode) ||
|
||||
OwnedByBindingManager(currentDoc, aNode))) {
|
||||
(!unoptimizable || NodeHasActiveFrame(currentDoc, aNode))) {
|
||||
MarkNodeChildren(aNode);
|
||||
return true;
|
||||
}
|
||||
@ -1779,10 +1683,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(FragmentOrElement)
|
||||
}
|
||||
|
||||
nsAutoCString orphan;
|
||||
if (!tmp->IsInComposedDoc() &&
|
||||
// Ignore xbl:content, which is never in the document and hence always
|
||||
// appears to be orphaned.
|
||||
!tmp->NodeInfo()->Equals(nsGkAtoms::content, kNameSpaceID_XBL)) {
|
||||
if (!tmp->IsInComposedDoc()) {
|
||||
orphan.AppendLiteral(" (orphan)");
|
||||
}
|
||||
|
||||
@ -1800,8 +1701,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(FragmentOrElement)
|
||||
return NS_SUCCESS_INTERRUPTED_TRAVERSE;
|
||||
}
|
||||
|
||||
tmp->OwnerDoc()->BindingManager()->Traverse(tmp, cb);
|
||||
|
||||
// Check that whenever we have effect properties, MayHaveAnimations is set.
|
||||
#ifdef DEBUG
|
||||
nsAtom** effectProps = EffectSet::GetEffectSetPropertyAtoms();
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "nsIContent.h" // base class
|
||||
#include "nsIHTMLCollection.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsXBLBinding.h"
|
||||
|
||||
class ContentUnbinder;
|
||||
class nsContentList;
|
||||
@ -97,7 +96,6 @@ class FragmentOrElement : public nsIContent {
|
||||
virtual uint32_t TextLength() const override;
|
||||
virtual bool TextIsOnlyWhitespace() override;
|
||||
virtual bool ThreadSafeTextIsOnlyWhitespace() const override;
|
||||
virtual nsXBLBinding* DoGetXBLBinding() const override;
|
||||
virtual bool IsLink(nsIURI** aURI) const override;
|
||||
|
||||
virtual void DestroyContent() override;
|
||||
@ -185,11 +183,6 @@ class FragmentOrElement : public nsIContent {
|
||||
*/
|
||||
RefPtr<ShadowRoot> mShadowRoot;
|
||||
|
||||
/**
|
||||
* XBL binding installed on the element.
|
||||
*/
|
||||
RefPtr<nsXBLBinding> mXBLBinding;
|
||||
|
||||
/**
|
||||
* Web components custom element data.
|
||||
*/
|
||||
|
@ -88,7 +88,7 @@ class FullscreenRequest : public FullscreenChange {
|
||||
dom::CallerType::NonSystem, false));
|
||||
}
|
||||
|
||||
~FullscreenRequest() { MOZ_COUNT_DTOR(FullscreenRequest); }
|
||||
MOZ_COUNTED_DTOR(FullscreenRequest)
|
||||
|
||||
dom::Element* Element() const { return mElement; }
|
||||
|
||||
|
@ -8,9 +8,7 @@
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIReferrerInfo.h"
|
||||
#include "nsBindingManager.h"
|
||||
#include "nsEscape.h"
|
||||
#include "nsXBLPrototypeBinding.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -57,52 +55,19 @@ void IDTracker::ResetToURIFragmentID(nsIContent* aFromContent, nsIURI* aURI,
|
||||
if (NS_FAILED(rv) || ref.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
rv = NS_OK;
|
||||
|
||||
nsIContent* bindingParent = aFromContent->GetBindingParent();
|
||||
if (bindingParent && !aFromContent->IsInShadowTree()) {
|
||||
nsXBLBinding* binding = bindingParent->GetXBLBinding();
|
||||
if (!binding) {
|
||||
// This happens, for example, if aFromContent is part of the content
|
||||
// inserted by a call to Document::InsertAnonymousContent, which we
|
||||
// also want to handle. (It also happens for <use>'s anonymous
|
||||
// content etc.)
|
||||
Element* anonRoot =
|
||||
doc->GetAnonRootIfInAnonymousContentContainer(aFromContent);
|
||||
if (anonRoot) {
|
||||
mElement = nsContentUtils::MatchElementId(anonRoot, ref);
|
||||
// We don't have watching working yet for anonymous content, so bail out
|
||||
// here.
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
bool isEqualExceptRef;
|
||||
rv = aURI->EqualsExceptRef(binding->PrototypeBinding()->DocURI(),
|
||||
&isEqualExceptRef);
|
||||
if (NS_SUCCEEDED(rv) && isEqualExceptRef) {
|
||||
// XXX sXBL/XBL2 issue
|
||||
// Our content is an anonymous XBL element from a binding inside the
|
||||
// same document that the referenced URI points to. In order to avoid
|
||||
// the risk of ID collisions we restrict ourselves to anonymous
|
||||
// elements from this binding; specifically, URIs that are relative to
|
||||
// the binding document should resolve to the copy of the target
|
||||
// element that has been inserted into the bound document.
|
||||
// If the URI points to a different document we don't need this
|
||||
// restriction.
|
||||
nsINodeList* anonymousChildren =
|
||||
doc->BindingManager()->GetAnonymousNodesFor(bindingParent);
|
||||
|
||||
if (anonymousChildren) {
|
||||
uint32_t length = anonymousChildren->Length();
|
||||
for (uint32_t i = 0; i < length && !mElement; ++i) {
|
||||
mElement =
|
||||
nsContentUtils::MatchElementId(anonymousChildren->Item(i), ref);
|
||||
}
|
||||
}
|
||||
|
||||
// We don't have watching working yet for XBL, so bail out here.
|
||||
return;
|
||||
}
|
||||
if (aFromContent->IsInNativeAnonymousSubtree()) {
|
||||
// This happens, for example, if aFromContent is part of the content
|
||||
// inserted by a call to Document::InsertAnonymousContent, which we
|
||||
// also want to handle. (It also happens for other native anonymous content
|
||||
// etc.)
|
||||
Element* anonRoot =
|
||||
doc->GetAnonRootIfInAnonymousContentContainer(aFromContent);
|
||||
if (anonRoot) {
|
||||
mElement = nsContentUtils::MatchElementId(anonRoot, ref);
|
||||
// We don't have watching working yet for anonymous content, so bail out
|
||||
// here.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ Location::Location(nsPIDOMWindowInner* aWindow, nsIDocShell* aDocShell)
|
||||
mDocShell = do_GetWeakReference(aDocShell);
|
||||
}
|
||||
|
||||
Location::~Location() {}
|
||||
Location::~Location() = default;
|
||||
|
||||
// QueryInterface implementation for Location
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Location)
|
||||
|
@ -20,7 +20,6 @@
|
||||
#ifdef MOZ_XUL
|
||||
# include "nsXULElement.h"
|
||||
#endif
|
||||
#include "nsBindingManager.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "mozilla/AnimationTarget.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
@ -51,6 +50,10 @@ enum class IsRemoveNotification {
|
||||
# define COMPOSED_DOC_DECL
|
||||
#endif
|
||||
|
||||
#define CALL_BINDING_MANAGER(func_, params_) \
|
||||
do { \
|
||||
} while (0)
|
||||
|
||||
// This macro expects the ownerDocument of content_ to be in scope as
|
||||
// |Document* doc|
|
||||
#define IMPL_MUTATION_NOTIFICATION(func_, content_, params_, remove_) \
|
||||
@ -67,7 +70,7 @@ enum class IsRemoveNotification {
|
||||
presShell->func_ params_; \
|
||||
} \
|
||||
} \
|
||||
doc->BindingManager()->func_ params_; \
|
||||
CALL_BINDING_MANAGER(func_, params_); \
|
||||
nsINode* last; \
|
||||
do { \
|
||||
nsINode::nsSlots* slots = node->GetExistingSlots(); \
|
||||
|
@ -19,13 +19,12 @@ static const int32_t kNameSpaceID_None = 0;
|
||||
#define kNameSpaceID_XHTML 3
|
||||
#define kNameSpaceID_XLink 4
|
||||
#define kNameSpaceID_XSLT 5
|
||||
#define kNameSpaceID_XBL 6
|
||||
#define kNameSpaceID_MathML 7
|
||||
#define kNameSpaceID_RDF 8
|
||||
#define kNameSpaceID_XUL 9
|
||||
#define kNameSpaceID_SVG 10
|
||||
#define kNameSpaceID_disabled_MathML 11
|
||||
#define kNameSpaceID_disabled_SVG 12
|
||||
#define kNameSpaceID_LastBuiltin 12 // last 'built-in' namespace
|
||||
#define kNameSpaceID_MathML 6
|
||||
#define kNameSpaceID_RDF 7
|
||||
#define kNameSpaceID_XUL 8
|
||||
#define kNameSpaceID_SVG 9
|
||||
#define kNameSpaceID_disabled_MathML 10
|
||||
#define kNameSpaceID_disabled_SVG 11
|
||||
#define kNameSpaceID_LastBuiltin 11 // last 'built-in' namespace
|
||||
|
||||
#endif // mozilla_dom_NameSpaceConstants_h__
|
||||
|
55
dom/base/PlacesBookmarkRemoved.h
Normal file
55
dom/base/PlacesBookmarkRemoved.h
Normal file
@ -0,0 +1,55 @@
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_dom_PlacesBookmarkRemoved_h
|
||||
#define mozilla_dom_PlacesBookmarkRemoved_h
|
||||
|
||||
#include "mozilla/dom/PlacesBookmark.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class PlacesBookmarkRemoved final : public PlacesBookmark {
|
||||
public:
|
||||
explicit PlacesBookmarkRemoved()
|
||||
: PlacesBookmark(PlacesEventType::Bookmark_removed) {}
|
||||
|
||||
static already_AddRefed<PlacesBookmarkRemoved> Constructor(
|
||||
const GlobalObject& aGlobal, const PlacesBookmarkRemovedInit& aInitDict) {
|
||||
RefPtr<PlacesBookmarkRemoved> event = new PlacesBookmarkRemoved();
|
||||
event->mItemType = aInitDict.mItemType;
|
||||
event->mId = aInitDict.mId;
|
||||
event->mParentId = aInitDict.mParentId;
|
||||
event->mIndex = aInitDict.mIndex;
|
||||
event->mUrl = aInitDict.mUrl;
|
||||
event->mGuid = aInitDict.mGuid;
|
||||
event->mParentGuid = aInitDict.mParentGuid;
|
||||
event->mSource = aInitDict.mSource;
|
||||
event->mIsTagging = aInitDict.mIsTagging;
|
||||
event->mIsDescendantRemoval = aInitDict.mIsDescendantRemoval;
|
||||
return event.forget();
|
||||
}
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override {
|
||||
return PlacesBookmarkRemoved_Binding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
const PlacesBookmarkRemoved* AsPlacesBookmarkRemoved() const override {
|
||||
return this;
|
||||
}
|
||||
|
||||
int32_t Index() { return mIndex; }
|
||||
bool IsDescendantRemoval() { return mIsDescendantRemoval; }
|
||||
|
||||
int32_t mIndex;
|
||||
bool mIsDescendantRemoval;
|
||||
|
||||
private:
|
||||
~PlacesBookmarkRemoved() = default;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
@ -35,6 +35,9 @@ class PlacesEvent : public nsWrapperCache {
|
||||
virtual const PlacesBookmarkAddition* AsPlacesBookmarkAddition() const {
|
||||
return nullptr;
|
||||
}
|
||||
virtual const PlacesBookmarkRemoved* AsPlacesBookmarkRemoved() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~PlacesEvent() = default;
|
||||
|
@ -46,7 +46,7 @@ PostMessageEvent::PostMessageEvent(BrowsingContext* aSource,
|
||||
mCallerDocumentURI(aCallerDocumentURI),
|
||||
mIsFromPrivateWindow(aIsFromPrivateWindow) {}
|
||||
|
||||
PostMessageEvent::~PostMessageEvent() {}
|
||||
PostMessageEvent::~PostMessageEvent() = default;
|
||||
|
||||
NS_IMETHODIMP
|
||||
PostMessageEvent::Run() {
|
||||
|
@ -36,13 +36,15 @@ nsINode* RangeUtils::ComputeRootNode(nsINode* aNode) {
|
||||
nsIContent* content = aNode->AsContent();
|
||||
|
||||
// If the node is in a shadow tree then the ShadowRoot is the root.
|
||||
//
|
||||
// FIXME(emilio): Should this be after the NAC check below? We can have NAC
|
||||
// inside Shadow DOM which will peek this path rather than the one below.
|
||||
if (ShadowRoot* containingShadow = content->GetContainingShadow()) {
|
||||
return containingShadow;
|
||||
}
|
||||
|
||||
// If the node has a binding parent, that should be the root.
|
||||
// XXXbz maybe only for native anonymous content?
|
||||
if (nsINode* root = content->GetBindingParent()) {
|
||||
// If the node is in NAC, then the NAC parent should be the root.
|
||||
if (nsINode* root = content->GetClosestNativeAnonymousSubtreeRootParent()) {
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
@ -2816,7 +2816,7 @@ nsIFrame* Selection::GetSelectionAnchorGeometry(SelectionRegion aRegion,
|
||||
// make focusRect relative to anchorFrame
|
||||
focusRect += focusFrame->GetOffsetTo(anchorFrame);
|
||||
|
||||
aRect->UnionRectEdges(anchorRect, focusRect);
|
||||
*aRect = anchorRect.UnionEdges(focusRect);
|
||||
return anchorFrame;
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "ChildIterator.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsWindowSizes.h"
|
||||
#include "nsXBLPrototypeBinding.h"
|
||||
#include "mozilla/dom/DirectionalityUtils.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/HTMLSlotElement.h"
|
||||
@ -60,7 +59,6 @@ ShadowRoot::ShadowRoot(Element* aElement, ShadowRootMode aMode,
|
||||
SetFlags(NODE_IS_IN_SHADOW_TREE);
|
||||
Bind();
|
||||
|
||||
ExtendedDOMSlots()->mBindingParent = aElement;
|
||||
ExtendedDOMSlots()->mContainingShadow = this;
|
||||
}
|
||||
|
||||
@ -89,8 +87,8 @@ void ShadowRoot::AddSizeOfExcludingThis(nsWindowSizes& aSizes,
|
||||
ShadowRootAuthorStylesMallocEnclosingSizeOf, mServoStyles.get());
|
||||
}
|
||||
|
||||
JSObject* ShadowRoot::WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) {
|
||||
JSObject* ShadowRoot::WrapNode(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) {
|
||||
return mozilla::dom::ShadowRoot_Binding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
@ -521,7 +519,7 @@ void ShadowRoot::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
|
||||
aVisitor.SetParentTarget(shadowHost, false);
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aVisitor.mEvent->mTarget));
|
||||
if (content && content->GetBindingParent() == shadowHost) {
|
||||
if (content && content->GetContainingShadow() == this) {
|
||||
aVisitor.mEventTargetAtParent = shadowHost;
|
||||
}
|
||||
}
|
||||
@ -667,7 +665,7 @@ void ShadowRoot::MaybeUnslotHostChild(nsIContent& aChild) {
|
||||
"How did aChild end up assigned to a slot?");
|
||||
// If the slot is going to start showing fallback content, we need to tell
|
||||
// layout about it.
|
||||
if (slot->AssignedNodes().Length() == 1) {
|
||||
if (slot->AssignedNodes().Length() == 1 && slot->HasChildren()) {
|
||||
InvalidateStyleAndLayoutOnSubtree(slot);
|
||||
}
|
||||
|
||||
@ -693,7 +691,8 @@ void ShadowRoot::MaybeSlotHostChild(nsIContent& aChild) {
|
||||
}
|
||||
|
||||
// Fallback content will go away, let layout know.
|
||||
if (assignment.mSlot->AssignedNodes().IsEmpty()) {
|
||||
if (assignment.mSlot->AssignedNodes().IsEmpty() &&
|
||||
assignment.mSlot->HasChildren()) {
|
||||
InvalidateStyleAndLayoutOnSubtree(assignment.mSlot);
|
||||
}
|
||||
|
||||
|
@ -151,6 +151,10 @@ class ShadowRoot final : public DocumentFragment,
|
||||
void AddSlot(HTMLSlotElement* aSlot);
|
||||
void RemoveSlot(HTMLSlotElement* aSlot);
|
||||
bool HasSlots() const { return !mSlotMap.IsEmpty(); };
|
||||
HTMLSlotElement* GetDefaultSlot() const {
|
||||
SlotArray* list = mSlotMap.Get(NS_LITERAL_STRING(""));
|
||||
return list ? (*list)->ElementAt(0) : nullptr;
|
||||
}
|
||||
|
||||
void PartAdded(const Element&);
|
||||
void PartRemoved(const Element&);
|
||||
@ -167,8 +171,7 @@ class ShadowRoot final : public DocumentFragment,
|
||||
|
||||
mozilla::ServoStyleRuleMap& ServoStyleRuleMap();
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
JSObject* WrapNode(JSContext*, JS::Handle<JSObject*> aGivenProto) final;
|
||||
|
||||
void NodeInfoChanged(Document* aOldDoc) override {
|
||||
DocumentFragment::NodeInfoChanged(aOldDoc);
|
||||
|
@ -86,15 +86,6 @@ void Text::GetWholeText(nsAString& aWholeText, ErrorResult& aRv) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t index = parent->ComputeIndexOf(this);
|
||||
NS_WARNING_ASSERTION(index >= 0,
|
||||
"Trying to use .wholeText with an anonymous"
|
||||
"text node child of a binding parent?");
|
||||
if (NS_WARN_IF(index < 0)) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
Text* first = FirstLogicallyAdjacentTextNode(this);
|
||||
Text* last = LastLogicallyAdjacentTextNode(this);
|
||||
|
||||
|
@ -33,7 +33,7 @@ class TimeoutHandler : public nsISupports {
|
||||
TimeoutHandler() : mFileName(""), mLineNo(0), mColumn(0) {}
|
||||
explicit TimeoutHandler(JSContext* aCx);
|
||||
|
||||
virtual ~TimeoutHandler() {}
|
||||
virtual ~TimeoutHandler() = default;
|
||||
|
||||
// filename, line number and JS language version string of the
|
||||
// caller of setTimeout()
|
||||
@ -60,7 +60,7 @@ class ScriptTimeoutHandler : public TimeoutHandler {
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual ~ScriptTimeoutHandler() {}
|
||||
virtual ~ScriptTimeoutHandler() = default;
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> mGlobal;
|
||||
// The expression to evaluate or function to call. If mFunction is non-null
|
||||
|
@ -2,7 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="import" href="1027461-inner.xul">
|
||||
<link rel="import" href="1027461-inner.xhtml">
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<iframe id="iframe" src="1370968-inner.xul"></iframe>
|
||||
<iframe id="iframe" src="1370968-inner.xhtml"></iframe>
|
||||
<script>
|
||||
var io = new IntersectionObserver(function () {
|
||||
}, { });
|
||||
|
@ -1,3 +0,0 @@
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" onload="var button=document.getElementsByTagName('button')[0]; try { button.appendChild(SpecialPowers.unwrap(SpecialPowers.wrap(document).getAnonymousNodes(button))[0]); } catch(e) { }">
|
||||
<button/>
|
||||
</window>
|
@ -1,35 +0,0 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
|
||||
|
||||
<head>
|
||||
|
||||
<script>
|
||||
|
||||
function init()
|
||||
{
|
||||
var foopy = document.getElementById("foopy");
|
||||
var emb = document.getElementById("emb");
|
||||
|
||||
try {
|
||||
foopy.appendChild(SpecialPowers.unwrap(SpecialPowers.wrap(document).getAnonymousNodes(emb))[0]);
|
||||
emb.parentNode.removeChild(emb);
|
||||
foopy.parentNode.removeChild(foopy);
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
||||
|
||||
window.addEventListener("load", function() { setTimeout(init, 30); }, false);
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="foopy"/>
|
||||
|
||||
<embed src="data:foo/bar,baz" id="emb" />
|
||||
|
||||
</body>
|
||||
</html>
|
@ -4,6 +4,6 @@
|
||||
setTimeout('document.documentElement.className = ""', 500);
|
||||
</script>
|
||||
<body>
|
||||
<iframe src="384663-1-inner.xul"></iframe>
|
||||
<iframe src="384663-1-inner.xhtml"></iframe>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -7,7 +7,6 @@ load 231475-1.html
|
||||
load 244933-1.html
|
||||
load 275912-1.html
|
||||
load 293388-1.html
|
||||
load 308120-1.xul
|
||||
load 325730-1.html
|
||||
load 326618-1.html
|
||||
load 326646-1.html
|
||||
@ -16,7 +15,6 @@ load 327571-1.html
|
||||
load 327694.html
|
||||
load 327695-1.html
|
||||
load 329481-1.xhtml
|
||||
load 330925-1.xhtml
|
||||
load 336381-1.xhtml
|
||||
load 336715-1.xhtml
|
||||
load 338391-1.xhtml
|
||||
@ -204,9 +202,9 @@ load 1326194-2.html
|
||||
load 1332939.html
|
||||
load 1341693.html
|
||||
load 1352453.html
|
||||
load 1353529.xul
|
||||
load chrome://reftest/content/crashtests/dom/base/crashtests/1353529.xhtml
|
||||
load 1368327.html
|
||||
load 1369363.xul
|
||||
load chrome://reftest/content/crashtests/dom/base/crashtests/1369363.xhtml
|
||||
load 1370072.html
|
||||
pref(clipboard.autocopy,true) load 1370737.html
|
||||
load 1370968.html
|
||||
|
@ -210,6 +210,7 @@ EXPORTS.mozilla.dom += [
|
||||
'ParentProcessMessageManager.h',
|
||||
'PlacesBookmark.h',
|
||||
'PlacesBookmarkAddition.h',
|
||||
'PlacesBookmarkRemoved.h',
|
||||
'PlacesEvent.h',
|
||||
'PlacesObservers.h',
|
||||
'PlacesVisit.h',
|
||||
@ -501,7 +502,6 @@ LOCAL_INCLUDES += [
|
||||
'/dom/storage',
|
||||
'/dom/svg',
|
||||
'/dom/u2f',
|
||||
'/dom/xbl',
|
||||
'/dom/xml',
|
||||
'/dom/xslt/xpath',
|
||||
'/dom/xul',
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "XULDocument.h"
|
||||
#include "InProcessBrowserChildMessageManager.h"
|
||||
#include "nsIWindowMediator.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
@ -17,7 +16,7 @@
|
||||
#include "nsISHEntry.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsIXULWindow.h"
|
||||
#include "nsIAppWindow.h"
|
||||
#include "nsIAppShellService.h"
|
||||
#include "nsAppShellCID.h"
|
||||
#include "nsContentUtils.h"
|
||||
@ -351,23 +350,12 @@ nsresult nsCCUncollectableMarker::Observe(nsISupports* aSubject,
|
||||
bool hasHiddenWindow = false;
|
||||
appShell->GetHasHiddenWindow(&hasHiddenWindow);
|
||||
if (hasHiddenWindow) {
|
||||
nsCOMPtr<nsIXULWindow> hw;
|
||||
nsCOMPtr<nsIAppWindow> hw;
|
||||
appShell->GetHiddenWindow(getter_AddRefs(hw));
|
||||
nsCOMPtr<nsIDocShell> shell;
|
||||
hw->GetDocShell(getter_AddRefs(shell));
|
||||
MarkDocShell(shell, cleanupJS);
|
||||
}
|
||||
bool hasHiddenPrivateWindow = false;
|
||||
appShell->GetHasHiddenPrivateWindow(&hasHiddenPrivateWindow);
|
||||
if (hasHiddenPrivateWindow) {
|
||||
nsCOMPtr<nsIXULWindow> hw;
|
||||
appShell->GetHiddenPrivateWindow(getter_AddRefs(hw));
|
||||
if (hw) {
|
||||
nsCOMPtr<nsIDocShell> shell;
|
||||
hw->GetDocShell(getter_AddRefs(shell));
|
||||
MarkDocShell(shell, cleanupJS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
|
@ -285,7 +285,7 @@ nsContentAreaDragDropDataProvider::GetFlavorData(nsITransferable* aTransferable,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
newFileName.Append(".");
|
||||
newFileName.Append(primaryExtension);
|
||||
targetFilename = NS_ConvertUTF8toUTF16(newFileName);
|
||||
CopyUTF8toUTF16(newFileName, targetFilename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ class nsContentAreaDragDrop {
|
||||
// during the drop instead of when it is added to the drag data transfer. This
|
||||
// ensures that the image data is only created when an image drop is allowed.
|
||||
class nsContentAreaDragDropDataProvider : public nsIFlavorDataProvider {
|
||||
virtual ~nsContentAreaDragDropDataProvider() {}
|
||||
virtual ~nsContentAreaDragDropDataProvider() = default;
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -98,7 +98,6 @@ inline const char* NS_CP_ContentTypeName(uint32_t contentType) {
|
||||
CASE_RETURN(TYPE_DOCUMENT);
|
||||
CASE_RETURN(TYPE_SUBDOCUMENT);
|
||||
CASE_RETURN(TYPE_REFRESH);
|
||||
CASE_RETURN(TYPE_XBL);
|
||||
CASE_RETURN(TYPE_PING);
|
||||
CASE_RETURN(TYPE_XMLHTTPREQUEST);
|
||||
CASE_RETURN(TYPE_OBJECT_SUBREQUEST);
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/DocumentInlines.h"
|
||||
#include "mozilla/dom/MessageBroadcaster.h"
|
||||
#include "mozilla/dom/MessagePort.h"
|
||||
#include "mozilla/dom/DocumentFragment.h"
|
||||
#include "mozilla/dom/DOMException.h"
|
||||
#include "mozilla/dom/DOMExceptionBinding.h"
|
||||
@ -120,7 +121,6 @@
|
||||
#include "nsAttrName.h"
|
||||
#include "nsAttrValue.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
#include "nsBindingManager.h"
|
||||
#include "nsCanvasFrame.h"
|
||||
#include "nsCaret.h"
|
||||
#include "nsCCUncollectableMarker.h"
|
||||
@ -565,7 +565,7 @@ class nsContentUtils::UserInteractionObserver final
|
||||
static Atomic<bool> sUserActive;
|
||||
|
||||
private:
|
||||
~UserInteractionObserver() {}
|
||||
~UserInteractionObserver() = default;
|
||||
};
|
||||
|
||||
/* static */
|
||||
@ -2101,7 +2101,7 @@ bool nsContentUtils::IsCallerContentXBL() {
|
||||
return true;
|
||||
}
|
||||
|
||||
return xpc::IsContentXBLScope(realm);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool nsContentUtils::IsCallerUAWidget() {
|
||||
@ -2134,9 +2134,7 @@ bool nsContentUtils::ThreadsafeIsSystemCaller(JSContext* aCx) {
|
||||
bool nsContentUtils::LookupBindingMember(
|
||||
JSContext* aCx, nsIContent* aContent, JS::Handle<jsid> aId,
|
||||
JS::MutableHandle<JS::PropertyDescriptor> aDesc) {
|
||||
nsXBLBinding* binding = aContent->GetXBLBinding();
|
||||
if (!binding) return true;
|
||||
return binding->LookupMember(aCx, aId, aDesc);
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
@ -3551,7 +3549,6 @@ void nsContentUtils::GetEventArgNames(int32_t aNameSpaceID, nsAtom* aEventName,
|
||||
static const char* gPropertiesFiles[nsContentUtils::PropertiesFile_COUNT] = {
|
||||
// Must line up with the enum values in |PropertiesFile| enum.
|
||||
"chrome://global/locale/css.properties",
|
||||
"chrome://global/locale/xbl.properties",
|
||||
"chrome://global/locale/xul.properties",
|
||||
"chrome://global/locale/layout_errors.properties",
|
||||
"chrome://global/locale/layout/HtmlForm.properties",
|
||||
@ -4270,7 +4267,7 @@ void nsContentUtils::RequestFrameFocus(Element& aFrameElement, bool aCanRaise) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFocusManager> fm = nsFocusManager::GetFocusManager();
|
||||
RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager();
|
||||
if (!fm) {
|
||||
return;
|
||||
}
|
||||
@ -4409,14 +4406,6 @@ bool nsContentUtils::HasMutationListeners(nsINode* aNode, uint32_t aType,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aNode->IsContent()) {
|
||||
nsIContent* insertionPoint = aNode->AsContent()->GetXBLInsertionPoint();
|
||||
if (insertionPoint) {
|
||||
aNode = insertionPoint->GetParent();
|
||||
MOZ_ASSERT(aNode);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
aNode = aNode->GetParentNode();
|
||||
}
|
||||
|
||||
@ -5173,18 +5162,18 @@ bool nsContentUtils::IsInSameAnonymousTree(const nsINode* aNode,
|
||||
MOZ_ASSERT(aNode, "Must have a node to work with");
|
||||
MOZ_ASSERT(aContent, "Must have a content to work with");
|
||||
|
||||
if (!aNode->IsContent()) {
|
||||
/**
|
||||
* The root isn't an nsIContent, so it's a document or attribute. The only
|
||||
* nodes in the same anonymous subtree as it will have a null
|
||||
* bindingParent.
|
||||
*
|
||||
* XXXbz strictly speaking, that's not true for attribute nodes.
|
||||
*/
|
||||
return aContent->GetBindingParent() == nullptr;
|
||||
if (aNode->IsInNativeAnonymousSubtree() != aContent->IsInNativeAnonymousSubtree()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return aNode->AsContent()->GetBindingParent() == aContent->GetBindingParent();
|
||||
if (aNode->IsInNativeAnonymousSubtree()) {
|
||||
return aContent->GetClosestNativeAnonymousSubtreeRoot() ==
|
||||
aNode->GetClosestNativeAnonymousSubtreeRoot();
|
||||
}
|
||||
|
||||
// FIXME: This doesn't deal with disconnected nodes whatsoever, but it didn't
|
||||
// use to either. Maybe that's fine.
|
||||
return aNode->GetContainingShadow() == aContent->GetContainingShadow();
|
||||
}
|
||||
|
||||
/* static */
|
||||
@ -5937,7 +5926,7 @@ nsresult nsContentUtils::GetUTFOrigin(nsIPrincipal* aPrincipal,
|
||||
asciiOrigin.AssignLiteral("null");
|
||||
}
|
||||
|
||||
aOrigin = NS_ConvertUTF8toUTF16(asciiOrigin);
|
||||
CopyUTF8toUTF16(asciiOrigin, aOrigin);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -5963,7 +5952,7 @@ nsresult nsContentUtils::GetUTFOrigin(nsIURI* aURI, nsAString& aOrigin) {
|
||||
rv = GetASCIIOrigin(aURI, asciiOrigin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aOrigin = NS_ConvertUTF8toUTF16(asciiOrigin);
|
||||
CopyUTF8toUTF16(asciiOrigin, aOrigin);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -8853,7 +8842,7 @@ void nsContentUtils::GetPresentationURL(nsIDocShell* aDocShell,
|
||||
|
||||
nsAutoCString uriStr;
|
||||
uri->GetSpec(uriStr);
|
||||
aPresentationUrl = NS_ConvertUTF8toUTF16(uriStr);
|
||||
CopyUTF8toUTF16(uriStr, aPresentationUrl);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -9496,11 +9485,8 @@ void nsContentUtils::AppendDocumentLevelNativeAnonymousContentTo(
|
||||
"scroll frame should always implement nsIAnonymousContentCreator");
|
||||
creator->AppendAnonymousContentTo(aElements, 0);
|
||||
}
|
||||
|
||||
if (nsCanvasFrame* canvasFrame = presShell->GetCanvasFrame()) {
|
||||
if (Element* container = canvasFrame->GetCustomContentContainer()) {
|
||||
aElements.AppendElement(container);
|
||||
}
|
||||
canvasFrame->AppendAnonymousContentTo(aElements, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9660,6 +9646,41 @@ nsresult nsContentUtils::CreateJSValueFromSequenceOfObject(
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void nsContentUtils::StructuredClone(JSContext* aCx, nsIGlobalObject* aGlobal,
|
||||
JS::Handle<JS::Value> aValue,
|
||||
const StructuredSerializeOptions& aOptions,
|
||||
JS::MutableHandle<JS::Value> aRetval,
|
||||
ErrorResult& aError) {
|
||||
JS::Rooted<JS::Value> transferArray(aCx, JS::UndefinedValue());
|
||||
aError = nsContentUtils::CreateJSValueFromSequenceOfObject(
|
||||
aCx, aOptions.mTransfer, &transferArray);
|
||||
if (NS_WARN_IF(aError.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
JS::CloneDataPolicy clonePolicy;
|
||||
//clonePolicy.allowIntraClusterClonableSharedObjects();
|
||||
//clonePolicy.allowSharedMemoryObjects();
|
||||
clonePolicy.denySharedArrayBuffer();
|
||||
|
||||
StructuredCloneHolder holder(StructuredCloneHolder::CloningSupported,
|
||||
StructuredCloneHolder::TransferringSupported,
|
||||
JS::StructuredCloneScope::SameProcess);
|
||||
holder.Write(aCx, aValue, transferArray, clonePolicy, aError);
|
||||
if (NS_WARN_IF(aError.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
holder.Read(aGlobal, aCx, aRetval, aError);
|
||||
if (NS_WARN_IF(aError.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsTArray<RefPtr<MessagePort>> ports = holder.TakeTransferredPorts();
|
||||
Unused << ports;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool nsContentUtils::ShouldBlockReservedKeys(WidgetKeyboardEvent* aKeyEvent) {
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
|
@ -153,6 +153,7 @@ class MessageBroadcaster;
|
||||
class NodeInfo;
|
||||
class Selection;
|
||||
class StaticRange;
|
||||
struct StructuredSerializeOptions;
|
||||
class WorkerPrivate;
|
||||
} // namespace dom
|
||||
|
||||
@ -1118,7 +1119,6 @@ class nsContentUtils {
|
||||
*/
|
||||
enum PropertiesFile {
|
||||
eCSS_PROPERTIES,
|
||||
eXBL_PROPERTIES,
|
||||
eXUL_PROPERTIES,
|
||||
eLAYOUT_PROPERTIES,
|
||||
eFORMS_PROPERTIES,
|
||||
@ -3098,6 +3098,15 @@ class nsContentUtils {
|
||||
JSContext* aCx, const mozilla::dom::Sequence<JSObject*>& aTransfer,
|
||||
JS::MutableHandle<JS::Value> aValue);
|
||||
|
||||
/**
|
||||
* This implements the structured cloning algorithm as described by
|
||||
* https://html.spec.whatwg.org/#structured-cloning.
|
||||
*/
|
||||
static void StructuredClone(
|
||||
JSContext* aCx, nsIGlobalObject* aGlobal, JS::Handle<JS::Value> aValue,
|
||||
const mozilla::dom::StructuredSerializeOptions& aOptions,
|
||||
JS::MutableHandle<JS::Value> aRetval, mozilla::ErrorResult& aError);
|
||||
|
||||
/**
|
||||
* Returns true if reserved key events should be prevented from being sent
|
||||
* to their target. Instead, the key event should be handled by chrome only.
|
||||
|
@ -117,15 +117,6 @@ static nsresult EncodeForTextUnicode(nsIDocumentEncoder& aEncoder,
|
||||
rv = aEncoder.GetMimeType(mimeType);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!selForcedTextPlain && mimeType.EqualsLiteral(kTextMime)) {
|
||||
// SetSelection and EncodeToString use this case to signal that text/plain
|
||||
// was forced because the document is either not an HTMLDocument or it's
|
||||
// XHTML. We want to pretty print XHTML but not non-HTMLDocuments.
|
||||
if (!aDocument.IsHTMLOrXHTML()) {
|
||||
selForcedTextPlain = true;
|
||||
}
|
||||
}
|
||||
|
||||
// The mime type is ultimately text/html if the encoder successfully encoded
|
||||
// the selection as text/html.
|
||||
aEncodedAsTextHTMLResult = mimeType.EqualsLiteral(kHTMLMime);
|
||||
|
@ -49,8 +49,7 @@ class nsAttrKey {
|
||||
nsAttrKey(int32_t aNs, nsAtom* aName)
|
||||
: mNamespaceID(aNs), mLocalName(aName) {}
|
||||
|
||||
nsAttrKey(const nsAttrKey& aAttr)
|
||||
: mNamespaceID(aAttr.mNamespaceID), mLocalName(aAttr.mLocalName) {}
|
||||
nsAttrKey(const nsAttrKey& aAttr) = default;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -63,7 +62,7 @@ class nsAttrHashKey : public PLDHashEntryHdr {
|
||||
|
||||
explicit nsAttrHashKey(KeyTypePointer aKey) : mKey(*aKey) {}
|
||||
nsAttrHashKey(const nsAttrHashKey& aCopy) : mKey(aCopy.mKey) {}
|
||||
~nsAttrHashKey() {}
|
||||
~nsAttrHashKey() = default;
|
||||
|
||||
KeyType GetKey() const { return mKey; }
|
||||
bool KeyEquals(KeyTypePointer aKey) const {
|
||||
|
@ -31,7 +31,7 @@ class nsDOMMutationObserver;
|
||||
using mozilla::dom::MutationObservingInfo;
|
||||
|
||||
class nsDOMMutationRecord final : public nsISupports, public nsWrapperCache {
|
||||
virtual ~nsDOMMutationRecord() {}
|
||||
virtual ~nsDOMMutationRecord() = default;
|
||||
|
||||
public:
|
||||
typedef nsTArray<RefPtr<mozilla::dom::Animation>> AnimationArray;
|
||||
@ -112,7 +112,7 @@ class nsDOMMutationRecord final : public nsISupports, public nsWrapperCache {
|
||||
// members to make sure we go through getters/setters.
|
||||
class nsMutationReceiverBase : public nsStubAnimationObserver {
|
||||
public:
|
||||
virtual ~nsMutationReceiverBase() {}
|
||||
virtual ~nsMutationReceiverBase() = default;
|
||||
|
||||
nsDOMMutationObserver* Observer();
|
||||
nsINode* Target() { return mParent ? mParent->Target() : mTarget; }
|
||||
@ -398,7 +398,7 @@ class nsAnimationReceiver : public nsMutationReceiver {
|
||||
NS_DECL_NSIANIMATIONOBSERVER_ANIMATIONREMOVED
|
||||
|
||||
protected:
|
||||
virtual ~nsAnimationReceiver() {}
|
||||
virtual ~nsAnimationReceiver() = default;
|
||||
|
||||
nsAnimationReceiver(nsINode* aTarget, nsDOMMutationObserver* aObserver)
|
||||
: nsMutationReceiver(aTarget, aObserver) {}
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsCaret.h"
|
||||
#include "nsIBaseWindow.h"
|
||||
#include "nsIXULWindow.h"
|
||||
#include "nsIAppWindow.h"
|
||||
#include "nsTextControlFrame.h"
|
||||
#include "nsViewManager.h"
|
||||
#include "nsFrameSelection.h"
|
||||
@ -33,7 +33,6 @@
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIObjectFrame.h"
|
||||
#include "nsBindingManager.h"
|
||||
#include "BrowserChild.h"
|
||||
#include "nsFrameLoader.h"
|
||||
#include "nsHTMLDocument.h"
|
||||
@ -250,7 +249,9 @@ static nsPIDOMWindowOuter* GetContentWindow(nsIContent* aContent) {
|
||||
Document* doc = aContent->GetComposedDoc();
|
||||
if (doc) {
|
||||
Document* subdoc = doc->GetSubDocumentFor(aContent);
|
||||
if (subdoc) return subdoc->GetWindow();
|
||||
if (subdoc) {
|
||||
return subdoc->GetWindow();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@ -319,17 +320,12 @@ Element* nsFocusManager::GetFocusedDescendant(
|
||||
Element* nsFocusManager::GetRedirectedFocus(nsIContent* aContent) {
|
||||
#ifdef MOZ_XUL
|
||||
if (aContent->IsXULElement()) {
|
||||
if (aContent->IsXULElement(nsGkAtoms::textbox)) {
|
||||
return aContent->OwnerDoc()->GetAnonymousElementByAttribute(
|
||||
aContent, nsGkAtoms::anonid, NS_LITERAL_STRING("input"));
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMXULMenuListElement> menulist =
|
||||
aContent->AsElement()->AsXULMenuList();
|
||||
if (menulist) {
|
||||
RefPtr<Element> inputField;
|
||||
menulist->GetInputField(getter_AddRefs(inputField));
|
||||
return inputField;
|
||||
}
|
||||
nsCOMPtr<nsIDOMXULMenuListElement> menulist =
|
||||
aContent->AsElement()->AsXULMenuList();
|
||||
if (menulist) {
|
||||
RefPtr<Element> inputField;
|
||||
menulist->GetInputField(getter_AddRefs(inputField));
|
||||
return inputField;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -408,7 +404,9 @@ NS_IMETHODIMP nsFocusManager::SetFocusedWindow(
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> rootWindow = windowToFocus->GetPrivateRoot();
|
||||
if (rootWindow) RaiseWindow(rootWindow);
|
||||
if (rootWindow) {
|
||||
RaiseWindow(rootWindow);
|
||||
}
|
||||
|
||||
LOGFOCUS(("<<SetFocusedWindow end>>"));
|
||||
|
||||
@ -430,7 +428,9 @@ nsFocusManager::GetLastFocusMethod(mozIDOMWindowProxy* aWindow,
|
||||
if (aWindow) {
|
||||
window = nsPIDOMWindowOuter::From(aWindow);
|
||||
}
|
||||
if (!window) window = mFocusedWindow;
|
||||
if (!window) {
|
||||
window = mFocusedWindow;
|
||||
}
|
||||
|
||||
*aLastFocusMethod = window ? window->GetFocusMethod() : 0;
|
||||
|
||||
@ -559,7 +559,9 @@ nsFocusManager::GetFocusedElementForWindow(mozIDOMWindowProxy* aWindow,
|
||||
mozIDOMWindowProxy** aFocusedWindow,
|
||||
Element** aElement) {
|
||||
*aElement = nullptr;
|
||||
if (aFocusedWindow) *aFocusedWindow = nullptr;
|
||||
if (aFocusedWindow) {
|
||||
*aFocusedWindow = nullptr;
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(aWindow, NS_ERROR_INVALID_ARG);
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
|
||||
@ -573,7 +575,9 @@ nsFocusManager::GetFocusedElementForWindow(mozIDOMWindowProxy* aWindow,
|
||||
|
||||
focusedElement.forget(aElement);
|
||||
|
||||
if (aFocusedWindow) NS_IF_ADDREF(*aFocusedWindow = focusedWindow);
|
||||
if (aFocusedWindow) {
|
||||
NS_IF_ADDREF(*aFocusedWindow = focusedWindow);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -590,7 +594,9 @@ nsFocusManager::MoveCaretToFocus(mozIDOMWindowProxy* aWindow) {
|
||||
// don't move the caret for editable documents
|
||||
bool isEditable;
|
||||
docShell->GetEditable(&isEditable);
|
||||
if (isEditable) return NS_OK;
|
||||
if (isEditable) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<PresShell> presShell = docShell->GetPresShell();
|
||||
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
|
||||
@ -606,9 +612,11 @@ nsFocusManager::MoveCaretToFocus(mozIDOMWindowProxy* aWindow) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFocusManager::WindowRaised(mozIDOMWindowProxy* aWindow) {
|
||||
NS_ENSURE_TRUE(aWindow, NS_ERROR_INVALID_ARG);
|
||||
void nsFocusManager::WindowRaised(mozIDOMWindowProxy* aWindow) {
|
||||
if (!aWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
|
||||
|
||||
if (MOZ_LOG_TEST(gFocusLog, LogLevel::Debug)) {
|
||||
@ -637,7 +645,7 @@ nsFocusManager::WindowRaised(mozIDOMWindowProxy* aWindow) {
|
||||
// what the focus manager thinks should be the current widget is actually
|
||||
// focused.
|
||||
EnsureCurrentWidgetFocused();
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
// lower the existing window, if any. This shouldn't happen usually.
|
||||
@ -646,7 +654,9 @@ nsFocusManager::WindowRaised(mozIDOMWindowProxy* aWindow) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem = window->GetDocShell();
|
||||
// If there's no docShellAsItem, this window must have been closed,
|
||||
// in that case there is no tree owner.
|
||||
NS_ENSURE_TRUE(docShellAsItem, NS_OK);
|
||||
if (!docShellAsItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
// set this as the active window
|
||||
mActiveWindow = window;
|
||||
@ -658,7 +668,7 @@ nsFocusManager::WindowRaised(mozIDOMWindowProxy* aWindow) {
|
||||
if (baseWindow) {
|
||||
bool isEnabled = true;
|
||||
if (NS_SUCCEEDED(baseWindow->GetEnabled(&isEnabled)) && !isEnabled) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return;
|
||||
}
|
||||
|
||||
baseWindow->SetVisibility(true);
|
||||
@ -680,19 +690,21 @@ nsFocusManager::WindowRaised(mozIDOMWindowProxy* aWindow) {
|
||||
window, eIncludeAllDescendants, getter_AddRefs(currentWindow));
|
||||
|
||||
NS_ASSERTION(currentWindow, "window raised with no window current");
|
||||
if (!currentWindow) return NS_OK;
|
||||
if (!currentWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If there is no nsIXULWindow, then this is an embedded or child process
|
||||
// If there is no nsIAppWindow, then this is an embedded or child process
|
||||
// window. Pass false for aWindowRaised so that commands get updated.
|
||||
nsCOMPtr<nsIXULWindow> xulWin(do_GetInterface(baseWindow));
|
||||
Focus(currentWindow, currentFocus, 0, true, false, xulWin != nullptr, true);
|
||||
|
||||
return NS_OK;
|
||||
nsCOMPtr<nsIAppWindow> appWin(do_GetInterface(baseWindow));
|
||||
Focus(currentWindow, currentFocus, 0, true, false, appWin != nullptr, true);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFocusManager::WindowLowered(mozIDOMWindowProxy* aWindow) {
|
||||
NS_ENSURE_TRUE(aWindow, NS_ERROR_INVALID_ARG);
|
||||
void nsFocusManager::WindowLowered(mozIDOMWindowProxy* aWindow) {
|
||||
if (!aWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
|
||||
|
||||
if (MOZ_LOG_TEST(gFocusLog, LogLevel::Debug)) {
|
||||
@ -712,7 +724,9 @@ nsFocusManager::WindowLowered(mozIDOMWindowProxy* aWindow) {
|
||||
}
|
||||
}
|
||||
|
||||
if (mActiveWindow != window) return NS_OK;
|
||||
if (mActiveWindow != window) {
|
||||
return;
|
||||
}
|
||||
|
||||
// clear the mouse capture as the active window has changed
|
||||
PresShell::ReleaseCapturingContent();
|
||||
@ -742,11 +756,11 @@ nsFocusManager::WindowLowered(mozIDOMWindowProxy* aWindow) {
|
||||
mWindowBeingLowered = mActiveWindow;
|
||||
mActiveWindow = nullptr;
|
||||
|
||||
if (mFocusedWindow) Blur(nullptr, nullptr, true, true);
|
||||
if (mFocusedWindow) {
|
||||
Blur(nullptr, nullptr, true, true);
|
||||
}
|
||||
|
||||
mWindowBeingLowered = nullptr;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsFocusManager::ContentRemoved(Document* aDocument,
|
||||
@ -755,15 +769,16 @@ nsresult nsFocusManager::ContentRemoved(Document* aDocument,
|
||||
NS_ENSURE_ARG(aContent);
|
||||
|
||||
nsPIDOMWindowOuter* window = aDocument->GetWindow();
|
||||
if (!window) return NS_OK;
|
||||
if (!window) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// if the content is currently focused in the window, or is an
|
||||
// shadow-including inclusive ancestor of the currently focused element,
|
||||
// reset the focus within that window.
|
||||
nsIContent* content = window->GetFocusedElement();
|
||||
Element* content = window->GetFocusedElement();
|
||||
if (content &&
|
||||
nsContentUtils::ContentIsHostIncludingDescendantOf(content, aContent)) {
|
||||
bool shouldShowFocusRing = window->ShouldShowFocusRing();
|
||||
window->SetFocusedElement(nullptr);
|
||||
|
||||
// if this window is currently focused, clear the global focused
|
||||
@ -803,16 +818,19 @@ nsresult nsFocusManager::ContentRemoved(Document* aDocument,
|
||||
}
|
||||
}
|
||||
|
||||
NotifyFocusStateChange(content, nullptr, shouldShowFocusRing, 0,
|
||||
/* aGettingFocus = */ false);
|
||||
NotifyFocusStateChange(content, nullptr, 0, /* aGettingFocus = */ false,
|
||||
false);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFocusManager::WindowShown(mozIDOMWindowProxy* aWindow, bool aNeedsFocus) {
|
||||
NS_ENSURE_TRUE(aWindow, NS_ERROR_INVALID_ARG);
|
||||
void nsFocusManager::WindowShown(mozIDOMWindowProxy* aWindow,
|
||||
bool aNeedsFocus) {
|
||||
if (!aWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
|
||||
|
||||
if (MOZ_LOG_TEST(gFocusLog, LogLevel::Debug)) {
|
||||
@ -840,31 +858,34 @@ nsFocusManager::WindowShown(mozIDOMWindowProxy* aWindow, bool aNeedsFocus) {
|
||||
}
|
||||
}
|
||||
|
||||
if (mFocusedWindow != window) return NS_OK;
|
||||
if (mFocusedWindow != window) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aNeedsFocus) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> currentWindow;
|
||||
RefPtr<Element> currentFocus = GetFocusedDescendant(
|
||||
window, eIncludeAllDescendants, getter_AddRefs(currentWindow));
|
||||
if (currentWindow)
|
||||
if (currentWindow) {
|
||||
Focus(currentWindow, currentFocus, 0, true, false, false, true);
|
||||
}
|
||||
} else {
|
||||
// Sometimes, an element in a window can be focused before the window is
|
||||
// visible, which would mean that the widget may not be properly focused.
|
||||
// When the window becomes visible, make sure the right widget is focused.
|
||||
EnsureCurrentWidgetFocused();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFocusManager::WindowHidden(mozIDOMWindowProxy* aWindow) {
|
||||
void nsFocusManager::WindowHidden(mozIDOMWindowProxy* aWindow) {
|
||||
// if there is no window or it is not the same or an ancestor of the
|
||||
// currently focused window, just return, as the current focus will not
|
||||
// be affected.
|
||||
|
||||
NS_ENSURE_TRUE(aWindow, NS_ERROR_INVALID_ARG);
|
||||
if (!aWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
|
||||
|
||||
if (MOZ_LOG_TEST(gFocusLog, LogLevel::Debug)) {
|
||||
@ -894,7 +915,9 @@ nsFocusManager::WindowHidden(mozIDOMWindowProxy* aWindow) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsSameOrAncestor(window, mFocusedWindow)) return NS_OK;
|
||||
if (!IsSameOrAncestor(window, mFocusedWindow)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// at this point, we know that the window being hidden is either the focused
|
||||
// window, or an ancestor of the focused window. Either way, the focus is no
|
||||
@ -903,11 +926,14 @@ nsFocusManager::WindowHidden(mozIDOMWindowProxy* aWindow) {
|
||||
RefPtr<Element> oldFocusedElement = std::move(mFocusedElement);
|
||||
|
||||
nsCOMPtr<nsIDocShell> focusedDocShell = mFocusedWindow->GetDocShell();
|
||||
if (!focusedDocShell) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<PresShell> presShell = focusedDocShell->GetPresShell();
|
||||
|
||||
if (oldFocusedElement && oldFocusedElement->IsInComposedDoc()) {
|
||||
NotifyFocusStateChange(oldFocusedElement, nullptr,
|
||||
mFocusedWindow->ShouldShowFocusRing(), 0, false);
|
||||
NotifyFocusStateChange(oldFocusedElement, nullptr, 0, false, false);
|
||||
window->UpdateCommands(u"focus"_ns, nullptr, 0);
|
||||
|
||||
if (presShell) {
|
||||
@ -942,11 +968,13 @@ nsFocusManager::WindowHidden(mozIDOMWindowProxy* aWindow) {
|
||||
// not happen if nsIAppStartup::eForceQuit is used to quit, and can cause
|
||||
// a leak. So if the active window is being destroyed, call WindowLowered
|
||||
// directly.
|
||||
if (mActiveWindow == mFocusedWindow || mActiveWindow == window)
|
||||
if (mActiveWindow == mFocusedWindow || mActiveWindow == window) {
|
||||
WindowLowered(mActiveWindow);
|
||||
else
|
||||
}
|
||||
else {
|
||||
ClearFocus(mActiveWindow);
|
||||
return NS_OK;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// if the window being hidden is an ancestor of the focused window, adjust
|
||||
@ -960,20 +988,19 @@ nsFocusManager::WindowHidden(mozIDOMWindowProxy* aWindow) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> parentDsti;
|
||||
dsti->GetInProcessParent(getter_AddRefs(parentDsti));
|
||||
if (parentDsti) {
|
||||
if (nsCOMPtr<nsPIDOMWindowOuter> parentWindow = parentDsti->GetWindow())
|
||||
if (nsCOMPtr<nsPIDOMWindowOuter> parentWindow =
|
||||
parentDsti->GetWindow()) {
|
||||
parentWindow->SetFocusedElement(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetFocusedWindowInternal(window);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFocusManager::FireDelayedEvents(Document* aDocument) {
|
||||
NS_ENSURE_ARG(aDocument);
|
||||
void nsFocusManager::FireDelayedEvents(Document* aDocument) {
|
||||
MOZ_ASSERT(aDocument);
|
||||
|
||||
// fire any delayed focus and blur events in the same order that they were
|
||||
// added
|
||||
@ -1000,36 +1027,90 @@ nsFocusManager::FireDelayedEvents(Document* aDocument) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFocusManager::FocusPlugin(Element* aPlugin) {
|
||||
nsresult nsFocusManager::FocusPlugin(Element* aPlugin) {
|
||||
NS_ENSURE_ARG(aPlugin);
|
||||
SetFocusInner(aPlugin, 0, true, false);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFocusManager::ParentActivated(mozIDOMWindowProxy* aWindow, bool aActive) {
|
||||
void nsFocusManager::ParentActivated(mozIDOMWindowProxy* aWindow,
|
||||
bool aActive) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
|
||||
NS_ENSURE_TRUE(window, NS_ERROR_INVALID_ARG);
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
||||
ActivateOrDeactivate(window, aActive);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool ShouldMatchFocusVisible(const Element& aElement,
|
||||
int32_t aFocusFlags) {
|
||||
switch (nsFocusManager::GetFocusMoveActionCause(aFocusFlags)) {
|
||||
case InputContextAction::CAUSE_UNKNOWN:
|
||||
case InputContextAction::CAUSE_KEY:
|
||||
nsFocusManager::BlurredElementInfo::BlurredElementInfo(Element& aElement)
|
||||
: mElement(aElement),
|
||||
mHadRing(aElement.State().HasState(NS_EVENT_STATE_FOCUSRING)) {}
|
||||
|
||||
nsFocusManager::BlurredElementInfo::~BlurredElementInfo() = default;
|
||||
|
||||
// https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo
|
||||
static bool ShouldMatchFocusVisible(
|
||||
nsPIDOMWindowOuter* aWindow, const Element& aElement, int32_t aFocusFlags,
|
||||
const Maybe<nsFocusManager::BlurredElementInfo>& aBlurredElementInfo,
|
||||
bool aIsRefocus, bool aRefocusedElementUsedToShowOutline) {
|
||||
// If we were explicitly requested to show the ring, do it.
|
||||
if (aFocusFlags & nsIFocusManager::FLAG_SHOWRING) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aWindow->ShouldShowFocusRing()) {
|
||||
// The window decision also trumps any other heuristic.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Any element which supports keyboard input (such as an input element, or any
|
||||
// other element which may trigger a virtual keyboard to be shown on focus if
|
||||
// a physical keyboard is not present) should always match :focus-visible when
|
||||
// focused.
|
||||
{
|
||||
if (aElement.IsHTMLElement(nsGkAtoms::textarea) || aElement.IsEditable()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (auto* input = HTMLInputElement::FromNode(aElement)) {
|
||||
if (input->IsSingleLineTextControl()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (nsFocusManager::GetFocusMoveActionCause(aFocusFlags)) {
|
||||
case InputContextAction::CAUSE_KEY:
|
||||
// If the user interacts with the page via the keyboard, the currently
|
||||
// focused element should match :focus-visible (i.e. keyboard usage may
|
||||
// change whether this pseudo-class matches even if it doesn't affect
|
||||
// :focus).
|
||||
return true;
|
||||
case InputContextAction::CAUSE_UNKNOWN:
|
||||
// If the active element matches :focus-visible, and a script causes focus
|
||||
// to move elsewhere, the newly focused element should match
|
||||
// :focus-visible.
|
||||
//
|
||||
// Conversely, if the active element does not match :focus-visible, and a
|
||||
// script causes focus to move elsewhere, the newly focused element should
|
||||
// not match :focus-visible.
|
||||
//
|
||||
// There's an special-case here. If this is a refocus, we just keep the
|
||||
// outline as it was before, the focus isn't moving after all.
|
||||
if (aIsRefocus) {
|
||||
return aRefocusedElementUsedToShowOutline;
|
||||
}
|
||||
return !aBlurredElementInfo || aBlurredElementInfo->mHadRing;
|
||||
case InputContextAction::CAUSE_MOUSE:
|
||||
case InputContextAction::CAUSE_TOUCH:
|
||||
case InputContextAction::CAUSE_LONGPRESS:
|
||||
break;
|
||||
// If the user interacts with the page via a pointing device, such that
|
||||
// the focus is moved to a new element which does not support user input,
|
||||
// the newly focused element should not match :focus-visible.
|
||||
return false;
|
||||
case InputContextAction::CAUSE_UNKNOWN_CHROME:
|
||||
case InputContextAction::CAUSE_UNKNOWN_DURING_KEYBOARD_INPUT:
|
||||
case InputContextAction::CAUSE_UNKNOWN_DURING_NON_KEYBOARD_INPUT:
|
||||
@ -1044,60 +1125,31 @@ static bool ShouldMatchFocusVisible(const Element& aElement,
|
||||
return false;
|
||||
}
|
||||
|
||||
// On Windows and Linux, focus rings are only shown when the FLAG_SHOWRING flag
|
||||
// is used.
|
||||
static bool ShouldShowFocusRingForElement(Element& aElement, int32_t aFlags) {
|
||||
if (aFlags & nsIFocusManager::FLAG_SHOWRING) {
|
||||
return true;
|
||||
}
|
||||
#if defined(XP_MACOSX) || defined(ANDROID)
|
||||
if (aFlags & nsIFocusManager::FLAG_BYMOUSE) {
|
||||
return !nsContentUtils::ContentIsLink(&aElement) &&
|
||||
!aElement.IsAnyOfHTMLElements(nsGkAtoms::video, nsGkAtoms::audio);
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* static */
|
||||
void nsFocusManager::NotifyFocusStateChange(nsIContent* aContent,
|
||||
nsIContent* aContentToFocus,
|
||||
bool aWindowShouldShowFocusRing,
|
||||
int32_t aFlags,
|
||||
bool aGettingFocus) {
|
||||
MOZ_ASSERT_IF(aContentToFocus, !aGettingFocus);
|
||||
auto* element = Element::FromNode(aContent);
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
void nsFocusManager::NotifyFocusStateChange(Element* aElement,
|
||||
Element* aElementToFocus,
|
||||
int32_t aFlags, bool aGettingFocus,
|
||||
bool aShouldShowFocusRing) {
|
||||
MOZ_ASSERT_IF(aElementToFocus, !aGettingFocus);
|
||||
nsIContent* commonAncestor = nullptr;
|
||||
if (aContentToFocus && aContentToFocus->IsElement()) {
|
||||
if (aElementToFocus) {
|
||||
commonAncestor = nsContentUtils::GetCommonFlattenedTreeAncestor(
|
||||
aContent, aContentToFocus);
|
||||
aElement, aElementToFocus);
|
||||
}
|
||||
|
||||
if (aGettingFocus) {
|
||||
EventStates eventStateToAdd = NS_EVENT_STATE_FOCUS;
|
||||
if (aWindowShouldShowFocusRing ||
|
||||
ShouldShowFocusRingForElement(*element, aFlags)) {
|
||||
if (aShouldShowFocusRing) {
|
||||
eventStateToAdd |= NS_EVENT_STATE_FOCUSRING;
|
||||
}
|
||||
if (aWindowShouldShowFocusRing ||
|
||||
ShouldMatchFocusVisible(*element, aFlags)) {
|
||||
eventStateToAdd |= NS_EVENT_STATE_FOCUS_VISIBLE;
|
||||
}
|
||||
element->AddStates(eventStateToAdd);
|
||||
aElement->AddStates(eventStateToAdd);
|
||||
} else {
|
||||
EventStates eventStateToRemove = NS_EVENT_STATE_FOCUS |
|
||||
NS_EVENT_STATE_FOCUSRING |
|
||||
NS_EVENT_STATE_FOCUS_VISIBLE;
|
||||
element->RemoveStates(eventStateToRemove);
|
||||
EventStates eventStateToRemove =
|
||||
NS_EVENT_STATE_FOCUS | NS_EVENT_STATE_FOCUSRING;
|
||||
aElement->RemoveStates(eventStateToRemove);
|
||||
}
|
||||
|
||||
for (nsIContent* content = aContent; content && content != commonAncestor;
|
||||
for (nsIContent* content = aElement; content && content != commonAncestor;
|
||||
content = content->GetFlattenedTreeParent()) {
|
||||
Element* element = Element::FromNode(content);
|
||||
if (!element) {
|
||||
@ -1169,7 +1221,7 @@ void nsFocusManager::ActivateOrDeactivate(nsPIDOMWindowOuter* aWindow,
|
||||
}
|
||||
|
||||
void nsFocusManager::SetFocusInner(Element* aNewContent, int32_t aFlags,
|
||||
bool aFocusChanged, bool aAdjustWidget) {
|
||||
bool aFocusChanged, bool aAdjustWidgets) {
|
||||
// if the element is not focusable, just return and leave the focus as is
|
||||
RefPtr<Element> elementToFocus =
|
||||
FlushAndCheckIfFocusable(aNewContent, aFlags);
|
||||
@ -1315,7 +1367,10 @@ void nsFocusManager::SetFocusInner(Element* aNewContent, int32_t aFlags,
|
||||
isElementInActiveWindow, isElementInFocusedWindow, sendFocusEvent));
|
||||
|
||||
if (sendFocusEvent) {
|
||||
RefPtr<Element> oldFocusedElement = mFocusedElement;
|
||||
Maybe<BlurredElementInfo> blurredInfo;
|
||||
if (mFocusedElement) {
|
||||
blurredInfo.emplace(*mFocusedElement);
|
||||
}
|
||||
// return if blurring fails or the focus changes during the blur
|
||||
if (mFocusedWindow) {
|
||||
// if the focus is being moved to another element in the same document,
|
||||
@ -1342,14 +1397,14 @@ void nsFocusManager::SetFocusInner(Element* aNewContent, int32_t aFlags,
|
||||
commonAncestor = GetCommonAncestor(newWindow, mFocusedWindow);
|
||||
|
||||
if (!Blur(currentIsSameOrAncestor ? mFocusedWindow.get() : nullptr,
|
||||
commonAncestor, !isElementInFocusedWindow, aAdjustWidget,
|
||||
commonAncestor, !isElementInFocusedWindow, aAdjustWidgets,
|
||||
elementToFocus)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Focus(newWindow, elementToFocus, aFlags, !isElementInFocusedWindow,
|
||||
aFocusChanged, false, aAdjustWidget, oldFocusedElement);
|
||||
aFocusChanged, false, aAdjustWidgets, blurredInfo);
|
||||
} else {
|
||||
// otherwise, for inactive windows and when the caller cannot steal the
|
||||
// focus, update the node in the window, and raise the window if desired.
|
||||
@ -1371,7 +1426,9 @@ void nsFocusManager::SetFocusInner(Element* aNewContent, int32_t aFlags,
|
||||
|
||||
// update the commands even when inactive so that the attributes for that
|
||||
// window are up to date.
|
||||
if (allowFrameSwitch) newWindow->UpdateCommands(u"focus"_ns, nullptr, 0);
|
||||
if (allowFrameSwitch) {
|
||||
newWindow->UpdateCommands(u"focus"_ns, nullptr, 0);
|
||||
}
|
||||
|
||||
if (aFlags & FLAG_RAISE) RaiseWindow(newRootWindow);
|
||||
}
|
||||
@ -1475,16 +1532,22 @@ void nsFocusManager::AdjustWindowFocus(nsPIDOMWindowOuter* aWindow,
|
||||
}
|
||||
|
||||
bool nsFocusManager::IsWindowVisible(nsPIDOMWindowOuter* aWindow) {
|
||||
if (!aWindow || aWindow->IsFrozen()) return false;
|
||||
if (!aWindow || aWindow->IsFrozen()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the inner window is frozen as well. This can happen when a focus
|
||||
// change occurs while restoring a previous page.
|
||||
nsPIDOMWindowInner* innerWindow = aWindow->GetCurrentInnerWindow();
|
||||
if (!innerWindow || innerWindow->IsFrozen()) return false;
|
||||
if (!innerWindow || innerWindow->IsFrozen()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell = aWindow->GetDocShell();
|
||||
nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(docShell));
|
||||
if (!baseWin) return false;
|
||||
if (!baseWin) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool visible = false;
|
||||
baseWin->GetVisibility(&visible);
|
||||
@ -1509,7 +1572,9 @@ bool nsFocusManager::IsNonFocusableRoot(nsIContent* aContent) {
|
||||
|
||||
Element* nsFocusManager::FlushAndCheckIfFocusable(Element* aElement,
|
||||
uint32_t aFlags) {
|
||||
if (!aElement) return nullptr;
|
||||
if (!aElement) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<Document> doc = aElement->GetComposedDoc();
|
||||
// can't focus elements that are not in documents
|
||||
@ -1585,7 +1650,7 @@ Element* nsFocusManager::FlushAndCheckIfFocusable(Element* aElement,
|
||||
bool nsFocusManager::Blur(nsPIDOMWindowOuter* aWindowToClear,
|
||||
nsPIDOMWindowOuter* aAncestorWindowToFocus,
|
||||
bool aIsLeavingDocument, bool aAdjustWidgets,
|
||||
nsIContent* aContentToFocus) {
|
||||
Element* aElementToFocus) {
|
||||
LOGFOCUS(("<<Blur begin>>"));
|
||||
|
||||
// hold a reference to the focused content, which may be null
|
||||
@ -1635,7 +1700,6 @@ bool nsFocusManager::Blur(nsPIDOMWindowOuter* aWindowToClear,
|
||||
// now adjust the actual focus, by clearing the fields in the focus manager
|
||||
// and in the window.
|
||||
mFocusedElement = nullptr;
|
||||
bool shouldShowFocusRing = window->ShouldShowFocusRing();
|
||||
if (aWindowToClear) aWindowToClear->SetFocusedElement(nullptr);
|
||||
|
||||
LOGCONTENT("Element %s has been blurred", element.get());
|
||||
@ -1645,8 +1709,7 @@ bool nsFocusManager::Blur(nsPIDOMWindowOuter* aWindowToClear,
|
||||
element && element->IsInComposedDoc() && !IsNonFocusableRoot(element);
|
||||
if (element) {
|
||||
if (sendBlurEvent) {
|
||||
NotifyFocusStateChange(element, aContentToFocus, shouldShowFocusRing, 0,
|
||||
false);
|
||||
NotifyFocusStateChange(element, aElementToFocus, 0, false, false);
|
||||
}
|
||||
|
||||
// if an object/plug-in/remote browser is being blurred, move the system
|
||||
@ -1702,11 +1765,12 @@ bool nsFocusManager::Blur(nsPIDOMWindowOuter* aWindowToClear,
|
||||
// if there is an active window, update commands. If there isn't an active
|
||||
// window, then this was a blur caused by the active window being lowered,
|
||||
// so there is no need to update the commands
|
||||
if (mActiveWindow)
|
||||
if (mActiveWindow) {
|
||||
window->UpdateCommands(u"focus"_ns, nullptr, 0);
|
||||
}
|
||||
|
||||
SendFocusOrBlurEvent(eBlur, presShell, element->GetComposedDoc(), element,
|
||||
1, false, false, aContentToFocus);
|
||||
1, false, false, aElementToFocus);
|
||||
}
|
||||
|
||||
// if we are leaving the document or the window was lowered, make the caret
|
||||
@ -1782,21 +1846,27 @@ void nsFocusManager::ActivateRemoteFrameIfNeeded(Element& aElement) {
|
||||
}
|
||||
}
|
||||
|
||||
void nsFocusManager::Focus(nsPIDOMWindowOuter* aWindow, Element* aElement,
|
||||
uint32_t aFlags, bool aIsNewDocument,
|
||||
bool aFocusChanged, bool aWindowRaised,
|
||||
bool aAdjustWidgets, nsIContent* aContentLostFocus) {
|
||||
void nsFocusManager::Focus(
|
||||
nsPIDOMWindowOuter* aWindow, Element* aElement, uint32_t aFlags,
|
||||
bool aIsNewDocument, bool aFocusChanged, bool aWindowRaised,
|
||||
bool aAdjustWidgets, const Maybe<BlurredElementInfo>& aBlurredElementInfo) {
|
||||
LOGFOCUS(("<<Focus begin>>"));
|
||||
|
||||
if (!aWindow) return;
|
||||
|
||||
if (aElement && (aElement == mFirstFocusEvent || aElement == mFirstBlurEvent))
|
||||
if (!aWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aElement &&
|
||||
(aElement == mFirstFocusEvent || aElement == mFirstBlurEvent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Keep a reference to the presShell since dispatching the DOM event may
|
||||
// cause the document to be destroyed.
|
||||
nsCOMPtr<nsIDocShell> docShell = aWindow->GetDocShell();
|
||||
if (!docShell) return;
|
||||
if (!docShell) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<PresShell> presShell = docShell->GetPresShell();
|
||||
if (!presShell) {
|
||||
@ -1848,7 +1918,9 @@ void nsFocusManager::Focus(nsPIDOMWindowOuter* aWindow, Element* aElement,
|
||||
}
|
||||
|
||||
// indicate that the window has taken focus.
|
||||
if (aWindow->TakeFocus(true, focusMethod)) aIsNewDocument = true;
|
||||
if (aWindow->TakeFocus(true, focusMethod)) {
|
||||
aIsNewDocument = true;
|
||||
}
|
||||
|
||||
SetFocusedWindowInternal(aWindow);
|
||||
|
||||
@ -1859,7 +1931,9 @@ void nsFocusManager::Focus(nsPIDOMWindowOuter* aWindow, Element* aElement,
|
||||
if (aElement) {
|
||||
nsIFrame* contentFrame = aElement->GetPrimaryFrame();
|
||||
nsIObjectFrame* objectFrame = do_QueryFrame(contentFrame);
|
||||
if (objectFrame) objectFrameWidget = objectFrame->GetWidget();
|
||||
if (objectFrame) {
|
||||
objectFrameWidget = objectFrame->GetWidget();
|
||||
}
|
||||
}
|
||||
if (aAdjustWidgets && !objectFrameWidget && !sTestMode) {
|
||||
if (nsViewManager* vm = presShell->GetViewManager()) {
|
||||
@ -1898,21 +1972,26 @@ void nsFocusManager::Focus(nsPIDOMWindowOuter* aWindow, Element* aElement,
|
||||
mFocusedElement = aElement;
|
||||
|
||||
nsIContent* focusedNode = aWindow->GetFocusedElement();
|
||||
bool isRefocus = focusedNode && focusedNode == aElement;
|
||||
const bool sendFocusEvent = aElement && aElement->IsInComposedDoc() &&
|
||||
!IsNonFocusableRoot(aElement);
|
||||
const bool isRefocus = focusedNode && focusedNode == aElement;
|
||||
const bool shouldShowFocusRing =
|
||||
sendFocusEvent &&
|
||||
ShouldMatchFocusVisible(
|
||||
aWindow, *aElement, aFlags, aBlurredElementInfo, isRefocus,
|
||||
isRefocus && aWindow->FocusedElementShowedOutline());
|
||||
|
||||
aWindow->SetFocusedElement(aElement, focusMethod);
|
||||
aWindow->SetFocusedElement(aElement, focusMethod, false,
|
||||
shouldShowFocusRing);
|
||||
|
||||
// if the focused element changed, scroll it into view
|
||||
if (aElement && aFocusChanged) {
|
||||
ScrollIntoView(presShell, aElement, aFlags);
|
||||
}
|
||||
|
||||
bool sendFocusEvent = aElement && aElement->IsInComposedDoc() &&
|
||||
!IsNonFocusableRoot(aElement);
|
||||
nsPresContext* presContext = presShell->GetPresContext();
|
||||
if (sendFocusEvent) {
|
||||
NotifyFocusStateChange(aElement, nullptr, aWindow->ShouldShowFocusRing(),
|
||||
aFlags, /* aGettingFocus = */ true);
|
||||
NotifyFocusStateChange(aElement, nullptr, aFlags,
|
||||
/* aGettingFocus = */ true, shouldShowFocusRing);
|
||||
|
||||
// if this is an object/plug-in/remote browser, focus its widget. Note
|
||||
// that we might no longer be in the same document, due to the events we
|
||||
@ -1933,12 +2012,15 @@ void nsFocusManager::Focus(nsPIDOMWindowOuter* aWindow, Element* aElement,
|
||||
// as long as this focus wasn't because a window was raised, update the
|
||||
// commands
|
||||
// XXXndeakin P2 someone could adjust the focus during the update
|
||||
if (!aWindowRaised)
|
||||
if (!aWindowRaised) {
|
||||
aWindow->UpdateCommands(u"focus"_ns, nullptr, 0);
|
||||
}
|
||||
|
||||
SendFocusOrBlurEvent(eFocus, presShell, aElement->GetComposedDoc(),
|
||||
aElement, aFlags & FOCUSMETHOD_MASK, aWindowRaised,
|
||||
isRefocus, aContentLostFocus);
|
||||
SendFocusOrBlurEvent(
|
||||
eFocus, presShell, aElement->GetComposedDoc(), aElement,
|
||||
aFlags & FOCUSMETHOD_MASK, aWindowRaised, isRefocus,
|
||||
aBlurredElementInfo ? aBlurredElementInfo->mElement.get()
|
||||
: nullptr);
|
||||
} else {
|
||||
IMEStateManager::OnChangeFocus(presContext, nullptr,
|
||||
GetFocusMoveActionCause(aFlags));
|
||||
@ -1969,7 +2051,9 @@ void nsFocusManager::Focus(nsPIDOMWindowOuter* aWindow, Element* aElement,
|
||||
GetFocusMoveActionCause(aFlags));
|
||||
}
|
||||
|
||||
if (!aWindowRaised) aWindow->UpdateCommands(u"focus"_ns, nullptr, 0);
|
||||
if (!aWindowRaised) {
|
||||
aWindow->UpdateCommands(u"focus"_ns, nullptr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// update the caret visibility and position to match the newly focused
|
||||
@ -1982,7 +2066,9 @@ void nsFocusManager::Focus(nsPIDOMWindowOuter* aWindow, Element* aElement,
|
||||
UpdateCaret(aFocusChanged && !(aFlags & FLAG_BYMOUSE), aIsNewDocument,
|
||||
mFocusedElement);
|
||||
|
||||
if (clearFirstFocusEvent) mFirstFocusEvent = nullptr;
|
||||
if (clearFirstFocusEvent) {
|
||||
mFirstFocusEvent = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
class FocusBlurEvent : public Runnable {
|
||||
@ -2217,10 +2303,14 @@ void nsFocusManager::RaiseWindow(nsPIDOMWindowOuter* aWindow) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> childWindow;
|
||||
GetFocusedDescendant(aWindow, eIncludeAllDescendants,
|
||||
getter_AddRefs(childWindow));
|
||||
if (!childWindow) childWindow = aWindow;
|
||||
if (!childWindow) {
|
||||
childWindow = aWindow;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell = aWindow->GetDocShell();
|
||||
if (!docShell) return;
|
||||
if (!docShell) {
|
||||
return;
|
||||
}
|
||||
|
||||
PresShell* presShell = docShell->GetPresShell();
|
||||
if (!presShell) {
|
||||
@ -2230,7 +2320,9 @@ void nsFocusManager::RaiseWindow(nsPIDOMWindowOuter* aWindow) {
|
||||
if (nsViewManager* vm = presShell->GetViewManager()) {
|
||||
nsCOMPtr<nsIWidget> widget;
|
||||
vm->GetRootWidget(getter_AddRefs(widget));
|
||||
if (widget) widget->SetFocus(nsIWidget::Raise::Yes);
|
||||
if (widget) {
|
||||
widget->SetFocus(nsIWidget::Raise::Yes);
|
||||
}
|
||||
}
|
||||
#else
|
||||
nsCOMPtr<nsIBaseWindow> treeOwnerAsWin =
|
||||
@ -2238,7 +2330,9 @@ void nsFocusManager::RaiseWindow(nsPIDOMWindowOuter* aWindow) {
|
||||
if (treeOwnerAsWin) {
|
||||
nsCOMPtr<nsIWidget> widget;
|
||||
treeOwnerAsWin->GetMainWidget(getter_AddRefs(widget));
|
||||
if (widget) widget->SetFocus(nsIWidget::Raise::Yes);
|
||||
if (widget) {
|
||||
widget->SetFocus(nsIWidget::Raise::Yes);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -2251,7 +2345,9 @@ void nsFocusManager::UpdateCaret(bool aMoveCaretToFocus, bool aUpdateVisibility,
|
||||
nsIContent* aContent) {
|
||||
LOGFOCUS(("Update Caret: %d %d", aMoveCaretToFocus, aUpdateVisibility));
|
||||
|
||||
if (!mFocusedWindow) return;
|
||||
if (!mFocusedWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
// this is called when a document is focused or when the caretbrowsing
|
||||
// preference is changed
|
||||
@ -2285,14 +2381,18 @@ void nsFocusManager::UpdateCaret(bool aMoveCaretToFocus, bool aUpdateVisibility,
|
||||
doc->GetEditingState() == Document::EditingState::eContentEditable;
|
||||
|
||||
bool isFocusEditable = aContent && aContent->HasFlag(NODE_IS_EDITABLE);
|
||||
if (!isContentEditableDoc || isFocusEditable) return;
|
||||
if (!isContentEditableDoc || isFocusEditable) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isEditable && aMoveCaretToFocus) {
|
||||
MoveCaretToFocus(presShell, aContent);
|
||||
}
|
||||
|
||||
if (!aUpdateVisibility) return;
|
||||
if (!aUpdateVisibility) {
|
||||
return;
|
||||
}
|
||||
|
||||
// XXXndeakin this doesn't seem right. It should be checking for this only
|
||||
// on the nearest ancestor frame which is a chrome frame. But this is
|
||||
@ -2352,17 +2452,23 @@ nsresult nsFocusManager::SetCaretVisible(PresShell* aPresShell, bool aVisible,
|
||||
// Return early if there is no caret. This can happen for the testcase
|
||||
// for bug 308025 where a window is closed in a blur handler.
|
||||
RefPtr<nsCaret> caret = aPresShell->GetCaret();
|
||||
if (!caret) return NS_OK;
|
||||
if (!caret) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool caretVisible = caret->IsVisible();
|
||||
if (!aVisible && !caretVisible) return NS_OK;
|
||||
if (!aVisible && !caretVisible) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<nsFrameSelection> frameSelection;
|
||||
if (aContent) {
|
||||
NS_ASSERTION(aContent->GetComposedDoc() == aPresShell->GetDocument(),
|
||||
"Wrong document?");
|
||||
nsIFrame* focusFrame = aContent->GetPrimaryFrame();
|
||||
if (focusFrame) frameSelection = focusFrame->GetFrameSelection();
|
||||
if (focusFrame) {
|
||||
frameSelection = focusFrame->GetFrameSelection();
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<nsFrameSelection> docFrameSelection = aPresShell->FrameSelection();
|
||||
@ -2618,19 +2724,22 @@ nsresult nsFocusManager::DetermineElementToMoveFocus(
|
||||
int32_t tabIndex = forward ? 1 : 0;
|
||||
if (startContent) {
|
||||
nsIFrame* frame = startContent->GetPrimaryFrame();
|
||||
if (startContent->IsHTMLElement(nsGkAtoms::area))
|
||||
if (startContent->IsHTMLElement(nsGkAtoms::area)) {
|
||||
startContent->IsFocusable(&tabIndex);
|
||||
else if (frame)
|
||||
} else if (frame) {
|
||||
frame->IsFocusable(&tabIndex, 0);
|
||||
else
|
||||
} else {
|
||||
startContent->IsFocusable(&tabIndex);
|
||||
}
|
||||
|
||||
// if the current element isn't tabbable, ignore the tabindex and just
|
||||
// look for the next element. The root content won't have a tabindex
|
||||
// so just treat this as the beginning of the tab order.
|
||||
if (tabIndex < 0) {
|
||||
tabIndex = 1;
|
||||
if (startContent != rootContent) ignoreTabIndex = true;
|
||||
if (startContent != rootContent) {
|
||||
ignoreTabIndex = true;
|
||||
}
|
||||
}
|
||||
|
||||
// check if the focus is currently inside a popup. Elements such as the
|
||||
@ -2666,7 +2775,9 @@ nsresult nsFocusManager::DetermineElementToMoveFocus(
|
||||
// if there is no focus, yet a panel is open, focus the first item in
|
||||
// the panel
|
||||
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
||||
if (pm) popupFrame = pm->GetTopPopup(ePopupTypePanel);
|
||||
if (pm) {
|
||||
popupFrame = pm->GetTopPopup(ePopupTypePanel);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (popupFrame) {
|
||||
@ -2813,7 +2924,9 @@ nsresult nsFocusManager::DetermineElementToMoveFocus(
|
||||
ignoreTabIndex = false;
|
||||
|
||||
if (aNoParentTraversal) {
|
||||
if (startContent == rootContent) return NS_OK;
|
||||
if (startContent == rootContent) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
startContent = rootContent;
|
||||
tabIndex = forward ? 1 : 0;
|
||||
@ -2875,10 +2988,11 @@ nsresult nsFocusManager::DetermineElementToMoveFocus(
|
||||
// If the tree owner took the focus, blur the current element.
|
||||
if (tookFocus) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = docShell->GetWindow();
|
||||
if (window->GetFocusedElement() == mFocusedElement)
|
||||
if (window->GetFocusedElement() == mFocusedElement) {
|
||||
Blur(mFocusedWindow, nullptr, true, true);
|
||||
else
|
||||
} else {
|
||||
window->SetFocusedElement(nullptr);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -2911,7 +3025,9 @@ nsresult nsFocusManager::DetermineElementToMoveFocus(
|
||||
|
||||
// wrapped all the way around and didn't find anything to move the focus
|
||||
// to, so just break out
|
||||
if (startContent == originalStartContent) break;
|
||||
if (startContent == originalStartContent) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -3604,10 +3720,11 @@ nsresult nsFocusManager::GetNextTabbableContent(
|
||||
// and the end of the span, and the span would end up getting focused
|
||||
// again.
|
||||
do {
|
||||
if (aForward)
|
||||
if (aForward) {
|
||||
frameTraversal->Next();
|
||||
else
|
||||
} else {
|
||||
frameTraversal->Prev();
|
||||
}
|
||||
frame = static_cast<nsIFrame*>(frameTraversal->CurrentItem());
|
||||
} while (frame && frame->GetPrevContinuation());
|
||||
}
|
||||
@ -3708,7 +3825,9 @@ nsIContent* nsFocusManager::GetNextTabbableMapArea(bool aForward,
|
||||
MOZ_ASSERT(imgElement);
|
||||
|
||||
nsCOMPtr<nsIContent> mapContent = imgElement->FindImageMap();
|
||||
if (!mapContent) return nullptr;
|
||||
if (!mapContent) {
|
||||
return nullptr;
|
||||
}
|
||||
uint32_t count = mapContent->GetChildCount();
|
||||
// First see if the the start content is in this map
|
||||
|
||||
@ -3976,7 +4095,9 @@ void nsFocusManager::GetFocusInSelection(nsPIDOMWindowOuter* aWindow,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (selectionNode == endSelectionNode) break;
|
||||
if (selectionNode == endSelectionNode) {
|
||||
break;
|
||||
}
|
||||
testNode = selectionNode->GetNextSibling();
|
||||
if (testNode) {
|
||||
selectionNode = testNode;
|
||||
@ -3997,7 +4118,9 @@ void nsFocusManager::GetFocusInSelection(nsPIDOMWindowOuter* aWindow,
|
||||
break;
|
||||
}
|
||||
selectionNode = testNode->GetNextSibling();
|
||||
if (selectionNode) break;
|
||||
if (selectionNode) {
|
||||
break;
|
||||
}
|
||||
selectionNode = testNode;
|
||||
} while (true);
|
||||
} while (selectionNode && selectionNode != endSelectionNode);
|
||||
|
@ -179,6 +179,53 @@ class nsFocusManager final : public nsIFocusManager,
|
||||
*/
|
||||
void ActivateRemoteFrameIfNeeded(mozilla::dom::Element&);
|
||||
|
||||
/**
|
||||
* Raises the top-level window aWindow at the widget level.
|
||||
*/
|
||||
void RaiseWindow(nsPIDOMWindowOuter* aWindow);
|
||||
|
||||
/**
|
||||
* Called when a window has been raised.
|
||||
*/
|
||||
void WindowRaised(mozIDOMWindowProxy* aWindow);
|
||||
|
||||
/**
|
||||
* Called when a window has been lowered.
|
||||
*/
|
||||
void WindowLowered(mozIDOMWindowProxy* aWindow);
|
||||
|
||||
/**
|
||||
* Called when a new document in a window is shown.
|
||||
*
|
||||
* If aNeedsFocus is true, then focus events are expected to be fired on the
|
||||
* window if this window is in the focused window chain.
|
||||
*/
|
||||
void WindowShown(mozIDOMWindowProxy* aWindow, bool aNeedsFocus);
|
||||
|
||||
/**
|
||||
* Called when a document in a window has been hidden or otherwise can no
|
||||
* longer accept focus.
|
||||
*/
|
||||
void WindowHidden(mozIDOMWindowProxy* aWindow);
|
||||
|
||||
/**
|
||||
* Fire any events that have been delayed due to synchronized actions.
|
||||
*/
|
||||
void FireDelayedEvents(Document* aDocument);
|
||||
|
||||
/**
|
||||
* Used in a child process to indicate that the parent window is now
|
||||
* active or deactive.
|
||||
*/
|
||||
void ParentActivated(mozIDOMWindowProxy* aWindow, bool aActive);
|
||||
|
||||
/**
|
||||
* Indicate that a plugin wishes to take the focus. This is similar to a
|
||||
* normal focus except that the widget focus is not changed. Updating the
|
||||
* widget focus state is the responsibility of the caller.
|
||||
*/
|
||||
nsresult FocusPlugin(mozilla::dom::Element* aPlugin);
|
||||
|
||||
static uint32_t FocusOptionsToFocusManagerFlags(
|
||||
const mozilla::dom::FocusOptions& aOptions);
|
||||
|
||||
@ -203,6 +250,14 @@ class nsFocusManager final : public nsIFocusManager,
|
||||
|
||||
static void MarkUncollectableForCCGeneration(uint32_t aGeneration);
|
||||
|
||||
struct BlurredElementInfo {
|
||||
const mozilla::OwningNonNull<mozilla::dom::Element> mElement;
|
||||
const bool mHadRing;
|
||||
|
||||
explicit BlurredElementInfo(mozilla::dom::Element&);
|
||||
~BlurredElementInfo();
|
||||
};
|
||||
|
||||
protected:
|
||||
nsFocusManager();
|
||||
~nsFocusManager();
|
||||
@ -311,7 +366,7 @@ class nsFocusManager final : public nsIFocusManager,
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
bool Blur(nsPIDOMWindowOuter* aWindowToClear,
|
||||
nsPIDOMWindowOuter* aAncestorWindowToFocus, bool aIsLeavingDocument,
|
||||
bool aAdjustWidget, nsIContent* aContentToFocus = nullptr);
|
||||
bool aAdjustWidget, mozilla::dom::Element* aElementToFocus = nullptr);
|
||||
|
||||
/**
|
||||
* Focus an element in the active window and child frame.
|
||||
@ -343,7 +398,7 @@ class nsFocusManager final : public nsIFocusManager,
|
||||
void Focus(nsPIDOMWindowOuter* aWindow, mozilla::dom::Element* aContent,
|
||||
uint32_t aFlags, bool aIsNewDocument, bool aFocusChanged,
|
||||
bool aWindowRaised, bool aAdjustWidget,
|
||||
nsIContent* aContentLostFocus = nullptr);
|
||||
const mozilla::Maybe<BlurredElementInfo>& = mozilla::Nothing());
|
||||
|
||||
/**
|
||||
* Send a focus or blur event at aTarget. It may be added to the delayed
|
||||
@ -403,11 +458,6 @@ class nsFocusManager final : public nsIFocusManager,
|
||||
void ScrollIntoView(mozilla::PresShell* aPresShell, nsIContent* aContent,
|
||||
uint32_t aFlags);
|
||||
|
||||
/**
|
||||
* Raises the top-level window aWindow at the widget level.
|
||||
*/
|
||||
void RaiseWindow(nsPIDOMWindowOuter* aWindow);
|
||||
|
||||
/**
|
||||
* Updates the caret positon and visibility to match the focus.
|
||||
*
|
||||
@ -616,18 +666,19 @@ class nsFocusManager final : public nsIFocusManager,
|
||||
nsIContent** aFocusedContent);
|
||||
|
||||
private:
|
||||
// Notify that the focus state of aContent has changed. Note that
|
||||
// we need to pass in whether the window should show a focus ring
|
||||
// before the SetFocusedNode call on it happened when losing focus
|
||||
// and after the SetFocusedNode call when gaining focus, which is
|
||||
// why that information needs to be an explicit argument instead of
|
||||
// just passing in the window and asking it whether it should show
|
||||
// focus rings: in the losing focus case that information could be
|
||||
// wrong..
|
||||
static void NotifyFocusStateChange(nsIContent* aContent,
|
||||
nsIContent* aContentToFocus,
|
||||
bool aWindowShouldShowFocusRing,
|
||||
int32_t aFlags, bool aGettingFocus);
|
||||
// Notify that the focus state of aElement has changed. Note that we need to
|
||||
// pass in whether the window should show a focus ring before the
|
||||
// SetFocusedNode call on it happened when losing focus and after the
|
||||
// SetFocusedNode call when gaining focus, which is why that information needs
|
||||
// to be an explicit argument instead of just passing in the window and asking
|
||||
// it whether it should show focus rings: in the losing focus case that
|
||||
// information could be wrong.
|
||||
//
|
||||
// aShouldShowFocusRing is only relevant if aGettingFocus is true.
|
||||
static void NotifyFocusStateChange(mozilla::dom::Element* aElement,
|
||||
mozilla::dom::Element* aElementToFocus,
|
||||
int32_t aFlags, bool aGettingFocus,
|
||||
bool aShouldShowFocusRing);
|
||||
|
||||
void SetFocusedWindowInternal(nsPIDOMWindowOuter* aWindow);
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsSubDocumentFrame.h"
|
||||
#include "nsError.h"
|
||||
#include "nsIXULWindow.h"
|
||||
#include "nsIAppWindow.h"
|
||||
#include "nsIMozBrowserFrame.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
@ -427,11 +427,6 @@ void nsFrameLoader::LoadFrame(bool aOriginalSrc) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (doc->IsLoadedAsInteractiveData()) {
|
||||
// XBL bindings doc shouldn't load sub-documents.
|
||||
return;
|
||||
}
|
||||
|
||||
nsIURI* base_uri = mOwnerContent->GetBaseURI();
|
||||
auto encoding = doc->GetDocumentCharacterSet();
|
||||
|
||||
@ -494,8 +489,8 @@ nsresult nsFrameLoader::LoadURI(nsIURI* aURI,
|
||||
|
||||
void nsFrameLoader::ResumeLoad(uint64_t aPendingSwitchID) {
|
||||
Document* doc = mOwnerContent->OwnerDoc();
|
||||
if (doc->IsStaticDocument() || doc->IsLoadedAsInteractiveData()) {
|
||||
// Static & XBL bindings doc shouldn't load sub-documents.
|
||||
if (doc->IsStaticDocument()) {
|
||||
// Static doc shouldn't load sub-documents.
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2631,7 +2626,7 @@ bool nsFrameLoader::TryRemoteBrowser() {
|
||||
!parentOwner) {
|
||||
return false;
|
||||
}
|
||||
nsCOMPtr<nsIXULWindow> window(do_GetInterface(parentOwner));
|
||||
nsCOMPtr<nsIAppWindow> window(do_GetInterface(parentOwner));
|
||||
if (window && NS_FAILED(window->GetChromeFlags(&chromeFlags))) {
|
||||
return false;
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ nsresult nsSelectionCommandsBase::GetSelectionControllerFromWindow(
|
||||
// Helpers for nsSelectMoveScrollCommand and nsPhysicalSelectMoveScrollCommand
|
||||
static void AdjustFocusAfterCaretMove(nsPIDOMWindowOuter* aWindow) {
|
||||
// adjust the focus to the new caret position
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (fm) {
|
||||
RefPtr<dom::Element> result;
|
||||
fm->MoveFocus(aWindow, nullptr, nsIFocusManager::MOVEFOCUS_CARET,
|
||||
|
@ -294,9 +294,6 @@
|
||||
# include "nsIWebBrowserPrint.h"
|
||||
#endif
|
||||
|
||||
#include "nsBindingManager.h"
|
||||
#include "nsXBLService.h"
|
||||
|
||||
#ifdef HAVE_SIDEBAR
|
||||
# include "mozilla/dom/ExternalBinding.h"
|
||||
#endif
|
||||
@ -1110,13 +1107,6 @@ void nsGlobalWindowInner::ShutDown() {
|
||||
sInnerWindowsById = nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
void nsGlobalWindowInner::CleanupCachedXBLHandlers() {
|
||||
if (mCachedXBLPrototypeHandlers && mCachedXBLPrototypeHandlers->Count() > 0) {
|
||||
mCachedXBLPrototypeHandlers->Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void nsGlobalWindowInner::FreeInnerObjects() {
|
||||
if (IsDying()) {
|
||||
return;
|
||||
@ -1206,8 +1196,6 @@ void nsGlobalWindowInner::FreeInnerObjects() {
|
||||
|
||||
NotifyWindowIDDestroyed("inner-window-destroyed");
|
||||
|
||||
CleanupCachedXBLHandlers();
|
||||
|
||||
for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
|
||||
mAudioContexts[i]->Shutdown();
|
||||
}
|
||||
@ -1332,12 +1320,6 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsGlobalWindowInner)
|
||||
return true;
|
||||
}
|
||||
tmp->mCanSkipCCGeneration = nsCCUncollectableMarker::sGeneration;
|
||||
if (tmp->mCachedXBLPrototypeHandlers) {
|
||||
for (auto iter = tmp->mCachedXBLPrototypeHandlers->Iter(); !iter.Done();
|
||||
iter.Next()) {
|
||||
iter.Data().exposeToActiveJS();
|
||||
}
|
||||
}
|
||||
if (EventListenerManager* elm = tmp->GetExistingListenerManager()) {
|
||||
elm->MarkForCC();
|
||||
}
|
||||
@ -1473,8 +1455,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindowInner)
|
||||
JS::SetRealmNonLive(js::GetNonCCWObjectRealm(wrapper));
|
||||
}
|
||||
|
||||
tmp->CleanupCachedXBLHandlers();
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mNavigator)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPerformance)
|
||||
@ -1593,12 +1573,6 @@ void nsGlobalWindowInner::RiskyUnlink() {
|
||||
#endif
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsGlobalWindowInner)
|
||||
if (tmp->mCachedXBLPrototypeHandlers) {
|
||||
for (auto iter = tmp->mCachedXBLPrototypeHandlers->Iter(); !iter.Done();
|
||||
iter.Next()) {
|
||||
aCallbacks.Trace(&iter.Data(), "Cached XBL prototype handler", aClosure);
|
||||
}
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
@ -2021,11 +1995,6 @@ nsresult nsGlobalWindowInner::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Execute bindingdetached handlers before we tear ourselves
|
||||
// down.
|
||||
if (mDoc) {
|
||||
mDoc->BindingManager()->ExecuteDetachedHandlers();
|
||||
}
|
||||
mIsDocumentLoaded = false;
|
||||
} else if (aVisitor.mEvent->mMessage == eLoad &&
|
||||
aVisitor.mEvent->IsTrusted()) {
|
||||
@ -3888,25 +3857,6 @@ void nsGlobalWindowInner::NotifyDOMWindowThawed(nsGlobalWindowInner* aWindow) {
|
||||
}
|
||||
}
|
||||
|
||||
JSObject* nsGlobalWindowInner::GetCachedXBLPrototypeHandler(
|
||||
nsXBLPrototypeHandler* aKey) {
|
||||
JS::Rooted<JSObject*> handler(RootingCx());
|
||||
if (mCachedXBLPrototypeHandlers) {
|
||||
mCachedXBLPrototypeHandlers->Get(aKey, handler.address());
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
|
||||
void nsGlobalWindowInner::CacheXBLPrototypeHandler(
|
||||
nsXBLPrototypeHandler* aKey, JS::Handle<JSObject*> aHandler) {
|
||||
if (!mCachedXBLPrototypeHandlers) {
|
||||
mCachedXBLPrototypeHandlers = MakeUnique<XBLPrototypeHandlerTable>();
|
||||
PreserveWrapper(ToSupports(this));
|
||||
}
|
||||
|
||||
mCachedXBLPrototypeHandlers->Put(aKey, aHandler);
|
||||
}
|
||||
|
||||
Element* nsGlobalWindowInner::GetFrameElement(nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError) {
|
||||
FORWARD_TO_OUTER_OR_THROW(GetFrameElementOuter, (aSubjectPrincipal), aError,
|
||||
@ -4105,7 +4055,8 @@ void nsGlobalWindowInner::StopVRActivity() {
|
||||
|
||||
void nsGlobalWindowInner::SetFocusedElement(Element* aElement,
|
||||
uint32_t aFocusMethod,
|
||||
bool aNeedsFocus) {
|
||||
bool aNeedsFocus,
|
||||
bool aWillShowOutline) {
|
||||
if (aElement && aElement->GetComposedDoc() != mDoc) {
|
||||
NS_WARNING("Trying to set focus to a node from a wrong document");
|
||||
return;
|
||||
@ -4115,13 +4066,17 @@ void nsGlobalWindowInner::SetFocusedElement(Element* aElement,
|
||||
NS_ASSERTION(!aElement, "Trying to focus cleaned up window!");
|
||||
aElement = nullptr;
|
||||
aNeedsFocus = false;
|
||||
aWillShowOutline = false;
|
||||
}
|
||||
if (mFocusedElement != aElement) {
|
||||
UpdateCanvasFocus(false, aElement);
|
||||
mFocusedElement = aElement;
|
||||
// TODO: Maybe this should be set on refocus too?
|
||||
mFocusMethod = aFocusMethod & FOCUSMETHOD_MASK;
|
||||
}
|
||||
|
||||
mFocusedElementShowedOutlines = aWillShowOutline;
|
||||
|
||||
if (mFocusedElement) {
|
||||
// if a node was focused by a keypress, turn on focus rings for the
|
||||
// window.
|
||||
@ -4130,7 +4085,9 @@ void nsGlobalWindowInner::SetFocusedElement(Element* aElement,
|
||||
}
|
||||
}
|
||||
|
||||
if (aNeedsFocus) mNeedsFocus = aNeedsFocus;
|
||||
if (aNeedsFocus) {
|
||||
mNeedsFocus = aNeedsFocus;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t nsGlobalWindowInner::GetFocusMethod() { return mFocusMethod; }
|
||||
@ -4175,7 +4132,7 @@ void nsGlobalWindowInner::SetReadyForFocus() {
|
||||
bool oldNeedsFocus = mNeedsFocus;
|
||||
mNeedsFocus = false;
|
||||
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (fm) {
|
||||
fm->WindowShown(GetOuterWindow(), oldNeedsFocus);
|
||||
}
|
||||
@ -4186,7 +4143,7 @@ void nsGlobalWindowInner::PageHidden() {
|
||||
// no longer valid. Use the persisted field to determine if the document
|
||||
// is being destroyed.
|
||||
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (fm) {
|
||||
fm->WindowHidden(GetOuterWindow());
|
||||
}
|
||||
@ -7020,6 +6977,14 @@ mozilla::dom::TabGroup* nsGlobalWindowInner::TabGroupInner() {
|
||||
return tabGroup;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/#structured-cloning
|
||||
void nsGlobalWindowInner::StructuredClone(
|
||||
JSContext* aCx, JS::Handle<JS::Value> aValue,
|
||||
const StructuredSerializeOptions& aOptions,
|
||||
JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError) {
|
||||
nsContentUtils::StructuredClone(aCx, this, aValue, aOptions, aRetval, aError);
|
||||
}
|
||||
|
||||
nsresult nsGlobalWindowInner::Dispatch(
|
||||
TaskCategory aCategory, already_AddRefed<nsIRunnable>&& aRunnable) {
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
|
@ -452,8 +452,6 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
||||
static void ShutDown();
|
||||
static bool IsCallerChrome();
|
||||
|
||||
void CleanupCachedXBLHandlers();
|
||||
|
||||
friend class WindowStateHolder;
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(
|
||||
@ -465,12 +463,6 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
||||
void RiskyUnlink();
|
||||
#endif
|
||||
|
||||
virtual JSObject* GetCachedXBLPrototypeHandler(
|
||||
nsXBLPrototypeHandler* aKey) override;
|
||||
|
||||
virtual void CacheXBLPrototypeHandler(
|
||||
nsXBLPrototypeHandler* aKey, JS::Handle<JSObject*> aHandler) override;
|
||||
|
||||
virtual bool TakeFocus(bool aFocus, uint32_t aFocusMethod) override;
|
||||
virtual void SetReadyForFocus() override;
|
||||
virtual void PageHidden() override;
|
||||
@ -894,6 +886,11 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
||||
int32_t aSx, int32_t aSy, int32_t aSw, int32_t aSh,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
void StructuredClone(JSContext* aCx, JS::Handle<JS::Value> aValue,
|
||||
const mozilla::dom::StructuredSerializeOptions& aOptions,
|
||||
JS::MutableHandle<JS::Value> aRetval,
|
||||
mozilla::ErrorResult& aError);
|
||||
|
||||
// ChromeWindow bits. Do NOT call these unless your window is in
|
||||
// fact chrome.
|
||||
uint16_t WindowState();
|
||||
@ -1122,13 +1119,13 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
||||
|
||||
bool IsInModalState();
|
||||
|
||||
virtual void SetFocusedElement(mozilla::dom::Element* aElement,
|
||||
uint32_t aFocusMethod = 0,
|
||||
bool aNeedsFocus = false) override;
|
||||
void SetFocusedElement(mozilla::dom::Element* aElement,
|
||||
uint32_t aFocusMethod = 0, bool aNeedsFocus = false,
|
||||
bool aWillShowOutline = false) override;
|
||||
|
||||
virtual uint32_t GetFocusMethod() override;
|
||||
uint32_t GetFocusMethod() override;
|
||||
|
||||
virtual bool ShouldShowFocusRing() override;
|
||||
bool ShouldShowFocusRing() override;
|
||||
|
||||
// Inner windows only.
|
||||
void UpdateCanvasFocus(bool aFocusChanged, nsIContent* aNewContent);
|
||||
@ -1364,7 +1361,7 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
||||
uint32_t mSerial;
|
||||
#endif
|
||||
|
||||
// the method that was used to focus mFocusedNode
|
||||
// the method that was used to focus mFocusedElement
|
||||
uint32_t mFocusMethod;
|
||||
|
||||
// The current idle request callback handle
|
||||
@ -1378,10 +1375,6 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
||||
|
||||
RefPtr<nsDOMOfflineResourceList> mApplicationCache;
|
||||
|
||||
using XBLPrototypeHandlerTable =
|
||||
nsJSThingHashtable<nsPtrHashKey<nsXBLPrototypeHandler>, JSObject*>;
|
||||
mozilla::UniquePtr<XBLPrototypeHandlerTable> mCachedXBLPrototypeHandlers;
|
||||
|
||||
RefPtr<mozilla::dom::IDBFactory> mIndexedDB;
|
||||
|
||||
// This counts the number of windows that have been opened in rapid succession
|
||||
@ -1466,11 +1459,9 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
||||
// Members in the mChromeFields member should only be used in chrome windows.
|
||||
// All accesses to this field should be guarded by a check of mIsChrome.
|
||||
struct ChromeFields {
|
||||
ChromeFields() : mGroupMessageManagers(1) {}
|
||||
|
||||
RefPtr<mozilla::dom::ChromeMessageBroadcaster> mMessageManager;
|
||||
nsRefPtrHashtable<nsStringHashKey, mozilla::dom::ChromeMessageBroadcaster>
|
||||
mGroupMessageManagers;
|
||||
mGroupMessageManagers{1};
|
||||
} mChromeFields;
|
||||
|
||||
// These fields are used by the inner and outer windows to prevent
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "nsISecureBrowserUI.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "mozilla/AntiTrackingCommon.h"
|
||||
#include "mozilla/dom/BrowserChild.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/BrowsingContextBinding.h"
|
||||
#include "mozilla/dom/ContentFrameMessageManager.h"
|
||||
@ -140,6 +141,7 @@
|
||||
#include "nsDOMWindowUtils.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsPIWindowWatcher.h"
|
||||
#include "nsIAppWindow.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsIControllers.h"
|
||||
@ -153,7 +155,6 @@
|
||||
#include "mozilla/EventStateManager.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsIXULWindow.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "mozilla/dom/CustomEvent.h"
|
||||
#include "nsIScreenManager.h"
|
||||
@ -171,11 +172,8 @@
|
||||
#include "nsNetCID.h"
|
||||
#include "nsIArray.h"
|
||||
|
||||
#include "XULDocument.h"
|
||||
#include "nsIDOMXULCommandDispatcher.h"
|
||||
|
||||
#include "nsBindingManager.h"
|
||||
#include "nsXBLService.h"
|
||||
#include "mozilla/GlobalKeyListener.h"
|
||||
|
||||
#include "nsIDragService.h"
|
||||
@ -1766,7 +1764,7 @@ void nsGlobalWindowOuter::SetInitialPrincipalToSubject(
|
||||
// We should never create windows with an expanded principal.
|
||||
// If we have a system principal, make sure we're not using it for a content
|
||||
// docshell.
|
||||
// NOTE: Please keep this logic in sync with nsWebShellWindow::Initialize().
|
||||
// NOTE: Please keep this logic in sync with AppWindow::Initialize().
|
||||
if (nsContentUtils::IsExpandedPrincipal(newWindowPrincipal) ||
|
||||
(newWindowPrincipal->IsSystemPrincipal() &&
|
||||
GetDocShell()->ItemType() != nsIDocShellTreeItem::typeChrome)) {
|
||||
@ -3557,42 +3555,55 @@ void nsGlobalWindowOuter::SetNameOuter(const nsAString& aName,
|
||||
}
|
||||
|
||||
// Helper functions used by many methods below.
|
||||
int32_t nsGlobalWindowOuter::DevToCSSIntPixels(int32_t px) {
|
||||
if (!mDocShell) return px; // assume 1:1
|
||||
|
||||
RefPtr<nsPresContext> presContext = mDocShell->GetPresContext();
|
||||
if (!presContext) return px;
|
||||
|
||||
return presContext->DevPixelsToIntCSSPixels(px);
|
||||
int32_t nsGlobalWindowOuter::DevToCSSIntPixelsForBaseWindow(
|
||||
int32_t aDevicePixels, nsIBaseWindow* aWindow) {
|
||||
MOZ_ASSERT(aWindow);
|
||||
double scale;
|
||||
aWindow->GetUnscaledDevicePixelsPerCSSPixel(&scale);
|
||||
double zoom = 1.0;
|
||||
if (mDocShell && mDocShell->GetPresContext()) {
|
||||
zoom = mDocShell->GetPresContext()->GetFullZoom();
|
||||
}
|
||||
return std::floor(aDevicePixels / scale / zoom + 0.5);
|
||||
}
|
||||
|
||||
int32_t nsGlobalWindowOuter::CSSToDevIntPixels(int32_t px) {
|
||||
if (!mDocShell) return px; // assume 1:1
|
||||
|
||||
RefPtr<nsPresContext> presContext = mDocShell->GetPresContext();
|
||||
if (!presContext) return px;
|
||||
|
||||
return presContext->CSSPixelsToDevPixels(px);
|
||||
nsIntSize nsGlobalWindowOuter::DevToCSSIntPixelsForBaseWindow(
|
||||
nsIntSize aDeviceSize, nsIBaseWindow* aWindow) {
|
||||
MOZ_ASSERT(aWindow);
|
||||
double scale;
|
||||
aWindow->GetUnscaledDevicePixelsPerCSSPixel(&scale);
|
||||
double zoom = 1.0;
|
||||
if (mDocShell && mDocShell->GetPresContext()) {
|
||||
zoom = mDocShell->GetPresContext()->GetFullZoom();
|
||||
}
|
||||
return nsIntSize::Round(
|
||||
static_cast<float>(aDeviceSize.width / scale / zoom),
|
||||
static_cast<float>(aDeviceSize.height / scale / zoom));
|
||||
}
|
||||
|
||||
nsIntSize nsGlobalWindowOuter::DevToCSSIntPixels(nsIntSize px) {
|
||||
if (!mDocShell) return px; // assume 1:1
|
||||
|
||||
RefPtr<nsPresContext> presContext = mDocShell->GetPresContext();
|
||||
if (!presContext) return px;
|
||||
|
||||
return nsIntSize(presContext->DevPixelsToIntCSSPixels(px.width),
|
||||
presContext->DevPixelsToIntCSSPixels(px.height));
|
||||
int32_t nsGlobalWindowOuter::CSSToDevIntPixelsForBaseWindow(
|
||||
int32_t aCSSPixels, nsIBaseWindow* aWindow) {
|
||||
MOZ_ASSERT(aWindow);
|
||||
double scale;
|
||||
aWindow->GetUnscaledDevicePixelsPerCSSPixel(&scale);
|
||||
double zoom = 1.0;
|
||||
if (mDocShell && mDocShell->GetPresContext()) {
|
||||
zoom = mDocShell->GetPresContext()->GetFullZoom();
|
||||
}
|
||||
return std::floor(aCSSPixels * scale * zoom + 0.5);
|
||||
}
|
||||
|
||||
nsIntSize nsGlobalWindowOuter::CSSToDevIntPixels(nsIntSize px) {
|
||||
if (!mDocShell) return px; // assume 1:1
|
||||
|
||||
RefPtr<nsPresContext> presContext = mDocShell->GetPresContext();
|
||||
if (!presContext) return px;
|
||||
|
||||
return nsIntSize(presContext->CSSPixelsToDevPixels(px.width),
|
||||
presContext->CSSPixelsToDevPixels(px.height));
|
||||
nsIntSize nsGlobalWindowOuter::CSSToDevIntPixelsForBaseWindow(
|
||||
nsIntSize aCSSSize, nsIBaseWindow* aWindow) {
|
||||
MOZ_ASSERT(aWindow);
|
||||
double scale;
|
||||
aWindow->GetUnscaledDevicePixelsPerCSSPixel(&scale);
|
||||
double zoom = 1.0;
|
||||
if (mDocShell && mDocShell->GetPresContext()) {
|
||||
zoom = mDocShell->GetPresContext()->GetFullZoom();
|
||||
}
|
||||
return nsIntSize::Round(static_cast<float>(aCSSSize.width * scale * zoom),
|
||||
static_cast<float>(aCSSSize.height * scale * zoom));
|
||||
}
|
||||
|
||||
nsresult nsGlobalWindowOuter::GetInnerSize(CSSIntSize& aSize) {
|
||||
@ -3608,12 +3619,6 @@ nsresult nsGlobalWindowOuter::GetInnerSize(CSSIntSize& aSize) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If the visual viewport has been overriden, return that.
|
||||
if (presShell->IsVisualViewportSizeSet()) {
|
||||
aSize = CSSIntRect::FromAppUnitsRounded(presShell->GetVisualViewportSize());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Whether or not the css viewport has been overridden, we can get the
|
||||
// correct value by looking at the visible area of the presContext.
|
||||
RefPtr<nsViewManager> viewManager = presShell->GetViewManager();
|
||||
@ -3646,24 +3651,8 @@ void nsGlobalWindowOuter::SetInnerWidthOuter(int32_t aInnerWidth,
|
||||
CheckSecurityWidthAndHeight(&aInnerWidth, nullptr, aCallerType);
|
||||
RefPtr<PresShell> presShell = mDocShell->GetPresShell();
|
||||
|
||||
// Setting inner width should set the visual viewport. Most of the
|
||||
// time, this is the same as the CSS viewport, and when we set one,
|
||||
// we implicitly set both of them. But if
|
||||
// presShell->IsVisualViewportSizeSet() returns true, that means
|
||||
// that the two diverge. In that case we only set the visual viewport.
|
||||
// This mirrors the logic in ::GetInnerSize() and ensures that JS
|
||||
// behaves sanely when setting and then getting the innerWidth.
|
||||
if (presShell && presShell->IsVisualViewportSizeSet()) {
|
||||
CSSSize viewportSize =
|
||||
CSSRect::FromAppUnits(presShell->GetVisualViewportSize());
|
||||
viewportSize.width = aInnerWidth;
|
||||
nsLayoutUtils::SetVisualViewportSize(presShell, viewportSize);
|
||||
return;
|
||||
}
|
||||
|
||||
// We're going to set both viewports. If the css viewport has been
|
||||
// overridden, change the css viewport override. The visual viewport
|
||||
// will adopt this value via the logic in ::GetInnerSize().
|
||||
// Setting inner width should set the CSS viewport. If the CSS viewport
|
||||
// has been overridden, change the override.
|
||||
if (presShell && presShell->GetIsViewportOverridden()) {
|
||||
nscoord height = 0;
|
||||
|
||||
@ -3677,14 +3666,14 @@ void nsGlobalWindowOuter::SetInnerWidthOuter(int32_t aInnerWidth,
|
||||
return;
|
||||
}
|
||||
|
||||
// Nothing has been overriden, so change the docshell itself, which will
|
||||
// affect both viewports.
|
||||
// Nothing has been overriden, so change the docshell itself.
|
||||
int32_t height = 0;
|
||||
int32_t unused = 0;
|
||||
|
||||
nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(mDocShell));
|
||||
docShellAsWin->GetSize(&unused, &height);
|
||||
aError = SetDocShellWidthAndHeight(CSSToDevIntPixels(aInnerWidth), height);
|
||||
aError = SetDocShellWidthAndHeight(
|
||||
CSSToDevIntPixelsForBaseWindow(aInnerWidth, docShellAsWin), height);
|
||||
}
|
||||
|
||||
int32_t nsGlobalWindowOuter::GetInnerHeightOuter(ErrorResult& aError) {
|
||||
@ -3708,24 +3697,8 @@ void nsGlobalWindowOuter::SetInnerHeightOuter(int32_t aInnerHeight,
|
||||
CheckSecurityWidthAndHeight(nullptr, &aInnerHeight, aCallerType);
|
||||
RefPtr<PresShell> presShell = mDocShell->GetPresShell();
|
||||
|
||||
// Setting inner height should set the visual viewport. Most of the
|
||||
// time, this is the same as the CSS viewport, and when we set one,
|
||||
// we implicitly set both of them. But if
|
||||
// presShell->IsVisualViewportSizeSet() returns true, that means
|
||||
// that the two diverge. In that case we only set the visual viewport.
|
||||
// This mirrors the logic in ::GetInnerSize() and ensures that JS
|
||||
// behaves sanely when setting and then getting the innerHeight.
|
||||
if (presShell && presShell->IsVisualViewportSizeSet()) {
|
||||
CSSSize viewportSize =
|
||||
CSSRect::FromAppUnits(presShell->GetVisualViewportSize());
|
||||
viewportSize.height = aInnerHeight;
|
||||
nsLayoutUtils::SetVisualViewportSize(presShell, viewportSize);
|
||||
return;
|
||||
}
|
||||
|
||||
// We're going to set both viewports. If the css viewport has been
|
||||
// overridden, change the css viewport override. The visual viewport
|
||||
// will adopt this value via the logic in ::GetInnerSize().
|
||||
// Setting inner height should set the CSS viewport. If the CSS viewport
|
||||
// has been overridden, change the override.
|
||||
if (presShell && presShell->GetIsViewportOverridden()) {
|
||||
nscoord width = 0;
|
||||
|
||||
@ -3739,14 +3712,14 @@ void nsGlobalWindowOuter::SetInnerHeightOuter(int32_t aInnerHeight,
|
||||
return;
|
||||
}
|
||||
|
||||
// Nothing has been overriden, so change the docshell itself, which will
|
||||
// affect both viewports.
|
||||
// Nothing has been overriden, so change the docshell itself.
|
||||
int32_t height = 0;
|
||||
int32_t width = 0;
|
||||
|
||||
nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(mDocShell));
|
||||
docShellAsWin->GetSize(&width, &height);
|
||||
aError = SetDocShellWidthAndHeight(width, CSSToDevIntPixels(aInnerHeight));
|
||||
aError = SetDocShellWidthAndHeight(
|
||||
width, CSSToDevIntPixelsForBaseWindow(aInnerHeight, docShellAsWin));
|
||||
}
|
||||
|
||||
nsIntSize nsGlobalWindowOuter::GetOuterSize(CallerType aCallerType,
|
||||
@ -3757,23 +3730,13 @@ nsIntSize nsGlobalWindowOuter::GetOuterSize(CallerType aCallerType,
|
||||
return nsIntSize(size.width, size.height);
|
||||
}
|
||||
|
||||
if (mDoc && mDoc->InRDMPane()) {
|
||||
CSSIntSize size;
|
||||
aError = GetInnerSize(size);
|
||||
|
||||
// Obtain the current zoom of the presentation shell. The zoom value will
|
||||
// be used to scale the size of the visual viewport to the device browser's
|
||||
// outer size values. Once RDM no longer relies on the having the page
|
||||
// content being embedded in a <iframe mozbrowser>, we can do away with
|
||||
// this approach and retrieve the size of the frame containing the browser
|
||||
// content.
|
||||
RefPtr<nsPresContext> presContext = mDocShell->GetPresContext();
|
||||
|
||||
if (presContext) {
|
||||
float zoom = presContext->GetDeviceFullZoom();
|
||||
int32_t width = std::round(size.width * zoom);
|
||||
int32_t height = std::round(size.height * zoom);
|
||||
return nsIntSize(width, height);
|
||||
// Windows showing documents in RDM panes and any subframes within them
|
||||
// return the simulated device size.
|
||||
if (mDoc) {
|
||||
Maybe<CSSIntSize> deviceSize = GetRDMDeviceSize(*mDoc);
|
||||
if (deviceSize.isSome()) {
|
||||
const CSSIntSize& size = deviceSize.value();
|
||||
return nsIntSize(size.width, size.height);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3789,7 +3752,7 @@ nsIntSize nsGlobalWindowOuter::GetOuterSize(CallerType aCallerType,
|
||||
return nsIntSize();
|
||||
}
|
||||
|
||||
return DevToCSSIntPixels(sizeDevPixels);
|
||||
return DevToCSSIntPixelsForBaseWindow(sizeDevPixels, treeOwnerAsWin);
|
||||
}
|
||||
|
||||
int32_t nsGlobalWindowOuter::GetOuterWidthOuter(CallerType aCallerType,
|
||||
@ -3821,7 +3784,8 @@ void nsGlobalWindowOuter::SetOuterSize(int32_t aLengthCSSPixels, bool aIsWidth,
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t lengthDevPixels = CSSToDevIntPixels(aLengthCSSPixels);
|
||||
int32_t lengthDevPixels =
|
||||
CSSToDevIntPixelsForBaseWindow(aLengthCSSPixels, treeOwnerAsWin);
|
||||
if (aIsWidth) {
|
||||
width = lengthDevPixels;
|
||||
} else {
|
||||
@ -3915,6 +3879,41 @@ nsRect nsGlobalWindowOuter::GetInnerScreenRect() {
|
||||
return rootFrame->GetScreenRectInAppUnits();
|
||||
}
|
||||
|
||||
Maybe<CSSIntSize> nsGlobalWindowOuter::GetRDMDeviceSize(
|
||||
const Document& aDocument) {
|
||||
// RDM device size should reflect the simulated device resolution, and
|
||||
// be independent of any full zoom or resolution zoom applied to the
|
||||
// content. To get this value, we get the "unscaled" browser child size,
|
||||
// and divide by the full zoom. "Unscaled" in this case means unscaled
|
||||
// from device to screen but it has been affected (multipled) by the
|
||||
// full zoom and we need to compensate for that.
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Bug 1576256: This does not work for cross-process subframes.
|
||||
const Document* topInProcessContentDoc =
|
||||
aDocument.GetTopLevelContentDocument();
|
||||
if (topInProcessContentDoc && topInProcessContentDoc->InRDMPane()) {
|
||||
nsIDocShell* docShell = topInProcessContentDoc->GetDocShell();
|
||||
if (docShell) {
|
||||
nsPresContext* presContext = docShell->GetPresContext();
|
||||
if (presContext) {
|
||||
nsCOMPtr<nsIBrowserChild> child = docShell->GetBrowserChild();
|
||||
if (child) {
|
||||
// We intentionally use GetFullZoom here instead of
|
||||
// GetDeviceFullZoom, because the unscaledInnerSize is based
|
||||
// on the full zoom and not the device full zoom (which is
|
||||
// rounded to result in integer device pixels).
|
||||
float zoom = presContext->GetFullZoom();
|
||||
BrowserChild* bc = static_cast<BrowserChild*>(child.get());
|
||||
CSSSize unscaledSize = bc->GetUnscaledInnerSize();
|
||||
return Some(CSSIntSize(gfx::RoundedToInt(unscaledSize / zoom)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
float nsGlobalWindowOuter::GetMozInnerScreenXOuter(CallerType aCallerType) {
|
||||
// When resisting fingerprinting, always return 0.
|
||||
if (nsContentUtils::ResistFingerprinting(aCallerType)) {
|
||||
@ -3990,7 +3989,7 @@ void nsGlobalWindowOuter::SetScreenXOuter(int32_t aScreenX,
|
||||
}
|
||||
|
||||
CheckSecurityLeftAndTop(&aScreenX, nullptr, aCallerType);
|
||||
x = CSSToDevIntPixels(aScreenX);
|
||||
x = CSSToDevIntPixelsForBaseWindow(aScreenX, treeOwnerAsWin);
|
||||
|
||||
aError = treeOwnerAsWin->SetPosition(x, y);
|
||||
|
||||
@ -4018,7 +4017,7 @@ void nsGlobalWindowOuter::SetScreenYOuter(int32_t aScreenY,
|
||||
}
|
||||
|
||||
CheckSecurityLeftAndTop(nullptr, &aScreenY, aCallerType);
|
||||
y = CSSToDevIntPixels(aScreenY);
|
||||
y = CSSToDevIntPixelsForBaseWindow(aScreenY, treeOwnerAsWin);
|
||||
|
||||
aError = treeOwnerAsWin->SetPosition(x, y);
|
||||
|
||||
@ -4105,22 +4104,23 @@ void nsGlobalWindowOuter::CheckSecurityLeftAndTop(int32_t* aLeft, int32_t* aTop,
|
||||
rootWindow->FlushPendingNotifications(FlushType::Layout);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIBaseWindow> treeOwner = GetTreeOwnerWindow();
|
||||
nsCOMPtr<nsIBaseWindow> treeOwnerAsWin = GetTreeOwnerWindow();
|
||||
|
||||
RefPtr<nsScreen> screen = GetScreen();
|
||||
|
||||
if (treeOwner && screen) {
|
||||
if (treeOwnerAsWin && screen) {
|
||||
int32_t winLeft, winTop, winWidth, winHeight;
|
||||
|
||||
// Get the window size
|
||||
treeOwner->GetPositionAndSize(&winLeft, &winTop, &winWidth, &winHeight);
|
||||
treeOwnerAsWin->GetPositionAndSize(&winLeft, &winTop, &winWidth,
|
||||
&winHeight);
|
||||
|
||||
// convert those values to CSS pixels
|
||||
// XXX four separate retrievals of the prescontext
|
||||
winLeft = DevToCSSIntPixels(winLeft);
|
||||
winTop = DevToCSSIntPixels(winTop);
|
||||
winWidth = DevToCSSIntPixels(winWidth);
|
||||
winHeight = DevToCSSIntPixels(winHeight);
|
||||
winLeft = DevToCSSIntPixelsForBaseWindow(winLeft, treeOwnerAsWin);
|
||||
winTop = DevToCSSIntPixelsForBaseWindow(winTop, treeOwnerAsWin);
|
||||
winWidth = DevToCSSIntPixelsForBaseWindow(winWidth, treeOwnerAsWin);
|
||||
winHeight = DevToCSSIntPixelsForBaseWindow(winHeight, treeOwnerAsWin);
|
||||
|
||||
// Get the screen dimensions
|
||||
// XXX This should use nsIScreenManager once it's fully fleshed out.
|
||||
@ -4646,9 +4646,9 @@ nsresult nsGlobalWindowOuter::SetFullscreenInternal(FullscreenReason aReason,
|
||||
// Prevent chrome documents which are still loading from resizing
|
||||
// the window after we set fullscreen mode.
|
||||
nsCOMPtr<nsIBaseWindow> treeOwnerAsWin = GetTreeOwnerWindow();
|
||||
nsCOMPtr<nsIXULWindow> xulWin(do_GetInterface(treeOwnerAsWin));
|
||||
if (aFullscreen && xulWin) {
|
||||
xulWin->SetIntrinsicallySized(false);
|
||||
nsCOMPtr<nsIAppWindow> appWin(do_GetInterface(treeOwnerAsWin));
|
||||
if (aFullscreen && appWin) {
|
||||
appWin->SetIntrinsicallySized(false);
|
||||
}
|
||||
|
||||
// Set this before so if widget sends an event indicating its
|
||||
@ -5159,10 +5159,7 @@ void nsGlobalWindowOuter::FocusOuter() {
|
||||
// if there is no parent, this must be a toplevel window, so raise the
|
||||
// window if canFocus is true. If this is a child process, the raise
|
||||
// window request will get forwarded to the parent by the puppet widget.
|
||||
DebugOnly<nsresult> rv = fm->SetActiveWindow(this);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv),
|
||||
"SetActiveWindow only fails if passed null or a non-toplevel "
|
||||
"window, which is not the case here.");
|
||||
fm->RaiseWindow(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5187,7 +5184,7 @@ void nsGlobalWindowOuter::BlurOuter() {
|
||||
siteWindow->Blur();
|
||||
|
||||
// if the root is focused, clear the focus
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (fm && mDoc) {
|
||||
RefPtr<Element> element;
|
||||
fm->GetFocusedElementForWindow(this, false, nullptr,
|
||||
@ -5373,14 +5370,15 @@ void nsGlobalWindowOuter::MoveByOuter(int32_t aXDif, int32_t aYDif,
|
||||
}
|
||||
|
||||
// mild abuse of a "size" object so we don't need more helper functions
|
||||
nsIntSize cssPos(DevToCSSIntPixels(nsIntSize(x, y)));
|
||||
nsIntSize cssPos(
|
||||
DevToCSSIntPixelsForBaseWindow(nsIntSize(x, y), treeOwnerAsWin));
|
||||
|
||||
cssPos.width += aXDif;
|
||||
cssPos.height += aYDif;
|
||||
|
||||
CheckSecurityLeftAndTop(&cssPos.width, &cssPos.height, aCallerType);
|
||||
|
||||
nsIntSize newDevPos(CSSToDevIntPixels(cssPos));
|
||||
nsIntSize newDevPos(CSSToDevIntPixelsForBaseWindow(cssPos, treeOwnerAsWin));
|
||||
|
||||
aError = treeOwnerAsWin->SetPosition(newDevPos.width, newDevPos.height);
|
||||
|
||||
@ -5415,7 +5413,7 @@ void nsGlobalWindowOuter::ResizeToOuter(int32_t aWidth, int32_t aHeight,
|
||||
nsIntSize cssSize(aWidth, aHeight);
|
||||
CheckSecurityWidthAndHeight(&cssSize.width, &cssSize.height, aCallerType);
|
||||
|
||||
nsIntSize devSz(CSSToDevIntPixels(cssSize));
|
||||
nsIntSize devSz(CSSToDevIntPixelsForBaseWindow(cssSize, treeOwnerAsWin));
|
||||
|
||||
aError = treeOwnerAsWin->SetSize(devSz.width, devSz.height, true);
|
||||
|
||||
@ -5450,14 +5448,15 @@ void nsGlobalWindowOuter::ResizeByOuter(int32_t aWidthDif, int32_t aHeightDif,
|
||||
// into CSS pixels, add the arguments, do the security check, and
|
||||
// then convert back to device pixels for the call to SetSize.
|
||||
|
||||
nsIntSize cssSize(DevToCSSIntPixels(nsIntSize(width, height)));
|
||||
nsIntSize cssSize(
|
||||
DevToCSSIntPixelsForBaseWindow(nsIntSize(width, height), treeOwnerAsWin));
|
||||
|
||||
cssSize.width += aWidthDif;
|
||||
cssSize.height += aHeightDif;
|
||||
|
||||
CheckSecurityWidthAndHeight(&cssSize.width, &cssSize.height, aCallerType);
|
||||
|
||||
nsIntSize newDevSize(CSSToDevIntPixels(cssSize));
|
||||
nsIntSize newDevSize(CSSToDevIntPixelsForBaseWindow(cssSize, treeOwnerAsWin));
|
||||
|
||||
aError = treeOwnerAsWin->SetSize(newDevSize.width, newDevSize.height, true);
|
||||
|
||||
@ -5488,8 +5487,8 @@ void nsGlobalWindowOuter::SizeToContentOuter(CallerType aCallerType,
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t width, height;
|
||||
aError = cv->GetContentSize(&width, &height);
|
||||
nsIntSize contentSize;
|
||||
aError = cv->GetContentSize(&contentSize.width, &contentSize.height);
|
||||
if (aError.Failed()) {
|
||||
return;
|
||||
}
|
||||
@ -5502,10 +5501,21 @@ void nsGlobalWindowOuter::SizeToContentOuter(CallerType aCallerType,
|
||||
return;
|
||||
}
|
||||
|
||||
nsIntSize cssSize(DevToCSSIntPixels(nsIntSize(width, height)));
|
||||
// Don't use DevToCSSIntPixelsForBaseWindow() nor
|
||||
// CSSToDevIntPixelsForBaseWindow() here because contentSize is comes from
|
||||
// nsIContentViewer::GetContentSize() and it's computed with nsPresContext so
|
||||
// that we need to work with nsPresContext here too.
|
||||
RefPtr<nsPresContext> presContext = cv->GetPresContext();
|
||||
MOZ_ASSERT(
|
||||
presContext,
|
||||
"Should be non-nullptr if nsIContentViewer::GetContentSize() succeeded");
|
||||
nsIntSize cssSize(presContext->DevPixelsToIntCSSPixels(contentSize.width),
|
||||
presContext->DevPixelsToIntCSSPixels(contentSize.height));
|
||||
|
||||
CheckSecurityWidthAndHeight(&cssSize.width, &cssSize.height, aCallerType);
|
||||
|
||||
nsIntSize newDevSize(CSSToDevIntPixels(cssSize));
|
||||
nsIntSize newDevSize(presContext->CSSPixelsToDevPixels(cssSize.width),
|
||||
presContext->CSSPixelsToDevPixels(cssSize.height));
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell = mDocShell;
|
||||
aError =
|
||||
@ -6050,7 +6060,7 @@ bool nsGlobalWindowOuter::GatherPostMessageData(
|
||||
if (!callerPrin->IsSystemPrincipal()) {
|
||||
nsAutoCString asciiOrigin;
|
||||
callerPrin->GetAsciiOrigin(asciiOrigin);
|
||||
aOrigin = NS_ConvertUTF8toUTF16(asciiOrigin);
|
||||
CopyUTF8toUTF16(asciiOrigin, aOrigin);
|
||||
} else if (callerInnerWin) {
|
||||
if (!*aCallerDocumentURI) {
|
||||
return false;
|
||||
@ -6916,10 +6926,10 @@ void nsGlobalWindowOuter::ActivateOrDeactivate(bool aActivate) {
|
||||
// Get the top level widget's nsGlobalWindowOuter
|
||||
nsCOMPtr<nsPIDOMWindowOuter> topLevelWindow;
|
||||
|
||||
// widgetListener should be a nsXULWindow
|
||||
// widgetListener should be an AppWindow
|
||||
nsIWidgetListener* listener = topLevelWidget->GetWidgetListener();
|
||||
if (listener) {
|
||||
nsCOMPtr<nsIXULWindow> window = listener->GetXULWindow();
|
||||
nsCOMPtr<nsIAppWindow> window = listener->GetAppWindow();
|
||||
nsCOMPtr<nsIInterfaceRequestor> req(do_QueryInterface(window));
|
||||
topLevelWindow = do_GetInterface(req);
|
||||
}
|
||||
@ -7022,9 +7032,10 @@ void nsGlobalWindowOuter::SetChromeEventHandler(
|
||||
|
||||
void nsGlobalWindowOuter::SetFocusedElement(Element* aElement,
|
||||
uint32_t aFocusMethod,
|
||||
bool aNeedsFocus) {
|
||||
FORWARD_TO_INNER_VOID(SetFocusedElement,
|
||||
(aElement, aFocusMethod, aNeedsFocus));
|
||||
bool aNeedsFocus,
|
||||
bool aWillShowOutline) {
|
||||
FORWARD_TO_INNER_VOID(SetFocusedElement, (aElement, aFocusMethod, aNeedsFocus,
|
||||
aWillShowOutline));
|
||||
}
|
||||
|
||||
uint32_t nsGlobalWindowOuter::GetFocusMethod() {
|
||||
@ -7625,7 +7636,7 @@ nsresult nsGlobalWindowOuter::RestoreWindowState(nsISupports* aState) {
|
||||
// it easy to tell which link was last clicked when going back a page.
|
||||
Element* focusedElement = inner->GetFocusedElement();
|
||||
if (nsContentUtils::ContentIsLink(focusedElement)) {
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (fm) {
|
||||
// XXXbz Do we need the stack strong ref here?
|
||||
RefPtr<Element> kungFuDeathGrip(focusedElement);
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "nsCheapSets.h"
|
||||
#include "mozilla/dom/ImageBitmapSource.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/dom/BrowsingContext.h"
|
||||
|
||||
class nsDocShell;
|
||||
class nsIArray;
|
||||
@ -85,7 +86,6 @@ class DOMEventTargetHelper;
|
||||
class ThrottledEventQueue;
|
||||
namespace dom {
|
||||
class BarProp;
|
||||
class BrowsingContext;
|
||||
struct ChannelPixelLayout;
|
||||
class Console;
|
||||
class Crypto;
|
||||
@ -869,6 +869,7 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
||||
mozilla::dom::CallerType aCallerType,
|
||||
mozilla::ErrorResult& aError);
|
||||
nsRect GetInnerScreenRect();
|
||||
static Maybe<mozilla::CSSIntSize> GetRDMDeviceSize(const Document& aDocument);
|
||||
|
||||
bool IsFrame();
|
||||
|
||||
@ -890,33 +891,44 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
||||
}
|
||||
|
||||
// Convenience functions for the many methods that need to scale
|
||||
// from device to CSS pixels or vice versa. Note: if a presentation
|
||||
// context is not available, they will assume a 1:1 ratio.
|
||||
// from device to CSS pixels. This computes it with cached scale in
|
||||
// PresContext which may be not recent information of the widget.
|
||||
// Note: if PresContext is not available, they will assume a 1:1 ratio.
|
||||
int32_t DevToCSSIntPixels(int32_t px);
|
||||
int32_t CSSToDevIntPixels(int32_t px);
|
||||
nsIntSize DevToCSSIntPixels(nsIntSize px);
|
||||
nsIntSize CSSToDevIntPixels(nsIntSize px);
|
||||
|
||||
virtual void SetFocusedElement(mozilla::dom::Element* aElement,
|
||||
uint32_t aFocusMethod = 0,
|
||||
bool aNeedsFocus = false) override;
|
||||
// Convenience functions for the methods which call methods of nsIBaseWindow
|
||||
// because it takes/returns device pixels. Unfortunately, mPresContext may
|
||||
// have older scale value for the corresponding widget. Therefore, these
|
||||
// helper methods convert between CSS pixels and device pixels with aWindow.
|
||||
int32_t DevToCSSIntPixelsForBaseWindow(int32_t aDevicePixels,
|
||||
nsIBaseWindow* aWindow);
|
||||
nsIntSize DevToCSSIntPixelsForBaseWindow(nsIntSize aDeviceSize,
|
||||
nsIBaseWindow* aWindow);
|
||||
int32_t CSSToDevIntPixelsForBaseWindow(int32_t aCSSPixels,
|
||||
nsIBaseWindow* aWindow);
|
||||
nsIntSize CSSToDevIntPixelsForBaseWindow(nsIntSize aCSSSize,
|
||||
nsIBaseWindow* aWindow);
|
||||
|
||||
virtual uint32_t GetFocusMethod() override;
|
||||
void SetFocusedElement(mozilla::dom::Element* aElement,
|
||||
uint32_t aFocusMethod = 0, bool aNeedsFocus = false,
|
||||
bool aWillShowOutline = false) override;
|
||||
|
||||
virtual bool ShouldShowFocusRing() override;
|
||||
uint32_t GetFocusMethod() override;
|
||||
|
||||
virtual void SetKeyboardIndicators(UIStateChangeType aShowFocusRings)
|
||||
override;
|
||||
bool ShouldShowFocusRing() override;
|
||||
|
||||
void SetKeyboardIndicators(UIStateChangeType aShowFocusRings) override;
|
||||
|
||||
public:
|
||||
virtual already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() override;
|
||||
already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() override;
|
||||
|
||||
protected:
|
||||
void NotifyWindowIDDestroyed(const char* aTopic);
|
||||
|
||||
void ClearStatus();
|
||||
|
||||
virtual void UpdateParentTarget() override;
|
||||
void UpdateParentTarget() override;
|
||||
|
||||
void InitializeShowFocusRings();
|
||||
|
||||
|
@ -19,7 +19,6 @@ class nsAttrValue;
|
||||
class nsAttrName;
|
||||
class nsTextFragment;
|
||||
class nsIFrame;
|
||||
class nsXBLBinding;
|
||||
|
||||
namespace mozilla {
|
||||
class EventChainPreVisitor;
|
||||
@ -67,6 +66,7 @@ class nsIContent : public nsINode {
|
||||
explicit nsIContent(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
|
||||
: nsINode(std::move(aNodeInfo)) {
|
||||
MOZ_ASSERT(mNodeInfo);
|
||||
MOZ_ASSERT(static_cast<nsINode*>(this) == reinterpret_cast<nsINode*>(this));
|
||||
SetNodeIsContent();
|
||||
}
|
||||
#endif // MOZILLA_INTERNAL_API
|
||||
@ -125,48 +125,28 @@ class nsIContent : public nsINode {
|
||||
*
|
||||
* @note the result children order is
|
||||
* 1. :before generated node
|
||||
* 2. XBL flattened tree children of this node
|
||||
* 2. Shadow DOM flattened tree children of this node
|
||||
* 3. native anonymous nodes
|
||||
* 4. :after generated node
|
||||
*/
|
||||
eAllChildren = 0,
|
||||
|
||||
/**
|
||||
* All XBL explicit children of the node (see
|
||||
* http://www.w3.org/TR/xbl/#explicit3 ), as well as :before and :after
|
||||
* anonymous content and native anonymous children.
|
||||
*
|
||||
* @note the result children order is
|
||||
* 1. :before generated node
|
||||
* 2. XBL explicit children of the node
|
||||
* 3. native anonymous nodes
|
||||
* 4. :after generated node
|
||||
* Skip native anonymous content created for placeholder of HTML input.
|
||||
*/
|
||||
eAllButXBL = 1,
|
||||
|
||||
/**
|
||||
* Skip native anonymous content created for placeholder of HTML input,
|
||||
* used in conjunction with eAllChildren or eAllButXBL.
|
||||
*/
|
||||
eSkipPlaceholderContent = 2,
|
||||
eSkipPlaceholderContent = 1 << 0,
|
||||
|
||||
/**
|
||||
* Skip native anonymous content created by ancestor frames of the root
|
||||
* element's primary frame, such as scrollbar elements created by the root
|
||||
* scroll frame.
|
||||
*/
|
||||
eSkipDocumentLevelNativeAnonymousContent = 4,
|
||||
eSkipDocumentLevelNativeAnonymousContent = 1 << 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* Return either the XBL explicit children of the node or the XBL flattened
|
||||
* tree children of the node, depending on the filter, as well as
|
||||
* native anonymous children.
|
||||
*
|
||||
* @note calling this method with eAllButXBL will return children that are
|
||||
* also in the eAllButXBL and eAllChildren child lists of other descendants
|
||||
* of this node in the tree, but those other nodes cannot be reached from the
|
||||
* eAllButXBL child list.
|
||||
* Return the flattened tree children of the node, depending on the filter, as
|
||||
* well as native anonymous children.
|
||||
*/
|
||||
virtual already_AddRefed<nsINodeList> GetChildren(uint32_t aFilter) = 0;
|
||||
|
||||
@ -175,7 +155,7 @@ class nsIContent : public nsINode {
|
||||
* @see nsIAnonymousContentCreator
|
||||
*/
|
||||
void SetIsNativeAnonymousRoot() {
|
||||
SetFlags(NODE_IS_ANONYMOUS_ROOT | NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE |
|
||||
SetFlags(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE |
|
||||
NODE_IS_NATIVE_ANONYMOUS_ROOT);
|
||||
}
|
||||
|
||||
@ -185,28 +165,16 @@ class nsIContent : public nsINode {
|
||||
*/
|
||||
nsIContent* FindFirstNonChromeOnlyAccessContent() const;
|
||||
|
||||
#ifdef DEBUG
|
||||
void AssertAnonymousSubtreeRelatedInvariants() const;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns true if and only if this node has a parent, but is not in
|
||||
* its parent's child list.
|
||||
*
|
||||
* FIXME(emilio): Remove along nsINode::IsInAnonymousSubtree.
|
||||
*/
|
||||
bool IsRootOfAnonymousSubtree() const {
|
||||
#ifdef DEBUG
|
||||
AssertAnonymousSubtreeRelatedInvariants();
|
||||
#endif
|
||||
return HasFlag(NODE_IS_ANONYMOUS_ROOT);
|
||||
return IsRootOfNativeAnonymousSubtree();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if there is NOT a path through child lists
|
||||
* from the top of this node's parent chain back to this node or
|
||||
* if the node is in native anonymous subtree without a parent.
|
||||
*/
|
||||
inline bool IsInAnonymousSubtree() const;
|
||||
|
||||
/**
|
||||
* Return true iff this node is in an HTML document (in the HTML5 sense of
|
||||
* the term, i.e. not in an XHTML/XML document).
|
||||
@ -272,8 +240,6 @@ class nsIContent : public nsINode {
|
||||
return IsMathMLElement() && IsNodeInternal(aFirst, aArgs...);
|
||||
}
|
||||
|
||||
inline bool IsActiveChildrenElement() const;
|
||||
|
||||
bool IsGeneratedContentContainerForBefore() const {
|
||||
return IsRootOfNativeAnonymousSubtree() &&
|
||||
mNodeInfo->NameAtom() == nsGkAtoms::mozgeneratedcontentbefore;
|
||||
@ -380,36 +346,6 @@ class nsIContent : public nsINode {
|
||||
*/
|
||||
virtual IMEState GetDesiredIMEState();
|
||||
|
||||
/**
|
||||
* Gets content node with the binding (or native code, possibly on the
|
||||
* frame) responsible for our construction (and existence). Used by
|
||||
* anonymous content (both XBL-generated and native-anonymous).
|
||||
*
|
||||
* null for all explicit content (i.e., content reachable from the top
|
||||
* of its GetParent() chain via child lists).
|
||||
*
|
||||
* @return the binding parent
|
||||
*/
|
||||
virtual mozilla::dom::Element* GetBindingParent() const {
|
||||
const nsExtendedContentSlots* slots = GetExistingExtendedContentSlots();
|
||||
return slots ? slots->mBindingParent.get() : nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current XBL binding that is bound to this element.
|
||||
*
|
||||
* @return the current binding.
|
||||
*/
|
||||
nsXBLBinding* GetXBLBinding() const {
|
||||
if (!HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return DoGetXBLBinding();
|
||||
}
|
||||
|
||||
virtual nsXBLBinding* DoGetXBLBinding() const = 0;
|
||||
|
||||
/**
|
||||
* Gets the ShadowRoot binding for this element.
|
||||
*
|
||||
@ -419,8 +355,6 @@ class nsIContent : public nsINode {
|
||||
|
||||
/**
|
||||
* Gets the root of the node tree for this content if it is in a shadow tree.
|
||||
* This method is called |GetContainingShadow| instead of |GetRootShadowRoot|
|
||||
* to avoid confusion with |GetShadowRoot|.
|
||||
*
|
||||
* @return The ShadowRoot that is the root of the node tree.
|
||||
*/
|
||||
@ -429,14 +363,6 @@ class nsIContent : public nsINode {
|
||||
return slots ? slots->mContainingShadow.get() : nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the shadow host if this content is in a shadow tree. That is, the host
|
||||
* of |GetContainingShadow|, if its not null.
|
||||
*
|
||||
* @return The shadow host, if this is in shadow tree, or null.
|
||||
*/
|
||||
nsIContent* GetContainingShadowHost() const;
|
||||
|
||||
/**
|
||||
* Gets the assigned slot associated with this content.
|
||||
*
|
||||
@ -463,29 +389,6 @@ class nsIContent : public nsINode {
|
||||
*/
|
||||
mozilla::dom::HTMLSlotElement* GetAssignedSlotByMode() const;
|
||||
|
||||
nsIContent* GetXBLInsertionParent() const {
|
||||
nsIContent* ip = GetXBLInsertionPoint();
|
||||
return ip ? ip->GetParent() : nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the insertion parent element of the XBL binding.
|
||||
* The insertion parent is our one true parent in the transformed DOM.
|
||||
*
|
||||
* @return the insertion parent element.
|
||||
*/
|
||||
nsIContent* GetXBLInsertionPoint() const {
|
||||
const nsExtendedContentSlots* slots = GetExistingExtendedContentSlots();
|
||||
return slots ? slots->mXBLInsertionPoint.get() : nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the insertion parent element of the XBL binding.
|
||||
*
|
||||
* @param aContent The insertion parent element.
|
||||
*/
|
||||
void SetXBLInsertionPoint(nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* Same as GetFlattenedTreeParentNode, but returns null if the parent is
|
||||
* non-nsIContent.
|
||||
@ -542,9 +445,8 @@ class nsIContent : public nsINode {
|
||||
* For container elements, this is called *before* any of the children are
|
||||
* created or added into the tree.
|
||||
*
|
||||
* NOTE: this is currently only called for input and button, in the HTML
|
||||
* content sink. If you want to call it on your element, modify the content
|
||||
* sink of your choice to do so. This is an efficiency measure.
|
||||
* NOTE: this is only called for elements listed in
|
||||
* RequiresDoneCreatingElement. This is an efficiency measure.
|
||||
*
|
||||
* If you also need to determine whether the parser is the one creating your
|
||||
* element (through createElement() or cloneNode() generally) then add a
|
||||
@ -565,10 +467,8 @@ class nsIContent : public nsINode {
|
||||
* This method is called when the parser finishes creating the element's
|
||||
* children, if any are present.
|
||||
*
|
||||
* NOTE: this is currently only called for textarea, select, and object
|
||||
* elements in the HTML content sink. If you want to call it on your element,
|
||||
* modify the content sink of your choice to do so. This is an efficiency
|
||||
* measure.
|
||||
* NOTE: this is only called for elements listed in
|
||||
* RequiresDoneAddingChildren. This is an efficiency measure.
|
||||
*
|
||||
* If you also need to determine whether the parser is the one creating your
|
||||
* element (through createElement() or cloneNode() generally) then add a
|
||||
@ -595,6 +495,47 @@ class nsIContent : public nsINode {
|
||||
*/
|
||||
virtual bool IsDoneAddingChildren() { return true; }
|
||||
|
||||
/**
|
||||
* Returns true if an element needs its DoneCreatingElement method to be
|
||||
* called after it has been created.
|
||||
* @see nsIContent::DoneCreatingElement
|
||||
*
|
||||
* @param aNamespaceID the node's namespace ID
|
||||
* @param aName the node's tag name
|
||||
*/
|
||||
static inline bool RequiresDoneCreatingElement(int32_t aNamespace,
|
||||
nsAtom* aName) {
|
||||
if (aNamespace == kNameSpaceID_XHTML &&
|
||||
(aName == nsGkAtoms::input || aName == nsGkAtoms::button ||
|
||||
aName == nsGkAtoms::menuitem || aName == nsGkAtoms::audio ||
|
||||
aName == nsGkAtoms::video)) {
|
||||
MOZ_ASSERT(
|
||||
!RequiresDoneAddingChildren(aNamespace, aName),
|
||||
"Both DoneCreatingElement and DoneAddingChildren on a same element "
|
||||
"isn't supported.");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if an element needs its DoneAddingChildren method to be
|
||||
* called after all of its children have been added.
|
||||
* @see nsIContent::DoneAddingChildren
|
||||
*
|
||||
* @param aNamespace the node's namespace ID
|
||||
* @param aName the node's tag name
|
||||
*/
|
||||
static inline bool RequiresDoneAddingChildren(int32_t aNamespace,
|
||||
nsAtom* aName) {
|
||||
return (aNamespace == kNameSpaceID_XHTML &&
|
||||
(aName == nsGkAtoms::select || aName == nsGkAtoms::textarea ||
|
||||
aName == nsGkAtoms::head || aName == nsGkAtoms::title ||
|
||||
aName == nsGkAtoms::object || aName == nsGkAtoms::output)) ||
|
||||
(aNamespace == kNameSpaceID_SVG && aName == nsGkAtoms::title) ||
|
||||
(aNamespace == kNameSpaceID_XUL && aName == nsGkAtoms::linkset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of this content node (the atom corresponding to the
|
||||
* value of the id attribute). This may be null if there is no ID.
|
||||
@ -737,18 +678,6 @@ class nsIContent : public nsINode {
|
||||
virtual size_t SizeOfExcludingThis(
|
||||
mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
/**
|
||||
* The nearest enclosing content node with a binding that created us.
|
||||
*
|
||||
* @see nsIContent::GetBindingParent
|
||||
*/
|
||||
RefPtr<mozilla::dom::Element> mBindingParent;
|
||||
|
||||
/**
|
||||
* @see nsIContent::GetXBLInsertionPoint
|
||||
*/
|
||||
nsCOMPtr<nsIContent> mXBLInsertionPoint;
|
||||
|
||||
/**
|
||||
* @see nsIContent::GetContainingShadow
|
||||
*/
|
||||
@ -887,13 +816,4 @@ class nsIContent : public nsINode {
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIContent, NS_ICONTENT_IID)
|
||||
|
||||
inline nsIContent* nsINode::AsContent() {
|
||||
MOZ_ASSERT(IsContent());
|
||||
return static_cast<nsIContent*>(this);
|
||||
}
|
||||
|
||||
inline const nsIContent* nsINode::AsContent() const {
|
||||
return const_cast<nsINode*>(this)->AsContent();
|
||||
}
|
||||
|
||||
#endif /* nsIContent_h___ */
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
#include "nsIContent.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "nsBindingManager.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsAtom.h"
|
||||
#include "nsIFrame.h"
|
||||
@ -116,23 +115,6 @@ static inline nsINode* GetFlattenedTreeParentNode(const nsINode* aNode) {
|
||||
}
|
||||
}
|
||||
|
||||
if (content->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR) ||
|
||||
parent->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
|
||||
if (nsIContent* xblInsertionPoint = content->GetXBLInsertionPoint()) {
|
||||
return xblInsertionPoint->GetParent();
|
||||
}
|
||||
|
||||
if (parent->OwnerDoc()->BindingManager()->GetBindingWithContent(
|
||||
parentAsContent)) {
|
||||
// This is an unassigned node child of the bound element, so it isn't part
|
||||
// of the flat tree.
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!parentAsContent->IsActiveChildrenElement(),
|
||||
"<xbl:children> isn't in the flattened tree");
|
||||
|
||||
// Common case.
|
||||
return parent;
|
||||
}
|
||||
@ -180,45 +162,6 @@ inline bool nsINode::IsEditable() const {
|
||||
return doc && doc->HasFlag(NODE_IS_EDITABLE);
|
||||
}
|
||||
|
||||
inline bool nsIContent::IsActiveChildrenElement() const {
|
||||
if (!mNodeInfo->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsIContent* bindingParent = GetBindingParent();
|
||||
if (!bindingParent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We reuse the binding parent machinery for Shadow DOM too, so prevent that
|
||||
// from getting us confused in this case.
|
||||
return !bindingParent->GetShadowRoot();
|
||||
}
|
||||
|
||||
inline bool nsIContent::IsInAnonymousSubtree() const {
|
||||
NS_ASSERTION(
|
||||
!IsInNativeAnonymousSubtree() || GetBindingParent() ||
|
||||
(!IsInUncomposedDoc() && static_cast<nsIContent*>(SubtreeRoot())
|
||||
->IsInNativeAnonymousSubtree()),
|
||||
"Must have binding parent when in native anonymous subtree which is in "
|
||||
"document.\n"
|
||||
"Native anonymous subtree which is not in document must have native "
|
||||
"anonymous root.");
|
||||
|
||||
if (IsInNativeAnonymousSubtree()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsIContent* bindingParent = GetBindingParent();
|
||||
if (!bindingParent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We reuse the binding parent machinery for Shadow DOM too, so prevent that
|
||||
// from getting us confused in this case.
|
||||
return !bindingParent->GetShadowRoot();
|
||||
}
|
||||
|
||||
inline void nsIContent::HandleInsertionToOrRemovalFromSlot() {
|
||||
using mozilla::dom::HTMLSlotElement;
|
||||
|
||||
|
@ -105,11 +105,9 @@ interface nsIContentPolicy : nsISupports
|
||||
*/
|
||||
const nsContentPolicyType TYPE_REFRESH = 8;
|
||||
|
||||
/**
|
||||
* Indicates an XBL binding request, triggered either by -moz-binding CSS
|
||||
* property.
|
||||
/*
|
||||
* XXX: nsContentPolicyType = 9 used to inicate an XBL binding request.
|
||||
*/
|
||||
const nsContentPolicyType TYPE_XBL = 9;
|
||||
|
||||
/**
|
||||
* Indicates a ping triggered by a click on <A PING="..."> element.
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include "mozilla/dom/L10nOverlays.h"
|
||||
#include "mozilla/StaticPrefs_layout.h"
|
||||
#include "nsAttrValueOrString.h"
|
||||
#include "nsBindingManager.h"
|
||||
#include "nsCCUncollectableMarker.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsContentList.h"
|
||||
@ -78,7 +77,6 @@
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsNameSpaceManager.h"
|
||||
#include "nsNodeInfoManager.h"
|
||||
#include "nsPIBoxObject.h"
|
||||
#include "nsObjectLoadingContent.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsPresContext.h"
|
||||
@ -88,8 +86,6 @@
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsTextNode.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsXBLBinding.h"
|
||||
#include "nsXBLPrototypeBinding.h"
|
||||
#include "nsWindowSizes.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "xpcpublic.h"
|
||||
@ -497,20 +493,19 @@ static nsIContent* GetRootForContentSubtree(nsIContent* aContent) {
|
||||
// Special case for ShadowRoot because the ShadowRoot itself is
|
||||
// the root. This is necessary to prevent selection from crossing
|
||||
// the ShadowRoot boundary.
|
||||
ShadowRoot* containingShadow = aContent->GetContainingShadow();
|
||||
if (containingShadow) {
|
||||
//
|
||||
// FIXME(emilio): The NAC check should probably be done before this? We can
|
||||
// have NAC inside shadow DOM.
|
||||
if (ShadowRoot* containingShadow = aContent->GetContainingShadow()) {
|
||||
return containingShadow;
|
||||
}
|
||||
|
||||
nsIContent* stop = aContent->GetBindingParent();
|
||||
while (aContent) {
|
||||
nsIContent* parent = aContent->GetParent();
|
||||
if (parent == stop) {
|
||||
break;
|
||||
}
|
||||
aContent = parent;
|
||||
if (nsIContent* nativeAnonRoot = aContent->GetClosestNativeAnonymousSubtreeRoot()) {
|
||||
return nativeAnonRoot;
|
||||
}
|
||||
return aContent;
|
||||
if (Document* doc = aContent->GetUncomposedDoc()) {
|
||||
return doc->GetRootElement();
|
||||
}
|
||||
return nsIContent::FromNode(aContent->SubtreeRoot());
|
||||
}
|
||||
|
||||
nsIContent* nsINode::GetSelectionRootContent(PresShell* aPresShell) {
|
||||
@ -523,7 +518,7 @@ nsIContent* nsINode::GetSelectionRootContent(PresShell* aPresShell) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (static_cast<nsIContent*>(this)->HasIndependentSelection()) {
|
||||
if (AsContent()->HasIndependentSelection()) {
|
||||
// This node should be a descendant of input/textarea editor.
|
||||
nsIContent* content = GetTextEditorRootContent();
|
||||
if (content) return content;
|
||||
@ -541,7 +536,7 @@ nsIContent* nsINode::GetSelectionRootContent(PresShell* aPresShell) {
|
||||
NS_ENSURE_TRUE(editorRoot, nullptr);
|
||||
return nsContentUtils::IsInSameAnonymousTree(this, editorRoot)
|
||||
? editorRoot
|
||||
: GetRootForContentSubtree(static_cast<nsIContent*>(this));
|
||||
: GetRootForContentSubtree(AsContent());
|
||||
}
|
||||
// If the document isn't editable but this is editable, this is in
|
||||
// contenteditable. Use the editing host element for selection root.
|
||||
@ -565,7 +560,7 @@ nsIContent* nsINode::GetSelectionRootContent(PresShell* aPresShell) {
|
||||
// root. Otherwise, we can return the content simply.
|
||||
NS_ENSURE_TRUE(content, nullptr);
|
||||
if (!nsContentUtils::IsInSameAnonymousTree(this, content)) {
|
||||
content = GetRootForContentSubtree(static_cast<nsIContent*>(this));
|
||||
content = GetRootForContentSubtree(AsContent());
|
||||
// Fixup for ShadowRoot because the ShadowRoot itself does not have a frame.
|
||||
// Use the host as the root.
|
||||
if (ShadowRoot* shadowRoot = ShadowRoot::FromNode(content)) {
|
||||
@ -680,38 +675,12 @@ void nsINode::LastRelease() {
|
||||
UnsetFlags(NODE_HAS_LISTENERMANAGER);
|
||||
}
|
||||
|
||||
if (Element* element = Element::FromNode(this)) {
|
||||
element->OwnerDoc()->ClearBoxObjectFor(element);
|
||||
NS_ASSERTION(!element->GetXBLBinding(), "Node has binding on destruction");
|
||||
}
|
||||
|
||||
ReleaseWrapper(this);
|
||||
|
||||
FragmentOrElement::RemoveBlackMarkedNode(this);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void nsINode::CheckNotNativeAnonymous() const {
|
||||
if (!IsContent()) return;
|
||||
nsIContent* content =
|
||||
static_cast<const nsIContent*>(this)->GetBindingParent();
|
||||
while (content) {
|
||||
if (content->IsRootOfNativeAnonymousSubtree()) {
|
||||
NS_ERROR("Element not marked to be in native anonymous subtree!");
|
||||
break;
|
||||
}
|
||||
content = content->GetBindingParent();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool nsINode::IsInAnonymousSubtree() const {
|
||||
if (!IsContent()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return AsContent()->IsInAnonymousSubtree();
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& aStream, const nsINode& aNode) {
|
||||
nsAutoString elemDesc;
|
||||
@ -740,9 +709,23 @@ std::ostream& operator<<(std::ostream& aStream, const nsINode& aNode) {
|
||||
return aStream << str.get();
|
||||
}
|
||||
|
||||
ShadowRoot* nsINode::GetContainingShadow() const {
|
||||
if (!IsInShadowTree()) {
|
||||
return nullptr;
|
||||
}
|
||||
return AsContent()->GetContainingShadow();
|
||||
}
|
||||
|
||||
nsIContent* nsINode::GetContainingShadowHost() const {
|
||||
if (ShadowRoot* shadow = GetContainingShadow()) {
|
||||
return shadow->GetHost();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SVGUseElement* nsINode::DoGetContainingSVGUseShadowHost() const {
|
||||
MOZ_ASSERT(IsInShadowTree());
|
||||
return SVGUseElement::FromNodeOrNull(AsContent()->GetContainingShadowHost());
|
||||
return SVGUseElement::FromNodeOrNull(GetContainingShadowHost());
|
||||
}
|
||||
|
||||
void nsINode::GetNodeValueInternal(nsAString& aNodeValue) {
|
||||
@ -1344,12 +1327,7 @@ nsIGlobalObject* nsINode::GetOwnerGlobal() const {
|
||||
}
|
||||
|
||||
bool nsINode::UnoptimizableCCNode() const {
|
||||
const uintptr_t problematicFlags =
|
||||
(NODE_IS_ANONYMOUS_ROOT | NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE |
|
||||
NODE_IS_NATIVE_ANONYMOUS_ROOT | NODE_MAY_BE_IN_BINDING_MNGR);
|
||||
return HasFlag(problematicFlags) || NodeType() == ATTRIBUTE_NODE ||
|
||||
// For strange cases like xbl:content/xbl:children
|
||||
(IsElement() && AsElement()->IsInNamespace(kNameSpaceID_XBL));
|
||||
return IsInNativeAnonymousSubtree() || IsAttr();
|
||||
}
|
||||
|
||||
/* static */
|
||||
@ -2801,29 +2779,47 @@ bool nsINode::Contains(const nsINode* aOther) const {
|
||||
if (aOther == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!aOther || OwnerDoc() != aOther->OwnerDoc() ||
|
||||
IsInUncomposedDoc() != aOther->IsInUncomposedDoc() ||
|
||||
!aOther->IsContent() || !GetFirstChild()) {
|
||||
!aOther->IsContent() || !HasChildren()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const nsIContent* other = static_cast<const nsIContent*>(aOther);
|
||||
if (this == OwnerDoc()) {
|
||||
if (IsDocument()) {
|
||||
// document.contains(aOther) returns true if aOther is in the document,
|
||||
// but is not in any anonymous subtree.
|
||||
// IsInUncomposedDoc() check is done already before this.
|
||||
return !other->IsInAnonymousSubtree();
|
||||
return !aOther->IsInAnonymousSubtree();
|
||||
}
|
||||
|
||||
if (!IsElement() && !IsDocumentFragment()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AsContent()->GetBindingParent() != other->GetBindingParent()) {
|
||||
if (IsInShadowTree() != aOther->IsInShadowTree() ||
|
||||
IsInNativeAnonymousSubtree() != aOther->IsInNativeAnonymousSubtree()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return other->IsInclusiveDescendantOf(this);
|
||||
if (IsInNativeAnonymousSubtree()) {
|
||||
if (GetClosestNativeAnonymousSubtreeRoot() !=
|
||||
aOther->GetClosestNativeAnonymousSubtreeRoot()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsInShadowTree()) {
|
||||
ShadowRoot* otherRoot = aOther->GetContainingShadow();
|
||||
if (IsShadowRoot()) {
|
||||
return otherRoot == this;
|
||||
}
|
||||
if (otherRoot != GetContainingShadow()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return aOther->IsInclusiveDescendantOf(this);
|
||||
}
|
||||
|
||||
uint32_t nsINode::Length() const {
|
||||
@ -3174,7 +3170,6 @@ already_AddRefed<nsINode> nsINode::CloneAndAdopt(
|
||||
|
||||
bool wasRegistered = false;
|
||||
if (elem) {
|
||||
oldDoc->ClearBoxObjectFor(elem);
|
||||
wasRegistered = oldDoc->UnregisterActivityObserver(elem);
|
||||
}
|
||||
|
||||
@ -3479,21 +3474,3 @@ size_t nsNodeWeakReference::SizeOfOnlyThis(
|
||||
mozilla::MallocSizeOf aMallocSizeOf) const {
|
||||
return aMallocSizeOf(this);
|
||||
}
|
||||
|
||||
nsIContent* nsINode::GetClosestNativeAnonymousSubtreeRoot() const {
|
||||
if (!IsInNativeAnonymousSubtree()) {
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ASSERT(IsContent(), "How did non-content end up in NAC?");
|
||||
for (const nsINode* node = this; node; node = node->GetParentNode()) {
|
||||
if (node->IsRootOfNativeAnonymousSubtree()) {
|
||||
return const_cast<nsINode*>(node)->AsContent();
|
||||
}
|
||||
}
|
||||
// FIXME(emilio): This should not happen, usually, but editor removes nodes
|
||||
// in native anonymous subtrees, and we don't clean nodes from the current
|
||||
// event content stack from ContentRemoved, so it can actually happen, see
|
||||
// bug 1510208.
|
||||
NS_WARNING("GetClosestNativeAnonymousSubtreeRoot on disconnected NAC!");
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -97,6 +97,7 @@ class Optional;
|
||||
class OwningNodeOrString;
|
||||
template <typename>
|
||||
class Sequence;
|
||||
class ShadowRoot;
|
||||
class SVGUseElement;
|
||||
class Text;
|
||||
class TextOrElementOrDocument;
|
||||
@ -116,47 +117,35 @@ enum {
|
||||
// Whether this node has had any properties set on it
|
||||
NODE_HAS_PROPERTIES = NODE_FLAG_BIT(1),
|
||||
|
||||
// Whether this node is the root of an anonymous subtree. Note that this
|
||||
// need not be a native anonymous subtree. Any anonymous subtree, including
|
||||
// XBL-generated ones, will do. This flag is set-once: once a node has it,
|
||||
// it must not be removed.
|
||||
// NOTE: Should only be used on nsIContent nodes
|
||||
NODE_IS_ANONYMOUS_ROOT = NODE_FLAG_BIT(2),
|
||||
|
||||
// Whether the node has some ancestor, possibly itself, that is native
|
||||
// anonymous. This includes ancestors crossing XBL scopes, in cases when an
|
||||
// XBL binding is attached to an element which has a native anonymous
|
||||
// ancestor. This flag is set-once: once a node has it, it must not be
|
||||
// removed.
|
||||
// NOTE: Should only be used on nsIContent nodes
|
||||
NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE = NODE_FLAG_BIT(3),
|
||||
NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE = NODE_FLAG_BIT(2),
|
||||
|
||||
// Whether this node is the root of a native anonymous (from the perspective
|
||||
// of its parent) subtree. This flag is set-once: once a node has it, it
|
||||
// must not be removed.
|
||||
// NOTE: Should only be used on nsIContent nodes
|
||||
NODE_IS_NATIVE_ANONYMOUS_ROOT = NODE_FLAG_BIT(4),
|
||||
NODE_IS_NATIVE_ANONYMOUS_ROOT = NODE_FLAG_BIT(3),
|
||||
|
||||
// Whether a binding manager may have a pointer to this
|
||||
NODE_MAY_BE_IN_BINDING_MNGR = NODE_FLAG_BIT(5),
|
||||
|
||||
NODE_IS_EDITABLE = NODE_FLAG_BIT(6),
|
||||
|
||||
// Free bit here.
|
||||
NODE_IS_EDITABLE = NODE_FLAG_BIT(4),
|
||||
|
||||
// Whether the node participates in a shadow tree.
|
||||
NODE_IS_IN_SHADOW_TREE = NODE_FLAG_BIT(8),
|
||||
NODE_IS_IN_SHADOW_TREE = NODE_FLAG_BIT(5),
|
||||
|
||||
// Node has an :empty or :-moz-only-whitespace selector
|
||||
NODE_HAS_EMPTY_SELECTOR = NODE_FLAG_BIT(9),
|
||||
NODE_HAS_EMPTY_SELECTOR = NODE_FLAG_BIT(6),
|
||||
|
||||
// A child of the node has a selector such that any insertion,
|
||||
// removal, or appending of children requires restyling the parent.
|
||||
NODE_HAS_SLOW_SELECTOR = NODE_FLAG_BIT(10),
|
||||
NODE_HAS_SLOW_SELECTOR = NODE_FLAG_BIT(7),
|
||||
|
||||
// A child of the node has a :first-child, :-moz-first-node,
|
||||
// :only-child, :last-child or :-moz-last-node selector.
|
||||
NODE_HAS_EDGE_CHILD_SELECTOR = NODE_FLAG_BIT(11),
|
||||
NODE_HAS_EDGE_CHILD_SELECTOR = NODE_FLAG_BIT(8),
|
||||
|
||||
// A child of the node has a selector such that any insertion or
|
||||
// removal of children requires restyling later siblings of that
|
||||
@ -165,7 +154,7 @@ enum {
|
||||
// other content tree changes (e.g., the child changes to or from
|
||||
// matching :empty due to a grandchild insertion or removal), the
|
||||
// child's later siblings must also be restyled.
|
||||
NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS = NODE_FLAG_BIT(12),
|
||||
NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS = NODE_FLAG_BIT(9),
|
||||
|
||||
NODE_ALL_SELECTOR_FLAGS = NODE_HAS_EMPTY_SELECTOR | NODE_HAS_SLOW_SELECTOR |
|
||||
NODE_HAS_EDGE_CHILD_SELECTOR |
|
||||
@ -173,32 +162,32 @@ enum {
|
||||
|
||||
// This node needs to go through frame construction to get a frame (or
|
||||
// undisplayed entry).
|
||||
NODE_NEEDS_FRAME = NODE_FLAG_BIT(13),
|
||||
NODE_NEEDS_FRAME = NODE_FLAG_BIT(10),
|
||||
|
||||
// At least one descendant in the flattened tree has NODE_NEEDS_FRAME set.
|
||||
// This should be set on every node on the flattened tree path between the
|
||||
// node(s) with NODE_NEEDS_FRAME and the root content.
|
||||
NODE_DESCENDANTS_NEED_FRAMES = NODE_FLAG_BIT(14),
|
||||
NODE_DESCENDANTS_NEED_FRAMES = NODE_FLAG_BIT(11),
|
||||
|
||||
// Set if the node has the accesskey attribute set.
|
||||
NODE_HAS_ACCESSKEY = NODE_FLAG_BIT(15),
|
||||
NODE_HAS_ACCESSKEY = NODE_FLAG_BIT(12),
|
||||
|
||||
// Set if the node has right-to-left directionality
|
||||
NODE_HAS_DIRECTION_RTL = NODE_FLAG_BIT(16),
|
||||
NODE_HAS_DIRECTION_RTL = NODE_FLAG_BIT(13),
|
||||
|
||||
// Set if the node has left-to-right directionality
|
||||
NODE_HAS_DIRECTION_LTR = NODE_FLAG_BIT(17),
|
||||
NODE_HAS_DIRECTION_LTR = NODE_FLAG_BIT(14),
|
||||
|
||||
NODE_ALL_DIRECTION_FLAGS = NODE_HAS_DIRECTION_LTR | NODE_HAS_DIRECTION_RTL,
|
||||
|
||||
NODE_HAS_BEEN_IN_UA_WIDGET = NODE_FLAG_BIT(18),
|
||||
NODE_HAS_BEEN_IN_UA_WIDGET = NODE_FLAG_BIT(15),
|
||||
|
||||
// Set if the node has a nonce value and a header delivered CSP.
|
||||
NODE_HAS_NONCE_AND_HEADER_CSP = NODE_FLAG_BIT(19),
|
||||
NODE_HAS_NONCE_AND_HEADER_CSP = NODE_FLAG_BIT(16),
|
||||
|
||||
NODE_KEEPS_DOMARENA = NODE_FLAG_BIT(20),
|
||||
NODE_KEEPS_DOMARENA = NODE_FLAG_BIT(17),
|
||||
// Remaining bits are node type specific.
|
||||
NODE_TYPE_SPECIFIC_BITS_OFFSET = 21
|
||||
NODE_TYPE_SPECIFIC_BITS_OFFSET = 18
|
||||
};
|
||||
|
||||
// Make sure we have space for our bits
|
||||
@ -463,8 +452,7 @@ class nsINode : public mozilla::dom::EventTarget {
|
||||
inline mozilla::dom::DocumentFragment* AsDocumentFragment();
|
||||
inline const mozilla::dom::DocumentFragment* AsDocumentFragment() const;
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
JSObject* WrapObject(JSContext*, JS::Handle<JSObject*> aGivenProto) final;
|
||||
|
||||
/**
|
||||
* Hook for constructing JS::ubi::Concrete specializations for memory
|
||||
@ -539,10 +527,18 @@ class nsINode : public mozilla::dom::EventTarget {
|
||||
|
||||
/**
|
||||
* Return this node as nsIContent. Should only be used for nodes for which
|
||||
* IsContent() is true. This is defined inline in nsIContent.h.
|
||||
* IsContent() is true.
|
||||
*
|
||||
* The assertion in nsIContent's constructor makes this safe.
|
||||
*/
|
||||
inline nsIContent* AsContent();
|
||||
inline const nsIContent* AsContent() const;
|
||||
nsIContent* AsContent() {
|
||||
MOZ_ASSERT(IsContent());
|
||||
return reinterpret_cast<nsIContent*>(this);
|
||||
}
|
||||
const nsIContent* AsContent() const {
|
||||
MOZ_ASSERT(IsContent());
|
||||
return reinterpret_cast<const nsIContent*>(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return whether the node is a Text node (which might be an actual
|
||||
@ -957,7 +953,7 @@ class nsINode : public mozilla::dom::EventTarget {
|
||||
*/
|
||||
nsIContent* GetParent() const {
|
||||
return MOZ_LIKELY(GetBoolFlag(ParentIsContent))
|
||||
? reinterpret_cast<nsIContent*>(mParent)
|
||||
? mParent->AsContent()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
@ -1269,19 +1265,18 @@ class nsINode : public mozilla::dom::EventTarget {
|
||||
void SetFlags(FlagsType aFlagsToSet) {
|
||||
NS_ASSERTION(
|
||||
!(aFlagsToSet &
|
||||
(NODE_IS_ANONYMOUS_ROOT | NODE_IS_NATIVE_ANONYMOUS_ROOT |
|
||||
NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE | NODE_DESCENDANTS_NEED_FRAMES |
|
||||
NODE_NEEDS_FRAME | NODE_HAS_BEEN_IN_UA_WIDGET)) ||
|
||||
(NODE_IS_NATIVE_ANONYMOUS_ROOT | NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE |
|
||||
NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME |
|
||||
NODE_HAS_BEEN_IN_UA_WIDGET)) ||
|
||||
IsContent(),
|
||||
"Flag only permitted on nsIContent nodes");
|
||||
nsWrapperCache::SetFlags(aFlagsToSet);
|
||||
}
|
||||
|
||||
void UnsetFlags(FlagsType aFlagsToUnset) {
|
||||
NS_ASSERTION(
|
||||
!(aFlagsToUnset & (NODE_IS_ANONYMOUS_ROOT | NODE_HAS_BEEN_IN_UA_WIDGET |
|
||||
NODE_IS_NATIVE_ANONYMOUS_ROOT)),
|
||||
"Trying to unset write-only flags");
|
||||
NS_ASSERTION(!(aFlagsToUnset & (NODE_HAS_BEEN_IN_UA_WIDGET |
|
||||
NODE_IS_NATIVE_ANONYMOUS_ROOT)),
|
||||
"Trying to unset write-only flags");
|
||||
nsWrapperCache::UnsetFlags(aFlagsToUnset);
|
||||
}
|
||||
|
||||
@ -1299,25 +1294,41 @@ class nsINode : public mozilla::dom::EventTarget {
|
||||
* Returns true if |this| or any of its ancestors is native anonymous.
|
||||
*/
|
||||
bool IsInNativeAnonymousSubtree() const {
|
||||
#ifdef DEBUG
|
||||
if (HasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE)) {
|
||||
return true;
|
||||
}
|
||||
CheckNotNativeAnonymous();
|
||||
return false;
|
||||
#else
|
||||
return HasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool IsInAnonymousSubtree() const;
|
||||
/**
|
||||
* Returns true if there is NOT a path through child lists
|
||||
* from the top of this node's parent chain back to this node or
|
||||
* if the node is in native anonymous subtree without a parent.
|
||||
*
|
||||
* TODO(emilio):: Remove this function, and use just
|
||||
* IsInNativeAnonymousSubtree, or something?
|
||||
*/
|
||||
bool IsInAnonymousSubtree() const { return IsInNativeAnonymousSubtree(); }
|
||||
|
||||
/**
|
||||
* If |this| or any ancestor is native anonymous, return the root of the
|
||||
* native anonymous subtree. Note that in case of nested native anonymous
|
||||
* content, this returns the innermost root, not the outermost.
|
||||
*/
|
||||
nsIContent* GetClosestNativeAnonymousSubtreeRoot() const;
|
||||
nsIContent* GetClosestNativeAnonymousSubtreeRoot() const {
|
||||
if (!IsInNativeAnonymousSubtree()) {
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ASSERT(IsContent(), "How did non-content end up in NAC?");
|
||||
for (const nsINode* node = this; node; node = node->GetParentNode()) {
|
||||
if (node->IsRootOfNativeAnonymousSubtree()) {
|
||||
return const_cast<nsINode*>(node)->AsContent();
|
||||
}
|
||||
}
|
||||
// FIXME(emilio): This should not happen, usually, but editor removes nodes
|
||||
// in native anonymous subtrees, and we don't clean nodes from the current
|
||||
// event content stack from ContentRemoved, so it can actually happen, see
|
||||
// bug 1510208.
|
||||
NS_WARNING("GetClosestNativeAnonymousSubtreeRoot on disconnected NAC!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* If |this| or any ancestor is native anonymous, return the parent of the
|
||||
@ -1334,6 +1345,18 @@ class nsINode : public mozilla::dom::EventTarget {
|
||||
return reinterpret_cast<const nsINode*>(root)->GetParent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the root of the node tree for this content if it is in a shadow tree.
|
||||
*/
|
||||
mozilla::dom::ShadowRoot* GetContainingShadow() const;
|
||||
/**
|
||||
* Gets the shadow host if this content is in a shadow tree. That is, the host
|
||||
* of |GetContainingShadow|, if its not null.
|
||||
*
|
||||
* @return The shadow host, if this is in shadow tree, or null.
|
||||
*/
|
||||
nsIContent* GetContainingShadowHost() const;
|
||||
|
||||
bool IsInSVGUseShadowTree() const {
|
||||
return !!GetContainingSVGUseShadowHost();
|
||||
}
|
||||
@ -1354,6 +1377,17 @@ class nsINode : public mozilla::dom::EventTarget {
|
||||
NODE_HAS_BEEN_IN_UA_WIDGET);
|
||||
}
|
||||
|
||||
const nsIContent* GetChromeOnlyAccessSubtreeRootParent() const {
|
||||
if (!ChromeOnlyAccess()) {
|
||||
return nullptr;
|
||||
}
|
||||
// We can have NAC in UA widgets, but not the other way around.
|
||||
if (IsInNativeAnonymousSubtree()) {
|
||||
return GetClosestNativeAnonymousSubtreeRootParent();
|
||||
}
|
||||
return GetContainingShadowHost();
|
||||
}
|
||||
|
||||
bool IsInShadowTree() const { return HasFlag(NODE_IS_IN_SHADOW_TREE); }
|
||||
|
||||
/**
|
||||
@ -1362,10 +1396,9 @@ class nsINode : public mozilla::dom::EventTarget {
|
||||
* @return whether this content is anonymous
|
||||
*/
|
||||
bool IsRootOfNativeAnonymousSubtree() const {
|
||||
NS_ASSERTION(!HasFlag(NODE_IS_NATIVE_ANONYMOUS_ROOT) ||
|
||||
(HasFlag(NODE_IS_ANONYMOUS_ROOT) &&
|
||||
HasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE)),
|
||||
"Some flags seem to be missing!");
|
||||
NS_ASSERTION(
|
||||
!HasFlag(NODE_IS_NATIVE_ANONYMOUS_ROOT) || IsInNativeAnonymousSubtree(),
|
||||
"Some flags seem to be missing!");
|
||||
return HasFlag(NODE_IS_NATIVE_ANONYMOUS_ROOT);
|
||||
}
|
||||
|
||||
@ -2108,12 +2141,6 @@ class nsINode : public mozilla::dom::EventTarget {
|
||||
nsIPrincipal* aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError) {}
|
||||
|
||||
#ifdef DEBUG
|
||||
// Note: virtual so that IsInNativeAnonymousSubtree can be called accross
|
||||
// module boundaries.
|
||||
virtual void CheckNotNativeAnonymous() const;
|
||||
#endif
|
||||
|
||||
void EnsurePreInsertionValidity1(mozilla::ErrorResult& aError);
|
||||
void EnsurePreInsertionValidity2(bool aReplace, nsINode& aNewChild,
|
||||
nsINode* aRefChild,
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "nsINode.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTPromiseFlatString.h"
|
||||
#include "nsXBLPrototypeBinding.h"
|
||||
#include "nscore.h"
|
||||
|
||||
#if !defined(DEBUG) && !defined(MOZ_ENABLE_JS_DUMP)
|
||||
@ -218,29 +217,6 @@ bool nsJSUtils::GetScopeChainForElement(
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool nsJSUtils::GetScopeChainForXBL(
|
||||
JSContext* aCx, Element* aElement,
|
||||
const nsXBLPrototypeBinding& aProtoBinding,
|
||||
JS::MutableHandleVector<JSObject*> aScopeChain) {
|
||||
if (!aElement) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!aProtoBinding.SimpleScopeChain()) {
|
||||
return GetScopeChainForElement(aCx, aElement, aScopeChain);
|
||||
}
|
||||
|
||||
if (!AddScopeChainItem(aCx, aElement, aScopeChain)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!AddScopeChainItem(aCx, aElement->OwnerDoc(), aScopeChain)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void nsJSUtils::ResetTimeZone() { JS::ResetTimeZone(); }
|
||||
|
||||
|
@ -100,17 +100,6 @@ class nsJSUtils {
|
||||
JSContext* aCx, mozilla::dom::Element* aElement,
|
||||
JS::MutableHandleVector<JSObject*> aScopeChain);
|
||||
|
||||
// Returns a scope chain suitable for XBL execution.
|
||||
//
|
||||
// This is by default GetScopeChainForElemenet, but will be different if the
|
||||
// <binding> element had the simpleScopeChain attribute.
|
||||
//
|
||||
// This is to prevent footguns like bug 1446342.
|
||||
static bool GetScopeChainForXBL(
|
||||
JSContext* aCx, mozilla::dom::Element* aBoundElement,
|
||||
const nsXBLPrototypeBinding& aProtoBinding,
|
||||
JS::MutableHandleVector<JSObject*> aScopeChain);
|
||||
|
||||
static void ResetTimeZone();
|
||||
|
||||
static bool DumpEnabled();
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "nsString.h"
|
||||
#include "mozilla/dom/NodeInfo.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/dom/XBLChildrenElement.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
@ -70,7 +69,6 @@ bool nsNameSpaceManager::Init() {
|
||||
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xhtml, kNameSpaceID_XHTML);
|
||||
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xlink, kNameSpaceID_XLink);
|
||||
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xslt, kNameSpaceID_XSLT);
|
||||
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xbl, kNameSpaceID_XBL);
|
||||
REGISTER_NAMESPACE(nsGkAtoms::nsuri_mathml, kNameSpaceID_MathML);
|
||||
REGISTER_NAMESPACE(nsGkAtoms::nsuri_rdf, kNameSpaceID_RDF);
|
||||
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xul, kNameSpaceID_XUL);
|
||||
@ -165,8 +163,8 @@ int32_t nsNameSpaceManager::GetNameSpaceID(nsAtom* aURI, bool aInChromeDoc) {
|
||||
// static
|
||||
const char* nsNameSpaceManager::GetNameSpaceDisplayName(uint32_t aNameSpaceID) {
|
||||
static const char* kNSURIs[] = {"([none])", "(xmlns)", "(xml)", "(xhtml)",
|
||||
"(XLink)", "(XSLT)", "(XBL)", "(MathML)",
|
||||
"(RDF)", "(XUL)", "(SVG)"};
|
||||
"(XLink)", "(XSLT)", "(MathML)", "(RDF)",
|
||||
"(XUL)", "(SVG)"};
|
||||
if (aNameSpaceID < ArrayLength(kNSURIs)) {
|
||||
return kNSURIs[aNameSpaceID];
|
||||
}
|
||||
@ -212,12 +210,6 @@ nsresult NS_NewElement(Element** aResult,
|
||||
ni->NodeType(), ni->GetExtraName());
|
||||
return NS_NewXMLElement(aResult, genericXMLNI.forget());
|
||||
}
|
||||
if (ns == kNameSpaceID_XBL && ni->Equals(nsGkAtoms::children)) {
|
||||
RefPtr<mozilla::dom::NodeInfo> nodeInfo(ni);
|
||||
auto* nim = nodeInfo->NodeInfoManager();
|
||||
NS_ADDREF(*aResult = new (nim) XBLChildrenElement(nodeInfo.forget()));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_NewXMLElement(aResult, ni.forget());
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ class nsNameSpaceManager final {
|
||||
const int32_t aNameSpaceID);
|
||||
nsresult AddDisabledNameSpace(already_AddRefed<nsAtom> aURI,
|
||||
const int32_t aNameSpaceID);
|
||||
~nsNameSpaceManager(){};
|
||||
~nsNameSpaceManager() = default;
|
||||
|
||||
nsDataHashtable<nsRefPtrHashKey<nsAtom>, int32_t> mURIToIDTable;
|
||||
nsDataHashtable<nsRefPtrHashKey<nsAtom>, int32_t> mDisabledURIToIDTable;
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsLayoutStatics.h"
|
||||
#include "nsBindingManager.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsCCUncollectableMarker.h"
|
||||
#include "nsNameSpaceManager.h"
|
||||
@ -61,8 +60,6 @@ nsNodeInfoManager::~nsNodeInfoManager() {
|
||||
|
||||
mArena = nullptr;
|
||||
|
||||
mBindingManager = nullptr;
|
||||
|
||||
if (gNodeInfoManagerLeakPRLog)
|
||||
MOZ_LOG(gNodeInfoManagerLeakPRLog, LogLevel::Debug,
|
||||
("NODEINFOMANAGER %p destroyed", this));
|
||||
@ -77,7 +74,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsNodeInfoManager)
|
||||
if (tmp->mNonDocumentNodeInfos) {
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mDocument)
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBindingManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsNodeInfoManager, AddRef)
|
||||
@ -109,10 +105,6 @@ nsresult nsNodeInfoManager::Init(mozilla::dom::Document* aDocument) {
|
||||
|
||||
mPrincipal = NullPrincipal::CreateWithoutOriginAttributes();
|
||||
|
||||
if (aDocument) {
|
||||
mBindingManager = new nsBindingManager(aDocument);
|
||||
}
|
||||
|
||||
mDefaultPrincipal = mPrincipal;
|
||||
|
||||
mDocument = aDocument;
|
||||
@ -125,10 +117,6 @@ nsresult nsNodeInfoManager::Init(mozilla::dom::Document* aDocument) {
|
||||
}
|
||||
|
||||
void nsNodeInfoManager::DropDocumentReference() {
|
||||
if (mBindingManager) {
|
||||
mBindingManager->DropDocumentReference();
|
||||
}
|
||||
|
||||
// This is probably not needed anymore.
|
||||
for (auto iter = mNodeInfoHash.Iter(); !iter.Done(); iter.Next()) {
|
||||
iter.Data()->mDocument = nullptr;
|
||||
@ -414,11 +402,6 @@ bool nsNodeInfoManager::InternalMathMLEnabled() {
|
||||
void nsNodeInfoManager::AddSizeOfIncludingThis(nsWindowSizes& aSizes) const {
|
||||
aSizes.mDOMOtherSize += aSizes.mState.mMallocSizeOf(this);
|
||||
|
||||
if (mBindingManager) {
|
||||
aSizes.mBindingsSize +=
|
||||
mBindingManager->SizeOfIncludingThis(aSizes.mState.mMallocSizeOf);
|
||||
}
|
||||
|
||||
// Measurement of the following members may be added later if DMD finds it
|
||||
// is worthwhile:
|
||||
// - mNodeInfoHash
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsStringFwd.h"
|
||||
|
||||
class nsBindingManager;
|
||||
class nsAtom;
|
||||
class nsIPrincipal;
|
||||
class nsWindowSizes;
|
||||
@ -97,8 +96,6 @@ class nsNodeInfoManager final {
|
||||
|
||||
void RemoveNodeInfo(mozilla::dom::NodeInfo* aNodeInfo);
|
||||
|
||||
nsBindingManager* GetBindingManager() const { return mBindingManager; }
|
||||
|
||||
/**
|
||||
* Returns true if SVG nodes in this document have real SVG semantics.
|
||||
*/
|
||||
@ -171,7 +168,6 @@ class nsNodeInfoManager final {
|
||||
mCommentNodeInfo; // WEAK to avoid circular ownership
|
||||
mozilla::dom::NodeInfo* MOZ_NON_OWNING_REF
|
||||
mDocumentNodeInfo; // WEAK to avoid circular ownership
|
||||
RefPtr<nsBindingManager> mBindingManager;
|
||||
NodeInfoCache mRecentlyUsedNodeInfos;
|
||||
mozilla::Maybe<bool> mSVGEnabled; // Lazily initialized.
|
||||
mozilla::Maybe<bool> mMathMLEnabled; // Lazily initialized.
|
||||
|
@ -41,7 +41,6 @@ class nsIURI;
|
||||
class nsPIDOMWindowInner;
|
||||
class nsPIDOMWindowOuter;
|
||||
class nsPIWindowRoot;
|
||||
class nsXBLPrototypeHandler;
|
||||
|
||||
typedef uint32_t SuspendTypes;
|
||||
|
||||
@ -439,11 +438,6 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
||||
return mMayHaveSelectionChangeEventListener;
|
||||
}
|
||||
|
||||
virtual JSObject* GetCachedXBLPrototypeHandler(
|
||||
nsXBLPrototypeHandler* aKey) = 0;
|
||||
virtual void CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
|
||||
JS::Handle<JSObject*> aHandler) = 0;
|
||||
|
||||
/*
|
||||
* Get and set the currently focused element within the document. If
|
||||
* aNeedsFocus is true, then set mNeedsFocus to true to indicate that a
|
||||
@ -452,10 +446,22 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
||||
* DO NOT CALL EITHER OF THESE METHODS DIRECTLY. USE THE FOCUS MANAGER
|
||||
* INSTEAD.
|
||||
*/
|
||||
inline mozilla::dom::Element* GetFocusedElement() const;
|
||||
mozilla::dom::Element* GetFocusedElement() const {
|
||||
return mFocusedElement.get();
|
||||
}
|
||||
|
||||
virtual void SetFocusedElement(mozilla::dom::Element* aElement,
|
||||
uint32_t aFocusMethod = 0,
|
||||
bool aNeedsFocus = false) = 0;
|
||||
bool aNeedsFocus = false,
|
||||
bool aWillShowOutline = false) = 0;
|
||||
/**
|
||||
* Get whether the focused element did show outlines when it was focused.
|
||||
*
|
||||
* Only for the focus manager. Returns false if there was no focused element.
|
||||
*/
|
||||
bool FocusedElementShowedOutline() const {
|
||||
return mFocusedElementShowedOutlines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the method that was used to focus the current node.
|
||||
@ -647,6 +653,8 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
||||
// notification.
|
||||
bool mHasNotifiedGlobalCreated;
|
||||
|
||||
bool mFocusedElementShowedOutlines = false;
|
||||
|
||||
uint32_t mMarkedCCGeneration;
|
||||
|
||||
// mTopInnerWindow is used for tab-wise check by timeout throttling. It could
|
||||
@ -940,9 +948,17 @@ class nsPIDOMWindowOuter : public mozIDOMWindowProxy {
|
||||
* INSTEAD.
|
||||
*/
|
||||
inline mozilla::dom::Element* GetFocusedElement() const;
|
||||
|
||||
virtual void SetFocusedElement(mozilla::dom::Element* aElement,
|
||||
uint32_t aFocusMethod = 0,
|
||||
bool aNeedsFocus = false) = 0;
|
||||
bool aNeedsFocus = false,
|
||||
bool aWillShowOutline = false) = 0;
|
||||
/**
|
||||
* Get whether the focused element did show outlines when it was focused.
|
||||
*
|
||||
* Only for the focus manager. Returns false if there was no focused element.
|
||||
*/
|
||||
bool FocusedElementShowedOutline() const;
|
||||
|
||||
/**
|
||||
* Retrieves the method that was used to focus the current node.
|
||||
|
@ -2,7 +2,10 @@
|
||||
* 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/. */
|
||||
|
||||
bool nsPIDOMWindowOuter::IsLoading() const {
|
||||
#ifndef dom_base_nsPIDOMWindowInlines_h___
|
||||
#define dom_base_nsPIDOMWindowInlines_h___
|
||||
|
||||
inline bool nsPIDOMWindowOuter::IsLoading() const {
|
||||
auto* win = GetCurrentInnerWindow();
|
||||
|
||||
if (!win) {
|
||||
@ -14,7 +17,7 @@ bool nsPIDOMWindowOuter::IsLoading() const {
|
||||
return win->IsLoading();
|
||||
}
|
||||
|
||||
bool nsPIDOMWindowInner::IsLoading() const {
|
||||
inline bool nsPIDOMWindowInner::IsLoading() const {
|
||||
if (!mOuterWindow) {
|
||||
NS_ERROR("IsLoading() called on orphan inner window!");
|
||||
|
||||
@ -24,7 +27,7 @@ bool nsPIDOMWindowInner::IsLoading() const {
|
||||
return !mIsDocumentLoaded;
|
||||
}
|
||||
|
||||
bool nsPIDOMWindowOuter::IsHandlingResizeEvent() const {
|
||||
inline bool nsPIDOMWindowOuter::IsHandlingResizeEvent() const {
|
||||
auto* win = GetCurrentInnerWindow();
|
||||
|
||||
if (!win) {
|
||||
@ -36,7 +39,7 @@ bool nsPIDOMWindowOuter::IsHandlingResizeEvent() const {
|
||||
return win->IsHandlingResizeEvent();
|
||||
}
|
||||
|
||||
bool nsPIDOMWindowInner::IsHandlingResizeEvent() const {
|
||||
inline bool nsPIDOMWindowInner::IsHandlingResizeEvent() const {
|
||||
if (!mOuterWindow) {
|
||||
NS_ERROR("IsHandlingResizeEvent() called on orphan inner window!");
|
||||
|
||||
@ -46,34 +49,39 @@ bool nsPIDOMWindowInner::IsHandlingResizeEvent() const {
|
||||
return mIsHandlingResizeEvent;
|
||||
}
|
||||
|
||||
bool nsPIDOMWindowInner::IsCurrentInnerWindow() const {
|
||||
inline bool nsPIDOMWindowInner::IsCurrentInnerWindow() const {
|
||||
return mOuterWindow && mOuterWindow->GetCurrentInnerWindow() == this;
|
||||
}
|
||||
|
||||
bool nsPIDOMWindowInner::HasActiveDocument() {
|
||||
inline bool nsPIDOMWindowInner::HasActiveDocument() {
|
||||
return IsCurrentInnerWindow() ||
|
||||
(mOuterWindow && mOuterWindow->GetCurrentInnerWindow() &&
|
||||
mOuterWindow->GetCurrentInnerWindow()->GetDoc() == mDoc);
|
||||
}
|
||||
|
||||
bool nsPIDOMWindowInner::IsTopInnerWindow() const {
|
||||
inline bool nsPIDOMWindowInner::IsTopInnerWindow() const {
|
||||
return mTopInnerWindow == this;
|
||||
}
|
||||
|
||||
nsIDocShell* nsPIDOMWindowOuter::GetDocShell() const { return mDocShell; }
|
||||
inline nsIDocShell* nsPIDOMWindowOuter::GetDocShell() const {
|
||||
return mDocShell;
|
||||
}
|
||||
|
||||
nsIDocShell* nsPIDOMWindowInner::GetDocShell() const {
|
||||
inline nsIDocShell* nsPIDOMWindowInner::GetDocShell() const {
|
||||
return mOuterWindow ? mOuterWindow->GetDocShell() : nullptr;
|
||||
}
|
||||
|
||||
mozilla::dom::BrowsingContext* nsPIDOMWindowOuter::GetBrowsingContext() const {
|
||||
inline mozilla::dom::BrowsingContext* nsPIDOMWindowOuter::GetBrowsingContext()
|
||||
const {
|
||||
return mBrowsingContext;
|
||||
}
|
||||
|
||||
mozilla::dom::Element* nsPIDOMWindowOuter::GetFocusedElement() const {
|
||||
inline mozilla::dom::Element* nsPIDOMWindowOuter::GetFocusedElement() const {
|
||||
return mInnerWindow ? mInnerWindow->GetFocusedElement() : nullptr;
|
||||
}
|
||||
|
||||
mozilla::dom::Element* nsPIDOMWindowInner::GetFocusedElement() const {
|
||||
return mFocusedElement;
|
||||
inline bool nsPIDOMWindowOuter::FocusedElementShowedOutline() const {
|
||||
return mInnerWindow && mInnerWindow->FocusedElementShowedOutline();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -856,10 +856,10 @@ void nsRange::DoSetRange(const RangeBoundaryBase<SPT, SRT>& aStartBoundary,
|
||||
!aRootNode ||
|
||||
(aStartBoundary.Container()->IsContent() &&
|
||||
aEndBoundary.Container()->IsContent() &&
|
||||
aRootNode == static_cast<nsIContent*>(aStartBoundary.Container())
|
||||
->GetBindingParent() &&
|
||||
aRootNode == static_cast<nsIContent*>(aEndBoundary.Container())
|
||||
->GetBindingParent()) ||
|
||||
aRootNode ==
|
||||
RangeUtils::ComputeRootNode(aStartBoundary.Container()) &&
|
||||
aRootNode ==
|
||||
RangeUtils::ComputeRootNode(aEndBoundary.Container())) ||
|
||||
(!aRootNode->GetParentNode() &&
|
||||
(aRootNode->IsDocument() || aRootNode->IsAttr() ||
|
||||
aRootNode->IsDocumentFragment() ||
|
||||
@ -1286,7 +1286,7 @@ class MOZ_STACK_CLASS RangeSubtreeIterator {
|
||||
|
||||
public:
|
||||
RangeSubtreeIterator() : mIterState(eDone) {}
|
||||
~RangeSubtreeIterator() {}
|
||||
~RangeSubtreeIterator() = default;
|
||||
|
||||
nsresult Init(nsRange* aRange);
|
||||
already_AddRefed<nsINode> GetCurrentNode();
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "nsScreen.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
@ -84,6 +83,22 @@ nsresult nsScreen::GetRect(nsRect& aRect) {
|
||||
return GetWindowInnerRect(aRect);
|
||||
}
|
||||
|
||||
// Here we manipulate the value of aRect to represent the screen size,
|
||||
// if in RDM.
|
||||
nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner();
|
||||
if (owner) {
|
||||
mozilla::dom::Document* doc = owner->GetExtantDoc();
|
||||
if (doc) {
|
||||
Maybe<mozilla::CSSIntSize> deviceSize =
|
||||
nsGlobalWindowOuter::GetRDMDeviceSize(*doc);
|
||||
if (deviceSize.isSome()) {
|
||||
const mozilla::CSSIntSize& size = deviceSize.value();
|
||||
aRect.SetRect(0, 0, size.width, size.height);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsDeviceContext* context = GetDeviceContext();
|
||||
|
||||
if (!context) {
|
||||
@ -111,10 +126,20 @@ nsresult nsScreen::GetAvailRect(nsRect& aRect) {
|
||||
return GetWindowInnerRect(aRect);
|
||||
}
|
||||
|
||||
// Here we manipulate the value of aRect to represent the screen avail size,
|
||||
// Here we manipulate the value of aRect to represent the screen size,
|
||||
// if in RDM.
|
||||
if (IsInRDMPane()) {
|
||||
return GetRDMScreenSize(aRect);
|
||||
nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner();
|
||||
if (owner) {
|
||||
mozilla::dom::Document* doc = owner->GetExtantDoc();
|
||||
if (doc) {
|
||||
Maybe<mozilla::CSSIntSize> deviceSize =
|
||||
nsGlobalWindowOuter::GetRDMDeviceSize(*doc);
|
||||
if (deviceSize.isSome()) {
|
||||
const mozilla::CSSIntSize& size = deviceSize.value();
|
||||
aRect.SetRect(0, 0, size.width, size.height);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsDeviceContext* context = GetDeviceContext();
|
||||
@ -143,29 +168,6 @@ nsresult nsScreen::GetAvailRect(nsRect& aRect) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsScreen::GetRDMScreenSize(nsRect& aRect) {
|
||||
GetWindowInnerRect(aRect);
|
||||
|
||||
// GetOwner(), GetDocShell(), and GetPresContext() can potentially return
|
||||
// nullptr, so to be safe let's make sure we check these before proceeding.
|
||||
nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner();
|
||||
if (owner) {
|
||||
nsIDocShell* docShell = owner->GetDocShell();
|
||||
if (docShell) {
|
||||
RefPtr<nsPresContext> presContext = docShell->GetPresContext();
|
||||
if (presContext) {
|
||||
float zoom = presContext->GetDeviceFullZoom();
|
||||
int32_t width = std::round(aRect.Width() * zoom);
|
||||
int32_t height = std::round(aRect.Height() * zoom);
|
||||
aRect.SetHeight(height);
|
||||
aRect.SetWidth(width);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mozilla::dom::ScreenOrientation* nsScreen::Orientation() const {
|
||||
return mScreenOrientation;
|
||||
}
|
||||
@ -279,16 +281,6 @@ void nsScreen::MozUnlockOrientation() {
|
||||
mScreenOrientation->UnlockDeviceOrientation();
|
||||
}
|
||||
|
||||
bool nsScreen::IsDeviceSizePageSize() {
|
||||
if (nsPIDOMWindowInner* owner = GetOwner()) {
|
||||
nsIDocShell* docShell = owner->GetDocShell();
|
||||
if (docShell) {
|
||||
return docShell->GetDeviceSizeIsPageSize();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
JSObject* nsScreen::WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) {
|
||||
@ -315,15 +307,3 @@ bool nsScreen::ShouldResistFingerprinting() const {
|
||||
}
|
||||
return resist;
|
||||
}
|
||||
|
||||
bool nsScreen::IsInRDMPane() const {
|
||||
bool isInRDM = false;
|
||||
nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner();
|
||||
|
||||
if (owner) {
|
||||
Document* doc = owner->GetExtantDoc();
|
||||
isInRDM = doc && doc->InRDMPane();
|
||||
}
|
||||
|
||||
return isInRDM;
|
||||
}
|
||||
|
@ -45,38 +45,12 @@ class nsScreen : public mozilla::DOMEventTargetHelper {
|
||||
|
||||
int32_t GetWidth(ErrorResult& aRv) {
|
||||
nsRect rect;
|
||||
if (IsDeviceSizePageSize()) {
|
||||
if (IsInRDMPane()) {
|
||||
GetRDMScreenSize(rect);
|
||||
return rect.Width();
|
||||
}
|
||||
|
||||
if (nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner()) {
|
||||
int32_t innerWidth = 0;
|
||||
aRv = owner->GetInnerWidth(&innerWidth);
|
||||
return innerWidth;
|
||||
}
|
||||
}
|
||||
|
||||
aRv = GetRect(rect);
|
||||
return rect.Width();
|
||||
}
|
||||
|
||||
int32_t GetHeight(ErrorResult& aRv) {
|
||||
nsRect rect;
|
||||
if (IsDeviceSizePageSize()) {
|
||||
if (IsInRDMPane()) {
|
||||
GetRDMScreenSize(rect);
|
||||
return rect.Height();
|
||||
}
|
||||
|
||||
if (nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner()) {
|
||||
int32_t innerHeight = 0;
|
||||
aRv = owner->GetInnerHeight(&innerHeight);
|
||||
return innerHeight;
|
||||
}
|
||||
}
|
||||
|
||||
aRv = GetRect(rect);
|
||||
return rect.Height();
|
||||
}
|
||||
@ -144,17 +118,14 @@ class nsScreen : public mozilla::DOMEventTargetHelper {
|
||||
nsresult GetRect(nsRect& aRect);
|
||||
nsresult GetAvailRect(nsRect& aRect);
|
||||
nsresult GetWindowInnerRect(nsRect& aRect);
|
||||
nsresult GetRDMScreenSize(nsRect& aRect);
|
||||
|
||||
private:
|
||||
explicit nsScreen(nsPIDOMWindowInner* aWindow);
|
||||
virtual ~nsScreen();
|
||||
|
||||
bool IsDeviceSizePageSize();
|
||||
|
||||
bool ShouldResistFingerprinting() const;
|
||||
|
||||
bool IsInRDMPane() const;
|
||||
mozilla::dom::Document* TopContentDocumentInRDMPane() const;
|
||||
|
||||
RefPtr<mozilla::dom::ScreenOrientation> mScreenOrientation;
|
||||
};
|
||||
|
@ -1062,92 +1062,16 @@ bool nsTreeSanitizer::MustPrune(int32_t aNamespace, nsAtom* aLocal,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool nsTreeSanitizer::SanitizeStyleDeclaration(DeclarationBlock* aDeclaration) {
|
||||
return aDeclaration->RemovePropertyByID(eCSSProperty__moz_binding);
|
||||
}
|
||||
|
||||
void nsTreeSanitizer::SanitizeStyleSheet(const nsAString& aOriginal,
|
||||
nsAString& aSanitized,
|
||||
Document* aDocument,
|
||||
nsIURI* aBaseURI) {
|
||||
aSanitized.Truncate();
|
||||
NS_ConvertUTF16toUTF8 style(aOriginal);
|
||||
RefPtr<nsIReferrerInfo> referrer =
|
||||
ReferrerInfo::CreateForInternalCSSResources(aDocument);
|
||||
if (StaticPrefs::layout_css_moz_binding_content_enabled() ||
|
||||
aDocument->IsDocumentURISchemeChrome()) {
|
||||
// aSanitized will hold the permitted CSS text.
|
||||
// -moz-binding is blacklisted.
|
||||
bool didSanitize = false;
|
||||
// Create a sheet to hold the parsed CSS
|
||||
RefPtr<StyleSheet> sheet = new StyleSheet(mozilla::css::eAuthorSheetFeatures,
|
||||
CORS_NONE, SRIMetadata());
|
||||
sheet->SetURIs(aDocument->GetDocumentURI(), nullptr, aBaseURI);
|
||||
sheet->SetPrincipal(aDocument->NodePrincipal());
|
||||
sheet->ParseSheetSync(aDocument->CSSLoader(),
|
||||
NS_ConvertUTF16toUTF8(aOriginal),
|
||||
/* aLoadData = */ nullptr,
|
||||
/* aLineNumber = */ 0);
|
||||
// Mark the sheet as complete.
|
||||
MOZ_ASSERT(!sheet->HasForcedUniqueInner(),
|
||||
"should not get a forced unique inner during parsing");
|
||||
|
||||
NS_ConvertUTF16toUTF8 style(aOriginal);
|
||||
sheet->SetComplete();
|
||||
// Loop through all the rules found in the CSS text
|
||||
ErrorResult err;
|
||||
RefPtr<dom::CSSRuleList> rules =
|
||||
sheet->GetCssRules(*nsContentUtils::GetSystemPrincipal(), err);
|
||||
err.SuppressException();
|
||||
if (!rules) {
|
||||
return;
|
||||
}
|
||||
uint32_t ruleCount = rules->Length();
|
||||
for (uint32_t i = 0; i < ruleCount; ++i) {
|
||||
mozilla::css::Rule* rule = rules->Item(i);
|
||||
if (!rule) continue;
|
||||
switch (rule->Type()) {
|
||||
default:
|
||||
didSanitize = true;
|
||||
// Ignore these rule types.
|
||||
break;
|
||||
case StyleCssRuleType::Namespace:
|
||||
case StyleCssRuleType::FontFace: {
|
||||
// Append @namespace and @font-face rules verbatim.
|
||||
nsAutoCString cssText;
|
||||
rule->GetCssText(cssText);
|
||||
aSanitized.Append(NS_ConvertUTF8toUTF16(cssText).get());
|
||||
break;
|
||||
}
|
||||
case StyleCssRuleType::Style: {
|
||||
// For style rules, we will just look for and remove the
|
||||
// -moz-binding properties.
|
||||
auto styleRule = static_cast<BindingStyleRule*>(rule);
|
||||
DeclarationBlock* styleDecl = styleRule->GetDeclarationBlock();
|
||||
MOZ_ASSERT(styleDecl);
|
||||
if (SanitizeStyleDeclaration(styleDecl)) {
|
||||
didSanitize = true;
|
||||
}
|
||||
nsAutoCString decl;
|
||||
styleRule->GetCssText(decl);
|
||||
aSanitized.Append(NS_ConvertUTF8toUTF16(decl).get());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (didSanitize) {
|
||||
if (mLogRemovals) {
|
||||
LogMessage("Removed some rules and/or properties from stylesheet.",
|
||||
aDocument);
|
||||
}
|
||||
} else {
|
||||
aSanitized.Assign(aOriginal);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
NS_ConvertUTF16toUTF8 style(aOriginal);
|
||||
RefPtr<URLExtraData> extraData =
|
||||
new URLExtraData(aBaseURI, referrer, aDocument->NodePrincipal());
|
||||
auto sanitizationKind = StyleSanitizationKind::Standard;
|
||||
auto extraData =
|
||||
MakeRefPtr<URLExtraData>(aBaseURI, referrer, aDocument->NodePrincipal());
|
||||
RefPtr<RawServoStyleSheetContents> contents =
|
||||
Servo_StyleSheet_FromUTF8Bytes(
|
||||
/* loader = */ nullptr,
|
||||
@ -1156,9 +1080,8 @@ void nsTreeSanitizer::SanitizeStyleSheet(const nsAString& aOriginal,
|
||||
css::SheetParsingMode::eAuthorSheetFeatures, extraData.get(),
|
||||
/* line_number_offset = */ 0, aDocument->GetCompatibilityMode(),
|
||||
/* reusable_sheets = */ nullptr,
|
||||
StyleAllowImportRules::Yes,
|
||||
sanitizationKind, &aSanitized)
|
||||
.Consume();
|
||||
StyleAllowImportRules::Yes, StyleSanitizationKind::Standard,
|
||||
&aSanitized).Consume();
|
||||
|
||||
if (mLogRemovals && aSanitized.Length() != aOriginal.Length()) {
|
||||
LogMessage("Removed some rules and/or properties from stylesheet.",
|
||||
@ -1194,26 +1117,6 @@ void nsTreeSanitizer::SanitizeAttributes(mozilla::dom::Element* aElement,
|
||||
|
||||
if (kNameSpaceID_None == attrNs) {
|
||||
if (aAllowed.mStyle && nsGkAtoms::style == attrLocal) {
|
||||
nsAutoString value;
|
||||
aElement->GetAttr(attrNs, attrLocal, value);
|
||||
Document* document = aElement->OwnerDoc();
|
||||
RefPtr<URLExtraData> urlExtra(aElement->GetURLDataForStyleAttr());
|
||||
RefPtr<DeclarationBlock> decl = DeclarationBlock::FromCssText(
|
||||
value, urlExtra, document->GetCompatibilityMode(),
|
||||
document->CSSLoader(), StyleCssRuleType::Style);
|
||||
if (decl) {
|
||||
if (SanitizeStyleDeclaration(decl)) {
|
||||
nsAutoCString cleanValue;
|
||||
decl->ToString(cleanValue);
|
||||
aElement->SetAttr(kNameSpaceID_None, nsGkAtoms::style,
|
||||
NS_ConvertUTF8toUTF16(cleanValue), false);
|
||||
if (mLogRemovals) {
|
||||
LogMessage(
|
||||
"Removed -moz-binding styling from element style attribute.",
|
||||
aElement->OwnerDoc(), aElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (aAllowed.mDangerousSrc && nsGkAtoms::src == attrLocal) {
|
||||
|
@ -76,7 +76,7 @@
|
||||
* its own sub-tree, even if multiple tabs are showing the same URI.
|
||||
*
|
||||
* - <top-uri> is the URI of the top window. Excepting special windows (such
|
||||
* as browser.xul or hiddenWindow.html) it's what the address bar shows for
|
||||
* as browser.xhtml or hiddenWindow.html) it's what the address bar shows for
|
||||
* the tab.
|
||||
*
|
||||
*/
|
||||
|
@ -57,3 +57,4 @@ skip-if = (os == "win" && processor == "aarch64") # aarch64 due to bug 1536566
|
||||
[browser_multiple_popups.js]
|
||||
skip-if = os == 'win' && !debug # Bug 1505235
|
||||
support-files = browser_multiple_popups.html
|
||||
[browser_outline_refocus.js]
|
||||
|
65
dom/base/test/browser_outline_refocus.js
Normal file
65
dom/base/test/browser_outline_refocus.js
Normal file
@ -0,0 +1,65 @@
|
||||
const URL = `data:text/html,<a target="_blank" href="http://example.com">Click me</a>`;
|
||||
|
||||
async function test_browser_outline_refocus(
|
||||
aMessage,
|
||||
aShouldFocusBeVisible,
|
||||
aOpenTabCallback
|
||||
) {
|
||||
await BrowserTestUtils.withNewTab(URL, async function(browser) {
|
||||
let tab = gBrowser.getTabForBrowser(browser);
|
||||
let newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser);
|
||||
|
||||
await aOpenTabCallback(browser);
|
||||
|
||||
info("waiting for new tab");
|
||||
let newTab = await newTabPromise;
|
||||
|
||||
is(gBrowser.selectedTab, newTab, "Should've switched to the new tab");
|
||||
|
||||
info("switching back");
|
||||
await BrowserTestUtils.switchTab(gBrowser, tab);
|
||||
|
||||
info("checking focus");
|
||||
let [wasFocused, wasFocusVisible] = await SpecialPowers.spawn(
|
||||
browser,
|
||||
[],
|
||||
() => {
|
||||
let link = content.document.querySelector("a");
|
||||
return [link.matches(":focus"), link.matches(":focus-visible")];
|
||||
}
|
||||
);
|
||||
|
||||
ok(wasFocused, "Link should be refocused");
|
||||
is(wasFocusVisible, aShouldFocusBeVisible, aMessage);
|
||||
|
||||
info("closing tab");
|
||||
await BrowserTestUtils.removeTab(newTab);
|
||||
});
|
||||
}
|
||||
|
||||
add_task(async function browser_outline_refocus_mouse() {
|
||||
await test_browser_outline_refocus(
|
||||
"Link shouldn't show outlines since it was originally focused by mouse",
|
||||
false,
|
||||
function(aBrowser) {
|
||||
info("clicking on link");
|
||||
return BrowserTestUtils.synthesizeMouseAtCenter("a", {}, aBrowser);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function browser_outline_refocus_key() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["accessibility.tabfocus", 7]],
|
||||
});
|
||||
|
||||
await test_browser_outline_refocus(
|
||||
"Link should show outlines since it was originally focused by keyboard",
|
||||
true,
|
||||
function(aBrowser) {
|
||||
info("Navigating via keyboard");
|
||||
EventUtils.sendKey("tab");
|
||||
EventUtils.sendKey("return");
|
||||
}
|
||||
);
|
||||
});
|
@ -15,7 +15,7 @@ support-files =
|
||||
referrer_testserver.sjs
|
||||
!/image/test/mochitest/shaver.png
|
||||
|
||||
[test_anonymousContent_xul_window.xul]
|
||||
[test_anonymousContent_xul_window.xhtml]
|
||||
[test_blockParsing.html]
|
||||
[test_blocking_image.html]
|
||||
[test_bug419527.xhtml]
|
||||
@ -23,12 +23,11 @@ support-files =
|
||||
[test_bug1008126.html]
|
||||
[test_bug1016960.html]
|
||||
[test_anchor_target_blank_referrer.html]
|
||||
[test_copypaste.xul]
|
||||
[test_domrequesthelper.xul]
|
||||
[test_fragment_sanitization.xul]
|
||||
[test_domrequesthelper.xhtml]
|
||||
[test_fragment_sanitization.xhtml]
|
||||
[test_messagemanager_send_principal.html]
|
||||
[test_navigator_resolve_identity_xrays.xul]
|
||||
support-files = file_navigator_resolve_identity_xrays.xul
|
||||
[test_navigator_resolve_identity_xrays.xhtml]
|
||||
support-files = file_navigator_resolve_identity_xrays.xhtml
|
||||
[test_sandboxed_blob_uri.html]
|
||||
[test_sendQueryContentAndSelectionSetEvent.html]
|
||||
[test_urgent_start.html]
|
||||
|
@ -2,87 +2,83 @@
|
||||
skip-if = os == 'android'
|
||||
support-files =
|
||||
bug418986-1.js
|
||||
cpows_child.js
|
||||
cpows_parent.xul
|
||||
file_bug549682.xul
|
||||
file_bug616841.xul
|
||||
file_bug816340.xul
|
||||
file_bug990812-1.xul
|
||||
file_bug990812-2.xul
|
||||
file_bug990812-3.xul
|
||||
file_bug990812-4.xul
|
||||
file_bug990812-5.xul
|
||||
file_bug1139964.xul
|
||||
file_bug1209621.xul
|
||||
clonedoc/**
|
||||
file_bug549682.xhtml
|
||||
file_bug616841.xhtml
|
||||
file_bug816340.xhtml
|
||||
file_bug990812-1.xhtml
|
||||
file_bug990812-2.xhtml
|
||||
file_bug990812-3.xhtml
|
||||
file_bug990812-4.xhtml
|
||||
file_bug990812-5.xhtml
|
||||
file_bug1139964.xhtml
|
||||
file_bug1209621.xhtml
|
||||
fileconstructor_file.png
|
||||
frame_bug814638.xul
|
||||
frame_bug814638.xhtml
|
||||
frame_custom_element_content.html
|
||||
custom_element_ep.js
|
||||
host_bug814638.xul
|
||||
window_nsITextInputProcessor.xul
|
||||
title_window.xul
|
||||
window_swapFrameLoaders.xul
|
||||
host_bug814638.xhtml
|
||||
window_nsITextInputProcessor.xhtml
|
||||
title_window.xhtml
|
||||
window_swapFrameLoaders.xhtml
|
||||
|
||||
[test_bug120684.xul]
|
||||
[test_bug206691.xul]
|
||||
[test_bug289714.xul]
|
||||
[test_bug339494.xul]
|
||||
[test_bug357450.xul]
|
||||
[test_bug120684.xhtml]
|
||||
[test_bug206691.xhtml]
|
||||
[test_bug289714.xhtml]
|
||||
[test_bug339494.xhtml]
|
||||
[test_bug357450.xhtml]
|
||||
support-files = ../file_bug357450.js
|
||||
[test_bug380418.html]
|
||||
[test_bug380418.html^headers^]
|
||||
[test_bug383430.html]
|
||||
[test_bug418986-1.xul]
|
||||
[test_bug421622.xul]
|
||||
[test_bug429785.xul]
|
||||
[test_bug430050.xul]
|
||||
[test_bug467123.xul]
|
||||
[test_bug473284.xul]
|
||||
[test_bug549682.xul]
|
||||
[test_bug418986-1.xhtml]
|
||||
[test_bug421622.xhtml]
|
||||
[test_bug429785.xhtml]
|
||||
[test_bug430050.xhtml]
|
||||
[test_bug467123.xhtml]
|
||||
[test_bug473284.xhtml]
|
||||
[test_bug549682.xhtml]
|
||||
skip-if = verify
|
||||
[test_bug571390.xul]
|
||||
[test_bug1098074_throw_from_ReceiveMessage.xul]
|
||||
[test_bug616841.xul]
|
||||
[test_bug635835.xul]
|
||||
[test_bug571390.xhtml]
|
||||
[test_bug1098074_throw_from_ReceiveMessage.xhtml]
|
||||
[test_bug616841.xhtml]
|
||||
[test_bug635835.xhtml]
|
||||
[test_bug682305.html]
|
||||
[test_bug683852.xul]
|
||||
[test_bug752226-3.xul]
|
||||
[test_bug752226-4.xul]
|
||||
[test_bug683852.xhtml]
|
||||
[test_bug752226-3.xhtml]
|
||||
[test_bug752226-4.xhtml]
|
||||
[test_bug765993.html]
|
||||
[test_bug780199.xul]
|
||||
[test_bug780529.xul]
|
||||
[test_bug800386.xul]
|
||||
[test_bug814638.xul]
|
||||
[test_bug816340.xul]
|
||||
[test_bug884693.xul]
|
||||
[test_bug780199.xhtml]
|
||||
[test_bug780529.xhtml]
|
||||
[test_bug800386.xhtml]
|
||||
[test_bug814638.xhtml]
|
||||
[test_bug816340.xhtml]
|
||||
[test_bug884693.xhtml]
|
||||
[test_bug914381.html]
|
||||
[test_bug990812.xul]
|
||||
[test_bug1063837.xul]
|
||||
[test_bug1139964.xul]
|
||||
[test_bug1209621.xul]
|
||||
[test_bug990812.xhtml]
|
||||
[test_bug1063837.xhtml]
|
||||
[test_bug1139964.xhtml]
|
||||
[test_bug1209621.xhtml]
|
||||
[test_bug1346936.html]
|
||||
[test_chromeOuterWindowID.xul]
|
||||
[test_chromeOuterWindowID.xhtml]
|
||||
support-files =
|
||||
window_chromeOuterWindowID.xul
|
||||
[test_cpows.xul]
|
||||
support-files =
|
||||
cpows_child.html
|
||||
window_chromeOuterWindowID.xhtml
|
||||
[test_getElementsWithGrid.html]
|
||||
[test_custom_element_content.xul]
|
||||
[test_custom_element_ep.xul]
|
||||
[test_document-element-inserted.xul]
|
||||
[test_custom_element_content.xhtml]
|
||||
[test_custom_element_ep.xhtml]
|
||||
[test_document-element-inserted.xhtml]
|
||||
support-files =
|
||||
file_document-element-inserted.xul
|
||||
file_document-element-inserted-inner.xul
|
||||
[test_domparsing.xul]
|
||||
[test_fileconstructor.xul]
|
||||
file_document-element-inserted.xhtml
|
||||
file_document-element-inserted-inner.xhtml
|
||||
[test_domparsing.xhtml]
|
||||
[test_fileconstructor.xhtml]
|
||||
[test_input_value_set_preserve_undo.xhtml]
|
||||
[test_nsITextInputProcessor.xul]
|
||||
[test_permission_isHandlingUserInput.xul]
|
||||
[test_nsITextInputProcessor.xhtml]
|
||||
[test_permission_isHandlingUserInput.xhtml]
|
||||
support-files = ../dummy.html
|
||||
[test_range_getClientRectsAndTexts.html]
|
||||
[test_title.xul]
|
||||
support-files = file_title.xul
|
||||
[test_windowroot.xul]
|
||||
[test_swapFrameLoaders.xul]
|
||||
[test_title.xhtml]
|
||||
support-files = file_title.xhtml
|
||||
[test_windowroot.xhtml]
|
||||
[test_swapFrameLoaders.xhtml]
|
||||
[test_bug1339722.html]
|
||||
|
1
dom/base/test/chrome/clonedoc/chrome.manifest
Normal file
1
dom/base/test/chrome/clonedoc/chrome.manifest
Normal file
@ -0,0 +1 @@
|
||||
content clonedoc content/
|
4
dom/base/test/chrome/clonedoc/content/doc.xml
Normal file
4
dom/base/test/chrome/clonedoc/content/doc.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<something>
|
||||
<somethinglese/>
|
||||
</something>
|
@ -173,7 +173,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=549682
|
||||
messageManager.removeDelayedFrameScript(toBeRemovedScript);
|
||||
|
||||
var oldValue = globalListenerCallCount;
|
||||
var b = document.createElement("browser");
|
||||
var b = document.createXULElement("browser");
|
||||
b.setAttribute("type", "content");
|
||||
document.documentElement.appendChild(b);
|
||||
is(globalListenerCallCount, oldValue + 1,
|
@ -45,7 +45,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=990812
|
||||
}
|
||||
});
|
||||
|
||||
var browser = document.createElement("browser");
|
||||
var browser = document.createXULElement("browser");
|
||||
browser.setAttribute("messagemanagergroup", "test");
|
||||
browser.setAttribute("src", "about:mozilla");
|
||||
browser.setAttribute("type", "content");
|
@ -39,7 +39,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=990812
|
||||
}
|
||||
});
|
||||
|
||||
var browser = document.createElement("browser");
|
||||
var browser = document.createXULElement("browser");
|
||||
browser.setAttribute("messagemanagergroup", "test");
|
||||
browser.setAttribute("src", "about:mozilla");
|
||||
browser.setAttribute("type", "content");
|
@ -1,3 +1,3 @@
|
||||
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'>
|
||||
<iframe src='file_document-element-inserted-inner.xul'></iframe>
|
||||
<iframe src='file_document-element-inserted-inner.xhtml'></iframe>
|
||||
</window>
|
@ -5,5 +5,5 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=814638
|
||||
-->
|
||||
<window title="Mozilla Bug 814638"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<iframe flex="1" src="frame_bug814638.xul"/>
|
||||
<iframe flex="1" src="frame_bug814638.xhtml"/>
|
||||
</window>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user