Permalink
Browse files

event tests and docs, observable and gesture docs, minor fixes

  • Loading branch information...
1 parent a9ea0f4 commit fac08188ca433a476a6d9414378106d557aed3f7 @voloko committed Mar 12, 2011
View
@@ -11,12 +11,12 @@ Install {node and npm}[https://github.com/joyent/node/wiki/Installation]
node express.js
= Goals for 0.4
-* Keep core to bare minimum. Should be under 10KB gziped. Ideally under 9216b (9KB).
+* Keep core to bare minimum. Should be under 10KB gziped..
* Keep core and common view pack under 30KB gziped.
* Use css instead of js based themes.
* Data Model and Bindings in the core.
* Use native browser layout instead of rect() + layout()
-* CommonJs require() instead of homegrown include()
+* CommonJS require() instead of homegrown include()
* Use serverside/clientside js together
* `npm install uki-pack` should work on client side without any extra configuration
* Docs
View
@@ -0,0 +1,95 @@
+## Event
+
+Handle native and surrogate dom events.
+
+### evt.EventMethods
+
+Mixin added to all the events.
+
+### evt.EventMethods.targetView()
+
+Returns the closest view to event `target`. Same as native `event.target` but
+instead of a dom node will return an instance of view. May be optionally overridden by
+setting `_targetView` property. May return null if no view is found.
+
+### evt.EventMethods.simulateBubbles = false
+
+[Experimental]. Can be used on surrogate events to make it bubble through dom nodes.
+
+ evt.createEvent({ type: 'selection', simulateBubbles: true });
+
+### evt.EventMethods.preventDefault()
+
+Cross browser preventDefault. Works on surrogate events also.
+
+### evt.EventMethods.stopPropagation()
+
+Cross browser stopPropagation. Works on surrogate events also.
+
+### evt.EventMethods.isDefaultPrevented()
+
+Works cross browser and on surrogate events.
+
+### evt.EventMethods.isPropagationStopped()
+
+Works cross browser and on surrogate events.
+
+### evt.createEvent(baseEvent, [options])
+
+Creates an out of `baseEvent` description. Extends the result with
+`options` if provided.
+
+ evt.createEvent({ type: 'click' });
+
+Returns an object with API of `evt.EventMethods`. `baseEvent` will be
+accessible through `e.baseEvent`.
+
+### evt.wrapDomEvent(baseEvent)
+
+Wraps a dom event so it supports `evt.EventMethods` api. It's reasonably safe
+to write to wrapped event properties:
+
+ e = evt.wrapDomEvent(e)
+ e.type = 'draggesture';
+
+Original event is accessible through `e.baseEvent`.
+Used to create special events. Like `mousenter` or `draggesturestart`.
+
+### evt.special = {}
+
+An object holding handlers for special event types. See implementation of `mousenter`,
+`mouseleave` to understand how it works.
+
+### evt.trigger(element, e)
+
+Triggers a dom/surrogate event on `element`. `e` should conform to `evt.EventMethods`
+API and at least have `type`:
+
+ evt.trigger(domNode, evt.createEvent({ type: 'click' }))
+
+
+### evt.addListener(element, types, listener)
+### evt.on(element, types, listener)
+
+Ads event `listener` for `types` to `element`. `types` can be a space separated string:
+
+ evt.on(domNode, 'blur mouseup', function() {});
+
+### evt.removeListner(element, [types], [listener])
+
+Removes event `listener` for `types` from `element`. `types` can be a space separated string.
+If `listener` if not provided will remove all `listeners` for given types. If `types` is
+not provided will remove all events from `element`. Useful in destruct.
+
+ // remove all click handler for blur and mouseup
+ evt.removeListener(domNode, 'blur mouseup', function() {});
+ // remove all click handlers
+ evt.removeListener(domNode, 'click');
+ // remove all handlers
+ evt.removeListener(domNode);
+
+### evt.preventDefaultHandler
+
+Helper function to prevent event default.
+
+ evt.on(dom, 'dragstart', evt.preventDefaultHandler);
View
@@ -0,0 +1,19 @@
+## Gesture
+
+Ads support for `draggesturestart`, `draggesturestop` and `draggesture` events.
+
+ evt.on(handle, 'draggesturestart', function() {
+ console.log('start dragging');
+
+ // set body cursor while dragging
+ e.cursor = 'row-resize';
+ });
+
+ evt.on(handle, 'draggesture', function(e) {
+ console.log('moved to', e.dragOffset);
+ console.log(gesture.draggable === handle);
+ });
+
+ evt.on(handle, 'draggesturestop', function(e) {
+ console.log('stopped dragging');
+ });
@@ -0,0 +1,59 @@
+## Observable
+
+Mixin to make an object observable. So you can `addListener` and `trigger` on this object.
+
+### Observable.addListener(types, listener)
+### Observable.on(types, listener)
+
+Ads event `listener` for `types`. `types` can be a space separated string:
+
+ obj.on('selection blur', function() {});
+
+### Observable.removeListner(types, listener)
+
+Removes event `listener` for `types`. `types` can be a space separated string.
+If `listener` if not provided will remove all `listeners` for given types. If `types` is
+not provided will remove all events from `element`. Useful in destruct.
+
+ // remove all listener
+ obj.removeListener();
+
+### Observable.trigger(e)
+
+Triggers a surrogate event on this. `e` at least have `type`. It will not bubble and cannot be
+prevent.
+
+ obj.trigger({ type: 'change' });
+
+### Observable.destruct
+
+Removes all listeners from this.
+
+### Observable.triggerChanges(name, source)
+
+Generates `change` and `change.name` events. Used in bindings to observe data.
+See also `Observable.newProp`.
+
+### Observable.muteEvents(state)
+
+Experimental. Mutes all events on a given object.
+
+ obj.muteEvents(true)
+ // will not work
+ obj.trigger({ type: 'change' });
+ obj.muteEvents(false);
+
+### Observable.newProp(name, [setter])
+
+Conforms to `fun.newProp` API. When property is changed `change` events will be triggered.
+
+ var Klass = fun.newClass(Observable, {
+ name: Observable.newProp(name)
+ });
+
+ var obj = new Klass();
+ obj.on('change.name', function() {
+ alert('name changed');
+ });
+ // will trigger handler
+ obj.name('Bob');
@@ -0,0 +1,3 @@
+### Base view
+
+Default API for all views.
View
@@ -113,13 +113,13 @@ exports.reduceRight = function(fun, accumulator) {
exports.keys = function(o) {
var ret = [], p;
for (p in o) {
- if (o.hasOwnProperty.call(p)) {
+ if (o.hasOwnProperty(p)) {
ret.push(p);
}
}
return ret;
};
-exports.trim = function(s) {
- return s.replace(/^\s*|\s*$/g, "");
+exports.trim = function() {
+ return this.replace(/^\s*|\s*$/g, "");
};
View
@@ -9,7 +9,10 @@ function EventWrapper () {}
var EventMethods = {
targetView: function() {
- return require('./view').closest(this.target);
+ if (!this._targetView) {
+ this._targetView = require('./view').closest(this.target);
+ }
+ return this._targetView;
},
simulateBubbles: false,
@@ -119,7 +122,7 @@ var eventProps = "altKey attrChange attrName bubbles button cancelable charCode
function domHandler(e) {
e = e || env.root.event;
var wrapped = wrapDomEvent(e);
- evt.trigger.call(this, normalize(wrapped));
+ evt.trigger(this, normalize(wrapped));
}
function wrapDomEvent(baseEvent) {
@@ -142,7 +145,7 @@ function createEvent(baseEvent, options) {
// from base event.
EventWrapper.prototype = baseEvent;
e = new EventWrapper();
- utils.extend(e.prototype, EventMethods);
+ utils.extend(e, EventMethods);
e.baseEvent = baseEvent;
utils.extend(e, options);
return e;
@@ -159,17 +162,21 @@ var evt = module.exports = {
listeners: listeners,
domHandlers: domHandlers,
+
+ EventMethods: EventMethods,
- trigger: function(e) {
- var listenerForEl = evt.listeners[this[expando]] || {},
+ trigger: function(el, e) {
+ var listenerForEl = evt.listeners[el[expando]] || {},
listenersForType = listenerForEl[e.type];
+
+ if (!e.target) { e.target = el; }
listenersForType && utils.forEach(listenersForType, function(l) {
- l.call(this, e);
- }, this);
+ l.call(el, e);
+ });
- if (e.simulateBubbles && !e.isPropagationStopped() && this.parentNode) {
- evt.trigger(this.parentNode, e);
+ if (e.simulateBubbles && !e.isPropagationStopped() && el.parentNode) {
+ evt.trigger(el.parentNode, e);
}
},
@@ -240,7 +247,7 @@ utils.forEach({
if (parent !== this) {
var wrapped = createEvent(e, { type: specialName, simulateBubbling: true });
- evt.trigger.call(this, wrapped);
+ evt.trigger(this, wrapped);
}
} catch(e) { }
}
View
@@ -60,7 +60,7 @@ function stopGesture () {
function dragGestureStart (e) {
e = evt.createEvent(e, {type: 'draggesturestart'});
- evt.trigger.call(this, e);
+ evt.trigger(this, e);
if (!e.isDefaultPrevented()) {
gesture.position = { x: e.pageX, y: e.pageY };
startGesture(this, e);
@@ -73,7 +73,7 @@ function dragGesture (e) {
x: e.pageX - gesture.position.x,
y: e.pageY - gesture.position.y
};
- evt.trigger.call(gesture.draggable, e);
+ evt.trigger(gesture.draggable, e);
if (e.isDefaultPrevented()) stopGesture(gesture.draggable);
}
@@ -84,7 +84,7 @@ function dragGestureEnd (e) {
x: e.pageX - gesture.position.x,
y: e.pageY - gesture.position.y
};
- evt.trigger.call(gesture.draggable, e);
+ evt.trigger(gesture.draggable, e);
stopGesture(gesture.draggable);
}
Oops, something went wrong.

0 comments on commit fac0818

Please sign in to comment.