webkit开发之JS扩展篇

http://blog.csdn.net/lqrensn/article/details/8109498

我们在做webkit的JS扩展时总会用到#include <JavaScriptCore/JavaScript.h>
在做webkit javascript扩展时,一般我们按以下流程做:
首先创建一个类
JSClassRef JSClassCreate(const JSClassDefinition* definition);
然后创建一个对象或者创建多个对象
JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data);
JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
接下来就是对对象的相关操作

a.可以设置或获取对象的prototype
JSValueRef JSObjectGetPrototype(JSContextRef ctx, JSObjectRef object);
void JSObjectSetPrototype(JSContextRef ctx, JSObjectRef object, JSValueRef value);
b.从一个对象中设置或获取属性
JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception);
void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception);

 

举一个简单的例子:
我们在页面加载的时候添加如下代码:
{
......
  JSContextRef globalCtx = webFrame->globalContext();
  JSObjectRef globalObj  = JSContextGetGlobalObject(globalCtx);
  JSClassRef cls = JSClassCreate(&testObjClassDefinition);
  JSObjectRef jsObj = JSObjectMake(globalCtx, cls, NULL); 
  JSStringRef name  = JSStringCreateWithUTF8CString("testObj_0");
  JSObjectSetProperty(globalCtx, globalObj, name, jsObj, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete, 0);
......
}
testObj_0就是我们要在Js脚本中要使用的对象。以上代码中只有testObjClassDefinition需要定义,如下:
JSClassDefinition testObjClassDefinition =
{
 0,      // version
 kJSClassAttributeNone, // attributes
 "testObj",  // className
 0,      // parentClass
 0,      // staticValues
 testObjFunc, // staticFunctions
 0,      // Initialize
 0,      // Finalize
 0,      // has Property
 0,      // get Property
 0,      // set Property
 0,      // deleteProperty
 0,      // getPropertyNames
 0,      // callAsFunction
 0,      // hasInstance
 0,      // callAsConstructor
 0       // convertToType
};
由以上的定义又需要对testObjFunc来处理
JSStaticFunction testObjFunc[] = {
   { "test", testObj_test, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
   { 0, 0, 0 }
  };
最后我们实现一下testObj_test函数即可
JSValueRef testObj_test(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
 printf("Yes,This is a testObj test Function!\n");
 return JSValueMakeBoolean(ctx,true);
}
重新编译基于webkit的浏览器,要测试的话,在webServer端,我们可以加入以下代码作为测试:
<script type="text/javascript">
  document.write("testObj test!" + testObj_0.test());
</script>
如果一切都正常,你的自定义浏览器会输出Yes,This is a testObj test Function!


分析是我简要分析了以下#include <JavaScriptCore/JavaScript.h>中的接口:
#include <JavaScriptCore/JSBase.h> 
#include <JavaScriptCore/JSContextRef.h> 
#include <JavaScriptCore/JSStringRef.h> 
#include <JavaScriptCore/JSObjectRef.h> 
#include <JavaScriptCore/JSValueRef.h> 

一个文件一个文件的来分析
JSBase.h   /* JavaScript engine interface */

求JS字符串的值
JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception);

检查JS语法错误
bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception);

执行JS垃圾回收
JS_EXPORT void JSGarbageCollect(JSContextRef ctx);


JSContextRef.h

创建javascript context组
将不同的JS context关联起来,在同一个组的context可以共享JavaScript对象,当对象在同一个组中,在多线程里面,需要精确的同步保证。
JSContextGroupRef JSContextGroupCreate()

保持在同一个组里
JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group)

释放一个JS context组
void JSContextGroupRelease(JSContextGroupRef group)

创建一个全局的JS可执行context
JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass)
其会调用JSGlobalContextCreateInGroup();

在group中创建一个全局可执行的context
JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClassRef globalObjectClass)

保持全局可执行的JS context
JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef ctx);

释放一个全局的JS可执行context
void JSGlobalContextRelease(JSGlobalContextRef ctx);

