Home | History | Annotate | Download | only in DumpRenderTree
      1 /*
      2  * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     14  *     its contributors may be used to endorse or promote products derived
     15  *     from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #include "config.h"
     30 #include "LayoutTestController.h"
     31 
     32 #include "WorkQueue.h"
     33 #include "WorkQueueItem.h"
     34 #include <JavaScriptCore/JSContextRef.h>
     35 #include <JavaScriptCore/JSObjectRef.h>
     36 #include <JavaScriptCore/JSRetainPtr.h>
     37 #include <stdio.h>
     38 #include <wtf/Assertions.h>
     39 #include <wtf/MathExtras.h>
     40 #include <wtf/RefPtr.h>
     41 
     42 LayoutTestController::LayoutTestController(const std::string& testPathOrURL, const std::string& expectedPixelHash)
     43     : m_dumpAsPDF(false)
     44     , m_dumpAsText(false)
     45     , m_dumpBackForwardList(false)
     46     , m_dumpChildFrameScrollPositions(false)
     47     , m_dumpChildFramesAsText(false)
     48     , m_dumpDOMAsWebArchive(false)
     49     , m_dumpDatabaseCallbacks(false)
     50     , m_dumpEditingCallbacks(false)
     51     , m_dumpFrameLoadCallbacks(false)
     52     , m_dumpHistoryDelegateCallbacks(false)
     53     , m_dumpResourceLoadCallbacks(false)
     54     , m_dumpResourceResponseMIMETypes(false)
     55     , m_dumpSelectionRect(false)
     56     , m_dumpSourceAsWebArchive(false)
     57     , m_dumpStatusCallbacks(false)
     58     , m_dumpTitleChanges(false)
     59     , m_dumpVisitedLinksCallback(false)
     60     , m_dumpWillCacheResponse(false)
     61     , m_callCloseOnWebViews(true)
     62     , m_canOpenWindows(false)
     63     , m_closeRemainingWindowsWhenComplete(true)
     64     , m_newWindowsCopyBackForwardList(false)
     65     , m_stopProvisionalFrameLoads(false)
     66     , m_testOnscreen(false)
     67     , m_testRepaint(false)
     68     , m_testRepaintSweepHorizontally(false)
     69     , m_waitToDump(false)
     70     , m_willSendRequestReturnsNull(false)
     71     , m_willSendRequestReturnsNullOnRedirect(false)
     72     , m_windowIsKey(true)
     73     , m_alwaysAcceptCookies(false)
     74     , m_globalFlag(false)
     75     , m_isGeolocationPermissionSet(false)
     76     , m_geolocationPermission(false)
     77     , m_testPathOrURL(testPathOrURL)
     78     , m_expectedPixelHash(expectedPixelHash)
     79 {
     80 }
     81 
     82 // Static Functions
     83 
     84 static JSValueRef dumpAsPDFCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
     85 {
     86     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
     87     controller->setDumpAsPDF(true);
     88     return JSValueMakeUndefined(context);
     89 }
     90 
     91 static JSValueRef dumpAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
     92 {
     93     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
     94     controller->setDumpAsText(true);
     95     return JSValueMakeUndefined(context);
     96 }
     97 
     98 static JSValueRef dumpBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
     99 {
    100     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    101     controller->setDumpBackForwardList(true);
    102     return JSValueMakeUndefined(context);
    103 }
    104 
    105 static JSValueRef dumpChildFramesAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    106 {
    107     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    108     controller->setDumpChildFramesAsText(true);
    109     return JSValueMakeUndefined(context);
    110 }
    111 
    112 static JSValueRef dumpChildFrameScrollPositionsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    113 {
    114     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    115     controller->setDumpChildFrameScrollPositions(true);
    116     return JSValueMakeUndefined(context);
    117 }
    118 
    119 static JSValueRef dumpDatabaseCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    120 {
    121     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    122     controller->setDumpDatabaseCallbacks(true);
    123     return JSValueMakeUndefined(context);
    124 }
    125 
    126 static JSValueRef dumpDOMAsWebArchiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    127 {
    128     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    129     controller->setDumpDOMAsWebArchive(true);
    130     return JSValueMakeUndefined(context);
    131 }
    132 
    133 static JSValueRef dumpEditingCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    134 {
    135     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    136     controller->setDumpEditingCallbacks(true);
    137     return JSValueMakeUndefined(context);
    138 }
    139 
    140 static JSValueRef dumpFrameLoadCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    141 {
    142     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    143     controller->setDumpFrameLoadCallbacks(true);
    144     return JSValueMakeUndefined(context);
    145 }
    146 
    147 static JSValueRef dumpResourceLoadCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    148 {
    149     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    150     controller->setDumpResourceLoadCallbacks(true);
    151     return JSValueMakeUndefined(context);
    152 }
    153 
    154 static JSValueRef dumpResourceResponseMIMETypesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    155 {
    156     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    157     controller->setDumpResourceResponseMIMETypes(true);
    158     return JSValueMakeUndefined(context);
    159 }
    160 
    161 static JSValueRef dumpSelectionRectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    162 {
    163     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    164     controller->setDumpSelectionRect(true);
    165     return JSValueMakeUndefined(context);
    166 }
    167 
    168 static JSValueRef dumpSourceAsWebArchiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    169 {
    170     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    171     controller->setDumpSourceAsWebArchive(true);
    172     return JSValueMakeUndefined(context);
    173 }
    174 
    175 static JSValueRef dumpStatusCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    176 {
    177     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    178     controller->setDumpStatusCallbacks(true);
    179     return JSValueMakeUndefined(context);
    180 }
    181 
    182 static JSValueRef dumpTitleChangesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    183 {
    184     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    185     controller->setDumpTitleChanges(true);
    186     return JSValueMakeUndefined(context);
    187 }
    188 
    189 static JSValueRef dumpWillCacheResponseCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    190 {
    191     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    192     controller->setDumpWillCacheResponse(true);
    193     return JSValueMakeUndefined(context);
    194 }
    195 
    196 static JSValueRef pathToLocalResourceCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    197 {
    198     if (argumentCount < 1)
    199         return JSValueMakeUndefined(context);
    200 
    201     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    202     JSRetainPtr<JSStringRef> localPath(Adopt, JSValueToStringCopy(context, arguments[0], exception));
    203     ASSERT(!*exception);
    204 
    205     JSRetainPtr<JSStringRef> convertedPath(Adopt, controller->pathToLocalResource(context, localPath.get()));
    206     if (!convertedPath)
    207         return JSValueMakeUndefined(context);
    208 
    209     return JSValueMakeString(context, convertedPath.get());
    210 }
    211 
    212 static JSValueRef removeAllVisitedLinksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    213 {
    214     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    215     controller->setDumpVisitedLinksCallback(true);
    216     controller->removeAllVisitedLinks();
    217     return JSValueMakeUndefined(context);
    218 }
    219 
    220 static JSValueRef repaintSweepHorizontallyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    221 {
    222     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    223     controller->setTestRepaintSweepHorizontally(true);
    224     return JSValueMakeUndefined(context);
    225 }
    226 
    227 static JSValueRef setCallCloseOnWebViewsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    228 {
    229     if (argumentCount < 1)
    230         return JSValueMakeUndefined(context);
    231 
    232     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    233     controller->setCallCloseOnWebViews(JSValueToBoolean(context, arguments[0]));
    234     return JSValueMakeUndefined(context);
    235 }
    236 
    237 static JSValueRef setCanOpenWindowsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    238 {
    239     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    240     controller->setCanOpenWindows(true);
    241     return JSValueMakeUndefined(context);
    242 }
    243 
    244 static JSValueRef setCloseRemainingWindowsWhenCompleteCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    245 {
    246     if (argumentCount < 1)
    247         return JSValueMakeUndefined(context);
    248 
    249     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    250     controller->setCloseRemainingWindowsWhenComplete(JSValueToBoolean(context, arguments[0]));
    251     return JSValueMakeUndefined(context);
    252 }
    253 
    254 static JSValueRef testOnscreenCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    255 {
    256     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    257     controller->setTestOnscreen(true);
    258     return JSValueMakeUndefined(context);
    259 }
    260 
    261 static JSValueRef testRepaintCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    262 {
    263     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    264     controller->setTestRepaint(true);
    265     return JSValueMakeUndefined(context);
    266 }
    267 
    268 static JSValueRef addDisallowedURLCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    269 {
    270     // Has mac implementation
    271     if (argumentCount < 1)
    272         return JSValueMakeUndefined(context);
    273 
    274     JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
    275     ASSERT(!*exception);
    276 
    277     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    278     controller->addDisallowedURL(url.get());
    279 
    280     return JSValueMakeUndefined(context);
    281 }
    282 
    283 static JSValueRef clearAllDatabasesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    284 {
    285     // Has mac & windows implementation
    286     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    287     controller->clearAllDatabases();
    288 
    289     return JSValueMakeUndefined(context);
    290 }
    291 
    292 static JSValueRef clearBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    293 {
    294     // Has mac & windows implementation
    295     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    296     controller->clearBackForwardList();
    297 
    298     return JSValueMakeUndefined(context);
    299 }
    300 
    301 static JSValueRef clearPersistentUserStyleSheetCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    302 {
    303     // Has mac & windows implementation
    304     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    305     controller->clearPersistentUserStyleSheet();
    306 
    307     return JSValueMakeUndefined(context);
    308 }
    309 
    310 static JSValueRef decodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    311 {
    312     // Has mac implementation
    313     if (argumentCount < 1)
    314         return JSValueMakeUndefined(context);
    315 
    316     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
    317     ASSERT(!*exception);
    318 
    319     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    320     JSRetainPtr<JSStringRef> decodedHostName(Adopt, controller->copyDecodedHostName(name.get()));
    321     return JSValueMakeString(context, decodedHostName.get());
    322 }
    323 
    324 static JSValueRef disableImageLoadingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    325 {
    326     // Has mac implementation, needs windows implementation
    327     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    328     controller->disableImageLoading();
    329 
    330     return JSValueMakeUndefined(context);
    331 }
    332 
    333 static JSValueRef dispatchPendingLoadRequestsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    334 {
    335     // Has mac implementation, needs windows implementation
    336     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    337     controller->dispatchPendingLoadRequests();
    338 
    339     return JSValueMakeUndefined(context);
    340 }
    341 
    342 static JSValueRef displayCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    343 {
    344     // Has mac & windows implementation
    345     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    346     controller->display();
    347 
    348     return JSValueMakeUndefined(context);
    349 }
    350 
    351 static JSValueRef encodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    352 {
    353     // Has mac implementation
    354     if (argumentCount < 1)
    355         return JSValueMakeUndefined(context);
    356 
    357     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
    358     ASSERT(!*exception);
    359 
    360     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    361     JSRetainPtr<JSStringRef> encodedHostName(Adopt, controller->copyEncodedHostName(name.get()));
    362     return JSValueMakeString(context, encodedHostName.get());
    363 }
    364 
    365 static JSValueRef execCommandCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    366 {
    367     // Has Mac & Windows implementations.
    368     if (argumentCount < 1)
    369         return JSValueMakeUndefined(context);
    370 
    371     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
    372     ASSERT(!*exception);
    373 
    374     // Ignoring the second parameter (userInterface), as this command emulates a manual action.
    375 
    376     JSRetainPtr<JSStringRef> value;
    377     if (argumentCount >= 3) {
    378         value.adopt(JSValueToStringCopy(context, arguments[2], exception));
    379         ASSERT(!*exception);
    380     } else
    381         value.adopt(JSStringCreateWithUTF8CString(""));
    382 
    383 
    384     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    385     controller->execCommand(name.get(), value.get());
    386 
    387     return JSValueMakeUndefined(context);
    388 }
    389 
    390 static JSValueRef counterValueForElementByIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    391 {
    392     if (argumentCount < 1)
    393         return JSValueMakeUndefined(context);
    394 
    395     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[0], exception));
    396     if (*exception)
    397         return JSValueMakeUndefined(context);
    398 
    399     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    400     JSRetainPtr<JSStringRef> counterValue(controller->counterValueForElementById(elementId.get()));
    401     if (!counterValue.get())
    402         return JSValueMakeUndefined(context);
    403     return JSValueMakeString(context, counterValue.get());
    404 }
    405 
    406 static JSValueRef grantDesktopNotificationPermissionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    407 {
    408     // Has Windows implementation
    409     if (argumentCount < 1)
    410         return JSValueMakeUndefined(context);
    411 
    412     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    413 
    414     controller->grantDesktopNotificationPermission(JSValueToStringCopy(context, arguments[0], NULL));
    415 
    416     return JSValueMakeUndefined(context);
    417 }
    418 
    419 static JSValueRef isCommandEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    420 {
    421     // Has Mac implementation.
    422 
    423     if (argumentCount < 1)
    424         return JSValueMakeUndefined(context);
    425 
    426     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
    427     ASSERT(!*exception);
    428 
    429     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    430 
    431     return JSValueMakeBoolean(context, controller->isCommandEnabled(name.get()));
    432 }
    433 
    434 static JSValueRef overridePreferenceCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    435 {
    436     if (argumentCount < 2)
    437         return JSValueMakeUndefined(context);
    438 
    439     JSRetainPtr<JSStringRef> key(Adopt, JSValueToStringCopy(context, arguments[0], exception));
    440     ASSERT(!*exception);
    441     JSRetainPtr<JSStringRef> value(Adopt, JSValueToStringCopy(context, arguments[1], exception));
    442     ASSERT(!*exception);
    443 
    444     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    445     controller->overridePreference(key.get(), value.get());
    446 
    447     return JSValueMakeUndefined(context);
    448 }
    449 
    450 static JSValueRef keepWebHistoryCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    451 {
    452     // Has mac implementation
    453     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    454     controller->keepWebHistory();
    455 
    456     return JSValueMakeUndefined(context);
    457 }
    458 
    459 static JSValueRef notifyDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    460 {
    461     // Has mac & windows implementation
    462     // May be able to be made platform independant by using shared WorkQueue
    463     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    464     controller->notifyDone();
    465     return JSValueMakeUndefined(context);
    466 }
    467 
    468 static bool parsePageParameters(JSContextRef context, int argumentCount, const JSValueRef* arguments, JSValueRef* exception, float& pageWidthInPixels, float& pageHeightInPixels)
    469 {
    470     // FIXME: These values should sync with maxViewWidth/Height in
    471     //        DumpRenderTree.mm. Factor these values out to somewhere.
    472     pageWidthInPixels = 800;
    473     pageHeightInPixels = 600;
    474     switch (argumentCount) {
    475     case 2:
    476         pageWidthInPixels = static_cast<float>(JSValueToNumber(context, arguments[0], exception));
    477         if (*exception)
    478             return false;
    479         pageHeightInPixels = static_cast<float>(JSValueToNumber(context, arguments[1], exception));
    480         if (*exception)
    481             return false;
    482     case 0: // Fall through.
    483         break;
    484     default:
    485         return false;
    486     }
    487     return true;
    488 }
    489 
    490 static JSValueRef pageNumberForElementByIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    491 {
    492     float pageWidthInPixels = 0;
    493     float pageHeightInPixels = 0;
    494     if (!parsePageParameters(context, argumentCount - 1, arguments + 1, exception, pageWidthInPixels, pageHeightInPixels))
    495         return JSValueMakeUndefined(context);
    496 
    497     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[0], exception));
    498     if (*exception)
    499         return JSValueMakeUndefined(context);
    500 
    501     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    502     int pageNumber = controller->pageNumberForElementById(elementId.get(), pageWidthInPixels, pageHeightInPixels);
    503     return JSValueMakeNumber(context, pageNumber);
    504 }
    505 
    506 static JSValueRef numberOfPagesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    507 {
    508     float pageWidthInPixels = 0;
    509     float pageHeightInPixels = 0;
    510     if (!parsePageParameters(context, argumentCount, arguments, exception, pageWidthInPixels, pageHeightInPixels))
    511         return JSValueMakeUndefined(context);
    512 
    513     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    514     return JSValueMakeNumber(context, controller->numberOfPages(pageWidthInPixels, pageHeightInPixels));
    515 }
    516 
    517 static JSValueRef queueBackNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    518 {
    519     // Has mac & windows implementation
    520     // May be able to be made platform independant by using shared WorkQueue
    521     if (argumentCount < 1)
    522         return JSValueMakeUndefined(context);
    523 
    524     double howFarBackDouble = JSValueToNumber(context, arguments[0], exception);
    525     ASSERT(!*exception);
    526 
    527     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    528     controller->queueBackNavigation(static_cast<int>(howFarBackDouble));
    529 
    530     return JSValueMakeUndefined(context);
    531 }
    532 
    533 static JSValueRef queueForwardNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    534 {
    535     // Has mac & windows implementation
    536     // May be able to be made platform independant by using shared WorkQueue
    537     if (argumentCount < 1)
    538         return JSValueMakeUndefined(context);
    539 
    540     double howFarForwardDouble = JSValueToNumber(context, arguments[0], exception);
    541     ASSERT(!*exception);
    542 
    543     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    544     controller->queueForwardNavigation(static_cast<int>(howFarForwardDouble));
    545 
    546     return JSValueMakeUndefined(context);
    547 }
    548 
    549 static JSValueRef queueLoadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    550 {
    551     // Has mac & windows implementation
    552     // May be able to be made platform independant by using shared WorkQueue
    553     if (argumentCount < 1)
    554         return JSValueMakeUndefined(context);
    555 
    556     JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
    557     ASSERT(!*exception);
    558 
    559     JSRetainPtr<JSStringRef> target;
    560     if (argumentCount >= 2) {
    561         target.adopt(JSValueToStringCopy(context, arguments[1], exception));
    562         ASSERT(!*exception);
    563     } else
    564         target.adopt(JSStringCreateWithUTF8CString(""));
    565 
    566     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    567     controller->queueLoad(url.get(), target.get());
    568 
    569     return JSValueMakeUndefined(context);
    570 }
    571 
    572 static JSValueRef queueReloadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    573 {
    574     // Has mac & windows implementation
    575     // May be able to be made platform independant by using shared WorkQueue
    576 
    577     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    578     controller->queueReload();
    579 
    580     return JSValueMakeUndefined(context);
    581 }
    582 
    583 static JSValueRef queueLoadingScriptCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    584 {
    585     // Has mac & windows implementation
    586     // May be able to be made platform independant by using shared WorkQueue
    587     if (argumentCount < 1)
    588         return JSValueMakeUndefined(context);
    589 
    590     JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[0], exception));
    591     ASSERT(!*exception);
    592 
    593     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    594     controller->queueLoadingScript(script.get());
    595 
    596     return JSValueMakeUndefined(context);
    597 }
    598 
    599 static JSValueRef queueNonLoadingScriptCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    600 {
    601     // Has mac & windows implementation
    602     // May be able to be made platform independant by using shared WorkQueue
    603     if (argumentCount < 1)
    604         return JSValueMakeUndefined(context);
    605 
    606     JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[0], exception));
    607     ASSERT(!*exception);
    608 
    609     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    610     controller->queueNonLoadingScript(script.get());
    611 
    612     return JSValueMakeUndefined(context);
    613 }
    614 
    615 static JSValueRef setAcceptsEditingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    616 {
    617     // Has mac & windows implementation
    618     if (argumentCount < 1)
    619         return JSValueMakeUndefined(context);
    620 
    621     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    622     controller->setAcceptsEditing(JSValueToBoolean(context, arguments[0]));
    623 
    624     return JSValueMakeUndefined(context);
    625 }
    626 
    627 static JSValueRef setAlwaysAcceptCookiesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    628 {
    629     // Has mac & windows implementation
    630     if (argumentCount < 1)
    631         return JSValueMakeUndefined(context);
    632 
    633     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    634     controller->setAlwaysAcceptCookies(JSValueToBoolean(context, arguments[0]));
    635 
    636     return JSValueMakeUndefined(context);
    637 }
    638 
    639 static JSValueRef setAppCacheMaximumSizeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    640 {
    641     // Has mac implementation
    642     if (argumentCount < 1)
    643         return JSValueMakeUndefined(context);
    644 
    645     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    646 
    647     double size = JSValueToNumber(context, arguments[0], NULL);
    648     if (!isnan(size))
    649         controller->setAppCacheMaximumSize(static_cast<unsigned long long>(size));
    650 
    651     return JSValueMakeUndefined(context);
    652 
    653 }
    654 
    655 static JSValueRef setAuthenticationPasswordCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    656 {
    657     // Has mac & windows implementation
    658     if (argumentCount < 1)
    659         return JSValueMakeUndefined(context);
    660 
    661     JSRetainPtr<JSStringRef> password(Adopt, JSValueToStringCopy(context, arguments[0], exception));
    662     ASSERT(!*exception);
    663 
    664     size_t maxLength = JSStringGetMaximumUTF8CStringSize(password.get());
    665     char* passwordBuffer = new char[maxLength + 1];
    666     JSStringGetUTF8CString(password.get(), passwordBuffer, maxLength + 1);
    667 
    668     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    669     controller->setAuthenticationPassword(passwordBuffer);
    670     delete[] passwordBuffer;
    671 
    672     return JSValueMakeUndefined(context);
    673 }
    674 
    675 static JSValueRef setAuthenticationUsernameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    676 {
    677     // Has mac & windows implementation
    678     if (argumentCount < 1)
    679         return JSValueMakeUndefined(context);
    680 
    681     JSRetainPtr<JSStringRef> username(Adopt, JSValueToStringCopy(context, arguments[0], exception));
    682     ASSERT(!*exception);
    683 
    684     size_t maxLength = JSStringGetMaximumUTF8CStringSize(username.get());
    685     char* usernameBuffer = new char[maxLength + 1];
    686     JSStringGetUTF8CString(username.get(), usernameBuffer, maxLength + 1);
    687 
    688     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    689     controller->setAuthenticationUsername(usernameBuffer);
    690     delete[] usernameBuffer;
    691 
    692     return JSValueMakeUndefined(context);
    693 }
    694 
    695 static JSValueRef setAuthorAndUserStylesEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    696 {
    697     // Has mac & windows implementation
    698     if (argumentCount < 1)
    699         return JSValueMakeUndefined(context);
    700 
    701     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    702     controller->setAuthorAndUserStylesEnabled(JSValueToBoolean(context, arguments[0]));
    703 
    704     return JSValueMakeUndefined(context);
    705 }
    706 
    707 static JSValueRef setCacheModelCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    708 {
    709     // Has Mac implementation.
    710     if (argumentCount < 1)
    711         return JSValueMakeUndefined(context);
    712 
    713     int cacheModel = JSValueToNumber(context, arguments[0], exception);
    714     ASSERT(!*exception);
    715 
    716     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    717     controller->setCacheModel(cacheModel);
    718 
    719     return JSValueMakeUndefined(context);
    720 }
    721 
    722 static JSValueRef setCustomPolicyDelegateCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    723 {
    724     // Has mac implementation
    725     if (argumentCount < 1)
    726         return JSValueMakeUndefined(context);
    727 
    728     bool permissive = false;
    729     if (argumentCount >= 2)
    730         permissive = JSValueToBoolean(context, arguments[1]);
    731 
    732     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    733     controller->setCustomPolicyDelegate(JSValueToBoolean(context, arguments[0]), permissive);
    734 
    735     return JSValueMakeUndefined(context);
    736 }
    737 
    738 static JSValueRef setDatabaseQuotaCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    739 {
    740     // Has mac implementation
    741     if (argumentCount < 1)
    742         return JSValueMakeUndefined(context);
    743 
    744     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    745 
    746     double quota = JSValueToNumber(context, arguments[0], NULL);
    747     if (!isnan(quota))
    748         controller->setDatabaseQuota(static_cast<unsigned long long>(quota));
    749 
    750     return JSValueMakeUndefined(context);
    751 }
    752 
    753 static JSValueRef setDomainRelaxationForbiddenForURLSchemeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    754 {
    755     // Has Mac and Windows implementation
    756     if (argumentCount < 2)
    757         return JSValueMakeUndefined(context);
    758 
    759     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    760 
    761     bool forbidden = JSValueToBoolean(context, arguments[0]);
    762     JSRetainPtr<JSStringRef> scheme(Adopt, JSValueToStringCopy(context, arguments[1], 0));
    763     controller->setDomainRelaxationForbiddenForURLScheme(forbidden, scheme.get());
    764 
    765     return JSValueMakeUndefined(context);
    766 }
    767 
    768 static JSValueRef setMockGeolocationPositionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    769 {
    770     if (argumentCount < 3)
    771         return JSValueMakeUndefined(context);
    772 
    773     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    774     controller->setMockGeolocationPosition(JSValueToNumber(context, arguments[0], NULL),  // latitude
    775                                            JSValueToNumber(context, arguments[1], NULL),  // longitude
    776                                            JSValueToNumber(context, arguments[2], NULL));  // accuracy
    777 
    778     return JSValueMakeUndefined(context);
    779 }
    780 
    781 static JSValueRef setMockGeolocationErrorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    782 {
    783     if (argumentCount < 2)
    784         return JSValueMakeUndefined(context);
    785 
    786     int code = JSValueToNumber(context, arguments[0], NULL);
    787     JSRetainPtr<JSStringRef> message(Adopt, JSValueToStringCopy(context, arguments[1], exception));
    788     ASSERT(!*exception);
    789 
    790     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    791     controller->setMockGeolocationError(code, message.get());
    792 
    793     return JSValueMakeUndefined(context);
    794 }
    795 
    796 static JSValueRef setNewWindowsCopyBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    797 {
    798     // Has mac implementation
    799     if (argumentCount < 1)
    800         return JSValueMakeUndefined(context);
    801 
    802     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    803     controller->setNewWindowsCopyBackForwardList(JSValueToBoolean(context, arguments[0]));
    804 
    805     return JSValueMakeUndefined(context);
    806 }
    807 
    808 static JSValueRef setGeolocationPermissionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    809 {
    810     // Has mac implementation
    811     if (argumentCount < 1)
    812         return JSValueMakeUndefined(context);
    813 
    814     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    815     controller->setGeolocationPermission(JSValueToBoolean(context, arguments[0]));
    816 
    817     return JSValueMakeUndefined(context);
    818 }
    819 
    820 static JSValueRef setHandlesAuthenticationChallengesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    821 {
    822     // Has mac & windows implementation
    823     if (argumentCount < 1)
    824         return JSValueMakeUndefined(context);
    825 
    826     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    827     controller->setHandlesAuthenticationChallenges(JSValueToBoolean(context, arguments[0]));
    828 
    829     return JSValueMakeUndefined(context);
    830 }
    831 
    832 static JSValueRef setPOSIXLocaleCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    833 {
    834     if (argumentCount < 1)
    835         return JSValueMakeUndefined(context);
    836 
    837     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    838     JSRetainPtr<JSStringRef> locale(Adopt, JSValueToStringCopy(context, arguments[0], exception));
    839     ASSERT(!*exception);
    840     controller->setPOSIXLocale(locale.get());
    841 
    842     return JSValueMakeUndefined(context);
    843 }
    844 
    845 static JSValueRef setIconDatabaseEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    846 {
    847     // Has mac & windows implementation
    848     if (argumentCount < 1)
    849         return JSValueMakeUndefined(context);
    850 
    851     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    852     controller->setIconDatabaseEnabled(JSValueToBoolean(context, arguments[0]));
    853 
    854     return JSValueMakeUndefined(context);
    855 }
    856 
    857 static JSValueRef setJavaScriptProfilingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    858 {
    859     if (argumentCount < 1)
    860         return JSValueMakeUndefined(context);
    861 
    862     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    863     controller->setJavaScriptProfilingEnabled(JSValueToBoolean(context, arguments[0]));
    864 
    865     return JSValueMakeUndefined(context);
    866 }
    867 
    868 static JSValueRef setMainFrameIsFirstResponderCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    869 {
    870     // Has mac implementation
    871     if (argumentCount < 1)
    872         return JSValueMakeUndefined(context);
    873 
    874     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    875     controller->setMainFrameIsFirstResponder(JSValueToBoolean(context, arguments[0]));
    876 
    877     return JSValueMakeUndefined(context);
    878 }
    879 
    880 static JSValueRef setPersistentUserStyleSheetLocationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    881 {
    882     // Has mac implementation
    883     if (argumentCount < 1)
    884         return JSValueMakeUndefined(context);
    885 
    886     JSRetainPtr<JSStringRef> path(Adopt, JSValueToStringCopy(context, arguments[0], exception));
    887     ASSERT(!*exception);
    888 
    889     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    890     controller->setPersistentUserStyleSheetLocation(path.get());
    891 
    892     return JSValueMakeUndefined(context);
    893 }
    894 
    895 static JSValueRef setPrivateBrowsingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    896 {
    897     // Has mac & windows implementation
    898     if (argumentCount < 1)
    899         return JSValueMakeUndefined(context);
    900 
    901     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    902     controller->setPrivateBrowsingEnabled(JSValueToBoolean(context, arguments[0]));
    903 
    904     return JSValueMakeUndefined(context);
    905 }
    906 
    907 static JSValueRef setXSSAuditorEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    908 {
    909     // Has mac & windows implementation
    910     if (argumentCount < 1)
    911         return JSValueMakeUndefined(context);
    912 
    913     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    914     controller->setXSSAuditorEnabled(JSValueToBoolean(context, arguments[0]));
    915 
    916     return JSValueMakeUndefined(context);
    917 }
    918 
    919 static JSValueRef setFrameSetFlatteningEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    920 {
    921     // Has mac & windows implementation
    922     if (argumentCount < 1)
    923         return JSValueMakeUndefined(context);
    924 
    925     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    926     controller->setFrameSetFlatteningEnabled(JSValueToBoolean(context, arguments[0]));
    927 
    928     return JSValueMakeUndefined(context);
    929 }
    930 
    931 static JSValueRef setAllowUniversalAccessFromFileURLsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    932 {
    933     // Has mac & windows implementation
    934     if (argumentCount < 1)
    935         return JSValueMakeUndefined(context);
    936 
    937     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    938     controller->setAllowUniversalAccessFromFileURLs(JSValueToBoolean(context, arguments[0]));
    939 
    940     return JSValueMakeUndefined(context);
    941 }
    942 
    943 static JSValueRef setTabKeyCyclesThroughElementsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    944 {
    945     // Has mac & windows implementation
    946     if (argumentCount < 1)
    947         return JSValueMakeUndefined(context);
    948 
    949     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    950     controller->setTabKeyCyclesThroughElements(JSValueToBoolean(context, arguments[0]));
    951 
    952     return JSValueMakeUndefined(context);
    953 }
    954 
    955 static JSValueRef setTimelineProfilingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    956 {
    957     if (argumentCount < 1)
    958         return JSValueMakeUndefined(context);
    959 
    960     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    961     controller->setTimelineProfilingEnabled(JSValueToBoolean(context, arguments[0]));
    962     return JSValueMakeUndefined(context);
    963 }
    964 
    965 static JSValueRef setUseDashboardCompatibilityModeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    966 {
    967     // Has mac implementation
    968     if (argumentCount < 1)
    969         return JSValueMakeUndefined(context);
    970 
    971     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    972     controller->setUseDashboardCompatibilityMode(JSValueToBoolean(context, arguments[0]));
    973 
    974     return JSValueMakeUndefined(context);
    975 }
    976 
    977 static JSValueRef setUserStyleSheetEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    978 {
    979     // Has mac implementation
    980     if (argumentCount < 1)
    981         return JSValueMakeUndefined(context);
    982 
    983     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    984     controller->setUserStyleSheetEnabled(JSValueToBoolean(context, arguments[0]));
    985 
    986     return JSValueMakeUndefined(context);
    987 }
    988 
    989 static JSValueRef setUserStyleSheetLocationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    990 {
    991     // Has mac implementation
    992     if (argumentCount < 1)
    993         return JSValueMakeUndefined(context);
    994 
    995     JSRetainPtr<JSStringRef> path(Adopt, JSValueToStringCopy(context, arguments[0], exception));
    996     ASSERT(!*exception);
    997 
    998     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
    999     controller->setUserStyleSheetLocation(path.get());
   1000 
   1001     return JSValueMakeUndefined(context);
   1002 }
   1003 
   1004 static JSValueRef setWillSendRequestReturnsNullCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
   1005 {
   1006     // Has cross-platform implementation
   1007     if (argumentCount < 1)
   1008         return JSValueMakeUndefined(context);
   1009 
   1010     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1011     controller->setWillSendRequestReturnsNull(JSValueToBoolean(context, arguments[0]));
   1012 
   1013     return JSValueMakeUndefined(context);
   1014 }
   1015 
   1016 static JSValueRef setWillSendRequestReturnsNullOnRedirectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
   1017 {
   1018     // Has cross-platform implementation
   1019     if (argumentCount < 1)
   1020         return JSValueMakeUndefined(context);
   1021 
   1022     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1023     controller->setWillSendRequestReturnsNullOnRedirect(JSValueToBoolean(context, arguments[0]));
   1024 
   1025     return JSValueMakeUndefined(context);
   1026 }
   1027 
   1028 static JSValueRef setWindowIsKeyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
   1029 {
   1030     // Has mac implementation
   1031     if (argumentCount < 1)
   1032         return JSValueMakeUndefined(context);
   1033 
   1034     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1035     controller->setWindowIsKey(JSValueToBoolean(context, arguments[0]));
   1036 
   1037     return JSValueMakeUndefined(context);
   1038 }
   1039 
   1040 static JSValueRef waitUntilDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
   1041 {
   1042     // Has mac & windows implementation
   1043     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1044     controller->setWaitToDump(true);
   1045 
   1046     return JSValueMakeUndefined(context);
   1047 }
   1048 
   1049 static JSValueRef windowCountCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
   1050 {
   1051     // Has mac implementation
   1052     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1053     int windows = controller->windowCount();
   1054     return JSValueMakeNumber(context, windows);
   1055 }
   1056 
   1057 static JSValueRef setPopupBlockingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
   1058 {
   1059     // Has mac & windows implementation
   1060     if (argumentCount < 1)
   1061         return JSValueMakeUndefined(context);
   1062 
   1063     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1064     controller->setPopupBlockingEnabled(JSValueToBoolean(context, arguments[0]));
   1065 
   1066     return JSValueMakeUndefined(context);
   1067 }
   1068 
   1069 static JSValueRef setSmartInsertDeleteEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
   1070 {
   1071     if (argumentCount < 1)
   1072         return JSValueMakeUndefined(context);
   1073 
   1074     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1075     controller->setSmartInsertDeleteEnabled(JSValueToBoolean(context, arguments[0]));
   1076     return JSValueMakeUndefined(context);
   1077 }
   1078 
   1079 static JSValueRef setSelectTrailingWhitespaceEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
   1080 {
   1081     if (argumentCount < 1)
   1082         return JSValueMakeUndefined(context);
   1083 
   1084     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1085     controller->setSelectTrailingWhitespaceEnabled(JSValueToBoolean(context, arguments[0]));
   1086     return JSValueMakeUndefined(context);
   1087 }
   1088 
   1089 static JSValueRef setStopProvisionalFrameLoadsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
   1090 {
   1091     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1092     controller->setStopProvisionalFrameLoads(true);
   1093     return JSValueMakeUndefined(context);
   1094 }
   1095 
   1096 static JSValueRef showWebInspectorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
   1097 {
   1098     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1099     controller->showWebInspector();
   1100     return JSValueMakeUndefined(context);
   1101 }
   1102 
   1103 static JSValueRef closeWebInspectorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
   1104 {
   1105     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1106     controller->setTimelineProfilingEnabled(false);
   1107     controller->closeWebInspector();
   1108     return JSValueMakeUndefined(context);
   1109 }
   1110 
   1111 static JSValueRef evaluateInWebInspectorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
   1112 {
   1113     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1114     double callId = JSValueToNumber(context, arguments[0], exception);
   1115     ASSERT(!*exception);
   1116     JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[1], exception));
   1117     ASSERT(!*exception);
   1118 
   1119     controller->evaluateInWebInspector(static_cast<long>(callId), script.get());
   1120     return JSValueMakeUndefined(context);
   1121 }
   1122 
   1123 static JSValueRef evaluateScriptInIsolatedWorldCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
   1124 {
   1125     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1126     double worldID = JSValueToNumber(context, arguments[0], exception);
   1127     ASSERT(!*exception);
   1128     JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[1], exception));
   1129     ASSERT(!*exception);
   1130 
   1131     controller->evaluateScriptInIsolatedWorld(static_cast<unsigned>(worldID), JSContextGetGlobalObject(context), script.get());
   1132     return JSValueMakeUndefined(context);
   1133 }
   1134 
   1135 static JSValueRef elementDoesAutoCompleteForElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
   1136 {
   1137     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1138     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[0], exception));
   1139     ASSERT(!*exception);
   1140 
   1141     bool autoCompletes = controller->elementDoesAutoCompleteForElementWithId(elementId.get());
   1142 
   1143     return JSValueMakeBoolean(context, autoCompletes);
   1144 }
   1145 
   1146 static JSValueRef pauseAnimationAtTimeOnElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
   1147 {
   1148     if (argumentCount != 3)
   1149         return JSValueMakeUndefined(context);
   1150 
   1151     JSRetainPtr<JSStringRef> animationName(Adopt, JSValueToStringCopy(context, arguments[0], exception));
   1152     ASSERT(!*exception);
   1153     double time = JSValueToNumber(context, arguments[1], exception);
   1154     ASSERT(!*exception);
   1155     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[2], exception));
   1156     ASSERT(!*exception);
   1157 
   1158     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1159     return JSValueMakeBoolean(context, controller->pauseAnimationAtTimeOnElementWithId(animationName.get(), time, elementId.get()));
   1160 }
   1161 
   1162 static JSValueRef pauseTransitionAtTimeOnElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
   1163 {
   1164     if (argumentCount != 3)
   1165         return JSValueMakeUndefined(context);
   1166 
   1167     JSRetainPtr<JSStringRef> propertyName(Adopt, JSValueToStringCopy(context, arguments[0], exception));
   1168     ASSERT(!*exception);
   1169     double time = JSValueToNumber(context, arguments[1], exception);
   1170     ASSERT(!*exception);
   1171     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[2], exception));
   1172     ASSERT(!*exception);
   1173 
   1174     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1175     return JSValueMakeBoolean(context, controller->pauseTransitionAtTimeOnElementWithId(propertyName.get(), time, elementId.get()));
   1176 }
   1177 
   1178 static JSValueRef sampleSVGAnimationForElementAtTimeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
   1179 {
   1180     if (argumentCount != 3)
   1181         return JSValueMakeUndefined(context);
   1182 
   1183     JSRetainPtr<JSStringRef> animationId(Adopt, JSValueToStringCopy(context, arguments[0], exception));
   1184     ASSERT(!*exception);
   1185     double time = JSValueToNumber(context, arguments[1], exception);
   1186     ASSERT(!*exception);
   1187     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[2], exception));
   1188     ASSERT(!*exception);
   1189 
   1190     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1191     return JSValueMakeBoolean(context, controller->sampleSVGAnimationForElementAtTime(animationId.get(), time, elementId.get()));
   1192 }
   1193 
   1194 static JSValueRef numberOfActiveAnimationsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
   1195 {
   1196     if (argumentCount != 0)
   1197         return JSValueMakeUndefined(context);
   1198 
   1199     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1200     return JSValueMakeNumber(context, controller->numberOfActiveAnimations());
   1201 }
   1202 
   1203 static JSValueRef waitForPolicyDelegateCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t, const JSValueRef[], JSValueRef*)
   1204 {
   1205     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1206     controller->waitForPolicyDelegate();
   1207     return JSValueMakeUndefined(context);
   1208 }
   1209 
   1210 static JSValueRef whiteListAccessFromOriginCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
   1211 {
   1212     if (argumentCount != 4)
   1213         return JSValueMakeUndefined(context);
   1214 
   1215     JSRetainPtr<JSStringRef> sourceOrigin(Adopt, JSValueToStringCopy(context, arguments[0], exception));
   1216     ASSERT(!*exception);
   1217     JSRetainPtr<JSStringRef> destinationProtocol(Adopt, JSValueToStringCopy(context, arguments[1], exception));
   1218     ASSERT(!*exception);
   1219     JSRetainPtr<JSStringRef> destinationHost(Adopt, JSValueToStringCopy(context, arguments[2], exception));
   1220     ASSERT(!*exception);
   1221     bool allowDestinationSubdomains = JSValueToBoolean(context, arguments[3]);
   1222 
   1223     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1224     controller->whiteListAccessFromOrigin(sourceOrigin.get(), destinationProtocol.get(), destinationHost.get(), allowDestinationSubdomains);
   1225     return JSValueMakeUndefined(context);
   1226 }
   1227 
   1228 static JSValueRef addUserScriptCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
   1229 {
   1230     if (argumentCount != 2)
   1231         return JSValueMakeUndefined(context);
   1232 
   1233     JSRetainPtr<JSStringRef> source(Adopt, JSValueToStringCopy(context, arguments[0], exception));
   1234     ASSERT(!*exception);
   1235     bool runAtStart = JSValueToBoolean(context, arguments[1]);
   1236 
   1237     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1238     controller->addUserScript(source.get(), runAtStart);
   1239     return JSValueMakeUndefined(context);
   1240 }
   1241 
   1242 static JSValueRef addUserStyleSheetCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
   1243 {
   1244     if (argumentCount != 1)
   1245         return JSValueMakeUndefined(context);
   1246 
   1247     JSRetainPtr<JSStringRef> source(Adopt, JSValueToStringCopy(context, arguments[0], exception));
   1248     ASSERT(!*exception);
   1249 
   1250     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1251     controller->addUserStyleSheet(source.get());
   1252     return JSValueMakeUndefined(context);
   1253 }
   1254 
   1255 // Static Values
   1256 
   1257 static JSValueRef getGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
   1258 {
   1259     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1260     return JSValueMakeBoolean(context, controller->globalFlag());
   1261 }
   1262 
   1263 static JSValueRef getWebHistoryItemCountCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
   1264 {
   1265     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1266     return JSValueMakeNumber(context, controller->webHistoryItemCount());
   1267 }
   1268 
   1269 static JSValueRef getWorkerThreadCountCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
   1270 {
   1271     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1272     return JSValueMakeNumber(context, controller->workerThreadCount());
   1273 }
   1274 
   1275 static bool setGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
   1276 {
   1277     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
   1278     controller->setGlobalFlag(JSValueToBoolean(context, value));
   1279     return true;
   1280 }
   1281 
   1282 static void layoutTestControllerObjectFinalize(JSObjectRef object)
   1283 {
   1284     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(object));
   1285     controller->deref();
   1286 }
   1287 
   1288 // Object Creation
   1289 
   1290 void LayoutTestController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
   1291 {
   1292     JSRetainPtr<JSStringRef> layoutTestContollerStr(Adopt, JSStringCreateWithUTF8CString("layoutTestController"));
   1293     ref();
   1294 
   1295     JSClassRef classRef = getJSClass();
   1296     JSValueRef layoutTestContollerObject = JSObjectMake(context, classRef, this);
   1297     JSClassRelease(classRef);
   1298 
   1299     JSObjectSetProperty(context, windowObject, layoutTestContollerStr.get(), layoutTestContollerObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
   1300 }
   1301 
   1302 JSClassRef LayoutTestController::getJSClass()
   1303 {
   1304     static JSStaticValue* staticValues = LayoutTestController::staticValues();
   1305     static JSStaticFunction* staticFunctions = LayoutTestController::staticFunctions();
   1306     static JSClassDefinition classDefinition = {
   1307         0, kJSClassAttributeNone, "LayoutTestController", 0, staticValues, staticFunctions,
   1308         0, layoutTestControllerObjectFinalize, 0, 0, 0, 0, 0, 0, 0, 0, 0
   1309     };
   1310 
   1311     return JSClassCreate(&classDefinition);
   1312 }
   1313 
   1314 JSStaticValue* LayoutTestController::staticValues()
   1315 {
   1316     static JSStaticValue staticValues[] = {
   1317         { "globalFlag", getGlobalFlagCallback, setGlobalFlagCallback, kJSPropertyAttributeNone },
   1318         { "webHistoryItemCount", getWebHistoryItemCountCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1319         { "workerThreadCount", getWorkerThreadCountCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1320         { 0, 0, 0, 0 }
   1321     };
   1322     return staticValues;
   1323 }
   1324 
   1325 JSStaticFunction* LayoutTestController::staticFunctions()
   1326 {
   1327     static JSStaticFunction staticFunctions[] = {
   1328         { "addDisallowedURL", addDisallowedURLCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1329         { "addUserScript", addUserScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1330         { "addUserStyleSheet", addUserStyleSheetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1331         { "clearAllDatabases", clearAllDatabasesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1332         { "clearBackForwardList", clearBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1333         { "clearPersistentUserStyleSheet", clearPersistentUserStyleSheetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1334         { "closeWebInspector", closeWebInspectorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1335         { "decodeHostName", decodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1336         { "disableImageLoading", disableImageLoadingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1337         { "dispatchPendingLoadRequests", dispatchPendingLoadRequestsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1338         { "display", displayCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1339         { "dumpAsText", dumpAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1340         { "dumpBackForwardList", dumpBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1341         { "dumpChildFrameScrollPositions", dumpChildFrameScrollPositionsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1342         { "dumpChildFramesAsText", dumpChildFramesAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1343         { "dumpDOMAsWebArchive", dumpDOMAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1344         { "dumpDatabaseCallbacks", dumpDatabaseCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1345         { "dumpEditingCallbacks", dumpEditingCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1346         { "dumpFrameLoadCallbacks", dumpFrameLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1347         { "dumpResourceLoadCallbacks", dumpResourceLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1348         { "dumpResourceResponseMIMETypes", dumpResourceResponseMIMETypesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1349         { "dumpSelectionRect", dumpSelectionRectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1350         { "dumpSourceAsWebArchive", dumpSourceAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1351         { "dumpStatusCallbacks", dumpStatusCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1352         { "dumpTitleChanges", dumpTitleChangesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1353         { "dumpWillCacheResponse", dumpWillCacheResponseCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1354         { "elementDoesAutoCompleteForElementWithId", elementDoesAutoCompleteForElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1355         { "encodeHostName", encodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1356         { "evaluateInWebInspector", evaluateInWebInspectorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1357         { "evaluateScriptInIsolatedWorld", evaluateScriptInIsolatedWorldCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1358         { "execCommand", execCommandCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1359         { "counterValueForElementById", counterValueForElementByIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1360         { "grantDesktopNotificationPermission", grantDesktopNotificationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1361         { "isCommandEnabled", isCommandEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1362         { "keepWebHistory", keepWebHistoryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1363         { "numberOfPages", numberOfPagesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1364         { "notifyDone", notifyDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1365         { "numberOfActiveAnimations", numberOfActiveAnimationsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1366         { "overridePreference", overridePreferenceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1367         { "pageNumberForElementById", pageNumberForElementByIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1368         { "pathToLocalResource", pathToLocalResourceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1369         { "pauseAnimationAtTimeOnElementWithId", pauseAnimationAtTimeOnElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1370         { "pauseTransitionAtTimeOnElementWithId", pauseTransitionAtTimeOnElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1371         { "sampleSVGAnimationForElementAtTime", sampleSVGAnimationForElementAtTimeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1372         { "printToPDF", dumpAsPDFCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1373         { "queueBackNavigation", queueBackNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1374         { "queueForwardNavigation", queueForwardNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1375         { "queueLoad", queueLoadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1376         { "queueLoadingScript", queueLoadingScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1377         { "queueNonLoadingScript", queueNonLoadingScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1378         { "queueReload", queueReloadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1379         { "removeAllVisitedLinks", removeAllVisitedLinksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1380         { "repaintSweepHorizontally", repaintSweepHorizontallyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1381         { "setAcceptsEditing", setAcceptsEditingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1382         { "setAllowUniversalAccessFromFileURLs", setAllowUniversalAccessFromFileURLsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1383         { "setAlwaysAcceptCookies", setAlwaysAcceptCookiesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1384         { "setAppCacheMaximumSize", setAppCacheMaximumSizeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1385         { "setAuthenticationPassword", setAuthenticationPasswordCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1386         { "setAuthenticationUsername", setAuthenticationUsernameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1387         { "setAuthorAndUserStylesEnabled", setAuthorAndUserStylesEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1388         { "setCallCloseOnWebViews", setCallCloseOnWebViewsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1389         { "setCanOpenWindows", setCanOpenWindowsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1390         { "setCacheModel", setCacheModelCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1391         { "setCloseRemainingWindowsWhenComplete", setCloseRemainingWindowsWhenCompleteCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1392         { "setCustomPolicyDelegate", setCustomPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1393         { "setDatabaseQuota", setDatabaseQuotaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1394         { "setDomainRelaxationForbiddenForURLScheme", setDomainRelaxationForbiddenForURLSchemeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1395         { "setGeolocationPermission", setGeolocationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1396         { "setHandlesAuthenticationChallenges", setHandlesAuthenticationChallengesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1397         { "setPOSIXLocale", setPOSIXLocaleCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1398         { "setIconDatabaseEnabled", setIconDatabaseEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1399         { "setJavaScriptProfilingEnabled", setJavaScriptProfilingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1400         { "setMainFrameIsFirstResponder", setMainFrameIsFirstResponderCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1401         { "setMockGeolocationPosition", setMockGeolocationPositionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1402         { "setMockGeolocationError", setMockGeolocationErrorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1403         { "setNewWindowsCopyBackForwardList", setNewWindowsCopyBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1404         { "setPersistentUserStyleSheetLocation", setPersistentUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1405         { "setPopupBlockingEnabled", setPopupBlockingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1406         { "setPrivateBrowsingEnabled", setPrivateBrowsingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1407         { "setXSSAuditorEnabled", setXSSAuditorEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1408         { "setFrameSetFlatteningEnabled", setFrameSetFlatteningEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1409         { "setSelectTrailingWhitespaceEnabled", setSelectTrailingWhitespaceEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1410         { "setSmartInsertDeleteEnabled", setSmartInsertDeleteEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1411         { "setStopProvisionalFrameLoads", setStopProvisionalFrameLoadsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1412         { "setTabKeyCyclesThroughElements", setTabKeyCyclesThroughElementsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1413         { "setTimelineProfilingEnabled", setTimelineProfilingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1414         { "setUseDashboardCompatibilityMode", setUseDashboardCompatibilityModeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1415         { "setUserStyleSheetEnabled", setUserStyleSheetEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1416         { "setUserStyleSheetLocation", setUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1417         { "setWillSendRequestReturnsNull", setWillSendRequestReturnsNullCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1418         { "setWillSendRequestReturnsNullOnRedirect", setWillSendRequestReturnsNullOnRedirectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1419         { "setWindowIsKey", setWindowIsKeyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1420         { "showWebInspector", showWebInspectorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1421         { "testOnscreen", testOnscreenCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1422         { "testRepaint", testRepaintCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1423         { "waitForPolicyDelegate", waitForPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1424         { "waitUntilDone", waitUntilDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1425         { "windowCount", windowCountCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1426         { "whiteListAccessFromOrigin", whiteListAccessFromOriginCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
   1427         { 0, 0, 0 }
   1428     };
   1429 
   1430     return staticFunctions;
   1431 }
   1432 
   1433 void LayoutTestController::queueBackNavigation(int howFarBack)
   1434 {
   1435     WorkQueue::shared()->queue(new BackItem(howFarBack));
   1436 }
   1437 
   1438 void LayoutTestController::queueForwardNavigation(int howFarForward)
   1439 {
   1440     WorkQueue::shared()->queue(new ForwardItem(howFarForward));
   1441 }
   1442 
   1443 void LayoutTestController::queueLoadingScript(JSStringRef script)
   1444 {
   1445     WorkQueue::shared()->queue(new LoadingScriptItem(script));
   1446 }
   1447 
   1448 void LayoutTestController::queueNonLoadingScript(JSStringRef script)
   1449 {
   1450     WorkQueue::shared()->queue(new NonLoadingScriptItem(script));
   1451 }
   1452 
   1453 void LayoutTestController::queueReload()
   1454 {
   1455     WorkQueue::shared()->queue(new ReloadItem);
   1456 }
   1457 
   1458 void LayoutTestController::grantDesktopNotificationPermission(JSStringRef origin)
   1459 {
   1460     m_desktopNotificationAllowedOrigins.push_back(JSStringRetain(origin));
   1461 }
   1462 
   1463 bool LayoutTestController::checkDesktopNotificationPermission(JSStringRef origin)
   1464 {
   1465     std::vector<JSStringRef>::iterator i;
   1466     for (i = m_desktopNotificationAllowedOrigins.begin();
   1467          i != m_desktopNotificationAllowedOrigins.end();
   1468          ++i) {
   1469         if (JSStringIsEqual(*i, origin))
   1470             return true;
   1471     }
   1472     return false;
   1473 }
   1474 
   1475 void LayoutTestController::waitToDumpWatchdogTimerFired()
   1476 {
   1477     const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
   1478     fprintf(stderr, "%s", message);
   1479     fprintf(stdout, "%s", message);
   1480     notifyDone();
   1481 }
   1482 
   1483 void LayoutTestController::setGeolocationPermission(bool allow)
   1484 {
   1485     m_isGeolocationPermissionSet = true;
   1486     m_geolocationPermission = allow;
   1487 }
   1488 
   1489 void LayoutTestController::setPOSIXLocale(JSStringRef locale)
   1490 {
   1491     char localeBuf[32];
   1492     JSStringGetUTF8CString(locale, localeBuf, sizeof(localeBuf));
   1493     setlocale(LC_ALL, localeBuf);
   1494 }
   1495