145 lines
		
	
	
	
		
			4.5 KiB
			
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			145 lines
		
	
	
	
		
			4.5 KiB
			
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
const electron = require('electron');
 | 
						|
const app = electron.app;
 | 
						|
const fs = require('fs');
 | 
						|
const path = require('path');
 | 
						|
const url = require('url');
 | 
						|
 | 
						|
// Mapping between hostname and file path.
 | 
						|
var hostPathMap = {};
 | 
						|
var hostPathMapNextKey = 0;
 | 
						|
 | 
						|
var getHostForPath = function(path) {
 | 
						|
  var key;
 | 
						|
  key = "extension-" + (++hostPathMapNextKey);
 | 
						|
  hostPathMap[key] = path;
 | 
						|
  return key;
 | 
						|
};
 | 
						|
 | 
						|
var getPathForHost = function(host) {
 | 
						|
  return hostPathMap[host];
 | 
						|
};
 | 
						|
 | 
						|
// Cache extensionInfo.
 | 
						|
var extensionInfoMap = {};
 | 
						|
 | 
						|
var getExtensionInfoFromPath = function(srcDirectory) {
 | 
						|
  var manifest, page;
 | 
						|
  manifest = JSON.parse(fs.readFileSync(path.join(srcDirectory, 'manifest.json')));
 | 
						|
  if (extensionInfoMap[manifest.name] == null) {
 | 
						|
 | 
						|
    // We can not use 'file://' directly because all resources in the extension
 | 
						|
    // will be treated as relative to the root in Chrome.
 | 
						|
    page = url.format({
 | 
						|
      protocol: 'chrome-extension',
 | 
						|
      slashes: true,
 | 
						|
      hostname: getHostForPath(srcDirectory),
 | 
						|
      pathname: manifest.devtools_page
 | 
						|
    });
 | 
						|
    extensionInfoMap[manifest.name] = {
 | 
						|
      startPage: page,
 | 
						|
      name: manifest.name,
 | 
						|
      srcDirectory: srcDirectory,
 | 
						|
      exposeExperimentalAPIs: true
 | 
						|
    };
 | 
						|
    return extensionInfoMap[manifest.name];
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
// The loaded extensions cache and its persistent path.
 | 
						|
var loadedExtensions = null;
 | 
						|
var loadedExtensionsPath = null;
 | 
						|
 | 
						|
app.on('will-quit', function() {
 | 
						|
  try {
 | 
						|
    loadedExtensions = Object.keys(extensionInfoMap).map(function(key) {
 | 
						|
      return extensionInfoMap[key].srcDirectory;
 | 
						|
    });
 | 
						|
    if (loadedExtensions.length > 0) {
 | 
						|
      try {
 | 
						|
        fs.mkdirSync(path.dirname(loadedExtensionsPath));
 | 
						|
      } catch (error) {
 | 
						|
        // Ignore error
 | 
						|
      }
 | 
						|
      fs.writeFileSync(loadedExtensionsPath, JSON.stringify(loadedExtensions));
 | 
						|
    } else {
 | 
						|
      fs.unlinkSync(loadedExtensionsPath);
 | 
						|
    }
 | 
						|
  } catch (error) {
 | 
						|
    // Ignore error
 | 
						|
  }
 | 
						|
});
 | 
						|
 | 
						|
// We can not use protocol or BrowserWindow until app is ready.
 | 
						|
app.once('ready', function() {
 | 
						|
  var BrowserWindow, chromeExtensionHandler, i, init, len, protocol, srcDirectory;
 | 
						|
  protocol = electron.protocol, BrowserWindow = electron.BrowserWindow;
 | 
						|
 | 
						|
  // Load persisted extensions.
 | 
						|
  loadedExtensionsPath = path.join(app.getPath('userData'), 'DevTools Extensions');
 | 
						|
  try {
 | 
						|
    loadedExtensions = JSON.parse(fs.readFileSync(loadedExtensionsPath));
 | 
						|
    if (!Array.isArray(loadedExtensions)) {
 | 
						|
      loadedExtensions = [];
 | 
						|
    }
 | 
						|
 | 
						|
    // Preheat the extensionInfo cache.
 | 
						|
    for (i = 0, len = loadedExtensions.length; i < len; i++) {
 | 
						|
      srcDirectory = loadedExtensions[i];
 | 
						|
      getExtensionInfoFromPath(srcDirectory);
 | 
						|
    }
 | 
						|
  } catch (error) {
 | 
						|
    // Ignore error
 | 
						|
  }
 | 
						|
 | 
						|
  // The chrome-extension: can map a extension URL request to real file path.
 | 
						|
  chromeExtensionHandler = function(request, callback) {
 | 
						|
    var directory, parsed;
 | 
						|
    parsed = url.parse(request.url);
 | 
						|
    if (!(parsed.hostname && (parsed.path != null))) {
 | 
						|
      return callback();
 | 
						|
    }
 | 
						|
    if (!/extension-\d+/.test(parsed.hostname)) {
 | 
						|
      return callback();
 | 
						|
    }
 | 
						|
    directory = getPathForHost(parsed.hostname);
 | 
						|
    if (directory == null) {
 | 
						|
      return callback();
 | 
						|
    }
 | 
						|
    return callback(path.join(directory, parsed.path));
 | 
						|
  };
 | 
						|
  protocol.registerFileProtocol('chrome-extension', chromeExtensionHandler, function(error) {
 | 
						|
    if (error) {
 | 
						|
      return console.error('Unable to register chrome-extension protocol');
 | 
						|
    }
 | 
						|
  });
 | 
						|
  BrowserWindow.prototype._loadDevToolsExtensions = function(extensionInfoArray) {
 | 
						|
    var ref;
 | 
						|
    return (ref = this.devToolsWebContents) != null ? ref.executeJavaScript("DevToolsAPI.addExtensions(" + (JSON.stringify(extensionInfoArray)) + ");") : void 0;
 | 
						|
  };
 | 
						|
  BrowserWindow.addDevToolsExtension = function(srcDirectory) {
 | 
						|
    var extensionInfo, j, len1, ref, window;
 | 
						|
    extensionInfo = getExtensionInfoFromPath(srcDirectory);
 | 
						|
    if (extensionInfo) {
 | 
						|
      ref = BrowserWindow.getAllWindows();
 | 
						|
      for (j = 0, len1 = ref.length; j < len1; j++) {
 | 
						|
        window = ref[j];
 | 
						|
        window._loadDevToolsExtensions([extensionInfo]);
 | 
						|
      }
 | 
						|
      return extensionInfo.name;
 | 
						|
    }
 | 
						|
  };
 | 
						|
  BrowserWindow.removeDevToolsExtension = function(name) {
 | 
						|
    return delete extensionInfoMap[name];
 | 
						|
  };
 | 
						|
 | 
						|
  // Load persistented extensions when devtools is opened.
 | 
						|
  init = BrowserWindow.prototype._init;
 | 
						|
  return BrowserWindow.prototype._init = function() {
 | 
						|
    init.call(this);
 | 
						|
    return this.on('devtools-opened', function() {
 | 
						|
      return this._loadDevToolsExtensions(Object.keys(extensionInfoMap).map(function(key) {
 | 
						|
        return extensionInfoMap[key];
 | 
						|
      }));
 | 
						|
    });
 | 
						|
  };
 | 
						|
});
 |