webkit 扩展 JavaScript 对象

WebKit中JsCore的扩展方法.pdf 本文介绍了如何利用C++对wekbit的javascrpit进行扩展到方法... 立即下载

转载请注明出处:http://blog.youkuaiyun.com/awebkit


我在 上一讲 中说了对于浏览器开发者需要能提供自定义 JavaScript 接口的能力,就像 android 平台的 addJavaScriptInterface 把 java 对象和 JavaScript 对象联系起来。上一讲只讲了加入自定义 JavaScript 对象的时机,即在 FrameLoaderClient 的 dispatchDidClearWindowObjectInWorld 接口中实现自定义的 JavaScript 对象。那么,关键来了,如何实现自定义 JavaScript 对象呢?

我们知道 JavaScript Engine 只认识对象,而这个对象就是 JSObject 。
JavaScriptCore/API 下面有 JavaScript Engine 提供的接口。主要的数据类型有 JSContextRef , JSObjectRef , JSStringRef , JSValueRef 

JavaScriptCore/API/tests 下面有个例子(minidom.c)说明了如何扩展一个函数(print)以及一个对象(Node)。

如何扩展一个函数

从扩展 print 函数的例子开讲。代码如下
    JSGlobalContextRef context = JSGlobalContextCreateInGroup(NULL, NULL);
    JSObjectRef globalObject = JSContextGetGlobalObject(context);
        
    JSStringRef printIString = JSStringCreateWithUTF8CString("print");
    JSObjectSetProperty(context, globalObject, printIString, JSObjectMakeFunctionWithCallback(context, printIString, print), kJSPropertyAttributeNone, NULL);
    JSStringRelease(printIString);

 首先创建 JavaScript 执行环境 JSGlobalContextRef 。关于 JSGlobalContextRef 和  JSContextRef ,可以认为他们是一样的。定义如下。
/*! @typedef JSContextRef A JavaScript execution context. Holds the global object and other execution state. */
typedef const struct OpaqueJSContext* JSContextRef;

/*! @typedef JSGlobalContextRef A global JavaScript execution context. A JSGlobalContext is a JSContext. */
typedef struct OpaqueJSContext* JSGlobalContextRef;

别去找 OpaqueJSContext 的定义了,没有!当时我搜了好久。。。只要知道这是指针即可。

然后在这个 context 中建立了一个 JSObjectRef 对象。我前面说了,JavaScript Engine 只认识 JSObject 对象,顾名思义,JSObjectRef 和 JSObject 之间有联系,但是我也说不太清,我觉得都是指针。

然后就定义了一个 JSStringRef ,这个对应 JavaScript 函数名。记得用完要释放哦

关键的一步:JSObjectSetProperty 我们看看定义
/*!
@function
@abstract Sets a property on an object.
@param ctx The execution context to use.
@param object The JSObject whose property you want to set.
@param propertyName A JSString containing the property's name.
@param value A JSValue to use as the property's value.
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
@param attributes A logically ORed set of JSPropertyAttributes to give to the property.
*/
JS_EXPORT void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception);

所以,这句话的意思就是,在全局对象上加一个属性,属性名叫 print ,值对应  JSObjectMakeFunctionWithCallback(context, printIString, print) 。这也是一个关键函数。
JSObjectMakeFunctionWithCallback 定义如下,写的比较清楚,就是通过一个回调函数实现一个 JavaScript 函数
/*!
@function
@abstract Convenience method for creating a JavaScript function with a given callback as its implementation.
@param ctx The execution context to use.
@param name A JSString containing the function's name. This will be used when converting the function to string. Pass NULL to create an anonymous function.
@param callAsFunction The JSObjectCallAsFunctionCallback to invoke when the function is called.
@result A JSObject that is a function. The object's prototype will be the default function prototype.
*/
JS_EXPORT JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name, JSObjectCallAsFunctionCallback callAsFunction);

JSObjectCallAsFunctionCallback 的定义
/*! 
@typedef JSObjectCallAsFunctionCallback
@abstract The callback invoked when an object is called as a function.
@param ctx The execution context to use.
@param function A JSObject that is the function being called.
@param thisObject A JSObject that is the 'this' variable in the function's scope.
@param argumentCount An integer count of the number of arguments in arguments.
@param arguments A JSValue array of the  arguments passed to the function.
@param exception A pointer to a JSValueRef in which to return an exception, if any.
@result A JSValue that is the function's return value.
@discussion If you named your function CallAsFunction, you would declare it like this:

JSValueRef CallAsFunction(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);

If your callback were invoked by the JavaScript expression 'myObject.myFunction()', function would be set to myFunction, and thisObject would be set to myObject.

If this callback is NULL, calling your object as a function will throw an exception.
*/
typedef JSValueRef
(*JSObjectCallAsFunctionCallback) (JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);

