247 lines
		
	
	
	
		
			7.4 KiB
			
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			247 lines
		
	
	
	
		
			7.4 KiB
			
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
const ipcMain = require('electron').ipcMain;
 | 
						|
const webContents = require('electron').webContents;
 | 
						|
 | 
						|
var slice = [].slice;
 | 
						|
 | 
						|
// Doesn't exist in early initialization.
 | 
						|
var webViewManager = null;
 | 
						|
 | 
						|
var supportedWebViewEvents = [
 | 
						|
  'load-commit',
 | 
						|
  'did-finish-load',
 | 
						|
  'did-fail-load',
 | 
						|
  'did-frame-finish-load',
 | 
						|
  'did-start-loading',
 | 
						|
  'did-stop-loading',
 | 
						|
  'did-get-response-details',
 | 
						|
  'did-get-redirect-request',
 | 
						|
  'dom-ready',
 | 
						|
  'console-message',
 | 
						|
  'devtools-opened',
 | 
						|
  'devtools-closed',
 | 
						|
  'devtools-focused',
 | 
						|
  'new-window',
 | 
						|
  'will-navigate',
 | 
						|
  'did-navigate',
 | 
						|
  'did-navigate-in-page',
 | 
						|
  'close',
 | 
						|
  'crashed',
 | 
						|
  'gpu-crashed',
 | 
						|
  'plugin-crashed',
 | 
						|
  'destroyed',
 | 
						|
  'page-title-updated',
 | 
						|
  'page-favicon-updated',
 | 
						|
  'enter-html-full-screen',
 | 
						|
  'leave-html-full-screen',
 | 
						|
  'media-started-playing',
 | 
						|
  'media-paused',
 | 
						|
  'found-in-page',
 | 
						|
  'did-change-theme-color'
 | 
						|
];
 | 
						|
 | 
						|
var nextInstanceId = 0;
 | 
						|
var guestInstances = {};
 | 
						|
var embedderElementsMap = {};
 | 
						|
var reverseEmbedderElementsMap = {};
 | 
						|
 | 
						|
// Moves the last element of array to the first one.
 | 
						|
var moveLastToFirst = function(list) {
 | 
						|
  return list.unshift(list.pop());
 | 
						|
};
 | 
						|
 | 
						|
// Generate guestInstanceId.
 | 
						|
var getNextInstanceId = function() {
 | 
						|
  return ++nextInstanceId;
 | 
						|
};
 | 
						|
 | 
						|
// Create a new guest instance.
 | 
						|
