| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) | 2 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) |
| 3 * | 3 * |
| 4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
| 5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
| 6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
| 7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
| 8 * | 8 * |
| 9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 #include "core/css/MediaQueryEvaluator.h" | 24 #include "core/css/MediaQueryEvaluator.h" |
| 25 #include "core/css/MediaQueryList.h" | 25 #include "core/css/MediaQueryList.h" |
| 26 #include "core/css/MediaQueryListListener.h" | 26 #include "core/css/MediaQueryListListener.h" |
| 27 #include "core/css/resolver/StyleResolver.h" | 27 #include "core/css/resolver/StyleResolver.h" |
| 28 #include "core/dom/Document.h" | 28 #include "core/dom/Document.h" |
| 29 #include "core/frame/FrameView.h" | 29 #include "core/frame/FrameView.h" |
| 30 #include "core/frame/LocalFrame.h" | 30 #include "core/frame/LocalFrame.h" |
| 31 | 31 |
| 32 namespace WebCore { | 32 namespace WebCore { |
| 33 | 33 |
| 34 MediaQueryMatcher::Listener::Listener(PassRefPtrWillBeRawPtr<MediaQueryListListe
ner> listener, PassRefPtrWillBeRawPtr<MediaQueryList> query) | 34 MediaQueryMatcher::MediaQueryMatcher(Document& document) |
| 35 : m_listener(listener) | 35 : m_document(&document) |
| 36 , m_query(query) | |
| 37 { | |
| 38 } | |
| 39 | |
| 40 void MediaQueryMatcher::Listener::evaluate(MediaQueryEvaluator* evaluator) | |
| 41 { | |
| 42 if (m_query->evaluate(evaluator)) | |
| 43 m_listener->queryChanged(m_query.get()); | |
| 44 } | |
| 45 | |
| 46 void MediaQueryMatcher::Listener::trace(Visitor* visitor) | |
| 47 { | |
| 48 visitor->trace(m_listener); | |
| 49 visitor->trace(m_query); | |
| 50 } | |
| 51 | |
| 52 MediaQueryMatcher::MediaQueryMatcher(Document* document) | |
| 53 : m_document(document) | |
| 54 , m_evaluationRound(1) | |
| 55 { | 36 { |
| 56 ASSERT(m_document); | 37 ASSERT(m_document); |
| 57 } | 38 } |
| 58 | 39 |
| 59 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQueryMatcher) | 40 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQueryMatcher) |
| 60 | 41 |
| 61 void MediaQueryMatcher::documentDestroyed() | 42 void MediaQueryMatcher::documentDetached() |
| 62 { | 43 { |
| 63 m_listeners.clear(); | |
| 64 m_document = nullptr; | 44 m_document = nullptr; |
| 45 |
| 46 // Take a ref to each MediaQueryList as removing the listeners in documentDe
tached |
| 47 // could release the last ref and mutate the m_mediaLists. |
| 48 WillBeHeapVector<RefPtrWillBeMember<MediaQueryList> > lists; |
| 49 copyToVector(m_mediaLists, lists); |
| 50 |
| 51 for (size_t i = 0; i < lists.size(); ++i) |
| 52 lists[i]->documentDetached(); |
| 65 } | 53 } |
| 66 | 54 |
| 67 AtomicString MediaQueryMatcher::mediaType() const | 55 AtomicString MediaQueryMatcher::mediaType() const |
| 68 { | 56 { |
| 69 if (!m_document || !m_document->frame() || !m_document->frame()->view()) | 57 if (!m_document || !m_document->frame() || !m_document->frame()->view()) |
| 70 return nullAtom; | 58 return nullAtom; |
| 71 | 59 |
| 72 return m_document->frame()->view()->mediaType(); | 60 return m_document->frame()->view()->mediaType(); |
| 73 } | 61 } |
| 74 | 62 |
| 75 PassOwnPtr<MediaQueryEvaluator> MediaQueryMatcher::prepareEvaluator() const | 63 PassOwnPtr<MediaQueryEvaluator> MediaQueryMatcher::createEvaluator() const |
| 76 { | 64 { |
| 77 if (!m_document || !m_document->frame()) | 65 if (!m_document || !m_document->frame()) |
| 78 return nullptr; | 66 return nullptr; |
| 79 | 67 |
| 80 return adoptPtr(new MediaQueryEvaluator(mediaType(), m_document->frame())); | 68 return adoptPtr(new MediaQueryEvaluator(mediaType(), m_document->frame())); |
| 81 } | 69 } |
| 82 | 70 |
| 83 bool MediaQueryMatcher::evaluate(const MediaQuerySet* media) | 71 bool MediaQueryMatcher::evaluate(const MediaQuerySet* media) |
| 84 { | 72 { |
| 85 if (!media) | 73 if (!media) |
| 86 return false; | 74 return false; |
| 87 | 75 |
| 88 OwnPtr<MediaQueryEvaluator> evaluator(prepareEvaluator()); | 76 if (m_evaluator) |
| 89 return evaluator && evaluator->eval(media); | 77 return m_evaluator->eval(media); |
| 78 |
| 79 if (OwnPtr<MediaQueryEvaluator> evaluator = createEvaluator()) |
| 80 return evaluator->eval(media); |
| 81 |
| 82 return false; |
| 90 } | 83 } |
| 91 | 84 |
| 92 PassRefPtrWillBeRawPtr<MediaQueryList> MediaQueryMatcher::matchMedia(const Strin
g& query) | 85 PassRefPtrWillBeRawPtr<MediaQueryList> MediaQueryMatcher::matchMedia(const Strin
g& query) |
| 93 { | 86 { |
| 94 if (!m_document) | 87 if (!m_document) |
| 95 return nullptr; | 88 return nullptr; |
| 96 | 89 |
| 97 RefPtrWillBeRawPtr<MediaQuerySet> media = MediaQuerySet::create(query); | 90 RefPtrWillBeRawPtr<MediaQuerySet> media = MediaQuerySet::create(query); |
| 98 // Add warning message to inspector whenever dpi/dpcm values are used for "s
creen" media. | 91 // Add warning message to inspector whenever dpi/dpcm values are used for "s
creen" media. |
| 99 reportMediaQueryWarningIfNeeded(m_document, media.get()); | 92 reportMediaQueryWarningIfNeeded(m_document, media.get()); |
| 100 return MediaQueryList::create(this, media, evaluate(media.get())); | 93 return MediaQueryList::create(this, media); |
| 101 } | 94 } |
| 102 | 95 |
| 103 void MediaQueryMatcher::addListener(PassRefPtrWillBeRawPtr<MediaQueryListListene
r> listener, PassRefPtrWillBeRawPtr<MediaQueryList> query) | 96 void MediaQueryMatcher::addMediaQueryList(MediaQueryList* query) |
| 97 { |
| 98 if (!m_document) |
| 99 return; |
| 100 m_mediaLists.add(query); |
| 101 } |
| 102 |
| 103 void MediaQueryMatcher::removeMediaQueryList(MediaQueryList* query) |
| 104 { |
| 105 if (!m_document) |
| 106 return; |
| 107 m_mediaLists.remove(query); |
| 108 } |
| 109 |
| 110 void MediaQueryMatcher::mediaFeaturesChanged() |
| 104 { | 111 { |
| 105 if (!m_document) | 112 if (!m_document) |
| 106 return; | 113 return; |
| 107 | 114 |
| 108 for (size_t i = 0; i < m_listeners.size(); ++i) { | 115 // Cache an evaluator so we don't allocate one for each list below. |
| 109 if (*m_listeners[i]->listener() == *listener && m_listeners[i]->query()
== query) | 116 m_evaluator = createEvaluator(); |
| 110 return; | 117 if (!m_evaluator) |
| 111 } | |
| 112 | |
| 113 m_listeners.append(adoptPtrWillBeNoop(new Listener(listener, query))); | |
| 114 } | |
| 115 | |
| 116 void MediaQueryMatcher::removeListener(MediaQueryListListener* listener, MediaQu
eryList* query) | |
| 117 { | |
| 118 if (!m_document) | |
| 119 return; | 118 return; |
| 120 | 119 |
| 121 for (size_t i = 0; i < m_listeners.size(); ++i) { | 120 WillBeHeapVector<RefPtrWillBeMember<MediaQueryListListener> > listenersToNot
ify; |
| 122 if (*m_listeners[i]->listener() == *listener && m_listeners[i]->query()
== query) { | 121 for (MediaQueryListSet::iterator it = m_mediaLists.begin(); it != m_mediaLis
ts.end(); ++it) |
| 123 m_listeners.remove(i); | 122 (*it)->mediaFeaturesChanged(&listenersToNotify); |
| 124 return; | |
| 125 } | |
| 126 } | |
| 127 } | |
| 128 | 123 |
| 129 void MediaQueryMatcher::styleResolverChanged() | 124 m_evaluator = nullptr; |
| 130 { | 125 // FIXME: This should be async! We're running script inside ::layout() or ::
updateRenderTree(). |
| 131 if (!m_document) | 126 for (size_t i = 0; i < listenersToNotify.size(); ++i) |
| 132 return; | 127 listenersToNotify[i]->call(); |
| 133 | |
| 134 ++m_evaluationRound; | |
| 135 OwnPtr<MediaQueryEvaluator> evaluator = prepareEvaluator(); | |
| 136 if (!evaluator) | |
| 137 return; | |
| 138 | |
| 139 for (size_t i = 0; i < m_listeners.size(); ++i) | |
| 140 m_listeners[i]->evaluate(evaluator.get()); | |
| 141 } | 128 } |
| 142 | 129 |
| 143 void MediaQueryMatcher::trace(Visitor* visitor) | 130 void MediaQueryMatcher::trace(Visitor* visitor) |
| 144 { | 131 { |
| 145 visitor->trace(m_document); | 132 visitor->trace(m_document); |
| 146 // We don't support tracing of vectors of OwnPtrs (ie. Vector<OwnPtr<Listene
r> >). | 133 visitor->trace(m_mediaLists); |
| 147 // Since this is a transitional object we are just ifdef'ing it out when oil
pan is not enabled. | |
| 148 #if ENABLE(OILPAN) | |
| 149 visitor->trace(m_listeners); | |
| 150 #endif | |
| 151 } | 134 } |
| 152 | 135 |
| 153 } | 136 } |
| OLD | NEW |