summaryrefslogtreecommitdiffstats
path: root/chrome/renderer/resources/event_bindings.js
blob: f8a65178d510c87a69c0935d77ac872f823f5df8 (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
112
113
114
115
116
117
118
119
120
var chromium = chromium || {};
(function () {
  native function AttachEvent(eventName);
  native function DetachEvent(eventName);

  // Event object.  If opt_eventName is provided, this object represents
  // the unique instance of that named event, and dispatching an event
  // with that name will route through this object's listeners.
  //
  // Example:
  //   chromium.ontabchanged = new Event('tabchanged');
  //   chromium.ontabchanged.addListener(function(data) { alert(data); });
  //   chromium.Event.dispatch_('tabchanged', 'hi');
  // will result in an alert dialog that says 'hi'.
  chromium.Event = function(opt_eventName) {
    this.eventName_ = opt_eventName;
    this.listeners_ = [];
  };

  // A map of event names to the event object that is registered to that name.
  chromium.Event.attached_ = {};

  // Dispatches a named event with the given JSON data, which is deserialized
  // before dispatch.
  chromium.Event.dispatchJSON_ = function(name, data) {
    if (chromium.Event.attached_[name]) {
      if (data) {
        data = goog.json.parse(data);
      }
      chromium.Event.attached_[name].dispatch(data);
    }
  };

  // Dispatches a named event with the given object data.
  chromium.Event.dispatch_ = function(name, data) {
    if (chromium.Event.attached_[name]) {
      chromium.Event.attached_[name].dispatch(data);
    }
  };

  // Registers a callback to be called when this event is dispatched.
  chromium.Event.prototype.addListener = function(cb) {
    this.listeners_.push(cb);
    if (this.listeners_.length == 1) {
      this.attach_();
    }
  };

  // Unregisters a callback.
  chromium.Event.prototype.removeListener = function(cb) {
    var idx = this.findListener_(cb);
    if (idx == -1) {
      return;
    }

    this.listeners_.splice(idx, 1);
    if (this.listeners_.length == 0) {
      this.detach_();
    }
  };

  // Test if the given callback is registered for this event.
  chromium.Event.prototype.hasListener = function(cb) {
    return this.findListeners_(cb) > -1;
  };

  // Returns the index of the given callback if registered, or -1 if not
  // found.
  chromium.Event.prototype.findListener_ = function(cb) {
    for (var i = 0; i < this.listeners_.length; i++) {
      if (this.listeners_[i] == cb) {
        return i;
      }
    }

    return -1;
  };

  // Dispatches this event object to all listeners, passing all supplied
  // arguments to this function each listener.
  chromium.Event.prototype.dispatch = function(varargs) {
    var args = Array.prototype.slice.call(arguments);
    for (var i = 0; i < this.listeners_.length; i++) {
      try {
        this.listeners_[i].apply(null, args);
      } catch (e) {
        console.error(e);
      }
    }
  };

  // Attaches this event object to its name.  Only one object can have a given
  // name.
  chromium.Event.prototype.attach_ = function() {
    AttachEvent(this.eventName_);
    if (!this.eventName_)
      return;

    if (chromium.Event.attached_[this.eventName_]) {
      throw new Error("chromium.Event '" + this.eventName_ +
                      "' is already attached.");
    }

    chromium.Event.attached_[this.eventName_] = this;
  };

  // Detaches this event object from its name.
  chromium.Event.prototype.detach_ = function() {
    DetachEvent(this.eventName_);
    if (!this.eventName_)
      return;

    if (!chromium.Event.attached_[this.eventName_]) {
      throw new Error("chromium.Event '" + this.eventName_ +
                      "' is not attached.");
    }

    delete chromium.Event.attached_[this.eventName_];
  };
})();