我们再回到开头,print 对应的 JSObjectCallAsFunctionCallback 是如下定义的,这是 c++ 和 JavaScript 对应的函数。(哦,下面的代码忘记释放JSStringRef 了)
static JSValueRef print(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    UNUSED_PARAM(object);
    UNUSED_PARAM(thisObject);

    if (argumentCount > 0) {
        JSStringRef string = JSValueToStringCopy(context, arguments[0], exception);
        size_t numChars = JSStringGetMaximumUTF8CStringSize(string);
        char stringUTF8[numChars];
        JSStringGetUTF8CString(string, stringUTF8, numChars);
        printf("%s\n", stringUTF8);
    }       
        
    return JSValueMakeUndefined(context);
}

总结一下,创建 context ,获取全局对象,设置全局对象新的属性和值。这样就把一个函数加入到了 JavaScript Engine

如何扩展一个对象

扩展一个对象的流程和扩展一个函数的流程差不多,只是最后一步不再是创建一个函数而是一个对象,即不再是调用 
JSObjectMakeFunctionWithCallback 而是 JSObjectMakeConstructor 。看代码
    JSStringRef node = JSStringCreateWithUTF8CString("Node");
    JSObjectSetProperty(context, globalObject, node, JSObjectMakeConstructor(context, JSNode_class(context), JSNode_construct), kJSPropertyAttributeNone, NULL);
    JSStringRelease(node);

JSObjectMakeConstructor 的定义如下
/*!
@function
@abstract Convenience method for creating a JavaScript constructor.
@param ctx The execution context to use.
@param jsClass A JSClass that is the class your constructor will assign to the objects its constructs. jsClass will be used to set the constructor's .prototype property, and to evaluate 'instanceof' expressions. Pass NULL to use the default object class.
@param callAsConstructor A JSObjectCallAsConstructorCallback to invoke when your constructor is used in a 'new' expression. Pass NULL to use the default object constructor.
@result A JSObject that is a constructor. The object's prototype will be the default object prototype.
@discussion The default object constructor takes no arguments and constructs an object of class jsClass with no private data.
*/
JS_EXPORT JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObjectCallAsConstructorCallback callAsConstructor);

这里, JSClassRef 要复杂很多。如果对插件的 NPAPI 接口熟悉,就知道这个也是一些函数指针需要初始化。我们还回到例子中,看例子里面都实现了哪些函数
JSClassRef JSNode_class(JSContextRef context)
{
    UNUSED_PARAM(context);

    static JSClassRef jsClass;
    if (!jsClass) {
        JSClassDefinition definition = kJSClassDefinitionEmpty;
        definition.staticValues = JSNode_staticValues;
        definition.staticFunctions = JSNode_staticFunctions;
        definition.initialize = JSNode_initialize;
        definition.finalize = JSNode_finalize;

        jsClass = JSClassCreate(&definition);
    }   
    return jsClass;
}

这里只实现了 JSClassRef 的 staticValues(静态属性)  staticFunctions(静态方法) initialize finalize。 initialize 和 finalize 相当于构造函数和析构函数。