从ctx获取全局对象
JSObjectRef JSContextGetGlobalObject(JSContextRef ctx);

获取ctx所在的组
JSContextGroupRef JSContextGetGroup(JSContextRef ctx)

 

JSObjectRef.h
/*!
@struct JSClassDefinition
@abstract This structure contains properties and callbacks that define a type of object. All fields other than the version field are optional. Any pointer may be NULL.
@field version The version number of this structure. The current version is 0.
@field attributes A logically ORed set of JSClassAttributes to give to the class.
@field className A null-terminated UTF8 string containing the class's name.
@field parentClass A JSClass to set as the class's parent class. Pass NULL use the default object class.
@field staticValues A JSStaticValue array containing the class's statically declared value properties. Pass NULL to specify no statically declared value properties. The array must be terminated by a JSStaticValue whose name field is NULL.
@field staticFunctions A JSStaticFunction array containing the class's statically declared function properties. Pass NULL to specify no statically declared function properties. The array must be terminated by a JSStaticFunction whose name field is NULL.
@field initialize The callback invoked when an object is first created. Use this callback to initialize the object.
@field finalize The callback invoked when an object is finalized (prepared for garbage collection). Use this callback to release resources allocated for the object, and perform other cleanup.
@field hasProperty The callback invoked when determining whether an object has a property. If this field is NULL, getProperty is called instead. The hasProperty callback enables optimization in cases where only a property's existence needs to be known, not its value, and computing its value is expensive.
@field getProperty The callback invoked when getting a property's value.
@field setProperty The callback invoked when setting a property's value.
@field deleteProperty The callback invoked when deleting a property.
@field getPropertyNames The callback invoked when collecting the names of an object's properties.
@field callAsFunction The callback invoked when an object is called as a function.
@field hasInstance The callback invoked when an object is used as the target of an 'instanceof' expression.
@field callAsConstructor The callback invoked when an object is used as a constructor in a 'new' expression.
@field convertToType The callback invoked when converting an object to a particular JavaScript type.
@discussion The staticValues and staticFunctions arrays are the simplest and most efficient means for vending custom properties. Statically declared properties autmatically service requests like getProperty, setProperty, and getPropertyNames. Property access callbacks are required only to implement unusual properties, like array indexes, whose names are not known at compile-time.

If you named your getter function "GetX" and your setter function "SetX", you would declare a JSStaticValue array containing "X" like this:

JSStaticValue StaticValueArray[] = {
    { "X", GetX, SetX, kJSPropertyAttributeNone },
    { 0, 0, 0, 0 }
};

Standard JavaScript practice calls for storing function objects in prototypes, so they can be shared. The default JSClass created by JSClassCreate follows this idiom, instantiating objects with a shared, automatically generating prototype containing the class's function objects. The kJSClassAttributeNoAutomaticPrototype attribute specifies that a JSClass should not automatically generate such a prototype. The resulting JSClass instantiates objects with the default object prototype, and gives each instance object its own copy of the class's function objects.

A NULL callback specifies that the default object callback should substitute, except in the case of hasProperty, where it specifies that getProperty should substitute.
*/
typedef struct {
    int                                 version; /* current (and only) version is 0 */
    JSClassAttributes                   attributes;

    const char*                         className;
    JSClassRef                          parentClass;
       
    const JSStaticValue*                staticValues;
    const JSStaticFunction*             staticFunctions;
   
    JSObjectInitializeCallback          initialize;
    JSObjectFinalizeCallback            finalize;
    JSObjectHasPropertyCallback         hasProperty;
    JSObjectGetPropertyCallback         getProperty;
    JSObjectSetPropertyCallback         setProperty;
    JSObjectDeletePropertyCallback      deleteProperty;
    JSObjectGetPropertyNamesCallback    getPropertyNames;
    JSObjectCallAsFunctionCallback      callAsFunction;
    JSObjectCallAsConstructorCallback   callAsConstructor;
    JSObjectHasInstanceCallback         hasInstance;
    JSObjectConvertToTypeCallback       convertToType;
} JSClassDefinition;


