Changeset 62912 in webkit


Ignore:
Timestamp:
Jul 9, 2010 1:08:48 AM (14 years ago)
Author:
abarth@webkit.org
Message:

2010-07-08 Adam Barth <abarth@webkit.org>

Reviewed by Eric Seidel.

Handle whitespace correctly
https://bugs.webkit.org/show_bug.cgi?id=41907

This patch introduces an extra memcpy in the character token pipeline.
I'll remove the memcpy in a future patch.

  • html/HTMLConstructionSite.cpp: (WebCore::HTMLConstructionSite::insertTextNode):
  • html/HTMLConstructionSite.h:
  • html/HTMLTreeBuilder.cpp: (WebCore::HTMLTreeBuilder::processCharacter):
  • html/HTMLTreeBuilder.h:

2010-07-08 Adam Barth <abarth@webkit.org>

Reviewed by Eric Seidel.

Handle whitespace correctly
https://bugs.webkit.org/show_bug.cgi?id=41907

Update expectations to show massive progression.

  • html5lib/resources/doctype01.dat:
    • When I created this test, I set the expectations incorrectly. The new expectations now match the spec and Minefield.
  • html5lib/runner-expected-html5.txt:
  • html5lib/runner-expected.txt:
Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r62905 r62912  
     12010-07-08  Adam Barth  <abarth@webkit.org>
     2
     3        Reviewed by Eric Seidel.
     4
     5        Handle whitespace correctly
     6        https://bugs.webkit.org/show_bug.cgi?id=41907
     7
     8        Update expectations to show massive progression.
     9
     10        * html5lib/resources/doctype01.dat:
     11          - When I created this test, I set the expectations incorrectly.  The
     12            new expectations now match the spec and Minefield.
     13        * html5lib/runner-expected-html5.txt:
     14        * html5lib/runner-expected.txt:
     15
    1162010-07-09  Csaba Osztrogonác  <ossy@webkit.org>
    217
  • trunk/LayoutTests/html5lib/resources/doctype01.dat

    r61280 r62912  
    310310|   <head>
    311311|   <body>
    312 |     "
    313 ]>"
     312|     "]>"
    314313
    315314#data
  • trunk/LayoutTests/html5lib/runner-expected-html5.txt

    r62891 r62912  
    7730
    8832
    9 50
    10952
    111053
     
    9392|                   "please!"
    9493|             <!-- X -->
    95 
    96 Test 50 of 113 in resources/tests1.dat failed. Input:
    97 <!DOCTYPE html><script> <!-- </script> --> </script> EOF
    98 Got:
    99 | <!DOCTYPE html>
    100 | <html>
    101 |   <head>
    102 |     <script>
    103 |       " <!-- "
    104 |   <body>
    105 |     " -->  EOF"
    106 Expected:
    107 | <!DOCTYPE html>
    108 | <html>
    109 |   <head>
    110 |     <script>
    111 |       " <!-- "
    112 |     " "
    113 |   <body>
    114 |     "-->  EOF"
    11594
    11695Test 52 of 113 in resources/tests1.dat failed. Input:
     
    306285resources/tests2.dat:
    30728613
    308 47
    309 48
    310 49
    311287
    312288Test 13 of 59 in resources/tests2.dat failed. Input:
     
    330306|       <tbody>
    331307|         <tr>
    332 
    333 Test 47 of 59 in resources/tests2.dat failed. Input:
    334  
    335  
    336 Got:
    337 | <html>
    338 |   <head>
    339 |   <body>
    340 |     "
    341  "
    342 Expected:
    343 | <html>
    344 |   <head>
    345 |   <body>
    346 
    347 Test 48 of 59 in resources/tests2.dat failed. Input:
    348 <!DOCTYPE html>  <html>
    349 Got:
    350 | <!DOCTYPE html>
    351 | <html>
    352 |   <head>
    353 |   <body>
    354 |     "  "
    355 Expected:
    356 | <!DOCTYPE html>
    357 | <html>
    358 |   <head>
    359 |   <body>
    360 
    361 Test 49 of 59 in resources/tests2.dat failed. Input:
    362 <!DOCTYPE html><script>
    363 </script>  <title>x</title>  </head>
    364 Got:
    365 | <!DOCTYPE html>
    366 | <html>
    367 |   <head>
    368 |     <script>
    369 |       "
    370 "
    371 |   <body>
    372 |     "  "
    373 |     <title>
    374 |       "x"
    375 |     "  "
    376 Expected:
    377 | <!DOCTYPE html>
    378 | <html>
    379 |   <head>
    380 |     <script>
    381 |       "
    382 "
    383 |     "  "
    384 |     <title>
    385 |       "x"
    386 |     "  "
    387 |   <body>
    388308resources/tests3.dat:
    38930916
     
    490410| <title>
    491411|   "setting head's innerHTML"
    492 resources/tests5.dat:
    493 2
    494 7
    495 8
    496 
    497 Test 2 of 16 in resources/tests5.dat failed. Input:
    498 <style> <!-- </style> --> </style>x
    499 Got:
    500 | <html>
    501 |   <head>
    502 |     <style>
    503 |       " <!-- "
    504 |   <body>
    505 |     " --> x"
    506 Expected:
    507 | <html>
    508 |   <head>
    509 |     <style>
    510 |       " <!-- "
    511 |     " "
    512 |   <body>
    513 |     "--> x"
    514 
    515 Test 7 of 16 in resources/tests5.dat failed. Input:
    516 <script> <!-- </script> --> </script>x
    517 Got:
    518 | <html>
    519 |   <head>
    520 |     <script>
    521 |       " <!-- "
    522 |   <body>
    523 |     " --> x"
    524 Expected:
    525 | <html>
    526 |   <head>
    527 |     <script>
    528 |       " <!-- "
    529 |     " "
    530 |   <body>
    531 |     "--> x"
    532 
    533 Test 8 of 16 in resources/tests5.dat failed. Input:
    534 <title> <!-- </title> --> </title>x
    535 Got:
    536 | <html>
    537 |   <head>
    538 |     <title>
    539 |       " <!-- "
    540 |   <body>
    541 |     " --> x"
    542 Expected:
    543 | <html>
    544 |   <head>
    545 |     <title>
    546 |       " <!-- "
    547 |     " "
    548 |   <body>
    549 |     "--> x"
     412resources/tests5.dat: PASS
     413
    550414resources/tests6.dat:
    551 1
    552 8
    553 9
    554 10
    555 11
    556 12
    55741526
    55841627
     
    56141944
    56242045
    563 46
    56442147
    565 
    566 Test 1 of 51 in resources/tests6.dat failed. Input:
    567 <!doctype html></head> <head>
    568 Got:
    569 | <!DOCTYPE html>
    570 | <html>
    571 |   <head>
    572 |   <body>
    573 |     " "
    574 Expected:
    575 | <!DOCTYPE html>
    576 | <html>
    577 |   <head>
    578 |   " "
    579 |   <body>
    580 
    581 Test 8 of 51 in resources/tests6.dat failed. Input:
    582 <frameset></frameset>
    583 foo
    584 Got:
    585 | <html>
    586 |   <head>
    587 |   <frameset>
    588 Expected:
    589 | <html>
    590 |   <head>
    591 |   <frameset>
    592 |   "
    593 "
    594 
    595 Test 9 of 51 in resources/tests6.dat failed. Input:
    596 <frameset></frameset>
    597 <noframes>
    598 Got:
    599 | <html>
    600 |   <head>
    601 |   <frameset>
    602 |   <noframes>
    603 Expected:
    604 | <html>
    605 |   <head>
    606 |   <frameset>
    607 |   "
    608 "
    609 |   <noframes>
    610 
    611 Test 10 of 51 in resources/tests6.dat failed. Input:
    612 <frameset></frameset>
    613 <div>
    614 Got:
    615 | <html>
    616 |   <head>
    617 |   <frameset>
    618 Expected:
    619 | <html>
    620 |   <head>
    621 |   <frameset>
    622 |   "
    623 "
    624 
    625 Test 11 of 51 in resources/tests6.dat failed. Input:
    626 <frameset></frameset>
    627 </html>
    628 Got:
    629 | <html>
    630 |   <head>
    631 |   <frameset>
    632 Expected:
    633 | <html>
    634 |   <head>
    635 |   <frameset>
    636 |   "
    637 "
    638 
    639 Test 12 of 51 in resources/tests6.dat failed. Input:
    640 <frameset></frameset>
    641 </div>
    642 Got:
    643 | <html>
    644 |   <head>
    645 |   <frameset>
    646 Expected:
    647 | <html>
    648 |   <head>
    649 |   <frameset>
    650 |   "
    651 "
    652422
    653423Test 26 of 51 in resources/tests6.dat failed. Input:
     
    710480| <body>
    711481
    712 Test 46 of 51 in resources/tests6.dat failed. Input:
    713 <html><frameset></frameset></html>
    714 Got:
    715 | <html>
    716 |   <head>
    717 |   <frameset>
    718 Expected:
    719 | <html>
    720 |   <head>
    721 |   <frameset>
    722 |   " "
    723 
    724482Test 47 of 51 in resources/tests6.dat failed. Input:
    725483<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"><html></html>
     
    736494resources/tests7.dat:
    7374956
    738 7
    739 8
    74049616
    74149724
     
    773529|             <table>
    774530|               " "
    775 
    776 Test 7 of 30 in resources/tests7.dat failed. Input:
    777 <!doctype html><html> <head>
    778 Got:
    779 | <!DOCTYPE html>
    780 | <html>
    781 |   <head>
    782 |   <body>
    783 |     " "
    784 Expected:
    785 | <!DOCTYPE html>
    786 | <html>
    787 |   <head>
    788 |   <body>
    789 
    790 Test 8 of 30 in resources/tests7.dat failed. Input:
    791 <!doctype html> <head>
    792 Got:
    793 | <!DOCTYPE html>
    794 | <html>
    795 |   <head>
    796 |   <body>
    797 |     " "
    798 Expected:
    799 | <!DOCTYPE html>
    800 | <html>
    801 |   <head>
    802 |   <body>
    803531
    804532Test 16 of 30 in resources/tests7.dat failed. Input:
  • trunk/LayoutTests/html5lib/runner-expected.txt

    r62623 r62912  
    49434943|           "a"
    49444944|         <nobr>
    4945 resources/doctype01.dat: PASS
    4946 
     4945resources/doctype01.dat:
     494631
     4947
     4948Test 31 of 37 in resources/doctype01.dat failed. Input:
     4949<!DOCTYPE root-element [SYSTEM OR PUBLIC FPI] "uri" [
     4950<!-- internal declarations -->
     4951]>
     4952Got:
     4953| <!DOCTYPE root-element>
     4954| <html>
     4955|   <head>
     4956|   <body>
     4957|     "
     4958]>"
     4959Expected:
     4960| <!DOCTYPE root-element>
     4961| <html>
     4962|   <head>
     4963|   <body>
     4964|     "]>"
    49474965resources/scriptdata01.dat: PASS
    49484966
  • trunk/WebCore/ChangeLog

    r62911 r62912  
     12010-07-08  Adam Barth  <abarth@webkit.org>
     2
     3        Reviewed by Eric Seidel.
     4
     5        Handle whitespace correctly
     6        https://bugs.webkit.org/show_bug.cgi?id=41907
     7
     8        This patch introduces an extra memcpy in the character token pipeline.
     9        I'll remove the memcpy in a future patch.
     10
     11        * html/HTMLConstructionSite.cpp:
     12        (WebCore::HTMLConstructionSite::insertTextNode):
     13        * html/HTMLConstructionSite.h:
     14        * html/HTMLTreeBuilder.cpp:
     15        (WebCore::HTMLTreeBuilder::processCharacter):
     16        * html/HTMLTreeBuilder.h:
     17
    1182010-07-09  Eric Seidel  <eric@webkit.org>
    219
  • trunk/WebCore/html/HTMLConstructionSite.cpp

    r62907 r62912  
    220220}
    221221
    222 void HTMLConstructionSite::insertTextNode(AtomicHTMLToken& token)
     222void HTMLConstructionSite::insertTextNode(const String& characters)
    223223{
    224224    if (Node* lastChild = currentElement()->lastChild()) {
     
    227227            // was the last text node inserted by the parser.
    228228            CharacterData* textNode = static_cast<CharacterData*>(lastChild);
    229             textNode->parserAppendData(token.characters());
     229            textNode->parserAppendData(characters);
    230230            return;
    231231        }
    232232    }
    233     attach(currentElement(), Text::create(m_document, token.characters()));
     233    attach(currentElement(), Text::create(m_document, characters));
    234234}
    235235
  • trunk/WebCore/html/HTMLConstructionSite.h

    r62907 r62912  
    5757    void insertHTMLBodyElement(AtomicHTMLToken&);
    5858    void insertScriptElement(AtomicHTMLToken&);
    59     void insertTextNode(AtomicHTMLToken&);
    60 
    61     bool insertLeadingWhitespace(AtomicHTMLToken&)
    62     {
    63         notImplemented();
    64         return false;
    65     }
    66 
    67     bool insertLeadingWhitespaceWithActiveFormattingElements(AtomicHTMLToken&)
    68     {
    69         notImplemented();
    70         return false;
    71     }
     59    void insertTextNode(const String&);
    7260
    7361    void insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken&);
  • trunk/WebCore/html/HTMLTreeBuilder.cpp

    r62911 r62912  
    6666    return cc == '\t' || cc == '\x0A' || cc == '\x0C' || cc == '\x0D' || cc == ' ';
    6767}
     68
     69class ExternalCharacterTokenBuffer : public Noncopyable {
     70public:
     71    explicit ExternalCharacterTokenBuffer(AtomicHTMLToken& token)
     72        : m_current(token.characters().characters())
     73        , m_end(m_current + token.characters().length())
     74    {
     75        ASSERT(!isEmpty());
     76    }
     77
     78    ~ExternalCharacterTokenBuffer()
     79    {
     80        ASSERT(isEmpty());
     81    }
     82
     83    bool isEmpty() const { return m_current == m_end; }
     84
     85    void skipLeadingWhitespace()
     86    {
     87        ASSERT(!isEmpty());
     88        while (isTreeBuilderWhitepace(*m_current)) {
     89            if (++m_current == m_end)
     90                return;
     91        }
     92    }
     93
     94    String takeLeadingWhitespace()
     95    {
     96        ASSERT(!isEmpty());
     97        const UChar* start = m_current;
     98        skipLeadingWhitespace();
     99        if (start == m_current)
     100            return String();
     101        return String(start, m_current - start);
     102    }
     103
     104    String takeRemaining()
     105    {
     106        ASSERT(!isEmpty());
     107        const UChar* start = m_current;
     108        m_current = m_end;
     109        return String(start, m_current - start);
     110    }
     111
     112    String takeRemainingWhitespace()
     113    {
     114        ASSERT(!isEmpty());
     115        Vector<UChar> whitespace;
     116        do {
     117            UChar cc = *m_current++;
     118            if (isTreeBuilderWhitepace(cc))
     119                whitespace.append(cc);
     120        } while (m_current < m_end);
     121        // Returning the null string when there aren't any whitespace
     122        // characters is slightly cleaner semantically because we don't want
     123        // to insert a text node (as opposed to inserting an empty text node).
     124        if (whitespace.isEmpty())
     125            return String();
     126        return String::adopt(whitespace);
     127    }
     128
     129private:
     130    const UChar* m_current;
     131    const UChar* m_end;
     132};
    68133
    69134inline bool hasNonWhitespace(const String& string)
     
    20712136{
    20722137    ASSERT(token.type() == HTMLToken::Character);
    2073     // FIXME: We need to figure out how to handle each character individually.
     2138
     2139    // FIXME: Currently this design has an extra memcpy because we copy the
     2140    // characters out of the HTMLTokenizer's buffer into the AtomicHTMLToken
     2141    // and then into the text node.  What we'd really like is to copy directly
     2142    // from the HTMLTokenizer's buffer into the text node.
     2143    ExternalCharacterTokenBuffer buffer(token);
     2144
     2145ReprocessBuffer:
    20742146    switch (insertionMode()) {
    2075     case InitialMode:
     2147    case InitialMode: {
    20762148        ASSERT(insertionMode() == InitialMode);
    2077         if (skipLeadingWhitespace(token))
     2149        buffer.skipLeadingWhitespace();
     2150        if (buffer.isEmpty())
    20782151            return;
    20792152        processDefaultForInitialMode(token);
    20802153        // Fall through.
    2081     case BeforeHTMLMode:
     2154    }
     2155    case BeforeHTMLMode: {
    20822156        ASSERT(insertionMode() == BeforeHTMLMode);
    2083         if (skipLeadingWhitespace(token))
     2157        buffer.skipLeadingWhitespace();
     2158        if (buffer.isEmpty())
    20842159            return;
    20852160        processDefaultForBeforeHTMLMode(token);
    20862161        // Fall through.
    2087     case BeforeHeadMode:
     2162    }
     2163    case BeforeHeadMode: {
    20882164        ASSERT(insertionMode() == BeforeHeadMode);
    2089         if (skipLeadingWhitespace(token))
     2165        buffer.skipLeadingWhitespace();
     2166        if (buffer.isEmpty())
    20902167            return;
    20912168        processDefaultForBeforeHeadMode(token);
    20922169        // Fall through.
    2093     case InHeadMode:
     2170    }
     2171    case InHeadMode: {
    20942172        ASSERT(insertionMode() == InHeadMode);
    2095         if (m_tree.insertLeadingWhitespace(token))
     2173        String leadingWhitespace = buffer.takeLeadingWhitespace();
     2174        if (!leadingWhitespace.isEmpty())
     2175            m_tree.insertTextNode(leadingWhitespace);
     2176        if (buffer.isEmpty())
    20962177            return;
    20972178        processDefaultForInHeadMode(token);
    20982179        // Fall through.
    2099     case AfterHeadMode:
     2180    }
     2181    case AfterHeadMode: {
    21002182        ASSERT(insertionMode() == AfterHeadMode);
    2101         if (m_tree.insertLeadingWhitespace(token))
     2183        String leadingWhitespace = buffer.takeLeadingWhitespace();
     2184        if (!leadingWhitespace.isEmpty())
     2185            m_tree.insertTextNode(leadingWhitespace);
     2186        if (buffer.isEmpty())
    21022187            return;
    21032188        processDefaultForAfterHeadMode(token);
    2104         // Fall through
     2189        // Fall through.
     2190    }
    21052191    case InBodyMode:
    21062192    case InCaptionMode:
    2107     case InCellMode:
     2193    case InCellMode: {
    21082194        ASSERT(insertionMode() == InBodyMode || insertionMode() == InCaptionMode || insertionMode() == InCellMode);
    21092195        m_tree.reconstructTheActiveFormattingElements();
    2110         m_tree.insertTextNode(token);
    2111         if (m_framesetOk && hasNonWhitespace(token.characters()))
     2196        String characters = buffer.takeRemaining();
     2197        m_tree.insertTextNode(characters);
     2198        if (m_framesetOk && hasNonWhitespace(characters))
    21122199            m_framesetOk = false;
    21132200        break;
     2201    }
    21142202    case InTableMode:
    21152203    case InTableBodyMode:
    2116     case InRowMode:
     2204    case InRowMode: {
    21172205        ASSERT(insertionMode() == InTableMode || insertionMode() == InTableBodyMode || insertionMode() == InRowMode);
    21182206        notImplemented(); // Crazy pending characters.
    2119         m_tree.insertTextNode(token);
    2120         break;
    2121     case InTableTextMode:
     2207        m_tree.insertTextNode(buffer.takeRemaining());
     2208        break;
     2209    }
     2210    case InTableTextMode: {
    21222211        notImplemented(); // Crazy pending characters.
    21232212        break;
    2124     case InColumnGroupMode:
     2213    }
     2214    case InColumnGroupMode: {
    21252215        ASSERT(insertionMode() == InColumnGroupMode);
    2126         if (m_tree.insertLeadingWhitespace(token))
     2216        String leadingWhitespace = buffer.takeLeadingWhitespace();
     2217        if (!leadingWhitespace.isEmpty())
     2218            m_tree.insertTextNode(leadingWhitespace);
     2219        if (buffer.isEmpty())
    21272220            return;
    21282221        if (!processColgroupEndTagForInColumnGroup()) {
     
    21302223            return;
    21312224        }
    2132         processCharacter(token);
    2133         break;
     2225        goto ReprocessBuffer;
     2226    }
    21342227    case AfterBodyMode:
    2135     case AfterAfterBodyMode:
     2228    case AfterAfterBodyMode: {
    21362229        ASSERT(insertionMode() == AfterBodyMode || insertionMode() == AfterAfterBodyMode);
    21372230        parseError(token);
    21382231        m_insertionMode = InBodyMode;
    2139         processCharacter(token);
    2140         break;
    2141     case TextMode:
     2232        goto ReprocessBuffer;
     2233        break;
     2234    }
     2235    case TextMode: {
     2236        ASSERT(insertionMode() == TextMode);
     2237        m_tree.insertTextNode(buffer.takeRemaining());
     2238        break;
     2239    }
     2240    case InHeadNoscriptMode: {
     2241        ASSERT(insertionMode() == InHeadNoscriptMode);
     2242        String leadingWhitespace = buffer.takeLeadingWhitespace();
     2243        if (!leadingWhitespace.isEmpty())
     2244            m_tree.insertTextNode(leadingWhitespace);
     2245        if (buffer.isEmpty())
     2246            return;
     2247        processDefaultForInHeadNoscriptMode(token);
     2248        goto ReprocessBuffer;
     2249        break;
     2250    }
     2251    case InFramesetMode:
     2252    case AfterFramesetMode: {
     2253        ASSERT(insertionMode() == InFramesetMode || insertionMode() == AfterFramesetMode || insertionMode() == AfterAfterFramesetMode);
     2254        String leadingWhitespace = buffer.takeRemainingWhitespace();
     2255        if (!leadingWhitespace.isEmpty())
     2256            m_tree.insertTextNode(leadingWhitespace);
     2257        // FIXME: We should generate a parse error if we skipped over any
     2258        // non-whitespace characters.
     2259        break;
     2260    }
     2261    case InSelectInTableMode:
     2262    case InSelectMode: {
     2263        ASSERT(insertionMode() == InSelectMode || insertionMode() == InSelectInTableMode);
     2264        m_tree.insertTextNode(buffer.takeRemaining());
     2265        break;
     2266    }
     2267    case InForeignContentMode: {
    21422268        notImplemented();
    2143         m_tree.insertTextNode(token);
    2144         break;
    2145     case InHeadNoscriptMode:
    2146         ASSERT(insertionMode() == InHeadNoscriptMode);
    2147         if (m_tree.insertLeadingWhitespace(token))
    2148             return;
    2149         processDefaultForInHeadNoscriptMode(token);
    2150         processToken(token);
    2151         break;
    2152     case InFramesetMode:
    2153     case AfterFramesetMode:
    2154         ASSERT(insertionMode() == InFramesetMode || insertionMode() == AfterFramesetMode || insertionMode() == AfterAfterFramesetMode);
    2155         if (m_tree.insertLeadingWhitespace(token))
    2156             return;
    2157         parseError(token);
    2158         // FIXME: We probably need some sort of loop here. We're basically
    2159         // filtering out the non-whitespace characters.
    2160         break;
    2161     case InSelectInTableMode:
    2162     case InSelectMode:
    2163         ASSERT(insertionMode() == InSelectMode || insertionMode() == InSelectInTableMode);
    2164         m_tree.insertTextNode(token);
    2165         break;
    2166     case InForeignContentMode:
    2167         notImplemented();
    2168         break;
    2169     case AfterAfterFramesetMode:
    2170         if (m_tree.insertLeadingWhitespaceWithActiveFormattingElements(token))
    2171             return;
    2172         parseError(token);
    2173         // FIXME: We probably need some sort of loop here. We're basically
    2174         // filtering out the non-whitespace characters.
    2175         break;
     2269        break;
     2270    }
     2271    case AfterAfterFramesetMode: {
     2272        String leadingWhitespace = buffer.takeRemainingWhitespace();
     2273        if (!leadingWhitespace.isEmpty()) {
     2274            m_tree.reconstructTheActiveFormattingElements();
     2275            m_tree.insertTextNode(leadingWhitespace);
     2276        }
     2277        // FIXME: We should generate a parse error if we skipped over any
     2278        // non-whitespace characters.
     2279        break;
     2280    }
    21762281    }
    21772282}
  • trunk/WebCore/html/HTMLTreeBuilder.h

    r62911 r62912  
    158158    void callTheAdoptionAgency(AtomicHTMLToken&);
    159159
    160     bool skipLeadingWhitespace(AtomicHTMLToken&)
    161     {
    162         notImplemented();
    163         return false;
    164     }
    165 
    166160    void closeTheCell();
    167161
Note: See TracChangeset for help on using the changeset viewer.