Electronic (2) – inject JS and CSS into WebView

Time:2020-10-26

One of the company’s internal desktop software is written based on the electronics Vue. The person who was responsible for developing this client left the company a few days ago, and I became a temporary file pick-up optimization person. As a person who writes Vue but contacts the electronics for the first time, he spent several days browsing the overall architecture of the official documents of the electronics and the electronics Vue, and the client code. Even so, there are still many problems in the optimization process. After the project is finished, this is the general conclusion.
Electronic (2) - inject JS and CSS into WebView

In order to save development cost and time, existing web pages will be used. However, due to business differences, we always need to make some small changes to the existing web pages in the electronic project. At this time, we need to inject some JS and CSS into the WebView page to support these small changes, so as to achieve the purpose of not affecting the business logic before the web page, but also being used by the business of the current project.

(1) Injecting CSS into WebView pages

In the WebView DOM read phase, inject new styles through insertcss()

mounted() {
    const webview = this.$refs.webview

    webview.addEventListener('dom-ready', (e) => {
      this.mInsertCSS()
    })
 }
mInsertCSS() {
      webview.insertCSS(`
        .customer-panel {
          display: relative;
        }
      `)
    },

(1) Inject JS into WebView

Official website:https://www.electronjs.org/docs/api/webview-tag
JS code injection through preload attribute
A String that specifies a script that will be loaded before other scripts run in the guest page. 

The preload attribute can execute the specified script before all scripts in WebView are executed. The protocol of the script URL must be file:asar : one of the two, because in the visitor page, it is loaded through “internal” require

mounted() {
    const webview = this.$refs.webview

    let preloadFile
    if (process.env.NODE_ENV === 'production') {
      preloadFile = `file://${global.__static}/preload.js`
    } else {
      preloadFile = 'file://' + require('path').resolve('static/preload.js')
    }
    webview.setAttribute('preload', preloadFile)
 }

Preload environment can use node API, which is a special environment that can not only use node API, but also access Dom and BOM. Such an environment can be used in the introduced JS codeipcRenderer && ipcRenderer.sendToHost(paramsJSON)Send information to electron rendering process (for specific operation, you can see the communication between electronic (1) – WebView and its loading page, between rendering process and between rendering process and main processhttps://segmentfault.com/a/11…

The JS code is executed in the WebView page through the executejibscript () method, and promise is returned to the electron rendering process
<webview>.executeJavaScript(code[, userGesture])
-code String
-Usergesture Boolean (optional) – default to false

Returns Promise<any> – A promise that resolves with the result of the executed code or is rejected if the result of the code is a rejected promise.

This method means that: execute a certain JavaScript code, return promise, inject JS code with preload attribute, and execute javascript() is more about executing a section of code, such as executing the JS method injected by preload before the execution of WebView code, and can do certain operation on the return

this.$refs.webview.executeJavaScript(`__webViewFunction.getPhoneNumberList()`).then(result => {
        this.phoneNumberList = result || []
        //Query cache
        if (this.checkAllInCache(this.phoneNumberList)) {
          //All phone numbers that need to be queried are cached
          console.log('allCache' + this.phoneNumberList)
        }
      })

Happy time is always so short, and it’s time to say goodbye
Electronic (2) - inject JS and CSS into WebView