Merge inbound to mozilla-central. a=merge

This commit is contained in:
Dorel Luca 2019-01-05 23:52:28 +02:00
commit e0ab49f760
5 changed files with 112 additions and 58 deletions

View File

@ -0,0 +1,14 @@
<script>
function eh1() {
a.remove()
window.event.composedPath()
}
function eh2() {
b.addEventListener("DOMNodeInserted", eh1)
c.insertAdjacentElement("afterBegin", document.createElement("s"))
}
</script>
<image srcset="A" onerror="eh2()"></image>
<marquee id="a">
<time id="b">
<dialog id="c">AA</dialog>

View File

@ -247,3 +247,4 @@ load 1505875.html
load 1505811.html
load 1508845.html
load 1516560.html
load 1516289.html

View File

@ -185,12 +185,12 @@ class EventTargetChainItem {
return nullptr;
}
bool IsValid() {
bool IsValid() const {
NS_WARNING_ASSERTION(!!(mTarget), "Event target is not valid!");
return !!(mTarget);
}
EventTarget* GetNewTarget() { return mNewTarget; }
EventTarget* GetNewTarget() const { return mNewTarget; }
void SetNewTarget(EventTarget* aNewTarget) { mNewTarget = aNewTarget; }
@ -205,7 +205,7 @@ class EventTargetChainItem {
mRetargetedTouchTargets = std::move(aTargets);
}
bool HasRetargetTouchTargets() {
bool HasRetargetTouchTargets() const {
return mRetargetedTouchTargets.isSome() || mInitialTargetTouches.isSome();
}
@ -253,41 +253,41 @@ class EventTargetChainItem {
mFlags.mForceContentDispatch = aForce;
}
bool ForceContentDispatch() { return mFlags.mForceContentDispatch; }
bool ForceContentDispatch() const { return mFlags.mForceContentDispatch; }
void SetWantsWillHandleEvent(bool aWants) {
mFlags.mWantsWillHandleEvent = aWants;
}
bool WantsWillHandleEvent() { return mFlags.mWantsWillHandleEvent; }
bool WantsWillHandleEvent() const { return mFlags.mWantsWillHandleEvent; }
void SetWantsPreHandleEvent(bool aWants) {
mFlags.mWantsPreHandleEvent = aWants;
}
bool WantsPreHandleEvent() { return mFlags.mWantsPreHandleEvent; }
bool WantsPreHandleEvent() const { return mFlags.mWantsPreHandleEvent; }
void SetPreHandleEventOnly(bool aWants) {
mFlags.mPreHandleEventOnly = aWants;
}
bool PreHandleEventOnly() { return mFlags.mPreHandleEventOnly; }
bool PreHandleEventOnly() const { return mFlags.mPreHandleEventOnly; }
void SetRootOfClosedTree(bool aSet) { mFlags.mRootOfClosedTree = aSet; }
bool IsRootOfClosedTree() { return mFlags.mRootOfClosedTree; }
bool IsRootOfClosedTree() const { return mFlags.mRootOfClosedTree; }
void SetItemInShadowTree(bool aSet) { mFlags.mItemInShadowTree = aSet; }
bool IsItemInShadowTree() { return mFlags.mItemInShadowTree; }
bool IsItemInShadowTree() const { return mFlags.mItemInShadowTree; }
void SetIsSlotInClosedTree(bool aSet) { mFlags.mIsSlotInClosedTree = aSet; }
bool IsSlotInClosedTree() { return mFlags.mIsSlotInClosedTree; }
bool IsSlotInClosedTree() const { return mFlags.mIsSlotInClosedTree; }
void SetIsChromeHandler(bool aSet) { mFlags.mIsChromeHandler = aSet; }
bool IsChromeHandler() { return mFlags.mIsChromeHandler; }
bool IsChromeHandler() const { return mFlags.mIsChromeHandler; }
void SetMayHaveListenerManager(bool aMayHave) {
mFlags.mMayHaveManager = aMayHave;
@ -295,7 +295,7 @@ class EventTargetChainItem {
bool MayHaveListenerManager() { return mFlags.mMayHaveManager; }
EventTarget* CurrentTarget() { return mTarget; }
EventTarget* CurrentTarget() const { return mTarget; }
/**
* Dispatches event through the event target chain.
@ -1295,9 +1295,41 @@ static bool ShouldClearTargets(WidgetEvent* aEvent) {
return nullptr;
}
// static
struct CurrentTargetPathInfo {
uint32_t mIndex;
int32_t mHiddenSubtreeLevel;
};
static CurrentTargetPathInfo TargetPathInfo(
const nsTArray<EventTargetChainItem>& aEventPath,
const EventTarget& aCurrentTarget) {
int32_t currentTargetHiddenSubtreeLevel = 0;
for (uint32_t index = aEventPath.Length(); index--;) {
const EventTargetChainItem& item = aEventPath.ElementAt(index);
if (item.PreHandleEventOnly()) {
continue;
}
if (item.IsRootOfClosedTree()) {
currentTargetHiddenSubtreeLevel++;
}
if (item.CurrentTarget() == &aCurrentTarget) {
return {index, currentTargetHiddenSubtreeLevel};
}
if (item.IsSlotInClosedTree()) {
currentTargetHiddenSubtreeLevel--;
}
}
MOZ_ASSERT_UNREACHABLE("No target found?");
return {0, 0};
}
// https://dom.spec.whatwg.org/#dom-event-composedpath
void EventDispatcher::GetComposedPathFor(WidgetEvent* aEvent,
nsTArray<RefPtr<EventTarget>>& aPath) {
MOZ_ASSERT(aPath.IsEmpty());
nsTArray<EventTargetChainItem>* path = aEvent->mPath;
if (!path || path->IsEmpty() || !aEvent->mCurrentTarget) {
return;
@ -1309,47 +1341,68 @@ void EventDispatcher::GetComposedPathFor(WidgetEvent* aEvent,
return;
}
AutoTArray<EventTarget*, 128> reversedComposedPath;
bool hasSeenCurrentTarget = false;
uint32_t hiddenSubtreeLevel = 0;
for (uint32_t i = path->Length(); i;) {
--i;
CurrentTargetPathInfo currentTargetInfo =
TargetPathInfo(*path, *currentTarget);
EventTargetChainItem& item = path->ElementAt(i);
if (item.PreHandleEventOnly()) {
continue;
}
{
int32_t maxHiddenLevel = currentTargetInfo.mHiddenSubtreeLevel;
int32_t currentHiddenLevel = currentTargetInfo.mHiddenSubtreeLevel;
for (uint32_t index = currentTargetInfo.mIndex; index--;) {
EventTargetChainItem& item = path->ElementAt(index);
if (item.PreHandleEventOnly()) {
continue;
}
if (!hasSeenCurrentTarget && currentTarget == item.CurrentTarget()) {
hasSeenCurrentTarget = true;
} else if (hasSeenCurrentTarget && item.IsRootOfClosedTree()) {
++hiddenSubtreeLevel;
}
if (item.IsRootOfClosedTree()) {
currentHiddenLevel++;
}
if (hiddenSubtreeLevel == 0) {
reversedComposedPath.AppendElement(item.CurrentTarget());
}
if (currentHiddenLevel <= maxHiddenLevel) {
aPath.AppendElement(item.CurrentTarget()->GetTargetForDOMEvent());
}
if (item.IsSlotInClosedTree() && hiddenSubtreeLevel > 0) {
--hiddenSubtreeLevel;
}
if (item.IsChromeHandler()) {
if (hasSeenCurrentTarget) {
// The current behavior is to include only EventTargets from
// either chrome side of event path or content side, not from both.
if (item.IsChromeHandler()) {
break;
}
// Need to start all over to collect the composed path on content side.
reversedComposedPath.Clear();
if (item.IsSlotInClosedTree()) {
currentHiddenLevel--;
maxHiddenLevel = std::min(maxHiddenLevel, currentHiddenLevel);
}
}
aPath.Reverse();
}
aPath.SetCapacity(reversedComposedPath.Length());
for (uint32_t i = reversedComposedPath.Length(); i;) {
--i;
aPath.AppendElement(reversedComposedPath[i]->GetTargetForDOMEvent());
aPath.AppendElement(currentTarget->GetTargetForDOMEvent());
{
int32_t maxHiddenLevel = currentTargetInfo.mHiddenSubtreeLevel;
int32_t currentHiddenLevel = currentTargetInfo.mHiddenSubtreeLevel;
for (uint32_t index = currentTargetInfo.mIndex + 1; index < path->Length();
++index) {
EventTargetChainItem& item = path->ElementAt(index);
if (item.PreHandleEventOnly()) {
continue;
}
if (item.IsSlotInClosedTree()) {
currentHiddenLevel++;
}
if (item.IsChromeHandler()) {
break;
}
if (currentHiddenLevel <= maxHiddenLevel) {
aPath.AppendElement(item.CurrentTarget()->GetTargetForDOMEvent());
}
if (item.IsRootOfClosedTree()) {
currentHiddenLevel--;
maxHiddenLevel = std::min(maxHiddenLevel, currentHiddenLevel);
}
}
}
}

View File

@ -1,7 +0,0 @@
[Extensions-to-Event-Interface.html]
[The event must not propagate out of closed mode shadow tree of the target but must propagate out of inner shadow trees when the scoped flag is set]
expected: FAIL
[composedPath() must contain and only contain the unclosed nodes of target in closed mode shadow trees]
expected: FAIL

View File

@ -1,7 +0,0 @@
[event-composed-path.html]
[Event Path with a slot in a closed Shadow Root.]
expected: FAIL
[Event Path with slots in nested ShadowRoots: closed > closed.]
expected: FAIL