最近项目需要,同时也是为了记下最近所做的工作以及碰到的问题,因此记录下载方便以后忘记的时候查阅。
所谓扩展 JavaScript 对象,就是增加一个JS 对象,但它并不是点已在标准的JS 对象集合中的,如果网页中包含了扩展的JS 对象,是不能识别的。
下面介绍一下 Chromium 扩展 JavsScript 对象的方法,同样以大众的HelloWorld 开始。一生二二生三三生万物。
1.添 加 HelloWorld.h 、 HelloWorld.cpp 、HelloWorld.idl 三 个 文 件 到third_party/WebKit/Source/core/frame目录下。
------start HelloWorld.h------
<span style="font-family:Microsoft YaHei;">#ifndef HelloWorld_h
#define HelloWorld_h
#include "base/gtest_prod_util.h"
#include "bindings/core/v8/ScriptWrappable.h"
#include "bindings/core/v8/SerializedScriptValue.h"
#include "core/frame/DOMWindowProperty.h"
#include "wtf/Forward.h"
#include "platform/Supplementable.h"
#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
namespace blink {
class LocalFrame;
class ScriptArguments;
class CORE_EXPORT HelloWorld final : public GarbageCollectedFinalized<HelloWorld>, public ScriptWrappable, public HeapSupplementable<HelloWorld>, public DOMWindowProperty {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(HelloWorld);
public:
static HelloWorld* create(LocalFrame* frame) { return new HelloWorld(frame); }
void description(ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>);
DECLARE_VIRTUAL_TRACE();
private:
explicit HelloWorld(LocalFrame*);
};
}
#endif
</span>
------end HelloWorld.h------
------start HelloWorld.cpp------
<span style="font-family:Microsoft YaHei;">#include "HelloWorld.h"
#include <android/log.h>
#include "core/frame/LocalFrame.h"
namespace blink {
HelloWorld::HelloWorld(LocalFrame* frame) : DOMWindowProperty(frame)
{
__android_log_print(ANDROID_LOG_INFO, "log", "some logs");
}
DEFINE_TRACE(HelloWorld)
{
}
void HelloWorld::description(ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>)
{
__android_log_print(ANDROID_LOG_INFO, "log", "some logs");
}
}
</span>
------end HelloWorld.cpp------
------start HelloWorld.idl------
<span style="font-family:Microsoft YaHei;">[
NoInterfaceObject,
GarbageCollected,
] interface HelloWorld {
[CallWith=(ScriptArguments,ScriptState)] void description();
};</span>
------end HelloWorld.idl------
2.修改third_party/WebKit/Source/core/frame/DOMWindow.h文件,添加如下声明
添加class声明:
class HelloWorld;
添加public函数声明:
virtual HelloWrold* helloworld() const = 0;
3.修改third_party/WebKit/Source/core/frame/LocalDOMWindow.h文件,重写父类DOMWindow中的helloworld方法:
HelloWorld*helloworld () const override;
并且添加私有变量声明:
mutable PersistentWillBeMember< HelloWorld> m_ helloworld;
4.修改third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp文件,添加头文件引用:
#include "core/frame/ HelloWorld.h"
给出helloworld方法的实现:
<span style="font-family:Microsoft YaHei;">HelloWorld * LocalDOMWindow::helloworld()const
{
if (!m_helloworld)
m_helloworld= HelloWorld::create(frame());
return m_helloworld.get();
}</span>
在函数void LocalDOMWindow::reset()中复位私有变量m_helloworld:
m_helloworld = nullptr;
5.为了编译通过还需要修改third_party/WebKit/Source/core/frame/RemoteDOMWindow.h文件,这个文件中其实没有具体的实现,只是因为他继承了DOMWindow,有债要还。。。
重写父类DOMWindow中的helloworld方法:
<span style="font-family:Microsoft YaHei;">HelloWorld* helloworld () const override;</span>
6.修改third_party/WebKit/Source/core/frame/ RemoteDOMWindow.cpp文件,添加空实现:
<span style="font-family:Microsoft YaHei;">HelloWorld* RemoteDOMWindow::helloworld()const
{
ASSERT_NOT_REACHED();
return nullptr;
}</span>
7.修改third_party/WebKit/Source/core/frame/ Window.idl,添加
[Replaceable] readonly attribute HelloWorldhelloworld;
只有在此添加了这个属性才能够扩展javascript对象,这个接口会通过python脚本最后生成到out/Release/gen/blink/bindings/core/v8/V8Window.cpp中,然后通过此脚本找到out/Release/gen/blink/bindings/core/v8/V8HelloWorld.cpp,然后找到咱们上边的实现。
8.修改third_party/WebKit/Source/core/core.gypi文件,在gyp脚本的变量'webcore_non_rendering_files'中添加以上文件:
'frame/HelloWorld.cpp',
'frame/HelloWorld.h',
在变量'core_idl_files'中添加
'frame/HelloWorld.idl',
编译通过python脚本解析此文件生成out/Release/gen/blink/bindings/core/v8/V8HelloWorld.cpp/h。
到此编译完成后的产物就是支持扩展对象helloworld的了~
最后上一个例子。
<html>
<head>
<script> function callme() { helloworld.description(); } </script>
</head>
<body οnlοad="callme()"> This is an testfile. </body>
</html>