1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Event management for GuestViewContainers.
7 var EventBindings = require('event_bindings');
9 var CreateEvent = function(name) {
10 var eventOpts = {supportsListeners: true, supportsFilters: true};
11 return new EventBindings.Event(name, undefined, eventOpts);
14 function GuestViewEvents(view) {
18 // |setupEventProperty| is normally called automatically, but these events are
19 // are registered here because they are dispatched from GuestViewContainer
20 // instead of in response to extension events.
21 this.setupEventProperty('contentresize');
22 this.setupEventProperty('resize');
26 // |GuestViewEvents.EVENTS| is a dictionary of extension events to be listened
27 // for, which specifies how each event should be handled. The events are
28 // organized by name, and by default will be dispatched as DOM events with
30 // |cancelable| (default: false) specifies whether the DOM event's default
31 // behavior can be canceled. If the default action associated with the event
32 // is prevented, then its dispatch function will return false in its event
33 // handler. The event must have a specified |handler| for this to be
35 // |evt| specifies a descriptor object for the extension event. An event
36 // listener will be attached to this descriptor.
37 // |fields| (default: none) specifies the public-facing fields in the DOM event
38 // that are accessible to developers.
39 // |handler| specifies the name of a handler function to be called each time
40 // that extension event is caught by its event listener. The DOM event
41 // should be dispatched within this handler function (if desired). With no
42 // handler function, the DOM event will be dispatched by default each time
43 // the extension event is caught.
44 // |internal| (default: false) specifies that the event will not be dispatched
45 // as a DOM event, and will also not appear as an on* property on the view’s
46 // element. A |handler| should be specified for all internal events, and
47 // |fields| and |cancelable| should be left unspecified (as they are only
48 // meaningful for DOM events).
49 GuestViewEvents.EVENTS = {};
51 // Sets up the handling of events.
52 GuestViewEvents.prototype.setupEvents = function() {
53 for (var eventName in GuestViewEvents.EVENTS) {
54 this.setupEvent(eventName, GuestViewEvents.EVENTS[eventName]);
57 var events = this.getEvents();
58 for (var eventName in events) {
59 this.setupEvent(eventName, events[eventName]);
63 // Sets up the handling of the |eventName| event.
64 GuestViewEvents.prototype.setupEvent = function(eventName, eventInfo) {
65 if (!eventInfo.internal) {
66 this.setupEventProperty(eventName);
69 var listenerOpts = { instanceId: this.view.viewInstanceId };
70 if (eventInfo.handler) {
71 eventInfo.evt.addListener(function(e) {
72 this[eventInfo.handler](e, eventName);
73 }.bind(this), listenerOpts);
77 // Internal events are not dispatched as DOM events.
78 if (eventInfo.internal) {
82 eventInfo.evt.addListener(function(e) {
83 var domEvent = this.makeDomEvent(e, eventName);
84 this.view.dispatchEvent(domEvent);
85 }.bind(this), listenerOpts);
88 // Constructs a DOM event based on the info for the |eventName| event provided
89 // in either |GuestViewEvents.EVENTS| or getEvents().
90 GuestViewEvents.prototype.makeDomEvent = function(event, eventName) {
92 GuestViewEvents.EVENTS[eventName] || this.getEvents()[eventName];
94 // Internal events are not dispatched as DOM events.
95 if (eventInfo.internal) {
99 var details = { bubbles: true };
100 if (eventInfo.cancelable) {
101 details.cancelable = true;
103 var domEvent = new Event(eventName, details);
104 if (eventInfo.fields) {
105 $Array.forEach(eventInfo.fields, function(field) {
106 if (event[field] !== undefined) {
107 domEvent[field] = event[field];
115 // Adds an 'on<event>' property on the view, which can be used to set/unset
117 GuestViewEvents.prototype.setupEventProperty = function(eventName) {
118 var propertyName = 'on' + eventName.toLowerCase();
119 $Object.defineProperty(this.view.element, propertyName, {
121 return this.on[propertyName];
123 set: function(value) {
124 if (this.on[propertyName]) {
125 this.view.element.removeEventListener(eventName, this.on[propertyName]);
127 this.on[propertyName] = value;
129 this.view.element.addEventListener(eventName, value);
136 // Implemented by the derived event manager, if one exists.
137 GuestViewEvents.prototype.getEvents = function() { return {}; };
140 exports.GuestViewEvents = GuestViewEvents;
141 exports.CreateEvent = CreateEvent;