WebCore:
authormitz@apple.com <mitz@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Dec 2007 18:46:45 +0000 (18:46 +0000)
committermitz@apple.com <mitz@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Dec 2007 18:46:45 +0000 (18:46 +0000)
        Reviewed by Darin Adler.

        - WebCore part of fixing <rdar://problem/5111082> Flash popup video ad doesn't close when clicked at http://www.firestonecompleteautocare.com/

        * manual-tests/nested-plug-ins.html: Added.
        * manual-tests/resources/nested-plug-ins-inner-frame.html: Added.
        * manual-tests/resources/nested-plug-ins-outer-frame.html: Added.
        * platform/ScrollView.h:
        * platform/Widget.h:
        (WebCore::Widget::attachToWindow): Added. Tells the widget that it is connected
        via visible ScrollViews to the root ScrollView of the WebView.
        (WebCore::Widget::detachFromWindow): Added. Tells the widget that it is no longer
        connected via visible ScrollViews to the root ScrollView of the WebView.
        * platform/win/ScrollViewWin.cpp:
        (WebCore::ScrollView::ScrollViewPrivate::ScrollViewPrivate): Added
        m_visible and m_attachedToWindow members.
        (WebCore::ScrollView::attachToWindow): Added. Attaches all children if this
        view is visible.
        (WebCore::ScrollView::detachFromWindow): Added. Detaches all children if this
        view is visible (otherwise they would be detached already).
        (WebCore::ScrollView::show): Added. Attaches all children if this view
        is attached.
        (WebCore::ScrollView::hide): Added. Detaches all children if this view
        is attached (otherwise they would be detached already).
        (WebCore::ScrollView::isAttachedToWindow): Added.
        * platform/win/WidgetWin.cpp:
        (WebCore::Widget::setParent): Added calls to attachToWindow() and detachFromWindow()
        depending on whether the parent is set and attached or not.
        * plugins/win/PluginViewWin.cpp:
        (WebCore::PluginViewWin::setFocus):
        (WebCore::PluginViewWin::show): Changed to show the plug-in only if
        this view is attached.
        (WebCore::PluginViewWin::hide): Changed to hide the plug-in only if this
        view is attached (otherwise it would be hidden already).
        (WebCore::PluginViewWin::attachToWindow): Added. Shows the plug-in if this view
        is visible.
        (WebCore::PluginViewWin::detachFromWindow): Added. Hides the plug-in if this view
        is visible (otherwise it would be hidden already).
        (WebCore::PluginViewWin::PluginViewWin):
        * plugins/win/PluginViewWin.h: Added m_attachedToWindow member.

WebKit/win:

        Reviewed by Darin Adler.

        - WebKit/win part of fixing <rdar://problem/5111082> Flash popup video ad doesn't close when clicked at http://www.firestonecompleteautocare.com/

        * WebView.cpp:
        (WebView::initWithFrame): Attach the main frame's view.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@28442 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
WebCore/ChangeLog
WebCore/manual-tests/nested-plug-ins.html [new file with mode: 0644]
WebCore/manual-tests/resources/nested-plug-ins-inner-frame.html [new file with mode: 0644]
WebCore/manual-tests/resources/nested-plug-ins-outer-frame.html [new file with mode: 0644]
WebCore/platform/ScrollView.h
WebCore/platform/Widget.h
WebCore/platform/win/ScrollViewWin.cpp
WebCore/platform/win/WidgetWin.cpp
WebCore/plugins/win/PluginViewWin.cpp
WebCore/plugins/win/PluginViewWin.h
WebKit/win/ChangeLog
WebKit/win/WebView.cpp

