一、介绍

谷歌浏览器和CEF使用V8JavaScript Engine作为内容的JavaScript实现。在浏览器中的每个窗口都有它自己在的JS上下文提供作用域和在窗口中安全的执行JS代码。CEF暴露大量JS功能集成在客户端应用程序。
CEF3的Webkit和JS在单独的渲染进程中运行。在渲染进程的主线程中使用TID_RENDERER 作为唯一标识。所有V8的执行必须放置在这个线程中。
与JS执行相关的回调函数被暴露是通过CefRenderProcessHandler接口实现。当一个新的渲染进程被初始化时通过CefApp::GetRenderProcessHandler()函数获取这个接口。

二、执行JavaScript

在客户端应用程序中简单的方式执行JS使用CefFrame::ExecuteJavaScript()函数,这个函数在浏览进程一和渲染进程中都可用。在一个JS上下文外可安全使用。

CefRefPtr<CefBrowser> browser = ...;
CefRefPtr<CefFrame> frame = browser->GetMainFrame(); 
frame->ExecuteJavaScript("alert('ExecuteJavaScript works!');", frame->GetURL(), 0);

上面的引起alert('ExecuteJavaScript works!')在浏览器的主窗口中执行。

在窗口的JS上下文中ExecuteJavaScript函数可用于函数和变量交互。是为了从JS到客户端应用程序返回值使用窗口绑定和扩展。

三、窗口绑定

窗口绑定允许客户端应用程序系上一个值到窗口的window对象上,窗口绑定的实现使用CefRenderProcessHandler::OnContextCreated()函数。

如:

void MyRenderProcessHandler::OnContextCreated(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context) {
// Retrieve the context's window object.
CefRefPtr<CefV8Value> object = context->GetGlobal(); // Create a new V8 string value. See the "Basic JS Types" section below.
CefRefPtr<CefV8Value> str = CefV8Value::CreateString("My Value!"); // Add the string to the window object as "window.myval". See the "JS Objects" section below.
object->SetValue("myval", str, V8_PROPERTY_ATTRIBUTE_NONE);
}

JavaScript框架可以与之交互的窗口绑定。

<script language="JavaScript">
alert(window.myval); // Shows an alert box with "My Value!"
</script>

窗口绑定是每次重新加载一个框架加载给客户端应用程序在必要时更改绑定的机会。例如,不同的框架通过修改绑定框架的窗口对象值可以访问不同的特性。

四、扩展

扩展像window绑定一样除了为每个框架 加载到上下文之外,一旦加载就不能修改,当一个扩展已经加载并试图在扩展加载中访问DOM就会出现DOM不存在的crash。扩展应该在CefRenderProcessHandler::OnWebKitInitialized()函数中使用CefRegisterExtension函数注册。

void MyRenderProcessHandler::OnWebKitInitialized() {
// Define the extension contents.
std::string extensionCode =
"var test;"
"if (!test)"
" test = {};"
"(function() {"
" test.myval = 'My Value!';"
"})();"; // Register the extension.
CefRegisterExtension("v8/test", extensionCode, NULL);
}

通过extensionCode描述的字符串可以是任何有效的代码,JS框架可以和扩展代码进行交互

<script language="JavaScript">
alert(test.myval); // Shows an alert box with "My Value!"
</script>

五、基本JS类型

CEF支持基本数据类型的创建,包括:undefined, null, bool, int, double, date 和 string.这些基本数据类型使用CefV8Value::Create*()系列静态函数创建。如创建一个JS字符串:CefRefPtr<CefV8Value> str = CefV8Value::CreateString("My Value!");

基本数据类型可在任何地方创建和在所关联的上下文中不用初始化。如:

