mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-20 06:08:35 +02:00
Ticket #11
Some code refactoring. Improvement of emails displaying. Mootools update (new version is 1.2.3). Fx.Slide added (version 1.2.3.1).
This commit is contained in:
@@ -21,7 +21,19 @@ from datetime import datetime
|
||||
import email
|
||||
import re
|
||||
import os
|
||||
import lxml.html
|
||||
from lxml.html.clean import Cleaner
|
||||
|
||||
attached_map = {}
|
||||
|
||||
def map_cid(url):
|
||||
map = globals()["attached_map"]
|
||||
m = re.match(".*cid:([^\"]+)", url)
|
||||
if m:
|
||||
if map.has_key(m.group(1)):
|
||||
return map[m.group(1)]
|
||||
return url
|
||||
|
||||
def init():
|
||||
events.register("UserMenuDisplay", menu)
|
||||
|
||||
@@ -74,6 +86,73 @@ ORDER BY msgs.time_num DESC
|
||||
"current_page" : pagenum, "last_page" : paginator._get_num_pages()
|
||||
})
|
||||
|
||||
@login_required
|
||||
def viewmail_plain(request, content):
|
||||
body = decode(content)
|
||||
return (True, body)
|
||||
|
||||
@login_required
|
||||
def viewmail_html(request, content):
|
||||
links = request.GET.has_key("links") and request.GET["links"] or "0"
|
||||
html = lxml.html.fromstring(content)
|
||||
if links == "0":
|
||||
html.rewrite_links(lambda x: None)
|
||||
else:
|
||||
html.rewrite_links(map_cid)
|
||||
body = lxml.html.tostring(html)
|
||||
body = Template(decode(body)).render({})
|
||||
return (False, body)
|
||||
|
||||
@login_required
|
||||
def getmailcontent(request, mail_id):
|
||||
conn = db.getconnection("amavis_quarantine")
|
||||
status, cursor = db.execute(conn, """
|
||||
SELECT mail_text
|
||||
FROM quarantine
|
||||
WHERE quarantine.mail_id='%s'
|
||||
""" % mail_id)
|
||||
content = ""
|
||||
for part in cursor.fetchall():
|
||||
content += part[0]
|
||||
msg = email.message_from_string(content)
|
||||
links = request.GET.has_key("links") and request.GET["links"] or "0"
|
||||
mode = request.GET.has_key("mode") and request.GET["mode"] or "plain"
|
||||
contents = {"html" : "", "plain" : ""}
|
||||
for part in msg.walk():
|
||||
print part.get_content_type()
|
||||
if part.get_content_maintype() == 'multipart':
|
||||
continue
|
||||
if part.get_content_type() in ("text/html", "text/plain"):
|
||||
contents[part.get_content_subtype()] += part.get_payload(decode=True)
|
||||
if mode != "html" or links == "0":
|
||||
continue
|
||||
|
||||
if part.get_content_maintype() == "image":
|
||||
if part.has_key("Content-Location"):
|
||||
fname = part["Content-Location"]
|
||||
if re.match("^http:", fname):
|
||||
path = fname
|
||||
else:
|
||||
path = "/%s" % os.path.join("static/tmp", fname)
|
||||
fp = open(path, "wb")
|
||||
fp.write(part.get_payload(decode=True))
|
||||
fp.close()
|
||||
m = re.match("<(.+)>", part["Content-ID"])
|
||||
if m:
|
||||
attached_map[m.group(1)] = path
|
||||
else:
|
||||
attached_map[part["Content-ID"]] = path
|
||||
|
||||
if not contents.has_key(mode) or contents[mode] == "":
|
||||
if mode == "html":
|
||||
mode = "plain"
|
||||
else:
|
||||
mode = "html"
|
||||
(pre, body) = globals()["viewmail_%s" % mode](request, contents[mode])
|
||||
return _render(request, 'amavis_quarantine/getmailcontent.html', {
|
||||
"body" : body, "pre" : pre
|
||||
})
|
||||
|
||||
@login_required
|
||||
def viewmail(request, mail_id):
|
||||
conn = db.getconnection("amavis_quarantine")
|
||||
@@ -86,32 +165,10 @@ WHERE quarantine.mail_id='%s'
|
||||
for part in cursor.fetchall():
|
||||
content += part[0]
|
||||
msg = email.message_from_string(content)
|
||||
|
||||
html_body = ""
|
||||
text_body = ""
|
||||
for part in msg.walk():
|
||||
print part.get_content_type()
|
||||
if part.get_content_maintype() == 'multipart':
|
||||
continue
|
||||
if part.get_content_type() in ("text/html"):
|
||||
html_body += part.get_payload()
|
||||
if part.get_content_type() in ("text/plain"):
|
||||
text_body += part.get_payload(decode=True)
|
||||
pre = None
|
||||
if html_body != "":
|
||||
html_body = email.utils.quote(html_body)
|
||||
html_body = re.sub('(\n|\r|\r\n)', '\\\\n', html_body)
|
||||
body = Template(decode(html_body)).render({})
|
||||
else:
|
||||
text_body = email.utils.quote(text_body)
|
||||
text_body = re.sub('(\n|\r|\r\n)', '\\\\n', text_body)
|
||||
body = decode(text_body)
|
||||
pre = True
|
||||
|
||||
return _render(request, 'amavis_quarantine/viewmail.html', {
|
||||
"headers" : msg, "alert" : msg.get("X-Amavis-Alert"),
|
||||
"body" : body, "pre" : pre, "mail_id" : mail_id,
|
||||
"page_id" : request.GET["page"]
|
||||
"mail_id" : mail_id, "page_id" : request.GET["page"],
|
||||
"params" : request.GET
|
||||
})
|
||||
|
||||
@login_required
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{% if pre %}<pre>{% endif %}{{ body }}{% if pre %}</pre>{% endif %}
|
||||
@@ -3,20 +3,14 @@
|
||||
{% block html_head %}
|
||||
<script type="text/javascript">
|
||||
window.addEvent("domready", function() {
|
||||
doc = $("mailcontent").contentWindow.document;
|
||||
doc.open();
|
||||
{% if pre %}
|
||||
doc.write("<pre>{{ body }}</pre>");
|
||||
{% else %}
|
||||
doc.write("{{ body }}");
|
||||
{% endif %}
|
||||
doc.close();
|
||||
|
||||
SqueezeBox.assign($$('a.boxed'), {
|
||||
parse: 'rel'
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script src="/static/js/mootools-more.js" type="text/javascript"></script>
|
||||
<script src="/static/js/common.js" type="text/javascript"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/static/stylesheets/box.css" />
|
||||
<style type="text/css">
|
||||
td {
|
||||
@@ -36,11 +30,12 @@ td.left {
|
||||
</style>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="menu2">
|
||||
<div class="menu2" id="menu2">
|
||||
{% load amextras %}
|
||||
{% viewm_menu "headers" mail_id page_id perms %}
|
||||
{% viewm_menu "" mail_id page_id perms %}
|
||||
</div>
|
||||
|
||||
<div id="table-container">
|
||||
<table border="0">
|
||||
<tr>
|
||||
<th colspan="2">{% trans "Message" %}</th>
|
||||
@@ -51,9 +46,9 @@ td.left {
|
||||
<tr><td class="left">Date</td><td>{{ headers.date }}</td></tr>
|
||||
<tr><td class="left">Subject</td><td>{{ headers.subject }}</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
<iframe id="mailcontent"></iframe>
|
||||
|
||||
{% url extensions.amavis_quarantine.main.getmailcontent mail_id as geturl %}
|
||||
<iframe id="mailcontent" src="{{ geturl }}?mode={{ params.mode }}&links={{ params.links }}"></iframe>
|
||||
|
||||
{% endblock %}
|
||||
@@ -8,6 +8,21 @@ register = template.Library()
|
||||
|
||||
@register.simple_tag
|
||||
def viewm_menu(selection, mail_id, page_id, perms):
|
||||
options_menu = [
|
||||
{"name" : "plain",
|
||||
"label" : _("View as plain text"),
|
||||
"url" : reverse(amavis_quarantine.main.viewmail, args=[mail_id])
|
||||
+ "?page=%s&mode=plain" % page_id},
|
||||
{"name" : "html",
|
||||
"label" : _("View as HTML"),
|
||||
"url" : reverse(amavis_quarantine.main.viewmail, args=[mail_id])
|
||||
+ "?page=%s&mode=html" % page_id},
|
||||
{"name" : "links",
|
||||
"label" : _("Activate links"),
|
||||
"url" : reverse(amavis_quarantine.main.viewmail, args=[mail_id])
|
||||
+ "?page=%s&mode=html&links=1" % page_id}
|
||||
]
|
||||
|
||||
entries = [
|
||||
{"name" : "back",
|
||||
"url" : reverse(amavis_quarantine.main.index) + "?page=%s" % page_id,
|
||||
@@ -30,7 +45,11 @@ def viewm_menu(selection, mail_id, page_id, perms):
|
||||
+ "?page=%s" % page_id,
|
||||
"img" : "/static/pics/remove.png",
|
||||
"label" : _("Delete"),
|
||||
"confirm" : _("Delete this message?")}
|
||||
"confirm" : _("Delete this message?")},
|
||||
{"name" : "options",
|
||||
"label" : _("Options"),
|
||||
"img" : "/static/pics/settings.png",
|
||||
"menu" : options_menu}
|
||||
]
|
||||
|
||||
return render_to_string('main/menu.html',
|
||||
|
||||
@@ -3,6 +3,7 @@ from django.conf.urls.defaults import *
|
||||
urlpatterns = patterns('mailng.extensions.amavis_quarantine.main',
|
||||
(r'^$', 'index'),
|
||||
(r'^viewmail/(?P<mail_id>[\w\-\+]+)/$', 'viewmail'),
|
||||
(r'^getmailcontent/(?P<mail_id>[\w\-\+]+)/$', 'getmailcontent'),
|
||||
(r'^viewheaders/(?P<mail_id>[\w\-\+]+)/$', 'viewheaders'),
|
||||
(r'^process/$', 'process'),
|
||||
(r'^delete/(?P<mail_id>[\w\-\+]+)/$', 'delete'),
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
window.addEvent('domready', function(){
|
||||
$('menu2').getElements('li.dropdown').each( function( elem ){
|
||||
var list = elem.getElement('ul.links');
|
||||
var myFx = new Fx.Slide(list).hide();
|
||||
elem.addEvents({
|
||||
'mouseenter' : function(){
|
||||
myFx.cancel();
|
||||
myFx.slideIn();
|
||||
},
|
||||
'mouseleave' : function(){
|
||||
myFx.cancel();
|
||||
myFx.slideOut();
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
@@ -0,0 +1,146 @@
|
||||
//MooTools More, <http://mootools.net/more>. Copyright (c) 2006-2009 Aaron Newton <http://clientcide.com/>, Valerio Proietti <http://mad4milk.net> & the MooTools team <http://mootools.net/developers>, MIT Style License.
|
||||
|
||||
MooTools.More = {
|
||||
'version': '1.2.3.1'
|
||||
};
|
||||
|
||||
/*
|
||||
Script: Fx.Slide.js
|
||||
Effect to slide an element in and out of view.
|
||||
|
||||
License:
|
||||
MIT-style license.
|
||||
|
||||
Authors:
|
||||
Valerio Proietti
|
||||
*/
|
||||
|
||||
Fx.Slide = new Class({
|
||||
|
||||
Extends: Fx,
|
||||
|
||||
options: {
|
||||
mode: 'vertical'
|
||||
},
|
||||
|
||||
initialize: function(element, options){
|
||||
this.addEvent('complete', function(){
|
||||
this.open = (this.wrapper['offset' + this.layout.capitalize()] != 0);
|
||||
if (this.open && Browser.Engine.webkit419) this.element.dispose().inject(this.wrapper);
|
||||
}, true);
|
||||
this.element = this.subject = document.id(element);
|
||||
this.parent(options);
|
||||
var wrapper = this.element.retrieve('wrapper');
|
||||
this.wrapper = wrapper || new Element('div', {
|
||||
styles: $extend(this.element.getStyles('margin', 'position'), {overflow: 'hidden'})
|
||||
}).wraps(this.element);
|
||||
this.element.store('wrapper', this.wrapper).setStyle('margin', 0);
|
||||
this.now = [];
|
||||
this.open = true;
|
||||
},
|
||||
|
||||
vertical: function(){
|
||||
this.margin = 'margin-top';
|
||||
this.layout = 'height';
|
||||
this.offset = this.element.offsetHeight;
|
||||
},
|
||||
|
||||
horizontal: function(){
|
||||
this.margin = 'margin-left';
|
||||
this.layout = 'width';
|
||||
this.offset = this.element.offsetWidth;
|
||||
},
|
||||
|
||||
set: function(now){
|
||||
this.element.setStyle(this.margin, now[0]);
|
||||
this.wrapper.setStyle(this.layout, now[1]);
|
||||
return this;
|
||||
},
|
||||
|
||||
compute: function(from, to, delta){
|
||||
return [0, 1].map(function(i){
|
||||
return Fx.compute(from[i], to[i], delta);
|
||||
});
|
||||
},
|
||||
|
||||
start: function(how, mode){
|
||||
if (!this.check(how, mode)) return this;
|
||||
this[mode || this.options.mode]();
|
||||
var margin = this.element.getStyle(this.margin).toInt();
|
||||
var layout = this.wrapper.getStyle(this.layout).toInt();
|
||||
var caseIn = [[margin, layout], [0, this.offset]];
|
||||
var caseOut = [[margin, layout], [-this.offset, 0]];
|
||||
var start;
|
||||
switch (how){
|
||||
case 'in': start = caseIn; break;
|
||||
case 'out': start = caseOut; break;
|
||||
case 'toggle': start = (layout == 0) ? caseIn : caseOut;
|
||||
}
|
||||
return this.parent(start[0], start[1]);
|
||||
},
|
||||
|
||||
slideIn: function(mode){
|
||||
return this.start('in', mode);
|
||||
},
|
||||
|
||||
slideOut: function(mode){
|
||||
return this.start('out', mode);
|
||||
},
|
||||
|
||||
hide: function(mode){
|
||||
this[mode || this.options.mode]();
|
||||
this.open = false;
|
||||
return this.set([-this.offset, 0]);
|
||||
},
|
||||
|
||||
show: function(mode){
|
||||
this[mode || this.options.mode]();
|
||||
this.open = true;
|
||||
return this.set([0, this.offset]);
|
||||
},
|
||||
|
||||
toggle: function(mode){
|
||||
return this.start('toggle', mode);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Element.Properties.slide = {
|
||||
|
||||
set: function(options){
|
||||
var slide = this.retrieve('slide');
|
||||
if (slide) slide.cancel();
|
||||
return this.eliminate('slide').store('slide:options', $extend({link: 'cancel'}, options));
|
||||
},
|
||||
|
||||
get: function(options){
|
||||
if (options || !this.retrieve('slide')){
|
||||
if (options || !this.retrieve('slide:options')) this.set('slide', options);
|
||||
this.store('slide', new Fx.Slide(this, this.retrieve('slide:options')));
|
||||
}
|
||||
return this.retrieve('slide');
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Element.implement({
|
||||
|
||||
slide: function(how, mode){
|
||||
how = how || 'toggle';
|
||||
var slide = this.get('slide'), toggle;
|
||||
switch (how){
|
||||
case 'hide': slide.hide(mode); break;
|
||||
case 'show': slide.show(mode); break;
|
||||
case 'toggle':
|
||||
var flag = this.retrieve('slide:flag', slide.open);
|
||||
slide[flag ? 'slideOut' : 'slideIn'](mode);
|
||||
this.store('slide:flag', !flag);
|
||||
toggle = true;
|
||||
break;
|
||||
default: slide.start(how, mode);
|
||||
}
|
||||
if (!toggle) this.eliminate('slide:flag');
|
||||
return this;
|
||||
}
|
||||
|
||||
});
|
||||
+299
-209
@@ -17,8 +17,8 @@ Inspiration:
|
||||
*/
|
||||
|
||||
var MooTools = {
|
||||
'version': '1.2.1',
|
||||
'build': '0d4845aab3d9a4fdee2f0d4a6dd59210e4b697cf'
|
||||
'version': '1.2.3',
|
||||
'build': '4980aa0fb74d2f6eb80bcd9f5b8e1fd6fbb8f607'
|
||||
};
|
||||
|
||||
var Native = function(options){
|
||||
@@ -53,7 +53,8 @@ var Native = function(options){
|
||||
|
||||
object.alias = function(a1, a2, a3){
|
||||
if (typeof a1 == 'string'){
|
||||
if ((a1 = this.prototype[a1])) return add(this, a2, a1, a3);
|
||||
var pa1 = this.prototype[a1];
|
||||
if ((a1 = pa1)) return add(this, a2, a1, a3);
|
||||
}
|
||||
for (var a in a1) this.alias(a, a1[a], a2);
|
||||
return this;
|
||||
@@ -99,8 +100,8 @@ Native.typize = function(object, family){
|
||||
'String': ["charAt", "charCodeAt", "concat", "indexOf", "lastIndexOf", "match", "replace", "search", "slice", "split", "substr", "substring", "toLowerCase", "toUpperCase", "valueOf"]
|
||||
};
|
||||
for (var g in generics){
|
||||
for (var i = generics[g].length; i--;) Native.genericize(window[g], generics[g][i], true);
|
||||
};
|
||||
for (var i = generics[g].length; i--;) Native.genericize(natives[g], generics[g][i], true);
|
||||
}
|
||||
})();
|
||||
|
||||
var Hash = new Native({
|
||||
@@ -155,8 +156,8 @@ Array.alias('forEach', 'each');
|
||||
|
||||
function $A(iterable){
|
||||
if (iterable.item){
|
||||
var array = [];
|
||||
for (var i = 0, l = iterable.length; i < l; i++) array[i] = iterable[i];
|
||||
var l = iterable.length, array = new Array(l);
|
||||
while (l--) array[l] = iterable[l];
|
||||
return array;
|
||||
}
|
||||
return Array.prototype.slice.call(iterable);
|
||||
@@ -199,19 +200,24 @@ function $H(object){
|
||||
};
|
||||
|
||||
function $lambda(value){
|
||||
return (typeof value == 'function') ? value : function(){
|
||||
return ($type(value) == 'function') ? value : function(){
|
||||
return value;
|
||||
};
|
||||
};
|
||||
|
||||
function $merge(){
|
||||
var mix = {};
|
||||
for (var i = 0, l = arguments.length; i < l; i++){
|
||||
var args = Array.slice(arguments);
|
||||
args.unshift({});
|
||||
return $mixin.apply(null, args);
|
||||
};
|
||||
|
||||
function $mixin(mix){
|
||||
for (var i = 1, l = arguments.length; i < l; i++){
|
||||
var object = arguments[i];
|
||||
if ($type(object) != 'object') continue;
|
||||
for (var key in object){
|
||||
var op = object[key], mp = mix[key];
|
||||
mix[key] = (mp && $type(op) == 'object' && $type(mp) == 'object') ? $merge(mp, op) : $unlink(op);
|
||||
mix[key] = (mp && $type(op) == 'object' && $type(mp) == 'object') ? $mixin(mp, op) : $unlink(op);
|
||||
}
|
||||
}
|
||||
return mix;
|
||||
@@ -356,7 +362,7 @@ Browser.Plugins.Flash = (function(){
|
||||
}, function(){
|
||||
return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
|
||||
}) || '0 r0').match(/\d+/g);
|
||||
return {version: parseInt(version[0] || 0 + '.' + version[1] || 0), build: parseInt(version[2] || 0)};
|
||||
return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0};
|
||||
})();
|
||||
|
||||
function $exec(text){
|
||||
@@ -517,7 +523,7 @@ Array.implement({
|
||||
for (var i = 0, j = array.length; i < j; i++) this.push(array[i]);
|
||||
return this;
|
||||
},
|
||||
|
||||
|
||||
getLast: function(){
|
||||
return (this.length) ? this[this.length - 1] : null;
|
||||
},
|
||||
@@ -801,14 +807,14 @@ Hash.implement({
|
||||
},
|
||||
|
||||
extend: function(properties){
|
||||
Hash.each(properties, function(value, key){
|
||||
Hash.each(properties || {}, function(value, key){
|
||||
Hash.set(this, key, value);
|
||||
}, this);
|
||||
return this;
|
||||
},
|
||||
|
||||
combine: function(properties){
|
||||
Hash.each(properties, function(value, key){
|
||||
Hash.each(properties || {}, function(value, key){
|
||||
Hash.include(this, key, value);
|
||||
}, this);
|
||||
return this;
|
||||
@@ -836,8 +842,7 @@ Hash.implement({
|
||||
},
|
||||
|
||||
include: function(key, value){
|
||||
var k = this[key];
|
||||
if (k == undefined) this[key] = value;
|
||||
if (this[key] == undefined) this[key] = value;
|
||||
return this;
|
||||
},
|
||||
|
||||
@@ -1038,117 +1043,151 @@ License:
|
||||
MIT-style license.
|
||||
*/
|
||||
|
||||
var Class = new Native({
|
||||
function Class(params){
|
||||
|
||||
if (params instanceof Function) params = {initialize: params};
|
||||
|
||||
var newClass = function(){
|
||||
Object.reset(this);
|
||||
if (newClass._prototyping) return this;
|
||||
this._current = $empty;
|
||||
var value = (this.initialize) ? this.initialize.apply(this, arguments) : this;
|
||||
delete this._current; delete this.caller;
|
||||
return value;
|
||||
}.extend(this);
|
||||
|
||||
newClass.implement(params);
|
||||
|
||||
newClass.constructor = Class;
|
||||
newClass.prototype.constructor = newClass;
|
||||
|
||||
name: 'Class',
|
||||
|
||||
initialize: function(properties){
|
||||
properties = properties || {};
|
||||
var klass = function(){
|
||||
for (var key in this){
|
||||
if ($type(this[key]) != 'function') this[key] = $unlink(this[key]);
|
||||
}
|
||||
this.constructor = klass;
|
||||
if (Class.prototyping) return this;
|
||||
var instance = (this.initialize) ? this.initialize.apply(this, arguments) : this;
|
||||
if (this.options && this.options.initialize) this.options.initialize.call(this);
|
||||
return instance;
|
||||
};
|
||||
|
||||
for (var mutator in Class.Mutators){
|
||||
if (!properties[mutator]) continue;
|
||||
properties = Class.Mutators[mutator](properties, properties[mutator]);
|
||||
delete properties[mutator];
|
||||
}
|
||||
|
||||
$extend(klass, this);
|
||||
klass.constructor = Class;
|
||||
klass.prototype = properties;
|
||||
return klass;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Class.Mutators = {
|
||||
|
||||
Extends: function(self, klass){
|
||||
Class.prototyping = klass.prototype;
|
||||
var subclass = new klass;
|
||||
delete subclass.parent;
|
||||
subclass = Class.inherit(subclass, self);
|
||||
delete Class.prototyping;
|
||||
return subclass;
|
||||
},
|
||||
|
||||
Implements: function(self, klasses){
|
||||
$splat(klasses).each(function(klass){
|
||||
Class.prototying = klass;
|
||||
$extend(self, ($type(klass) == 'class') ? new klass : klass);
|
||||
delete Class.prototyping;
|
||||
});
|
||||
return self;
|
||||
}
|
||||
return newClass;
|
||||
|
||||
};
|
||||
|
||||
Class.extend({
|
||||
|
||||
inherit: function(object, properties){
|
||||
var caller = arguments.callee.caller;
|
||||
for (var key in properties){
|
||||
var override = properties[key];
|
||||
var previous = object[key];
|
||||
var type = $type(override);
|
||||
if (previous && type == 'function'){
|
||||
if (override != previous){
|
||||
if (caller){
|
||||
override.__parent = previous;
|
||||
object[key] = override;
|
||||
} else {
|
||||
Class.override(object, key, override);
|
||||
}
|
||||
}
|
||||
} else if(type == 'object'){
|
||||
object[key] = $merge(previous, override);
|
||||
} else {
|
||||
object[key] = override;
|
||||
}
|
||||
}
|
||||
|
||||
if (caller) object.parent = function(){
|
||||
return arguments.callee.caller.__parent.apply(this, arguments);
|
||||
};
|
||||
Function.prototype.protect = function(){
|
||||
this._protected = true;
|
||||
return this;
|
||||
};
|
||||
|
||||
Object.reset = function(object, key){
|
||||
|
||||
if (key == null){
|
||||
for (var p in object) Object.reset(object, p);
|
||||
return object;
|
||||
},
|
||||
|
||||
override: function(object, name, method){
|
||||
var parent = Class.prototyping;
|
||||
if (parent && object[name] != parent[name]) parent = null;
|
||||
var override = function(){
|
||||
var previous = this.parent;
|
||||
this.parent = parent ? parent[name] : object[name];
|
||||
var value = method.apply(this, arguments);
|
||||
this.parent = previous;
|
||||
return value;
|
||||
};
|
||||
object[name] = override;
|
||||
}
|
||||
|
||||
delete object[key];
|
||||
|
||||
switch ($type(object[key])){
|
||||
case 'object':
|
||||
var F = function(){};
|
||||
F.prototype = object[key];
|
||||
var i = new F;
|
||||
object[key] = Object.reset(i);
|
||||
break;
|
||||
case 'array': object[key] = $unlink(object[key]); break;
|
||||
}
|
||||
|
||||
return object;
|
||||
|
||||
};
|
||||
|
||||
new Native({name: 'Class', initialize: Class}).extend({
|
||||
|
||||
instantiate: function(F){
|
||||
F._prototyping = true;
|
||||
var proto = new F;
|
||||
delete F._prototyping;
|
||||
return proto;
|
||||
},
|
||||
|
||||
wrap: function(self, key, method){
|
||||
if (method._origin) method = method._origin;
|
||||
|
||||
return function(){
|
||||
if (method._protected && this._current == null) throw new Error('The method "' + key + '" cannot be called.');
|
||||
var caller = this.caller, current = this._current;
|
||||
this.caller = current; this._current = arguments.callee;
|
||||
var result = method.apply(this, arguments);
|
||||
this._current = current; this.caller = caller;
|
||||
return result;
|
||||
}.extend({_owner: self, _origin: method, _name: key});
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Class.implement({
|
||||
|
||||
implement: function(){
|
||||
|
||||
implement: function(key, value){
|
||||
|
||||
if ($type(key) == 'object'){
|
||||
for (var p in key) this.implement(p, key[p]);
|
||||
return this;
|
||||
}
|
||||
|
||||
var mutator = Class.Mutators[key];
|
||||
|
||||
if (mutator){
|
||||
value = mutator.call(this, value);
|
||||
if (value == null) return this;
|
||||
}
|
||||
|
||||
var proto = this.prototype;
|
||||
$each(arguments, function(properties){
|
||||
Class.inherit(proto, properties);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
switch ($type(value)){
|
||||
|
||||
case 'function':
|
||||
if (value._hidden) return this;
|
||||
proto[key] = Class.wrap(this, key, value);
|
||||
break;
|
||||
|
||||
case 'object':
|
||||
var previous = proto[key];
|
||||
if ($type(previous) == 'object') $mixin(previous, value);
|
||||
else proto[key] = $unlink(value);
|
||||
break;
|
||||
|
||||
case 'array':
|
||||
proto[key] = $unlink(value);
|
||||
break;
|
||||
|
||||
default: proto[key] = value;
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Class.Mutators = {
|
||||
|
||||
Extends: function(parent){
|
||||
|
||||
this.parent = parent;
|
||||
this.prototype = Class.instantiate(parent);
|
||||
|
||||
this.implement('parent', function(){
|
||||
var name = this.caller._name, previous = this.caller._owner.parent.prototype[name];
|
||||
if (!previous) throw new Error('The method "' + name + '" has no parent.');
|
||||
return previous.apply(this, arguments);
|
||||
}.protect());
|
||||
|
||||
},
|
||||
|
||||
Implements: function(items){
|
||||
$splat(items).each(function(item){
|
||||
if (item instanceof Function) item = Class.instantiate(item);
|
||||
this.implement(item);
|
||||
}, this);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Script: Class.Extras.js
|
||||
@@ -1214,12 +1253,13 @@ var Events = new Class({
|
||||
},
|
||||
|
||||
removeEvents: function(events){
|
||||
var type;
|
||||
if ($type(events) == 'object'){
|
||||
for (var type in events) this.removeEvent(type, events[type]);
|
||||
for (type in events) this.removeEvent(type, events[type]);
|
||||
return this;
|
||||
}
|
||||
if (events) events = Events.removeOn(events);
|
||||
for (var type in this.$events){
|
||||
for (type in this.$events){
|
||||
if (events && events != type) continue;
|
||||
var fns = this.$events[type];
|
||||
for (var i = fns.length; i--; i) this.removeEvent(type, fns[i]);
|
||||
@@ -1270,7 +1310,7 @@ var Element = new Native({
|
||||
var konstructor = Element.Constructors.get(tag);
|
||||
if (konstructor) return konstructor(props);
|
||||
if (typeof tag == 'string') return document.newElement(tag, props);
|
||||
return $(tag).set(props);
|
||||
return document.id(tag).set(props);
|
||||
},
|
||||
|
||||
afterImplement: function(key, value){
|
||||
@@ -1302,23 +1342,26 @@ var IFrame = new Native({
|
||||
initialize: function(){
|
||||
var params = Array.link(arguments, {properties: Object.type, iframe: $defined});
|
||||
var props = params.properties || {};
|
||||
var iframe = $(params.iframe) || false;
|
||||
var iframe = document.id(params.iframe);
|
||||
var onload = props.onload || $empty;
|
||||
delete props.onload;
|
||||
props.id = props.name = $pick(props.id, props.name, iframe.id, iframe.name, 'IFrame_' + $time());
|
||||
props.id = props.name = $pick(props.id, props.name, iframe ? (iframe.id || iframe.name) : 'IFrame_' + $time());
|
||||
iframe = new Element(iframe || 'iframe', props);
|
||||
var onFrameLoad = function(){
|
||||
var host = $try(function(){
|
||||
return iframe.contentWindow.location.host;
|
||||
});
|
||||
if (host && host == window.location.host){
|
||||
if (!host || host == window.location.host){
|
||||
var win = new Window(iframe.contentWindow);
|
||||
new Document(iframe.contentWindow.document);
|
||||
$extend(win.Element.prototype, Element.Prototype);
|
||||
}
|
||||
onload.call(iframe.contentWindow, iframe.contentWindow.document);
|
||||
};
|
||||
(window.frames[props.id]) ? onFrameLoad() : iframe.addListener('load', onFrameLoad);
|
||||
var contentWindow = $try(function(){
|
||||
return iframe.contentWindow;
|
||||
});
|
||||
((contentWindow && contentWindow.document.body) || window.frames[props.id]) ? onFrameLoad() : iframe.addListener('load', onFrameLoad);
|
||||
return iframe;
|
||||
}
|
||||
|
||||
@@ -1332,7 +1375,7 @@ var Elements = new Native({
|
||||
if (options.ddup || options.cash){
|
||||
var uniques = {}, returned = [];
|
||||
for (var i = 0, l = elements.length; i < l; i++){
|
||||
var el = $.element(elements[i], !options.cash);
|
||||
var el = document.id(elements[i], !options.cash);
|
||||
if (options.ddup){
|
||||
if (uniques[el.uid]) continue;
|
||||
uniques[el.uid] = true;
|
||||
@@ -1368,7 +1411,7 @@ Document.implement({
|
||||
});
|
||||
tag = '<' + tag + '>';
|
||||
}
|
||||
return $.element(this.createElement(tag)).set(props);
|
||||
return document.id(this.createElement(tag)).set(props);
|
||||
},
|
||||
|
||||
newTextNode: function(text){
|
||||
@@ -1381,17 +1424,52 @@ Document.implement({
|
||||
|
||||
getWindow: function(){
|
||||
return this.window;
|
||||
}
|
||||
},
|
||||
|
||||
id: (function(){
|
||||
|
||||
var types = {
|
||||
|
||||
string: function(id, nocash, doc){
|
||||
id = doc.getElementById(id);
|
||||
return (id) ? types.element(id, nocash) : null;
|
||||
},
|
||||
|
||||
element: function(el, nocash){
|
||||
$uid(el);
|
||||
if (!nocash && !el.$family && !(/^object|embed$/i).test(el.tagName)){
|
||||
var proto = Element.Prototype;
|
||||
for (var p in proto) el[p] = proto[p];
|
||||
};
|
||||
return el;
|
||||
},
|
||||
|
||||
object: function(obj, nocash, doc){
|
||||
if (obj.toElement) return types.element(obj.toElement(doc), nocash);
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
types.textnode = types.whitespace = types.window = types.document = $arguments(0);
|
||||
|
||||
return function(el, nocash, doc){
|
||||
if (el && el.$family && el.uid) return el;
|
||||
var type = $type(el);
|
||||
return (types[type]) ? types[type](el, nocash, doc || document) : null;
|
||||
};
|
||||
|
||||
})()
|
||||
|
||||
});
|
||||
|
||||
Window.implement({
|
||||
if (window.$ == null) Window.implement({
|
||||
$: function(el, nc){
|
||||
return document.id(el, nc, this.document);
|
||||
}
|
||||
});
|
||||
|
||||
$: function(el, nocash){
|
||||
if (el && el.$family && el.uid) return el;
|
||||
var type = $type(el);
|
||||
return ($[type]) ? $[type](el, nocash, this.document) : null;
|
||||
},
|
||||
Window.implement({
|
||||
|
||||
$$: function(selector){
|
||||
if (arguments.length == 1 && typeof selector == 'string') return this.document.getElements(selector);
|
||||
@@ -1417,31 +1495,10 @@ Window.implement({
|
||||
|
||||
});
|
||||
|
||||
$.string = function(id, nocash, doc){
|
||||
id = doc.getElementById(id);
|
||||
return (id) ? $.element(id, nocash) : null;
|
||||
};
|
||||
|
||||
$.element = function(el, nocash){
|
||||
$uid(el);
|
||||
if (!nocash && !el.$family && !(/^object|embed$/i).test(el.tagName)){
|
||||
var proto = Element.Prototype;
|
||||
for (var p in proto) el[p] = proto[p];
|
||||
};
|
||||
return el;
|
||||
};
|
||||
|
||||
$.object = function(obj, nocash, doc){
|
||||
if (obj.toElement) return $.element(obj.toElement(doc), nocash);
|
||||
return null;
|
||||
};
|
||||
|
||||
$.textnode = $.whitespace = $.window = $.document = $arguments(0);
|
||||
|
||||
Native.implement([Element, Document], {
|
||||
|
||||
getElement: function(selector, nocash){
|
||||
return $(this.getElements(selector, true)[0] || null, nocash);
|
||||
return document.id(this.getElements(selector, true)[0] || null, nocash);
|
||||
},
|
||||
|
||||
getElements: function(tags, nocash){
|
||||
@@ -1500,7 +1557,7 @@ var walk = function(element, walk, start, match, all, nocash){
|
||||
var elements = [];
|
||||
while (el){
|
||||
if (el.nodeType == 1 && (!match || Element.match(el, match))){
|
||||
if (!all) return $(el, nocash);
|
||||
if (!all) return document.id(el, nocash);
|
||||
elements.push(el);
|
||||
}
|
||||
el = el[walk];
|
||||
@@ -1512,12 +1569,15 @@ var attributes = {
|
||||
'html': 'innerHTML',
|
||||
'class': 'className',
|
||||
'for': 'htmlFor',
|
||||
'defaultValue': 'defaultValue',
|
||||
'text': (Browser.Engine.trident || (Browser.Engine.webkit && Browser.Engine.version < 420)) ? 'innerText' : 'textContent'
|
||||
};
|
||||
var bools = ['compact', 'nowrap', 'ismap', 'declare', 'noshade', 'checked', 'disabled', 'readonly', 'multiple', 'selected', 'noresize', 'defer'];
|
||||
var camels = ['value', 'accessKey', 'cellPadding', 'cellSpacing', 'colSpan', 'frameBorder', 'maxLength', 'readOnly', 'rowSpan', 'tabIndex', 'useMap'];
|
||||
var camels = ['value', 'type', 'defaultValue', 'accessKey', 'cellPadding', 'cellSpacing', 'colSpan', 'frameBorder', 'maxLength', 'readOnly', 'rowSpan', 'tabIndex', 'useMap'];
|
||||
|
||||
Hash.extend(attributes, bools.associate(bools));
|
||||
bools = bools.associate(bools);
|
||||
|
||||
Hash.extend(attributes, bools);
|
||||
Hash.extend(attributes, camels.associate(camels.map(String.toLowerCase)));
|
||||
|
||||
var inserters = {
|
||||
@@ -1550,12 +1610,12 @@ Hash.each(inserters, function(inserter, where){
|
||||
where = where.capitalize();
|
||||
|
||||
Element.implement('inject' + where, function(el){
|
||||
inserter(this, $(el, true));
|
||||
inserter(this, document.id(el, true));
|
||||
return this;
|
||||
});
|
||||
|
||||
Element.implement('grab' + where, function(el){
|
||||
inserter($(el, true), this);
|
||||
inserter(document.id(el, true), this);
|
||||
return this;
|
||||
});
|
||||
|
||||
@@ -1641,7 +1701,7 @@ Element.implement({
|
||||
|
||||
adopt: function(){
|
||||
Array.flatten(arguments).each(function(element){
|
||||
element = $(element, true);
|
||||
element = document.id(element, true);
|
||||
if (element) this.appendChild(element);
|
||||
}, this);
|
||||
return this;
|
||||
@@ -1652,23 +1712,23 @@ Element.implement({
|
||||
},
|
||||
|
||||
grab: function(el, where){
|
||||
inserters[where || 'bottom']($(el, true), this);
|
||||
inserters[where || 'bottom'](document.id(el, true), this);
|
||||
return this;
|
||||
},
|
||||
|
||||
inject: function(el, where){
|
||||
inserters[where || 'bottom'](this, $(el, true));
|
||||
inserters[where || 'bottom'](this, document.id(el, true));
|
||||
return this;
|
||||
},
|
||||
|
||||
replaces: function(el){
|
||||
el = $(el, true);
|
||||
el = document.id(el, true);
|
||||
el.parentNode.replaceChild(this, el);
|
||||
return this;
|
||||
},
|
||||
|
||||
wraps: function(el, where){
|
||||
el = $(el, true);
|
||||
el = document.id(el, true);
|
||||
return this.replaces(el).grab(el, where);
|
||||
},
|
||||
|
||||
@@ -1703,6 +1763,10 @@ Element.implement({
|
||||
getParents: function(match, nocash){
|
||||
return walk(this, 'parentNode', null, match, true, nocash);
|
||||
},
|
||||
|
||||
getSiblings: function(match, nocash) {
|
||||
return this.getParent().getChildren(match, nocash).erase(this);
|
||||
},
|
||||
|
||||
getChildren: function(match, nocash){
|
||||
return walk(this, 'nextSibling', 'firstChild', match, true, nocash);
|
||||
@@ -1722,7 +1786,7 @@ Element.implement({
|
||||
for (var parent = el.parentNode; parent != this; parent = parent.parentNode){
|
||||
if (!parent) return null;
|
||||
}
|
||||
return $.element(el, nocash);
|
||||
return document.id(el, nocash);
|
||||
},
|
||||
|
||||
getSelected: function(){
|
||||
@@ -1740,7 +1804,7 @@ Element.implement({
|
||||
toQueryString: function(){
|
||||
var queryString = [];
|
||||
this.getElements('input, select, textarea', true).each(function(el){
|
||||
if (!el.name || el.disabled) return;
|
||||
if (!el.name || el.disabled || el.type == 'submit' || el.type == 'reset' || el.type == 'file') return;
|
||||
var value = (el.tagName.toLowerCase() == 'select') ? Element.getSelected(el).map(function(opt){
|
||||
return opt.value;
|
||||
}) : ((el.type == 'radio' || el.type == 'checkbox') && !el.checked) ? null : el.value;
|
||||
@@ -1775,7 +1839,7 @@ Element.implement({
|
||||
}
|
||||
|
||||
clean(clone, this);
|
||||
return $(clone);
|
||||
return document.id(clone);
|
||||
},
|
||||
|
||||
destroy: function(){
|
||||
@@ -1797,7 +1861,7 @@ Element.implement({
|
||||
},
|
||||
|
||||
hasChild: function(el){
|
||||
el = $(el, true);
|
||||
el = document.id(el, true);
|
||||
if (!el) return false;
|
||||
if (Browser.Engine.webkit && Browser.Engine.version < 420) return $A(this.getElementsByTagName(el.tagName)).contains(el);
|
||||
return (this.contains) ? (this != el && this.contains(el)) : !!(this.compareDocumentPosition(el) & 16);
|
||||
@@ -1992,14 +2056,15 @@ Native.implement([Element, Window, Document], {
|
||||
},
|
||||
|
||||
removeEvents: function(events){
|
||||
var type;
|
||||
if ($type(events) == 'object'){
|
||||
for (var type in events) this.removeEvent(type, events[type]);
|
||||
for (type in events) this.removeEvent(type, events[type]);
|
||||
return this;
|
||||
}
|
||||
var attached = this.retrieve('events');
|
||||
if (!attached) return this;
|
||||
if (!events){
|
||||
for (var type in attached) this.removeEvents(type);
|
||||
for (type in attached) this.removeEvents(type);
|
||||
this.eliminate('events');
|
||||
} else if (attached[events]){
|
||||
while (attached[events].keys[0]) this.removeEvent(events, attached[events].keys[0]);
|
||||
@@ -2018,7 +2083,7 @@ Native.implement([Element, Window, Document], {
|
||||
},
|
||||
|
||||
cloneEvents: function(from, type){
|
||||
from = $(from);
|
||||
from = document.id(from);
|
||||
var fevents = from.retrieve('events');
|
||||
if (!fevents) return this;
|
||||
if (!type){
|
||||
@@ -2157,7 +2222,7 @@ Element.implement({
|
||||
var color = result.match(/rgba?\([\d\s,]+\)/);
|
||||
if (color) result = result.replace(color[0], color[0].rgbToHex());
|
||||
}
|
||||
if (Browser.Engine.presto || (Browser.Engine.trident && !$chk(parseInt(result)))){
|
||||
if (Browser.Engine.presto || (Browser.Engine.trident && !$chk(parseInt(result, 10)))){
|
||||
if (property.test(/^(height|width)$/)){
|
||||
var values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom'], size = 0;
|
||||
values.each(function(value){
|
||||
@@ -2178,7 +2243,7 @@ Element.implement({
|
||||
|
||||
getStyles: function(){
|
||||
var result = {};
|
||||
Array.each(arguments, function(key){
|
||||
Array.flatten(arguments).each(function(key){
|
||||
result[key] = this.getStyle(key);
|
||||
}, this);
|
||||
return result;
|
||||
@@ -2276,12 +2341,15 @@ Element.implement({
|
||||
return null;
|
||||
},
|
||||
|
||||
getOffsets: function(){
|
||||
if (Browser.Engine.trident){
|
||||
var bound = this.getBoundingClientRect(), html = this.getDocument().documentElement;
|
||||
getOffsets: function(){
|
||||
if (this.getBoundingClientRect){
|
||||
var bound = this.getBoundingClientRect(),
|
||||
html = document.id(this.getDocument().documentElement),
|
||||
scroll = html.getScroll(),
|
||||
isFixed = (styleString(this, 'position') == 'fixed');
|
||||
return {
|
||||
x: bound.left + html.scrollLeft - html.clientLeft,
|
||||
y: bound.top + html.scrollTop - html.clientTop
|
||||
x: parseInt(bound.left, 10) + ((isFixed) ? 0 : scroll.x) - html.clientLeft,
|
||||
y: parseInt(bound.top, 10) + ((isFixed) ? 0 : scroll.y) - html.clientTop
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2320,7 +2388,7 @@ Element.implement({
|
||||
if (isBody(this)) return {x: 0, y: 0};
|
||||
var offset = this.getOffsets(), scroll = this.getScrolls();
|
||||
var position = {x: offset.x - scroll.x, y: offset.y - scroll.y};
|
||||
var relativePosition = (relative && (relative = $(relative))) ? relative.getPosition() : {x: 0, y: 0};
|
||||
var relativePosition = (relative && (relative = document.id(relative))) ? relative.getPosition() : {x: 0, y: 0};
|
||||
return {x: position.x - relativePosition.x, y: position.y - relativePosition.y};
|
||||
},
|
||||
|
||||
@@ -2337,30 +2405,31 @@ Element.implement({
|
||||
return {left: obj.x - styleNumber(this, 'margin-left'), top: obj.y - styleNumber(this, 'margin-top')};
|
||||
},
|
||||
|
||||
position: function(obj){
|
||||
setPosition: function(obj){
|
||||
return this.setStyles(this.computePosition(obj));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
Native.implement([Document, Window], {
|
||||
|
||||
getSize: function(){
|
||||
var win = this.getWindow();
|
||||
if (Browser.Engine.presto || Browser.Engine.webkit) return {x: win.innerWidth, y: win.innerHeight};
|
||||
if (Browser.Engine.presto || Browser.Engine.webkit) {
|
||||
var win = this.getWindow();
|
||||
return {x: win.innerWidth, y: win.innerHeight};
|
||||
}
|
||||
var doc = getCompatElement(this);
|
||||
return {x: doc.clientWidth, y: doc.clientHeight};
|
||||
},
|
||||
|
||||
getScroll: function(){
|
||||
var win = this.getWindow();
|
||||
var doc = getCompatElement(this);
|
||||
var win = this.getWindow(), doc = getCompatElement(this);
|
||||
return {x: win.pageXOffset || doc.scrollLeft, y: win.pageYOffset || doc.scrollTop};
|
||||
},
|
||||
|
||||
getScrollSize: function(){
|
||||
var doc = getCompatElement(this);
|
||||
var min = this.getSize();
|
||||
var doc = getCompatElement(this), min = this.getSize();
|
||||
return {x: Math.max(doc.scrollWidth, min.x), y: Math.max(doc.scrollHeight, min.y)};
|
||||
},
|
||||
|
||||
@@ -2407,6 +2476,7 @@ function getCompatElement(element){
|
||||
})();
|
||||
|
||||
//aliases
|
||||
Element.alias('setPosition', 'position'); //compatability
|
||||
|
||||
Native.implement([Window, Document, Element], {
|
||||
|
||||
@@ -2504,10 +2574,10 @@ Selectors.Utils = {
|
||||
if (Selectors.Cache.nth[argument]) return Selectors.Cache.nth[argument];
|
||||
var parsed = argument.match(/^([+-]?\d*)?([a-z]+)?([+-]?\d*)?$/);
|
||||
if (!parsed) return false;
|
||||
var inta = parseInt(parsed[1]);
|
||||
var inta = parseInt(parsed[1], 10);
|
||||
var a = (inta || inta === 0) ? inta : 1;
|
||||
var special = parsed[2] || false;
|
||||
var b = parseInt(parsed[3]) || 0;
|
||||
var b = parseInt(parsed[3], 10) || 0;
|
||||
if (a != 0){
|
||||
b--;
|
||||
while (b < 1) b += a;
|
||||
@@ -2725,7 +2795,7 @@ Selectors.Pseudo = new Hash({
|
||||
checked: function(){
|
||||
return this.checked;
|
||||
},
|
||||
|
||||
|
||||
empty: function(){
|
||||
return !(this.innerText || this.textContent || '').length;
|
||||
},
|
||||
@@ -2801,6 +2871,14 @@ Selectors.Pseudo = new Hash({
|
||||
|
||||
odd: function(argument, local){
|
||||
return Selectors.Pseudo['nth-child'].call(this, '2n', local);
|
||||
},
|
||||
|
||||
selected: function(){
|
||||
return this.selected;
|
||||
},
|
||||
|
||||
enabled: function(){
|
||||
return (this.disabled === false);
|
||||
}
|
||||
|
||||
});
|
||||
@@ -2835,8 +2913,8 @@ Element.Events.domready = {
|
||||
var temp = document.createElement('div');
|
||||
(function(){
|
||||
($try(function(){
|
||||
temp.doScroll('left');
|
||||
return $(temp).inject(document.body).set('html', 'temp').dispose();
|
||||
temp.doScroll(); // Technique by Diego Perini
|
||||
return document.id(temp).inject(document.body).set('html', 'temp').dispose();
|
||||
})) ? domready() : arguments.callee.delay(50);
|
||||
})();
|
||||
} else if (Browser.Engine.webkit && Browser.Engine.version < 525){
|
||||
@@ -2875,7 +2953,7 @@ var JSON = new Hash({
|
||||
case 'string':
|
||||
return '"' + obj.replace(/[\x00-\x1f\\"]/g, JSON.$replaceChars) + '"';
|
||||
case 'array':
|
||||
return '[' + String(obj.map(JSON.encode).filter($defined)) + ']';
|
||||
return '[' + String(obj.map(JSON.encode).clean()) + ']';
|
||||
case 'object': case 'hash':
|
||||
var string = [];
|
||||
Hash.each(obj, function(value, key){
|
||||
@@ -3014,7 +3092,7 @@ var Swiff = new Class({
|
||||
this.setOptions(options);
|
||||
options = this.options;
|
||||
var id = this.id = options.id || this.instance;
|
||||
var container = $(options.container);
|
||||
var container = document.id(options.container);
|
||||
|
||||
Swiff.CallBacks[this.instance] = {};
|
||||
|
||||
@@ -3051,13 +3129,13 @@ var Swiff = new Class({
|
||||
},
|
||||
|
||||
replaces: function(element){
|
||||
element = $(element, true);
|
||||
element = document.id(element, true);
|
||||
element.parentNode.replaceChild(this.toElement(), element);
|
||||
return this;
|
||||
},
|
||||
|
||||
inject: function(element){
|
||||
$(element, true).appendChild(this.toElement());
|
||||
document.id(element, true).appendChild(this.toElement());
|
||||
return this;
|
||||
},
|
||||
|
||||
@@ -3132,17 +3210,17 @@ var Fx = new Class({
|
||||
return Fx.compute(from, to, delta);
|
||||
},
|
||||
|
||||
check: function(caller){
|
||||
check: function(){
|
||||
if (!this.timer) return true;
|
||||
switch (this.options.link){
|
||||
case 'cancel': this.cancel(); return true;
|
||||
case 'chain': this.chain(caller.bind(this, Array.slice(arguments, 1))); return false;
|
||||
case 'chain': this.chain(this.caller.bind(this, arguments)); return false;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
start: function(from, to){
|
||||
if (!this.check(arguments.callee, from, to)) return this;
|
||||
if (!this.check(from, to)) return this;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.time = 0;
|
||||
@@ -3355,7 +3433,7 @@ Fx.Tween = new Class({
|
||||
Extends: Fx.CSS,
|
||||
|
||||
initialize: function(element, options){
|
||||
this.element = this.subject = $(element);
|
||||
this.element = this.subject = document.id(element);
|
||||
this.parent(options);
|
||||
},
|
||||
|
||||
@@ -3369,7 +3447,7 @@ Fx.Tween = new Class({
|
||||
},
|
||||
|
||||
start: function(property, from, to){
|
||||
if (!this.check(arguments.callee, property, from, to)) return this;
|
||||
if (!this.check(property, from, to)) return this;
|
||||
var args = Array.flatten(arguments);
|
||||
this.property = this.options.property || args.shift();
|
||||
var parsed = this.prepare(this.element, this.property, args);
|
||||
@@ -3452,7 +3530,7 @@ Fx.Morph = new Class({
|
||||
Extends: Fx.CSS,
|
||||
|
||||
initialize: function(element, options){
|
||||
this.element = this.subject = $(element);
|
||||
this.element = this.subject = document.id(element);
|
||||
this.parent(options);
|
||||
},
|
||||
|
||||
@@ -3469,7 +3547,7 @@ Fx.Morph = new Class({
|
||||
},
|
||||
|
||||
start: function(properties){
|
||||
if (!this.check(arguments.callee, properties)) return this;
|
||||
if (!this.check(properties)) return this;
|
||||
if (typeof properties == 'string') properties = this.search(properties);
|
||||
var from = {}, to = {};
|
||||
for (var p in properties){
|
||||
@@ -3642,7 +3720,8 @@ var Request = new Class({
|
||||
urlEncoded: true,
|
||||
encoding: 'utf-8',
|
||||
evalScripts: false,
|
||||
evalResponse: false
|
||||
evalResponse: false,
|
||||
noCache: false
|
||||
},
|
||||
|
||||
initialize: function(options){
|
||||
@@ -3659,6 +3738,7 @@ var Request = new Class({
|
||||
$try(function(){
|
||||
this.status = this.xhr.status;
|
||||
}.bind(this));
|
||||
this.xhr.onreadystatechange = $empty;
|
||||
if (this.options.isSuccess.call(this, this.status)){
|
||||
this.response = {text: this.xhr.responseText, xml: this.xhr.responseXML};
|
||||
this.success(this.response.text, this.response.xml);
|
||||
@@ -3666,7 +3746,6 @@ var Request = new Class({
|
||||
this.response = {text: null, xml: null};
|
||||
this.failure();
|
||||
}
|
||||
this.xhr.onreadystatechange = $empty;
|
||||
},
|
||||
|
||||
isSuccess: function(){
|
||||
@@ -3705,17 +3784,17 @@ var Request = new Class({
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
check: function(caller){
|
||||
check: function(){
|
||||
if (!this.running) return true;
|
||||
switch (this.options.link){
|
||||
case 'cancel': this.cancel(); return true;
|
||||
case 'chain': this.chain(caller.bind(this, Array.slice(arguments, 1))); return false;
|
||||
case 'chain': this.chain(this.caller.bind(this, arguments)); return false;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
send: function(options){
|
||||
if (!this.check(arguments.callee, options)) return this;
|
||||
if (!this.check(options)) return this;
|
||||
this.running = true;
|
||||
|
||||
var type = $type(options);
|
||||
@@ -3723,10 +3802,10 @@ var Request = new Class({
|
||||
|
||||
var old = this.options;
|
||||
options = $extend({data: old.data, url: old.url, method: old.method}, options);
|
||||
var data = options.data, url = options.url, method = options.method;
|
||||
var data = options.data, url = options.url, method = options.method.toLowerCase();
|
||||
|
||||
switch ($type(data)){
|
||||
case 'element': data = $(data).toQueryString(); break;
|
||||
case 'element': data = document.id(data).toQueryString(); break;
|
||||
case 'object': case 'hash': data = Hash.toQueryString(data);
|
||||
}
|
||||
|
||||
@@ -3735,7 +3814,7 @@ var Request = new Class({
|
||||
data = (data) ? format + '&' + data : format;
|
||||
}
|
||||
|
||||
if (this.options.emulation && ['put', 'delete'].contains(method)){
|
||||
if (this.options.emulation && !['get', 'post'].contains(method)){
|
||||
var _method = '_method=' + method;
|
||||
data = (data) ? _method + '&' + data : _method;
|
||||
method = 'post';
|
||||
@@ -3746,6 +3825,14 @@ var Request = new Class({
|
||||
this.headers.set('Content-type', 'application/x-www-form-urlencoded' + encoding);
|
||||
}
|
||||
|
||||
if (this.options.noCache){
|
||||
var noCache = 'noCache=' + new Date().getTime();
|
||||
data = (data) ? noCache + '&' + data : noCache;
|
||||
}
|
||||
|
||||
var trimPosition = url.lastIndexOf('/');
|
||||
if (trimPosition > -1 && (trimPosition = url.indexOf('#')) > -1) url = url.substr(0, trimPosition);
|
||||
|
||||
if (data && method == 'get'){
|
||||
url = url + (url.contains('?') ? '&' : '?') + data;
|
||||
data = null;
|
||||
@@ -3787,7 +3874,7 @@ var methods = {};
|
||||
['get', 'post', 'put', 'delete', 'GET', 'POST', 'PUT', 'DELETE'].each(function(method){
|
||||
methods[method] = function(){
|
||||
var params = Array.link(arguments, {url: String.type, data: $defined});
|
||||
return this.send($extend(params, {method: method.toLowerCase()}));
|
||||
return this.send($extend(params, {method: method}));
|
||||
};
|
||||
});
|
||||
|
||||
@@ -3840,6 +3927,7 @@ Request.HTML = new Class({
|
||||
|
||||
options: {
|
||||
update: false,
|
||||
append: false,
|
||||
evalScripts: true,
|
||||
filter: false
|
||||
},
|
||||
@@ -3860,6 +3948,7 @@ Request.HTML = new Class({
|
||||
doc = new DOMParser().parseFromString(root, 'text/xml');
|
||||
}
|
||||
root = doc.getElementsByTagName('root')[0];
|
||||
if (!root) return null;
|
||||
for (var i = 0, k = root.childNodes.length; i < k; i++){
|
||||
var child = Element.clone(root.childNodes[i], true, true);
|
||||
if (child) container.grab(child);
|
||||
@@ -3881,7 +3970,8 @@ Request.HTML = new Class({
|
||||
response.elements = temp.getElements('*');
|
||||
|
||||
if (options.filter) response.tree = response.elements.filter(options.filter);
|
||||
if (options.update) $(options.update).empty().set('html', response.html);
|
||||
if (options.update) document.id(options.update).empty().set('html', response.html);
|
||||
else if (options.append) document.id(options.append).adopt(temp.getChildren());
|
||||
if (options.evalScripts) $exec(response.javascript);
|
||||
|
||||
this.onSuccess(response.tree, response.elements, response.html, response.javascript);
|
||||
|
||||
@@ -146,17 +146,28 @@ body {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
#menu2 {
|
||||
position: absolute;
|
||||
height: 30px;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#table-container {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.menu2 {
|
||||
font-size: 95%;
|
||||
white-space: nowrap;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.menu2 ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
float: left;
|
||||
width: 100%;
|
||||
font-weight: bold;
|
||||
color: #2a4069;
|
||||
}
|
||||
|
||||
.menu2 li {
|
||||
@@ -165,6 +176,21 @@ body {
|
||||
margin: 2px 5px;
|
||||
}
|
||||
|
||||
.dropdown ul {
|
||||
display: block;
|
||||
background: #ffffcc;
|
||||
width: 150px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.menu2 li ul li {
|
||||
padding: 5px;
|
||||
display: block;
|
||||
float: none;
|
||||
}
|
||||
|
||||
.menu2 li.selected {
|
||||
/* text-decoration: underline;*/
|
||||
background: #ffffcc;
|
||||
|
||||
@@ -1,14 +1,29 @@
|
||||
{% load i18n %}
|
||||
<ul>
|
||||
{% for entry in entries %}
|
||||
{% if entry.menu %}
|
||||
<li class="dropdown">
|
||||
<img src="{{ entry.img }}" border="0" />
|
||||
{{ entry.label }}
|
||||
<ul class="links">
|
||||
{% for sentry in entry.menu %}
|
||||
<a href="{{ sentry.url }}" name="{{ sentry.name }}">
|
||||
<li>{{ sentry.label }}</li>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
{% else %}
|
||||
<li {% ifequal selection entry.name %}class="selected"{% endifequal %}>
|
||||
<a href="{{ entry.url }}" name="{{ entry.name }}"
|
||||
<a href="{{ entry.url }}" name="{{ entry.name }}"
|
||||
{% if entry.class %}class={{ entry.class }}{% endif %}
|
||||
{% if entry.rel %}rel={{ entry.rel }}{% endif %}
|
||||
{% if entry.confirm %} onclick="return confirm('{{ entry.confirm }}')"{% endif %}>
|
||||
<img src="{{ entry.img }}" border="0" />
|
||||
{{ entry.label }}
|
||||
</a>
|
||||
|
||||
<img src="{{ entry.img }}" border="0" />
|
||||
{{ entry.label }}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
Reference in New Issue
Block a user