静态属性和静态方法看代码,还是比较好理解的
static JSStaticValue JSNode_staticValues[] = {
    { "nodeType", JSNode_getNodeType, NULL, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
    { "childNodes", JSNode_getChildNodes, NULL, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
    { "firstChild", JSNode_getFirstChild, NULL, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
    { 0, 0, 0, 0 }
};
static JSStaticFunction JSNode_staticFunctions[] = {
    { "appendChild", JSNode_appendChild, kJSPropertyAttributeDontDelete },
    { "removeChild", JSNode_removeChild, kJSPropertyAttributeDontDelete },
    { "replaceChild", JSNode_replaceChild, kJSPropertyAttributeDontDelete },
    { 0, 0, 0 }
};

好了,对象的绑定大概就这么多吧

理解了函数和对象的绑定,然后在 JavaScript 绑定的入口地方就可以添加对象到 JavaScript Engine 中了。
Ubuntu操作系统等保测评指南 阅读详情

相关推荐

Oracle19c时区升级实战:从32到42版本的数据泵TSTZ报错解决方案

本文详细介绍了Oracle19c时区版本从32升级到42的实战步骤,重点解决数据泵TSTZ报错问题。通过检查时区版本、下载补丁包、应用补丁及执行升级脚本等关键操作,确保数据库时区数据更新,避免夏令时转换错误和历史时区规则不匹配等问题。文章还提供了常见问题排查和升级后的注意事项,帮助DBA高效完成时区升级任务。

n7o8p的博客 284

webkit开发之JS扩展篇

我们在做webkit的JS扩展时总会用到#include 在做webkit javascript扩展时,一般我们按以下流程做: 首先创建一个类 JSClassRef JSClassCreate(const JSClassDefinition* definition); 然后创建一个对象或者创建多个对象 JSObjectRef JSObjectMake(JSContextRef ctx,

Jieen的专栏 1万+

用OpenIPC复活你的旧摄像头:手把手教你给君正T31芯片设备刷开源固件

本文详细介绍了如何使用OpenIPC项目为君正T31芯片的旧摄像头刷入开源固件,解锁更多功能并延长设备寿命。从硬件识别、风险控制到详细刷机步骤和后期配置,手把手教你将闲置摄像头改造为智能监控设备,实现隐私可控、功能扩展等优势。

weixin_30790841的博客 765

面向对象object与constructor

什么是constructor属性?它来自哪里?又将会指向何处? 什么是constructor属性? constructor是构造函数属性。 它来自哪里? 其实constructor属性是来自 prototy原型属性 所指向的那个对象的属性,如果不明白这里的“那个对象”具体指的是哪个对象,可以看看我上一章讲的javascript面向对象——prototype属性(原型属性),里面有着详细的讲...

weixin_34419321的博客 220

Field _II 仿真 学习笔记

参考Field II的使用说明,进行了四个例子的练习。仿真程序和结果如下: PURPOSE1:Calculate the received response from all elements of a linear array and plot the responses and the summed response 【计算来自所有线性阵元的接收响应,并绘制该响应以及叠加响应。】 >>

qq_34018578的博客 1万+

【Creo】关于Creo一换网络就报错许可证丢失问题解决方案

依照我的个人理解,Creo只要一更换网络,则其许可证里面的网卡参数和现在的网络就对不上了,所以就会出现报错,并且有可能是报错代码(-9),提示许可证激活有问题。

weixin_52002180的博客 6036

Objective-c与javascript交互

在写 JavaScript 的时候,可以使用一个叫做 window 的对象,像是我们想要从现在的网页跳到另外一个网页的时候,就会去修改 window.location.href 的位置;在我们的 Objective-C 程序码中,如果我们可以取得指定的 WebView 的指标,也就可以拿到这个出现在 JavaScript 中的 window 对象,也就是 [webView windowScri

pjk1129专栏 1万+

内容审核与文本安全技术综述:检测、过滤与对齐

检测质量高度依赖数据。毒性/仇恨/冒犯语言检测领域形成了一批经典数据集,但它们的标签体系差异很大:例如 OLID(OffensEval)强调“是否冒犯—冒犯类型—目标对象”三层结构;HateXplain 在“hate/offensive/normal”三分类之外,还提供目标群体与人类标注的 rationale span;RealToxicityPrompts 则不做离散标签,而是用毒性分数来研究“模型续写时的毒性退化”。ACL 汇编。

nmdbbzcl的博客 1370

javasript与c&c++的交互

相信初学javascript的工作于嵌入式系统的人,当然包括我自己,都有一个疑问,如果应用是html/css/javascrip写,而中间件是c/c++写,那么javascript与c/c++中间件API是如何相互调用的呢?通过一段时间的学习,在此做个总结 1.JavaScri

3961

openpi 入门教程(一)安装、训练、微调与推理

OpenPI是由物理智能团队发布的机器人开源模型和软件包,包含两种主要模型:基于流的扩散视觉-语言-动作模型(VLA)的π₀模型和基于FAST动作标记器的自回归VLA的π₀-FAST模型。这些模型已在超过10,000小时的机器人数据上进行了预训练,并提供了基础模型检查点,支持开箱即用或根据用户数据集进行微调。OpenPI的实验性质意味着它可能不适用于所有平台,但鼓励研究人员和从业者进行创造性实验。运行这些模型需要至少具备NVIDIA GPU,推荐使用RTX 4090或更高规格的显卡。OpenPI支持在Ubu

2506_90492529的博客 5106

PyCharm配置SSH远程解释器第3步时弹框报错:com.google.gson.stream.MalformedJsonException: Expected value at l...如何解决?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 1928

Lynx技术分析-JS引擎扩展技术基础

背景 Lynx 作为一个基于 JavaScript 语言(后续简称 JS )的跨平台开发框架,与 JS 的通信是"与生俱来"的,框架和 JS 引擎打交道是必不可少的能力。JS 引擎提供了 Extension 功能,提供接入方间接和 JS 通信的桥梁,Lynx 的 JS Binding 正是基于这个能力进行了封装,构建一套基础的 JS API,将能力开放给前端开发者。 当前主流浏览器基本都拥有自己的...

weixin_33720452的博客 1353

vue2/3 - 【超详细】最新网站接入使用支付宝支付功能,点击支付跳转新页面后生成订单及支付二维码,实现支付宝在线付款详细的教程(整个支付的完整配置及支付流程,一键复制源码开箱即用)!

vue支付宝付款,vue支付宝支付,vue如何实现支付宝在线付款,vue网页pc项目接入支付宝支付,vue支付宝支付详细教程,vue2支付宝在线支付的详细示例代码,vue如何做支付宝付款,vue怎么实现支付宝的付款功能,vue调用支付宝进行付款支付,vue PC项目实现 支付宝支付,vue h5页面调用支付宝支付,vue页面唤起支付宝支付功能,vue支付宝支付跳转到新页面,vue如何跳转新开一页展示支付宝二维码支付,vue怎么新开页面进行支付宝在线支付,vue新页面支付宝支付功能,前端vue支付宝支付教程,

✅ 精选推荐文章 5729

WebKit的JavaScript对象扩展

WebKit的JavaScript对象扩展 放飞梦想 » WebKit的JavaScript对象扩展WebKit的JavaScript对象扩展2012年1月12日 alex 发表评论 阅读评论转载时请注明出处和作者联系方式: http://mogoweb.net ...

192

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

webkit的js对象扩展(一)——binding方式创建自定义对象(单实例)

通过binding方式 要扩展一个全局JS对象除了要为webkit添加这个对象的头文件和cpp文件外,还需要为这个对象写一个idl文件以便webkit自动生成相应的代码;另外,还需要修改DOMWindow.*以便把新对象注册上去。下面以MyObject对象为例介绍具体步骤。 WebCore/page/ 1.添加MyObject.h文件 view pl

RTC hacker 6313

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

WebKit JS extension Conclusion (4)

So far(from JS extention 1, 2 and 3), in WebKit JS engine, we can1) add functions2) add callback functions3) add global objects4) add attributes and functions for an extenal global object 

