- Revision
- 261012
- Author
- cdu...@apple.com
- Date
- 2020-05-01 12:42:45 -0700 (Fri, 01 May 2020)
Log Message
REGRESSION (r260243): [ Mac WK1 ] fast/media/mq-inverted-colors-live-update-for-listener.html is a flaky failure
https://bugs.webkit.org/show_bug.cgi?id=211154
<rdar://problem/62555128>
Reviewed by Darin Adler.
Make MediaQueryList an ActiveDOMObject and make sure its JS wrapper stays alive as long as
it may fire change events and there is at least 1 change event listener.
No new tests, already covered by existing tests.
* css/MediaQueryList.cpp:
(WebCore::MediaQueryList::MediaQueryList):
(WebCore::MediaQueryList::create):
(WebCore::MediaQueryList::~MediaQueryList):
(WebCore::MediaQueryList::detachFromMatcher):
(WebCore::MediaQueryList::evaluate):
(WebCore::MediaQueryList::setMatches):
(WebCore::MediaQueryList::matches):
(WebCore::MediaQueryList::eventListenersDidChange):
(WebCore::MediaQueryList::activeDOMObjectName const):
(WebCore::MediaQueryList::virtualHasPendingActivity const):
* css/MediaQueryList.h:
* css/MediaQueryList.idl:
* css/MediaQueryMatcher.cpp:
(WebCore::MediaQueryMatcher::documentDestroyed):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (261011 => 261012)
--- trunk/Source/WebCore/ChangeLog 2020-05-01 19:20:10 UTC (rev 261011)
+++ trunk/Source/WebCore/ChangeLog 2020-05-01 19:42:45 UTC (rev 261012)
@@ -1,3 +1,32 @@
+2020-05-01 Chris Dumez <cdu...@apple.com>
+
+ REGRESSION (r260243): [ Mac WK1 ] fast/media/mq-inverted-colors-live-update-for-listener.html is a flaky failure
+ https://bugs.webkit.org/show_bug.cgi?id=211154
+ <rdar://problem/62555128>
+
+ Reviewed by Darin Adler.
+
+ Make MediaQueryList an ActiveDOMObject and make sure its JS wrapper stays alive as long as
+ it may fire change events and there is at least 1 change event listener.
+
+ No new tests, already covered by existing tests.
+
+ * css/MediaQueryList.cpp:
+ (WebCore::MediaQueryList::MediaQueryList):
+ (WebCore::MediaQueryList::create):
+ (WebCore::MediaQueryList::~MediaQueryList):
+ (WebCore::MediaQueryList::detachFromMatcher):
+ (WebCore::MediaQueryList::evaluate):
+ (WebCore::MediaQueryList::setMatches):
+ (WebCore::MediaQueryList::matches):
+ (WebCore::MediaQueryList::eventListenersDidChange):
+ (WebCore::MediaQueryList::activeDOMObjectName const):
+ (WebCore::MediaQueryList::virtualHasPendingActivity const):
+ * css/MediaQueryList.h:
+ * css/MediaQueryList.idl:
+ * css/MediaQueryMatcher.cpp:
+ (WebCore::MediaQueryMatcher::documentDestroyed):
+
2020-05-01 Don Olmstead <don.olmst...@sony.com>
Use export macros on all platforms
Modified: trunk/Source/WebCore/css/MediaQueryList.cpp (261011 => 261012)
--- trunk/Source/WebCore/css/MediaQueryList.cpp 2020-05-01 19:20:10 UTC (rev 261011)
+++ trunk/Source/WebCore/css/MediaQueryList.cpp 2020-05-01 19:42:45 UTC (rev 261012)
@@ -28,26 +28,34 @@
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaQueryList);
MediaQueryList::MediaQueryList(Document& document, MediaQueryMatcher& matcher, Ref<MediaQuerySet>&& media, bool matches)
- : ContextDestructionObserver(&document)
- , m_matcher(matcher)
+ : ActiveDOMObject(&document)
+ , m_matcher(&matcher)
, m_media(WTFMove(media))
- , m_evaluationRound(m_matcher->evaluationRound())
+ , m_evaluationRound(matcher.evaluationRound())
, m_changeRound(m_evaluationRound - 1) // Any value that is not the same as m_evaluationRound would do.
, m_matches(matches)
{
- m_matcher->addMediaQueryList(*this);
+ matcher.addMediaQueryList(*this);
}
Ref<MediaQueryList> MediaQueryList::create(Document& document, MediaQueryMatcher& matcher, Ref<MediaQuerySet>&& media, bool matches)
{
- return adoptRef(*new MediaQueryList(document, matcher, WTFMove(media), matches));
+ auto list = adoptRef(*new MediaQueryList(document, matcher, WTFMove(media), matches));
+ list->suspendIfNeeded();
+ return list;
}
MediaQueryList::~MediaQueryList()
{
- m_matcher->removeMediaQueryList(*this);
+ if (m_matcher)
+ m_matcher->removeMediaQueryList(*this);
}
+void MediaQueryList::detachFromMatcher()
+{
+ m_matcher = nullptr;
+}
+
String MediaQueryList::media() const
{
return m_media->mediaText();
@@ -71,6 +79,11 @@
void MediaQueryList::evaluate(MediaQueryEvaluator& evaluator, bool& notificationNeeded)
{
+ if (!m_matcher) {
+ notificationNeeded = false;
+ return;
+ }
+
if (m_evaluationRound != m_matcher->evaluationRound())
setMatches(evaluator.evaluate(m_media.get()));
notificationNeeded = m_changeRound == m_matcher->evaluationRound();
@@ -78,6 +91,7 @@
void MediaQueryList::setMatches(bool newValue)
{
+ ASSERT(m_matcher);
m_evaluationRound = m_matcher->evaluationRound();
if (newValue == m_matches)
@@ -89,9 +103,24 @@
bool MediaQueryList::matches()
{
- if (m_evaluationRound != m_matcher->evaluationRound())
+ if (m_matcher && m_evaluationRound != m_matcher->evaluationRound())
setMatches(m_matcher->evaluate(m_media.get()));
return m_matches;
}
+void MediaQueryList::eventListenersDidChange()
+{
+ m_hasChangeEventListener = hasEventListeners(eventNames().changeEvent);
}
+
+const char* MediaQueryList::activeDOMObjectName() const
+{
+ return "MediaQueryList";
+}
+
+bool MediaQueryList::virtualHasPendingActivity() const
+{
+ return m_hasChangeEventListener && m_matcher;
+}
+
+}
Modified: trunk/Source/WebCore/css/MediaQueryList.h (261011 => 261012)
--- trunk/Source/WebCore/css/MediaQueryList.h 2020-05-01 19:20:10 UTC (rev 261011)
+++ trunk/Source/WebCore/css/MediaQueryList.h 2020-05-01 19:42:45 UTC (rev 261012)
@@ -19,7 +19,7 @@
#pragma once
-#include "ContextDestructionObserver.h"
+#include "ActiveDOMObject.h"
#include "EventTarget.h"
#include "MediaList.h"
#include "MediaQueryEvaluator.h"
@@ -32,7 +32,7 @@
// retrieve the current value of the given media query and to add/remove listeners that
// will be called whenever the value of the query changes.
-class MediaQueryList final : public RefCounted<MediaQueryList>, public EventTargetWithInlineData, public CanMakeWeakPtr<MediaQueryList>, private ContextDestructionObserver {
+class MediaQueryList final : public RefCounted<MediaQueryList>, public EventTargetWithInlineData, public CanMakeWeakPtr<MediaQueryList>, public ActiveDOMObject {
WTF_MAKE_ISO_ALLOCATED(MediaQueryList);
public:
static Ref<MediaQueryList> create(Document&, MediaQueryMatcher&, Ref<MediaQuerySet>&&, bool matches);
@@ -46,6 +46,8 @@
void evaluate(MediaQueryEvaluator&, bool& notificationNeeded);
+ void detachFromMatcher();
+
using RefCounted::ref;
using RefCounted::deref;
@@ -58,12 +60,18 @@
ScriptExecutionContext* scriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); }
void refEventTarget() final { ref(); }
void derefEventTarget() final { deref(); }
+ void eventListenersDidChange() final;
- Ref<MediaQueryMatcher> m_matcher;
+ // ActiveDOMObject.
+ const char* activeDOMObjectName() const final;
+ bool virtualHasPendingActivity() const final;
+
+ RefPtr<MediaQueryMatcher> m_matcher;
Ref<MediaQuerySet> m_media;
unsigned m_evaluationRound; // Indicates if the query has been evaluated after the last style selector change.
unsigned m_changeRound; // Used to know if the query has changed in the last style selector change.
bool m_matches;
+ bool m_hasChangeEventListener { false };
};
}
Modified: trunk/Source/WebCore/css/MediaQueryList.idl (261011 => 261012)
--- trunk/Source/WebCore/css/MediaQueryList.idl 2020-05-01 19:20:10 UTC (rev 261011)
+++ trunk/Source/WebCore/css/MediaQueryList.idl 2020-05-01 19:42:45 UTC (rev 261012)
@@ -17,6 +17,7 @@
* Boston, MA 02110-1301, USA.
*/
[
+ ActiveDOMObject,
Exposed=Window
] interface MediaQueryList : EventTarget {
readonly attribute DOMString media;
Modified: trunk/Source/WebCore/css/MediaQueryMatcher.cpp (261011 => 261012)
--- trunk/Source/WebCore/css/MediaQueryMatcher.cpp 2020-05-01 19:20:10 UTC (rev 261011)
+++ trunk/Source/WebCore/css/MediaQueryMatcher.cpp 2020-05-01 19:42:45 UTC (rev 261012)
@@ -48,7 +48,11 @@
void MediaQueryMatcher::documentDestroyed()
{
m_document = nullptr;
- m_mediaQueryLists.clear();
+ auto mediaQueryLists = std::exchange(m_mediaQueryLists, { });
+ for (auto& mediaQueryList : mediaQueryLists) {
+ if (mediaQueryList)
+ mediaQueryList->detachFromMatcher();
+ }
}
String MediaQueryMatcher::mediaType() const