Home | History | Annotate | Download | only in WebView
      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)dealloc
     79 {
     80     ASSERT(allWorlds().contains(_private->world.get()));
     81     allWorlds().remove(_private->world.get());
     82 
     83     [_private release];
     84     _private = nil;
     85     [super dealloc];
     86 }
     87 
     88 + (WebScriptWorld *)standardWorld
     89 {
     90     static WebScriptWorld *world = [[WebScriptWorld alloc] initWithWorld:mainThreadNormalWorld()];
     91     return world;
     92 }
     93 
     94 + (WebScriptWorld *)world
     95 {
     96     return [[[self alloc] init] autorelease];
     97 }
     98 
     99 + (WebScriptWorld *)scriptWorldForGlobalContext:(JSGlobalContextRef)context
    100 {
    101     return [self findOrCreateWorld:currentWorld(toJS(context))];
    102 }
    103 
    104 @end
    105 
    106 @implementation WebScriptWorld (WebInternal)
    107 
    108 DOMWrapperWorld* core(WebScriptWorld *world)
    109 {
    110     return world ? world->_private->world.get() : 0;
    111 }
    112 
    113 + (WebScriptWorld *)findOrCreateWorld:(DOMWrapperWorld*) world
    114 {
    115     ASSERT_ARG(world, world);
    116 
    117     if (world == mainThreadNormalWorld())
    118         return [self standardWorld];
    119 
    120     if (WebScriptWorld *existingWorld = allWorlds().get(world))
    121         return existingWorld;
    122 
    123     return [[[self alloc] initWithWorld:world] autorelease];
    124 }
    125 
    126 @end
    127