index 1b31edc073d843c3fd6e56697f533130e55094bf..3c288b1cef346698efcc8776ac525cbcfce4e93f 100644 (file)
@@ -1,3 +1,46 @@
+2007-12-05  Dan Bernstein  <mitz@apple.com>
+
+        Reviewed by Darin Adler.
+
+        - WebCore part of fixing <rdar://problem/5111082> Flash popup video ad doesn't close when clicked at http://www.firestonecompleteautocare.com/
+
+        * manual-tests/nested-plug-ins.html: Added.
+        * manual-tests/resources/nested-plug-ins-inner-frame.html: Added.
+        * manual-tests/resources/nested-plug-ins-outer-frame.html: Added.
+        * platform/ScrollView.h:
+        * platform/Widget.h:
+        (WebCore::Widget::attachToWindow): Added. Tells the widget that it is connected
+        via visible ScrollViews to the root ScrollView of the WebView.
+        (WebCore::Widget::detachFromWindow): Added. Tells the widget that it is no longer
+        connected via visible ScrollViews to the root ScrollView of the WebView.
+        * platform/win/ScrollViewWin.cpp:
+        (WebCore::ScrollView::ScrollViewPrivate::ScrollViewPrivate): Added
+        m_visible and m_attachedToWindow members.
+        (WebCore::ScrollView::attachToWindow): Added. Attaches all children if this
+        view is visible.
+        (WebCore::ScrollView::detachFromWindow): Added. Detaches all children if this
+        view is visible (otherwise they would be detached already).
+        (WebCore::ScrollView::show): Added. Attaches all children if this view
+        is attached.
+        (WebCore::ScrollView::hide): Added. Detaches all children if this view
+        is attached (otherwise they would be detached already).
+        (WebCore::ScrollView::isAttachedToWindow): Added.
+        * platform/win/WidgetWin.cpp:
+        (WebCore::Widget::setParent): Added calls to attachToWindow() and detachFromWindow()
+        depending on whether the parent is set and attached or not.
+        * plugins/win/PluginViewWin.cpp:
+        (WebCore::PluginViewWin::setFocus):
+        (WebCore::PluginViewWin::show): Changed to show the plug-in only if
+        this view is attached.
+        (WebCore::PluginViewWin::hide): Changed to hide the plug-in only if this
+        view is attached (otherwise it would be hidden already).
+        (WebCore::PluginViewWin::attachToWindow): Added. Shows the plug-in if this view
+        is visible.
+        (WebCore::PluginViewWin::detachFromWindow): Added. Hides the plug-in if this view
+        is visible (otherwise it would be hidden already).
+        (WebCore::PluginViewWin::PluginViewWin):
+        * plugins/win/PluginViewWin.h: Added m_attachedToWindow member.
+
 2007-12-04  Alp Toker  <alp@atoker.com>
 
         Potential GTK+ build fix for the glib-genmarshal issue.
diff --git a/WebCore/manual-tests/nested-plug-ins.html b/WebCore/manual-tests/nested-plug-ins.html
new file mode 100644 (file)
index 0000000..20a11fa
--- /dev/null
@@ -0,0 +1,45 @@
+<script>
+    function toggleDisplay(element, button)
+    {
+        if (element.style.display == "none")
+            element.style.display = "";
+        else
+            element.style.display = "none";
+    }
+
+    function toggleVisibility(element, button)
+    {
+        if (element.style.visibility == "hidden")
+            element.style.visibility = "";
+        else
+            element.style.visibility = "hidden";
+    }
+
+</script>
+<p>
+    Play with the display and visibility toggles. Make sure that turning an inner element visible does not show it if it has a hidden or
+       non-displaying ancestor, and that making an ancestor visible and displaying shows only its descendants the are visible and displaying.
+</p>
+<table>
+    <tr>
+        <td>
+            <input type="checkbox" checked="true" onclick="toggleDisplay(document.getElementById('middle'))"> Outer frame display
+        </td>
+        <td>
+            <input type="checkbox" checked="true" onclick="toggleDisplay(document.getElementById('middle').contentDocument.getElementById('inner'))"> Inner frame display
+        </td>
+    </tr>
+    <tr>
+        <td>
+            <input type="checkbox" checked="true" onclick="toggleVisibility(document.getElementById('middle'))"> Outer frame visibility
+            </td>
+        <td>
+            <input type="checkbox" checked="true" onclick="toggleVisibility(document.getElementById('middle').contentDocument.getElementById('inner'))"> Inner frame visibility
+        </td>
+        <td>
+            <input type="checkbox" checked="true" onclick="toggleVisibility(document.getElementById('middle').contentDocument.getElementById('inner').contentDocument.getElementById('plugin'))"> Inner plug-in visibility
+        </td>
+    </tr>
+</table>
+
+<iframe id="middle" style="height: 400px; width: 400px;" src="resources/nested-plug-ins-outer-frame.html"></iframe>
diff --git a/WebCore/manual-tests/resources/nested-plug-ins-inner-frame.html b/WebCore/manual-tests/resources/nested-plug-ins-inner-frame.html
new file mode 100644 (file)
index 0000000..193bbe9
--- /dev/null
@@ -0,0 +1 @@
+<embed id="plugin" width='100' height='100' src='spinbox.swf' wmode='window'>
diff --git a/WebCore/manual-tests/resources/nested-plug-ins-outer-frame.html b/WebCore/manual-tests/resources/nested-plug-ins-outer-frame.html
new file mode 100644 (file)
index 0000000..c447d16
--- /dev/null
@@ -0,0 +1,3 @@
+<embed id="plugin" width='100' height='100' src='spinbox.swf' wmode='window'>
+<br>
+<iframe style="height: 200px; width: 200px;" id='inner' src='nested-plug-ins-inner-frame.html'></iframe>
index ec8a1685cd961135298337f6861572456f2d09e2..6cb7976eeca45048a041e06b61fd6679336b1a46 100644 (file)
@@ -135,6 +135,13 @@ namespace WebCore {
         
         virtual void setParent(ScrollView*);
 
+        virtual void attachToWindow();
+        virtual void detachFromWindow();
+        bool isAttachedToWindow() const;
+
+        virtual void show();
+        virtual void hide();
+
         void addToDirtyRegion(const IntRect&);
         void scrollBackingStore(int dx, int dy, const IntRect& scrollViewRect, const IntRect& clipRect);
         void updateBackingStore();
index d8ed7b17ccf2844fb4dc2f7c800bb025259f357d..1f204eddd574416a74aef8b4f884f0406a957414 100644 (file)
@@ -126,6 +126,9 @@ namespace WebCore {
         virtual void setParent(ScrollView*);
         ScrollView* parent() const;
 
+        virtual void attachToWindow() { }
+        virtual void detachFromWindow() { }
+
         virtual void geometryChanged() const {};
         
         IntRect convertToContainingWindow(const IntRect&) const;
index 4569c63800bf2ec6897de112de46de46b5bfeb25..f38b5433c66889eef5a6c4e43ff5585aa54065df 100644 (file)
@@ -60,6 +60,8 @@ public:
         , m_scrollbarsAvoidingResizer(0)
         , m_vScrollbarMode(ScrollbarAuto)
         , m_hScrollbarMode(ScrollbarAuto)
+        , m_visible(false)
+        , m_attachedToWindow(false)
     {
     }
 
@@ -93,6 +95,8 @@ public:
     RefPtr<PlatformScrollbar> m_hBar;
     HRGN m_dirtyRegion;
     HashSet<Widget*> m_children;
+    bool m_visible;
+    bool m_attachedToWindow;
 };
 
 void ScrollView::ScrollViewPrivate::setHasHorizontalScrollbar(bool hasBar)
@@ -728,6 +732,67 @@ void ScrollView::setParent(ScrollView* parentView)
     Widget::setParent(parentView);
 }
 
