Tables with vertical-lr writing-mode doesn't apply correctly vertical-align: baseline
[WebKit-https.git] / Source / WebCore / history / CachedPage.cpp
index 19af56a..0686ae8 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 #include "Document.h"
 #include "Element.h"
 #include "FocusController.h"
 #include "Document.h"
 #include "Element.h"
 #include "FocusController.h"
+#include "Frame.h"
+#include "FrameLoader.h"
 #include "FrameView.h"
 #include "FrameView.h"
-#include "MainFrame.h"
+#include "HistoryController.h"
+#include "HistoryItem.h"
 #include "Node.h"
 #include "Page.h"
 #include "Node.h"
 #include "Page.h"
+#include "PageTransitionEvent.h"
+#include "ScriptDisallowedScope.h"
 #include "Settings.h"
 #include "VisitedLinkState.h"
 #include "Settings.h"
 #include "VisitedLinkState.h"
-#include <wtf/CurrentTime.h>
 #include <wtf/RefCountedLeakCounter.h>
 #include <wtf/StdLibExtras.h>
 
 #include <wtf/RefCountedLeakCounter.h>
 #include <wtf/StdLibExtras.h>
 
-using namespace JSC;
+#if PLATFORM(IOS_FAMILY)
+#include "FrameSelection.h"
+#endif
+
 
 namespace WebCore {
 
 namespace WebCore {
+using namespace JSC;
 
 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, cachedPageCounter, ("CachedPage"));
 
 
 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, cachedPageCounter, ("CachedPage"));
 
-PassOwnPtr<CachedPage> CachedPage::create(Page& page)
-{
-    return adoptPtr(new CachedPage(page));
-}
-
 CachedPage::CachedPage(Page& page)
 CachedPage::CachedPage(Page& page)
-    : m_timeStamp(monotonicallyIncreasingTime())
-    , m_expirationTime(m_timeStamp + page.settings().backForwardCacheExpirationInterval())
-    , m_cachedMainFrame(CachedFrame::create(page.mainFrame()))
-    , m_needStyleRecalcForVisitedLinks(false)
-    , m_needsFullStyleRecalc(false)
-    , m_needsCaptionPreferencesChanged(false)
-    , m_needsDeviceScaleChanged(false)
+    : m_page(page)
+    , m_expirationTime(MonotonicTime::now() + Seconds(page.settings().backForwardCacheExpirationInterval()))
+    , m_cachedMainFrame(std::make_unique<CachedFrame>(page.mainFrame()))
 {
 #ifndef NDEBUG
     cachedPageCounter.increment();
 {
 #ifndef NDEBUG
     cachedPageCounter.increment();
@@ -70,43 +69,102 @@ CachedPage::~CachedPage()
     cachedPageCounter.decrement();
 #endif
 
     cachedPageCounter.decrement();
 #endif
 
-    destroy();
-    ASSERT(!m_cachedMainFrame);
+    if (m_cachedMainFrame)
+        m_cachedMainFrame->destroy();
+}
+
+static void firePageShowAndPopStateEvents(Page& page)
+{
+    // Dispatching JavaScript events can cause frame destruction.
+    auto& mainFrame = page.mainFrame();
+    Vector<Ref<Frame>> childFrames;
+    for (auto* child = mainFrame.tree().traverseNextInPostOrder(CanWrap::Yes); child; child = child->tree().traverseNextInPostOrder(CanWrap::No))
+        childFrames.append(*child);
+
+    for (auto& child : childFrames) {
+        if (!child->tree().isDescendantOf(&mainFrame))
+            continue;
+        auto* document = child->document();
+        if (!document)
+            continue;
+
+        // FIXME: Update Page Visibility state here.
+        // https://bugs.webkit.org/show_bug.cgi?id=116770
+        document->dispatchPageshowEvent(PageshowEventPersisted);
+
+        auto* historyItem = child->loader().history().currentItem();
+        if (historyItem && historyItem->stateObject())
+            document->dispatchPopstateEvent(historyItem->stateObject());
+    }
 }
 
 }
 
