electron源码编译 添加builtin 内建 c++扩展

 

一、js层面

1,在D:\dev\electron7\src\electron\lib\browser\api\module-keys.js 中添加新的module:

// Browser side modules, please sort alphabetically.
module.exports = [
  { name: 'app' },
  { name: 'autoUpdater' },
  { name: 'BrowserCache' },
  { name: 'BrowserView' },
  { name: 'BrowserWindow' },

2,在 D:\dev\electron7\src\electron\lib\browser\api\module-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:\dev\electron7\src\electron\lib\browser\api\browser-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++扩展

1,添加文件 D:\dev\electron7\src\electron\shell\browser\api\atom_api_browser_cache.cc

// 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",
           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,头文件

 

3,加入 D:\dev\electron7\src\electron\shell\common\node_bindings.cc

#define ELECTRON_BUILTIN_MODULES(V)  \
  V(atom_browser_app)                \
  V(atom_browser_auto_updater)       \
  V(atom_browser_cache)       \

4,加入gn编译文件

d:\dev\electron7\src\electron\filenames.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",

 

上一篇:SAAS ,IAAS ,PAAS


下一篇:基于 Serverless 的云原生转型实践