+void ScrollView::attachToWindow()
+{
+    if (m_data->m_attachedToWindow)
+        return;
+
+    m_data->m_attachedToWindow = true;
+
+    if (m_data->m_visible) {
+        HashSet<Widget*>::iterator end = m_data->m_children.end();
+        for (HashSet<Widget*>::iterator it = m_data->m_children.begin(); it != end; ++it)
+            (*it)->attachToWindow();
+    }
+}
+
+void ScrollView::detachFromWindow()
+{
+    if (!m_data->m_attachedToWindow)
+        return;
+
+    if (m_data->m_visible) {
+        HashSet<Widget*>::iterator end = m_data->m_children.end();
+        for (HashSet<Widget*>::iterator it = m_data->m_children.begin(); it != end; ++it)
+            (*it)->detachFromWindow();
+    }
+
+    m_data->m_attachedToWindow = false;
+}
+
+void ScrollView::show()
+{
+    if (!m_data->m_visible) {
+        m_data->m_visible = true;
+        if (isAttachedToWindow()) {
+            HashSet<Widget*>::iterator end = m_data->m_children.end();
+            for (HashSet<Widget*>::iterator it = m_data->m_children.begin(); it != end; ++it)
+                (*it)->attachToWindow();
+        }
+    }
+
+    Widget::show();
+}
+
+void ScrollView::hide()
+{
+    if (m_data->m_visible) {
+        if (isAttachedToWindow()) {
+            HashSet<Widget*>::iterator end = m_data->m_children.end();
+            for (HashSet<Widget*>::iterator it = m_data->m_children.begin(); it != end; ++it)
+                (*it)->detachFromWindow();
+        }
+        m_data->m_visible = false;
+    }
+
+    Widget::hide();
+}
+
+bool ScrollView::isAttachedToWindow() const
+{
+    return m_data->m_attachedToWindow;
+}
+
 void ScrollView::addToDirtyRegion(const IntRect& containingWindowRect)
 {
     ASSERT(isFrameView());
index f29a0df546e9a51f549abd037553aafcf11e562e..fc0adba4c90560cf64ca89596644eee275356e1e 100644 (file)
@@ -100,7 +100,11 @@ void Widget::setFrameGeometry(const IntRect &rect)
 
 void Widget::setParent(ScrollView* v)
 {
+    if (!v || !v->isAttachedToWindow())
+        detachFromWindow();
     data->parent = v;
+    if (v && v->isAttachedToWindow())
+        attachToWindow();
 }
 
 ScrollView* Widget::parent() const
index 084f4deef5e6ef4c1f9653383e9764cef8de227c..5351660f65435de9d8165db562465bde0366213c 100644 (file)
@@ -355,8 +355,8 @@ void PluginViewWin::geometryChanged() const
 
 void PluginViewWin::setFocus()
 {
-    if (HWND window = m_window)
-        SetFocus(window);
+    if (m_window)
+        SetFocus(m_window);
 
     Widget::setFocus();
 }
@@ -365,8 +365,8 @@ void PluginViewWin::show()
 {
     m_isVisible = true;
 
-    if (HWND window = m_window)
-        ShowWindow(window, SW_SHOWNA);
+    if (m_attachedToWindow && m_window)
+        ShowWindow(m_window, SW_SHOWNA);
 
     Widget::show();
 }
@@ -375,8 +375,8 @@ void PluginViewWin::hide()
 {
     m_isVisible = false;
 
-    if (HWND window = m_window)
-        ShowWindow(window, SW_HIDE);
+    if (m_attachedToWindow && m_window)
+        ShowWindow(m_window, SW_HIDE);
 
     Widget::hide();
 }
@@ -593,6 +593,26 @@ void PluginViewWin::setParent(ScrollView* parent)
 
 }
 