/*!
@function
@abstract Creates a JavaScript class suitable for use with JSObjectMake.
@param definition A JSClassDefinition that defines the class.
@result A JSClass with the given definition. Ownership follows the Create Rule.
*/
为JSObjectMake使用创建一个JS类
JSClassRef JSClassCreate(const JSClassDefinition* definition);

保持
JSClassRef JSClassRetain(JSClassRef jsClass);

释放
JS_EXPORT void JSClassRelease(JSClassRef jsClass);

创建一个JS对象。jsClass非空时才允许有私有数据,可通过JSObjectGetPrivate获取
JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data);

使用callback方便创建JS函数
JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name, JSObjectCallAsFunctionCallback callAsFunction);

利用回调创建JS构造函数
JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObjectCallAsConstructorCallback callAsConstructor);

 创建一组JS对象
JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)

创建一个JS日期对象
JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)

创建一个JS错误对象
JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)

创建一个JS正则表达式对象
JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)

创建一个函数,使用body作为主题
JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned parameterCount, const JSStringRef parameterNames[], JSStringRef body, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception);

获取object prototype
JSValueRef JSObjectGetPrototype(JSContextRef ctx, JSObjectRef object);

设置一个对象的prototype
void JSObjectSetPrototype(JSContextRef ctx, JSObjectRef object, JSValueRef value);

测试对象是否有propertyName属性
bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName);

从一个对象中获取属性
JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception);

向对象设置属性
void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception);

删除某个属性
bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception);

从对象中按索引获取属性
JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef* exception);

通过索引设置对象属性
void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef value, JSValueRef* exception);

获取对象私有数据
void* JSObjectGetPrivate(JSObjectRef object);

设置对象私有数据
bool JSObjectSetPrivate(JSObjectRef object, void* data);

判断对象是否可以像函数一样被调用
bool JSObjectIsFunction(JSContextRef ctx, JSObjectRef object);

将对象作为函数一样调用
JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);

对象可否作为构造函数调用
bool JSObjectIsConstructor(JSContextRef ctx, JSObjectRef object);

对象作为构造函数调用
JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);

获取对象列举的属性名称
JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef object);

保持JS属性名称组
JSPropertyNameArrayRef JSPropertyNameArrayRetain(JSPropertyNameArrayRef array);

释放JS属性名称组
void JSPropertyNameArrayRelease(JSPropertyNameArrayRef array);

获取JS属性名称组的个数
size_t JSPropertyNameArrayGetCount(JSPropertyNameArrayRef array);

通过索引获取JS属性名称组
JSStringRef JSPropertyNameArrayGetNameAtIndex(JSPropertyNameArrayRef array, size_t index);

添加一个JS属性
void JSPropertyNameAccumulatorAddName(JSPropertyNameAccumulatorRef accumulator, JSStringRef propertyName);


JSStringRef.h


创建一个JS字串
JSStringRef JSStringCreateWithCharacters(const JSChar* chars, size_t numChars);

同上
JSStringRef JSStringCreateWithUTF8CString(const char* string);

保持
JSStringRef JSStringRetain(JSStringRef string);

释放
JS_EXPORT void JSStringRelease(JSStringRef string);

获取字串数
size_t JSStringGetLength(JSStringRef string);

获取指向string的指针地址
const JSChar* JSStringGetCharactersPtr(JSStringRef string);

获取字串占用的最大值
size_t JSStringGetMaximumUTF8CStringSize(JSStringRef string);

获取字串
size_t JSStringGetUTF8CString(JSStringRef string, char* buffer, size_t bufferSize);

比较字串是否一致
bool JSStringIsEqual(JSStringRef a, JSStringRef b);

比较a,b
bool JSStringIsEqualToUTF8CString(JSStringRef a, const char* b);

你可能感兴趣的:(webkit)