Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(481)

Side by Side Diff: Source/core/css/MediaQueryMatcher.cpp

Issue 348893004: Rework MediaQueryMatcher to batch up listener notification (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: now with it Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/css/MediaQueryMatcher.h ('k') | Source/core/dom/Document.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 }
OLDNEW
« no previous file with comments | « Source/core/css/MediaQueryMatcher.h ('k') | Source/core/dom/Document.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698