We use cookies to make our website more effective. By using our website you agree to our privacy policy.

Source: events.js

/**
 * events.js is part of Aloha Editor project http://www.alohaeditor.org
 *
 * Aloha Editor ● JavaScript Content Editing Library
 * Copyright (c) 2010-2015 Gentics Software GmbH, Vienna, Austria.
 * Contributors http://www.alohaeditor.org/docs/contributing.html
 *
 * @see
 * http://www.w3.org/TR/DOM-Level-3-Events/#idl-interface-MouseEvent-initializers
 * @namespace events
 */
define([
	'functions',
	'misc',
	'assert'
], function (
	Fn,
	Misc,
	Assert
) {
	'use strict';

	/**
	 * Registers an event listener to fire the given callback when a specified
	 * event is triggered on the given object.
	 *
	 * @param {Element|Document|Window} obj
	 *        Object which supports events.  This includes DOM elements, the
	 *        Document itself, and the Window object for example.
	 * @param {string} event
	 *        Name of the event for which to register the given callback.
	 * @param {function} handler
	 *        Function to be invoked when event is triggered on the given
	 *        object.
	 * @param {boolean=} opt_useCapture
	 *        Optional.  Whether to add the handler in the capturing phase.
	 * @memberOf events
	 */
	function add(obj, event, handler, opt_useCapture) {
		var useCapture = !!opt_useCapture;
		if (obj.addEventListener) {
			obj.addEventListener(event, handler, useCapture);
		} else if (obj.attachEvent) {
			obj.attachEvent('on' + event, handler);
		} else {
			Assert.error();
		}
	}

	/**
	 * Detaches the specified event callback from the given event.
	 *
	 * @param {Element|Document|Window} obj
	 *        Object which supports events.  This includes DOM elements, the
	 *        Document itself, and the Window object for example.
	 * @param {string} event
	 *        Name of the event to detach.
	 * @param {function} handler
	 *        Function to be de-registered.
	 * @param {boolean=} opt_useCapture
	 *        Optional.  Must be true if the handler was registered with a true
	 *        useCapture argument.
	 * @memberOf events
	 */
	function remove(obj, event, handler, opt_useCapture) {
		var useCapture = !!opt_useCapture;
		if (obj.removeEventListener) {
			obj.removeEventListener(event, handler, useCapture);
		} else if (obj.detachEvent) {
			obj.detachEvent('on' + event, handler);
		} else {
			Assert.error();
		}
	}

	/**
	 * This function is missing documentation.
	 * @TODO Complete documentation.
	 *
	 * @memberOf events
	 */
	function dispatch(doc, obj, event) {
		var eventObj;
		if (obj.dispatchEvent) {
			// NB This method is to create events is deprecated:
			// https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Events/Creating_and_triggering_events
			// But the new way doesn't work on IE9.
			// var eventObj = new window['Event'](event);
			eventObj = doc.createEvent('Event');
			eventObj.initEvent(event, true, true);
			obj.dispatchEvent(eventObj);
		} else if (obj.fireEvent) {
			eventObj = doc.createEventObject();
			eventObj['type'] = event;
			obj.fireEvent('on' + event, eventObj);
		} else {
			Assert.error();
		}
	}

	/**
	 * Given an event object, checks whether the ctrl key is depressed.
	 *
	 * @param  {Event} event
	 * @return {boolean}
	 * @memberOf events
	 */
	function hasKeyModifier(event, modifier) {
		return event.meta.indexOf(modifier) > -1;
	}

	/**
	 * Runs the given function after the current event handler returns
	 * to the browser.
	 *
	 * Currently implemented just with setTimeout() which is specced to
	 * have a minimum timeout value of 4 milliseconds. Alternate
	 * implementations are possible that are faster, for example:
	 * https://github.com/NobleJS/setImmediate
	 *
	 * @param fn {function} a function to call
	 * @memberOf events
	 */
	function nextTick(fn) {
		setTimeout(fn, 4);
	}

	/**
	 * Sets up all editing browser events to call `editor` on the given
	 * document.
	 *
	 * @see
	 * https://en.wikipedia.org/wiki/DOM_Events
	 * http://www.w3.org/TR/DOM-Level-3-Events
	 *
	 * @param {function} editor
	 * @param {Document} doc
	 * @memberOf events
	 */
	function setup(doc, editor) {
		add(doc, 'resize',     editor);

		add(doc, 'keyup',      editor);
		add(doc, 'keydown',    editor);
		add(doc, 'keypress',   editor);

		add(doc, 'click',      editor);
		add(doc, 'mouseup',    editor);
		add(doc, 'mousedown',  editor);
		add(doc, 'mousemove',  editor);
		add(doc, 'dblclick',   editor);

		add(doc, 'dragstart',  editor);
		add(doc, 'drag',       editor);
		add(doc, 'dragenter',  editor);
		add(doc, 'dragexit',   editor);
		add(doc, 'dragleave',  editor);
		add(doc, 'dragover',   editor);
		add(doc, 'drop',       editor);
		add(doc, 'dragend',    editor);
		add(doc, 'paste',      editor);
	}

	/**
	 * Flags the given event to prevent native handlers from performing default
	 * behavior for it.
	 *
	 * @param {Event} event
	 * @memberOf events
	 */
	function preventDefault(event) {
		if (event.preventDefault) {
			event.preventDefault();
		} else {
			event['returnValue'] = false;
		}
	}

	/**
	 * Stops this event from bubbling any further up the DOM tree.
	 *
	 * @param {Event} event
	 * @memberOf events
	 */
	function stopPropagation(event) {
		if (event.stopPropagation) {
			event.stopPropagation();
		} else {
			event['cancelBubble'] = true;
		}
	}

	/**
	 * "Suppresses" the given event such that it will not trigger default
	 * behavior and nor propagate.  This will prevent any parent handlers up of
	 * the DOM tree from being notified of this event.
	 *
	 * @param {Event} event
	 * @memberOf events
	 */
	function suppress(event) {
		stopPropagation(event);
		preventDefault(event);
	}

	/**
	 * Returns true if the given value is a native browser event object.
	 *
	 * @param  {*} obj
	 * @return {boolean}
	 * @memberOf events
	 */
	function is(obj) {
		return obj
		    && obj.hasOwnProperty
		    && obj.hasOwnProperty('type')
		    && !Fn.isNou(obj.stopPropagation)
		    && !Fn.isNou(obj.preventDefault);
	}

	return {
		is              : is,
		add             : add,
		remove          : remove,
		setup           : setup,
		hasKeyModifier  : hasKeyModifier,
		dispatch        : dispatch,
		nextTick        : nextTick,
		preventDefault  : preventDefault,
		stopPropagation : stopPropagation,
		suppress        : suppress
	};
});
comments powered by Disqus