OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. |
3 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) | 3 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
196 RefPtr<SerializedScriptValue> m_message; | 196 RefPtr<SerializedScriptValue> m_message; |
197 String m_origin; | 197 String m_origin; |
198 RefPtrWillBeMember<LocalDOMWindow> m_source; | 198 RefPtrWillBeMember<LocalDOMWindow> m_source; |
199 OwnPtr<MessagePortChannelArray> m_channels; | 199 OwnPtr<MessagePortChannelArray> m_channels; |
200 RefPtr<SecurityOrigin> m_targetOrigin; | 200 RefPtr<SecurityOrigin> m_targetOrigin; |
201 RefPtrWillBeMember<ScriptCallStack> m_stackTrace; | 201 RefPtrWillBeMember<ScriptCallStack> m_stackTrace; |
202 RefPtr<UserGestureToken> m_userGestureToken; | 202 RefPtr<UserGestureToken> m_userGestureToken; |
203 int m_asyncOperationId; | 203 int m_asyncOperationId; |
204 }; | 204 }; |
205 | 205 |
206 static void disableSuddenTermination() | 206 static void updateSuddenTerminationStatus(LocalDOMWindow* domWindow, bool addedL istener, FrameLoaderClient::SuddenTerminationDisablerType disablerType) |
207 { | 207 { |
208 blink::Platform::current()->suddenTerminationChanged(false); | 208 blink::Platform::current()->suddenTerminationChanged(!addedListener); |
209 } | 209 if (domWindow->frame() && domWindow->frame()->loader().client()) |
210 | 210 domWindow->frame()->loader().client()->suddenTerminationDisablerChanged( addedListener, disablerType); |
211 static void enableSuddenTermination() | |
212 { | |
213 blink::Platform::current()->suddenTerminationChanged(true); | |
214 } | 211 } |
215 | 212 |
216 typedef HashCountedSet<LocalDOMWindow*> DOMWindowSet; | 213 typedef HashCountedSet<LocalDOMWindow*> DOMWindowSet; |
217 | 214 |
218 static DOMWindowSet& windowsWithUnloadEventListeners() | 215 static DOMWindowSet& windowsWithUnloadEventListeners() |
219 { | 216 { |
220 DEFINE_STATIC_LOCAL(DOMWindowSet, windowsWithUnloadEventListeners, ()); | 217 DEFINE_STATIC_LOCAL(DOMWindowSet, windowsWithUnloadEventListeners, ()); |
221 return windowsWithUnloadEventListeners; | 218 return windowsWithUnloadEventListeners; |
222 } | 219 } |
223 | 220 |
224 static DOMWindowSet& windowsWithBeforeUnloadEventListeners() | 221 static DOMWindowSet& windowsWithBeforeUnloadEventListeners() |
225 { | 222 { |
226 DEFINE_STATIC_LOCAL(DOMWindowSet, windowsWithBeforeUnloadEventListeners, ()) ; | 223 DEFINE_STATIC_LOCAL(DOMWindowSet, windowsWithBeforeUnloadEventListeners, ()) ; |
227 return windowsWithBeforeUnloadEventListeners; | 224 return windowsWithBeforeUnloadEventListeners; |
228 } | 225 } |
229 | 226 |
230 static void addUnloadEventListener(LocalDOMWindow* domWindow) | 227 static void addUnloadEventListener(LocalDOMWindow* domWindow) |
231 { | 228 { |
232 DOMWindowSet& set = windowsWithUnloadEventListeners(); | 229 DOMWindowSet& set = windowsWithUnloadEventListeners(); |
233 if (set.isEmpty()) { | 230 if (set.isEmpty()) |
234 disableSuddenTermination(); | 231 updateSuddenTerminationStatus(domWindow, true, FrameLoaderClient::Unload Handler); |
235 if (domWindow->frame()) { | 232 |
236 domWindow->frame()->loader().client()->suddenTerminationDisablerChan ged( | |
237 true, FrameLoaderClient::UnloadHandler); | |
238 } | |
239 } | |
240 set.add(domWindow); | 233 set.add(domWindow); |
241 } | 234 } |
242 | 235 |
243 static void removeUnloadEventListener(LocalDOMWindow* domWindow) | 236 static void removeUnloadEventListener(LocalDOMWindow* domWindow) |
244 { | 237 { |
245 DOMWindowSet& set = windowsWithUnloadEventListeners(); | 238 DOMWindowSet& set = windowsWithUnloadEventListeners(); |
246 DOMWindowSet::iterator it = set.find(domWindow); | 239 DOMWindowSet::iterator it = set.find(domWindow); |
247 if (it == set.end()) | 240 if (it == set.end()) |
248 return; | 241 return; |
249 set.remove(it); | 242 set.remove(it); |
250 if (set.isEmpty()) { | 243 if (set.isEmpty()) |
251 enableSuddenTermination(); | 244 updateSuddenTerminationStatus(domWindow, false, FrameLoaderClient::Unloa dHandler); |
252 if (domWindow->frame()) { | |
253 domWindow->frame()->loader().client()->suddenTerminationDisablerChan ged( | |
254 false, FrameLoaderClient::UnloadHandler); | |
255 } | |
256 } | |
257 } | 245 } |
258 | 246 |
259 static void removeAllUnloadEventListeners(LocalDOMWindow* domWindow) | 247 static void removeAllUnloadEventListeners(LocalDOMWindow* domWindow) |
260 { | 248 { |
261 DOMWindowSet& set = windowsWithUnloadEventListeners(); | 249 DOMWindowSet& set = windowsWithUnloadEventListeners(); |
262 DOMWindowSet::iterator it = set.find(domWindow); | 250 DOMWindowSet::iterator it = set.find(domWindow); |
263 if (it == set.end()) | 251 if (it == set.end()) |
264 return; | 252 return; |
265 set.removeAll(it); | 253 set.removeAll(it); |
266 if (set.isEmpty()) { | 254 if (set.isEmpty()) |
267 enableSuddenTermination(); | 255 updateSuddenTerminationStatus(domWindow, false, FrameLoaderClient::Unloa dHandler); |
268 if (domWindow->frame()) { | |
269 domWindow->frame()->loader().client()->suddenTerminationDisablerChan ged( | |
270 false, FrameLoaderClient::UnloadHandler); | |
271 } | |
272 } | |
273 } | 256 } |
274 | 257 |
275 static void addBeforeUnloadEventListener(LocalDOMWindow* domWindow) | 258 static void addBeforeUnloadEventListener(LocalDOMWindow* domWindow) |
276 { | 259 { |
277 DOMWindowSet& set = windowsWithBeforeUnloadEventListeners(); | 260 DOMWindowSet& set = windowsWithBeforeUnloadEventListeners(); |
278 if (set.isEmpty()) { | 261 if (set.isEmpty()) |
279 disableSuddenTermination(); | 262 updateSuddenTerminationStatus(domWindow, true, FrameLoaderClient::Before UnloadHandler); |
280 if (domWindow->frame()) { | 263 |
281 domWindow->frame()->loader().client()->suddenTerminationDisablerChan ged( | |
282 true, FrameLoaderClient::BeforeUnloadHandler); | |
283 } | |
284 } | |
285 set.add(domWindow); | 264 set.add(domWindow); |
286 } | 265 } |
287 | 266 |
288 static void removeBeforeUnloadEventListener(LocalDOMWindow* domWindow) | 267 static void removeBeforeUnloadEventListener(LocalDOMWindow* domWindow) |
289 { | 268 { |
290 DOMWindowSet& set = windowsWithBeforeUnloadEventListeners(); | 269 DOMWindowSet& set = windowsWithBeforeUnloadEventListeners(); |
291 DOMWindowSet::iterator it = set.find(domWindow); | 270 DOMWindowSet::iterator it = set.find(domWindow); |
292 if (it == set.end()) | 271 if (it == set.end()) |
293 return; | 272 return; |
294 set.remove(it); | 273 set.remove(it); |
295 if (set.isEmpty()) { | 274 if (set.isEmpty()) |
296 enableSuddenTermination(); | 275 updateSuddenTerminationStatus(domWindow, false, FrameLoaderClient::Befor eUnloadHandler); |
297 if (domWindow->frame()) { | |
298 domWindow->frame()->loader().client()->suddenTerminationDisablerChan ged( | |
299 false, FrameLoaderClient::BeforeUnloadHandler); | |
300 } | |
301 } | |
302 } | 276 } |
303 | 277 |
304 static void removeAllBeforeUnloadEventListeners(LocalDOMWindow* domWindow) | 278 static void removeAllBeforeUnloadEventListeners(LocalDOMWindow* domWindow) |
305 { | 279 { |
306 DOMWindowSet& set = windowsWithBeforeUnloadEventListeners(); | 280 DOMWindowSet& set = windowsWithBeforeUnloadEventListeners(); |
307 DOMWindowSet::iterator it = set.find(domWindow); | 281 DOMWindowSet::iterator it = set.find(domWindow); |
308 if (it == set.end()) | 282 if (it == set.end()) |
309 return; | 283 return; |
310 set.removeAll(it); | 284 set.removeAll(it); |
311 if (set.isEmpty()) { | 285 if (set.isEmpty()) |
312 enableSuddenTermination(); | 286 updateSuddenTerminationStatus(domWindow, false, FrameLoaderClient::Befor eUnloadHandler); |
313 if (domWindow->frame()) { | |
314 domWindow->frame()->loader().client()->suddenTerminationDisablerChan ged( | |
315 false, FrameLoaderClient::BeforeUnloadHandler); | |
316 } | |
317 } | |
318 } | 287 } |
319 | 288 |
320 static bool allowsBeforeUnloadListeners(LocalDOMWindow* window) | 289 static bool allowsBeforeUnloadListeners(LocalDOMWindow* window) |
321 { | 290 { |
322 ASSERT_ARG(window, window); | 291 ASSERT_ARG(window, window); |
323 LocalFrame* frame = window->frame(); | 292 LocalFrame* frame = window->frame(); |
324 if (!frame) | 293 if (!frame) |
325 return false; | 294 return false; |
326 return frame->isMainFrame(); | 295 return frame->isMainFrame(); |
327 } | 296 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
372 return frame() && allowPopUp(*frame()); | 341 return frame() && allowPopUp(*frame()); |
373 } | 342 } |
374 | 343 |
375 LocalDOMWindow::LocalDOMWindow(LocalFrame& frame) | 344 LocalDOMWindow::LocalDOMWindow(LocalFrame& frame) |
376 : m_frameObserver(WindowFrameObserver::create(this, frame)) | 345 : m_frameObserver(WindowFrameObserver::create(this, frame)) |
377 , m_shouldPrintWhenFinishedLoading(false) | 346 , m_shouldPrintWhenFinishedLoading(false) |
378 #if ENABLE(ASSERT) | 347 #if ENABLE(ASSERT) |
379 , m_hasBeenReset(false) | 348 , m_hasBeenReset(false) |
380 #endif | 349 #endif |
381 { | 350 { |
351 #if ENABLE(OILPAN) | |
352 ThreadState::current()->registerPreFinalizer(*this); | |
353 #endif | |
382 } | 354 } |
383 | 355 |
384 void LocalDOMWindow::clearDocument() | 356 void LocalDOMWindow::clearDocument() |
385 { | 357 { |
386 if (!m_document) | 358 if (!m_document) |
387 return; | 359 return; |
388 | 360 |
389 if (m_document->isActive()) { | 361 if (m_document->isActive()) { |
390 // FIXME: We don't call willRemove here. Why is that OK? | 362 // FIXME: We don't call willRemove here. Why is that OK? |
391 // This detach() call is also mostly redundant. Most of the calls to | 363 // This detach() call is also mostly redundant. Most of the calls to |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
524 // Per step 11 of section 6.5.9 (history traversal) of the HTML5 spec, we | 496 // Per step 11 of section 6.5.9 (history traversal) of the HTML5 spec, we |
525 // defer firing of popstate until we're in the complete state. | 497 // defer firing of popstate until we're in the complete state. |
526 if (document()->isLoadCompleted()) | 498 if (document()->isLoadCompleted()) |
527 enqueuePopstateEvent(stateObject); | 499 enqueuePopstateEvent(stateObject); |
528 else | 500 else |
529 m_pendingStateObject = stateObject; | 501 m_pendingStateObject = stateObject; |
530 } | 502 } |
531 | 503 |
532 LocalDOMWindow::~LocalDOMWindow() | 504 LocalDOMWindow::~LocalDOMWindow() |
533 { | 505 { |
534 #if ENABLE(OILPAN) | 506 #if ENABLE(OILPAN) |
haraken
2015/03/18 23:38:45
Not related to your CL, I'm wondering if we could
sof
2015/03/19 06:27:36
It would be nice to empty this dtor entirely of an
| |
535 // Oilpan: the frame host and document objects are | |
536 // also garbage collected; cannot notify these | |
537 // when removing event listeners. | |
538 removeAllEventListenersInternal(DoNotBroadcastListenerRemoval); | |
539 | |
540 // Cleared when detaching document. | 507 // Cleared when detaching document. |
541 ASSERT(!m_eventQueue); | 508 ASSERT(!m_eventQueue); |
542 #else | 509 #else |
543 ASSERT(m_hasBeenReset); | 510 ASSERT(m_hasBeenReset); |
544 reset(); | |
545 | |
546 removeAllEventListenersInternal(DoBroadcastListenerRemoval); | |
547 | |
548 ASSERT(m_document->isStopped()); | 511 ASSERT(m_document->isStopped()); |
549 clearDocument(); | 512 clearDocument(); |
550 #endif | 513 #endif |
551 } | 514 } |
552 | 515 |
516 void LocalDOMWindow::dispose() | |
517 { | |
518 // Oilpan: should the LocalDOMWindow be GCed along with its LocalFrame, the frame | |
519 // may not have explicitly detached itself first. In that case, handle the c learing | |
520 // of event listeners in a prefinalizing action. | |
521 // | |
522 // (Non-Oilpan, LocalDOMWindow::reset() will always be invoked which takes c are of this step.) | |
haraken
2015/03/18 23:38:45
Help me understand: The LocalDOMWindow::reset() is
sof
2015/03/19 06:27:36
Yes, if the frame is detached, reset() will be cal
haraken
2015/03/19 06:54:45
Thanks for the clarification; makes sense!
| |
523 if (!frame()) | |
524 return; | |
525 | |
526 removeAllEventListeners(); | |
527 } | |
528 | |
553 const AtomicString& LocalDOMWindow::interfaceName() const | 529 const AtomicString& LocalDOMWindow::interfaceName() const |
554 { | 530 { |
555 return EventTargetNames::LocalDOMWindow; | 531 return EventTargetNames::LocalDOMWindow; |
556 } | 532 } |
557 | 533 |
558 ExecutionContext* LocalDOMWindow::executionContext() const | 534 ExecutionContext* LocalDOMWindow::executionContext() const |
559 { | 535 { |
560 return m_document.get(); | 536 return m_document.get(); |
561 } | 537 } |
562 | 538 |
(...skipping 17 matching lines...) Expand all Loading... | |
580 frame()->host()->eventHandlerRegistry().didRemoveAllEventHandlers(*this); | 556 frame()->host()->eventHandlerRegistry().didRemoveAllEventHandlers(*this); |
581 frame()->host()->consoleMessageStorage().frameWindowDiscarded(this); | 557 frame()->host()->consoleMessageStorage().frameWindowDiscarded(this); |
582 LocalDOMWindow::notifyContextDestroyed(); | 558 LocalDOMWindow::notifyContextDestroyed(); |
583 } | 559 } |
584 | 560 |
585 void LocalDOMWindow::frameDestroyed() | 561 void LocalDOMWindow::frameDestroyed() |
586 { | 562 { |
587 willDestroyDocumentInFrame(); | 563 willDestroyDocumentInFrame(); |
588 resetLocation(); | 564 resetLocation(); |
589 m_properties.clear(); | 565 m_properties.clear(); |
566 removeAllEventListeners(); | |
590 } | 567 } |
591 | 568 |
592 void LocalDOMWindow::willDestroyDocumentInFrame() | 569 void LocalDOMWindow::willDestroyDocumentInFrame() |
593 { | 570 { |
594 for (const auto& domWindowProperty : m_properties) | 571 for (const auto& domWindowProperty : m_properties) |
595 domWindowProperty->willDestroyGlobalObjectInFrame(); | 572 domWindowProperty->willDestroyGlobalObjectInFrame(); |
596 } | 573 } |
597 | 574 |
598 void LocalDOMWindow::willDetachDocumentFromFrame() | 575 void LocalDOMWindow::willDetachDocumentFromFrame() |
599 { | 576 { |
(...skipping 970 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1570 RefPtrWillBeRawPtr<Event> event = prpEvent; | 1547 RefPtrWillBeRawPtr<Event> event = prpEvent; |
1571 | 1548 |
1572 event->setTarget(prpTarget ? prpTarget : this); | 1549 event->setTarget(prpTarget ? prpTarget : this); |
1573 event->setCurrentTarget(this); | 1550 event->setCurrentTarget(this); |
1574 event->setEventPhase(Event::AT_TARGET); | 1551 event->setEventPhase(Event::AT_TARGET); |
1575 | 1552 |
1576 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "EventDispatch" , "data", InspectorEventDispatchEvent::data(*event)); | 1553 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "EventDispatch" , "data", InspectorEventDispatchEvent::data(*event)); |
1577 return fireEventListeners(event.get()); | 1554 return fireEventListeners(event.get()); |
1578 } | 1555 } |
1579 | 1556 |
1580 void LocalDOMWindow::removeAllEventListenersInternal(BroadcastListenerRemoval mo de) | 1557 void LocalDOMWindow::removeAllEventListeners() |
1581 { | 1558 { |
1582 EventTarget::removeAllEventListeners(); | 1559 EventTarget::removeAllEventListeners(); |
1583 | 1560 |
1584 if (mode == DoBroadcastListenerRemoval) { | 1561 notifyRemoveAllEventListeners(this); |
1585 notifyRemoveAllEventListeners(this); | 1562 if (frame() && frame()->host()) |
1586 if (frame() && frame()->host()) | 1563 frame()->host()->eventHandlerRegistry().didRemoveAllEventHandlers(*this) ; |
1587 frame()->host()->eventHandlerRegistry().didRemoveAllEventHandlers(*t his); | |
1588 } | |
1589 | 1564 |
1590 removeAllUnloadEventListeners(this); | 1565 removeAllUnloadEventListeners(this); |
1591 removeAllBeforeUnloadEventListeners(this); | 1566 removeAllBeforeUnloadEventListeners(this); |
1592 } | 1567 } |
1593 | 1568 |
1594 void LocalDOMWindow::removeAllEventListeners() | |
1595 { | |
1596 removeAllEventListenersInternal(DoBroadcastListenerRemoval); | |
1597 } | |
1598 | |
1599 void LocalDOMWindow::finishedLoading() | 1569 void LocalDOMWindow::finishedLoading() |
1600 { | 1570 { |
1601 if (m_shouldPrintWhenFinishedLoading) { | 1571 if (m_shouldPrintWhenFinishedLoading) { |
1602 m_shouldPrintWhenFinishedLoading = false; | 1572 m_shouldPrintWhenFinishedLoading = false; |
1603 print(); | 1573 print(); |
1604 } | 1574 } |
1605 } | 1575 } |
1606 | 1576 |
1607 void LocalDOMWindow::printErrorMessage(const String& message) | 1577 void LocalDOMWindow::printErrorMessage(const String& message) |
1608 { | 1578 { |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1781 return m_frameObserver->frame(); | 1751 return m_frameObserver->frame(); |
1782 } | 1752 } |
1783 | 1753 |
1784 v8::Handle<v8::Object> LocalDOMWindow::wrap(v8::Handle<v8::Object> creationConte xt, v8::Isolate* isolate) | 1754 v8::Handle<v8::Object> LocalDOMWindow::wrap(v8::Handle<v8::Object> creationConte xt, v8::Isolate* isolate) |
1785 { | 1755 { |
1786 ASSERT_NOT_REACHED(); // LocalDOMWindow has [Custom=ToV8]. | 1756 ASSERT_NOT_REACHED(); // LocalDOMWindow has [Custom=ToV8]. |
1787 return v8::Handle<v8::Object>(); | 1757 return v8::Handle<v8::Object>(); |
1788 } | 1758 } |
1789 | 1759 |
1790 } // namespace blink | 1760 } // namespace blink |
OLD | NEW |