Comparing version 0.2.8 to 0.2.9
217
jymin.js
/** | ||
* _ _ ___ ____ ___ | ||
* | |_ _ _ __ ___ (_)_ __ __ __/ _ \ |___ \ ( _ ) | ||
* _ | | | | | '_ ` _ \| | '_ \ \ \ / / | | | __) | / _ \ | ||
* | |_| | |_| | | | | | | | | | | \ V /| |_| | / __/ | (_) | | ||
* \___/ \__, |_| |_| |_|_|_| |_| \_/ \___(_)_____(_)___/ | ||
* _ _ ___ ____ ___ | ||
* | |_ _ _ __ ___ (_)_ __ __ __/ _ \ |___ \ / _ \ | ||
* _ | | | | | '_ ` _ \| | '_ \ \ \ / / | | | __) | (_) | | ||
* | |_| | |_| | | | | | | | | | | \ V /| |_| | / __/ \__, | | ||
* \___/ \__, |_| |_| |_|_|_| |_| \_/ \___(_)_____(_)/_/ | ||
* |___/ | ||
@@ -33,3 +33,3 @@ * | ||
this.jymin = {version: '0.2.8'}; | ||
this.jymin = {version: '0.2.9'}; | ||
@@ -424,3 +424,2 @@ /** | ||
} | ||
// If the argument is not a string, just assume it's already an element reference, and return it. | ||
return isString(id) ? parentElement.getElementById(id) : id; | ||
@@ -738,2 +737,53 @@ }; | ||
/** | ||
* Get an attribute from a DOM element, if it can be found. | ||
*/ | ||
var getAttribute = function ( | ||
element, | ||
attributeName | ||
) { | ||
// Ensure that we have an element, not just an ID. | ||
element = getElement(element); | ||
if (element) { | ||
return element.getAttribute(attributeName); | ||
} | ||
}; | ||
/** | ||
* Set an attribute on a DOM element, if it can be found. | ||
*/ | ||
var setAttribute = function ( | ||
element, | ||
attributeName, | ||
value | ||
) { | ||
// Ensure that we have an element, not just an ID. | ||
element = getElement(element); | ||
if (element) { | ||
// Set the element's innerText. | ||
element.setAttribute(attributeName, value); | ||
} | ||
}; | ||
/** | ||
* Get a data attribute from a DOM element. | ||
*/ | ||
var getData = function ( | ||
element, | ||
dataKey | ||
) { | ||
return getAttribute(element, 'data-' + dataKey); | ||
}; | ||
/** | ||
* Set a data attribute on a DOM element. | ||
*/ | ||
var setData = function ( | ||
element, | ||
dataKey, | ||
value | ||
) { | ||
setAttribute(element, 'data-' + dataKey, value); | ||
}; | ||
/** | ||
* Get a DOM element's class name if the element can be found. | ||
@@ -933,4 +983,14 @@ */ | ||
else if (selector[0] == '#') { | ||
var element = getElement(parentElement, selector.substr(1)); | ||
elements = element ? [element] : []; | ||
var id = selector.substr(1); | ||
var child = getElement(parentElement.ownerDocument || document, id); | ||
if (child) { | ||
var parent = getParent(child); | ||
while (parent) { | ||
if (parent === parentElement) { | ||
elements = [child]; | ||
break; | ||
} | ||
parent = getParent(parent); | ||
} | ||
} | ||
} | ||
@@ -943,3 +1003,3 @@ else { | ||
} | ||
return elements; | ||
return elements || []; | ||
}; | ||
@@ -964,4 +1024,3 @@ | ||
eventHandler, // function: Function to run when the event is triggered. `eventHandler(element, event, target, customData)` | ||
customData, // object|: Custom data to pass through to the event handler when it's triggered. | ||
multiBindCustomData | ||
customData // object|: Custom data to pass through to the event handler when it's triggered. | ||
) { | ||
@@ -972,3 +1031,3 @@ // Allow multiple events to be bound at once using a space-delimited string. | ||
forEach(eventNames, function (singleEventName) { | ||
bind(element, singleEventName, eventHandler, customData, multiBindCustomData); | ||
bind(element, singleEventName, eventHandler, customData); | ||
}); | ||
@@ -1000,3 +1059,6 @@ return; | ||
} | ||
return eventHandler(element, event, target, multiBindCustomData || customData); | ||
var result = eventHandler(element, event, target, customData); | ||
if (result === false) { | ||
preventDefault(event); | ||
} | ||
}; | ||
@@ -1022,2 +1084,53 @@ | ||
/** | ||
* Bind an event handler on an element that delegates to specified child elements. | ||
*/ | ||
var on = function ( | ||
element, | ||
selector, // Supports "tag.class,tag.class" but does not support nesting. | ||
eventName, | ||
eventHandler, | ||
customData | ||
) { | ||
// If there's no parent element, assume it's the document. | ||
if (isFunction(eventName)) { | ||
customData = eventHandler; | ||
eventHandler = eventName; | ||
eventName = selector; | ||
selector = element; | ||
element = document; | ||
} | ||
var parts = selector.split(','); | ||
var onHandler = function(element, event, target, customData) { | ||
forEach(parts, function (part) { | ||
var found = false; | ||
if ((part[0] == '#') && part == target.id) { | ||
found = true; | ||
} | ||
else { | ||
var tagAndClass = part.split('.'); | ||
var tagName = tagAndClass[0].toUpperCase(); | ||
var className = tagAndClass[1]; | ||
if (!tagName || (target.tagName == tagName)) { | ||
if (!className || hasClass(target, className)) { | ||
found = true; | ||
} | ||
} | ||
} | ||
if (found) { | ||
var result = eventHandler(target, event, element, customData); | ||
if (result === false) { | ||
preventDefault(event); | ||
} | ||
} | ||
}); | ||
// Bubble up to find a selector match because we didn't find one this time. | ||
target = getParent(target); | ||
if (target) { | ||
onHandler(element, event, target, customData); | ||
} | ||
}; | ||
bind(element, eventName, onHandler, customData); | ||
}; | ||
/** | ||
* Trigger an element event. | ||
@@ -1035,9 +1148,13 @@ */ | ||
if (!target) { | ||
customData = target; | ||
target = element; | ||
} | ||
customData = customData || {}; | ||
customData._TRIGGERED = true; | ||
var handlers = element._HANDLERS; | ||
if (handlers) { | ||
var queue = handlers[event.type]; | ||
forEach(queue, function (callback) { | ||
callback(element, event, target, customData); | ||
forEach(queue, function (handler) { | ||
handler(element, event, target, customData); | ||
}); | ||
@@ -1059,6 +1176,13 @@ } | ||
) { | ||
event.cancelBubble = true; | ||
if (event.stopPropagation) { | ||
event.stopPropagation(); | ||
if (event) { | ||
event.cancelBubble = true; | ||
if (event.stopPropagation) { | ||
event.stopPropagation(); | ||
} | ||
} | ||
//+env:debug | ||
else { | ||
error('[Jymin] Called stopPropagation on a non-event.', event); | ||
} | ||
//-env:debug | ||
}; | ||
@@ -1072,3 +1196,12 @@ | ||
) { | ||
event.preventDefault(); | ||
if (event) { | ||
if (event.preventDefault) { | ||
event.preventDefault(); | ||
} | ||
} | ||
//+env:debug | ||
else { | ||
error('[Jymin] Called preventDefault on a non-event.', event); | ||
} | ||
//-env:debug | ||
}; | ||
@@ -1104,31 +1237,2 @@ | ||
/** | ||
* Bind an event handler on an element that delegates to specified child elements. | ||
*/ | ||
var on = function ( | ||
element, | ||
tagAndClass, | ||
eventName, | ||
eventHandler, | ||
customData, | ||
multiBindCustomData | ||
) { | ||
tagAndClass = tagAndClass.split('.'); | ||
var tagName = tagAndClass[0].toUpperCase(); | ||
var className = tagAndClass[1]; | ||
var onHandler = function(element, event, target, customData) { | ||
if (!tagName || (target.tagName == tagName)) { | ||
if (!className || hasClass(target, className)) { | ||
return eventHandler(target, event, element, multiBindCustomData || customData); | ||
} | ||
} | ||
// Bubble up to find a tagAndClass match because we didn't find one this time. | ||
target = getParent(target); | ||
if (target) { | ||
onHandler(element, event, target, customData); | ||
} | ||
}; | ||
bind(element, eventName, onHandler, customData); | ||
}; | ||
/** | ||
* Bind an event handler for both the mouseenter and mouseleave events. | ||
@@ -1201,5 +1305,10 @@ */ | ||
var focusMethod = element.focus; | ||
if (focusMethod) { | ||
if (isFunction(focusMethod)) { | ||
focusMethod.call(element); | ||
} | ||
else { | ||
//+env:debug | ||
error('[Jymin] Element does not exist, or has no focus method', element); | ||
//-env:debug | ||
} | ||
} | ||
@@ -1543,3 +1652,3 @@ }; | ||
var onReady = window._ON_READY = function ( | ||
callback | ||
callbackOrElement | ||
) { | ||
@@ -1550,3 +1659,3 @@ // If there's no queue, create it as a property of this function. | ||
// If there's a callback, push it into the queue. | ||
if (callback) { | ||
if (typeof callbackOrElement == 'function') { | ||
@@ -1571,3 +1680,3 @@ // The 1st callback makes schedules onReady, if not waiting for scripts. | ||
// Put an item in the queue and wait. | ||
push(queue, callback); | ||
push(queue, callbackOrElement); | ||
} | ||
@@ -1578,3 +1687,3 @@ | ||
forEach(queue, function (callback) { | ||
callback(); | ||
callback(callbackOrElement || document); | ||
}); | ||
@@ -1581,0 +1690,0 @@ } |
@@ -15,3 +15,3 @@ { | ||
], | ||
"version": "0.2.8", | ||
"version": "0.2.9", | ||
"main": "chug/chug.js", | ||
@@ -18,0 +18,0 @@ "homepage": "http://lighter.io/jymin", |
@@ -14,3 +14,2 @@ /** | ||
} | ||
// If the argument is not a string, just assume it's already an element reference, and return it. | ||
return isString(id) ? parentElement.getElementById(id) : id; | ||
@@ -328,2 +327,53 @@ }; | ||
/** | ||
* Get an attribute from a DOM element, if it can be found. | ||
*/ | ||
var getAttribute = function ( | ||
element, | ||
attributeName | ||
) { | ||
// Ensure that we have an element, not just an ID. | ||
element = getElement(element); | ||
if (element) { | ||
return element.getAttribute(attributeName); | ||
} | ||
}; | ||
/** | ||
* Set an attribute on a DOM element, if it can be found. | ||
*/ | ||
var setAttribute = function ( | ||
element, | ||
attributeName, | ||
value | ||
) { | ||
// Ensure that we have an element, not just an ID. | ||
element = getElement(element); | ||
if (element) { | ||
// Set the element's innerText. | ||
element.setAttribute(attributeName, value); | ||
} | ||
}; | ||
/** | ||
* Get a data attribute from a DOM element. | ||
*/ | ||
var getData = function ( | ||
element, | ||
dataKey | ||
) { | ||
return getAttribute(element, 'data-' + dataKey); | ||
}; | ||
/** | ||
* Set a data attribute on a DOM element. | ||
*/ | ||
var setData = function ( | ||
element, | ||
dataKey, | ||
value | ||
) { | ||
setAttribute(element, 'data-' + dataKey, value); | ||
}; | ||
/** | ||
* Get a DOM element's class name if the element can be found. | ||
@@ -523,4 +573,14 @@ */ | ||
else if (selector[0] == '#') { | ||
var element = getElement(parentElement, selector.substr(1)); | ||
elements = element ? [element] : []; | ||
var id = selector.substr(1); | ||
var child = getElement(parentElement.ownerDocument || document, id); | ||
if (child) { | ||
var parent = getParent(child); | ||
while (parent) { | ||
if (parent === parentElement) { | ||
elements = [child]; | ||
break; | ||
} | ||
parent = getParent(parent); | ||
} | ||
} | ||
} | ||
@@ -533,3 +593,3 @@ else { | ||
} | ||
return elements; | ||
return elements || []; | ||
}; | ||
@@ -536,0 +596,0 @@ |
@@ -8,4 +8,3 @@ /** | ||
eventHandler, // function: Function to run when the event is triggered. `eventHandler(element, event, target, customData)` | ||
customData, // object|: Custom data to pass through to the event handler when it's triggered. | ||
multiBindCustomData | ||
customData // object|: Custom data to pass through to the event handler when it's triggered. | ||
) { | ||
@@ -16,3 +15,3 @@ // Allow multiple events to be bound at once using a space-delimited string. | ||
forEach(eventNames, function (singleEventName) { | ||
bind(element, singleEventName, eventHandler, customData, multiBindCustomData); | ||
bind(element, singleEventName, eventHandler, customData); | ||
}); | ||
@@ -44,3 +43,6 @@ return; | ||
} | ||
return eventHandler(element, event, target, multiBindCustomData || customData); | ||
var result = eventHandler(element, event, target, customData); | ||
if (result === false) { | ||
preventDefault(event); | ||
} | ||
}; | ||
@@ -66,2 +68,53 @@ | ||
/** | ||
* Bind an event handler on an element that delegates to specified child elements. | ||
*/ | ||
var on = function ( | ||
element, | ||
selector, // Supports "tag.class,tag.class" but does not support nesting. | ||
eventName, | ||
eventHandler, | ||
customData | ||
) { | ||
// If there's no parent element, assume it's the document. | ||
if (isFunction(eventName)) { | ||
customData = eventHandler; | ||
eventHandler = eventName; | ||
eventName = selector; | ||
selector = element; | ||
element = document; | ||
} | ||
var parts = selector.split(','); | ||
var onHandler = function(element, event, target, customData) { | ||
forEach(parts, function (part) { | ||
var found = false; | ||
if ((part[0] == '#') && part == target.id) { | ||
found = true; | ||
} | ||
else { | ||
var tagAndClass = part.split('.'); | ||
var tagName = tagAndClass[0].toUpperCase(); | ||
var className = tagAndClass[1]; | ||
if (!tagName || (target.tagName == tagName)) { | ||
if (!className || hasClass(target, className)) { | ||
found = true; | ||
} | ||
} | ||
} | ||
if (found) { | ||
var result = eventHandler(target, event, element, customData); | ||
if (result === false) { | ||
preventDefault(event); | ||
} | ||
} | ||
}); | ||
// Bubble up to find a selector match because we didn't find one this time. | ||
target = getParent(target); | ||
if (target) { | ||
onHandler(element, event, target, customData); | ||
} | ||
}; | ||
bind(element, eventName, onHandler, customData); | ||
}; | ||
/** | ||
* Trigger an element event. | ||
@@ -79,9 +132,13 @@ */ | ||
if (!target) { | ||
customData = target; | ||
target = element; | ||
} | ||
customData = customData || {}; | ||
customData._TRIGGERED = true; | ||
var handlers = element._HANDLERS; | ||
if (handlers) { | ||
var queue = handlers[event.type]; | ||
forEach(queue, function (callback) { | ||
callback(element, event, target, customData); | ||
forEach(queue, function (handler) { | ||
handler(element, event, target, customData); | ||
}); | ||
@@ -103,6 +160,13 @@ } | ||
) { | ||
event.cancelBubble = true; | ||
if (event.stopPropagation) { | ||
event.stopPropagation(); | ||
if (event) { | ||
event.cancelBubble = true; | ||
if (event.stopPropagation) { | ||
event.stopPropagation(); | ||
} | ||
} | ||
//+env:debug | ||
else { | ||
error('[Jymin] Called stopPropagation on a non-event.', event); | ||
} | ||
//-env:debug | ||
}; | ||
@@ -116,3 +180,12 @@ | ||
) { | ||
event.preventDefault(); | ||
if (event) { | ||
if (event.preventDefault) { | ||
event.preventDefault(); | ||
} | ||
} | ||
//+env:debug | ||
else { | ||
error('[Jymin] Called preventDefault on a non-event.', event); | ||
} | ||
//-env:debug | ||
}; | ||
@@ -148,31 +221,2 @@ | ||
/** | ||
* Bind an event handler on an element that delegates to specified child elements. | ||
*/ | ||
var on = function ( | ||
element, | ||
tagAndClass, | ||
eventName, | ||
eventHandler, | ||
customData, | ||
multiBindCustomData | ||
) { | ||
tagAndClass = tagAndClass.split('.'); | ||
var tagName = tagAndClass[0].toUpperCase(); | ||
var className = tagAndClass[1]; | ||
var onHandler = function(element, event, target, customData) { | ||
if (!tagName || (target.tagName == tagName)) { | ||
if (!className || hasClass(target, className)) { | ||
return eventHandler(target, event, element, multiBindCustomData || customData); | ||
} | ||
} | ||
// Bubble up to find a tagAndClass match because we didn't find one this time. | ||
target = getParent(target); | ||
if (target) { | ||
onHandler(element, event, target, customData); | ||
} | ||
}; | ||
bind(element, eventName, onHandler, customData); | ||
}; | ||
/** | ||
* Bind an event handler for both the mouseenter and mouseleave events. | ||
@@ -245,5 +289,10 @@ */ | ||
var focusMethod = element.focus; | ||
if (focusMethod) { | ||
if (isFunction(focusMethod)) { | ||
focusMethod.call(element); | ||
} | ||
else { | ||
//+env:debug | ||
error('[Jymin] Element does not exist, or has no focus method', element); | ||
//-env:debug | ||
} | ||
} | ||
@@ -250,0 +299,0 @@ }; |
@@ -5,3 +5,3 @@ /** | ||
var onReady = window._ON_READY = function ( | ||
callback | ||
callbackOrElement | ||
) { | ||
@@ -12,3 +12,3 @@ // If there's no queue, create it as a property of this function. | ||
// If there's a callback, push it into the queue. | ||
if (callback) { | ||
if (typeof callbackOrElement == 'function') { | ||
@@ -33,3 +33,3 @@ // The 1st callback makes schedules onReady, if not waiting for scripts. | ||
// Put an item in the queue and wait. | ||
push(queue, callback); | ||
push(queue, callbackOrElement); | ||
} | ||
@@ -40,5 +40,5 @@ | ||
forEach(queue, function (callback) { | ||
callback(); | ||
callback(callbackOrElement || document); | ||
}); | ||
} | ||
}; |
102652
3834