15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2011 Google Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * documentation and/or other materials provided with the distribution. 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * its contributors may be used to endorse or promote products derived 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * from this software without specific prior written permission. 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "IDBFactoryBackendProxy.h" 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 325267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "public/platform/WebIDBDatabase.h" 335267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "public/platform/WebIDBDatabaseError.h" 345267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "public/platform/WebIDBFactory.h" 355267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "public/platform/WebVector.h" 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "IDBDatabaseBackendProxy.h" 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "WebFrameImpl.h" 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "WebIDBCallbacksImpl.h" 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "WebIDBDatabaseCallbacksImpl.h" 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "WebKit.h" 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "WebPermissionClient.h" 4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "WebSecurityOrigin.h" 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "WebViewImpl.h" 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "WebWorkerBase.h" 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "WebWorkerClientImpl.h" 4693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "WorkerAllowMainThreadBridgeBase.h" 4753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/WorkerScriptController.h" 4853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/CrossThreadTask.h" 49591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/dom/DOMError.h" 50591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/dom/ExceptionCode.h" 5153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/ScriptExecutionContext.h" 52591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/workers/WorkerGlobalScope.h" 5353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/workers/WorkerLoaderProxy.h" 5453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/workers/WorkerThread.h" 5553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/indexeddb/IDBDatabaseCallbacks.h" 56e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "weborigin/SecurityOrigin.h" 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace WebCore; 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebKit { 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<IDBFactoryBackendInterface> IDBFactoryBackendProxy::create() 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return adoptRef(new IDBFactoryBackendProxy()); 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)IDBFactoryBackendProxy::IDBFactoryBackendProxy() 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 705267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) m_webIDBFactory = WebKit::Platform::current()->idbFactory(); 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)IDBFactoryBackendProxy::~IDBFactoryBackendProxy() 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const char allowIndexedDBMode[] = "allowIndexedDBMode"; 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)class AllowIndexedDBMainThreadBridge : public WorkerAllowMainThreadBridgeBase { 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 81591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch static PassRefPtr<AllowIndexedDBMainThreadBridge> create(WorkerGlobalScope* workerGlobalScope, WebWorkerBase* webWorkerBase, const String& mode, const String& name) 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 83591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return adoptRef(new AllowIndexedDBMainThreadBridge(workerGlobalScope, webWorkerBase, mode, name)); 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 8793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) class AllowIDBParams : public AllowParams 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 8993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) public: 9093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) AllowIDBParams(const String& mode, const String& name) 9193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) : AllowParams(mode) 9293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) , m_name(name.isolatedCopy()) 9393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) { 9493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 9593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) String m_name; 9693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) }; 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 98591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch AllowIndexedDBMainThreadBridge(WorkerGlobalScope* workerGlobalScope, WebWorkerBase* webWorkerBase, const String& mode, const String& name) 99591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch : WorkerAllowMainThreadBridgeBase(workerGlobalScope, webWorkerBase) 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 10193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) postTaskToMainThread(adoptPtr(new AllowIDBParams(mode, name))); 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) virtual bool allowOnMainThread(WebCommonWorkerClient* commonClient, AllowParams* params) 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 10693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) ASSERT(isMainThread()); 10793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) AllowIDBParams* allowIDBParams = static_cast<AllowIDBParams*>(params); 10893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return commonClient->allowIndexedDB(allowIDBParams->m_name); 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool IDBFactoryBackendProxy::allowIndexedDB(ScriptExecutionContext* context, const String& name, const WebSecurityOrigin& origin, PassRefPtr<IDBCallbacks> callbacks) 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool allowed; 115591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT_WITH_SECURITY_IMPLICATION(context->isDocument() || context->isWorkerGlobalScope()); 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (context->isDocument()) { 117591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch Document* document = toDocument(context); 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame()); 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) WebViewImpl* webView = webFrame->viewImpl(); 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: webView->permissionClient() returns 0 in test_shell and content_shell http://crbug.com/137269 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) allowed = !webView->permissionClient() || webView->permissionClient()->allowIndexedDB(webFrame, name, origin); 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 123591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); 124591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch WebWorkerBase* webWorkerBase = static_cast<WebWorkerBase*>(workerGlobalScope->thread()->workerLoaderProxy().toWebWorkerBase()); 125591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch WorkerRunLoop& runLoop = workerGlobalScope->thread()->runLoop(); 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String mode = allowIndexedDBMode; 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) mode.append(String::number(runLoop.createUniqueId())); 129591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<AllowIndexedDBMainThreadBridge> bridge = AllowIndexedDBMainThreadBridge::create(workerGlobalScope, webWorkerBase, mode, name); 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Either the bridge returns, or the queue gets terminated. 132591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (runLoop.runInMode(workerGlobalScope, mode) == MessageQueueTerminated) { 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bridge->cancel(); 134926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return false; 135926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 136926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) allowed = bridge->result(); 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!allowed) 140591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch callbacks->onError(WebIDBDatabaseError(UnknownError, "The user denied permission to access the database.")); 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return allowed; 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 145591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid IDBFactoryBackendProxy::getDatabaseNames(PassRefPtr<IDBCallbacks> prpCallbacks, const String& databaseIdentifier, ScriptExecutionContext* context) 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<IDBCallbacks> callbacks(prpCallbacks); 14853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) WebSecurityOrigin origin(context->securityOrigin()); 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!allowIndexedDB(context, "Database Listing", origin, callbacks)) 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 152591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_webIDBFactory->getDatabaseNames(new WebIDBCallbacksImpl(callbacks), databaseIdentifier); 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 155591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid IDBFactoryBackendProxy::open(const String& name, int64_t version, int64_t transactionId, PassRefPtr<IDBCallbacks> prpCallbacks, PassRefPtr<IDBDatabaseCallbacks> prpDatabaseCallbacks, const String& databaseIdentifier, ScriptExecutionContext* context) 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<IDBCallbacks> callbacks(prpCallbacks); 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<IDBDatabaseCallbacks> databaseCallbacks(prpDatabaseCallbacks); 15953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) WebSecurityOrigin origin(context->securityOrigin()); 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!allowIndexedDB(context, name, origin, callbacks)) 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 163591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_webIDBFactory->open(name, version, transactionId, new WebIDBCallbacksImpl(callbacks), new WebIDBDatabaseCallbacksImpl(databaseCallbacks), databaseIdentifier); 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 166591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid IDBFactoryBackendProxy::deleteDatabase(const String& name, PassRefPtr<IDBCallbacks> prpCallbacks, const String& databaseIdentifier, ScriptExecutionContext* context) 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<IDBCallbacks> callbacks(prpCallbacks); 16953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) WebSecurityOrigin origin(context->securityOrigin()); 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!allowIndexedDB(context, name, origin, callbacks)) 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 173591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_webIDBFactory->deleteDatabase(name, new WebIDBCallbacksImpl(callbacks), databaseIdentifier); 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebKit 177