Tables with vertical-lr writing-mode doesn't apply correctly vertical-align: baseline
[WebKit-https.git] / Source / WebCore / history / CachedPage.cpp
index 84aa030..0686ae8 100644 (file)
 #include "Document.h"
 #include "Element.h"
 #include "FocusController.h"
+#include "Frame.h"
+#include "FrameLoader.h"
 #include "FrameView.h"
-#include "MainFrame.h"
+#include "HistoryController.h"
+#include "HistoryItem.h"
 #include "Node.h"
 #include "Page.h"
+#include "PageTransitionEvent.h"
+#include "ScriptDisallowedScope.h"
 #include "Settings.h"
 #include "VisitedLinkState.h"
-#include <wtf/CurrentTime.h>
 #include <wtf/RefCountedLeakCounter.h>
 #include <wtf/StdLibExtras.h>
 
-#if PLATFORM(IOS)
+#if PLATFORM(IOS_FAMILY)
 #include "FrameSelection.h"
 #endif
 
-using namespace JSC;
 
 namespace WebCore {
+using namespace JSC;
 
 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, cachedPageCounter, ("CachedPage"));
 
 CachedPage::CachedPage(Page& page)
-    : m_expirationTime(monotonicallyIncreasingTime() + page.settings().backForwardCacheExpirationInterval())
+    : m_page(page)
+    , m_expirationTime(MonotonicTime::now() + Seconds(page.settings().backForwardCacheExpirationInterval()))
     , m_cachedMainFrame(std::make_unique<CachedFrame>(page.mainFrame()))
-    , m_needStyleRecalcForVisitedLinks(false)
-    , m_needsFullStyleRecalc(false)
-#if ENABLE(VIDEO_TRACK)
-    , m_needsCaptionPreferencesChanged(false)
-#endif
-    , m_needsDeviceScaleChanged(false)
 {
 #ifndef NDEBUG
     cachedPageCounter.increment();
@@ -74,19 +73,62 @@ CachedPage::~CachedPage()
         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);
     ASSERT(m_cachedMainFrame->view()->frame().isMainFrame());
     ASSERT(!page.subframeCount());
 
+    CachedPageRestorationScope restorationScope(page);
     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();
     if (Element* element = focusedDocument->focusedElement()) {
-#if PLATFORM(IOS)
+#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();
@@ -98,30 +140,31 @@ void CachedPage::restore(Page& page)
             frameView->setProhibitsScrolling(true);
         }
 #endif
-        element->updateFocusAppearance(true);
-#if PLATFORM(IOS)
+        element->updateFocusAppearance(SelectionRestorationMode::Restore);
+#if PLATFORM(IOS_FAMILY)
         if (frameView)
             frameView->setProhibitsScrolling(hadProhibitsScrolling);
         page.mainFrame().selection().restoreScrolling();
 #endif
     }
 
-    if (m_needStyleRecalcForVisitedLinks) {
-        for (Frame* frame = &page.mainFrame(); frame; frame = frame->tree().traverseNext())
-            frame->document()->visitedLinkState().invalidateStyleForAllLinks();
-    }
-
-    if (m_needsDeviceScaleChanged)
+    if (m_needsDeviceOrPageScaleChanged)
         page.mainFrame().deviceOrPageScaleFactorChanged();
 
-    if (m_needsFullStyleRecalc)
-        page.setNeedsRecalcStyleInAllFrames();
+    page.setNeedsRecalcStyleInAllFrames();
 
 #if ENABLE(VIDEO_TRACK)
     if (m_needsCaptionPreferencesChanged)
         page.captionPreferencesChanged();
 #endif
 
+    if (m_needsUpdateContentsSize) {
+        if (FrameView* frameView = page.mainFrame().view())
+            frameView->updateContentsSize();
+    }
+
+    firePageShowAndPopStateEvents(page);
+
     clear();
 }
 
@@ -130,17 +173,16 @@ void CachedPage::clear()
     ASSERT(m_cachedMainFrame);
     m_cachedMainFrame->clear();
     m_cachedMainFrame = nullptr;
-    m_needStyleRecalcForVisitedLinks = false;
-    m_needsFullStyleRecalc = false;
 #if ENABLE(VIDEO_TRACK)
     m_needsCaptionPreferencesChanged = false;
 #endif
-    m_needsDeviceScaleChanged = false;
+    m_needsDeviceOrPageScaleChanged = false;
+    m_needsUpdateContentsSize = false;
 }
 
 bool CachedPage::hasExpired() const
 {
-    return monotonicallyIncreasingTime() > m_expirationTime;
+    return MonotonicTime::now() > m_expirationTime;
 }
 
 } // namespace WebCore