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",
|
from: "1",
|
||||||
to: "0"
|
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": {
|
"-moz-text-size-adjust": {
|
||||||
// https://drafts.csswg.org/css-size-adjust/#propdef-text-size-adjust
|
// https://drafts.csswg.org/css-size-adjust/#propdef-text-size-adjust
|
||||||
from: "none",
|
from: "none",
|
||||||
|
@ -41,9 +41,6 @@ const testcases = [
|
|||||||
property: "-moz-osx-font-smoothing",
|
property: "-moz-osx-font-smoothing",
|
||||||
pref: "layout.css.osx-font-smoothing.enabled"
|
pref: "layout.css.osx-font-smoothing.enabled"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
property: "-moz-stack-sizing"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
property: "-moz-text-size-adjust"
|
property: "-moz-text-size-adjust"
|
||||||
},
|
},
|
||||||
|
@ -28,8 +28,6 @@ mozilla::LazyLogModule gAudioChannelLog("AudioChannel");
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool sAudioChannelCompeting = false;
|
|
||||||
bool sAudioChannelCompetingAllAgents = false;
|
|
||||||
bool sXPCOMShuttingDown = false;
|
bool sXPCOMShuttingDown = false;
|
||||||
|
|
||||||
class NotifyChannelActiveRunnable final : public Runnable {
|
class NotifyChannelActiveRunnable final : public Runnable {
|
||||||
@ -117,20 +115,6 @@ class AudioPlaybackRunnable final : public Runnable {
|
|||||||
AudioChannelService::AudibleChangedReasons mReason;
|
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
|
} // anonymous namespace
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
@ -250,12 +234,6 @@ void AudioChannelService::Shutdown() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
|
||||||
bool AudioChannelService::IsEnableAudioCompeting() {
|
|
||||||
CreateServiceIfNeeded();
|
|
||||||
return sAudioChannelCompeting;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_INTERFACE_MAP_BEGIN(AudioChannelService)
|
NS_INTERFACE_MAP_BEGIN(AudioChannelService)
|
||||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||||
@ -270,11 +248,6 @@ AudioChannelService::AudioChannelService() {
|
|||||||
obs->AddObserver(this, "xpcom-shutdown", false);
|
obs->AddObserver(this, "xpcom-shutdown", false);
|
||||||
obs->AddObserver(this, "outer-window-destroyed", false);
|
obs->AddObserver(this, "outer-window-destroyed", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Preferences::AddBoolVarCache(&sAudioChannelCompeting,
|
|
||||||
"dom.audiochannel.audioCompeting");
|
|
||||||
Preferences::AddBoolVarCache(&sAudioChannelCompetingAllAgents,
|
|
||||||
"dom.audiochannel.audioCompeting.allAgents");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioChannelService::~AudioChannelService() {}
|
AudioChannelService::~AudioChannelService() {}
|
||||||
@ -334,9 +307,6 @@ AudioPlaybackConfig AudioChannelService::GetMediaConfig(
|
|||||||
if (winData) {
|
if (winData) {
|
||||||
config.mVolume *= winData->mConfig.mVolume;
|
config.mVolume *= winData->mConfig.mVolume;
|
||||||
config.mMuted = config.mMuted || winData->mConfig.mMuted;
|
config.mMuted = config.mMuted || winData->mConfig.mMuted;
|
||||||
config.mSuspend = winData->mOwningAudioFocus
|
|
||||||
? config.mSuspend
|
|
||||||
: nsISuspendedTypes::SUSPENDED_STOP_DISPOSABLE;
|
|
||||||
config.mCapturedAudio = winData->mIsAudioCaptured;
|
config.mCapturedAudio = winData->mIsAudioCaptured;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -532,20 +502,6 @@ bool AudioChannelService::IsWindowActive(nsPIDOMWindowOuter* aWindow) {
|
|||||||
return !winData->mAudibleAgents.IsEmpty();
|
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(
|
void AudioChannelService::NotifyMediaResumedFromBlock(
|
||||||
nsPIDOMWindowOuter* aWindow) {
|
nsPIDOMWindowOuter* aWindow) {
|
||||||
MOZ_ASSERT(aWindow);
|
MOZ_ASSERT(aWindow);
|
||||||
@ -563,168 +519,13 @@ void AudioChannelService::NotifyMediaResumedFromBlock(
|
|||||||
winData->NotifyMediaBlockStop(aWindow);
|
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(
|
void AudioChannelService::AudioChannelWindow::AppendAgent(
|
||||||
AudioChannelAgent* aAgent, AudibleState aAudible) {
|
AudioChannelAgent* aAgent, AudibleState aAudible) {
|
||||||
MOZ_ASSERT(aAgent);
|
MOZ_ASSERT(aAgent);
|
||||||
|
|
||||||
RequestAudioFocus(aAgent);
|
|
||||||
AppendAgentAndIncreaseAgentsNum(aAgent);
|
AppendAgentAndIncreaseAgentsNum(aAgent);
|
||||||
AudioAudibleChanged(aAgent, aAudible,
|
AudioAudibleChanged(aAgent, aAudible,
|
||||||
AudibleChangedReasons::eDataAudibleChanged);
|
AudibleChangedReasons::eDataAudibleChanged);
|
||||||
if (IsEnableAudioCompetingForAllAgents() &&
|
|
||||||
aAudible != AudibleState::eAudible) {
|
|
||||||
NotifyAudioCompetingChanged(aAgent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioChannelService::AudioChannelWindow::RemoveAgent(
|
void AudioChannelService::AudioChannelWindow::RemoveAgent(
|
||||||
@ -794,7 +595,6 @@ void AudioChannelService::AudioChannelWindow::AudioAudibleChanged(
|
|||||||
|
|
||||||
if (aAudible == AudibleState::eAudible) {
|
if (aAudible == AudibleState::eAudible) {
|
||||||
AppendAudibleAgentIfNotContained(aAgent, aReason);
|
AppendAudibleAgentIfNotContained(aAgent, aReason);
|
||||||
NotifyAudioCompetingChanged(aAgent);
|
|
||||||
} else {
|
} else {
|
||||||
RemoveAudibleAgentIfContained(aAgent, aReason);
|
RemoveAudibleAgentIfContained(aAgent, aReason);
|
||||||
}
|
}
|
||||||
@ -839,12 +639,6 @@ bool AudioChannelService::AudioChannelWindow::IsLastAudibleAgent() const {
|
|||||||
return mAudibleAgents.IsEmpty();
|
return mAudibleAgents.IsEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioChannelService::AudioChannelWindow::IsInactiveWindow() const {
|
|
||||||
return IsEnableAudioCompetingForAllAgents()
|
|
||||||
? mAudibleAgents.IsEmpty() && mAgents.IsEmpty()
|
|
||||||
: mAudibleAgents.IsEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioChannelService::AudioChannelWindow::NotifyAudioAudibleChanged(
|
void AudioChannelService::AudioChannelWindow::NotifyAudioAudibleChanged(
|
||||||
nsPIDOMWindowOuter* aWindow, AudibleState aAudible,
|
nsPIDOMWindowOuter* aWindow, AudibleState aAudible,
|
||||||
AudibleChangedReasons aReason) {
|
AudibleChangedReasons aReason) {
|
||||||
|
@ -183,10 +183,8 @@ class AudioChannelService final : public nsIObserver {
|
|||||||
explicit AudioChannelWindow(uint64_t aWindowID)
|
explicit AudioChannelWindow(uint64_t aWindowID)
|
||||||
: mWindowID(aWindowID),
|
: mWindowID(aWindowID),
|
||||||
mIsAudioCaptured(false),
|
mIsAudioCaptured(false),
|
||||||
mOwningAudioFocus(!AudioChannelService::IsEnableAudioCompeting()),
|
|
||||||
mShouldSendActiveMediaBlockStopEvent(false) {}
|
mShouldSendActiveMediaBlockStopEvent(false) {}
|
||||||
|
|
||||||
void AudioFocusChanged(AudioChannelAgent* aNewPlayingAgent);
|
|
||||||
void AudioAudibleChanged(AudioChannelAgent* aAgent, AudibleState aAudible,
|
void AudioAudibleChanged(AudioChannelAgent* aAgent, AudibleState aAudible,
|
||||||
AudibleChangedReasons aReason);
|
AudibleChangedReasons aReason);
|
||||||
|
|
||||||
@ -203,10 +201,6 @@ class AudioChannelService final : public nsIObserver {
|
|||||||
nsTObserverArray<AudioChannelAgent*> mAgents;
|
nsTObserverArray<AudioChannelAgent*> mAgents;
|
||||||
nsTObserverArray<AudioChannelAgent*> mAudibleAgents;
|
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
|
// If we've dispatched "activeMediaBlockStart" event, we must dispatch
|
||||||
// another event "activeMediablockStop" when the window is resumed from
|
// another event "activeMediablockStop" when the window is resumed from
|
||||||
// suspend-block.
|
// suspend-block.
|
||||||
@ -230,18 +224,6 @@ class AudioChannelService final : public nsIObserver {
|
|||||||
|
|
||||||
void NotifyChannelActive(uint64_t aWindowID, bool aActive);
|
void NotifyChannelActive(uint64_t aWindowID, bool aActive);
|
||||||
void MaybeNotifyMediaBlockStart(AudioChannelAgent* aAgent);
|
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);
|
AudioChannelWindow* GetOrCreateWindowData(nsPIDOMWindowOuter* aWindow);
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
#ifndef mozilla_dom_BindContext_h__
|
#ifndef mozilla_dom_BindContext_h__
|
||||||
#define mozilla_dom_BindContext_h__
|
#define mozilla_dom_BindContext_h__
|
||||||
|
|
||||||
#include "nsXBLBinding.h"
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/AutoRestore.h"
|
#include "mozilla/AutoRestore.h"
|
||||||
#include "mozilla/dom/Document.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.
|
// Whether our subtree root is changing as a result of this operation.
|
||||||
bool SubtreeRootChanges() const { return mSubtreeRootChanges; }
|
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.
|
// This constructor should be used for regular appends to content.
|
||||||
explicit BindContext(nsINode& aParent)
|
explicit BindContext(nsINode& aParent)
|
||||||
: mDoc(*aParent.OwnerDoc()),
|
: mDoc(*aParent.OwnerDoc()),
|
||||||
mBindingParent(aParent.IsContent()
|
|
||||||
? aParent.AsContent()->GetBindingParent()
|
|
||||||
: nullptr),
|
|
||||||
mInComposedDoc(aParent.IsInComposedDoc()),
|
mInComposedDoc(aParent.IsInComposedDoc()),
|
||||||
mInUncomposedDoc(aParent.IsInUncomposedDoc()),
|
mInUncomposedDoc(aParent.IsInUncomposedDoc()),
|
||||||
mSubtreeRootChanges(true) {}
|
mSubtreeRootChanges(true) {}
|
||||||
@ -69,7 +60,6 @@ struct MOZ_STACK_CLASS BindContext final {
|
|||||||
// This constructor is only meant to be used in that situation.
|
// This constructor is only meant to be used in that situation.
|
||||||
explicit BindContext(ShadowRoot& aShadowRoot)
|
explicit BindContext(ShadowRoot& aShadowRoot)
|
||||||
: mDoc(*aShadowRoot.OwnerDoc()),
|
: mDoc(*aShadowRoot.OwnerDoc()),
|
||||||
mBindingParent(aShadowRoot.Host()),
|
|
||||||
mInComposedDoc(aShadowRoot.IsInComposedDoc()),
|
mInComposedDoc(aShadowRoot.IsInComposedDoc()),
|
||||||
mInUncomposedDoc(false),
|
mInUncomposedDoc(false),
|
||||||
mSubtreeRootChanges(false) {}
|
mSubtreeRootChanges(false) {}
|
||||||
@ -79,21 +69,12 @@ struct MOZ_STACK_CLASS BindContext final {
|
|||||||
enum ForNativeAnonymous { ForNativeAnonymous };
|
enum ForNativeAnonymous { ForNativeAnonymous };
|
||||||
BindContext(Element& aParentElement, enum ForNativeAnonymous)
|
BindContext(Element& aParentElement, enum ForNativeAnonymous)
|
||||||
: mDoc(*aParentElement.OwnerDoc()),
|
: mDoc(*aParentElement.OwnerDoc()),
|
||||||
mBindingParent(&aParentElement),
|
|
||||||
mInComposedDoc(aParentElement.IsInComposedDoc()),
|
mInComposedDoc(aParentElement.IsInComposedDoc()),
|
||||||
mInUncomposedDoc(aParentElement.IsInUncomposedDoc()),
|
mInUncomposedDoc(aParentElement.IsInUncomposedDoc()),
|
||||||
mSubtreeRootChanges(true) {
|
mSubtreeRootChanges(true) {
|
||||||
MOZ_ASSERT(mInComposedDoc, "Binding NAC in a disconnected subtree?");
|
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:
|
private:
|
||||||
static bool IsLikelyUndisplayed(const nsINode& aParent) {
|
static bool IsLikelyUndisplayed(const nsINode& aParent) {
|
||||||
return aParent.IsAnyOfHTMLElements(nsGkAtoms::style, nsGkAtoms::script);
|
return aParent.IsAnyOfHTMLElements(nsGkAtoms::style, nsGkAtoms::script);
|
||||||
@ -101,8 +82,6 @@ struct MOZ_STACK_CLASS BindContext final {
|
|||||||
|
|
||||||
Document& mDoc;
|
Document& mDoc;
|
||||||
|
|
||||||
Element* const mBindingParent;
|
|
||||||
|
|
||||||
const bool mInComposedDoc;
|
const bool mInComposedDoc;
|
||||||
const bool mInUncomposedDoc;
|
const bool mInUncomposedDoc;
|
||||||
|
|
||||||
|
@ -506,7 +506,7 @@ void BodyConsumer::BeginConsumeBodyMainThread(ThreadSafeWorkerRef* aWorkerRef) {
|
|||||||
rv = GetBodyLocalFile(getter_AddRefs(file));
|
rv = GetBodyLocalFile(getter_AddRefs(file));
|
||||||
if (!NS_WARN_IF(NS_FAILED(rv)) && file) {
|
if (!NS_WARN_IF(NS_FAILED(rv)) && file) {
|
||||||
ChromeFilePropertyBag bag;
|
ChromeFilePropertyBag bag;
|
||||||
bag.mType = NS_ConvertUTF8toUTF16(mBodyMimeType);
|
CopyUTF8toUTF16(mBodyMimeType, bag.mType);
|
||||||
|
|
||||||
ErrorResult error;
|
ErrorResult error;
|
||||||
RefPtr<Promise> promise =
|
RefPtr<Promise> promise =
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
#include "nsChangeHint.h"
|
#include "nsChangeHint.h"
|
||||||
#include "nsCOMArray.h"
|
#include "nsCOMArray.h"
|
||||||
#include "mozilla/dom/DirectionalityUtils.h"
|
#include "mozilla/dom/DirectionalityUtils.h"
|
||||||
#include "nsBindingManager.h"
|
|
||||||
#include "nsCCUncollectableMarker.h"
|
#include "nsCCUncollectableMarker.h"
|
||||||
#include "mozAutoDocUpdate.h"
|
#include "mozAutoDocUpdate.h"
|
||||||
#include "nsTextNode.h"
|
#include "nsTextNode.h"
|
||||||
@ -36,6 +35,10 @@
|
|||||||
#include "nsWindowSizes.h"
|
#include "nsWindowSizes.h"
|
||||||
#include "nsWrapperCacheInlines.h"
|
#include "nsWrapperCacheInlines.h"
|
||||||
|
|
||||||
|
#if defined(ACCESSIBILITY) && defined(DEBUG)
|
||||||
|
# include "nsAccessibilityService.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
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.
|
// only assert if our parent is _changing_ while we have a parent.
|
||||||
MOZ_ASSERT(!GetParentNode() || &aParent == GetParentNode(),
|
MOZ_ASSERT(!GetParentNode() || &aParent == GetParentNode(),
|
||||||
"Already have a parent. Unbind first!");
|
"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();
|
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()) {
|
if (aParent.IsInNativeAnonymousSubtree()) {
|
||||||
SetFlags(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE);
|
SetFlags(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE);
|
||||||
}
|
}
|
||||||
if (aParent.HasFlag(NODE_HAS_BEEN_IN_UA_WIDGET)) {
|
if (aParent.HasFlag(NODE_HAS_BEEN_IN_UA_WIDGET)) {
|
||||||
SetFlags(NODE_HAS_BEEN_IN_UA_WIDGET);
|
SetFlags(NODE_HAS_BEEN_IN_UA_WIDGET);
|
||||||
}
|
}
|
||||||
if (HasFlag(NODE_IS_ANONYMOUS_ROOT)) {
|
if (IsRootOfNativeAnonymousSubtree()) {
|
||||||
aParent.SetMayHaveAnonymousChildren();
|
aParent.SetMayHaveAnonymousChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,8 +464,6 @@ nsresult CharacterData::BindToTree(BindContext& aContext, nsINode& aParent) {
|
|||||||
MOZ_ASSERT(IsInComposedDoc() == aContext.InComposedDoc());
|
MOZ_ASSERT(IsInComposedDoc() == aContext.InComposedDoc());
|
||||||
MOZ_ASSERT(IsInUncomposedDoc() == aContext.InUncomposedDoc());
|
MOZ_ASSERT(IsInUncomposedDoc() == aContext.InUncomposedDoc());
|
||||||
MOZ_ASSERT(&aParent == GetParentNode(), "Bound to wrong parent node");
|
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.IsInUncomposedDoc() == IsInUncomposedDoc());
|
||||||
MOZ_ASSERT(aParent.IsInComposedDoc() == IsInComposedDoc());
|
MOZ_ASSERT(aParent.IsInComposedDoc() == IsInComposedDoc());
|
||||||
MOZ_ASSERT(aParent.IsInShadowTree() == IsInShadowTree());
|
MOZ_ASSERT(aParent.IsInShadowTree() == IsInShadowTree());
|
||||||
@ -501,8 +477,6 @@ void CharacterData::UnbindFromTree(bool aNullParent) {
|
|||||||
|
|
||||||
HandleShadowDOMRelatedRemovalSteps(aNullParent);
|
HandleShadowDOMRelatedRemovalSteps(aNullParent);
|
||||||
|
|
||||||
Document* document = GetComposedDoc();
|
|
||||||
|
|
||||||
if (aNullParent) {
|
if (aNullParent) {
|
||||||
if (IsRootOfNativeAnonymousSubtree()) {
|
if (IsRootOfNativeAnonymousSubtree()) {
|
||||||
MutationObservers::NotifyNativeAnonymousChildListChange(this, true);
|
MutationObservers::NotifyNativeAnonymousChildListChange(this, true);
|
||||||
@ -524,26 +498,18 @@ void CharacterData::UnbindFromTree(bool aNullParent) {
|
|||||||
SetSubtreeRootPointer(aNullParent ? this : mParent->SubtreeRoot());
|
SetSubtreeRootPointer(aNullParent ? this : mParent->SubtreeRoot());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document && !GetContainingShadow()) {
|
if (nsExtendedContentSlots* slots = GetExistingExtendedContentSlots()) {
|
||||||
// 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 (aNullParent || !mParent->IsInShadowTree()) {
|
if (aNullParent || !mParent->IsInShadowTree()) {
|
||||||
slots->mContainingShadow = nullptr;
|
slots->mContainingShadow = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MutationObservers::NotifyParentChainChanged(this);
|
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 {}
|
void DumpContent(FILE* out, int32_t aIndent, bool aDumpAll) const override {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsXBLBinding* DoGetXBLBinding() const final { return nullptr; }
|
|
||||||
|
|
||||||
bool IsNodeOfType(uint32_t aFlags) const override { return false; }
|
bool IsNodeOfType(uint32_t aFlags) const override { return false; }
|
||||||
|
|
||||||
bool IsLink(nsIURI** aURI) const final {
|
bool IsLink(nsIURI** aURI) const final {
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "mozilla/dom/Document.h"
|
#include "mozilla/dom/Document.h"
|
||||||
#include "mozilla/dom/HTMLSlotElement.h"
|
#include "mozilla/dom/HTMLSlotElement.h"
|
||||||
#include "mozilla/dom/XBLChildrenElement.h"
|
|
||||||
#include "mozilla/dom/ShadowRoot.h"
|
#include "mozilla/dom/ShadowRoot.h"
|
||||||
#include "nsIAnonymousContentCreator.h"
|
#include "nsIAnonymousContentCreator.h"
|
||||||
#include "nsIFrame.h"
|
#include "nsIFrame.h"
|
||||||
@ -45,17 +44,10 @@ nsIContent* ExplicitChildIterator::GetNextChild() {
|
|||||||
return mChild;
|
return mChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(mChild->IsActiveChildrenElement());
|
MOZ_ASSERT_UNREACHABLE("This needs to be revisited");
|
||||||
auto* childrenElement = static_cast<XBLChildrenElement*>(mChild);
|
|
||||||
if (mIndexInInserted < childrenElement->InsertedChildrenLength()) {
|
|
||||||
return childrenElement->InsertedChild(mIndexInInserted++);
|
|
||||||
}
|
|
||||||
mIndexInInserted = 0;
|
|
||||||
mChild = mChild->GetNextSibling();
|
|
||||||
} else if (mDefaultChild) {
|
} else if (mDefaultChild) {
|
||||||
// If we're already in default content, check if there are more nodes there
|
// If we're already in default content, check if there are more nodes there
|
||||||
MOZ_ASSERT(mChild);
|
MOZ_ASSERT(mChild);
|
||||||
MOZ_ASSERT(mChild->IsActiveChildrenElement());
|
|
||||||
|
|
||||||
mDefaultChild = mDefaultChild->GetNextSibling();
|
mDefaultChild = mDefaultChild->GetNextSibling();
|
||||||
if (mDefaultChild) {
|
if (mDefaultChild) {
|
||||||
@ -83,89 +75,23 @@ nsIContent* ExplicitChildIterator::GetNextChild() {
|
|||||||
mChild = mChild->GetNextSibling();
|
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;
|
return mChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlattenedChildIterator::Init(bool aIgnoreXBL) {
|
void FlattenedChildIterator::Init() {
|
||||||
if (aIgnoreXBL) {
|
if (!mParent->IsElement()) {
|
||||||
mXBLInvolved = Some(false);
|
// TODO(emilio): I think it probably makes sense to only allow constructing
|
||||||
|
// FlattenedChildIterators with Element.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (ShadowRoot* shadow = mParent->AsElement()->GetShadowRoot()) {
|
||||||
// TODO(emilio): I think it probably makes sense to only allow constructing
|
mParent = shadow;
|
||||||
// FlattenedChildIterators with Element.
|
mShadowDOMInvolved = true;
|
||||||
if (mParent->IsElement()) {
|
return;
|
||||||
if (ShadowRoot* shadow = mParent->AsElement()->GetShadowRoot()) {
|
|
||||||
mParent = shadow;
|
|
||||||
mXBLInvolved = Some(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) {
|
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) {
|
bool ExplicitChildIterator::Seek(const nsIContent* aChildToFind) {
|
||||||
@ -177,7 +103,6 @@ bool ExplicitChildIterator::Seek(const nsIContent* aChildToFind) {
|
|||||||
mIndexInInserted = 0;
|
mIndexInInserted = 0;
|
||||||
mDefaultChild = nullptr;
|
mDefaultChild = nullptr;
|
||||||
mIsFirst = false;
|
mIsFirst = false;
|
||||||
MOZ_ASSERT(!mChild->IsActiveChildrenElement());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,9 +123,7 @@ nsIContent* ExplicitChildIterator::Get() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mIndexInInserted) {
|
if (mIndexInInserted) {
|
||||||
MOZ_ASSERT(mChild->IsActiveChildrenElement());
|
MOZ_ASSERT_UNREACHABLE("This needs to be revisited");
|
||||||
auto* childrenElement = static_cast<XBLChildrenElement*>(mChild);
|
|
||||||
return childrenElement->InsertedChild(mIndexInInserted - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mDefaultChild ? mDefaultChild : mChild;
|
return mDefaultChild ? mDefaultChild : mChild;
|
||||||
@ -223,14 +146,7 @@ nsIContent* ExplicitChildIterator::GetPreviousChild() {
|
|||||||
return mChild;
|
return mChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NB: mIndexInInserted points one past the last returned child so we need
|
MOZ_ASSERT_UNREACHABLE("This needs to be revisited");
|
||||||
// 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();
|
|
||||||
} else if (mDefaultChild) {
|
} else if (mDefaultChild) {
|
||||||
// If we're already in default content, check if there are more nodes there
|
// If we're already in default content, check if there are more nodes there
|
||||||
mDefaultChild = mDefaultChild->GetPreviousSibling();
|
mDefaultChild = mDefaultChild->GetPreviousSibling();
|
||||||
@ -259,32 +175,6 @@ nsIContent* ExplicitChildIterator::GetPreviousChild() {
|
|||||||
mChild = mParent->GetLastChild();
|
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) {
|
if (!mChild) {
|
||||||
mIsFirst = true;
|
mIsFirst = true;
|
||||||
}
|
}
|
||||||
|
@ -34,22 +34,6 @@ class ExplicitChildIterator {
|
|||||||
explicit ExplicitChildIterator(const nsIContent* aParent,
|
explicit ExplicitChildIterator(const nsIContent* aParent,
|
||||||
bool aStartAtBeginning = true);
|
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();
|
nsIContent* GetNextChild();
|
||||||
|
|
||||||
// Looks for aChildToFind respecting insertion points until aChildToFind is
|
// Looks for aChildToFind respecting insertion points until aChildToFind is
|
||||||
@ -129,61 +113,30 @@ class FlattenedChildIterator : public ExplicitChildIterator {
|
|||||||
bool aStartAtBeginning = true)
|
bool aStartAtBeginning = true)
|
||||||
: ExplicitChildIterator(aParent, aStartAtBeginning),
|
: ExplicitChildIterator(aParent, aStartAtBeginning),
|
||||||
mOriginalContent(aParent) {
|
mOriginalContent(aParent) {
|
||||||
Init(false);
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
FlattenedChildIterator(FlattenedChildIterator&& aOther)
|
bool ShadowDOMInvolved() { return mShadowDOMInvolved; }
|
||||||
: 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
const nsIContent* Parent() const { return mOriginalContent; }
|
const nsIContent* Parent() const { return mOriginalContent; }
|
||||||
|
|
||||||
private:
|
|
||||||
bool ComputeWhetherXBLIsInvolved() const;
|
|
||||||
|
|
||||||
void Init(bool aIgnoreXBL);
|
|
||||||
|
|
||||||
protected:
|
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;
|
const nsIContent* mOriginalContent;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void Init();
|
||||||
|
|
||||||
// For certain optimizations, nsCSSFrameConstructor needs to know if the child
|
// For certain optimizations, nsCSSFrameConstructor needs to know if the child
|
||||||
// list of the element that we're iterating matches its .childNodes.
|
// list of the element that we're iterating matches its .childNodes.
|
||||||
//
|
bool mShadowDOMInvolved = false;
|
||||||
// This is lazily computed when asked for it.
|
|
||||||
Maybe<bool> mXBLInvolved;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AllChildrenIterator traverses the children of an element including before /
|
* AllChildrenIterator traverses the children of an element including before /
|
||||||
* after content and optionally XBL children. The iterator can be initialized
|
* after content and shadow DOM. The iterator can be initialized to start at
|
||||||
* to start at the end by providing false for aStartAtBeginning in order to
|
* the end by providing false for aStartAtBeginning in order to start iterating
|
||||||
* start iterating in reverse from the last child.
|
* in reverse from the last child.
|
||||||
*
|
*
|
||||||
* Note: it assumes that no mutation of the DOM or frame tree takes place during
|
* 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.
|
* iteration, and will break horribly if that is not true.
|
||||||
@ -192,31 +145,22 @@ class AllChildrenIterator : private FlattenedChildIterator {
|
|||||||
public:
|
public:
|
||||||
AllChildrenIterator(const nsIContent* aNode, uint32_t aFlags,
|
AllChildrenIterator(const nsIContent* aNode, uint32_t aFlags,
|
||||||
bool aStartAtBeginning = true)
|
bool aStartAtBeginning = true)
|
||||||
: FlattenedChildIterator(aNode, aFlags, aStartAtBeginning),
|
: FlattenedChildIterator(aNode, aStartAtBeginning),
|
||||||
mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0),
|
mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0),
|
||||||
mFlags(aFlags),
|
mFlags(aFlags),
|
||||||
mPhase(aStartAtBeginning ? eAtBegin : eAtEnd) {}
|
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
|
#ifdef DEBUG
|
||||||
,
|
AllChildrenIterator(AllChildrenIterator&&) = default;
|
||||||
mMutationGuard(aOther.mMutationGuard)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
AllChildrenIterator& operator=(AllChildrenIterator&& aOther) {
|
AllChildrenIterator& operator=(AllChildrenIterator&& aOther) {
|
||||||
|
// Explicitly call the destructor to ensure the assertion in the destructor
|
||||||
|
// is checked.
|
||||||
this->~AllChildrenIterator();
|
this->~AllChildrenIterator();
|
||||||
new (this) AllChildrenIterator(std::move(aOther));
|
new (this) AllChildrenIterator(std::move(aOther));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
~AllChildrenIterator() { MOZ_ASSERT(!mMutationGuard.Mutated(0)); }
|
~AllChildrenIterator() { MOZ_ASSERT(!mMutationGuard.Mutated(0)); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -305,10 +249,7 @@ class MOZ_NEEDS_MEMMOVABLE_MEMBERS StyleChildrenIterator
|
|||||||
MOZ_COUNT_CTOR(StyleChildrenIterator);
|
MOZ_COUNT_CTOR(StyleChildrenIterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
StyleChildrenIterator& operator=(StyleChildrenIterator&& aOther) {
|
StyleChildrenIterator& operator=(StyleChildrenIterator&& aOther) = default;
|
||||||
AllChildrenIterator::operator=(std::move(aOther));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_COUNTED_DTOR(StyleChildrenIterator)
|
MOZ_COUNTED_DTOR(StyleChildrenIterator)
|
||||||
|
|
||||||
|
@ -385,16 +385,6 @@ class CustomElementRegistry final : public nsISupports, public nsWrapperCache {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public:
|
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.
|
* Looking up a custom element definition.
|
||||||
* https://html.spec.whatwg.org/#look-up-a-custom-element-definition
|
* https://html.spec.whatwg.org/#look-up-a-custom-element-definition
|
||||||
|
@ -172,7 +172,6 @@
|
|||||||
#include "nsContentCreatorFunctions.h"
|
#include "nsContentCreatorFunctions.h"
|
||||||
|
|
||||||
#include "nsIScriptContext.h"
|
#include "nsIScriptContext.h"
|
||||||
#include "nsBindingManager.h"
|
|
||||||
#include "nsHTMLDocument.h"
|
#include "nsHTMLDocument.h"
|
||||||
#include "nsIRequest.h"
|
#include "nsIRequest.h"
|
||||||
#include "mozilla/dom/BlobURLProtocolHandler.h"
|
#include "mozilla/dom/BlobURLProtocolHandler.h"
|
||||||
@ -292,17 +291,17 @@
|
|||||||
#include "mozilla/dom/SVGSVGElement.h"
|
#include "mozilla/dom/SVGSVGElement.h"
|
||||||
#include "mozilla/dom/DocGroup.h"
|
#include "mozilla/dom/DocGroup.h"
|
||||||
#include "mozilla/dom/TabGroup.h"
|
#include "mozilla/dom/TabGroup.h"
|
||||||
|
#include "mozilla/dom/ChromeObserver.h"
|
||||||
#ifdef MOZ_XUL
|
#ifdef MOZ_XUL
|
||||||
# include "mozilla/dom/XULBroadcastManager.h"
|
# include "mozilla/dom/XULBroadcastManager.h"
|
||||||
# include "mozilla/dom/XULPersist.h"
|
# include "mozilla/dom/XULPersist.h"
|
||||||
# include "nsIXULWindow.h"
|
# include "nsIAppWindow.h"
|
||||||
# include "nsIChromeRegistry.h"
|
# include "nsIChromeRegistry.h"
|
||||||
# include "nsXULPrototypeDocument.h"
|
# include "nsXULPrototypeDocument.h"
|
||||||
# include "nsXULCommandDispatcher.h"
|
# include "nsXULCommandDispatcher.h"
|
||||||
# include "nsXULPopupManager.h"
|
# include "nsXULPopupManager.h"
|
||||||
# include "nsIDocShellTreeOwner.h"
|
# include "nsIDocShellTreeOwner.h"
|
||||||
#endif
|
#endif
|
||||||
#include "mozilla/dom/BoxObject.h"
|
|
||||||
|
|
||||||
#include "mozilla/DocLoadingTimelineMarker.h"
|
#include "mozilla/DocLoadingTimelineMarker.h"
|
||||||
|
|
||||||
@ -829,19 +828,14 @@ nsresult ExternalResourceMap::AddExternalResource(nsIURI* aURI,
|
|||||||
doc = aViewer->GetDocument();
|
doc = aViewer->GetDocument();
|
||||||
NS_ASSERTION(doc, "Must have a document");
|
NS_ASSERTION(doc, "Must have a document");
|
||||||
|
|
||||||
if (doc->IsXULDocument()) {
|
doc->SetDisplayDocument(aDisplayDocument);
|
||||||
// We don't handle XUL stuff here yet.
|
|
||||||
rv = NS_ERROR_NOT_AVAILABLE;
|
|
||||||
} else {
|
|
||||||
doc->SetDisplayDocument(aDisplayDocument);
|
|
||||||
|
|
||||||
// Make sure that hiding our viewer will tear down its presentation.
|
// Make sure that hiding our viewer will tear down its presentation.
|
||||||
aViewer->SetSticky(false);
|
aViewer->SetSticky(false);
|
||||||
|
|
||||||
rv = aViewer->Init(nullptr, nsIntRect(0, 0, 0, 0));
|
rv = aViewer->Init(nullptr, nsIntRect(0, 0, 0, 0));
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
rv = aViewer->Open(nullptr, nullptr);
|
rv = aViewer->Open(nullptr, nullptr);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
@ -1204,7 +1198,6 @@ Document::Document(const char* aContentType)
|
|||||||
mIsInitialDocumentInWindow(false),
|
mIsInitialDocumentInWindow(false),
|
||||||
mIgnoreDocGroupMismatches(false),
|
mIgnoreDocGroupMismatches(false),
|
||||||
mLoadedAsData(false),
|
mLoadedAsData(false),
|
||||||
mLoadedAsInteractiveData(false),
|
|
||||||
mMayStartLayout(true),
|
mMayStartLayout(true),
|
||||||
mHaveFiredTitleChange(false),
|
mHaveFiredTitleChange(false),
|
||||||
mIsShowing(false),
|
mIsShowing(false),
|
||||||
@ -1265,7 +1258,6 @@ Document::Document(const char* aContentType)
|
|||||||
mAutoFocusFired(false),
|
mAutoFocusFired(false),
|
||||||
mScrolledToRefAlready(false),
|
mScrolledToRefAlready(false),
|
||||||
mChangeScrollPosWhenScrollingToRef(false),
|
mChangeScrollPosWhenScrollingToRef(false),
|
||||||
mHasWarnedAboutBoxObjects(false),
|
|
||||||
mDelayFrameLoaderInitialization(false),
|
mDelayFrameLoaderInitialization(false),
|
||||||
mSynchronousDOMContentLoaded(false),
|
mSynchronousDOMContentLoaded(false),
|
||||||
mMaybeServiceWorkerControlled(false),
|
mMaybeServiceWorkerControlled(false),
|
||||||
@ -1325,7 +1317,6 @@ Document::Document(const char* aContentType)
|
|||||||
mHeaderData(nullptr),
|
mHeaderData(nullptr),
|
||||||
mScrollAnchorAdjustmentLength(0),
|
mScrollAnchorAdjustmentLength(0),
|
||||||
mScrollAnchorAdjustmentCount(0),
|
mScrollAnchorAdjustmentCount(0),
|
||||||
mBoxObjectTable(nullptr),
|
|
||||||
mCurrentOrientationAngle(0),
|
mCurrentOrientationAngle(0),
|
||||||
mCurrentOrientationType(OrientationType::Portrait_primary),
|
mCurrentOrientationType(OrientationType::Portrait_primary),
|
||||||
mServoRestyleRootDirtyBits(0),
|
mServoRestyleRootDirtyBits(0),
|
||||||
@ -1357,19 +1348,6 @@ Document::Document(const char* aContentType)
|
|||||||
mReferrerInfo = new dom::ReferrerInfo(nullptr);
|
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 {
|
bool Document::IsAboutPage() const {
|
||||||
nsCOMPtr<nsIPrincipal> principal = NodePrincipal();
|
nsCOMPtr<nsIPrincipal> principal = NodePrincipal();
|
||||||
return principal->SchemeIs("about");
|
return principal->SchemeIs("about");
|
||||||
@ -1551,8 +1529,6 @@ Document::~Document() {
|
|||||||
|
|
||||||
delete mHeaderData;
|
delete mHeaderData;
|
||||||
|
|
||||||
ClearAllBoxObjects();
|
|
||||||
|
|
||||||
mPendingTitleChangeEvent.Revoke();
|
mPendingTitleChangeEvent.Revoke();
|
||||||
|
|
||||||
mPlugins.Clear();
|
mPlugins.Clear();
|
||||||
@ -1658,13 +1634,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(Document)
|
|||||||
return NS_SUCCESS_INTERRUPTED_TRAVERSE;
|
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);
|
tmp->mExternalResourceMap.Traverse(&cb);
|
||||||
|
|
||||||
// Traverse all Document pointer members.
|
// Traverse all Document pointer members.
|
||||||
@ -1683,15 +1652,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(Document)
|
|||||||
|
|
||||||
DocumentOrShadowRoot::Traverse(tmp, cb);
|
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(mChannel)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLayoutHistoryState)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLayoutHistoryState)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOnloadBlocker)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOnloadBlocker)
|
||||||
@ -1802,7 +1762,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Document)
|
|||||||
|
|
||||||
tmp->mCachedRootElement = nullptr; // Avoid a dangling pointer
|
tmp->mCachedRootElement = nullptr; // Avoid a dangling pointer
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDisplayDocument)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDisplayDocument)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMaybeEndOutermostXBLUpdateRunner)
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMImplementation)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMImplementation)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mImageMaps)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mImageMaps)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCachedEncoder)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCachedEncoder)
|
||||||
@ -1835,8 +1794,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Document)
|
|||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIntersectionObservers)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIntersectionObservers)
|
||||||
|
|
||||||
tmp->ClearAllBoxObjects();
|
|
||||||
|
|
||||||
if (tmp->mListenerManager) {
|
if (tmp->mListenerManager) {
|
||||||
tmp->mListenerManager->Disconnect();
|
tmp->mListenerManager->Disconnect();
|
||||||
tmp->UnsetFlags(NODE_HAS_LISTENERMANAGER);
|
tmp->UnsetFlags(NODE_HAS_LISTENERMANAGER);
|
||||||
@ -1974,7 +1931,7 @@ void Document::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) {
|
|||||||
nsCOMPtr<nsIPrincipal> principal;
|
nsCOMPtr<nsIPrincipal> principal;
|
||||||
nsCOMPtr<nsIPrincipal> storagePrincipal;
|
nsCOMPtr<nsIPrincipal> storagePrincipal;
|
||||||
if (aChannel) {
|
if (aChannel) {
|
||||||
// Note: this code is duplicated in XULDocument::StartDocumentLoad and
|
// Note: this code is duplicated in PrototypeDocumentContentSink::Init and
|
||||||
// nsScriptSecurityManager::GetChannelResultPrincipals.
|
// nsScriptSecurityManager::GetChannelResultPrincipals.
|
||||||
// Note: this should match nsDocShell::OnLoadingSite
|
// Note: this should match nsDocShell::OnLoadingSite
|
||||||
NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
|
NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
|
||||||
@ -2641,6 +2598,9 @@ nsresult Document::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
|
|||||||
IsSynthesized() && XRE_IsContentProcess()) {
|
IsSynthesized() && XRE_IsContentProcess()) {
|
||||||
ContentChild::UpdateCookieStatus(mChannel);
|
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
|
// 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 the doc is an addon, apply its CSP.
|
||||||
if (addonPolicy) {
|
if (addonPolicy) {
|
||||||
nsAutoString addonCSP;
|
nsAutoString extensionPageCSP;
|
||||||
Unused << ExtensionPolicyService::GetSingleton().GetBaseCSP(addonCSP);
|
Unused << ExtensionPolicyService::GetSingleton().GetBaseCSP(
|
||||||
mCSP->AppendPolicy(addonCSP, false, false);
|
extensionPageCSP);
|
||||||
|
mCSP->AppendPolicy(extensionPageCSP, false, false);
|
||||||
|
|
||||||
mCSP->AppendPolicy(addonPolicy->ContentSecurityPolicy(), false, false);
|
mCSP->AppendPolicy(addonPolicy->ExtensionPageCSP(), false, false);
|
||||||
// Bug 1548468: Move CSP off ExpandedPrincipal
|
// Bug 1548468: Move CSP off ExpandedPrincipal
|
||||||
// Currently the LoadInfo holds the source of truth for every resource load
|
// Currently the LoadInfo holds the source of truth for every resource load
|
||||||
// because LoadInfo::GetCSP() queries the CSP from an ExpandedPrincipal
|
// 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
|
/* Return true if the document is in the focused top-level window, and is an
|
||||||
* ancestor of the focused DOMWindow. */
|
* ancestor of the focused DOMWindow. */
|
||||||
bool Document::HasFocus(ErrorResult& rv) const {
|
bool Document::HasFocus(ErrorResult& rv) const {
|
||||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||||
if (!fm) {
|
if (!fm) {
|
||||||
rv.Throw(NS_ERROR_NOT_AVAILABLE);
|
rv.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||||
return false;
|
return false;
|
||||||
@ -5390,9 +5351,9 @@ Element* Document::GetActiveElement() {
|
|||||||
if (bodyElement) {
|
if (bodyElement) {
|
||||||
return bodyElement;
|
return bodyElement;
|
||||||
}
|
}
|
||||||
// Special case to handle the transition to browser.xhtml where there is
|
// Special case to handle the transition to XHTML from XUL documents
|
||||||
// currently not a body element, but we need to match the XUL behavior.
|
// where there currently isn't a body element, but we need to match the
|
||||||
// This should be removed when bug 1492582 is resolved.
|
// XUL behavior. This should be removed when bug 1540278 is resolved.
|
||||||
if (nsContentUtils::IsChromeDoc(this)) {
|
if (nsContentUtils::IsChromeDoc(this)) {
|
||||||
Element* docElement = GetDocumentElement();
|
Element* docElement = GetDocumentElement();
|
||||||
if (docElement && docElement->IsXULElement()) {
|
if (docElement && docElement->IsXULElement()) {
|
||||||
@ -5604,20 +5565,6 @@ static inline void AssertNoStaleServoDataIn(nsINode& aSubtreeRoot) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(!element->HasServoData());
|
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
|
#endif
|
||||||
}
|
}
|
||||||
@ -6521,24 +6468,6 @@ bool Document::RemoveObserver(nsIDocumentObserver* aObserver) {
|
|||||||
return mObservers.Contains(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() {
|
void Document::BeginUpdate() {
|
||||||
// If the document is going away, then it's probably okay to do things to it
|
// 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
|
// in the wrong DocGroup. We're unlikely to run JS or do anything else
|
||||||
@ -6551,11 +6480,6 @@ void Document::BeginUpdate() {
|
|||||||
mDocGroup->ValidateAccess();
|
mDocGroup->ValidateAccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mUpdateNestLevel == 0 && !mInXBLUpdate) {
|
|
||||||
mInXBLUpdate = true;
|
|
||||||
BindingManager()->BeginOutermostUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
++mUpdateNestLevel;
|
++mUpdateNestLevel;
|
||||||
nsContentUtils::AddScriptBlocker();
|
nsContentUtils::AddScriptBlocker();
|
||||||
NS_DOCUMENT_NOTIFY_OBSERVERS(BeginUpdate, (this));
|
NS_DOCUMENT_NOTIFY_OBSERVERS(BeginUpdate, (this));
|
||||||
@ -6571,10 +6495,6 @@ void Document::EndUpdate() {
|
|||||||
|
|
||||||
--mUpdateNestLevel;
|
--mUpdateNestLevel;
|
||||||
|
|
||||||
// This set of updates may have created XBL bindings. Let the
|
|
||||||
// binding manager know we're done.
|
|
||||||
MaybeEndOutermostXBLUpdate();
|
|
||||||
|
|
||||||
MaybeInitializeFinalizeFrameLoaders();
|
MaybeInitializeFinalizeFrameLoaders();
|
||||||
if (mXULBroadcastManager) {
|
if (mXULBroadcastManager) {
|
||||||
mXULBroadcastManager->MaybeBroadcast();
|
mXULBroadcastManager->MaybeBroadcast();
|
||||||
@ -6772,10 +6692,9 @@ void Document::EndLoad() {
|
|||||||
bool turnOnEditing =
|
bool turnOnEditing =
|
||||||
mParser && (HasFlag(NODE_IS_EDITABLE) || mContentEditableCount > 0);
|
mParser && (HasFlag(NODE_IS_EDITABLE) || mContentEditableCount > 0);
|
||||||
|
|
||||||
#if defined(DEBUG) && !defined(ANDROID)
|
#if defined(DEBUG)
|
||||||
// only assert if nothing stopped the load on purpose
|
// only assert if nothing stopped the load on purpose
|
||||||
// TODO: we probably also want to check XUL documents here too
|
if (!mParserAborted) {
|
||||||
if (!mParserAborted && !IsXULDocument()) {
|
|
||||||
nsContentSecurityUtils::AssertAboutPageHasCSP(this);
|
nsContentSecurityUtils::AssertAboutPageHasCSP(this);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -6799,6 +6718,14 @@ void Document::EndLoad() {
|
|||||||
mParser = nullptr;
|
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));
|
NS_DOCUMENT_NOTIFY_OBSERVERS(EndLoad, (this));
|
||||||
|
|
||||||
// Part 2: Code that only executes when this EndLoad matches a BeginLoad.
|
// 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;
|
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) {
|
already_AddRefed<nsRange> Document::CreateRange(ErrorResult& rv) {
|
||||||
return nsRange::Create(this, 0, this, 0, rv);
|
return nsRange::Create(this, 0, this, 0, rv);
|
||||||
}
|
}
|
||||||
@ -7944,55 +7792,6 @@ void Document::DoNotifyPossibleTitleChange() {
|
|||||||
Cancelable::eYes);
|
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(
|
already_AddRefed<MediaQueryList> Document::MatchMedia(
|
||||||
const nsACString& aMediaQueryList, CallerType aCallerType) {
|
const nsACString& aMediaQueryList, CallerType aCallerType) {
|
||||||
RefPtr<MediaQueryList> result =
|
RefPtr<MediaQueryList> result =
|
||||||
@ -8009,7 +7808,7 @@ void Document::SetMayStartLayout(bool aMayStartLayout) {
|
|||||||
// Before starting layout, check whether we're a toplevel chrome
|
// 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
|
// window. If we are, setup some state so that we don't have to restyle
|
||||||
// the whole tree after StartLayout.
|
// the whole tree after StartLayout.
|
||||||
if (nsCOMPtr<nsIXULWindow> win = GetXULWindowIfToplevelChrome()) {
|
if (nsCOMPtr<nsIAppWindow> win = GetAppWindowIfToplevelChrome()) {
|
||||||
// We're the chrome document!
|
// We're the chrome document!
|
||||||
win->BeforeStartLayout();
|
win->BeforeStartLayout();
|
||||||
}
|
}
|
||||||
@ -8117,6 +7916,7 @@ void Document::TryCancelFrameLoaderInitialization(nsIDocShell* aShell) {
|
|||||||
|
|
||||||
void Document::SetPrototypeDocument(nsXULPrototypeDocument* aPrototype) {
|
void Document::SetPrototypeDocument(nsXULPrototypeDocument* aPrototype) {
|
||||||
mPrototypeDocument = aPrototype;
|
mPrototypeDocument = aPrototype;
|
||||||
|
mSynchronousDOMContentLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Document* Document::RequestExternalResource(
|
Document* Document::RequestExternalResource(
|
||||||
@ -8143,7 +7943,7 @@ SMILAnimationController* Document::GetAnimationController() {
|
|||||||
// one and only SVG documents and the like will call this
|
// one and only SVG documents and the like will call this
|
||||||
if (mAnimationController) return mAnimationController;
|
if (mAnimationController) return mAnimationController;
|
||||||
// Refuse to create an Animation Controller for data documents.
|
// Refuse to create an Animation Controller for data documents.
|
||||||
if (mLoadedAsData || mLoadedAsInteractiveData) return nullptr;
|
if (mLoadedAsData) return nullptr;
|
||||||
|
|
||||||
mAnimationController = new SMILAnimationController(this);
|
mAnimationController = new SMILAnimationController(this);
|
||||||
|
|
||||||
@ -8895,14 +8695,6 @@ nsINode* Document::AdoptNode(nsINode& aAdoptedNode, ErrorResult& rv) {
|
|||||||
parent->RemoveChildNode(adoptedNode->AsContent(), true);
|
parent->RemoveChildNode(adoptedNode->AsContent(), true);
|
||||||
} else {
|
} else {
|
||||||
MOZ_ASSERT(!adoptedNode->IsInUncomposedDoc());
|
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;
|
break;
|
||||||
@ -10749,14 +10541,15 @@ void Document::SetReadyStateInternal(ReadyState aReadyState,
|
|||||||
}
|
}
|
||||||
// At the time of loading start, we don't have timing object, record time.
|
// At the time of loading start, we don't have timing object, record time.
|
||||||
|
|
||||||
if (READYSTATE_INTERACTIVE == aReadyState) {
|
if (READYSTATE_INTERACTIVE == aReadyState &&
|
||||||
if (NodePrincipal()->IsSystemPrincipal()) {
|
NodePrincipal()->IsSystemPrincipal()) {
|
||||||
Element* root = GetRootElement();
|
if (!mXULPersist) {
|
||||||
if ((root && root->HasAttr(kNameSpaceID_None, nsGkAtoms::mozpersist)) ||
|
mXULPersist = new XULPersist(this);
|
||||||
IsXULDocument()) {
|
mXULPersist->Init();
|
||||||
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,
|
static void FireOrClearDelayedEvents(nsTArray<nsCOMPtr<Document>>& aDocuments,
|
||||||
bool aFireEvents) {
|
bool aFireEvents) {
|
||||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||||
if (!fm) return;
|
if (!fm) return;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < aDocuments.Length(); ++i) {
|
for (uint32_t i = 0; i < aDocuments.Length(); ++i) {
|
||||||
@ -11077,14 +10870,14 @@ RefPtr<StyleSheet> Document::LoadChromeSheetSync(nsIURI* uri) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Document::ResetDocumentDirection() {
|
void Document::ResetDocumentDirection() {
|
||||||
if (!(nsContentUtils::IsChromeDoc(this) || IsXULDocument())) {
|
if (!nsContentUtils::IsChromeDoc(this)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
UpdateDocumentStates(NS_DOCUMENT_STATE_RTL_LOCALE, true);
|
UpdateDocumentStates(NS_DOCUMENT_STATE_RTL_LOCALE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Document::IsDocumentRightToLeft() {
|
bool Document::IsDocumentRightToLeft() {
|
||||||
if (!(nsContentUtils::IsChromeDoc(this) || IsXULDocument())) {
|
if (!nsContentUtils::IsChromeDoc(this)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// setting the localedir attribute on the root element forces a
|
// 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()) {
|
if (ShadowRoot* shadow = element->GetShadowRoot()) {
|
||||||
AddSizeOfNodeTree(*shadow, aWindowSizes);
|
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);
|
aType, aResult, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsIXULWindow> Document::GetXULWindowIfToplevelChrome() const {
|
already_AddRefed<nsIAppWindow> Document::GetAppWindowIfToplevelChrome() const {
|
||||||
nsCOMPtr<nsIDocShellTreeItem> item = GetDocShell();
|
nsCOMPtr<nsIDocShellTreeItem> item = GetDocShell();
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
nsCOMPtr<nsIDocShellTreeOwner> owner;
|
nsCOMPtr<nsIDocShellTreeOwner> owner;
|
||||||
item->GetTreeOwner(getter_AddRefs(owner));
|
item->GetTreeOwner(getter_AddRefs(owner));
|
||||||
nsCOMPtr<nsIXULWindow> xulWin = do_GetInterface(owner);
|
nsCOMPtr<nsIAppWindow> appWin = do_GetInterface(owner);
|
||||||
if (!xulWin) {
|
if (!appWin) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
nsCOMPtr<nsIDocShell> xulWinShell;
|
nsCOMPtr<nsIDocShell> appWinShell;
|
||||||
xulWin->GetDocShell(getter_AddRefs(xulWinShell));
|
appWin->GetDocShell(getter_AddRefs(appWinShell));
|
||||||
if (!SameCOMIdentity(xulWinShell, item)) {
|
if (!SameCOMIdentity(appWinShell, item)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return xulWin.forget();
|
return appWin.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
Document* Document::GetTopLevelContentDocument() {
|
Document* Document::GetTopLevelContentDocument() {
|
||||||
|
@ -79,7 +79,6 @@ class ElementCreationOptionsOrString;
|
|||||||
|
|
||||||
class gfxUserFontSet;
|
class gfxUserFontSet;
|
||||||
class imgIRequest;
|
class imgIRequest;
|
||||||
class nsBindingManager;
|
|
||||||
class nsCachableElementsByNameNodeList;
|
class nsCachableElementsByNameNodeList;
|
||||||
class nsContentList;
|
class nsContentList;
|
||||||
class nsIDocShell;
|
class nsIDocShell;
|
||||||
@ -124,7 +123,7 @@ class nsWindowSizes;
|
|||||||
class nsDOMCaretPosition;
|
class nsDOMCaretPosition;
|
||||||
class nsViewportInfo;
|
class nsViewportInfo;
|
||||||
class nsIGlobalObject;
|
class nsIGlobalObject;
|
||||||
class nsIXULWindow;
|
class nsIAppWindow;
|
||||||
class nsXULPrototypeDocument;
|
class nsXULPrototypeDocument;
|
||||||
class nsXULPrototypeElement;
|
class nsXULPrototypeElement;
|
||||||
class PermissionDelegateHandler;
|
class PermissionDelegateHandler;
|
||||||
@ -162,9 +161,9 @@ class Rule;
|
|||||||
namespace dom {
|
namespace dom {
|
||||||
class AnonymousContent;
|
class AnonymousContent;
|
||||||
class Attr;
|
class Attr;
|
||||||
class BoxObject;
|
|
||||||
class XULBroadcastManager;
|
class XULBroadcastManager;
|
||||||
class XULPersist;
|
class XULPersist;
|
||||||
|
class ChromeObserver;
|
||||||
class ClientInfo;
|
class ClientInfo;
|
||||||
class ClientState;
|
class ClientState;
|
||||||
class CDATASection;
|
class CDATASection;
|
||||||
@ -218,7 +217,6 @@ class XPathEvaluator;
|
|||||||
class XPathExpression;
|
class XPathExpression;
|
||||||
class XPathNSResolver;
|
class XPathNSResolver;
|
||||||
class XPathResult;
|
class XPathResult;
|
||||||
class XULDocument;
|
|
||||||
template <typename>
|
template <typename>
|
||||||
class Sequence;
|
class Sequence;
|
||||||
|
|
||||||
@ -1019,9 +1017,6 @@ class Document : public nsINode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SetLoadedAsData(bool aLoadedAsData) { mLoadedAsData = aLoadedAsData; }
|
void SetLoadedAsData(bool aLoadedAsData) { mLoadedAsData = aLoadedAsData; }
|
||||||
void SetLoadedAsInteractiveData(bool aLoadedAsInteractiveData) {
|
|
||||||
mLoadedAsInteractiveData = aLoadedAsInteractiveData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normally we assert if a runnable labeled with one DocGroup touches data
|
* Normally we assert if a runnable labeled with one DocGroup touches data
|
||||||
@ -1715,10 +1710,6 @@ class Document : public nsINode,
|
|||||||
|
|
||||||
void DoUnblockOnload();
|
void DoUnblockOnload();
|
||||||
|
|
||||||
void ClearAllBoxObjects();
|
|
||||||
|
|
||||||
void MaybeEndOutermostXBLUpdate();
|
|
||||||
|
|
||||||
void RetrieveRelevantHeaders(nsIChannel* aChannel);
|
void RetrieveRelevantHeaders(nsIChannel* aChannel);
|
||||||
|
|
||||||
void TryChannelCharset(nsIChannel* aChannel, int32_t& aCharsetSource,
|
void TryChannelCharset(nsIChannel* aChannel, int32_t& aCharsetSource,
|
||||||
@ -2304,10 +2295,6 @@ class Document : public nsINode,
|
|||||||
DoUpdateSVGUseElementShadowTrees();
|
DoUpdateSVGUseElementShadowTrees();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsBindingManager* BindingManager() const {
|
|
||||||
return mNodeInfoManager->GetBindingManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only to be used inside Gecko, you can't really do anything with the
|
* Only to be used inside Gecko, you can't really do anything with the
|
||||||
* pointer outside Gecko anyway.
|
* pointer outside Gecko anyway.
|
||||||
@ -2372,14 +2359,8 @@ class Document : public nsINode,
|
|||||||
bool IsHTMLOrXHTML() const { return mType == eHTML || mType == eXHTML; }
|
bool IsHTMLOrXHTML() const { return mType == eHTML || mType == eXHTML; }
|
||||||
bool IsXMLDocument() const { return !IsHTMLDocument(); }
|
bool IsXMLDocument() const { return !IsHTMLDocument(); }
|
||||||
bool IsSVGDocument() const { return mType == eSVG; }
|
bool IsSVGDocument() const { return mType == eSVG; }
|
||||||
bool IsXULDocument() const { return mType == eXUL; }
|
bool IsUnstyledDocument() { return IsLoadedAsData(); }
|
||||||
bool IsUnstyledDocument() {
|
|
||||||
return IsLoadedAsData() || IsLoadedAsInteractiveData();
|
|
||||||
}
|
|
||||||
bool LoadsFullXULStyleSheetUpFront() {
|
bool LoadsFullXULStyleSheetUpFront() {
|
||||||
if (IsXULDocument()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (IsSVGDocument()) {
|
if (IsSVGDocument()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2618,20 +2599,6 @@ class Document : public nsINode,
|
|||||||
// Refreshes the hrefs of all the links in the document.
|
// Refreshes the hrefs of all the links in the document.
|
||||||
void RefreshLinkHrefs();
|
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()
|
* Support for window.matchMedia()
|
||||||
*/
|
*/
|
||||||
@ -2652,10 +2619,6 @@ class Document : public nsINode,
|
|||||||
*/
|
*/
|
||||||
bool HaveFiredDOMTitleChange() const { return mHaveFiredTitleChange; }
|
bool HaveFiredDOMTitleChange() const { return mHaveFiredTitleChange; }
|
||||||
|
|
||||||
Element* GetAnonymousElementByAttribute(nsIContent* aElement,
|
|
||||||
nsAtom* aAttrName,
|
|
||||||
const nsAString& aAttrValue) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To batch DOMSubtreeModified, document needs to be informed when
|
* To batch DOMSubtreeModified, document needs to be informed when
|
||||||
* a mutation event might be dispatched, even if the event isn't actually
|
* 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 IsLoadedAsData() { return mLoadedAsData; }
|
||||||
|
|
||||||
bool IsLoadedAsInteractiveData() { return mLoadedAsInteractiveData; }
|
|
||||||
|
|
||||||
bool MayStartLayout() { return mMayStartLayout; }
|
bool MayStartLayout() { return mMayStartLayout; }
|
||||||
|
|
||||||
void SetMayStartLayout(bool aMayStartLayout);
|
void SetMayStartLayout(bool aMayStartLayout);
|
||||||
@ -3447,9 +3408,9 @@ class Document : public nsINode,
|
|||||||
Document* GetTopLevelContentDocument();
|
Document* GetTopLevelContentDocument();
|
||||||
const Document* GetTopLevelContentDocument() const;
|
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.
|
// null otherwise.
|
||||||
already_AddRefed<nsIXULWindow> GetXULWindowIfToplevelChrome() const;
|
already_AddRefed<nsIAppWindow> GetAppWindowIfToplevelChrome() const;
|
||||||
|
|
||||||
already_AddRefed<Element> CreateElement(
|
already_AddRefed<Element> CreateElement(
|
||||||
const nsAString& aTagName, const ElementCreationOptionsOrString& aOptions,
|
const nsAString& aTagName, const ElementCreationOptionsOrString& aOptions,
|
||||||
@ -3640,13 +3601,7 @@ class Document : public nsINode,
|
|||||||
bool IsScrollingElement(Element* aElement);
|
bool IsScrollingElement(Element* aElement);
|
||||||
|
|
||||||
// QuerySelector and QuerySelectorAll already defined on nsINode
|
// 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,
|
XPathExpression* CreateExpression(const nsAString& aExpression,
|
||||||
XPathNSResolver* aResolver,
|
XPathNSResolver* aResolver,
|
||||||
ErrorResult& rv);
|
ErrorResult& rv);
|
||||||
@ -3726,12 +3681,6 @@ class Document : public nsINode,
|
|||||||
inline SVGDocument* AsSVGDocument();
|
inline SVGDocument* AsSVGDocument();
|
||||||
inline const SVGDocument* AsSVGDocument() const;
|
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
|
* 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.
|
* 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.
|
// as scripts and plugins, disabled.
|
||||||
bool mLoadedAsData : 1;
|
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
|
// If true, whoever is creating the document has gotten it to the
|
||||||
// point where it's safe to start layout on it.
|
// point where it's safe to start layout on it.
|
||||||
bool mMayStartLayout : 1;
|
bool mMayStartLayout : 1;
|
||||||
@ -4668,8 +4612,6 @@ class Document : public nsINode,
|
|||||||
bool mScrolledToRefAlready : 1;
|
bool mScrolledToRefAlready : 1;
|
||||||
bool mChangeScrollPosWhenScrollingToRef : 1;
|
bool mChangeScrollPosWhenScrollingToRef : 1;
|
||||||
|
|
||||||
bool mHasWarnedAboutBoxObjects : 1;
|
|
||||||
|
|
||||||
bool mDelayFrameLoaderInitialization : 1;
|
bool mDelayFrameLoaderInitialization : 1;
|
||||||
|
|
||||||
bool mSynchronousDOMContentLoaded : 1;
|
bool mSynchronousDOMContentLoaded : 1;
|
||||||
@ -4777,8 +4719,7 @@ class Document : public nsINode,
|
|||||||
eHTML,
|
eHTML,
|
||||||
eXHTML,
|
eXHTML,
|
||||||
eGenericXML,
|
eGenericXML,
|
||||||
eSVG,
|
eSVG
|
||||||
eXUL
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Type mType;
|
Type mType;
|
||||||
@ -5046,8 +4987,6 @@ class Document : public nsINode,
|
|||||||
|
|
||||||
RefPtr<dom::ScriptLoader> mScriptLoader;
|
RefPtr<dom::ScriptLoader> mScriptLoader;
|
||||||
|
|
||||||
nsRefPtrHashtable<nsPtrHashKey<nsIContent>, BoxObject>* mBoxObjectTable;
|
|
||||||
|
|
||||||
// Tracker for animations that are waiting to start.
|
// Tracker for animations that are waiting to start.
|
||||||
// nullptr until GetOrCreatePendingAnimationTracker is called.
|
// nullptr until GetOrCreatePendingAnimationTracker is called.
|
||||||
RefPtr<PendingAnimationTracker> mPendingAnimationTracker;
|
RefPtr<PendingAnimationTracker> mPendingAnimationTracker;
|
||||||
@ -5100,7 +5039,6 @@ class Document : public nsINode,
|
|||||||
|
|
||||||
RefPtr<EventListenerManager> mListenerManager;
|
RefPtr<EventListenerManager> mListenerManager;
|
||||||
|
|
||||||
nsCOMPtr<nsIRunnable> mMaybeEndOutermostXBLUpdateRunner;
|
|
||||||
nsCOMPtr<nsIRequest> mOnloadBlocker;
|
nsCOMPtr<nsIRequest> mOnloadBlocker;
|
||||||
|
|
||||||
// Gecko-internal sheets used for extensions and such.
|
// Gecko-internal sheets used for extensions and such.
|
||||||
@ -5147,6 +5085,7 @@ class Document : public nsINode,
|
|||||||
|
|
||||||
RefPtr<XULBroadcastManager> mXULBroadcastManager;
|
RefPtr<XULBroadcastManager> mXULBroadcastManager;
|
||||||
RefPtr<XULPersist> mXULPersist;
|
RefPtr<XULPersist> mXULPersist;
|
||||||
|
RefPtr<ChromeObserver> mChromeObserver;
|
||||||
|
|
||||||
RefPtr<HTMLAllCollection> mAll;
|
RefPtr<HTMLAllCollection> mAll;
|
||||||
|
|
||||||
@ -5308,12 +5247,6 @@ nsresult NS_NewDOMDocument(
|
|||||||
nsIURI* aDocumentURI, nsIURI* aBaseURI, nsIPrincipal* aPrincipal,
|
nsIURI* aDocumentURI, nsIURI* aBaseURI, nsIPrincipal* aPrincipal,
|
||||||
bool aLoadedAsData, nsIGlobalObject* aEventObject, DocumentFlavor aFlavor);
|
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);
|
nsresult NS_NewPluginDocument(mozilla::dom::Document** aInstancePtrResult);
|
||||||
|
|
||||||
inline mozilla::dom::Document* nsINode::GetOwnerDocument() const {
|
inline mozilla::dom::Document* nsINode::GetOwnerDocument() const {
|
||||||
|
@ -46,7 +46,6 @@
|
|||||||
#include "nsContentList.h"
|
#include "nsContentList.h"
|
||||||
#include "nsVariant.h"
|
#include "nsVariant.h"
|
||||||
#include "nsDOMTokenList.h"
|
#include "nsDOMTokenList.h"
|
||||||
#include "nsXBLPrototypeBinding.h"
|
|
||||||
#include "nsError.h"
|
#include "nsError.h"
|
||||||
#include "nsDOMString.h"
|
#include "nsDOMString.h"
|
||||||
#include "mozilla/dom/AnimatableBinding.h"
|
#include "mozilla/dom/AnimatableBinding.h"
|
||||||
@ -93,10 +92,7 @@
|
|||||||
# include "nsRange.h"
|
# include "nsRange.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "nsBindingManager.h"
|
|
||||||
#include "nsXBLBinding.h"
|
|
||||||
#include "nsPIDOMWindow.h"
|
#include "nsPIDOMWindow.h"
|
||||||
#include "nsPIBoxObject.h"
|
|
||||||
#include "mozilla/dom/DOMRect.h"
|
#include "mozilla/dom/DOMRect.h"
|
||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
#include "nsGkAtoms.h"
|
#include "nsGkAtoms.h"
|
||||||
@ -128,7 +124,6 @@
|
|||||||
#include "mozilla/dom/NodeListBinding.h"
|
#include "mozilla/dom/NodeListBinding.h"
|
||||||
|
|
||||||
#include "nsStyledElement.h"
|
#include "nsStyledElement.h"
|
||||||
#include "nsXBLService.h"
|
|
||||||
#include "nsITextControlFrame.h"
|
#include "nsITextControlFrame.h"
|
||||||
#include "nsISupportsImpl.h"
|
#include "nsISupportsImpl.h"
|
||||||
#include "mozilla/dom/CSSPseudoElement.h"
|
#include "mozilla/dom/CSSPseudoElement.h"
|
||||||
@ -166,6 +161,10 @@
|
|||||||
|
|
||||||
#include "DOMMatrix.h"
|
#include "DOMMatrix.h"
|
||||||
|
|
||||||
|
#if defined(ACCESSIBILITY) && defined(DEBUG)
|
||||||
|
# include "nsAccessibilityService.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
using mozilla::gfx::Matrix4x4;
|
using mozilla::gfx::Matrix4x4;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
@ -255,9 +254,7 @@ Element::QueryInterface(REFNSIID aIID, void** aInstancePtr) {
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Give the binding manager a chance to get an interface for this element.
|
return NS_NOINTERFACE;
|
||||||
return OwnerDoc()->BindingManager()->GetBindingImplementation(this, aIID,
|
|
||||||
aInstancePtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EventStates Element::IntrinsicState() const {
|
EventStates Element::IntrinsicState() const {
|
||||||
@ -387,46 +384,6 @@ void Element::SetTabIndex(int32_t aTabIndex, mozilla::ErrorResult& aError) {
|
|||||||
SetAttr(nsGkAtoms::tabindex, value, 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) {
|
void Element::SetShadowRoot(ShadowRoot* aShadowRoot) {
|
||||||
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
|
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
|
||||||
slots->mShadowRoot = aShadowRoot;
|
slots->mShadowRoot = aShadowRoot;
|
||||||
@ -443,7 +400,7 @@ void Element::Blur(mozilla::ErrorResult& aError) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsPIDOMWindowOuter* win = doc->GetWindow();
|
nsPIDOMWindowOuter* win = doc->GetWindow();
|
||||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||||
if (win && fm) {
|
if (win && fm) {
|
||||||
aError = fm->ClearFocus(win);
|
aError = fm->ClearFocus(win);
|
||||||
}
|
}
|
||||||
@ -535,121 +492,6 @@ void Element::ClearStyleStateLocks() {
|
|||||||
NotifyStyleStateChange(locks.mLocks);
|
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 */
|
/* virtual */
|
||||||
nsINode* Element::GetScopeChainParent() const { return OwnerDoc(); }
|
nsINode* Element::GetScopeChainParent() const { return OwnerDoc(); }
|
||||||
|
|
||||||
@ -1165,7 +1007,7 @@ bool Element::CanAttachShadowDOM() const {
|
|||||||
* XUL elements.
|
* XUL elements.
|
||||||
*/
|
*/
|
||||||
if (!IsHTMLElement() &&
|
if (!IsHTMLElement() &&
|
||||||
!(XRE_IsParentProcess() && IsXULElement() &&
|
!(IsXULElement() &&
|
||||||
nsContentUtils::AllowXULXBLForPrincipal(NodePrincipal()))) {
|
nsContentUtils::AllowXULXBLForPrincipal(NodePrincipal()))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1238,7 +1080,7 @@ already_AddRefed<ShadowRoot> Element::AttachShadow(const ShadowRootInit& aInit,
|
|||||||
* 4. If context object is a shadow host, then throw
|
* 4. If context object is a shadow host, then throw
|
||||||
* an "NotSupportedError" DOMException.
|
* an "NotSupportedError" DOMException.
|
||||||
*/
|
*/
|
||||||
if (GetShadowRoot() || GetXBLBinding()) {
|
if (GetShadowRoot()) {
|
||||||
aError.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
aError.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -1259,12 +1101,19 @@ already_AddRefed<ShadowRoot> Element::AttachShadowWithoutNameChecks(
|
|||||||
nsGkAtoms::documentFragmentNodeName, nullptr, kNameSpaceID_None,
|
nsGkAtoms::documentFragmentNodeName, nullptr, kNameSpaceID_None,
|
||||||
DOCUMENT_FRAGMENT_NODE);
|
DOCUMENT_FRAGMENT_NODE);
|
||||||
|
|
||||||
if (Document* doc = GetComposedDoc()) {
|
// If there are no children, the flat tree is not changing due to the presence
|
||||||
if (PresShell* presShell = doc->GetPresShell()) {
|
// of the shadow root, so we don't need to invalidate style / layout.
|
||||||
presShell->DestroyFramesForAndRestyle(this);
|
//
|
||||||
|
// 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
|
* 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.
|
// only assert if our parent is _changing_ while we have a parent.
|
||||||
MOZ_ASSERT(!GetParentNode() || &aParent == GetParentNode(),
|
MOZ_ASSERT(!GetParentNode() || &aParent == GetParentNode(),
|
||||||
"Already have a parent. Unbind first!");
|
"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();
|
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()) {
|
if (aParent.IsInNativeAnonymousSubtree()) {
|
||||||
SetFlags(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE);
|
SetFlags(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE);
|
||||||
}
|
}
|
||||||
if (aParent.HasFlag(NODE_HAS_BEEN_IN_UA_WIDGET)) {
|
if (aParent.HasFlag(NODE_HAS_BEEN_IN_UA_WIDGET)) {
|
||||||
SetFlags(NODE_HAS_BEEN_IN_UA_WIDGET);
|
SetFlags(NODE_HAS_BEEN_IN_UA_WIDGET);
|
||||||
}
|
}
|
||||||
if (HasFlag(NODE_IS_ANONYMOUS_ROOT)) {
|
if (IsRootOfNativeAnonymousSubtree()) {
|
||||||
aParent.SetMayHaveAnonymousChildren();
|
aParent.SetMayHaveAnonymousChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1758,17 +1573,6 @@ nsresult Element::BindToTree(BindContext& aContext, nsINode& aParent) {
|
|||||||
|
|
||||||
UpdateEditableState(false);
|
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.
|
// Call BindToTree on shadow root children.
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
if (ShadowRoot* shadowRoot = GetShadowRoot()) {
|
if (ShadowRoot* shadowRoot = GetShadowRoot()) {
|
||||||
@ -1839,8 +1643,6 @@ nsresult Element::BindToTree(BindContext& aContext, nsINode& aParent) {
|
|||||||
MOZ_ASSERT(IsInComposedDoc() == aContext.InComposedDoc());
|
MOZ_ASSERT(IsInComposedDoc() == aContext.InComposedDoc());
|
||||||
MOZ_ASSERT(IsInUncomposedDoc() == aContext.InUncomposedDoc());
|
MOZ_ASSERT(IsInUncomposedDoc() == aContext.InUncomposedDoc());
|
||||||
MOZ_ASSERT(&aParent == GetParentNode(), "Bound to wrong parent node");
|
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.IsInUncomposedDoc() == IsInUncomposedDoc());
|
||||||
MOZ_ASSERT(aParent.IsInComposedDoc() == IsInComposedDoc());
|
MOZ_ASSERT(aParent.IsInComposedDoc() == IsInComposedDoc());
|
||||||
MOZ_ASSERT(aParent.IsInShadowTree() == IsInShadowTree());
|
MOZ_ASSERT(aParent.IsInShadowTree() == IsInShadowTree());
|
||||||
@ -1848,32 +1650,6 @@ nsresult Element::BindToTree(BindContext& aContext, nsINode& aParent) {
|
|||||||
return NS_OK;
|
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) {
|
bool WillDetachFromShadowOnUnbind(const Element& aElement, bool aNullParent) {
|
||||||
// If our parent still is in a shadow tree by now, and we're not removing
|
// 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
|
// 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...");
|
"propagated scrollbar styles) - that's dangerous...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifdef ACCESSIBILITY
|
||||||
|
MOZ_ASSERT(!GetAccService() || !GetAccService()->HasAccessible(this),
|
||||||
|
"An accessible for this element still exists!");
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Ensure that CSS transitions don't continue on an element at a
|
// 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());
|
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 (nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots()) {
|
||||||
if (clearBindingParent) {
|
|
||||||
slots->mBindingParent = nullptr;
|
|
||||||
}
|
|
||||||
if (aNullParent || !mParent->IsInShadowTree()) {
|
if (aNullParent || !mParent->IsInShadowTree()) {
|
||||||
slots->mContainingShadow = nullptr;
|
slots->mContainingShadow = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document) {
|
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 must be enqueued whenever a connected custom element becomes
|
||||||
// disconnected.
|
// disconnected.
|
||||||
CustomElementData* data = GetCustomElementData();
|
CustomElementData* data = GetCustomElementData();
|
||||||
@ -2553,13 +2306,6 @@ nsresult Element::SetAttrAndNotify(
|
|||||||
oldValue = aOldValue;
|
oldValue = aOldValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aComposedDocument) {
|
|
||||||
RefPtr<nsXBLBinding> binding = GetXBLBinding();
|
|
||||||
if (binding) {
|
|
||||||
binding->AttributeChanged(aName, aNamespaceID, false, aNotify);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HasElementCreatedFromPrototypeAndHasUnmodifiedL10n() &&
|
if (HasElementCreatedFromPrototypeAndHasUnmodifiedL10n() &&
|
||||||
aNamespaceID == kNameSpaceID_None &&
|
aNamespaceID == kNameSpaceID_None &&
|
||||||
(aName == nsGkAtoms::datal10nid || aName == nsGkAtoms::datal10nargs)) {
|
(aName == nsGkAtoms::datal10nid || aName == nsGkAtoms::datal10nargs)) {
|
||||||
@ -2874,13 +2620,6 @@ nsresult Element::UnsetAttr(int32_t aNameSpaceID, nsAtom* aName, bool aNotify) {
|
|||||||
|
|
||||||
PostIdMaybeChange(aNameSpaceID, aName, nullptr);
|
PostIdMaybeChange(aNameSpaceID, aName, nullptr);
|
||||||
|
|
||||||
if (document) {
|
|
||||||
RefPtr<nsXBLBinding> binding = GetXBLBinding();
|
|
||||||
if (binding) {
|
|
||||||
binding->AttributeChanged(aName, aNameSpaceID, true, aNotify);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const CustomElementData* data = GetCustomElementData();
|
const CustomElementData* data = GetCustomElementData();
|
||||||
if (data && data->mState == CustomElementData::State::eCustom) {
|
if (data && data->mState == CustomElementData::State::eCustom) {
|
||||||
CustomElementDefinition* definition = data->GetCustomElementDefinition();
|
CustomElementDefinition* definition = data->GetCustomElementDefinition();
|
||||||
@ -3004,51 +2743,6 @@ void Element::List(FILE* out, int32_t aIndent, const nsCString& aPrefix) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fputs(">\n", out);
|
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 {
|
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;
|
aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
|
||||||
|
|
||||||
if (IsInComposedDoc()) {
|
if (IsInComposedDoc()) {
|
||||||
if (nsIFocusManager* fm = nsFocusManager::GetFocusManager()) {
|
if (nsFocusManager* fm = nsFocusManager::GetFocusManager()) {
|
||||||
RefPtr<Element> kungFuDeathGrip(this);
|
RefPtr<Element> kungFuDeathGrip(this);
|
||||||
fm->SetFocus(kungFuDeathGrip, nsIFocusManager::FLAG_BYMOUSE |
|
fm->SetFocus(kungFuDeathGrip, nsIFocusManager::FLAG_BYMOUSE |
|
||||||
nsIFocusManager::FLAG_NOSCROLL);
|
nsIFocusManager::FLAG_NOSCROLL);
|
||||||
@ -4099,11 +3793,6 @@ void Element::GetCustomInterface(nsGetterAddRefs<T> aResult) {
|
|||||||
return;
|
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) {
|
void Element::ClearServoData(Document* aDoc) {
|
||||||
|
@ -222,22 +222,6 @@ class Element : public FragmentOrElement {
|
|||||||
*/
|
*/
|
||||||
void SetTabIndex(int32_t aTabIndex, mozilla::ErrorResult& aError);
|
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
|
* Sets the ShadowRoot binding for this element. The contents of the
|
||||||
* binding is rendered in place of this node's children.
|
* 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;
|
Directionality GetComputedDirectionality() const;
|
||||||
|
|
||||||
static const uint32_t kAllServoDescendantBits =
|
static const uint32_t kAllServoDescendantBits =
|
||||||
@ -1444,8 +1426,6 @@ class Element : public FragmentOrElement {
|
|||||||
*/
|
*/
|
||||||
static CORSMode AttrValueToCORSMode(const nsAttrValue* aValue);
|
static CORSMode AttrValueToCORSMode(const nsAttrValue* aValue);
|
||||||
|
|
||||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
|
|
||||||
|
|
||||||
nsINode* GetScopeChainParent() const override;
|
nsINode* GetScopeChainParent() const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1914,20 +1894,6 @@ class Element : public FragmentOrElement {
|
|||||||
AttrArray mAttrs;
|
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)
|
NS_DEFINE_STATIC_IID_ACCESSOR(Element, NS_ELEMENT_IID)
|
||||||
|
|
||||||
inline bool Element::HasAttr(int32_t aNameSpaceID, const nsAtom* aName) const {
|
inline bool Element::HasAttr(int32_t aNameSpaceID, const nsAtom* aName) const {
|
||||||
|
@ -49,7 +49,6 @@
|
|||||||
#include "nsNameSpaceManager.h"
|
#include "nsNameSpaceManager.h"
|
||||||
#include "nsContentList.h"
|
#include "nsContentList.h"
|
||||||
#include "nsDOMTokenList.h"
|
#include "nsDOMTokenList.h"
|
||||||
#include "nsXBLPrototypeBinding.h"
|
|
||||||
#include "nsError.h"
|
#include "nsError.h"
|
||||||
#include "nsDOMString.h"
|
#include "nsDOMString.h"
|
||||||
#include "mozilla/InternalMutationEvent.h"
|
#include "mozilla/InternalMutationEvent.h"
|
||||||
@ -64,11 +63,8 @@
|
|||||||
# include "nsRange.h"
|
# include "nsRange.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "nsBindingManager.h"
|
|
||||||
#include "nsFrameLoader.h"
|
#include "nsFrameLoader.h"
|
||||||
#include "nsXBLBinding.h"
|
|
||||||
#include "nsPIDOMWindow.h"
|
#include "nsPIDOMWindow.h"
|
||||||
#include "nsPIBoxObject.h"
|
|
||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
#include "nsGkAtoms.h"
|
#include "nsGkAtoms.h"
|
||||||
#include "nsContentUtils.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 {
|
nsIContent* nsIContent::FindFirstNonChromeOnlyAccessContent() const {
|
||||||
// This handles also nested native anonymous content.
|
// This handles also nested native anonymous content.
|
||||||
for (const nsIContent* content = this; content;
|
for (const nsIContent* content = this; content;
|
||||||
content = content->GetBindingParent()) {
|
content = content->GetChromeOnlyAccessSubtreeRootParent()) {
|
||||||
if (!content->ChromeOnlyAccess()) {
|
if (!content->ChromeOnlyAccess()) {
|
||||||
// Oops, this function signature allows casting const to
|
// Oops, this function signature allows casting const to
|
||||||
// non-const. (Then again, so does
|
// non-const. (Then again, so does GetFirstChild()->GetParent().)
|
||||||
// GetChildAt_Deprecated(0)->GetParent().)
|
|
||||||
return const_cast<nsIContent*>(content);
|
return const_cast<nsIContent*>(content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -522,28 +517,20 @@ static_assert(sizeof(FragmentOrElement::nsDOMSlots) <= MaxDOMSlotSizeAllowed,
|
|||||||
"DOM slots cannot be grown without consideration");
|
"DOM slots cannot be grown without consideration");
|
||||||
|
|
||||||
void nsIContent::nsExtendedContentSlots::UnlinkExtendedSlots() {
|
void nsIContent::nsExtendedContentSlots::UnlinkExtendedSlots() {
|
||||||
mBindingParent = nullptr;
|
|
||||||
mXBLInsertionPoint = nullptr;
|
|
||||||
mContainingShadow = nullptr;
|
mContainingShadow = nullptr;
|
||||||
mAssignedSlot = nullptr;
|
mAssignedSlot = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsIContent::nsExtendedContentSlots::TraverseExtendedSlots(
|
void nsIContent::nsExtendedContentSlots::TraverseExtendedSlots(
|
||||||
nsCycleCollectionTraversalCallback& aCb) {
|
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");
|
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mContainingShadow");
|
||||||
aCb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mContainingShadow));
|
aCb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mContainingShadow));
|
||||||
|
|
||||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mAssignedSlot");
|
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mAssignedSlot");
|
||||||
aCb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mAssignedSlot.get()));
|
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;
|
nsIContent::nsExtendedContentSlots::~nsExtendedContentSlots() = default;
|
||||||
|
|
||||||
@ -629,13 +616,12 @@ size_t FragmentOrElement::nsDOMSlots::SizeOfIncludingThis(
|
|||||||
|
|
||||||
// The following member are not measured:
|
// The following member are not measured:
|
||||||
// - mControllers: because it is non-owning
|
// - mControllers: because it is non-owning
|
||||||
// - mBindingParent: because it is some ancestor element.
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
FragmentOrElement::nsExtendedDOMSlots::nsExtendedDOMSlots() = default;
|
FragmentOrElement::nsExtendedDOMSlots::nsExtendedDOMSlots() = default;
|
||||||
|
|
||||||
FragmentOrElement::nsExtendedDOMSlots::~nsExtendedDOMSlots() {}
|
FragmentOrElement::nsExtendedDOMSlots::~nsExtendedDOMSlots() = default;
|
||||||
|
|
||||||
void FragmentOrElement::nsExtendedDOMSlots::UnlinkExtendedSlots() {
|
void FragmentOrElement::nsExtendedDOMSlots::UnlinkExtendedSlots() {
|
||||||
nsIContent::nsExtendedContentSlots::UnlinkExtendedSlots();
|
nsIContent::nsExtendedContentSlots::UnlinkExtendedSlots();
|
||||||
@ -670,10 +656,6 @@ void FragmentOrElement::nsExtendedDOMSlots::TraverseExtendedSlots(
|
|||||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mShadowRoot");
|
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mShadowRoot");
|
||||||
aCb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, 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) {
|
if (mCustomElementData) {
|
||||||
mCustomElementData->Traverse(aCb);
|
mCustomElementData->Traverse(aCb);
|
||||||
}
|
}
|
||||||
@ -707,12 +689,6 @@ size_t FragmentOrElement::nsExtendedDOMSlots::SizeOfExcludingThis(
|
|||||||
// mShadowRoot should be handled during normal DOM tree memory reporting, just
|
// mShadowRoot should be handled during normal DOM tree memory reporting, just
|
||||||
// like kids, siblings, etc.
|
// 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) {
|
if (mCustomElementData) {
|
||||||
n += mCustomElementData->SizeOfIncludingThis(aMallocSizeOf);
|
n += mCustomElementData->SizeOfIncludingThis(aMallocSizeOf);
|
||||||
}
|
}
|
||||||
@ -878,23 +854,12 @@ void nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
|
|||||||
aVisitor.mEventTargetAtParent = parent;
|
aVisitor.mEventTargetAtParent = parent;
|
||||||
} else if (parent && aVisitor.mOriginalTargetIsInAnon) {
|
} else if (parent && aVisitor.mOriginalTargetIsInAnon) {
|
||||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aVisitor.mEvent->mTarget));
|
nsCOMPtr<nsIContent> content(do_QueryInterface(aVisitor.mEvent->mTarget));
|
||||||
if (content && content->GetBindingParent() == parent) {
|
if (content &&
|
||||||
|
content->GetClosestNativeAnonymousSubtreeRootParent() == parent) {
|
||||||
aVisitor.mEventTargetAtParent = 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 &&
|
if (!aVisitor.mEvent->mFlags.mComposedInNativeAnonymousContent &&
|
||||||
IsRootOfNativeAnonymousSubtree() && OwnerDoc()->GetWindow()) {
|
IsRootOfNativeAnonymousSubtree() && OwnerDoc()->GetWindow()) {
|
||||||
aVisitor.SetParentTarget(OwnerDoc()->GetWindow()->GetParentTarget(), true);
|
aVisitor.SetParentTarget(OwnerDoc()->GetWindow()->GetParentTarget(), true);
|
||||||
@ -1067,58 +1032,11 @@ bool FragmentOrElement::IsLink(nsIURI** aURI) const {
|
|||||||
return false;
|
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) {
|
void nsIContent::SetAssignedSlot(HTMLSlotElement* aSlot) {
|
||||||
MOZ_ASSERT(aSlot || GetExistingExtendedContentSlots());
|
MOZ_ASSERT(aSlot || GetExistingExtendedContentSlots());
|
||||||
ExtendedContentSlots()->mAssignedSlot = aSlot;
|
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,
|
void FragmentOrElement::GetTextContentInternal(nsAString& aTextContent,
|
||||||
OOMReporter& aError) {
|
OOMReporter& aError) {
|
||||||
if (!nsContentUtils::GetNodeTextContent(this, true, aTextContent, fallible)) {
|
if (!nsContentUtils::GetNodeTextContent(this, true, aTextContent, fallible)) {
|
||||||
@ -1143,12 +1061,6 @@ void FragmentOrElement::DestroyContent() {
|
|||||||
AsElement()->ClearServoData();
|
AsElement()->ClearServoData();
|
||||||
}
|
}
|
||||||
|
|
||||||
Document* document = OwnerDoc();
|
|
||||||
|
|
||||||
document->BindingManager()->RemovedFromDocument(this, document,
|
|
||||||
nsBindingManager::eRunDtor);
|
|
||||||
document->ClearBoxObjectFor(this);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
uint32_t oldChildCount = GetChildCount();
|
uint32_t oldChildCount = GetChildCount();
|
||||||
#endif
|
#endif
|
||||||
@ -1354,9 +1266,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FragmentOrElement)
|
|||||||
tmp->ExtendedDOMSlots()->mShadowRoot = nullptr;
|
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_UNLINK_END
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(FragmentOrElement)
|
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(FragmentOrElement)
|
||||||
@ -1581,10 +1490,6 @@ bool NodeHasActiveFrame(Document* aCurrentDoc, nsINode* aNode) {
|
|||||||
aNode->AsElement()->GetPrimaryFrame();
|
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
|
// 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
|
// 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
|
// 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();
|
bool unoptimizable = aNode->UnoptimizableCCNode();
|
||||||
Document* currentDoc = aNode->GetComposedDoc();
|
Document* currentDoc = aNode->GetComposedDoc();
|
||||||
if (currentDoc && IsCertainlyAliveNode(aNode, currentDoc) &&
|
if (currentDoc && IsCertainlyAliveNode(aNode, currentDoc) &&
|
||||||
(!unoptimizable || NodeHasActiveFrame(currentDoc, aNode) ||
|
(!unoptimizable || NodeHasActiveFrame(currentDoc, aNode))) {
|
||||||
OwnedByBindingManager(currentDoc, aNode))) {
|
|
||||||
MarkNodeChildren(aNode);
|
MarkNodeChildren(aNode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1779,10 +1683,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(FragmentOrElement)
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsAutoCString orphan;
|
nsAutoCString orphan;
|
||||||
if (!tmp->IsInComposedDoc() &&
|
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)) {
|
|
||||||
orphan.AppendLiteral(" (orphan)");
|
orphan.AppendLiteral(" (orphan)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1800,8 +1701,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(FragmentOrElement)
|
|||||||
return NS_SUCCESS_INTERRUPTED_TRAVERSE;
|
return NS_SUCCESS_INTERRUPTED_TRAVERSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp->OwnerDoc()->BindingManager()->Traverse(tmp, cb);
|
|
||||||
|
|
||||||
// Check that whenever we have effect properties, MayHaveAnimations is set.
|
// Check that whenever we have effect properties, MayHaveAnimations is set.
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
nsAtom** effectProps = EffectSet::GetEffectSetPropertyAtoms();
|
nsAtom** effectProps = EffectSet::GetEffectSetPropertyAtoms();
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include "nsIContent.h" // base class
|
#include "nsIContent.h" // base class
|
||||||
#include "nsIHTMLCollection.h"
|
#include "nsIHTMLCollection.h"
|
||||||
#include "nsDataHashtable.h"
|
#include "nsDataHashtable.h"
|
||||||
#include "nsXBLBinding.h"
|
|
||||||
|
|
||||||
class ContentUnbinder;
|
class ContentUnbinder;
|
||||||
class nsContentList;
|
class nsContentList;
|
||||||
@ -97,7 +96,6 @@ class FragmentOrElement : public nsIContent {
|
|||||||
virtual uint32_t TextLength() const override;
|
virtual uint32_t TextLength() const override;
|
||||||
virtual bool TextIsOnlyWhitespace() override;
|
virtual bool TextIsOnlyWhitespace() override;
|
||||||
virtual bool ThreadSafeTextIsOnlyWhitespace() const override;
|
virtual bool ThreadSafeTextIsOnlyWhitespace() const override;
|
||||||
virtual nsXBLBinding* DoGetXBLBinding() const override;
|
|
||||||
virtual bool IsLink(nsIURI** aURI) const override;
|
virtual bool IsLink(nsIURI** aURI) const override;
|
||||||
|
|
||||||
virtual void DestroyContent() override;
|
virtual void DestroyContent() override;
|
||||||
@ -185,11 +183,6 @@ class FragmentOrElement : public nsIContent {
|
|||||||
*/
|
*/
|
||||||
RefPtr<ShadowRoot> mShadowRoot;
|
RefPtr<ShadowRoot> mShadowRoot;
|
||||||
|
|
||||||
/**
|
|
||||||
* XBL binding installed on the element.
|
|
||||||
*/
|
|
||||||
RefPtr<nsXBLBinding> mXBLBinding;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Web components custom element data.
|
* Web components custom element data.
|
||||||
*/
|
*/
|
||||||
|
@ -88,7 +88,7 @@ class FullscreenRequest : public FullscreenChange {
|
|||||||
dom::CallerType::NonSystem, false));
|
dom::CallerType::NonSystem, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
~FullscreenRequest() { MOZ_COUNT_DTOR(FullscreenRequest); }
|
MOZ_COUNTED_DTOR(FullscreenRequest)
|
||||||
|
|
||||||
dom::Element* Element() const { return mElement; }
|
dom::Element* Element() const { return mElement; }
|
||||||
|
|
||||||
|
@ -8,9 +8,7 @@
|
|||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsIURI.h"
|
#include "nsIURI.h"
|
||||||
#include "nsIReferrerInfo.h"
|
#include "nsIReferrerInfo.h"
|
||||||
#include "nsBindingManager.h"
|
|
||||||
#include "nsEscape.h"
|
#include "nsEscape.h"
|
||||||
#include "nsXBLPrototypeBinding.h"
|
|
||||||
#include "nsCycleCollectionParticipant.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
@ -57,52 +55,19 @@ void IDTracker::ResetToURIFragmentID(nsIContent* aFromContent, nsIURI* aURI,
|
|||||||
if (NS_FAILED(rv) || ref.IsEmpty()) {
|
if (NS_FAILED(rv) || ref.IsEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rv = NS_OK;
|
|
||||||
|
|
||||||
nsIContent* bindingParent = aFromContent->GetBindingParent();
|
if (aFromContent->IsInNativeAnonymousSubtree()) {
|
||||||
if (bindingParent && !aFromContent->IsInShadowTree()) {
|
// This happens, for example, if aFromContent is part of the content
|
||||||
nsXBLBinding* binding = bindingParent->GetXBLBinding();
|
// inserted by a call to Document::InsertAnonymousContent, which we
|
||||||
if (!binding) {
|
// also want to handle. (It also happens for other native anonymous content
|
||||||
// This happens, for example, if aFromContent is part of the content
|
// etc.)
|
||||||
// inserted by a call to Document::InsertAnonymousContent, which we
|
Element* anonRoot =
|
||||||
// also want to handle. (It also happens for <use>'s anonymous
|
doc->GetAnonRootIfInAnonymousContentContainer(aFromContent);
|
||||||
// content etc.)
|
if (anonRoot) {
|
||||||
Element* anonRoot =
|
mElement = nsContentUtils::MatchElementId(anonRoot, ref);
|
||||||
doc->GetAnonRootIfInAnonymousContentContainer(aFromContent);
|
// We don't have watching working yet for anonymous content, so bail out
|
||||||
if (anonRoot) {
|
// here.
|
||||||
mElement = nsContentUtils::MatchElementId(anonRoot, ref);
|
return;
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ Location::Location(nsPIDOMWindowInner* aWindow, nsIDocShell* aDocShell)
|
|||||||
mDocShell = do_GetWeakReference(aDocShell);
|
mDocShell = do_GetWeakReference(aDocShell);
|
||||||
}
|
}
|
||||||
|
|
||||||
Location::~Location() {}
|
Location::~Location() = default;
|
||||||
|
|
||||||
// QueryInterface implementation for Location
|
// QueryInterface implementation for Location
|
||||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Location)
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Location)
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
#ifdef MOZ_XUL
|
#ifdef MOZ_XUL
|
||||||
# include "nsXULElement.h"
|
# include "nsXULElement.h"
|
||||||
#endif
|
#endif
|
||||||
#include "nsBindingManager.h"
|
|
||||||
#include "nsGenericHTMLElement.h"
|
#include "nsGenericHTMLElement.h"
|
||||||
#include "mozilla/AnimationTarget.h"
|
#include "mozilla/AnimationTarget.h"
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
@ -51,6 +50,10 @@ enum class IsRemoveNotification {
|
|||||||
# define COMPOSED_DOC_DECL
|
# define COMPOSED_DOC_DECL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define CALL_BINDING_MANAGER(func_, params_) \
|
||||||
|
do { \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
// This macro expects the ownerDocument of content_ to be in scope as
|
// This macro expects the ownerDocument of content_ to be in scope as
|
||||||
// |Document* doc|
|
// |Document* doc|
|
||||||
#define IMPL_MUTATION_NOTIFICATION(func_, content_, params_, remove_) \
|
#define IMPL_MUTATION_NOTIFICATION(func_, content_, params_, remove_) \
|
||||||
@ -67,7 +70,7 @@ enum class IsRemoveNotification {
|
|||||||
presShell->func_ params_; \
|
presShell->func_ params_; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
doc->BindingManager()->func_ params_; \
|
CALL_BINDING_MANAGER(func_, params_); \
|
||||||
nsINode* last; \
|
nsINode* last; \
|
||||||
do { \
|
do { \
|
||||||
nsINode::nsSlots* slots = node->GetExistingSlots(); \
|
nsINode::nsSlots* slots = node->GetExistingSlots(); \
|
||||||
|
@ -19,13 +19,12 @@ static const int32_t kNameSpaceID_None = 0;
|
|||||||
#define kNameSpaceID_XHTML 3
|
#define kNameSpaceID_XHTML 3
|
||||||
#define kNameSpaceID_XLink 4
|
#define kNameSpaceID_XLink 4
|
||||||
#define kNameSpaceID_XSLT 5
|
#define kNameSpaceID_XSLT 5
|
||||||
#define kNameSpaceID_XBL 6
|
#define kNameSpaceID_MathML 6
|
||||||
#define kNameSpaceID_MathML 7
|
#define kNameSpaceID_RDF 7
|
||||||
#define kNameSpaceID_RDF 8
|
#define kNameSpaceID_XUL 8
|
||||||
#define kNameSpaceID_XUL 9
|
#define kNameSpaceID_SVG 9
|
||||||
#define kNameSpaceID_SVG 10
|
#define kNameSpaceID_disabled_MathML 10
|
||||||
#define kNameSpaceID_disabled_MathML 11
|
#define kNameSpaceID_disabled_SVG 11
|
||||||
#define kNameSpaceID_disabled_SVG 12
|
#define kNameSpaceID_LastBuiltin 11 // last 'built-in' namespace
|
||||||
#define kNameSpaceID_LastBuiltin 12 // last 'built-in' namespace
|
|
||||||
|
|
||||||
#endif // mozilla_dom_NameSpaceConstants_h__
|
#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 {
|
virtual const PlacesBookmarkAddition* AsPlacesBookmarkAddition() const {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
virtual const PlacesBookmarkRemoved* AsPlacesBookmarkRemoved() const {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~PlacesEvent() = default;
|
virtual ~PlacesEvent() = default;
|
||||||
|
@ -46,7 +46,7 @@ PostMessageEvent::PostMessageEvent(BrowsingContext* aSource,
|
|||||||
mCallerDocumentURI(aCallerDocumentURI),
|
mCallerDocumentURI(aCallerDocumentURI),
|
||||||
mIsFromPrivateWindow(aIsFromPrivateWindow) {}
|
mIsFromPrivateWindow(aIsFromPrivateWindow) {}
|
||||||
|
|
||||||
PostMessageEvent::~PostMessageEvent() {}
|
PostMessageEvent::~PostMessageEvent() = default;
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
PostMessageEvent::Run() {
|
PostMessageEvent::Run() {
|
||||||
|
@ -36,13 +36,15 @@ nsINode* RangeUtils::ComputeRootNode(nsINode* aNode) {
|
|||||||
nsIContent* content = aNode->AsContent();
|
nsIContent* content = aNode->AsContent();
|
||||||
|
|
||||||
// If the node is in a shadow tree then the ShadowRoot is the root.
|
// 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()) {
|
if (ShadowRoot* containingShadow = content->GetContainingShadow()) {
|
||||||
return containingShadow;
|
return containingShadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the node has a binding parent, that should be the root.
|
// If the node is in NAC, then the NAC parent should be the root.
|
||||||
// XXXbz maybe only for native anonymous content?
|
if (nsINode* root = content->GetClosestNativeAnonymousSubtreeRootParent()) {
|
||||||
if (nsINode* root = content->GetBindingParent()) {
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2816,7 +2816,7 @@ nsIFrame* Selection::GetSelectionAnchorGeometry(SelectionRegion aRegion,
|
|||||||
// make focusRect relative to anchorFrame
|
// make focusRect relative to anchorFrame
|
||||||
focusRect += focusFrame->GetOffsetTo(anchorFrame);
|
focusRect += focusFrame->GetOffsetTo(anchorFrame);
|
||||||
|
|
||||||
aRect->UnionRectEdges(anchorRect, focusRect);
|
*aRect = anchorRect.UnionEdges(focusRect);
|
||||||
return anchorFrame;
|
return anchorFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include "ChildIterator.h"
|
#include "ChildIterator.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsWindowSizes.h"
|
#include "nsWindowSizes.h"
|
||||||
#include "nsXBLPrototypeBinding.h"
|
|
||||||
#include "mozilla/dom/DirectionalityUtils.h"
|
#include "mozilla/dom/DirectionalityUtils.h"
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
#include "mozilla/dom/HTMLSlotElement.h"
|
#include "mozilla/dom/HTMLSlotElement.h"
|
||||||
@ -60,7 +59,6 @@ ShadowRoot::ShadowRoot(Element* aElement, ShadowRootMode aMode,
|
|||||||
SetFlags(NODE_IS_IN_SHADOW_TREE);
|
SetFlags(NODE_IS_IN_SHADOW_TREE);
|
||||||
Bind();
|
Bind();
|
||||||
|
|
||||||
ExtendedDOMSlots()->mBindingParent = aElement;
|
|
||||||
ExtendedDOMSlots()->mContainingShadow = this;
|
ExtendedDOMSlots()->mContainingShadow = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,8 +87,8 @@ void ShadowRoot::AddSizeOfExcludingThis(nsWindowSizes& aSizes,
|
|||||||
ShadowRootAuthorStylesMallocEnclosingSizeOf, mServoStyles.get());
|
ShadowRootAuthorStylesMallocEnclosingSizeOf, mServoStyles.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
JSObject* ShadowRoot::WrapObject(JSContext* aCx,
|
JSObject* ShadowRoot::WrapNode(JSContext* aCx,
|
||||||
JS::Handle<JSObject*> aGivenProto) {
|
JS::Handle<JSObject*> aGivenProto) {
|
||||||
return mozilla::dom::ShadowRoot_Binding::Wrap(aCx, this, aGivenProto);
|
return mozilla::dom::ShadowRoot_Binding::Wrap(aCx, this, aGivenProto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -521,7 +519,7 @@ void ShadowRoot::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
|
|||||||
aVisitor.SetParentTarget(shadowHost, false);
|
aVisitor.SetParentTarget(shadowHost, false);
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aVisitor.mEvent->mTarget));
|
nsCOMPtr<nsIContent> content(do_QueryInterface(aVisitor.mEvent->mTarget));
|
||||||
if (content && content->GetBindingParent() == shadowHost) {
|
if (content && content->GetContainingShadow() == this) {
|
||||||
aVisitor.mEventTargetAtParent = shadowHost;
|
aVisitor.mEventTargetAtParent = shadowHost;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -667,7 +665,7 @@ void ShadowRoot::MaybeUnslotHostChild(nsIContent& aChild) {
|
|||||||
"How did aChild end up assigned to a slot?");
|
"How did aChild end up assigned to a slot?");
|
||||||
// If the slot is going to start showing fallback content, we need to tell
|
// If the slot is going to start showing fallback content, we need to tell
|
||||||
// layout about it.
|
// layout about it.
|
||||||
if (slot->AssignedNodes().Length() == 1) {
|
if (slot->AssignedNodes().Length() == 1 && slot->HasChildren()) {
|
||||||
InvalidateStyleAndLayoutOnSubtree(slot);
|
InvalidateStyleAndLayoutOnSubtree(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -693,7 +691,8 @@ void ShadowRoot::MaybeSlotHostChild(nsIContent& aChild) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fallback content will go away, let layout know.
|
// Fallback content will go away, let layout know.
|
||||||
if (assignment.mSlot->AssignedNodes().IsEmpty()) {
|
if (assignment.mSlot->AssignedNodes().IsEmpty() &&
|
||||||
|
assignment.mSlot->HasChildren()) {
|
||||||
InvalidateStyleAndLayoutOnSubtree(assignment.mSlot);
|
InvalidateStyleAndLayoutOnSubtree(assignment.mSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,6 +151,10 @@ class ShadowRoot final : public DocumentFragment,
|
|||||||
void AddSlot(HTMLSlotElement* aSlot);
|
void AddSlot(HTMLSlotElement* aSlot);
|
||||||
void RemoveSlot(HTMLSlotElement* aSlot);
|
void RemoveSlot(HTMLSlotElement* aSlot);
|
||||||
bool HasSlots() const { return !mSlotMap.IsEmpty(); };
|
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 PartAdded(const Element&);
|
||||||
void PartRemoved(const Element&);
|
void PartRemoved(const Element&);
|
||||||
@ -167,8 +171,7 @@ class ShadowRoot final : public DocumentFragment,
|
|||||||
|
|
||||||
mozilla::ServoStyleRuleMap& ServoStyleRuleMap();
|
mozilla::ServoStyleRuleMap& ServoStyleRuleMap();
|
||||||
|
|
||||||
JSObject* WrapObject(JSContext* aCx,
|
JSObject* WrapNode(JSContext*, JS::Handle<JSObject*> aGivenProto) final;
|
||||||
JS::Handle<JSObject*> aGivenProto) override;
|
|
||||||
|
|
||||||
void NodeInfoChanged(Document* aOldDoc) override {
|
void NodeInfoChanged(Document* aOldDoc) override {
|
||||||
DocumentFragment::NodeInfoChanged(aOldDoc);
|
DocumentFragment::NodeInfoChanged(aOldDoc);
|
||||||
|
@ -86,15 +86,6 @@ void Text::GetWholeText(nsAString& aWholeText, ErrorResult& aRv) {
|
|||||||
return;
|
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* first = FirstLogicallyAdjacentTextNode(this);
|
||||||
Text* last = LastLogicallyAdjacentTextNode(this);
|
Text* last = LastLogicallyAdjacentTextNode(this);
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ class TimeoutHandler : public nsISupports {
|
|||||||
TimeoutHandler() : mFileName(""), mLineNo(0), mColumn(0) {}
|
TimeoutHandler() : mFileName(""), mLineNo(0), mColumn(0) {}
|
||||||
explicit TimeoutHandler(JSContext* aCx);
|
explicit TimeoutHandler(JSContext* aCx);
|
||||||
|
|
||||||
virtual ~TimeoutHandler() {}
|
virtual ~TimeoutHandler() = default;
|
||||||
|
|
||||||
// filename, line number and JS language version string of the
|
// filename, line number and JS language version string of the
|
||||||
// caller of setTimeout()
|
// caller of setTimeout()
|
||||||
@ -60,7 +60,7 @@ class ScriptTimeoutHandler : public TimeoutHandler {
|
|||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~ScriptTimeoutHandler() {}
|
virtual ~ScriptTimeoutHandler() = default;
|
||||||
|
|
||||||
nsCOMPtr<nsIGlobalObject> mGlobal;
|
nsCOMPtr<nsIGlobalObject> mGlobal;
|
||||||
// The expression to evaluate or function to call. If mFunction is non-null
|
// The expression to evaluate or function to call. If mFunction is non-null
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="import" href="1027461-inner.xul">
|
<link rel="import" href="1027461-inner.xhtml">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
</body>
|
</body>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
<iframe id="iframe" src="1370968-inner.xul"></iframe>
|
<iframe id="iframe" src="1370968-inner.xhtml"></iframe>
|
||||||
<script>
|
<script>
|
||||||
var io = new IntersectionObserver(function () {
|
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);
|
setTimeout('document.documentElement.className = ""', 500);
|
||||||
</script>
|
</script>
|
||||||
<body>
|
<body>
|
||||||
<iframe src="384663-1-inner.xul"></iframe>
|
<iframe src="384663-1-inner.xhtml"></iframe>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -7,7 +7,6 @@ load 231475-1.html
|
|||||||
load 244933-1.html
|
load 244933-1.html
|
||||||
load 275912-1.html
|
load 275912-1.html
|
||||||
load 293388-1.html
|
load 293388-1.html
|
||||||
load 308120-1.xul
|
|
||||||
load 325730-1.html
|
load 325730-1.html
|
||||||
load 326618-1.html
|
load 326618-1.html
|
||||||
load 326646-1.html
|
load 326646-1.html
|
||||||
@ -16,7 +15,6 @@ load 327571-1.html
|
|||||||
load 327694.html
|
load 327694.html
|
||||||
load 327695-1.html
|
load 327695-1.html
|
||||||
load 329481-1.xhtml
|
load 329481-1.xhtml
|
||||||
load 330925-1.xhtml
|
|
||||||
load 336381-1.xhtml
|
load 336381-1.xhtml
|
||||||
load 336715-1.xhtml
|
load 336715-1.xhtml
|
||||||
load 338391-1.xhtml
|
load 338391-1.xhtml
|
||||||
@ -204,9 +202,9 @@ load 1326194-2.html
|
|||||||
load 1332939.html
|
load 1332939.html
|
||||||
load 1341693.html
|
load 1341693.html
|
||||||
load 1352453.html
|
load 1352453.html
|
||||||
load 1353529.xul
|
load chrome://reftest/content/crashtests/dom/base/crashtests/1353529.xhtml
|
||||||
load 1368327.html
|
load 1368327.html
|
||||||
load 1369363.xul
|
load chrome://reftest/content/crashtests/dom/base/crashtests/1369363.xhtml
|
||||||
load 1370072.html
|
load 1370072.html
|
||||||
pref(clipboard.autocopy,true) load 1370737.html
|
pref(clipboard.autocopy,true) load 1370737.html
|
||||||
load 1370968.html
|
load 1370968.html
|
||||||
|
@ -210,6 +210,7 @@ EXPORTS.mozilla.dom += [
|
|||||||
'ParentProcessMessageManager.h',
|
'ParentProcessMessageManager.h',
|
||||||
'PlacesBookmark.h',
|
'PlacesBookmark.h',
|
||||||
'PlacesBookmarkAddition.h',
|
'PlacesBookmarkAddition.h',
|
||||||
|
'PlacesBookmarkRemoved.h',
|
||||||
'PlacesEvent.h',
|
'PlacesEvent.h',
|
||||||
'PlacesObservers.h',
|
'PlacesObservers.h',
|
||||||
'PlacesVisit.h',
|
'PlacesVisit.h',
|
||||||
@ -501,7 +502,6 @@ LOCAL_INCLUDES += [
|
|||||||
'/dom/storage',
|
'/dom/storage',
|
||||||
'/dom/svg',
|
'/dom/svg',
|
||||||
'/dom/u2f',
|
'/dom/u2f',
|
||||||
'/dom/xbl',
|
|
||||||
'/dom/xml',
|
'/dom/xml',
|
||||||
'/dom/xslt/xpath',
|
'/dom/xslt/xpath',
|
||||||
'/dom/xul',
|
'/dom/xul',
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "nsIContentViewer.h"
|
#include "nsIContentViewer.h"
|
||||||
#include "mozilla/dom/Document.h"
|
#include "mozilla/dom/Document.h"
|
||||||
#include "XULDocument.h"
|
|
||||||
#include "InProcessBrowserChildMessageManager.h"
|
#include "InProcessBrowserChildMessageManager.h"
|
||||||
#include "nsIWindowMediator.h"
|
#include "nsIWindowMediator.h"
|
||||||
#include "nsPIDOMWindow.h"
|
#include "nsPIDOMWindow.h"
|
||||||
@ -17,7 +16,7 @@
|
|||||||
#include "nsISHEntry.h"
|
#include "nsISHEntry.h"
|
||||||
#include "nsIWindowWatcher.h"
|
#include "nsIWindowWatcher.h"
|
||||||
#include "mozilla/Services.h"
|
#include "mozilla/Services.h"
|
||||||
#include "nsIXULWindow.h"
|
#include "nsIAppWindow.h"
|
||||||
#include "nsIAppShellService.h"
|
#include "nsIAppShellService.h"
|
||||||
#include "nsAppShellCID.h"
|
#include "nsAppShellCID.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
@ -351,23 +350,12 @@ nsresult nsCCUncollectableMarker::Observe(nsISupports* aSubject,
|
|||||||
bool hasHiddenWindow = false;
|
bool hasHiddenWindow = false;
|
||||||
appShell->GetHasHiddenWindow(&hasHiddenWindow);
|
appShell->GetHasHiddenWindow(&hasHiddenWindow);
|
||||||
if (hasHiddenWindow) {
|
if (hasHiddenWindow) {
|
||||||
nsCOMPtr<nsIXULWindow> hw;
|
nsCOMPtr<nsIAppWindow> hw;
|
||||||
appShell->GetHiddenWindow(getter_AddRefs(hw));
|
appShell->GetHiddenWindow(getter_AddRefs(hw));
|
||||||
nsCOMPtr<nsIDocShell> shell;
|
nsCOMPtr<nsIDocShell> shell;
|
||||||
hw->GetDocShell(getter_AddRefs(shell));
|
hw->GetDocShell(getter_AddRefs(shell));
|
||||||
MarkDocShell(shell, cleanupJS);
|
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
|
#ifdef MOZ_XUL
|
||||||
|
@ -285,7 +285,7 @@ nsContentAreaDragDropDataProvider::GetFlavorData(nsITransferable* aTransferable,
|
|||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
newFileName.Append(".");
|
newFileName.Append(".");
|
||||||
newFileName.Append(primaryExtension);
|
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
|
// 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.
|
// ensures that the image data is only created when an image drop is allowed.
|
||||||
class nsContentAreaDragDropDataProvider : public nsIFlavorDataProvider {
|
class nsContentAreaDragDropDataProvider : public nsIFlavorDataProvider {
|
||||||
virtual ~nsContentAreaDragDropDataProvider() {}
|
virtual ~nsContentAreaDragDropDataProvider() = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
@ -98,7 +98,6 @@ inline const char* NS_CP_ContentTypeName(uint32_t contentType) {
|
|||||||
CASE_RETURN(TYPE_DOCUMENT);
|
CASE_RETURN(TYPE_DOCUMENT);
|
||||||
CASE_RETURN(TYPE_SUBDOCUMENT);
|
CASE_RETURN(TYPE_SUBDOCUMENT);
|
||||||
CASE_RETURN(TYPE_REFRESH);
|
CASE_RETURN(TYPE_REFRESH);
|
||||||
CASE_RETURN(TYPE_XBL);
|
|
||||||
CASE_RETURN(TYPE_PING);
|
CASE_RETURN(TYPE_PING);
|
||||||
CASE_RETURN(TYPE_XMLHTTPREQUEST);
|
CASE_RETURN(TYPE_XMLHTTPREQUEST);
|
||||||
CASE_RETURN(TYPE_OBJECT_SUBREQUEST);
|
CASE_RETURN(TYPE_OBJECT_SUBREQUEST);
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
#include "mozilla/dom/Document.h"
|
#include "mozilla/dom/Document.h"
|
||||||
#include "mozilla/dom/DocumentInlines.h"
|
#include "mozilla/dom/DocumentInlines.h"
|
||||||
#include "mozilla/dom/MessageBroadcaster.h"
|
#include "mozilla/dom/MessageBroadcaster.h"
|
||||||
|
#include "mozilla/dom/MessagePort.h"
|
||||||
#include "mozilla/dom/DocumentFragment.h"
|
#include "mozilla/dom/DocumentFragment.h"
|
||||||
#include "mozilla/dom/DOMException.h"
|
#include "mozilla/dom/DOMException.h"
|
||||||
#include "mozilla/dom/DOMExceptionBinding.h"
|
#include "mozilla/dom/DOMExceptionBinding.h"
|
||||||
@ -120,7 +121,6 @@
|
|||||||
#include "nsAttrName.h"
|
#include "nsAttrName.h"
|
||||||
#include "nsAttrValue.h"
|
#include "nsAttrValue.h"
|
||||||
#include "nsAttrValueInlines.h"
|
#include "nsAttrValueInlines.h"
|
||||||
#include "nsBindingManager.h"
|
|
||||||
#include "nsCanvasFrame.h"
|
#include "nsCanvasFrame.h"
|
||||||
#include "nsCaret.h"
|
#include "nsCaret.h"
|
||||||
#include "nsCCUncollectableMarker.h"
|
#include "nsCCUncollectableMarker.h"
|
||||||
@ -565,7 +565,7 @@ class nsContentUtils::UserInteractionObserver final
|
|||||||
static Atomic<bool> sUserActive;
|
static Atomic<bool> sUserActive;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~UserInteractionObserver() {}
|
~UserInteractionObserver() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
@ -2101,7 +2101,7 @@ bool nsContentUtils::IsCallerContentXBL() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return xpc::IsContentXBLScope(realm);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsContentUtils::IsCallerUAWidget() {
|
bool nsContentUtils::IsCallerUAWidget() {
|
||||||
@ -2134,9 +2134,7 @@ bool nsContentUtils::ThreadsafeIsSystemCaller(JSContext* aCx) {
|
|||||||
bool nsContentUtils::LookupBindingMember(
|
bool nsContentUtils::LookupBindingMember(
|
||||||
JSContext* aCx, nsIContent* aContent, JS::Handle<jsid> aId,
|
JSContext* aCx, nsIContent* aContent, JS::Handle<jsid> aId,
|
||||||
JS::MutableHandle<JS::PropertyDescriptor> aDesc) {
|
JS::MutableHandle<JS::PropertyDescriptor> aDesc) {
|
||||||
nsXBLBinding* binding = aContent->GetXBLBinding();
|
return true;
|
||||||
if (!binding) return true;
|
|
||||||
return binding->LookupMember(aCx, aId, aDesc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
@ -3551,7 +3549,6 @@ void nsContentUtils::GetEventArgNames(int32_t aNameSpaceID, nsAtom* aEventName,
|
|||||||
static const char* gPropertiesFiles[nsContentUtils::PropertiesFile_COUNT] = {
|
static const char* gPropertiesFiles[nsContentUtils::PropertiesFile_COUNT] = {
|
||||||
// Must line up with the enum values in |PropertiesFile| enum.
|
// Must line up with the enum values in |PropertiesFile| enum.
|
||||||
"chrome://global/locale/css.properties",
|
"chrome://global/locale/css.properties",
|
||||||
"chrome://global/locale/xbl.properties",
|
|
||||||
"chrome://global/locale/xul.properties",
|
"chrome://global/locale/xul.properties",
|
||||||
"chrome://global/locale/layout_errors.properties",
|
"chrome://global/locale/layout_errors.properties",
|
||||||
"chrome://global/locale/layout/HtmlForm.properties",
|
"chrome://global/locale/layout/HtmlForm.properties",
|
||||||
@ -4270,7 +4267,7 @@ void nsContentUtils::RequestFrameFocus(Element& aFrameElement, bool aCanRaise) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIFocusManager> fm = nsFocusManager::GetFocusManager();
|
RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager();
|
||||||
if (!fm) {
|
if (!fm) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -4409,14 +4406,6 @@ bool nsContentUtils::HasMutationListeners(nsINode* aNode, uint32_t aType,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aNode->IsContent()) {
|
|
||||||
nsIContent* insertionPoint = aNode->AsContent()->GetXBLInsertionPoint();
|
|
||||||
if (insertionPoint) {
|
|
||||||
aNode = insertionPoint->GetParent();
|
|
||||||
MOZ_ASSERT(aNode);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
aNode = aNode->GetParentNode();
|
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(aNode, "Must have a node to work with");
|
||||||
MOZ_ASSERT(aContent, "Must have a content to work with");
|
MOZ_ASSERT(aContent, "Must have a content to work with");
|
||||||
|
|
||||||
if (!aNode->IsContent()) {
|
if (aNode->IsInNativeAnonymousSubtree() != aContent->IsInNativeAnonymousSubtree()) {
|
||||||
/**
|
return false;
|
||||||
* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 */
|
/* static */
|
||||||
@ -5937,7 +5926,7 @@ nsresult nsContentUtils::GetUTFOrigin(nsIPrincipal* aPrincipal,
|
|||||||
asciiOrigin.AssignLiteral("null");
|
asciiOrigin.AssignLiteral("null");
|
||||||
}
|
}
|
||||||
|
|
||||||
aOrigin = NS_ConvertUTF8toUTF16(asciiOrigin);
|
CopyUTF8toUTF16(asciiOrigin, aOrigin);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5963,7 +5952,7 @@ nsresult nsContentUtils::GetUTFOrigin(nsIURI* aURI, nsAString& aOrigin) {
|
|||||||
rv = GetASCIIOrigin(aURI, asciiOrigin);
|
rv = GetASCIIOrigin(aURI, asciiOrigin);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
aOrigin = NS_ConvertUTF8toUTF16(asciiOrigin);
|
CopyUTF8toUTF16(asciiOrigin, aOrigin);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8853,7 +8842,7 @@ void nsContentUtils::GetPresentationURL(nsIDocShell* aDocShell,
|
|||||||
|
|
||||||
nsAutoCString uriStr;
|
nsAutoCString uriStr;
|
||||||
uri->GetSpec(uriStr);
|
uri->GetSpec(uriStr);
|
||||||
aPresentationUrl = NS_ConvertUTF8toUTF16(uriStr);
|
CopyUTF8toUTF16(uriStr, aPresentationUrl);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9496,11 +9485,8 @@ void nsContentUtils::AppendDocumentLevelNativeAnonymousContentTo(
|
|||||||
"scroll frame should always implement nsIAnonymousContentCreator");
|
"scroll frame should always implement nsIAnonymousContentCreator");
|
||||||
creator->AppendAnonymousContentTo(aElements, 0);
|
creator->AppendAnonymousContentTo(aElements, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nsCanvasFrame* canvasFrame = presShell->GetCanvasFrame()) {
|
if (nsCanvasFrame* canvasFrame = presShell->GetCanvasFrame()) {
|
||||||
if (Element* container = canvasFrame->GetCustomContentContainer()) {
|
canvasFrame->AppendAnonymousContentTo(aElements, 0);
|
||||||
aElements.AppendElement(container);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9660,6 +9646,41 @@ nsresult nsContentUtils::CreateJSValueFromSequenceOfObject(
|
|||||||
return NS_OK;
|
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 */
|
/* static */
|
||||||
bool nsContentUtils::ShouldBlockReservedKeys(WidgetKeyboardEvent* aKeyEvent) {
|
bool nsContentUtils::ShouldBlockReservedKeys(WidgetKeyboardEvent* aKeyEvent) {
|
||||||
nsCOMPtr<nsIPrincipal> principal;
|
nsCOMPtr<nsIPrincipal> principal;
|
||||||
|
@ -153,6 +153,7 @@ class MessageBroadcaster;
|
|||||||
class NodeInfo;
|
class NodeInfo;
|
||||||
class Selection;
|
class Selection;
|
||||||
class StaticRange;
|
class StaticRange;
|
||||||
|
struct StructuredSerializeOptions;
|
||||||
class WorkerPrivate;
|
class WorkerPrivate;
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
||||||
@ -1118,7 +1119,6 @@ class nsContentUtils {
|
|||||||
*/
|
*/
|
||||||
enum PropertiesFile {
|
enum PropertiesFile {
|
||||||
eCSS_PROPERTIES,
|
eCSS_PROPERTIES,
|
||||||
eXBL_PROPERTIES,
|
|
||||||
eXUL_PROPERTIES,
|
eXUL_PROPERTIES,
|
||||||
eLAYOUT_PROPERTIES,
|
eLAYOUT_PROPERTIES,
|
||||||
eFORMS_PROPERTIES,
|
eFORMS_PROPERTIES,
|
||||||
@ -3098,6 +3098,15 @@ class nsContentUtils {
|
|||||||
JSContext* aCx, const mozilla::dom::Sequence<JSObject*>& aTransfer,
|
JSContext* aCx, const mozilla::dom::Sequence<JSObject*>& aTransfer,
|
||||||
JS::MutableHandle<JS::Value> aValue);
|
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
|
* 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.
|
* 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);
|
rv = aEncoder.GetMimeType(mimeType);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
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 mime type is ultimately text/html if the encoder successfully encoded
|
||||||
// the selection as text/html.
|
// the selection as text/html.
|
||||||
aEncodedAsTextHTMLResult = mimeType.EqualsLiteral(kHTMLMime);
|
aEncodedAsTextHTMLResult = mimeType.EqualsLiteral(kHTMLMime);
|
||||||
|
@ -49,8 +49,7 @@ class nsAttrKey {
|
|||||||
nsAttrKey(int32_t aNs, nsAtom* aName)
|
nsAttrKey(int32_t aNs, nsAtom* aName)
|
||||||
: mNamespaceID(aNs), mLocalName(aName) {}
|
: mNamespaceID(aNs), mLocalName(aName) {}
|
||||||
|
|
||||||
nsAttrKey(const nsAttrKey& aAttr)
|
nsAttrKey(const nsAttrKey& aAttr) = default;
|
||||||
: mNamespaceID(aAttr.mNamespaceID), mLocalName(aAttr.mLocalName) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,7 +62,7 @@ class nsAttrHashKey : public PLDHashEntryHdr {
|
|||||||
|
|
||||||
explicit nsAttrHashKey(KeyTypePointer aKey) : mKey(*aKey) {}
|
explicit nsAttrHashKey(KeyTypePointer aKey) : mKey(*aKey) {}
|
||||||
nsAttrHashKey(const nsAttrHashKey& aCopy) : mKey(aCopy.mKey) {}
|
nsAttrHashKey(const nsAttrHashKey& aCopy) : mKey(aCopy.mKey) {}
|
||||||
~nsAttrHashKey() {}
|
~nsAttrHashKey() = default;
|
||||||
|
|
||||||
KeyType GetKey() const { return mKey; }
|
KeyType GetKey() const { return mKey; }
|
||||||
bool KeyEquals(KeyTypePointer aKey) const {
|
bool KeyEquals(KeyTypePointer aKey) const {
|
||||||
|
@ -31,7 +31,7 @@ class nsDOMMutationObserver;
|
|||||||
using mozilla::dom::MutationObservingInfo;
|
using mozilla::dom::MutationObservingInfo;
|
||||||
|
|
||||||
class nsDOMMutationRecord final : public nsISupports, public nsWrapperCache {
|
class nsDOMMutationRecord final : public nsISupports, public nsWrapperCache {
|
||||||
virtual ~nsDOMMutationRecord() {}
|
virtual ~nsDOMMutationRecord() = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef nsTArray<RefPtr<mozilla::dom::Animation>> AnimationArray;
|
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.
|
// members to make sure we go through getters/setters.
|
||||||
class nsMutationReceiverBase : public nsStubAnimationObserver {
|
class nsMutationReceiverBase : public nsStubAnimationObserver {
|
||||||
public:
|
public:
|
||||||
virtual ~nsMutationReceiverBase() {}
|
virtual ~nsMutationReceiverBase() = default;
|
||||||
|
|
||||||
nsDOMMutationObserver* Observer();
|
nsDOMMutationObserver* Observer();
|
||||||
nsINode* Target() { return mParent ? mParent->Target() : mTarget; }
|
nsINode* Target() { return mParent ? mParent->Target() : mTarget; }
|
||||||
@ -398,7 +398,7 @@ class nsAnimationReceiver : public nsMutationReceiver {
|
|||||||
NS_DECL_NSIANIMATIONOBSERVER_ANIMATIONREMOVED
|
NS_DECL_NSIANIMATIONOBSERVER_ANIMATIONREMOVED
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~nsAnimationReceiver() {}
|
virtual ~nsAnimationReceiver() = default;
|
||||||
|
|
||||||
nsAnimationReceiver(nsINode* aTarget, nsDOMMutationObserver* aObserver)
|
nsAnimationReceiver(nsINode* aTarget, nsDOMMutationObserver* aObserver)
|
||||||
: nsMutationReceiver(aTarget, aObserver) {}
|
: nsMutationReceiver(aTarget, aObserver) {}
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
#include "nsIWebNavigation.h"
|
#include "nsIWebNavigation.h"
|
||||||
#include "nsCaret.h"
|
#include "nsCaret.h"
|
||||||
#include "nsIBaseWindow.h"
|
#include "nsIBaseWindow.h"
|
||||||
#include "nsIXULWindow.h"
|
#include "nsIAppWindow.h"
|
||||||
#include "nsTextControlFrame.h"
|
#include "nsTextControlFrame.h"
|
||||||
#include "nsViewManager.h"
|
#include "nsViewManager.h"
|
||||||
#include "nsFrameSelection.h"
|
#include "nsFrameSelection.h"
|
||||||
@ -33,7 +33,6 @@
|
|||||||
#include "nsIPrincipal.h"
|
#include "nsIPrincipal.h"
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
#include "nsIObjectFrame.h"
|
#include "nsIObjectFrame.h"
|
||||||
#include "nsBindingManager.h"
|
|
||||||
#include "BrowserChild.h"
|
#include "BrowserChild.h"
|
||||||
#include "nsFrameLoader.h"
|
#include "nsFrameLoader.h"
|
||||||
#include "nsHTMLDocument.h"
|
#include "nsHTMLDocument.h"
|
||||||
@ -250,7 +249,9 @@ static nsPIDOMWindowOuter* GetContentWindow(nsIContent* aContent) {
|
|||||||
Document* doc = aContent->GetComposedDoc();
|
Document* doc = aContent->GetComposedDoc();
|
||||||
if (doc) {
|
if (doc) {
|
||||||
Document* subdoc = doc->GetSubDocumentFor(aContent);
|
Document* subdoc = doc->GetSubDocumentFor(aContent);
|
||||||
if (subdoc) return subdoc->GetWindow();
|
if (subdoc) {
|
||||||
|
return subdoc->GetWindow();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -319,17 +320,12 @@ Element* nsFocusManager::GetFocusedDescendant(
|
|||||||
Element* nsFocusManager::GetRedirectedFocus(nsIContent* aContent) {
|
Element* nsFocusManager::GetRedirectedFocus(nsIContent* aContent) {
|
||||||
#ifdef MOZ_XUL
|
#ifdef MOZ_XUL
|
||||||
if (aContent->IsXULElement()) {
|
if (aContent->IsXULElement()) {
|
||||||
if (aContent->IsXULElement(nsGkAtoms::textbox)) {
|
nsCOMPtr<nsIDOMXULMenuListElement> menulist =
|
||||||
return aContent->OwnerDoc()->GetAnonymousElementByAttribute(
|
aContent->AsElement()->AsXULMenuList();
|
||||||
aContent, nsGkAtoms::anonid, NS_LITERAL_STRING("input"));
|
if (menulist) {
|
||||||
} else {
|
RefPtr<Element> inputField;
|
||||||
nsCOMPtr<nsIDOMXULMenuListElement> menulist =
|
menulist->GetInputField(getter_AddRefs(inputField));
|
||||||
aContent->AsElement()->AsXULMenuList();
|
return inputField;
|
||||||
if (menulist) {
|
|
||||||
RefPtr<Element> inputField;
|
|
||||||
menulist->GetInputField(getter_AddRefs(inputField));
|
|
||||||
return inputField;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -408,7 +404,9 @@ NS_IMETHODIMP nsFocusManager::SetFocusedWindow(
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> rootWindow = windowToFocus->GetPrivateRoot();
|
nsCOMPtr<nsPIDOMWindowOuter> rootWindow = windowToFocus->GetPrivateRoot();
|
||||||
if (rootWindow) RaiseWindow(rootWindow);
|
if (rootWindow) {
|
||||||
|
RaiseWindow(rootWindow);
|
||||||
|
}
|
||||||
|
|
||||||
LOGFOCUS(("<<SetFocusedWindow end>>"));
|
LOGFOCUS(("<<SetFocusedWindow end>>"));
|
||||||
|
|
||||||
@ -430,7 +428,9 @@ nsFocusManager::GetLastFocusMethod(mozIDOMWindowProxy* aWindow,
|
|||||||
if (aWindow) {
|
if (aWindow) {
|
||||||
window = nsPIDOMWindowOuter::From(aWindow);
|
window = nsPIDOMWindowOuter::From(aWindow);
|
||||||
}
|
}
|
||||||
if (!window) window = mFocusedWindow;
|
if (!window) {
|
||||||
|
window = mFocusedWindow;
|
||||||
|
}
|
||||||
|
|
||||||
*aLastFocusMethod = window ? window->GetFocusMethod() : 0;
|
*aLastFocusMethod = window ? window->GetFocusMethod() : 0;
|
||||||
|
|
||||||
@ -559,7 +559,9 @@ nsFocusManager::GetFocusedElementForWindow(mozIDOMWindowProxy* aWindow,
|
|||||||
mozIDOMWindowProxy** aFocusedWindow,
|
mozIDOMWindowProxy** aFocusedWindow,
|
||||||
Element** aElement) {
|
Element** aElement) {
|
||||||
*aElement = nullptr;
|
*aElement = nullptr;
|
||||||
if (aFocusedWindow) *aFocusedWindow = nullptr;
|
if (aFocusedWindow) {
|
||||||
|
*aFocusedWindow = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
NS_ENSURE_TRUE(aWindow, NS_ERROR_INVALID_ARG);
|
NS_ENSURE_TRUE(aWindow, NS_ERROR_INVALID_ARG);
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
|
nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
|
||||||
@ -573,7 +575,9 @@ nsFocusManager::GetFocusedElementForWindow(mozIDOMWindowProxy* aWindow,
|
|||||||
|
|
||||||
focusedElement.forget(aElement);
|
focusedElement.forget(aElement);
|
||||||
|
|
||||||
if (aFocusedWindow) NS_IF_ADDREF(*aFocusedWindow = focusedWindow);
|
if (aFocusedWindow) {
|
||||||
|
NS_IF_ADDREF(*aFocusedWindow = focusedWindow);
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -590,7 +594,9 @@ nsFocusManager::MoveCaretToFocus(mozIDOMWindowProxy* aWindow) {
|
|||||||
// don't move the caret for editable documents
|
// don't move the caret for editable documents
|
||||||
bool isEditable;
|
bool isEditable;
|
||||||
docShell->GetEditable(&isEditable);
|
docShell->GetEditable(&isEditable);
|
||||||
if (isEditable) return NS_OK;
|
if (isEditable) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
RefPtr<PresShell> presShell = docShell->GetPresShell();
|
RefPtr<PresShell> presShell = docShell->GetPresShell();
|
||||||
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
|
||||||
@ -606,9 +612,11 @@ nsFocusManager::MoveCaretToFocus(mozIDOMWindowProxy* aWindow) {
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
void nsFocusManager::WindowRaised(mozIDOMWindowProxy* aWindow) {
|
||||||
nsFocusManager::WindowRaised(mozIDOMWindowProxy* aWindow) {
|
if (!aWindow) {
|
||||||
NS_ENSURE_TRUE(aWindow, NS_ERROR_INVALID_ARG);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
|
nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
|
||||||
|
|
||||||
if (MOZ_LOG_TEST(gFocusLog, LogLevel::Debug)) {
|
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
|
// what the focus manager thinks should be the current widget is actually
|
||||||
// focused.
|
// focused.
|
||||||
EnsureCurrentWidgetFocused();
|
EnsureCurrentWidgetFocused();
|
||||||
return NS_OK;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// lower the existing window, if any. This shouldn't happen usually.
|
// lower the existing window, if any. This shouldn't happen usually.
|
||||||
@ -646,7 +654,9 @@ nsFocusManager::WindowRaised(mozIDOMWindowProxy* aWindow) {
|
|||||||
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem = window->GetDocShell();
|
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem = window->GetDocShell();
|
||||||
// If there's no docShellAsItem, this window must have been closed,
|
// If there's no docShellAsItem, this window must have been closed,
|
||||||
// in that case there is no tree owner.
|
// in that case there is no tree owner.
|
||||||
NS_ENSURE_TRUE(docShellAsItem, NS_OK);
|
if (!docShellAsItem) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// set this as the active window
|
// set this as the active window
|
||||||
mActiveWindow = window;
|
mActiveWindow = window;
|
||||||
@ -658,7 +668,7 @@ nsFocusManager::WindowRaised(mozIDOMWindowProxy* aWindow) {
|
|||||||
if (baseWindow) {
|
if (baseWindow) {
|
||||||
bool isEnabled = true;
|
bool isEnabled = true;
|
||||||
if (NS_SUCCEEDED(baseWindow->GetEnabled(&isEnabled)) && !isEnabled) {
|
if (NS_SUCCEEDED(baseWindow->GetEnabled(&isEnabled)) && !isEnabled) {
|
||||||
return NS_ERROR_FAILURE;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
baseWindow->SetVisibility(true);
|
baseWindow->SetVisibility(true);
|
||||||
@ -680,19 +690,21 @@ nsFocusManager::WindowRaised(mozIDOMWindowProxy* aWindow) {
|
|||||||
window, eIncludeAllDescendants, getter_AddRefs(currentWindow));
|
window, eIncludeAllDescendants, getter_AddRefs(currentWindow));
|
||||||
|
|
||||||
NS_ASSERTION(currentWindow, "window raised with no window current");
|
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.
|
// window. Pass false for aWindowRaised so that commands get updated.
|
||||||
nsCOMPtr<nsIXULWindow> xulWin(do_GetInterface(baseWindow));
|
nsCOMPtr<nsIAppWindow> appWin(do_GetInterface(baseWindow));
|
||||||
Focus(currentWindow, currentFocus, 0, true, false, xulWin != nullptr, true);
|
Focus(currentWindow, currentFocus, 0, true, false, appWin != nullptr, true);
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
void nsFocusManager::WindowLowered(mozIDOMWindowProxy* aWindow) {
|
||||||
nsFocusManager::WindowLowered(mozIDOMWindowProxy* aWindow) {
|
if (!aWindow) {
|
||||||
NS_ENSURE_TRUE(aWindow, NS_ERROR_INVALID_ARG);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
|
nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
|
||||||
|
|
||||||
if (MOZ_LOG_TEST(gFocusLog, LogLevel::Debug)) {
|
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
|
// clear the mouse capture as the active window has changed
|
||||||
PresShell::ReleaseCapturingContent();
|
PresShell::ReleaseCapturingContent();
|
||||||
@ -742,11 +756,11 @@ nsFocusManager::WindowLowered(mozIDOMWindowProxy* aWindow) {
|
|||||||
mWindowBeingLowered = mActiveWindow;
|
mWindowBeingLowered = mActiveWindow;
|
||||||
mActiveWindow = nullptr;
|
mActiveWindow = nullptr;
|
||||||
|
|
||||||
if (mFocusedWindow) Blur(nullptr, nullptr, true, true);
|
if (mFocusedWindow) {
|
||||||
|
Blur(nullptr, nullptr, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
mWindowBeingLowered = nullptr;
|
mWindowBeingLowered = nullptr;
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult nsFocusManager::ContentRemoved(Document* aDocument,
|
nsresult nsFocusManager::ContentRemoved(Document* aDocument,
|
||||||
@ -755,15 +769,16 @@ nsresult nsFocusManager::ContentRemoved(Document* aDocument,
|
|||||||
NS_ENSURE_ARG(aContent);
|
NS_ENSURE_ARG(aContent);
|
||||||
|
|
||||||
nsPIDOMWindowOuter* window = aDocument->GetWindow();
|
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
|
// if the content is currently focused in the window, or is an
|
||||||
// shadow-including inclusive ancestor of the currently focused element,
|
// shadow-including inclusive ancestor of the currently focused element,
|
||||||
// reset the focus within that window.
|
// reset the focus within that window.
|
||||||
nsIContent* content = window->GetFocusedElement();
|
Element* content = window->GetFocusedElement();
|
||||||
if (content &&
|
if (content &&
|
||||||
nsContentUtils::ContentIsHostIncludingDescendantOf(content, aContent)) {
|
nsContentUtils::ContentIsHostIncludingDescendantOf(content, aContent)) {
|
||||||
bool shouldShowFocusRing = window->ShouldShowFocusRing();
|
|
||||||
window->SetFocusedElement(nullptr);
|
window->SetFocusedElement(nullptr);
|
||||||
|
|
||||||
// if this window is currently focused, clear the global focused
|
// if this window is currently focused, clear the global focused
|
||||||
@ -803,16 +818,19 @@ nsresult nsFocusManager::ContentRemoved(Document* aDocument,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NotifyFocusStateChange(content, nullptr, shouldShowFocusRing, 0,
|
NotifyFocusStateChange(content, nullptr, 0, /* aGettingFocus = */ false,
|
||||||
/* aGettingFocus = */ false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
void nsFocusManager::WindowShown(mozIDOMWindowProxy* aWindow,
|
||||||
nsFocusManager::WindowShown(mozIDOMWindowProxy* aWindow, bool aNeedsFocus) {
|
bool aNeedsFocus) {
|
||||||
NS_ENSURE_TRUE(aWindow, NS_ERROR_INVALID_ARG);
|
if (!aWindow) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
|
nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
|
||||||
|
|
||||||
if (MOZ_LOG_TEST(gFocusLog, LogLevel::Debug)) {
|
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) {
|
if (aNeedsFocus) {
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> currentWindow;
|
nsCOMPtr<nsPIDOMWindowOuter> currentWindow;
|
||||||
RefPtr<Element> currentFocus = GetFocusedDescendant(
|
RefPtr<Element> currentFocus = GetFocusedDescendant(
|
||||||
window, eIncludeAllDescendants, getter_AddRefs(currentWindow));
|
window, eIncludeAllDescendants, getter_AddRefs(currentWindow));
|
||||||
if (currentWindow)
|
if (currentWindow) {
|
||||||
Focus(currentWindow, currentFocus, 0, true, false, false, true);
|
Focus(currentWindow, currentFocus, 0, true, false, false, true);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Sometimes, an element in a window can be focused before the window is
|
// 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.
|
// visible, which would mean that the widget may not be properly focused.
|
||||||
// When the window becomes visible, make sure the right widget is focused.
|
// When the window becomes visible, make sure the right widget is focused.
|
||||||
EnsureCurrentWidgetFocused();
|
EnsureCurrentWidgetFocused();
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
void nsFocusManager::WindowHidden(mozIDOMWindowProxy* aWindow) {
|
||||||
nsFocusManager::WindowHidden(mozIDOMWindowProxy* aWindow) {
|
|
||||||
// if there is no window or it is not the same or an ancestor of the
|
// 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
|
// currently focused window, just return, as the current focus will not
|
||||||
// be affected.
|
// be affected.
|
||||||
|
|
||||||
NS_ENSURE_TRUE(aWindow, NS_ERROR_INVALID_ARG);
|
if (!aWindow) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
|
nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
|
||||||
|
|
||||||
if (MOZ_LOG_TEST(gFocusLog, LogLevel::Debug)) {
|
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
|
// 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
|
// 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);
|
RefPtr<Element> oldFocusedElement = std::move(mFocusedElement);
|
||||||
|
|
||||||
nsCOMPtr<nsIDocShell> focusedDocShell = mFocusedWindow->GetDocShell();
|
nsCOMPtr<nsIDocShell> focusedDocShell = mFocusedWindow->GetDocShell();
|
||||||
|
if (!focusedDocShell) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
RefPtr<PresShell> presShell = focusedDocShell->GetPresShell();
|
RefPtr<PresShell> presShell = focusedDocShell->GetPresShell();
|
||||||
|
|
||||||
if (oldFocusedElement && oldFocusedElement->IsInComposedDoc()) {
|
if (oldFocusedElement && oldFocusedElement->IsInComposedDoc()) {
|
||||||
NotifyFocusStateChange(oldFocusedElement, nullptr,
|
NotifyFocusStateChange(oldFocusedElement, nullptr, 0, false, false);
|
||||||
mFocusedWindow->ShouldShowFocusRing(), 0, false);
|
|
||||||
window->UpdateCommands(u"focus"_ns, nullptr, 0);
|
window->UpdateCommands(u"focus"_ns, nullptr, 0);
|
||||||
|
|
||||||
if (presShell) {
|
if (presShell) {
|
||||||
@ -942,11 +968,13 @@ nsFocusManager::WindowHidden(mozIDOMWindowProxy* aWindow) {
|
|||||||
// not happen if nsIAppStartup::eForceQuit is used to quit, and can cause
|
// not happen if nsIAppStartup::eForceQuit is used to quit, and can cause
|
||||||
// a leak. So if the active window is being destroyed, call WindowLowered
|
// a leak. So if the active window is being destroyed, call WindowLowered
|
||||||
// directly.
|
// directly.
|
||||||
if (mActiveWindow == mFocusedWindow || mActiveWindow == window)
|
if (mActiveWindow == mFocusedWindow || mActiveWindow == window) {
|
||||||
WindowLowered(mActiveWindow);
|
WindowLowered(mActiveWindow);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
ClearFocus(mActiveWindow);
|
ClearFocus(mActiveWindow);
|
||||||
return NS_OK;
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the window being hidden is an ancestor of the focused window, adjust
|
// if the window being hidden is an ancestor of the focused window, adjust
|
||||||
@ -960,20 +988,19 @@ nsFocusManager::WindowHidden(mozIDOMWindowProxy* aWindow) {
|
|||||||
nsCOMPtr<nsIDocShellTreeItem> parentDsti;
|
nsCOMPtr<nsIDocShellTreeItem> parentDsti;
|
||||||
dsti->GetInProcessParent(getter_AddRefs(parentDsti));
|
dsti->GetInProcessParent(getter_AddRefs(parentDsti));
|
||||||
if (parentDsti) {
|
if (parentDsti) {
|
||||||
if (nsCOMPtr<nsPIDOMWindowOuter> parentWindow = parentDsti->GetWindow())
|
if (nsCOMPtr<nsPIDOMWindowOuter> parentWindow =
|
||||||
|
parentDsti->GetWindow()) {
|
||||||
parentWindow->SetFocusedElement(nullptr);
|
parentWindow->SetFocusedElement(nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetFocusedWindowInternal(window);
|
SetFocusedWindowInternal(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
void nsFocusManager::FireDelayedEvents(Document* aDocument) {
|
||||||
nsFocusManager::FireDelayedEvents(Document* aDocument) {
|
MOZ_ASSERT(aDocument);
|
||||||
NS_ENSURE_ARG(aDocument);
|
|
||||||
|
|
||||||
// fire any delayed focus and blur events in the same order that they were
|
// fire any delayed focus and blur events in the same order that they were
|
||||||
// added
|
// added
|
||||||
@ -1000,36 +1027,90 @@ nsFocusManager::FireDelayedEvents(Document* aDocument) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
nsresult nsFocusManager::FocusPlugin(Element* aPlugin) {
|
||||||
nsFocusManager::FocusPlugin(Element* aPlugin) {
|
|
||||||
NS_ENSURE_ARG(aPlugin);
|
NS_ENSURE_ARG(aPlugin);
|
||||||
SetFocusInner(aPlugin, 0, true, false);
|
SetFocusInner(aPlugin, 0, true, false);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
void nsFocusManager::ParentActivated(mozIDOMWindowProxy* aWindow,
|
||||||
nsFocusManager::ParentActivated(mozIDOMWindowProxy* aWindow, bool aActive) {
|
bool aActive) {
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
|
nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
|
||||||
NS_ENSURE_TRUE(window, NS_ERROR_INVALID_ARG);
|
if (!window) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ActivateOrDeactivate(window, aActive);
|
ActivateOrDeactivate(window, aActive);
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ShouldMatchFocusVisible(const Element& aElement,
|
nsFocusManager::BlurredElementInfo::BlurredElementInfo(Element& aElement)
|
||||||
int32_t aFocusFlags) {
|
: mElement(aElement),
|
||||||
switch (nsFocusManager::GetFocusMoveActionCause(aFocusFlags)) {
|
mHadRing(aElement.State().HasState(NS_EVENT_STATE_FOCUSRING)) {}
|
||||||
case InputContextAction::CAUSE_UNKNOWN:
|
|
||||||
case InputContextAction::CAUSE_KEY:
|
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;
|
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_MOUSE:
|
||||||
case InputContextAction::CAUSE_TOUCH:
|
case InputContextAction::CAUSE_TOUCH:
|
||||||
case InputContextAction::CAUSE_LONGPRESS:
|
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_CHROME:
|
||||||
case InputContextAction::CAUSE_UNKNOWN_DURING_KEYBOARD_INPUT:
|
case InputContextAction::CAUSE_UNKNOWN_DURING_KEYBOARD_INPUT:
|
||||||
case InputContextAction::CAUSE_UNKNOWN_DURING_NON_KEYBOARD_INPUT:
|
case InputContextAction::CAUSE_UNKNOWN_DURING_NON_KEYBOARD_INPUT:
|
||||||
@ -1044,60 +1125,31 @@ static bool ShouldMatchFocusVisible(const Element& aElement,
|
|||||||
return false;
|
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 */
|
/* static */
|
||||||
void nsFocusManager::NotifyFocusStateChange(nsIContent* aContent,
|
void nsFocusManager::NotifyFocusStateChange(Element* aElement,
|
||||||
nsIContent* aContentToFocus,
|
Element* aElementToFocus,
|
||||||
bool aWindowShouldShowFocusRing,
|
int32_t aFlags, bool aGettingFocus,
|
||||||
int32_t aFlags,
|
bool aShouldShowFocusRing) {
|
||||||
bool aGettingFocus) {
|
MOZ_ASSERT_IF(aElementToFocus, !aGettingFocus);
|
||||||
MOZ_ASSERT_IF(aContentToFocus, !aGettingFocus);
|
|
||||||
auto* element = Element::FromNode(aContent);
|
|
||||||
if (!element) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIContent* commonAncestor = nullptr;
|
nsIContent* commonAncestor = nullptr;
|
||||||
if (aContentToFocus && aContentToFocus->IsElement()) {
|
if (aElementToFocus) {
|
||||||
commonAncestor = nsContentUtils::GetCommonFlattenedTreeAncestor(
|
commonAncestor = nsContentUtils::GetCommonFlattenedTreeAncestor(
|
||||||
aContent, aContentToFocus);
|
aElement, aElementToFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aGettingFocus) {
|
if (aGettingFocus) {
|
||||||
EventStates eventStateToAdd = NS_EVENT_STATE_FOCUS;
|
EventStates eventStateToAdd = NS_EVENT_STATE_FOCUS;
|
||||||
if (aWindowShouldShowFocusRing ||
|
if (aShouldShowFocusRing) {
|
||||||
ShouldShowFocusRingForElement(*element, aFlags)) {
|
|
||||||
eventStateToAdd |= NS_EVENT_STATE_FOCUSRING;
|
eventStateToAdd |= NS_EVENT_STATE_FOCUSRING;
|
||||||
}
|
}
|
||||||
if (aWindowShouldShowFocusRing ||
|
aElement->AddStates(eventStateToAdd);
|
||||||
ShouldMatchFocusVisible(*element, aFlags)) {
|
|
||||||
eventStateToAdd |= NS_EVENT_STATE_FOCUS_VISIBLE;
|
|
||||||
}
|
|
||||||
element->AddStates(eventStateToAdd);
|
|
||||||
} else {
|
} else {
|
||||||
EventStates eventStateToRemove = NS_EVENT_STATE_FOCUS |
|
EventStates eventStateToRemove =
|
||||||
NS_EVENT_STATE_FOCUSRING |
|
NS_EVENT_STATE_FOCUS | NS_EVENT_STATE_FOCUSRING;
|
||||||
NS_EVENT_STATE_FOCUS_VISIBLE;
|
aElement->RemoveStates(eventStateToRemove);
|
||||||
element->RemoveStates(eventStateToRemove);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (nsIContent* content = aContent; content && content != commonAncestor;
|
for (nsIContent* content = aElement; content && content != commonAncestor;
|
||||||
content = content->GetFlattenedTreeParent()) {
|
content = content->GetFlattenedTreeParent()) {
|
||||||
Element* element = Element::FromNode(content);
|
Element* element = Element::FromNode(content);
|
||||||
if (!element) {
|
if (!element) {
|
||||||
@ -1169,7 +1221,7 @@ void nsFocusManager::ActivateOrDeactivate(nsPIDOMWindowOuter* aWindow,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void nsFocusManager::SetFocusInner(Element* aNewContent, int32_t aFlags,
|
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
|
// if the element is not focusable, just return and leave the focus as is
|
||||||
RefPtr<Element> elementToFocus =
|
RefPtr<Element> elementToFocus =
|
||||||
FlushAndCheckIfFocusable(aNewContent, aFlags);
|
FlushAndCheckIfFocusable(aNewContent, aFlags);
|
||||||
@ -1315,7 +1367,10 @@ void nsFocusManager::SetFocusInner(Element* aNewContent, int32_t aFlags,
|
|||||||
isElementInActiveWindow, isElementInFocusedWindow, sendFocusEvent));
|
isElementInActiveWindow, isElementInFocusedWindow, sendFocusEvent));
|
||||||
|
|
||||||
if (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
|
// return if blurring fails or the focus changes during the blur
|
||||||
if (mFocusedWindow) {
|
if (mFocusedWindow) {
|
||||||
// if the focus is being moved to another element in the same document,
|
// 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);
|
commonAncestor = GetCommonAncestor(newWindow, mFocusedWindow);
|
||||||
|
|
||||||
if (!Blur(currentIsSameOrAncestor ? mFocusedWindow.get() : nullptr,
|
if (!Blur(currentIsSameOrAncestor ? mFocusedWindow.get() : nullptr,
|
||||||
commonAncestor, !isElementInFocusedWindow, aAdjustWidget,
|
commonAncestor, !isElementInFocusedWindow, aAdjustWidgets,
|
||||||
elementToFocus)) {
|
elementToFocus)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Focus(newWindow, elementToFocus, aFlags, !isElementInFocusedWindow,
|
Focus(newWindow, elementToFocus, aFlags, !isElementInFocusedWindow,
|
||||||
aFocusChanged, false, aAdjustWidget, oldFocusedElement);
|
aFocusChanged, false, aAdjustWidgets, blurredInfo);
|
||||||
} else {
|
} else {
|
||||||
// otherwise, for inactive windows and when the caller cannot steal the
|
// otherwise, for inactive windows and when the caller cannot steal the
|
||||||
// focus, update the node in the window, and raise the window if desired.
|
// 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
|
// update the commands even when inactive so that the attributes for that
|
||||||
// window are up to date.
|
// 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);
|
if (aFlags & FLAG_RAISE) RaiseWindow(newRootWindow);
|
||||||
}
|
}
|
||||||
@ -1475,16 +1532,22 @@ void nsFocusManager::AdjustWindowFocus(nsPIDOMWindowOuter* aWindow,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool nsFocusManager::IsWindowVisible(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
|
// Check if the inner window is frozen as well. This can happen when a focus
|
||||||
// change occurs while restoring a previous page.
|
// change occurs while restoring a previous page.
|
||||||
nsPIDOMWindowInner* innerWindow = aWindow->GetCurrentInnerWindow();
|
nsPIDOMWindowInner* innerWindow = aWindow->GetCurrentInnerWindow();
|
||||||
if (!innerWindow || innerWindow->IsFrozen()) return false;
|
if (!innerWindow || innerWindow->IsFrozen()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIDocShell> docShell = aWindow->GetDocShell();
|
nsCOMPtr<nsIDocShell> docShell = aWindow->GetDocShell();
|
||||||
nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(docShell));
|
nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(docShell));
|
||||||
if (!baseWin) return false;
|
if (!baseWin) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool visible = false;
|
bool visible = false;
|
||||||
baseWin->GetVisibility(&visible);
|
baseWin->GetVisibility(&visible);
|
||||||
@ -1509,7 +1572,9 @@ bool nsFocusManager::IsNonFocusableRoot(nsIContent* aContent) {
|
|||||||
|
|
||||||
Element* nsFocusManager::FlushAndCheckIfFocusable(Element* aElement,
|
Element* nsFocusManager::FlushAndCheckIfFocusable(Element* aElement,
|
||||||
uint32_t aFlags) {
|
uint32_t aFlags) {
|
||||||
if (!aElement) return nullptr;
|
if (!aElement) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<Document> doc = aElement->GetComposedDoc();
|
nsCOMPtr<Document> doc = aElement->GetComposedDoc();
|
||||||
// can't focus elements that are not in documents
|
// can't focus elements that are not in documents
|
||||||
@ -1585,7 +1650,7 @@ Element* nsFocusManager::FlushAndCheckIfFocusable(Element* aElement,
|
|||||||
bool nsFocusManager::Blur(nsPIDOMWindowOuter* aWindowToClear,
|
bool nsFocusManager::Blur(nsPIDOMWindowOuter* aWindowToClear,
|
||||||
nsPIDOMWindowOuter* aAncestorWindowToFocus,
|
nsPIDOMWindowOuter* aAncestorWindowToFocus,
|
||||||
bool aIsLeavingDocument, bool aAdjustWidgets,
|
bool aIsLeavingDocument, bool aAdjustWidgets,
|
||||||
nsIContent* aContentToFocus) {
|
Element* aElementToFocus) {
|
||||||
LOGFOCUS(("<<Blur begin>>"));
|
LOGFOCUS(("<<Blur begin>>"));
|
||||||
|
|
||||||
// hold a reference to the focused content, which may be null
|
// 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
|
// now adjust the actual focus, by clearing the fields in the focus manager
|
||||||
// and in the window.
|
// and in the window.
|
||||||
mFocusedElement = nullptr;
|
mFocusedElement = nullptr;
|
||||||
bool shouldShowFocusRing = window->ShouldShowFocusRing();
|
|
||||||
if (aWindowToClear) aWindowToClear->SetFocusedElement(nullptr);
|
if (aWindowToClear) aWindowToClear->SetFocusedElement(nullptr);
|
||||||
|
|
||||||
LOGCONTENT("Element %s has been blurred", element.get());
|
LOGCONTENT("Element %s has been blurred", element.get());
|
||||||
@ -1645,8 +1709,7 @@ bool nsFocusManager::Blur(nsPIDOMWindowOuter* aWindowToClear,
|
|||||||
element && element->IsInComposedDoc() && !IsNonFocusableRoot(element);
|
element && element->IsInComposedDoc() && !IsNonFocusableRoot(element);
|
||||||
if (element) {
|
if (element) {
|
||||||
if (sendBlurEvent) {
|
if (sendBlurEvent) {
|
||||||
NotifyFocusStateChange(element, aContentToFocus, shouldShowFocusRing, 0,
|
NotifyFocusStateChange(element, aElementToFocus, 0, false, false);
|
||||||
false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if an object/plug-in/remote browser is being blurred, move the system
|
// 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
|
// 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,
|
// window, then this was a blur caused by the active window being lowered,
|
||||||
// so there is no need to update the commands
|
// so there is no need to update the commands
|
||||||
if (mActiveWindow)
|
if (mActiveWindow) {
|
||||||
window->UpdateCommands(u"focus"_ns, nullptr, 0);
|
window->UpdateCommands(u"focus"_ns, nullptr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
SendFocusOrBlurEvent(eBlur, presShell, element->GetComposedDoc(), element,
|
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
|
// 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,
|
void nsFocusManager::Focus(
|
||||||
uint32_t aFlags, bool aIsNewDocument,
|
nsPIDOMWindowOuter* aWindow, Element* aElement, uint32_t aFlags,
|
||||||
bool aFocusChanged, bool aWindowRaised,
|
bool aIsNewDocument, bool aFocusChanged, bool aWindowRaised,
|
||||||
bool aAdjustWidgets, nsIContent* aContentLostFocus) {
|
bool aAdjustWidgets, const Maybe<BlurredElementInfo>& aBlurredElementInfo) {
|
||||||
LOGFOCUS(("<<Focus begin>>"));
|
LOGFOCUS(("<<Focus begin>>"));
|
||||||
|
|
||||||
if (!aWindow) return;
|
if (!aWindow) {
|
||||||
|
|
||||||
if (aElement && (aElement == mFirstFocusEvent || aElement == mFirstBlurEvent))
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aElement &&
|
||||||
|
(aElement == mFirstFocusEvent || aElement == mFirstBlurEvent)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Keep a reference to the presShell since dispatching the DOM event may
|
// Keep a reference to the presShell since dispatching the DOM event may
|
||||||
// cause the document to be destroyed.
|
// cause the document to be destroyed.
|
||||||
nsCOMPtr<nsIDocShell> docShell = aWindow->GetDocShell();
|
nsCOMPtr<nsIDocShell> docShell = aWindow->GetDocShell();
|
||||||
if (!docShell) return;
|
if (!docShell) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
RefPtr<PresShell> presShell = docShell->GetPresShell();
|
RefPtr<PresShell> presShell = docShell->GetPresShell();
|
||||||
if (!presShell) {
|
if (!presShell) {
|
||||||
@ -1848,7 +1918,9 @@ void nsFocusManager::Focus(nsPIDOMWindowOuter* aWindow, Element* aElement,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// indicate that the window has taken focus.
|
// indicate that the window has taken focus.
|
||||||
if (aWindow->TakeFocus(true, focusMethod)) aIsNewDocument = true;
|
if (aWindow->TakeFocus(true, focusMethod)) {
|
||||||
|
aIsNewDocument = true;
|
||||||
|
}
|
||||||
|
|
||||||
SetFocusedWindowInternal(aWindow);
|
SetFocusedWindowInternal(aWindow);
|
||||||
|
|
||||||
@ -1859,7 +1931,9 @@ void nsFocusManager::Focus(nsPIDOMWindowOuter* aWindow, Element* aElement,
|
|||||||
if (aElement) {
|
if (aElement) {
|
||||||
nsIFrame* contentFrame = aElement->GetPrimaryFrame();
|
nsIFrame* contentFrame = aElement->GetPrimaryFrame();
|
||||||
nsIObjectFrame* objectFrame = do_QueryFrame(contentFrame);
|
nsIObjectFrame* objectFrame = do_QueryFrame(contentFrame);
|
||||||
if (objectFrame) objectFrameWidget = objectFrame->GetWidget();
|
if (objectFrame) {
|
||||||
|
objectFrameWidget = objectFrame->GetWidget();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (aAdjustWidgets && !objectFrameWidget && !sTestMode) {
|
if (aAdjustWidgets && !objectFrameWidget && !sTestMode) {
|
||||||
if (nsViewManager* vm = presShell->GetViewManager()) {
|
if (nsViewManager* vm = presShell->GetViewManager()) {
|
||||||
@ -1898,21 +1972,26 @@ void nsFocusManager::Focus(nsPIDOMWindowOuter* aWindow, Element* aElement,
|
|||||||
mFocusedElement = aElement;
|
mFocusedElement = aElement;
|
||||||
|
|
||||||
nsIContent* focusedNode = aWindow->GetFocusedElement();
|
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 the focused element changed, scroll it into view
|
||||||
if (aElement && aFocusChanged) {
|
if (aElement && aFocusChanged) {
|
||||||
ScrollIntoView(presShell, aElement, aFlags);
|
ScrollIntoView(presShell, aElement, aFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sendFocusEvent = aElement && aElement->IsInComposedDoc() &&
|
|
||||||
!IsNonFocusableRoot(aElement);
|
|
||||||
nsPresContext* presContext = presShell->GetPresContext();
|
nsPresContext* presContext = presShell->GetPresContext();
|
||||||
if (sendFocusEvent) {
|
if (sendFocusEvent) {
|
||||||
NotifyFocusStateChange(aElement, nullptr, aWindow->ShouldShowFocusRing(),
|
NotifyFocusStateChange(aElement, nullptr, aFlags,
|
||||||
aFlags, /* aGettingFocus = */ true);
|
/* aGettingFocus = */ true, shouldShowFocusRing);
|
||||||
|
|
||||||
// if this is an object/plug-in/remote browser, focus its widget. Note
|
// 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
|
// 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
|
// as long as this focus wasn't because a window was raised, update the
|
||||||
// commands
|
// commands
|
||||||
// XXXndeakin P2 someone could adjust the focus during the update
|
// XXXndeakin P2 someone could adjust the focus during the update
|
||||||
if (!aWindowRaised)
|
if (!aWindowRaised) {
|
||||||
aWindow->UpdateCommands(u"focus"_ns, nullptr, 0);
|
aWindow->UpdateCommands(u"focus"_ns, nullptr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
SendFocusOrBlurEvent(eFocus, presShell, aElement->GetComposedDoc(),
|
SendFocusOrBlurEvent(
|
||||||
aElement, aFlags & FOCUSMETHOD_MASK, aWindowRaised,
|
eFocus, presShell, aElement->GetComposedDoc(), aElement,
|
||||||
isRefocus, aContentLostFocus);
|
aFlags & FOCUSMETHOD_MASK, aWindowRaised, isRefocus,
|
||||||
|
aBlurredElementInfo ? aBlurredElementInfo->mElement.get()
|
||||||
|
: nullptr);
|
||||||
} else {
|
} else {
|
||||||
IMEStateManager::OnChangeFocus(presContext, nullptr,
|
IMEStateManager::OnChangeFocus(presContext, nullptr,
|
||||||
GetFocusMoveActionCause(aFlags));
|
GetFocusMoveActionCause(aFlags));
|
||||||
@ -1969,7 +2051,9 @@ void nsFocusManager::Focus(nsPIDOMWindowOuter* aWindow, Element* aElement,
|
|||||||
GetFocusMoveActionCause(aFlags));
|
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
|
// 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,
|
UpdateCaret(aFocusChanged && !(aFlags & FLAG_BYMOUSE), aIsNewDocument,
|
||||||
mFocusedElement);
|
mFocusedElement);
|
||||||
|
|
||||||
if (clearFirstFocusEvent) mFirstFocusEvent = nullptr;
|
if (clearFirstFocusEvent) {
|
||||||
|
mFirstFocusEvent = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FocusBlurEvent : public Runnable {
|
class FocusBlurEvent : public Runnable {
|
||||||
@ -2217,10 +2303,14 @@ void nsFocusManager::RaiseWindow(nsPIDOMWindowOuter* aWindow) {
|
|||||||
nsCOMPtr<nsPIDOMWindowOuter> childWindow;
|
nsCOMPtr<nsPIDOMWindowOuter> childWindow;
|
||||||
GetFocusedDescendant(aWindow, eIncludeAllDescendants,
|
GetFocusedDescendant(aWindow, eIncludeAllDescendants,
|
||||||
getter_AddRefs(childWindow));
|
getter_AddRefs(childWindow));
|
||||||
if (!childWindow) childWindow = aWindow;
|
if (!childWindow) {
|
||||||
|
childWindow = aWindow;
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIDocShell> docShell = aWindow->GetDocShell();
|
nsCOMPtr<nsIDocShell> docShell = aWindow->GetDocShell();
|
||||||
if (!docShell) return;
|
if (!docShell) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
PresShell* presShell = docShell->GetPresShell();
|
PresShell* presShell = docShell->GetPresShell();
|
||||||
if (!presShell) {
|
if (!presShell) {
|
||||||
@ -2230,7 +2320,9 @@ void nsFocusManager::RaiseWindow(nsPIDOMWindowOuter* aWindow) {
|
|||||||
if (nsViewManager* vm = presShell->GetViewManager()) {
|
if (nsViewManager* vm = presShell->GetViewManager()) {
|
||||||
nsCOMPtr<nsIWidget> widget;
|
nsCOMPtr<nsIWidget> widget;
|
||||||
vm->GetRootWidget(getter_AddRefs(widget));
|
vm->GetRootWidget(getter_AddRefs(widget));
|
||||||
if (widget) widget->SetFocus(nsIWidget::Raise::Yes);
|
if (widget) {
|
||||||
|
widget->SetFocus(nsIWidget::Raise::Yes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
nsCOMPtr<nsIBaseWindow> treeOwnerAsWin =
|
nsCOMPtr<nsIBaseWindow> treeOwnerAsWin =
|
||||||
@ -2238,7 +2330,9 @@ void nsFocusManager::RaiseWindow(nsPIDOMWindowOuter* aWindow) {
|
|||||||
if (treeOwnerAsWin) {
|
if (treeOwnerAsWin) {
|
||||||
nsCOMPtr<nsIWidget> widget;
|
nsCOMPtr<nsIWidget> widget;
|
||||||
treeOwnerAsWin->GetMainWidget(getter_AddRefs(widget));
|
treeOwnerAsWin->GetMainWidget(getter_AddRefs(widget));
|
||||||
if (widget) widget->SetFocus(nsIWidget::Raise::Yes);
|
if (widget) {
|
||||||
|
widget->SetFocus(nsIWidget::Raise::Yes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -2251,7 +2345,9 @@ void nsFocusManager::UpdateCaret(bool aMoveCaretToFocus, bool aUpdateVisibility,
|
|||||||
nsIContent* aContent) {
|
nsIContent* aContent) {
|
||||||
LOGFOCUS(("Update Caret: %d %d", aMoveCaretToFocus, aUpdateVisibility));
|
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
|
// this is called when a document is focused or when the caretbrowsing
|
||||||
// preference is changed
|
// preference is changed
|
||||||
@ -2285,14 +2381,18 @@ void nsFocusManager::UpdateCaret(bool aMoveCaretToFocus, bool aUpdateVisibility,
|
|||||||
doc->GetEditingState() == Document::EditingState::eContentEditable;
|
doc->GetEditingState() == Document::EditingState::eContentEditable;
|
||||||
|
|
||||||
bool isFocusEditable = aContent && aContent->HasFlag(NODE_IS_EDITABLE);
|
bool isFocusEditable = aContent && aContent->HasFlag(NODE_IS_EDITABLE);
|
||||||
if (!isContentEditableDoc || isFocusEditable) return;
|
if (!isContentEditableDoc || isFocusEditable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isEditable && aMoveCaretToFocus) {
|
if (!isEditable && aMoveCaretToFocus) {
|
||||||
MoveCaretToFocus(presShell, aContent);
|
MoveCaretToFocus(presShell, aContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!aUpdateVisibility) return;
|
if (!aUpdateVisibility) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// XXXndeakin this doesn't seem right. It should be checking for this only
|
// 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
|
// 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
|
// 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.
|
// for bug 308025 where a window is closed in a blur handler.
|
||||||
RefPtr<nsCaret> caret = aPresShell->GetCaret();
|
RefPtr<nsCaret> caret = aPresShell->GetCaret();
|
||||||
if (!caret) return NS_OK;
|
if (!caret) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
bool caretVisible = caret->IsVisible();
|
bool caretVisible = caret->IsVisible();
|
||||||
if (!aVisible && !caretVisible) return NS_OK;
|
if (!aVisible && !caretVisible) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
RefPtr<nsFrameSelection> frameSelection;
|
RefPtr<nsFrameSelection> frameSelection;
|
||||||
if (aContent) {
|
if (aContent) {
|
||||||
NS_ASSERTION(aContent->GetComposedDoc() == aPresShell->GetDocument(),
|
NS_ASSERTION(aContent->GetComposedDoc() == aPresShell->GetDocument(),
|
||||||
"Wrong document?");
|
"Wrong document?");
|
||||||
nsIFrame* focusFrame = aContent->GetPrimaryFrame();
|
nsIFrame* focusFrame = aContent->GetPrimaryFrame();
|
||||||
if (focusFrame) frameSelection = focusFrame->GetFrameSelection();
|
if (focusFrame) {
|
||||||
|
frameSelection = focusFrame->GetFrameSelection();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<nsFrameSelection> docFrameSelection = aPresShell->FrameSelection();
|
RefPtr<nsFrameSelection> docFrameSelection = aPresShell->FrameSelection();
|
||||||
@ -2618,19 +2724,22 @@ nsresult nsFocusManager::DetermineElementToMoveFocus(
|
|||||||
int32_t tabIndex = forward ? 1 : 0;
|
int32_t tabIndex = forward ? 1 : 0;
|
||||||
if (startContent) {
|
if (startContent) {
|
||||||
nsIFrame* frame = startContent->GetPrimaryFrame();
|
nsIFrame* frame = startContent->GetPrimaryFrame();
|
||||||
if (startContent->IsHTMLElement(nsGkAtoms::area))
|
if (startContent->IsHTMLElement(nsGkAtoms::area)) {
|
||||||
startContent->IsFocusable(&tabIndex);
|
startContent->IsFocusable(&tabIndex);
|
||||||
else if (frame)
|
} else if (frame) {
|
||||||
frame->IsFocusable(&tabIndex, 0);
|
frame->IsFocusable(&tabIndex, 0);
|
||||||
else
|
} else {
|
||||||
startContent->IsFocusable(&tabIndex);
|
startContent->IsFocusable(&tabIndex);
|
||||||
|
}
|
||||||
|
|
||||||
// if the current element isn't tabbable, ignore the tabindex and just
|
// 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
|
// look for the next element. The root content won't have a tabindex
|
||||||
// so just treat this as the beginning of the tab order.
|
// so just treat this as the beginning of the tab order.
|
||||||
if (tabIndex < 0) {
|
if (tabIndex < 0) {
|
||||||
tabIndex = 1;
|
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
|
// 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
|
// if there is no focus, yet a panel is open, focus the first item in
|
||||||
// the panel
|
// the panel
|
||||||
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
||||||
if (pm) popupFrame = pm->GetTopPopup(ePopupTypePanel);
|
if (pm) {
|
||||||
|
popupFrame = pm->GetTopPopup(ePopupTypePanel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (popupFrame) {
|
if (popupFrame) {
|
||||||
@ -2813,7 +2924,9 @@ nsresult nsFocusManager::DetermineElementToMoveFocus(
|
|||||||
ignoreTabIndex = false;
|
ignoreTabIndex = false;
|
||||||
|
|
||||||
if (aNoParentTraversal) {
|
if (aNoParentTraversal) {
|
||||||
if (startContent == rootContent) return NS_OK;
|
if (startContent == rootContent) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
startContent = rootContent;
|
startContent = rootContent;
|
||||||
tabIndex = forward ? 1 : 0;
|
tabIndex = forward ? 1 : 0;
|
||||||
@ -2875,10 +2988,11 @@ nsresult nsFocusManager::DetermineElementToMoveFocus(
|
|||||||
// If the tree owner took the focus, blur the current element.
|
// If the tree owner took the focus, blur the current element.
|
||||||
if (tookFocus) {
|
if (tookFocus) {
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> window = docShell->GetWindow();
|
nsCOMPtr<nsPIDOMWindowOuter> window = docShell->GetWindow();
|
||||||
if (window->GetFocusedElement() == mFocusedElement)
|
if (window->GetFocusedElement() == mFocusedElement) {
|
||||||
Blur(mFocusedWindow, nullptr, true, true);
|
Blur(mFocusedWindow, nullptr, true, true);
|
||||||
else
|
} else {
|
||||||
window->SetFocusedElement(nullptr);
|
window->SetFocusedElement(nullptr);
|
||||||
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2911,7 +3025,9 @@ nsresult nsFocusManager::DetermineElementToMoveFocus(
|
|||||||
|
|
||||||
// wrapped all the way around and didn't find anything to move the focus
|
// wrapped all the way around and didn't find anything to move the focus
|
||||||
// to, so just break out
|
// to, so just break out
|
||||||
if (startContent == originalStartContent) break;
|
if (startContent == originalStartContent) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -3604,10 +3720,11 @@ nsresult nsFocusManager::GetNextTabbableContent(
|
|||||||
// and the end of the span, and the span would end up getting focused
|
// and the end of the span, and the span would end up getting focused
|
||||||
// again.
|
// again.
|
||||||
do {
|
do {
|
||||||
if (aForward)
|
if (aForward) {
|
||||||
frameTraversal->Next();
|
frameTraversal->Next();
|
||||||
else
|
} else {
|
||||||
frameTraversal->Prev();
|
frameTraversal->Prev();
|
||||||
|
}
|
||||||
frame = static_cast<nsIFrame*>(frameTraversal->CurrentItem());
|
frame = static_cast<nsIFrame*>(frameTraversal->CurrentItem());
|
||||||
} while (frame && frame->GetPrevContinuation());
|
} while (frame && frame->GetPrevContinuation());
|
||||||
}
|
}
|
||||||
@ -3708,7 +3825,9 @@ nsIContent* nsFocusManager::GetNextTabbableMapArea(bool aForward,
|
|||||||
MOZ_ASSERT(imgElement);
|
MOZ_ASSERT(imgElement);
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> mapContent = imgElement->FindImageMap();
|
nsCOMPtr<nsIContent> mapContent = imgElement->FindImageMap();
|
||||||
if (!mapContent) return nullptr;
|
if (!mapContent) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
uint32_t count = mapContent->GetChildCount();
|
uint32_t count = mapContent->GetChildCount();
|
||||||
// First see if the the start content is in this map
|
// First see if the the start content is in this map
|
||||||
|
|
||||||
@ -3976,7 +4095,9 @@ void nsFocusManager::GetFocusInSelection(nsPIDOMWindowOuter* aWindow,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectionNode == endSelectionNode) break;
|
if (selectionNode == endSelectionNode) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
testNode = selectionNode->GetNextSibling();
|
testNode = selectionNode->GetNextSibling();
|
||||||
if (testNode) {
|
if (testNode) {
|
||||||
selectionNode = testNode;
|
selectionNode = testNode;
|
||||||
@ -3997,7 +4118,9 @@ void nsFocusManager::GetFocusInSelection(nsPIDOMWindowOuter* aWindow,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
selectionNode = testNode->GetNextSibling();
|
selectionNode = testNode->GetNextSibling();
|
||||||
if (selectionNode) break;
|
if (selectionNode) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
selectionNode = testNode;
|
selectionNode = testNode;
|
||||||
} while (true);
|
} while (true);
|
||||||
} while (selectionNode && selectionNode != endSelectionNode);
|
} while (selectionNode && selectionNode != endSelectionNode);
|
||||||
|
@ -179,6 +179,53 @@ class nsFocusManager final : public nsIFocusManager,
|
|||||||
*/
|
*/
|
||||||
void ActivateRemoteFrameIfNeeded(mozilla::dom::Element&);
|
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(
|
static uint32_t FocusOptionsToFocusManagerFlags(
|
||||||
const mozilla::dom::FocusOptions& aOptions);
|
const mozilla::dom::FocusOptions& aOptions);
|
||||||
|
|
||||||
@ -203,6 +250,14 @@ class nsFocusManager final : public nsIFocusManager,
|
|||||||
|
|
||||||
static void MarkUncollectableForCCGeneration(uint32_t aGeneration);
|
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:
|
protected:
|
||||||
nsFocusManager();
|
nsFocusManager();
|
||||||
~nsFocusManager();
|
~nsFocusManager();
|
||||||
@ -311,7 +366,7 @@ class nsFocusManager final : public nsIFocusManager,
|
|||||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||||
bool Blur(nsPIDOMWindowOuter* aWindowToClear,
|
bool Blur(nsPIDOMWindowOuter* aWindowToClear,
|
||||||
nsPIDOMWindowOuter* aAncestorWindowToFocus, bool aIsLeavingDocument,
|
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.
|
* 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,
|
void Focus(nsPIDOMWindowOuter* aWindow, mozilla::dom::Element* aContent,
|
||||||
uint32_t aFlags, bool aIsNewDocument, bool aFocusChanged,
|
uint32_t aFlags, bool aIsNewDocument, bool aFocusChanged,
|
||||||
bool aWindowRaised, bool aAdjustWidget,
|
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
|
* 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,
|
void ScrollIntoView(mozilla::PresShell* aPresShell, nsIContent* aContent,
|
||||||
uint32_t aFlags);
|
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.
|
* Updates the caret positon and visibility to match the focus.
|
||||||
*
|
*
|
||||||
@ -616,18 +666,19 @@ class nsFocusManager final : public nsIFocusManager,
|
|||||||
nsIContent** aFocusedContent);
|
nsIContent** aFocusedContent);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Notify that the focus state of aContent has changed. Note that
|
// Notify that the focus state of aElement has changed. Note that we need to
|
||||||
// we need to pass in whether the window should show a focus ring
|
// pass in whether the window should show a focus ring before the
|
||||||
// before the SetFocusedNode call on it happened when losing focus
|
// SetFocusedNode call on it happened when losing focus and after the
|
||||||
// and after the SetFocusedNode call when gaining focus, which is
|
// SetFocusedNode call when gaining focus, which is why that information needs
|
||||||
// why that information needs to be an explicit argument instead of
|
// to be an explicit argument instead of just passing in the window and asking
|
||||||
// just passing in the window and asking it whether it should show
|
// it whether it should show focus rings: in the losing focus case that
|
||||||
// focus rings: in the losing focus case that information could be
|
// information could be wrong.
|
||||||
// wrong..
|
//
|
||||||
static void NotifyFocusStateChange(nsIContent* aContent,
|
// aShouldShowFocusRing is only relevant if aGettingFocus is true.
|
||||||
nsIContent* aContentToFocus,
|
static void NotifyFocusStateChange(mozilla::dom::Element* aElement,
|
||||||
bool aWindowShouldShowFocusRing,
|
mozilla::dom::Element* aElementToFocus,
|
||||||
int32_t aFlags, bool aGettingFocus);
|
int32_t aFlags, bool aGettingFocus,
|
||||||
|
bool aShouldShowFocusRing);
|
||||||
|
|
||||||
void SetFocusedWindowInternal(nsPIDOMWindowOuter* aWindow);
|
void SetFocusedWindowInternal(nsPIDOMWindowOuter* aWindow);
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
#include "nsIScrollableFrame.h"
|
#include "nsIScrollableFrame.h"
|
||||||
#include "nsSubDocumentFrame.h"
|
#include "nsSubDocumentFrame.h"
|
||||||
#include "nsError.h"
|
#include "nsError.h"
|
||||||
#include "nsIXULWindow.h"
|
#include "nsIAppWindow.h"
|
||||||
#include "nsIMozBrowserFrame.h"
|
#include "nsIMozBrowserFrame.h"
|
||||||
#include "nsIScriptError.h"
|
#include "nsIScriptError.h"
|
||||||
#include "nsGlobalWindow.h"
|
#include "nsGlobalWindow.h"
|
||||||
@ -427,11 +427,6 @@ void nsFrameLoader::LoadFrame(bool aOriginalSrc) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doc->IsLoadedAsInteractiveData()) {
|
|
||||||
// XBL bindings doc shouldn't load sub-documents.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIURI* base_uri = mOwnerContent->GetBaseURI();
|
nsIURI* base_uri = mOwnerContent->GetBaseURI();
|
||||||
auto encoding = doc->GetDocumentCharacterSet();
|
auto encoding = doc->GetDocumentCharacterSet();
|
||||||
|
|
||||||
@ -494,8 +489,8 @@ nsresult nsFrameLoader::LoadURI(nsIURI* aURI,
|
|||||||
|
|
||||||
void nsFrameLoader::ResumeLoad(uint64_t aPendingSwitchID) {
|
void nsFrameLoader::ResumeLoad(uint64_t aPendingSwitchID) {
|
||||||
Document* doc = mOwnerContent->OwnerDoc();
|
Document* doc = mOwnerContent->OwnerDoc();
|
||||||
if (doc->IsStaticDocument() || doc->IsLoadedAsInteractiveData()) {
|
if (doc->IsStaticDocument()) {
|
||||||
// Static & XBL bindings doc shouldn't load sub-documents.
|
// Static doc shouldn't load sub-documents.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2631,7 +2626,7 @@ bool nsFrameLoader::TryRemoteBrowser() {
|
|||||||
!parentOwner) {
|
!parentOwner) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
nsCOMPtr<nsIXULWindow> window(do_GetInterface(parentOwner));
|
nsCOMPtr<nsIAppWindow> window(do_GetInterface(parentOwner));
|
||||||
if (window && NS_FAILED(window->GetChromeFlags(&chromeFlags))) {
|
if (window && NS_FAILED(window->GetChromeFlags(&chromeFlags))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -235,7 +235,7 @@ nsresult nsSelectionCommandsBase::GetSelectionControllerFromWindow(
|
|||||||
// Helpers for nsSelectMoveScrollCommand and nsPhysicalSelectMoveScrollCommand
|
// Helpers for nsSelectMoveScrollCommand and nsPhysicalSelectMoveScrollCommand
|
||||||
static void AdjustFocusAfterCaretMove(nsPIDOMWindowOuter* aWindow) {
|
static void AdjustFocusAfterCaretMove(nsPIDOMWindowOuter* aWindow) {
|
||||||
// adjust the focus to the new caret position
|
// adjust the focus to the new caret position
|
||||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||||
if (fm) {
|
if (fm) {
|
||||||
RefPtr<dom::Element> result;
|
RefPtr<dom::Element> result;
|
||||||
fm->MoveFocus(aWindow, nullptr, nsIFocusManager::MOVEFOCUS_CARET,
|
fm->MoveFocus(aWindow, nullptr, nsIFocusManager::MOVEFOCUS_CARET,
|
||||||
|
@ -294,9 +294,6 @@
|
|||||||
# include "nsIWebBrowserPrint.h"
|
# include "nsIWebBrowserPrint.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "nsBindingManager.h"
|
|
||||||
#include "nsXBLService.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_SIDEBAR
|
#ifdef HAVE_SIDEBAR
|
||||||
# include "mozilla/dom/ExternalBinding.h"
|
# include "mozilla/dom/ExternalBinding.h"
|
||||||
#endif
|
#endif
|
||||||
@ -1110,13 +1107,6 @@ void nsGlobalWindowInner::ShutDown() {
|
|||||||
sInnerWindowsById = nullptr;
|
sInnerWindowsById = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
|
||||||
void nsGlobalWindowInner::CleanupCachedXBLHandlers() {
|
|
||||||
if (mCachedXBLPrototypeHandlers && mCachedXBLPrototypeHandlers->Count() > 0) {
|
|
||||||
mCachedXBLPrototypeHandlers->Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsGlobalWindowInner::FreeInnerObjects() {
|
void nsGlobalWindowInner::FreeInnerObjects() {
|
||||||
if (IsDying()) {
|
if (IsDying()) {
|
||||||
return;
|
return;
|
||||||
@ -1206,8 +1196,6 @@ void nsGlobalWindowInner::FreeInnerObjects() {
|
|||||||
|
|
||||||
NotifyWindowIDDestroyed("inner-window-destroyed");
|
NotifyWindowIDDestroyed("inner-window-destroyed");
|
||||||
|
|
||||||
CleanupCachedXBLHandlers();
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
|
for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
|
||||||
mAudioContexts[i]->Shutdown();
|
mAudioContexts[i]->Shutdown();
|
||||||
}
|
}
|
||||||
@ -1332,12 +1320,6 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsGlobalWindowInner)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
tmp->mCanSkipCCGeneration = nsCCUncollectableMarker::sGeneration;
|
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()) {
|
if (EventListenerManager* elm = tmp->GetExistingListenerManager()) {
|
||||||
elm->MarkForCC();
|
elm->MarkForCC();
|
||||||
}
|
}
|
||||||
@ -1473,8 +1455,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindowInner)
|
|||||||
JS::SetRealmNonLive(js::GetNonCCWObjectRealm(wrapper));
|
JS::SetRealmNonLive(js::GetNonCCWObjectRealm(wrapper));
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp->CleanupCachedXBLHandlers();
|
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mNavigator)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mNavigator)
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPerformance)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPerformance)
|
||||||
@ -1593,12 +1573,6 @@ void nsGlobalWindowInner::RiskyUnlink() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsGlobalWindowInner)
|
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_PRESERVED_WRAPPER
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||||
|
|
||||||
@ -2021,11 +1995,6 @@ nsresult nsGlobalWindowInner::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// Execute bindingdetached handlers before we tear ourselves
|
|
||||||
// down.
|
|
||||||
if (mDoc) {
|
|
||||||
mDoc->BindingManager()->ExecuteDetachedHandlers();
|
|
||||||
}
|
|
||||||
mIsDocumentLoaded = false;
|
mIsDocumentLoaded = false;
|
||||||
} else if (aVisitor.mEvent->mMessage == eLoad &&
|
} else if (aVisitor.mEvent->mMessage == eLoad &&
|
||||||
aVisitor.mEvent->IsTrusted()) {
|
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,
|
Element* nsGlobalWindowInner::GetFrameElement(nsIPrincipal& aSubjectPrincipal,
|
||||||
ErrorResult& aError) {
|
ErrorResult& aError) {
|
||||||
FORWARD_TO_OUTER_OR_THROW(GetFrameElementOuter, (aSubjectPrincipal), aError,
|
FORWARD_TO_OUTER_OR_THROW(GetFrameElementOuter, (aSubjectPrincipal), aError,
|
||||||
@ -4105,7 +4055,8 @@ void nsGlobalWindowInner::StopVRActivity() {
|
|||||||
|
|
||||||
void nsGlobalWindowInner::SetFocusedElement(Element* aElement,
|
void nsGlobalWindowInner::SetFocusedElement(Element* aElement,
|
||||||
uint32_t aFocusMethod,
|
uint32_t aFocusMethod,
|
||||||
bool aNeedsFocus) {
|
bool aNeedsFocus,
|
||||||
|
bool aWillShowOutline) {
|
||||||
if (aElement && aElement->GetComposedDoc() != mDoc) {
|
if (aElement && aElement->GetComposedDoc() != mDoc) {
|
||||||
NS_WARNING("Trying to set focus to a node from a wrong document");
|
NS_WARNING("Trying to set focus to a node from a wrong document");
|
||||||
return;
|
return;
|
||||||
@ -4115,13 +4066,17 @@ void nsGlobalWindowInner::SetFocusedElement(Element* aElement,
|
|||||||
NS_ASSERTION(!aElement, "Trying to focus cleaned up window!");
|
NS_ASSERTION(!aElement, "Trying to focus cleaned up window!");
|
||||||
aElement = nullptr;
|
aElement = nullptr;
|
||||||
aNeedsFocus = false;
|
aNeedsFocus = false;
|
||||||
|
aWillShowOutline = false;
|
||||||
}
|
}
|
||||||
if (mFocusedElement != aElement) {
|
if (mFocusedElement != aElement) {
|
||||||
UpdateCanvasFocus(false, aElement);
|
UpdateCanvasFocus(false, aElement);
|
||||||
mFocusedElement = aElement;
|
mFocusedElement = aElement;
|
||||||
|
// TODO: Maybe this should be set on refocus too?
|
||||||
mFocusMethod = aFocusMethod & FOCUSMETHOD_MASK;
|
mFocusMethod = aFocusMethod & FOCUSMETHOD_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mFocusedElementShowedOutlines = aWillShowOutline;
|
||||||
|
|
||||||
if (mFocusedElement) {
|
if (mFocusedElement) {
|
||||||
// if a node was focused by a keypress, turn on focus rings for the
|
// if a node was focused by a keypress, turn on focus rings for the
|
||||||
// window.
|
// window.
|
||||||
@ -4130,7 +4085,9 @@ void nsGlobalWindowInner::SetFocusedElement(Element* aElement,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aNeedsFocus) mNeedsFocus = aNeedsFocus;
|
if (aNeedsFocus) {
|
||||||
|
mNeedsFocus = aNeedsFocus;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t nsGlobalWindowInner::GetFocusMethod() { return mFocusMethod; }
|
uint32_t nsGlobalWindowInner::GetFocusMethod() { return mFocusMethod; }
|
||||||
@ -4175,7 +4132,7 @@ void nsGlobalWindowInner::SetReadyForFocus() {
|
|||||||
bool oldNeedsFocus = mNeedsFocus;
|
bool oldNeedsFocus = mNeedsFocus;
|
||||||
mNeedsFocus = false;
|
mNeedsFocus = false;
|
||||||
|
|
||||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||||
if (fm) {
|
if (fm) {
|
||||||
fm->WindowShown(GetOuterWindow(), oldNeedsFocus);
|
fm->WindowShown(GetOuterWindow(), oldNeedsFocus);
|
||||||
}
|
}
|
||||||
@ -4186,7 +4143,7 @@ void nsGlobalWindowInner::PageHidden() {
|
|||||||
// no longer valid. Use the persisted field to determine if the document
|
// no longer valid. Use the persisted field to determine if the document
|
||||||
// is being destroyed.
|
// is being destroyed.
|
||||||
|
|
||||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||||
if (fm) {
|
if (fm) {
|
||||||
fm->WindowHidden(GetOuterWindow());
|
fm->WindowHidden(GetOuterWindow());
|
||||||
}
|
}
|
||||||
@ -7020,6 +6977,14 @@ mozilla::dom::TabGroup* nsGlobalWindowInner::TabGroupInner() {
|
|||||||
return tabGroup;
|
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(
|
nsresult nsGlobalWindowInner::Dispatch(
|
||||||
TaskCategory aCategory, already_AddRefed<nsIRunnable>&& aRunnable) {
|
TaskCategory aCategory, already_AddRefed<nsIRunnable>&& aRunnable) {
|
||||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||||
|
@ -452,8 +452,6 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
|||||||
static void ShutDown();
|
static void ShutDown();
|
||||||
static bool IsCallerChrome();
|
static bool IsCallerChrome();
|
||||||
|
|
||||||
void CleanupCachedXBLHandlers();
|
|
||||||
|
|
||||||
friend class WindowStateHolder;
|
friend class WindowStateHolder;
|
||||||
|
|
||||||
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(
|
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(
|
||||||
@ -465,12 +463,6 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
|||||||
void RiskyUnlink();
|
void RiskyUnlink();
|
||||||
#endif
|
#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 bool TakeFocus(bool aFocus, uint32_t aFocusMethod) override;
|
||||||
virtual void SetReadyForFocus() override;
|
virtual void SetReadyForFocus() override;
|
||||||
virtual void PageHidden() 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,
|
int32_t aSx, int32_t aSy, int32_t aSw, int32_t aSh,
|
||||||
mozilla::ErrorResult& aRv);
|
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
|
// ChromeWindow bits. Do NOT call these unless your window is in
|
||||||
// fact chrome.
|
// fact chrome.
|
||||||
uint16_t WindowState();
|
uint16_t WindowState();
|
||||||
@ -1122,13 +1119,13 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
|||||||
|
|
||||||
bool IsInModalState();
|
bool IsInModalState();
|
||||||
|
|
||||||
virtual void SetFocusedElement(mozilla::dom::Element* aElement,
|
void SetFocusedElement(mozilla::dom::Element* aElement,
|
||||||
uint32_t aFocusMethod = 0,
|
uint32_t aFocusMethod = 0, bool aNeedsFocus = false,
|
||||||
bool aNeedsFocus = false) override;
|
bool aWillShowOutline = false) override;
|
||||||
|
|
||||||
virtual uint32_t GetFocusMethod() override;
|
uint32_t GetFocusMethod() override;
|
||||||
|
|
||||||
virtual bool ShouldShowFocusRing() override;
|
bool ShouldShowFocusRing() override;
|
||||||
|
|
||||||
// Inner windows only.
|
// Inner windows only.
|
||||||
void UpdateCanvasFocus(bool aFocusChanged, nsIContent* aNewContent);
|
void UpdateCanvasFocus(bool aFocusChanged, nsIContent* aNewContent);
|
||||||
@ -1364,7 +1361,7 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
|||||||
uint32_t mSerial;
|
uint32_t mSerial;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// the method that was used to focus mFocusedNode
|
// the method that was used to focus mFocusedElement
|
||||||
uint32_t mFocusMethod;
|
uint32_t mFocusMethod;
|
||||||
|
|
||||||
// The current idle request callback handle
|
// The current idle request callback handle
|
||||||
@ -1378,10 +1375,6 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
|||||||
|
|
||||||
RefPtr<nsDOMOfflineResourceList> mApplicationCache;
|
RefPtr<nsDOMOfflineResourceList> mApplicationCache;
|
||||||
|
|
||||||
using XBLPrototypeHandlerTable =
|
|
||||||
nsJSThingHashtable<nsPtrHashKey<nsXBLPrototypeHandler>, JSObject*>;
|
|
||||||
mozilla::UniquePtr<XBLPrototypeHandlerTable> mCachedXBLPrototypeHandlers;
|
|
||||||
|
|
||||||
RefPtr<mozilla::dom::IDBFactory> mIndexedDB;
|
RefPtr<mozilla::dom::IDBFactory> mIndexedDB;
|
||||||
|
|
||||||
// This counts the number of windows that have been opened in rapid succession
|
// 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.
|
// 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.
|
// All accesses to this field should be guarded by a check of mIsChrome.
|
||||||
struct ChromeFields {
|
struct ChromeFields {
|
||||||
ChromeFields() : mGroupMessageManagers(1) {}
|
|
||||||
|
|
||||||
RefPtr<mozilla::dom::ChromeMessageBroadcaster> mMessageManager;
|
RefPtr<mozilla::dom::ChromeMessageBroadcaster> mMessageManager;
|
||||||
nsRefPtrHashtable<nsStringHashKey, mozilla::dom::ChromeMessageBroadcaster>
|
nsRefPtrHashtable<nsStringHashKey, mozilla::dom::ChromeMessageBroadcaster>
|
||||||
mGroupMessageManagers;
|
mGroupMessageManagers{1};
|
||||||
} mChromeFields;
|
} mChromeFields;
|
||||||
|
|
||||||
// These fields are used by the inner and outer windows to prevent
|
// These fields are used by the inner and outer windows to prevent
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "nsISecureBrowserUI.h"
|
#include "nsISecureBrowserUI.h"
|
||||||
#include "nsIWebProgressListener.h"
|
#include "nsIWebProgressListener.h"
|
||||||
#include "mozilla/AntiTrackingCommon.h"
|
#include "mozilla/AntiTrackingCommon.h"
|
||||||
|
#include "mozilla/dom/BrowserChild.h"
|
||||||
#include "mozilla/dom/BindingUtils.h"
|
#include "mozilla/dom/BindingUtils.h"
|
||||||
#include "mozilla/dom/BrowsingContextBinding.h"
|
#include "mozilla/dom/BrowsingContextBinding.h"
|
||||||
#include "mozilla/dom/ContentFrameMessageManager.h"
|
#include "mozilla/dom/ContentFrameMessageManager.h"
|
||||||
@ -140,6 +141,7 @@
|
|||||||
#include "nsDOMWindowUtils.h"
|
#include "nsDOMWindowUtils.h"
|
||||||
#include "nsIWindowWatcher.h"
|
#include "nsIWindowWatcher.h"
|
||||||
#include "nsPIWindowWatcher.h"
|
#include "nsPIWindowWatcher.h"
|
||||||
|
#include "nsIAppWindow.h"
|
||||||
#include "nsIContentViewer.h"
|
#include "nsIContentViewer.h"
|
||||||
#include "nsIScriptError.h"
|
#include "nsIScriptError.h"
|
||||||
#include "nsIControllers.h"
|
#include "nsIControllers.h"
|
||||||
@ -153,7 +155,6 @@
|
|||||||
#include "mozilla/EventStateManager.h"
|
#include "mozilla/EventStateManager.h"
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
#include "nsFocusManager.h"
|
#include "nsFocusManager.h"
|
||||||
#include "nsIXULWindow.h"
|
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "mozilla/dom/CustomEvent.h"
|
#include "mozilla/dom/CustomEvent.h"
|
||||||
#include "nsIScreenManager.h"
|
#include "nsIScreenManager.h"
|
||||||
@ -171,11 +172,8 @@
|
|||||||
#include "nsNetCID.h"
|
#include "nsNetCID.h"
|
||||||
#include "nsIArray.h"
|
#include "nsIArray.h"
|
||||||
|
|
||||||
#include "XULDocument.h"
|
|
||||||
#include "nsIDOMXULCommandDispatcher.h"
|
#include "nsIDOMXULCommandDispatcher.h"
|
||||||
|
|
||||||
#include "nsBindingManager.h"
|
|
||||||
#include "nsXBLService.h"
|
|
||||||
#include "mozilla/GlobalKeyListener.h"
|
#include "mozilla/GlobalKeyListener.h"
|
||||||
|
|
||||||
#include "nsIDragService.h"
|
#include "nsIDragService.h"
|
||||||
@ -1766,7 +1764,7 @@ void nsGlobalWindowOuter::SetInitialPrincipalToSubject(
|
|||||||
// We should never create windows with an expanded principal.
|
// 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
|
// If we have a system principal, make sure we're not using it for a content
|
||||||
// docshell.
|
// 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) ||
|
if (nsContentUtils::IsExpandedPrincipal(newWindowPrincipal) ||
|
||||||
(newWindowPrincipal->IsSystemPrincipal() &&
|
(newWindowPrincipal->IsSystemPrincipal() &&
|
||||||
GetDocShell()->ItemType() != nsIDocShellTreeItem::typeChrome)) {
|
GetDocShell()->ItemType() != nsIDocShellTreeItem::typeChrome)) {
|
||||||
@ -3557,42 +3555,55 @@ void nsGlobalWindowOuter::SetNameOuter(const nsAString& aName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper functions used by many methods below.
|
// Helper functions used by many methods below.
|
||||||
int32_t nsGlobalWindowOuter::DevToCSSIntPixels(int32_t px) {
|
int32_t nsGlobalWindowOuter::DevToCSSIntPixelsForBaseWindow(
|
||||||
if (!mDocShell) return px; // assume 1:1
|
int32_t aDevicePixels, nsIBaseWindow* aWindow) {
|
||||||
|
MOZ_ASSERT(aWindow);
|
||||||
RefPtr<nsPresContext> presContext = mDocShell->GetPresContext();
|
double scale;
|
||||||
if (!presContext) return px;
|
aWindow->GetUnscaledDevicePixelsPerCSSPixel(&scale);
|
||||||
|
double zoom = 1.0;
|
||||||
return presContext->DevPixelsToIntCSSPixels(px);
|
if (mDocShell && mDocShell->GetPresContext()) {
|
||||||
|
zoom = mDocShell->GetPresContext()->GetFullZoom();
|
||||||
|
}
|
||||||
|
return std::floor(aDevicePixels / scale / zoom + 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t nsGlobalWindowOuter::CSSToDevIntPixels(int32_t px) {
|
nsIntSize nsGlobalWindowOuter::DevToCSSIntPixelsForBaseWindow(
|
||||||
if (!mDocShell) return px; // assume 1:1
|
nsIntSize aDeviceSize, nsIBaseWindow* aWindow) {
|
||||||
|
MOZ_ASSERT(aWindow);
|
||||||
RefPtr<nsPresContext> presContext = mDocShell->GetPresContext();
|
double scale;
|
||||||
if (!presContext) return px;
|
aWindow->GetUnscaledDevicePixelsPerCSSPixel(&scale);
|
||||||
|
double zoom = 1.0;
|
||||||
return presContext->CSSPixelsToDevPixels(px);
|
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) {
|
int32_t nsGlobalWindowOuter::CSSToDevIntPixelsForBaseWindow(
|
||||||
if (!mDocShell) return px; // assume 1:1
|
int32_t aCSSPixels, nsIBaseWindow* aWindow) {
|
||||||
|
MOZ_ASSERT(aWindow);
|
||||||
RefPtr<nsPresContext> presContext = mDocShell->GetPresContext();
|
double scale;
|
||||||
if (!presContext) return px;
|
aWindow->GetUnscaledDevicePixelsPerCSSPixel(&scale);
|
||||||
|
double zoom = 1.0;
|
||||||
return nsIntSize(presContext->DevPixelsToIntCSSPixels(px.width),
|
if (mDocShell && mDocShell->GetPresContext()) {
|
||||||
presContext->DevPixelsToIntCSSPixels(px.height));
|
zoom = mDocShell->GetPresContext()->GetFullZoom();
|
||||||
|
}
|
||||||
|
return std::floor(aCSSPixels * scale * zoom + 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIntSize nsGlobalWindowOuter::CSSToDevIntPixels(nsIntSize px) {
|
nsIntSize nsGlobalWindowOuter::CSSToDevIntPixelsForBaseWindow(
|
||||||
if (!mDocShell) return px; // assume 1:1
|
nsIntSize aCSSSize, nsIBaseWindow* aWindow) {
|
||||||
|
MOZ_ASSERT(aWindow);
|
||||||
RefPtr<nsPresContext> presContext = mDocShell->GetPresContext();
|
double scale;
|
||||||
if (!presContext) return px;
|
aWindow->GetUnscaledDevicePixelsPerCSSPixel(&scale);
|
||||||
|
double zoom = 1.0;
|
||||||
return nsIntSize(presContext->CSSPixelsToDevPixels(px.width),
|
if (mDocShell && mDocShell->GetPresContext()) {
|
||||||
presContext->CSSPixelsToDevPixels(px.height));
|
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) {
|
nsresult nsGlobalWindowOuter::GetInnerSize(CSSIntSize& aSize) {
|
||||||
@ -3608,12 +3619,6 @@ nsresult nsGlobalWindowOuter::GetInnerSize(CSSIntSize& aSize) {
|
|||||||
return NS_OK;
|
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
|
// Whether or not the css viewport has been overridden, we can get the
|
||||||
// correct value by looking at the visible area of the presContext.
|
// correct value by looking at the visible area of the presContext.
|
||||||
RefPtr<nsViewManager> viewManager = presShell->GetViewManager();
|
RefPtr<nsViewManager> viewManager = presShell->GetViewManager();
|
||||||
@ -3646,24 +3651,8 @@ void nsGlobalWindowOuter::SetInnerWidthOuter(int32_t aInnerWidth,
|
|||||||
CheckSecurityWidthAndHeight(&aInnerWidth, nullptr, aCallerType);
|
CheckSecurityWidthAndHeight(&aInnerWidth, nullptr, aCallerType);
|
||||||
RefPtr<PresShell> presShell = mDocShell->GetPresShell();
|
RefPtr<PresShell> presShell = mDocShell->GetPresShell();
|
||||||
|
|
||||||
// Setting inner width should set the visual viewport. Most of the
|
// Setting inner width should set the CSS viewport. If the CSS viewport
|
||||||
// time, this is the same as the CSS viewport, and when we set one,
|
// has been overridden, change the override.
|
||||||
// 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().
|
|
||||||
if (presShell && presShell->GetIsViewportOverridden()) {
|
if (presShell && presShell->GetIsViewportOverridden()) {
|
||||||
nscoord height = 0;
|
nscoord height = 0;
|
||||||
|
|
||||||
@ -3677,14 +3666,14 @@ void nsGlobalWindowOuter::SetInnerWidthOuter(int32_t aInnerWidth,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nothing has been overriden, so change the docshell itself, which will
|
// Nothing has been overriden, so change the docshell itself.
|
||||||
// affect both viewports.
|
|
||||||
int32_t height = 0;
|
int32_t height = 0;
|
||||||
int32_t unused = 0;
|
int32_t unused = 0;
|
||||||
|
|
||||||
nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(mDocShell));
|
nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(mDocShell));
|
||||||
docShellAsWin->GetSize(&unused, &height);
|
docShellAsWin->GetSize(&unused, &height);
|
||||||
aError = SetDocShellWidthAndHeight(CSSToDevIntPixels(aInnerWidth), height);
|
aError = SetDocShellWidthAndHeight(
|
||||||
|
CSSToDevIntPixelsForBaseWindow(aInnerWidth, docShellAsWin), height);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t nsGlobalWindowOuter::GetInnerHeightOuter(ErrorResult& aError) {
|
int32_t nsGlobalWindowOuter::GetInnerHeightOuter(ErrorResult& aError) {
|
||||||
@ -3708,24 +3697,8 @@ void nsGlobalWindowOuter::SetInnerHeightOuter(int32_t aInnerHeight,
|
|||||||
CheckSecurityWidthAndHeight(nullptr, &aInnerHeight, aCallerType);
|
CheckSecurityWidthAndHeight(nullptr, &aInnerHeight, aCallerType);
|
||||||
RefPtr<PresShell> presShell = mDocShell->GetPresShell();
|
RefPtr<PresShell> presShell = mDocShell->GetPresShell();
|
||||||
|
|
||||||
// Setting inner height should set the visual viewport. Most of the
|
// Setting inner height should set the CSS viewport. If the CSS viewport
|
||||||
// time, this is the same as the CSS viewport, and when we set one,
|
// has been overridden, change the override.
|
||||||
// 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().
|
|
||||||
if (presShell && presShell->GetIsViewportOverridden()) {
|
if (presShell && presShell->GetIsViewportOverridden()) {
|
||||||
nscoord width = 0;
|
nscoord width = 0;
|
||||||
|
|
||||||
@ -3739,14 +3712,14 @@ void nsGlobalWindowOuter::SetInnerHeightOuter(int32_t aInnerHeight,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nothing has been overriden, so change the docshell itself, which will
|
// Nothing has been overriden, so change the docshell itself.
|
||||||
// affect both viewports.
|
|
||||||
int32_t height = 0;
|
int32_t height = 0;
|
||||||
int32_t width = 0;
|
int32_t width = 0;
|
||||||
|
|
||||||
nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(mDocShell));
|
nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(mDocShell));
|
||||||
docShellAsWin->GetSize(&width, &height);
|
docShellAsWin->GetSize(&width, &height);
|
||||||
aError = SetDocShellWidthAndHeight(width, CSSToDevIntPixels(aInnerHeight));
|
aError = SetDocShellWidthAndHeight(
|
||||||
|
width, CSSToDevIntPixelsForBaseWindow(aInnerHeight, docShellAsWin));
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIntSize nsGlobalWindowOuter::GetOuterSize(CallerType aCallerType,
|
nsIntSize nsGlobalWindowOuter::GetOuterSize(CallerType aCallerType,
|
||||||
@ -3757,23 +3730,13 @@ nsIntSize nsGlobalWindowOuter::GetOuterSize(CallerType aCallerType,
|
|||||||
return nsIntSize(size.width, size.height);
|
return nsIntSize(size.width, size.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDoc && mDoc->InRDMPane()) {
|
// Windows showing documents in RDM panes and any subframes within them
|
||||||
CSSIntSize size;
|
// return the simulated device size.
|
||||||
aError = GetInnerSize(size);
|
if (mDoc) {
|
||||||
|
Maybe<CSSIntSize> deviceSize = GetRDMDeviceSize(*mDoc);
|
||||||
// Obtain the current zoom of the presentation shell. The zoom value will
|
if (deviceSize.isSome()) {
|
||||||
// be used to scale the size of the visual viewport to the device browser's
|
const CSSIntSize& size = deviceSize.value();
|
||||||
// outer size values. Once RDM no longer relies on the having the page
|
return nsIntSize(size.width, size.height);
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3789,7 +3752,7 @@ nsIntSize nsGlobalWindowOuter::GetOuterSize(CallerType aCallerType,
|
|||||||
return nsIntSize();
|
return nsIntSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
return DevToCSSIntPixels(sizeDevPixels);
|
return DevToCSSIntPixelsForBaseWindow(sizeDevPixels, treeOwnerAsWin);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t nsGlobalWindowOuter::GetOuterWidthOuter(CallerType aCallerType,
|
int32_t nsGlobalWindowOuter::GetOuterWidthOuter(CallerType aCallerType,
|
||||||
@ -3821,7 +3784,8 @@ void nsGlobalWindowOuter::SetOuterSize(int32_t aLengthCSSPixels, bool aIsWidth,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t lengthDevPixels = CSSToDevIntPixels(aLengthCSSPixels);
|
int32_t lengthDevPixels =
|
||||||
|
CSSToDevIntPixelsForBaseWindow(aLengthCSSPixels, treeOwnerAsWin);
|
||||||
if (aIsWidth) {
|
if (aIsWidth) {
|
||||||
width = lengthDevPixels;
|
width = lengthDevPixels;
|
||||||
} else {
|
} else {
|
||||||
@ -3915,6 +3879,41 @@ nsRect nsGlobalWindowOuter::GetInnerScreenRect() {
|
|||||||
return rootFrame->GetScreenRectInAppUnits();
|
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) {
|
float nsGlobalWindowOuter::GetMozInnerScreenXOuter(CallerType aCallerType) {
|
||||||
// When resisting fingerprinting, always return 0.
|
// When resisting fingerprinting, always return 0.
|
||||||
if (nsContentUtils::ResistFingerprinting(aCallerType)) {
|
if (nsContentUtils::ResistFingerprinting(aCallerType)) {
|
||||||
@ -3990,7 +3989,7 @@ void nsGlobalWindowOuter::SetScreenXOuter(int32_t aScreenX,
|
|||||||
}
|
}
|
||||||
|
|
||||||
CheckSecurityLeftAndTop(&aScreenX, nullptr, aCallerType);
|
CheckSecurityLeftAndTop(&aScreenX, nullptr, aCallerType);
|
||||||
x = CSSToDevIntPixels(aScreenX);
|
x = CSSToDevIntPixelsForBaseWindow(aScreenX, treeOwnerAsWin);
|
||||||
|
|
||||||
aError = treeOwnerAsWin->SetPosition(x, y);
|
aError = treeOwnerAsWin->SetPosition(x, y);
|
||||||
|
|
||||||
@ -4018,7 +4017,7 @@ void nsGlobalWindowOuter::SetScreenYOuter(int32_t aScreenY,
|
|||||||
}
|
}
|
||||||
|
|
||||||
CheckSecurityLeftAndTop(nullptr, &aScreenY, aCallerType);
|
CheckSecurityLeftAndTop(nullptr, &aScreenY, aCallerType);
|
||||||
y = CSSToDevIntPixels(aScreenY);
|
y = CSSToDevIntPixelsForBaseWindow(aScreenY, treeOwnerAsWin);
|
||||||
|
|
||||||
aError = treeOwnerAsWin->SetPosition(x, y);
|
aError = treeOwnerAsWin->SetPosition(x, y);
|
||||||
|
|
||||||
@ -4105,22 +4104,23 @@ void nsGlobalWindowOuter::CheckSecurityLeftAndTop(int32_t* aLeft, int32_t* aTop,
|
|||||||
rootWindow->FlushPendingNotifications(FlushType::Layout);
|
rootWindow->FlushPendingNotifications(FlushType::Layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIBaseWindow> treeOwner = GetTreeOwnerWindow();
|
nsCOMPtr<nsIBaseWindow> treeOwnerAsWin = GetTreeOwnerWindow();
|
||||||
|
|
||||||
RefPtr<nsScreen> screen = GetScreen();
|
RefPtr<nsScreen> screen = GetScreen();
|
||||||
|
|
||||||
if (treeOwner && screen) {
|
if (treeOwnerAsWin && screen) {
|
||||||
int32_t winLeft, winTop, winWidth, winHeight;
|
int32_t winLeft, winTop, winWidth, winHeight;
|
||||||
|
|
||||||
// Get the window size
|
// Get the window size
|
||||||
treeOwner->GetPositionAndSize(&winLeft, &winTop, &winWidth, &winHeight);
|
treeOwnerAsWin->GetPositionAndSize(&winLeft, &winTop, &winWidth,
|
||||||
|
&winHeight);
|
||||||
|
|
||||||
// convert those values to CSS pixels
|
// convert those values to CSS pixels
|
||||||
// XXX four separate retrievals of the prescontext
|
// XXX four separate retrievals of the prescontext
|
||||||
winLeft = DevToCSSIntPixels(winLeft);
|
winLeft = DevToCSSIntPixelsForBaseWindow(winLeft, treeOwnerAsWin);
|
||||||
winTop = DevToCSSIntPixels(winTop);
|
winTop = DevToCSSIntPixelsForBaseWindow(winTop, treeOwnerAsWin);
|
||||||
winWidth = DevToCSSIntPixels(winWidth);
|
winWidth = DevToCSSIntPixelsForBaseWindow(winWidth, treeOwnerAsWin);
|
||||||
winHeight = DevToCSSIntPixels(winHeight);
|
winHeight = DevToCSSIntPixelsForBaseWindow(winHeight, treeOwnerAsWin);
|
||||||
|
|
||||||
// Get the screen dimensions
|
// Get the screen dimensions
|
||||||
// XXX This should use nsIScreenManager once it's fully fleshed out.
|
// 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
|
// Prevent chrome documents which are still loading from resizing
|
||||||
// the window after we set fullscreen mode.
|
// the window after we set fullscreen mode.
|
||||||
nsCOMPtr<nsIBaseWindow> treeOwnerAsWin = GetTreeOwnerWindow();
|
nsCOMPtr<nsIBaseWindow> treeOwnerAsWin = GetTreeOwnerWindow();
|
||||||
nsCOMPtr<nsIXULWindow> xulWin(do_GetInterface(treeOwnerAsWin));
|
nsCOMPtr<nsIAppWindow> appWin(do_GetInterface(treeOwnerAsWin));
|
||||||
if (aFullscreen && xulWin) {
|
if (aFullscreen && appWin) {
|
||||||
xulWin->SetIntrinsicallySized(false);
|
appWin->SetIntrinsicallySized(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set this before so if widget sends an event indicating its
|
// 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
|
// 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 if canFocus is true. If this is a child process, the raise
|
||||||
// window request will get forwarded to the parent by the puppet widget.
|
// window request will get forwarded to the parent by the puppet widget.
|
||||||
DebugOnly<nsresult> rv = fm->SetActiveWindow(this);
|
fm->RaiseWindow(this);
|
||||||
MOZ_ASSERT(NS_SUCCEEDED(rv),
|
|
||||||
"SetActiveWindow only fails if passed null or a non-toplevel "
|
|
||||||
"window, which is not the case here.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5187,7 +5184,7 @@ void nsGlobalWindowOuter::BlurOuter() {
|
|||||||
siteWindow->Blur();
|
siteWindow->Blur();
|
||||||
|
|
||||||
// if the root is focused, clear the focus
|
// if the root is focused, clear the focus
|
||||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||||
if (fm && mDoc) {
|
if (fm && mDoc) {
|
||||||
RefPtr<Element> element;
|
RefPtr<Element> element;
|
||||||
fm->GetFocusedElementForWindow(this, false, nullptr,
|
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
|
// 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.width += aXDif;
|
||||||
cssPos.height += aYDif;
|
cssPos.height += aYDif;
|
||||||
|
|
||||||
CheckSecurityLeftAndTop(&cssPos.width, &cssPos.height, aCallerType);
|
CheckSecurityLeftAndTop(&cssPos.width, &cssPos.height, aCallerType);
|
||||||
|
|
||||||
nsIntSize newDevPos(CSSToDevIntPixels(cssPos));
|
nsIntSize newDevPos(CSSToDevIntPixelsForBaseWindow(cssPos, treeOwnerAsWin));
|
||||||
|
|
||||||
aError = treeOwnerAsWin->SetPosition(newDevPos.width, newDevPos.height);
|
aError = treeOwnerAsWin->SetPosition(newDevPos.width, newDevPos.height);
|
||||||
|
|
||||||
@ -5415,7 +5413,7 @@ void nsGlobalWindowOuter::ResizeToOuter(int32_t aWidth, int32_t aHeight,
|
|||||||
nsIntSize cssSize(aWidth, aHeight);
|
nsIntSize cssSize(aWidth, aHeight);
|
||||||
CheckSecurityWidthAndHeight(&cssSize.width, &cssSize.height, aCallerType);
|
CheckSecurityWidthAndHeight(&cssSize.width, &cssSize.height, aCallerType);
|
||||||
|
|
||||||
nsIntSize devSz(CSSToDevIntPixels(cssSize));
|
nsIntSize devSz(CSSToDevIntPixelsForBaseWindow(cssSize, treeOwnerAsWin));
|
||||||
|
|
||||||
aError = treeOwnerAsWin->SetSize(devSz.width, devSz.height, true);
|
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
|
// into CSS pixels, add the arguments, do the security check, and
|
||||||
// then convert back to device pixels for the call to SetSize.
|
// 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.width += aWidthDif;
|
||||||
cssSize.height += aHeightDif;
|
cssSize.height += aHeightDif;
|
||||||
|
|
||||||
CheckSecurityWidthAndHeight(&cssSize.width, &cssSize.height, aCallerType);
|
CheckSecurityWidthAndHeight(&cssSize.width, &cssSize.height, aCallerType);
|
||||||
|
|
||||||
nsIntSize newDevSize(CSSToDevIntPixels(cssSize));
|
nsIntSize newDevSize(CSSToDevIntPixelsForBaseWindow(cssSize, treeOwnerAsWin));
|
||||||
|
|
||||||
aError = treeOwnerAsWin->SetSize(newDevSize.width, newDevSize.height, true);
|
aError = treeOwnerAsWin->SetSize(newDevSize.width, newDevSize.height, true);
|
||||||
|
|
||||||
@ -5488,8 +5487,8 @@ void nsGlobalWindowOuter::SizeToContentOuter(CallerType aCallerType,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t width, height;
|
nsIntSize contentSize;
|
||||||
aError = cv->GetContentSize(&width, &height);
|
aError = cv->GetContentSize(&contentSize.width, &contentSize.height);
|
||||||
if (aError.Failed()) {
|
if (aError.Failed()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -5502,10 +5501,21 @@ void nsGlobalWindowOuter::SizeToContentOuter(CallerType aCallerType,
|
|||||||
return;
|
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);
|
CheckSecurityWidthAndHeight(&cssSize.width, &cssSize.height, aCallerType);
|
||||||
|
|
||||||
nsIntSize newDevSize(CSSToDevIntPixels(cssSize));
|
nsIntSize newDevSize(presContext->CSSPixelsToDevPixels(cssSize.width),
|
||||||
|
presContext->CSSPixelsToDevPixels(cssSize.height));
|
||||||
|
|
||||||
nsCOMPtr<nsIDocShell> docShell = mDocShell;
|
nsCOMPtr<nsIDocShell> docShell = mDocShell;
|
||||||
aError =
|
aError =
|
||||||
@ -6050,7 +6060,7 @@ bool nsGlobalWindowOuter::GatherPostMessageData(
|
|||||||
if (!callerPrin->IsSystemPrincipal()) {
|
if (!callerPrin->IsSystemPrincipal()) {
|
||||||
nsAutoCString asciiOrigin;
|
nsAutoCString asciiOrigin;
|
||||||
callerPrin->GetAsciiOrigin(asciiOrigin);
|
callerPrin->GetAsciiOrigin(asciiOrigin);
|
||||||
aOrigin = NS_ConvertUTF8toUTF16(asciiOrigin);
|
CopyUTF8toUTF16(asciiOrigin, aOrigin);
|
||||||
} else if (callerInnerWin) {
|
} else if (callerInnerWin) {
|
||||||
if (!*aCallerDocumentURI) {
|
if (!*aCallerDocumentURI) {
|
||||||
return false;
|
return false;
|
||||||
@ -6916,10 +6926,10 @@ void nsGlobalWindowOuter::ActivateOrDeactivate(bool aActivate) {
|
|||||||
// Get the top level widget's nsGlobalWindowOuter
|
// Get the top level widget's nsGlobalWindowOuter
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> topLevelWindow;
|
nsCOMPtr<nsPIDOMWindowOuter> topLevelWindow;
|
||||||
|
|
||||||
// widgetListener should be a nsXULWindow
|
// widgetListener should be an AppWindow
|
||||||
nsIWidgetListener* listener = topLevelWidget->GetWidgetListener();
|
nsIWidgetListener* listener = topLevelWidget->GetWidgetListener();
|
||||||
if (listener) {
|
if (listener) {
|
||||||
nsCOMPtr<nsIXULWindow> window = listener->GetXULWindow();
|
nsCOMPtr<nsIAppWindow> window = listener->GetAppWindow();
|
||||||
nsCOMPtr<nsIInterfaceRequestor> req(do_QueryInterface(window));
|
nsCOMPtr<nsIInterfaceRequestor> req(do_QueryInterface(window));
|
||||||
topLevelWindow = do_GetInterface(req);
|
topLevelWindow = do_GetInterface(req);
|
||||||
}
|
}
|
||||||
@ -7022,9 +7032,10 @@ void nsGlobalWindowOuter::SetChromeEventHandler(
|
|||||||
|
|
||||||
void nsGlobalWindowOuter::SetFocusedElement(Element* aElement,
|
void nsGlobalWindowOuter::SetFocusedElement(Element* aElement,
|
||||||
uint32_t aFocusMethod,
|
uint32_t aFocusMethod,
|
||||||
bool aNeedsFocus) {
|
bool aNeedsFocus,
|
||||||
FORWARD_TO_INNER_VOID(SetFocusedElement,
|
bool aWillShowOutline) {
|
||||||
(aElement, aFocusMethod, aNeedsFocus));
|
FORWARD_TO_INNER_VOID(SetFocusedElement, (aElement, aFocusMethod, aNeedsFocus,
|
||||||
|
aWillShowOutline));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t nsGlobalWindowOuter::GetFocusMethod() {
|
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.
|
// it easy to tell which link was last clicked when going back a page.
|
||||||
Element* focusedElement = inner->GetFocusedElement();
|
Element* focusedElement = inner->GetFocusedElement();
|
||||||
if (nsContentUtils::ContentIsLink(focusedElement)) {
|
if (nsContentUtils::ContentIsLink(focusedElement)) {
|
||||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||||
if (fm) {
|
if (fm) {
|
||||||
// XXXbz Do we need the stack strong ref here?
|
// XXXbz Do we need the stack strong ref here?
|
||||||
RefPtr<Element> kungFuDeathGrip(focusedElement);
|
RefPtr<Element> kungFuDeathGrip(focusedElement);
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
#include "nsCheapSets.h"
|
#include "nsCheapSets.h"
|
||||||
#include "mozilla/dom/ImageBitmapSource.h"
|
#include "mozilla/dom/ImageBitmapSource.h"
|
||||||
#include "mozilla/UniquePtr.h"
|
#include "mozilla/UniquePtr.h"
|
||||||
|
#include "mozilla/dom/BrowsingContext.h"
|
||||||
|
|
||||||
class nsDocShell;
|
class nsDocShell;
|
||||||
class nsIArray;
|
class nsIArray;
|
||||||
@ -85,7 +86,6 @@ class DOMEventTargetHelper;
|
|||||||
class ThrottledEventQueue;
|
class ThrottledEventQueue;
|
||||||
namespace dom {
|
namespace dom {
|
||||||
class BarProp;
|
class BarProp;
|
||||||
class BrowsingContext;
|
|
||||||
struct ChannelPixelLayout;
|
struct ChannelPixelLayout;
|
||||||
class Console;
|
class Console;
|
||||||
class Crypto;
|
class Crypto;
|
||||||
@ -869,6 +869,7 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
|||||||
mozilla::dom::CallerType aCallerType,
|
mozilla::dom::CallerType aCallerType,
|
||||||
mozilla::ErrorResult& aError);
|
mozilla::ErrorResult& aError);
|
||||||
nsRect GetInnerScreenRect();
|
nsRect GetInnerScreenRect();
|
||||||
|
static Maybe<mozilla::CSSIntSize> GetRDMDeviceSize(const Document& aDocument);
|
||||||
|
|
||||||
bool IsFrame();
|
bool IsFrame();
|
||||||
|
|
||||||
@ -890,33 +891,44 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convenience functions for the many methods that need to scale
|
// Convenience functions for the many methods that need to scale
|
||||||
// from device to CSS pixels or vice versa. Note: if a presentation
|
// from device to CSS pixels. This computes it with cached scale in
|
||||||
// context is not available, they will assume a 1:1 ratio.
|
// 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 DevToCSSIntPixels(int32_t px);
|
||||||
int32_t CSSToDevIntPixels(int32_t px);
|
|
||||||
nsIntSize DevToCSSIntPixels(nsIntSize px);
|
nsIntSize DevToCSSIntPixels(nsIntSize px);
|
||||||
nsIntSize CSSToDevIntPixels(nsIntSize px);
|
|
||||||
|
|
||||||
virtual void SetFocusedElement(mozilla::dom::Element* aElement,
|
// Convenience functions for the methods which call methods of nsIBaseWindow
|
||||||
uint32_t aFocusMethod = 0,
|
// because it takes/returns device pixels. Unfortunately, mPresContext may
|
||||||
bool aNeedsFocus = false) override;
|
// 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)
|
bool ShouldShowFocusRing() override;
|
||||||
override;
|
|
||||||
|
void SetKeyboardIndicators(UIStateChangeType aShowFocusRings) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() override;
|
already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void NotifyWindowIDDestroyed(const char* aTopic);
|
void NotifyWindowIDDestroyed(const char* aTopic);
|
||||||
|
|
||||||
void ClearStatus();
|
void ClearStatus();
|
||||||
|
|
||||||
virtual void UpdateParentTarget() override;
|
void UpdateParentTarget() override;
|
||||||
|
|
||||||
void InitializeShowFocusRings();
|
void InitializeShowFocusRings();
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@ class nsAttrValue;
|
|||||||
class nsAttrName;
|
class nsAttrName;
|
||||||
class nsTextFragment;
|
class nsTextFragment;
|
||||||
class nsIFrame;
|
class nsIFrame;
|
||||||
class nsXBLBinding;
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
class EventChainPreVisitor;
|
class EventChainPreVisitor;
|
||||||
@ -67,6 +66,7 @@ class nsIContent : public nsINode {
|
|||||||
explicit nsIContent(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
|
explicit nsIContent(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
|
||||||
: nsINode(std::move(aNodeInfo)) {
|
: nsINode(std::move(aNodeInfo)) {
|
||||||
MOZ_ASSERT(mNodeInfo);
|
MOZ_ASSERT(mNodeInfo);
|
||||||
|
MOZ_ASSERT(static_cast<nsINode*>(this) == reinterpret_cast<nsINode*>(this));
|
||||||
SetNodeIsContent();
|
SetNodeIsContent();
|
||||||
}
|
}
|
||||||
#endif // MOZILLA_INTERNAL_API
|
#endif // MOZILLA_INTERNAL_API
|
||||||
@ -125,48 +125,28 @@ class nsIContent : public nsINode {
|
|||||||
*
|
*
|
||||||
* @note the result children order is
|
* @note the result children order is
|
||||||
* 1. :before generated node
|
* 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
|
* 3. native anonymous nodes
|
||||||
* 4. :after generated node
|
* 4. :after generated node
|
||||||
*/
|
*/
|
||||||
eAllChildren = 0,
|
eAllChildren = 0,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All XBL explicit children of the node (see
|
* Skip native anonymous content created for placeholder of HTML input.
|
||||||
* 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
|
|
||||||
*/
|
*/
|
||||||
eAllButXBL = 1,
|
eSkipPlaceholderContent = 1 << 0,
|
||||||
|
|
||||||
/**
|
|
||||||
* Skip native anonymous content created for placeholder of HTML input,
|
|
||||||
* used in conjunction with eAllChildren or eAllButXBL.
|
|
||||||
*/
|
|
||||||
eSkipPlaceholderContent = 2,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Skip native anonymous content created by ancestor frames of the root
|
* Skip native anonymous content created by ancestor frames of the root
|
||||||
* element's primary frame, such as scrollbar elements created by the root
|
* element's primary frame, such as scrollbar elements created by the root
|
||||||
* scroll frame.
|
* scroll frame.
|
||||||
*/
|
*/
|
||||||
eSkipDocumentLevelNativeAnonymousContent = 4,
|
eSkipDocumentLevelNativeAnonymousContent = 1 << 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return either the XBL explicit children of the node or the XBL flattened
|
* Return the flattened tree children of the node, depending on the filter, as
|
||||||
* tree children of the node, depending on the filter, as well as
|
* well as native anonymous children.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
virtual already_AddRefed<nsINodeList> GetChildren(uint32_t aFilter) = 0;
|
virtual already_AddRefed<nsINodeList> GetChildren(uint32_t aFilter) = 0;
|
||||||
|
|
||||||
@ -175,7 +155,7 @@ class nsIContent : public nsINode {
|
|||||||
* @see nsIAnonymousContentCreator
|
* @see nsIAnonymousContentCreator
|
||||||
*/
|
*/
|
||||||
void SetIsNativeAnonymousRoot() {
|
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);
|
NODE_IS_NATIVE_ANONYMOUS_ROOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,28 +165,16 @@ class nsIContent : public nsINode {
|
|||||||
*/
|
*/
|
||||||
nsIContent* FindFirstNonChromeOnlyAccessContent() const;
|
nsIContent* FindFirstNonChromeOnlyAccessContent() const;
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
void AssertAnonymousSubtreeRelatedInvariants() const;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if and only if this node has a parent, but is not in
|
* Returns true if and only if this node has a parent, but is not in
|
||||||
* its parent's child list.
|
* its parent's child list.
|
||||||
|
*
|
||||||
|
* FIXME(emilio): Remove along nsINode::IsInAnonymousSubtree.
|
||||||
*/
|
*/
|
||||||
bool IsRootOfAnonymousSubtree() const {
|
bool IsRootOfAnonymousSubtree() const {
|
||||||
#ifdef DEBUG
|
return IsRootOfNativeAnonymousSubtree();
|
||||||
AssertAnonymousSubtreeRelatedInvariants();
|
|
||||||
#endif
|
|
||||||
return HasFlag(NODE_IS_ANONYMOUS_ROOT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
* 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).
|
* the term, i.e. not in an XHTML/XML document).
|
||||||
@ -272,8 +240,6 @@ class nsIContent : public nsINode {
|
|||||||
return IsMathMLElement() && IsNodeInternal(aFirst, aArgs...);
|
return IsMathMLElement() && IsNodeInternal(aFirst, aArgs...);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsActiveChildrenElement() const;
|
|
||||||
|
|
||||||
bool IsGeneratedContentContainerForBefore() const {
|
bool IsGeneratedContentContainerForBefore() const {
|
||||||
return IsRootOfNativeAnonymousSubtree() &&
|
return IsRootOfNativeAnonymousSubtree() &&
|
||||||
mNodeInfo->NameAtom() == nsGkAtoms::mozgeneratedcontentbefore;
|
mNodeInfo->NameAtom() == nsGkAtoms::mozgeneratedcontentbefore;
|
||||||
@ -380,36 +346,6 @@ class nsIContent : public nsINode {
|
|||||||
*/
|
*/
|
||||||
virtual IMEState GetDesiredIMEState();
|
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.
|
* 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.
|
* 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.
|
* @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;
|
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.
|
* Gets the assigned slot associated with this content.
|
||||||
*
|
*
|
||||||
@ -463,29 +389,6 @@ class nsIContent : public nsINode {
|
|||||||
*/
|
*/
|
||||||
mozilla::dom::HTMLSlotElement* GetAssignedSlotByMode() const;
|
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
|
* Same as GetFlattenedTreeParentNode, but returns null if the parent is
|
||||||
* non-nsIContent.
|
* non-nsIContent.
|
||||||
@ -542,9 +445,8 @@ class nsIContent : public nsINode {
|
|||||||
* For container elements, this is called *before* any of the children are
|
* For container elements, this is called *before* any of the children are
|
||||||
* created or added into the tree.
|
* created or added into the tree.
|
||||||
*
|
*
|
||||||
* NOTE: this is currently only called for input and button, in the HTML
|
* NOTE: this is only called for elements listed in
|
||||||
* content sink. If you want to call it on your element, modify the content
|
* RequiresDoneCreatingElement. This is an efficiency measure.
|
||||||
* sink of your choice to do so. This is an efficiency measure.
|
|
||||||
*
|
*
|
||||||
* If you also need to determine whether the parser is the one creating your
|
* If you also need to determine whether the parser is the one creating your
|
||||||
* element (through createElement() or cloneNode() generally) then add a
|
* 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
|
* This method is called when the parser finishes creating the element's
|
||||||
* children, if any are present.
|
* children, if any are present.
|
||||||
*
|
*
|
||||||
* NOTE: this is currently only called for textarea, select, and object
|
* NOTE: this is only called for elements listed in
|
||||||
* elements in the HTML content sink. If you want to call it on your element,
|
* RequiresDoneAddingChildren. This is an efficiency measure.
|
||||||
* modify the content sink of your choice to do so. This is an efficiency
|
|
||||||
* measure.
|
|
||||||
*
|
*
|
||||||
* If you also need to determine whether the parser is the one creating your
|
* If you also need to determine whether the parser is the one creating your
|
||||||
* element (through createElement() or cloneNode() generally) then add a
|
* element (through createElement() or cloneNode() generally) then add a
|
||||||
@ -595,6 +495,47 @@ class nsIContent : public nsINode {
|
|||||||
*/
|
*/
|
||||||
virtual bool IsDoneAddingChildren() { return true; }
|
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
|
* 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.
|
* 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(
|
virtual size_t SizeOfExcludingThis(
|
||||||
mozilla::MallocSizeOf aMallocSizeOf) const;
|
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
|
* @see nsIContent::GetContainingShadow
|
||||||
*/
|
*/
|
||||||
@ -887,13 +816,4 @@ class nsIContent : public nsINode {
|
|||||||
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIContent, NS_ICONTENT_IID)
|
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___ */
|
#endif /* nsIContent_h___ */
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
#include "mozilla/dom/Document.h"
|
#include "mozilla/dom/Document.h"
|
||||||
#include "nsBindingManager.h"
|
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsAtom.h"
|
#include "nsAtom.h"
|
||||||
#include "nsIFrame.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.
|
// Common case.
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
@ -180,45 +162,6 @@ inline bool nsINode::IsEditable() const {
|
|||||||
return doc && doc->HasFlag(NODE_IS_EDITABLE);
|
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() {
|
inline void nsIContent::HandleInsertionToOrRemovalFromSlot() {
|
||||||
using mozilla::dom::HTMLSlotElement;
|
using mozilla::dom::HTMLSlotElement;
|
||||||
|
|
||||||
|
@ -105,11 +105,9 @@ interface nsIContentPolicy : nsISupports
|
|||||||
*/
|
*/
|
||||||
const nsContentPolicyType TYPE_REFRESH = 8;
|
const nsContentPolicyType TYPE_REFRESH = 8;
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Indicates an XBL binding request, triggered either by -moz-binding CSS
|
* XXX: nsContentPolicyType = 9 used to inicate an XBL binding request.
|
||||||
* property.
|
|
||||||
*/
|
*/
|
||||||
const nsContentPolicyType TYPE_XBL = 9;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates a ping triggered by a click on <A PING="..."> element.
|
* Indicates a ping triggered by a click on <A PING="..."> element.
|
||||||
|
@ -43,7 +43,6 @@
|
|||||||
#include "mozilla/dom/L10nOverlays.h"
|
#include "mozilla/dom/L10nOverlays.h"
|
||||||
#include "mozilla/StaticPrefs_layout.h"
|
#include "mozilla/StaticPrefs_layout.h"
|
||||||
#include "nsAttrValueOrString.h"
|
#include "nsAttrValueOrString.h"
|
||||||
#include "nsBindingManager.h"
|
|
||||||
#include "nsCCUncollectableMarker.h"
|
#include "nsCCUncollectableMarker.h"
|
||||||
#include "nsContentCreatorFunctions.h"
|
#include "nsContentCreatorFunctions.h"
|
||||||
#include "nsContentList.h"
|
#include "nsContentList.h"
|
||||||
@ -78,7 +77,6 @@
|
|||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
#include "nsNameSpaceManager.h"
|
#include "nsNameSpaceManager.h"
|
||||||
#include "nsNodeInfoManager.h"
|
#include "nsNodeInfoManager.h"
|
||||||
#include "nsPIBoxObject.h"
|
|
||||||
#include "nsObjectLoadingContent.h"
|
#include "nsObjectLoadingContent.h"
|
||||||
#include "nsPIDOMWindow.h"
|
#include "nsPIDOMWindow.h"
|
||||||
#include "nsPresContext.h"
|
#include "nsPresContext.h"
|
||||||
@ -88,8 +86,6 @@
|
|||||||
#include "nsStyleConsts.h"
|
#include "nsStyleConsts.h"
|
||||||
#include "nsTextNode.h"
|
#include "nsTextNode.h"
|
||||||
#include "nsUnicharUtils.h"
|
#include "nsUnicharUtils.h"
|
||||||
#include "nsXBLBinding.h"
|
|
||||||
#include "nsXBLPrototypeBinding.h"
|
|
||||||
#include "nsWindowSizes.h"
|
#include "nsWindowSizes.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "xpcpublic.h"
|
#include "xpcpublic.h"
|
||||||
@ -497,20 +493,19 @@ static nsIContent* GetRootForContentSubtree(nsIContent* aContent) {
|
|||||||
// Special case for ShadowRoot because the ShadowRoot itself is
|
// Special case for ShadowRoot because the ShadowRoot itself is
|
||||||
// the root. This is necessary to prevent selection from crossing
|
// the root. This is necessary to prevent selection from crossing
|
||||||
// the ShadowRoot boundary.
|
// 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;
|
return containingShadow;
|
||||||
}
|
}
|
||||||
|
if (nsIContent* nativeAnonRoot = aContent->GetClosestNativeAnonymousSubtreeRoot()) {
|
||||||
nsIContent* stop = aContent->GetBindingParent();
|
return nativeAnonRoot;
|
||||||
while (aContent) {
|
|
||||||
nsIContent* parent = aContent->GetParent();
|
|
||||||
if (parent == stop) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
aContent = parent;
|
|
||||||
}
|
}
|
||||||
return aContent;
|
if (Document* doc = aContent->GetUncomposedDoc()) {
|
||||||
|
return doc->GetRootElement();
|
||||||
|
}
|
||||||
|
return nsIContent::FromNode(aContent->SubtreeRoot());
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIContent* nsINode::GetSelectionRootContent(PresShell* aPresShell) {
|
nsIContent* nsINode::GetSelectionRootContent(PresShell* aPresShell) {
|
||||||
@ -523,7 +518,7 @@ nsIContent* nsINode::GetSelectionRootContent(PresShell* aPresShell) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (static_cast<nsIContent*>(this)->HasIndependentSelection()) {
|
if (AsContent()->HasIndependentSelection()) {
|
||||||
// This node should be a descendant of input/textarea editor.
|
// This node should be a descendant of input/textarea editor.
|
||||||
nsIContent* content = GetTextEditorRootContent();
|
nsIContent* content = GetTextEditorRootContent();
|
||||||
if (content) return content;
|
if (content) return content;
|
||||||
@ -541,7 +536,7 @@ nsIContent* nsINode::GetSelectionRootContent(PresShell* aPresShell) {
|
|||||||
NS_ENSURE_TRUE(editorRoot, nullptr);
|
NS_ENSURE_TRUE(editorRoot, nullptr);
|
||||||
return nsContentUtils::IsInSameAnonymousTree(this, editorRoot)
|
return nsContentUtils::IsInSameAnonymousTree(this, editorRoot)
|
||||||
? editorRoot
|
? editorRoot
|
||||||
: GetRootForContentSubtree(static_cast<nsIContent*>(this));
|
: GetRootForContentSubtree(AsContent());
|
||||||
}
|
}
|
||||||
// If the document isn't editable but this is editable, this is in
|
// If the document isn't editable but this is editable, this is in
|
||||||
// contenteditable. Use the editing host element for selection root.
|
// 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.
|
// root. Otherwise, we can return the content simply.
|
||||||
NS_ENSURE_TRUE(content, nullptr);
|
NS_ENSURE_TRUE(content, nullptr);
|
||||||
if (!nsContentUtils::IsInSameAnonymousTree(this, content)) {
|
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.
|
// Fixup for ShadowRoot because the ShadowRoot itself does not have a frame.
|
||||||
// Use the host as the root.
|
// Use the host as the root.
|
||||||
if (ShadowRoot* shadowRoot = ShadowRoot::FromNode(content)) {
|
if (ShadowRoot* shadowRoot = ShadowRoot::FromNode(content)) {
|
||||||
@ -680,38 +675,12 @@ void nsINode::LastRelease() {
|
|||||||
UnsetFlags(NODE_HAS_LISTENERMANAGER);
|
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);
|
ReleaseWrapper(this);
|
||||||
|
|
||||||
FragmentOrElement::RemoveBlackMarkedNode(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) {
|
std::ostream& operator<<(std::ostream& aStream, const nsINode& aNode) {
|
||||||
nsAutoString elemDesc;
|
nsAutoString elemDesc;
|
||||||
@ -740,9 +709,23 @@ std::ostream& operator<<(std::ostream& aStream, const nsINode& aNode) {
|
|||||||
return aStream << str.get();
|
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 {
|
SVGUseElement* nsINode::DoGetContainingSVGUseShadowHost() const {
|
||||||
MOZ_ASSERT(IsInShadowTree());
|
MOZ_ASSERT(IsInShadowTree());
|
||||||
return SVGUseElement::FromNodeOrNull(AsContent()->GetContainingShadowHost());
|
return SVGUseElement::FromNodeOrNull(GetContainingShadowHost());
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsINode::GetNodeValueInternal(nsAString& aNodeValue) {
|
void nsINode::GetNodeValueInternal(nsAString& aNodeValue) {
|
||||||
@ -1344,12 +1327,7 @@ nsIGlobalObject* nsINode::GetOwnerGlobal() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool nsINode::UnoptimizableCCNode() const {
|
bool nsINode::UnoptimizableCCNode() const {
|
||||||
const uintptr_t problematicFlags =
|
return IsInNativeAnonymousSubtree() || IsAttr();
|
||||||
(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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
@ -2801,29 +2779,47 @@ bool nsINode::Contains(const nsINode* aOther) const {
|
|||||||
if (aOther == this) {
|
if (aOther == this) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!aOther || OwnerDoc() != aOther->OwnerDoc() ||
|
if (!aOther || OwnerDoc() != aOther->OwnerDoc() ||
|
||||||
IsInUncomposedDoc() != aOther->IsInUncomposedDoc() ||
|
IsInUncomposedDoc() != aOther->IsInUncomposedDoc() ||
|
||||||
!aOther->IsContent() || !GetFirstChild()) {
|
!aOther->IsContent() || !HasChildren()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const nsIContent* other = static_cast<const nsIContent*>(aOther);
|
if (IsDocument()) {
|
||||||
if (this == OwnerDoc()) {
|
|
||||||
// document.contains(aOther) returns true if aOther is in the document,
|
// document.contains(aOther) returns true if aOther is in the document,
|
||||||
// but is not in any anonymous subtree.
|
// but is not in any anonymous subtree.
|
||||||
// IsInUncomposedDoc() check is done already before this.
|
// IsInUncomposedDoc() check is done already before this.
|
||||||
return !other->IsInAnonymousSubtree();
|
return !aOther->IsInAnonymousSubtree();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsElement() && !IsDocumentFragment()) {
|
if (!IsElement() && !IsDocumentFragment()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AsContent()->GetBindingParent() != other->GetBindingParent()) {
|
if (IsInShadowTree() != aOther->IsInShadowTree() ||
|
||||||
|
IsInNativeAnonymousSubtree() != aOther->IsInNativeAnonymousSubtree()) {
|
||||||
return false;
|
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 {
|
uint32_t nsINode::Length() const {
|
||||||
@ -3174,7 +3170,6 @@ already_AddRefed<nsINode> nsINode::CloneAndAdopt(
|
|||||||
|
|
||||||
bool wasRegistered = false;
|
bool wasRegistered = false;
|
||||||
if (elem) {
|
if (elem) {
|
||||||
oldDoc->ClearBoxObjectFor(elem);
|
|
||||||
wasRegistered = oldDoc->UnregisterActivityObserver(elem);
|
wasRegistered = oldDoc->UnregisterActivityObserver(elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3479,21 +3474,3 @@ size_t nsNodeWeakReference::SizeOfOnlyThis(
|
|||||||
mozilla::MallocSizeOf aMallocSizeOf) const {
|
mozilla::MallocSizeOf aMallocSizeOf) const {
|
||||||
return aMallocSizeOf(this);
|
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;
|
class OwningNodeOrString;
|
||||||
template <typename>
|
template <typename>
|
||||||
class Sequence;
|
class Sequence;
|
||||||
|
class ShadowRoot;
|
||||||
class SVGUseElement;
|
class SVGUseElement;
|
||||||
class Text;
|
class Text;
|
||||||
class TextOrElementOrDocument;
|
class TextOrElementOrDocument;
|
||||||
@ -116,47 +117,35 @@ enum {
|
|||||||
// Whether this node has had any properties set on it
|
// Whether this node has had any properties set on it
|
||||||
NODE_HAS_PROPERTIES = NODE_FLAG_BIT(1),
|
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
|
// Whether the node has some ancestor, possibly itself, that is native
|
||||||
// anonymous. This includes ancestors crossing XBL scopes, in cases when an
|
// anonymous. This includes ancestors crossing XBL scopes, in cases when an
|
||||||
// XBL binding is attached to an element which has a native anonymous
|
// 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
|
// ancestor. This flag is set-once: once a node has it, it must not be
|
||||||
// removed.
|
// removed.
|
||||||
// NOTE: Should only be used on nsIContent nodes
|
// 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
|
// 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
|
// of its parent) subtree. This flag is set-once: once a node has it, it
|
||||||
// must not be removed.
|
// must not be removed.
|
||||||
// NOTE: Should only be used on nsIContent nodes
|
// 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_IS_EDITABLE = NODE_FLAG_BIT(4),
|
||||||
NODE_MAY_BE_IN_BINDING_MNGR = NODE_FLAG_BIT(5),
|
|
||||||
|
|
||||||
NODE_IS_EDITABLE = NODE_FLAG_BIT(6),
|
|
||||||
|
|
||||||
// Free bit here.
|
|
||||||
|
|
||||||
// Whether the node participates in a shadow tree.
|
// 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 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,
|
// A child of the node has a selector such that any insertion,
|
||||||
// removal, or appending of children requires restyling the parent.
|
// 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,
|
// A child of the node has a :first-child, :-moz-first-node,
|
||||||
// :only-child, :last-child or :-moz-last-node selector.
|
// :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
|
// A child of the node has a selector such that any insertion or
|
||||||
// removal of children requires restyling later siblings of that
|
// 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
|
// other content tree changes (e.g., the child changes to or from
|
||||||
// matching :empty due to a grandchild insertion or removal), the
|
// matching :empty due to a grandchild insertion or removal), the
|
||||||
// child's later siblings must also be restyled.
|
// 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_ALL_SELECTOR_FLAGS = NODE_HAS_EMPTY_SELECTOR | NODE_HAS_SLOW_SELECTOR |
|
||||||
NODE_HAS_EDGE_CHILD_SELECTOR |
|
NODE_HAS_EDGE_CHILD_SELECTOR |
|
||||||
@ -173,32 +162,32 @@ enum {
|
|||||||
|
|
||||||
// This node needs to go through frame construction to get a frame (or
|
// This node needs to go through frame construction to get a frame (or
|
||||||
// undisplayed entry).
|
// 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.
|
// 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
|
// 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(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.
|
// 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
|
// 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
|
// 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_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.
|
// 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.
|
// 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
|
// Make sure we have space for our bits
|
||||||
@ -463,8 +452,7 @@ class nsINode : public mozilla::dom::EventTarget {
|
|||||||
inline mozilla::dom::DocumentFragment* AsDocumentFragment();
|
inline mozilla::dom::DocumentFragment* AsDocumentFragment();
|
||||||
inline const mozilla::dom::DocumentFragment* AsDocumentFragment() const;
|
inline const mozilla::dom::DocumentFragment* AsDocumentFragment() const;
|
||||||
|
|
||||||
virtual JSObject* WrapObject(JSContext* aCx,
|
JSObject* WrapObject(JSContext*, JS::Handle<JSObject*> aGivenProto) final;
|
||||||
JS::Handle<JSObject*> aGivenProto) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook for constructing JS::ubi::Concrete specializations for memory
|
* 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
|
* 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();
|
nsIContent* AsContent() {
|
||||||
inline const nsIContent* AsContent() const;
|
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
|
* 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 {
|
nsIContent* GetParent() const {
|
||||||
return MOZ_LIKELY(GetBoolFlag(ParentIsContent))
|
return MOZ_LIKELY(GetBoolFlag(ParentIsContent))
|
||||||
? reinterpret_cast<nsIContent*>(mParent)
|
? mParent->AsContent()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1269,19 +1265,18 @@ class nsINode : public mozilla::dom::EventTarget {
|
|||||||
void SetFlags(FlagsType aFlagsToSet) {
|
void SetFlags(FlagsType aFlagsToSet) {
|
||||||
NS_ASSERTION(
|
NS_ASSERTION(
|
||||||
!(aFlagsToSet &
|
!(aFlagsToSet &
|
||||||
(NODE_IS_ANONYMOUS_ROOT | NODE_IS_NATIVE_ANONYMOUS_ROOT |
|
(NODE_IS_NATIVE_ANONYMOUS_ROOT | NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE |
|
||||||
NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE | NODE_DESCENDANTS_NEED_FRAMES |
|
NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME |
|
||||||
NODE_NEEDS_FRAME | NODE_HAS_BEEN_IN_UA_WIDGET)) ||
|
NODE_HAS_BEEN_IN_UA_WIDGET)) ||
|
||||||
IsContent(),
|
IsContent(),
|
||||||
"Flag only permitted on nsIContent nodes");
|
"Flag only permitted on nsIContent nodes");
|
||||||
nsWrapperCache::SetFlags(aFlagsToSet);
|
nsWrapperCache::SetFlags(aFlagsToSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnsetFlags(FlagsType aFlagsToUnset) {
|
void UnsetFlags(FlagsType aFlagsToUnset) {
|
||||||
NS_ASSERTION(
|
NS_ASSERTION(!(aFlagsToUnset & (NODE_HAS_BEEN_IN_UA_WIDGET |
|
||||||
!(aFlagsToUnset & (NODE_IS_ANONYMOUS_ROOT | NODE_HAS_BEEN_IN_UA_WIDGET |
|
NODE_IS_NATIVE_ANONYMOUS_ROOT)),
|
||||||
NODE_IS_NATIVE_ANONYMOUS_ROOT)),
|
"Trying to unset write-only flags");
|
||||||
"Trying to unset write-only flags");
|
|
||||||
nsWrapperCache::UnsetFlags(aFlagsToUnset);
|
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.
|
* Returns true if |this| or any of its ancestors is native anonymous.
|
||||||
*/
|
*/
|
||||||
bool IsInNativeAnonymousSubtree() const {
|
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);
|
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
|
* If |this| or any ancestor is native anonymous, return the root of the
|
||||||
* native anonymous subtree. Note that in case of nested native anonymous
|
* native anonymous subtree. Note that in case of nested native anonymous
|
||||||
* content, this returns the innermost root, not the outermost.
|
* 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
|
* 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();
|
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 {
|
bool IsInSVGUseShadowTree() const {
|
||||||
return !!GetContainingSVGUseShadowHost();
|
return !!GetContainingSVGUseShadowHost();
|
||||||
}
|
}
|
||||||
@ -1354,6 +1377,17 @@ class nsINode : public mozilla::dom::EventTarget {
|
|||||||
NODE_HAS_BEEN_IN_UA_WIDGET);
|
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); }
|
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
|
* @return whether this content is anonymous
|
||||||
*/
|
*/
|
||||||
bool IsRootOfNativeAnonymousSubtree() const {
|
bool IsRootOfNativeAnonymousSubtree() const {
|
||||||
NS_ASSERTION(!HasFlag(NODE_IS_NATIVE_ANONYMOUS_ROOT) ||
|
NS_ASSERTION(
|
||||||
(HasFlag(NODE_IS_ANONYMOUS_ROOT) &&
|
!HasFlag(NODE_IS_NATIVE_ANONYMOUS_ROOT) || IsInNativeAnonymousSubtree(),
|
||||||
HasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE)),
|
"Some flags seem to be missing!");
|
||||||
"Some flags seem to be missing!");
|
|
||||||
return HasFlag(NODE_IS_NATIVE_ANONYMOUS_ROOT);
|
return HasFlag(NODE_IS_NATIVE_ANONYMOUS_ROOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2108,12 +2141,6 @@ class nsINode : public mozilla::dom::EventTarget {
|
|||||||
nsIPrincipal* aSubjectPrincipal,
|
nsIPrincipal* aSubjectPrincipal,
|
||||||
mozilla::ErrorResult& aError) {}
|
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 EnsurePreInsertionValidity1(mozilla::ErrorResult& aError);
|
||||||
void EnsurePreInsertionValidity2(bool aReplace, nsINode& aNewChild,
|
void EnsurePreInsertionValidity2(bool aReplace, nsINode& aNewChild,
|
||||||
nsINode* aRefChild,
|
nsINode* aRefChild,
|
||||||
|
@ -36,7 +36,6 @@
|
|||||||
#include "nsINode.h"
|
#include "nsINode.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsTPromiseFlatString.h"
|
#include "nsTPromiseFlatString.h"
|
||||||
#include "nsXBLPrototypeBinding.h"
|
|
||||||
#include "nscore.h"
|
#include "nscore.h"
|
||||||
|
|
||||||
#if !defined(DEBUG) && !defined(MOZ_ENABLE_JS_DUMP)
|
#if !defined(DEBUG) && !defined(MOZ_ENABLE_JS_DUMP)
|
||||||
@ -218,29 +217,6 @@ bool nsJSUtils::GetScopeChainForElement(
|
|||||||
return true;
|
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 */
|
/* static */
|
||||||
void nsJSUtils::ResetTimeZone() { JS::ResetTimeZone(); }
|
void nsJSUtils::ResetTimeZone() { JS::ResetTimeZone(); }
|
||||||
|
|
||||||
|
@ -100,17 +100,6 @@ class nsJSUtils {
|
|||||||
JSContext* aCx, mozilla::dom::Element* aElement,
|
JSContext* aCx, mozilla::dom::Element* aElement,
|
||||||
JS::MutableHandleVector<JSObject*> aScopeChain);
|
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 void ResetTimeZone();
|
||||||
|
|
||||||
static bool DumpEnabled();
|
static bool DumpEnabled();
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "mozilla/dom/NodeInfo.h"
|
#include "mozilla/dom/NodeInfo.h"
|
||||||
#include "mozilla/ClearOnShutdown.h"
|
#include "mozilla/ClearOnShutdown.h"
|
||||||
#include "mozilla/dom/XBLChildrenElement.h"
|
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
|
|
||||||
@ -70,7 +69,6 @@ bool nsNameSpaceManager::Init() {
|
|||||||
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xhtml, kNameSpaceID_XHTML);
|
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xhtml, kNameSpaceID_XHTML);
|
||||||
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xlink, kNameSpaceID_XLink);
|
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xlink, kNameSpaceID_XLink);
|
||||||
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xslt, kNameSpaceID_XSLT);
|
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_mathml, kNameSpaceID_MathML);
|
||||||
REGISTER_NAMESPACE(nsGkAtoms::nsuri_rdf, kNameSpaceID_RDF);
|
REGISTER_NAMESPACE(nsGkAtoms::nsuri_rdf, kNameSpaceID_RDF);
|
||||||
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xul, kNameSpaceID_XUL);
|
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xul, kNameSpaceID_XUL);
|
||||||
@ -165,8 +163,8 @@ int32_t nsNameSpaceManager::GetNameSpaceID(nsAtom* aURI, bool aInChromeDoc) {
|
|||||||
// static
|
// static
|
||||||
const char* nsNameSpaceManager::GetNameSpaceDisplayName(uint32_t aNameSpaceID) {
|
const char* nsNameSpaceManager::GetNameSpaceDisplayName(uint32_t aNameSpaceID) {
|
||||||
static const char* kNSURIs[] = {"([none])", "(xmlns)", "(xml)", "(xhtml)",
|
static const char* kNSURIs[] = {"([none])", "(xmlns)", "(xml)", "(xhtml)",
|
||||||
"(XLink)", "(XSLT)", "(XBL)", "(MathML)",
|
"(XLink)", "(XSLT)", "(MathML)", "(RDF)",
|
||||||
"(RDF)", "(XUL)", "(SVG)"};
|
"(XUL)", "(SVG)"};
|
||||||
if (aNameSpaceID < ArrayLength(kNSURIs)) {
|
if (aNameSpaceID < ArrayLength(kNSURIs)) {
|
||||||
return kNSURIs[aNameSpaceID];
|
return kNSURIs[aNameSpaceID];
|
||||||
}
|
}
|
||||||
@ -212,12 +210,6 @@ nsresult NS_NewElement(Element** aResult,
|
|||||||
ni->NodeType(), ni->GetExtraName());
|
ni->NodeType(), ni->GetExtraName());
|
||||||
return NS_NewXMLElement(aResult, genericXMLNI.forget());
|
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());
|
return NS_NewXMLElement(aResult, ni.forget());
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ class nsNameSpaceManager final {
|
|||||||
const int32_t aNameSpaceID);
|
const int32_t aNameSpaceID);
|
||||||
nsresult AddDisabledNameSpace(already_AddRefed<nsAtom> aURI,
|
nsresult AddDisabledNameSpace(already_AddRefed<nsAtom> aURI,
|
||||||
const int32_t aNameSpaceID);
|
const int32_t aNameSpaceID);
|
||||||
~nsNameSpaceManager(){};
|
~nsNameSpaceManager() = default;
|
||||||
|
|
||||||
nsDataHashtable<nsRefPtrHashKey<nsAtom>, int32_t> mURIToIDTable;
|
nsDataHashtable<nsRefPtrHashKey<nsAtom>, int32_t> mURIToIDTable;
|
||||||
nsDataHashtable<nsRefPtrHashKey<nsAtom>, int32_t> mDisabledURIToIDTable;
|
nsDataHashtable<nsRefPtrHashKey<nsAtom>, int32_t> mDisabledURIToIDTable;
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
#include "nsGkAtoms.h"
|
#include "nsGkAtoms.h"
|
||||||
#include "nsComponentManagerUtils.h"
|
#include "nsComponentManagerUtils.h"
|
||||||
#include "nsLayoutStatics.h"
|
#include "nsLayoutStatics.h"
|
||||||
#include "nsBindingManager.h"
|
|
||||||
#include "nsHashKeys.h"
|
#include "nsHashKeys.h"
|
||||||
#include "nsCCUncollectableMarker.h"
|
#include "nsCCUncollectableMarker.h"
|
||||||
#include "nsNameSpaceManager.h"
|
#include "nsNameSpaceManager.h"
|
||||||
@ -61,8 +60,6 @@ nsNodeInfoManager::~nsNodeInfoManager() {
|
|||||||
|
|
||||||
mArena = nullptr;
|
mArena = nullptr;
|
||||||
|
|
||||||
mBindingManager = nullptr;
|
|
||||||
|
|
||||||
if (gNodeInfoManagerLeakPRLog)
|
if (gNodeInfoManagerLeakPRLog)
|
||||||
MOZ_LOG(gNodeInfoManagerLeakPRLog, LogLevel::Debug,
|
MOZ_LOG(gNodeInfoManagerLeakPRLog, LogLevel::Debug,
|
||||||
("NODEINFOMANAGER %p destroyed", this));
|
("NODEINFOMANAGER %p destroyed", this));
|
||||||
@ -77,7 +74,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsNodeInfoManager)
|
|||||||
if (tmp->mNonDocumentNodeInfos) {
|
if (tmp->mNonDocumentNodeInfos) {
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mDocument)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mDocument)
|
||||||
}
|
}
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBindingManager)
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsNodeInfoManager, AddRef)
|
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsNodeInfoManager, AddRef)
|
||||||
@ -109,10 +105,6 @@ nsresult nsNodeInfoManager::Init(mozilla::dom::Document* aDocument) {
|
|||||||
|
|
||||||
mPrincipal = NullPrincipal::CreateWithoutOriginAttributes();
|
mPrincipal = NullPrincipal::CreateWithoutOriginAttributes();
|
||||||
|
|
||||||
if (aDocument) {
|
|
||||||
mBindingManager = new nsBindingManager(aDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
mDefaultPrincipal = mPrincipal;
|
mDefaultPrincipal = mPrincipal;
|
||||||
|
|
||||||
mDocument = aDocument;
|
mDocument = aDocument;
|
||||||
@ -125,10 +117,6 @@ nsresult nsNodeInfoManager::Init(mozilla::dom::Document* aDocument) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void nsNodeInfoManager::DropDocumentReference() {
|
void nsNodeInfoManager::DropDocumentReference() {
|
||||||
if (mBindingManager) {
|
|
||||||
mBindingManager->DropDocumentReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is probably not needed anymore.
|
// This is probably not needed anymore.
|
||||||
for (auto iter = mNodeInfoHash.Iter(); !iter.Done(); iter.Next()) {
|
for (auto iter = mNodeInfoHash.Iter(); !iter.Done(); iter.Next()) {
|
||||||
iter.Data()->mDocument = nullptr;
|
iter.Data()->mDocument = nullptr;
|
||||||
@ -414,11 +402,6 @@ bool nsNodeInfoManager::InternalMathMLEnabled() {
|
|||||||
void nsNodeInfoManager::AddSizeOfIncludingThis(nsWindowSizes& aSizes) const {
|
void nsNodeInfoManager::AddSizeOfIncludingThis(nsWindowSizes& aSizes) const {
|
||||||
aSizes.mDOMOtherSize += aSizes.mState.mMallocSizeOf(this);
|
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
|
// Measurement of the following members may be added later if DMD finds it
|
||||||
// is worthwhile:
|
// is worthwhile:
|
||||||
// - mNodeInfoHash
|
// - mNodeInfoHash
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include "nsDataHashtable.h"
|
#include "nsDataHashtable.h"
|
||||||
#include "nsStringFwd.h"
|
#include "nsStringFwd.h"
|
||||||
|
|
||||||
class nsBindingManager;
|
|
||||||
class nsAtom;
|
class nsAtom;
|
||||||
class nsIPrincipal;
|
class nsIPrincipal;
|
||||||
class nsWindowSizes;
|
class nsWindowSizes;
|
||||||
@ -97,8 +96,6 @@ class nsNodeInfoManager final {
|
|||||||
|
|
||||||
void RemoveNodeInfo(mozilla::dom::NodeInfo* aNodeInfo);
|
void RemoveNodeInfo(mozilla::dom::NodeInfo* aNodeInfo);
|
||||||
|
|
||||||
nsBindingManager* GetBindingManager() const { return mBindingManager; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if SVG nodes in this document have real SVG semantics.
|
* 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
|
mCommentNodeInfo; // WEAK to avoid circular ownership
|
||||||
mozilla::dom::NodeInfo* MOZ_NON_OWNING_REF
|
mozilla::dom::NodeInfo* MOZ_NON_OWNING_REF
|
||||||
mDocumentNodeInfo; // WEAK to avoid circular ownership
|
mDocumentNodeInfo; // WEAK to avoid circular ownership
|
||||||
RefPtr<nsBindingManager> mBindingManager;
|
|
||||||
NodeInfoCache mRecentlyUsedNodeInfos;
|
NodeInfoCache mRecentlyUsedNodeInfos;
|
||||||
mozilla::Maybe<bool> mSVGEnabled; // Lazily initialized.
|
mozilla::Maybe<bool> mSVGEnabled; // Lazily initialized.
|
||||||
mozilla::Maybe<bool> mMathMLEnabled; // Lazily initialized.
|
mozilla::Maybe<bool> mMathMLEnabled; // Lazily initialized.
|
||||||
|
@ -41,7 +41,6 @@ class nsIURI;
|
|||||||
class nsPIDOMWindowInner;
|
class nsPIDOMWindowInner;
|
||||||
class nsPIDOMWindowOuter;
|
class nsPIDOMWindowOuter;
|
||||||
class nsPIWindowRoot;
|
class nsPIWindowRoot;
|
||||||
class nsXBLPrototypeHandler;
|
|
||||||
|
|
||||||
typedef uint32_t SuspendTypes;
|
typedef uint32_t SuspendTypes;
|
||||||
|
|
||||||
@ -439,11 +438,6 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
|||||||
return mMayHaveSelectionChangeEventListener;
|
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
|
* Get and set the currently focused element within the document. If
|
||||||
* aNeedsFocus is true, then set mNeedsFocus to true to indicate that a
|
* 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
|
* DO NOT CALL EITHER OF THESE METHODS DIRECTLY. USE THE FOCUS MANAGER
|
||||||
* INSTEAD.
|
* INSTEAD.
|
||||||
*/
|
*/
|
||||||
inline mozilla::dom::Element* GetFocusedElement() const;
|
mozilla::dom::Element* GetFocusedElement() const {
|
||||||
|
return mFocusedElement.get();
|
||||||
|
}
|
||||||
|
|
||||||
virtual void SetFocusedElement(mozilla::dom::Element* aElement,
|
virtual void SetFocusedElement(mozilla::dom::Element* aElement,
|
||||||
uint32_t aFocusMethod = 0,
|
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.
|
* Retrieves the method that was used to focus the current node.
|
||||||
@ -647,6 +653,8 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
|||||||
// notification.
|
// notification.
|
||||||
bool mHasNotifiedGlobalCreated;
|
bool mHasNotifiedGlobalCreated;
|
||||||
|
|
||||||
|
bool mFocusedElementShowedOutlines = false;
|
||||||
|
|
||||||
uint32_t mMarkedCCGeneration;
|
uint32_t mMarkedCCGeneration;
|
||||||
|
|
||||||
// mTopInnerWindow is used for tab-wise check by timeout throttling. It could
|
// mTopInnerWindow is used for tab-wise check by timeout throttling. It could
|
||||||
@ -940,9 +948,17 @@ class nsPIDOMWindowOuter : public mozIDOMWindowProxy {
|
|||||||
* INSTEAD.
|
* INSTEAD.
|
||||||
*/
|
*/
|
||||||
inline mozilla::dom::Element* GetFocusedElement() const;
|
inline mozilla::dom::Element* GetFocusedElement() const;
|
||||||
|
|
||||||
virtual void SetFocusedElement(mozilla::dom::Element* aElement,
|
virtual void SetFocusedElement(mozilla::dom::Element* aElement,
|
||||||
uint32_t aFocusMethod = 0,
|
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.
|
* 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
|
* 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/. */
|
* 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();
|
auto* win = GetCurrentInnerWindow();
|
||||||
|
|
||||||
if (!win) {
|
if (!win) {
|
||||||
@ -14,7 +17,7 @@ bool nsPIDOMWindowOuter::IsLoading() const {
|
|||||||
return win->IsLoading();
|
return win->IsLoading();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsPIDOMWindowInner::IsLoading() const {
|
inline bool nsPIDOMWindowInner::IsLoading() const {
|
||||||
if (!mOuterWindow) {
|
if (!mOuterWindow) {
|
||||||
NS_ERROR("IsLoading() called on orphan inner window!");
|
NS_ERROR("IsLoading() called on orphan inner window!");
|
||||||
|
|
||||||
@ -24,7 +27,7 @@ bool nsPIDOMWindowInner::IsLoading() const {
|
|||||||
return !mIsDocumentLoaded;
|
return !mIsDocumentLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsPIDOMWindowOuter::IsHandlingResizeEvent() const {
|
inline bool nsPIDOMWindowOuter::IsHandlingResizeEvent() const {
|
||||||
auto* win = GetCurrentInnerWindow();
|
auto* win = GetCurrentInnerWindow();
|
||||||
|
|
||||||
if (!win) {
|
if (!win) {
|
||||||
@ -36,7 +39,7 @@ bool nsPIDOMWindowOuter::IsHandlingResizeEvent() const {
|
|||||||
return win->IsHandlingResizeEvent();
|
return win->IsHandlingResizeEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsPIDOMWindowInner::IsHandlingResizeEvent() const {
|
inline bool nsPIDOMWindowInner::IsHandlingResizeEvent() const {
|
||||||
if (!mOuterWindow) {
|
if (!mOuterWindow) {
|
||||||
NS_ERROR("IsHandlingResizeEvent() called on orphan inner window!");
|
NS_ERROR("IsHandlingResizeEvent() called on orphan inner window!");
|
||||||
|
|
||||||
@ -46,34 +49,39 @@ bool nsPIDOMWindowInner::IsHandlingResizeEvent() const {
|
|||||||
return mIsHandlingResizeEvent;
|
return mIsHandlingResizeEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsPIDOMWindowInner::IsCurrentInnerWindow() const {
|
inline bool nsPIDOMWindowInner::IsCurrentInnerWindow() const {
|
||||||
return mOuterWindow && mOuterWindow->GetCurrentInnerWindow() == this;
|
return mOuterWindow && mOuterWindow->GetCurrentInnerWindow() == this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsPIDOMWindowInner::HasActiveDocument() {
|
inline bool nsPIDOMWindowInner::HasActiveDocument() {
|
||||||
return IsCurrentInnerWindow() ||
|
return IsCurrentInnerWindow() ||
|
||||||
(mOuterWindow && mOuterWindow->GetCurrentInnerWindow() &&
|
(mOuterWindow && mOuterWindow->GetCurrentInnerWindow() &&
|
||||||
mOuterWindow->GetCurrentInnerWindow()->GetDoc() == mDoc);
|
mOuterWindow->GetCurrentInnerWindow()->GetDoc() == mDoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsPIDOMWindowInner::IsTopInnerWindow() const {
|
inline bool nsPIDOMWindowInner::IsTopInnerWindow() const {
|
||||||
return mTopInnerWindow == this;
|
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;
|
return mOuterWindow ? mOuterWindow->GetDocShell() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
mozilla::dom::BrowsingContext* nsPIDOMWindowOuter::GetBrowsingContext() const {
|
inline mozilla::dom::BrowsingContext* nsPIDOMWindowOuter::GetBrowsingContext()
|
||||||
|
const {
|
||||||
return mBrowsingContext;
|
return mBrowsingContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
mozilla::dom::Element* nsPIDOMWindowOuter::GetFocusedElement() const {
|
inline mozilla::dom::Element* nsPIDOMWindowOuter::GetFocusedElement() const {
|
||||||
return mInnerWindow ? mInnerWindow->GetFocusedElement() : nullptr;
|
return mInnerWindow ? mInnerWindow->GetFocusedElement() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
mozilla::dom::Element* nsPIDOMWindowInner::GetFocusedElement() const {
|
inline bool nsPIDOMWindowOuter::FocusedElementShowedOutline() const {
|
||||||
return mFocusedElement;
|
return mInnerWindow && mInnerWindow->FocusedElementShowedOutline();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -856,10 +856,10 @@ void nsRange::DoSetRange(const RangeBoundaryBase<SPT, SRT>& aStartBoundary,
|
|||||||
!aRootNode ||
|
!aRootNode ||
|
||||||
(aStartBoundary.Container()->IsContent() &&
|
(aStartBoundary.Container()->IsContent() &&
|
||||||
aEndBoundary.Container()->IsContent() &&
|
aEndBoundary.Container()->IsContent() &&
|
||||||
aRootNode == static_cast<nsIContent*>(aStartBoundary.Container())
|
aRootNode ==
|
||||||
->GetBindingParent() &&
|
RangeUtils::ComputeRootNode(aStartBoundary.Container()) &&
|
||||||
aRootNode == static_cast<nsIContent*>(aEndBoundary.Container())
|
aRootNode ==
|
||||||
->GetBindingParent()) ||
|
RangeUtils::ComputeRootNode(aEndBoundary.Container())) ||
|
||||||
(!aRootNode->GetParentNode() &&
|
(!aRootNode->GetParentNode() &&
|
||||||
(aRootNode->IsDocument() || aRootNode->IsAttr() ||
|
(aRootNode->IsDocument() || aRootNode->IsAttr() ||
|
||||||
aRootNode->IsDocumentFragment() ||
|
aRootNode->IsDocumentFragment() ||
|
||||||
@ -1286,7 +1286,7 @@ class MOZ_STACK_CLASS RangeSubtreeIterator {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
RangeSubtreeIterator() : mIterState(eDone) {}
|
RangeSubtreeIterator() : mIterState(eDone) {}
|
||||||
~RangeSubtreeIterator() {}
|
~RangeSubtreeIterator() = default;
|
||||||
|
|
||||||
nsresult Init(nsRange* aRange);
|
nsresult Init(nsRange* aRange);
|
||||||
already_AddRefed<nsINode> GetCurrentNode();
|
already_AddRefed<nsINode> GetCurrentNode();
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#include "nsScreen.h"
|
#include "nsScreen.h"
|
||||||
#include "mozilla/dom/Document.h"
|
#include "mozilla/dom/Document.h"
|
||||||
#include "nsIDocShell.h"
|
#include "nsIDocShell.h"
|
||||||
#include "mozilla/dom/Document.h"
|
|
||||||
#include "nsPresContext.h"
|
#include "nsPresContext.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsIDocShellTreeItem.h"
|
#include "nsIDocShellTreeItem.h"
|
||||||
@ -84,6 +83,22 @@ nsresult nsScreen::GetRect(nsRect& aRect) {
|
|||||||
return GetWindowInnerRect(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();
|
nsDeviceContext* context = GetDeviceContext();
|
||||||
|
|
||||||
if (!context) {
|
if (!context) {
|
||||||
@ -111,10 +126,20 @@ nsresult nsScreen::GetAvailRect(nsRect& aRect) {
|
|||||||
return GetWindowInnerRect(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 in RDM.
|
||||||
if (IsInRDMPane()) {
|
nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner();
|
||||||
return GetRDMScreenSize(aRect);
|
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();
|
nsDeviceContext* context = GetDeviceContext();
|
||||||
@ -143,29 +168,6 @@ nsresult nsScreen::GetAvailRect(nsRect& aRect) {
|
|||||||
return NS_OK;
|
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 {
|
mozilla::dom::ScreenOrientation* nsScreen::Orientation() const {
|
||||||
return mScreenOrientation;
|
return mScreenOrientation;
|
||||||
}
|
}
|
||||||
@ -279,16 +281,6 @@ void nsScreen::MozUnlockOrientation() {
|
|||||||
mScreenOrientation->UnlockDeviceOrientation();
|
mScreenOrientation->UnlockDeviceOrientation();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsScreen::IsDeviceSizePageSize() {
|
|
||||||
if (nsPIDOMWindowInner* owner = GetOwner()) {
|
|
||||||
nsIDocShell* docShell = owner->GetDocShell();
|
|
||||||
if (docShell) {
|
|
||||||
return docShell->GetDeviceSizeIsPageSize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */
|
/* virtual */
|
||||||
JSObject* nsScreen::WrapObject(JSContext* aCx,
|
JSObject* nsScreen::WrapObject(JSContext* aCx,
|
||||||
JS::Handle<JSObject*> aGivenProto) {
|
JS::Handle<JSObject*> aGivenProto) {
|
||||||
@ -315,15 +307,3 @@ bool nsScreen::ShouldResistFingerprinting() const {
|
|||||||
}
|
}
|
||||||
return resist;
|
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) {
|
int32_t GetWidth(ErrorResult& aRv) {
|
||||||
nsRect rect;
|
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);
|
aRv = GetRect(rect);
|
||||||
return rect.Width();
|
return rect.Width();
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t GetHeight(ErrorResult& aRv) {
|
int32_t GetHeight(ErrorResult& aRv) {
|
||||||
nsRect rect;
|
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);
|
aRv = GetRect(rect);
|
||||||
return rect.Height();
|
return rect.Height();
|
||||||
}
|
}
|
||||||
@ -144,17 +118,14 @@ class nsScreen : public mozilla::DOMEventTargetHelper {
|
|||||||
nsresult GetRect(nsRect& aRect);
|
nsresult GetRect(nsRect& aRect);
|
||||||
nsresult GetAvailRect(nsRect& aRect);
|
nsresult GetAvailRect(nsRect& aRect);
|
||||||
nsresult GetWindowInnerRect(nsRect& aRect);
|
nsresult GetWindowInnerRect(nsRect& aRect);
|
||||||
nsresult GetRDMScreenSize(nsRect& aRect);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit nsScreen(nsPIDOMWindowInner* aWindow);
|
explicit nsScreen(nsPIDOMWindowInner* aWindow);
|
||||||
virtual ~nsScreen();
|
virtual ~nsScreen();
|
||||||
|
|
||||||
bool IsDeviceSizePageSize();
|
|
||||||
|
|
||||||
bool ShouldResistFingerprinting() const;
|
bool ShouldResistFingerprinting() const;
|
||||||
|
|
||||||
bool IsInRDMPane() const;
|
mozilla::dom::Document* TopContentDocumentInRDMPane() const;
|
||||||
|
|
||||||
RefPtr<mozilla::dom::ScreenOrientation> mScreenOrientation;
|
RefPtr<mozilla::dom::ScreenOrientation> mScreenOrientation;
|
||||||
};
|
};
|
||||||
|
@ -1062,92 +1062,16 @@ bool nsTreeSanitizer::MustPrune(int32_t aNamespace, nsAtom* aLocal,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsTreeSanitizer::SanitizeStyleDeclaration(DeclarationBlock* aDeclaration) {
|
|
||||||
return aDeclaration->RemovePropertyByID(eCSSProperty__moz_binding);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsTreeSanitizer::SanitizeStyleSheet(const nsAString& aOriginal,
|
void nsTreeSanitizer::SanitizeStyleSheet(const nsAString& aOriginal,
|
||||||
nsAString& aSanitized,
|
nsAString& aSanitized,
|
||||||
Document* aDocument,
|
Document* aDocument,
|
||||||
nsIURI* aBaseURI) {
|
nsIURI* aBaseURI) {
|
||||||
aSanitized.Truncate();
|
aSanitized.Truncate();
|
||||||
|
NS_ConvertUTF16toUTF8 style(aOriginal);
|
||||||
RefPtr<nsIReferrerInfo> referrer =
|
RefPtr<nsIReferrerInfo> referrer =
|
||||||
ReferrerInfo::CreateForInternalCSSResources(aDocument);
|
ReferrerInfo::CreateForInternalCSSResources(aDocument);
|
||||||
if (StaticPrefs::layout_css_moz_binding_content_enabled() ||
|
auto extraData =
|
||||||
aDocument->IsDocumentURISchemeChrome()) {
|
MakeRefPtr<URLExtraData>(aBaseURI, referrer, aDocument->NodePrincipal());
|
||||||
// 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;
|
|
||||||
RefPtr<RawServoStyleSheetContents> contents =
|
RefPtr<RawServoStyleSheetContents> contents =
|
||||||
Servo_StyleSheet_FromUTF8Bytes(
|
Servo_StyleSheet_FromUTF8Bytes(
|
||||||
/* loader = */ nullptr,
|
/* loader = */ nullptr,
|
||||||
@ -1156,9 +1080,8 @@ void nsTreeSanitizer::SanitizeStyleSheet(const nsAString& aOriginal,
|
|||||||
css::SheetParsingMode::eAuthorSheetFeatures, extraData.get(),
|
css::SheetParsingMode::eAuthorSheetFeatures, extraData.get(),
|
||||||
/* line_number_offset = */ 0, aDocument->GetCompatibilityMode(),
|
/* line_number_offset = */ 0, aDocument->GetCompatibilityMode(),
|
||||||
/* reusable_sheets = */ nullptr,
|
/* reusable_sheets = */ nullptr,
|
||||||
StyleAllowImportRules::Yes,
|
StyleAllowImportRules::Yes, StyleSanitizationKind::Standard,
|
||||||
sanitizationKind, &aSanitized)
|
&aSanitized).Consume();
|
||||||
.Consume();
|
|
||||||
|
|
||||||
if (mLogRemovals && aSanitized.Length() != aOriginal.Length()) {
|
if (mLogRemovals && aSanitized.Length() != aOriginal.Length()) {
|
||||||
LogMessage("Removed some rules and/or properties from stylesheet.",
|
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 (kNameSpaceID_None == attrNs) {
|
||||||
if (aAllowed.mStyle && nsGkAtoms::style == attrLocal) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
if (aAllowed.mDangerousSrc && nsGkAtoms::src == attrLocal) {
|
if (aAllowed.mDangerousSrc && nsGkAtoms::src == attrLocal) {
|
||||||
|
@ -76,7 +76,7 @@
|
|||||||
* its own sub-tree, even if multiple tabs are showing the same URI.
|
* 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
|
* - <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.
|
* the tab.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -57,3 +57,4 @@ skip-if = (os == "win" && processor == "aarch64") # aarch64 due to bug 1536566
|
|||||||
[browser_multiple_popups.js]
|
[browser_multiple_popups.js]
|
||||||
skip-if = os == 'win' && !debug # Bug 1505235
|
skip-if = os == 'win' && !debug # Bug 1505235
|
||||||
support-files = browser_multiple_popups.html
|
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
|
referrer_testserver.sjs
|
||||||
!/image/test/mochitest/shaver.png
|
!/image/test/mochitest/shaver.png
|
||||||
|
|
||||||
[test_anonymousContent_xul_window.xul]
|
[test_anonymousContent_xul_window.xhtml]
|
||||||
[test_blockParsing.html]
|
[test_blockParsing.html]
|
||||||
[test_blocking_image.html]
|
[test_blocking_image.html]
|
||||||
[test_bug419527.xhtml]
|
[test_bug419527.xhtml]
|
||||||
@ -23,12 +23,11 @@ support-files =
|
|||||||
[test_bug1008126.html]
|
[test_bug1008126.html]
|
||||||
[test_bug1016960.html]
|
[test_bug1016960.html]
|
||||||
[test_anchor_target_blank_referrer.html]
|
[test_anchor_target_blank_referrer.html]
|
||||||
[test_copypaste.xul]
|
[test_domrequesthelper.xhtml]
|
||||||
[test_domrequesthelper.xul]
|
[test_fragment_sanitization.xhtml]
|
||||||
[test_fragment_sanitization.xul]
|
|
||||||
[test_messagemanager_send_principal.html]
|
[test_messagemanager_send_principal.html]
|
||||||
[test_navigator_resolve_identity_xrays.xul]
|
[test_navigator_resolve_identity_xrays.xhtml]
|
||||||
support-files = file_navigator_resolve_identity_xrays.xul
|
support-files = file_navigator_resolve_identity_xrays.xhtml
|
||||||
[test_sandboxed_blob_uri.html]
|
[test_sandboxed_blob_uri.html]
|
||||||
[test_sendQueryContentAndSelectionSetEvent.html]
|
[test_sendQueryContentAndSelectionSetEvent.html]
|
||||||
[test_urgent_start.html]
|
[test_urgent_start.html]
|
||||||
|
@ -2,87 +2,83 @@
|
|||||||
skip-if = os == 'android'
|
skip-if = os == 'android'
|
||||||
support-files =
|
support-files =
|
||||||
bug418986-1.js
|
bug418986-1.js
|
||||||
cpows_child.js
|
clonedoc/**
|
||||||
cpows_parent.xul
|
file_bug549682.xhtml
|
||||||
file_bug549682.xul
|
file_bug616841.xhtml
|
||||||
file_bug616841.xul
|
file_bug816340.xhtml
|
||||||
file_bug816340.xul
|
file_bug990812-1.xhtml
|
||||||
file_bug990812-1.xul
|
file_bug990812-2.xhtml
|
||||||
file_bug990812-2.xul
|
file_bug990812-3.xhtml
|
||||||
file_bug990812-3.xul
|
file_bug990812-4.xhtml
|
||||||
file_bug990812-4.xul
|
file_bug990812-5.xhtml
|
||||||
file_bug990812-5.xul
|
file_bug1139964.xhtml
|
||||||
file_bug1139964.xul
|
file_bug1209621.xhtml
|
||||||
file_bug1209621.xul
|
|
||||||
fileconstructor_file.png
|
fileconstructor_file.png
|
||||||
frame_bug814638.xul
|
frame_bug814638.xhtml
|
||||||
frame_custom_element_content.html
|
frame_custom_element_content.html
|
||||||
custom_element_ep.js
|
custom_element_ep.js
|
||||||
host_bug814638.xul
|
host_bug814638.xhtml
|
||||||
window_nsITextInputProcessor.xul
|
window_nsITextInputProcessor.xhtml
|
||||||
title_window.xul
|
title_window.xhtml
|
||||||
window_swapFrameLoaders.xul
|
window_swapFrameLoaders.xhtml
|
||||||
|
|
||||||
[test_bug120684.xul]
|
[test_bug120684.xhtml]
|
||||||
[test_bug206691.xul]
|
[test_bug206691.xhtml]
|
||||||
[test_bug289714.xul]
|
[test_bug289714.xhtml]
|
||||||
[test_bug339494.xul]
|
[test_bug339494.xhtml]
|
||||||
[test_bug357450.xul]
|
[test_bug357450.xhtml]
|
||||||
support-files = ../file_bug357450.js
|
support-files = ../file_bug357450.js
|
||||||
[test_bug380418.html]
|
[test_bug380418.html]
|
||||||
[test_bug380418.html^headers^]
|
[test_bug380418.html^headers^]
|
||||||
[test_bug383430.html]
|
[test_bug383430.html]
|
||||||
[test_bug418986-1.xul]
|
[test_bug418986-1.xhtml]
|
||||||
[test_bug421622.xul]
|
[test_bug421622.xhtml]
|
||||||
[test_bug429785.xul]
|
[test_bug429785.xhtml]
|
||||||
[test_bug430050.xul]
|
[test_bug430050.xhtml]
|
||||||
[test_bug467123.xul]
|
[test_bug467123.xhtml]
|
||||||
[test_bug473284.xul]
|
[test_bug473284.xhtml]
|
||||||
[test_bug549682.xul]
|
[test_bug549682.xhtml]
|
||||||
skip-if = verify
|
skip-if = verify
|
||||||
[test_bug571390.xul]
|
[test_bug571390.xhtml]
|
||||||
[test_bug1098074_throw_from_ReceiveMessage.xul]
|
[test_bug1098074_throw_from_ReceiveMessage.xhtml]
|
||||||
[test_bug616841.xul]
|
[test_bug616841.xhtml]
|
||||||
[test_bug635835.xul]
|
[test_bug635835.xhtml]
|
||||||
[test_bug682305.html]
|
[test_bug682305.html]
|
||||||
[test_bug683852.xul]
|
[test_bug683852.xhtml]
|
||||||
[test_bug752226-3.xul]
|
[test_bug752226-3.xhtml]
|
||||||
[test_bug752226-4.xul]
|
[test_bug752226-4.xhtml]
|
||||||
[test_bug765993.html]
|
[test_bug765993.html]
|
||||||
[test_bug780199.xul]
|
[test_bug780199.xhtml]
|
||||||
[test_bug780529.xul]
|
[test_bug780529.xhtml]
|
||||||
[test_bug800386.xul]
|
[test_bug800386.xhtml]
|
||||||
[test_bug814638.xul]
|
[test_bug814638.xhtml]
|
||||||
[test_bug816340.xul]
|
[test_bug816340.xhtml]
|
||||||
[test_bug884693.xul]
|
[test_bug884693.xhtml]
|
||||||
[test_bug914381.html]
|
[test_bug914381.html]
|
||||||
[test_bug990812.xul]
|
[test_bug990812.xhtml]
|
||||||
[test_bug1063837.xul]
|
[test_bug1063837.xhtml]
|
||||||
[test_bug1139964.xul]
|
[test_bug1139964.xhtml]
|
||||||
[test_bug1209621.xul]
|
[test_bug1209621.xhtml]
|
||||||
[test_bug1346936.html]
|
[test_bug1346936.html]
|
||||||
[test_chromeOuterWindowID.xul]
|
[test_chromeOuterWindowID.xhtml]
|
||||||
support-files =
|
support-files =
|
||||||
window_chromeOuterWindowID.xul
|
window_chromeOuterWindowID.xhtml
|
||||||
[test_cpows.xul]
|
|
||||||
support-files =
|
|
||||||
cpows_child.html
|
|
||||||
[test_getElementsWithGrid.html]
|
[test_getElementsWithGrid.html]
|
||||||
[test_custom_element_content.xul]
|
[test_custom_element_content.xhtml]
|
||||||
[test_custom_element_ep.xul]
|
[test_custom_element_ep.xhtml]
|
||||||
[test_document-element-inserted.xul]
|
[test_document-element-inserted.xhtml]
|
||||||
support-files =
|
support-files =
|
||||||
file_document-element-inserted.xul
|
file_document-element-inserted.xhtml
|
||||||
file_document-element-inserted-inner.xul
|
file_document-element-inserted-inner.xhtml
|
||||||
[test_domparsing.xul]
|
[test_domparsing.xhtml]
|
||||||
[test_fileconstructor.xul]
|
[test_fileconstructor.xhtml]
|
||||||
[test_input_value_set_preserve_undo.xhtml]
|
[test_input_value_set_preserve_undo.xhtml]
|
||||||
[test_nsITextInputProcessor.xul]
|
[test_nsITextInputProcessor.xhtml]
|
||||||
[test_permission_isHandlingUserInput.xul]
|
[test_permission_isHandlingUserInput.xhtml]
|
||||||
support-files = ../dummy.html
|
support-files = ../dummy.html
|
||||||
[test_range_getClientRectsAndTexts.html]
|
[test_range_getClientRectsAndTexts.html]
|
||||||
[test_title.xul]
|
[test_title.xhtml]
|
||||||
support-files = file_title.xul
|
support-files = file_title.xhtml
|
||||||
[test_windowroot.xul]
|
[test_windowroot.xhtml]
|
||||||
[test_swapFrameLoaders.xul]
|
[test_swapFrameLoaders.xhtml]
|
||||||
[test_bug1339722.html]
|
[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);
|
messageManager.removeDelayedFrameScript(toBeRemovedScript);
|
||||||
|
|
||||||
var oldValue = globalListenerCallCount;
|
var oldValue = globalListenerCallCount;
|
||||||
var b = document.createElement("browser");
|
var b = document.createXULElement("browser");
|
||||||
b.setAttribute("type", "content");
|
b.setAttribute("type", "content");
|
||||||
document.documentElement.appendChild(b);
|
document.documentElement.appendChild(b);
|
||||||
is(globalListenerCallCount, oldValue + 1,
|
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("messagemanagergroup", "test");
|
||||||
browser.setAttribute("src", "about:mozilla");
|
browser.setAttribute("src", "about:mozilla");
|
||||||
browser.setAttribute("type", "content");
|
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("messagemanagergroup", "test");
|
||||||
browser.setAttribute("src", "about:mozilla");
|
browser.setAttribute("src", "about:mozilla");
|
||||||
browser.setAttribute("type", "content");
|
browser.setAttribute("type", "content");
|
@ -1,3 +1,3 @@
|
|||||||
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'>
|
<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>
|
</window>
|
@ -5,5 +5,5 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=814638
|
|||||||
-->
|
-->
|
||||||
<window title="Mozilla Bug 814638"
|
<window title="Mozilla Bug 814638"
|
||||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
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>
|
</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