一、js层面
1,在D:develectron7srcelectronlibbrowserapimodule-keys.js 中添加新的module:
// Browser side modules, please sort alphabetically.
module.exports = [
{ name: 'app' },
{ name: 'autoUpdater' },
{ name: 'BrowserCache' },
{ name: 'BrowserView' },
{ name: 'BrowserWindow' },
2,在 D:develectron7srcelectronlibbrowserapimodule-list.js 中引入
browser-cache.js 文件。
module.exports = [
{ name: 'app', loader: () => require('./app') },
{ name: 'autoUpdater', loader: () => require('./auto-updater') },
{ name: 'BrowserCache', loader: () => require('./browser-cache') },
3,D:develectron7srcelectronlibbrowserapibrowser-cache.js
这个js的
const { BrowserCache } = process.electronBinding('cache');
引入了c++模块注册的module cache。然后js封装了对外接口,提供外部调用。[外部调用 const { BrowserCache} = require('electron')]
module.exports = BrowserCache
'use strict';
const electron = require('electron');
const { WebContentsView, TopLevelWindow, deprecate } = electron;
const { BrowserCache } = process.electronBinding('cache');
Object.setPrototypeOf(BrowserCache.prototype, TopLevelWindow.prototype);
BrowserCache.prototype._init = function () {
// Call parent class's _init.
TopLevelWindow.prototype._init.call(this);
// Avoid recursive require.
const { app } = electron;
// Create WebContentsView.
this.setContentView(new WebContentsView(this.webContents));
this.webContents.on('move', (event, size) => {
this.setBounds(size);
});
// Hide the auto-hide menu when webContents is focused.
this.webContents.on('activate', () => {
if (process.platform !== 'darwin' && this.autoHideMenuBar && this.isMenuBarVisible()) {
this.setMenuBarVisibility(false);
}
});
const visibilityEvents = ['show', 'hide', 'minimize', 'maximize', 'restore'];
for (const event of visibilityEvents) {
this.on(event, visibilityChanged);
}
// Properties
Object.defineProperty(this, 'fullScreenable', {
get: () => this.isFullScreenable(),
set: (full) => this.setFullScreenable(full)
});
Object.defineProperty(this, 'simple', {
get: () => this.isSimple(),
set: (simple) => this.setSimple(simple)
});
};
const isBrowserCache = (cache) => {
return cache && cache.constructor.name === 'BrowserCache';
};
// Helpers.
Object.assign(BrowserCache.prototype, {
getURL (...args) {
return this.webContents.getURL();
},
loadFile (...args) {
return this.webContents.loadFile(...args);
}
});
module.exports = BrowserCache;
如果直接导出c++接口,参照app.ts
// Only one app object permitted.
export default app;
js文件改动后,需要动动module-list.js,才会重新生成js2c的文件。即js转成c文件存放。
二、C++扩展
1,添加文件 D:develectron7srcelectronshellbrowserapiatom_api_browser_cache.cc
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/browser/api/atom_api_browser_cache.h"
#include <iostream>
#include <memory>
#include "base/threading/thread_task_runner_handle.h"
#include "gin/converter.h"
#include "native_mate/dictionary.h"
#include "shell/common/api/constructor.h"
#include "shell/common/node_includes.h"
#include "shell/common/api/constructor.h"
#include "shell/common/application_info.h"
#include "shell/common/atom_command_line.h"
#include "shell/common/color_util.h"
#include "shell/common/native_mate_converters/callback.h"
#include "shell/common/native_mate_converters/file_path_converter.h"
#include "shell/common/native_mate_converters/gurl_converter.h"
#include "shell/common/native_mate_converters/once_callback.h"
#include "shell/common/native_mate_converters/value_converter.h"
#include "shell/common/node_includes.h"
#include "shell/common/options_switches.h"
#include "ui/gl/gpu_switching_manager.h"
#include "native_mate/object_template_builder.h"
namespace electron {
namespace api {
BrowserCache::BrowserCache(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options)
: weak_factory_(this) {
// Use options.webPreferences in WebContents.
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
options.Get(options::kWebPreferences, &web_preferences);
// Copy the backgroundColor to webContents.
v8::Local<v8::Value> value;
if (options.Get(options::kBackgroundColor, &value))
web_preferences.Set(options::kBackgroundColor, value);
// Copy the transparent setting to webContents
v8::Local<v8::Value> transparent;
if (options.Get("transparent", &transparent))
web_preferences.Set("transparent", transparent);
InitWith(isolate, wrapper);
}
BrowserCache::~BrowserCache() {}
v8::Local<v8::Value> BrowserCache::GetWebContents(v8::Isolate* isolate) {
return v8::Null(isolate);
// return v8::Local<v8::Value>::New(isolate, web_contents_);
}
std::string BrowserCache::GetHeader(mate::Arguments* args,
const std::string& url) {
// bool succeed = false;
return "ok";
}
v8::Local<v8::Value> BrowserCache::GetContent(mate::Arguments* args,
const std::string& url) {
// bool succeed = false;
std::string data = "hello world"; // Read(format_string);
return node::Buffer::Copy(args->isolate(), data.data(), data.length())
.ToLocalChecked();
}
// static
mate::WrappableBase* BrowserCache::New(mate::Arguments* args) {
if (args->Length() > 1) {
args->ThrowError();
// return ;
}
mate::Dictionary options;
if (!(args->Length() == 1 && args->GetNext(&options))) {
options = mate::Dictionary::CreateEmpty(args->isolate());
}
return new BrowserCache(args->isolate(), args->GetThis(), options);
// return mate::CreateHandle(args->isolate(), new
// BrowserCache(args->isolate(), args->GetThis(), options));
}
#if 0
// static
mate::Handle<BrowserCache> App::Create(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new BrowserCache(isolate));
}
#endif
// static
void BrowserCache::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "BrowserCache"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("getHeader", &BrowserCache::GetHeader)
.SetMethod("getContent", &BrowserCache::GetContent)
.SetProperty("webContents", &BrowserCache::GetWebContents);
}
} // namespace api
} // namespace electron
namespace {
using electron::api::BrowserCache;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
std::cout << "xxxxxxx BrowserCache "
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
<< std::endl;
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
#if 0
dict.Set("BrowserCache", electron::api::App::GetConstructor(isolate)
->GetFunction(context)
.ToLocalChecked());
dict.Set("browserCache", electron::api::BrowserCache::Create(isolate));
#else
dict.Set("BrowserCache",
mate::CreateConstructor<BrowserCache>(
isolate, base::BindRepeating(&BrowserCache::New)));
#endif
}
} // namespace
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_cache, Initialize)
View Code
// static new一个object
mate::WrappableBase* BrowserCache::New(mate::Arguments* args) {
if (args->Length() > 1) {
args->ThrowError();
return nullptr;
}
mate::Dictionary options;
if (!(args->Length() == 1 && args->GetNext(&options))) {
options = mate::Dictionary::CreateEmpty(args->isolate());
}
return new BrowserCache(args->isolate(), args->GetThis(), options); //new一个实例
}
// static 这里加入成员函数,属性。
void BrowserCache::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "BrowserCache"));//设置对外类名
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("focusOnWebView", &BrowserCache::FocusOnWebView)
.SetMethod("blurWebView", &BrowserCache::BlurWebView)
.SetMethod("isWebViewFocused", &BrowserCache::IsWebViewFocused)
.SetProperty("webContents", &BrowserCache::GetWebContents);
}
// static
v8::Local<v8::Value> BrowserCache::From(v8::Isolate* isolate,
NativeWindow* native_window) {
auto* existing = TrackableObject::FromWrappedClass(isolate, native_window);
if (existing)
return existing->GetWrapper();
else
return v8::Null(isolate);
}
} // namespace api
} // namespace electron
namespace {
using electron::api::BrowserCache;
using electron::api::TopLevelWindow;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("BrowserCache",//这个是类名,js这里会用到 const { BrowserCache } = process.electronBinding('cache');
mate::CreateConstructor<BrowserCache>(
isolate, base::BindRepeating(&BrowserCache::New))); //字典名字,到New创建构造函数。会调用到buildtype加入成员函数。
}
} // namespace
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_cache, Initialize) //将atom_browser_cache的初始化绑定到initialize上。这个宏会生成register_xxx函数。然后将 atom_browser_cache 加入到node_binding.cc中,这样会调用这个注册函数。 这里的cache就是上面js require时的名字 ???
2,头文件
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef SHELL_BROWSER_API_ATOM_API_BROWSER_CACHE_H_
#define SHELL_BROWSER_API_ATOM_API_BROWSER_CACHE_H_
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include "base/task/cancelable_task_tracker.h"
#include "native_mate/dictionary.h"
#include "native_mate/handle.h"
#include "base/threading/thread_task_runner_handle.h"
#include "gin/converter.h"
#include "native_mate/dictionary.h"
#include "shell/browser/browser.h"
#include "shell/browser/unresponsive_suppressor.h"
#include "shell/browser/web_contents_preferences.h"
#include "shell/browser/window_list.h"
#include "native_mate/dictionary.h"
#include "native_mate/handle.h"
#include "native_mate/object_template_builder.h"
#include "shell/common/application_info.h"
#include "shell/common/atom_command_line.h"
#include "shell/common/native_mate_converters/callback.h"
#include "shell/common/native_mate_converters/file_path_converter.h"
#include "shell/common/native_mate_converters/gurl_converter.h"
#include "shell/common/native_mate_converters/image_converter.h"
#include "shell/common/native_mate_converters/net_converter.h"
#include "shell/common/native_mate_converters/network_converter.h"
#include "shell/common/native_mate_converters/once_callback.h"
#include "shell/common/native_mate_converters/value_converter.h"
#include "shell/common/node_includes.h"
#include "shell/common/options_switches.h"
#include "ui/gl/gpu_switching_manager.h"
#include "shell/browser/api/event_emitter.h"
#include "shell/common/native_mate_converters/callback.h"
#include "shell/common/promise_util.h"
#include "shell/common/api/constructor.h"
namespace mate {
class Arguments;
} // namespace mate
namespace electron {
namespace api {
class BrowserCache : public mate::EventEmitter<BrowserCache> {
public:
static mate::WrappableBase* New(mate::Arguments* args);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
base::WeakPtr<BrowserCache> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
protected:
BrowserCache(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options);
~BrowserCache() override;
v8::Local<v8::Value> GetWebContents(v8::Isolate* isolate);
std::string GetHeader(mate::Arguments* args, const std::string& url);
v8::Local<v8::Value> GetContent(mate::Arguments* args,
const std::string& url);
private:
#if defined(OS_MACOSX)
void OverrideNSWindowContentView(InspectableWebContents* iwc);
#endif
// Helpers.
base::WeakPtrFactory<BrowserCache> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(BrowserCache);
};
} // namespace api
} // namespace electron
#endif // SHELL_BROWSER_API_ATOM_API_BROWSER_WINDOW_H_
View Code
3,加入 D:develectron7srcelectronshellcommonnode_bindings.cc
#define ELECTRON_BUILTIN_MODULES(V)
V(atom_browser_app)
V(atom_browser_auto_updater)
V(atom_browser_cache)
4,加入gn编译文件
d:develectron7srcelectronfilenames.gni
lib_sources = [
"shell/browser/api/atom_api_browser_cache.cc",
"shell/browser/api/atom_api_browser_cache.h",
"shell/app/atom_content_client.cc",
"shell/app/atom_content_client.h",
"shell/app/atom_main_delegate.cc",
"shell/app/atom_main_delegate.h",
三、外围调用
const electron = require('electron')
const BrowserCache = electron.BrowserCache
var cache = new BrowserCache({width: 800})
console.log("========== cache generated:"+cache )
console.log("========== cache getHeader:"+cache.getHeader("will error") );
var cont=cache.getContent("will error");
console.log("========== cache getContent:"+cont );
四、原理部分
最终导出的 require(electron)是在 D:develectron7srcelectronlibbrowserapiexportselectron.js中导出的。
'use strict';
const common = require('@electron/internal/common/api/exports/electron');
// since browser module list is also used in renderer, keep it separate.
const moduleList = require('@electron/internal/browser/api/module-list');
// Import common modules.
common.defineProperties(exports);
for (const module of moduleList) {
Object.defineProperty(exports, module.name, {
enumerable: !module.private,
get: common.handleESModule(module.loader)
});
}
原文链接: https://www.cnblogs.com/bigben0123/p/13630821.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/202484
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!