summaryrefslogtreecommitdiffstats
path: root/extensions/renderer/resources/extension_custom_bindings.js
blob: 68450d56b3afbbf6fe39b44c9898274060e0be8b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the extension API.

var binding = require('binding').Binding.create('extension');

var messaging = require('messaging');
var runtimeNatives = requireNative('runtime');
var GetExtensionViews = runtimeNatives.GetExtensionViews;
var chrome = requireNative('chrome').GetChrome();

var inIncognitoContext = requireNative('process').InIncognitoContext();
var sendRequestIsDisabled = requireNative('process').IsSendRequestDisabled();
var contextType = requireNative('process').GetContextType();
var manifestVersion = requireNative('process').GetManifestVersion();

// This should match chrome.windows.WINDOW_ID_NONE.
//
// We can't use chrome.windows.WINDOW_ID_NONE directly because the
// chrome.windows API won't exist unless this extension has permission for it;
// which may not be the case.
var WINDOW_ID_NONE = -1;

binding.registerCustomHook(function(bindingsAPI, extensionId) {
  var extension = bindingsAPI.compiledApi;
  if (manifestVersion < 2) {
    chrome.self = extension;
    extension.inIncognitoTab = inIncognitoContext;
  }
  extension.inIncognitoContext = inIncognitoContext;

  var apiFunctions = bindingsAPI.apiFunctions;

  apiFunctions.setHandleRequest('getViews', function(properties) {
    var windowId = WINDOW_ID_NONE;
    var type = 'ALL';
    if (properties) {
      if (properties.type != null) {
        type = properties.type;
      }
      if (properties.windowId != null) {
        windowId = properties.windowId;
      }
    }
    return GetExtensionViews(windowId, type);
  });

  apiFunctions.setHandleRequest('getBackgroundPage', function() {
    return GetExtensionViews(-1, 'BACKGROUND')[0] || null;
  });

  apiFunctions.setHandleRequest('getExtensionTabs', function(windowId) {
    if (windowId == null)
      windowId = WINDOW_ID_NONE;
    return GetExtensionViews(windowId, 'TAB');
  });

  apiFunctions.setHandleRequest('getURL', function(path) {
    path = String(path);
    if (!path.length || path[0] != '/')
      path = '/' + path;
    return 'chrome-extension://' + extensionId + path;
  });

  // Alias several messaging deprecated APIs to their runtime counterparts.
  var mayNeedAlias = [
    // Types
    'Port',
    // Functions
    'connect', 'sendMessage', 'connectNative', 'sendNativeMessage',
    // Events
    'onConnect', 'onConnectExternal', 'onMessage', 'onMessageExternal'
  ];
  $Array.forEach(mayNeedAlias, function(alias) {
    // Checking existence isn't enough since some functions are disabled via
    // getters that throw exceptions. Assume that any getter is such a function.
    if (chrome.runtime &&
        $Object.hasOwnProperty(chrome.runtime, alias) &&
        chrome.runtime.__lookupGetter__(alias) === undefined) {
      extension[alias] = chrome.runtime[alias];
    }
  });

  apiFunctions.setUpdateArgumentsPreValidate('sendRequest',
      $Function.bind(messaging.sendMessageUpdateArguments,
                     null, 'sendRequest', false /* hasOptionsArgument */));

  apiFunctions.setHandleRequest('sendRequest',
                                function(targetId, request, responseCallback) {
    if (sendRequestIsDisabled)
      throw new Error(sendRequestIsDisabled);
    var port = chrome.runtime.connect(targetId || extensionId,
                                      {name: messaging.kRequestChannel});
    messaging.sendMessageImpl(port, request, responseCallback);
  });

  if (sendRequestIsDisabled) {
    extension.onRequest.addListener = function() {
      throw new Error(sendRequestIsDisabled);
    };
    if (contextType == 'BLESSED_EXTENSION') {
      extension.onRequestExternal.addListener = function() {
        throw new Error(sendRequestIsDisabled);
      };
    }
  }
});

exports.$set('binding', binding.generate());