+class CachedPageRestorationScope {
+public:
+    CachedPageRestorationScope(Page& page)
+        : m_page(page)
+    {
+        m_page.setIsRestoringCachedPage(true);
+    }
+
+    ~CachedPageRestorationScope()
+    {
+        m_page.setIsRestoringCachedPage(false);
+    }
+
+private:
+    Page& m_page;
+};
+
 void CachedPage::restore(Page& page)
 {
     ASSERT(m_cachedMainFrame);
 void CachedPage::restore(Page& page)
 {
     ASSERT(m_cachedMainFrame);
-    ASSERT(page.frameIsMainFrame(&m_cachedMainFrame->view()->frame()));
+    ASSERT(m_cachedMainFrame->view()->frame().isMainFrame());
     ASSERT(!page.subframeCount());
 
     ASSERT(!page.subframeCount());
 
+    CachedPageRestorationScope restorationScope(page);
     m_cachedMainFrame->open();
     m_cachedMainFrame->open();
-    
+
     // Restore the focus appearance for the focused element.
     // FIXME: Right now we don't support pages w/ frames in the b/f cache.  This may need to be tweaked when we add support for that.
     Document* focusedDocument = page.focusController().focusedOrMainFrame().document();
     // Restore the focus appearance for the focused element.
     // FIXME: Right now we don't support pages w/ frames in the b/f cache.  This may need to be tweaked when we add support for that.
     Document* focusedDocument = page.focusController().focusedOrMainFrame().document();
-    if (Element* element = focusedDocument->focusedElement())
-        element->updateFocusAppearance(true);
-
-    if (m_needStyleRecalcForVisitedLinks) {
-        for (Frame* frame = &page.mainFrame(); frame; frame = frame->tree().traverseNext())
-            frame->document()->visitedLinkState().invalidateStyleForAllLinks();
+    if (Element* element = focusedDocument->focusedElement()) {
+#if PLATFORM(IOS_FAMILY)
+        // We don't want focused nodes changing scroll position when restoring from the cache
+        // as it can cause ugly jumps before we manage to restore the cached position.
+        page.mainFrame().selection().suppressScrolling();
+
+        bool hadProhibitsScrolling = false;
+        FrameView* frameView = page.mainFrame().view();
+        if (frameView) {
+            hadProhibitsScrolling = frameView->prohibitsScrolling();
+            frameView->setProhibitsScrolling(true);
+        }
+#endif
+        element->updateFocusAppearance(SelectionRestorationMode::Restore);
+#if PLATFORM(IOS_FAMILY)
+        if (frameView)
+            frameView->setProhibitsScrolling(hadProhibitsScrolling);
+        page.mainFrame().selection().restoreScrolling();
+#endif
     }
 
     }
 
-#if USE(ACCELERATED_COMPOSITING)
-    if (m_needsDeviceScaleChanged) {
+    if (m_needsDeviceOrPageScaleChanged)
         page.mainFrame().deviceOrPageScaleFactorChanged();
         page.mainFrame().deviceOrPageScaleFactorChanged();
-    }
-#endif
 
 
-    if (m_needsFullStyleRecalc)
-        page.setNeedsRecalcStyleInAllFrames();
+    page.setNeedsRecalcStyleInAllFrames();
 
 #if ENABLE(VIDEO_TRACK)
     if (m_needsCaptionPreferencesChanged)
         page.captionPreferencesChanged();
 #endif
 
 
 #if ENABLE(VIDEO_TRACK)
     if (m_needsCaptionPreferencesChanged)
         page.captionPreferencesChanged();
 #endif
 
+    if (m_needsUpdateContentsSize) {
+        if (FrameView* frameView = page.mainFrame().view())
+            frameView->updateContentsSize();
+    }
+
+    firePageShowAndPopStateEvents(page);
+
     clear();
 }
 
     clear();
 }
 
@@ -114,22 +172,17 @@ void CachedPage::clear()
 {
     ASSERT(m_cachedMainFrame);
     m_cachedMainFrame->clear();
 {
     ASSERT(m_cachedMainFrame);
     m_cachedMainFrame->clear();
-    m_cachedMainFrame = 0;
-    m_needStyleRecalcForVisitedLinks = false;
-    m_needsFullStyleRecalc = false;
-}
-
-void CachedPage::destroy()
-{
-    if (m_cachedMainFrame)
-        m_cachedMainFrame->destroy();
-
-    m_cachedMainFrame = 0;
+    m_cachedMainFrame = nullptr;
+#if ENABLE(VIDEO_TRACK)
+    m_needsCaptionPreferencesChanged = false;
+#endif
+    m_needsDeviceOrPageScaleChanged = false;
+    m_needsUpdateContentsSize = false;
 }
 
 bool CachedPage::hasExpired() const
 {
 }
 
 bool CachedPage::hasExpired() const
 {
-    return monotonicallyIncreasingTime() > m_expirationTime;
+    return MonotonicTime::now() > m_expirationTime;
 }
 
 } // namespace WebCore
 }
 
 } // namespace WebCore