高雄的专栏 820

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

webkit js扩展方式之Binding添加新DOM对象

webkit js Binding添加新DOM对象 一.基础知识 首先WebKit IDL并非完全遵循Web IDL,只是借鉴使用。WebKit官网提供了一份说明(WebKitIDL),比如Web IDL称"operation”(操作), 而WebKitIDL称为"method"(方法),具体详细定义请参见:http://trac.webkit.org/wiki/WebKitIDL。

m632587166的专栏 939

WebKit中为JS binding扩展DOM对象

DOM对象有三种形态 一.寄生于现有对象,单实例 从属于某个全局变量,访问时通过宿主对象完成。如window.object,也可以直接调用object.method。这个方法最为简单,按需分配,并且随着宿主对象释放。参考window的Navigator实现。 1、添加CooperWebObject.h, CooperWebObject.cpp, CooperWebObject.idl文件

1570

android 上 webkit js 扩展之全局本地对象实现步骤

原文出处:    csdn lidp  http://blog.youkuaiyun.com/perfectpdl 最近在做广电项目,要求根据规范做浏览器端javascript扩展。android本身应用层提供了扩展方法,但是这可恶的规范导致应用层根本不可行,只好在webkit引擎里面做。。。 android 上编写 浏览器插件有三种方式, 1. app 层,通过android fram

RTC hacker 5994

android 上 webkit js 本地扩展之全局本地对象实现步骤

android 上编写 浏览器插件有三种方式, 1. app 层,通过android framwork 层提供的 封装扩展,优劣:简单,有局限性 2. 通过 NPAPI 方式, 在 webkit上 通过 NPAPI方式扩展,优劣:相对复杂,接口统一,方便移植到其他平台 3. 通过本地扩展方式,类似于js中对象的实现,在webcore 上实现,优劣:复杂,功能强大,移植性不好。 下面为and

scusyq的专栏 1588

[WebKit]为JavaScript Binding添加新DOM对象的三种方式及实作

转载请注明出处:http://blog.youkuaiyun.com/horkychen  一.基础知识 首先WebKit IDL并非完全遵循Web IDL,只是借鉴使用。WebKit官网提供了一份说明(WebKitIDL),比如Web IDL称"operation”(操作), 而WebKitIDL称为"method"(方法), 另外Web IDL也不像WebKitIDL那样将属性和参数分开。

求索 1万+
上一篇: webkit 中 javascript 与 WebCore DOM 的绑定
下一篇: poj1003 调和级数
awebkit
博客等级 码龄16年 105粉丝 56原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值