Skip to content

Understanding how it works for contributors

arjunj132 edited this page Jul 14, 2022 · 2 revisions

A brief introduction to the 3 most important files

The main.js (starts app)

It runs using Electron. It first sets up a BrowserWindow and all necessary components:

function createWindow () {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
      enableRemoteModule: true,
      webviewTag: true
    }
  })


// menus and error handling
...

app.whenReady().then(() => {
  createWindow()

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow()
    }
  })
})

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

It creates a menu bar and context menu. Errors and problems are caught and if there are any, the err.html file is called. Otherwise, it calls the index.html file to open in the window.

It also gets the URL that is default loaded and gives it to the renderer.js

ipcMain.handle('url', async function (event, path) {
  http_check()
  return url
})

Simple, right?

The index.html (the browser UI)

The HTML loads the libraries Bootstrap, Bootstrap icons, and jQuery:

        <!-- CSS only -->
        <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
        <!-- JavaScript Bundle with Popper -->
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
        <link rel="stylesheet" href="styles.css">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-icons/1.8.1/font/bootstrap-icons.min.css" integrity="sha512-Oy+sz5W86PK0ZIkawrG0iv7XwWhYecM3exvUtMKNJMekGFJtVAhibhRPTpmyTj8+lJCkmWfnpxKgT2OopquBHA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
        <script
            src="https://code.jquery.com/jquery-3.6.0.min.js"
            integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
            crossorigin="anonymous"></script>

Then creates a menu of buttons and info using Bootstrap icons:

<i class="bi bi-arrow-left" style="cursor: pointer;" title="Back" onclick="goBack()"></i>&nbsp;&nbsp;<i class="bi bi-arrow-right"  style="cursor: pointer;" title="Forward" onclick="goForward()">&nbsp;&nbsp;<i class="bi bi-arrow-clockwise" style="cursor: pointer;" title="Reload" onclick="reload()"></i></i>&nbsp;&nbsp;<i class="bi bi-shield-check" id='secure' title="Secure"></i>

An address bar is then created that calls a JavaScript function in another file, renderer.js

<form action="javascript:search()">
        <div class="input-group mb-3">
            <input type="text" class="form-control" placeholder="URL" aria-label="URL" aria-describedby="button-addon2" id="url">
            <div class="input-group-append">
              <button class="btn btn-outline-secondary" type="button" id="button-addon2" type="submit"><i class="bi bi-search"></i></button>
            </div>
        </div>
</form>

Then, a webview is created

<webview style="width:100%; height: calc(100% - 75px)" id="browser" onload="restart()" allowpopups ></webview>

Finally, it calls renderer.js the load the website into the webview

<script src="renderer.js"></script>

A very simple but powerful UI.

The renderer.js (the browser)

First, it gets the webview and opens the URL that is given in the main process:

var webview = document.getElementById('browser')
const webview1 = document.querySelector('webview')

var url_find = ipcRenderer.invoke('url').then((result) => {
    if (result == "") {
        result = "https://google.com"
    }
    webview.src = result;
})

Next, it gives the buttons in the html functionality:

function goBack() {
    webview1.goBack()
}
function goForward() {
    webview1.goForward()
}

function reload() {
    webview.reload()
}

Then it does the search feature:

function search() {
    ...
}

Inside the search function, if it has HTTPS or HTTP defined, it will open the website and change the security sign.

if (result.includes("https://") == true || result.includes("http://") == true) {
        url = result
            // open url:
    console.log('Navigating to ' + url)
    document.getElementById('browser').src = url;
    // change security:
    if (url.includes('https://') == true) {
        document.getElementById('secure').className = 'bi bi-shield-check';
    } else {
        document.getElementById('secure').className = 'bi bi-shield-exclamation';
    }
      }

Otherwise, it will check if it is a file and open and change the security:

else {
        if (result.includes("file:///") == true) { url = result 
        // open url:
        console.log('Navigating to ' + url)
        document.getElementById('browser').src = url;
        // change security:
        document.getElementById('secure').className = '';
        document.getElementById('secure').innerHTML = '<code>file</code>';
        document.getElementById('secure').title = 'File: If you downloaded it from somewhere, be carful';
    }

If it is not any of these, it will define an ajax XMLHttpRequest call:

function ajax(a, b, c){ // URL, callback, just a placeholder
                c = new XMLHttpRequest;
                c.open('GET', a);
                c.onload = b;
                c.addEventListener('error', http_url);
                c.send()
}

Then it will create a request using the ajax function assuming it is a HTTPS page:

ajax('https://' + result, callback);

If there is an error, we assume it is an HTTP page and load it in the webview:

function http_url(e) {
                url = 'http://' + result
                // open url:
                console.log('Navigating to ' + url)
                document.getElementById('browser').src = url;
                // change security:
                if (url.includes('https://') == true) {
                    document.getElementById('secure').className = 'bi bi-shield-check';
                } else {
                    document.getElementById('secure').className = 'bi bi-shield-exclamation';
                }
}

Then if it succeeds and we receive a callback, we load the HTTPS page:

function callback(e){
                url = 'https://' + result
                // open url:
                console.log('Navigating to ' + url)
                document.getElementById('browser').src = url;
                // change security:
                if (url.includes('https://') == true) {
                    document.getElementById('secure').className = 'bi bi-shield-check';
                    document.getElementById('secure').title = 'Secure';
                } else {
                    document.getElementById('secure').className = 'bi bi-shield-exclamation';
                    document.getElementById('secure').title = 'Unsecure';
                }
}

After all these crazy if statements are done, we can change the address bar to update the URL:

      // change url in bar
      webview.addEventListener('dom-ready', () => {
          document.getElementById('url').value = document.getElementById('browser').src;
      }

Then that's it! The page has loaded!

So now you understand the basic logic and algorithms in DinoBrowse!