1 /* 2 * Copyright (C) 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 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 */ 24 25 #import "WebScriptWorld.h" 26 27 #import "WebScriptWorldInternal.h" 28 #import <WebCore/JSDOMBinding.h> 29 #import <WebCore/ScriptController.h> 30 #import <JavaScriptCore/APICast.h> 31 32 #import <wtf/RefPtr.h> 33 34 using namespace WebCore; 35 36 @interface WebScriptWorldPrivate : NSObject { 37 @public 38 RefPtr<DOMWrapperWorld> world; 39 } 40 @end 41 42 @implementation WebScriptWorldPrivate 43 @end 44 45 typedef HashMap<DOMWrapperWorld*, WebScriptWorld*> WorldMap; 46 static WorldMap& allWorlds() 47 { 48 static WorldMap& map = *new WorldMap; 49 return map; 50 } 51 52 @implementation WebScriptWorld 53 54 - (id)initWithWorld:(PassRefPtr<DOMWrapperWorld>)world 55 { 56 ASSERT_ARG(world, world); 57 if (!world) 58 return nil; 59 60 self = [super init]; 61 if (!self) 62 return nil; 63 64 _private = [[WebScriptWorldPrivate alloc] init]; 65 _private->world = world; 66 67 ASSERT_ARG(world, !allWorlds().contains(_private->world.get())); 68 allWorlds().add(_private->world.get(), self); 69 70 return self; 71 } 72 73 - (id)init 74 { 75 return [self initWithWorld:ScriptController::createWorld()]; 76 } 77 78 - (void)unregisterWorld 79 { 80 _private->world->clearWrappers(); 81 } 82 83 - (void)dealloc 84 { 85 ASSERT(allWorlds().contains(_private->world.get())); 86 allWorlds().remove(_private->world.get()); 87 88 [_private release]; 89 _private = nil; 90 [super dealloc]; 91 } 92 93 + (WebScriptWorld *)standardWorld 94 { 95 static WebScriptWorld *world = [[WebScriptWorld alloc] initWithWorld:mainThreadNormalWorld()]; 96 return world; 97 } 98 99 + (WebScriptWorld *)world 100 { 101 return [[[self alloc] init] autorelease]; 102 } 103 104 + (WebScriptWorld *)scriptWorldForGlobalContext:(JSGlobalContextRef)context 105 { 106 return [self findOrCreateWorld:currentWorld(toJS(context))]; 107 } 108 109 @end 110 111 @implementation WebScriptWorld (WebInternal) 112 113 DOMWrapperWorld* core(WebScriptWorld *world) 114 { 115 return world ? world->_private->world.get() : 0; 116 } 117 118 + (WebScriptWorld *)findOrCreateWorld:(DOMWrapperWorld*) world 119 { 120 ASSERT_ARG(world, world); 121 122 if (world == mainThreadNormalWorld()) 123 return [self standardWorld]; 124 125 if (WebScriptWorld *existingWorld = allWorlds().get(world)) 126 return existingWorld; 127 128 return [[[self alloc] initWithWorld:world] autorelease]; 129 } 130 131 @end 132