| 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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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) |
| 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 witho
ut the |
| 519 // frame having first notified its observers of imminent destruction, the |
| 520 // LocalDOMWindow will not have had an opportunity to remove event listeners
. |
| 521 // Do that here by way of a prefinalizing action. |
| 522 // |
| 523 // (Non-Oilpan, LocalDOMWindow::reset() will always be invoked, the last opp
ortunity |
| 524 // being via ~LocalFrame's setDOMWindow() call.) |
| 525 if (!frame()) |
| 526 return; |
| 527 |
| 528 // (Prefinalizing actions run to completion before the Oilpan GC start to la
zily sweep, |
| 529 // so keeping them short is worthwhile. Something that's worth keeping in mi
nd when |
| 530 // working out where to best place some actions that have to be performed ve
ry late |
| 531 // on in LocalDOMWindow's lifetime.) |
| 532 removeAllEventListeners(); |
| 533 } |
| 534 |
| 553 const AtomicString& LocalDOMWindow::interfaceName() const | 535 const AtomicString& LocalDOMWindow::interfaceName() const |
| 554 { | 536 { |
| 555 return EventTargetNames::LocalDOMWindow; | 537 return EventTargetNames::LocalDOMWindow; |
| 556 } | 538 } |
| 557 | 539 |
| 558 ExecutionContext* LocalDOMWindow::executionContext() const | 540 ExecutionContext* LocalDOMWindow::executionContext() const |
| 559 { | 541 { |
| 560 return m_document.get(); | 542 return m_document.get(); |
| 561 } | 543 } |
| 562 | 544 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 580 frame()->host()->eventHandlerRegistry().didRemoveAllEventHandlers(*this); | 562 frame()->host()->eventHandlerRegistry().didRemoveAllEventHandlers(*this); |
| 581 frame()->host()->consoleMessageStorage().frameWindowDiscarded(this); | 563 frame()->host()->consoleMessageStorage().frameWindowDiscarded(this); |
| 582 LocalDOMWindow::notifyContextDestroyed(); | 564 LocalDOMWindow::notifyContextDestroyed(); |
| 583 } | 565 } |
| 584 | 566 |
| 585 void LocalDOMWindow::frameDestroyed() | 567 void LocalDOMWindow::frameDestroyed() |
| 586 { | 568 { |
| 587 willDestroyDocumentInFrame(); | 569 willDestroyDocumentInFrame(); |
| 588 resetLocation(); | 570 resetLocation(); |
| 589 m_properties.clear(); | 571 m_properties.clear(); |
| 572 removeAllEventListeners(); |
| 590 } | 573 } |
| 591 | 574 |
| 592 void LocalDOMWindow::willDestroyDocumentInFrame() | 575 void LocalDOMWindow::willDestroyDocumentInFrame() |
| 593 { | 576 { |
| 594 for (const auto& domWindowProperty : m_properties) | 577 for (const auto& domWindowProperty : m_properties) |
| 595 domWindowProperty->willDestroyGlobalObjectInFrame(); | 578 domWindowProperty->willDestroyGlobalObjectInFrame(); |
| 596 } | 579 } |
| 597 | 580 |
| 598 void LocalDOMWindow::willDetachDocumentFromFrame() | 581 void LocalDOMWindow::willDetachDocumentFromFrame() |
| 599 { | 582 { |
| (...skipping 970 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1570 RefPtrWillBeRawPtr<Event> event = prpEvent; | 1553 RefPtrWillBeRawPtr<Event> event = prpEvent; |
| 1571 | 1554 |
| 1572 event->setTarget(prpTarget ? prpTarget : this); | 1555 event->setTarget(prpTarget ? prpTarget : this); |
| 1573 event->setCurrentTarget(this); | 1556 event->setCurrentTarget(this); |
| 1574 event->setEventPhase(Event::AT_TARGET); | 1557 event->setEventPhase(Event::AT_TARGET); |
| 1575 | 1558 |
| 1576 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "EventDispatch"
, "data", InspectorEventDispatchEvent::data(*event)); | 1559 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "EventDispatch"
, "data", InspectorEventDispatchEvent::data(*event)); |
| 1577 return fireEventListeners(event.get()); | 1560 return fireEventListeners(event.get()); |
| 1578 } | 1561 } |
| 1579 | 1562 |
| 1580 void LocalDOMWindow::removeAllEventListenersInternal(BroadcastListenerRemoval mo
de) | 1563 void LocalDOMWindow::removeAllEventListeners() |
| 1581 { | 1564 { |
| 1582 EventTarget::removeAllEventListeners(); | 1565 EventTarget::removeAllEventListeners(); |
| 1583 | 1566 |
| 1584 if (mode == DoBroadcastListenerRemoval) { | 1567 notifyRemoveAllEventListeners(this); |
| 1585 notifyRemoveAllEventListeners(this); | 1568 if (frame() && frame()->host()) |
| 1586 if (frame() && frame()->host()) | 1569 frame()->host()->eventHandlerRegistry().didRemoveAllEventHandlers(*this)
; |
| 1587 frame()->host()->eventHandlerRegistry().didRemoveAllEventHandlers(*t
his); | |
| 1588 } | |
| 1589 | 1570 |
| 1590 removeAllUnloadEventListeners(this); | 1571 removeAllUnloadEventListeners(this); |
| 1591 removeAllBeforeUnloadEventListeners(this); | 1572 removeAllBeforeUnloadEventListeners(this); |
| 1592 } | 1573 } |
| 1593 | 1574 |
| 1594 void LocalDOMWindow::removeAllEventListeners() | |
| 1595 { | |
| 1596 removeAllEventListenersInternal(DoBroadcastListenerRemoval); | |
| 1597 } | |
| 1598 | |
| 1599 void LocalDOMWindow::finishedLoading() | 1575 void LocalDOMWindow::finishedLoading() |
| 1600 { | 1576 { |
| 1601 if (m_shouldPrintWhenFinishedLoading) { | 1577 if (m_shouldPrintWhenFinishedLoading) { |
| 1602 m_shouldPrintWhenFinishedLoading = false; | 1578 m_shouldPrintWhenFinishedLoading = false; |
| 1603 print(); | 1579 print(); |
| 1604 } | 1580 } |
| 1605 } | 1581 } |
| 1606 | 1582 |
| 1607 void LocalDOMWindow::printErrorMessage(const String& message) | 1583 void LocalDOMWindow::printErrorMessage(const String& message) |
| 1608 { | 1584 { |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1781 return m_frameObserver->frame(); | 1757 return m_frameObserver->frame(); |
| 1782 } | 1758 } |
| 1783 | 1759 |
| 1784 v8::Handle<v8::Object> LocalDOMWindow::wrap(v8::Handle<v8::Object> creationConte
xt, v8::Isolate* isolate) | 1760 v8::Handle<v8::Object> LocalDOMWindow::wrap(v8::Handle<v8::Object> creationConte
xt, v8::Isolate* isolate) |
| 1785 { | 1761 { |
| 1786 ASSERT_NOT_REACHED(); // LocalDOMWindow has [Custom=ToV8]. | 1762 ASSERT_NOT_REACHED(); // LocalDOMWindow has [Custom=ToV8]. |
| 1787 return v8::Handle<v8::Object>(); | 1763 return v8::Handle<v8::Object>(); |
| 1788 } | 1764 } |
| 1789 | 1765 |
| 1790 } // namespace blink | 1766 } // namespace blink |
| OLD | NEW |