diff options
Diffstat (limited to 'Source/WebCore/css/MediaQueryMatcher.cpp')
-rw-r--r-- | Source/WebCore/css/MediaQueryMatcher.cpp | 103 |
1 files changed, 42 insertions, 61 deletions
diff --git a/Source/WebCore/css/MediaQueryMatcher.cpp b/Source/WebCore/css/MediaQueryMatcher.cpp index 21849292f..d1a30d37d 100644 --- a/Source/WebCore/css/MediaQueryMatcher.cpp +++ b/Source/WebCore/css/MediaQueryMatcher.cpp @@ -21,42 +21,24 @@ #include "MediaQueryMatcher.h" #include "Document.h" -#include "Element.h" #include "Frame.h" #include "FrameView.h" #include "MediaList.h" #include "MediaQueryEvaluator.h" #include "MediaQueryList.h" #include "MediaQueryListListener.h" +#include "NodeRenderStyle.h" +#include "RenderElement.h" #include "StyleResolver.h" +#include "StyleScope.h" namespace WebCore { -MediaQueryMatcher::Listener::Listener(PassRefPtr<MediaQueryListListener> listener, PassRefPtr<MediaQueryList> query) - : m_listener(listener) - , m_query(query) +MediaQueryMatcher::MediaQueryMatcher(Document& document) + : m_document(&document) { } -MediaQueryMatcher::Listener::~Listener() -{ -} - -void MediaQueryMatcher::Listener::evaluate(MediaQueryEvaluator* evaluator) -{ - bool notify; - m_query->evaluate(evaluator, notify); - if (notify) - m_listener->queryChanged(m_query.get()); -} - -MediaQueryMatcher::MediaQueryMatcher(Document* document) - : m_document(document) - , m_evaluationRound(1) -{ - ASSERT(m_document); -} - MediaQueryMatcher::~MediaQueryMatcher() { } @@ -64,7 +46,7 @@ MediaQueryMatcher::~MediaQueryMatcher() void MediaQueryMatcher::documentDestroyed() { m_listeners.clear(); - m_document = 0; + m_document = nullptr; } String MediaQueryMatcher::mediaType() const @@ -75,66 +57,55 @@ String MediaQueryMatcher::mediaType() const return m_document->frame()->view()->mediaType(); } -std::unique_ptr<MediaQueryEvaluator> MediaQueryMatcher::prepareEvaluator() const +std::unique_ptr<RenderStyle> MediaQueryMatcher::documentElementUserAgentStyle() const { if (!m_document || !m_document->frame()) return nullptr; - Element* documentElement = m_document->documentElement(); + auto* documentElement = m_document->documentElement(); if (!documentElement) return nullptr; - RefPtr<RenderStyle> rootStyle = m_document->ensureStyleResolver().styleForElement(documentElement, 0 /*defaultParent*/, DisallowStyleSharing, MatchOnlyUserAgentRules); - - return std::make_unique<MediaQueryEvaluator>(mediaType(), m_document->frame(), rootStyle.get()); + return m_document->styleScope().resolver().styleForElement(*documentElement, m_document->renderStyle(), nullptr, MatchOnlyUserAgentRules).renderStyle; } -bool MediaQueryMatcher::evaluate(const MediaQuerySet* media) +bool MediaQueryMatcher::evaluate(const MediaQuerySet& media) { - if (!media) + auto style = documentElementUserAgentStyle(); + if (!style) return false; - - std::unique_ptr<MediaQueryEvaluator> evaluator = prepareEvaluator(); - return evaluator && evaluator->eval(media); + return MediaQueryEvaluator { mediaType(), *m_document, style.get() }.evaluate(media); } -PassRefPtr<MediaQueryList> MediaQueryMatcher::matchMedia(const String& query) +RefPtr<MediaQueryList> MediaQueryMatcher::matchMedia(const String& query) { if (!m_document) - return 0; - - RefPtr<MediaQuerySet> media = MediaQuerySet::create(query); -#if ENABLE(RESOLUTION_MEDIA_QUERY) - // Add warning message to inspector whenever dpi/dpcm values are used for "screen" media. - reportMediaQueryWarningIfNeeded(m_document, media.get()); -#endif - return MediaQueryList::create(this, media, evaluate(media.get())); + return nullptr; + + auto media = MediaQuerySet::create(query); + reportMediaQueryWarningIfNeeded(m_document, media.ptr()); + bool result = evaluate(media.get()); + return MediaQueryList::create(*this, WTFMove(media), result); } -void MediaQueryMatcher::addListener(PassRefPtr<MediaQueryListListener> listener, PassRefPtr<MediaQueryList> query) +void MediaQueryMatcher::addListener(Ref<MediaQueryListListener>&& listener, MediaQueryList& query) { if (!m_document) return; - for (size_t i = 0; i < m_listeners.size(); ++i) { - if (*m_listeners[i]->listener() == *listener && m_listeners[i]->query() == query) + for (auto& existingListener : m_listeners) { + if (existingListener.listener.get() == listener.get() && existingListener.query.ptr() == &query) return; } - m_listeners.append(std::make_unique<Listener>(listener, query)); + m_listeners.append(Listener { WTFMove(listener), query }); } -void MediaQueryMatcher::removeListener(MediaQueryListListener* listener, MediaQueryList* query) +void MediaQueryMatcher::removeListener(MediaQueryListListener& listener, MediaQueryList& query) { - if (!m_document) - return; - - for (size_t i = 0; i < m_listeners.size(); ++i) { - if (*m_listeners[i]->listener() == *listener && m_listeners[i]->query() == query) { - m_listeners.remove(i); - return; - } - } + m_listeners.removeFirstMatching([&listener, &query](auto& existingListener) { + return existingListener.listener.get() == listener && existingListener.query.ptr() == &query; + }); } void MediaQueryMatcher::styleResolverChanged() @@ -142,12 +113,22 @@ void MediaQueryMatcher::styleResolverChanged() ASSERT(m_document); ++m_evaluationRound; - std::unique_ptr<MediaQueryEvaluator> evaluator = prepareEvaluator(); - if (!evaluator) + + auto style = documentElementUserAgentStyle(); + if (!style) return; - for (size_t i = 0; i < m_listeners.size(); ++i) - m_listeners[i]->evaluate(evaluator.get()); + MediaQueryEvaluator evaluator { mediaType(), *m_document, style.get() }; + Vector<Listener> listeners; + listeners.reserveInitialCapacity(m_listeners.size()); + for (auto& listener : m_listeners) + listeners.uncheckedAppend({ listener.listener.copyRef(), listener.query.copyRef() }); + for (auto& listener : listeners) { + bool notify; + listener.query->evaluate(evaluator, notify); + if (notify) + listener.listener->handleEvent(listener.query.ptr()); + } } } // namespace WebCore |