zoukankan      html  css  js  c++  java
  • electron源码编译 添加builtin 内建 c++扩展

    一、js层面

    1,在D:develectron7srcelectronlibrowserapimodule-keys.js 中添加新的module:

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

    2,在 D:develectron7srcelectronlibrowserapimodule-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:develectron7srcelectronlibrowserapirowser-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:develectron7srcelectronshellrowserapiatom_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:develectron7srcelectronshellcommon ode_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({ 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:develectron7srcelectronlibrowserapiexportselectron.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)
      });
    }
  • 相关阅读:
    python远程连接服务器并查看服务器上的文件
    python中xe6x80xa5xe8xafx8a如何转为中文
    idea+testng+maven环境搭建
    Django restfulframework系列
    django-基于函数的视图与基于类的视图
    yaml结合数据驱动编写测试用例
    pycharm社区版找不到工具栏找不到Database的解决办法
    Content-Type 对照表
    ffmpeg C# 切第一秒的有图片
    Angular HttpClient POST 服务器(springboot)获取不到参数问题
  • 原文地址:https://www.cnblogs.com/bigben0123/p/13630821.html
Copyright © 2011-2022 走看看