+void PluginViewWin::attachToWindow()
+{
+    if (m_attachedToWindow)
+        return;
+
+    m_attachedToWindow = true;
+    if (m_isVisible && m_window)
+        ShowWindow(m_window, SW_SHOWNA);
+}
+
+void PluginViewWin::detachFromWindow()
+{
+    if (!m_attachedToWindow)
+        return;
+
+    if (m_isVisible && m_window)
+        ShowWindow(m_window, SW_HIDE);
+    m_attachedToWindow = false;
+}
+
 void PluginViewWin::setNPWindowRect(const IntRect& rect)
 {
     if (!m_isStarted)
@@ -1425,6 +1445,7 @@ PluginViewWin::PluginViewWin(Frame* parentFrame, const IntSize& size, PluginPack
     , m_isWindowed(true)
     , m_isTransparent(false)
     , m_isVisible(false)
+    , m_attachedToWindow(false)
     , m_haveInitialized(false)
     , m_lastMessage(0)
     , m_isCallingPluginWndProc(false)
index af74537b3b9cadc57e16a4a511d06d13dabf260a..7aef466d1d219a8320da685154565e41f0664876 100644 (file)
@@ -125,6 +125,9 @@ namespace WebCore {
         virtual void handleEvent(Event*);
         virtual void setParent(ScrollView*);
 
+        virtual void attachToWindow();
+        virtual void detachFromWindow();
+
         LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
         WNDPROC pluginWndProc() const { return m_pluginWndProc; }
 
@@ -185,6 +188,7 @@ namespace WebCore {
         bool m_isWindowed;
         bool m_isTransparent;
         bool m_isVisible;
+        bool m_attachedToWindow;
         bool m_haveInitialized;
 
         WNDPROC m_pluginWndProc;
index 8f31995f2c110394e6009c50258f979bca68d692..c497fc607f220223d3402e44e10317d4002628dd 100644 (file)
@@ -1,3 +1,12 @@
+2007-12-05  Dan Bernstein  <mitz@apple.com>
+
+        Reviewed by Darin Adler.
+
+        - WebKit/win part of fixing <rdar://problem/5111082> Flash popup video ad doesn't close when clicked at http://www.firestonecompleteautocare.com/
+
+        * WebView.cpp:
+        (WebView::initWithFrame): Attach the main frame's view.
+
 2007-12-04  Ada Chan  <adachan@apple.com>
 
         Provide API for setting the default storage quota per database origin
index 606f4473b70ba0047fc363dca9a768ecbda9d369..e7cf6960ced70b7c6b676c0aeb96fac7c71c4e12 100644 (file)
@@ -1993,6 +1993,7 @@ HRESULT STDMETHODCALLTYPE WebView::initWithFrame(
     webFrame->initWithWebFrameView(0 /*FIXME*/, this, m_page, 0);
     m_mainFrame = webFrame;
     webFrame->Release(); // The WebFrame is owned by the Frame, so release our reference to it.
+    m_page->mainFrame()->view()->attachToWindow();
     m_page->mainFrame()->view()->resize(frame.right - frame.left, frame.bottom - frame.top);
 
     m_page->mainFrame()->tree()->setName(String(frameName, SysStringLen(frameName)));