var createGuest = function(embedder, params) {
 | 
						|
  var destroy, destroyEvents, event, fn, guest, i, id, j, len, len1, listeners;
 | 
						|
  if (webViewManager == null) {
 | 
						|
    webViewManager = process.atomBinding('web_view_manager');
 | 
						|
  }
 | 
						|
  id = getNextInstanceId(embedder);
 | 
						|
  guest = webContents.create({
 | 
						|
    isGuest: true,
 | 
						|
    partition: params.partition,
 | 
						|
    embedder: embedder
 | 
						|
  });
 | 
						|
  guestInstances[id] = {
 | 
						|
    guest: guest,
 | 
						|
    embedder: embedder
 | 
						|
  };
 | 
						|
 | 
						|
  // Destroy guest when the embedder is gone or navigated.
 | 
						|
  destroyEvents = ['will-destroy', 'crashed', 'did-navigate'];
 | 
						|
  destroy = function() {
 | 
						|
    if (guestInstances[id] != null) {
 | 
						|
      return destroyGuest(embedder, id);
 | 
						|
    }
 | 
						|
  };
 | 
						|
  for (i = 0, len = destroyEvents.length; i < len; i++) {
 | 
						|
    event = destroyEvents[i];
 | 
						|
    embedder.once(event, destroy);
 | 
						|
 | 
						|
    // Users might also listen to the crashed event, so We must ensure the guest
 | 
						|
    // is destroyed before users' listener gets called. It is done by moving our
 | 
						|
    // listener to the first one in queue.
 | 
						|
    listeners = embedder._events[event];
 | 
						|
    if (Array.isArray(listeners)) {
 | 
						|
      moveLastToFirst(listeners);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  guest.once('destroyed', function() {
 | 
						|
    var j, len1, results;
 | 
						|
    results = [];
 | 
						|
    for (j = 0, len1 = destroyEvents.length; j < len1; j++) {
 | 
						|
      event = destroyEvents[j];
 | 
						|
      results.push(embedder.removeListener(event, destroy));
 | 
						|
    }
 | 
						|
    return results;
 | 
						|
  });
 | 
						|
 | 
						|
  // Init guest web view after attached.
 | 
						|
  guest.once('did-attach', function() {
 | 
						|
    var opts;
 | 
						|
    params = this.attachParams;
 | 
						|
    delete this.attachParams;
 | 
						|
    this.viewInstanceId = params.instanceId;
 | 
						|
    this.setSize({
 | 
						|
      normal: {
 | 
						|
        width: params.elementWidth,
 | 
						|
        height: params.elementHeight
 | 
						|
      },
 | 
						|
      enableAutoSize: params.autosize,
 | 
						|
      min: {
 | 
						|
        width: params.minwidth,
 | 
						|
        height: params.minheight
 | 
						|
      },
 | 
						|
      max: {
 | 
						|
        width: params.maxwidth,
 | 
						|
        height: params.maxheight
 | 
						|
      }
 | 
						|
    });
 | 
						|
    if (params.src) {
 | 
						|
      opts = {};
 | 
						|
      if (params.httpreferrer) {
 | 
						|
        opts.httpReferrer = params.httpreferrer;
 | 
						|
      }
 | 
						|
      if (params.useragent) {
 | 
						|
        opts.userAgent = params.useragent;
 | 
						|
      }
 | 
						|
      this.loadURL(params.src, opts);
 | 
						|
    }
 | 
						|
    if (params.allowtransparency != null) {
 | 
						|
      this.setAllowTransparency(params.allowtransparency);
 | 
						|
    }
 | 
						|
    return guest.allowPopups = params.allowpopups;
 | 
						|
  });
 | 
						|
 | 
						|
  // Dispatch events to embedder.
 | 
						|
  fn = function(event) {
 | 
						|
    return guest.on(event, function() {
 | 
						|
      var args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
 | 
						|
      return embedder.send.apply(embedder, ["ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-" + guest.viewInstanceId, event].concat(slice.call(args)));
 | 
						|
    });
 | 
						|
  };
 | 
						|
  for (j = 0, len1 = supportedWebViewEvents.length; j < len1; j++) {
 | 
						|
    event = supportedWebViewEvents[j];
 | 
						|
    fn(event);
 | 
						|
  }
 | 
						|
 | 
						|
  // Dispatch guest's IPC messages to embedder.
 | 
						|
  guest.on('ipc-message-host', function(_, packed) {
 | 
						|
    var args, channel;
 | 
						|
    channel = packed[0], args = 2 <= packed.length ? slice.call(packed, 1) : [];
 | 
						|
    return embedder.send.apply(embedder, ["ATOM_SHELL_GUEST_VIEW_INTERNAL_IPC_MESSAGE-" + guest.viewInstanceId, channel].concat(slice.call(args)));
 | 
						|
  });
 | 
						|
 | 
						|
  // Autosize.
 | 
						|
  guest.on('size-changed', function() {
 | 
						|
    var args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
 | 
						|
    return embedder.send.apply(embedder, ["ATOM_SHELL_GUEST_VIEW_INTERNAL_SIZE_CHANGED-" + guest.viewInstanceId].concat(slice.call(args)));
 | 
						|
  });
 | 
						|
  return id;
 | 
						|
};
 | 
						|
 | 
						|
// Attach the guest to an element of embedder.
 | 
						|
var attachGuest = function(embedder, elementInstanceId, guestInstanceId, params) {
 | 
						|
  var guest, key, oldGuestInstanceId, ref1, webPreferences;
 | 
						|
  guest = guestInstances[guestInstanceId].guest;
 | 
						|
 | 
						|
  // Destroy the old guest when attaching.
 | 
						|
  key = (embedder.getId()) + "-" + elementInstanceId;
 | 
						|
  oldGuestInstanceId = embedderElementsMap[key];
 | 
						|
  if (oldGuestInstanceId != null) {
 | 
						|
 | 
						|
    // Reattachment to the same guest is not currently supported.
 | 
						|
    if (oldGuestInstanceId === guestInstanceId) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    if (guestInstances[oldGuestInstanceId] == null) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    destroyGuest(embedder, oldGuestInstanceId);
 | 
						|
  }
 | 
						|
  webPreferences = {
 | 
						|
    guestInstanceId: guestInstanceId,
 | 
						|
    nodeIntegration: (ref1 = params.nodeintegration) != null ? ref1 : false,
 | 
						|
    plugins: params.plugins,
 | 
						|
    webSecurity: !params.disablewebsecurity,
 | 
						|
    blinkFeatures: params.blinkfeatures
 | 
						|
  };
 | 
						|
  if (params.preload) {
 | 
						|
    webPreferences.preloadURL = params.preload;
 | 
						|
  }
 | 
						|
  webViewManager.addGuest(guestInstanceId, elementInstanceId, embedder, guest, webPreferences);
 | 
						|
  guest.attachParams = params;
 | 
						|
  embedderElementsMap[key] = guestInstanceId;
 | 
						|
  return reverseEmbedderElementsMap[guestInstanceId] = key;
 | 
						|
};
 | 
						|
 | 
						|
// Destroy an existing guest instance.
 | 
						|
var destroyGuest = function(embedder, id) {
 | 
						|
  var key;
 | 
						|
  webViewManager.removeGuest(embedder, id);
 | 
						|
  guestInstances[id].guest.destroy();
 | 
						|
  delete guestInstances[id];
 | 
						|
  key = reverseEmbedderElementsMap[id];
 | 
						|
  if (key != null) {
 | 
						|
    delete reverseEmbedderElementsMap[id];
 | 
						|
    return delete embedderElementsMap[key];
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
ipcMain.on('ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', function(event, params, requestId) {
 | 
						|
  return event.sender.send("ATOM_SHELL_RESPONSE_" + requestId, createGuest(event.sender, params));
 | 
						|
});
 | 
						|
 | 
						|
ipcMain.on('ATOM_SHELL_GUEST_VIEW_MANAGER_ATTACH_GUEST', function(event, elementInstanceId, guestInstanceId, params) {
 | 
						|
  return attachGuest(event.sender, elementInstanceId, guestInstanceId, params);
 | 
						|
});
 | 
						|
 | 
						|
ipcMain.on('ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', function(event, id) {
 | 
						|
  return destroyGuest(event.sender, id);
 | 
						|
});
 | 
						|
 | 
						|
ipcMain.on('ATOM_SHELL_GUEST_VIEW_MANAGER_SET_SIZE', function(event, id, params) {
 | 
						|
  var ref1;
 | 
						|
  return (ref1 = guestInstances[id]) != null ? ref1.guest.setSize(params) : void 0;
 | 
						|
});
 | 
						|
 | 
						|
ipcMain.on('ATOM_SHELL_GUEST_VIEW_MANAGER_SET_ALLOW_TRANSPARENCY', function(event, id, allowtransparency) {
 | 
						|
  var ref1;
 | 
						|
  return (ref1 = guestInstances[id]) != null ? ref1.guest.setAllowTransparency(allowtransparency) : void 0;
 | 
						|
});
 | 
						|
 | 
						|
// Returns WebContents from its guest id.
 | 
						|
exports.getGuest = function(id) {
 | 
						|
  var ref1;
 | 
						|
  return (ref1 = guestInstances[id]) != null ? ref1.guest : void 0;
 | 
						|
};
 | 
						|
 | 
						|
// Returns the embedder of the guest.
 | 
						|
exports.getEmbedder = function(id) {
 | 
						|
  var ref1;
 | 
						|
  return (ref1 = guestInstances[id]) != null ? ref1.embedder : void 0;
 | 
						|
};
 |