CefRefPtr<CefV8Value> val = ...;
if (val.IsString())
{ // The value is a string. }

使用Get*Value()系列函数获取值:CefString strVal = val.GetStringValue();

六、JS数组

使用CefV8Value::CreateArray()静态函数并传递一个长度作为参数创建数组。数组只能在上下文内部创建并使用。如:

CefRefPtr<CefV8Value> arr = CefV8Value::CreateArray(2);

值赋给一个数组使用SetValue()方法的变体,以一个索引作为第一个参数。
arr->SetValue(0, CefV8Value::CreateString("My First String!"));
arr->SetValue(1, CefV8Value::CreateString("My Second String!"));

IsArray()函数测试CefV8Value是否为数组,GetArrayLength()函数获取数据的长度,从数组中获取一个值使用GetValue()变体函数。

七、JS对象

使用CefV8Value::CreateObject静态函数可带一个可选的CefV8Accessor参数创建JS对象。对象也只能在js上下文中创建并使用。

CefRefPtr<CefV8Value> obj = CefV8Value::CreateObject(NULL);

使用SetValue()变体函数并以字符串key作为第一参数给对象分配值。

八、对象的访问者

JS对象可选择使用一个与之关联的CefV8Accessor以提供一个源生的getting和setting值的实现。
CefRefPtr<CefV8Accessor> accessor = …;
CefRefPtr<CefV8Value> obj = CefV8Value::CreateObject(accessor);

CefV8Accessor接口的一个实现,必须由客户端应用程序提供。

class MyV8Accessor : public CefV8Accessor {
public:
MyV8Accessor() {} virtual bool Get(const CefString& name,
const CefRefPtr<CefV8Value> object,
CefRefPtr<CefV8Value>& retval,
CefString& exception) OVERRIDE {
if (name == "myval") {
// Return the value.
retval = CefV8Value::CreateString(myval_);
return true;
} // Value does not exist.
return false;
} virtual bool Set(const CefString& name,
const CefRefPtr<CefV8Value> object,
const CefRefPtr<CefV8Value> value,
CefString& exception) OVERRIDE {
if (name == "myval") {
if (value.IsString()) {
// Store the value.
myval_ = value.GetStringValue();
} else {
// Throw an exception.
exception = "Invalid value type";
}
return true;
} // Value does not exist.
return false;
} // Variable used for storing the value.
CefString myval_; // Provide the reference counting implementation for this class.
IMPLEMENT_REFCOUNTING(MyV8Accessor);
};

为了将值传递给访问者必须使用SetValue()变体函数设置,接受AccessControl和PropertyAttribute参数

九、JS函数

CEF支持JS函数创建和本地实现,

CEF3研究(四)之javascript集成的更多相关文章

  1. 第四章 JavaScript操作DOM对象

    第四章   JavaScript操作DOM对象 一.DOM操作 DOM是Document Object Model的缩写,即文档对象模型,是基于文档编程的一套API接口,1988年,W3C发布了第一级 ...

  2. JavaScript DOM编程艺术第四章 — JavaScript图片库案例研究

    这一章通过JavaScript图片库案例,学习了一些DOM属性. HTML代码 <!DOCTYPE html> <html> <head> <meta cha ...

  3. CEF3研究(三)

    一.Off-Screen Rendering 脱屏绘制 CEF的脱屏渲染并不创建源生的浏览器窗口,而是CEF提供主应用程序在无效区域和像素buffer里渲染,然后主应用程序通过鼠标.键盘和焦点事件通知 ...

  4. CEF3研究(二)

    应用程序结构 每个CEF3应用程序都有一个相同的结构: 提供一个入口函数以初始化CEF和运行每个子进程逻辑和CEF消息处理 提供一个CefApp子类处理某个进程的回调 提供一个CefClinet子类处 ...

  5. 王爽-汇编语言-综合研究四-不使用main函数编程

    (一) 研究目的 使用C语言编程,我们一定要使用main函数么? (二) 研究过程 1) 最初的程序 首先,我们编写一个不写main函数的C语言程序. 程序如下: 在编译的过程中,没有发现错误.在链接 ...

  6. 四种JavaScript隐式类型转换的总结

    一般存在四种情况,JavaScript会对变量的数据类型进行转换. 目录 * if中的条件会被自动转为Boolean类型 * 会被转为false的数据 * 会被转为true的数据 * 参与+运算都会被 ...

  7. python自动化开发-[第十四天]-javascript(续)

    今日概要: 1.数据类型 2.函数function 3.BOM 4.DOM 1.运算符 算术运算符: + - * / % ++ -- 比较运算符: > >= < <= != = ...

  8. JQuery制作网页—— 第四章JavaScript对象及初识面向对象

    1.对象:在JavaScript中,所有事物都是对象,如字符串.数值.数组.函数等. JavaScript中的基本数据类型: number(数值类型)   string(字符串类型)  boolean ...

  9. Chrome自带恐龙小游戏的源码研究(四)

    在上一篇<Chrome自带恐龙小游戏的源码研究(三)>中实现了让游戏昼夜交替,这一篇主要研究如何绘制障碍物. 障碍物有两种:仙人掌和翼龙.仙人掌有大小两种类型,可以同时并列多个:翼龙按高. ...

随机推荐

  1. Animate.css_css3动画库介绍

    插件描述:Animate.css内置了很多典型的css3动画,兼容性好使用方便. Animate.css是一个有趣的,跨浏览器的css3动画库.很值得我们在项目中引用. 用法 1.首先引入animat ...

  2. iview table icon dorpdown html页面级别vue组件 #vuez#

    iview table icon dorpdown html页面级别vue组件 <!DOCTYPE html> <html> <head> <meta cha ...

  3. python基础一 day2 字符串操作

    s.capitalize()  s.upper()  s.lower() s.swapcase()   s.title()  s.center(20,"#")   s.expand ...

  4. jquery-closest

    1.closest() 本例演示如何通过 closest() 完成事件委托.当被最接近的列表元素或其子后代元素被点击时,会切换黄色背景: $( document ).bind("click& ...

  5. bzoj4951 [Wf2017]Money for Nothing

    题目描述 题解: 答案显然是$max((q-p)*(e-d))$ 依然先贪心. 对于工厂,我们倾向于$pi<pj,di<dj$的; 对于买家,我们倾向于$qi>qj,ei>ej ...

  6. 【Linux】Centos6的iptables防火墙设置

    1,查看防火墙状态 # service iptables status //或 # /etc/init.d/iptables status 2,防火墙的启动.重启,关闭 # service iptab ...

  7. 谈一谈flex布局使用中碰到的一些问题

    起因 工作以后由于大量使用到了flex布局而碰到了一些尚不清楚的问题,以及一些有意思的特性,在此写篇博客记录一下. flex三个值的含义 众所周知,flex布局所有的属性有两种:一种作用在弹性容器(F ...

  8. js layui 分页脚本

    //分页 layui.use(['laypage'], function(){ var laypage = layui.laypage; laypage.render({ elem: 'page' , ...

  9. LeetCode(86) Partition List

    题目 Given a linked list and a value x, partition it such that all nodes less than x come before nodes ...

  10. LeetCode 464. Can I Win

    In the "100 game," two players take turns adding, to a running total, any integer from 1.. ...