You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

574 lines
12 KiB

14 years ago
// MooTools: the javascript framework.
// Load this file's selection again by visiting: http://mootools.net/more/452f2740e09082a2109bec9f69fbf8dc
// Or build this file again with packager using: packager build More/URI More/Element.Delegation More/Element.Shortcuts
/*
---
script: More.js
name: More
description: MooTools More
license: MIT-style license
authors:
- Guillermo Rauch
- Thomas Aylott
- Scott Kyle
- Arian Stolwijk
- Tim Wienk
- Christoph Pojer
- Aaron Newton
requires:
- Core/MooTools
provides: [MooTools.More]
...
*/
MooTools.More = {
'version': '1.3.0.1',
'build': '6dce99bed2792dffcbbbb4ddc15a1fb9a41994b5'
};
/*
---
script: String.QueryString.js
name: String.QueryString
description: Methods for dealing with URI query strings.
license: MIT-style license
authors:
- Sebastian Markbåge
- Aaron Newton
- Lennart Pilon
- Valerio Proietti
requires:
- Core/Array
- Core/String
- /MooTools.More
provides: [String.QueryString]
...
*/
String.implement({
parseQueryString: function(decodeKeys, decodeValues){
if (decodeKeys == null) decodeKeys = true;
if (decodeValues == null) decodeValues = true;
var vars = this.split(/[&;]/),
object = {};
if (!vars.length) return object;
vars.each(function(val){
var index = val.indexOf('='),
value = val.substr(index + 1),
keys = index < 0 ? [''] : val.substr(0, index).match(/([^\]\[]+|(\B)(?=\]))/g),
obj = object;
if (decodeValues) value = decodeURIComponent(value);
keys.each(function(key, i){
if (decodeKeys) key = decodeURIComponent(key);
var current = obj[key];
if (i < keys.length - 1) obj = obj[key] = current || {};
else if (typeOf(current) == 'array') current.push(value);
else obj[key] = current != null ? [current, value] : value;
});
});
return object;
},
cleanQueryString: function(method){
return this.split('&').filter(function(val){
var index = val.indexOf('='),
key = index < 0 ? '' : val.substr(0, index),
value = val.substr(index + 1);
return method ? method.call(null, key, value) : (value || value === 0);
}).join('&');
}
});
/*
---
script: URI.js
name: URI
description: Provides methods useful in managing the window location and uris.
license: MIT-style license
authors:
- Sebastian Markbåge
- Aaron Newton
requires:
- Core/Object
- Core/Class
- Core/Class.Extras
- Core/Element
- /String.QueryString
provides: [URI]
...
*/
(function(){
var toString = function(){
return this.get('value');
};
var URI = this.URI = new Class({
Implements: Options,
options: {
/*base: false*/
},
regex: /^(?:(\w+):)?(?:\/\/(?:(?:([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?)?(\.\.?$|(?:[^?#\/]*\/)*)([^?#]*)(?:\?([^#]*))?(?:#(.*))?/,
parts: ['scheme', 'user', 'password', 'host', 'port', 'directory', 'file', 'query', 'fragment'],
schemes: {http: 80, https: 443, ftp: 21, rtsp: 554, mms: 1755, file: 0},
initialize: function(uri, options){
this.setOptions(options);
var base = this.options.base || URI.base;
if (!uri) uri = base;
if (uri && uri.parsed) this.parsed = Object.clone(uri.parsed);
else this.set('value', uri.href || uri.toString(), base ? new URI(base) : false);
},
parse: function(value, base){
var bits = value.match(this.regex);
if (!bits) return false;
bits.shift();
return this.merge(bits.associate(this.parts), base);
},
merge: function(bits, base){
if ((!bits || !bits.scheme) && (!base || !base.scheme)) return false;
if (base){
this.parts.every(function(part){
if (bits[part]) return false;
bits[part] = base[part] || '';
return true;
});
}
bits.port = bits.port || this.schemes[bits.scheme.toLowerCase()];
bits.directory = bits.directory ? this.parseDirectory(bits.directory, base ? base.directory : '') : '/';
return bits;
},
parseDirectory: function(directory, baseDirectory){
directory = (directory.substr(0, 1) == '/' ? '' : (baseDirectory || '/')) + directory;
if (!directory.test(URI.regs.directoryDot)) return directory;
var result = [];
directory.replace(URI.regs.endSlash, '').split('/').each(function(dir){
if (dir == '..' && result.length > 0) result.pop();
else if (dir != '.') result.push(dir);
});
return result.join('/') + '/';
},
combine: function(bits){
return bits.value || bits.scheme + '://' +
(bits.user ? bits.user + (bits.password ? ':' + bits.password : '') + '@' : '') +
(bits.host || '') + (bits.port && bits.port != this.schemes[bits.scheme] ? ':' + bits.port : '') +
(bits.directory || '/') + (bits.file || '') +
(bits.query ? '?' + bits.query : '') +
(bits.fragment ? '#' + bits.fragment : '');
},
set: function(part, value, base){
if (part == 'value'){
var scheme = value.match(URI.regs.scheme);
if (scheme) scheme = scheme[1];
if (scheme && this.schemes[scheme.toLowerCase()] == null) this.parsed = { scheme: scheme, value: value };
else this.parsed = this.parse(value, (base || this).parsed) || (scheme ? { scheme: scheme, value: value } : { value: value });
} else if (part == 'data'){
this.setData(value);
} else {
this.parsed[part] = value;
}
return this;
},
get: function(part, base){
switch(part){
case 'value': return this.combine(this.parsed, base ? base.parsed : false);
case 'data' : return this.getData();
}
return this.parsed[part] || '';
},
go: function(){
document.location.href = this.toString();
},
toURI: function(){
return this;
},
getData: function(key, part){
var qs = this.get(part || 'query');
if (!(qs || qs === 0)) return key ? null : {};
var obj = qs.parseQueryString();
return key ? obj[key] : obj;
},
setData: function(values, merge, part){
if (typeof values == 'string'){
var data = this.getData();
data[arguments[0]] = arguments[1];
values = data;
} else if (merge){
values = Object.merge(this.getData(), values);
}
return this.set(part || 'query', Object.toQueryString(values));
},
clearData: function(part){
return this.set(part || 'query', '');
},
toString: toString,
valueOf: toString
});
URI.regs = {
endSlash: /\/$/,
scheme: /^(\w+):/,
directoryDot: /\.\/|\.$/
};
URI.base = new URI(Array.from(document.getElements('base[href]', true)).getLast(), {base: document.location});
String.implement({
toURI: function(options){
return new URI(this, options);
}
});
})();
/*
---
name: Events.Pseudos
description: Adds the functionallity to add pseudo events
license: MIT-style license
authors:
- Arian Stolwijk
requires: [Core/Class.Extras, Core/Slick.Parser, More/MooTools.More]
provides: [Events.Pseudos]
...
*/
Events.Pseudos = function(pseudos, addEvent, removeEvent){
var storeKey = 'monitorEvents:';
var storageOf = function(object){
return {
store: object.store ? function(key, value){
object.store(storeKey + key, value);
} : function(key, value){
(object.$monitorEvents || (object.$monitorEvents = {}))[key] = value;
},
retrieve: object.retrieve ? function(key, dflt){
return object.retrieve(storeKey + key, dflt);
} : function(key, dflt){
if (!object.$monitorEvents) return dflt;
return object.$monitorEvents[key] || dflt;
}
};
};
var splitType = function(type){
if (type.indexOf(':') == -1) return null;
var parsed = Slick.parse(type).expressions[0][0],
parsedPseudos = parsed.pseudos;
return (pseudos && pseudos[parsedPseudos[0].key]) ? {
event: parsed.tag,
value: parsedPseudos[0].value,
pseudo: parsedPseudos[0].key,
original: type
} : null;
};
return {
addEvent: function(type, fn, internal){
var split = splitType(type);
if (!split) return addEvent.call(this, type, fn, internal);
var storage = storageOf(this),
events = storage.retrieve(type, []),
pseudoArgs = Array.from(pseudos[split.pseudo]),
proxy = pseudoArgs[1];
var self = this;
var monitor = function(){
pseudoArgs[0].call(self, split, fn, arguments, proxy);
};
events.include({event: fn, monitor: monitor});
storage.store(type, events);
var eventType = split.event;
if (proxy && proxy[eventType]) eventType = proxy[eventType].base;
addEvent.call(this, type, fn, internal);
return addEvent.call(this, eventType, monitor, internal);
},
removeEvent: function(type, fn){
var split = splitType(type);
if (!split) return removeEvent.call(this, type, fn);
var storage = storageOf(this),
events = storage.retrieve(type),
pseudoArgs = Array.from(pseudos[split.pseudo]),
proxy = pseudoArgs[1];
if (!events) return this;
var eventType = split.event;
if (proxy && proxy[eventType]) eventType = proxy[eventType].base;
removeEvent.call(this, type, fn);
events.each(function(monitor, i){
if (!fn || monitor.event == fn) removeEvent.call(this, eventType, monitor.monitor);
delete events[i];
}, this);
storage.store(type, events);
return this;
}
};
};
(function(){
var pseudos = {
once: function(split, fn, args){
fn.apply(this, args);
this.removeEvent(split.original, fn);
}
};
Events.definePseudo = function(key, fn){
pseudos[key] = fn;
};
var proto = Events.prototype;
Events.implement(Events.Pseudos(pseudos, proto.addEvent, proto.removeEvent));
})();
/*
---
name: Element.Event.Pseudos
description: Adds the functionality to add pseudo events for Elements
license: MIT-style license
authors:
- Arian Stolwijk
requires: [Core/Element.Event, Events.Pseudos]
provides: [Element.Event.Pseudos]
...
*/
(function(){
var pseudos = {
once: function(split, fn, args){
fn.apply(this, args);
this.removeEvent(split.original, fn);
}
};
Event.definePseudo = function(key, fn, proxy){
pseudos[key] = [fn, proxy];
};
var proto = Element.prototype;
[Element, Window, Document].invoke('implement', Events.Pseudos(pseudos, proto.addEvent, proto.removeEvent));
})();
/*
---
script: Element.Delegation.js
name: Element.Delegation
description: Extends the Element native object to include the delegate method for more efficient event management.
credits:
- "Event checking based on the work of Daniel Steigerwald. License: MIT-style license. Copyright: Copyright (c) 2008 Daniel Steigerwald, daniel.steigerwald.cz"
license: MIT-style license
authors:
- Aaron Newton
- Daniel Steigerwald
requires: [/MooTools.More, Element.Event.Pseudos]
provides: [Element.Delegation]
...
*/
Event.definePseudo('relay', function(split, fn, args, proxy){
var event = args[0];
var check = proxy ? proxy.condition : null;
for (var target = event.target; target && target != this; target = target.parentNode){
var finalTarget = document.id(target);
if (Slick.match(target, split.value) && (!check || check.call(finalTarget, event))){
if (finalTarget) fn.call(finalTarget, event, finalTarget);
return;
}
}
}, {
mouseenter: {
base: 'mouseover',
condition: Element.Events.mouseenter.condition
},
mouseleave: {
base: 'mouseout',
condition: Element.Events.mouseleave.condition
}
});
/*
---
script: Element.Shortcuts.js
name: Element.Shortcuts
description: Extends the Element native object to include some shortcut methods.
license: MIT-style license
authors:
- Aaron Newton
requires:
- Core/Element.Style
- /MooTools.More
provides: [Element.Shortcuts]
...
*/
Element.implement({
isDisplayed: function(){
return this.getStyle('display') != 'none';
},
isVisible: function(){
var w = this.offsetWidth,
h = this.offsetHeight;
return (w == 0 && h == 0) ? false : (w > 0 && h > 0) ? true : this.style.display != 'none';
},
toggle: function(){
return this[this.isDisplayed() ? 'hide' : 'show']();
},
hide: function(){
var d;
try {
//IE fails here if the element is not in the dom
d = this.getStyle('display');
} catch(e){}
if (d == 'none') return this;
return this.store('element:_originalDisplay', d || '').setStyle('display', 'none');
},
show: function(display){
if (!display && this.isDisplayed()) return this;
display = display || this.retrieve('element:_originalDisplay') || 'block';
return this.setStyle('display', (display == 'none') ? 'block' : display);
},
swapClass: function(remove, add){
return this.removeClass(remove).addClass(add);
}
});
Document.implement({
clearSelection: function(){
if (document.selection && document.selection.empty){
document.selection.empty();
} else if (window.getSelection){
var selection = window.getSelection();
if (selection && selection.removeAllRanges) selection.removeAllRanges();
}
}
});