summaryrefslogtreecommitdiff
path: root/lib/dojo/on.js.uncompressed.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dojo/on.js.uncompressed.js')
-rw-r--r--lib/dojo/on.js.uncompressed.js514
1 files changed, 0 insertions, 514 deletions
diff --git a/lib/dojo/on.js.uncompressed.js b/lib/dojo/on.js.uncompressed.js
deleted file mode 100644
index cea30aca6..000000000
--- a/lib/dojo/on.js.uncompressed.js
+++ /dev/null
@@ -1,514 +0,0 @@
-define("dojo/on", ["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], function(aspect, dojo, has){
-
- "use strict";
- if( 1 ){ // check to make sure we are in a browser, this module should work anywhere
- var major = window.ScriptEngineMajorVersion;
- has.add("jscript", major && (major() + ScriptEngineMinorVersion() / 10));
- has.add("event-orientationchange", has("touch") && !has("android")); // TODO: how do we detect this?
- has.add("event-stopimmediatepropagation", window.Event && !!window.Event.prototype && !!window.Event.prototype.stopImmediatePropagation);
- }
- var on = function(target, type, listener, dontFix){
- // summary:
- // A function that provides core event listening functionality. With this function
- // you can provide a target, event type, and listener to be notified of
- // future matching events that are fired.
- // target: Element|Object
- // This is the target object or DOM element that to receive events from
- // type: String|Function
- // This is the name of the event to listen for or an extension event type.
- // listener: Function
- // This is the function that should be called when the event fires.
- // returns: Object
- // An object with a remove() method that can be used to stop listening for this
- // event.
- // description:
- // To listen for "click" events on a button node, we can do:
- // | define(["dojo/on"], function(listen){
- // | on(button, "click", clickHandler);
- // | ...
- // Evented JavaScript objects can also have their own events.
- // | var obj = new Evented;
- // | on(obj, "foo", fooHandler);
- // And then we could publish a "foo" event:
- // | on.emit(obj, "foo", {key: "value"});
- // We can use extension events as well. For example, you could listen for a tap gesture:
- // | define(["dojo/on", "dojo/gesture/tap", function(listen, tap){
- // | on(button, tap, tapHandler);
- // | ...
- // which would trigger fooHandler. Note that for a simple object this is equivalent to calling:
- // | obj.onfoo({key:"value"});
- // If you use on.emit on a DOM node, it will use native event dispatching when possible.
-
- if(typeof target.on == "function" && typeof type != "function"){
- // delegate to the target's on() method, so it can handle it's own listening if it wants
- return target.on(type, listener);
- }
- // delegate to main listener code
- return on.parse(target, type, listener, addListener, dontFix, this);
- };
- on.pausable = function(target, type, listener, dontFix){
- // summary:
- // This function acts the same as on(), but with pausable functionality. The
- // returned signal object has pause() and resume() functions. Calling the
- // pause() method will cause the listener to not be called for future events. Calling the
- // resume() method will cause the listener to again be called for future events.
- var paused;
- var signal = on(target, type, function(){
- if(!paused){
- return listener.apply(this, arguments);
- }
- }, dontFix);
- signal.pause = function(){
- paused = true;
- };
- signal.resume = function(){
- paused = false;
- };
- return signal;
- };
- on.once = function(target, type, listener, dontFix){
- // summary:
- // This function acts the same as on(), but will only call the listener once. The
- // listener will be called for the first
- // event that takes place and then listener will automatically be removed.
- var signal = on(target, type, function(){
- // remove this listener
- signal.remove();
- // proceed to call the listener
- return listener.apply(this, arguments);
- });
- return signal;
- };
- on.parse = function(target, type, listener, addListener, dontFix, matchesTarget){
- if(type.call){
- // event handler function
- // on(node, touch.press, touchListener);
- return type.call(matchesTarget, target, listener);
- }
-
- if(type.indexOf(",") > -1){
- // we allow comma delimited event names, so you can register for multiple events at once
- var events = type.split(/\s*,\s*/);
- var handles = [];
- var i = 0;
- var eventName;
- while(eventName = events[i++]){
- handles.push(addListener(target, eventName, listener, dontFix, matchesTarget));
- }
- handles.remove = function(){
- for(var i = 0; i < handles.length; i++){
- handles[i].remove();
- }
- };
- return handles;
- }
- return addListener(target, type, listener, dontFix, matchesTarget);
- };
- var touchEvents = /^touch/;
- function addListener(target, type, listener, dontFix, matchesTarget){
- // event delegation:
- var selector = type.match(/(.*):(.*)/);
- // if we have a selector:event, the last one is interpreted as an event, and we use event delegation
- if(selector){
- type = selector[2];
- selector = selector[1];
- // create the extension event for selectors and directly call it
- return on.selector(selector, type).call(matchesTarget, target, listener);
- }
- // test to see if it a touch event right now, so we don't have to do it every time it fires
- if(has("touch")){
- if(touchEvents.test(type)){
- // touch event, fix it
- listener = fixTouchListener(listener);
- }
- if(!has("event-orientationchange") && (type == "orientationchange")){
- //"orientationchange" not supported <= Android 2.1,
- //but works through "resize" on window
- type = "resize";
- target = window;
- listener = fixTouchListener(listener);
- }
- }
- if(addStopImmediate){
- // add stopImmediatePropagation if it doesn't exist
- listener = addStopImmediate(listener);
- }
- // normal path, the target is |this|
- if(target.addEventListener){
- // the target has addEventListener, which should be used if available (might or might not be a node, non-nodes can implement this method as well)
- // check for capture conversions
- var capture = type in captures,
- adjustedType = capture ? captures[type] : type;
- target.addEventListener(adjustedType, listener, capture);
- // create and return the signal
- return {
- remove: function(){
- target.removeEventListener(adjustedType, listener, capture);
- }
- };
- }
- type = "on" + type;
- if(fixAttach && target.attachEvent){
- return fixAttach(target, type, listener);
- }
- throw new Error("Target must be an event emitter");
- }
-
- on.selector = function(selector, eventType, children){
- // summary:
- // Creates a new extension event with event delegation. This is based on
- // the provided event type (can be extension event) that
- // only calls the listener when the CSS selector matches the target of the event.
- //
- // The application must require() an appropriate level of dojo/query to handle the selector.
- // selector:
- // The CSS selector to use for filter events and determine the |this| of the event listener.
- // eventType:
- // The event to listen for
- // children:
- // Indicates if children elements of the selector should be allowed. This defaults to
- // true
- // example:
- // | require(["dojo/on", "dojo/mouse", "dojo/query!css2"], function(listen, mouse){
- // | on(node, on.selector(".my-class", mouse.enter), handlerForMyHover);
- return function(target, listener){
- // if the selector is function, use it to select the node, otherwise use the matches method
- var matchesTarget = typeof selector == "function" ? {matches: selector} : this,
- bubble = eventType.bubble;
- function select(eventTarget){
- // see if we have a valid matchesTarget or default to dojo.query
- matchesTarget = matchesTarget && matchesTarget.matches ? matchesTarget : dojo.query;
- // there is a selector, so make sure it matches
- while(!matchesTarget.matches(eventTarget, selector, target)){
- if(eventTarget == target || children === false || !(eventTarget = eventTarget.parentNode) || eventTarget.nodeType != 1){ // intentional assignment
- return;
- }
- }
- return eventTarget;
- }
- if(bubble){
- // the event type doesn't naturally bubble, but has a bubbling form, use that, and give it the selector so it can perform the select itself
- return on(target, bubble(select), listener);
- }
- // standard event delegation
- return on(target, eventType, function(event){
- // call select to see if we match
- var eventTarget = select(event.target);
- // if it matches we call the listener
- return eventTarget && listener.call(eventTarget, event);
- });
- };
- };
-
- function syntheticPreventDefault(){
- this.cancelable = false;
- }
- function syntheticStopPropagation(){
- this.bubbles = false;
- }
- var slice = [].slice,
- syntheticDispatch = on.emit = function(target, type, event){
- // summary:
- // Fires an event on the target object.
- // target:
- // The target object to fire the event on. This can be a DOM element or a plain
- // JS object. If the target is a DOM element, native event emiting mechanisms
- // are used when possible.
- // type:
- // The event type name. You can emulate standard native events like "click" and
- // "mouseover" or create custom events like "open" or "finish".
- // event:
- // An object that provides the properties for the event. See https://developer.mozilla.org/en/DOM/event.initEvent
- // for some of the properties. These properties are copied to the event object.
- // Of particular importance are the cancelable and bubbles properties. The
- // cancelable property indicates whether or not the event has a default action
- // that can be cancelled. The event is cancelled by calling preventDefault() on
- // the event object. The bubbles property indicates whether or not the
- // event will bubble up the DOM tree. If bubbles is true, the event will be called
- // on the target and then each parent successively until the top of the tree
- // is reached or stopPropagation() is called. Both bubbles and cancelable
- // default to false.
- // returns:
- // If the event is cancelable and the event is not cancelled,
- // emit will return true. If the event is cancelable and the event is cancelled,
- // emit will return false.
- // details:
- // Note that this is designed to emit events for listeners registered through
- // dojo/on. It should actually work with any event listener except those
- // added through IE's attachEvent (IE8 and below's non-W3C event emiting
- // doesn't support custom event types). It should work with all events registered
- // through dojo/on. Also note that the emit method does do any default
- // action, it only returns a value to indicate if the default action should take
- // place. For example, emiting a keypress event would not cause a character
- // to appear in a textbox.
- // example:
- // To fire our own click event
- // | on.emit(dojo.byId("button"), "click", {
- // | cancelable: true,
- // | bubbles: true,
- // | screenX: 33,
- // | screenY: 44
- // | });
- // We can also fire our own custom events:
- // | on.emit(dojo.byId("slider"), "slide", {
- // | cancelable: true,
- // | bubbles: true,
- // | direction: "left-to-right"
- // | });
- var args = slice.call(arguments, 2);
- var method = "on" + type;
- if("parentNode" in target){
- // node (or node-like), create event controller methods
- var newEvent = args[0] = {};
- for(var i in event){
- newEvent[i] = event[i];
- }
- newEvent.preventDefault = syntheticPreventDefault;
- newEvent.stopPropagation = syntheticStopPropagation;
- newEvent.target = target;
- newEvent.type = type;
- event = newEvent;
- }
- do{
- // call any node which has a handler (note that ideally we would try/catch to simulate normal event propagation but that causes too much pain for debugging)
- target[method] && target[method].apply(target, args);
- // and then continue up the parent node chain if it is still bubbling (if started as bubbles and stopPropagation hasn't been called)
- }while(event && event.bubbles && (target = target.parentNode));
- return event && event.cancelable && event; // if it is still true (was cancelable and was cancelled), return the event to indicate default action should happen
- };
- var captures = {};
- if(!has("event-stopimmediatepropagation")){
- var stopImmediatePropagation =function(){
- this.immediatelyStopped = true;
- this.modified = true; // mark it as modified so the event will be cached in IE
- };
- var addStopImmediate = function(listener){
- return function(event){
- if(!event.immediatelyStopped){// check to make sure it hasn't been stopped immediately
- event.stopImmediatePropagation = stopImmediatePropagation;
- return listener.apply(this, arguments);
- }
- };
- }
- }
- if(has("dom-addeventlistener")){
- // normalize focusin and focusout
- captures = {
- focusin: "focus",
- focusout: "blur"
- };
-
- // emiter that works with native event handling
- on.emit = function(target, type, event){
- if(target.dispatchEvent && document.createEvent){
- // use the native event emiting mechanism if it is available on the target object
- // create a generic event
- // we could create branch into the different types of event constructors, but
- // that would be a lot of extra code, with little benefit that I can see, seems
- // best to use the generic constructor and copy properties over, making it
- // easy to have events look like the ones created with specific initializers
- var nativeEvent = target.ownerDocument.createEvent("HTMLEvents");
- nativeEvent.initEvent(type, !!event.bubbles, !!event.cancelable);
- // and copy all our properties over
- for(var i in event){
- var value = event[i];
- if(!(i in nativeEvent)){
- nativeEvent[i] = event[i];
- }
- }
- return target.dispatchEvent(nativeEvent) && nativeEvent;
- }
- return syntheticDispatch.apply(on, arguments); // emit for a non-node
- };
- }else{
- // no addEventListener, basically old IE event normalization
- on._fixEvent = function(evt, sender){
- // summary:
- // normalizes properties on the event object including event
- // bubbling methods, keystroke normalization, and x/y positions
- // evt:
- // native event object
- // sender:
- // node to treat as "currentTarget"
- if(!evt){
- var w = sender && (sender.ownerDocument || sender.document || sender).parentWindow || window;
- evt = w.event;
- }
- if(!evt){return evt;}
- if(lastEvent && evt.type == lastEvent.type){
- // should be same event, reuse event object (so it can be augmented)
- evt = lastEvent;
- }
- if(!evt.target){ // check to see if it has been fixed yet
- evt.target = evt.srcElement;
- evt.currentTarget = (sender || evt.srcElement);
- if(evt.type == "mouseover"){
- evt.relatedTarget = evt.fromElement;
- }
- if(evt.type == "mouseout"){
- evt.relatedTarget = evt.toElement;
- }
- if(!evt.stopPropagation){
- evt.stopPropagation = stopPropagation;
- evt.preventDefault = preventDefault;
- }
- switch(evt.type){
- case "keypress":
- var c = ("charCode" in evt ? evt.charCode : evt.keyCode);
- if (c==10){
- // CTRL-ENTER is CTRL-ASCII(10) on IE, but CTRL-ENTER on Mozilla
- c=0;
- evt.keyCode = 13;
- }else if(c==13||c==27){
- c=0; // Mozilla considers ENTER and ESC non-printable
- }else if(c==3){
- c=99; // Mozilla maps CTRL-BREAK to CTRL-c
- }
- // Mozilla sets keyCode to 0 when there is a charCode
- // but that stops the event on IE.
- evt.charCode = c;
- _setKeyChar(evt);
- break;
- }
- }
- return evt;
- };
- var lastEvent, IESignal = function(handle){
- this.handle = handle;
- };
- IESignal.prototype.remove = function(){
- delete _dojoIEListeners_[this.handle];
- };
- var fixListener = function(listener){
- // this is a minimal function for closing on the previous listener with as few as variables as possible
- return function(evt){
- evt = on._fixEvent(evt, this);
- var result = listener.call(this, evt);
- if(evt.modified){
- // cache the last event and reuse it if we can
- if(!lastEvent){
- setTimeout(function(){
- lastEvent = null;
- });
- }
- lastEvent = evt;
- }
- return result;
- };
- };
- var fixAttach = function(target, type, listener){
- listener = fixListener(listener);
- if(((target.ownerDocument ? target.ownerDocument.parentWindow : target.parentWindow || target.window || window) != top ||
- has("jscript") < 5.8) &&
- !has("config-_allow_leaks")){
- // IE will leak memory on certain handlers in frames (IE8 and earlier) and in unattached DOM nodes for JScript 5.7 and below.
- // Here we use global redirection to solve the memory leaks
- if(typeof _dojoIEListeners_ == "undefined"){
- _dojoIEListeners_ = [];
- }
- var emiter = target[type];
- if(!emiter || !emiter.listeners){
- var oldListener = emiter;
- emiter = Function('event', 'var callee = arguments.callee; for(var i = 0; i<callee.listeners.length; i++){var listener = _dojoIEListeners_[callee.listeners[i]]; if(listener){listener.call(this,event);}}');
- emiter.listeners = [];
- target[type] = emiter;
- emiter.global = this;
- if(oldListener){
- emiter.listeners.push(_dojoIEListeners_.push(oldListener) - 1);
- }
- }
- var handle;
- emiter.listeners.push(handle = (emiter.global._dojoIEListeners_.push(listener) - 1));
- return new IESignal(handle);
- }
- return aspect.after(target, type, listener, true);
- };
-
- var _setKeyChar = function(evt){
- evt.keyChar = evt.charCode ? String.fromCharCode(evt.charCode) : '';
- evt.charOrCode = evt.keyChar || evt.keyCode;
- };
- // Called in Event scope
- var stopPropagation = function(){
- this.cancelBubble = true;
- };
- var preventDefault = on._preventDefault = function(){
- // Setting keyCode to 0 is the only way to prevent certain keypresses (namely
- // ctrl-combinations that correspond to menu accelerator keys).
- // Otoh, it prevents upstream listeners from getting this information
- // Try to split the difference here by clobbering keyCode only for ctrl
- // combinations. If you still need to access the key upstream, bubbledKeyCode is
- // provided as a workaround.
- this.bubbledKeyCode = this.keyCode;
- if(this.ctrlKey){
- try{
- // squelch errors when keyCode is read-only
- // (e.g. if keyCode is ctrl or shift)
- this.keyCode = 0;
- }catch(e){
- }
- }
- this.defaultPrevented = true;
- this.returnValue = false;
- };
- }
- if(has("touch")){
- var Event = function(){};
- var windowOrientation = window.orientation;
- var fixTouchListener = function(listener){
- return function(originalEvent){
- //Event normalization(for ontouchxxx and resize):
- //1.incorrect e.pageX|pageY in iOS
- //2.there are no "e.rotation", "e.scale" and "onorientationchange" in Andriod
- //3.More TBD e.g. force | screenX | screenX | clientX | clientY | radiusX | radiusY
-
- // see if it has already been corrected
- var event = originalEvent.corrected;
- if(!event){
- var type = originalEvent.type;
- try{
- delete originalEvent.type; // on some JS engines (android), deleting properties make them mutable
- }catch(e){}
- if(originalEvent.type){
- // deleting properties doesn't work (older iOS), have to use delegation
- Event.prototype = originalEvent;
- var event = new Event;
- // have to delegate methods to make them work
- event.preventDefault = function(){
- originalEvent.preventDefault();
- };
- event.stopPropagation = function(){
- originalEvent.stopPropagation();
- };
- }else{
- // deletion worked, use property as is
- event = originalEvent;
- event.type = type;
- }
- originalEvent.corrected = event;
- if(type == 'resize'){
- if(windowOrientation == window.orientation){
- return null;//double tap causes an unexpected 'resize' in Andriod
- }
- windowOrientation = window.orientation;
- event.type = "orientationchange";
- return listener.call(this, event);
- }
- // We use the original event and augment, rather than doing an expensive mixin operation
- if(!("rotation" in event)){ // test to see if it has rotation
- event.rotation = 0;
- event.scale = 1;
- }
- //use event.changedTouches[0].pageX|pageY|screenX|screenY|clientX|clientY|target
- var firstChangeTouch = event.changedTouches[0];
- for(var i in firstChangeTouch){ // use for-in, we don't need to have dependency on dojo/_base/lang here
- delete event[i]; // delete it first to make it mutable
- event[i] = firstChangeTouch[i];
- }
- }
- return listener.call(this, event);
- };
- };
- }
- return on;
-});