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 { | 36 { |
38 } | 37 } |
39 | 38 |
40 void MediaQueryMatcher::Listener::evaluate(ScriptState* state, MediaQueryEvaluat or* evaluator) | |
41 { | |
42 if (m_query->evaluate(evaluator)) | |
43 m_listener->queryChanged(state, 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 { | |
56 ASSERT(m_document); | |
57 } | |
58 | |
59 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQueryMatcher) | 39 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQueryMatcher) |
60 | 40 |
61 void MediaQueryMatcher::documentDestroyed() | 41 void MediaQueryMatcher::documentDetached() |
62 { | 42 { |
63 m_listeners.clear(); | |
64 m_document = 0; | 43 m_document = 0; |
44 | |
45 // Take a ref to each MediaQuerylist as removing the listeners in documentDe tached | |
46 // could release the last ref and mutate the m_mediaLists. | |
47 WillBeHeapVector<RefPtrWillBeMember<MediaQueryList> > lists; | |
48 copyToVector(m_mediaLists, lists); | |
49 | |
50 for (size_t i = 0; i < lists.size(); ++i) | |
51 lists[i]->documentDetached(); | |
65 } | 52 } |
66 | 53 |
67 AtomicString MediaQueryMatcher::mediaType() const | 54 AtomicString MediaQueryMatcher::mediaType() const |
68 { | 55 { |
69 if (!m_document || !m_document->frame() || !m_document->frame()->view()) | 56 if (!m_document || !m_document->frame() || !m_document->frame()->view()) |
70 return nullAtom; | 57 return nullAtom; |
71 | 58 |
72 return m_document->frame()->view()->mediaType(); | 59 return m_document->frame()->view()->mediaType(); |
73 } | 60 } |
74 | 61 |
75 PassOwnPtr<MediaQueryEvaluator> MediaQueryMatcher::prepareEvaluator() const | 62 PassOwnPtr<MediaQueryEvaluator> MediaQueryMatcher::createEvaluator() const |
76 { | 63 { |
77 if (!m_document || !m_document->frame()) | 64 if (!m_document || !m_document->frame()) |
78 return nullptr; | 65 return nullptr; |
79 | 66 |
80 Element* documentElement = m_document->documentElement(); | 67 Element* documentElement = m_document->documentElement(); |
81 if (!documentElement) | 68 if (!documentElement) |
82 return nullptr; | 69 return nullptr; |
83 | 70 |
84 StyleResolver& styleResolver = m_document->ensureStyleResolver(); | 71 StyleResolver& styleResolver = m_document->ensureStyleResolver(); |
85 RefPtr<RenderStyle> rootStyle = styleResolver.styleForElement(documentElemen t, 0 /*defaultParent*/, DisallowStyleSharing, MatchOnlyUserAgentRules); | 72 RefPtr<RenderStyle> rootStyle = styleResolver.styleForElement(documentElemen t, 0 /*defaultParent*/, DisallowStyleSharing, MatchOnlyUserAgentRules); |
86 | 73 |
87 return adoptPtr(new MediaQueryEvaluator(mediaType(), m_document->frame(), ro otStyle.get())); | 74 return adoptPtr(new MediaQueryEvaluator(mediaType(), m_document->frame(), ro otStyle.get())); |
88 } | 75 } |
89 | 76 |
90 bool MediaQueryMatcher::evaluate(const MediaQuerySet* media) | 77 bool MediaQueryMatcher::evaluate(const MediaQuerySet* media) |
91 { | 78 { |
92 if (!media) | 79 if (!media) |
93 return false; | 80 return false; |
94 | 81 |
95 OwnPtr<MediaQueryEvaluator> evaluator(prepareEvaluator()); | 82 if (m_evaluator) |
96 return evaluator && evaluator->eval(media); | 83 return m_evaluator->eval(media); |
84 | |
85 if (OwnPtr<MediaQueryEvaluator> evaluator = createEvaluator()) | |
86 return evaluator->eval(media); | |
87 | |
88 return false; | |
97 } | 89 } |
98 | 90 |
99 PassRefPtrWillBeRawPtr<MediaQueryList> MediaQueryMatcher::matchMedia(const Strin g& query) | 91 PassRefPtrWillBeRawPtr<MediaQueryList> MediaQueryMatcher::matchMedia(const Strin g& query) |
100 { | 92 { |
101 if (!m_document) | 93 if (!m_document) |
102 return nullptr; | 94 return nullptr; |
103 | 95 |
104 RefPtrWillBeRawPtr<MediaQuerySet> media = MediaQuerySet::create(query); | 96 RefPtrWillBeRawPtr<MediaQuerySet> media = MediaQuerySet::create(query); |
105 // Add warning message to inspector whenever dpi/dpcm values are used for "s creen" media. | 97 // Add warning message to inspector whenever dpi/dpcm values are used for "s creen" media. |
106 reportMediaQueryWarningIfNeeded(m_document, media.get()); | 98 reportMediaQueryWarningIfNeeded(m_document, media.get()); |
107 return MediaQueryList::create(this, media, evaluate(media.get())); | 99 return MediaQueryList::create(this, media); |
108 } | 100 } |
109 | 101 |
110 void MediaQueryMatcher::addListener(PassRefPtrWillBeRawPtr<MediaQueryListListene r> listener, PassRefPtrWillBeRawPtr<MediaQueryList> query) | 102 void MediaQueryMatcher::addMediaQueryList(MediaQueryList* query) |
103 { | |
104 if (!m_document) | |
105 return; | |
106 m_mediaLists.add(query); | |
107 } | |
108 | |
109 void MediaQueryMatcher::removeMediaQueryList(MediaQueryList* query) | |
110 { | |
111 if (!m_document) | |
112 return; | |
113 m_mediaLists.remove(query); | |
114 } | |
115 | |
116 void MediaQueryMatcher::mediaChanged() | |
111 { | 117 { |
112 if (!m_document) | 118 if (!m_document) |
113 return; | 119 return; |
114 | 120 |
115 for (size_t i = 0; i < m_listeners.size(); ++i) { | 121 // FIXME: We should allow listeners in other worlds. |
116 if (*m_listeners[i]->listener() == *listener && m_listeners[i]->query() == query) | |
117 return; | |
118 } | |
119 | |
120 m_listeners.append(adoptPtrWillBeNoop(new Listener(listener, query))); | |
121 } | |
122 | |
123 void MediaQueryMatcher::removeListener(MediaQueryListListener* listener, MediaQu eryList* query) | |
124 { | |
125 if (!m_document) | |
126 return; | |
127 | |
128 for (size_t i = 0; i < m_listeners.size(); ++i) { | |
129 if (*m_listeners[i]->listener() == *listener && m_listeners[i]->query() == query) { | |
130 m_listeners.remove(i); | |
131 return; | |
132 } | |
133 } | |
134 } | |
135 | |
136 void MediaQueryMatcher::styleResolverChanged() | |
137 { | |
138 if (!m_document) | |
139 return; | |
140 | |
141 ScriptState* scriptState = m_document->frame() ? mainWorldScriptState(m_docu ment->frame()) : 0; | 122 ScriptState* scriptState = m_document->frame() ? mainWorldScriptState(m_docu ment->frame()) : 0; |
142 if (!scriptState) | 123 if (!scriptState) |
143 return; | 124 return; |
144 | 125 |
145 ++m_evaluationRound; | 126 // Cache an evaluator so we don't allocate one for each list below. |
146 OwnPtr<MediaQueryEvaluator> evaluator = prepareEvaluator(); | 127 m_evaluator = createEvaluator(); |
147 if (!evaluator) | 128 if (!m_evaluator) |
148 return; | 129 return; |
149 | 130 |
150 for (size_t i = 0; i < m_listeners.size(); ++i) | 131 WillBeHeapVector<RefPtrWillBeMember<MediaQueryListListener> > toNotify; |
151 m_listeners[i]->evaluate(scriptState, evaluator.get()); | 132 |
133 for (MediaQueryListSet::iterator it = m_mediaLists.begin(); it != m_mediaLis ts.end(); ++it) | |
134 (*it)->mediaChanged(toNotify); | |
kenneth.r.christiansen
2014/04/03 21:54:15
couldn't the name be made more clear to what happe
| |
135 | |
136 m_evaluator = 0; | |
137 | |
138 // FIXME: This should be async! We're running script inside ::layout() or :: updateRenderTree(). | |
139 for (size_t i = 0; i < toNotify.size(); ++i) | |
140 toNotify[i]->call(scriptState); | |
152 } | 141 } |
153 | 142 |
154 void MediaQueryMatcher::trace(Visitor* visitor) | 143 void MediaQueryMatcher::trace(Visitor* visitor) |
155 { | 144 { |
156 // We don't support tracing of vectors of OwnPtrs (ie. Vector<OwnPtr<Listene r> >). | 145 visitor->trace(m_mediaLists); |
157 // Since this is a transitional object we are just ifdef'ing it out when oil pan is not enabled. | |
158 #if ENABLE(OILPAN) | |
159 visitor->trace(m_listeners); | |
160 #endif | |
161 } | 146 } |
162 | 147 |
163 } | 148 } |
OLD | NEW |