Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: src/plugin/PluginDomTraverserBase.h

Issue 6237450183639040: Issue 1283 - wrong usage of memset, fix sizeof, make proper initializing (Closed)
Patch Set: Created Sept. 1, 2014, 11:52 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 #ifndef _PLUGIN_DOM_TRAVERSER_BASE_H_ 1 #ifndef _PLUGIN_DOM_TRAVERSER_BASE_H_
2 #define _PLUGIN_DOM_TRAVERSER_BASE_H_ 2 #define _PLUGIN_DOM_TRAVERSER_BASE_H_
3 3
4 4
5 #include "PluginTypedef.h" 5 #include "PluginTypedef.h"
6 #include "PluginTab.h" 6 #include "PluginTab.h"
7 7
8 8
9 class CPluginDomTraverserCacheBase 9 class CPluginDomTraverserCacheBase
10 { 10 {
(...skipping 14 matching lines...) Expand all
25 CPluginDomTraverserBase(CPluginTab* tab); 25 CPluginDomTraverserBase(CPluginTab* tab);
26 ~CPluginDomTraverserBase(); 26 ~CPluginDomTraverserBase();
27 27
28 void TraverseHeader(bool isHeaderTraversed); 28 void TraverseHeader(bool isHeaderTraversed);
29 29
30 void TraverseDocument(IWebBrowser2* pBrowser, const CString& domain, const CSt ring& documentName); 30 void TraverseDocument(IWebBrowser2* pBrowser, const CString& domain, const CSt ring& documentName);
31 void TraverseSubdocument(IWebBrowser2* pBrowser, const CString& domain, const CString& documentName); 31 void TraverseSubdocument(IWebBrowser2* pBrowser, const CString& domain, const CString& documentName);
32 32
33 virtual void ClearCache(); 33 virtual void ClearCache();
34 34
35 void ShowNotification(CPluginTab* tab); 35 void ShowNotification(CPluginTab* /*tab*/){}
Eric 2014/09/26 16:36:40 ShowNotification is completely dead code. The symb
Oleksandr 2014/10/06 20:19:32 +1 On 2014/09/26 16:36:40, Eric wrote:
36 36
37 protected: 37 protected:
38 38
39 virtual bool OnIFrame(IHTMLElement* pEl, const CString& url, CString& indent) { return true; } 39 virtual bool OnIFrame(IHTMLElement* pEl, const CString& url, CString& indent) { return true; }
40 virtual bool OnElement(IHTMLElement* pEl, const CString& tag, T* cache, bool i sDebug, CString& indent) { return true; } 40 virtual bool OnElement(IHTMLElement* pEl, const CString& tag, T* cache, bool i sDebug, CString& indent) { return true; }
41 41
42 virtual bool IsEnabled(); 42 virtual bool IsEnabled();
43 43
44 protected: 44 protected:
45 45
46 void TraverseDocument(IWebBrowser2* pBrowser, bool isMainDoc, CString indent); 46 void TraverseDocument(IWebBrowser2* pBrowser, bool isMainDoc, CString indent);
47 void TraverseChild(IHTMLElement* pEl, IWebBrowser2* pBrowser, CString& indent, bool isCached=true); 47 void TraverseChild(IHTMLElement* pEl, IWebBrowser2* pBrowser, CString& indent, bool isCached=true);
48 48
49 typedef ATL::CComCritSecLock<CComAutoCriticalSection> CriticalSectionLock;
Eric 2014/10/08 16:26:55 "Sentry" is the word that Stroustrup uses for thes
49 CComAutoCriticalSection m_criticalSection; 50 CComAutoCriticalSection m_criticalSection;
50 51
51 CString m_domain; 52 CString m_domain;
52 CString m_documentName; 53 CString m_documentName;
53 54
54 bool m_isHeaderTraversed; 55 bool m_isHeaderTraversed;
55 56
56 // Caching
57 long m_cacheDomElementCount;
58
59 int m_cacheIndexLast;
60 int m_cacheElementsMax;
61 std::set<CString> m_cacheDocumentHasFrames; 57 std::set<CString> m_cacheDocumentHasFrames;
62 std::set<CString> m_cacheDocumentHasIframes; 58 std::set<CString> m_cacheDocumentHasIframes;
63 59
64 T* m_cacheElements; 60 std::vector<T> m_cacheElements;
65 61
66 CPluginTab* m_tab; 62 CPluginTab* m_tab;
67 CComPtr<IWebBrowser2> m_pBrowser; 63 CComPtr<IWebBrowser2> m_pBrowser;
68 }; 64 };
69 65
70 template <class T> 66 template <class T>
71 CPluginDomTraverserBase<T>::CPluginDomTraverserBase(CPluginTab* tab) : 67 CPluginDomTraverserBase<T>::CPluginDomTraverserBase(CPluginTab* tab) :
72 m_tab(tab), m_isHeaderTraversed(false), m_cacheDomElementCount(0), m_cacheInde xLast(0), m_cacheElementsMax(5000) 68 m_tab(tab), m_isHeaderTraversed(false)
73 { 69 {
74 m_cacheElements = new T[m_cacheElementsMax]; 70 m_cacheElements.reserve(5000);
75 } 71 }
76 72
77
78 template <class T> 73 template <class T>
79 CPluginDomTraverserBase<T>::~CPluginDomTraverserBase() 74 CPluginDomTraverserBase<T>::~CPluginDomTraverserBase()
80 { 75 {
81 delete [] m_cacheElements;
82 } 76 }
83 77
84 template <class T> 78 template <class T>
85 void CPluginDomTraverserBase<T>::TraverseHeader(bool isHeaderTraversed) 79 void CPluginDomTraverserBase<T>::TraverseHeader(bool isHeaderTraversed)
86 { 80 {
87 m_isHeaderTraversed = isHeaderTraversed; 81 m_isHeaderTraversed = isHeaderTraversed;
88 } 82 }
89 83
90 template <class T> 84 template <class T>
91 void CPluginDomTraverserBase<T>::TraverseDocument(IWebBrowser2* pBrowser, const CString& domain, const CString& documentName) 85 void CPluginDomTraverserBase<T>::TraverseDocument(IWebBrowser2* pBrowser, const CString& domain, const CString& documentName)
92 { 86 {
93 m_domain = domain; 87 m_domain = domain;
94
95 TraverseDocument(pBrowser, true, ""); 88 TraverseDocument(pBrowser, true, "");
96 } 89 }
97 90
98 91
99 template <class T> 92 template <class T>
100 void CPluginDomTraverserBase<T>::TraverseSubdocument(IWebBrowser2* pBrowser, con st CString& domain, const CString& documentName) 93 void CPluginDomTraverserBase<T>::TraverseSubdocument(IWebBrowser2* pBrowser, con st CString& domain, const CString& documentName)
101 { 94 {
102 m_domain = domain; 95 m_domain = domain;
103
104 TraverseDocument(pBrowser, false, ""); 96 TraverseDocument(pBrowser, false, "");
105 } 97 }
106 98
107 99
108 template <class T> 100 template <class T>
109 bool CPluginDomTraverserBase<T>::IsEnabled() 101 bool CPluginDomTraverserBase<T>::IsEnabled()
110 { 102 {
111 return CPluginSettings::GetInstance()->IsPluginEnabled(); 103 return CPluginSettings::GetInstance()->IsPluginEnabled();
112 } 104 }
113 105
114 106
115 template <class T> 107 template <class T>
116 void CPluginDomTraverserBase<T>::TraverseDocument(IWebBrowser2* pBrowser, bool i sMainDoc, CString indent) 108 void CPluginDomTraverserBase<T>::TraverseDocument(IWebBrowser2* pBrowser, bool i sMainDoc, CString indent)
117 { 109 {
118 DWORD res = WaitForSingleObject(m_tab->m_filter->hideFiltersLoadedEvent, ENGIN E_STARTUP_TIMEOUT); 110 DWORD res = WaitForSingleObject(m_tab->m_filter->hideFiltersLoadedEvent, ENGIN E_STARTUP_TIMEOUT);
119 if (!IsEnabled()) return; 111 if (!IsEnabled()) return;
120 112
121 VARIANT_BOOL isBusy; 113 VARIANT_BOOL isBusy;
122 if (SUCCEEDED(pBrowser->get_Busy(&isBusy))) 114 if (FAILED(pBrowser->get_Busy(&isBusy)) || isBusy)
123 { 115 {
124 if (isBusy) 116 return;
125 {
126 return;
127 }
128 } 117 }
129 118
130 // Get document 119 // Get document
131 CComPtr<IDispatch> pDocDispatch; 120 CComPtr<IDispatch> pDocDispatch;
132 HRESULT hr = pBrowser->get_Document(&pDocDispatch); 121 HRESULT hr = pBrowser->get_Document(&pDocDispatch);
133 if (FAILED(hr) || !pDocDispatch) 122 if (FAILED(hr) || !pDocDispatch)
134 { 123 {
135 return; 124 return;
136 } 125 }
137 126
(...skipping 11 matching lines...) Expand all
149 138
150 CComPtr<IHTMLElement> pBodyEl; 139 CComPtr<IHTMLElement> pBodyEl;
151 140
152 if (m_isHeaderTraversed) 141 if (m_isHeaderTraversed)
153 { 142 {
154 pBodyEl = pBody; 143 pBodyEl = pBody;
155 } 144 }
156 else 145 else
157 { 146 {
158 CComPtr<IHTMLElementCollection> pBodyCollection; 147 CComPtr<IHTMLElementCollection> pBodyCollection;
159 if (FAILED(pDoc->getElementsByTagName(L"body", &pBodyCollection)) || !pBodyC ollection) 148 if (FAILED(pDoc->getElementsByTagName(ATL::CComBSTR(L"body"), &pBodyCollecti on)) || !pBodyCollection)
Oleksandr 2014/10/06 20:19:32 I would be willing to have this committed without
160 { 149 {
161 return; 150 return;
162 } 151 }
163 152
164 CComVariant vIndex(0); 153 CComVariant vIndex(0);
165 CComPtr<IDispatch> pBodyDispatch; 154 CComPtr<IDispatch> pBodyDispatch;
166 if (FAILED(pBodyCollection->item(vIndex, vIndex, &pBodyDispatch)) || !pBodyD ispatch) 155 if (FAILED(pBodyCollection->item(vIndex, vIndex, &pBodyDispatch)) || !pBodyD ispatch)
167 { 156 {
168 return; 157 return;
169 } 158 }
170 159
171 if (FAILED(pBodyDispatch->QueryInterface(IID_IHTMLElement, (LPVOID*)&pBodyEl )) || !pBodyEl) 160 if (FAILED(pBodyDispatch->QueryInterface(IID_IHTMLElement, (LPVOID*)&pBodyEl )) || !pBodyEl)
172 { 161 {
173 return; 162 return;
174 } 163 }
175 } 164 }
176 165
177 // Clear cache (if eg. refreshing) ??? 166 // Clear cache (if eg. refreshing) ???
178 if (isMainDoc) 167 if (isMainDoc)
179 { 168 {
180 CComVariant vCacheIndex; 169 CComVariant vCacheIndex;
181 170
182 if (FAILED(pBodyEl->getAttribute(L"abp", 0, &vCacheIndex)) || vCacheIndex.vt == VT_NULL) 171 if (FAILED(pBodyEl->getAttribute(ATL::CComBSTR(L"abp"), 0, &vCacheIndex)) || vCacheIndex.vt == VT_NULL)
183 { 172 {
184 ClearCache(); 173 ClearCache();
185 } 174 }
186 } 175 }
187 176
188 // Hide elements in body part 177 // Hide elements in body part
189 TraverseChild(pBodyEl, pBrowser, indent); 178 TraverseChild(pBodyEl, pBrowser, indent);
190 179
191 // Check frames and iframes 180 // Check frames and iframes
192 bool hasFrames = false; 181 bool hasFrames = false;
193 bool hasIframes = false; 182 bool hasIframes = false;
194 183
195 m_criticalSection.Lock(); 184 m_criticalSection.Lock();
196 { 185 {
197 hasFrames = m_cacheDocumentHasFrames.find(m_documentName) != m_cacheDocument HasFrames.end(); 186 hasFrames = m_cacheDocumentHasFrames.find(m_documentName) != m_cacheDocument HasFrames.end();
198 hasIframes = m_cacheDocumentHasIframes.find(m_documentName) != m_cacheDocume ntHasIframes.end(); 187 hasIframes = m_cacheDocumentHasIframes.find(m_documentName) != m_cacheDocume ntHasIframes.end();
199 } 188 }
200 m_criticalSection.Unlock(); 189 m_criticalSection.Unlock();
201 190
202 // Frames 191 // Frames
203 if (hasFrames) 192 if (hasFrames)
204 { 193 {
205 // eg. http://gamecopyworld.com/ 194 // eg. http://gamecopyworld.com/
206 long frameCount = 0; 195 long frameCount = 0;
207 CComPtr<IHTMLElementCollection> pFrameCollection; 196 CComPtr<IHTMLElementCollection> pFrameCollection;
208 if (SUCCEEDED(pDoc->getElementsByTagName(L"frame", &pFrameCollection)) && pF rameCollection) 197 if (SUCCEEDED(pDoc->getElementsByTagName(ATL::CComBSTR(L"frame"), &pFrameCol lection)) && pFrameCollection)
209 { 198 {
210 pFrameCollection->get_length(&frameCount); 199 pFrameCollection->get_length(&frameCount);
211 } 200 }
212 201
213 // Iterate through all frames 202 // Iterate through all frames
214 for (long i = 0; i < frameCount; i++) 203 for (long i = 0; i < frameCount; i++)
215 { 204 {
216 CComVariant vIndex(i); 205 CComVariant vIndex(i);
217 CComVariant vRetIndex; 206 CComVariant vRetIndex;
218 CComPtr<IDispatch> pFrameDispatch; 207 CComPtr<IDispatch> pFrameDispatch;
(...skipping 19 matching lines...) Expand all
238 } 227 }
239 } 228 }
240 } 229 }
241 } 230 }
242 231
243 // Iframes 232 // Iframes
244 if (hasIframes) 233 if (hasIframes)
245 { 234 {
246 long frameCount = 0; 235 long frameCount = 0;
247 CComPtr<IHTMLElementCollection> pFrameCollection; 236 CComPtr<IHTMLElementCollection> pFrameCollection;
248 if (SUCCEEDED(pDoc->getElementsByTagName(L"iframe", &pFrameCollection)) && p FrameCollection) 237 if (SUCCEEDED(pDoc->getElementsByTagName(ATL::CComBSTR(L"iframe"), &pFrameCo llection)) && pFrameCollection)
249 { 238 {
250 pFrameCollection->get_length(&frameCount); 239 pFrameCollection->get_length(&frameCount);
251 } 240 }
252 241
253 // Iterate through all iframes 242 // Iterate through all iframes
254 for (long i = 0; i < frameCount; i++) 243 for (long i = 0; i < frameCount; i++)
255 { 244 {
256 CComVariant vIndex(i); 245 CComVariant vIndex(i);
257 CComVariant vRetIndex; 246 CComVariant vRetIndex;
258 CComPtr<IDispatch> pFrameDispatch; 247 CComPtr<IDispatch> pFrameDispatch;
259 248
260 if (SUCCEEDED(pFrameCollection->item(vIndex, vRetIndex, &pFrameDispatch)) && pFrameDispatch) 249 if (SUCCEEDED(pFrameCollection->item(vIndex, vRetIndex, &pFrameDispatch)) && pFrameDispatch)
261 { 250 {
262 CComQIPtr<IHTMLElement> pFrameEl = pFrameDispatch; 251 CComQIPtr<IHTMLElement> pFrameEl = pFrameDispatch;
263 if (pFrameEl) 252 if (pFrameEl)
264 { 253 {
265 CComVariant vAttr; 254 CComVariant vAttr;
266 255 if (SUCCEEDED(pFrameEl->getAttribute(ATL::CComBSTR(L"scr"), 0, &vAttr) ) && vAttr.vt == VT_BSTR && ::SysStringLen(vAttr.bstrVal) > 0)
267 if (SUCCEEDED(pFrameEl->getAttribute(L"src", 0, &vAttr)) && vAttr.vt = = VT_BSTR && ::SysStringLen(vAttr.bstrVal) > 0)
268 { 256 {
269 CString src = vAttr.bstrVal; 257 CString src = vAttr.bstrVal;
270 258
271 // Some times, domain is missing. Should this be added on image src' s as well?'' 259 // Some times, domain is missing. Should this be added on image src' s as well?''
272 260
273 // eg. gadgetzone.com.au 261 // eg. gadgetzone.com.au
274 if (src.Left(2) == L"//") 262 if (src.Left(2) == L"//")
275 { 263 {
276 src = L"http:" + src; 264 src = L"http:" + src;
277 } 265 }
(...skipping 18 matching lines...) Expand all
296 } 284 }
297 } 285 }
298 } 286 }
299 } 287 }
300 } 288 }
301 289
302 290
303 template <class T> 291 template <class T>
304 void CPluginDomTraverserBase<T>::TraverseChild(IHTMLElement* pEl, IWebBrowser2* pBrowser, CString& indent, bool isCached) 292 void CPluginDomTraverserBase<T>::TraverseChild(IHTMLElement* pEl, IWebBrowser2* pBrowser, CString& indent, bool isCached)
305 { 293 {
306 int cacheIndex = -1; 294 uint32_t cacheIndex = -1;
307 long cacheAllElementsCount = -1; 295 long cacheAllElementsCount = -1;
308
309 m_criticalSection.Lock();
310 { 296 {
297 CriticalSectionLock lock(m_criticalSection);
311 CComVariant vCacheIndex; 298 CComVariant vCacheIndex;
312 if (isCached && SUCCEEDED(pEl->getAttribute(L"abp", 0, &vCacheIndex)) && vCa cheIndex.vt == VT_I4) 299 if (isCached
300 && SUCCEEDED(pEl->getAttribute(ATL::CComBSTR(L"abp"), 0, &vCacheIndex))
301 && SUCCEEDED(vCacheIndex.ChangeType(VT_UI4)))
313 { 302 {
314 cacheIndex = vCacheIndex.intVal; 303 cacheIndex = vCacheIndex.uintVal;
315 304 // right now the user can set arbitrary value of abp attribute which in th e best case will
305 // cause the crash. Test cacheIndex belongs to [0, m_cacheElements.size())
306 if (cacheIndex >= m_cacheElements.size())
307 {
308 return;
Oleksandr 2014/10/06 20:19:32 I agree. This makes it very easy for someone to di
309 }
316 cacheAllElementsCount = m_cacheElements[cacheIndex].m_elements; 310 cacheAllElementsCount = m_cacheElements[cacheIndex].m_elements;
317 } 311 }
318 else 312 else
319 { 313 {
320 isCached = false; 314 isCached = false;
321 315
322 cacheIndex = m_cacheIndexLast++; 316 // it's important to set cacheIndex before extending m_cacheElements becau se it's zero based.
323 317 cacheIndex = m_cacheElements.size();
324 // Resize cache??? 318 m_cacheElements.emplace_back(T());
325 if (cacheIndex >= m_cacheElementsMax)
326 {
327 T* oldCacheElements = m_cacheElements;
328
329 m_cacheElements = new T[2*m_cacheElementsMax];
330
331 memcpy(m_cacheElements, oldCacheElements, m_cacheElementsMax*sizeof(T));
332
333 m_cacheElementsMax *= 2;
334
335 delete [] oldCacheElements;
336 }
337
338 m_cacheElements[cacheIndex].Init(); 319 m_cacheElements[cacheIndex].Init();
339 320
340 vCacheIndex.vt = VT_I4; 321 vCacheIndex = cacheIndex;
341 vCacheIndex.intVal = cacheIndex; 322 pEl->setAttribute(ATL::CComBSTR(L"abp"), vCacheIndex);
342
343 pEl->setAttribute(L"abp", vCacheIndex);
344 } 323 }
345 } 324 }
346 m_criticalSection.Unlock();
347 325
348 // Get number of elements in the scope of pEl 326 // Get number of elements in the scope of pEl
349 long allElementsCount = 0; 327 long allElementsCount = 0;
350 328
351 CComPtr<IDispatch> pAllCollectionDisp; 329 CComPtr<IDispatch> pAllCollectionDisp;
352 330
353 if (SUCCEEDED(pEl->get_all(&pAllCollectionDisp)) && pAllCollectionDisp) 331 if (SUCCEEDED(pEl->get_all(&pAllCollectionDisp)) && pAllCollectionDisp)
354 { 332 {
355 CComPtr<IHTMLElementCollection> pAllCollection; 333 CComPtr<IHTMLElementCollection> pAllCollection;
356 334
357 if (SUCCEEDED(pAllCollectionDisp->QueryInterface(IID_IHTMLElementCollection, (LPVOID*)&pAllCollection)) && pAllCollection) 335 if (SUCCEEDED(pAllCollectionDisp->QueryInterface(IID_IHTMLElementCollection, (LPVOID*)&pAllCollection)) && pAllCollection)
358 { 336 {
359 // If number of elements = cached number, return 337 // If number of elements = cached number, return
360 if (SUCCEEDED(pAllCollection->get_length(&allElementsCount)) && allElement sCount == cacheAllElementsCount) 338 if (SUCCEEDED(pAllCollection->get_length(&allElementsCount)) && allElement sCount == cacheAllElementsCount)
361 { 339 {
362 return; 340 return;
363 } 341 }
364 } 342 }
365 } 343 }
366 344
367 // Update cache 345 // Update cache
Eric 2014/10/08 16:26:55 Yes, this would perform better, at the expense of
368 m_criticalSection.Lock();
369 { 346 {
347 CriticalSectionLock lock(m_criticalSection);
370 m_cacheElements[cacheIndex].m_elements = allElementsCount; 348 m_cacheElements[cacheIndex].m_elements = allElementsCount;
371 } 349 }
372 m_criticalSection.Unlock();
373 350
374 // Get tag 351 // Get tag
375 CComBSTR bstrTag; 352 CComBSTR bstrTag;
376 if (FAILED(pEl->get_tagName(&bstrTag)) || !bstrTag) 353 if (FAILED(pEl->get_tagName(&bstrTag)) || !bstrTag)
377 { 354 {
378 return; 355 return;
379 } 356 }
380 357
381 CString tag = bstrTag; 358 CString tag = bstrTag;
382 tag.MakeLower(); 359 tag.MakeLower();
383 360
384 // Custom OnElement 361 // Custom OnElement
385 if (!OnElement(pEl, tag, &m_cacheElements[cacheIndex], false, indent)) 362 if (!OnElement(pEl, tag, &m_cacheElements[cacheIndex], false, indent))
386 { 363 {
387 return; 364 return;
388 } 365 }
389 366
390 // Update frame/iframe cache 367 // Update frame/iframe cache
391 if (tag == "iframe") 368 if (tag == "iframe")
392 { 369 {
393 m_criticalSection.Lock(); 370 CriticalSectionLock lock(m_criticalSection);
394 { 371 m_cacheDocumentHasIframes.insert(m_documentName);
395 m_cacheDocumentHasIframes.insert(m_documentName);
396 }
397 m_criticalSection.Unlock();
398 } 372 }
399 else if (tag == "frame") 373 else if (tag == "frame")
400 { 374 {
401 m_criticalSection.Lock(); 375 CriticalSectionLock lock(m_criticalSection);
402 { 376 m_cacheDocumentHasFrames.insert(m_documentName);
403 m_cacheDocumentHasFrames.insert(m_documentName);
404 }
405 m_criticalSection.Unlock();
406 } 377 }
407 378
408 // Iterate through children of this element 379 // Iterate through children of this element
409 if (allElementsCount > 0) 380 if (allElementsCount > 0)
410 { 381 {
411 long childElementsCount = 0; 382 long childElementsCount = 0;
412 383
413 CComPtr<IDispatch> pChildCollectionDisp; 384 CComPtr<IDispatch> pChildCollectionDisp;
414 if (SUCCEEDED(pEl->get_children(&pChildCollectionDisp)) && pChildCollectionD isp) 385 if (SUCCEEDED(pEl->get_children(&pChildCollectionDisp)) && pChildCollectionD isp)
415 { 386 {
(...skipping 23 matching lines...) Expand all
439 } 410 }
440 } 411 }
441 } 412 }
442 } 413 }
443 } 414 }
444 415
445 416
446 template <class T> 417 template <class T>
447 void CPluginDomTraverserBase<T>::ClearCache() 418 void CPluginDomTraverserBase<T>::ClearCache()
448 { 419 {
449 m_criticalSection.Lock(); 420 CriticalSectionLock lock(m_criticalSection);
450 { 421 m_cacheElements.clear();
451 m_cacheIndexLast = 0; 422 m_cacheDocumentHasFrames.clear();
452 m_cacheDocumentHasFrames.clear(); 423 m_cacheDocumentHasIframes.clear();
453 m_cacheDocumentHasIframes.clear();
454 }
455 m_criticalSection.Unlock();
456 }
457 template <class T>
458 void CPluginDomTraverserBase<T>::ShowNotification(CPluginTab* tab)
459 {
460 if (tab->m_plugin->GetTabHWND() == NULL)
461 {
462 return;
463 }
464
465
466 } 424 }
467 425
468
469 #endif // _PLUGIN_DOM_TRAVERSER_BASE_H_ 426 #endif // _PLUGIN_DOM_TRAVERSER_BASE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld