Changeset 46418 in webkit


Ignore:
Timestamp:
Jul 27, 2009 10:04:35 AM (15 years ago)
Author:
Nikolas Zimmermann
Message:

[WML] History handling / page cache / loading is buggy and depends on several hacks
https://bugs.webkit.org/show_bug.cgi?id=27707

Redesign WML history/loading handling. See ChangeLog for details.

Location:
trunk
Files:
8 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r46412 r46418  
     12009-07-27  Nikolas Zimmermann  <nikolas.zimmermann@torchmobile.com>
     2
     3        Reviewed by George Staikos.
     4
     5        [WML] History handling / page cache / loading is buggy and depends on several hacks
     6        https://bugs.webkit.org/show_bug.cgi?id=27707
     7
     8        Add two new WML layout tests after redesigning WML history/loading handling.
     9
     10        * wml/enter-card-with-events-expected.txt: Added.
     11        * wml/enter-card-with-events.html: Added.
     12        * wml/enter-first-card-with-events-expected.txt: Added.
     13        * wml/enter-first-card-with-events.html: Added.
     14        * wml/resources/WMLTestCase.js:
     15        * wml/resources/enter-card-with-events.js: Added.
     16        (setupTestDocument):
     17        (prepareTest):
     18        (executeTest):
     19        * wml/resources/enter-card-with-events.wml: Added.
     20        * wml/resources/enter-first-card-with-events.js: Added.
     21        (setupTestDocument):
     22        (prepareTest):
     23        (executeTest):
     24        * wml/resources/enter-first-card-with-events.wml: Added.
     25
    1262009-07-27  Jan Michael Alonzo  <jmalonzo@webkit.org>
    227
  • trunk/LayoutTests/wml/resources/WMLTestCase.js

    r46395 r46418  
    1010}
    1111
    12 function createWMLTestCase(testDescription, substitutesVariables, testName, executeImmediately) {
     12function createWMLTestCase(testDescription, substitutesVariables, testName, executeImmediately, needsReset) {
    1313    // Setup default test options
    1414    if (substitutesVariables == null) {
     
    2424    }
    2525
     26    // Some tests may want to handle resetting the page state themselves
     27    if (needsReset == null) {
     28        needsReset = true;
     29    }
     30
    2631    // Initialize JS test
    2732    description(testDescription);
     
    2934
    3035    // Clear variable state & history
    31     document.resetWMLPageState();
     36    if (needsReset)
     37        document.resetWMLPageState();
    3238
    3339    // Setup DRT specific settings
  • trunk/WebCore/ChangeLog

    r46417 r46418  
     12009-07-27  Nikolas Zimmermann  <nikolas.zimmermann@torchmobile.com>
     2
     3        Reviewed by George Staikos.
     4
     5        [WML] History handling / page cache / loading is buggy and depends on several hacks
     6        https://bugs.webkit.org/show_bug.cgi?id=27707
     7
     8        Redesign WML history/loading handling. In detail:
     9
     10        - Remove FrameLoader::setForceReloadWmlDeck(). WML used to force a special loading behaviour
     11          by calling this method from WMLGoElement & friends - instead teach FrameLoader to detect
     12          WML content itself.
     13
     14          WML content is usually a standalone WML document (isWMLDocument()=true) or as special case
     15          an XHTML document which embeds a WML document (that's the way the WML layout tests work).
     16          Force WML loading behaviour even for XHTML document which embed WML documents. This only
     17          applies to our layout tests, not for any real world site. Though it gives us a perfect
     18          way to test the WML loading code even when we're not operating on a standalone WML document.
     19
     20          Whenever a WMLCardElement is inserted into the document it will check wheter it's inserted
     21          in a standalone WML document or wheter the main frame document is different. If it differs
     22          the main frame documents' "containsWMLContent" property is set to true.
     23
     24          -> Make FrameLoader::shouldReload() use the new frameContainsWMLContent() method, which
     25             checks if the associated frame document is a WML document or wheter it contains WML content.
     26
     27        - Change FrameLoader::loadItem() to use the new frameContainsWMLContent() method for 'shouldScroll'
     28          detection. WML documents (or those containing WML content) always want new loads even for in-page
     29          navigation. No "scroll to anchor" mechanism should apply.
     30
     31        - Modify FrameLoader::canCachePageContainingThisFrame() to check for !frameContainsWMLContent().
     32          WML pages should never be cached, potential security problem due the use of variables (per spec).
     33
     34        Add two new WML tests which were broken before, testing onenterforward/onenterbackward event handling
     35        and history navigation (<prev/> task).
     36
     37        Tests: wml/enter-card-with-events.html
     38               wml/enter-first-card-with-events.html
     39
     40        * dom/Document.cpp: Initialize new 'm_containsWMLContent' property.
     41        (WebCore::Document::Document):
     42        * dom/Document.h: Add new helper methods and 'm_containsWMLContent" variable (explained above).
     43        (WebCore::Document::setContainsWMLContent):
     44        (WebCore::Document::containsWMLContent):
     45        * history/BackForwardList.cpp:
     46        (WebCore::BackForwardList::clearWMLPageHistory): Renamed from clearWmlPageHistory() & slight cleanup.
     47        * history/BackForwardList.h:
     48        * loader/FrameLoader.cpp: Rework WML loading behaviour (explained above).
     49        (WebCore::FrameLoader::FrameLoader):
     50        (WebCore::frameContainsWMLContent):
     51        (WebCore::FrameLoader::canCachePageContainingThisFrame):
     52        (WebCore::FrameLoader::shouldReload):
     53        (WebCore::FrameLoader::loadItem):
     54        * loader/FrameLoader.h:
     55        * wml/WMLCardElement.cpp:
     56        (WebCore::WMLCardElement::handleIntrinsicEventIfNeeded): No need anymore to manually track history length.
     57        (WebCore::WMLCardElement::insertedIntoDocument): Handle setting containsWMLContent on the main frame document.
     58        * wml/WMLGoElement.cpp:
     59        (WebCore::WMLGoElement::executeTask): Remove call to FrameLoader::setForceReloadWmlDeck()
     60        * wml/WMLPageState.cpp: Remove 'm_historyLength' - no need anymore to track history length on our own.
     61        (WebCore::WMLPageState::WMLPageState):
     62        (WebCore::WMLPageState::dump):
     63        (WebCore::WMLPageState::reset):
     64        * wml/WMLPageState.h:
     65
    1662009-07-27  Pavel Feldman  <pfeldman@chromium.org>
    267
  • trunk/WebCore/dom/Document.cpp

    r46301 r46418  
    336336#endif
    337337    , m_usingGeolocation(false)
     338#if ENABLE(WML)
     339    , m_containsWMLContent(false)
     340#endif
    338341{
    339342    m_document.resetSkippingRef(this);
  • trunk/WebCore/dom/Document.h

    r46136 r46418  
    10351035
    10361036#if ENABLE(WML)
     1037    void setContainsWMLContent(bool value) { m_containsWMLContent = value; }
     1038    bool containsWMLContent() const { return m_containsWMLContent; }
     1039
    10371040    void resetWMLPageState();
    10381041    void initializeWMLPageState();
     
    11171120   
    11181121    bool m_usingGeolocation;
     1122
     1123#if ENABLE(WML)
     1124    bool m_containsWMLContent;
     1125#endif
    11191126};
    11201127
  • trunk/WebCore/history/BackForwardList.cpp

    r39432 r46418  
    267267
    268268#if ENABLE(WML)
    269 void BackForwardList::clearWmlPageHistory()
    270 {
    271     PassRefPtr<HistoryItem> cur = currentItem();
    272 
    273     for (unsigned i = 0; i < m_entries.size(); ++i)
     269void BackForwardList::clearWMLPageHistory()
     270{
     271    int size = m_entries.size();
     272    for (int i = 0; i < size; ++i)
    274273        pageCache()->remove(m_entries[i].get());
    275274
  • trunk/WebCore/history/BackForwardList.h

    r39989 r46418  
    9898   
    9999#if ENABLE(WML)
    100     void clearWmlPageHistory();
     100    void clearWMLPageHistory();
    101101#endif
    102102
  • trunk/WebCore/loader/FrameLoader.cpp

    r46298 r46418  
    272272    , m_didDispatchDidCommitLoad(false)
    273273#endif
    274 #if ENABLE(WML)
    275     , m_forceReloadWmlDeck(false)
    276 #endif
    277274{
    278275}
     
    17841781}
    17851782
     1783#if ENABLE(WML)
     1784static inline bool frameContainsWMLContent(Frame* frame)
     1785{
     1786    Document* document = frame ? frame->document() : 0;
     1787    if (!document)
     1788        return false;
     1789
     1790    return document->containsWMLContent() || document->isWMLDocument();
     1791}
     1792#endif
     1793
    17861794bool FrameLoader::canCachePageContainingThisFrame()
    17871795{
     
    18111819        && !m_documentLoader->applicationCache()
    18121820        && !m_documentLoader->candidateApplicationCacheGroup()
     1821#endif
     1822#if ENABLE(WML)
     1823        && !frameContainsWMLContent(m_frame)
    18131824#endif
    18141825        && m_client->canCachePage()
     
    29642975}
    29652976
     2977bool FrameLoader::shouldReload(const KURL& currentURL, const KURL& destinationURL)
     2978{
    29662979#if ENABLE(WML)
    2967 void FrameLoader::setForceReloadWmlDeck(bool reload)
    2968 {
    2969     m_forceReloadWmlDeck = reload;
    2970 }
    2971 #endif
    2972 
    2973 bool FrameLoader::shouldReload(const KURL& currentURL, const KURL& destinationURL)
    2974 {
    2975 #if ENABLE(WML)
    2976     // As for WML deck, sometimes it's supposed to be reloaded even if the same URL with fragment
    2977     if (m_forceReloadWmlDeck)
     2980    // All WML decks are supposed to be reloaded, even within the same URL fragment
     2981    if (frameContainsWMLContent(m_frame))
    29782982        return true;
    29792983#endif
     
    44304434
    44314435#if ENABLE(WML)
    4432     if (m_frame->document()->isWMLDocument())
     4436    // All WML decks should go through the real load mechanism, not the scroll-to-anchor code
     4437    if (frameContainsWMLContent(m_frame))
    44334438        shouldScroll = false;
    44344439#endif
  • trunk/WebCore/loader/FrameLoader.h

    r45891 r46418  
    11/*
    22 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
    3  * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
     3 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
    44 *
    55 * Redistribution and use in source and binary forms, with or without
     
    237237        void didFirstVisuallyNonEmptyLayout();
    238238
    239 #if ENABLE(WML)
    240         void setForceReloadWmlDeck(bool);
    241 #endif
    242 
    243239        void loadedResourceFromMemoryCache(const CachedResource*);
    244240        void tellClientAboutPastMemoryCacheLoads();
     
    626622        bool m_didDispatchDidCommitLoad;
    627623#endif
    628 
    629 #if ENABLE(WML)
    630         bool m_forceReloadWmlDeck;
    631 #endif
    632624    };
    633625
  • trunk/WebCore/wml/WMLCardElement.cpp

    r45342 r46418  
    2929#include "MappedAttribute.h"
    3030#include "NodeList.h"
     31#include "Page.h"
    3132#include "RenderStyle.h"
    3233#include "WMLDocument.h"
     
    132133    if (!loader)
    133134        return;
    134    
    135     int currentHistoryLength = loader->getHistoryLength();
    136     int lastHistoryLength = pageState->historyLength();
    137135
    138136    // Calculate the entry method of current card
    139137    WMLIntrinsicEventType eventType = WMLIntrinsicEventUnknown;
    140     if (lastHistoryLength > currentHistoryLength)
     138
     139    switch (loader->loadType()) {
     140    case FrameLoadTypeReload:
     141        break;
     142    case FrameLoadTypeBack:
    141143        eventType = WMLIntrinsicEventOnEnterBackward;
    142     else if (lastHistoryLength < currentHistoryLength)
     144        break;
     145    default:
    143146        eventType = WMLIntrinsicEventOnEnterForward;
    144 
    145     // Synchronize history length with WMLPageState
    146     pageState->setHistoryLength(currentHistoryLength);
    147  
     147        break;
     148    }
     149
    148150    // Figure out target event handler
    149151    WMLIntrinsicEventHandler* eventHandler = this->eventHandler();
     
    242244{
    243245    WMLElement::insertedIntoDocument();
     246    Document* document = this->document();
    244247
    245248    // The first card inserted into a document, is visible by default.
    246249    if (!m_isVisible) {
    247         RefPtr<NodeList> nodeList = document()->getElementsByTagName("card");
     250        RefPtr<NodeList> nodeList = document->getElementsByTagName("card");
    248251        if (nodeList && nodeList->length() == 1 && nodeList->item(0) == this)
    249252            m_isVisible = true;
     253    }
     254
     255    // For the WML layout tests we embed WML content in a XHTML document. Navigating to different cards
     256    // within the same deck has a different behaviour in HTML than in WML. HTML wants to "scroll to anchor"
     257    // (see FrameLoader) but WML wants a reload. Notify the root document of the layout test that we want
     258    // to mimic WML behaviour. This is rather tricky, but has been tested extensively. Usually it's not possible
     259    // at all to embed WML in HTML, it's not designed that way, we're just "abusing" it for dynamically created layout tests.
     260    if (document->page() && document->page()->mainFrame()) {
     261        Document* rootDocument = document->page()->mainFrame()->document();
     262        if (rootDocument && rootDocument != document)
     263            rootDocument->setContainsWMLContent(true);
    250264    }
    251265}
  • trunk/WebCore/wml/WMLGoElement.cpp

    r43310 r46418  
    11/**
    2  * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
     2 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
    33 *
    44 * This library is free software; you can redistribute it and/or
     
    103103    bool inSameDeck = doc->url().path() == url.path();
    104104    if (inSameDeck && url.hasRef()) {
    105         // Force frame loader to load the URL with fragment identifier
    106         loader->setForceReloadWmlDeck(true);
    107 
    108105        if (WMLCardElement* card = WMLCardElement::findNamedCardInDocument(doc, url.ref())) {
    109106            if (card->isNewContext())
  • trunk/WebCore/wml/WMLPageState.cpp

    r45444 r46418  
    11/*
    2  * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
    3  *
     2 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
    43 * Copyright (C) 2004-2007 Apple Inc. All rights reserved.
    54 *
     
    2625#include "WMLPageState.h"
    2726
     27#include "CString.h"
    2828#include "HistoryItem.h"
    2929#include "KURL.h"
     
    3434WMLPageState::WMLPageState(Page* page)
    3535    : m_page(page)
    36     , m_historyLength(0)
    3736    , m_activeCard(0)
    3837    , m_hasDeckAccess(false)
     
    4544}
    4645
     46#ifndef NDEBUG
     47// Debugging helper for use within gdb
     48void WMLPageState::dump()
     49{
     50    WMLVariableMap::iterator it = m_variables.begin();
     51    WMLVariableMap::iterator end = m_variables.end();
     52
     53    fprintf(stderr, "Dumping WMLPageState (this=%p) associated with Page (page=%p)...\n", this, m_page);
     54    for (; it != end; ++it)
     55        fprintf(stderr, "\t-> name: '%s'\tvalue: '%s'\n", (*it).first.latin1().data(), (*it).second.latin1().data());
     56}
     57#endif
     58
    4759void WMLPageState::reset()
    4860{
    49     // remove all the variables in the current browser context
     61    // Remove all the variables
    5062    m_variables.clear();
    5163
    52     // clear the navigation history state
    53     if (m_page)
    54         m_page->backForwardList()->clearWmlPageHistory();
    55 
    56     // reset implementation-specfic state if UA has
    57     m_historyLength = 0;
     64    // Clear the navigation history state
     65    if (BackForwardList* list = m_page ? m_page->backForwardList() : 0)
     66        list->clearWMLPageHistory();
    5867}
    5968
  • trunk/WebCore/wml/WMLPageState.h

    r39432 r46418  
    4040    virtual ~WMLPageState();
    4141
     42#ifndef NDEBUG
     43    void dump();
     44#endif
     45
    4246    // reset the browser context when 'newcontext' attribute
    4347    // of card element is performed as part of go task
Note: See TracChangeset for help on using the changeset viewer.