tinymce-editor/copy_this/modules/hdi/hdi-tinymce/tinymce/classes/util/Observable.js
2013-07-25 23:50:43 +02:00

233 regels
5.4 KiB
JavaScript
Executable File

/**
* Observable.js
*
* Copyright, Moxiecode Systems AB
* Released under LGPL License.
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
/**
* This mixin will add event binding logic to classes.
*
* @mixin tinymce.util.Observable
*/
define("tinymce/util/Observable", [
"tinymce/util/Tools"
], function(Tools) {
var bindingsName = "__bindings";
var nativeEvents = Tools.makeMap(
"focusin focusout click dblclick mousedown mouseup mousemove mouseover beforepaste paste cut copy selectionchange" +
" mouseout mouseenter mouseleave keydown keypress keyup contextmenu dragend dragover draggesture dragdrop drop drag", ' '
);
function returnFalse() {
return false;
}
function returnTrue() {
return true;
}
return {
/**
* Fires the specified event by name.
*
* @method fire
* @param {String} name Name of the event to fire.
* @param {tinymce.Event/Object?} args Event arguments.
* @param {Boolean?} bubble True/false if the event is to be bubbled.
* @return {tinymce.Event} Event instance passed in converted into tinymce.Event instance.
* @example
* instance.fire('event', {...});
*/
fire: function(name, args, bubble) {
var self = this, handlers, i, l, callback, parent;
name = name.toLowerCase();
args = args || {};
args.type = name;
// Setup target is there isn't one
if (!args.target) {
args.target = self;
}
// Add event delegation methods if they are missing
if (!args.preventDefault) {
// Add preventDefault method
args.preventDefault = function() {
args.isDefaultPrevented = returnTrue;
};
// Add stopPropagation
args.stopPropagation = function() {
args.isPropagationStopped = returnTrue;
};
// Add stopImmediatePropagation
args.stopImmediatePropagation = function() {
args.isImmediatePropagationStopped = returnTrue;
};
// Add event delegation states
args.isDefaultPrevented = returnFalse;
args.isPropagationStopped = returnFalse;
args.isImmediatePropagationStopped = returnFalse;
}
//console.log(name, args);
if (self[bindingsName]) {
handlers = self[bindingsName][name];
if (handlers) {
for (i = 0, l = handlers.length; i < l; i++) {
handlers[i] = callback = handlers[i];
// Stop immediate propagation if needed
if (args.isImmediatePropagationStopped()) {
break;
}
// If callback returns false then prevent default and stop all propagation
if (callback.call(self, args) === false) {
args.preventDefault();
return args;
}
}
}
}
// Bubble event up to parents
if (bubble !== false && self.parent) {
parent = self.parent();
while (parent && !args.isPropagationStopped()) {
parent.fire(name, args, false);
parent = parent.parent();
}
}
return args;
},
/**
* Binds an event listener to a specific event by name.
*
* @method on
* @param {String} name Event name or space separated list of events to bind.
* @param {callback} callback Callback to be executed when the event occurs.
* @return {Object} Current class instance.
* @example
* instance.on('event', function(e) {
* // Callback logic
* });
*/
on: function(name, callback) {
var self = this, bindings, handlers, names, i;
if (callback === false) {
callback = function() {
return false;
};
}
if (callback) {
names = name.toLowerCase().split(' ');
i = names.length;
while (i--) {
name = names[i];
bindings = self[bindingsName];
if (!bindings) {
bindings = self[bindingsName] = {};
}
handlers = bindings[name];
if (!handlers) {
handlers = bindings[name] = [];
if (self.bindNative && nativeEvents[name]) {
self.bindNative(name);
}
}
handlers.push(callback);
}
}
return self;
},
/**
* Unbinds an event listener to a specific event by name.
*
* @method off
* @param {String?} name Name of the event to unbind.
* @param {callback?} callback Callback to unbind.
* @return {Object} Current class instance.
* @example
* // Unbind specific callback
* instance.off('event', handler);
*
* // Unbind all listeners by name
* instance.off('event');
*
* // Unbind all events
* instance.off();
*/
off: function(name, callback) {
var self = this, i, bindings = self[bindingsName], handlers, bindingName, names, hi;
if (bindings) {
if (name) {
names = name.toLowerCase().split(' ');
i = names.length;
while (i--) {
name = names[i];
handlers = bindings[name];
// Unbind all handlers
if (!name) {
for (bindingName in bindings) {
bindings[name].length = 0;
}
return self;
}
if (handlers) {
// Unbind all by name
if (!callback) {
handlers.length = 0;
} else {
// Unbind specific ones
hi = handlers.length;
while (hi--) {
if (handlers[hi] === callback) {
handlers.splice(hi, 1);
}
}
}
if (!handlers.length && self.unbindNative && nativeEvents[name]) {
self.unbindNative(name);
delete bindings[name];
}
}
}
} else {
if (self.unbindNative) {
for (name in bindings) {
self.unbindNative(name);
}
}
self[bindingsName] = [];
}
}
return self;
}
};
});