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)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