wip: Global user interface improvment
* Use of jQuery in place of Mootools * Most of the custom mootools plugins have been ported to jQuery * Use of bootstrap from Twitter in place of the old CSS * Most of the admin templates have been reworked * The sievefilters extension has been ported * The postfix autoreply extension is almost done * more... see #204
@@ -1,15 +1,25 @@
|
||||
# coding: utf-8
|
||||
from django import forms
|
||||
from django.contrib.auth.models import Group
|
||||
from modoboa.admin.models import *
|
||||
from django.utils.translation import ugettext as _, ugettext_noop
|
||||
from django.http import QueryDict
|
||||
from modoboa.admin.templatetags.admin_extras import gender
|
||||
from modoboa.lib import tables
|
||||
from modoboa.lib.emailutils import split_mailbox
|
||||
from modoboa.lib.permissions import get_account_roles
|
||||
from modoboa.lib.formutils import *
|
||||
from modoboa.lib.permissions import *
|
||||
|
||||
class DomainForm(forms.ModelForm, DynamicForm):
|
||||
aliases = DomainNameField(
|
||||
label=ugettext_noop("Alias(es)"),
|
||||
required=False,
|
||||
help_text=ugettext_noop("Alias(es) of this domain")
|
||||
)
|
||||
|
||||
class DomainForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Domain
|
||||
fields = ("name", "quota", "enabled")
|
||||
fields = ("name", "quota", "aliases", "enabled")
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.oldname = None
|
||||
@@ -17,240 +27,235 @@ class DomainForm(forms.ModelForm):
|
||||
self.oldname = kwargs["instance"].name
|
||||
super(DomainForm, self).__init__(*args, **kwargs)
|
||||
|
||||
def save(self, force_insert=False, force_update=False, commit=True):
|
||||
if len(args) and isinstance(args[0], QueryDict):
|
||||
self._load_from_qdict(args[0], "aliases", DomainNameField)
|
||||
elif kwargs.has_key("instance"):
|
||||
d = kwargs["instance"]
|
||||
for pos, dalias in enumerate(d.domainalias_set.all()):
|
||||
name = "aliases_%d" % (pos + 1)
|
||||
self._create_field(forms.CharField, name, dalias.name, 3)
|
||||
|
||||
def clean(self):
|
||||
super(DomainForm, self).clean()
|
||||
if len(self._errors):
|
||||
raise forms.ValidationError(self._errors)
|
||||
|
||||
cleaned_data = self.cleaned_data
|
||||
name = cleaned_data["name"]
|
||||
|
||||
try:
|
||||
DomainAlias.objects.get(name=name)
|
||||
except DomainAlias.DoesNotExist:
|
||||
pass
|
||||
else:
|
||||
self._errors["name"] = self.error_class([_("An alias with this name already exists")])
|
||||
del cleaned_data["name"]
|
||||
|
||||
errors = []
|
||||
for k in cleaned_data.keys():
|
||||
if not k.startswith("aliases"):
|
||||
continue
|
||||
if cleaned_data[k] == "":
|
||||
del cleaned_data[k]
|
||||
continue
|
||||
try:
|
||||
Domain.objects.get(name=cleaned_data[k])
|
||||
except Domain.DoesNotExist:
|
||||
pass
|
||||
else:
|
||||
self._errors[k] = self.error_class([_("A domain with this name already exists")])
|
||||
del cleaned_data[k]
|
||||
|
||||
return cleaned_data
|
||||
|
||||
def save(self, user, commit=True):
|
||||
d = super(DomainForm, self).save(commit=False)
|
||||
if commit:
|
||||
if self.oldname is not None and d.name != self.oldname:
|
||||
if not d.rename_dir(self.oldname):
|
||||
raise AdminError(_("Failed to rename domain, check permissions"))
|
||||
d.save()
|
||||
for k, v in self.cleaned_data.iteritems():
|
||||
if not k.startswith("aliases"):
|
||||
continue
|
||||
if v in ["", None]:
|
||||
continue
|
||||
try:
|
||||
d.domainalias_set.get(name=v)
|
||||
except DomainAlias.DoesNotExist:
|
||||
pass
|
||||
else:
|
||||
continue
|
||||
events.raiseEvent("CanCreate", user, "domain_aliases")
|
||||
al = DomainAlias(name=v, target=d, enabled=d.enabled)
|
||||
al.save()
|
||||
grant_access_to_object(user, al, is_owner=True)
|
||||
events.raiseEvent("DomainAliasCreated", user, al)
|
||||
|
||||
for dalias in d.domainalias_set.all():
|
||||
if not len(filter(lambda name: self.cleaned_data[name] == dalias.name,
|
||||
self.cleaned_data.keys())):
|
||||
events.raiseEvent("DomainAliasDeleted", dalias)
|
||||
ungrant_access_to_object(dalias)
|
||||
dalias.delete()
|
||||
return d
|
||||
|
||||
class ProxyForm(forms.ModelForm):
|
||||
def __init__(self, user, *args, **kwargs):
|
||||
super(ProxyForm, self).__init__(*args, **kwargs)
|
||||
|
||||
if not user.is_superuser:
|
||||
self._domains = user.get_domains()
|
||||
else:
|
||||
self._domains = None
|
||||
|
||||
class DomainAliasForm(ProxyForm):
|
||||
class Meta:
|
||||
model = DomainAlias
|
||||
fields = ('name', 'target', 'enabled')
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DomainAliasForm, self).__init__(*args, **kwargs)
|
||||
if self._domains is not None:
|
||||
#self.fields["target"].queryset = Domain.objects.filter(pk=self._domain.id)
|
||||
self.fields["target"].queryset = self._domains
|
||||
|
||||
class MailboxForm(ProxyForm):
|
||||
name = forms.CharField(
|
||||
label=ugettext_noop("Name"), max_length=100,
|
||||
help_text=ugettext_noop("First name and last name of mailbox owner")
|
||||
class DlistForm(forms.ModelForm, DynamicForm):
|
||||
email = forms.EmailField(
|
||||
label=ugettext_noop("Email address"),
|
||||
help_text=ugettext_noop("")
|
||||
)
|
||||
recipients = forms.EmailField(
|
||||
label=ugettext_noop("Recipients"), required=False,
|
||||
help_text=ugettext_noop("Mailbox(es) this alias will point to")
|
||||
)
|
||||
quota = forms.IntegerField(label=ugettext_noop("Quota"), required=False,
|
||||
help_text=ugettext_noop("Mailbox quota in MB (default to domain quota if blank)"))
|
||||
enabled = forms.BooleanField(label=gender("Enabled", "f"), required=False,
|
||||
initial=True,
|
||||
help_text=ugettext_noop("Check to activate this mailbox"))
|
||||
|
||||
class Meta:
|
||||
model = Mailbox
|
||||
fields = ('domain', 'address')
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(MailboxForm, self).__init__(*args, **kwargs)
|
||||
for f in ['name', 'address', 'quota']:
|
||||
self.fields[f].widget.attrs['size'] = 14
|
||||
if self._domains is not None:
|
||||
self.fields["domain"].queryset = self._domains
|
||||
#self.fields["domain"].queryset = Domain.objects.filter(pk=self._domain.id)
|
||||
#self.fields["domain"].initial = self._domain
|
||||
|
||||
if kwargs.has_key("instance"):
|
||||
mb = kwargs["instance"]
|
||||
self.fields['name'].initial = unicode(mb.user)
|
||||
self.fields['quota'].initial = mb.quota
|
||||
self.fields['enabled'].initial = mb.user.is_active
|
||||
|
||||
def clean_address(self):
|
||||
if self.cleaned_data["address"].find('@') != -1:
|
||||
return self.cleaned_data["address"].rsplit("@", 1)[0]
|
||||
return self.cleaned_data["address"]
|
||||
|
||||
def commit_save(self, mb, **kwargs):
|
||||
mb.save(name=self.cleaned_data["name"],
|
||||
enabled=self.cleaned_data["enabled"],
|
||||
quota=self.cleaned_data["quota"],
|
||||
**kwargs)
|
||||
|
||||
def save(self, force_insert=False, force_update=False, commit=True):
|
||||
m = super(MailboxForm, self).save(commit=False)
|
||||
if commit:
|
||||
self.commit_save(m)
|
||||
return m
|
||||
|
||||
class MailboxWithPasswordForm(MailboxForm):
|
||||
password1 = forms.CharField(label=ugettext_noop("Password"),
|
||||
widget=forms.PasswordInput(render_value=True),
|
||||
help_text=ugettext_noop("Password used to log in"))
|
||||
password2 = forms.CharField(label=ugettext_noop("Confirmation"),
|
||||
widget=forms.PasswordInput(render_value=True),
|
||||
help_text=ugettext_noop("Password confirmation"))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(MailboxWithPasswordForm, self).__init__(*args, **kwargs)
|
||||
for f in ['password1', 'password2']:
|
||||
self.fields[f].widget.attrs['size'] = 14
|
||||
self.fields.keyOrder = ['name', 'domain', 'address', 'quota',
|
||||
'password1', 'password2', 'enabled']
|
||||
|
||||
def clean_password2(self):
|
||||
if self.cleaned_data["password1"] != self.cleaned_data["password2"]:
|
||||
raise forms.ValidationError(_("Passwords mismatch"))
|
||||
return self.cleaned_data["password2"]
|
||||
|
||||
def commit_save(self, mb):
|
||||
super(MailboxWithPasswordForm, self).commit_save(
|
||||
mb, password=self.cleaned_data["password1"]
|
||||
)
|
||||
|
||||
class AliasForm(ProxyForm):
|
||||
targets = forms.CharField(label=ugettext_noop("Target(s)"), required=False,
|
||||
help_text=ugettext_noop("Mailbox(es) this alias will point to"))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(AliasForm, self).__init__(*args, **kwargs)
|
||||
self.fields['address'].widget.attrs['size'] = 14
|
||||
|
||||
# This part is a little bit tricky. As 'domain' is not a
|
||||
# member of Alias, we need to fill it manually. if
|
||||
# self._domain exists, it means a DomainAdmin is going to
|
||||
# create a new alias, we know how to fill the fields.
|
||||
# if self._domain is not None:
|
||||
# self.fields["domain"].queryset = Domain.objects.filter(pk=self._domain.id)
|
||||
|
||||
if self._domains is not None:
|
||||
self.fields["domain"].queryset = self._domains
|
||||
|
||||
# if 'instance' exists, it means we are modifying an existing
|
||||
# record, we need to select the right value for 'domain' and
|
||||
# to fill the first "targets" input (because it is created by the
|
||||
# Form object, not by us).
|
||||
#domain = None
|
||||
# if self._domain:
|
||||
# domain = self._domain
|
||||
if kwargs.has_key("instance"):
|
||||
# if self._domain is None:
|
||||
# domain = kwargs["instance"].domain
|
||||
self.fields["targets"].initial = kwargs["instance"].first_target()
|
||||
|
||||
# if domain is not None:
|
||||
# self.fields["domain"].initial = domain
|
||||
|
||||
self.fields.keyOrder = ['address', 'domain', 'enabled', 'targets']
|
||||
|
||||
class Meta:
|
||||
model = Alias
|
||||
fields = ('address', 'domain', 'enabled')
|
||||
fields = ("enabled",)
|
||||
|
||||
def clean_address(self):
|
||||
if self.cleaned_data["address"].find('@') != -1:
|
||||
return self.cleaned_data["address"].rsplit("@", 1)[0]
|
||||
return self.cleaned_data["address"]
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DlistForm, self).__init__(*args, **kwargs)
|
||||
self.fields.keyOrder = ['email', 'recipients', 'enabled']
|
||||
|
||||
def set_targets(self, user, values):
|
||||
"""Targets dispatching
|
||||
if len(args) and isinstance(args[0], QueryDict):
|
||||
self._load_from_qdict(args[0], "recipients", forms.EmailField)
|
||||
elif kwargs.has_key("instance"):
|
||||
dlist = kwargs["instance"]
|
||||
self.fields["email"].initial = dlist.full_address
|
||||
cpt = 1
|
||||
for mb in dlist.mboxes.all():
|
||||
name = "recipients_%d" % (cpt)
|
||||
self._create_field(forms.EmailField, name, mb.full_address, 2)
|
||||
cpt += 1
|
||||
for addr in dlist.extmboxes.split(','):
|
||||
if addr == "":
|
||||
continue
|
||||
name = "recipients_%d" % (cpt)
|
||||
self._create_field(forms.EmailField, name, addr, 2)
|
||||
cpt += 1
|
||||
|
||||
We make a difference between 'local' targets (the ones hosted
|
||||
by Modoboa) and 'external targets.
|
||||
def clean_email(self):
|
||||
localpart, domname = split_mailbox(self.cleaned_data["email"])
|
||||
try:
|
||||
Domain.objects.get(name=domname)
|
||||
except Domain.DoesNotExist:
|
||||
raise forms.ValidationError(_("Domain does not exist"))
|
||||
return self.cleaned_data["email"]
|
||||
|
||||
def set_recipients(self, user):
|
||||
"""Recipients dispatching
|
||||
|
||||
We make a difference between 'local' recipients (the ones hosted
|
||||
by Modoboa) and 'external' recipients.
|
||||
"""
|
||||
self.ext_targets = []
|
||||
self.int_targets = []
|
||||
self.ext_rcpts = []
|
||||
self.int_rcpts = []
|
||||
total = 0
|
||||
|
||||
for addr in values:
|
||||
if addr == "":
|
||||
for k, v in self.cleaned_data.iteritems():
|
||||
if not k.startswith("recipients"):
|
||||
continue
|
||||
local_part, domname = split_mailbox(addr)
|
||||
if v == "":
|
||||
continue
|
||||
local_part, domname = split_mailbox(v)
|
||||
if domname is None:
|
||||
raise AdminError("%s %s" % (_("Invalid mailbox"), addr))
|
||||
raise AdminError("%s %s" % (_("Invalid mailbox"), v))
|
||||
try:
|
||||
domain = Domain.objects.get(name=domname)
|
||||
except Domain.DoesNotExist:
|
||||
domain = None
|
||||
if domain:
|
||||
if not user.is_owner(domain):
|
||||
raise PermDeniedException(addr)
|
||||
raise PermDeniedException(v)
|
||||
try:
|
||||
mb = Mailbox.objects.get(domain=domain, address=local_part)
|
||||
except Mailbox.DoesNotExist:
|
||||
raise AdminError(_("Mailbox %s does not exist" % addr))
|
||||
self.int_targets += [mb]
|
||||
raise AdminError(_("Mailbox %s does not exist" % v))
|
||||
self.int_rcpts += [mb]
|
||||
total += 1
|
||||
continue
|
||||
|
||||
self.ext_targets += [addr]
|
||||
self.ext_rcpts += [v]
|
||||
total += 1
|
||||
|
||||
def save(self, force_insert=False, force_update=False, commit=True):
|
||||
a = super(AliasForm, self).save(commit=False)
|
||||
if total == 0:
|
||||
raise AdminError(_("No recipient defined"))
|
||||
|
||||
if total < 2:
|
||||
raise AdminError(_("A distribution list must contain at least two recipients"))
|
||||
|
||||
def save(self, commit=True):
|
||||
dlist = super(DlistForm, self).save(commit=False)
|
||||
localpart, domname = split_mailbox(self.cleaned_data["email"])
|
||||
dlist.address = localpart
|
||||
dlist.domain = Domain.objects.get(name=domname)
|
||||
if commit:
|
||||
a.save(self.int_targets, self.ext_targets)
|
||||
dlist.save(self.int_rcpts, self.ext_rcpts)
|
||||
self.save_m2m()
|
||||
return a
|
||||
return dlist
|
||||
|
||||
class SuperAdminForm(forms.Form):
|
||||
def __init__(self, user, *args, **kwargs):
|
||||
super(SuperAdminForm, self).__init__(*args, **kwargs)
|
||||
class ImportDataForm(forms.Form):
|
||||
sourcefile = forms.FileField(label=_("Select a file"))
|
||||
sepcar = forms.CharField(label=_("Separator"), max_length=1, required=False)
|
||||
|
||||
self.fields["user"] = \
|
||||
forms.ModelChoiceField([], label=_("User"), required=True,
|
||||
empty_label=_("Select a user"),
|
||||
help_text=_("Select a user in the list"))
|
||||
self.fields["user"].queryset = User.objects.exclude(pk__in=[1, user.id])
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ImportDataForm, self).__init__(*args, **kwargs)
|
||||
self.fields["sepcar"].widget.attrs = {"class" : "span1"}
|
||||
|
||||
class DomainAdminForm(forms.Form):
|
||||
createfrom = forms.ChoiceField(
|
||||
choices=[("new", ugettext_noop("Create a new account")),
|
||||
("select", ugettext_noop("Promote an existing account"))],
|
||||
widget=forms.RadioSelect)
|
||||
def clean_sepcar(self):
|
||||
if self.cleaned_data["sepcar"] == "":
|
||||
return ";"
|
||||
return str(self.cleaned_data["sepcar"])
|
||||
|
||||
domain = forms.ModelChoiceField(
|
||||
queryset=Domain.objects.all(),
|
||||
label=_("Domain"),
|
||||
required=True,
|
||||
empty_label=ugettext_noop("Select a domain"),
|
||||
help_text=ugettext_noop("Select a domain in the list")
|
||||
)
|
||||
|
||||
user = forms.ChoiceField(
|
||||
label=ugettext_noop("User"), required=True,
|
||||
choices=[("", ugettext_noop("Empty"))],
|
||||
help_text=ugettext_noop("Select a user in the list"))
|
||||
|
||||
class UserForm(forms.ModelForm):
|
||||
createmb = forms.BooleanField(
|
||||
label=ugettext_noop("Create mailbox"), required=False,
|
||||
help_text=ugettext_noop("Create a mailbox for this user using the given address")
|
||||
class AccountFormGeneral(forms.ModelForm):
|
||||
role = forms.ChoiceField(
|
||||
choices=[('', ugettext_noop("Choose"))]
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ("username", "first_name", "last_name", "email")
|
||||
fields = ("username", "first_name", "last_name", "role", "is_active")
|
||||
|
||||
def save(self, commit=True, group=None):
|
||||
user = super(UserForm, self).save(commit=False)
|
||||
if self.cleaned_data.has_key("password1"):
|
||||
user.set_password(self.cleaned_data["password1"])
|
||||
def __init__(self, user, *args, **kwargs):
|
||||
super(AccountFormGeneral, self).__init__(*args, **kwargs)
|
||||
|
||||
self.user = user
|
||||
if user.belongs_to_group("DomainAdmins"):
|
||||
del self.fields["role"]
|
||||
return
|
||||
|
||||
self.fields["role"].choices = \
|
||||
[('', ugettext_noop("Choose"))] + get_account_roles(user)
|
||||
if kwargs.has_key("instance"):
|
||||
u = kwargs["instance"]
|
||||
if u.is_superuser:
|
||||
role = "SuperAdmins"
|
||||
else:
|
||||
try:
|
||||
role = u.groups.all()[0].name
|
||||
except IndexError:
|
||||
pass
|
||||
self.fields["role"].initial = role
|
||||
|
||||
def save(self, commit=True):
|
||||
account = super(AccountFormGeneral, self).save(commit=False)
|
||||
if commit:
|
||||
user.save()
|
||||
if group:
|
||||
user.groups.add(Group.objects.get(name=group))
|
||||
user.save()
|
||||
return user
|
||||
account.save()
|
||||
if self.cleaned_data.has_key("role"):
|
||||
role = self.cleaned_data["role"]
|
||||
else:
|
||||
role = "SimpleUsers"
|
||||
if role == "SuperAdmins":
|
||||
account.is_superuser = True
|
||||
else:
|
||||
account.is_superuser = False
|
||||
account.groups.clear()
|
||||
account.groups.add(Group.objects.get(name=role))
|
||||
account.save()
|
||||
return account
|
||||
|
||||
class UserWithPasswordForm(UserForm):
|
||||
class AccountFormGeneralPwd(AccountFormGeneral):
|
||||
password1 = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
|
||||
password2 = forms.CharField(
|
||||
label=ugettext_noop("Confirmation"),
|
||||
@@ -258,6 +263,11 @@ class UserWithPasswordForm(UserForm):
|
||||
help_text=ugettext_noop("Enter the same password as above, for verification.")
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ("username", "first_name", "last_name",
|
||||
"password1", "password2", "role", "is_active")
|
||||
|
||||
def clean_password2(self):
|
||||
password1 = self.cleaned_data.get("password1", "")
|
||||
password2 = self.cleaned_data["password2"]
|
||||
@@ -265,38 +275,194 @@ class UserWithPasswordForm(UserForm):
|
||||
raise forms.ValidationError(_("The two password fields didn't match."))
|
||||
return password2
|
||||
|
||||
class DomainAdminPromotionForm(forms.Form):
|
||||
name = forms.CharField(
|
||||
label=ugettext_noop("Name"),
|
||||
help_text=ugettext_noop("The username/email address/name of the account to promote")
|
||||
def save(self, commit=True, **kwargs):
|
||||
user = super(AccountFormGeneralPwd, self).save(**kwargs)
|
||||
if self.cleaned_data.has_key("password1"):
|
||||
user.set_password(self.cleaned_data["password1"])
|
||||
if commit:
|
||||
user.save()
|
||||
return user
|
||||
|
||||
class AccountFormMail(forms.Form, DynamicForm):
|
||||
# FIXME
|
||||
# * ajout du quota
|
||||
# * Renommage de boite ?
|
||||
|
||||
email = forms.EmailField(label=_("E-mail"), required=False)
|
||||
aliases = forms.EmailField(
|
||||
label=ugettext_noop("Alias(es)"),
|
||||
required=False,
|
||||
help_text=ugettext_noop("Alias(es) of this mailbox")
|
||||
)
|
||||
|
||||
def clean_name(self):
|
||||
def __init__(self, *args, **kwargs):
|
||||
if kwargs.has_key("instance"):
|
||||
self.mb = kwargs["instance"]
|
||||
del kwargs["instance"]
|
||||
super(AccountFormMail, self).__init__(*args, **kwargs)
|
||||
if not hasattr(self, "mb") or self.mb is None:
|
||||
return
|
||||
self.fields["email"].required = True
|
||||
for pos, alias in enumerate(self.mb.alias_set.all()):
|
||||
if len(alias.get_recipients()) >= 2:
|
||||
continue
|
||||
name = "aliases_%d" % (pos + 1)
|
||||
self._create_field(forms.EmailField, name, alias.full_address)
|
||||
self.fields["email"].initial = self.mb.full_address
|
||||
if len(args) and isinstance(args[0], QueryDict):
|
||||
self._load_from_qdict(args[0], "aliases", forms.EmailField)
|
||||
|
||||
def save(self, user, account):
|
||||
if self.cleaned_data["email"] == "":
|
||||
return None
|
||||
|
||||
locpart, domname = split_mailbox(self.cleaned_data["email"])
|
||||
try:
|
||||
u = User.objects.get(username=self.cleaned_data["name"])
|
||||
except User.DoesNotExist:
|
||||
raise forms.ValidationError(_("Unknown user"))
|
||||
return self.cleaned_data["name"]
|
||||
domain = Domain.objects.get(name=domname)
|
||||
except Domain.DoesNotExist:
|
||||
raise AdminError(_("Domain does not exist"))
|
||||
|
||||
class AssignDomainsForm(forms.Form):
|
||||
domains = forms.ModelMultipleChoiceField(
|
||||
queryset=None,
|
||||
label=ugettext_noop("Domains"),
|
||||
required=True,
|
||||
help_text=ugettext_noop("Select one or more domains in the list")
|
||||
if not user.can_access(domain):
|
||||
raise PermDeniedException(_("You don't have access to this domain"))
|
||||
|
||||
if not hasattr(self, "mb") or self.mb is None:
|
||||
try:
|
||||
self.mb = Mailbox.objects.get(address=locpart, domain=domain)
|
||||
except Mailbox.DoesNotExist:
|
||||
events.raiseEvent("CanCreate", user, "mailboxes")
|
||||
self.mb = Mailbox()
|
||||
self.mb.save_from_user(locpart, domain, account)
|
||||
grant_access_to_object(user, self.mb, is_owner=True)
|
||||
events.raiseEvent("CreateMailbox", user, self.mb)
|
||||
else:
|
||||
if self.cleaned_data["email"] != self.mb.full_address:
|
||||
if self.mb.rename_dir(domname, locpart):
|
||||
self.mb.domain = domain
|
||||
self.mb.address = locpart
|
||||
self.mb.save()
|
||||
else:
|
||||
raise AdminError(_("Failed to rename mailbox, check permissions"))
|
||||
|
||||
account.email = self.cleaned_data["email"]
|
||||
account.save()
|
||||
|
||||
for name, value in self.cleaned_data.iteritems():
|
||||
if not name.startswith("aliases"):
|
||||
continue
|
||||
if value == "":
|
||||
continue
|
||||
local_part, domname = split_mailbox(value)
|
||||
try:
|
||||
self.mb.alias_set.get(address=local_part, domain__name=domname)
|
||||
except Alias.DoesNotExist:
|
||||
pass
|
||||
else:
|
||||
continue
|
||||
events.raiseEvent("CanCreate", user, "mailbox_aliases")
|
||||
al = Alias(address=local_part, enabled=account.is_active)
|
||||
al.domain = Domain.objects.get(name=domname)
|
||||
al.save([self.mb], [])
|
||||
grant_access_to_object(user, al, is_owner=True)
|
||||
events.raiseEvent("MailboxAliasCreated", user, al)
|
||||
|
||||
for alias in self.mb.alias_set.all():
|
||||
if len(alias.get_recipients()) >= 2:
|
||||
continue
|
||||
if not len(filter(lambda name: self.cleaned_data[name] == alias.full_address,
|
||||
self.cleaned_data.keys())):
|
||||
events.raiseEvent("MailboxAliasDeleted", alias)
|
||||
ungrant_access_to_object(alias)
|
||||
alias.delete()
|
||||
|
||||
return self.mb
|
||||
|
||||
class AccountPermissionsForm(forms.Form, DynamicForm):
|
||||
domains = DomainNameField(
|
||||
label=ugettext_noop("Domain(s)"),
|
||||
required=False,
|
||||
help_text=ugettext_noop("Domain(s) that user administrates")
|
||||
)
|
||||
|
||||
def __init__(self, user, domadmin, *args, **kwargs):
|
||||
super(AssignDomainsForm, self).__init__(*args, **kwargs)
|
||||
self.fields["domains"].queryset = user.get_domains()
|
||||
self.fields["domains"].initial = domadmin.get_domains()
|
||||
def __init__(self, *args, **kwargs):
|
||||
if kwargs.has_key("instance"):
|
||||
self.account = kwargs["instance"]
|
||||
del kwargs["instance"]
|
||||
|
||||
super(AccountPermissionsForm, self).__init__(*args, **kwargs)
|
||||
|
||||
class ImportDataForm(forms.Form):
|
||||
sourcefile = forms.FileField(label=_("Select a file"))
|
||||
sepcar = forms.CharField(label=_("Separator"), max_length=1, required=False)
|
||||
if not hasattr(self, "account") or self.account is None:
|
||||
return
|
||||
for pos, domain in enumerate(self.account.get_domains()):
|
||||
name = "domains_%d" % (pos + 1)
|
||||
self._create_field(DomainNameField, name, domain.name)
|
||||
if len(args) and isinstance(args[0], QueryDict):
|
||||
self._load_from_qdict(args[0], "domains", DomainNameField)
|
||||
|
||||
def clean_sepcar(self):
|
||||
if self.cleaned_data["sepcar"] == "":
|
||||
return ";"
|
||||
return self.cleaned_data["sepcar"]
|
||||
def save(self):
|
||||
current_domains = map(lambda dom: dom.name, self.account.get_domains())
|
||||
for name, value in self.cleaned_data.iteritems():
|
||||
if not name.startswith("domains"):
|
||||
continue
|
||||
if value in ["", None]:
|
||||
continue
|
||||
if not value in current_domains:
|
||||
domain = Domain.objects.get(name=value)
|
||||
grant_access_to_object(self.account, domain)
|
||||
|
||||
for domain in self.account.get_domains():
|
||||
if not len(filter(lambda name: self.cleaned_data[name] == domain.name,
|
||||
self.cleaned_data.keys())):
|
||||
ungrant_access_to_object(domain, self.account)
|
||||
|
||||
class AccountForm(TabForms):
|
||||
|
||||
def __init__(self, user, *args, **kwargs):
|
||||
self.user = user
|
||||
self.forms = [
|
||||
dict(id="general", title=_("General"), cls=AccountFormGeneralPwd,
|
||||
new_args=[user], mandatory=True),
|
||||
dict(id="mail", title=_("Mail"), formtpl="admin/mailform.html",
|
||||
cls=AccountFormMail),
|
||||
dict(id="perms", title=_("Permissions"), formtpl="admin/permsform.html",
|
||||
cls=AccountPermissionsForm)
|
||||
]
|
||||
cbargs = [user]
|
||||
if kwargs.has_key("instances"):
|
||||
cbargs += [kwargs["instances"]["general"]]
|
||||
self.forms += events.raiseQueryEvent("ExtraAccountForm", *cbargs)
|
||||
|
||||
super(AccountForm, self).__init__(*args, **kwargs)
|
||||
|
||||
def check_perms(self, account):
|
||||
if account.is_superuser:
|
||||
return False
|
||||
return account.has_perm("admin.view_domain")
|
||||
|
||||
def _before_is_valid(self, form):
|
||||
if form["id"] == "general":
|
||||
return True
|
||||
|
||||
if hasattr(self, "check_%s" % form["id"]):
|
||||
if not getattr(self, "check_%s" % form["id"])(self.account):
|
||||
return False
|
||||
return True
|
||||
|
||||
if False in events.raiseQueryEvent("CheckExtraAccountForm", self.account, form):
|
||||
return False
|
||||
return True
|
||||
|
||||
def save_general_form(self):
|
||||
self.account = self.forms[0]["instance"].save()
|
||||
|
||||
def save(self):
|
||||
"""Custom save method
|
||||
|
||||
As forms interact with each other, it is simpler to make
|
||||
custom code to save them.
|
||||
"""
|
||||
self.forms[1]["instance"].save(self.user, self.account)
|
||||
if len(self.forms) <= 2:
|
||||
return
|
||||
for f in self.forms[2:]:
|
||||
f["instance"].save()
|
||||
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
# coding: utf-8
|
||||
from functools import wraps
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
||||
from models import *
|
||||
from modoboa.lib.webutils import _render_error, _render
|
||||
from modoboa.lib.webutils import _render
|
||||
from modoboa.lib import parameters
|
||||
from modoboa.admin.tables import *
|
||||
from exceptions import *
|
||||
|
||||
@@ -36,98 +34,10 @@ def render_listing(request, objtype, tplname="admin/listing.html",
|
||||
except ValueError:
|
||||
page = 1
|
||||
try:
|
||||
kwargs["objects"] = paginator.page(page)
|
||||
kwargs["page"] = paginator.page(page)
|
||||
except (EmptyPage, PageNotAnInteger):
|
||||
kwargs["objects"] = paginator.page(paginator.num_pages)
|
||||
kwargs["last_page"] = paginator.num_pages
|
||||
kwargs["total"] = paginator.count
|
||||
kwargs["table"] = tblclass(request, kwargs["objects"].object_list)
|
||||
kwargs["page"] = paginator.page(paginator.num_pages)
|
||||
kwargs["table"] = tblclass(request, kwargs["page"].object_list)
|
||||
kwargs["selection"] = objtype
|
||||
|
||||
return _render(request, tplname, kwargs)
|
||||
|
||||
def grant_access_to_object(user, obj, is_owner=False):
|
||||
"""Grant access to an object for a given user
|
||||
|
||||
There are two different cases where we want to grant access to an
|
||||
object for a specific user:
|
||||
|
||||
* He is the owner (he's just created the object)
|
||||
* He is going to administrate the object (but he is not the owner)
|
||||
|
||||
:param user: a ``User`` object
|
||||
:param obj: an admin. object (Domain, Mailbox, ...)
|
||||
:param is_owner: the user is the unique object's owner
|
||||
"""
|
||||
ct = get_content_type(obj)
|
||||
try:
|
||||
entry = user.objectaccess_set.get(content_type=ct, object_id=obj.id)
|
||||
entry.is_owner = is_owner
|
||||
entry.save()
|
||||
except ObjectAccess.DoesNotExist:
|
||||
pass
|
||||
else:
|
||||
return
|
||||
|
||||
try:
|
||||
objaccess = ObjectAccess(user=user, content_type=ct,
|
||||
object_id=obj.id, is_owner=is_owner)
|
||||
objaccess.save()
|
||||
except IntegrityError, e:
|
||||
raise AdminError(_("Failed to grant access (%s)" % str(e)))
|
||||
|
||||
def ungrant_access_to_object(obj, user=None):
|
||||
"""Ungrant access to an object for a specific user
|
||||
|
||||
If no user is provided, all entries referencing this object are
|
||||
deleted from the database.
|
||||
|
||||
:param obj: an object inheriting from ``models.Model``
|
||||
:param user: a ``User`` object
|
||||
"""
|
||||
ct = get_content_type(obj)
|
||||
if user:
|
||||
try:
|
||||
ObjectAccess.objects.get(user=user, content_type=ct, object_id=obj.id).delete()
|
||||
except ObjectAccess.DoesNotExist:
|
||||
pass
|
||||
else:
|
||||
ObjectAccess.objects.filter(content_type=ct, object_id=obj.id).delete()
|
||||
|
||||
def get_object_owner(obj):
|
||||
"""Return the unique owner of this object
|
||||
|
||||
:param obj: an object inheriting from ``model.Model``
|
||||
:return: a ``User`` object
|
||||
"""
|
||||
ct = get_content_type(obj)
|
||||
try:
|
||||
entry = ObjectAccess.objects.get(content_type=ct, object_id=obj.id, is_owner=True)
|
||||
except ObjectAccess.DoesNotExist:
|
||||
return None
|
||||
return entry.user
|
||||
|
||||
def check_domain_access(f):
|
||||
"""Decorator to check if the current user can access a domain
|
||||
|
||||
This decorator only applies to url that contain a 'domid' or
|
||||
'mbid' parameter. (for a direct access)
|
||||
|
||||
Raise a ``PermDeniedError`` if the current user can't view the
|
||||
requested object.
|
||||
"""
|
||||
@wraps(f)
|
||||
def dec(request, **kwargs):
|
||||
if not request.user.is_superuser:
|
||||
domain = None
|
||||
domid = request.GET.get("domid", None)
|
||||
if domid:
|
||||
domain = Domain.objects.get(pk=domid)
|
||||
else:
|
||||
mbid = request.GET.get("mbid", None)
|
||||
if mbid:
|
||||
domain = Mailbox.objects.get(pk=mbid).domain
|
||||
if domain and not request.user.can_access(domain):
|
||||
raise PermDeniedError(_("You can't access this domain"))
|
||||
|
||||
return f(request, **kwargs)
|
||||
return dec
|
||||
|
||||
@@ -93,4 +93,4 @@ class Migration(DataMigration):
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['admin']
|
||||
complete_apps = ['admin', 'contenttypes']
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
# encoding: utf-8
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding unique constraint on 'Alias', fields ['domain', 'address']
|
||||
db.create_unique('admin_alias', ['domain_id', 'address'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Removing unique constraint on 'Alias', fields ['domain', 'address']
|
||||
db.delete_unique('admin_alias', ['domain_id', 'address'])
|
||||
|
||||
|
||||
models = {
|
||||
'admin.alias': {
|
||||
'Meta': {'unique_together': "(('address', 'domain'),)", 'object_name': 'Alias'},
|
||||
'address': ('django.db.models.fields.CharField', [], {'max_length': '254'}),
|
||||
'dates': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.ObjectDates']"}),
|
||||
'domain': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.Domain']"}),
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'extmboxes': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'mboxes': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['admin.Mailbox']", 'symmetrical': 'False'})
|
||||
},
|
||||
'admin.domain': {
|
||||
'Meta': {'object_name': 'Domain'},
|
||||
'dates': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.ObjectDates']"}),
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
|
||||
'quota': ('django.db.models.fields.IntegerField', [], {})
|
||||
},
|
||||
'admin.domainalias': {
|
||||
'Meta': {'object_name': 'DomainAlias'},
|
||||
'dates': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.ObjectDates']"}),
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
|
||||
'target': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.Domain']"})
|
||||
},
|
||||
'admin.extension': {
|
||||
'Meta': {'object_name': 'Extension'},
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
|
||||
},
|
||||
'admin.mailbox': {
|
||||
'Meta': {'object_name': 'Mailbox'},
|
||||
'address': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'dates': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.ObjectDates']"}),
|
||||
'domain': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.Domain']"}),
|
||||
'gid': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'path': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'quota': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'uid': ('django.db.models.fields.IntegerField', [], {}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
|
||||
},
|
||||
'admin.objectaccess': {
|
||||
'Meta': {'unique_together': "(('user', 'content_type', 'object_id'),)", 'object_name': 'ObjectAccess'},
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_owner': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
|
||||
},
|
||||
'admin.objectdates': {
|
||||
'Meta': {'object_name': 'ObjectDates'},
|
||||
'creation': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'last_modification': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
|
||||
},
|
||||
'admin.user': {
|
||||
'Meta': {'object_name': 'User', 'db_table': "'auth_user'", '_ormbases': ['auth.User'], 'proxy': 'True'}
|
||||
},
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['admin']
|
||||
@@ -24,15 +24,6 @@ try:
|
||||
except ImportError:
|
||||
ldap_available = False
|
||||
|
||||
def get_content_type(obj):
|
||||
"""Simple function that use the right method to retrieve a content type
|
||||
|
||||
:param obj: a django model
|
||||
:return: a ``ContentType`` object
|
||||
"""
|
||||
return obj.get_content_type() if hasattr(obj, "get_content_type") \
|
||||
else ContentType.objects.get_for_model(obj)
|
||||
|
||||
class User(DUser):
|
||||
"""Proxy for the ``User`` model.
|
||||
|
||||
@@ -50,6 +41,37 @@ class User(DUser):
|
||||
def __unicode__(self):
|
||||
return u"%s %s" % (self.first_name, self.last_name)
|
||||
|
||||
def delete(self, fromuser, keep_mb_dir, *args, **kwargs):
|
||||
"""Custom delete method
|
||||
"""
|
||||
from modoboa.lib.permissions import \
|
||||
get_object_owner, grant_access_to_object, ungrant_access_to_object
|
||||
|
||||
if not fromuser.can_access(self):
|
||||
raise PermDeniedException(_("You don't have access to this account"))
|
||||
if fromuser == self:
|
||||
raise AdminError(_("You can't delete your own account"))
|
||||
if self.has_mailbox:
|
||||
mb = self.mailbox_set.all()[0]
|
||||
if not fromuser.can_access(mb.domain):
|
||||
raise PermDeniedException(_("You don't have access to this domain"))
|
||||
events.raiseEvent("DeleteMailbox", mb)
|
||||
ungrant_access_to_object(mb)
|
||||
mb.delete(keepdir=keep_mb_dir)
|
||||
|
||||
owner = get_object_owner(self)
|
||||
for ooentry in self.objectaccess_set.all():
|
||||
if ooentry.is_owner:
|
||||
if ooentry.content_object is not None:
|
||||
grant_access_to_object(owner, ooentry.content_object, True)
|
||||
else:
|
||||
print "ORPHELIN!!!"
|
||||
ooentry.delete()
|
||||
|
||||
events.raiseEvent("AccountDeleted", self)
|
||||
ungrant_access_to_object(self)
|
||||
super(User, self).delete(*args, **kwargs)
|
||||
|
||||
@staticmethod
|
||||
def get_content_type():
|
||||
"""An uggly hack to retrieve the appropriate content_type!
|
||||
@@ -130,6 +152,27 @@ class User(DUser):
|
||||
return "%s %s" % (self.first_name, self.last_name)
|
||||
return self.username
|
||||
|
||||
@property
|
||||
def identity(self):
|
||||
if self.email != "":
|
||||
return self.email
|
||||
return self.username
|
||||
|
||||
@property
|
||||
def name_or_rcpt(self):
|
||||
if self.first_name != "":
|
||||
return "%s %s" % (self.first_name, self.last_name)
|
||||
return "----"
|
||||
|
||||
@property
|
||||
def group(self):
|
||||
if self.is_superuser:
|
||||
return "SuperAdmin"
|
||||
try:
|
||||
return self.groups.all()[0].name
|
||||
except IndexError:
|
||||
return "?"
|
||||
|
||||
def belongs_to_group(self, name):
|
||||
"""Simple shortcut to check if this user is a member of a
|
||||
specific group.
|
||||
@@ -216,6 +259,8 @@ class User(DUser):
|
||||
:param obj: an object inheriting from ``models.Model``
|
||||
:return: a boolean
|
||||
"""
|
||||
from modoboa.lib.permissions import get_content_type
|
||||
|
||||
ct = get_content_type(obj)
|
||||
try:
|
||||
ooentry = self.objectaccess_set.get(content_type=ct, object_id=obj.id)
|
||||
@@ -233,6 +278,8 @@ class User(DUser):
|
||||
:param obj: a admin object
|
||||
:return: a boolean
|
||||
"""
|
||||
from modoboa.lib.permissions import get_content_type
|
||||
|
||||
if self.is_superuser:
|
||||
return True
|
||||
|
||||
@@ -360,8 +407,8 @@ class Domain(DatesAware):
|
||||
# Not very optimized but currently, this is the simple way
|
||||
# I've found to delete all related objects (mailboxes, users
|
||||
# and aliases)!
|
||||
for mb in self.mailbox_set.all():
|
||||
mb.delete(keepdir=keepdir)
|
||||
# for mb in self.mailbox_set.all():
|
||||
# mb.delete(keepdir=keepdir)
|
||||
super(Domain, self).delete(*args, **kwargs)
|
||||
if not keepdir:
|
||||
self.delete_dir()
|
||||
@@ -379,14 +426,19 @@ class DomainAlias(DatesAware):
|
||||
help_text=ugettext_noop("The alias name"))
|
||||
target = models.ForeignKey(Domain, verbose_name=ugettext_noop('target'),
|
||||
help_text=ugettext_noop("The domain this alias points to"))
|
||||
enabled = models.BooleanField(ugettext_noop('enabled'),
|
||||
help_text=ugettext_noop("Check to activate this alias"))
|
||||
enabled = models.BooleanField(
|
||||
ugettext_noop('enabled'),
|
||||
help_text=ugettext_noop("Check to activate this alias")
|
||||
)
|
||||
|
||||
class Meta:
|
||||
permissions = (
|
||||
("view_domaliases", "View domain aliases"),
|
||||
)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
class Mailbox(DatesAware):
|
||||
address = models.CharField(
|
||||
ugettext_noop('address'), max_length=100,
|
||||
@@ -456,13 +508,14 @@ class Mailbox(DatesAware):
|
||||
% (abspath, self.mdirroot, dir, sdir))
|
||||
return True
|
||||
|
||||
def rename_dir(self, domain, newaddress):
|
||||
def rename_dir(self, newdomain, newaddress):
|
||||
if parameters.get_admin("CREATE_DIRECTORIES") == "yes":
|
||||
if self.domain.name == domain and newaddress == self.address:
|
||||
return True
|
||||
path = "%s/%s" % (parameters.get_admin("STORAGE_PATH"), domain)
|
||||
oldpath = "%s/%s" % (parameters.get_admin("STORAGE_PATH"), self.domain.name)
|
||||
newpath = "%s/%s" % (parameters.get_admin("STORAGE_PATH"), newdomain)
|
||||
code = exec_as_vuser("mv %s/%s %s/%s" \
|
||||
% (path, self.address, path, newaddress))
|
||||
% (oldpath, self.address, newpath, newaddress))
|
||||
if code:
|
||||
self.path = "%s/" % newaddress
|
||||
return code
|
||||
@@ -498,8 +551,8 @@ class Mailbox(DatesAware):
|
||||
user.set_password(kwargs["password"])
|
||||
try:
|
||||
user.save()
|
||||
except IntegrityError:
|
||||
raise AdminError(_("Mailbox with this address already exists"))
|
||||
except IntegrityError, e:
|
||||
raise AdminError(_("Account '%s' already exists" % user.username))
|
||||
self.user = user
|
||||
|
||||
if len(user.groups.all()) == 0:
|
||||
@@ -538,7 +591,6 @@ class Mailbox(DatesAware):
|
||||
:param domain: the associated Domain object
|
||||
:param user: the associated User object
|
||||
"""
|
||||
self.name = "%s %s" % (user.first_name, user.last_name)
|
||||
self.address = localpart
|
||||
self.domain = domain
|
||||
self.user = user
|
||||
@@ -556,7 +608,7 @@ class Mailbox(DatesAware):
|
||||
self.gid = v_gid
|
||||
else:
|
||||
self.gid = pwd.getpwnam(parameters.get_admin("VIRTUAL_GID")).pw_gid
|
||||
self.quota = self.domain.quota
|
||||
self.quota = self.domain.quota
|
||||
super(Mailbox, self).save()
|
||||
|
||||
def create_from_csv(self, user, line):
|
||||
@@ -591,18 +643,21 @@ class Mailbox(DatesAware):
|
||||
alias.mboxes.remove(self)
|
||||
if len(alias.mboxes.all()) == 0:
|
||||
alias.delete()
|
||||
self.user.delete()
|
||||
super(Mailbox, self).delete(*args, **kwargs)
|
||||
if not keepdir:
|
||||
self.delete_dir()
|
||||
|
||||
|
||||
class Alias(DatesAware):
|
||||
address = models.CharField(ugettext_noop('address'), max_length=254,
|
||||
help_text=ugettext_noop("The alias address (without the domain part). For a 'catch-all' address, just enter an * character."))
|
||||
address = models.CharField(
|
||||
ugettext_noop('address'), max_length=254,
|
||||
help_text=ugettext_noop("The alias address (without the domain part). For a 'catch-all' address, just enter an * character.")
|
||||
)
|
||||
domain = models.ForeignKey(Domain)
|
||||
mboxes = models.ManyToManyField(Mailbox, verbose_name=ugettext_noop('mailboxes'),
|
||||
help_text=ugettext_noop("The mailboxes this alias points to"))
|
||||
mboxes = models.ManyToManyField(
|
||||
Mailbox, verbose_name=ugettext_noop('mailboxes'),
|
||||
help_text=ugettext_noop("The mailboxes this alias points to")
|
||||
)
|
||||
extmboxes = models.TextField(blank=True)
|
||||
enabled = models.BooleanField(ugettext_noop('enabled'),
|
||||
help_text=ugettext_noop("Check to activate this alias"))
|
||||
@@ -611,64 +666,43 @@ class Alias(DatesAware):
|
||||
permissions = (
|
||||
("view_aliases", "View aliases"),
|
||||
)
|
||||
unique_together = (("address", "domain"),)
|
||||
|
||||
@property
|
||||
def full_address(self):
|
||||
return "%s@%s" % (self.address, self.domain.name)
|
||||
|
||||
@property
|
||||
def targets(self):
|
||||
ret = "<br/>".join(map(lambda m: str(m), self.mboxes.all()))
|
||||
ret += "<br/>" + self.repr_extmboxes()
|
||||
return ret
|
||||
def identity(self):
|
||||
return self.full_address
|
||||
|
||||
def save(self, int_targets, ext_targets, *args, **kwargs):
|
||||
if len(ext_targets):
|
||||
self.extmboxes = ",".join(ext_targets)
|
||||
@property
|
||||
def name_or_rcpt(self):
|
||||
return "%s, ..." % self.get_recipients()[0]
|
||||
|
||||
def save(self, int_rcpts, ext_rcpts, *args, **kwargs):
|
||||
if len(ext_rcpts):
|
||||
self.extmboxes = ",".join(ext_rcpts)
|
||||
else:
|
||||
self.extmboxes = ""
|
||||
super(Alias, self).save(*args, **kwargs)
|
||||
curmboxes = self.mboxes.all()
|
||||
for t in int_targets:
|
||||
for t in int_rcpts:
|
||||
if not t in curmboxes:
|
||||
self.mboxes.add(t)
|
||||
for t in curmboxes:
|
||||
if not t in int_targets:
|
||||
if not t in int_rcpts:
|
||||
self.mboxes.remove(t)
|
||||
|
||||
def first_target(self):
|
||||
"""Return the first target of this alias
|
||||
|
||||
It is taken from internal addresses, or external addresses.
|
||||
"""
|
||||
if len(self.mboxes.all()):
|
||||
return self.mboxes.all()[0]
|
||||
if len(self.extmboxes):
|
||||
return self.extmboxes.split(",")[0]
|
||||
return None
|
||||
|
||||
def get_targets(self):
|
||||
"""Return a list containing targeted mailboxes
|
||||
def get_recipients(self):
|
||||
"""Return a the recipients list
|
||||
|
||||
Internal and external addresses are mixed into a single list.
|
||||
"""
|
||||
result = []
|
||||
if len(self.mboxes.all()):
|
||||
for mb in self.mboxes.all()[1:]:
|
||||
result += [mb.full_address]
|
||||
if len(self.extmboxes):
|
||||
result += self.extmboxes.split(",")
|
||||
else:
|
||||
result = self.extmboxes.split(",")[1:]
|
||||
result = map(lambda mb: mb.full_address, self.mboxes.all())
|
||||
result += self.extmboxes.split(',')
|
||||
return result
|
||||
|
||||
def repr_extmboxes(self):
|
||||
"""Return external targets as a string
|
||||
|
||||
A ready to print representation of external targets.
|
||||
"""
|
||||
return "<br/>".join(self.extmboxes.split(","))
|
||||
|
||||
def ui_disabled(self, user):
|
||||
if user.is_superuser:
|
||||
return False
|
||||
@@ -699,11 +733,12 @@ class Extension(models.Model):
|
||||
module.destroy()
|
||||
|
||||
def on(self):
|
||||
self.load()
|
||||
self.init()
|
||||
self.enabled = True
|
||||
self.save()
|
||||
|
||||
self.load()
|
||||
self.init()
|
||||
|
||||
extdir = "%s/extensions/%s" % (settings.MODOBOA_DIR, self.name)
|
||||
scriptdir = "%s/%s" % (extdir, "scripts")
|
||||
if os.path.exists(scriptdir):
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
# coding: utf-8
|
||||
|
||||
import datetime
|
||||
from django.utils.translation import ugettext as _, ugettext_noop
|
||||
from django.contrib.auth.models import Group
|
||||
from modoboa.lib.webutils import _render, getctx, _render_to_string
|
||||
from modoboa.lib import events
|
||||
from forms import *
|
||||
from models import User
|
||||
from tables import SuperAdminsTable, DomainAdminsTable
|
||||
from lib import grant_access_to_object, ungrant_access_to_object
|
||||
|
||||
class Permissions(object):
|
||||
submit_label = ugettext_noop("Add")
|
||||
formtpl = 'admin/add_permission.html'
|
||||
|
||||
@staticmethod
|
||||
def is_authorized(user):
|
||||
return user.is_superuser
|
||||
|
||||
def get_add_form(self, request):
|
||||
raise NotImplementedError
|
||||
|
||||
def add(self, request):
|
||||
raise NotImplementedError
|
||||
|
||||
def delete(self, request, selection):
|
||||
raise NotImplementedError
|
||||
|
||||
def get(self, request):
|
||||
raise NotImplementedError
|
||||
|
||||
def _render_form(self, request, form, instring=False):
|
||||
ctx = dict(form=form, title=self.title, submit_label=self.submit_label,
|
||||
role=self.role)
|
||||
if instring:
|
||||
return _render_to_string(request, self.formtpl, ctx)
|
||||
return _render(request, self.formtpl, ctx)
|
||||
|
||||
class SuperAdminsPerms(Permissions):
|
||||
title = ugettext_noop("Add super administrator")
|
||||
role = "super_admins"
|
||||
|
||||
def get_add_form(self, request):
|
||||
form = SuperAdminForm(request.user)
|
||||
return self._render_form(request, form)
|
||||
|
||||
def add(self, request):
|
||||
form = SuperAdminForm(request.user, request.POST)
|
||||
if form.is_valid():
|
||||
user = User.objects.get(pk=request.POST["user"])
|
||||
user.is_superuser = True
|
||||
user.date_joined = datetime.datetime.now()
|
||||
events.raiseEvent("SuperAdminPromotion", user)
|
||||
user.groups.clear()
|
||||
user.save()
|
||||
return True, None
|
||||
|
||||
content = self._render_form(request, form, True)
|
||||
return False, getctx("ko", content=content)
|
||||
|
||||
def delete(self, selection):
|
||||
for s in selection:
|
||||
user = User.objects.get(pk=int(s))
|
||||
if user.username == "admin":
|
||||
continue
|
||||
user.is_superuser = False
|
||||
user.save()
|
||||
|
||||
def get(self, request):
|
||||
admins = User.objects.filter(is_superuser=True)
|
||||
return SuperAdminsTable(request, admins).render()
|
||||
|
||||
|
||||
class DomainAdminsPerms(Permissions):
|
||||
title = ugettext_noop("Add domain administrator")
|
||||
role = "domain_admins"
|
||||
formtpl = 'admin/add_domain_admin.html'
|
||||
|
||||
@staticmethod
|
||||
def is_authorized(user):
|
||||
return user.has_perm("admin.view_domains")
|
||||
|
||||
def get_add_form(self, request):
|
||||
form = DomainAdminForm()
|
||||
return self._render_form(request, form)
|
||||
|
||||
def delete(self, selection):
|
||||
dagrp = Group.objects.get(name="DomainAdmins")
|
||||
sugrp = Group.objects.get(name="SimpleUsers")
|
||||
for uid in selection:
|
||||
u = User.objects.get(pk=uid)
|
||||
u.groups.remove(dagrp)
|
||||
u.save()
|
||||
events.raiseEvent("DomainAdminDeleted", u)
|
||||
if not len(u.mailbox_set.all()):
|
||||
ungrant_access_to_object(u)
|
||||
u.delete()
|
||||
else:
|
||||
u.groups.add(sugrp)
|
||||
|
||||
def get(self, request):
|
||||
domainadmins = User.objects.filter(groups__name="DomainAdmins")
|
||||
domainadmins = filter(lambda da: request.user.is_owner(da), domainadmins)
|
||||
return DomainAdminsTable(request, domainadmins).render()
|
||||
|
||||
def get_perms_class(user, role):
|
||||
"""Retrieves the class associated to a given role
|
||||
|
||||
The provided user must have the required permission to retrieve
|
||||
this class.
|
||||
|
||||
If "role" is one of those provided by the admin component, its
|
||||
class is directly returned. Otherwise, a "PermsGetClass" event is
|
||||
raised to check if one of the active plugins provide the desired
|
||||
class.
|
||||
|
||||
:param user: a User object
|
||||
:param role: the role to look for
|
||||
"""
|
||||
parts = role.split("_")
|
||||
cname = ""
|
||||
for p in parts:
|
||||
cname += p.capitalize()
|
||||
cname += "Perms"
|
||||
if globals().has_key(cname):
|
||||
if globals()[cname].is_authorized(user):
|
||||
return globals()[cname]
|
||||
return None
|
||||
res = events.raiseQueryEvent("PermsGetClass", role)
|
||||
if not len(res):
|
||||
return None
|
||||
return res[0]
|
||||
@@ -26,7 +26,7 @@ class DomainsTable(tables.Table):
|
||||
|
||||
cols_order = ["name", "creation", "modified",
|
||||
"domaliases", "mboxes", "mbaliases",
|
||||
"quota", "enabled", "actions"]
|
||||
"quota", "actions"]
|
||||
|
||||
def __init__(self, request, doms):
|
||||
super(DomainsTable, self).__init__(request)
|
||||
@@ -38,91 +38,10 @@ class DomainsTable(tables.Table):
|
||||
def parse_enabled(self, value):
|
||||
return _("yes") if value else _("no")
|
||||
|
||||
class DomaliasesTable(tables.Table):
|
||||
tableid = "objects_table"
|
||||
idkey = "id"
|
||||
|
||||
name = tables.Column("name", label=ugettext_noop("Name"))
|
||||
target = tables.Column("target", label=ugettext_noop("Targeted domain"))
|
||||
creation = tables.Column("creation", label=ugettext_noop("Created"), width="170px")
|
||||
modified = tables.Column("last_modification", label=ugettext_noop("Last modified"),
|
||||
width="170px")
|
||||
enabled = tables.Column("enabled", label=gender("Enabled", "m"), width="50px",
|
||||
align="center")
|
||||
actions = tables.ActionColumn("actions", label=ugettext_noop("Actions"),
|
||||
width="50px", align="center",
|
||||
defvalue=domalias_actions)
|
||||
|
||||
cols_order = ["name", "target", "creation",
|
||||
"modified", "enabled", "actions"]
|
||||
|
||||
def __init__(self, request, domaliases):
|
||||
super(DomaliasesTable, self).__init__(request)
|
||||
self.populate(self._rows_from_model(domaliases))
|
||||
|
||||
def parse_enabled(self, value):
|
||||
return _("yes") if value else _("no")
|
||||
|
||||
class MailboxesTable(tables.Table):
|
||||
tableid = "objects_table"
|
||||
idkey = "id"
|
||||
|
||||
address = tables.Column("full_address", label=ugettext_noop("Address"))
|
||||
name = tables.Column("user", label=ugettext_noop("Name"))
|
||||
creation = tables.Column("creation", label=ugettext_noop("Created"),
|
||||
width="160px")
|
||||
modified = tables.Column("last_modification", label=ugettext_noop("Last modified"),
|
||||
width="160px")
|
||||
aliases = tables.Column("alias_count", label=ugettext_noop("Aliases"), width="70px",
|
||||
align="center")
|
||||
quota = tables.Column("quota", label=ugettext_noop("Quota"),
|
||||
width="50px", align="center")
|
||||
enabled = tables.Column("enabled", label=gender("Enabled", "f"), width="50px",
|
||||
align="center")
|
||||
actions = tables.ActionColumn("actions", label=ugettext_noop("Actions"),
|
||||
width="70px", align="center", defvalue=mailbox_actions)
|
||||
|
||||
cols_order = ["address", "name", "creation", "modified", "aliases",
|
||||
"quota", "enabled", "actions"]
|
||||
|
||||
def __init__(self, request, mailboxes):
|
||||
super(MailboxesTable, self).__init__(request)
|
||||
self.populate(self._rows_from_model(mailboxes))
|
||||
|
||||
def parse_quota(self, value):
|
||||
return "%s %s" % (value, _("MB"))
|
||||
|
||||
def parse_enabled(self, value):
|
||||
return _("yes") if value else _("no")
|
||||
|
||||
def parse_name(self, user):
|
||||
return "%s %s" % (user.first_name, user.last_name)
|
||||
|
||||
class MbaliasesTable(tables.Table):
|
||||
tableid = "objects_table"
|
||||
idkey = "id"
|
||||
|
||||
address = tables.Column("full_address", label=ugettext_noop("Address"))
|
||||
targets = tables.Column("targets", label=ugettext_noop("Target(s)"), safe=True)
|
||||
creation = tables.Column("creation", label=ugettext_noop("Created"), width="170px")
|
||||
modified = tables.Column("last_modification", label=ugettext_noop("Last modified"),
|
||||
width="170px")
|
||||
enabled = tables.Column("enabled", label=gender("Enabled", "m"), width="50px",
|
||||
align="center")
|
||||
actions = tables.ActionColumn("actions", label=ugettext_noop("Actions"), width="50px",
|
||||
align="center", defvalue=mbalias_actions)
|
||||
|
||||
cols_order = ["address", "targets", "creation", "modified", "enabled", "actions"]
|
||||
|
||||
def __init__(self, request, aliases):
|
||||
super(MbaliasesTable, self).__init__(request)
|
||||
self.populate(self._rows_from_model(aliases))
|
||||
|
||||
def rowoptions(self, request, alias):
|
||||
return "{ui_disabled : '%s'}" % alias.ui_disabled(request.user)
|
||||
|
||||
def parse_enabled(self, value):
|
||||
return _("yes") if value else _("no")
|
||||
def row_class(self, request, domain):
|
||||
if not domain.enabled:
|
||||
return "muted"
|
||||
return ""
|
||||
|
||||
class ExtensionsTable(tables.Table):
|
||||
idkey = "id"
|
||||
@@ -133,43 +52,55 @@ class ExtensionsTable(tables.Table):
|
||||
|
||||
cols_order = ["selection", "name", "version", "descr"]
|
||||
|
||||
class SuperAdminsTable(tables.Table):
|
||||
class AccountsTable(tables.Table):
|
||||
idkey = "id"
|
||||
selection = tables.SelectionColumn("selection", width="4%")
|
||||
username = tables.Column("username", label=ugettext_noop("User name"))
|
||||
first_name = tables.Column("first_name", label=ugettext_noop("First name"))
|
||||
last_name = tables.Column("last_name", label=ugettext_noop("Last name"))
|
||||
date_joined = tables.Column("date_joined", label=ugettext_noop("Defined"))
|
||||
enabled = tables.Column("enabled", label=gender("Enabled", "m"), width="10%")
|
||||
|
||||
cols_order = ["selection", "username", "first_name", "last_name",
|
||||
"date_joined", "enabled"]
|
||||
|
||||
def __init__(self, request, users):
|
||||
super(SuperAdminsTable, self).__init__(request)
|
||||
self.populate(self._rows_from_model(users))
|
||||
|
||||
def parse_enabled(self, value):
|
||||
return _("yes") if value else _("no")
|
||||
|
||||
class DomainAdminsTable(tables.Table):
|
||||
idkey = "id"
|
||||
selection = tables.SelectionColumn("selection", width="4%")
|
||||
username = tables.Column("username", label=ugettext_noop("User name"))
|
||||
first_name = tables.Column("first_name", label=ugettext_noop("First name"))
|
||||
last_name = tables.Column("last_name", label=ugettext_noop("Last name"))
|
||||
date_joined = tables.Column("date_joined", label=ugettext_noop("Defined"))
|
||||
enabled = tables.Column("is_active", label=gender("Enabled", "m"), width="10%")
|
||||
role = tables.Column("group", label=ugettext_noop("Role"))
|
||||
actions = tables.ActionColumn("actions", label=ugettext_noop("Actions"),
|
||||
width="70px", align="center",
|
||||
defvalue=domain_admin_actions)
|
||||
defvalue=account_actions)
|
||||
|
||||
cols_order = ["selection", "username", "first_name",
|
||||
"last_name", "date_joined", "enabled", "actions"]
|
||||
cols_order = ["username", "first_name", "last_name", "date_joined",
|
||||
"role", "actions"]
|
||||
|
||||
def __init__(self, request, users):
|
||||
super(DomainAdminsTable, self).__init__(request)
|
||||
super(AccountsTable, self).__init__(request)
|
||||
self.populate(self._rows_from_model(users))
|
||||
|
||||
def parse_is_active(self, value):
|
||||
return _("yes") if value else _("no")
|
||||
|
||||
def parse_group(self, value):
|
||||
if value == "SimpleUsers":
|
||||
return "U"
|
||||
return value[:1]
|
||||
|
||||
def row_class(self, request, obj):
|
||||
if not obj.is_active:
|
||||
return "muted"
|
||||
return ""
|
||||
|
||||
class IdentitiesTable(tables.Table):
|
||||
idkey = "id"
|
||||
identity = tables.Column("identity", label=ugettext_noop("Email/Username"))
|
||||
name_or_rcpt = tables.Column("name_or_rcpt", label=ugettext_noop("Fullname/Recipient"))
|
||||
actions = tables.ActionColumn("actions", label=ugettext_noop("Actions"),
|
||||
width="70px", align="center",
|
||||
defvalue=identity_actions)
|
||||
|
||||
cols_order = ["identity", "name_or_rcpt", "actions"]
|
||||
|
||||
def __init__(self, request, identities):
|
||||
super(IdentitiesTable, self).__init__(request)
|
||||
self.populate(self._rows_from_model(identities, True))
|
||||
|
||||
def row_class(self, request, obj):
|
||||
if obj.__class__.__name__ == "User" and not obj.is_active:
|
||||
return "muted"
|
||||
if not obj.enabled:
|
||||
return "muted"
|
||||
return ""
|
||||
|
||||
@@ -13,15 +13,7 @@ genders = {
|
||||
}
|
||||
|
||||
@register.simple_tag
|
||||
def admin_menu(user):
|
||||
# entries = [
|
||||
# {"name" : "admin",
|
||||
# "img" : static_url('pics/admin.png'),
|
||||
# "label" : _("Admin"),
|
||||
# "class" : "topdropdown",
|
||||
# "menu" : []
|
||||
# }
|
||||
# ]
|
||||
def admin_menu(selection, user):
|
||||
entries = []
|
||||
if user.has_perm("admin.view_domains"):
|
||||
entries += [
|
||||
@@ -30,21 +22,14 @@ def admin_menu(user):
|
||||
"label" : _("Domains"),
|
||||
"img" : static_url("pics/domains.png")}
|
||||
]
|
||||
elif user.has_perm("admin.view_mailboxes"):
|
||||
entries += [
|
||||
{"name" : "mailboxes",
|
||||
"url" : reverse(admin.views.domains),
|
||||
"label" : _("Mailboxes"),
|
||||
"img" : static_url("pics/mailbox.png")}
|
||||
]
|
||||
entries += \
|
||||
events.raiseQueryEvent("AdminMenuDisplay", "top_menu", user)
|
||||
if user.has_perm("auth.view_permissions"):
|
||||
if user.has_perm("auth.add_user") or user.has_perm("admin.add_mailbox"):
|
||||
entries += [
|
||||
{"name" : "permissions",
|
||||
"url" : reverse(admin.views.permissions),
|
||||
"label" : _("Accounts"),
|
||||
"img" : static_url("pics/permissions.png")}
|
||||
{"name" : "identities",
|
||||
"url" : reverse(admin.views.identities),
|
||||
"label" : _("Identities")},
|
||||
|
||||
]
|
||||
if user.is_superuser:
|
||||
entries += [
|
||||
@@ -57,193 +42,127 @@ def admin_menu(user):
|
||||
if not len(entries):
|
||||
return ""
|
||||
return render_to_string("common/menulist.html",
|
||||
{"entries" : entries, "user" : user})
|
||||
{"entries" : entries, "selection" : selection, "user" : user})
|
||||
|
||||
@register.simple_tag
|
||||
def settings_menu(selection, user):
|
||||
entries = [
|
||||
{"name" : "parameters",
|
||||
"url" : reverse(admin.views.viewparameters),
|
||||
"img" : static_url("pics/domains.png"),
|
||||
"label" : _("Parameters")},
|
||||
{"name" : "extensions",
|
||||
"url" : reverse(admin.views.viewextensions),
|
||||
"label" : _("Extensions"),
|
||||
"img" : static_url("pics/extensions.png")},
|
||||
{"name" : "parameters",
|
||||
"url" : reverse(admin.views.viewparameters),
|
||||
"img" : static_url("pics/domains.png"),
|
||||
"label" : _("Parameters")},
|
||||
]
|
||||
return render_to_string('common/menu.html',
|
||||
{"selection" : selection, "entries" : entries,
|
||||
"user" : user})
|
||||
|
||||
def dommenu_entry(name, label, img, listurl, newurl):
|
||||
result = {"name" : name,
|
||||
"label" : label,
|
||||
"img" : img,
|
||||
"url" : listurl,
|
||||
"class" : "menubardropdown",
|
||||
}
|
||||
return result
|
||||
return render_to_string('common/menu.html', {
|
||||
"entries" : entries,
|
||||
"css" : "nav nav-list",
|
||||
"selection" : selection,
|
||||
"user" : user
|
||||
})
|
||||
|
||||
@register.simple_tag
|
||||
def domains_menu(selection, user, domid):
|
||||
args = domid != "" and ("?domid=%s" % domid) or ""
|
||||
entries = []
|
||||
if selection == "stats":
|
||||
disabled = True
|
||||
else:
|
||||
disabled = False
|
||||
|
||||
entries += [
|
||||
{"name" : "actions",
|
||||
"label" : _("Actions"),
|
||||
"img" : static_url("pics/tools.png"),
|
||||
"class" : "menubardropdown",
|
||||
"menu" : [
|
||||
{"name" : "new",
|
||||
"label" : _("New"),
|
||||
"img" : static_url("pics/add.png"),
|
||||
"disabled" : disabled},
|
||||
{"name" : "remove",
|
||||
"label" : _("Remove"),
|
||||
"img" : static_url("pics/remove.png"),
|
||||
"disabled" : disabled
|
||||
},
|
||||
{"name" : "import",
|
||||
"label" : _("Import data"),
|
||||
"img" : static_url("pics/import.png"),
|
||||
"class" : "boxed",
|
||||
"rel" : "{handler:'iframe',size:{x:370,y:250}}",
|
||||
"url" : reverse(admin.views.importdata)}
|
||||
]
|
||||
},
|
||||
]
|
||||
|
||||
entries += [{"separator" : True}]
|
||||
if user.has_perm("admin.view_domains"):
|
||||
entries += dommenu_entry("domains", _("Domains"),
|
||||
static_url("pics/domains.png"),
|
||||
reverse(admin.views.domains),
|
||||
reverse(admin.views.newdomain)),
|
||||
entries += [
|
||||
dommenu_entry("domaliases", _("Domain aliases"), static_url("pics/alias.png"),
|
||||
reverse(admin.views.domaliases) + args,
|
||||
reverse(admin.views.newdomalias) + args),
|
||||
dommenu_entry("mailboxes", _("Mailboxes"), static_url("pics/mailbox.png"),
|
||||
reverse(admin.views.mailboxes) + args,
|
||||
reverse(admin.views.newmailbox) + args),
|
||||
dommenu_entry("mbaliases", _("Mailbox aliases"), static_url("pics/alias.png"),
|
||||
reverse(admin.views.mbaliases) + args,
|
||||
reverse(admin.views.newmbalias) + args),
|
||||
]
|
||||
entries += events.raiseQueryEvent("AdminMenuDisplay", "admin_menu_box", user)
|
||||
return render_to_string('common/menu.html',
|
||||
{"entries" : entries,
|
||||
"selection" : selection,
|
||||
"user" : user})
|
||||
|
||||
@register.simple_tag
|
||||
def permissions_menu(user):
|
||||
def domains_menu(selection, user):
|
||||
entries = [
|
||||
{"name" : "addperm",
|
||||
"label" : _("Add permission"),
|
||||
"img" : static_url("pics/add.png"),
|
||||
"url" : reverse(admin.views.add_permission)},
|
||||
{"name" : "delperms",
|
||||
"label" : _("Remove permissions"),
|
||||
"img" : static_url("pics/remove.png"),
|
||||
"url" : reverse(admin.views.delete_permissions)},
|
||||
{"name" : "newdomain",
|
||||
"label" : _("New domain"),
|
||||
"img" : "icon-plus",
|
||||
"modal" : True,
|
||||
"modalcb" : "domainform_cb",
|
||||
"url" : reverse("modoboa.admin.views.newdomain")},
|
||||
{"name" : "import",
|
||||
"label" : _("Import"),
|
||||
"img" : "icon-folder-open",
|
||||
"url" : reverse(admin.views.import_domains),
|
||||
"modal" : True,
|
||||
"modalcb" : "importform_cb"}
|
||||
]
|
||||
return render_to_string('common/menu.html',
|
||||
{"entries" : entries, "user" : user})
|
||||
return render_to_string('common/menu.html', {
|
||||
"entries" : entries,
|
||||
"css" : "nav nav-list",
|
||||
"selection" : selection,
|
||||
"user" : user
|
||||
})
|
||||
|
||||
@register.simple_tag
|
||||
def identities_menu(user):
|
||||
entries = [
|
||||
{"name" : "newaccount",
|
||||
"label" : _("New account"),
|
||||
"img" : "icon-plus",
|
||||
"modal" : True,
|
||||
"modalcb" : "newaccount_cb",
|
||||
"url" : reverse(admin.views.newaccount)},
|
||||
{"name" : "newdlist",
|
||||
"label" : _("New distribution list"),
|
||||
"img" : "icon-plus",
|
||||
"modal" : True,
|
||||
"modalcb" : "dlistform_cb",
|
||||
"url" : reverse(admin.views.newdlist)},
|
||||
{"name" : "import",
|
||||
"label" : _("Import"),
|
||||
"img" : "icon-folder-open",
|
||||
"url" : reverse(admin.views.import_identities),
|
||||
"modal" : True,
|
||||
"modalcb" : "importform_cb"}
|
||||
]
|
||||
|
||||
return render_to_string('common/menu.html', {
|
||||
"entries" : entries,
|
||||
"css" : "nav nav-list",
|
||||
"user" : user
|
||||
})
|
||||
|
||||
@register.simple_tag
|
||||
def domain_actions(user, domid):
|
||||
actions = [
|
||||
{"name" : "editdomain",
|
||||
"url" : reverse(admin.views.editdomain, args=[domid]),
|
||||
"img" : static_url("pics/edit.png"),
|
||||
"img" : "icon-edit",
|
||||
"title" : _("Edit domain"),
|
||||
"class" : "boxed",
|
||||
"rel" : "{handler:'iframe',size:{x:310,y:190}}"},
|
||||
{"name" : "domaliases",
|
||||
"url" : reverse(admin.views.domaliases) + "?domid=%s" % domid,
|
||||
"img" : static_url("pics/alias.png"),
|
||||
"title" : _("View aliases of this domain")}
|
||||
"modal" : True,
|
||||
"modalcb" : "domainform_cb"},
|
||||
{"name" : "deldomain",
|
||||
"url" : reverse(admin.views.deldomain) + "?selection=%s" % domid,
|
||||
"img" : "icon-remove"},
|
||||
]
|
||||
if user.has_perm('admin.view_domains'):
|
||||
actions += [
|
||||
{"name" : "viewadmins",
|
||||
"url" : reverse(admin.views.view_domain_admins, args=[domid]),
|
||||
"img" : static_url("pics/administrators.png"),
|
||||
"title" : _("View administrators of this domain"),
|
||||
"class" : "boxed",
|
||||
"rel" : "{handler:'iframe',size:{x:310,y:190}}"},
|
||||
]
|
||||
|
||||
return render_actions(actions)
|
||||
|
||||
@register.simple_tag
|
||||
def domalias_actions(user, aid):
|
||||
def account_actions(user, accountid):
|
||||
actions = [
|
||||
{"name" : "editalias",
|
||||
"url" : reverse(admin.views.editdomalias, args=[aid]),
|
||||
"img" : static_url("pics/edit.png"),
|
||||
"title" : _("Edit alias"),
|
||||
"class" : "boxed",
|
||||
"rel" : "{handler:'iframe',size:{x:310,y:190}}"}
|
||||
{"name" : "editaccount",
|
||||
"url" : reverse(admin.views.editaccount, args=[accountid]),
|
||||
"img" : "icon-edit",
|
||||
"modal" : True,
|
||||
"modalcb" : "editaccount_cb",
|
||||
"title" : _("Edit account")},
|
||||
{"name" : "delaccount",
|
||||
"url" : reverse(admin.views.delaccount) + "?selection=%s" % accountid,
|
||||
"img" : "icon-remove",
|
||||
"title" : _("Delete this account")},
|
||||
]
|
||||
return render_actions(actions)
|
||||
|
||||
@register.simple_tag
|
||||
def mailbox_actions(user, mboxid):
|
||||
def identity_actions(user, iid):
|
||||
name, objid = iid.split(':')
|
||||
if name == "User":
|
||||
return account_actions(user, objid)
|
||||
actions = [
|
||||
{"name" : "editmailbox",
|
||||
"url" : reverse(admin.views.editmailbox, args=[mboxid]),
|
||||
"img" : static_url("pics/edit.png"),
|
||||
"title" : _("Edit mailbox"),
|
||||
"class" : "boxed",
|
||||
"rel" : "{handler:'iframe',size:{x:310,y:320}}"},
|
||||
{"name" : "aliases",
|
||||
"url" : reverse(admin.views.mbaliases) + "?mbid=%d" % mboxid,
|
||||
"img" : static_url("pics/alias.png"),
|
||||
"title" : _("View this mailbox aliases")},
|
||||
]
|
||||
return render_actions(actions)
|
||||
|
||||
@register.simple_tag
|
||||
def domain_admin_actions(user, daid):
|
||||
from modoboa.admin.models import User
|
||||
|
||||
actions = [
|
||||
{"name" : "editdomainadmin",
|
||||
"url" : reverse(admin.views.edit_domain_admin, args=[daid]),
|
||||
"img" : static_url("pics/edit.png"),
|
||||
"title" : _("Edit domain admin"),
|
||||
"class" : "boxed",
|
||||
"rel" : "{handler:'iframe',size:{x:350,y:320}}"},
|
||||
{"name" : "assigndomains",
|
||||
"url" : reverse(admin.views.assign_domains_to_admin, args=[daid]),
|
||||
"img" : static_url("pics/domains.png"),
|
||||
"title" : _("Assign domain(s) to this administrator"),
|
||||
"class" : "boxed",
|
||||
"rel" : "{handler:'iframe',size:{x:350,y:320}}"},
|
||||
]
|
||||
actions += events.raiseQueryEvent("DomainAdminActions", User.objects.get(pk=daid))
|
||||
return render_actions(actions)
|
||||
|
||||
@register.simple_tag
|
||||
def mbalias_actions(user, aliasid):
|
||||
from modoboa.admin.models import Alias
|
||||
|
||||
alias = Alias.objects.get(pk=aliasid)
|
||||
if alias.ui_disabled(user):
|
||||
return "--"
|
||||
actions = [
|
||||
{"name" : "editmbalias",
|
||||
"url" : reverse(admin.views.editmbalias, args=[aliasid]),
|
||||
"img" : static_url("pics/edit.png"),
|
||||
"title" : _("Edit mailbox alias"),
|
||||
"class" : "boxed",
|
||||
"rel" : "{handler:'iframe',size:{x:320,y:300}}"}
|
||||
{"name" : "editdlist",
|
||||
"url" : reverse(admin.views.editdlist, args=[objid]),
|
||||
"img" : "icon-edit",
|
||||
"modal" : True,
|
||||
"modalcb" : "dlistform_cb",
|
||||
"title" : _("Edit distribution list")},
|
||||
{"name" : "deldlist",
|
||||
"url" : reverse(admin.views.deldlist) + "?selection=%s" % objid,
|
||||
"img" : "icon-remove",
|
||||
"title" : _("Delete this distribution list")},
|
||||
]
|
||||
return render_actions(actions)
|
||||
|
||||
@@ -255,9 +174,11 @@ def loadadminextmenu(user):
|
||||
|
||||
@register.simple_tag
|
||||
def param(app, definition):
|
||||
result = """<div class='row'>
|
||||
<label>%s</label>""" % (definition.has_key("label") \
|
||||
and _(definition["label"]) or definition["name"])
|
||||
result = """<div class='control-group'>
|
||||
<label class="param-label">%s</label>
|
||||
<div class="param-controls">""" \
|
||||
% (definition.has_key("label") and _(definition["label"])
|
||||
or definition["name"])
|
||||
name = "%s.%s" % (app, definition["name"])
|
||||
value = definition.has_key("value") \
|
||||
and definition["value"] or definition["deflt"]
|
||||
@@ -290,10 +211,14 @@ def param(app, definition):
|
||||
|
||||
if definition.has_key("help"):
|
||||
result += """
|
||||
<a href='%s' onclick='return false;' class='Tips' title='%s'>
|
||||
<img src='%s' border='0' />
|
||||
</a>""" % (_(definition["help"]), _("Help"), static_url("pics/info.png"))
|
||||
<p class="help-block">%s</p>
|
||||
""" % definition["help"]
|
||||
# result += """
|
||||
# <a href='%s' onclick='return false;' class='Tips' title='%s'>
|
||||
# <img src='%s' border='0' />
|
||||
# </a>""" % (_(definition["help"]), _("Help"), static_url("pics/info.png"))
|
||||
result += """
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
return result
|
||||
|
||||
@@ -4,40 +4,31 @@ urlpatterns = patterns(
|
||||
'modoboa.admin.views',
|
||||
url(r'^$', 'domains', name="index"),
|
||||
url(r'^domains/$', 'domains', name="domains"),
|
||||
(r'^domains/list/$', 'domains_list'),
|
||||
(r'^domains/new/', 'newdomain'),
|
||||
(r'^domains/(?P<dom_id>\d+)/edit/$', 'editdomain'),
|
||||
(r'^domains/delete/$', 'deldomain'),
|
||||
(r'^domains/import/$', 'importdata'),
|
||||
(r'^domains/import/$', 'import_domains'),
|
||||
|
||||
(r'^domaliases/$', "domaliases"),
|
||||
(r'^domaliases/new/', 'newdomalias'),
|
||||
(r'^domaliases/edit/(?P<alias_id>\d+)/', 'editdomalias'),
|
||||
(r'^domaliases/delete/$', 'deldomalias'),
|
||||
|
||||
(r'^mailboxes/$', 'mailboxes'),
|
||||
(r'^mailboxes/new/$', 'newmailbox'),
|
||||
(r'^mailboxes/edit/(?P<mbox_id>\d+)/$', 'editmailbox'),
|
||||
(r'^mailboxes/delete/$', 'delmailbox'),
|
||||
(r'^mailboxes/search/$', 'mailboxes_search'),
|
||||
|
||||
(r'^mbaliases/$', 'mbaliases'),
|
||||
(r'^mbaliases/new/$', 'newmbalias'),
|
||||
(r'^mbaliases/edit/(?P<alias_id>\d+)/$', 'editmbalias'),
|
||||
(r'^mbaliases/delete/$', 'delmbalias'),
|
||||
|
||||
(r'^settings/$', 'viewparameters'),
|
||||
(r'^settings/parameters/$', 'viewparameters'),
|
||||
(r'^settings/parameters/save/$', 'saveparameters'),
|
||||
(r'^settings/extensions/$', 'viewextensions'),
|
||||
(r'^settings/extensions/save/$', 'saveextensions'),
|
||||
|
||||
(r'^permissions/$', 'permissions'),
|
||||
(r'^permissions/add/$', 'add_permission'),
|
||||
(r'^permissions/domainadmin/new/$', 'create_domain_admin'),
|
||||
(r'^permissions/domainadmin/edit/(?P<da_id>\d+)/$', 'edit_domain_admin'),
|
||||
(r'^permissions/domainadmin/promote/$', 'domain_admin_promotion'),
|
||||
(r'^permissions/domainadmin/assign/(?P<da_id>\d+)/$', 'assign_domains_to_admin'),
|
||||
(r'^permissions/domainadmins/(?P<dom_id>\d+)/$', 'view_domain_admins'),
|
||||
(r'^permissions/searchaccount/$', 'search_account'),
|
||||
(r'^permissions/delete/$', 'delete_permissions'),
|
||||
|
||||
(r'^identities/$', 'identities'),
|
||||
(r'^identities/import/$', 'import_identities'),
|
||||
|
||||
(r'^accounts/list/$', 'accounts_list'),
|
||||
(r'^accounts/new/$', 'newaccount'),
|
||||
(r'^accounts/edit/(?P<accountid>\d+)/$', 'editaccount'),
|
||||
(r'^accounts/delete/$', 'delaccount'),
|
||||
|
||||
(r'^distriblists/new/$', 'newdlist'),
|
||||
(r'^distriblists/edit/(?P<dlist_id>\d+)/$', 'editdlist'),
|
||||
(r'^distriblists/delete/$', 'deldlist'),
|
||||
)
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# coding: utf-8
|
||||
from django.http import HttpResponse, HttpResponseRedirect
|
||||
from django.utils import simplejson
|
||||
from django.utils.translation import ugettext as _, ungettext
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.contrib.auth.decorators \
|
||||
import login_required, permission_required, user_passes_test
|
||||
from django.db.models import Q
|
||||
from django.contrib.auth.models import Group
|
||||
from django.contrib import messages
|
||||
from django.db import transaction, IntegrityError, transaction
|
||||
from django.db import transaction, IntegrityError
|
||||
|
||||
from lib import *
|
||||
from lib import render_listing
|
||||
from forms import *
|
||||
from modoboa import admin, userprefs
|
||||
from models import *
|
||||
from modoboa.admin.permissions import *
|
||||
from models import *
|
||||
from modoboa.admin.tables import *
|
||||
from modoboa.lib import events, parameters
|
||||
from modoboa.lib.exceptions import *
|
||||
from modoboa.lib.webutils \
|
||||
import _render, ajax_response, ajax_simple_response, getctx
|
||||
import _render, ajax_response, ajax_simple_response
|
||||
from modoboa.lib.emailutils import split_mailbox
|
||||
from modoboa.lib.models import Parameter
|
||||
import copy
|
||||
from modoboa.lib.permissions import *
|
||||
|
||||
@login_required
|
||||
def domains(request):
|
||||
if not request.user.has_perm("admin.view_domains"):
|
||||
if request.user.has_perm("admin.view_mailboxes"):
|
||||
return HttpResponseRedirect(reverse(mailboxes))
|
||||
return HttpResponseRedirect(reverse(identities))
|
||||
|
||||
return HttpResponseRedirect(reverse(userprefs.views.preferences))
|
||||
|
||||
domains = request.user.get_domains()
|
||||
for dom in domains:
|
||||
dom.mbalias_counter = len(Alias.objects.filter(domain=dom.id))
|
||||
deloptions = {"keepdir" : _("Do not delete domain directory")}
|
||||
return render_listing(request, "domains",
|
||||
"admin/domains.html",
|
||||
title=_("Available domains"),
|
||||
objects=domains,
|
||||
rel="310 190",
|
||||
deloptions=deloptions)
|
||||
objects=domains)
|
||||
|
||||
def _validate_domain(request, form, successmsg, commonctx,
|
||||
callback=None, tplname="admin/adminform.html"):
|
||||
"""Domain validation
|
||||
@login_required
|
||||
@permission_required("admin.view_domains")
|
||||
def domains_list(request):
|
||||
doms = map(lambda dom: dom.name, request.user.get_domains())
|
||||
return ajax_simple_response(doms)
|
||||
|
||||
def _validate_domain(request, form, successmsg, commonctx, tplname,
|
||||
callback=None):
|
||||
"""Domain form validation
|
||||
|
||||
Common function shared between creation and modification actions.
|
||||
"""
|
||||
error = None
|
||||
if form.is_valid():
|
||||
try:
|
||||
domain = form.save()
|
||||
domain = form.save(request.user)
|
||||
except AdminError, e:
|
||||
error = str(e)
|
||||
except IntegrityError:
|
||||
error = _("Domain with this name already defined")
|
||||
error = _("An alias with this name already exists")
|
||||
else:
|
||||
if callback is not None:
|
||||
callback(request.user, domain)
|
||||
@@ -69,7 +69,7 @@ def _validate_domain(request, form, successmsg, commonctx,
|
||||
@login_required
|
||||
@permission_required("admin.add_domain")
|
||||
@transaction.commit_on_success
|
||||
def newdomain(request, tplname="admin/adminform.html"):
|
||||
def newdomain(request):
|
||||
events.raiseEvent("CanCreate", request.user, "domains")
|
||||
def newdomain_cb(user, domain):
|
||||
grant_access_to_object(user, domain, is_owner=True)
|
||||
@@ -82,15 +82,15 @@ def newdomain(request, tplname="admin/adminform.html"):
|
||||
if request.method == "POST":
|
||||
form = DomainForm(request.POST)
|
||||
return _validate_domain(request, form, _("Domain created"), commonctx,
|
||||
newdomain_cb)
|
||||
|
||||
"admin/domainform.html",
|
||||
callback=newdomain_cb)
|
||||
form = DomainForm()
|
||||
commonctx["form"] = form
|
||||
return _render(request, tplname, commonctx)
|
||||
return _render(request, "common/generic_modal_form.html", commonctx)
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.change_domain")
|
||||
def editdomain(request, dom_id, tplname="admin/adminform.html"):
|
||||
def editdomain(request, dom_id, tplname="admin/domainform.html"):
|
||||
domain = Domain.objects.get(pk=dom_id)
|
||||
if not request.user.is_owner(domain):
|
||||
raise PermDeniedException(_("You can't edit this domain"))
|
||||
@@ -101,7 +101,7 @@ def editdomain(request, dom_id, tplname="admin/adminform.html"):
|
||||
"formid" : "domform"}
|
||||
if request.method == "POST":
|
||||
form = DomainForm(request.POST, instance=domain)
|
||||
return _validate_domain(request, form, _("Domain modified"), commonctx)
|
||||
return _validate_domain(request, form, _("Domain modified"), commonctx, tplname)
|
||||
|
||||
form = DomainForm(instance=domain)
|
||||
commonctx["form"] = form
|
||||
@@ -120,11 +120,13 @@ def deldomain(request):
|
||||
mb = None
|
||||
|
||||
for dom in Domain.objects.filter(id__in=selection):
|
||||
if not request.user.is_owner(dom):
|
||||
if not request.user.can_access(dom):
|
||||
raise PermDeniedException(_("You can't delete this domain"))
|
||||
if mb and mb.domain == dom:
|
||||
raise AdminError(_("You can't delete your own domain"))
|
||||
|
||||
events.raiseEvent("DomainAliasDeleted", dom.domainalias_set.all())
|
||||
events.raiseEvent("DeleteMailbox", dom.mailbox_set.all())
|
||||
events.raiseEvent("DeleteDomain", dom)
|
||||
ungrant_access_to_object(dom)
|
||||
dom.delete(keepdir=keepdir)
|
||||
@@ -133,126 +135,6 @@ def deldomain(request):
|
||||
messages.info(request, msg, fail_silently=True)
|
||||
return ajax_response(request)
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.view_domaliases")
|
||||
@check_domain_access
|
||||
def domaliases(request):
|
||||
if request.GET.has_key("domid"):
|
||||
domain = Domain.objects.get(pk=request.GET["domid"])
|
||||
domaliases = DomainAlias.objects.filter(target=request.GET["domid"])
|
||||
else:
|
||||
domain = None
|
||||
domaliases = request.user.get_domaliases()
|
||||
return render_listing(request, "domaliases",
|
||||
title=_("Domain aliases"),
|
||||
rel="310 190",
|
||||
objects=domaliases)
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.add_domainalias")
|
||||
@transaction.commit_on_success
|
||||
def newdomalias(request, tplname="admin/adminform.html"):
|
||||
events.raiseEvent("CanCreate", request.user, "domain_aliases")
|
||||
commonctx = {"title" : _("New domain alias"),
|
||||
"submit_label" : _("Create"),
|
||||
"action" : reverse(newdomalias),
|
||||
"formid" : "domaliasform"}
|
||||
if request.method == "POST":
|
||||
form = DomainAliasForm(request.user, request.POST)
|
||||
error = None
|
||||
if form.is_valid():
|
||||
domalias = form.save(commit=False)
|
||||
if Domain.objects.filter(name=domalias.name):
|
||||
error = _("A domain with this name already exists")
|
||||
else:
|
||||
try:
|
||||
domalias.save()
|
||||
except IntegrityError:
|
||||
error = _("Alias with this name already exists")
|
||||
else:
|
||||
grant_access_to_object(request.user, domalias, is_owner=True)
|
||||
events.raiseEvent("DomainAliasCreated", request.user, domalias)
|
||||
messages.info(request, _("Domain alias created"), fail_silently=True)
|
||||
return ajax_response(request, url=reverse(admin.views.domaliases))
|
||||
|
||||
commonctx["form"] = form
|
||||
commonctx["error"] = error
|
||||
return ajax_response(request, status="ko", template=tplname, **commonctx)
|
||||
|
||||
form = DomainAliasForm(request.user)
|
||||
if request.GET.has_key("domid"):
|
||||
form.fields["target"].initial = request.GET["domid"]
|
||||
commonctx["form"] = form
|
||||
return _render(request, tplname, commonctx)
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.change_domainalias")
|
||||
def editdomalias(request, alias_id, tplname="admin/adminform.html"):
|
||||
domalias = DomainAlias.objects.get(pk=alias_id)
|
||||
if not request.user.is_owner(domalias.target):
|
||||
raise PermDeniedException(_("You do not have access to this domain"))
|
||||
|
||||
commonctx = {"title" : _("Domain alias editing"),
|
||||
"submit_label" : _("Update"),
|
||||
"action" : reverse(editdomalias, args=[alias_id]),
|
||||
"formid" : "domaliasform"}
|
||||
if request.method == "POST":
|
||||
form = DomainAliasForm(request.user, request.POST, instance=domalias)
|
||||
error = None
|
||||
if form.is_valid():
|
||||
ndomalias = form.save(commit=False)
|
||||
if Domain.objects.filter(name=ndomalias.name):
|
||||
error = _("A domain with this name already exists")
|
||||
else:
|
||||
try:
|
||||
ndomalias.save()
|
||||
except IntegrityError:
|
||||
error = _("Alias with this name already exists")
|
||||
else:
|
||||
messages.info(request, _("Domain alias updated"), fail_silently=True)
|
||||
return ajax_response(request, url=reverse(admin.views.domaliases))
|
||||
commonctx["form"] = form
|
||||
commonctx["error"] = error
|
||||
return ajax_response(request, status="ko", template=tplname, **commonctx)
|
||||
|
||||
form = DomainAliasForm(request.user, instance=domalias)
|
||||
commonctx["form"] = form
|
||||
return _render(request, tplname, commonctx)
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.delete_domainalias")
|
||||
@transaction.commit_on_success
|
||||
def deldomalias(request):
|
||||
selection = request.GET["selection"].split(",")
|
||||
for daid in selection:
|
||||
domalias = DomainAlias.objects.get(pk=daid)
|
||||
if not request.user.is_owner(domalias.target):
|
||||
raise PermDeniedException(_("You don't have acces to this domain"))
|
||||
events.raiseEvent("DomainAliasDeleted", domalias)
|
||||
ungrant_access_to_object(domalias)
|
||||
domalias.delete()
|
||||
msg = ungettext("Domain alias deleted", "Domain aliases deleted", len(selection))
|
||||
messages.info(request, msg, fail_silently=True)
|
||||
return ajax_response(request)
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.view_mailboxes")
|
||||
@check_domain_access
|
||||
def mailboxes(request):
|
||||
title = _("Available mailboxes")
|
||||
if request.GET.has_key("domid"):
|
||||
domain = Domain.objects.get(pk=request.GET["domid"])
|
||||
mboxes = Mailbox.objects.filter(domain=domain.id)
|
||||
title += " (%s)" % domain.name
|
||||
else:
|
||||
mboxes = request.user.get_mailboxes()
|
||||
domain = None
|
||||
deloptions = {"keepdir" : _("Do not delete mailbox directory")}
|
||||
return render_listing(request, "mailboxes",
|
||||
title=title,
|
||||
rel="310 320",
|
||||
objects=mboxes, domain=domain, deloptions=deloptions)
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.view_mailboxes")
|
||||
@check_domain_access
|
||||
@@ -271,135 +153,14 @@ def mailboxes_search(request):
|
||||
result = map(lambda mb: mb.full_address, mboxes)
|
||||
return ajax_simple_response(result)
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.add_mailbox")
|
||||
@transaction.commit_on_success
|
||||
def newmailbox(request, tplname="admin/adminform.html"):
|
||||
events.raiseEvent("CanCreate", request.user, "mailboxes")
|
||||
commonctx = {"title" : _("New mailbox"),
|
||||
"submit_label" : _("Create"),
|
||||
"action" : reverse(newmailbox),
|
||||
"formid" : "mboxform"}
|
||||
if request.method == "POST":
|
||||
form = MailboxWithPasswordForm(request.user, request.POST)
|
||||
error = None
|
||||
if form.is_valid():
|
||||
if not request.user.is_superuser:
|
||||
if not request.user.can_access(form.cleaned_data["domain"]):
|
||||
raise PermDeniedException(_("You do not have access to this domain"))
|
||||
|
||||
try:
|
||||
mb = form.save()
|
||||
except AdminError as e:
|
||||
error = str(e)
|
||||
else:
|
||||
grant_access_to_object(request.user, mb, is_owner=True)
|
||||
grant_access_to_object(request.user, mb.user, is_owner=True)
|
||||
events.raiseEvent("CreateMailbox", request.user, mb)
|
||||
messages.info(request, _("Mailbox created"),
|
||||
fail_silently=True)
|
||||
return ajax_response(request, url=reverse(admin.views.mailboxes) + "?domid=%d" % mb.domain.id)
|
||||
|
||||
commonctx["form"] = form
|
||||
commonctx["error"] = error
|
||||
return ajax_response(request, status="ko", template=tplname, **commonctx)
|
||||
|
||||
form = MailboxWithPasswordForm(request.user)
|
||||
commonctx["form"] = form
|
||||
return _render(request, tplname, commonctx)
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.change_mailbox")
|
||||
def editmailbox(request, mbox_id=None, tplname="admin/adminform.html"):
|
||||
mb = Mailbox.objects.get(pk=mbox_id)
|
||||
if not request.user.can_access(mb.domain):
|
||||
raise PermDeniedException(_("You do not have access to this domain"))
|
||||
|
||||
commonctx = {"title" : _("Mailbox editing"),
|
||||
"submit_label" : _("Create"),
|
||||
"action" : reverse(editmailbox, args=[mbox_id]),
|
||||
"formid" : "mboxform"}
|
||||
if request.method == "POST":
|
||||
if request.POST.get("password1", "") != "" or \
|
||||
request.POST.get("password2", "") != "":
|
||||
formclass = MailboxWithPasswordForm
|
||||
else:
|
||||
formclass = MailboxForm
|
||||
oldmb = copy.deepcopy(mb)
|
||||
form = formclass(request.user, request.POST, instance=mb)
|
||||
error = None
|
||||
if form.is_valid():
|
||||
try:
|
||||
mb = form.save(commit=False)
|
||||
except AdminError, inst:
|
||||
error = str(inst)
|
||||
else:
|
||||
if oldmb.rename_dir(mb.domain.name, mb.address):
|
||||
form.commit_save(mb)
|
||||
events.raiseEvent("ModifyMailbox", mb, oldmb)
|
||||
messages.info(request, _("Mailbox modified"),
|
||||
fail_silently=True)
|
||||
return ajax_response(request, url=reverse(admin.views.mailboxes) + "?domid=%d" % mb.domain.id)
|
||||
error = _("Failed to rename mailbox, check permissions")
|
||||
|
||||
commonctx["form"] = form
|
||||
commonctx["error"] = error
|
||||
return ajax_response(request, status="ko", template=tplname, **commonctx)
|
||||
|
||||
form = MailboxWithPasswordForm(request.user, instance=mb)
|
||||
commonctx["form"] = form
|
||||
return _render(request, tplname, commonctx)
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.delete_mailbox")
|
||||
@transaction.commit_on_success
|
||||
def delmailbox(request):
|
||||
selection = request.GET["selection"].split(",")
|
||||
error = None
|
||||
keepdir = True if request.GET.get("keepdir", "false") == "true" else False
|
||||
usermb = request.user.mailbox_set.all()[0] \
|
||||
if len(request.user.mailbox_set.all()) else None
|
||||
|
||||
for mb in Mailbox.objects.filter(id__in=selection):
|
||||
if not request.user.can_access(mb.domain):
|
||||
raise PermDeniedException(_("You don't have access to this domain"))
|
||||
if usermb and usermb == mb:
|
||||
raise AdminError(_("You can't delete your own mailbox"))
|
||||
events.raiseEvent("DeleteMailbox", mb)
|
||||
ungrant_access_to_object(mb)
|
||||
ungrant_access_to_object(mb.user)
|
||||
mb.delete(keepdir=keepdir)
|
||||
|
||||
msg = ungettext("Mailbox deleted", "Mailboxes deleted", len(selection))
|
||||
messages.info(request, msg, fail_silently=True)
|
||||
return ajax_response(request)
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.view_aliases")
|
||||
@check_domain_access
|
||||
def mbaliases(request):
|
||||
if request.GET.has_key("domid"):
|
||||
aliases = Alias.objects.filter(domain=request.GET["domid"])
|
||||
elif request.GET.has_key("mbid"):
|
||||
aliases = Alias.objects.filter(mboxes__id=request.GET["mbid"]).distinct()
|
||||
else:
|
||||
aliases = request.user.get_mbaliases()
|
||||
|
||||
return render_listing(request, "mbaliases",
|
||||
title=_("Mailbox aliases"),
|
||||
rel="320 300",
|
||||
objects=aliases)
|
||||
|
||||
def _validate_mbalias(request, form, successmsg, tplname, commonctx, callback=None):
|
||||
"""Mailbox alias validation
|
||||
def _validate_dlist(request, form, successmsg, tplname, commonctx, callback=None):
|
||||
"""Distribution list validation
|
||||
|
||||
Common function shared between creation and modification actions.
|
||||
"""
|
||||
error = None
|
||||
if form.is_valid():
|
||||
if not request.POST.has_key("targets"):
|
||||
raise AdminError(_("No target defined"))
|
||||
form.set_targets(request.user, request.POST.getlist("targets"))
|
||||
form.set_recipients(request.user)
|
||||
try:
|
||||
alias = form.save()
|
||||
except IntegrityError:
|
||||
@@ -408,8 +169,8 @@ def _validate_mbalias(request, form, successmsg, tplname, commonctx, callback=No
|
||||
if callback:
|
||||
callback(request.user, alias)
|
||||
|
||||
messages.info(request, successmsg, fail_silently=True)
|
||||
return ajax_response(request, url=reverse(admin.views.mbaliases))
|
||||
messages.info(request, successmsg)
|
||||
return ajax_response(request, url=reverse(admin.views.identities))
|
||||
|
||||
if request.POST.has_key("targets"):
|
||||
targets = request.POST.getlist("targets")
|
||||
@@ -422,218 +183,184 @@ def _validate_mbalias(request, form, successmsg, tplname, commonctx, callback=No
|
||||
@login_required
|
||||
@permission_required("admin.add_alias")
|
||||
@transaction.commit_on_success
|
||||
def newmbalias(request, tplname="admin/mbaliasform.html"):
|
||||
def newdlist(request, tplname="common/generic_modal_form.html"):
|
||||
events.raiseEvent("CanCreate", request.user, "mailbox_aliases")
|
||||
commonctx = {"title" : _("New mailbox alias"),
|
||||
commonctx = {"title" : _("New distribution list"),
|
||||
"submit_label" : _("Create"),
|
||||
"action" : reverse(newmbalias),
|
||||
"formid" : "mbaliasform"}
|
||||
"action" : reverse(newdlist),
|
||||
"formid" : "dlistform"}
|
||||
|
||||
if request.method == "POST":
|
||||
def callback(user, mbalias):
|
||||
grant_access_to_object(user, mbalias, is_owner=True)
|
||||
events.raiseEvent("MailboxAliasCreated", user, mbalias)
|
||||
def callback(user, dlist):
|
||||
grant_access_to_object(user, dlist, is_owner=True)
|
||||
events.raiseEvent("MailboxAliasCreated", user, dlist)
|
||||
|
||||
form = AliasForm(request.user, request.POST)
|
||||
return _validate_mbalias(request, form, _("Mailbox alias created"),
|
||||
tplname, commonctx, callback)
|
||||
form = DlistForm(request.POST)
|
||||
return _validate_dlist(request, form, _("Distribution list created"),
|
||||
tplname, commonctx, callback)
|
||||
|
||||
form = AliasForm(request.user)
|
||||
form = DlistForm()
|
||||
commonctx["form"] = form
|
||||
commonctx["noerrors"] = True
|
||||
return _render(request, tplname, commonctx)
|
||||
return _render(request, "common/generic_modal_form.html", commonctx)
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.change_alias")
|
||||
def editmbalias(request, alias_id, tplname="admin/mbaliasform.html"):
|
||||
alias = Alias.objects.get(pk=alias_id)
|
||||
if not request.user.is_owner(alias.domain):
|
||||
def editdlist(request, dlist_id, tplname="admin/dlistform.html"):
|
||||
dlist = Alias.objects.get(pk=dlist_id)
|
||||
if not request.user.is_owner(dlist.domain):
|
||||
raise PermDeniedException(_("You do not have access to this domain"))
|
||||
commonctx = {"title" : _("Mailbox alias editing"),
|
||||
commonctx = {"title" : dlist.full_address,
|
||||
"submit_label" : _("Update"),
|
||||
"action" : reverse(editmbalias, args=[alias.id]),
|
||||
"formid" : "mbaliasform"}
|
||||
"action" : reverse(editdlist, args=[dlist.id]),
|
||||
"formid" : "dlistform"}
|
||||
if request.method == "POST":
|
||||
form = AliasForm(request.user, request.POST, instance=alias)
|
||||
return _validate_mbalias(request, form, _("Mailbox alias modified"),
|
||||
tplname, commonctx)
|
||||
form = DlistForm(request.POST, instance=dlist)
|
||||
return _validate_dlist(request, form, _("Distribution list modified"),
|
||||
tplname, commonctx)
|
||||
|
||||
form = AliasForm(request.user, instance=alias)
|
||||
form = DlistForm(instance=dlist)
|
||||
commonctx["form"] = form
|
||||
commonctx["targets"] = alias.get_targets()
|
||||
return _render(request, tplname, commonctx)
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.delete_alias")
|
||||
@transaction.commit_on_success
|
||||
def delmbalias(request):
|
||||
def deldlist(request):
|
||||
selection = request.GET["selection"].split(",")
|
||||
for mbaid in selection:
|
||||
mbalias = Alias.objects.get(pk=mbaid)
|
||||
if not request.user.is_owner(mbalias.domain):
|
||||
for dlist_id in selection:
|
||||
dlist = Alias.objects.get(pk=dlist_id)
|
||||
if not request.user.is_owner(dlist.domain):
|
||||
raise PermDeniedException(_("You do not have access to this domain"))
|
||||
events.raiseEvent("MailboxAliasDeleted", mbalias)
|
||||
ungrant_access_to_object(mbalias)
|
||||
mbalias.delete()
|
||||
events.raiseEvent("MailboxAliasDeleted", dlist)
|
||||
ungrant_access_to_object(dlist)
|
||||
dlist.delete()
|
||||
|
||||
msg = ungettext("Alias deleted", "Aliases deleted", len(selection))
|
||||
messages.info(request, msg, fail_silently=True)
|
||||
msg = ungettext("Distribution list deleted",
|
||||
"Distribution lists deleted", len(selection))
|
||||
messages.info(request, msg)
|
||||
return ajax_response(request)
|
||||
|
||||
@login_required
|
||||
@permission_required("auth.view_permissions")
|
||||
def permissions(request, tplname='admin/permissions.html'):
|
||||
permtables = []
|
||||
if request.user.is_superuser:
|
||||
permtables += [
|
||||
{"id" : "super_admins",
|
||||
"title" : _("Super administrators"),
|
||||
"rel" : "300 140",
|
||||
"content" : SuperAdminsPerms().get(request)}
|
||||
]
|
||||
|
||||
permtables += events.raiseQueryEvent("PermsGetTables", request)
|
||||
|
||||
permtables += [
|
||||
{"id" : "domain_admins",
|
||||
"title" : _("Domain administrators"),
|
||||
"rel" : "350 100",
|
||||
"content" : DomainAdminsPerms().get(request)}
|
||||
]
|
||||
|
||||
return _render(request, tplname, {
|
||||
"permtables" : permtables
|
||||
})
|
||||
@user_passes_test(lambda u: u.has_perm("auth.add_user") or u.has_perm("admin.add_mailbox"))
|
||||
def identities(request, tplname='admin/identities.html'):
|
||||
accounts_list = []
|
||||
for account in User.objects.all():
|
||||
if request.user.can_access(account) or \
|
||||
account.has_mailbox and request.user.can_access(account.mailbox_set.all()[0].domain):
|
||||
accounts_list += [account]
|
||||
for mbalias in Alias.objects.all():
|
||||
if len(mbalias.get_recipients()) > 2:
|
||||
accounts_list += [mbalias]
|
||||
return render_listing(request, "identities", tplname, objects=accounts_list)
|
||||
|
||||
@login_required
|
||||
@permission_required("auth.view_permissions")
|
||||
def add_permission(request):
|
||||
role = request.method == "GET" and request.GET["role"] or request.POST["role"]
|
||||
pclass = get_perms_class(request.user, role)
|
||||
if pclass is None:
|
||||
messages.error(request, _("Permission denied!"),
|
||||
fail_silently=True)
|
||||
else:
|
||||
events.raiseEvent("CanCreate", request.user, role)
|
||||
pobj = pclass()
|
||||
if request.method == "GET":
|
||||
return pobj.get_add_form(request)
|
||||
status, data = pobj.add(request)
|
||||
if not status:
|
||||
return HttpResponse(simplejson.dumps(data), mimetype="application/json")
|
||||
try:
|
||||
msg = pobj.add_success_msg
|
||||
except AttributeError:
|
||||
msg = _("Permission added")
|
||||
messages.info(request, msg, fail_silently=True)
|
||||
return ajax_response(request, url=reverse(admin.views.permissions))
|
||||
def accounts_list(request):
|
||||
accs = User.objects.filter(is_superuser=False).exclude(groups__name='SimpleUsers')
|
||||
res = map(lambda a: a.username, accs.all())
|
||||
return ajax_simple_response(res)
|
||||
|
||||
@login_required
|
||||
@permission_required("auth.view_permissions")
|
||||
def create_domain_admin(request, tplname="admin/create_domain_admin.html"):
|
||||
events.raiseEvent("CanCreate", request.user, "domain_admins")
|
||||
if request.method == "POST":
|
||||
form = UserWithPasswordForm(request.POST)
|
||||
if form.is_valid():
|
||||
user = form.save(group="DomainAdmins")
|
||||
grant_access_to_object(request.user, user, is_owner=True)
|
||||
events.raiseEvent("DomainAdminCreated", user)
|
||||
messages.info(request, _("Domain admin created"), fail_silently=True)
|
||||
return ajax_response(request, url=reverse(admin.views.permissions))
|
||||
|
||||
return ajax_response(request, status="ko", template=tplname, form=form)
|
||||
|
||||
form = UserWithPasswordForm()
|
||||
return ajax_response(request, template=tplname, form=form)
|
||||
|
||||
@login_required
|
||||
@permission_required("auth.view_permissions")
|
||||
def edit_domain_admin(request, da_id, tplname="admin/adminform.html"):
|
||||
ctx = dict(title=_("Edit domain admin"),
|
||||
action=reverse(edit_domain_admin, args=[da_id]),
|
||||
formid="eda_form",
|
||||
submit_label=_("Update"))
|
||||
u = User.objects.get(pk=da_id, groups__name="DomainAdmins")
|
||||
if request.method == "POST":
|
||||
if request.POST.get("password1", "") != "" and \
|
||||
request.POST.get("password2", "") != "":
|
||||
form = UserWithPasswordForm(request.POST, instance=u)
|
||||
else:
|
||||
form = UserForm(request.POST, instance=u)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
if form.cleaned_data["createmb"]:
|
||||
pass
|
||||
messages.info(request, _("Domain admin updated"), fail_silently=True)
|
||||
return ajax_response(request,
|
||||
url=reverse("modoboa.admin.views.permissions"))
|
||||
ctx.update(form=form)
|
||||
return ajax_response(request, status="ko", template=tplname, **ctx)
|
||||
|
||||
form = UserWithPasswordForm(instance=u)
|
||||
ctx.update(form=form)
|
||||
return _render(request, tplname, ctx)
|
||||
|
||||
@login_required
|
||||
@permission_required("auth.view_permissions")
|
||||
def domain_admin_promotion(request, tplname="admin/domain_admin_promotion.html"):
|
||||
if request.method == "POST":
|
||||
form = DomainAdminPromotionForm(request.POST)
|
||||
if form.is_valid():
|
||||
u = User.objects.get(username=form.cleaned_data["name"])
|
||||
u.groups.add(Group.objects.get(name="DomainAdmins"))
|
||||
u.save()
|
||||
if not request.user.can_access(u):
|
||||
# The only case where we need to grant access to the
|
||||
# object is when ``u`` has been create by a super
|
||||
# admin
|
||||
grant_access_to_object(request.user, u, is_owner=True)
|
||||
events.raiseEvent("DomainAdminCreated", u)
|
||||
messages.info(request, _("Domain admin added"), fail_silently=True)
|
||||
return ajax_response(request, url=reverse(admin.views.permissions))
|
||||
|
||||
return ajax_response(request, status="ko", template=tplname, form=form)
|
||||
|
||||
form = DomainAdminPromotionForm()
|
||||
return ajax_response(request, template=tplname, form=form)
|
||||
|
||||
@login_required
|
||||
@permission_required("auth.view_permissions")
|
||||
@transaction.commit_on_success
|
||||
def assign_domains_to_admin(request, da_id, tplname="admin/adminform.html"):
|
||||
da = User.objects.get(pk=da_id)
|
||||
ctx = dict(title=_("Assign domains to %s" % da.username),
|
||||
action=reverse(assign_domains_to_admin, args=[da_id]),
|
||||
formid="assignform",
|
||||
submit_label=_("Assign"))
|
||||
def newaccount(request, tplname='admin/newaccount.html'):
|
||||
from modoboa.lib.formutils import CreationWizard
|
||||
|
||||
def create_account(steps):
|
||||
"""Account creation callback
|
||||
|
||||
Called when all the creation steps have been validated.
|
||||
|
||||
:param steps: the steps data
|
||||
"""
|
||||
genform = steps[0]["form"]
|
||||
genform.is_valid()
|
||||
account = genform.save()
|
||||
grant_access_to_object(request.user, account, is_owner=True)
|
||||
events.raiseEvent("AccountCreated", account)
|
||||
|
||||
mailform = steps[1]["form"]
|
||||
mailform.save(request.user, account)
|
||||
|
||||
ctx = dict(
|
||||
title=_("New account"),
|
||||
action=reverse(newaccount),
|
||||
formid="newaccount_form",
|
||||
submit_label=_("Create")
|
||||
)
|
||||
cwizard = CreationWizard(create_account)
|
||||
cwizard.add_step(AccountFormGeneralPwd,
|
||||
buttons=[dict(classes="btn-inverse next", label=_("Next"))],
|
||||
new_args=[request.user])
|
||||
cwizard.add_step(AccountFormMail,
|
||||
buttons=[dict(classes="btn-primary submit", label=_("Create")),
|
||||
dict(classes="btn-inverse prev", label=_("Previous"))])
|
||||
|
||||
if request.method == "POST":
|
||||
form = AssignDomainsForm(request.user, da, request.POST)
|
||||
if form.is_valid():
|
||||
current_domains = da.get_domains()
|
||||
for domain in form.cleaned_data["domains"]:
|
||||
if not domain in current_domains:
|
||||
grant_access_to_object(da, domain)
|
||||
else:
|
||||
current_domains.remove(domain)
|
||||
for domain in current_domains:
|
||||
ungrant_access_to_object(domain, da)
|
||||
msg = ungettext("Domain assigned", "Domains assigned",
|
||||
len(form.cleaned_data["domains"]))
|
||||
messages.info(request, msg)
|
||||
return ajax_response(request, url=reverse(admin.views.permissions))
|
||||
ctx.update(form=form)
|
||||
retcode, data = cwizard.validate_step(request)
|
||||
if retcode == -1:
|
||||
raise AdminError(data)
|
||||
if retcode == 1:
|
||||
return ajax_simple_response(dict(status="ok"))
|
||||
if retcode == 2:
|
||||
messages.info(request, _("Account created"))
|
||||
return ajax_simple_response(dict(status="ok"))
|
||||
ctx.update(steps=cwizard.steps)
|
||||
return ajax_response(request, status="ko", template=tplname, **ctx)
|
||||
|
||||
form = AssignDomainsForm(request.user, da)
|
||||
ctx.update(form=form)
|
||||
cwizard.create_forms()
|
||||
ctx.update(steps=cwizard.steps)
|
||||
return _render(request, tplname, ctx)
|
||||
|
||||
@login_required
|
||||
@permission_required("auth.view_permissions")
|
||||
def view_domain_admins(request, dom_id, tplname="admin/view_domain_admins.html"):
|
||||
domain = Domain.objects.get(pk=dom_id)
|
||||
return _render(request, tplname, {
|
||||
"domain" : domain
|
||||
})
|
||||
@transaction.commit_on_success
|
||||
def editaccount(request, accountid, tplname="common/tabforms.html"):
|
||||
account = User.objects.get(pk=accountid)
|
||||
mb = account.mailbox_set.all()[0] if account.has_mailbox else None
|
||||
instances = dict(general=account, mail=mb, perms=account)
|
||||
events.raiseEvent("FillAccountInstances", request.user, account, instances)
|
||||
|
||||
ctx = dict(
|
||||
title=account.username,
|
||||
action=reverse(editaccount, args=[accountid]),
|
||||
submit_label=_("Update")
|
||||
)
|
||||
|
||||
if request.method == "POST":
|
||||
classes = {}
|
||||
if request.POST.get("password1", "") == "" \
|
||||
and request.POST.get("password2", "") == "":
|
||||
classes["general"] = AccountFormGeneral
|
||||
form = AccountForm(request.user, request.POST,
|
||||
instances=instances, classes=classes)
|
||||
account.oldgroup = account.group
|
||||
if form.is_valid(mandatory_only=True):
|
||||
form.save_general_form()
|
||||
if form.is_valid(optional_only=True):
|
||||
events.raiseEvent("AccountModified", account, form.account)
|
||||
form.save()
|
||||
messages.info(request, _("Account updated"))
|
||||
return ajax_simple_response(dict(status="ok"))
|
||||
transaction.rollback()
|
||||
|
||||
ctx["tabs"] = form
|
||||
return ajax_response(request, status="ko", template=tplname, **ctx)
|
||||
|
||||
ctx["tabs"] = AccountForm(request.user, instances=instances)
|
||||
return _render(request, tplname, ctx)
|
||||
|
||||
@login_required
|
||||
@user_passes_test(lambda u: u.has_perm("auth.delete_user") or \
|
||||
u.has_perm("admin.delete_mailbox"))
|
||||
@transaction.commit_on_success
|
||||
def delaccount(request):
|
||||
selection = request.GET["selection"].split(",")
|
||||
keepdir = True if request.GET.get("keepdir", "false") == "true" else False
|
||||
|
||||
for account in User.objects.filter(id__in=selection):
|
||||
account.delete(request.user, keepdir)
|
||||
|
||||
msg = ungettext("Account deleted", "Accounts deleted", len(selection))
|
||||
messages.info(request, msg, fail_silently=True)
|
||||
return ajax_response(request)
|
||||
|
||||
@login_required
|
||||
@permission_required("auth.view_permissions")
|
||||
@@ -654,19 +381,6 @@ def search_account(request):
|
||||
result = map(lambda u: u.username, users.all())
|
||||
return ajax_simple_response(result)
|
||||
|
||||
@login_required
|
||||
def delete_permissions(request):
|
||||
pclass = get_perms_class(request.user, request.GET["role"])
|
||||
if pclass is None:
|
||||
ctx = getctx("ko", message=_("Permission denied!"))
|
||||
else:
|
||||
selection = request.GET["selection"].split(",")
|
||||
pobj = pclass()
|
||||
pobj.delete(selection)
|
||||
ctx = getctx("ok", content=pobj.get(request),
|
||||
message=_("Permissions removed"))
|
||||
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
|
||||
|
||||
@login_required
|
||||
@user_passes_test(lambda u: u.is_superuser)
|
||||
def viewparameters(request, tplname='admin/parameters.html'):
|
||||
@@ -688,6 +402,7 @@ def viewparameters(request, tplname='admin/parameters.html'):
|
||||
gparams += [tmp]
|
||||
|
||||
return _render(request, tplname, {
|
||||
"selection" : "parameters",
|
||||
"gparams" : gparams
|
||||
})
|
||||
|
||||
@@ -699,7 +414,7 @@ def saveparameters(request):
|
||||
continue
|
||||
app, name = pname.split('.')
|
||||
parameters.save_admin(name, v, app=app)
|
||||
return ajax_response(request)
|
||||
return ajax_simple_response(dict(status="ok", message=_("Parameters saved")))
|
||||
|
||||
@login_required
|
||||
@user_passes_test(lambda u: u.is_superuser)
|
||||
@@ -720,6 +435,7 @@ def viewextensions(request, tplname='admin/extensions.html'):
|
||||
|
||||
tbl = ExtensionsTable(request, exts)
|
||||
return _render(request, tplname, {
|
||||
"selection" : "extensions",
|
||||
"extensions" : tbl
|
||||
})
|
||||
|
||||
@@ -741,40 +457,92 @@ def saveextensions(request):
|
||||
for ext in actived_exts:
|
||||
if not ext in found:
|
||||
ext.off()
|
||||
messages.info(request, _("Modifications applied."), fail_silently=True)
|
||||
return HttpResponseRedirect(reverse(admin.views.viewextensions))
|
||||
|
||||
@login_required
|
||||
@permission_required("admin.add_mailbox")
|
||||
@transaction.commit_on_success
|
||||
def importdata(request, tplname="admin/import.html"):
|
||||
if request.method == "POST":
|
||||
error = None
|
||||
form = ImportDataForm(request.POST, request.FILES)
|
||||
if form.is_valid():
|
||||
import csv
|
||||
return ajax_simple_response(dict(
|
||||
status="ok", message=_("Modifications applied."), reload=True
|
||||
))
|
||||
|
||||
def import_domain(user, row):
|
||||
pass
|
||||
|
||||
def import_account(user, row):
|
||||
"""Specific code for accounts import"""
|
||||
mb = Mailbox()
|
||||
mb.create_from_csv(user, row)
|
||||
events.raiseEvent("AccountCreated", user, mb.user)
|
||||
events.raiseEvent("CreateMailbox", user, mb)
|
||||
grant_access_to_object(user, mb.user)
|
||||
grant_access_to_object(user, mb)
|
||||
|
||||
def importdata(request, typ):
|
||||
"""Generic import function
|
||||
|
||||
As the process of importing data from a CSV file is the same
|
||||
whatever the type, we do a maximum of the work here.
|
||||
|
||||
:param request: a ``Request`` instance
|
||||
:param typ: a string indicating the object type being imported
|
||||
:return: a ``Response`` instance
|
||||
"""
|
||||
error = None
|
||||
form = ImportDataForm(request.POST, request.FILES)
|
||||
if form.is_valid():
|
||||
import csv
|
||||
|
||||
try:
|
||||
reader = csv.reader(request.FILES['sourcefile'],
|
||||
delimiter=form.cleaned_data['sepcar'])
|
||||
except Exception, e:
|
||||
error = str(e)
|
||||
|
||||
if error is None:
|
||||
fct = globals()["import_%s" % typ]
|
||||
try:
|
||||
cpt = 0
|
||||
for row in reader:
|
||||
mb = Mailbox()
|
||||
mb.create_from_csv(request.user, row)
|
||||
events.raiseEvent("CreateMailbox", request.user, mb)
|
||||
fct(request.user, row)
|
||||
cpt += 1
|
||||
messages.info(request, _("%d mailboxes imported successfully" % cpt))
|
||||
messages.info(request, _("%d %s imported successfully" % (cpt, typ)))
|
||||
return _render(request, "admin/import_done.html", {
|
||||
"status" : "ok", "msg" : ""
|
||||
})
|
||||
except ModoboaException, e:
|
||||
error = str(e)
|
||||
|
||||
return _render(request, "admin/import_done.html", {
|
||||
"status" : "ko", "msg" : error
|
||||
})
|
||||
return _render(request, "admin/import_done.html", {
|
||||
"status" : "ko", "msg" : error
|
||||
})
|
||||
|
||||
form = ImportDataForm()
|
||||
ctx = dict(title=_("Import data"), action="", formid="importform",
|
||||
enctype="multipart/form-data", form=form, submit_label=_("Import"))
|
||||
return _render(request, tplname, ctx)
|
||||
@login_required
|
||||
@transaction.commit_on_success
|
||||
def import_identities(request):
|
||||
if request.method == "POST":
|
||||
return importdata(request, "account")
|
||||
|
||||
ctx = dict(
|
||||
title=_("Import identities"),
|
||||
submit_label=_("Import"),
|
||||
action=reverse(import_identities),
|
||||
formid="importform",
|
||||
enctype="multipart/form-data",
|
||||
target="import_target",
|
||||
form=ImportDataForm()
|
||||
)
|
||||
return _render(request, "admin/importform.html", ctx)
|
||||
|
||||
@login_required
|
||||
@transaction.commit_on_success
|
||||
def import_domains(request):
|
||||
if request.method == "POST":
|
||||
return importdata(request, "domain")
|
||||
|
||||
ctx = dict(
|
||||
title=_("Import domains"),
|
||||
submit_label=_("Import"),
|
||||
action=reverse(import_domains),
|
||||
formid="importform",
|
||||
enctype="multipart/form-data",
|
||||
target="import_target",
|
||||
form=ImportDataForm()
|
||||
)
|
||||
return _render(request, "admin/importform.html", ctx)
|
||||
|
||||
@@ -2,6 +2,12 @@ from django import forms
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
class LoginForm(forms.Form):
|
||||
username = forms.CharField(label=_("Username"))
|
||||
password = forms.CharField(label=_("Password"), widget=forms.PasswordInput,
|
||||
help_text=_("Password used to authenticate"))
|
||||
username = forms.CharField(
|
||||
label=_("Username"),
|
||||
widget=forms.TextInput()
|
||||
)
|
||||
password = forms.CharField(
|
||||
label=_("Password"),
|
||||
widget=forms.PasswordInput(),
|
||||
help_text=_("Password used to authenticate")
|
||||
)
|
||||
|
||||
@@ -9,10 +9,10 @@ from django.db import IntegrityError
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.utils.translation import ugettext_noop as _, ugettext
|
||||
from django.core.urlresolvers import reverse
|
||||
from modoboa.lib import events, parameters
|
||||
from modoboa.lib import events
|
||||
from modoboa.lib.webutils import static_url
|
||||
from modoboa.admin.models import User
|
||||
from models import *
|
||||
from forms import ResourcePoolForm
|
||||
import permissions
|
||||
import controls
|
||||
import views
|
||||
@@ -20,6 +20,8 @@ import views
|
||||
baseurl = "limits"
|
||||
|
||||
def init():
|
||||
from modoboa.admin.models import User
|
||||
|
||||
ct = ContentType.objects.get(app_label="admin", model="domain")
|
||||
dagrp = Group.objects.get(name="DomainAdmins")
|
||||
for pname in ["view_domains", "add_domain", "change_domain", "delete_domain"]:
|
||||
@@ -59,9 +61,9 @@ def infos():
|
||||
"url" : baseurl
|
||||
}
|
||||
|
||||
@events.observe('AdminFooterDisplay')
|
||||
#@events.observe('AdminFooterDisplay')
|
||||
def display_pool_usage(user, objtype):
|
||||
if user.id == 1:
|
||||
if user.is_superuser:
|
||||
return []
|
||||
if objtype == "domaliases":
|
||||
objtype = "domain_aliases"
|
||||
@@ -89,3 +91,36 @@ def get_da_actions(user):
|
||||
"class" : "boxed",
|
||||
"rel" : "{handler:'iframe',size:{x:330,y:280}}"},
|
||||
]
|
||||
|
||||
@events.observe("ExtraAccountForm")
|
||||
def extra_account_form(user, account=None):
|
||||
if not user.is_superuser and not user.belongs_to_group("Resellers"):
|
||||
return []
|
||||
if account:
|
||||
if not account.belongs_to_group("Resellers") and \
|
||||
not account.belongs_to_group("DomainAdmins"):
|
||||
return []
|
||||
|
||||
return [
|
||||
dict(
|
||||
id="resources", title=_("Resources"), cls=ResourcePoolForm
|
||||
)
|
||||
]
|
||||
|
||||
@events.observe("CheckExtraAccountForm")
|
||||
def check_form_access(account, form):
|
||||
if form["id"] != "resources":
|
||||
return [True]
|
||||
if not account.belongs_to_group("Resellers") and \
|
||||
not account.belongs_to_group("DomainAdmins"):
|
||||
return [False]
|
||||
return [True]
|
||||
|
||||
@events.observe("FillAccountInstances")
|
||||
def fill_account_instances(user, account, instances):
|
||||
if not user.is_superuser and not user.belongs_to_group("Resellers"):
|
||||
return
|
||||
if not account.belongs_to_group("Resellers") and \
|
||||
not account.belongs_to_group("DomainAdmins"):
|
||||
return
|
||||
instances["resources"] = account
|
||||
|
||||
@@ -4,13 +4,10 @@
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
"""
|
||||
from modoboa.admin.models import Mailbox
|
||||
from modoboa.admin.lib import \
|
||||
get_object_owner, grant_access_to_object, \
|
||||
ungrant_access_to_object
|
||||
from modoboa.lib import events
|
||||
from lib import *
|
||||
from models import *
|
||||
from modoboa.lib.permissions import get_object_owner
|
||||
|
||||
def check_limit(user, lname):
|
||||
"""Check if a user has reached a defined limit
|
||||
@@ -40,6 +37,22 @@ def dec_limit(user, lname):
|
||||
except LimitsPool.DoesNotExist:
|
||||
pass
|
||||
|
||||
def move_pool_resource(owner, user):
|
||||
try:
|
||||
pool = user.limitspool
|
||||
except LimitsPool.DoesNotExist:
|
||||
return
|
||||
if not owner.is_superuser:
|
||||
for lname in reseller_limits_tpl:
|
||||
l = user.limitspool.get_limit(lname)
|
||||
if l.maxvalue < 0:
|
||||
continue
|
||||
ol = owner.limitspool.get_limit(lname)
|
||||
ol.curvalue += l.curvalue
|
||||
ol.maxvalue += l.maxvalue
|
||||
ol.save()
|
||||
|
||||
user.limitspool.delete()
|
||||
|
||||
@events.observe('CreateDomain')
|
||||
def inc_nb_domains(user, domain):
|
||||
@@ -61,18 +74,29 @@ def inc_nb_domaliases(user, domalias):
|
||||
inc_limit(user, 'domain_aliases_limit')
|
||||
|
||||
@events.observe('DomainAliasDeleted')
|
||||
def dec_nb_domaliases(domainalias):
|
||||
owner = get_object_owner(domainalias)
|
||||
dec_limit(owner, 'domain_aliases_limit')
|
||||
def dec_nb_domaliases(domainaliases):
|
||||
from modoboa.admin.models import DomainAlias
|
||||
|
||||
if isinstance(domainaliases, DomainAlias):
|
||||
domainaliases = [domainaliases]
|
||||
for domainalias in domainaliases:
|
||||
owner = get_object_owner(domainalias)
|
||||
dec_limit(owner, 'domain_aliases_limit')
|
||||
|
||||
@events.observe('CreateMailbox')
|
||||
def inc_nb_mailboxes(user, mailbox):
|
||||
inc_limit(user, 'mailboxes_limit')
|
||||
|
||||
@events.observe('DeleteMailbox')
|
||||
def dec_nb_mailboxes(mailbox):
|
||||
owner = get_object_owner(mailbox)
|
||||
dec_limit(owner, 'mailboxes_limit')
|
||||
def dec_nb_mailboxes(mailboxes):
|
||||
from modoboa.admin.models import Mailbox
|
||||
|
||||
if isinstance(mailboxes, Mailbox):
|
||||
mailboxes = [mailboxes]
|
||||
for mailbox in mailboxes:
|
||||
owner = get_object_owner(mailbox)
|
||||
dec_limit(owner, 'mailboxes_limit')
|
||||
# FIXME: Gestion des alias ici
|
||||
|
||||
@events.observe('MailboxAliasCreated')
|
||||
def inc_nb_mbaliases(user, mailboxalias):
|
||||
@@ -87,30 +111,48 @@ def dec_nb_mbaliases(mailboxalias):
|
||||
def can_create_new_object(user, objtype):
|
||||
check_limit(user, '%s_limit' % objtype)
|
||||
|
||||
@events.observe("DomainAdminCreated")
|
||||
@events.observe("AccountCreated")
|
||||
def create_pool(user):
|
||||
owner = get_object_owner(user)
|
||||
inc_limit(owner, 'domain_admins_limit')
|
||||
p = LimitsPool(user=user)
|
||||
p.save()
|
||||
p.create_limits()
|
||||
if not owner.is_superuser and \
|
||||
not owner.belongs_to_group("Resellers"):
|
||||
return
|
||||
|
||||
@events.observe("DomainAdminDeleted", "SuperAdminPromotion")
|
||||
def move_pool_resource(user):
|
||||
owner = get_object_owner(user)
|
||||
if not owner.is_superuser:
|
||||
if user.belongs_to_group("DomainAdmins"):
|
||||
check_limit(owner, 'domain_admins_limit')
|
||||
inc_limit(owner, 'domain_admins_limit')
|
||||
|
||||
if user.belongs_to_group("DomainAdmins") or \
|
||||
user.belongs_to_group("Resellers"):
|
||||
p = LimitsPool(user=user)
|
||||
p.save()
|
||||
p.create_limits()
|
||||
|
||||
@events.observe("AccountModified")
|
||||
def on_account_modified(old, new):
|
||||
owner = get_object_owner(old)
|
||||
if owner.group not in ["SuperAdmins", "Resellers"]:
|
||||
return
|
||||
|
||||
if not new.group in ["DomainAdmins", "Resellers"]:
|
||||
move_pool_resource(owner, new)
|
||||
|
||||
if old.oldgroup == "DomainAdmins":
|
||||
if new.group != "DomainAdmins":
|
||||
dec_limit(owner, 'domain_admins_limit')
|
||||
return
|
||||
|
||||
if new.group == "DomainAdmins":
|
||||
check_limit(owner, 'domain_admins_limit')
|
||||
inc_limit(owner, 'domain_admins_limit')
|
||||
|
||||
@events.observe("AccountDeleted")
|
||||
def on_account_deleted(account):
|
||||
owner = get_object_owner(account)
|
||||
if not owner.group in ["SuperAdmins", "Resellers"]:
|
||||
return
|
||||
|
||||
move_pool_resource(owner, account)
|
||||
|
||||
if account.group == "DomainAdmins":
|
||||
dec_limit(owner, 'domain_admins_limit')
|
||||
|
||||
for ooentry in user.objectaccess_set.all():
|
||||
if ooentry.is_owner:
|
||||
grant_access_to_object(owner, ooentry.content_object, True)
|
||||
ooentry.delete()
|
||||
|
||||
for lname in reseller_limits_tpl:
|
||||
l = user.limitspool.get_limit(lname)
|
||||
ol = owner.limitspool.get_limit(lname)
|
||||
ol.curvalue += l.curvalue
|
||||
ol.maxvalue += l.maxvalue
|
||||
ol.save()
|
||||
|
||||
user.limitspool.delete()
|
||||
|
||||
@@ -3,33 +3,10 @@
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_noop as _
|
||||
from django.contrib.auth.models import User, Group
|
||||
from modoboa.admin.forms import UserForm, UserWithPasswordForm
|
||||
from modoboa.admin.lib import get_object_owner
|
||||
from models import *
|
||||
from lib import *
|
||||
|
||||
class ResellerForm(UserForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ResellerForm, self).__init__(*args, **kwargs)
|
||||
del self.fields["createmb"]
|
||||
|
||||
def save(self, commit=True, group=None):
|
||||
user = super(ResellerForm, self).save(commit, group)
|
||||
if commit:
|
||||
try:
|
||||
pool = user.limitspool
|
||||
except LimitsPool.DoesNotExist:
|
||||
pool = LimitsPool()
|
||||
pool.user = user
|
||||
pool.save()
|
||||
pool.create_limits()
|
||||
|
||||
return user
|
||||
|
||||
class ResellerWithPasswordForm(ResellerForm, UserWithPasswordForm):
|
||||
pass
|
||||
|
||||
class ResellerPoolForm(forms.Form):
|
||||
class ResourcePoolForm(forms.Form):
|
||||
domain_admins_limit = forms.IntegerField(
|
||||
ugettext_noop("Max domain admins"),
|
||||
help_text=ugettext_noop("Maximum number of domain administrators that can be created by this user")
|
||||
@@ -43,6 +20,16 @@ class ResellerPoolForm(forms.Form):
|
||||
mailbox_aliases_limit = forms.IntegerField(ugettext_noop("Max mailbox aliases"),
|
||||
help_text=ugettext_noop("Maximum number of mailbox aliases that can be created by this user"))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
if kwargs.has_key("instance"):
|
||||
self.account = kwargs["instance"]
|
||||
del kwargs["instance"]
|
||||
super(ResourcePoolForm, self).__init__(*args, **kwargs)
|
||||
if hasattr(self, "account"):
|
||||
if not self.account.belongs_to_group("Resellers"):
|
||||
del self.fields["domain_admins_limit"]
|
||||
self.load_from_user(self.account)
|
||||
|
||||
def check_limit_value(self, lname):
|
||||
if self.cleaned_data[lname] < -1:
|
||||
raise forms.ValidationError(_("Invalid limit"))
|
||||
@@ -84,12 +71,14 @@ class ResellerPoolForm(forms.Form):
|
||||
ol.maxvalue -= newvalue
|
||||
ol.save()
|
||||
|
||||
def save_new_limits(self, pool):
|
||||
owner = get_object_owner(pool.user)
|
||||
def save(self):
|
||||
from modoboa.lib.permissions import get_object_owner
|
||||
|
||||
owner = get_object_owner(self.account)
|
||||
for lname in reseller_limits_tpl:
|
||||
if not self.cleaned_data.has_key(lname):
|
||||
continue
|
||||
l = pool.limit_set.get(name=lname)
|
||||
l = self.account.limitspool.limit_set.get(name=lname)
|
||||
if not owner.is_superuser:
|
||||
self.allocate_from_pool(l, owner.limitspool)
|
||||
l.maxvalue = self.cleaned_data[lname]
|
||||
|
||||
@@ -1,53 +1,10 @@
|
||||
# coding: utf-8
|
||||
|
||||
from django.utils.translation import ugettext as _, ugettext_noop
|
||||
from modoboa.admin.permissions import Permissions
|
||||
from modoboa.admin.lib import grant_access_to_object, ungrant_access_to_object
|
||||
from modoboa.admin.models import User, ObjectAccess
|
||||
from modoboa.lib import events
|
||||
from modoboa.lib.webutils import _render, _render_to_string
|
||||
from tables import *
|
||||
from forms import *
|
||||
|
||||
class ResellersPerms(Permissions):
|
||||
title = ugettext_noop("New reseller")
|
||||
role = "resellers"
|
||||
add_success_msg = ugettext_noop("Reseller added")
|
||||
|
||||
def get_add_form(self, request):
|
||||
form = ResellerWithPasswordForm()
|
||||
return self._render_form(request, form)
|
||||
|
||||
def add(self, request):
|
||||
form = ResellerWithPasswordForm(request.POST)
|
||||
error = None
|
||||
if form.is_valid():
|
||||
r = form.save(group="Resellers")
|
||||
grant_access_to_object(request.user, r, True)
|
||||
return True, None
|
||||
content = self._render_form(request, form, True)
|
||||
return False, dict(status="ko", content=content)
|
||||
|
||||
def delete(self, selection):
|
||||
for u in User.objects.filter(id__in=selection):
|
||||
ungrant_access_to_object(u)
|
||||
u.delete()
|
||||
|
||||
def get(self, request):
|
||||
resellers = User.objects.filter(groups__name="Resellers")
|
||||
return ResellersTable(request, resellers).render()
|
||||
|
||||
@events.observe('PermsGetTables')
|
||||
def get_resellers_table(request):
|
||||
if not request.user.is_superuser:
|
||||
return []
|
||||
return [{"id" : "resellers",
|
||||
"title" : _("Resellers"),
|
||||
"rel" : "350 300",
|
||||
"content" : ResellersPerms().get(request)}]
|
||||
|
||||
@events.observe("PermsGetClass")
|
||||
def get_perms_class(role):
|
||||
if role != "resellers":
|
||||
return []
|
||||
return [ResellersPerms]
|
||||
@events.observe("GetExtraRoles")
|
||||
def get_extra_roles(user):
|
||||
if user.is_superuser:
|
||||
return [("Resellers", _("Reseller")),]
|
||||
return []
|
||||
|
||||
@@ -21,6 +21,23 @@ def infos():
|
||||
"url" : "postfix_autoreply"
|
||||
}
|
||||
|
||||
def init():
|
||||
from modoboa.admin.models import Domain
|
||||
|
||||
for dom in Domain.objects.all():
|
||||
try:
|
||||
trans = Transport.objects.get(domain="autoreply.%s" % dom.name)
|
||||
except Transport.DoesNotExist:
|
||||
onCreateDomain(None, dom)
|
||||
else:
|
||||
continue
|
||||
|
||||
for mb in dom.mailbox_set.all():
|
||||
try:
|
||||
alias = Alias.objects.get(full_address=mb.full_address)
|
||||
except Alias.DoesNotExist:
|
||||
onCreateMailbox(None, mb)
|
||||
|
||||
def load():
|
||||
parameters.register_admin(
|
||||
"AUTOREPLIES_TIMEOUT",
|
||||
@@ -48,10 +65,9 @@ def menu(target, user):
|
||||
return [
|
||||
{"name" : "autoreply",
|
||||
"url" : reverse(views.autoreply),
|
||||
"img" : static_url("pics/auto-reply.png"),
|
||||
"class" : "boxed",
|
||||
"rel" : "{handler:'iframe',size:{x:440,y:400}}",
|
||||
"label" : ugettext("Auto-reply message")}
|
||||
"label" : ugettext("Auto-reply message"),
|
||||
"modal": True,
|
||||
"modalcb" : "arform_cb"}
|
||||
]
|
||||
|
||||
@events.observe("CreateDomain")
|
||||
@@ -75,12 +91,18 @@ def onCreateMailbox(user, mailbox):
|
||||
alias.save()
|
||||
|
||||
@events.observe("DeleteMailbox")
|
||||
def onDeleteMailbox(mailbox):
|
||||
try:
|
||||
alias = Alias.objects.get(full_address=mailbox.full_address)
|
||||
alias.delete()
|
||||
except Alias.DoesNotExist:
|
||||
pass
|
||||
def onDeleteMailbox(mailboxes):
|
||||
from modoboa.admin.models import Mailbox
|
||||
|
||||
if isinstance(mailboxes, Mailbox):
|
||||
mailboxes = [mailboxes]
|
||||
for mailbox in mailboxes:
|
||||
try:
|
||||
alias = Alias.objects.get(full_address=mailbox.full_address)
|
||||
except Alias.DoesNotExist:
|
||||
pass
|
||||
else:
|
||||
alias.delete()
|
||||
|
||||
@events.observe("ModifyMailbox")
|
||||
def onModifyMailbox(mailbox, oldmailbox):
|
||||
@@ -91,3 +113,17 @@ def onModifyMailbox(mailbox, oldmailbox):
|
||||
alias.autoreply_address = \
|
||||
"%s@autoreply.%s" % (mailbox.full_address, mailbox.domain.name)
|
||||
alias.save()
|
||||
|
||||
@events.observe("GetStaticContent")
|
||||
def get_static_content(target):
|
||||
if target != "userprefs":
|
||||
return []
|
||||
return """<script type="text/javascript">
|
||||
function arform_cb() {
|
||||
$('#id_untildate').datepicker();
|
||||
$(".submit").one('click', function(e) {
|
||||
simple_ajax_form_post(e, arform_cb);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
"""
|
||||
|
||||
@@ -4,18 +4,15 @@ from django.utils.translation import ugettext as _
|
||||
import datetime
|
||||
|
||||
class ARmessageForm(forms.ModelForm):
|
||||
untildate = forms.DateField(label=_('Until'), required=False,
|
||||
help_text=_("Activate your auto reply until this date"))
|
||||
untildate = forms.DateField(
|
||||
label=_('Until'), required=False,
|
||||
help_text=_("Activate your auto reply until this date")
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = ARmessage
|
||||
fields = ('subject', 'content', 'enabled')
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ARmessageForm, self).__init__(*args, **kwargs)
|
||||
self.fields['subject'].widget.attrs['size'] = 40
|
||||
self.fields['content'].widget.attrs['cols'] = 50
|
||||
|
||||
def clean_untildate(self):
|
||||
if self.cleaned_data["untildate"] is not None:
|
||||
if self.cleaned_data["untildate"] < datetime.date.today():
|
||||
|
||||
@@ -1,42 +1,15 @@
|
||||
{% extends "layout_simple.html" %}
|
||||
{% load i18n %}
|
||||
{% block html_head %}
|
||||
<script src="{{ MEDIA_URL }}js/form.js" type="text/javascript"></script>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="{{ MEDIA_URL }}css/calendar.css" />
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/calendar.js"></script>
|
||||
<style type="text/css">
|
||||
#id_subject {
|
||||
width: 250px;
|
||||
}
|
||||
#id_content {
|
||||
width: 250px;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
window.addEvent("domready", function() {
|
||||
var cal = new Calendar({id_untildate: "Y-m-d"}, {tweak: {x: -100, y:-100}});
|
||||
var form = new Form();
|
||||
|
||||
form.register_error_callback("armform", function() {
|
||||
new Calendar({id_untildate: "Y-m-d"}, {
|
||||
tweak: {x: -100, y:-100}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="title"><h1>{% trans "Auto-reply message" %}</h1></div>
|
||||
|
||||
<form action="{% url modoboa.extensions.postfix_autoreply.views.autoreply %}"
|
||||
method="POST" id="armform" name="armform" class="simple">
|
||||
{% include "common/genericform.html" %}
|
||||
<div class="spacer"></div>
|
||||
|
||||
<div class="lastrow" align="center">
|
||||
<input type="submit" name="submit" value="{% trans 'Update' %}" />
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
<div class="modal-header">
|
||||
<a class="close" data-dismiss="modal">x</a>
|
||||
<h3>{% trans "Auto-reply message" %}</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
{% if error %}<div class="alert alert-error">{{ error }}</div>{% endif %}
|
||||
<form class="form-horizontal" action="{% url modoboa.extensions.postfix_autoreply.views.autoreply %}" method="POST">
|
||||
{% include "common/genericform.html" %}
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#" class="btn btn-primary submit">{% trans "Update" %}</a>
|
||||
<a class="btn" data-dismiss="modal">{% trans "Close" %}</a>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# coding: utf-8
|
||||
from django.http import HttpResponse
|
||||
from django.utils import simplejson
|
||||
from django.contrib.auth.decorators \
|
||||
@@ -14,7 +13,13 @@ from models import *
|
||||
|
||||
@login_required
|
||||
@needs_mailbox()
|
||||
def autoreply(request, tplname="postfix_autoreply/autoreply.html"):
|
||||
def autoreply(request, tplname="common/generic_modal_form.html"):
|
||||
ctx = dict(
|
||||
title=_("Auto-reply message"),
|
||||
action=reverse(autoreply),
|
||||
formid="arform",
|
||||
submit_label=_("Update")
|
||||
)
|
||||
mb = Mailbox.objects.get(user=request.user.id)
|
||||
try:
|
||||
arm = ARmessage.objects.get(mbox=mb.id)
|
||||
@@ -33,15 +38,13 @@ def autoreply(request, tplname="postfix_autoreply/autoreply.html"):
|
||||
arm.untildate = form.cleaned_data["untildate"]
|
||||
arm.mbox = mb
|
||||
arm.save()
|
||||
messages.info(request, _("Auto reply message updated successfully."),
|
||||
fail_silently=True)
|
||||
messages.info(request, _("Auto reply message updated successfully."))
|
||||
return ajax_response(request, url=reverse(userprefs.views.index))
|
||||
return ajax_response(request, status="ko", template=tplname,
|
||||
form=form, error=error)
|
||||
ctx.update(form=form, error=error)
|
||||
return ajax_response(request, status="ko", template=tplname, **ctx)
|
||||
|
||||
form = ARmessageForm(instance=arm)
|
||||
if arm is not None:
|
||||
form.fields['untildate'].initial = arm.untildate
|
||||
return _render(request, tplname, {
|
||||
"form" : form
|
||||
})
|
||||
ctx.update(form=form)
|
||||
return _render(request, tplname, ctx)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# coding: utf-8
|
||||
from django.utils.translation import ugettext_noop as _, ugettext
|
||||
from django.core.urlresolvers import reverse
|
||||
from modoboa.lib import events, parameters
|
||||
@@ -55,7 +55,7 @@ def menu(target, user):
|
||||
{"name" : "sievefilters",
|
||||
"label" : ugettext("Message filters"),
|
||||
"url" : reverse(views.index),
|
||||
"img" : static_url("pics/filters.png")}
|
||||
"img" : "icon-check"}
|
||||
]
|
||||
|
||||
@events.observe("Userlogout")
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
from django import forms
|
||||
from django.http import QueryDict
|
||||
from django.utils.translation import ugettext as _, ugettext_noop
|
||||
from django.forms.widgets import RadioFieldRenderer, RadioSelect, RadioInput
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.html import conditional_escape
|
||||
from django.utils.encoding import force_unicode
|
||||
from modoboa.admin.templatetags.admin_extras import gender
|
||||
|
||||
class FiltersSetForm(forms.Form):
|
||||
@@ -9,17 +13,52 @@ class FiltersSetForm(forms.Form):
|
||||
initial=False,
|
||||
help_text=ugettext_noop("Check to activate this filters set"))
|
||||
|
||||
class CustomRadioInput(RadioInput):
|
||||
def __unicode__(self):
|
||||
return self.render()
|
||||
|
||||
def render(self, name=None, value=None, attrs=None, choices=()):
|
||||
name = name or self.name
|
||||
value = value or self.value
|
||||
attrs = attrs or self.attrs
|
||||
if 'id' in self.attrs:
|
||||
label_for = ' for="%s_%s"' % (self.attrs['id'], self.index)
|
||||
else:
|
||||
label_for = ''
|
||||
choice_label = conditional_escape(force_unicode(self.choice_label))
|
||||
return mark_safe(
|
||||
u'<label%s class="radio inline">%s %s</label>' \
|
||||
% (label_for, self.tag(), choice_label)
|
||||
)
|
||||
|
||||
class CustomRadioFieldRenderer(RadioFieldRenderer):
|
||||
def __iter__(self):
|
||||
for i, choice in enumerate(self.choices):
|
||||
yield CustomRadioInput(self.name, self.value, self.attrs.copy(), choice, i)
|
||||
|
||||
def __getitem__(self, idx):
|
||||
choice = self.choices[idx]
|
||||
return CustomRadioInput(self.name, self.value, self.attrs.copy(), choice, idx)
|
||||
|
||||
def render(self):
|
||||
return mark_safe(u'\n'.join([force_unicode(w) for w in self]))
|
||||
|
||||
class CustomRadioSelect(RadioSelect):
|
||||
renderer = CustomRadioFieldRenderer
|
||||
|
||||
class FilterForm(forms.Form):
|
||||
def __init__(self, conditions, actions, request, *args, **kwargs):
|
||||
super(FilterForm, self).__init__(*args, **kwargs)
|
||||
|
||||
self.fields["name"] = forms.CharField(label=_("Name"))
|
||||
self.fields["match_type"] = forms.ChoiceField(choices=[("allof", _("All of the following")),
|
||||
("anyof", _("Any of the following")),
|
||||
("all", _("All messages"))],
|
||||
initial="anyof",
|
||||
widget=forms.RadioSelect)
|
||||
|
||||
self.fields["match_type"] = forms.ChoiceField(
|
||||
choices=[("allof", _("All of the following")),
|
||||
("anyof", _("Any of the following")),
|
||||
("all", _("All messages"))],
|
||||
initial="anyof",
|
||||
widget=CustomRadioSelect(attrs={"class" : "radio inline"})
|
||||
)
|
||||
|
||||
self.header_operators = [("contains", _("contains"), "string"),
|
||||
("notcontains", _("does not contain"), "string"),
|
||||
("is", _("is"), "string"),
|
||||
|
||||
@@ -42,6 +42,8 @@ class SieveClient(object):
|
||||
self.msc = None
|
||||
|
||||
def refresh(self, user, password):
|
||||
import ssl
|
||||
|
||||
if self.msc is not None:
|
||||
try:
|
||||
self.msc.capability()
|
||||
@@ -51,7 +53,7 @@ class SieveClient(object):
|
||||
return
|
||||
try:
|
||||
ret, msg = self.login(user, password)
|
||||
except Error, e:
|
||||
except (Error, ssl.SSLError), e:
|
||||
raise ConnectionError(e)
|
||||
if not ret:
|
||||
raise ConnectionError(msg)
|
||||
@@ -74,6 +76,8 @@ class SieveClient(object):
|
||||
return fs
|
||||
|
||||
def pushscript(self, name, content, active=False):
|
||||
if type(content) is unicode:
|
||||
content = str(content)
|
||||
if not self.msc.havespace(name, len(content)):
|
||||
error = "%s (%s)" % (_("Not enough space on server"), self.msc.errmsg)
|
||||
raise SieveClientError(error)
|
||||
|
||||
@@ -1,43 +1,6 @@
|
||||
#fsets_list {
|
||||
margin-left: 5px;
|
||||
float: left;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#fset_menu {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
#set_content {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
right: 10px;
|
||||
top: 0px;
|
||||
bottom: 10px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#set_content h1 {
|
||||
padding: 2px 5px;
|
||||
margin: 0;
|
||||
font-size: 1.2em;
|
||||
background: #CEDBEC;
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
}
|
||||
|
||||
#fsets_bar {
|
||||
margin-left: 10px;
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
#set_content textarea {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 2px;
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
#set_content label {
|
||||
@@ -54,14 +17,6 @@
|
||||
bottom: 0px;
|
||||
}
|
||||
|
||||
#feditor {
|
||||
position: absolute;
|
||||
left: 190px;
|
||||
right: 10px;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
}
|
||||
|
||||
#id_content {
|
||||
width: 95% !important;
|
||||
height: 270px;
|
||||
@@ -143,11 +98,6 @@ div.item input, div.item select {
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
#condlist label {
|
||||
margin: 0 !important;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul.errors {
|
||||
list-style: none;
|
||||
display: inline;
|
||||
|
||||
@@ -0,0 +1,328 @@
|
||||
(function($) {
|
||||
var DynamicCondition = function(element, options) {
|
||||
this.$element = $(element);
|
||||
this.options = $.extend({}, $.fn.dyncondition.defaults, options);
|
||||
this.fields_cnt = 1;
|
||||
this.nextid = 1;
|
||||
|
||||
var $addlink = $('<a />', {
|
||||
href: '#',
|
||||
id: this.$element.attr("id") + '_rmbtn',
|
||||
html: '<i class="icon-plus"></i>'
|
||||
});
|
||||
$("select[name*=cond_target_]").change($.proxy(this.target_change, this));
|
||||
$addlink.click($.proxy(this.addfields, this));
|
||||
this.$element.append($addlink);
|
||||
|
||||
for (var cpt = 1; true; cpt++) {
|
||||
var $div = $("#condition_" + cpt);
|
||||
|
||||
if (!$div.length) {
|
||||
break;
|
||||
}
|
||||
$div.append(this.newrmlink());
|
||||
this.nextid++;
|
||||
this.fields_cnt++;
|
||||
}
|
||||
};
|
||||
|
||||
DynamicCondition.prototype = {
|
||||
constructor: DynamicCondition,
|
||||
|
||||
loadoperators: function($container, tpl) {
|
||||
$container.empty();
|
||||
for (var ocpt = 0; ocpt < tpl.operators.length; ocpt++) {
|
||||
var $opt = $("<option />", {
|
||||
value: tpl["operators"][ocpt][0],
|
||||
html: tpl["operators"][ocpt][1]
|
||||
});
|
||||
|
||||
$container.append($opt);
|
||||
}
|
||||
},
|
||||
|
||||
removefields: function(e) {
|
||||
var $link = $(e.target).parent();
|
||||
var id = $link.attr("id");
|
||||
|
||||
e.preventDefault();
|
||||
$("#" + id.replace("_rmbtn", "")).remove();
|
||||
this.fields_cnt--;
|
||||
},
|
||||
|
||||
newrmlink: function() {
|
||||
return $('<a />', {
|
||||
href: '#',
|
||||
id: 'condition_' + this.nextid + '_rmbtn',
|
||||
html: '<i class="icon-remove"></i>'
|
||||
}).click($.proxy(this.removefields, this));
|
||||
},
|
||||
|
||||
addfields: function(e) {
|
||||
e.preventDefault();
|
||||
var $div = $("<div />", {
|
||||
id: "condition_" + this.nextid, 'class': "item"
|
||||
});
|
||||
var $condtarget = $("<select />", {
|
||||
id: "id_cond_target_" + this.nextid,
|
||||
name: "cond_target_" + this.nextid
|
||||
}).change($.proxy(this.target_change, this));
|
||||
var $condoperator = $("<select />", {
|
||||
id: "id_cond_operator_" + this.nextid,
|
||||
name: "cond_operator_" + this.nextid
|
||||
});
|
||||
var $condvalue = $("<input />", {
|
||||
id: "id_cond_value_" + this.nextid,
|
||||
name: "cond_value_" + this.nextid,
|
||||
type: "text"
|
||||
});
|
||||
var $rmlink = this.newrmlink();
|
||||
|
||||
for (var cpt = 0; cpt < this.options.templates.length; cpt++) {
|
||||
var tpl = this.options.templates[cpt];
|
||||
var $opt = $("<option />", {
|
||||
value: tpl.name,
|
||||
html: tpl.label
|
||||
});
|
||||
|
||||
$condtarget.append($opt);
|
||||
if (tpl.name != this.options.defaultcond) {
|
||||
continue;
|
||||
}
|
||||
this.loadoperators($condoperator, tpl);
|
||||
}
|
||||
|
||||
$div.append($condtarget, $condoperator, $condvalue, $rmlink);
|
||||
this.$element.after($div);
|
||||
this.nextid++;
|
||||
this.fields_cnt++;
|
||||
},
|
||||
|
||||
target_change: function(e) {
|
||||
var $target = $(e.target);
|
||||
var parts = $target.attr("name").split("_");
|
||||
var $container = $("#id_cond_operator_" + parts[2]);
|
||||
|
||||
for (var cpt = 0; cpt < this.options.templates.length; cpt++) {
|
||||
var tpl = this.options.templates[cpt];
|
||||
|
||||
if (tpl.name != $target.attr("value")) {
|
||||
continue;
|
||||
}
|
||||
this.loadoperators($container, tpl);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
counter: function() {
|
||||
return this.fields_cnt;
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.dyncondition = function(method) {
|
||||
return this.each(function() {
|
||||
var $this = $(this),
|
||||
data = $this.data('dyncondition'),
|
||||
options = typeof method === "object" && method;
|
||||
|
||||
if (!data) {
|
||||
$this.data('dyncondition', new DynamicCondition(this, options));
|
||||
}
|
||||
if (typeof method === "string") {
|
||||
data[method]();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.dyncondition.defaults = {
|
||||
defaultcond: "Subject",
|
||||
templates: []
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
|
||||
/*
|
||||
* Dynamic actions class
|
||||
*/
|
||||
(function($) {
|
||||
var DynamicAction = function(element, options) {
|
||||
this.$element = $(element);
|
||||
this.options = $.extend({}, $.fn.dynaction.defaults, options);
|
||||
this.nextid = 1;
|
||||
this.fields_cnt = 1;
|
||||
|
||||
var $addlink = $('<a />', {
|
||||
href: '#',
|
||||
id: this.$element.attr("id") + '_rmbtn',
|
||||
html: '<i class="icon-plus"></i>'
|
||||
});
|
||||
$("select[name*=action_name_]").change($.proxy(this.name_change, this));
|
||||
$addlink.click($.proxy(this.addfields, this));
|
||||
this.$element.append($addlink);
|
||||
|
||||
for (var cpt = 1; true; cpt++) {
|
||||
var $div = $("#action_" + cpt);
|
||||
|
||||
if (!$div.length) {
|
||||
break;
|
||||
}
|
||||
$div.append(this.newrmlink());
|
||||
this.nextid++;
|
||||
this.fields_cnt++;
|
||||
}
|
||||
|
||||
$("#id_action_arg_0_0").find("option").each(function() {
|
||||
var $this = $(this),
|
||||
cpt = 1,
|
||||
start = 0,
|
||||
value = $this.attr("value");
|
||||
|
||||
while (true) {
|
||||
var id = value.indexOf(".", start);
|
||||
if (id == -1) {
|
||||
break;
|
||||
}
|
||||
$this.css("margin-left", (cpt * 20) + "px");
|
||||
cpt++;
|
||||
start = id + 1;
|
||||
}
|
||||
});
|
||||
|
||||
this.$fdoptions = $("#id_action_arg_0_0").find("option");
|
||||
};
|
||||
|
||||
DynamicAction.prototype = {
|
||||
constructor: DynamicAction,
|
||||
|
||||
loadargs: function(id, tpl) {
|
||||
var res = [];
|
||||
|
||||
for (var acpt = 0; acpt < tpl.args.length; acpt++) {
|
||||
var argname = "action_arg_" + id + "_" + acpt;
|
||||
var $child = null;
|
||||
|
||||
if (tpl.args[acpt].type == "list") {
|
||||
$child = $("<select />", {id: "id_" + argname, name: argname});
|
||||
if (tpl.args[acpt].vloader != undefined) {
|
||||
this[tpl.args[acpt].vloader]($child);
|
||||
}
|
||||
} else if (tpl.args[acpt].type == "string") {
|
||||
$child = $("<input />", {
|
||||
type: "text",
|
||||
id: "id_" + argname,
|
||||
name: argname
|
||||
});
|
||||
}
|
||||
res.push($child);
|
||||
}
|
||||
return res;
|
||||
},
|
||||
|
||||
deletePrevArgs: function(id) {
|
||||
for (var cpt = 0; true; cpt++) {
|
||||
var $arg = $("#id_action_arg_" + id + "_" + cpt);
|
||||
if (!$arg.length) {
|
||||
break;
|
||||
}
|
||||
$arg.remove();
|
||||
}
|
||||
},
|
||||
|
||||
name_change: function(e) {
|
||||
var $target = $(e.target);
|
||||
var parts = $target.attr("name").split("_");
|
||||
var $pos = $("#action_" + parts[2] + "_rmbtn");
|
||||
|
||||
e.preventDefault();
|
||||
this.deletePrevArgs(parts[2]);
|
||||
for (var cpt = 0; cpt < this.options.templates.length; cpt++) {
|
||||
var tpl = this.options.templates[cpt];
|
||||
if (tpl.name != $target.attr("value")) {
|
||||
continue;
|
||||
}
|
||||
$.each(this.loadargs(parts[2], tpl), function(idx, arg) {
|
||||
$pos.before(arg);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
newrmlink: function() {
|
||||
return $('<a />', {
|
||||
href: '#',
|
||||
id: 'action_' + this.nextid + '_rmbtn',
|
||||
html: '<i class="icon-remove"></i>'
|
||||
}).click($.proxy(this.removefields, this));
|
||||
},
|
||||
|
||||
addfields: function(e) {
|
||||
e.preventDefault();
|
||||
var $div = $("<div />", {id: "action_" + this.nextid, "class": "item"});
|
||||
var $actioname = $("<select />", {
|
||||
id: "id_action_name_" + this.nextid,
|
||||
name: "action_name_" + this.nextid
|
||||
});
|
||||
var $rmlink = this.newrmlink();
|
||||
var args = null;
|
||||
|
||||
for (var cpt = 0; cpt < this.options.templates.length; cpt++) {
|
||||
var tpl = this.options.templates[cpt];
|
||||
var $opt = $("<option />", {
|
||||
value: tpl.name,
|
||||
html: tpl.label
|
||||
});
|
||||
|
||||
$actioname.append($opt);
|
||||
if (tpl.name != this.options.defaultaction) {
|
||||
continue;
|
||||
}
|
||||
args = this.loadargs(this.nextid, tpl);
|
||||
}
|
||||
$div.append($actioname);
|
||||
$actioname.change($.proxy(this.name_change, this));
|
||||
$.each(args, function(idx, element) {
|
||||
$div.append(element);
|
||||
});
|
||||
$div.append($rmlink);
|
||||
this.$element.after($div);
|
||||
this.nextid++;
|
||||
this.fields_cnt++;
|
||||
},
|
||||
|
||||
removefields: function(e) {
|
||||
var $link = $(e.target).parent();
|
||||
var id = $link.attr("id");
|
||||
|
||||
e.preventDefault();
|
||||
$("#" + id.replace("_rmbtn", "")).remove();
|
||||
this.fields_cnt--;
|
||||
},
|
||||
|
||||
userfolders: function($container) {
|
||||
this.$fdoptions.each(function() {
|
||||
$container.append($(this).clone());
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$.fn.dynaction = function(method) {
|
||||
return this.each(function() {
|
||||
var $this = $(this),
|
||||
data = $this.data('dynaction'),
|
||||
options = typeof method === "object" && method;
|
||||
|
||||
if (!data) {
|
||||
$this.data('dynaction', new DynamicAction(this, options));
|
||||
}
|
||||
if (typeof method === "string") {
|
||||
data[method]();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.dynaction.defaults = {
|
||||
defaultaction: "fileinto",
|
||||
templates: [],
|
||||
ufolders_url: null
|
||||
};
|
||||
})(jQuery);
|
||||
@@ -10,41 +10,40 @@ var curscript = null;
|
||||
*
|
||||
*/
|
||||
function removefilter(evt) {
|
||||
evt.stop();
|
||||
evt.preventDefault();
|
||||
if (!confirm(gettext("Remove this filter?"))) {
|
||||
return;
|
||||
}
|
||||
new Request.JSON.mdb({
|
||||
url: this.get("href"),
|
||||
onSuccess: function(response) {
|
||||
var $this = $(this);
|
||||
|
||||
$.ajax({
|
||||
url: $this.attr("href"),
|
||||
dataType: 'json',
|
||||
success: function(response) {
|
||||
if (response.status == "ok") {
|
||||
current_anchor.update(true);
|
||||
infobox.info(response.respmsg);
|
||||
infobox.hide(1);
|
||||
history.update(true);
|
||||
$("body").notify('success', response.respmsg, 2000);
|
||||
} else {
|
||||
infobox.error(response.respmsg);
|
||||
$("body").notify('error', response.respmsg);
|
||||
}
|
||||
}
|
||||
}).get();
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Handler listening for the "change" event on the filters sets list.
|
||||
*/
|
||||
function changefs(evt) {
|
||||
evt.stop();
|
||||
current_anchor.baseurl(this.get("value")).update();
|
||||
evt.preventDefault();
|
||||
history.baseurl($(this).attr("value")).update();
|
||||
}
|
||||
|
||||
/*
|
||||
* Initializes buttons located inside the filters list
|
||||
*/
|
||||
function init_filters_list() {
|
||||
SqueezeBox.assign($("filters_list").getElements('a[class=boxed]'), {
|
||||
parse: 'rel'
|
||||
});
|
||||
$$("a[name=togglestate]").addEvent("click", toggle_filter_state);
|
||||
$$("a[name*=movefilter_]").addEvent("click", move_filter);
|
||||
$("a[name=togglestate]").click(toggle_filter_state);
|
||||
$("a[name*=movefilter_]").click(move_filter);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -53,17 +52,21 @@ function init_filters_list() {
|
||||
* It updates the middle DIV and initializes the user interface.
|
||||
*/
|
||||
function loadfs(response) {
|
||||
curscript = current_anchor.getbaseurl();
|
||||
$("curfset").set("value", curscript);
|
||||
$("set_content").set("html", response.content);
|
||||
parse_menubar("fset_menu");
|
||||
if ($defined($("filters_list"))) {
|
||||
curscript = history.getbaseurl();
|
||||
$("#curfset").attr("value", curscript);
|
||||
$("#set_content").html(response.content);
|
||||
|
||||
if ($("#filters_list") != undefined) {
|
||||
init_filters_list();
|
||||
}
|
||||
$$("a[name=removefilter]").addEvent("click", removefilter);
|
||||
$$("a[name=activatefs]").addEvent("click", activatefs);
|
||||
$$("a[name=savefs]").addEvent("click", savefs);
|
||||
$$("a[name=removefs]").addEvent("click", removefs);
|
||||
if ($("#fsetmenu").length) {
|
||||
$("#fsetmenu").remove();
|
||||
}
|
||||
$("#menu").after($(response.menu));
|
||||
$("a[name=removefilter]").click(removefilter);
|
||||
$("a[name=activatefs]").click(activatefs);
|
||||
$("a[name=savefs]").click(savefs);
|
||||
$("a[name=removefs]").click(removefs);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -72,25 +75,23 @@ function loadfs(response) {
|
||||
* (remove, activate)
|
||||
*/
|
||||
function send_command(cmd, extracb) {
|
||||
new Request.JSON.mdb({
|
||||
$.ajax({
|
||||
url: cmd,
|
||||
onSuccess: function(response) {
|
||||
dataType: 'json',
|
||||
success: function(response) {
|
||||
if (response.status == "ko") {
|
||||
infobox.calcsize(300);
|
||||
infobox.error(response.respmsg);
|
||||
$("body").notify('error', response.respmsg);
|
||||
} else {
|
||||
if ($defined(extracb)) {
|
||||
extracb();
|
||||
if (extracb != undefined) {
|
||||
extracb(response);
|
||||
}
|
||||
if (!response.norefresh) {
|
||||
current_anchor.update(true);
|
||||
history.update(true);
|
||||
}
|
||||
infobox.calcsize();
|
||||
infobox.info(response.respmsg);
|
||||
infobox.hide(2);
|
||||
$("body").notify('success', response.respmsg, 2000);
|
||||
}
|
||||
}
|
||||
}).get();
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -98,11 +99,11 @@ function send_command(cmd, extracb) {
|
||||
* validate any new asked action. (activate, save, remove)
|
||||
*/
|
||||
function check_prereqs(evt, msg) {
|
||||
evt.stop();
|
||||
evt.preventDefault();
|
||||
if (!curscript) {
|
||||
return false;
|
||||
}
|
||||
if ($defined(msg) && !confirm(msg)) {
|
||||
if (msg != undefined && !confirm(msg)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -116,21 +117,21 @@ function savefs(evt) {
|
||||
if (!check_prereqs(evt, gettext("Save changes?"))) {
|
||||
return;
|
||||
}
|
||||
new Request.JSON.mdb({
|
||||
url: $("feditor").get("action"),
|
||||
method: $("feditor").get("method"),
|
||||
data: $("feditor").toQueryString(),
|
||||
onSuccess: function(response) {
|
||||
var $editor = $("#feditor");
|
||||
|
||||
$.ajax({
|
||||
url: $editor.attr("action"),
|
||||
type: $editor.attr("method"),
|
||||
dataType: 'json',
|
||||
data: $editor.serialize(),
|
||||
success: function(response) {
|
||||
if (response.status == "ko") {
|
||||
infobox.calcsize(300);
|
||||
infobox.error(response.respmsg);
|
||||
$("body").notify('error', response.respmsg);
|
||||
} else {
|
||||
infobox.calcsize();
|
||||
infobox.info(response.respmsg);
|
||||
infobox.hide(2);
|
||||
$("body").notify('success', response.respmsg, 2000);
|
||||
}
|
||||
}
|
||||
}).send();
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -143,14 +144,11 @@ function removefs(evt) {
|
||||
if (!check_prereqs(evt, gettext("Remove filters set?"))) {
|
||||
return;
|
||||
}
|
||||
send_command(this.get("href"), function() {
|
||||
$("curfset").getElements("option[value=" + curscript + "]").destroy();
|
||||
if (!$("curfset").getElements("option[value=" + curscript + "]").length) {
|
||||
current_anchor.reset().update();
|
||||
location.reload();
|
||||
} else {
|
||||
current_anchor.reset();
|
||||
}
|
||||
send_command($(this).attr("href"), function(response) {
|
||||
var $curfset = $("#curfset");
|
||||
|
||||
$curfset.find("option[value=" + curscript + "]").remove();
|
||||
history.baseurl(response.newfs, 1);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -158,46 +156,105 @@ function removefs(evt) {
|
||||
* Activate the current filters set.
|
||||
*/
|
||||
function activatefs(evt) {
|
||||
var $this = $(this);
|
||||
|
||||
if (!check_prereqs(evt, gettext("Activate this filters set?"))) {
|
||||
return;
|
||||
}
|
||||
send_command(
|
||||
this.get("href"),
|
||||
function() {
|
||||
$("curfset").getElements("option").each(function(item) {
|
||||
if (item.get("value") == curscript) {
|
||||
item.set("html", curscript + " (" + gettext("active") + ")");
|
||||
} else {
|
||||
item.set("html", item.get("value"));
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
send_command($this.attr("href"), function(response) {
|
||||
$("#curfset").find("option").each(function(index, element) {
|
||||
var $element = $(element);
|
||||
|
||||
($element.attr("value") == curscript)
|
||||
? $element.html(curscript + " (" + gettext("active") + ")")
|
||||
: $element.html($element.attr("value"));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable/Disable a specific filter
|
||||
*/
|
||||
function toggle_filter_state(event) {
|
||||
event.stop();
|
||||
new Request.JSON.mdb({
|
||||
url: this.get("href"),
|
||||
onSuccess: function(response) {
|
||||
var $this = $(this);
|
||||
|
||||
event.preventDefault();
|
||||
$.ajax({
|
||||
url: $this.attr("href"),
|
||||
dataType: 'json',
|
||||
success: function(response) {
|
||||
if (response.status == "ok") {
|
||||
this.set("html", response.label);
|
||||
this.set("class", "");
|
||||
this.addClass(response.color);
|
||||
$this.html(response.label);
|
||||
$this.attr("class", "");
|
||||
$this.addClass(response.color);
|
||||
} else {
|
||||
infobox.error(respmsg.respmsg);
|
||||
$("body").notify('error', response.respmsg);
|
||||
}
|
||||
}.bind(this)
|
||||
}).get();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function move_filter(event) {
|
||||
event.stop();
|
||||
new Request.JSON.mdb({
|
||||
url: this.get("href"),
|
||||
onSuccess: function(response) {
|
||||
$("filters_list").set("html", response.content);
|
||||
var $this = $(this);
|
||||
|
||||
event.preventDefault();
|
||||
$.ajax({
|
||||
url: $this.attr('href'),
|
||||
dataType: 'json',
|
||||
success: function(response) {
|
||||
$("#set_content").html(response.content);
|
||||
init_filters_list();
|
||||
}
|
||||
}).get();
|
||||
});
|
||||
}
|
||||
|
||||
function filterset_created(data) {
|
||||
var name = data.url;
|
||||
var option = $('<option value="' + name + '">' + name + '</option>');
|
||||
var curfset = $(parent.document).find("#curfset");
|
||||
|
||||
curfset.append(option);
|
||||
curfset.attr("value", name);
|
||||
|
||||
if ($("#id_active").checked) {
|
||||
curfset.find("option").each(function(index, element) {
|
||||
var $element = $(element);
|
||||
|
||||
if ($element.attr("value") == name) {
|
||||
$element.html(name + " (" + gettext("active") + ")");
|
||||
} else {
|
||||
$element.html($element.attr("value"));
|
||||
}
|
||||
});
|
||||
}
|
||||
history.baseurl(data.url, 1).update(1);
|
||||
}
|
||||
|
||||
function filtersetform_cb() {
|
||||
$(".submit").one('click', function(e) {
|
||||
simple_ajax_form_post(e, {
|
||||
reload_on_success: false,
|
||||
error_cb: filtersetform_cb,
|
||||
success_cb: filterset_created
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* From here: specific functions used by the user-friendly form to
|
||||
* create/edit filters.
|
||||
*/
|
||||
function fetch_templates(url, container) {
|
||||
if (container) {
|
||||
return container;
|
||||
}
|
||||
var result;
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
async: false,
|
||||
dataType: 'json',
|
||||
success: function(data) { result = data; }
|
||||
});
|
||||
return result;
|
||||
}
|
||||
@@ -1,96 +1,23 @@
|
||||
{% extends "layout_simple.html" %}
|
||||
{% load i18n sfilters_tags %}
|
||||
{% block html_head %}
|
||||
{{ block.super }}
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/form.js"></script>
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/dynamic_textinput.js"></script>
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}sievefilters/js/dynamic_fields.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}sievefilters/css/style.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
var cond_templates = null;
|
||||
var action_templates = null;
|
||||
var da = null;
|
||||
var dc = null;
|
||||
|
||||
function matchtype_cb(event) {
|
||||
if (this.get("value") == "all") {
|
||||
$$("#condlist div[class=item]").slide("out");
|
||||
} else {
|
||||
$("hide").setStyle("display", "block");
|
||||
$$("#condlist div[class=item]").slide("in");
|
||||
}
|
||||
}
|
||||
|
||||
function initform() {
|
||||
var clist = $$("select[name*=cond_target_]");
|
||||
var alist = $$("select[name*=action_name_]");
|
||||
|
||||
dc = new DynamicCondition(clist, {
|
||||
templates: cond_templates,
|
||||
parentContainer: $("condlist")
|
||||
});
|
||||
da = new DynamicAction(alist, {
|
||||
templates: action_templates,
|
||||
ufolders_url: "{% url modoboa.extensions.sievefilters.views.get_user_folders %}"
|
||||
});
|
||||
|
||||
clist.addEvent("change", dc.onTargetChange.bind(dc));
|
||||
alist.addEvent("change", da.onNameChange.bind(da));
|
||||
|
||||
$$("input[name=match_type]").addEvent("click", matchtype_cb);
|
||||
}
|
||||
|
||||
$(document).addEvent("domready", function() {
|
||||
var form = new Form();
|
||||
|
||||
new Request.JSON({
|
||||
url: "{% url modoboa.extensions.sievefilters.views.get_templates 'condition' %}",
|
||||
onSuccess: function(response) {
|
||||
cond_templates = response;
|
||||
}
|
||||
}).get();
|
||||
new Request.JSON({
|
||||
url: "{% url modoboa.extensions.sievefilters.views.get_templates 'action' %}",
|
||||
onSuccess: function(response) {
|
||||
action_templates = response;
|
||||
initform();
|
||||
}
|
||||
}).get();
|
||||
form.register_error_callback("filterform", initform);
|
||||
form.register_extra_data_callback("filterform", function() {
|
||||
return "conds=" + dc.fields_cnt + "&actions=" + da.fields_cnt;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="title"><h1>{{ title }}</h1></div>
|
||||
<form action="{{ actionurl }}" method="POST" id="filterform" name="filterform">
|
||||
{% extends "common/generic_modal_form.html" %}
|
||||
{% load i18n libextras sfilters_tags %}
|
||||
{% block formbody %}
|
||||
{% if oldname %}<input type="hidden" name="oldname" value="{{ oldname }}" />{% endif %}
|
||||
<label for="id_{{ form.name.html_name }}">{% trans form.name.label %}</label>:
|
||||
{{ form.name }}{% display_errors form.name.errors %}
|
||||
<h2>{% trans "Conditions" %}</h2>
|
||||
{% render_field form.name %}
|
||||
<h6>{% trans "Conditions" %}</h6>
|
||||
<div id="condlist">
|
||||
<div id="matchtype">
|
||||
<label>{% trans "Match type" %}:</label>
|
||||
{{ form.match_type }}{% display_errors form.match_type.errors %}
|
||||
<div class="spacer"></div>
|
||||
{% render_field form.match_type %}
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
<div id="hide" style="display:{{ hidestyle }}">
|
||||
{% for ec in conds_nb %}
|
||||
{% display_condition form ec %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<h2>{% trans "Actions" %}</h2>
|
||||
<h6>{% trans "Actions" %}</h6>
|
||||
<div id="actionlist">
|
||||
{% for ea in actions_nb %}
|
||||
{% display_action form ea %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<input type="submit" id="submit" name="submit" value='{% trans "Save" %}' />
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
{% load i18n sfilters_tags %}
|
||||
<h1>{% trans "Filters" %}</h1>
|
||||
<p>
|
||||
{% if fs.filters %}
|
||||
<table>
|
||||
<tr>
|
||||
<th width="10%">{% trans "Actions" %}</th>
|
||||
<th>{% trans "Name" %}</th>
|
||||
<th width="5%">{% trans "Active" %}</th>
|
||||
</tr>
|
||||
{% for filter in fs.filters %}
|
||||
<tr class="{% cycle 'odd' 'even' %}">
|
||||
<td>{% filter_actions fs.name filter forloop.counter forloop.last %}</td>
|
||||
<td>{{ filter.name }}</td>
|
||||
<td>
|
||||
<a name="togglestate"
|
||||
class={% if filter.enabled %}"green"{% else %}"red"{% endif %}
|
||||
href="{% url modoboa.extensions.sievefilters.views.toggle_filter_state fs.name filter.name %}">
|
||||
{{ filter.enabled|yesno }}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
<div class="info">{% trans "No filter defined yet" %}</div>
|
||||
{% endif %}
|
||||
</p>
|
||||
@@ -1,8 +1,25 @@
|
||||
{% load sfilters_tags i18n %}
|
||||
<div id="fset_menu" class="leftbox">
|
||||
<h1>{% trans "Actions" %}</h1>
|
||||
{% fset_menu "gui" fs.name %}
|
||||
</div>
|
||||
<div id="filters_list">
|
||||
{% include "sievefilters/filters.html" %}
|
||||
</div>
|
||||
{% load i18n sfilters_tags %}
|
||||
{% if fs.filters %}
|
||||
<table class="table table-striped table-bordered">
|
||||
<tr>
|
||||
<th width="10%">{% trans "Actions" %}</th>
|
||||
<th>{% trans "Name" %}</th>
|
||||
<th width="5%">{% trans "Active" %}</th>
|
||||
</tr>
|
||||
{% for filter in fs.filters %}
|
||||
<tr>
|
||||
<td>{% filter_actions fs.name filter forloop.counter forloop.last %}</td>
|
||||
<td>{{ filter.name }}</td>
|
||||
<td>
|
||||
<a name="togglestate"
|
||||
class={% if filter.enabled %}"green"{% else %}"red"{% endif %}
|
||||
href="{% url modoboa.extensions.sievefilters.views.toggle_filter_state fs.name filter.name %}">
|
||||
{{ filter.enabled|yesno }}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
<div class="alert alert-info">{% trans "No filter defined yet" %}</div>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,41 +1,77 @@
|
||||
{% extends "nlayout.html" %}
|
||||
{% load i18n libextras sfilters_tags %}
|
||||
{% extends "twocols.html" %}
|
||||
{% load i18n sfilters_tags %}
|
||||
{% block html_head %}
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/anchor_nav.js"></script>
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}sievefilters/js/lib.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}sievefilters/css/style.css" />
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/history.js"></script>
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}sievefilters/js/lib.js"></script>
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/dynamic_input.js"></script>
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}sievefilters/js/jquery.dynfields.js"></script>
|
||||
<script type="text/javascript">
|
||||
var current_anchor = new AnchorNavigation("{{ default_script }}", {
|
||||
var history = new History({
|
||||
deflocation: "{{ default_script }}",
|
||||
defcallback: loadfs
|
||||
});
|
||||
var cond_templates = null;
|
||||
var action_templates = null;
|
||||
|
||||
$(document).addEvent("domready", function() {
|
||||
$("curfset").addEvent("change", changefs);
|
||||
function filterform_cb() {
|
||||
cond_templates = fetch_templates("{% url modoboa.extensions.sievefilters.views.get_templates 'condition' %}", cond_templates);
|
||||
action_templates = fetch_templates("{% url modoboa.extensions.sievefilters.views.get_templates 'action' %}", action_templates);
|
||||
|
||||
var $dc = $("#condition_0").dyncondition({
|
||||
templates: cond_templates
|
||||
}).data('dyncondition');
|
||||
var $da = $("#action_0").dynaction({
|
||||
templates: action_templates,
|
||||
ufolders_url: "{% url modoboa.extensions.sievefilters.views.get_user_folders %}"
|
||||
}).data('dynaction');
|
||||
|
||||
$("input[name=match_type]").click(function(e) {
|
||||
if ($(this).attr("value") == "all") {
|
||||
$("div[id*=condition]").hide();
|
||||
} else {
|
||||
$("div[id*=condition]").show();
|
||||
}
|
||||
});
|
||||
|
||||
$(".submit").one('click', function(e) {
|
||||
var counters = "conds=" + $dc.fields_cnt + "&actions=" + $da.fields_cnt;
|
||||
|
||||
simple_ajax_form_post(e, {
|
||||
error_cb: filterform_cb,
|
||||
reload_mode: 'history',
|
||||
extradata: counters
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$("#curfset").change(changefs);
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block middletitle %}{% trans "Message filters" %}{% endblock %}
|
||||
{% block menu %}
|
||||
<div id="fsets_list">
|
||||
<label>{% trans "Filters sets" %}</label>
|
||||
<select id="curfset">
|
||||
{% if active_script %}
|
||||
<option value="{{ active_script }}">{{ active_script }} ({% trans "active" %})</option>
|
||||
{% endif %}
|
||||
{% for script in scripts %}
|
||||
<option value="{{ script }}">{{ script }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% block leftcol %}
|
||||
<div class="well sidebar-nav">
|
||||
<ul id="menu" class="nav nav-list">
|
||||
<li class="nav-header">{% trans "Filter sets" %}</li>
|
||||
<li>
|
||||
<select id="curfset" class="span2">
|
||||
{% if active_script %}
|
||||
<option value="{{ active_script }}">{{ active_script }} ({% trans "active" %})</option>
|
||||
{% endif %}
|
||||
{% for script in scripts %}
|
||||
<option value="{{ script }}">{{ script }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</li>
|
||||
{% sfilters_menu user %}
|
||||
</ul>
|
||||
</div>
|
||||
<ul>{% sfilters_menu user %}</ul>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
{% if messages %}
|
||||
{% display_messages messages %}
|
||||
{% endif %}
|
||||
{% block apparea %}
|
||||
<div id="set_content">
|
||||
{% if not active_script and not scripts %}
|
||||
<div class="info">{% trans "No filters set defined yet. You must create one in order to define filters." %}</div>
|
||||
<div class="alert alert-info">{% trans "No filters set defined yet. You must create one in order to define filters." %}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
{% extends "layout_simple.html" %}
|
||||
{% load i18n %}
|
||||
{% block html_head %}
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}sievefilters/css/style.css" />
|
||||
<script src="{{ MEDIA_URL }}js/form.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).addEvent("domready", function() {
|
||||
var form = new Form();
|
||||
|
||||
form.register_success_callback("newfiltersset", function(response) {
|
||||
var name = response.url;
|
||||
var option = new Element("option", {value: name, html: name});
|
||||
var curfset = $(parent.document).getElementById("curfset");
|
||||
|
||||
option.inject(curfset);
|
||||
curfset.set("value", name);
|
||||
if ($("id_active").checked) {
|
||||
curfset.getElements("option").each(function(item) {
|
||||
if (item.get("value") == name) {
|
||||
item.set("html", name + " (" + gettext("active") + ")");
|
||||
} else {
|
||||
item.set("html", item.get("value"));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="title"><h1>{{ title }}</h1></div>
|
||||
{% if error %}<div id="error" class="error">{{ error }}</div>{% endif %}
|
||||
<form action="{% url modoboa.extensions.sievefilters.views.new_filters_set %}"
|
||||
method="POST" id="{{ fname }}" name="{{ fname }}">
|
||||
{% include "common/genericform.html" %}
|
||||
<div id="submit_container">
|
||||
<input type="submit" name="submit" value='{{ submit_label }}'/>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -1,8 +1,3 @@
|
||||
{% load i18n sfilters_tags %}
|
||||
<div id="fset_menu" class="leftbox">
|
||||
<h1>{% trans "Actions" %}</h1>
|
||||
{% fset_menu "raw" name %}
|
||||
</div>
|
||||
<form action="{% url modoboa.extensions.sievefilters.views.savefs name %}"
|
||||
method="POST" id="feditor" name="feditor">
|
||||
<textarea id="scriptcontent" name="scriptcontent">{{ scriptcontent }}</textarea>
|
||||
|
||||
@@ -2,7 +2,6 @@ from django import template
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.core.urlresolvers import reverse
|
||||
from modoboa.extensions.sievefilters import views
|
||||
from modoboa.lib.webutils import render_actions
|
||||
|
||||
register = template.Library()
|
||||
@@ -13,11 +12,11 @@ from modoboa.lib.webutils import static_url
|
||||
def sfilters_menu(user):
|
||||
entries = [
|
||||
{"name" : "newfilterset",
|
||||
"img" : static_url("pics/add.png"),
|
||||
"img" : "icon-plus",
|
||||
"label" : _("New filters set"),
|
||||
"url" : reverse(views.new_filters_set),
|
||||
"class" : "boxed",
|
||||
"rel" : "{handler:'iframe',size:{x:300,y:170}}"
|
||||
"url" : reverse("modoboa.extensions.sievefilters.views.new_filters_set"),
|
||||
"modal" : True,
|
||||
"modalcb" : "filtersetform_cb"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -30,65 +29,74 @@ def fset_menu(mode, setname):
|
||||
if mode == "gui":
|
||||
entries += [
|
||||
{"name" : "newfilter",
|
||||
"img" : static_url("pics/add.png"),
|
||||
"img" : "icon-plus",
|
||||
"label" : _("New filter"),
|
||||
"url" : reverse(views.newfilter, args=[setname]),
|
||||
"class" : "boxed",
|
||||
"rel" : "{handler:'iframe',size:{x:700,y:400}}"},
|
||||
|
||||
"url" : reverse("modoboa.extensions.sievefilters.views.newfilter",
|
||||
args=[setname]),
|
||||
"modal" : True,
|
||||
"autowidth" : True,
|
||||
"modalcb" : "filterform_cb"}
|
||||
]
|
||||
if mode == "raw":
|
||||
entries += [
|
||||
{"name" : "savefs",
|
||||
"img" : static_url("pics/save.png"),
|
||||
"img" : "icon-download-alt",
|
||||
"label" : _("Save filters set"),
|
||||
"url" : reverse(views.savefs, args=[setname])},
|
||||
"url" : reverse("modoboa.extensions.sievefilters.views.savefs",
|
||||
args=[setname])},
|
||||
]
|
||||
|
||||
entries += [
|
||||
{"name" : "activatefs",
|
||||
"img" : static_url("pics/active.png"),
|
||||
"img" : "icon-ok",
|
||||
"label" : _("Activate filters set"),
|
||||
"url" : reverse(views.activate_filters_set, args=[setname])},
|
||||
"url" : reverse("modoboa.extensions.sievefilters.views.activate_filters_set",
|
||||
args=[setname])},
|
||||
{"name" : "removefs",
|
||||
"img" : static_url("pics/remove.png"),
|
||||
"img" : "icon-remove",
|
||||
"label" : _("Remove filters set"),
|
||||
"url" : reverse(views.remove_filters_set, args=[setname])},
|
||||
"url" : reverse("modoboa.extensions.sievefilters.views.remove_filters_set",
|
||||
args=[setname])},
|
||||
{"name" : "downloadfs",
|
||||
"img" : static_url("pics/download.png"),
|
||||
"img" : "icon-download",
|
||||
"label" : _("Download"),
|
||||
"url" : reverse(views.download_filters_set, args=[setname])}
|
||||
"url" : reverse("modoboa.extensions.sievefilters.views.download_filters_set",
|
||||
args=[setname])}
|
||||
]
|
||||
|
||||
return render_to_string('common/menu.html',
|
||||
return render_to_string('common/menulist.html',
|
||||
{"entries" : entries})
|
||||
|
||||
@register.simple_tag
|
||||
def filter_actions(setname, f, position, islast):
|
||||
actions = [
|
||||
{"name" : "editfilter",
|
||||
"url" : reverse(views.editfilter, args=[setname, f["name"]]),
|
||||
"img" : static_url("pics/edit.png"),
|
||||
"url" : reverse("modoboa.extensions.sievefilters.views.editfilter",
|
||||
args=[setname, f["name"]]),
|
||||
"img" : "icon-edit",
|
||||
"title" : _("Edit filter"),
|
||||
"class" : "boxed",
|
||||
"rel" : "{handler:'iframe',size:{x:650,y:400}}"},
|
||||
"modal" : True,
|
||||
"modalcb" : "filterform_cb"},
|
||||
{"name" : "removefilter",
|
||||
"url" : reverse(views.removefilter, args=[setname, f["name"]]),
|
||||
"img" : static_url("pics/remove.png"),
|
||||
"url" : reverse("modoboa.extensions.sievefilters.views.removefilter",
|
||||
args=[setname, f["name"]]),
|
||||
"img" : "icon-remove",
|
||||
"title" : _("Remove this filter")}
|
||||
]
|
||||
if position != 1:
|
||||
actions += [
|
||||
{"name" : "movefilter_up",
|
||||
"url" : reverse(views.move_filter_up, args=[setname, f["name"]]),
|
||||
"img" : static_url("pics/moveup.png"),
|
||||
"url" : reverse("modoboa.extensions.sievefilters.views.move_filter_up",
|
||||
args=[setname, f["name"]]),
|
||||
"img" : "icon-arrow-up",
|
||||
"title" : _("Move this filter up")}
|
||||
]
|
||||
if not islast:
|
||||
actions += [
|
||||
{"name" : "movefilter_down",
|
||||
"url" : reverse(views.move_filter_down, args=[setname, f["name"]]),
|
||||
"img" : static_url("pics/movedown.png"),
|
||||
"url" : reverse("modoboa.extensions.sievefilters.views.move_filter_down",
|
||||
args=[setname, f["name"]]),
|
||||
"img" : "icon-arrow-down",
|
||||
"title" : _("Move this filter down")},
|
||||
]
|
||||
return render_actions(actions)
|
||||
@@ -114,11 +122,12 @@ def display_condition(form, cnt):
|
||||
operator = form["cond_operator_%d" % cnt]
|
||||
value = form["cond_value_%d" % cnt]
|
||||
t = template.Template("""
|
||||
<div class="item">
|
||||
<div id="condition_{{ idx }}" class="item">
|
||||
{{ tfield }}{{ofield}}{{ vfield }}{{ verrors }}
|
||||
</div>
|
||||
""")
|
||||
return t.render(template.Context({
|
||||
"idx" : cnt,
|
||||
"tfield" : target,
|
||||
"ofield" : operator,
|
||||
"vfield" : value,
|
||||
@@ -140,11 +149,12 @@ def display_action(form, cnt):
|
||||
except KeyError:
|
||||
break
|
||||
t = template.Template("""
|
||||
<div class="item">
|
||||
<div id="action_{{ idx }}" class="item">
|
||||
{{ afield }}{% for v in values %}{{ v }}{% endfor %}{{ verrors }}
|
||||
</div>
|
||||
""")
|
||||
return t.render(template.Context({
|
||||
"idx" : cnt,
|
||||
"afield" : action, "values" : values,
|
||||
"verrors" : display_errors(verrors)
|
||||
}))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# coding: utf-8
|
||||
from sievelib.managesieve import Error
|
||||
from django.http import HttpResponse
|
||||
from django.template.loader import render_to_string
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.core.urlresolvers import reverse
|
||||
@@ -12,6 +13,7 @@ from modoboa.lib.connections import ConnectionError
|
||||
from modoboa.auth.lib import get_password
|
||||
from lib import *
|
||||
from forms import *
|
||||
from templatetags.sfilters_tags import fset_menu
|
||||
|
||||
@login_required
|
||||
@needs_mailbox()
|
||||
@@ -26,6 +28,7 @@ def index(request, tplname="sievefilters/index.html"):
|
||||
active_script, scripts = sc.listscripts()
|
||||
except Error, e:
|
||||
return _render_error(request, user_context={"error" : e})
|
||||
|
||||
if active_script is None:
|
||||
active_script = ""
|
||||
default_script = "%s/" % scripts[0] if len(scripts) else ""
|
||||
@@ -73,10 +76,18 @@ def getfs(request, name):
|
||||
return ajax_response(request, "ko", respmsg=error)
|
||||
|
||||
if editormode == "raw":
|
||||
return ajax_response(request, template="sievefilters/rawfilter.html",
|
||||
name=name, scriptcontent=content)
|
||||
return ajax_response(request, template="sievefilters/guieditor.html",
|
||||
fs=content)
|
||||
htmlcontent = render_to_string("sievefilters/rawfilter.html", dict(
|
||||
name=name, scriptcontent=content
|
||||
))
|
||||
else:
|
||||
htmlcontent = render_to_string("sievefilters/guieditor.html", dict(
|
||||
fs=content
|
||||
))
|
||||
|
||||
menu = '<ul id="fsetmenu" class="nav nav-list"><li class="nav-header">%s</li>%s</ul>' % \
|
||||
(_("Actions"), fset_menu(editormode, name))
|
||||
resp = dict(status="ok", menu=menu, content=htmlcontent)
|
||||
return ajax_simple_response(resp)
|
||||
|
||||
def build_filter_ctx(ctx, form):
|
||||
ctx["form"] = form
|
||||
@@ -111,8 +122,11 @@ def submitfilter(request, setname, okmsg, tplname, tplctx, update=False, sc=None
|
||||
@login_required
|
||||
@needs_mailbox()
|
||||
def newfilter(request, setname, tplname="sievefilters/filter.html"):
|
||||
ctx = {"title" : _("New filter"),
|
||||
"actionurl" : reverse(newfilter, args=[setname])}
|
||||
ctx = dict(
|
||||
title=_("New filter"),
|
||||
action=reverse(newfilter, args=[setname]),
|
||||
submit_label=_("Create")
|
||||
)
|
||||
if request.method == "POST":
|
||||
return submitfilter(request, setname, _("Filter created"), tplname, ctx)
|
||||
|
||||
@@ -124,9 +138,12 @@ def newfilter(request, setname, tplname="sievefilters/filter.html"):
|
||||
|
||||
@login_required
|
||||
@needs_mailbox()
|
||||
def editfilter(request, setname, fname, tplname="sievefilters/filter.html"):
|
||||
ctx = {"title" : _("Edit filter"),
|
||||
"actionurl" : reverse(editfilter, args=[setname, fname])}
|
||||
def editfilter(request, setname, fname, tplname="sievefilters/filter2.html"):
|
||||
ctx = dict(
|
||||
title=_("Edit filter"),
|
||||
action=reverse(editfilter, args=[setname, fname]),
|
||||
submit_label=_("Update")
|
||||
)
|
||||
sc = SieveClient(user=request.user.username,
|
||||
password=request.session["password"])
|
||||
if request.method == "POST":
|
||||
@@ -169,10 +186,11 @@ def savefs(request, name):
|
||||
|
||||
@login_required
|
||||
@needs_mailbox()
|
||||
def new_filters_set(request, tplname="sievefilters/newfiltersset.html"):
|
||||
def new_filters_set(request, tplname="common/generic_modal_form.html"):
|
||||
ctx = {"title" : _("Create a new filters set"),
|
||||
"fname" : "newfiltersset",
|
||||
"formid" : "newfiltersset",
|
||||
"submit_label" : _("Create"),
|
||||
"action" : reverse(new_filters_set),
|
||||
"withmenu" : False,
|
||||
"withunseen" : False}
|
||||
if request.method == "POST":
|
||||
@@ -206,8 +224,11 @@ def remove_filters_set(request, name):
|
||||
try:
|
||||
sc.deletescript(name)
|
||||
except SieveClientError, e:
|
||||
return ajax_response(request, "ko", respmsg=str(e))
|
||||
return ajax_response(request, respmsg=_("Filters set deleted"))
|
||||
return ajax_simple_response(dict(status="ko", respmsg=str(e)))
|
||||
acs, scripts = sc.listscripts()
|
||||
return ajax_simple_response(dict(
|
||||
status="ok", respmsg=_("Filters set deleted"), newfs=acs
|
||||
))
|
||||
|
||||
@login_required
|
||||
@needs_mailbox()
|
||||
@@ -272,7 +293,7 @@ def move_filter(request, setname, fname, direction):
|
||||
sc.pushscript(setname, str(fset))
|
||||
except (SieveClientError), e:
|
||||
return ajax_response(request, "ko", respmsg=str(e))
|
||||
return ajax_response(request, template="sievefilters/filters.html", fs=fset)
|
||||
return ajax_response(request, template="sievefilters/guieditor.html", fs=fset)
|
||||
|
||||
@login_required
|
||||
@needs_mailbox()
|
||||
|
||||
@@ -5,7 +5,7 @@ from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext as _, ugettext_noop
|
||||
from django.utils import simplejson
|
||||
from modoboa.lib.webutils import _render, _render_to_string, getctx
|
||||
from modoboa.admin.lib import check_domain_access
|
||||
from modoboa.lib.permissions import check_domain_access
|
||||
from modoboa.admin.models import Domain, Mailbox
|
||||
from django.contrib.auth.decorators \
|
||||
import login_required, user_passes_test, permission_required
|
||||
|
||||
@@ -13,8 +13,6 @@ import inspect
|
||||
import re
|
||||
|
||||
events = [
|
||||
"SuperAdminPromotion",
|
||||
|
||||
"CanCreate",
|
||||
|
||||
"CreateDomain",
|
||||
@@ -30,17 +28,22 @@ events = [
|
||||
"MailboxAliasCreated",
|
||||
"MailboxAliasDeleted",
|
||||
|
||||
"DomainAdminCreated",
|
||||
"AccountCreated",
|
||||
"AccountModified",
|
||||
"AccountDeleted",
|
||||
"DomainAdminActions",
|
||||
"DomainAdminDeleted",
|
||||
|
||||
"PasswordChange",
|
||||
|
||||
"UserMenuDisplay",
|
||||
"AdminMenuDisplay",
|
||||
"GetStaticContent",
|
||||
|
||||
"ExtraAccountForm",
|
||||
"CheckExtraAccountForm",
|
||||
"FillAccountInstances",
|
||||
|
||||
"PermsGetTables",
|
||||
"PermsGetClass",
|
||||
"GetExtraRoles",
|
||||
|
||||
"ExtEnabled",
|
||||
"ExtDisabled",
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
# coding: utf-8
|
||||
import re
|
||||
from django.utils.translation import ugettext as _
|
||||
from django import forms
|
||||
from django.forms.widgets import MultiWidget, TextInput
|
||||
from django.forms.fields import MultiValueField
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
class CreationWizard(object):
|
||||
def __init__(self, done_cb):
|
||||
self.steps = []
|
||||
self.done_cb = done_cb
|
||||
|
||||
def add_step(self, cls, buttons, new_args=None):
|
||||
self.steps += [dict(cls=cls, buttons=buttons, new_args=new_args)]
|
||||
|
||||
def create_forms(self, data=None):
|
||||
for step in self.steps:
|
||||
args = []
|
||||
if step.has_key("new_args") and step["new_args"]:
|
||||
args += step["new_args"]
|
||||
if data:
|
||||
args.append(data)
|
||||
step["form"] = step["cls"](*args)
|
||||
|
||||
def validate_step(self, request):
|
||||
stepid = request.POST.get("stepid", None)
|
||||
if stepid is None:
|
||||
return -1, _("Invalid request")
|
||||
|
||||
stepid = stepid.replace("step", "")
|
||||
stepid = int(stepid) - 1
|
||||
if stepid < 0 or stepid >= len(self.steps):
|
||||
return -1, _("Invalid request")
|
||||
self.create_forms(request.POST)
|
||||
if self.steps[stepid]["form"].is_valid():
|
||||
if stepid == len(self.steps) - 1:
|
||||
self.done_cb(self.steps)
|
||||
return 2, None
|
||||
return 1, None
|
||||
return 0, stepid
|
||||
|
||||
class DynamicForm(object):
|
||||
|
||||
def _create_field(self, typ, name, value=None, pos=None):
|
||||
self.fields[name] = typ(label="", required=False)
|
||||
if value is not None:
|
||||
self.fields[name].initial = value
|
||||
if pos:
|
||||
self.fields.keyOrder.remove(name)
|
||||
self.fields.keyOrder.insert(pos, name)
|
||||
|
||||
def _load_from_qdict(self, qdict, pattern, typ):
|
||||
expr = re.compile(r'%s_\d+' % pattern)
|
||||
values = []
|
||||
for k, v in qdict.iteritems():
|
||||
if k == pattern or expr.match(k):
|
||||
values.append((k, v))
|
||||
|
||||
ndata = self.data.copy()
|
||||
values.reverse()
|
||||
for v in values:
|
||||
if self.fields.has_key(v[0]):
|
||||
continue
|
||||
self._create_field(typ, v[0])
|
||||
ndata[v[0]] = v[1]
|
||||
self.data = ndata
|
||||
|
||||
class TabForms(object):
|
||||
"""
|
||||
Simple forms container
|
||||
|
||||
This class tries to encapsulate multiple forms that will be
|
||||
displayed using tabs. It is different from a classical formset
|
||||
because it can contain different forms.
|
||||
"""
|
||||
def __init__(self, data=None, instances=None, classes=None):
|
||||
to_remove = []
|
||||
for fd in self.forms:
|
||||
args = []
|
||||
kwargs = {}
|
||||
if fd.has_key("new_args"):
|
||||
args += fd["new_args"]
|
||||
if data:
|
||||
args.append(data)
|
||||
if instances:
|
||||
if hasattr(self, "check_%s" % fd["id"]):
|
||||
if not getattr(self, "check_%s" % fd["id"])(instances[fd["id"]]):
|
||||
to_remove += [fd]
|
||||
continue
|
||||
kwargs["instance"] = instances[fd["id"]]
|
||||
if classes and classes.has_key(fd["id"]):
|
||||
fd["instance"] = classes[fd["id"]](*args, **kwargs)
|
||||
else:
|
||||
fd["instance"] = fd["cls"](*args, **kwargs)
|
||||
map(lambda fd: self.forms.remove(fd), to_remove)
|
||||
self.active_id = self.forms[0]["id"]
|
||||
|
||||
def _before_is_valid(self, form):
|
||||
return True
|
||||
|
||||
def is_valid(self, mandatory_only=False, optional_only=False):
|
||||
to_remove = []
|
||||
for f in self.forms:
|
||||
if mandatory_only and \
|
||||
(not f.has_key("mandatory") or not f["mandatory"]):
|
||||
continue
|
||||
elif optional_only and \
|
||||
(f.has_key("mandatory") and f["mandatory"]):
|
||||
continue
|
||||
if not self._before_is_valid(f):
|
||||
to_remove.append(f)
|
||||
continue
|
||||
if not f["instance"].is_valid():
|
||||
self.active_id = f["id"]
|
||||
return False
|
||||
map(lambda fd: self.forms.remove(fd), to_remove)
|
||||
return True
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
raise RuntimeError
|
||||
|
||||
def remove_tab(self, tabid):
|
||||
for f in self.forms:
|
||||
if f["id"] == tabid:
|
||||
self.forms.remove(f)
|
||||
break
|
||||
|
||||
def __iter__(self):
|
||||
return self.forward()
|
||||
|
||||
def forward(self):
|
||||
for form in self.forms:
|
||||
yield form
|
||||
|
||||
#
|
||||
# Custom fields from here
|
||||
#
|
||||
|
||||
def is_valid_host(host):
|
||||
"""IDN compatible domain validator
|
||||
"""
|
||||
host = host.encode('idna').lower()
|
||||
if not hasattr(is_valid_host, '_re'):
|
||||
import re
|
||||
is_valid_host._re = re.compile(r'^([0-9a-z][-\w]*[0-9a-z]\.)+[a-z0-9\-]{2,15}$')
|
||||
return bool(is_valid_host._re.match(host))
|
||||
|
||||
def validate_domain_name(value):
|
||||
if not is_valid_host(value):
|
||||
raise ValidationError(_('Enter a valid domain name'), 'invalid')
|
||||
|
||||
class DomainNameField(forms.CharField):
|
||||
"""
|
||||
A subclass of CharField that only accepts a valid domain name.
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid' : _('Enter a valid domain name')
|
||||
}
|
||||
|
||||
default_validators = [validate_domain_name]
|
||||
|
||||
def clean(self, value):
|
||||
value = self.to_python(value).strip()
|
||||
return super(DomainNameField, self).clean(value)
|
||||
@@ -0,0 +1,118 @@
|
||||
# coding: utf-8
|
||||
from functools import wraps
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.utils.translation import ugettext as _
|
||||
from modoboa.admin.models import ObjectAccess
|
||||
import events
|
||||
|
||||
def get_content_type(obj):
|
||||
"""Simple function that use the right method to retrieve a content type
|
||||
|
||||
:param obj: a django model
|
||||
:return: a ``ContentType`` object
|
||||
"""
|
||||
return obj.get_content_type() if hasattr(obj, "get_content_type") \
|
||||
else ContentType.objects.get_for_model(obj)
|
||||
|
||||
def get_account_roles(user):
|
||||
"""Return the list of supported account roles
|
||||
|
||||
This list can be extended by extensions which listen to the
|
||||
``GetExtraRoles`` event.
|
||||
|
||||
:return: list of strings
|
||||
"""
|
||||
std_roles = [("SimpleUsers", _("Simple user"))]
|
||||
if user.is_superuser:
|
||||
std_roles += [("SuperAdmins", _("Super administrator"))]
|
||||
if user.has_perm("admin.add_domain"):
|
||||
std_roles += [("DomainAdmins", _("Domain administrator"))]
|
||||
std_roles += events.raiseQueryEvent("GetExtraRoles", user)
|
||||
return sorted(std_roles, key=lambda role: role[1])
|
||||
|
||||
def grant_access_to_object(user, obj, is_owner=False):
|
||||
"""Grant access to an object for a given user
|
||||
|
||||
There are two different cases where we want to grant access to an
|
||||
object for a specific user:
|
||||
|
||||
* He is the owner (he's just created the object)
|
||||
* He is going to administrate the object (but he is not the owner)
|
||||
|
||||
:param user: a ``User`` object
|
||||
:param obj: an admin. object (Domain, Mailbox, ...)
|
||||
:param is_owner: the user is the unique object's owner
|
||||
"""
|
||||
ct = get_content_type(obj)
|
||||
try:
|
||||
entry = user.objectaccess_set.get(content_type=ct, object_id=obj.id)
|
||||
entry.is_owner = is_owner
|
||||
entry.save()
|
||||
except ObjectAccess.DoesNotExist:
|
||||
pass
|
||||
else:
|
||||
return
|
||||
|
||||
try:
|
||||
objaccess = ObjectAccess(user=user, content_type=ct,
|
||||
object_id=obj.id, is_owner=is_owner)
|
||||
objaccess.save()
|
||||
except IntegrityError, e:
|
||||
raise AdminError(_("Failed to grant access (%s)" % str(e)))
|
||||
|
||||
def ungrant_access_to_object(obj, user=None):
|
||||
"""Ungrant access to an object for a specific user
|
||||
|
||||
If no user is provided, all entries referencing this object are
|
||||
deleted from the database.
|
||||
|
||||
:param obj: an object inheriting from ``models.Model``
|
||||
:param user: a ``User`` object
|
||||
"""
|
||||
ct = get_content_type(obj)
|
||||
if user:
|
||||
try:
|
||||
ObjectAccess.objects.get(user=user, content_type=ct, object_id=obj.id).delete()
|
||||
except ObjectAccess.DoesNotExist:
|
||||
pass
|
||||
else:
|
||||
ObjectAccess.objects.filter(content_type=ct, object_id=obj.id).delete()
|
||||
|
||||
def get_object_owner(obj):
|
||||
"""Return the unique owner of this object
|
||||
|
||||
:param obj: an object inheriting from ``model.Model``
|
||||
:return: a ``User`` object
|
||||
"""
|
||||
ct = get_content_type(obj)
|
||||
try:
|
||||
entry = ObjectAccess.objects.get(content_type=ct, object_id=obj.id, is_owner=True)
|
||||
except ObjectAccess.DoesNotExist:
|
||||
return None
|
||||
return entry.user
|
||||
|
||||
def check_domain_access(f):
|
||||
"""Decorator to check if the current user can access a domain
|
||||
|
||||
This decorator only applies to url that contain a 'domid' or
|
||||
'mbid' parameter. (for a direct access)
|
||||
|
||||
Raise a ``PermDeniedError`` if the current user can't view the
|
||||
requested object.
|
||||
"""
|
||||
@wraps(f)
|
||||
def dec(request, **kwargs):
|
||||
if not request.user.is_superuser:
|
||||
domain = None
|
||||
domid = request.GET.get("domid", None)
|
||||
if domid:
|
||||
domain = Domain.objects.get(pk=domid)
|
||||
else:
|
||||
mbid = request.GET.get("mbid", None)
|
||||
if mbid:
|
||||
domain = Mailbox.objects.get(pk=mbid).domain
|
||||
if domain and not request.user.can_access(domain):
|
||||
raise PermDeniedError(_("You can't access this domain"))
|
||||
|
||||
return f(request, **kwargs)
|
||||
return dec
|
||||
@@ -155,13 +155,15 @@ class Table(object):
|
||||
self.rows += [nrow]
|
||||
trcpt += 1
|
||||
|
||||
def _rows_from_model(self, objects):
|
||||
def _rows_from_model(self, objects, include_type_in_id=False):
|
||||
rows = []
|
||||
for obj in objects:
|
||||
nrow = {}
|
||||
try:
|
||||
idkey = getattr(self, "idkey")
|
||||
nrow[idkey] = getattr(obj, idkey)
|
||||
if include_type_in_id:
|
||||
nrow[idkey] = "%s:%s" % (obj.__class__.__name__, nrow[idkey])
|
||||
except AttributeError:
|
||||
pass
|
||||
for c in self.columns:
|
||||
@@ -169,10 +171,11 @@ class Table(object):
|
||||
nrow[c.name] = getattr(obj, c.name)
|
||||
except AttributeError:
|
||||
pass
|
||||
try:
|
||||
nrow["options"] = getattr(self, "rowoptions")(self.request, obj)
|
||||
except AttributeError:
|
||||
pass
|
||||
for meth in ["options", "class"]:
|
||||
try:
|
||||
nrow[meth] = getattr(self, "row_%s" % meth)(self.request, obj)
|
||||
except AttributeError:
|
||||
pass
|
||||
rows += [nrow]
|
||||
return rows
|
||||
|
||||
@@ -188,7 +191,7 @@ class Table(object):
|
||||
def render(self):
|
||||
if len(self.rows):
|
||||
t = Template("""
|
||||
<table id="{{ tableid }}">
|
||||
<table id="{{ tableid }}" class="table table-striped table-bordered">
|
||||
{% include "common/table_head.html" %}
|
||||
{% include "common/table_body.html" %}
|
||||
</table>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# coding: utf-8
|
||||
import os
|
||||
from django.conf import settings
|
||||
from django import template
|
||||
@@ -44,15 +44,20 @@ def display_messages(msgs):
|
||||
for m in msgs:
|
||||
level = m.tags
|
||||
text += unicode(m) + "\\\n"
|
||||
|
||||
|
||||
if level == "info":
|
||||
level = "success"
|
||||
timeout = "2000"
|
||||
else:
|
||||
timeout = "undefined"
|
||||
|
||||
return """
|
||||
<script type="text/javascript">
|
||||
window.addEvent("domready", function() {
|
||||
infobox.%s("%s");
|
||||
infobox.hide(2);
|
||||
});
|
||||
$(document).ready(function() {
|
||||
$('body').notify('%s', '%s', %s);
|
||||
});
|
||||
</script>
|
||||
""" % (level, text)
|
||||
""" % (level, text, timeout)
|
||||
|
||||
@register.simple_tag
|
||||
def load_optionalmenu(user):
|
||||
@@ -61,41 +66,53 @@ def load_optionalmenu(user):
|
||||
{"entries" : menu, "user" : user})
|
||||
|
||||
@register.simple_tag
|
||||
def user_menu(user):
|
||||
entries = [
|
||||
{"name" : "user",
|
||||
"img" : static_url('pics/administrators.png'),
|
||||
"label" : user.fullname,
|
||||
"class" : "topdropdown",
|
||||
"menu" : [
|
||||
{"name" : "changepwd",
|
||||
"url" : reverse("modoboa.userprefs.views.changepassword"),
|
||||
"img" : static_url("pics/edit.png"),
|
||||
"label" : _("Change password"),
|
||||
"class" : "boxed",
|
||||
"rel" : "{handler:'iframe',size:{x:360,y:200},closeBtn:true}"},
|
||||
{"name" : "preferences",
|
||||
"img" : static_url("pics/user.png"),
|
||||
"label" : _("Preferences"),
|
||||
"url" : reverse("modoboa.userprefs.views.preferences")},
|
||||
{"name" : "logout",
|
||||
"url" : reverse("modoboa.auth.views.dologout"),
|
||||
"label" : _("Logout"),
|
||||
"img" : static_url("pics/logout.png")}
|
||||
]
|
||||
}
|
||||
]
|
||||
if user.belongs_to_group('SimpleUsers'):
|
||||
entries[0]["menu"] += [{
|
||||
"name" : "setforwards",
|
||||
"url" : reverse("modoboa.userprefs.views.setforward"),
|
||||
"img" : static_url("pics/alias.png"),
|
||||
"label" : _("Forward"),
|
||||
"class" : "boxed",
|
||||
"rel" : "{handler:'iframe',size:{x:360,y:350},closeBtn:true}"
|
||||
}]
|
||||
def render_form(form, tpl=None):
|
||||
if tpl is not None:
|
||||
return render_to_string(tpl, dict(form=form))
|
||||
|
||||
entries[0]["menu"] += events.raiseQueryEvent("UserMenuDisplay", "options_menu", user)
|
||||
ret = ""
|
||||
for field in form:
|
||||
ret += "%s\n" % render_field(field)
|
||||
return ret
|
||||
|
||||
return render_to_string("common/menulist.html",
|
||||
{"entries" : entries, "user" : user})
|
||||
@register.simple_tag
|
||||
def render_field(field):
|
||||
return render_to_string("common/generic_field.html", dict(
|
||||
field=field
|
||||
))
|
||||
|
||||
@register.simple_tag
|
||||
def render_fields_group(form, pattern):
|
||||
from django.forms import forms
|
||||
|
||||
first = forms.BoundField(form, form.fields[pattern], pattern)
|
||||
label = first.label
|
||||
group = [first]
|
||||
cpt = 1
|
||||
haserror = len(first.errors) != 0
|
||||
while True:
|
||||
fname = "%s_%d" % (pattern, cpt)
|
||||
if not form.fields.has_key(fname):
|
||||
break
|
||||
bfield = forms.BoundField(form, form.fields[fname], fname)
|
||||
if len(bfield.errors):
|
||||
haserror = True
|
||||
group += [bfield]
|
||||
cpt += 1
|
||||
|
||||
return render_to_string("common/generic_fields_group.html", dict(
|
||||
label=label, group=group, haserror=haserror
|
||||
))
|
||||
|
||||
@register.simple_tag
|
||||
def pagination_bar(page):
|
||||
return render_to_string("common/pagination_bar.html", dict(
|
||||
page=page
|
||||
))
|
||||
|
||||
@register.simple_tag
|
||||
def alert(msg, typ):
|
||||
return """<div class="alert alert-%s">
|
||||
<a class="close" data-dismiss="alert">×</a>
|
||||
%s
|
||||
</div>""" % (typ, msg)
|
||||
|
||||
@@ -37,9 +37,11 @@ def _render_error(request, errortpl="error", user_context={}):
|
||||
def render_actions(actions):
|
||||
t = template.Template("""
|
||||
{% for a in actions %}
|
||||
<a href="{{ a.url }}" name="{{ a.name }}" class="{{ a.class }}" rel="{{ a.rel }}"
|
||||
<a href="{{ a.url }}" name="{{ a.name }}"
|
||||
{% if a.modal %}data-toggle="ajaxmodal"{% endif %}
|
||||
{% if a.modalcb %}modalcb="{{ a.modalcb }}"{% endif %}
|
||||
{% if a.confirm %}onclick="return confirm('{{ a.confirm }}')"{% endif %}>
|
||||
<img src="{{ a.img }}" border="0" title="{{ a.title }}" /></a>
|
||||
<i class="{{ a.img }}" title="{{ a.title }}"></i></a>
|
||||
{% endfor %}
|
||||
""")
|
||||
return t.render(template.Context({
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
ul.autocompleter-choices
|
||||
{
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
border: 1px solid #7c7c7c;
|
||||
border-left-color: #c3c3c3;
|
||||
border-right-color: #c3c3c3;
|
||||
border-bottom-color: #ddd;
|
||||
background-color: #fff;
|
||||
text-align: left;
|
||||
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
|
||||
z-index: 50;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
ul.autocompleter-choices li
|
||||
{
|
||||
position: relative;
|
||||
margin: -2px 0 0 0;
|
||||
padding: 0.2em 1.5em 0.2em 1em;
|
||||
display: block;
|
||||
float: none !important;
|
||||
cursor: pointer;
|
||||
font-weight: normal;
|
||||
white-space: nowrap;
|
||||
font-size: 1em;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
ul.autocompleter-choices li.autocompleter-selected
|
||||
{
|
||||
background-color: #444;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
ul.autocompleter-choices span.autocompleter-queried
|
||||
{
|
||||
display: inline;
|
||||
float: none;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul.autocompleter-choices li.autocompleter-selected span.autocompleter-queried
|
||||
{
|
||||
color: #9FCFFF;
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
/**
|
||||
* SqueezeBox - Expandable Lightbox
|
||||
*
|
||||
* Allows to open various content as modal,
|
||||
* centered and animated box.
|
||||
*
|
||||
* @version 1.1 rc4
|
||||
*
|
||||
* @license MIT-style license
|
||||
* @author Harald Kirschner <mail [at] digitarald.de>
|
||||
* @copyright Author
|
||||
*/
|
||||
|
||||
#sbox-overlay {
|
||||
position: absolute;
|
||||
background-color: #000;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
zoom: 1;
|
||||
}
|
||||
|
||||
#sbox-window {
|
||||
position: absolute;
|
||||
background-color: #fff;
|
||||
text-align: left;
|
||||
overflow: visible;
|
||||
padding: 10px;
|
||||
/* invalid values, but looks smoother! */
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
}
|
||||
|
||||
#sbox-btn-close {
|
||||
position: absolute;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
right: -15px;
|
||||
top: -15px;
|
||||
background: url(closebox.png) no-repeat center;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.sbox-window-ie6 #sbox-btn-close {
|
||||
background-image: url(closebox.gif);
|
||||
}
|
||||
|
||||
.sbox-loading #sbox-content {
|
||||
background-image: url(spinner.gif);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
#sbox-content {
|
||||
clear: both;
|
||||
overflow: auto;
|
||||
background-color: #fff;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sbox-content-image#sbox-content {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
#sbox-image {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.sbox-content-image img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.sbox-content-iframe#sbox-content {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/* Hides scrollbars */
|
||||
.body-overlayed {
|
||||
overflow: hidden;
|
||||
}
|
||||
/* Hides flash (Firefox problem) and selects (IE) */
|
||||
.body-overlayed embed, .body-overlayed object, .body-overlayed select {
|
||||
visibility: hidden;
|
||||
}
|
||||
#sbox-window embed, #sbox-window object, #sbox-window select {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* Shadows */
|
||||
.sbox-bg {
|
||||
position: absolute;
|
||||
width: 33px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.sbox-bg-n {
|
||||
left: 0;
|
||||
top: -40px;
|
||||
width: 100%;
|
||||
background: url(bg_n.png) repeat-x;
|
||||
}
|
||||
.sbox-bg-ne {
|
||||
right: -33px;
|
||||
top: -40px;
|
||||
background: url(bg_ne.png) no-repeat;
|
||||
}
|
||||
.sbox-bg-e {
|
||||
right: -33px;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
background: url(bg_e.png) repeat-y;
|
||||
}
|
||||
.sbox-bg-se {
|
||||
right: -33px;
|
||||
bottom: -40px;
|
||||
background: url(bg_se.png) no-repeat;
|
||||
}
|
||||
.sbox-bg-s {
|
||||
left: 0;
|
||||
bottom: -40px;
|
||||
width: 100%;
|
||||
background: url(bg_s.png) repeat-x;
|
||||
}
|
||||
.sbox-bg-sw {
|
||||
left: -33px;
|
||||
bottom: -40px;
|
||||
background: url(bg_sw.png) no-repeat;
|
||||
}
|
||||
.sbox-bg-w {
|
||||
left: -33px;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
background: url(bg_w.png) repeat-y;
|
||||
}
|
||||
.sbox-bg-nw {
|
||||
left: -33px;
|
||||
top: -40px;
|
||||
background: url(bg_nw.png) no-repeat;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 990 B |
|
Before Width: | Height: | Size: 986 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 985 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 981 B |
@@ -0,0 +1,632 @@
|
||||
article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block;}
|
||||
audio,canvas,video{display:inline-block;*display:inline;*zoom:1;}
|
||||
audio:not([controls]){display:none;}
|
||||
html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;}
|
||||
a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}
|
||||
a:hover,a:active{outline:0;}
|
||||
sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline;}
|
||||
sup{top:-0.5em;}
|
||||
sub{bottom:-0.25em;}
|
||||
img{max-width:100%;height:auto;border:0;-ms-interpolation-mode:bicubic;}
|
||||
button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle;}
|
||||
button,input{*overflow:visible;line-height:normal;}
|
||||
button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0;}
|
||||
button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;}
|
||||
input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;}
|
||||
input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none;}
|
||||
textarea{overflow:auto;vertical-align:top;}
|
||||
.clearfix{*zoom:1;}.clearfix:before,.clearfix:after{display:table;content:"";}
|
||||
.clearfix:after{clear:both;}
|
||||
body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:18px;color:#333333;background-color:#ffffff;}
|
||||
a{color:#0088cc;text-decoration:none;}
|
||||
a:hover{color:#005580;text-decoration:underline;}
|
||||
.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";}
|
||||
.row:after{clear:both;}
|
||||
[class*="span"]{float:left;margin-left:20px;}
|
||||
.span1{width:60px;}
|
||||
.span2{width:140px;}
|
||||
.span3{width:220px;}
|
||||
.span4{width:300px;}
|
||||
.span5{width:380px;}
|
||||
.span6{width:460px;}
|
||||
.span7{width:540px;}
|
||||
.span8{width:620px;}
|
||||
.span9{width:700px;}
|
||||
.span10{width:780px;}
|
||||
.span11{width:860px;}
|
||||
.span12,.container{width:940px;}
|
||||
.offset1{margin-left:100px;}
|
||||
.offset2{margin-left:180px;}
|
||||
.offset3{margin-left:260px;}
|
||||
.offset4{margin-left:340px;}
|
||||
.offset5{margin-left:420px;}
|
||||
.offset6{margin-left:500px;}
|
||||
.offset7{margin-left:580px;}
|
||||
.offset8{margin-left:660px;}
|
||||
.offset9{margin-left:740px;}
|
||||
.offset10{margin-left:820px;}
|
||||
.offset11{margin-left:900px;}
|
||||
.row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";}
|
||||
.row-fluid:after{clear:both;}
|
||||
.row-fluid>[class*="span"]{float:left;margin-left:2.127659574%;}
|
||||
.row-fluid>[class*="span"]:first-child{margin-left:0;}
|
||||
.row-fluid>.span1{width:6.382978723%;}
|
||||
.row-fluid>.span2{width:14.89361702%;}
|
||||
.row-fluid>.span3{width:23.404255317%;}
|
||||
.row-fluid>.span4{width:31.914893614%;}
|
||||
.row-fluid>.span5{width:40.425531911%;}
|
||||
.row-fluid>.span6{width:48.93617020799999%;}
|
||||
.row-fluid>.span7{width:57.446808505%;}
|
||||
.row-fluid>.span8{width:65.95744680199999%;}
|
||||
.row-fluid>.span9{width:74.468085099%;}
|
||||
.row-fluid>.span10{width:82.97872339599999%;}
|
||||
.row-fluid>.span11{width:91.489361693%;}
|
||||
.row-fluid>.span12{width:99.99999998999999%;}
|
||||
.container{width:940px;margin-left:auto;margin-right:auto;*zoom:1;}.container:before,.container:after{display:table;content:"";}
|
||||
.container:after{clear:both;}
|
||||
.container-fluid{padding-left:20px;padding-right:20px;*zoom:1;}.container-fluid:before,.container-fluid:after{display:table;content:"";}
|
||||
.container-fluid:after{clear:both;}
|
||||
p{margin:0 0 9px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:18px;}p small{font-size:11px;color:#999999;}
|
||||
.lead{margin-bottom:18px;font-size:20px;font-weight:200;line-height:27px;}
|
||||
h1,h2,h3,h4,h5,h6{margin:0;font-weight:bold;color:#333333;text-rendering:optimizelegibility;}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;color:#999999;}
|
||||
h1{font-size:30px;line-height:36px;}h1 small{font-size:18px;}
|
||||
h2{font-size:24px;line-height:36px;}h2 small{font-size:18px;}
|
||||
h3{line-height:27px;font-size:18px;}h3 small{font-size:14px;}
|
||||
h4,h5,h6{line-height:18px;}
|
||||
h4{font-size:14px;}h4 small{font-size:12px;}
|
||||
h5{font-size:12px;}
|
||||
h6{font-size:11px;color:#999999;text-transform:uppercase;}
|
||||
.page-header{padding-bottom:17px;margin:18px 0;border-bottom:1px solid #eeeeee;}
|
||||
.page-header h1{line-height:1;}
|
||||
ul,ol{padding:0;margin:0 0 9px 25px;}
|
||||
ul ul,ul ol,ol ol,ol ul{margin-bottom:0;}
|
||||
ul{list-style:disc;}
|
||||
ol{list-style:decimal;}
|
||||
li{line-height:18px;}
|
||||
ul.unstyled,ol.unstyled{margin-left:0;list-style:none;}
|
||||
dl{margin-bottom:18px;}
|
||||
dt,dd{line-height:18px;}
|
||||
dt{font-weight:bold;}
|
||||
dd{margin-left:9px;}
|
||||
hr{margin:18px 0;border:0;border-top:1px solid #eeeeee;border-bottom:1px solid #ffffff;}
|
||||
strong{font-weight:bold;}
|
||||
em{font-style:italic;}
|
||||
.muted{color:#999999;}
|
||||
abbr{font-size:90%;text-transform:uppercase;border-bottom:1px dotted #ddd;cursor:help;}
|
||||
blockquote{padding:0 0 0 15px;margin:0 0 18px;border-left:5px solid #eeeeee;}blockquote p{margin-bottom:0;font-size:16px;font-weight:300;line-height:22.5px;}
|
||||
blockquote small{display:block;line-height:18px;color:#999999;}blockquote small:before{content:'\2014 \00A0';}
|
||||
blockquote.pull-right{float:right;padding-left:0;padding-right:15px;border-left:0;border-right:5px solid #eeeeee;}blockquote.pull-right p,blockquote.pull-right small{text-align:right;}
|
||||
q:before,q:after,blockquote:before,blockquote:after{content:"";}
|
||||
address{display:block;margin-bottom:18px;line-height:18px;font-style:normal;}
|
||||
small{font-size:100%;}
|
||||
cite{font-style:normal;}
|
||||
code,pre{padding:0 3px 2px;font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;color:#333333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
|
||||
code{padding:3px 4px;color:#d14;background-color:#f7f7f9;border:1px solid #e1e1e8;}
|
||||
pre{display:block;padding:8.5px;margin:0 0 9px;font-size:12px;line-height:18px;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;white-space:pre;white-space:pre-wrap;word-break:break-all;word-wrap:break-word;}pre.prettyprint{margin-bottom:18px;}
|
||||
pre code{padding:0;color:inherit;background-color:transparent;border:0;}
|
||||
.pre-scrollable{max-height:340px;overflow-y:scroll;}
|
||||
form{margin:0 0 18px;}
|
||||
fieldset{padding:0;margin:0;border:0;}
|
||||
legend{display:block;width:100%;padding:0;margin-bottom:27px;font-size:19.5px;line-height:36px;color:#333333;border:0;border-bottom:1px solid #eee;}legend small{font-size:13.5px;color:#999999;}
|
||||
label,input,button,select,textarea{font-size:13px;font-weight:normal;line-height:18px;}
|
||||
input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;}
|
||||
label{display:block;margin-bottom:5px;color:#333333;}
|
||||
input,textarea,select,.uneditable-input{display:inline-block;width:210px;height:18px;padding:4px;margin-bottom:9px;font-size:13px;line-height:18px;color:#555555;border:1px solid #ccc;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
|
||||
.uneditable-textarea{width:auto;height:auto;}
|
||||
label input,label textarea,label select{display:block;}
|
||||
input[type="image"],input[type="checkbox"],input[type="radio"]{width:auto;height:auto;padding:0;margin:3px 0;*margin-top:0;line-height:normal;cursor:pointer;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;border:0 \9;}
|
||||
input[type="image"]{border:0;}
|
||||
input[type="file"]{width:auto;padding:initial;line-height:initial;border:initial;background-color:#ffffff;background-color:initial;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}
|
||||
input[type="button"],input[type="reset"],input[type="submit"]{width:auto;height:auto;}
|
||||
select,input[type="file"]{height:28px;*margin-top:4px;line-height:28px;}
|
||||
input[type="file"]{line-height:18px \9;}
|
||||
select{width:220px;background-color:#ffffff;}
|
||||
select[multiple],select[size]{height:auto;}
|
||||
input[type="image"]{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}
|
||||
textarea{height:auto;}
|
||||
input[type="hidden"]{display:none;}
|
||||
.radio,.checkbox{padding-left:18px;}
|
||||
.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-18px;}
|
||||
.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px;}
|
||||
.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle;}
|
||||
.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px;}
|
||||
input,textarea{-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-webkit-transition:border linear 0.2s,box-shadow linear 0.2s;-moz-transition:border linear 0.2s,box-shadow linear 0.2s;-ms-transition:border linear 0.2s,box-shadow linear 0.2s;-o-transition:border linear 0.2s,box-shadow linear 0.2s;transition:border linear 0.2s,box-shadow linear 0.2s;}
|
||||
input:focus,textarea:focus{border-color:rgba(82, 168, 236, 0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(82, 168, 236, 0.6);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(82, 168, 236, 0.6);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(82, 168, 236, 0.6);outline:0;outline:thin dotted \9;}
|
||||
input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus,select:focus{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}
|
||||
.input-mini{width:60px;}
|
||||
.input-small{width:90px;}
|
||||
.input-medium{width:150px;}
|
||||
.input-large{width:210px;}
|
||||
.input-xlarge{width:270px;}
|
||||
.input-xxlarge{width:530px;}
|
||||
input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{float:none;margin-left:0;}
|
||||
input.span1,textarea.span1,.uneditable-input.span1{width:50px;}
|
||||
input.span2,textarea.span2,.uneditable-input.span2{width:130px;}
|
||||
input.span3,textarea.span3,.uneditable-input.span3{width:210px;}
|
||||
input.span4,textarea.span4,.uneditable-input.span4{width:290px;}
|
||||
input.span5,textarea.span5,.uneditable-input.span5{width:370px;}
|
||||
input.span6,textarea.span6,.uneditable-input.span6{width:450px;}
|
||||
input.span7,textarea.span7,.uneditable-input.span7{width:530px;}
|
||||
input.span8,textarea.span8,.uneditable-input.span8{width:610px;}
|
||||
input.span9,textarea.span9,.uneditable-input.span9{width:690px;}
|
||||
input.span10,textarea.span10,.uneditable-input.span10{width:770px;}
|
||||
input.span11,textarea.span11,.uneditable-input.span11{width:850px;}
|
||||
input.span12,textarea.span12,.uneditable-input.span12{width:930px;}
|
||||
input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{background-color:#f5f5f5;border-color:#ddd;cursor:not-allowed;}
|
||||
.control-group.warning>label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853;}
|
||||
.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853;border-color:#c09853;}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:0 0 6px #dbc59e;-moz-box-shadow:0 0 6px #dbc59e;box-shadow:0 0 6px #dbc59e;}
|
||||
.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853;}
|
||||
.control-group.error>label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48;}
|
||||
.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48;border-color:#b94a48;}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:0 0 6px #d59392;-moz-box-shadow:0 0 6px #d59392;box-shadow:0 0 6px #d59392;}
|
||||
.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48;}
|
||||
.control-group.success>label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847;}
|
||||
.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847;border-color:#468847;}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:0 0 6px #7aba7b;-moz-box-shadow:0 0 6px #7aba7b;box-shadow:0 0 6px #7aba7b;}
|
||||
.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847;}
|
||||
input:focus:required:invalid,textarea:focus:required:invalid,select:focus:required:invalid{color:#b94a48;border-color:#ee5f5b;}input:focus:required:invalid:focus,textarea:focus:required:invalid:focus,select:focus:required:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7;}
|
||||
.form-actions{padding:17px 20px 18px;margin-top:18px;margin-bottom:18px;background-color:#f5f5f5;border-top:1px solid #ddd;}
|
||||
.uneditable-input{display:block;background-color:#ffffff;border-color:#eee;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);cursor:not-allowed;}
|
||||
:-moz-placeholder{color:#999999;}
|
||||
::-webkit-input-placeholder{color:#999999;}
|
||||
.help-block{display:block;margin-top:5px;margin-bottom:0;color:#999999;}
|
||||
.help-inline{display:inline-block;*display:inline;*zoom:1;margin-bottom:9px;vertical-align:middle;padding-left:5px;}
|
||||
.input-prepend,.input-append{margin-bottom:5px;*zoom:1;}.input-prepend:before,.input-append:before,.input-prepend:after,.input-append:after{display:table;content:"";}
|
||||
.input-prepend:after,.input-append:after{clear:both;}
|
||||
.input-prepend input,.input-append input,.input-prepend .uneditable-input,.input-append .uneditable-input{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;}.input-prepend input:focus,.input-append input:focus,.input-prepend .uneditable-input:focus,.input-append .uneditable-input:focus{position:relative;z-index:2;}
|
||||
.input-prepend .uneditable-input,.input-append .uneditable-input{border-left-color:#ccc;}
|
||||
.input-prepend .add-on,.input-append .add-on{float:left;display:block;width:auto;min-width:16px;height:18px;margin-right:-1px;padding:4px 5px;font-weight:normal;line-height:18px;color:#999999;text-align:center;text-shadow:0 1px 0 #ffffff;background-color:#f5f5f5;border:1px solid #ccc;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;}
|
||||
.input-prepend .active,.input-append .active{background-color:#a9dba9;border-color:#46a546;}
|
||||
.input-prepend .add-on{*margin-top:1px;}
|
||||
.input-append input,.input-append .uneditable-input{float:left;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;}
|
||||
.input-append .uneditable-input{border-left-color:#eee;border-right-color:#ccc;}
|
||||
.input-append .add-on{margin-right:0;margin-left:-1px;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;}
|
||||
.input-append input:first-child{*margin-left:-160px;}.input-append input:first-child+.add-on{*margin-left:-21px;}
|
||||
.search-query{padding-left:14px;padding-right:14px;margin-bottom:0;-webkit-border-radius:14px;-moz-border-radius:14px;border-radius:14px;}
|
||||
.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input{display:inline-block;margin-bottom:0;}
|
||||
.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none;}
|
||||
.form-search label,.form-inline label,.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{display:inline-block;}
|
||||
.form-search .input-append .add-on,.form-inline .input-prepend .add-on,.form-search .input-append .add-on,.form-inline .input-prepend .add-on{vertical-align:middle;}
|
||||
.form-search .radio,.form-inline .radio,.form-search .checkbox,.form-inline .checkbox{margin-bottom:0;vertical-align:middle;}
|
||||
.control-group{margin-bottom:9px;}
|
||||
legend+.control-group{margin-top:18px;-webkit-margin-top-collapse:separate;}
|
||||
.form-horizontal .control-group{margin-bottom:18px;*zoom:1;}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:"";}
|
||||
.form-horizontal .control-group:after{clear:both;}
|
||||
.form-horizontal .control-label{float:left;width:140px;padding-top:5px;text-align:right;}
|
||||
.form-horizontal .controls{margin-left:160px;}
|
||||
.form-horizontal .form-actions{padding-left:160px;}
|
||||
table{max-width:100%;border-collapse:collapse;border-spacing:0;}
|
||||
.table{width:100%;margin-bottom:18px;}.table th,.table td{padding:8px;line-height:18px;text-align:left;vertical-align:top;border-top:1px solid #ddd;}
|
||||
.table th{font-weight:bold;}
|
||||
.table thead th{vertical-align:bottom;}
|
||||
.table thead:first-child tr th,.table thead:first-child tr td{border-top:0;}
|
||||
.table tbody+tbody{border-top:2px solid #ddd;}
|
||||
.table-condensed th,.table-condensed td{padding:4px 5px;}
|
||||
.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapsed;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.table-bordered th+th,.table-bordered td+td,.table-bordered th+td,.table-bordered td+th{border-left:1px solid #ddd;}
|
||||
.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0;}
|
||||
.table-bordered thead:first-child tr:first-child th:first-child,.table-bordered tbody:first-child tr:first-child td:first-child{-webkit-border-radius:4px 0 0 0;-moz-border-radius:4px 0 0 0;border-radius:4px 0 0 0;}
|
||||
.table-bordered thead:first-child tr:first-child th:last-child,.table-bordered tbody:first-child tr:first-child td:last-child{-webkit-border-radius:0 4px 0 0;-moz-border-radius:0 4px 0 0;border-radius:0 4px 0 0;}
|
||||
.table-bordered thead:last-child tr:last-child th:first-child,.table-bordered tbody:last-child tr:last-child td:first-child{-webkit-border-radius:0 0 0 4px;-moz-border-radius:0 0 0 4px;border-radius:0 0 0 4px;}
|
||||
.table-bordered thead:last-child tr:last-child th:last-child,.table-bordered tbody:last-child tr:last-child td:last-child{-webkit-border-radius:0 0 4px 0;-moz-border-radius:0 0 4px 0;border-radius:0 0 4px 0;}
|
||||
.table-striped tbody tr:nth-child(odd) td,.table-striped tbody tr:nth-child(odd) th{background-color:#f9f9f9;}
|
||||
.table tbody tr:hover td,.table tbody tr:hover th{background-color:#f5f5f5;}
|
||||
table .span1{float:none;width:44px;margin-left:0;}
|
||||
table .span2{float:none;width:124px;margin-left:0;}
|
||||
table .span3{float:none;width:204px;margin-left:0;}
|
||||
table .span4{float:none;width:284px;margin-left:0;}
|
||||
table .span5{float:none;width:364px;margin-left:0;}
|
||||
table .span6{float:none;width:444px;margin-left:0;}
|
||||
table .span7{float:none;width:524px;margin-left:0;}
|
||||
table .span8{float:none;width:604px;margin-left:0;}
|
||||
table .span9{float:none;width:684px;margin-left:0;}
|
||||
table .span10{float:none;width:764px;margin-left:0;}
|
||||
table .span11{float:none;width:844px;margin-left:0;}
|
||||
table .span12{float:none;width:924px;margin-left:0;}
|
||||
[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat;*margin-right:.3em;}[class^="icon-"]:last-child,[class*=" icon-"]:last-child{*margin-left:0;}
|
||||
.icon-white{background-image:url("../img/glyphicons-halflings-white.png");}
|
||||
.icon-glass{background-position:0 0;}
|
||||
.icon-music{background-position:-24px 0;}
|
||||
.icon-search{background-position:-48px 0;}
|
||||
.icon-envelope{background-position:-72px 0;}
|
||||
.icon-heart{background-position:-96px 0;}
|
||||
.icon-star{background-position:-120px 0;}
|
||||
.icon-star-empty{background-position:-144px 0;}
|
||||
.icon-user{background-position:-168px 0;}
|
||||
.icon-film{background-position:-192px 0;}
|
||||
.icon-th-large{background-position:-216px 0;}
|
||||
.icon-th{background-position:-240px 0;}
|
||||
.icon-th-list{background-position:-264px 0;}
|
||||
.icon-ok{background-position:-288px 0;}
|
||||
.icon-remove{background-position:-312px 0;}
|
||||
.icon-zoom-in{background-position:-336px 0;}
|
||||
.icon-zoom-out{background-position:-360px 0;}
|
||||
.icon-off{background-position:-384px 0;}
|
||||
.icon-signal{background-position:-408px 0;}
|
||||
.icon-cog{background-position:-432px 0;}
|
||||
.icon-trash{background-position:-456px 0;}
|
||||
.icon-home{background-position:0 -24px;}
|
||||
.icon-file{background-position:-24px -24px;}
|
||||
.icon-time{background-position:-48px -24px;}
|
||||
.icon-road{background-position:-72px -24px;}
|
||||
.icon-download-alt{background-position:-96px -24px;}
|
||||
.icon-download{background-position:-120px -24px;}
|
||||
.icon-upload{background-position:-144px -24px;}
|
||||
.icon-inbox{background-position:-168px -24px;}
|
||||
.icon-play-circle{background-position:-192px -24px;}
|
||||
.icon-repeat{background-position:-216px -24px;}
|
||||
.icon-refresh{background-position:-240px -24px;}
|
||||
.icon-list-alt{background-position:-264px -24px;}
|
||||
.icon-lock{background-position:-287px -24px;}
|
||||
.icon-flag{background-position:-312px -24px;}
|
||||
.icon-headphones{background-position:-336px -24px;}
|
||||
.icon-volume-off{background-position:-360px -24px;}
|
||||
.icon-volume-down{background-position:-384px -24px;}
|
||||
.icon-volume-up{background-position:-408px -24px;}
|
||||
.icon-qrcode{background-position:-432px -24px;}
|
||||
.icon-barcode{background-position:-456px -24px;}
|
||||
.icon-tag{background-position:0 -48px;}
|
||||
.icon-tags{background-position:-25px -48px;}
|
||||
.icon-book{background-position:-48px -48px;}
|
||||
.icon-bookmark{background-position:-72px -48px;}
|
||||
.icon-print{background-position:-96px -48px;}
|
||||
.icon-camera{background-position:-120px -48px;}
|
||||
.icon-font{background-position:-144px -48px;}
|
||||
.icon-bold{background-position:-167px -48px;}
|
||||
.icon-italic{background-position:-192px -48px;}
|
||||
.icon-text-height{background-position:-216px -48px;}
|
||||
.icon-text-width{background-position:-240px -48px;}
|
||||
.icon-align-left{background-position:-264px -48px;}
|
||||
.icon-align-center{background-position:-288px -48px;}
|
||||
.icon-align-right{background-position:-312px -48px;}
|
||||
.icon-align-justify{background-position:-336px -48px;}
|
||||
.icon-list{background-position:-360px -48px;}
|
||||
.icon-indent-left{background-position:-384px -48px;}
|
||||
.icon-indent-right{background-position:-408px -48px;}
|
||||
.icon-facetime-video{background-position:-432px -48px;}
|
||||
.icon-picture{background-position:-456px -48px;}
|
||||
.icon-pencil{background-position:0 -72px;}
|
||||
.icon-map-marker{background-position:-24px -72px;}
|
||||
.icon-adjust{background-position:-48px -72px;}
|
||||
.icon-tint{background-position:-72px -72px;}
|
||||
.icon-edit{background-position:-96px -72px;}
|
||||
.icon-share{background-position:-120px -72px;}
|
||||
.icon-check{background-position:-144px -72px;}
|
||||
.icon-move{background-position:-168px -72px;}
|
||||
.icon-step-backward{background-position:-192px -72px;}
|
||||
.icon-fast-backward{background-position:-216px -72px;}
|
||||
.icon-backward{background-position:-240px -72px;}
|
||||
.icon-play{background-position:-264px -72px;}
|
||||
.icon-pause{background-position:-288px -72px;}
|
||||
.icon-stop{background-position:-312px -72px;}
|
||||
.icon-forward{background-position:-336px -72px;}
|
||||
.icon-fast-forward{background-position:-360px -72px;}
|
||||
.icon-step-forward{background-position:-384px -72px;}
|
||||
.icon-eject{background-position:-408px -72px;}
|
||||
.icon-chevron-left{background-position:-432px -72px;}
|
||||
.icon-chevron-right{background-position:-456px -72px;}
|
||||
.icon-plus-sign{background-position:0 -96px;}
|
||||
.icon-minus-sign{background-position:-24px -96px;}
|
||||
.icon-remove-sign{background-position:-48px -96px;}
|
||||
.icon-ok-sign{background-position:-72px -96px;}
|
||||
.icon-question-sign{background-position:-96px -96px;}
|
||||
.icon-info-sign{background-position:-120px -96px;}
|
||||
.icon-screenshot{background-position:-144px -96px;}
|
||||
.icon-remove-circle{background-position:-168px -96px;}
|
||||
.icon-ok-circle{background-position:-192px -96px;}
|
||||
.icon-ban-circle{background-position:-216px -96px;}
|
||||
.icon-arrow-left{background-position:-240px -96px;}
|
||||
.icon-arrow-right{background-position:-264px -96px;}
|
||||
.icon-arrow-up{background-position:-289px -96px;}
|
||||
.icon-arrow-down{background-position:-312px -96px;}
|
||||
.icon-share-alt{background-position:-336px -96px;}
|
||||
.icon-resize-full{background-position:-360px -96px;}
|
||||
.icon-resize-small{background-position:-384px -96px;}
|
||||
.icon-plus{background-position:-408px -96px;}
|
||||
.icon-minus{background-position:-433px -96px;}
|
||||
.icon-asterisk{background-position:-456px -96px;}
|
||||
.icon-exclamation-sign{background-position:0 -120px;}
|
||||
.icon-gift{background-position:-24px -120px;}
|
||||
.icon-leaf{background-position:-48px -120px;}
|
||||
.icon-fire{background-position:-72px -120px;}
|
||||
.icon-eye-open{background-position:-96px -120px;}
|
||||
.icon-eye-close{background-position:-120px -120px;}
|
||||
.icon-warning-sign{background-position:-144px -120px;}
|
||||
.icon-plane{background-position:-168px -120px;}
|
||||
.icon-calendar{background-position:-192px -120px;}
|
||||
.icon-random{background-position:-216px -120px;}
|
||||
.icon-comment{background-position:-240px -120px;}
|
||||
.icon-magnet{background-position:-264px -120px;}
|
||||
.icon-chevron-up{background-position:-288px -120px;}
|
||||
.icon-chevron-down{background-position:-313px -119px;}
|
||||
.icon-retweet{background-position:-336px -120px;}
|
||||
.icon-shopping-cart{background-position:-360px -120px;}
|
||||
.icon-folder-close{background-position:-384px -120px;}
|
||||
.icon-folder-open{background-position:-408px -120px;}
|
||||
.icon-resize-vertical{background-position:-432px -119px;}
|
||||
.icon-resize-horizontal{background-position:-456px -118px;}
|
||||
.dropdown{position:relative;}
|
||||
.dropdown-toggle{*margin-bottom:-3px;}
|
||||
.dropdown-toggle:active,.open .dropdown-toggle{outline:0;}
|
||||
.caret{display:inline-block;width:0;height:0;text-indent:-99999px;*text-indent:0;vertical-align:top;border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid #000000;opacity:0.3;filter:alpha(opacity=30);content:"\2193";}
|
||||
.dropdown .caret{margin-top:8px;margin-left:2px;}
|
||||
.dropdown:hover .caret,.open.dropdown .caret{opacity:1;filter:alpha(opacity=100);}
|
||||
.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;float:left;display:none;min-width:160px;_width:160px;padding:4px 0;margin:0;list-style:none;background-color:#ffffff;border-color:#ccc;border-color:rgba(0, 0, 0, 0.2);border-style:solid;border-width:1px;-webkit-border-radius:0 0 5px 5px;-moz-border-radius:0 0 5px 5px;border-radius:0 0 5px 5px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;*border-right-width:2px;*border-bottom-width:2px;}.dropdown-menu.bottom-up{top:auto;bottom:100%;margin-bottom:2px;}
|
||||
.dropdown-menu .divider{height:1px;margin:5px 1px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;*width:100%;*margin:-5px 0 5px;}
|
||||
.dropdown-menu a{display:block;padding:3px 15px;clear:both;font-weight:normal;line-height:18px;color:#555555;white-space:nowrap;}
|
||||
.dropdown-menu li>a:hover,.dropdown-menu .active>a,.dropdown-menu .active>a:hover{color:#ffffff;text-decoration:none;background-color:#0088cc;}
|
||||
.dropdown.open{*z-index:1000;}.dropdown.open .dropdown-toggle{color:#ffffff;background:#ccc;background:rgba(0, 0, 0, 0.3);}
|
||||
.dropdown.open .dropdown-menu{display:block;}
|
||||
.typeahead{margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
|
||||
.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #eee;border:1px solid rgba(0, 0, 0, 0.05);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);}.well blockquote{border-color:#ddd;border-color:rgba(0, 0, 0, 0.15);}
|
||||
.fade{-webkit-transition:opacity 0.15s linear;-moz-transition:opacity 0.15s linear;-ms-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear;opacity:0;}.fade.in{opacity:1;}
|
||||
.collapse{-webkit-transition:height 0.35s ease;-moz-transition:height 0.35s ease;-ms-transition:height 0.35s ease;-o-transition:height 0.35s ease;transition:height 0.35s ease;position:relative;overflow:hidden;height:0;}.collapse.in{height:auto;}
|
||||
.close{float:right;font-size:20px;font-weight:bold;line-height:18px;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20);}.close:hover{color:#000000;text-decoration:none;opacity:0.4;filter:alpha(opacity=40);cursor:pointer;}
|
||||
.btn{display:inline-block;padding:4px 10px 4px;margin-bottom:0;font-size:13px;line-height:18px;color:#333333;text-align:center;text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);vertical-align:middle;background-color:#f5f5f5;background-image:-moz-linear-gradient(top, #ffffff, #e6e6e6);background-image:-ms-linear-gradient(top, #ffffff, #e6e6e6);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));background-image:-webkit-linear-gradient(top, #ffffff, #e6e6e6);background-image:-o-linear-gradient(top, #ffffff, #e6e6e6);background-image:linear-gradient(top, #ffffff, #e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border:1px solid #ccc;border-bottom-color:#bbb;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);cursor:pointer;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);*margin-left:.3em;}.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{background-color:#e6e6e6;}
|
||||
.btn:active,.btn.active{background-color:#cccccc \9;}
|
||||
.btn:first-child{*margin-left:0;}
|
||||
.btn:hover{color:#333333;text-decoration:none;background-color:#e6e6e6;background-position:0 -15px;-webkit-transition:background-position 0.1s linear;-moz-transition:background-position 0.1s linear;-ms-transition:background-position 0.1s linear;-o-transition:background-position 0.1s linear;transition:background-position 0.1s linear;}
|
||||
.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}
|
||||
.btn.active,.btn:active{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);background-color:#e6e6e6;background-color:#d9d9d9 \9;outline:0;}
|
||||
.btn.disabled,.btn[disabled]{cursor:default;background-image:none;background-color:#e6e6e6;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}
|
||||
.btn-large{padding:9px 14px;font-size:15px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;}
|
||||
.btn-large [class^="icon-"]{margin-top:1px;}
|
||||
.btn-small{padding:5px 9px;font-size:11px;line-height:16px;}
|
||||
.btn-small [class^="icon-"]{margin-top:-1px;}
|
||||
.btn-mini{padding:2px 6px;font-size:11px;line-height:14px;}
|
||||
.btn-primary,.btn-primary:hover,.btn-warning,.btn-warning:hover,.btn-danger,.btn-danger:hover,.btn-success,.btn-success:hover,.btn-info,.btn-info:hover,.btn-inverse,.btn-inverse:hover{text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);color:#ffffff;}
|
||||
.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-dark.active{color:rgba(255, 255, 255, 0.75);}
|
||||
.btn-primary{background-color:#006dcc;background-image:-moz-linear-gradient(top, #0088cc, #0044cc);background-image:-ms-linear-gradient(top, #0088cc, #0044cc);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));background-image:-webkit-linear-gradient(top, #0088cc, #0044cc);background-image:-o-linear-gradient(top, #0088cc, #0044cc);background-image:linear-gradient(top, #0088cc, #0044cc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);border-color:#0044cc #0044cc #002a80;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{background-color:#0044cc;}
|
||||
.btn-primary:active,.btn-primary.active{background-color:#003399 \9;}
|
||||
.btn-warning{background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-ms-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(top, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbb450', endColorstr='#f89406', GradientType=0);border-color:#f89406 #f89406 #ad6704;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{background-color:#f89406;}
|
||||
.btn-warning:active,.btn-warning.active{background-color:#c67605 \9;}
|
||||
.btn-danger{background-color:#da4f49;background-image:-moz-linear-gradient(top, #ee5f5b, #bd362f);background-image:-ms-linear-gradient(top, #ee5f5b, #bd362f);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));background-image:-webkit-linear-gradient(top, #ee5f5b, #bd362f);background-image:-o-linear-gradient(top, #ee5f5b, #bd362f);background-image:linear-gradient(top, #ee5f5b, #bd362f);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#bd362f', GradientType=0);border-color:#bd362f #bd362f #802420;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{background-color:#bd362f;}
|
||||
.btn-danger:active,.btn-danger.active{background-color:#942a25 \9;}
|
||||
.btn-success{background-color:#5bb75b;background-image:-moz-linear-gradient(top, #62c462, #51a351);background-image:-ms-linear-gradient(top, #62c462, #51a351);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));background-image:-webkit-linear-gradient(top, #62c462, #51a351);background-image:-o-linear-gradient(top, #62c462, #51a351);background-image:linear-gradient(top, #62c462, #51a351);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#51a351', GradientType=0);border-color:#51a351 #51a351 #387038;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{background-color:#51a351;}
|
||||
.btn-success:active,.btn-success.active{background-color:#408140 \9;}
|
||||
.btn-info{background-color:#49afcd;background-image:-moz-linear-gradient(top, #5bc0de, #2f96b4);background-image:-ms-linear-gradient(top, #5bc0de, #2f96b4);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));background-image:-webkit-linear-gradient(top, #5bc0de, #2f96b4);background-image:-o-linear-gradient(top, #5bc0de, #2f96b4);background-image:linear-gradient(top, #5bc0de, #2f96b4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#2f96b4', GradientType=0);border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{background-color:#2f96b4;}
|
||||
.btn-info:active,.btn-info.active{background-color:#24748c \9;}
|
||||
.btn-inverse{background-color:#393939;background-image:-moz-linear-gradient(top, #454545, #262626);background-image:-ms-linear-gradient(top, #454545, #262626);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#454545), to(#262626));background-image:-webkit-linear-gradient(top, #454545, #262626);background-image:-o-linear-gradient(top, #454545, #262626);background-image:linear-gradient(top, #454545, #262626);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#454545', endColorstr='#262626', GradientType=0);border-color:#262626 #262626 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{background-color:#262626;}
|
||||
.btn-inverse:active,.btn-inverse.active{background-color:#0c0c0c \9;}
|
||||
button.btn,input[type="submit"].btn{*padding-top:2px;*padding-bottom:2px;}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0;}
|
||||
button.btn.large,input[type="submit"].btn.large{*padding-top:7px;*padding-bottom:7px;}
|
||||
button.btn.small,input[type="submit"].btn.small{*padding-top:3px;*padding-bottom:3px;}
|
||||
.btn-group{position:relative;*zoom:1;*margin-left:.3em;}.btn-group:before,.btn-group:after{display:table;content:"";}
|
||||
.btn-group:after{clear:both;}
|
||||
.btn-group:first-child{*margin-left:0;}
|
||||
.btn-group+.btn-group{margin-left:5px;}
|
||||
.btn-toolbar{margin-top:9px;margin-bottom:9px;}.btn-toolbar .btn-group{display:inline-block;*display:inline;*zoom:1;}
|
||||
.btn-group .btn{position:relative;float:left;margin-left:-1px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
|
||||
.btn-group .btn:first-child{margin-left:0;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;}
|
||||
.btn-group .btn:last-child,.btn-group .dropdown-toggle{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;}
|
||||
.btn-group .btn.large:first-child{margin-left:0;-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px;}
|
||||
.btn-group .btn.large:last-child,.btn-group .large.dropdown-toggle{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;}
|
||||
.btn-group .btn:hover,.btn-group .btn:focus,.btn-group .btn:active,.btn-group .btn.active{z-index:2;}
|
||||
.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0;}
|
||||
.btn-group .dropdown-toggle{padding-left:8px;padding-right:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255, 255, 255, 0.125),inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 1px 0 0 rgba(255, 255, 255, 0.125),inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 1px 0 0 rgba(255, 255, 255, 0.125),inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);*padding-top:5px;*padding-bottom:5px;}
|
||||
.btn-group.open{*z-index:1000;}.btn-group.open .dropdown-menu{display:block;margin-top:1px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;}
|
||||
.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 1px 6px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 6px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 6px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);}
|
||||
.btn .caret{margin-top:7px;margin-left:0;}
|
||||
.btn:hover .caret,.open.btn-group .caret{opacity:1;filter:alpha(opacity=100);}
|
||||
.btn-primary .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#ffffff;opacity:0.75;filter:alpha(opacity=75);}
|
||||
.btn-small .caret{margin-top:4px;}
|
||||
.alert{padding:8px 35px 8px 14px;margin-bottom:18px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
|
||||
.alert,.alert-heading{color:#c09853;}
|
||||
.alert .close{position:relative;top:-2px;right:-21px;line-height:18px;}
|
||||
.alert-success{background-color:#dff0d8;border-color:#d6e9c6;}
|
||||
.alert-success,.alert-success .alert-heading{color:#468847;}
|
||||
.alert-danger,.alert-error{background-color:#f2dede;border-color:#eed3d7;}
|
||||
.alert-danger,.alert-error,.alert-danger .alert-heading,.alert-error .alert-heading{color:#b94a48;}
|
||||
.alert-info{background-color:#d9edf7;border-color:#bce8f1;}
|
||||
.alert-info,.alert-info .alert-heading{color:#3a87ad;}
|
||||
.alert-block{padding-top:14px;padding-bottom:14px;}
|
||||
.alert-block>p,.alert-block>ul{margin-bottom:0;}
|
||||
.alert-block p+p{margin-top:5px;}
|
||||
.nav{margin-left:0;margin-bottom:18px;list-style:none;}
|
||||
.nav>li>a{display:block;}
|
||||
.nav>li>a:hover{text-decoration:none;background-color:#eeeeee;}
|
||||
.nav .nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:18px;color:#999999;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);text-transform:uppercase;}
|
||||
.nav li+.nav-header{margin-top:9px;}
|
||||
.nav-list{padding-left:14px;padding-right:14px;margin-bottom:0;}
|
||||
.nav-list>li>a,.nav-list .nav-header{margin-left:-15px;margin-right:-15px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);}
|
||||
.nav-list>li>a{padding:3px 15px;}
|
||||
.nav-list .active>a,.nav-list .active>a:hover{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.2);background-color:#0088cc;}
|
||||
.nav-list [class^="icon-"]{margin-right:2px;}
|
||||
.nav-tabs,.nav-pills{*zoom:1;}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;content:"";}
|
||||
.nav-tabs:after,.nav-pills:after{clear:both;}
|
||||
.nav-tabs>li,.nav-pills>li{float:left;}
|
||||
.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px;}
|
||||
.nav-tabs{border-bottom:1px solid #ddd;}
|
||||
.nav-tabs>li{margin-bottom:-1px;}
|
||||
.nav-tabs>li>a{padding-top:9px;padding-bottom:9px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #dddddd;}
|
||||
.nav-tabs>.active>a,.nav-tabs>.active>a:hover{color:#555555;background-color:#ffffff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default;}
|
||||
.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;}
|
||||
.nav-pills .active>a,.nav-pills .active>a:hover{color:#ffffff;background-color:#0088cc;}
|
||||
.nav-stacked>li{float:none;}
|
||||
.nav-stacked>li>a{margin-right:0;}
|
||||
.nav-tabs.nav-stacked{border-bottom:0;}
|
||||
.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
|
||||
.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}
|
||||
.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;}
|
||||
.nav-tabs.nav-stacked>li>a:hover{border-color:#ddd;z-index:2;}
|
||||
.nav-pills.nav-stacked>li>a{margin-bottom:3px;}
|
||||
.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px;}
|
||||
.nav-tabs .dropdown-menu,.nav-pills .dropdown-menu{margin-top:1px;border-width:1px;}
|
||||
.nav-pills .dropdown-menu{-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
|
||||
.nav-tabs .dropdown-toggle .caret,.nav-pills .dropdown-toggle .caret{border-top-color:#0088cc;margin-top:6px;}
|
||||
.nav-tabs .dropdown-toggle:hover .caret,.nav-pills .dropdown-toggle:hover .caret{border-top-color:#005580;}
|
||||
.nav-tabs .active .dropdown-toggle .caret,.nav-pills .active .dropdown-toggle .caret{border-top-color:#333333;}
|
||||
.nav>.dropdown.active>a:hover{color:#000000;cursor:pointer;}
|
||||
.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>.open.active>a:hover{color:#ffffff;background-color:#999999;border-color:#999999;}
|
||||
.nav .open .caret,.nav .open.active .caret,.nav .open a:hover .caret{border-top-color:#ffffff;opacity:1;filter:alpha(opacity=100);}
|
||||
.tabs-stacked .open>a:hover{border-color:#999999;}
|
||||
.tabbable{*zoom:1;}.tabbable:before,.tabbable:after{display:table;content:"";}
|
||||
.tabbable:after{clear:both;}
|
||||
.tab-content{overflow:hidden;}
|
||||
.tabs-below .nav-tabs,.tabs-right .nav-tabs,.tabs-left .nav-tabs{border-bottom:0;}
|
||||
.tab-content>.tab-pane,.pill-content>.pill-pane{display:none;}
|
||||
.tab-content>.active,.pill-content>.active{display:block;}
|
||||
.tabs-below .nav-tabs{border-top:1px solid #ddd;}
|
||||
.tabs-below .nav-tabs>li{margin-top:-1px;margin-bottom:0;}
|
||||
.tabs-below .nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;}.tabs-below .nav-tabs>li>a:hover{border-bottom-color:transparent;border-top-color:#ddd;}
|
||||
.tabs-below .nav-tabs .active>a,.tabs-below .nav-tabs .active>a:hover{border-color:transparent #ddd #ddd #ddd;}
|
||||
.tabs-left .nav-tabs>li,.tabs-right .nav-tabs>li{float:none;}
|
||||
.tabs-left .nav-tabs>li>a,.tabs-right .nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px;}
|
||||
.tabs-left .nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd;}
|
||||
.tabs-left .nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;}
|
||||
.tabs-left .nav-tabs>li>a:hover{border-color:#eeeeee #dddddd #eeeeee #eeeeee;}
|
||||
.tabs-left .nav-tabs .active>a,.tabs-left .nav-tabs .active>a:hover{border-color:#ddd transparent #ddd #ddd;*border-right-color:#ffffff;}
|
||||
.tabs-right .nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd;}
|
||||
.tabs-right .nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}
|
||||
.tabs-right .nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #eeeeee #dddddd;}
|
||||
.tabs-right .nav-tabs .active>a,.tabs-right .nav-tabs .active>a:hover{border-color:#ddd #ddd #ddd transparent;*border-left-color:#ffffff;}
|
||||
.navbar{overflow:visible;margin-bottom:18px;}
|
||||
.navbar-inner{padding-left:20px;padding-right:20px;background-color:#2c2c2c;background-image:-moz-linear-gradient(top, #333333, #222222);background-image:-ms-linear-gradient(top, #333333, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222));background-image:-webkit-linear-gradient(top, #333333, #222222);background-image:-o-linear-gradient(top, #333333, #222222);background-image:linear-gradient(top, #333333, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1);-moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1);box-shadow:0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1);}
|
||||
.btn-navbar{display:none;float:right;padding:7px 10px;margin-left:5px;margin-right:5px;background-color:#2c2c2c;background-image:-moz-linear-gradient(top, #333333, #222222);background-image:-ms-linear-gradient(top, #333333, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222));background-image:-webkit-linear-gradient(top, #333333, #222222);background-image:-o-linear-gradient(top, #333333, #222222);background-image:linear-gradient(top, #333333, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);border-color:#222222 #222222 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.075);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.075);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.075);}.btn-navbar:hover,.btn-navbar:active,.btn-navbar.active,.btn-navbar.disabled,.btn-navbar[disabled]{background-color:#222222;}
|
||||
.btn-navbar:active,.btn-navbar.active{background-color:#080808 \9;}
|
||||
.btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);-moz-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);}
|
||||
.btn-navbar .icon-bar+.icon-bar{margin-top:3px;}
|
||||
.nav-collapse.collapse{height:auto;}
|
||||
.navbar .brand:hover{text-decoration:none;}
|
||||
.navbar .brand{float:left;display:block;padding:8px 20px 12px;margin-left:-20px;font-size:20px;font-weight:200;line-height:1;color:#ffffff;}
|
||||
.navbar .navbar-text{margin-bottom:0;line-height:40px;color:#999999;}.navbar .navbar-text a:hover{color:#ffffff;background-color:transparent;}
|
||||
.navbar .btn,.navbar .btn-group{margin-top:5px;}
|
||||
.navbar .btn-group .btn{margin-top:0;}
|
||||
.navbar-form{margin-bottom:0;*zoom:1;}.navbar-form:before,.navbar-form:after{display:table;content:"";}
|
||||
.navbar-form:after{clear:both;}
|
||||
.navbar-form input,.navbar-form select{display:inline-block;margin-top:5px;margin-bottom:0;}
|
||||
.navbar-form .radio,.navbar-form .checkbox{margin-top:5px;}
|
||||
.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px;}
|
||||
.navbar-form .input-append,.navbar-form .input-prepend{margin-top:6px;white-space:nowrap;}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0;}
|
||||
.navbar-search{position:relative;float:left;margin-top:6px;margin-bottom:0;}.navbar-search .search-query{padding:4px 9px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;color:#ffffff;color:rgba(255, 255, 255, 0.75);background:#666;background:rgba(255, 255, 255, 0.3);border:1px solid #111;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.15);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.15);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.15);-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none;}.navbar-search .search-query :-moz-placeholder{color:#eeeeee;}
|
||||
.navbar-search .search-query::-webkit-input-placeholder{color:#eeeeee;}
|
||||
.navbar-search .search-query:hover{color:#ffffff;background-color:#999999;background-color:rgba(255, 255, 255, 0.5);}
|
||||
.navbar-search .search-query:focus,.navbar-search .search-query.focused{padding:5px 10px;color:#333333;text-shadow:0 1px 0 #ffffff;background-color:#ffffff;border:0;-webkit-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);-moz-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);box-shadow:0 0 3px rgba(0, 0, 0, 0.15);outline:0;}
|
||||
.navbar-fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030;}
|
||||
.navbar-fixed-top .navbar-inner{padding-left:0;padding-right:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
|
||||
.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0;}
|
||||
.navbar .nav.pull-right{float:right;}
|
||||
.navbar .nav>li{display:block;float:left;}
|
||||
.navbar .nav>li>a{float:none;padding:10px 10px 11px;line-height:19px;color:#999999;text-decoration:none;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);}
|
||||
.navbar .nav>li>a:hover{background-color:transparent;color:#ffffff;text-decoration:none;}
|
||||
.navbar .nav .active>a,.navbar .nav .active>a:hover{color:#ffffff;text-decoration:none;background-color:#222222;}
|
||||
.navbar .divider-vertical{height:40px;width:1px;margin:0 9px;overflow:hidden;background-color:#222222;border-right:1px solid #333333;}
|
||||
.navbar .nav.pull-right{margin-left:10px;margin-right:0;}
|
||||
.navbar .dropdown-menu{margin-top:1px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.navbar .dropdown-menu:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0, 0, 0, 0.2);position:absolute;top:-7px;left:9px;}
|
||||
.navbar .dropdown-menu:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #ffffff;position:absolute;top:-6px;left:10px;}
|
||||
.navbar .nav .dropdown-toggle .caret,.navbar .nav .open.dropdown .caret{border-top-color:#ffffff;}
|
||||
.navbar .nav .active .caret{opacity:1;filter:alpha(opacity=100);}
|
||||
.navbar .nav .open>.dropdown-toggle,.navbar .nav .active>.dropdown-toggle,.navbar .nav .open.active>.dropdown-toggle{background-color:transparent;}
|
||||
.navbar .nav .active>.dropdown-toggle:hover{color:#ffffff;}
|
||||
.navbar .nav.pull-right .dropdown-menu{left:auto;right:0;}.navbar .nav.pull-right .dropdown-menu:before{left:auto;right:12px;}
|
||||
.navbar .nav.pull-right .dropdown-menu:after{left:auto;right:13px;}
|
||||
.breadcrumb{padding:7px 14px;margin:0 0 18px;background-color:#fbfbfb;background-image:-moz-linear-gradient(top, #ffffff, #f5f5f5);background-image:-ms-linear-gradient(top, #ffffff, #f5f5f5);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f5f5f5));background-image:-webkit-linear-gradient(top, #ffffff, #f5f5f5);background-image:-o-linear-gradient(top, #ffffff, #f5f5f5);background-image:linear-gradient(top, #ffffff, #f5f5f5);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f5f5f5', GradientType=0);border:1px solid #ddd;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;}.breadcrumb li{display:inline-block;text-shadow:0 1px 0 #ffffff;}
|
||||
.breadcrumb .divider{padding:0 5px;color:#999999;}
|
||||
.breadcrumb .active a{color:#333333;}
|
||||
.pagination{height:36px;margin:18px 0;}
|
||||
.pagination ul{display:inline-block;*display:inline;*zoom:1;margin-left:0;margin-bottom:0;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);}
|
||||
.pagination li{display:inline;}
|
||||
.pagination a{float:left;padding:0 14px;line-height:34px;text-decoration:none;border:1px solid #ddd;border-left-width:0;}
|
||||
.pagination a:hover,.pagination .active a{background-color:#f5f5f5;}
|
||||
.pagination .active a{color:#999999;cursor:default;}
|
||||
.pagination .disabled a,.pagination .disabled a:hover{color:#999999;background-color:transparent;cursor:default;}
|
||||
.pagination li:first-child a{border-left-width:1px;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;}
|
||||
.pagination li:last-child a{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;}
|
||||
.pagination-centered{text-align:center;}
|
||||
.pagination-right{text-align:right;}
|
||||
.pager{margin-left:0;margin-bottom:18px;list-style:none;text-align:center;*zoom:1;}.pager:before,.pager:after{display:table;content:"";}
|
||||
.pager:after{clear:both;}
|
||||
.pager li{display:inline;}
|
||||
.pager a{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;}
|
||||
.pager a:hover{text-decoration:none;background-color:#f5f5f5;}
|
||||
.pager .next a{float:right;}
|
||||
.pager .previous a{float:left;}
|
||||
.modal-open .dropdown-menu{z-index:2050;}
|
||||
.modal-open .dropdown.open{*z-index:2050;}
|
||||
.modal-open .popover{z-index:2060;}
|
||||
.modal-open .tooltip{z-index:2070;}
|
||||
.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000;}.modal-backdrop.fade{opacity:0;}
|
||||
.modal-backdrop,.modal-backdrop.fade.in{opacity:0.8;filter:alpha(opacity=80);}
|
||||
.modal{position:fixed;top:50%;left:50%;z-index:1050;max-height:500px;overflow:auto;width:560px;margin:-250px 0 0 -280px;background-color:#ffffff;border:1px solid #999;border:1px solid rgba(0, 0, 0, 0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;}.modal.fade{-webkit-transition:opacity .3s linear, top .3s ease-out;-moz-transition:opacity .3s linear, top .3s ease-out;-ms-transition:opacity .3s linear, top .3s ease-out;-o-transition:opacity .3s linear, top .3s ease-out;transition:opacity .3s linear, top .3s ease-out;top:-25%;}
|
||||
.modal.fade.in{top:50%;}
|
||||
.modal-header{padding:9px 15px;border-bottom:1px solid #eee;}.modal-header .close{margin-top:2px;}
|
||||
.modal-body{padding:15px;}
|
||||
.modal-body .modal-form{margin-bottom:0;}
|
||||
.modal-footer{padding:14px 15px 15px;margin-bottom:0;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;*zoom:1;}.modal-footer:before,.modal-footer:after{display:table;content:"";}
|
||||
.modal-footer:after{clear:both;}
|
||||
.modal-footer .btn{float:right;margin-left:5px;margin-bottom:0;}
|
||||
.tooltip{position:absolute;z-index:1020;display:block;visibility:visible;padding:5px;font-size:11px;opacity:0;filter:alpha(opacity=0);}.tooltip.in{opacity:0.8;filter:alpha(opacity=80);}
|
||||
.tooltip.top{margin-top:-2px;}
|
||||
.tooltip.right{margin-left:2px;}
|
||||
.tooltip.bottom{margin-top:2px;}
|
||||
.tooltip.left{margin-left:-2px;}
|
||||
.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000000;}
|
||||
.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid #000000;}
|
||||
.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid #000000;}
|
||||
.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:5px solid #000000;}
|
||||
.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;text-decoration:none;background-color:#000000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
|
||||
.tooltip-arrow{position:absolute;width:0;height:0;}
|
||||
.popover{position:absolute;top:0;left:0;z-index:1010;display:none;padding:5px;}.popover.top{margin-top:-5px;}
|
||||
.popover.right{margin-left:5px;}
|
||||
.popover.bottom{margin-top:5px;}
|
||||
.popover.left{margin-left:-5px;}
|
||||
.popover.top .arrow{bottom:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000000;}
|
||||
.popover.right .arrow{top:50%;left:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:5px solid #000000;}
|
||||
.popover.bottom .arrow{top:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid #000000;}
|
||||
.popover.left .arrow{top:50%;right:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid #000000;}
|
||||
.popover .arrow{position:absolute;width:0;height:0;}
|
||||
.popover-inner{padding:3px;width:280px;overflow:hidden;background:#000000;background:rgba(0, 0, 0, 0.8);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);}
|
||||
.popover-title{padding:9px 15px;line-height:1;background-color:#f5f5f5;border-bottom:1px solid #eee;-webkit-border-radius:3px 3px 0 0;-moz-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;}
|
||||
.popover-content{padding:14px;background-color:#ffffff;-webkit-border-radius:0 0 3px 3px;-moz-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;}.popover-content p,.popover-content ul,.popover-content ol{margin-bottom:0;}
|
||||
.thumbnails{margin-left:-20px;list-style:none;*zoom:1;}.thumbnails:before,.thumbnails:after{display:table;content:"";}
|
||||
.thumbnails:after{clear:both;}
|
||||
.thumbnails>li{float:left;margin:0 0 18px 20px;}
|
||||
.thumbnail{display:block;padding:4px;line-height:1;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);}
|
||||
a.thumbnail:hover{border-color:#0088cc;-webkit-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);-moz-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);}
|
||||
.thumbnail>img{display:block;max-width:100%;margin-left:auto;margin-right:auto;}
|
||||
.thumbnail .caption{padding:9px;}
|
||||
.label{padding:2px 4px 3px;font-size:11.049999999999999px;font-weight:bold;color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#999999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
|
||||
.label:hover{color:#ffffff;text-decoration:none;}
|
||||
.label-important{background-color:#b94a48;}
|
||||
.label-important:hover{background-color:#953b39;}
|
||||
.label-warning{background-color:#f89406;}
|
||||
.label-warning:hover{background-color:#c67605;}
|
||||
.label-success{background-color:#468847;}
|
||||
.label-success:hover{background-color:#356635;}
|
||||
.label-info{background-color:#3a87ad;}
|
||||
.label-info:hover{background-color:#2d6987;}
|
||||
@-webkit-keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}@-moz-keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}@keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}.progress{overflow:hidden;height:18px;margin-bottom:18px;background-color:#f7f7f7;background-image:-moz-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-ms-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));background-image:-webkit-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-o-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:linear-gradient(top, #f5f5f5, #f9f9f9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f5f5f5', endColorstr='#f9f9f9', GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
|
||||
.progress .bar{width:0%;height:18px;color:#ffffff;font-size:12px;text-align:center;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top, #149bdf, #0480be);background-image:-ms-linear-gradient(top, #149bdf, #0480be);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));background-image:-webkit-linear-gradient(top, #149bdf, #0480be);background-image:-o-linear-gradient(top, #149bdf, #0480be);background-image:linear-gradient(top, #149bdf, #0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#149bdf', endColorstr='#0480be', GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width 0.6s ease;-moz-transition:width 0.6s ease;-ms-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease;}
|
||||
.progress-striped .bar{background-color:#62c462;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px;}
|
||||
.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite;}
|
||||
.progress-danger .bar{background-color:#dd514c;background-image:-moz-linear-gradient(top, #ee5f5b, #c43c35);background-image:-ms-linear-gradient(top, #ee5f5b, #c43c35);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));background-image:-webkit-linear-gradient(top, #ee5f5b, #c43c35);background-image:-o-linear-gradient(top, #ee5f5b, #c43c35);background-image:linear-gradient(top, #ee5f5b, #c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0);}
|
||||
.progress-danger.progress-striped .bar{background-color:#ee5f5b;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}
|
||||
.progress-success .bar{background-color:#5eb95e;background-image:-moz-linear-gradient(top, #62c462, #57a957);background-image:-ms-linear-gradient(top, #62c462, #57a957);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));background-image:-webkit-linear-gradient(top, #62c462, #57a957);background-image:-o-linear-gradient(top, #62c462, #57a957);background-image:linear-gradient(top, #62c462, #57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0);}
|
||||
.progress-success.progress-striped .bar{background-color:#62c462;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}
|
||||
.progress-info .bar{background-color:#4bb1cf;background-image:-moz-linear-gradient(top, #5bc0de, #339bb9);background-image:-ms-linear-gradient(top, #5bc0de, #339bb9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9));background-image:-webkit-linear-gradient(top, #5bc0de, #339bb9);background-image:-o-linear-gradient(top, #5bc0de, #339bb9);background-image:linear-gradient(top, #5bc0de, #339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0);}
|
||||
.progress-info.progress-striped .bar{background-color:#5bc0de;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}
|
||||
.accordion{margin-bottom:18px;}
|
||||
.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
|
||||
.accordion-heading{border-bottom:0;}
|
||||
.accordion-heading .accordion-toggle{display:block;padding:8px 15px;}
|
||||
.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5;}
|
||||
.carousel{position:relative;margin-bottom:18px;line-height:1;}
|
||||
.carousel-inner{overflow:hidden;width:100%;position:relative;}
|
||||
.carousel .item{display:none;position:relative;-webkit-transition:0.6s ease-in-out left;-moz-transition:0.6s ease-in-out left;-ms-transition:0.6s ease-in-out left;-o-transition:0.6s ease-in-out left;transition:0.6s ease-in-out left;}
|
||||
.carousel .item>img{display:block;line-height:1;}
|
||||
.carousel .active,.carousel .next,.carousel .prev{display:block;}
|
||||
.carousel .active{left:0;}
|
||||
.carousel .next,.carousel .prev{position:absolute;top:0;width:100%;}
|
||||
.carousel .next{left:100%;}
|
||||
.carousel .prev{left:-100%;}
|
||||
.carousel .next.left,.carousel .prev.right{left:0;}
|
||||
.carousel .active.left{left:-100%;}
|
||||
.carousel .active.right{left:100%;}
|
||||
.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#ffffff;text-align:center;background:#222222;border:3px solid #ffffff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:0.5;filter:alpha(opacity=50);}.carousel-control.right{left:auto;right:15px;}
|
||||
.carousel-control:hover{color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90);}
|
||||
.carousel-caption{position:absolute;left:0;right:0;bottom:0;padding:10px 15px 5px;background:#333333;background:rgba(0, 0, 0, 0.75);}
|
||||
.carousel-caption h4,.carousel-caption p{color:#ffffff;}
|
||||
.hero-unit{padding:60px;margin-bottom:30px;background-color:#f5f5f5;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;}
|
||||
.hero-unit p{font-size:18px;font-weight:200;line-height:27px;}
|
||||
.pull-right{float:right;}
|
||||
.pull-left{float:left;}
|
||||
.hide{display:none;}
|
||||
.show{display:block;}
|
||||
.invisible{visibility:hidden;}
|
||||
@@ -1,207 +0,0 @@
|
||||
body {
|
||||
font-family: arial, helvetica, verdana, tahoma, sans-serif;
|
||||
font-size: 0.9em;
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.row {
|
||||
clear: both;
|
||||
padding-top: 10px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
div.row label {
|
||||
float: left;
|
||||
width: 120px;
|
||||
padding: 3px 0;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
input {
|
||||
border: 1px solid #cccccc;
|
||||
color: inherit;
|
||||
background-color: #eee;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
input[type=text], input[type=password] {
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
/*input:hover {
|
||||
color: inherit;
|
||||
background-color: #ffffcc;
|
||||
}*/
|
||||
|
||||
input:focus {
|
||||
color: inherit;
|
||||
background-color: #ffffcc;
|
||||
}
|
||||
|
||||
textarea {
|
||||
border: 1px solid #cccccc;
|
||||
background-color: #eee;
|
||||
width: 300px;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
select {
|
||||
width: 145px;
|
||||
background-color: #eee;
|
||||
border: 1px solid #cccccc;
|
||||
}
|
||||
|
||||
td.odd {
|
||||
background: #F7F9Fb;
|
||||
}
|
||||
|
||||
td.even {
|
||||
|
||||
}
|
||||
|
||||
.title {
|
||||
float: left;
|
||||
width: 100%;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.title img {
|
||||
float: left;
|
||||
margin: 1px 3px;;
|
||||
}
|
||||
|
||||
.title h1 {
|
||||
float: left;
|
||||
margin: 5px;
|
||||
font-size: medium;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.lastrow {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.errorlist ul {
|
||||
float: left;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.errorlist li {
|
||||
margin-left: 10px;
|
||||
float: left;
|
||||
display: inline;
|
||||
color: red;
|
||||
}
|
||||
|
||||
.error {
|
||||
margin-left: 20px;
|
||||
color: red;
|
||||
font-size: small;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#id_username {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
#id_password {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
/* Mootools tooltips */
|
||||
.tip {
|
||||
display: none;
|
||||
position: absolute;
|
||||
color: #fff;
|
||||
z-index: 2;
|
||||
border: 1px solid #cccccc;
|
||||
}
|
||||
|
||||
.tip-title {
|
||||
font-weight: bold;
|
||||
font-size: 11px;
|
||||
margin: 0;
|
||||
color: #9FD4FF;
|
||||
padding: 8px 8px 4px;
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
.tip-text {
|
||||
font-size: 0.9em;
|
||||
padding: 4px 8px 8px;
|
||||
background: #eee;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
/*
|
||||
* clearfix related
|
||||
*/
|
||||
.clearfix:after {
|
||||
content: ".";
|
||||
display: block;
|
||||
clear: both;
|
||||
visibility: hidden;
|
||||
overflow: hidden;
|
||||
line-height: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.clearfix {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
html[xmlns] .clearfix {
|
||||
display: block;
|
||||
}
|
||||
|
||||
* html .clearfix {
|
||||
height: 1%;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/*
|
||||
* Domain admin form
|
||||
*/
|
||||
#createfrom {
|
||||
margin: 10px auto;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
#permform > #id_name {
|
||||
width: 180px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assign domains form
|
||||
*/
|
||||
#assignform #id_domains {
|
||||
width: 310px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Domain admins list
|
||||
*/
|
||||
#domainadmins {
|
||||
width: 100%;
|
||||
height: 140px;
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
Document : calendar.css
|
||||
Created on : 29.07.2009
|
||||
Author : jens klose
|
||||
Description:
|
||||
example styles for calendar
|
||||
*/
|
||||
.calendarForm{
|
||||
float:right;
|
||||
}
|
||||
.calendar{
|
||||
font-family:verdana,sans-serif;
|
||||
font-size:10px;
|
||||
float:None;
|
||||
}
|
||||
button.calendar{
|
||||
position:relative;
|
||||
top:-3px;
|
||||
left:1px;
|
||||
background-color:transparent;
|
||||
background-image:url(../pics/calendar.gif);
|
||||
border:none;
|
||||
margin: 0px;
|
||||
padding:0px;
|
||||
margin-right:3px;
|
||||
cursor:pointer;
|
||||
width:20px;
|
||||
height:20px;
|
||||
}
|
||||
input.calendar{
|
||||
cursor:pointer;
|
||||
border: 1px solid #87847F;
|
||||
height:12px;
|
||||
width:100px;
|
||||
color: #87847F;
|
||||
}
|
||||
div.calendar{
|
||||
background:white;
|
||||
border: 1px solid #87847F;
|
||||
width:180px
|
||||
}
|
||||
a.footer{
|
||||
color:#474747;
|
||||
padding:2px;
|
||||
}
|
||||
.calendar table{
|
||||
width:100%;
|
||||
}
|
||||
.calendar th,
|
||||
.calendar td{
|
||||
text-align:center;
|
||||
font-size:10px;
|
||||
padding: 0.1em 0.25em 0.1em 0.3em;
|
||||
}
|
||||
.calendar tbody td,
|
||||
.calendar .invalid{
|
||||
color:silver;
|
||||
}
|
||||
.calendar .valid{
|
||||
color:blue;
|
||||
font-weight:bold;
|
||||
cursor:pointer;
|
||||
}
|
||||
.calendar .valid.hover{
|
||||
background:#FFFF77;
|
||||
font-weight:bold;
|
||||
}
|
||||
.calendar caption a,
|
||||
.calendar .next{
|
||||
color:blue;
|
||||
font-weight:bold;
|
||||
padding:2px;
|
||||
cursor:pointer;
|
||||
}
|
||||
.calendar caption a,
|
||||
.calendar .prev{
|
||||
color:blue;
|
||||
font-weight:bold;
|
||||
padding:2px;
|
||||
}
|
||||
.calendar .active,
|
||||
.calendar .hilite,
|
||||
.calendar .inactive{
|
||||
color:white;
|
||||
background-color:#BE3916;
|
||||
font-weight:bold;
|
||||
}
|
||||
.calendar .active,
|
||||
.calendar .inactive{
|
||||
background-color:red;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 495 B |
@@ -0,0 +1,64 @@
|
||||
body {
|
||||
padding-top: 60px;
|
||||
}
|
||||
|
||||
#bottom-bar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
#pagination_bar {
|
||||
color: #999999 !important;
|
||||
}
|
||||
|
||||
.simplepagination ul {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.simplepagination li {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.simplepagination .disabled a,
|
||||
.simplepagination .disabled a:hover {
|
||||
background-color: transparent;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.sidebar-nav {
|
||||
padding: 9px 0;
|
||||
}
|
||||
|
||||
.form-horizontal .param-label {
|
||||
float: left;
|
||||
padding-top: 5px;
|
||||
text-align: left;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.form-horizontal .param-controls {
|
||||
margin-left: 210px;
|
||||
}
|
||||
|
||||
.form-horizontal .control-group {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.spaced select,
|
||||
.spaced input[type="text"] {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.padded5 {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.buttons_list .bset {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.buttons_list .active {
|
||||
display: block;
|
||||
}
|
||||
@@ -68,7 +68,7 @@ div#footer {
|
||||
|
||||
#menubar {
|
||||
margin: 5px;
|
||||
display: table;
|
||||
/*display: table;*/
|
||||
width: 735px;
|
||||
margin-top: 35px;
|
||||
}
|
||||
@@ -83,7 +83,7 @@ div#footer {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#menubar a, #menubar a:visited {
|
||||
/*#menubar a, #menubar a:visited {
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
@@ -91,7 +91,7 @@ div#footer {
|
||||
#menubar label {
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
}*/
|
||||
|
||||
#page {
|
||||
width: 100%;
|
||||
@@ -167,7 +167,7 @@ div#footer {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.menubar a, .menubar a:visited {
|
||||
/*.menubar a, .menubar a:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ div#footer {
|
||||
|
||||
.menubar .title {
|
||||
color: white;
|
||||
}
|
||||
}*/
|
||||
|
||||
.menubardropdown ul {
|
||||
background: white;
|
||||
|
||||
@@ -1,93 +1,19 @@
|
||||
html, body {
|
||||
font-family: arial, helvetica, verdana, tahoma, sans-serif;
|
||||
font-size: small;
|
||||
background: #153F65;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#loginbox {
|
||||
margin: 100px auto 10px auto;
|
||||
padding: 0 0 15px 0;
|
||||
font-size: 1em;
|
||||
width: 630px;
|
||||
}
|
||||
|
||||
#logo {
|
||||
float: left;
|
||||
text-align: center;
|
||||
width: 300px;
|
||||
margin-top: 10px;
|
||||
border-right: 1px solid #ccc;
|
||||
#logo {
|
||||
margin-top: 60px;
|
||||
}
|
||||
|
||||
#logo img {
|
||||
height: 90px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
#test {
|
||||
float: right;
|
||||
width: 300px;
|
||||
input[type="text"],
|
||||
input[type="password"] {
|
||||
width: 315px;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
.roundedbox {
|
||||
margin: 10px auto;
|
||||
padding: 10px;
|
||||
width: 610px;
|
||||
background: white;
|
||||
font-size: 1.1em;
|
||||
|
||||
border: 5px solid #333;
|
||||
border-radius: 10px;
|
||||
.form-actions {
|
||||
padding-right: 0px;
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
.roundedbox h1 {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: 1.2em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.roundedbox h2 {
|
||||
margin: 30px 10px 0 10px;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
.roundedbox h3 {
|
||||
font-size: small;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.roundedbox a, a:visited {
|
||||
font-weight: bold;
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/* Mootools tooltips */
|
||||
.tip {
|
||||
color: #fff;
|
||||
width: 139px;
|
||||
z-index: 13000;
|
||||
border: 1px solid #cccccc;
|
||||
}
|
||||
|
||||
.tip-title {
|
||||
font-weight: bold;
|
||||
font-size: 11px;
|
||||
margin: 0;
|
||||
color: #9FD4FF;
|
||||
padding: 8px 8px 4px;
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
.tip-text {
|
||||
font-size: 11px;
|
||||
padding: 4px 8px 8px;
|
||||
background: #eee;
|
||||
color: black;
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
@@ -1,31 +0,0 @@
|
||||
/**
|
||||
* Autocompleter.Local
|
||||
*
|
||||
* http://digitarald.de/project/autocompleter/
|
||||
*
|
||||
* @version 1.1.2
|
||||
*
|
||||
* @license MIT-style license
|
||||
* @author Harald Kirschner <mail [at] digitarald.de>
|
||||
* @copyright Author
|
||||
*/
|
||||
|
||||
Autocompleter.Local = new Class({
|
||||
|
||||
Extends: Autocompleter,
|
||||
|
||||
options: {
|
||||
minLength: 0,
|
||||
delay: 200
|
||||
},
|
||||
|
||||
initialize: function(element, tokens, options) {
|
||||
this.parent(element, options);
|
||||
this.tokens = tokens;
|
||||
},
|
||||
|
||||
query: function() {
|
||||
this.update(this.filter());
|
||||
}
|
||||
|
||||
});
|
||||
@@ -1,109 +0,0 @@
|
||||
/**
|
||||
* Autocompleter.Request
|
||||
*
|
||||
* http://digitarald.de/project/autocompleter/
|
||||
*
|
||||
* @version 1.1.2
|
||||
*
|
||||
* @license MIT-style license
|
||||
* @author Harald Kirschner <mail [at] digitarald.de>
|
||||
* @copyright Author
|
||||
*/
|
||||
|
||||
Autocompleter.Request = new Class({
|
||||
|
||||
Extends: Autocompleter,
|
||||
|
||||
options: {/*
|
||||
indicator: null,
|
||||
indicatorClass: null,
|
||||
onRequest: $empty,
|
||||
onComplete: $empty,*/
|
||||
postData: {},
|
||||
ajaxOptions: {},
|
||||
postVar: 'value'
|
||||
|
||||
},
|
||||
|
||||
query: function(){
|
||||
var data = $unlink(this.options.postData) || {};
|
||||
data[this.options.postVar] = this.queryValue;
|
||||
var indicator = $(this.options.indicator);
|
||||
if (indicator) indicator.setStyle('display', '');
|
||||
var cls = this.options.indicatorClass;
|
||||
if (cls) this.element.addClass(cls);
|
||||
this.fireEvent('onRequest', [this.element, this.request, data, this.queryValue]);
|
||||
this.request.send({'data': data});
|
||||
},
|
||||
|
||||
/**
|
||||
* queryResponse - abstract
|
||||
*
|
||||
* Inherated classes have to extend this function and use this.parent()
|
||||
*/
|
||||
queryResponse: function() {
|
||||
var indicator = $(this.options.indicator);
|
||||
if (indicator) indicator.setStyle('display', 'none');
|
||||
var cls = this.options.indicatorClass;
|
||||
if (cls) this.element.removeClass(cls);
|
||||
return this.fireEvent('onComplete', [this.element, this.request]);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Autocompleter.Request.JSON = new Class({
|
||||
|
||||
Extends: Autocompleter.Request,
|
||||
|
||||
initialize: function(el, url, options) {
|
||||
this.parent(el, options);
|
||||
this.request = new Request.JSON($merge({
|
||||
'url': url,
|
||||
'link': 'cancel'
|
||||
}, this.options.ajaxOptions)).addEvent('onComplete', this.queryResponse.bind(this));
|
||||
},
|
||||
|
||||
queryResponse: function(response) {
|
||||
this.parent();
|
||||
this.update(response);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Autocompleter.Request.HTML = new Class({
|
||||
|
||||
Extends: Autocompleter.Request,
|
||||
|
||||
initialize: function(el, url, options) {
|
||||
this.parent(el, options);
|
||||
this.request = new Request.HTML($merge({
|
||||
'url': url,
|
||||
'link': 'cancel',
|
||||
'update': this.choices
|
||||
}, this.options.ajaxOptions)).addEvent('onComplete', this.queryResponse.bind(this));
|
||||
},
|
||||
|
||||
queryResponse: function(tree, elements) {
|
||||
this.parent();
|
||||
if (!elements || !elements.length) {
|
||||
this.hideChoices();
|
||||
} else {
|
||||
this.choices.getChildren(this.options.choicesMatch).each(this.options.injectChoice || function(choice) {
|
||||
var value = choice.innerHTML;
|
||||
choice.inputValue = value;
|
||||
this.addChoiceEvents(choice.set('html', this.markQueryValue(value)));
|
||||
}, this);
|
||||
this.showChoices();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/* compatibility */
|
||||
|
||||
Autocompleter.Ajax = {
|
||||
Base: Autocompleter.Request,
|
||||
Json: Autocompleter.Request.JSON,
|
||||
Xhtml: Autocompleter.Request.HTML
|
||||
};
|
||||
@@ -1,442 +0,0 @@
|
||||
/**
|
||||
* Autocompleter
|
||||
*
|
||||
* http://digitarald.de/project/autocompleter/
|
||||
*
|
||||
* @version 1.1.2
|
||||
*
|
||||
* @license MIT-style license
|
||||
* @author Harald Kirschner <mail [at] digitarald.de>
|
||||
* @copyright Author
|
||||
*/
|
||||
|
||||
var Autocompleter = new Class({
|
||||
|
||||
Implements: [Options, Events],
|
||||
|
||||
options: {/*
|
||||
onOver: $empty,
|
||||
onSelect: $empty,
|
||||
onSelection: $empty,
|
||||
onShow: $empty,
|
||||
onHide: $empty,
|
||||
onBlur: $empty,
|
||||
onFocus: $empty,*/
|
||||
minLength: 1,
|
||||
markQuery: true,
|
||||
width: 'inherit',
|
||||
maxChoices: 10,
|
||||
injectChoice: null,
|
||||
customChoices: null,
|
||||
emptyChoices: null,
|
||||
visibleChoices: true,
|
||||
className: 'autocompleter-choices',
|
||||
zIndex: 42,
|
||||
delay: 400,
|
||||
observerOptions: {},
|
||||
fxOptions: {},
|
||||
|
||||
autoSubmit: false,
|
||||
overflow: false,
|
||||
overflowMargin: 25,
|
||||
selectFirst: false,
|
||||
filter: null,
|
||||
filterCase: false,
|
||||
filterSubset: false,
|
||||
forceSelect: false,
|
||||
selectMode: true,
|
||||
choicesMatch: null,
|
||||
|
||||
multiple: false,
|
||||
separator: ', ',
|
||||
separatorSplit: /\s*[,;]\s*/,
|
||||
autoTrim: false,
|
||||
allowDupes: false,
|
||||
|
||||
cache: true,
|
||||
relative: false
|
||||
},
|
||||
|
||||
initialize: function(element, options) {
|
||||
this.element = $(element);
|
||||
this.setOptions(options);
|
||||
this.build();
|
||||
this.observer = new Observer(this.element, this.prefetch.bind(this), $merge({
|
||||
'delay': this.options.delay
|
||||
}, this.options.observerOptions));
|
||||
this.queryValue = null;
|
||||
if (this.options.filter) this.filter = this.options.filter.bind(this);
|
||||
var mode = this.options.selectMode;
|
||||
this.typeAhead = (mode == 'type-ahead');
|
||||
this.selectMode = (mode === true) ? 'selection' : mode;
|
||||
this.cached = [];
|
||||
},
|
||||
|
||||
/**
|
||||
* build - Initialize DOM
|
||||
*
|
||||
* Builds the html structure for choices and appends the events to the element.
|
||||
* Override this function to modify the html generation.
|
||||
*/
|
||||
build: function() {
|
||||
if ($(this.options.customChoices)) {
|
||||
this.choices = this.options.customChoices;
|
||||
} else {
|
||||
this.choices = new Element('ul', {
|
||||
'class': this.options.className,
|
||||
'styles': {
|
||||
'zIndex': this.options.zIndex
|
||||
}
|
||||
}).inject(document.body);
|
||||
this.relative = false;
|
||||
if (this.options.relative) {
|
||||
this.choices.inject(this.element, 'after');
|
||||
this.relative = this.element.getOffsetParent();
|
||||
}
|
||||
this.fix = new OverlayFix(this.choices);
|
||||
}
|
||||
if (!this.options.separator.test(this.options.separatorSplit)) {
|
||||
this.options.separatorSplit = this.options.separator;
|
||||
}
|
||||
this.fx = (!this.options.fxOptions) ? null : new Fx.Tween(this.choices, $merge({
|
||||
'property': 'opacity',
|
||||
'link': 'cancel',
|
||||
'duration': 200
|
||||
}, this.options.fxOptions)).addEvent('onStart', Chain.prototype.clearChain).set(0);
|
||||
this.element.setProperty('autocomplete', 'off')
|
||||
.addEvent((Browser.Engine.trident || Browser.Engine.webkit) ? 'keydown' : 'keypress', this.onCommand.bind(this))
|
||||
.addEvent('click', this.onCommand.bind(this, [false]))
|
||||
.addEvent('focus', this.toggleFocus.create({bind: this, arguments: true, delay: 100}))
|
||||
.addEvent('blur', this.toggleFocus.create({bind: this, arguments: false, delay: 100}));
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
if (this.fix) this.fix.destroy();
|
||||
this.choices = this.selected = this.choices.destroy();
|
||||
},
|
||||
|
||||
toggleFocus: function(state) {
|
||||
this.focussed = state;
|
||||
if (!state) this.hideChoices(true);
|
||||
this.fireEvent((state) ? 'onFocus' : 'onBlur', [this.element]);
|
||||
},
|
||||
|
||||
onCommand: function(e) {
|
||||
if (!e && this.focussed) return this.prefetch();
|
||||
if (e && e.key && !e.shift) {
|
||||
switch (e.key) {
|
||||
case 'enter':
|
||||
if (this.element.value != this.opted) return true;
|
||||
if (this.selected && this.visible) {
|
||||
this.choiceSelect(this.selected);
|
||||
return !!(this.options.autoSubmit);
|
||||
}
|
||||
break;
|
||||
case 'up': case 'down':
|
||||
if (!this.prefetch() && this.queryValue !== null) {
|
||||
var up = (e.key == 'up');
|
||||
this.choiceOver((this.selected || this.choices)[
|
||||
(this.selected) ? ((up) ? 'getPrevious' : 'getNext') : ((up) ? 'getLast' : 'getFirst')
|
||||
](this.options.choicesMatch), true);
|
||||
}
|
||||
return false;
|
||||
case 'esc': case 'tab':
|
||||
this.hideChoices(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
setSelection: function(finish) {
|
||||
var input = this.selected.inputValue, value = input;
|
||||
var start = this.queryValue.length, end = input.length;
|
||||
if (input.substr(0, start).toLowerCase() != this.queryValue.toLowerCase()) start = 0;
|
||||
if (this.options.multiple) {
|
||||
var split = this.options.separatorSplit;
|
||||
value = this.element.value;
|
||||
start += this.queryIndex;
|
||||
end += this.queryIndex;
|
||||
var old = value.substr(this.queryIndex).split(split, 1)[0];
|
||||
value = value.substr(0, this.queryIndex) + input + value.substr(this.queryIndex + old.length);
|
||||
if (finish) {
|
||||
var tokens = value.split(this.options.separatorSplit).filter(function(entry) {
|
||||
return this.test(entry);
|
||||
}, /[^\s,]+/);
|
||||
if (!this.options.allowDupes) tokens = [].combine(tokens);
|
||||
var sep = this.options.separator;
|
||||
value = tokens.join(sep) + sep;
|
||||
end = value.length;
|
||||
}
|
||||
}
|
||||
this.observer.setValue(value);
|
||||
this.opted = value;
|
||||
if (finish || this.selectMode == 'pick') start = end;
|
||||
this.element.selectRange(start, end);
|
||||
this.fireEvent('onSelection', [this.element, this.selected, value, input]);
|
||||
},
|
||||
|
||||
showChoices: function() {
|
||||
var match = this.options.choicesMatch, first = this.choices.getFirst(match);
|
||||
this.selected = this.selectedValue = null;
|
||||
if (this.fix) {
|
||||
var pos = this.element.getCoordinates(this.relative), width = this.options.width || 'auto';
|
||||
this.choices.setStyles({
|
||||
'left': pos.left,
|
||||
'top': pos.bottom,
|
||||
'width': (width === true || width == 'inherit') ? pos.width : width
|
||||
});
|
||||
}
|
||||
if (!first) return;
|
||||
if (!this.visible) {
|
||||
this.visible = true;
|
||||
this.choices.setStyle('display', '');
|
||||
if (this.fx) this.fx.start(1);
|
||||
this.fireEvent('onShow', [this.element, this.choices]);
|
||||
}
|
||||
if (this.options.selectFirst || this.typeAhead || first.inputValue == this.queryValue) this.choiceOver(first, this.typeAhead);
|
||||
var items = this.choices.getChildren(match), max = this.options.maxChoices;
|
||||
var styles = {'overflowY': 'hidden', 'height': ''};
|
||||
this.overflown = false;
|
||||
if (items.length > max) {
|
||||
var item = items[max - 1];
|
||||
styles.overflowY = 'scroll';
|
||||
styles.height = item.getCoordinates(this.choices).bottom;
|
||||
this.overflown = true;
|
||||
};
|
||||
this.choices.setStyles(styles);
|
||||
this.fix.show();
|
||||
if (this.options.visibleChoices) {
|
||||
var scroll = document.getScroll(),
|
||||
size = document.getSize(),
|
||||
coords = this.choices.getCoordinates();
|
||||
if (coords.right > scroll.x + size.x) scroll.x = coords.right - size.x;
|
||||
if (coords.bottom > scroll.y + size.y) scroll.y = coords.bottom - size.y;
|
||||
window.scrollTo(Math.min(scroll.x, coords.left), Math.min(scroll.y, coords.top));
|
||||
}
|
||||
},
|
||||
|
||||
hideChoices: function(clear) {
|
||||
if (clear) {
|
||||
var value = this.element.value;
|
||||
if (this.options.forceSelect) value = this.opted;
|
||||
if (this.options.autoTrim) {
|
||||
value = value.split(this.options.separatorSplit).filter($arguments(0)).join(this.options.separator);
|
||||
}
|
||||
this.observer.setValue(value);
|
||||
}
|
||||
if (!this.visible) return;
|
||||
this.visible = false;
|
||||
if (this.selected) this.selected.removeClass('autocompleter-selected');
|
||||
this.observer.clear();
|
||||
var hide = function(){
|
||||
this.choices.setStyle('display', 'none');
|
||||
this.fix.hide();
|
||||
}.bind(this);
|
||||
if (this.fx) this.fx.start(0).chain(hide);
|
||||
else hide();
|
||||
this.fireEvent('onHide', [this.element, this.choices]);
|
||||
},
|
||||
|
||||
prefetch: function() {
|
||||
var value = this.element.value, query = value;
|
||||
if (this.options.multiple) {
|
||||
var split = this.options.separatorSplit;
|
||||
var values = value.split(split);
|
||||
var index = this.element.getSelectedRange().start;
|
||||
var toIndex = value.substr(0, index).split(split);
|
||||
var last = toIndex.length - 1;
|
||||
index -= toIndex[last].length;
|
||||
query = values[last];
|
||||
}
|
||||
if (query.length < this.options.minLength) {
|
||||
this.hideChoices();
|
||||
} else {
|
||||
if (query === this.queryValue || (this.visible && query == this.selectedValue)) {
|
||||
if (this.visible) return false;
|
||||
this.showChoices();
|
||||
} else {
|
||||
this.queryValue = query;
|
||||
this.queryIndex = index;
|
||||
if (!this.fetchCached()) this.query();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
fetchCached: function() {
|
||||
return false;
|
||||
if (!this.options.cache
|
||||
|| !this.cached
|
||||
|| !this.cached.length
|
||||
|| this.cached.length >= this.options.maxChoices
|
||||
|| this.queryValue) return false;
|
||||
this.update(this.filter(this.cached));
|
||||
return true;
|
||||
},
|
||||
|
||||
update: function(tokens) {
|
||||
this.choices.empty();
|
||||
this.cached = tokens;
|
||||
var type = tokens && $type(tokens);
|
||||
if (!type || (type == 'array' && !tokens.length) || (type == 'hash' && !tokens.getLength())) {
|
||||
(this.options.emptyChoices || this.hideChoices).call(this);
|
||||
} else {
|
||||
if (this.options.maxChoices < tokens.length && !this.options.overflow) tokens.length = this.options.maxChoices;
|
||||
tokens.each(this.options.injectChoice || function(token){
|
||||
var choice = new Element('li', {'html': this.markQueryValue(token)});
|
||||
choice.inputValue = token;
|
||||
this.addChoiceEvents(choice).inject(this.choices);
|
||||
}, this);
|
||||
this.showChoices();
|
||||
}
|
||||
},
|
||||
|
||||
choiceOver: function(choice, selection) {
|
||||
if (!choice || choice == this.selected) return;
|
||||
if (this.selected) this.selected.removeClass('autocompleter-selected');
|
||||
this.selected = choice.addClass('autocompleter-selected');
|
||||
this.fireEvent('onSelect', [this.element, this.selected, selection]);
|
||||
if (!this.selectMode) this.opted = this.element.value;
|
||||
if (!selection) return;
|
||||
this.selectedValue = this.selected.inputValue;
|
||||
if (this.overflown) {
|
||||
var coords = this.selected.getCoordinates(this.choices), margin = this.options.overflowMargin,
|
||||
top = this.choices.scrollTop, height = this.choices.offsetHeight, bottom = top + height;
|
||||
if (coords.top - margin < top && top) this.choices.scrollTop = Math.max(coords.top - margin, 0);
|
||||
else if (coords.bottom + margin > bottom) this.choices.scrollTop = Math.min(coords.bottom - height + margin, bottom);
|
||||
}
|
||||
if (this.selectMode) this.setSelection();
|
||||
},
|
||||
|
||||
choiceSelect: function(choice) {
|
||||
if (choice) this.choiceOver(choice);
|
||||
this.setSelection(true);
|
||||
this.queryValue = false;
|
||||
this.hideChoices();
|
||||
},
|
||||
|
||||
filter: function(tokens) {
|
||||
return (tokens || this.tokens).filter(function(token) {
|
||||
return this.test(token);
|
||||
}, new RegExp(((this.options.filterSubset) ? '' : '^') + this.queryValue.escapeRegExp(), (this.options.filterCase) ? '' : 'i'));
|
||||
},
|
||||
|
||||
/**
|
||||
* markQueryValue
|
||||
*
|
||||
* Marks the queried word in the given string with <span class="autocompleter-queried">*</span>
|
||||
* Call this i.e. from your custom parseChoices, same for addChoiceEvents
|
||||
*
|
||||
* @param {String} Text
|
||||
* @return {String} Text
|
||||
*/
|
||||
markQueryValue: function(str) {
|
||||
return (!this.options.markQuery || !this.queryValue) ? str
|
||||
: str.replace(new RegExp('(' + ((this.options.filterSubset) ? '' : '^') + this.queryValue.escapeRegExp() + ')', (this.options.filterCase) ? '' : 'i'), '<span class="autocompleter-queried">$1</span>');
|
||||
},
|
||||
|
||||
/**
|
||||
* addChoiceEvents
|
||||
*
|
||||
* Appends the needed event handlers for a choice-entry to the given element.
|
||||
*
|
||||
* @param {Element} Choice entry
|
||||
* @return {Element} Choice entry
|
||||
*/
|
||||
addChoiceEvents: function(el) {
|
||||
return el.addEvents({
|
||||
'mouseover': this.choiceOver.bind(this, [el]),
|
||||
'click': this.choiceSelect.bind(this, [el])
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var OverlayFix = new Class({
|
||||
|
||||
initialize: function(el) {
|
||||
if (Browser.Engine.trident) {
|
||||
this.element = $(el);
|
||||
this.relative = this.element.getOffsetParent();
|
||||
this.fix = new Element('iframe', {
|
||||
'frameborder': '0',
|
||||
'scrolling': 'no',
|
||||
'src': 'javascript:false;',
|
||||
'styles': {
|
||||
'position': 'absolute',
|
||||
'border': 'none',
|
||||
'display': 'none',
|
||||
'filter': 'progid:DXImageTransform.Microsoft.Alpha(opacity=0)'
|
||||
}
|
||||
}).inject(this.element, 'after');
|
||||
}
|
||||
},
|
||||
|
||||
show: function() {
|
||||
if (this.fix) {
|
||||
var coords = this.element.getCoordinates(this.relative);
|
||||
delete coords.right;
|
||||
delete coords.bottom;
|
||||
this.fix.setStyles($extend(coords, {
|
||||
'display': '',
|
||||
'zIndex': (this.element.getStyle('zIndex') || 1) - 1
|
||||
}));
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
if (this.fix) this.fix.setStyle('display', 'none');
|
||||
return this;
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
if (this.fix) this.fix = this.fix.destroy();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Element.implement({
|
||||
|
||||
getSelectedRange: function() {
|
||||
if (!Browser.Engine.trident) return {start: this.selectionStart, end: this.selectionEnd};
|
||||
var pos = {start: 0, end: 0};
|
||||
var range = this.getDocument().selection.createRange();
|
||||
if (!range || range.parentElement() != this) return pos;
|
||||
var dup = range.duplicate();
|
||||
if (this.type == 'text') {
|
||||
pos.start = 0 - dup.moveStart('character', -100000);
|
||||
pos.end = pos.start + range.text.length;
|
||||
} else {
|
||||
var value = this.value;
|
||||
var offset = value.length - value.match(/[\n\r]*$/)[0].length;
|
||||
dup.moveToElementText(this);
|
||||
dup.setEndPoint('StartToEnd', range);
|
||||
pos.end = offset - dup.text.length;
|
||||
dup.setEndPoint('StartToStart', range);
|
||||
pos.start = offset - dup.text.length;
|
||||
}
|
||||
return pos;
|
||||
},
|
||||
|
||||
selectRange: function(start, end) {
|
||||
if (Browser.Engine.trident) {
|
||||
var diff = this.value.substr(start, end - start).replace(/\r/g, '').length;
|
||||
start = this.value.substr(0, start).replace(/\r/g, '').length;
|
||||
var range = this.createTextRange();
|
||||
range.collapse(true);
|
||||
range.moveEnd('character', start + diff);
|
||||
range.moveStart('character', start);
|
||||
range.select();
|
||||
} else {
|
||||
this.focus();
|
||||
this.setSelectionRange(start, end);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/* compatibility */
|
||||
|
||||
Autocompleter.Base = Autocompleter;
|
||||
@@ -1,69 +0,0 @@
|
||||
/**
|
||||
* Observer - Observe formelements for changes
|
||||
*
|
||||
* - Additional code from clientside.cnet.com
|
||||
*
|
||||
* @version 1.1
|
||||
*
|
||||
* @license MIT-style license
|
||||
* @author Harald Kirschner <mail [at] digitarald.de>
|
||||
* @copyright Author
|
||||
*/
|
||||
var Observer = new Class({
|
||||
|
||||
Implements: [Options, Events],
|
||||
|
||||
options: {
|
||||
periodical: false,
|
||||
delay: 1000
|
||||
},
|
||||
|
||||
initialize: function(el, onFired, options){
|
||||
this.element = $(el) || $$(el);
|
||||
this.addEvent('onFired', onFired);
|
||||
this.setOptions(options);
|
||||
this.bound = this.changed.bind(this);
|
||||
this.resume();
|
||||
},
|
||||
|
||||
changed: function() {
|
||||
var value = this.element.get('value');
|
||||
if ($equals(this.value, value)) return;
|
||||
this.clear();
|
||||
this.value = value;
|
||||
this.timeout = this.onFired.delay(this.options.delay, this);
|
||||
},
|
||||
|
||||
setValue: function(value) {
|
||||
this.value = value;
|
||||
this.element.set('value', value);
|
||||
return this.clear();
|
||||
},
|
||||
|
||||
onFired: function() {
|
||||
this.fireEvent('onFired', [this.value, this.element]);
|
||||
},
|
||||
|
||||
clear: function() {
|
||||
$clear(this.timeout || null);
|
||||
return this;
|
||||
},
|
||||
|
||||
pause: function(){
|
||||
if (this.timer) $clear(this.timer);
|
||||
else this.element.removeEvent('keyup', this.bound);
|
||||
return this.clear();
|
||||
},
|
||||
|
||||
resume: function(){
|
||||
this.value = this.element.get('value');
|
||||
if (this.options.periodical) this.timer = this.changed.periodical(this.options.periodical, this);
|
||||
else this.element.addEvent('keyup', this.bound);
|
||||
return this;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
var $equals = function(obj1, obj2) {
|
||||
return (obj1 == obj2 || JSON.encode(obj1) == JSON.encode(obj2));
|
||||
};
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
---
|
||||
description: ProgressBar
|
||||
|
||||
authors:
|
||||
- David Walsh (http://davidwalsh.name)
|
||||
|
||||
license:
|
||||
- MIT-style license
|
||||
|
||||
requires:
|
||||
core/1.2.1: '*'
|
||||
more/1.2.1: 'Fx.*'
|
||||
|
||||
provides:
|
||||
- ProgressBar
|
||||
...
|
||||
*/
|
||||
var ProgressBar=new Class({Implements:[Events,Options],options:{container:document.body,boxID:"progress-bar-box-id",percentageID:"progress-bar-percentage-id",displayID:"progress-bar-display-id",startPercentage:0,displayText:false,speed:10,step:1,allowMore:false,onComplete:$empty,onChange:$empty},initialize:function(a){this.setOptions(a);this.options.container=document.id(this.options.container);this.createElements();},createElements:function(){var b=new Element("div",{id:this.options.boxID});var a=new Element("div",{id:this.options.percentageID,style:"width:0px;"});a.inject(b);b.inject(this.options.container);if(this.options.displayText){var c=new Element("div",{id:this.options.displayID});c.inject(this.options.container);}this.set(this.options.startPercentage);},calculate:function(a){return(document.id(this.options.boxID).getStyle("width").replace("px","")*(a/100)).toInt();},animate:function(b){var c=false;var a=this;if(!a.options.allowMore&&b>100){b=100;}a.to=b.toInt();document.id(a.options.percentageID).set("morph",{duration:this.options.speed,link:"cancel",onComplete:function(){a.fireEvent("change",[a.to]);if(b>=100){a.fireEvent("complete",[a.to]);}}}).morph({width:a.calculate(b)});if(a.options.displayText){document.id(a.options.displayID).set("text",a.to+"%");}},set:function(a){this.animate(a);},step:function(){this.set(this.to+this.options.step);}});
|
||||
@@ -1,443 +0,0 @@
|
||||
/**
|
||||
* SqueezeBox - Expandable Lightbox
|
||||
*
|
||||
* Allows to open various content as modal,
|
||||
* centered and animated box.
|
||||
*
|
||||
* Dependencies: MooTools 1.3.1
|
||||
*
|
||||
* Inspired by
|
||||
* ... Lokesh Dhakar - The original Lightbox v2
|
||||
*
|
||||
* @version 1.3 rc1
|
||||
*
|
||||
* @license MIT-style license
|
||||
* @author Harald Kirschner <mail [at] digitarald.de>
|
||||
* @copyright Author
|
||||
*/
|
||||
|
||||
var SqueezeBox = {
|
||||
|
||||
presets: {
|
||||
onOpen: function(){},
|
||||
onClose: function(){},
|
||||
onUpdate: function(){},
|
||||
onResize: function(){},
|
||||
onMove: function(){},
|
||||
onShow: function(){},
|
||||
onHide: function(){},
|
||||
size: {x: 600, y: 450},
|
||||
sizeLoading: {x: 200, y: 150},
|
||||
marginInner: {x: 20, y: 20},
|
||||
marginImage: {x: 50, y: 75},
|
||||
handler: false,
|
||||
target: null,
|
||||
closable: true,
|
||||
closeBtn: true,
|
||||
zIndex: 65555,
|
||||
overlayOpacity: 0.7,
|
||||
classWindow: '',
|
||||
classOverlay: '',
|
||||
overlayFx: {},
|
||||
resizeFx: {},
|
||||
contentFx: {},
|
||||
parse: false, // 'rel'
|
||||
parseSecure: false,
|
||||
shadow: true,
|
||||
document: null,
|
||||
ajaxOptions: {}
|
||||
},
|
||||
|
||||
initialize: function(presets) {
|
||||
if (this.options) return this;
|
||||
|
||||
this.presets = Object.merge(this.presets, presets);
|
||||
this.doc = this.presets.document || document;
|
||||
this.options = {};
|
||||
this.setOptions(this.presets).build();
|
||||
this.bound = {
|
||||
window: this.reposition.pass(null,this),
|
||||
scroll: this.checkTarget.bind(this),
|
||||
close: this.close.bind(this),
|
||||
key: this.onKey.bind(this)
|
||||
};
|
||||
this.isOpen = this.isLoading = false;
|
||||
return this;
|
||||
},
|
||||
|
||||
build: function() {
|
||||
this.overlay = new Element('div', {
|
||||
id: 'sbox-overlay',
|
||||
styles: {display: 'none', zIndex: this.options.zIndex}
|
||||
});
|
||||
this.win = new Element('div', {
|
||||
id: 'sbox-window',
|
||||
styles: {display: 'none', zIndex: this.options.zIndex + 2}
|
||||
});
|
||||
if (this.options.shadow) {
|
||||
if (Browser.safari || Browser.chrome) {
|
||||
this.win.setStyle('-webkit-box-shadow', '0 0 10px rgba(0, 0, 0, 0.7)');
|
||||
} else if (!Browser.ie) {
|
||||
var shadow = new Element('div', {'class': 'sbox-bg-wrap'}).inject(this.win);
|
||||
var relay = function(e) {
|
||||
this.overlay.fireEvent('click', [e]);
|
||||
}.bind(this);
|
||||
['n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw'].each(function(dir) {
|
||||
new Element('div', {'class': 'sbox-bg sbox-bg-' + dir}).inject(shadow).addEvent('click', relay);
|
||||
});
|
||||
}
|
||||
}
|
||||
this.content = new Element('div', {id: 'sbox-content'}).inject(this.win);
|
||||
if (this.options.closeBtn) {
|
||||
this.closeBtn = new Element('a', {id: 'sbox-btn-close', href: '#'}).inject(this.win);
|
||||
}
|
||||
this.fx = {
|
||||
overlay: new Fx.Tween(this.overlay, Object.merge({
|
||||
property: 'opacity',
|
||||
onStart: Events.prototype.clearChain,
|
||||
duration: 250,
|
||||
link: 'cancel'
|
||||
}, this.options.overlayFx)).set(0),
|
||||
win: new Fx.Morph(this.win, Object.merge({
|
||||
onStart: Events.prototype.clearChain,
|
||||
unit: 'px',
|
||||
duration: 750,
|
||||
transition: Fx.Transitions.Quint.easeOut,
|
||||
link: 'cancel',
|
||||
unit: 'px'
|
||||
}, this.options.resizeFx)),
|
||||
content: new Fx.Tween(this.content, Object.merge({
|
||||
property: 'opacity',
|
||||
duration: 250,
|
||||
link: 'cancel'
|
||||
}, this.options.contentFx)).set(0)
|
||||
};
|
||||
$(this.doc.body).adopt(this.overlay, this.win);
|
||||
},
|
||||
|
||||
assign: function(to, options) {
|
||||
return ($(to) || $$(to)).addEvent('click', function() {
|
||||
return !SqueezeBox.fromElement(this, options);
|
||||
});
|
||||
},
|
||||
|
||||
open: function(subject, options) {
|
||||
this.initialize();
|
||||
|
||||
if (this.element != null) this.trash();
|
||||
this.element = $(subject) || false;
|
||||
|
||||
this.setOptions(Object.merge(this.presets, options || {}));
|
||||
if (this.element && this.options.parse) {
|
||||
var obj = this.element.getProperty(this.options.parse);
|
||||
if (obj && (obj = JSON.decode(obj, this.options.parseSecure))) this.setOptions(obj);
|
||||
}
|
||||
this.url = ((this.element) ? (this.element.get('href')) : subject) || this.options.url || '';
|
||||
|
||||
this.assignOptions();
|
||||
|
||||
var handler = handler || this.options.handler;
|
||||
if (handler) return this.setContent(handler, this.parsers[handler].call(this, true));
|
||||
var ret = false;
|
||||
return this.parsers.some(function(parser, key) {
|
||||
var content = parser.call(this);
|
||||
if (content) {
|
||||
ret = this.setContent(key, content);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}, this);
|
||||
},
|
||||
|
||||
fromElement: function(from, options) {
|
||||
return this.open(from, options);
|
||||
},
|
||||
|
||||
assignOptions: function() {
|
||||
this.overlay.set('class', this.options.classOverlay);
|
||||
this.win.set('class', this.options.classWindow);
|
||||
if (Browser.ie) this.win.addClass('sbox-window-ie6');
|
||||
if (!this.options.closeBtn) {
|
||||
this.closeBtn.dispose();
|
||||
} else {
|
||||
this.closeBtn.inject(this.win);
|
||||
}
|
||||
},
|
||||
|
||||
close: function(e) {
|
||||
var stoppable = (typeOf(e) == 'event');
|
||||
if (stoppable) e.stop();
|
||||
if (!this.isOpen || (stoppable && !Function.from(this.options.closable).call(this, e))) return this;
|
||||
this.fx.overlay.start(0).chain(this.toggleOverlay.bind(this));
|
||||
this.win.setStyle('display', 'none');
|
||||
this.fireEvent('onClose', [this.content]);
|
||||
this.trash();
|
||||
this.toggleListeners(false);
|
||||
this.isOpen = false;
|
||||
return this;
|
||||
},
|
||||
|
||||
trash: function() {
|
||||
this.element = this.asset = null;
|
||||
this.content.empty();
|
||||
this.options = {};
|
||||
this.removeEvents().setOptions(this.presets).callChain();
|
||||
},
|
||||
|
||||
onError: function() {
|
||||
this.asset = null;
|
||||
this.setContent('string', this.options.errorMsg || 'An error occurred');
|
||||
},
|
||||
|
||||
setContent: function(handler, content) {
|
||||
if (!this.handlers[handler]) return false;
|
||||
this.content.className = 'sbox-content-' + handler;
|
||||
this.applyTimer = this.applyContent.delay(this.fx.overlay.options.duration, this, this.handlers[handler].call(this, content));
|
||||
if (this.overlay.retrieve('opacity')) return this;
|
||||
this.toggleOverlay(true);
|
||||
this.fx.overlay.start(this.options.overlayOpacity);
|
||||
return this.reposition();
|
||||
},
|
||||
|
||||
applyContent: function(content, size) {
|
||||
if (!this.isOpen && !this.applyTimer) return;
|
||||
this.applyTimer = clearTimeout(this.applyTimer);
|
||||
this.hideContent();
|
||||
if (!content) {
|
||||
this.toggleLoading(true);
|
||||
} else {
|
||||
if (this.isLoading) this.toggleLoading(false);
|
||||
this.fireEvent('onUpdate', [this.content], 20);
|
||||
}
|
||||
if (content) {
|
||||
if (['string', 'array'].contains(typeOf(content))) this.content.set('html', content);
|
||||
else if ((!this.content.contains(content)) && content != this.content) this.content.adopt(content);
|
||||
}
|
||||
this.callChain();
|
||||
if (!this.isOpen) {
|
||||
this.toggleListeners(true);
|
||||
this.resize(size, true);
|
||||
this.isOpen = true;
|
||||
this.fireEvent('onOpen', [this.content]);
|
||||
} else {
|
||||
this.resize(size);
|
||||
}
|
||||
},
|
||||
|
||||
resize: function(size, instantly) {
|
||||
this.showTimer = clearTimeout(this.showTimer || null);
|
||||
var box = this.doc.getSize(), scroll = this.doc.getScroll();
|
||||
this.size = Object.merge((this.isLoading) ? this.options.sizeLoading : this.options.size, size);
|
||||
var to = {
|
||||
width: this.size.x,
|
||||
height: this.size.y,
|
||||
left: (scroll.x + (box.x - this.size.x - this.options.marginInner.x) / 2).toInt(),
|
||||
top: (scroll.y + (box.y - this.size.y - this.options.marginInner.y) / 2).toInt()
|
||||
};
|
||||
this.hideContent();
|
||||
if (!instantly) {
|
||||
this.fx.win.start(to).chain(this.showContent.bind(this));
|
||||
} else {
|
||||
this.win.setStyles(to).setStyle('display', '');
|
||||
this.showTimer = this.showContent.delay(50, this);
|
||||
}
|
||||
return this.reposition();
|
||||
},
|
||||
|
||||
toggleListeners: function(state) {
|
||||
var fn = (state) ? 'addEvent' : 'removeEvent';
|
||||
if (this.options.closeBtn) {
|
||||
this.closeBtn[fn]('click', this.bound.close);
|
||||
}
|
||||
this.overlay[fn]('click', this.bound.close);
|
||||
this.doc[fn]('keydown', this.bound.key)[fn]('mousewheel', this.bound.scroll);
|
||||
this.doc.getWindow()[fn]('resize', this.bound.window)[fn]('scroll', this.bound.window);
|
||||
},
|
||||
|
||||
toggleLoading: function(state) {
|
||||
this.isLoading = state;
|
||||
this.win[(state) ? 'addClass' : 'removeClass']('sbox-loading');
|
||||
if (state) this.fireEvent('onLoading', [this.win]);
|
||||
},
|
||||
|
||||
toggleOverlay: function(state) {
|
||||
var full = this.doc.getSize().x;
|
||||
this.overlay.setStyle('display', (state) ? '' : 'none');
|
||||
this.doc.body[(state) ? 'addClass' : 'removeClass']('body-overlayed');
|
||||
if (state) {
|
||||
this.scrollOffset = this.doc.getWindow().getSize().x - full;
|
||||
this.doc.body.setStyle('margin-right', this.scrollOffset);
|
||||
} else {
|
||||
this.doc.body.setStyle('margin-right', '');
|
||||
}
|
||||
},
|
||||
|
||||
showContent: function() {
|
||||
if (this.content.get('opacity')) this.fireEvent('onShow', [this.win]);
|
||||
this.fx.content.start(1);
|
||||
},
|
||||
|
||||
hideContent: function() {
|
||||
if (!this.content.get('opacity')) this.fireEvent('onHide', [this.win]);
|
||||
this.fx.content.cancel().set(0);
|
||||
},
|
||||
|
||||
onKey: function(e) {
|
||||
switch (e.key) {
|
||||
case 'esc': this.close(e);
|
||||
case 'up': case 'down': return false;
|
||||
}
|
||||
},
|
||||
|
||||
checkTarget: function(e) {
|
||||
return (this.content.contains(e.target) && e.target != this.content);
|
||||
},
|
||||
|
||||
reposition: function() {
|
||||
var size = this.doc.getSize(), scroll = this.doc.getScroll(), ssize = this.doc.getScrollSize();
|
||||
this.overlay.setStyles({
|
||||
width: ssize.x + 'px',
|
||||
height: ssize.y + 'px'
|
||||
});
|
||||
this.win.setStyles({
|
||||
left: (scroll.x + (size.x - this.win.offsetWidth) / 2 - this.scrollOffset).toInt() + 'px',
|
||||
top: (scroll.y + (size.y - this.win.offsetHeight) / 2).toInt() + 'px'
|
||||
});
|
||||
return this.fireEvent('onMove', [this.overlay, this.win]);
|
||||
},
|
||||
|
||||
removeEvents: function(type) {
|
||||
if (!this.$events) return this;
|
||||
if (!type) this.$events = null;
|
||||
else if (this.$events[type]) this.$events[type] = null;
|
||||
return this;
|
||||
},
|
||||
|
||||
extend: function(properties) {
|
||||
return Object.append(this, properties);
|
||||
},
|
||||
|
||||
handlers: new Hash(),
|
||||
|
||||
parsers: new Hash()
|
||||
|
||||
};
|
||||
|
||||
SqueezeBox.extend(new Events(function(){})).extend(new Options(function(){})).extend(new Chain(function(){}));
|
||||
|
||||
SqueezeBox.parsers.extend({
|
||||
|
||||
image: function(preset) {
|
||||
return (preset || (/\.(?:jpg|png|gif)$/i).test(this.url)) ? this.url : false;
|
||||
},
|
||||
|
||||
clone: function(preset) {
|
||||
if ($(this.options.target)) return $(this.options.target);
|
||||
if (this.element && !this.element.parentNode) return this.element;
|
||||
var bits = this.url.match(/#([\w-]+)$/);
|
||||
return (bits) ? $(bits[1]) : (preset ? this.element : false);
|
||||
},
|
||||
|
||||
ajax: function(preset) {
|
||||
return (preset || (this.url && !(/^(?:javascript|#)/i).test(this.url))) ? this.url : false;
|
||||
},
|
||||
|
||||
iframe: function(preset) {
|
||||
return (preset || this.url) ? this.url : false;
|
||||
},
|
||||
|
||||
string: function(preset) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
SqueezeBox.handlers.extend({
|
||||
|
||||
image: function(url) {
|
||||
var size, tmp = new Image();
|
||||
this.asset = null;
|
||||
tmp.onload = tmp.onabort = tmp.onerror = (function() {
|
||||
tmp.onload = tmp.onabort = tmp.onerror = null;
|
||||
if (!tmp.width) {
|
||||
this.onError.delay(10, this);
|
||||
return;
|
||||
}
|
||||
var box = this.doc.getSize();
|
||||
box.x -= this.options.marginImage.x;
|
||||
box.y -= this.options.marginImage.y;
|
||||
size = {x: tmp.width, y: tmp.height};
|
||||
for (var i = 2; i--;) {
|
||||
if (size.x > box.x) {
|
||||
size.y *= box.x / size.x;
|
||||
size.x = box.x;
|
||||
} else if (size.y > box.y) {
|
||||
size.x *= box.y / size.y;
|
||||
size.y = box.y;
|
||||
}
|
||||
}
|
||||
size.x = size.x.toInt();
|
||||
size.y = size.y.toInt();
|
||||
this.asset = $(tmp);
|
||||
tmp = null;
|
||||
this.asset.width = size.x;
|
||||
this.asset.height = size.y;
|
||||
this.applyContent(this.asset, size);
|
||||
}).bind(this);
|
||||
tmp.src = url;
|
||||
if (tmp && tmp.onload && tmp.complete) tmp.onload();
|
||||
return (this.asset) ? [this.asset, size] : null;
|
||||
},
|
||||
|
||||
clone: function(el) {
|
||||
if (el) return el.clone();
|
||||
return this.onError();
|
||||
},
|
||||
|
||||
adopt: function(el) {
|
||||
if (el) return el;
|
||||
return this.onError();
|
||||
},
|
||||
|
||||
ajax: function(url) {
|
||||
var options = this.options.ajaxOptions || {};
|
||||
this.asset = new Request.HTML(Object.merge({
|
||||
method: 'get',
|
||||
evalScripts: false
|
||||
}, this.options.ajaxOptions)).addEvents({
|
||||
onSuccess: function(resp) {
|
||||
this.applyContent(resp);
|
||||
if (options.evalScripts !== null && !options.evalScripts) Browser.exec(this.asset.response.javascript);
|
||||
this.fireEvent('onAjax', [resp, this.asset]);
|
||||
this.asset = null;
|
||||
}.bind(this),
|
||||
onFailure: this.onError.bind(this)
|
||||
});
|
||||
this.asset.send.delay(10, this.asset, [{url: url}]);
|
||||
},
|
||||
|
||||
iframe: function(url) {
|
||||
this.asset = new Element('iframe', Object.merge({
|
||||
src: url,
|
||||
frameBorder: 0,
|
||||
width: this.options.size.x,
|
||||
height: this.options.size.y
|
||||
}, this.options.iframeOptions));
|
||||
if (this.options.iframePreload) {
|
||||
this.asset.addEvent('load', function() {
|
||||
this.applyContent(this.asset.setStyle('display', ''));
|
||||
}.bind(this));
|
||||
this.asset.setStyle('display', 'none').inject(this.content);
|
||||
return false;
|
||||
}
|
||||
return this.asset;
|
||||
},
|
||||
|
||||
string: function(str) {
|
||||
return str;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
SqueezeBox.handlers.url = SqueezeBox.handlers.ajax;
|
||||
SqueezeBox.parsers.url = SqueezeBox.parsers.ajax;
|
||||
SqueezeBox.parsers.adopt = SqueezeBox.parsers.clone;
|
||||
@@ -0,0 +1,67 @@
|
||||
function domainform_cb() {
|
||||
$('input:text:visible:first').focus();
|
||||
$("#id_aliases").dynamic_input();
|
||||
$(".submit").one('click', function(e) {
|
||||
simple_ajax_form_post(e, domainform_cb);
|
||||
});
|
||||
}
|
||||
|
||||
function accountform_init() {
|
||||
$("#id_aliases").dynamic_input();
|
||||
$("#id_email").autocompleter({
|
||||
from_character: "@",
|
||||
choices: get_domains_list
|
||||
});
|
||||
$("#id_domains")
|
||||
.autocompleter({
|
||||
choices: get_domains_list
|
||||
})
|
||||
.dynamic_input();
|
||||
}
|
||||
|
||||
function newaccount_cb() {
|
||||
$('input:text:visible:first').focus();
|
||||
accountform_init();
|
||||
$("#wizard").cwizard();
|
||||
}
|
||||
|
||||
function editaccount_cb() {
|
||||
accountform_init();
|
||||
$('#submit').click(function(e) {
|
||||
simple_ajax_form_post(e, editaccount_cb);
|
||||
});
|
||||
}
|
||||
|
||||
function dlistform_cb() {
|
||||
$("#id_email").autocompleter({
|
||||
from_character: "@",
|
||||
choices: get_domains_list
|
||||
});
|
||||
$("#id_recipients").dynamic_input();
|
||||
$(".submit").one('click', function(e) {
|
||||
simple_ajax_form_post(e, dlistform_cb);
|
||||
});
|
||||
}
|
||||
|
||||
function importform_cb() {
|
||||
$(".submit").one('click', function(e) {
|
||||
if ($("#id_sourcefile").attr("value") == "") {
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
$("#import_status").css("display", "block");
|
||||
$("form").submit();
|
||||
});
|
||||
}
|
||||
|
||||
function importdone(status, msg) {
|
||||
$("#import_status").css("display", "none");
|
||||
if (status == "ok") {
|
||||
$("#modalbox").modal('hide');
|
||||
window.location.reload();
|
||||
} else {
|
||||
$("#import_result").html("");
|
||||
$(".modal-header").notify({top_position: 10});
|
||||
$(".modal-header").notify('error', msg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
(function($) {
|
||||
var Autocompleter = function(element, options) {
|
||||
this.$element = $(element);
|
||||
this.options = $.extend({}, $.fn.autocompleter.defaults, options);
|
||||
this.choices = {
|
||||
value: null
|
||||
};
|
||||
if (typeof this.options.choices === "function") {
|
||||
this.options.choices(this.choices);
|
||||
} else {
|
||||
this.choices.value = this.options.choices();
|
||||
}
|
||||
this.$menu =
|
||||
$('<ul class="dropdown-menu autocompleter" data-toggle="dropdown" />');
|
||||
$("body").append(this.$menu);
|
||||
this.$menu.on("click", $.proxy(this.select_entry, this));
|
||||
|
||||
this.$element.attr("autocomplete", "off");
|
||||
this.$element.keydown($.proxy(this.keydown, this));
|
||||
this.$element.keyup($.proxy(this.keyup, this));
|
||||
this.$element.blur($.proxy(this.hide_menu, this));
|
||||
};
|
||||
|
||||
Autocompleter.prototype = {
|
||||
constructor: Autocompleter,
|
||||
|
||||
check_user_input: function() {
|
||||
var value = this.$element.attr("value");
|
||||
var start = -1;
|
||||
var pattern = null;
|
||||
|
||||
if (this.options.from_character) {
|
||||
start = value.indexOf(this.options.from_character);
|
||||
if (start == -1) {
|
||||
return;
|
||||
}
|
||||
pattern = value.substr(start + 1);
|
||||
} else {
|
||||
pattern = value;
|
||||
}
|
||||
|
||||
var exp = new RegExp("^" + pattern);
|
||||
|
||||
this.$menu.empty();
|
||||
$.each(this.choices.value, $.proxy(function(index, value) {
|
||||
if (exp.test(value)) {
|
||||
this.$menu.append($('<li><a href="#" name="' + value
|
||||
+ '">' + value + '</a></li>'));
|
||||
}
|
||||
}, this));
|
||||
|
||||
var coords = this.$element.offset();
|
||||
|
||||
this.$menu.css({
|
||||
position: "absolute",
|
||||
top: coords.top + this.$element.outerHeight(),
|
||||
left: coords.left,
|
||||
width: this.$element.outerWidth()
|
||||
});
|
||||
|
||||
if (this.$menu.children().length) {
|
||||
this.$menu.show();
|
||||
} else {
|
||||
this.$menu.hide();
|
||||
}
|
||||
},
|
||||
|
||||
hide_menu: function() {
|
||||
setTimeout($.proxy(function() { this.$menu.hide(); }, this), 150);
|
||||
},
|
||||
|
||||
select_entry: function(evt) {
|
||||
if (evt != undefined) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
var $link = this.$menu.find('.active > a');
|
||||
var curvalue = this.$element.attr("value");
|
||||
|
||||
this.$element.attr("value", curvalue.substr(
|
||||
0, curvalue.indexOf(this.options.from_character) + 1
|
||||
) + $link.attr("name"));
|
||||
this.hide_menu();
|
||||
},
|
||||
|
||||
activate_next: function() {
|
||||
var active = this.$menu.find('.active').removeClass('active')
|
||||
, next = active.next();
|
||||
|
||||
if (!next.length) {
|
||||
next = $(this.$menu.find('li').first());
|
||||
}
|
||||
|
||||
next.addClass('active');
|
||||
},
|
||||
|
||||
activate_prev: function() {
|
||||
var active = this.$menu.find('.active').removeClass('active')
|
||||
, prev = active.prev();
|
||||
|
||||
if (!prev.length) {
|
||||
prev = this.$menu.find('li').last();
|
||||
}
|
||||
|
||||
prev.addClass('active');
|
||||
},
|
||||
|
||||
keydown: function(evt) {
|
||||
evt.stopPropagation();
|
||||
|
||||
switch (evt.keyCode) {
|
||||
case 13:
|
||||
case 27:
|
||||
evt.preventDefault();
|
||||
break;
|
||||
case 38:
|
||||
evt.preventDefault();
|
||||
this.activate_prev();
|
||||
break;
|
||||
case 40:
|
||||
evt.preventDefault();
|
||||
this.activate_next();
|
||||
break;
|
||||
};
|
||||
},
|
||||
|
||||
keyup: function(evt) {
|
||||
evt.stopPropagation();
|
||||
evt.preventDefault();
|
||||
|
||||
switch (evt.keyCode) {
|
||||
case 40:
|
||||
case 38:
|
||||
break;
|
||||
|
||||
case 13:
|
||||
this.select_entry();
|
||||
break;
|
||||
|
||||
case 27:
|
||||
this.hide_menu();
|
||||
break;
|
||||
|
||||
default:
|
||||
this.check_user_input();
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.autocompleter = function(option) {
|
||||
return this.each(function() {
|
||||
var $this = $(this),
|
||||
data = $this.data('autocompleter'),
|
||||
options = typeof option === "object" && option;
|
||||
|
||||
if (!data) {
|
||||
$this.data('autocompleter', new Autocompleter(this, options));
|
||||
}
|
||||
if (typeof option === "string") {
|
||||
data[option]();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.autocompleter.defaults = {};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,14 +1,17 @@
|
||||
window.addEvent('domready', function(){
|
||||
parse_menubar('topmenubar');
|
||||
parse_menubar('menubar');
|
||||
$(document).ready(function() {
|
||||
$(document).on('click', 'a[data-toggle="ajaxmodal"]', modalbox);
|
||||
$(document).on('click', 'a[data-toggle="ajaxmodal-autowidth"]', modalbox_autowidth);
|
||||
|
||||
infobox = new InfoBox({
|
||||
//parse_menubar('#topmenubar');
|
||||
//parse_menubar('#menubar');
|
||||
|
||||
/*infobox = new InfoBox({
|
||||
parent : $("menubar"),
|
||||
message : "Loading"
|
||||
});
|
||||
});*/
|
||||
|
||||
/* Specific javascript code for the demo... not the best place */
|
||||
$$("a[name=sendspam], a[name=sendvirus]").addEvent("click", function(evt) {
|
||||
/*$$("a[name=sendspam], a[name=sendvirus]").addEvent("click", function(evt) {
|
||||
evt.stop();
|
||||
new Request.JSON({
|
||||
url: this.get("href"),
|
||||
@@ -21,7 +24,7 @@ window.addEvent('domready', function(){
|
||||
}
|
||||
}
|
||||
}).get();
|
||||
});
|
||||
});*/
|
||||
});
|
||||
|
||||
var media_url = "";
|
||||
@@ -65,8 +68,29 @@ function enable_link(link, callback) {
|
||||
}
|
||||
|
||||
function parse_menubar(id) {
|
||||
if ($(id)) {
|
||||
$(id).getElements('li.dropdown').each(function(elem){
|
||||
var $menubar = $(id);
|
||||
|
||||
if ($menubar == undefined) {
|
||||
return;
|
||||
}
|
||||
$menubar.find('.dropdown-toggle').dropdown();
|
||||
$menubar.find('a[data-toggle="modal"]').click(function(e) {
|
||||
console.log(this);
|
||||
e.preventDefault();
|
||||
var href = $(this).attr('href');
|
||||
|
||||
if (href.indexOf('#') == 0) {
|
||||
$(href).modal('open');
|
||||
} else {
|
||||
$.get(href, function(data) {
|
||||
$('<div class="modal" >' + data + '</div>').modal();
|
||||
}).success(function() {
|
||||
$('input:text:visible:first').focus();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/*.each(function(elem){
|
||||
var list = elem.getElement('ul.links');
|
||||
var myFx = new Fx.Slide(list, {
|
||||
duration: 200
|
||||
@@ -76,7 +100,6 @@ function parse_menubar(id) {
|
||||
|
||||
myFx.wrapper.setStyles({
|
||||
position : "absolute",
|
||||
/*top: 30,*/
|
||||
left : coords['left']
|
||||
});
|
||||
myFx.hide();
|
||||
@@ -91,11 +114,11 @@ function parse_menubar(id) {
|
||||
myFx.slideOut();
|
||||
}
|
||||
});
|
||||
});
|
||||
SqueezeBox.assign($(id).getElements('a[class=boxed]'), {
|
||||
});*/
|
||||
/*SqueezeBox.assign($(id).getElements('a[class=boxed]'), {
|
||||
parse: 'rel'
|
||||
});
|
||||
}
|
||||
});*/
|
||||
|
||||
};
|
||||
|
||||
get_iframe_body = function(id) {
|
||||
@@ -220,17 +243,16 @@ gethref = function(obj) {
|
||||
return url;
|
||||
};
|
||||
|
||||
saveparams = function(id, message) {
|
||||
$$("input[name=update]").addEvent("click", function(evt) {
|
||||
evt.stop();
|
||||
$(id).set("send", {
|
||||
onSuccess: function(response) {
|
||||
var decode = JSON.decode(response);
|
||||
if (decode.status == "ok") {
|
||||
infobox.info(message);
|
||||
infobox.hide(1);
|
||||
}
|
||||
/*function saveparams(id, message) {
|
||||
$("#update").click(function(evt) {
|
||||
evt.preventDefault();
|
||||
var $form = $("form");
|
||||
|
||||
$.post($form.attr("action"), $form.serialize(), function(data) {
|
||||
if (data.status == "ok") {
|
||||
$("body").notify("success", message, 2000);
|
||||
}
|
||||
}).send();
|
||||
});
|
||||
});
|
||||
};
|
||||
};*/
|
||||
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
var Confirmation = new Class({
|
||||
Implements: [Options, Events],
|
||||
options: {
|
||||
checkboxes: []
|
||||
},
|
||||
|
||||
build_checkboxes: function() {
|
||||
var result = "";
|
||||
var cbhash = new Hash(this.options.checkboxes);
|
||||
|
||||
cbhash.each(function(value, key, hash) {
|
||||
result += "<input type='checkbox' name='" + key + "' value='' />";
|
||||
result += "<label>" + value + "</label>";
|
||||
});
|
||||
return result;
|
||||
},
|
||||
|
||||
initialize: function(url, urlparams, question, options) {
|
||||
this.setOptions(options);
|
||||
Confirmation.url = url;
|
||||
Confirmation.urlparams = urlparams;
|
||||
|
||||
var content = new Element("div", {id: "confirmbox"});
|
||||
var icondiv = new Element("div", {
|
||||
id: "dlg-iconbox",
|
||||
html: "<img src='/static/pics/dialog-warning.png' alt='Warning' />"
|
||||
}).inject(content);
|
||||
|
||||
this.textdiv = new Element("div", {
|
||||
id: "dlg-textbox",
|
||||
html: "<b>" + question + "</b>"
|
||||
+ "<p>" + this.build_checkboxes() + "</p>"
|
||||
}).inject(content);
|
||||
|
||||
var buttonsdiv = new Element("div", {
|
||||
id: "dlg-buttons"
|
||||
}).inject(content);
|
||||
new Element("input", {type: "button", name: "ok", id: "ok", value: "Ok"})
|
||||
.addEvent("click", this.ok_handler)
|
||||
.inject(buttonsdiv);
|
||||
new Element("input", {type: "button", name: "cancel", value: "Cancel"})
|
||||
.addEvent("click", this.cancel_handler)
|
||||
.inject(buttonsdiv);
|
||||
|
||||
new Element("input", {type: "hidden", name: "result",
|
||||
id: "result", value: "cancel"})
|
||||
.inject(content);
|
||||
|
||||
SqueezeBox.open(content, {
|
||||
size: {x: 350, y: 140},
|
||||
handler: "adopt",
|
||||
onClose: this.close_handler.bind(content)
|
||||
});
|
||||
},
|
||||
|
||||
close_handler: function(content) {
|
||||
var result = this.getElement("input[name=result]");
|
||||
if (result.get("value") != "ok") {
|
||||
return;
|
||||
}
|
||||
|
||||
var params = Confirmation.urlparams;
|
||||
$$("input[type=checkbox]:checked").each(function(item) {
|
||||
if (params != "") {
|
||||
params += "&";
|
||||
}
|
||||
params += item.get("name") + "=true";
|
||||
});
|
||||
new Request.JSON.mdb({
|
||||
method: "get",
|
||||
url: Confirmation.url,
|
||||
onSuccess: function(res) {
|
||||
if (res.status == "ok") {
|
||||
window.location.reload();
|
||||
} else {
|
||||
infobox.error(res.respmsg);
|
||||
infobox.hide(2);
|
||||
}
|
||||
}
|
||||
}).send(params);
|
||||
},
|
||||
|
||||
ok_handler: function(evt) {
|
||||
$("result").value = "ok";
|
||||
parent.SqueezeBox.close();
|
||||
},
|
||||
|
||||
cancel_handler: function(evt) {
|
||||
parent.SqueezeBox.close();
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,79 @@
|
||||
(function($) {
|
||||
var Cwizard = function(element, options) {
|
||||
this.$element = $(element);
|
||||
this.$element.carousel("pause");
|
||||
this.setcallbacks();
|
||||
};
|
||||
|
||||
Cwizard.prototype = {
|
||||
constructor: Cwizard,
|
||||
|
||||
setcallbacks: function() {
|
||||
$(".next").one("click", $.proxy(this.next, this));
|
||||
$(".prev").one("click", $.proxy(this.prev, this));
|
||||
$(".submit").one("click", $.proxy(this.submit, this));
|
||||
},
|
||||
|
||||
post: function(last) {
|
||||
var $form = $('form');
|
||||
var data = $form.serialize() + "&stepid=" + $(".item.active").attr("id");
|
||||
|
||||
$.post($form.attr("action"), data, $.proxy(function(resp) {
|
||||
if (resp.status == "ok") {
|
||||
if (!last) {
|
||||
this.$element.carousel('next');
|
||||
} else {
|
||||
$("#modalbox").modal('hide').remove();
|
||||
window.location.reload();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (resp.content) {
|
||||
$(".modal").html(resp.content);
|
||||
}
|
||||
if (resp.respmsg) {
|
||||
$(".modal-body").prepend(build_error_alert(resp.respmsg));
|
||||
}
|
||||
this.setcallbacks();
|
||||
}, this));
|
||||
},
|
||||
|
||||
update_buttons: function() {
|
||||
$('.bset.active').removeClass("active");
|
||||
$("#" + $(".item.active").attr("id") + "_buttons").addClass("active");
|
||||
},
|
||||
|
||||
next: function(evt) {
|
||||
evt.preventDefault();
|
||||
this.$element.on('slid', this.update_buttons);
|
||||
this.post(false);
|
||||
},
|
||||
|
||||
prev: function(evt) {
|
||||
evt.preventDefault();
|
||||
this.$element.on('slid', update_buttons);
|
||||
this.$element.carousel('prev');
|
||||
},
|
||||
|
||||
submit: function(evt) {
|
||||
evt.preventDefault();
|
||||
this.post(true);
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.cwizard = function(method) {
|
||||
return this.each(function() {
|
||||
var $this = $(this),
|
||||
data = $this.data('cwizard'),
|
||||
options = typeof method === "object" && method;
|
||||
|
||||
if (!data) {
|
||||
$this.data('cwizard', new Cwizard(this, options));
|
||||
}
|
||||
if (typeof method === "string") {
|
||||
data[method]();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,27 +1,7 @@
|
||||
var Domains = new Class({
|
||||
initialize: function(rooturl, deloptions) {
|
||||
this.rooturl = rooturl;
|
||||
if (deloptions != undefined) {
|
||||
this.deloptions = deloptions;
|
||||
} else {
|
||||
this.deloptions = new Array();
|
||||
}
|
||||
if ($("subcontent") != undefined) {
|
||||
SqueezeBox.assign($("subcontent").getElements('a[class=boxed]'), {
|
||||
parse: 'rel'
|
||||
});
|
||||
}
|
||||
setDivHeight("content", 20, 0);
|
||||
this.objtable = new HtmlTable($("objects_table"), {
|
||||
selectable: true
|
||||
});
|
||||
(function($) {
|
||||
var objtable = null;
|
||||
|
||||
$$("a[name=new]").addEvent("click", this.new_clickcb.bind(this));
|
||||
$$("a[name=remove]").addEvent("click", this.remove_clickcb.bind(this));
|
||||
|
||||
},
|
||||
|
||||
new_clickcb: function(evt) {
|
||||
function new_clickcb(evt) {
|
||||
var type = $("objects").get("name");
|
||||
var sizes = $("objects").get("rel").split(" ");
|
||||
|
||||
@@ -30,9 +10,9 @@ var Domains = new Class({
|
||||
size: {x: parseInt(sizes[0]), y: parseInt(sizes[1])},
|
||||
handler: 'iframe'
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
remove_clickcb: function(evt) {
|
||||
function remove_clickcb(evt) {
|
||||
evt.stop();
|
||||
if (this.objtable._selectedRows.length == 0) {
|
||||
return;
|
||||
@@ -62,5 +42,38 @@ var Domains = new Class({
|
||||
checkboxes: this.deloptions
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var methods = {
|
||||
init: function(rooturl, deloptions) {
|
||||
this.rooturl = rooturl;
|
||||
if (deloptions != undefined) {
|
||||
this.deloptions = deloptions;
|
||||
} else {
|
||||
this.deloptions = new Array();
|
||||
}
|
||||
if ($("subcontent") != undefined) {
|
||||
SqueezeBox.assign($("subcontent").getElements('a[class=boxed]'), {
|
||||
parse: 'rel'
|
||||
});
|
||||
}
|
||||
setDivHeight("content", 20, 0);
|
||||
this.objtable = new HtmlTable($("objects_table"), {
|
||||
selectable: true
|
||||
});
|
||||
|
||||
$$("a[name=new]").addEvent("click", new_clickcb);
|
||||
$$("a[name=remove]").addEvent("click", remove_clickcb);
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.Domains = function(method) {
|
||||
if (methods[method]) {
|
||||
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
||||
} else if (typeof method === 'object' || !method) {
|
||||
return methods.init.apply(this, arguments);
|
||||
} else {
|
||||
$.error(gettext('Unknown method: ') + method);
|
||||
}
|
||||
};
|
||||
})(jQuery);
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
(function($) {
|
||||
var DynamicInput = function(element, options) {
|
||||
console.log(element);
|
||||
this.$element = $(element);
|
||||
this.options = $.extend({}, $.fn.dynamic_input.defaults, options);
|
||||
this.nextid = 1;
|
||||
this.baseid = this.$element.attr("id");
|
||||
this.basename = this.$element.attr("name").split("_")[0];
|
||||
|
||||
this.$element.keyup($.proxy(this.checknotempty, this));
|
||||
for (var cpt = 1; true; cpt++) {
|
||||
var $input = $("#" + this.baseid + "_" + cpt);
|
||||
|
||||
if (!$input.length) {
|
||||
break;
|
||||
}
|
||||
$input.after(this.addrmlink($input));
|
||||
$input.focusout(this.checkempty);
|
||||
this.nextid++;
|
||||
}
|
||||
};
|
||||
|
||||
DynamicInput.prototype = {
|
||||
constructor: DynamicInput,
|
||||
|
||||
addrmlink: function(input) {
|
||||
var $rmlink = $('<a href="#"'
|
||||
+ 'id="' + input.attr("id") + '_rmbtn' + '"'
|
||||
+ '"><i class="icon-remove"></i></a>');
|
||||
|
||||
$rmlink.click($.proxy(this.removeinput, $rmlink));
|
||||
return $rmlink;
|
||||
},
|
||||
|
||||
addinput: function() {
|
||||
var id = this.baseid + '_' + this.nextid;
|
||||
var name = this.basename + '_' + this.nextid;
|
||||
var $ninput = $('<input type="text"'
|
||||
+ 'id="' + id + '" '
|
||||
+ 'name="' + name + '"'
|
||||
+ '/>');
|
||||
var $rmlink = this.addrmlink($ninput);
|
||||
|
||||
$ninput.focusout(this.checkempty);
|
||||
$ninput.attr("value", this.$element.attr("value"));
|
||||
this.$element.attr("value", this.options.emptylabel);
|
||||
this.$element.after($ninput, $rmlink);
|
||||
this.nextid++;
|
||||
},
|
||||
|
||||
removeinput: function(evt, force) {
|
||||
evt.preventDefault();
|
||||
var id = "#" + this.attr("id").replace("_rmbtn", "");
|
||||
var $input = $(id);
|
||||
|
||||
if ($input.attr("value") == "" && (force == undefined || !force)) {
|
||||
return;
|
||||
}
|
||||
$input.remove();
|
||||
this.remove();
|
||||
},
|
||||
|
||||
checknotempty: function(evt) {
|
||||
if (evt.keyCode != 13) {
|
||||
return;
|
||||
}
|
||||
if (this.$element.attr("value") == "") {
|
||||
return;
|
||||
}
|
||||
this.addinput();
|
||||
},
|
||||
|
||||
checkempty: function(evt) {
|
||||
var $input = $(evt.target);
|
||||
|
||||
if ($input.attr("value") == "") {
|
||||
$("#" + $input.attr("id") + "_rmbtn").trigger("click", true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.dynamic_input = function(method) {
|
||||
return this.each(function() {
|
||||
var $this = $(this),
|
||||
data = $this.data('dynamic_input'),
|
||||
options = typeof method === "object" && method;
|
||||
|
||||
if (!data) {
|
||||
$this.data('dynamic_input', new DynamicInput(this, options));
|
||||
}
|
||||
if (typeof method === "string") {
|
||||
data[method]();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* Allow an external access to the constructor (for inheritance)
|
||||
*/
|
||||
$.fn.dynamic_input.Constructor = DynamicInput;
|
||||
|
||||
$.fn.dynamic_input.defaults = {
|
||||
emptylabel: ""
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,94 +0,0 @@
|
||||
|
||||
var DynamicTextInput = new Class({
|
||||
Implements: [Options],
|
||||
|
||||
options: {
|
||||
parentContainer: null,
|
||||
containerLevel: 1
|
||||
},
|
||||
|
||||
initialize: function(targets, options) {
|
||||
if (!$defined(targets) || !targets.length) {
|
||||
return;
|
||||
}
|
||||
this.fields_cnt = 0;
|
||||
for (var cpt = 0; cpt < targets.length; cpt++) {
|
||||
var target = targets[cpt];
|
||||
var btn;
|
||||
|
||||
if (cpt == 0) {
|
||||
btn = new Element("img", {
|
||||
src: parent.static_url("pics/add.png")
|
||||
});
|
||||
btn.addEvent("click", this.newelement.bind(this));
|
||||
} else {
|
||||
var btnid = "btn_" + cpt;
|
||||
btn = new Element("img", {
|
||||
src: parent.static_url("pics/remove.png"),
|
||||
id: btnid
|
||||
});
|
||||
btn.addEvent("click", this.removeelement.bind(this));
|
||||
}
|
||||
btn.setStyles({
|
||||
"float": "right",
|
||||
"margin-top": "2px"
|
||||
});
|
||||
btn.inject(target, "after");
|
||||
this.fields_cnt++;
|
||||
}
|
||||
this.nextid = targets.length;
|
||||
this.target = targets[0];
|
||||
this.setOptions(options);
|
||||
},
|
||||
|
||||
createfield: function() {
|
||||
var div = new Element("div").addClass("row");
|
||||
var label = new Element("label").inject(div);
|
||||
var ninput = new Element("input", {
|
||||
type: "text",
|
||||
id: this.target.get("id") + "_" + this.nextid,
|
||||
name: this.target.get("name"),
|
||||
value: this.target.get("value")
|
||||
}).inject(div);
|
||||
|
||||
return [div, ninput];
|
||||
},
|
||||
|
||||
newelement: function(event) {
|
||||
if (this.target.get("value") == "") {
|
||||
return;
|
||||
}
|
||||
var field = this.createfield();
|
||||
var delbtn = new Element("img", {
|
||||
id: "delbtn_" + this.nextid,
|
||||
src: parent.static_url("pics/remove.png")
|
||||
});
|
||||
this.nextid += 1;
|
||||
delbtn.setStyles({
|
||||
"float" : "right",
|
||||
"margin-top": "2px"
|
||||
});
|
||||
if (!this.options.parentContainer) {
|
||||
var container = this.target;
|
||||
for (var i = 0; i < this.options.containerLevel; i++) {
|
||||
container = container.getParent()
|
||||
}
|
||||
field[0].inject(container, "after");
|
||||
} else {
|
||||
field[0].inject(this.options.parentContainer);
|
||||
}
|
||||
delbtn.inject(field[1], "after");
|
||||
delbtn.addEvent("click", this.removeelement.bind(this));
|
||||
this.target.set("value", "");
|
||||
this.fields_cnt++;
|
||||
},
|
||||
|
||||
removeelement: function(event) {
|
||||
var id = (event.target.get("id").split("_"))[1];
|
||||
var input = $("id_" + this.target.get("name") + "_" + id);
|
||||
|
||||
input.destroy();
|
||||
event.target.destroy();
|
||||
this.fields_cnt--;
|
||||
}
|
||||
});
|
||||
@@ -1,126 +0,0 @@
|
||||
var Form = new Class({
|
||||
Implements: [Options],
|
||||
|
||||
options: {
|
||||
resptarget: null
|
||||
},
|
||||
|
||||
callbacks: {
|
||||
error: {},
|
||||
success: {},
|
||||
extra_data: {}
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
this.setOptions(options);
|
||||
|
||||
$(document.body)
|
||||
.removeEvents("submit")
|
||||
.addEvent("submit", this.submit.bind(this));
|
||||
|
||||
this.init_help_messages();
|
||||
},
|
||||
|
||||
init_help_messages: function() {
|
||||
$$("input[type!=submit]", "select").addEvents({
|
||||
focus: function(evt) {
|
||||
var helpdiv = $(evt.target.name + "_helptext");
|
||||
if (helpdiv) {
|
||||
var coords = evt.target.getCoordinates();
|
||||
helpdiv.setPosition({x: 10, y: coords['top'] + coords['height'] + 5});
|
||||
helpdiv.setStyle("display", "block");
|
||||
}
|
||||
},
|
||||
blur: function(evt) {
|
||||
var helpdiv = $(evt.target.name + "_helptext");
|
||||
if (helpdiv) {
|
||||
helpdiv.setStyle("display", "none");
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
register_callback: function(category, name, callback) {
|
||||
if (this.callbacks[category] == undefined) {
|
||||
return false;
|
||||
}
|
||||
this.callbacks[category][name] = callback;
|
||||
return true;
|
||||
},
|
||||
|
||||
register_error_callback: function(name, callback) {
|
||||
return this.register_callback("error", name, callback);
|
||||
},
|
||||
|
||||
register_success_callback: function(name, callback) {
|
||||
return this.register_callback("success", name, callback);
|
||||
},
|
||||
|
||||
register_extra_data_callback: function(name, callback) {
|
||||
return this.register_callback("extra_data", name, callback);
|
||||
},
|
||||
|
||||
submit: function(event) {
|
||||
var form = event.target;
|
||||
var myid = form.get("id");
|
||||
var data = form.toQueryString();
|
||||
|
||||
event.stop();
|
||||
if (this.callbacks["extra_data"][myid] != undefined) {
|
||||
if (data != "") {
|
||||
data += "&";
|
||||
}
|
||||
data += this.callbacks["extra_data"][myid]();
|
||||
}
|
||||
|
||||
new Request.JSON({
|
||||
url: form.get("action"),
|
||||
method: form.get("method"),
|
||||
data: data,
|
||||
onSuccess: function(response) {
|
||||
if (response.status == "ko") {
|
||||
if (response.norefresh != undefined && response.norefresh == true) {
|
||||
$$("div[class=error]").set("html", response.respmsg);
|
||||
} else {
|
||||
var target = (this.options.resptarget)
|
||||
? $(this.options.resptarget) : $(document.body);
|
||||
|
||||
target.set("html", response.content);
|
||||
this.init_help_messages();
|
||||
/*$(document.body).addEvent("submit", ajax_submit);*/
|
||||
if (this.callbacks["error"][myid] != undefined) {
|
||||
this.callbacks["error"][myid]();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ($defined(response.respmsg)) {
|
||||
if ($defined(parent.current_anchor)) {
|
||||
parent.current_anchor.loading_message = response.respmsg;
|
||||
parent.current_anchor.loading_color = "green";
|
||||
} else {
|
||||
parent.infobox.info(response.respmsg);
|
||||
parent.infobox.hide(1);
|
||||
}
|
||||
}
|
||||
if ($defined(response.ajaxnav)) {
|
||||
if ($defined(response.url)) {
|
||||
parent.current_anchor.baseurl(response.url, 1);
|
||||
}
|
||||
parent.current_anchor.update(1);
|
||||
} else if ($defined(response.url)) {
|
||||
parent.location.href = response.url;
|
||||
}
|
||||
if (this.callbacks["success"][myid] != undefined) {
|
||||
this.callbacks["success"][myid](response);
|
||||
}
|
||||
parent.SqueezeBox.close();
|
||||
}.bind(this),
|
||||
onFailure: function(xhr) {
|
||||
parent.document.getElement('iframe')
|
||||
.setStyles({width: 800, height: 600});
|
||||
$(document.body).set("html", xhr.responseText);
|
||||
}
|
||||
}).send();
|
||||
}
|
||||
});
|
||||
@@ -1,32 +1,31 @@
|
||||
/*
|
||||
* Class that implements a simple anchor based navigation system for
|
||||
* AJAX applications.
|
||||
*/
|
||||
var AnchorNavigation = new Class({
|
||||
Implements: [Options],
|
||||
var History = function(options) {
|
||||
this.options = $.extend({}, this.defaults, options);
|
||||
this.callbacks = {};
|
||||
this.params = {};
|
||||
this.base = '';
|
||||
this.serialized = null;
|
||||
this.updatenext = true;
|
||||
this.reset_loading_infos();
|
||||
if (this.options.defcallback) {
|
||||
this.register_callback("default", this.options.defcallback);
|
||||
this.check_id =
|
||||
setInterval($.proxy(this.check, this), this.options.checkinterval);
|
||||
}
|
||||
};
|
||||
|
||||
options: {
|
||||
History.prototype = {
|
||||
constructor: History,
|
||||
|
||||
defaults: {
|
||||
checkinterval: 300,
|
||||
defloadingtext: gettext("Loading..."),
|
||||
defloadingcolor: "gray",
|
||||
deflocation: null,
|
||||
defcallback: null
|
||||
},
|
||||
|
||||
initialize: function(deflocation, options) {
|
||||
this.setOptions(options);
|
||||
|
||||
this.deflocation = deflocation;
|
||||
this.callbacks = {};
|
||||
this.params = $H();
|
||||
this.base = '';
|
||||
this.serialized = null;
|
||||
this.updatenext = true;
|
||||
this.reset_loading_infos();
|
||||
if (this.options.defcallback) {
|
||||
this.register_callback("default", this.options.defcallback);
|
||||
this.ca_id =
|
||||
this.check_anchor.bind(this).periodical(this.options.checkinterval);
|
||||
}
|
||||
paramslength: function() {
|
||||
return Object.keys(this.params).length;
|
||||
},
|
||||
|
||||
reset_loading_infos: function() {
|
||||
@@ -36,7 +35,7 @@ var AnchorNavigation = new Class({
|
||||
|
||||
reset: function() {
|
||||
this.base = null;
|
||||
this.params.empty();
|
||||
this.params = {};
|
||||
return this;
|
||||
},
|
||||
|
||||
@@ -47,13 +46,13 @@ var AnchorNavigation = new Class({
|
||||
if (splits.length == 0) {
|
||||
return this;
|
||||
}
|
||||
if (!$defined(reset)) {
|
||||
if (reset === undefined) {
|
||||
reset = false;
|
||||
}
|
||||
if (reset) {
|
||||
this.reset();
|
||||
}
|
||||
this.base = (splits[0] == "") ? this.deflocation : splits[0];
|
||||
this.base = (splits[0] == "") ? this.options.deflocation : splits[0];
|
||||
|
||||
var re = new RegExp("/$");
|
||||
if (!this.base.match(re)) {
|
||||
@@ -78,21 +77,21 @@ var AnchorNavigation = new Class({
|
||||
serialize: function() {
|
||||
var res = this.base;
|
||||
|
||||
if (this.params.getLength() != 0) {
|
||||
res += "?" + this.params.toQueryString();
|
||||
if (this.paramslength() != 0) {
|
||||
res += "?" + $.param(this.params);
|
||||
}
|
||||
return res;
|
||||
},
|
||||
|
||||
update: function(force, noupdate) {
|
||||
window.fireEvent("pageRefresh");
|
||||
$(window).trigger("pageRefresh");
|
||||
location.hash = this.serialize();
|
||||
|
||||
if (!$defined(noupdate)) {
|
||||
if (noupdate === undefined) {
|
||||
noupdate = false;
|
||||
}
|
||||
if (!noupdate) {
|
||||
if ($defined(force)) {
|
||||
if (force) {
|
||||
this.force = force;
|
||||
}
|
||||
} else {
|
||||
@@ -116,11 +115,11 @@ var AnchorNavigation = new Class({
|
||||
|
||||
setparamfromstring: function(str) {
|
||||
var def = str.split('=');
|
||||
this.params.set(def[0], def[1]);
|
||||
this.params[def[0]] = def[1];
|
||||
},
|
||||
|
||||
setparam: function(name, value) {
|
||||
this.params.set(name, value);
|
||||
this.params[name] = value;
|
||||
return this;
|
||||
},
|
||||
|
||||
@@ -137,7 +136,7 @@ var AnchorNavigation = new Class({
|
||||
},
|
||||
|
||||
baseurl: function(value, noreset) {
|
||||
if (!$defined(noreset) || noreset == 0) {
|
||||
if (noreset === undefined || noreset == 0) {
|
||||
this.reset();
|
||||
}
|
||||
this.base = value;
|
||||
@@ -175,51 +174,41 @@ var AnchorNavigation = new Class({
|
||||
|
||||
set_default_callback: function(callback) {
|
||||
this.register_callback("default", callback);
|
||||
if (!$defined(this.ca_id)) {
|
||||
if (this.ca_id === undefined) {
|
||||
this.ca_id =
|
||||
this.check_anchor.bind(this).periodical(this.options.checkinterval);
|
||||
setInterval($.proxy(this.check, this), this.options.checkinterval);
|
||||
}
|
||||
},
|
||||
|
||||
check_anchor: function() {
|
||||
if (this.serialized == location.hash
|
||||
&& !$defined(this.force)) {
|
||||
check: function() {
|
||||
if (this.serialized == location.hash && this.force === undefined) {
|
||||
return;
|
||||
}
|
||||
delete(this.force);
|
||||
this.from_string(location.hash);
|
||||
if (!this.serialized) {
|
||||
location.hash = this.deflocation;
|
||||
location.hash = this.options.deflocation;
|
||||
return;
|
||||
}
|
||||
if (!this.updatenext) {
|
||||
this.updatenext = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var query = this.serialized.substring(1);
|
||||
|
||||
infobox.show(this.loading_message, {
|
||||
profile: this.loading_color,
|
||||
spinner: true
|
||||
});
|
||||
new Request.JSON({
|
||||
$.ajax({
|
||||
url: query,
|
||||
noCache : true,
|
||||
onComplete: function() {
|
||||
ajax_login_redirect();
|
||||
},
|
||||
onSuccess: function(resp) {
|
||||
var callback = ($defined(resp.callback)) ? resp.callback : "default";
|
||||
cache: false,
|
||||
complete: $.proxy(function(XMLHttpRequest, textStatus) {
|
||||
var resp;
|
||||
try {
|
||||
resp = $.parseJSON(XMLHttpRequest.responseText);
|
||||
} catch (e) {
|
||||
resp = { status: 'ko', respmsg: gettext('Internal Error') };
|
||||
}
|
||||
var callback = (resp.callback != undefined) ? resp.callback : "default";
|
||||
this.callbacks[callback](resp);
|
||||
infobox.info(gettext("Done"));
|
||||
infobox.hide(1);
|
||||
this.reset_loading_infos();
|
||||
}.bind(this),
|
||||
onFailure: function(xhr) {
|
||||
$(document.body).set("html", xhr.responseText);
|
||||
$(document.body).setStyle("overflow", "auto");
|
||||
}
|
||||
}).get();
|
||||
}, this)
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -1,123 +0,0 @@
|
||||
var InfoBox = new Class({
|
||||
Implements: [Options, Events],
|
||||
options: {
|
||||
parent : null,
|
||||
message : "This is my info box!",
|
||||
width : 200
|
||||
},
|
||||
|
||||
profiles: {
|
||||
gray : {"background" : "#EEEEEE", "border" : "#CCCCCC"},
|
||||
green : {"background" : "#DAF8DA", "border" : "#166D14"},
|
||||
red : {"background" : "#F9D2D2", "border" : "#FF2A00"},
|
||||
yellow : {"background" : "#FDE6B5", "border" : "#FF7F00"}
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
this.setOptions(options);
|
||||
|
||||
var boxleft = $(document.body).getSize().x / 2 - this.options.width / 2;
|
||||
this.box = new Element("div", {"id" : "infobox"});
|
||||
this.box.setStyles({
|
||||
"font-size" : "1em",
|
||||
"font-weight" : "bold",
|
||||
"text-align" : "left",
|
||||
"padding" : "10px",
|
||||
"position" : "absolute",
|
||||
"display" : "none"
|
||||
});
|
||||
this.calcsize();
|
||||
this.setProfile("gray");
|
||||
this.spinner = new Element("img", {
|
||||
"src" : "/static/css/spinner.gif"
|
||||
});
|
||||
this.spinner.setStyle("float", "left");
|
||||
this.spinner.inject(this.box);
|
||||
|
||||
this.label = new Element("label").set("html", this.options.message);
|
||||
this.label.setStyles({
|
||||
"white-space": "pre-line"
|
||||
/*"margin-left" : "10px"*/
|
||||
});
|
||||
this.label.inject(this.box);
|
||||
this.box.inject($(document.body));
|
||||
},
|
||||
|
||||
calcsize: function(width) {
|
||||
var w = ($defined(width) ? width : this.options.width);
|
||||
var boxleft = $(document.body).getSize().x / 2 - w / 2;
|
||||
|
||||
this.box.setStyles({
|
||||
width: w + "px",
|
||||
left: boxleft + "px",
|
||||
top: "0px"
|
||||
});
|
||||
},
|
||||
|
||||
setMessage: function(text) {
|
||||
this.label.set("html", text);
|
||||
},
|
||||
|
||||
setProfile: function(color) {
|
||||
this.box.setStyles({
|
||||
"background" : this.profiles[color].background,
|
||||
"border" : "2px solid " + this.profiles[color].border
|
||||
});
|
||||
},
|
||||
|
||||
info: function(message) {
|
||||
this.show(message, {
|
||||
profile: "green"
|
||||
});
|
||||
},
|
||||
|
||||
error: function(message) {
|
||||
this.show(message, {
|
||||
profile: "red"
|
||||
});
|
||||
},
|
||||
|
||||
warning: function(message) {
|
||||
this.show(message, {
|
||||
profile: "yellow"
|
||||
});
|
||||
},
|
||||
|
||||
show: function(message, arguments) {
|
||||
if ($defined(this.start)) {
|
||||
if ($time() - this.start > this.delay) {
|
||||
$clear(this.showtimer);
|
||||
delete(this.start);
|
||||
delete(this.delay);
|
||||
} else {
|
||||
this.showtimer = this.show.delay(100, this, [message, arguments]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ($defined(message)) {
|
||||
this.setMessage(message);
|
||||
}
|
||||
if ($defined(arguments.profile)) {
|
||||
this.setProfile(arguments.profile);
|
||||
}
|
||||
if ($defined(arguments.delay)) {
|
||||
this.start = $time();
|
||||
this.delay = arguments.delay * 1000;
|
||||
}
|
||||
if ($defined(arguments.spinner) && arguments.spinner) {
|
||||
this.spinner.setStyle("display", "block");
|
||||
} else {
|
||||
this.spinner.setStyle("display", "none");
|
||||
}
|
||||
this.box.setStyle("display", "block");
|
||||
},
|
||||
|
||||
hide: function(timer) {
|
||||
this.timer = this.hide_cb.periodical(timer * 1000, this);
|
||||
},
|
||||
|
||||
hide_cb: function() {
|
||||
$clear(this.timer);
|
||||
this.box.setStyle("display", "none");
|
||||
}
|
||||
});
|
||||
@@ -1,314 +0,0 @@
|
||||
// MooTools: the javascript framework.
|
||||
// Load this file's selection again by visiting: http://mootools.net/more/0d7eff673be62f7563fb40582690b0f5
|
||||
// Or build this file again with packager using: packager build More/String.QueryString More/URI More/Hash More/Form.Request More/Fx.Accordion More/Fx.Slide More/Drag.Move More/HtmlTable.Select More/Tips
|
||||
/*
|
||||
---
|
||||
copyrights:
|
||||
- [MooTools](http://mootools.net)
|
||||
|
||||
licenses:
|
||||
- [MIT License](http://mootools.net/license.txt)
|
||||
...
|
||||
*/
|
||||
MooTools.More={version:"1.3.1.1",build:"0292a3af1eea242b817fecf9daa127417d10d4ce"};String.implement({parseQueryString:function(d,a){if(d==null){d=true;
|
||||
}if(a==null){a=true;}var c=this.split(/[&;]/),b={};if(!c.length){return b;}c.each(function(i){var e=i.indexOf("=")+1,g=e?i.substr(e):"",f=e?i.substr(0,e-1).match(/([^\]\[]+|(\B)(?=\]))/g):[i],h=b;
|
||||
if(!f){return;}if(a){g=decodeURIComponent(g);}f.each(function(k,j){if(d){k=decodeURIComponent(k);}var l=h[k];if(j<f.length-1){h=h[k]=l||{};}else{if(typeOf(l)=="array"){l.push(g);
|
||||
}else{h[k]=l!=null?[l,g]:g;}}});});return b;},cleanQueryString:function(a){return this.split("&").filter(function(e){var b=e.indexOf("="),c=b<0?"":e.substr(0,b),d=e.substr(b+1);
|
||||
return a?a.call(null,c,d):(d||d===0);}).join("&");}});(function(){var b=function(){return this.get("value");};var a=this.URI=new Class({Implements:Options,options:{},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(d,c){this.setOptions(c);
|
||||
var e=this.options.base||a.base;if(!d){d=e;}if(d&&d.parsed){this.parsed=Object.clone(d.parsed);}else{this.set("value",d.href||d.toString(),e?new a(e):false);
|
||||
}},parse:function(e,d){var c=e.match(this.regex);if(!c){return false;}c.shift();return this.merge(c.associate(this.parts),d);},merge:function(d,c){if((!d||!d.scheme)&&(!c||!c.scheme)){return false;
|
||||
}if(c){this.parts.every(function(e){if(d[e]){return false;}d[e]=c[e]||"";return true;});}d.port=d.port||this.schemes[d.scheme.toLowerCase()];d.directory=d.directory?this.parseDirectory(d.directory,c?c.directory:""):"/";
|
||||
return d;},parseDirectory:function(d,e){d=(d.substr(0,1)=="/"?"":(e||"/"))+d;if(!d.test(a.regs.directoryDot)){return d;}var c=[];d.replace(a.regs.endSlash,"").split("/").each(function(f){if(f==".."&&c.length>0){c.pop();
|
||||
}else{if(f!="."){c.push(f);}}});return c.join("/")+"/";},combine:function(c){return c.value||c.scheme+"://"+(c.user?c.user+(c.password?":"+c.password:"")+"@":"")+(c.host||"")+(c.port&&c.port!=this.schemes[c.scheme]?":"+c.port:"")+(c.directory||"/")+(c.file||"")+(c.query?"?"+c.query:"")+(c.fragment?"#"+c.fragment:"");
|
||||
},set:function(d,f,e){if(d=="value"){var c=f.match(a.regs.scheme);if(c){c=c[1];}if(c&&this.schemes[c.toLowerCase()]==null){this.parsed={scheme:c,value:f};
|
||||
}else{this.parsed=this.parse(f,(e||this).parsed)||(c?{scheme:c,value:f}:{value:f});}}else{if(d=="data"){this.setData(f);}else{this.parsed[d]=f;}}return this;
|
||||
},get:function(c,d){switch(c){case"value":return this.combine(this.parsed,d?d.parsed:false);case"data":return this.getData();}return this.parsed[c]||"";
|
||||
},go:function(){document.location.href=this.toString();},toURI:function(){return this;},getData:function(e,d){var c=this.get(d||"query");if(!(c||c===0)){return e?null:{};
|
||||
}var f=c.parseQueryString();return e?f[e]:f;},setData:function(c,f,d){if(typeof c=="string"){var e=this.getData();e[arguments[0]]=arguments[1];c=e;}else{if(f){c=Object.merge(this.getData(),c);
|
||||
}}return this.set(d||"query",Object.toQueryString(c));},clearData:function(c){return this.set(c||"query","");},toString:b,valueOf:b});a.regs={endSlash:/\/$/,scheme:/^(\w+):/,directoryDot:/\.\/|\.$/};
|
||||
a.base=new a(Array.from(document.getElements("base[href]",true)).getLast(),{base:document.location});String.implement({toURI:function(c){return new a(this,c);
|
||||
}});}).call(this);(function(){if(this.Hash){return;}var a=this.Hash=new Type("Hash",function(b){if(typeOf(b)=="hash"){b=Object.clone(b.getClean());}for(var c in b){this[c]=b[c];
|
||||
}return this;});this.$H=function(b){return new a(b);};a.implement({forEach:function(b,c){Object.forEach(this,b,c);},getClean:function(){var c={};for(var b in this){if(this.hasOwnProperty(b)){c[b]=this[b];
|
||||
}}return c;},getLength:function(){var c=0;for(var b in this){if(this.hasOwnProperty(b)){c++;}}return c;}});a.alias("each","forEach");a.implement({has:Object.prototype.hasOwnProperty,keyOf:function(b){return Object.keyOf(this,b);
|
||||
},hasValue:function(b){return Object.contains(this,b);},extend:function(b){a.each(b||{},function(d,c){a.set(this,c,d);},this);return this;},combine:function(b){a.each(b||{},function(d,c){a.include(this,c,d);
|
||||
},this);return this;},erase:function(b){if(this.hasOwnProperty(b)){delete this[b];}return this;},get:function(b){return(this.hasOwnProperty(b))?this[b]:null;
|
||||
},set:function(b,c){if(!this[b]||this.hasOwnProperty(b)){this[b]=c;}return this;},empty:function(){a.each(this,function(c,b){delete this[b];},this);return this;
|
||||
},include:function(b,c){if(this[b]==undefined){this[b]=c;}return this;},map:function(b,c){return new a(Object.map(this,b,c));},filter:function(b,c){return new a(Object.filter(this,b,c));
|
||||
},every:function(b,c){return Object.every(this,b,c);},some:function(b,c){return Object.some(this,b,c);},getKeys:function(){return Object.keys(this);},getValues:function(){return Object.values(this);
|
||||
},toQueryString:function(b){return Object.toQueryString(this,b);}});a.alias({indexOf:"keyOf",contains:"hasValue"});}).call(this);Class.Mutators.Binds=function(a){if(!this.prototype.initialize){this.implement("initialize",function(){});
|
||||
}return a;};Class.Mutators.initialize=function(a){return function(){Array.from(this.Binds).each(function(b){var c=this[b];if(c){this[b]=c.bind(this);}},this);
|
||||
return a.apply(this,arguments);};};Class.Occlude=new Class({occlude:function(c,b){b=document.id(b||this.element);var a=b.retrieve(c||this.property);if(a&&!this.occluded){return(this.occluded=a);
|
||||
}this.occluded=false;b.store(c||this.property,this);return this.occluded;}});Class.refactor=function(b,a){Object.each(a,function(e,d){var c=b.prototype[d];
|
||||
if(c&&c.$origin){c=c.$origin;}b.implement(d,(typeof e=="function")?function(){var f=this.previous;this.previous=c||function(){};var g=e.apply(this,arguments);
|
||||
this.previous=f;return g;}:e);});return b;};(function(){var b=function(e,d){var f=[];Object.each(d,function(g){Object.each(g,function(h){e.each(function(i){f.push(i+"-"+h+(i=="border"?"-width":""));
|
||||
});});});return f;};var c=function(f,e){var d=0;Object.each(e,function(h,g){if(g.test(f)){d=d+h.toInt();}});return d;};var a=function(d){return !!(!d||d.offsetHeight||d.offsetWidth);
|
||||
};Element.implement({measure:function(h){if(a(this)){return h.call(this);}var g=this.getParent(),e=[];while(!a(g)&&g!=document.body){e.push(g.expose());
|
||||
g=g.getParent();}var f=this.expose(),d=h.call(this);f();e.each(function(i){i();});return d;},expose:function(){if(this.getStyle("display")!="none"){return function(){};
|
||||
}var d=this.style.cssText;this.setStyles({display:"block",position:"absolute",visibility:"hidden"});return function(){this.style.cssText=d;}.bind(this);
|
||||
},getDimensions:function(d){d=Object.merge({computeSize:false},d);var i={x:0,y:0};var h=function(j,e){return(e.computeSize)?j.getComputedSize(e):j.getSize();
|
||||
};var f=this.getParent("body");if(f&&this.getStyle("display")=="none"){i=this.measure(function(){return h(this,d);});}else{if(f){try{i=h(this,d);}catch(g){}}}return Object.append(i,(i.x||i.x===0)?{width:i.x,height:i.y}:{x:i.width,y:i.height});
|
||||
},getComputedSize:function(d){if(d&&d.plains){d.planes=d.plains;}d=Object.merge({styles:["padding","border"],planes:{height:["top","bottom"],width:["left","right"]},mode:"both"},d);
|
||||
var g={},e={width:0,height:0},f;if(d.mode=="vertical"){delete e.width;delete d.planes.width;}else{if(d.mode=="horizontal"){delete e.height;delete d.planes.height;
|
||||
}}b(d.styles,d.planes).each(function(h){g[h]=this.getStyle(h).toInt();},this);Object.each(d.planes,function(i,h){var k=h.capitalize(),j=this.getStyle(h);
|
||||
if(j=="auto"&&!f){f=this.getDimensions();}j=g[h]=(j=="auto")?f[h]:j.toInt();e["total"+k]=j;i.each(function(m){var l=c(m,g);e["computed"+m.capitalize()]=l;
|
||||
e["total"+k]+=l;});},this);return Object.append(e,g);}});}).call(this);(function(){var a=Element.prototype.position;Element.implement({position:function(g){if(g&&(g.x!=null||g.y!=null)){return a?a.apply(this,arguments):this;
|
||||
}Object.each(g||{},function(u,t){if(u==null){delete g[t];}});g=Object.merge({relativeTo:document.body,position:{x:"center",y:"center"},offset:{x:0,y:0}},g);
|
||||
var r={x:0,y:0},e=false;var c=this.measure(function(){return document.id(this.getOffsetParent());});if(c&&c!=this.getDocument().body){r=c.measure(function(){return this.getPosition();
|
||||
});e=c!=document.id(g.relativeTo);g.offset.x=g.offset.x-r.x;g.offset.y=g.offset.y-r.y;}var s=function(t){if(typeOf(t)!="string"){return t;}t=t.toLowerCase();
|
||||
var u={};if(t.test("left")){u.x="left";}else{if(t.test("right")){u.x="right";}else{u.x="center";}}if(t.test("upper")||t.test("top")){u.y="top";}else{if(t.test("bottom")){u.y="bottom";
|
||||
}else{u.y="center";}}return u;};g.edge=s(g.edge);g.position=s(g.position);if(!g.edge){if(g.position.x=="center"&&g.position.y=="center"){g.edge={x:"center",y:"center"};
|
||||
}else{g.edge={x:"left",y:"top"};}}this.setStyle("position","absolute");var f=document.id(g.relativeTo)||document.body,d=f==document.body?window.getScroll():f.getPosition(),l=d.y,h=d.x;
|
||||
var n=this.getDimensions({computeSize:true,styles:["padding","border","margin"]});var j={},o=g.offset.y,q=g.offset.x,k=window.getSize();switch(g.position.x){case"left":j.x=h+q;
|
||||
break;case"right":j.x=h+q+f.offsetWidth;break;default:j.x=h+((f==document.body?k.x:f.offsetWidth)/2)+q;break;}switch(g.position.y){case"top":j.y=l+o;break;
|
||||
case"bottom":j.y=l+o+f.offsetHeight;break;default:j.y=l+((f==document.body?k.y:f.offsetHeight)/2)+o;break;}if(g.edge){var b={};switch(g.edge.x){case"left":b.x=0;
|
||||
break;case"right":b.x=-n.x-n.computedRight-n.computedLeft;break;default:b.x=-(n.totalWidth/2);break;}switch(g.edge.y){case"top":b.y=0;break;case"bottom":b.y=-n.y-n.computedTop-n.computedBottom;
|
||||
break;default:b.y=-(n.totalHeight/2);break;}j.x+=b.x;j.y+=b.y;}j={left:((j.x>=0||e||g.allowNegative)?j.x:0).toInt(),top:((j.y>=0||e||g.allowNegative)?j.y:0).toInt()};
|
||||
var i={left:"x",top:"y"};["minimum","maximum"].each(function(t){["left","top"].each(function(u){var v=g[t]?g[t][i[u]]:null;if(v!=null&&((t=="minimum")?j[u]<v:j[u]>v)){j[u]=v;
|
||||
}});});if(f.getStyle("position")=="fixed"||g.relFixedPosition){var m=window.getScroll();j.top+=m.y;j.left+=m.x;}if(g.ignoreScroll){var p=f.getScroll();
|
||||
j.top-=p.y;j.left-=p.x;}if(g.ignoreMargins){j.left+=(g.edge.x=="right"?n["margin-right"]:g.edge.x=="center"?-n["margin-left"]+((n["margin-right"]+n["margin-left"])/2):-n["margin-left"]);
|
||||
j.top+=(g.edge.y=="bottom"?n["margin-bottom"]:g.edge.y=="center"?-n["margin-top"]+((n["margin-bottom"]+n["margin-top"])/2):-n["margin-top"]);}j.left=Math.ceil(j.left);
|
||||
j.top=Math.ceil(j.top);if(g.returnPos){return j;}else{this.setStyles(j);}return this;}});}).call(this);var IframeShim=new Class({Implements:[Options,Events,Class.Occlude],options:{className:"iframeShim",src:'javascript:false;document.write("");',display:false,zIndex:null,margin:0,offset:{x:0,y:0},browsers:(Browser.ie6||(Browser.firefox&&Browser.version<3&&Browser.Platform.mac))},property:"IframeShim",initialize:function(b,a){this.element=document.id(b);
|
||||
if(this.occlude()){return this.occluded;}this.setOptions(a);this.makeShim();return this;},makeShim:function(){if(this.options.browsers){var c=this.element.getStyle("zIndex").toInt();
|
||||
if(!c){c=1;var b=this.element.getStyle("position");if(b=="static"||!b){this.element.setStyle("position","relative");}this.element.setStyle("zIndex",c);
|
||||
}c=((this.options.zIndex!=null||this.options.zIndex===0)&&c>this.options.zIndex)?this.options.zIndex:c-1;if(c<0){c=1;}this.shim=new Element("iframe",{src:this.options.src,scrolling:"no",frameborder:0,styles:{zIndex:c,position:"absolute",border:"none",filter:"progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)"},"class":this.options.className}).store("IframeShim",this);
|
||||
var a=(function(){this.shim.inject(this.element,"after");this[this.options.display?"show":"hide"]();this.fireEvent("inject");}).bind(this);if(!IframeShim.ready){window.addEvent("load",a);
|
||||
}else{a();}}else{this.position=this.hide=this.show=this.dispose=Function.from(this);}},position:function(){if(!IframeShim.ready||!this.shim){return this;
|
||||
}var a=this.element.measure(function(){return this.getSize();});if(this.options.margin!=undefined){a.x=a.x-(this.options.margin*2);a.y=a.y-(this.options.margin*2);
|
||||
this.options.offset.x+=this.options.margin;this.options.offset.y+=this.options.margin;}this.shim.set({width:a.x,height:a.y}).position({relativeTo:this.element,offset:this.options.offset});
|
||||
return this;},hide:function(){if(this.shim){this.shim.setStyle("display","none");}return this;},show:function(){if(this.shim){this.shim.setStyle("display","block");
|
||||
}return this.position();},dispose:function(){if(this.shim){this.shim.dispose();}return this;},destroy:function(){if(this.shim){this.shim.destroy();}return this;
|
||||
}});window.addEvent("load",function(){IframeShim.ready=true;});var Mask=new Class({Implements:[Options,Events],Binds:["position"],options:{style:{},"class":"mask",maskMargins:false,useIframeShim:true,iframeShimOptions:{}},initialize:function(b,a){this.target=document.id(b)||document.id(document.body);
|
||||
this.target.store("mask",this);this.setOptions(a);this.render();this.inject();},render:function(){this.element=new Element("div",{"class":this.options["class"],id:this.options.id||"mask-"+String.uniqueID(),styles:Object.merge({},this.options.style,{display:"none"}),events:{click:function(a){this.fireEvent("click",a);
|
||||
if(this.options.hideOnClick){this.hide();}}.bind(this)}});this.hidden=true;},toElement:function(){return this.element;},inject:function(b,a){a=a||(this.options.inject?this.options.inject.where:"")||this.target==document.body?"inside":"after";
|
||||
b=b||(this.options.inject&&this.options.inject.target)||this.target;this.element.inject(b,a);if(this.options.useIframeShim){this.shim=new IframeShim(this.element,this.options.iframeShimOptions);
|
||||
this.addEvents({show:this.shim.show.bind(this.shim),hide:this.shim.hide.bind(this.shim),destroy:this.shim.destroy.bind(this.shim)});}},position:function(){this.resize(this.options.width,this.options.height);
|
||||
this.element.position({relativeTo:this.target,position:"topLeft",ignoreMargins:!this.options.maskMargins,ignoreScroll:this.target==document.body});return this;
|
||||
},resize:function(a,e){var b={styles:["padding","border"]};if(this.options.maskMargins){b.styles.push("margin");}var d=this.target.getComputedSize(b);if(this.target==document.body){this.element.setStyles({width:0,height:0});
|
||||
var c=window.getScrollSize();if(d.totalHeight<c.y){d.totalHeight=c.y;}if(d.totalWidth<c.x){d.totalWidth=c.x;}}this.element.setStyles({width:Array.pick([a,d.totalWidth,d.x]),height:Array.pick([e,d.totalHeight,d.y])});
|
||||
return this;},show:function(){if(!this.hidden){return this;}window.addEvent("resize",this.position);this.position();this.showMask.apply(this,arguments);
|
||||
return this;},showMask:function(){this.element.setStyle("display","block");this.hidden=false;this.fireEvent("show");},hide:function(){if(this.hidden){return this;
|
||||
}window.removeEvent("resize",this.position);this.hideMask.apply(this,arguments);if(this.options.destroyOnHide){return this.destroy();}return this;},hideMask:function(){this.element.setStyle("display","none");
|
||||
this.hidden=true;this.fireEvent("hide");},toggle:function(){this[this.hidden?"show":"hide"]();},destroy:function(){this.hide();this.element.destroy();this.fireEvent("destroy");
|
||||
this.target.eliminate("mask");}});Element.Properties.mask={set:function(b){var a=this.retrieve("mask");if(a){a.destroy();}return this.eliminate("mask").store("mask:options",b);
|
||||
},get:function(){var a=this.retrieve("mask");if(!a){a=new Mask(this,this.retrieve("mask:options"));this.store("mask",a);}return a;}};Element.implement({mask:function(a){if(a){this.set("mask",a);
|
||||
}this.get("mask").show();return this;},unmask:function(){this.get("mask").hide();return this;}});var Spinner=new Class({Extends:Mask,Implements:Chain,options:{"class":"spinner",containerPosition:{},content:{"class":"spinner-content"},messageContainer:{"class":"spinner-msg"},img:{"class":"spinner-img"},fxOptions:{link:"chain"}},initialize:function(c,a){this.target=document.id(c)||document.id(document.body);
|
||||
this.target.store("spinner",this);this.setOptions(a);this.render();this.inject();var b=function(){this.active=false;}.bind(this);this.addEvents({hide:b,show:b});
|
||||
},render:function(){this.parent();this.element.set("id",this.options.id||"spinner-"+String.uniqueID());this.content=document.id(this.options.content)||new Element("div",this.options.content);
|
||||
this.content.inject(this.element);if(this.options.message){this.msg=document.id(this.options.message)||new Element("p",this.options.messageContainer).appendText(this.options.message);
|
||||
this.msg.inject(this.content);}if(this.options.img){this.img=document.id(this.options.img)||new Element("div",this.options.img);this.img.inject(this.content);
|
||||
}this.element.set("tween",this.options.fxOptions);},show:function(a){if(this.active){return this.chain(this.show.bind(this));}if(!this.hidden){this.callChain.delay(20,this);
|
||||
return this;}this.active=true;return this.parent(a);},showMask:function(a){var b=function(){this.content.position(Object.merge({relativeTo:this.element},this.options.containerPosition));
|
||||
}.bind(this);if(a){this.parent();b();}else{if(!this.options.style.opacity){this.options.style.opacity=this.element.getStyle("opacity").toFloat();}this.element.setStyles({display:"block",opacity:0}).tween("opacity",this.options.style.opacity);
|
||||
b();this.hidden=false;this.fireEvent("show");this.callChain();}},hide:function(a){if(this.active){return this.chain(this.hide.bind(this));}if(this.hidden){this.callChain.delay(20,this);
|
||||
return this;}this.active=true;return this.parent(a);},hideMask:function(a){if(a){return this.parent();}this.element.tween("opacity",0).get("tween").chain(function(){this.element.setStyle("display","none");
|
||||
this.hidden=true;this.fireEvent("hide");this.callChain();}.bind(this));},destroy:function(){this.content.destroy();this.parent();this.target.eliminate("spinner");
|
||||
}});Request=Class.refactor(Request,{options:{useSpinner:false,spinnerOptions:{},spinnerTarget:false},initialize:function(a){this._send=this.send;this.send=function(b){var c=this.getSpinner();
|
||||
if(c){c.chain(this._send.pass(b,this)).show();}else{this._send(b);}return this;};this.previous(a);},getSpinner:function(){if(!this.spinner){var b=document.id(this.options.spinnerTarget)||document.id(this.options.update);
|
||||
if(this.options.useSpinner&&b){b.set("spinner",this.options.spinnerOptions);var a=this.spinner=b.get("spinner");["complete","exception","cancel"].each(function(c){this.addEvent(c,a.hide.bind(a));
|
||||
},this);}}return this.spinner;}});Element.Properties.spinner={set:function(a){var b=this.retrieve("spinner");if(b){b.destroy();}return this.eliminate("spinner").store("spinner:options",a);
|
||||
},get:function(){var a=this.retrieve("spinner");if(!a){a=new Spinner(this,this.retrieve("spinner:options"));this.store("spinner",a);}return a;}};Element.implement({spin:function(a){if(a){this.set("spinner",a);
|
||||
}this.get("spinner").show();return this;},unspin:function(){this.get("spinner").hide();return this;}});Events.Pseudos=function(g,c,e){var b="monitorEvents:";
|
||||
var a=function(h){return{store:h.store?function(i,j){h.store(b+i,j);}:function(i,j){(h.$monitorEvents||(h.$monitorEvents={}))[i]=j;},retrieve:h.retrieve?function(i,j){return h.retrieve(b+i,j);
|
||||
}:function(i,j){if(!h.$monitorEvents){return j;}return h.$monitorEvents[i]||j;}};};var f=function(j){if(j.indexOf(":")==-1||!g){return null;}var i=Slick.parse(j).expressions[0][0],m=i.pseudos,h=m.length,k=[];
|
||||
while(h--){if(g[m[h].key]){k.push({event:i.tag,value:m[h].value,pseudo:m[h].key,original:j});}}return k.length?k:null;};var d=function(h){return Object.merge.apply(this,h.map(function(i){return g[i.pseudo].options||{};
|
||||
}));};return{addEvent:function(m,p,j){var n=f(m);if(!n){return c.call(this,m,p,j);}var k=a(this),s=k.retrieve(m,[]),h=n[0].event,t=d(n),o=p,i=t[h]||{},l=Array.slice(arguments,2),r=this,q;
|
||||
if(i.args){l.append(Array.from(i.args));}if(i.base){h=i.base;}if(i.onAdd){i.onAdd(this);}n.each(function(u){var v=o;o=function(){(i.listener||g[u.pseudo].listener).call(r,u,v,arguments,q,t);
|
||||
};});q=o.bind(this);s.include({event:p,monitor:q});k.store(m,s);c.apply(this,[m,p].concat(l));return c.apply(this,[h,q].concat(l));},removeEvent:function(l,n){var m=f(l);
|
||||
if(!m){return e.call(this,l,n);}var j=a(this),o=j.retrieve(l);if(!o){return this;}var h=m[0].event,p=d(m),i=p[h]||{},k=Array.slice(arguments,2);if(i.args){k.append(Array.from(i.args));
|
||||
}if(i.base){h=i.base;}if(i.onRemove){i.onRemove(this);}e.apply(this,[l,n].concat(k));o.each(function(q,r){if(!n||q.event==n){e.apply(this,[h,q.monitor].concat(k));
|
||||
}delete o[r];},this);j.store(l,o);return this;}};};(function(){var b={once:{listener:function(e,f,d,c){f.apply(this,d);this.removeEvent(e.event,c).removeEvent(e.original,f);
|
||||
}},throttle:{listener:function(d,e,c){if(!e._throttled){e.apply(this,c);e._throttled=setTimeout(function(){e._throttled=false;},d.value||250);}}},pause:{listener:function(d,e,c){clearTimeout(e._pause);
|
||||
e._pause=e.delay(d.value||250,this,c);}}};Events.definePseudo=function(c,d){b[c]=Type.isFunction(d)?{listener:d}:d;return this;};Events.lookupPseudo=function(c){return b[c];
|
||||
};var a=Events.prototype;Events.implement(Events.Pseudos(b,a.addEvent,a.removeEvent));["Request","Fx"].each(function(c){if(this[c]){this[c].implement(Events.prototype);
|
||||
}});}).call(this);(function(){var d={},c=["once","throttle","pause"],b=c.length;while(b--){d[c[b]]=Events.lookupPseudo(c[b]);}Event.definePseudo=function(e,f){d[e]=Type.isFunction(f)?{listener:f}:f;
|
||||
return this;};var a=Element.prototype;[Element,Window,Document].invoke("implement",Events.Pseudos(d,a.addEvent,a.removeEvent));}).call(this);(function(){var b=!(window.attachEvent&&!window.addEventListener),e=Element.NativeEvents;
|
||||
e.focusin=2;e.focusout=2;var c=function(g,j,h){var i=Element.Events[g.event],k;if(i){k=i.condition;}return Slick.match(j,g.value)&&(!k||k.call(j,h));};
|
||||
var f=function(g){var h="$delegation:";return{base:"focusin",onRemove:function(i){i.retrieve(h+"forms",[]).each(function(j){j.retrieve(h+"listeners",[]).each(function(k){j.removeEvent(g,k);
|
||||
});j.eliminate(h+g+"listeners").eliminate(h+g+"originalFn");});},listener:function(q,r,p,s,t){var j=p[0],i=this.retrieve(h+"forms",[]),o=j.target,l=(o.get("tag")=="form")?o:j.target.getParent("form"),n=l.retrieve(h+"originalFn",[]),k=l.retrieve(h+"listeners",[]);
|
||||
i.include(l);this.store(h+"forms",i);if(!n.contains(r)){var m=function(u){if(c(q,this,u)){r.call(this,u);}};l.addEvent(g,m);n.push(r);k.push(m);l.store(h+g+"originalFn",n).store(h+g+"listeners",k);
|
||||
}}};};var a=function(g){return{base:"focusin",listener:function(j,k,h){var i={blur:function(){this.removeEvents(i);}};i[g]=function(l){if(c(j,this,l)){k.call(this,l);
|
||||
}};h[0].target.addEvents(i);}};};var d={mouseenter:{base:"mouseover"},mouseleave:{base:"mouseout"},focus:{base:"focus"+(b?"":"in"),args:[true]},blur:{base:b?"blur":"focusout",args:[true]}};
|
||||
if(!b){Object.append(d,{submit:f("submit"),reset:f("reset"),change:a("change"),select:a("select")});}Event.definePseudo("relay",{listener:function(j,k,i,g,h){var l=i[0];
|
||||
for(var n=l.target;n&&n!=this;n=n.parentNode){var m=document.id(n);if(c(j,m,l)){if(m){k.call(m,l,m);}return;}}},options:d});}).call(this);if(!window.Form){window.Form={};
|
||||
}(function(){Form.Request=new Class({Binds:["onSubmit","onFormValidate"],Implements:[Options,Events,Class.Occlude],options:{requestOptions:{evalScripts:true,useSpinner:true,emulation:false,link:"ignore"},sendButtonClicked:true,extraData:{},resetForm:true},property:"form.request",initialize:function(b,c,a){this.element=document.id(b);
|
||||
if(this.occlude()){return this.occluded;}this.update=document.id(c);this.setOptions(a);this.makeRequest();if(this.options.resetForm){this.request.addEvent("success",function(){Function.attempt(function(){this.element.reset();
|
||||
}.bind(this));if(window.OverText){OverText.update();}}.bind(this));}this.attach();},toElement:function(){return this.element;},makeRequest:function(){this.request=new Request.HTML(Object.merge({update:this.update,emulation:false,spinnerTarget:this.element,method:this.element.get("method")||"post"},this.options.requestOptions)).addEvents({success:function(b,d,c,a){["complete","success"].each(function(e){this.fireEvent(e,[this.update,b,d,c,a]);
|
||||
},this);}.bind(this),failure:function(){this.fireEvent("complete",arguments).fireEvent("failure",arguments);}.bind(this),exception:function(){this.fireEvent("failure",arguments);
|
||||
}.bind(this)});},attach:function(a){if(a==null){a=true;}var c=a?"addEvent":"removeEvent";this.element[c]("click:relay(button, input[type=submit])",this.saveClickedButton.bind(this));
|
||||
var b=this.element.retrieve("validator");if(b){b[c]("onFormValidate",this.onFormValidate);}else{this.element[c]("submit",this.onSubmit);}},detach:function(){this.attach(false);
|
||||
return this;},enable:function(){this.attach();return this;},disable:function(){this.detach();return this;},onFormValidate:function(c,b,a){if(!a){return;
|
||||
}var d=this.element.retrieve("validator");if(c||(d&&!d.options.stopOnFailure)){a.stop();this.send();}},onSubmit:function(a){var b=this.element.retrieve("validator");
|
||||
if(b){this.element.removeEvent("submit",this.onSubmit);b.addEvent("onFormValidate",this.onFormValidate);this.element.validate();return;}if(a){a.stop();
|
||||
}this.send();},saveClickedButton:function(a,b){if(!this.options.sendButtonClicked||!b.get("name")){return;}this.options.extraData[b.get("name")]=b.get("value")||true;
|
||||
this.clickedCleaner=function(){delete this.options.extraData[b.get("name")];this.clickedCleaner=function(){};}.bind(this);},clickedCleaner:function(){},send:function(){var b=this.element.toQueryString().trim(),a=Object.toQueryString(this.options.extraData);
|
||||
if(b){b+="&"+a;}else{b=a;}this.fireEvent("send",[this.element,b.parseQueryString()]);this.request.send({data:b,url:this.options.requestOptions.url||this.element.get("action")});
|
||||
this.clickedCleaner();return this;}});Element.Properties.formRequest={set:function(){var a=Array.link(arguments,{options:Type.isObject,update:Type.isElement,updateId:Type.isString}),c=a.update||a.updateId,b=this.retrieve("form.request");
|
||||
if(c){if(b){b.update=document.id(c);}this.store("form.request:update",c);}if(a.options){if(b){b.setOptions(a.options);}this.store("form.request:options",a.options);
|
||||
}return this;},get:function(){var a=Array.link(arguments,{options:Type.isObject,update:Type.isElement,updateId:Type.isString}),b=a.update||a.updateId;if(a.options||b||!this.retrieve("form.request")){if(a.options||!this.retrieve("form.request:options")){this.set("form.request",a.options);
|
||||
}if(b){this.set("form.request",b);}this.store("form.request",new Form.Request(this,this.retrieve("form.request:update"),this.retrieve("form.request:options")));
|
||||
}return this.retrieve("form.request");}};Element.implement({formUpdate:function(b,a){this.get("formRequest",b,a).send();return this;}});}).call(this);Fx.Elements=new Class({Extends:Fx.CSS,initialize:function(b,a){this.elements=this.subject=$$(b);
|
||||
this.parent(a);},compute:function(g,h,j){var c={};for(var d in g){var a=g[d],e=h[d],f=c[d]={};for(var b in a){f[b]=this.parent(a[b],e[b],j);}}return c;
|
||||
},set:function(b){for(var c in b){if(!this.elements[c]){continue;}var a=b[c];for(var d in a){this.render(this.elements[c],d,a[d],this.options.unit);}}return this;
|
||||
},start:function(c){if(!this.check(c)){return this;}var h={},j={};for(var d in c){if(!this.elements[d]){continue;}var f=c[d],a=h[d]={},g=j[d]={};for(var b in f){var e=this.prepare(this.elements[d],b,f[b]);
|
||||
a[b]=e.from;g[b]=e.to;}}return this.parent(h,j);}});Fx.Accordion=new Class({Extends:Fx.Elements,options:{fixedHeight:false,fixedWidth:false,display:0,show:false,height:true,width:false,opacity:true,alwaysHide:false,trigger:"click",initialDisplayFx:true,resetHeight:true},initialize:function(){var g=function(h){return h!=null;
|
||||
};var f=Array.link(arguments,{container:Type.isElement,options:Type.isObject,togglers:g,elements:g});this.parent(f.elements,f.options);var b=this.options,e=this.togglers=$$(f.togglers);
|
||||
this.previous=-1;this.internalChain=new Chain();if(b.alwaysHide){this.options.link="chain";}if(b.show||this.options.show===0){b.display=false;this.previous=b.show;
|
||||
}if(b.start){b.display=false;b.show=false;}var d=this.effects={};if(b.opacity){d.opacity="fullOpacity";}if(b.width){d.width=b.fixedWidth?"fullWidth":"offsetWidth";
|
||||
}if(b.height){d.height=b.fixedHeight?"fullHeight":"scrollHeight";}for(var c=0,a=e.length;c<a;c++){this.addSection(e[c],this.elements[c]);}this.elements.each(function(j,h){if(b.show===h){this.fireEvent("active",[e[h],j]);
|
||||
}else{for(var k in d){j.setStyle(k,0);}}},this);if(b.display||b.display===0||b.initialDisplayFx===false){this.display(b.display,b.initialDisplayFx);}if(b.fixedHeight!==false){b.resetHeight=false;
|
||||
}this.addEvent("complete",this.internalChain.callChain.bind(this.internalChain));},addSection:function(g,d){g=document.id(g);d=document.id(d);this.togglers.include(g);
|
||||
this.elements.include(d);var f=this.togglers,c=this.options,h=f.contains(g),a=f.indexOf(g),b=this.display.pass(a,this);g.store("accordion:display",b).addEvent(c.trigger,b);
|
||||
if(c.height){d.setStyles({"padding-top":0,"border-top":"none","padding-bottom":0,"border-bottom":"none"});}if(c.width){d.setStyles({"padding-left":0,"border-left":"none","padding-right":0,"border-right":"none"});
|
||||
}d.fullOpacity=1;if(c.fixedWidth){d.fullWidth=c.fixedWidth;}if(c.fixedHeight){d.fullHeight=c.fixedHeight;}d.setStyle("overflow","hidden");if(!h){for(var e in this.effects){d.setStyle(e,0);
|
||||
}}return this;},removeSection:function(f,b){var e=this.togglers,a=e.indexOf(f),c=this.elements[a];var d=function(){e.erase(f);this.elements.erase(c);this.detach(f);
|
||||
}.bind(this);if(this.now==a||b!=null){this.display(b!=null?b:(a-1>=0?a-1:0)).chain(d);}else{d();}return this;},detach:function(b){var a=function(c){c.removeEvent(this.options.trigger,c.retrieve("accordion:display"));
|
||||
}.bind(this);if(!b){this.togglers.each(a);}else{a(b);}return this;},display:function(b,c){if(!this.check(b,c)){return this;}var h={},g=this.elements,a=this.options,f=this.effects;
|
||||
if(c==null){c=true;}if(typeOf(b)=="element"){b=g.indexOf(b);}if(b==this.previous&&!a.alwaysHide){return this;}if(a.resetHeight){var e=g[this.previous];
|
||||
if(e&&!this.selfHidden){for(var d in f){e.setStyle(d,e[f[d]]);}}}if((this.timer&&a.link=="chain")||(b===this.previous&&!a.alwaysHide)){return this;}this.previous=b;
|
||||
this.selfHidden=false;g.each(function(l,k){h[k]={};var j;if(k!=b){j=true;}else{if(a.alwaysHide&&((l.offsetHeight>0&&a.height)||l.offsetWidth>0&&a.width)){j=true;
|
||||
this.selfHidden=true;}}this.fireEvent(j?"background":"active",[this.togglers[k],l]);for(var m in f){h[k][m]=j?0:l[f[m]];}if(!c&&!j&&a.resetHeight){h[k].height="auto";
|
||||
}},this);this.internalChain.clearChain();this.internalChain.chain(function(){if(a.resetHeight&&!this.selfHidden){var i=g[b];if(i){i.setStyle("height","auto");
|
||||
}}}.bind(this));return c?this.start(h):this.set(h);}});var Accordion=new Class({Extends:Fx.Accordion,initialize:function(){this.parent.apply(this,arguments);
|
||||
var a=Array.link(arguments,{container:Type.isElement});this.container=a.container;},addSection:function(c,b,e){c=document.id(c);b=document.id(b);var d=this.togglers.contains(c);
|
||||
var a=this.togglers.length;if(a&&(!d||e)){e=e!=null?e:a-1;c.inject(this.togglers[e],"before");b.inject(c,"after");}else{if(this.container&&!d){c.inject(this.container);
|
||||
b.inject(this.container);}}return this.parent.apply(this,arguments);}});Fx.Slide=new Class({Extends:Fx,options:{mode:"vertical",wrapper:false,hideOverflow:true,resetHeight:false},initialize:function(b,a){b=this.element=this.subject=document.id(b);
|
||||
this.parent(a);a=this.options;var d=b.retrieve("wrapper"),c=b.getStyles("margin","position","overflow");if(a.hideOverflow){c=Object.append(c,{overflow:"hidden"});
|
||||
}if(a.wrapper){d=document.id(a.wrapper).setStyles(c);}if(!d){d=new Element("div",{styles:c}).wraps(b);}b.store("wrapper",d).setStyle("margin",0);if(b.getStyle("overflow")=="visible"){b.setStyle("overflow","hidden");
|
||||
}this.now=[];this.open=true;this.wrapper=d;this.addEvent("complete",function(){this.open=(d["offset"+this.layout.capitalize()]!=0);if(this.open&&a.resetHeight){d.setStyle("height","");
|
||||
}},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(a){this.element.setStyle(this.margin,a[0]);this.wrapper.setStyle(this.layout,a[1]);
|
||||
return this;},compute:function(c,b,a){return[0,1].map(function(d){return Fx.compute(c[d],b[d],a);});},start:function(b,e){if(!this.check(b,e)){return this;
|
||||
}this[e||this.options.mode]();var d=this.element.getStyle(this.margin).toInt(),c=this.wrapper.getStyle(this.layout).toInt(),a=[[d,c],[0,this.offset]],g=[[d,c],[-this.offset,0]],f;
|
||||
switch(b){case"in":f=a;break;case"out":f=g;break;case"toggle":f=(c==0)?a:g;}return this.parent(f[0],f[1]);},slideIn:function(a){return this.start("in",a);
|
||||
},slideOut:function(a){return this.start("out",a);},hide:function(a){this[a||this.options.mode]();this.open=false;return this.set([-this.offset,0]);},show:function(a){this[a||this.options.mode]();
|
||||
this.open=true;return this.set([0,this.offset]);},toggle:function(a){return this.start("toggle",a);}});Element.Properties.slide={set:function(a){this.get("slide").cancel().setOptions(a);
|
||||
return this;},get:function(){var a=this.retrieve("slide");if(!a){a=new Fx.Slide(this,{link:"cancel"});this.store("slide",a);}return a;}};Element.implement({slide:function(d,e){d=d||"toggle";
|
||||
var b=this.get("slide"),a;switch(d){case"hide":b.hide(e);break;case"show":b.show(e);break;case"toggle":var c=this.retrieve("slide:flag",b.open);b[c?"slideOut":"slideIn"](e);
|
||||
this.store("slide:flag",!c);a=true;break;default:b.start(d,e);}if(!a){this.eliminate("slide:flag");}return this;}});var Drag=new Class({Implements:[Events,Options],options:{snap:6,unit:"px",grid:false,style:true,limit:false,handle:false,invert:false,preventDefault:false,stopPropagation:false,modifiers:{x:"left",y:"top"}},initialize:function(){var b=Array.link(arguments,{options:Type.isObject,element:function(c){return c!=null;
|
||||
}});this.element=document.id(b.element);this.document=this.element.getDocument();this.setOptions(b.options||{});var a=typeOf(this.options.handle);this.handles=((a=="array"||a=="collection")?$$(this.options.handle):document.id(this.options.handle))||this.element;
|
||||
this.mouse={now:{},pos:{}};this.value={start:{},now:{}};this.selection=(Browser.ie)?"selectstart":"mousedown";if(Browser.ie&&!Drag.ondragstartFixed){document.ondragstart=Function.from(false);
|
||||
Drag.ondragstartFixed=true;}this.bound={start:this.start.bind(this),check:this.check.bind(this),drag:this.drag.bind(this),stop:this.stop.bind(this),cancel:this.cancel.bind(this),eventStop:Function.from(false)};
|
||||
this.attach();},attach:function(){this.handles.addEvent("mousedown",this.bound.start);return this;},detach:function(){this.handles.removeEvent("mousedown",this.bound.start);
|
||||
return this;},start:function(a){var k=this.options;if(a.rightClick){return;}if(k.preventDefault){a.preventDefault();}if(k.stopPropagation){a.stopPropagation();
|
||||
}this.mouse.start=a.page;this.fireEvent("beforeStart",this.element);var c=k.limit;this.limit={x:[],y:[]};var j=this.element.getStyles("left","right","top","bottom");
|
||||
this._invert={x:k.modifiers.x=="left"&&j.left=="auto"&&!isNaN(j.right.toInt())&&(k.modifiers.x="right"),y:k.modifiers.y=="top"&&j.top=="auto"&&!isNaN(j.bottom.toInt())&&(k.modifiers.y="bottom")};
|
||||
var e,g;for(e in k.modifiers){if(!k.modifiers[e]){continue;}var b=this.element.getStyle(k.modifiers[e]);if(b&&!b.match(/px$/)){if(!g){g=this.element.getCoordinates(this.element.getOffsetParent());
|
||||
}b=g[k.modifiers[e]];}if(k.style){this.value.now[e]=(b||0).toInt();}else{this.value.now[e]=this.element[k.modifiers[e]];}if(k.invert){this.value.now[e]*=-1;
|
||||
}if(this._invert[e]){this.value.now[e]*=-1;}this.mouse.pos[e]=a.page[e]-this.value.now[e];if(c&&c[e]){var d=2;while(d--){var f=c[e][d];if(f||f===0){this.limit[e][d]=(typeof f=="function")?f():f;
|
||||
}}}}if(typeOf(this.options.grid)=="number"){this.options.grid={x:this.options.grid,y:this.options.grid};}var h={mousemove:this.bound.check,mouseup:this.bound.cancel};
|
||||
h[this.selection]=this.bound.eventStop;this.document.addEvents(h);},check:function(a){if(this.options.preventDefault){a.preventDefault();}var b=Math.round(Math.sqrt(Math.pow(a.page.x-this.mouse.start.x,2)+Math.pow(a.page.y-this.mouse.start.y,2)));
|
||||
if(b>this.options.snap){this.cancel();this.document.addEvents({mousemove:this.bound.drag,mouseup:this.bound.stop});this.fireEvent("start",[this.element,a]).fireEvent("snap",this.element);
|
||||
}},drag:function(b){var a=this.options;if(a.preventDefault){b.preventDefault();}this.mouse.now=b.page;for(var c in a.modifiers){if(!a.modifiers[c]){continue;
|
||||
}this.value.now[c]=this.mouse.now[c]-this.mouse.pos[c];if(a.invert){this.value.now[c]*=-1;}if(this._invert[c]){this.value.now[c]*=-1;}if(a.limit&&this.limit[c]){if((this.limit[c][1]||this.limit[c][1]===0)&&(this.value.now[c]>this.limit[c][1])){this.value.now[c]=this.limit[c][1];
|
||||
}else{if((this.limit[c][0]||this.limit[c][0]===0)&&(this.value.now[c]<this.limit[c][0])){this.value.now[c]=this.limit[c][0];}}}if(a.grid[c]){this.value.now[c]-=((this.value.now[c]-(this.limit[c][0]||0))%a.grid[c]);
|
||||
}if(a.style){this.element.setStyle(a.modifiers[c],this.value.now[c]+a.unit);}else{this.element[a.modifiers[c]]=this.value.now[c];}}this.fireEvent("drag",[this.element,b]);
|
||||
},cancel:function(a){this.document.removeEvents({mousemove:this.bound.check,mouseup:this.bound.cancel});if(a){this.document.removeEvent(this.selection,this.bound.eventStop);
|
||||
this.fireEvent("cancel",this.element);}},stop:function(b){var a={mousemove:this.bound.drag,mouseup:this.bound.stop};a[this.selection]=this.bound.eventStop;
|
||||
this.document.removeEvents(a);if(b){this.fireEvent("complete",[this.element,b]);}}});Element.implement({makeResizable:function(a){var b=new Drag(this,Object.merge({modifiers:{x:"width",y:"height"}},a));
|
||||
this.store("resizer",b);return b.addEvent("drag",function(){this.fireEvent("resize",b);}.bind(this));}});Drag.Move=new Class({Extends:Drag,options:{droppables:[],container:false,precalculate:false,includeMargins:true,checkDroppables:true},initialize:function(b,a){this.parent(b,a);
|
||||
b=this.element;this.droppables=$$(this.options.droppables);this.container=document.id(this.options.container);if(this.container&&typeOf(this.container)!="element"){this.container=document.id(this.container.getDocument().body);
|
||||
}if(this.options.style){if(this.options.modifiers.x=="left"&&this.options.modifiers.y=="top"){var e,c=b.getOffsetParent();var d=b.getStyles("left","top");
|
||||
if(c&&(d.left=="auto"||d.top=="auto")){b.setPosition(b.getPosition(c));}}if(b.getStyle("position")=="static"){b.setStyle("position","absolute");}}this.addEvent("start",this.checkDroppables,true);
|
||||
this.overed=null;},start:function(a){if(this.container){this.options.limit=this.calculateLimit();}if(this.options.precalculate){this.positions=this.droppables.map(function(b){return b.getCoordinates();
|
||||
});}this.parent(a);},calculateLimit:function(){var j=this.element,e=this.container,d=document.id(j.getOffsetParent())||document.body,h=e.getCoordinates(d),c={},b={},k={},g={},m={};
|
||||
["top","right","bottom","left"].each(function(q){c[q]=j.getStyle("margin-"+q).toInt();b[q]=j.getStyle("border-"+q).toInt();k[q]=e.getStyle("margin-"+q).toInt();
|
||||
g[q]=e.getStyle("border-"+q).toInt();m[q]=d.getStyle("padding-"+q).toInt();},this);var f=j.offsetWidth+c.left+c.right,p=j.offsetHeight+c.top+c.bottom,i=0,l=0,o=h.right-g.right-f,a=h.bottom-g.bottom-p;
|
||||
if(this.options.includeMargins){i+=c.left;l+=c.top;}else{o+=c.right;a+=c.bottom;}if(j.getStyle("position")=="relative"){var n=j.getCoordinates(d);n.left-=j.getStyle("left").toInt();
|
||||
n.top-=j.getStyle("top").toInt();i-=n.left;l-=n.top;if(e.getStyle("position")!="relative"){i+=g.left;l+=g.top;}o+=c.left-n.left;a+=c.top-n.top;if(e!=d){i+=k.left+m.left;
|
||||
l+=((Browser.ie6||Browser.ie7)?0:k.top)+m.top;}}else{i-=c.left;l-=c.top;if(e!=d){i+=h.left+g.left;l+=h.top+g.top;}}return{x:[i,o],y:[l,a]};},getDroppableCoordinates:function(c){var b=c.getCoordinates();
|
||||
if(c.getStyle("position")=="fixed"){var a=window.getScroll();b.left+=a.x;b.right+=a.x;b.top+=a.y;b.bottom+=a.y;}return b;},checkDroppables:function(){var a=this.droppables.filter(function(d,c){d=this.positions?this.positions[c]:this.getDroppableCoordinates(d);
|
||||
var b=this.mouse.now;return(b.x>d.left&&b.x<d.right&&b.y<d.bottom&&b.y>d.top);},this).getLast();if(this.overed!=a){if(this.overed){this.fireEvent("leave",[this.element,this.overed]);
|
||||
}if(a){this.fireEvent("enter",[this.element,a]);}this.overed=a;}},drag:function(a){this.parent(a);if(this.options.checkDroppables&&this.droppables.length){this.checkDroppables();
|
||||
}},stop:function(a){this.checkDroppables();this.fireEvent("drop",[this.element,this.overed,a]);this.overed=null;return this.parent(a);}});Element.implement({makeDraggable:function(a){var b=new Drag.Move(this,a);
|
||||
this.store("dragger",b);return b;}});(function(){var a="$moo:keys-pressed",b="$moo:keys-keyup";Event.definePseudo("keys",function(d,e,c){var g=c[0],f=[],h=this.retrieve(a,[]);
|
||||
f.append(d.value.replace("++",function(){f.push("+");return"";}).split("+"));h.include(g.key);if(f.every(function(j){return h.contains(j);})){e.apply(this,c);
|
||||
}this.store(a,h);if(!this.retrieve(b)){var i=function(j){(function(){h=this.retrieve(a,[]).erase(j.key);this.store(a,h);}).delay(0,this);};this.store(b,i).addEvent("keyup",i);
|
||||
}});Object.append(Event.Keys,{shift:16,control:17,alt:18,capslock:20,pageup:33,pagedown:34,end:35,home:36,numlock:144,scrolllock:145,";":186,"=":187,",":188,"-":Browser.firefox?109:189,".":190,"/":191,"`":192,"[":219,"\\":220,"]":221,"'":222,"+":107});
|
||||
}).call(this);(function(){var a=this.Keyboard=new Class({Extends:Events,Implements:[Options],options:{defaultEventType:"keydown",active:false,manager:null,events:{},nonParsedEvents:["activate","deactivate","onactivate","ondeactivate","changed","onchanged"]},initialize:function(f){if(f&&f.manager){this._manager=f.manager;
|
||||
delete f.manager;}this.setOptions(f);this._setup();},addEvent:function(h,g,f){return this.parent(a.parse(h,this.options.defaultEventType,this.options.nonParsedEvents),g,f);
|
||||
},removeEvent:function(g,f){return this.parent(a.parse(g,this.options.defaultEventType,this.options.nonParsedEvents),f);},toggleActive:function(){return this[this.isActive()?"deactivate":"activate"]();
|
||||
},activate:function(f){if(f){if(f.isActive()){return this;}if(this._activeKB&&f!=this._activeKB){this.previous=this._activeKB;this.previous.fireEvent("deactivate");
|
||||
}this._activeKB=f.fireEvent("activate");a.manager.fireEvent("changed");}else{if(this._manager){this._manager.activate(this);}}return this;},isActive:function(){return this._manager?(this._manager._activeKB==this):(a.manager==this);
|
||||
},deactivate:function(f){if(f){if(f===this._activeKB){this._activeKB=null;f.fireEvent("deactivate");a.manager.fireEvent("changed");}}else{if(this._manager){this._manager.deactivate(this);
|
||||
}}return this;},relinquish:function(){if(this.isActive()&&this._manager&&this._manager.previous){this._manager.activate(this._manager.previous);}else{this.deactivate();
|
||||
}return this;},manage:function(f){if(f._manager){f._manager.drop(f);}this._instances.push(f);f._manager=this;if(!this._activeKB){this.activate(f);}return this;
|
||||
},drop:function(f){f.relinquish();this._instances.erase(f);if(this._activeKB==f){if(this.previous&&this._instances.contains(this.previous)){this.activate(this.previous);
|
||||
}else{this._activeKB=this._instances[0];}}return this;},trace:function(){a.trace(this);},each:function(f){a.each(this,f);},_instances:[],_disable:function(f){if(this._activeKB==f){this._activeKB=null;
|
||||
}},_setup:function(){this.addEvents(this.options.events);if(a.manager&&!this._manager){a.manager.manage(this);}if(this.options.active){this.activate();
|
||||
}else{this.relinquish();}},_handle:function(h,g){if(h.preventKeyboardPropagation){return;}var f=!!this._manager;if(f&&this._activeKB){this._activeKB._handle(h,g);
|
||||
if(h.preventKeyboardPropagation){return;}}this.fireEvent(g,h);if(!f&&this._activeKB){this._activeKB._handle(h,g);}}});var b={};var c=["shift","control","alt","meta"];
|
||||
var e=/^(?:shift|control|ctrl|alt|meta)$/;a.parse=function(h,g,k){if(k&&k.contains(h.toLowerCase())){return h;}h=h.toLowerCase().replace(/^(keyup|keydown):/,function(m,l){g=l;
|
||||
return"";});if(!b[h]){var f,j={};h.split("+").each(function(l){if(e.test(l)){j[l]=true;}else{f=l;}});j.control=j.control||j.ctrl;var i=[];c.each(function(l){if(j[l]){i.push(l);
|
||||
}});if(f){i.push(f);}b[h]=i.join("+");}return g+":keys("+b[h]+")";};a.each=function(f,g){var h=f||a.manager;while(h){g.run(h);h=h._activeKB;}};a.stop=function(f){f.preventKeyboardPropagation=true;
|
||||
};a.manager=new a({active:true});a.trace=function(f){f=f||a.manager;var g=window.console&&console.log;if(g){console.log("the following items have focus: ");
|
||||
}a.each(f,function(h){if(g){console.log(document.id(h.widget)||h.wiget||h);}});};var d=function(g){var f=[];c.each(function(h){if(g[h]){f.push(h);}});if(!e.test(g.key)){f.push(g.key);
|
||||
}a.manager._handle(g,g.type+":keys("+f.join("+")+")");};document.addEvents({keyup:d,keydown:d});}).call(this);Keyboard.prototype.options.nonParsedEvents.combine(["rebound","onrebound"]);
|
||||
Keyboard.implement({addShortcut:function(b,a){this._shortcuts=this._shortcuts||[];this._shortcutIndex=this._shortcutIndex||{};a.getKeyboard=Function.from(this);
|
||||
a.name=b;this._shortcutIndex[b]=a;this._shortcuts.push(a);if(a.keys){this.addEvent(a.keys,a.handler);}return this;},addShortcuts:function(b){for(var a in b){this.addShortcut(a,b[a]);
|
||||
}return this;},removeShortcut:function(b){var a=this.getShortcut(b);if(a&&a.keys){this.removeEvent(a.keys,a.handler);delete this._shortcutIndex[b];this._shortcuts.erase(a);
|
||||
}return this;},removeShortcuts:function(a){a.each(this.removeShortcut,this);return this;},getShortcuts:function(){return this._shortcuts||[];},getShortcut:function(a){return(this._shortcutIndex||{})[a];
|
||||
}});Keyboard.rebind=function(b,a){Array.from(a).each(function(c){c.getKeyboard().removeEvent(c.keys,c.handler);c.getKeyboard().addEvent(b,c.handler);c.keys=b;
|
||||
c.getKeyboard().fireEvent("rebound");});};Keyboard.getActiveShortcuts=function(b){var a=[],c=[];Keyboard.each(b,[].push.bind(a));a.each(function(d){c.extend(d.getShortcuts());
|
||||
});return c;};Keyboard.getShortcut=function(c,b,d){d=d||{};var a=d.many?[]:null,e=d.many?function(g){var f=g.getShortcut(c);if(f){a.push(f);}}:function(f){if(!a){a=f.getShortcut(c);
|
||||
}};Keyboard.each(b,e);return a;};Keyboard.getShortcuts=function(b,a){return Keyboard.getShortcut(b,a,{many:true});};var HtmlTable=new Class({Implements:[Options,Events,Class.Occlude],options:{properties:{cellpadding:0,cellspacing:0,border:0},rows:[],headers:[],footers:[]},property:"HtmlTable",initialize:function(){var a=Array.link(arguments,{options:Type.isObject,table:Type.isElement,id:Type.isString});
|
||||
this.setOptions(a.options);if(!a.table&&a.id){a.table=document.id(a.id);}this.element=a.table||new Element("table",this.options.properties);if(this.occlude()){return this.occluded;
|
||||
}this.build();},build:function(){this.element.store("HtmlTable",this);this.body=document.id(this.element.tBodies[0])||new Element("tbody").inject(this.element);
|
||||
$$(this.body.rows);if(this.options.headers.length){this.setHeaders(this.options.headers);}else{this.thead=document.id(this.element.tHead);}if(this.thead){this.head=this.getHead();
|
||||
}if(this.options.footers.length){this.setFooters(this.options.footers);}this.tfoot=document.id(this.element.tFoot);if(this.tfoot){this.foot=document.id(this.tfoot.rows[0]);
|
||||
}this.options.rows.each(function(a){this.push(a);},this);},toElement:function(){return this.element;},empty:function(){this.body.empty();return this;},set:function(e,a){var d=(e=="headers")?"tHead":"tFoot",b=d.toLowerCase();
|
||||
this[b]=(document.id(this.element[d])||new Element(b).inject(this.element,"top")).empty();var c=this.push(a,{},this[b],e=="headers"?"th":"td");if(e=="headers"){this.head=this.getHead();
|
||||
}else{this.foot=this.getHead();}return c;},getHead:function(){var a=this.thead.rows;return a.length>1?$$(a):a.length?document.id(a[0]):false;},setHeaders:function(a){this.set("headers",a);
|
||||
return this;},setFooters:function(a){this.set("footers",a);return this;},push:function(f,c,e,a,b){if(typeOf(f)=="element"&&f.get("tag")=="tr"){f.inject(e||this.body,b);
|
||||
return{tr:f,tds:f.getChildren("td")};}var d=f.map(function(i){var j=new Element(a||"td",i?i.properties:{}),h=(i?i.content:"")||i,g=typeOf(h);if(["element","array","collection","elements"].contains(g)){j.adopt(h);
|
||||
}else{j.set("html",h);}return j;});return{tr:new Element("tr",c).inject(e||this.body,b).adopt(d),tds:d};}});["adopt","inject","wraps","grab","replaces","dispose"].each(function(a){HtmlTable.implement(a,function(){this.element[a].apply(this.element,arguments);
|
||||
return this;});});Element.implement({isDisplayed:function(){return this.getStyle("display")!="none";},isVisible:function(){var a=this.offsetWidth,b=this.offsetHeight;
|
||||
return(a==0&&b==0)?false:(a>0&&b>0)?true:this.style.display!="none";},toggle:function(){return this[this.isDisplayed()?"hide":"show"]();},hide:function(){var b;
|
||||
try{b=this.getStyle("display");}catch(a){}if(b=="none"){return this;}return this.store("element:_originalDisplay",b||"").setStyle("display","none");},show:function(a){if(!a&&this.isDisplayed()){return this;
|
||||
}a=a||this.retrieve("element:_originalDisplay")||"block";return this.setStyle("display",(a=="none")?"block":a);},swapClass:function(a,b){return this.removeClass(a).addClass(b);
|
||||
}});Document.implement({clearSelection:function(){if(window.getSelection){var a=window.getSelection();if(a&&a.removeAllRanges){a.removeAllRanges();}}else{if(document.selection&&document.selection.empty){try{document.selection.empty();
|
||||
}catch(b){}}}}});HtmlTable=Class.refactor(HtmlTable,{options:{useKeyboard:true,classRowSelected:"table-tr-selected",classRowHovered:"table-tr-hovered",classSelectable:"table-selectable",shiftForMultiSelect:true,allowMultiSelect:true,selectable:false},initialize:function(){this.previous.apply(this,arguments);
|
||||
if(this.occluded){return this.occluded;}this._selectedRows=new Elements();this._bound={mouseleave:this._mouseleave.bind(this),clickRow:this._clickRow.bind(this)};
|
||||
if(this.options.selectable){this.enableSelect();}},empty:function(){this.selectNone();return this.previous();},enableSelect:function(){this._selectEnabled=true;
|
||||
this._attachSelects();this.element.addClass(this.options.classSelectable);return this;},disableSelect:function(){this._selectEnabled=false;this._attachSelects(false);
|
||||
this.element.removeClass(this.options.classSelectable);return this;},push:function(){var a=this.previous.apply(this,arguments);this._updateSelects();return a;
|
||||
},isSelected:function(a){return this._selectedRows.contains(a);},toggleRow:function(a){return this[(this.isSelected(a)?"de":"")+"selectRow"](a);},selectRow:function(b,a){if(this.isSelected(b)||(!a&&!this.body.getChildren().contains(b))){return;
|
||||
}if(!this.options.allowMultiSelect){this.selectNone();}if(!this.isSelected(b)){this._selectedRows.push(b);b.addClass(this.options.classRowSelected);this.fireEvent("rowFocus",[b,this._selectedRows]);
|
||||
}this._focused=b;document.clearSelection();return this;},deselectRow:function(b,a){if(!this.isSelected(b)||(!a&&!this.body.getChildren().contains(b))){return;
|
||||
}this._selectedRows=new Elements(Array.from(this._selectedRows).erase(b));b.removeClass(this.options.classRowSelected);this.fireEvent("rowUnfocus",[b,this._selectedRows]);
|
||||
return this;},selectAll:function(a){if(!a&&!this.options.allowMultiSelect){return;}this.selectRange(0,this.body.rows.length,a);return this;},selectNone:function(){return this.selectAll(true);
|
||||
},selectRange:function(b,a,f){if(!this.options.allowMultiSelect&&!f){return;}var g=f?"deselectRow":"selectRow",e=Array.clone(this.body.rows);if(typeOf(b)=="element"){b=e.indexOf(b);
|
||||
}if(typeOf(a)=="element"){a=e.indexOf(a);}a=a<e.length-1?a:e.length-1;if(a<b){var d=b;b=a;a=d;}for(var c=b;c<=a;c++){this[g](e[c],true);}return this;},deselectRange:function(b,a){this.selectRange(b,a,true);
|
||||
},getSelected:function(){return this._selectedRows;},_enterRow:function(a){if(this._hovered){this._hovered=this._leaveRow(this._hovered);}this._hovered=a.addClass(this.options.classRowHovered);
|
||||
},_leaveRow:function(a){a.removeClass(this.options.classRowHovered);},_updateSelects:function(){Array.each(this.body.rows,function(a){var b=a.retrieve("binders");
|
||||
if(!b&&!this._selectEnabled){return;}if(!b){b={mouseenter:this._enterRow.pass([a],this),mouseleave:this._leaveRow.pass([a],this)};a.store("binders",b);
|
||||
}if(this._selectEnabled){a.addEvents(b);}else{a.removeEvents(b);}},this);},_shiftFocus:function(b,a){if(!this._focused){return this.selectRow(this.body.rows[0],a);
|
||||
}var c=this._getRowByOffset(b);if(c===null||this._focused==this.body.rows[c]){return this;}this.toggleRow(this.body.rows[c],a);},_clickRow:function(a,b){var c=(a.shift||a.meta||a.control)&&this.options.shiftForMultiSelect;
|
||||
if(!c&&!(a.rightClick&&this.isSelected(b)&&this.options.allowMultiSelect)){this.selectNone();}if(a.rightClick){this.selectRow(b);}else{this.toggleRow(b);
|
||||
}if(a.shift){this.selectRange(this._rangeStart||this.body.rows[0],b,this._rangeStart?!this.isSelected(b):true);this._focused=b;}this._rangeStart=b;},_getRowByOffset:function(c){if(!this._focused){return 0;
|
||||
}var b=Array.clone(this.body.rows),a=b.indexOf(this._focused)+c;if(a<0){a=null;}if(a>=b.length){a=null;}return a;},_attachSelects:function(d){d=d!=null?d:true;
|
||||
var g=d?"addEvents":"removeEvents";this.element[g]({mouseleave:this._bound.mouseleave});this.body[g]({"click:relay(tr)":this._bound.clickRow,"contextmenu:relay(tr)":this._bound.clickRow});
|
||||
if(this.options.useKeyboard||this.keyboard){if(!this.keyboard){var f,e;var c=function(i){var h=function(j){clearTimeout(f);j.preventDefault();var k=this.body.rows[this._getRowByOffset(i)];
|
||||
if(j.shift&&k&&this.isSelected(k)){this.deselectRow(this._focused);this._focused=k;}else{if(k&&(!this.options.allowMultiSelect||!j.shift)){this.selectNone();
|
||||
}this._shiftFocus(i,j);}if(e){f=h.delay(100,this,j);}else{f=(function(){e=true;h(j);}).delay(400);}}.bind(this);return h;}.bind(this);var b=function(){clearTimeout(f);
|
||||
e=false;};this.keyboard=new Keyboard({events:{"keydown:shift+up":c(-1),"keydown:shift+down":c(1),"keyup:shift+up":b,"keyup:shift+down":b,"keyup:up":b,"keyup:down":b},active:true});
|
||||
var a="";if(this.options.allowMultiSelect&&this.options.shiftForMultiSelect&&this.options.useKeyboard){a=" (Shift multi-selects).";}this.keyboard.addShortcuts({"Select Previous Row":{keys:"up",shortcut:"up arrow",handler:c(-1),description:"Select the previous row in the table."+a},"Select Next Row":{keys:"down",shortcut:"down arrow",handler:c(1),description:"Select the next row in the table."+a}});
|
||||
}this.keyboard[d?"activate":"deactivate"]();}this._updateSelects();},_mouseleave:function(){if(this._hovered){this._leaveRow(this._hovered);}}});(function(){var a=function(c,b){return(c)?(typeOf(c)=="function"?c(b):b.get(c)):"";
|
||||
};this.Tips=new Class({Implements:[Events,Options],options:{onShow:function(){this.tip.setStyle("display","block");},onHide:function(){this.tip.setStyle("display","none");
|
||||
},title:"title",text:function(b){return b.get("rel")||b.get("href");},showDelay:100,hideDelay:100,className:"tip-wrap",offset:{x:16,y:16},windowPadding:{x:0,y:0},fixed:false},initialize:function(){var b=Array.link(arguments,{options:Type.isObject,elements:function(c){return c!=null;
|
||||
}});this.setOptions(b.options);if(b.elements){this.attach(b.elements);}this.container=new Element("div",{"class":"tip"});},toElement:function(){if(this.tip){return this.tip;
|
||||
}this.tip=new Element("div",{"class":this.options.className,styles:{position:"absolute",top:0,left:0}}).adopt(new Element("div",{"class":"tip-top"}),this.container,new Element("div",{"class":"tip-bottom"}));
|
||||
return this.tip;},attach:function(b){$$(b).each(function(d){var f=a(this.options.title,d),e=a(this.options.text,d);d.set("title","").store("tip:native",f).retrieve("tip:title",f);
|
||||
d.retrieve("tip:text",e);this.fireEvent("attach",[d]);var c=["enter","leave"];if(!this.options.fixed){c.push("move");}c.each(function(h){var g=d.retrieve("tip:"+h);
|
||||
if(!g){g=function(i){this["element"+h.capitalize()].apply(this,[i,d]);}.bind(this);}d.store("tip:"+h,g).addEvent("mouse"+h,g);},this);},this);return this;
|
||||
},detach:function(b){$$(b).each(function(d){["enter","leave","move"].each(function(e){d.removeEvent("mouse"+e,d.retrieve("tip:"+e)).eliminate("tip:"+e);
|
||||
});this.fireEvent("detach",[d]);if(this.options.title=="title"){var c=d.retrieve("tip:native");if(c){d.set("title",c);}}},this);return this;},elementEnter:function(c,b){clearTimeout(this.timer);
|
||||
this.timer=(function(){this.container.empty();["title","text"].each(function(e){var d=b.retrieve("tip:"+e);var f=this["_"+e+"Element"]=new Element("div",{"class":"tip-"+e}).inject(this.container);
|
||||
if(d){this.fill(f,d);}},this);this.show(b);this.position((this.options.fixed)?{page:b.getPosition()}:c);}).delay(this.options.showDelay,this);},elementLeave:function(c,b){clearTimeout(this.timer);
|
||||
this.timer=this.hide.delay(this.options.hideDelay,this,b);this.fireForParent(c,b);},setTitle:function(b){if(this._titleElement){this._titleElement.empty();
|
||||
this.fill(this._titleElement,b);}return this;},setText:function(b){if(this._textElement){this._textElement.empty();this.fill(this._textElement,b);}return this;
|
||||
},fireForParent:function(c,b){b=b.getParent();if(!b||b==document.body){return;}if(b.retrieve("tip:enter")){b.fireEvent("mouseenter",c);}else{this.fireForParent(c,b);
|
||||
}},elementMove:function(c,b){this.position(c);},position:function(f){if(!this.tip){document.id(this);}var c=window.getSize(),b=window.getScroll(),g={x:this.tip.offsetWidth,y:this.tip.offsetHeight},d={x:"left",y:"top"},e={y:false,x2:false,y2:false,x:false},h={};
|
||||
for(var i in d){h[d[i]]=f.page[i]+this.options.offset[i];if(h[d[i]]<0){e[i]=true;}if((h[d[i]]+g[i]-b[i])>c[i]-this.options.windowPadding[i]){h[d[i]]=f.page[i]-this.options.offset[i]-g[i];
|
||||
e[i+"2"]=true;}}this.fireEvent("bound",e);this.tip.setStyles(h);},fill:function(b,c){if(typeof c=="string"){b.set("html",c);}else{b.adopt(c);}},show:function(b){if(!this.tip){document.id(this);
|
||||
}if(!this.tip.getParent()){this.tip.inject(document.body);}this.fireEvent("show",[this.tip,b]);},hide:function(b){if(!this.tip){document.id(this);}this.fireEvent("hide",[this.tip,b]);
|
||||
}});}).call(this);
|
||||
@@ -1,485 +0,0 @@
|
||||
/*
|
||||
---
|
||||
MooTools: the javascript framework
|
||||
|
||||
web build:
|
||||
- http://mootools.net/core/7c56cfef9dddcf170a5d68e3fb61cfd7
|
||||
|
||||
packager build:
|
||||
- packager build Core/Core Core/Array Core/String Core/Number Core/Function Core/Object Core/Event Core/Browser Core/Class Core/Class.Extras Core/Slick.Parser Core/Slick.Finder Core/Element Core/Element.Style Core/Element.Event Core/Element.Dimensions Core/Fx Core/Fx.CSS Core/Fx.Tween Core/Fx.Morph Core/Fx.Transitions Core/Request Core/Request.HTML Core/Request.JSON Core/Cookie Core/JSON Core/DOMReady Core/Swiff
|
||||
|
||||
copyrights:
|
||||
- [MooTools](http://mootools.net)
|
||||
|
||||
licenses:
|
||||
- [MIT License](http://mootools.net/license.txt)
|
||||
...
|
||||
*/
|
||||
(function(){this.MooTools={version:"1.3.1",build:"af48c8d589f43f32212f9bb8ff68a127e6a3ba6c"};var e=this.typeOf=function(i){if(i==null){return"null";}if(i.$family){return i.$family();
|
||||
}if(i.nodeName){if(i.nodeType==1){return"element";}if(i.nodeType==3){return(/\S/).test(i.nodeValue)?"textnode":"whitespace";}}else{if(typeof i.length=="number"){if(i.callee){return"arguments";
|
||||
}if("item" in i){return"collection";}}}return typeof i;};var u=this.instanceOf=function(w,i){if(w==null){return false;}var v=w.$constructor||w.constructor;
|
||||
while(v){if(v===i){return true;}v=v.parent;}return w instanceof i;};var f=this.Function;var r=true;for(var q in {toString:1}){r=null;}if(r){r=["hasOwnProperty","valueOf","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","constructor"];
|
||||
}f.prototype.overloadSetter=function(v){var i=this;return function(x,w){if(x==null){return this;}if(v||typeof x!="string"){for(var y in x){i.call(this,y,x[y]);
|
||||
}if(r){for(var z=r.length;z--;){y=r[z];if(x.hasOwnProperty(y)){i.call(this,y,x[y]);}}}}else{i.call(this,x,w);}return this;};};f.prototype.overloadGetter=function(v){var i=this;
|
||||
return function(x){var y,w;if(v||typeof x!="string"){y=x;}else{if(arguments.length>1){y=arguments;}}if(y){w={};for(var z=0;z<y.length;z++){w[y[z]]=i.call(this,y[z]);
|
||||
}}else{w=i.call(this,x);}return w;};};f.prototype.extend=function(i,v){this[i]=v;}.overloadSetter();f.prototype.implement=function(i,v){this.prototype[i]=v;
|
||||
}.overloadSetter();var o=Array.prototype.slice;f.from=function(i){return(e(i)=="function")?i:function(){return i;};};Array.from=function(i){if(i==null){return[];
|
||||
}return(k.isEnumerable(i)&&typeof i!="string")?(e(i)=="array")?i:o.call(i):[i];};Number.from=function(v){var i=parseFloat(v);return isFinite(i)?i:null;
|
||||
};String.from=function(i){return i+"";};f.implement({hide:function(){this.$hidden=true;return this;},protect:function(){this.$protected=true;return this;
|
||||
}});var k=this.Type=function(x,w){if(x){var v=x.toLowerCase();var i=function(y){return(e(y)==v);};k["is"+x]=i;if(w!=null){w.prototype.$family=(function(){return v;
|
||||
}).hide();w.type=i;}}if(w==null){return null;}w.extend(this);w.$constructor=k;w.prototype.$constructor=w;return w;};var p=Object.prototype.toString;k.isEnumerable=function(i){return(i!=null&&typeof i.length=="number"&&p.call(i)!="[object Function]");
|
||||
};var b={};var d=function(i){var v=e(i.prototype);return b[v]||(b[v]=[]);};var h=function(w,A){if(A&&A.$hidden){return;}var v=d(this);for(var x=0;x<v.length;
|
||||
x++){var z=v[x];if(e(z)=="type"){h.call(z,w,A);}else{z.call(this,w,A);}}var y=this.prototype[w];if(y==null||!y.$protected){this.prototype[w]=A;}if(this[w]==null&&e(A)=="function"){t.call(this,w,function(i){return A.apply(i,o.call(arguments,1));
|
||||
});}};var t=function(i,w){if(w&&w.$hidden){return;}var v=this[i];if(v==null||!v.$protected){this[i]=w;}};k.implement({implement:h.overloadSetter(),extend:t.overloadSetter(),alias:function(i,v){h.call(this,i,this.prototype[v]);
|
||||
}.overloadSetter(),mirror:function(i){d(this).push(i);return this;}});new k("Type",k);var c=function(v,z,x){var w=(z!=Object),D=z.prototype;if(w){z=new k(v,z);
|
||||
}for(var A=0,y=x.length;A<y;A++){var E=x[A],C=z[E],B=D[E];if(C){C.protect();}if(w&&B){delete D[E];D[E]=B.protect();}}if(w){z.implement(D);}return c;};c("String",String,["charAt","charCodeAt","concat","indexOf","lastIndexOf","match","quote","replace","search","slice","split","substr","substring","toLowerCase","toUpperCase"])("Array",Array,["pop","push","reverse","shift","sort","splice","unshift","concat","join","slice","indexOf","lastIndexOf","filter","forEach","every","map","some","reduce","reduceRight"])("Number",Number,["toExponential","toFixed","toLocaleString","toPrecision"])("Function",f,["apply","call","bind"])("RegExp",RegExp,["exec","test"])("Object",Object,["create","defineProperty","defineProperties","keys","getPrototypeOf","getOwnPropertyDescriptor","getOwnPropertyNames","preventExtensions","isExtensible","seal","isSealed","freeze","isFrozen"])("Date",Date,["now"]);
|
||||
Object.extend=t.overloadSetter();Date.extend("now",function(){return +(new Date);});new k("Boolean",Boolean);Number.prototype.$family=function(){return isFinite(this)?"number":"null";
|
||||
}.hide();Number.extend("random",function(v,i){return Math.floor(Math.random()*(i-v+1)+v);});var l=Object.prototype.hasOwnProperty;Object.extend("forEach",function(i,w,x){for(var v in i){if(l.call(i,v)){w.call(x,i[v],v,i);
|
||||
}}});Object.each=Object.forEach;Array.implement({forEach:function(x,y){for(var w=0,v=this.length;w<v;w++){if(w in this){x.call(y,this[w],w,this);}}},each:function(i,v){Array.forEach(this,i,v);
|
||||
return this;}});var s=function(i){switch(e(i)){case"array":return i.clone();case"object":return Object.clone(i);default:return i;}};Array.implement("clone",function(){var v=this.length,w=new Array(v);
|
||||
while(v--){w[v]=s(this[v]);}return w;});var a=function(v,i,w){switch(e(w)){case"object":if(e(v[i])=="object"){Object.merge(v[i],w);}else{v[i]=Object.clone(w);
|
||||
}break;case"array":v[i]=w.clone();break;default:v[i]=w;}return v;};Object.extend({merge:function(C,y,x){if(e(y)=="string"){return a(C,y,x);}for(var B=1,w=arguments.length;
|
||||
B<w;B++){var z=arguments[B];for(var A in z){a(C,A,z[A]);}}return C;},clone:function(i){var w={};for(var v in i){w[v]=s(i[v]);}return w;},append:function(z){for(var y=1,w=arguments.length;
|
||||
y<w;y++){var v=arguments[y]||{};for(var x in v){z[x]=v[x];}}return z;}});["Object","WhiteSpace","TextNode","Collection","Arguments"].each(function(i){new k(i);
|
||||
});var j=Date.now();String.extend("uniqueID",function(){return(j++).toString(36);});var g=this.Hash=new k("Hash",function(i){if(e(i)=="hash"){i=Object.clone(i.getClean());
|
||||
}for(var v in i){this[v]=i[v];}return this;});g.implement({forEach:function(i,v){Object.forEach(this,i,v);},getClean:function(){var v={};for(var i in this){if(this.hasOwnProperty(i)){v[i]=this[i];
|
||||
}}return v;},getLength:function(){var v=0;for(var i in this){if(this.hasOwnProperty(i)){v++;}}return v;}});g.alias("each","forEach");Object.type=k.isObject;
|
||||
var n=this.Native=function(i){return new k(i.name,i.initialize);};n.type=k.type;n.implement=function(x,v){for(var w=0;w<x.length;w++){x[w].implement(v);
|
||||
}return n;};var m=Array.type;Array.type=function(i){return u(i,Array)||m(i);};this.$A=function(i){return Array.from(i).slice();};this.$arguments=function(v){return function(){return arguments[v];
|
||||
};};this.$chk=function(i){return !!(i||i===0);};this.$clear=function(i){clearTimeout(i);clearInterval(i);return null;};this.$defined=function(i){return(i!=null);
|
||||
};this.$each=function(w,v,x){var i=e(w);((i=="arguments"||i=="collection"||i=="array"||i=="elements")?Array:Object).each(w,v,x);};this.$empty=function(){};
|
||||
this.$extend=function(v,i){return Object.append(v,i);};this.$H=function(i){return new g(i);};this.$merge=function(){var i=Array.slice(arguments);i.unshift({});
|
||||
return Object.merge.apply(null,i);};this.$lambda=f.from;this.$mixin=Object.merge;this.$random=Number.random;this.$splat=Array.from;this.$time=Date.now;
|
||||
this.$type=function(i){var v=e(i);if(v=="elements"){return"array";}return(v=="null")?false:v;};this.$unlink=function(i){switch(e(i)){case"object":return Object.clone(i);
|
||||
case"array":return Array.clone(i);case"hash":return new g(i);default:return i;}};}).call(this);Array.implement({invoke:function(a){var b=Array.slice(arguments,1);
|
||||
return this.map(function(c){return c[a].apply(c,b);});},every:function(c,d){for(var b=0,a=this.length;b<a;b++){if((b in this)&&!c.call(d,this[b],b,this)){return false;
|
||||
}}return true;},filter:function(d,e){var c=[];for(var b=0,a=this.length;b<a;b++){if((b in this)&&d.call(e,this[b],b,this)){c.push(this[b]);}}return c;},clean:function(){return this.filter(function(a){return a!=null;
|
||||
});},indexOf:function(c,d){var a=this.length;for(var b=(d<0)?Math.max(0,a+d):d||0;b<a;b++){if(this[b]===c){return b;}}return -1;},map:function(d,e){var c=[];
|
||||
for(var b=0,a=this.length;b<a;b++){if(b in this){c[b]=d.call(e,this[b],b,this);}}return c;},some:function(c,d){for(var b=0,a=this.length;b<a;b++){if((b in this)&&c.call(d,this[b],b,this)){return true;
|
||||
}}return false;},associate:function(c){var d={},b=Math.min(this.length,c.length);for(var a=0;a<b;a++){d[c[a]]=this[a];}return d;},link:function(c){var a={};
|
||||
for(var e=0,b=this.length;e<b;e++){for(var d in c){if(c[d](this[e])){a[d]=this[e];delete c[d];break;}}}return a;},contains:function(a,b){return this.indexOf(a,b)!=-1;
|
||||
},append:function(a){this.push.apply(this,a);return this;},getLast:function(){return(this.length)?this[this.length-1]:null;},getRandom:function(){return(this.length)?this[Number.random(0,this.length-1)]:null;
|
||||
},include:function(a){if(!this.contains(a)){this.push(a);}return this;},combine:function(c){for(var b=0,a=c.length;b<a;b++){this.include(c[b]);}return this;
|
||||
},erase:function(b){for(var a=this.length;a--;){if(this[a]===b){this.splice(a,1);}}return this;},empty:function(){this.length=0;return this;},flatten:function(){var d=[];
|
||||
for(var b=0,a=this.length;b<a;b++){var c=typeOf(this[b]);if(c=="null"){continue;}d=d.concat((c=="array"||c=="collection"||c=="arguments"||instanceOf(this[b],Array))?Array.flatten(this[b]):this[b]);
|
||||
}return d;},pick:function(){for(var b=0,a=this.length;b<a;b++){if(this[b]!=null){return this[b];}}return null;},hexToRgb:function(b){if(this.length!=3){return null;
|
||||
}var a=this.map(function(c){if(c.length==1){c+=c;}return c.toInt(16);});return(b)?a:"rgb("+a+")";},rgbToHex:function(d){if(this.length<3){return null;}if(this.length==4&&this[3]==0&&!d){return"transparent";
|
||||
}var b=[];for(var a=0;a<3;a++){var c=(this[a]-0).toString(16);b.push((c.length==1)?"0"+c:c);}return(d)?b:"#"+b.join("");}});Array.alias("extend","append");
|
||||
var $pick=function(){return Array.from(arguments).pick();};String.implement({test:function(a,b){return((typeOf(a)=="regexp")?a:new RegExp(""+a,b)).test(this);
|
||||
},contains:function(a,b){return(b)?(b+this+b).indexOf(b+a+b)>-1:this.indexOf(a)>-1;},trim:function(){return this.replace(/^\s+|\s+$/g,"");},clean:function(){return this.replace(/\s+/g," ").trim();
|
||||
},camelCase:function(){return this.replace(/-\D/g,function(a){return a.charAt(1).toUpperCase();});},hyphenate:function(){return this.replace(/[A-Z]/g,function(a){return("-"+a.charAt(0).toLowerCase());
|
||||
});},capitalize:function(){return this.replace(/\b[a-z]/g,function(a){return a.toUpperCase();});},escapeRegExp:function(){return this.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1");
|
||||
},toInt:function(a){return parseInt(this,a||10);},toFloat:function(){return parseFloat(this);},hexToRgb:function(b){var a=this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
|
||||
return(a)?a.slice(1).hexToRgb(b):null;},rgbToHex:function(b){var a=this.match(/\d{1,3}/g);return(a)?a.rgbToHex(b):null;},substitute:function(a,b){return this.replace(b||(/\\?\{([^{}]+)\}/g),function(d,c){if(d.charAt(0)=="\\"){return d.slice(1);
|
||||
}return(a[c]!=null)?a[c]:"";});}});Number.implement({limit:function(b,a){return Math.min(a,Math.max(b,this));},round:function(a){a=Math.pow(10,a||0).toFixed(a<0?-a:0);
|
||||
return Math.round(this*a)/a;},times:function(b,c){for(var a=0;a<this;a++){b.call(c,a,this);}},toFloat:function(){return parseFloat(this);},toInt:function(a){return parseInt(this,a||10);
|
||||
}});Number.alias("each","times");(function(b){var a={};b.each(function(c){if(!Number[c]){a[c]=function(){return Math[c].apply(null,[this].concat(Array.from(arguments)));
|
||||
};}});Number.implement(a);})(["abs","acos","asin","atan","atan2","ceil","cos","exp","floor","log","max","min","pow","sin","sqrt","tan"]);Function.extend({attempt:function(){for(var b=0,a=arguments.length;
|
||||
b<a;b++){try{return arguments[b]();}catch(c){}}return null;}});Function.implement({attempt:function(a,c){try{return this.apply(c,Array.from(a));}catch(b){}return null;
|
||||
},bind:function(c){var a=this,b=(arguments.length>1)?Array.slice(arguments,1):null;return function(){if(!b&&!arguments.length){return a.call(c);}if(b&&arguments.length){return a.apply(c,b.concat(Array.from(arguments)));
|
||||
}return a.apply(c,b||arguments);};},pass:function(b,c){var a=this;if(b!=null){b=Array.from(b);}return function(){return a.apply(c,b||arguments);};},delay:function(b,c,a){return setTimeout(this.pass((a==null?[]:a),c),b);
|
||||
},periodical:function(c,b,a){return setInterval(this.pass((a==null?[]:a),b),c);}});delete Function.prototype.bind;Function.implement({create:function(b){var a=this;
|
||||
b=b||{};return function(d){var c=b.arguments;c=(c!=null)?Array.from(c):Array.slice(arguments,(b.event)?1:0);if(b.event){c=[d||window.event].extend(c);}var e=function(){return a.apply(b.bind||null,c);
|
||||
};if(b.delay){return setTimeout(e,b.delay);}if(b.periodical){return setInterval(e,b.periodical);}if(b.attempt){return Function.attempt(e);}return e();};
|
||||
},bind:function(c,b){var a=this;if(b!=null){b=Array.from(b);}return function(){return a.apply(c,b||arguments);};},bindWithEvent:function(c,b){var a=this;
|
||||
if(b!=null){b=Array.from(b);}return function(d){return a.apply(c,(b==null)?arguments:[d].concat(b));};},run:function(a,b){return this.apply(b,Array.from(a));
|
||||
}});var $try=Function.attempt;(function(){var a=Object.prototype.hasOwnProperty;Object.extend({subset:function(d,g){var f={};for(var e=0,b=g.length;e<b;
|
||||
e++){var c=g[e];f[c]=d[c];}return f;},map:function(b,e,f){var d={};for(var c in b){if(a.call(b,c)){d[c]=e.call(f,b[c],c,b);}}return d;},filter:function(b,d,e){var c={};
|
||||
Object.each(b,function(g,f){if(d.call(e,g,f,b)){c[f]=g;}});return c;},every:function(b,d,e){for(var c in b){if(a.call(b,c)&&!d.call(e,b[c],c)){return false;
|
||||
}}return true;},some:function(b,d,e){for(var c in b){if(a.call(b,c)&&d.call(e,b[c],c)){return true;}}return false;},keys:function(b){var d=[];for(var c in b){if(a.call(b,c)){d.push(c);
|
||||
}}return d;},values:function(c){var b=[];for(var d in c){if(a.call(c,d)){b.push(c[d]);}}return b;},getLength:function(b){return Object.keys(b).length;},keyOf:function(b,d){for(var c in b){if(a.call(b,c)&&b[c]===d){return c;
|
||||
}}return null;},contains:function(b,c){return Object.keyOf(b,c)!=null;},toQueryString:function(b,c){var d=[];Object.each(b,function(h,g){if(c){g=c+"["+g+"]";
|
||||
}var f;switch(typeOf(h)){case"object":f=Object.toQueryString(h,g);break;case"array":var e={};h.each(function(k,j){e[j]=k;});f=Object.toQueryString(e,g);
|
||||
break;default:f=g+"="+encodeURIComponent(h);}if(h!=null){d.push(f);}});return d.join("&");}});})();Hash.implement({has:Object.prototype.hasOwnProperty,keyOf:function(a){return Object.keyOf(this,a);
|
||||
},hasValue:function(a){return Object.contains(this,a);},extend:function(a){Hash.each(a||{},function(c,b){Hash.set(this,b,c);},this);return this;},combine:function(a){Hash.each(a||{},function(c,b){Hash.include(this,b,c);
|
||||
},this);return this;},erase:function(a){if(this.hasOwnProperty(a)){delete this[a];}return this;},get:function(a){return(this.hasOwnProperty(a))?this[a]:null;
|
||||
},set:function(a,b){if(!this[a]||this.hasOwnProperty(a)){this[a]=b;}return this;},empty:function(){Hash.each(this,function(b,a){delete this[a];},this);
|
||||
return this;},include:function(a,b){if(this[a]==null){this[a]=b;}return this;},map:function(a,b){return new Hash(Object.map(this,a,b));},filter:function(a,b){return new Hash(Object.filter(this,a,b));
|
||||
},every:function(a,b){return Object.every(this,a,b);},some:function(a,b){return Object.some(this,a,b);},getKeys:function(){return Object.keys(this);},getValues:function(){return Object.values(this);
|
||||
},toQueryString:function(a){return Object.toQueryString(this,a);}});Hash.extend=Object.append;Hash.alias({indexOf:"keyOf",contains:"hasValue"});(function(){var l=this.document;
|
||||
var j=l.window=this;var b=1;this.$uid=(j.ActiveXObject)?function(e){return(e.uid||(e.uid=[b++]))[0];}:function(e){return e.uid||(e.uid=b++);};$uid(j);$uid(l);
|
||||
var a=navigator.userAgent.toLowerCase(),c=navigator.platform.toLowerCase(),k=a.match(/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/)||[null,"unknown",0],g=k[1]=="ie"&&l.documentMode;
|
||||
var p=this.Browser={extend:Function.prototype.extend,name:(k[1]=="version")?k[3]:k[1],version:g||parseFloat((k[1]=="opera"&&k[4])?k[4]:k[2]),Platform:{name:a.match(/ip(?:ad|od|hone)/)?"ios":(a.match(/(?:webos|android)/)||c.match(/mac|win|linux/)||["other"])[0]},Features:{xpath:!!(l.evaluate),air:!!(j.runtime),query:!!(l.querySelector),json:!!(j.JSON)},Plugins:{}};
|
||||
p[p.name]=true;p[p.name+parseInt(p.version,10)]=true;p.Platform[p.Platform.name]=true;p.Request=(function(){var r=function(){return new XMLHttpRequest();
|
||||
};var q=function(){return new ActiveXObject("MSXML2.XMLHTTP");};var e=function(){return new ActiveXObject("Microsoft.XMLHTTP");};return Function.attempt(function(){r();
|
||||
return r;},function(){q();return q;},function(){e();return e;});})();p.Features.xhr=!!(p.Request);var i=(Function.attempt(function(){return navigator.plugins["Shockwave Flash"].description;
|
||||
},function(){return new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version");})||"0 r0").match(/\d+/g);p.Plugins.Flash={version:Number(i[0]||"0."+i[1])||0,build:Number(i[2])||0};
|
||||
p.exec=function(q){if(!q){return q;}if(j.execScript){j.execScript(q);}else{var e=l.createElement("script");e.setAttribute("type","text/javascript");e.text=q;
|
||||
l.head.appendChild(e);l.head.removeChild(e);}return q;};String.implement("stripScripts",function(q){var e="";var r=this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi,function(s,t){e+=t+"\n";
|
||||
return"";});if(q===true){p.exec(e);}else{if(typeOf(q)=="function"){q(e,r);}}return r;});p.extend({Document:this.Document,Window:this.Window,Element:this.Element,Event:this.Event});
|
||||
this.Window=this.$constructor=new Type("Window",function(){});this.$family=Function.from("window").hide();Window.mirror(function(e,q){j[e]=q;});this.Document=l.$constructor=new Type("Document",function(){});
|
||||
l.$family=Function.from("document").hide();Document.mirror(function(e,q){l[e]=q;});l.html=l.documentElement;l.head=l.getElementsByTagName("head")[0];if(l.execCommand){try{l.execCommand("BackgroundImageCache",false,true);
|
||||
}catch(h){}}if(this.attachEvent&&!this.addEventListener){var d=function(){this.detachEvent("onunload",d);l.head=l.html=l.window=null;};this.attachEvent("onunload",d);
|
||||
}var n=Array.from;try{n(l.html.childNodes);}catch(h){Array.from=function(q){if(typeof q!="string"&&Type.isEnumerable(q)&&typeOf(q)!="array"){var e=q.length,r=new Array(e);
|
||||
while(e--){r[e]=q[e];}return r;}return n(q);};var m=Array.prototype,o=m.slice;["pop","push","reverse","shift","sort","splice","unshift","concat","join","slice"].each(function(e){var q=m[e];
|
||||
Array[e]=function(r){return q.apply(Array.from(r),o.call(arguments,1));};});}if(p.Platform.ios){p.Platform.ipod=true;}p.Engine={};var f=function(q,e){p.Engine.name=q;
|
||||
p.Engine[q+e]=true;p.Engine.version=e;};if(p.ie){p.Engine.trident=true;switch(p.version){case 6:f("trident",4);break;case 7:f("trident",5);break;case 8:f("trident",6);
|
||||
}}if(p.firefox){p.Engine.gecko=true;if(p.version>=3){f("gecko",19);}else{f("gecko",18);}}if(p.safari||p.chrome){p.Engine.webkit=true;switch(p.version){case 2:f("webkit",419);
|
||||
break;case 3:f("webkit",420);break;case 4:f("webkit",525);}}if(p.opera){p.Engine.presto=true;if(p.version>=9.6){f("presto",960);}else{if(p.version>=9.5){f("presto",950);
|
||||
}else{f("presto",925);}}}if(p.name=="unknown"){switch((a.match(/(?:webkit|khtml|gecko)/)||[])[0]){case"webkit":case"khtml":p.Engine.webkit=true;break;case"gecko":p.Engine.gecko=true;
|
||||
}}this.$exec=p.exec;}).call(this);var Event=new Type("Event",function(a,i){if(!i){i=window;}var o=i.document;a=a||i.event;if(a.$extended){return a;}this.$extended=true;
|
||||
var n=a.type,k=a.target||a.srcElement,m={},c={},q=null,h,l,b,p;while(k&&k.nodeType==3){k=k.parentNode;}if(n.indexOf("key")!=-1){b=a.which||a.keyCode;p=Object.keyOf(Event.Keys,b);
|
||||
if(n=="keydown"){var d=b-111;if(d>0&&d<13){p="f"+d;}}if(!p){p=String.fromCharCode(b).toLowerCase();}}else{if((/click|mouse|menu/i).test(n)){o=(!o.compatMode||o.compatMode=="CSS1Compat")?o.html:o.body;
|
||||
m={x:(a.pageX!=null)?a.pageX:a.clientX+o.scrollLeft,y:(a.pageY!=null)?a.pageY:a.clientY+o.scrollTop};c={x:(a.pageX!=null)?a.pageX-i.pageXOffset:a.clientX,y:(a.pageY!=null)?a.pageY-i.pageYOffset:a.clientY};
|
||||
if((/DOMMouseScroll|mousewheel/).test(n)){l=(a.wheelDelta)?a.wheelDelta/120:-(a.detail||0)/3;}h=(a.which==3)||(a.button==2);if((/over|out/).test(n)){q=a.relatedTarget||a[(n=="mouseover"?"from":"to")+"Element"];
|
||||
var j=function(){while(q&&q.nodeType==3){q=q.parentNode;}return true;};var g=(Browser.firefox2)?j.attempt():j();q=(g)?q:null;}}else{if((/gesture|touch/i).test(n)){this.rotation=a.rotation;
|
||||
this.scale=a.scale;this.targetTouches=a.targetTouches;this.changedTouches=a.changedTouches;var f=this.touches=a.touches;if(f&&f[0]){var e=f[0];m={x:e.pageX,y:e.pageY};
|
||||
c={x:e.clientX,y:e.clientY};}}}}return Object.append(this,{event:a,type:n,page:m,client:c,rightClick:h,wheel:l,relatedTarget:document.id(q),target:document.id(k),code:b,key:p,shift:a.shiftKey,control:a.ctrlKey,alt:a.altKey,meta:a.metaKey});
|
||||
});Event.Keys={enter:13,up:38,down:40,left:37,right:39,esc:27,space:32,backspace:8,tab:9,"delete":46};Event.Keys=new Hash(Event.Keys);Event.implement({stop:function(){return this.stopPropagation().preventDefault();
|
||||
},stopPropagation:function(){if(this.event.stopPropagation){this.event.stopPropagation();}else{this.event.cancelBubble=true;}return this;},preventDefault:function(){if(this.event.preventDefault){this.event.preventDefault();
|
||||
}else{this.event.returnValue=false;}return this;}});(function(){var a=this.Class=new Type("Class",function(h){if(instanceOf(h,Function)){h={initialize:h};
|
||||
}var g=function(){e(this);if(g.$prototyping){return this;}this.$caller=null;var i=(this.initialize)?this.initialize.apply(this,arguments):this;this.$caller=this.caller=null;
|
||||
return i;}.extend(this).implement(h);g.$constructor=a;g.prototype.$constructor=g;g.prototype.parent=c;return g;});var c=function(){if(!this.$caller){throw new Error('The method "parent" cannot be called.');
|
||||
}var g=this.$caller.$name,h=this.$caller.$owner.parent,i=(h)?h.prototype[g]:null;if(!i){throw new Error('The method "'+g+'" has no parent.');}return i.apply(this,arguments);
|
||||
};var e=function(g){for(var h in g){var j=g[h];switch(typeOf(j)){case"object":var i=function(){};i.prototype=j;g[h]=e(new i);break;case"array":g[h]=j.clone();
|
||||
break;}}return g;};var b=function(g,h,j){if(j.$origin){j=j.$origin;}var i=function(){if(j.$protected&&this.$caller==null){throw new Error('The method "'+h+'" cannot be called.');
|
||||
}var l=this.caller,m=this.$caller;this.caller=m;this.$caller=i;var k=j.apply(this,arguments);this.$caller=m;this.caller=l;return k;}.extend({$owner:g,$origin:j,$name:h});
|
||||
return i;};var f=function(h,i,g){if(a.Mutators.hasOwnProperty(h)){i=a.Mutators[h].call(this,i);if(i==null){return this;}}if(typeOf(i)=="function"){if(i.$hidden){return this;
|
||||
}this.prototype[h]=(g)?i:b(this,h,i);}else{Object.merge(this.prototype,h,i);}return this;};var d=function(g){g.$prototyping=true;var h=new g;delete g.$prototyping;
|
||||
return h;};a.implement("implement",f.overloadSetter());a.Mutators={Extends:function(g){this.parent=g;this.prototype=d(g);},Implements:function(g){Array.from(g).each(function(j){var h=new j;
|
||||
for(var i in h){f.call(this,i,h[i],true);}},this);}};}).call(this);(function(){this.Chain=new Class({$chain:[],chain:function(){this.$chain.append(Array.flatten(arguments));
|
||||
return this;},callChain:function(){return(this.$chain.length)?this.$chain.shift().apply(this,arguments):false;},clearChain:function(){this.$chain.empty();
|
||||
return this;}});var a=function(b){return b.replace(/^on([A-Z])/,function(c,d){return d.toLowerCase();});};this.Events=new Class({$events:{},addEvent:function(d,c,b){d=a(d);
|
||||
if(c==$empty){return this;}this.$events[d]=(this.$events[d]||[]).include(c);if(b){c.internal=true;}return this;},addEvents:function(b){for(var c in b){this.addEvent(c,b[c]);
|
||||
}return this;},fireEvent:function(e,c,b){e=a(e);var d=this.$events[e];if(!d){return this;}c=Array.from(c);d.each(function(f){if(b){f.delay(b,this,c);}else{f.apply(this,c);
|
||||
}},this);return this;},removeEvent:function(e,d){e=a(e);var c=this.$events[e];if(c&&!d.internal){var b=c.indexOf(d);if(b!=-1){delete c[b];}}return this;
|
||||
},removeEvents:function(d){var e;if(typeOf(d)=="object"){for(e in d){this.removeEvent(e,d[e]);}return this;}if(d){d=a(d);}for(e in this.$events){if(d&&d!=e){continue;
|
||||
}var c=this.$events[e];for(var b=c.length;b--;){if(b in c){this.removeEvent(e,c[b]);}}}return this;}});this.Options=new Class({setOptions:function(){var b=this.options=Object.merge.apply(null,[{},this.options].append(arguments));
|
||||
if(this.addEvent){for(var c in b){if(typeOf(b[c])!="function"||!(/^on[A-Z]/).test(c)){continue;}this.addEvent(c,b[c]);delete b[c];}}return this;}});}).call(this);
|
||||
(function(){var k,n,l,g,a={},c={},m=/\\/g;var e=function(q,p){if(q==null){return null;}if(q.Slick===true){return q;}q=(""+q).replace(/^\s+|\s+$/g,"");g=!!p;
|
||||
var o=(g)?c:a;if(o[q]){return o[q];}k={Slick:true,expressions:[],raw:q,reverse:function(){return e(this.raw,true);}};n=-1;while(q!=(q=q.replace(j,b))){}k.length=k.expressions.length;
|
||||
return o[k.raw]=(g)?h(k):k;};var i=function(o){if(o==="!"){return" ";}else{if(o===" "){return"!";}else{if((/^!/).test(o)){return o.replace(/^!/,"");}else{return"!"+o;
|
||||
}}}};var h=function(u){var r=u.expressions;for(var p=0;p<r.length;p++){var t=r[p];var q={parts:[],tag:"*",combinator:i(t[0].combinator)};for(var o=0;o<t.length;
|
||||
o++){var s=t[o];if(!s.reverseCombinator){s.reverseCombinator=" ";}s.combinator=s.reverseCombinator;delete s.reverseCombinator;}t.reverse().push(q);}return u;
|
||||
};var f=function(o){return o.replace(/[-[\]{}()*+?.\\^$|,#\s]/g,function(p){return"\\"+p;});};var j=new RegExp("^(?:\\s*(,)\\s*|\\s*(<combinator>+)\\s*|(\\s+)|(<unicode>+|\\*)|\\#(<unicode>+)|\\.(<unicode>+)|\\[\\s*(<unicode1>+)(?:\\s*([*^$!~|]?=)(?:\\s*(?:([\"']?)(.*?)\\9)))?\\s*\\](?!\\])|(:+)(<unicode>+)(?:\\((?:(?:([\"'])([^\\13]*)\\13)|((?:\\([^)]+\\)|[^()]*)+))\\))?)".replace(/<combinator>/,"["+f(">+~`!@$%^&={}\\;</")+"]").replace(/<unicode>/g,"(?:[\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])").replace(/<unicode1>/g,"(?:[:\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])"));
|
||||
function b(x,s,D,z,r,C,q,B,A,y,u,F,G,v,p,w){if(s||n===-1){k.expressions[++n]=[];l=-1;if(s){return"";}}if(D||z||l===-1){D=D||" ";var t=k.expressions[n];
|
||||
if(g&&t[l]){t[l].reverseCombinator=i(D);}t[++l]={combinator:D,tag:"*"};}var o=k.expressions[n][l];if(r){o.tag=r.replace(m,"");}else{if(C){o.id=C.replace(m,"");
|
||||
}else{if(q){q=q.replace(m,"");if(!o.classList){o.classList=[];}if(!o.classes){o.classes=[];}o.classList.push(q);o.classes.push({value:q,regexp:new RegExp("(^|\\s)"+f(q)+"(\\s|$)")});
|
||||
}else{if(G){w=w||p;w=w?w.replace(m,""):null;if(!o.pseudos){o.pseudos=[];}o.pseudos.push({key:G.replace(m,""),value:w,type:F.length==1?"class":"element"});
|
||||
}else{if(B){B=B.replace(m,"");u=(u||"").replace(m,"");var E,H;switch(A){case"^=":H=new RegExp("^"+f(u));break;case"$=":H=new RegExp(f(u)+"$");break;case"~=":H=new RegExp("(^|\\s)"+f(u)+"(\\s|$)");
|
||||
break;case"|=":H=new RegExp("^"+f(u)+"(-|$)");break;case"=":E=function(I){return u==I;};break;case"*=":E=function(I){return I&&I.indexOf(u)>-1;};break;
|
||||
case"!=":E=function(I){return u!=I;};break;default:E=function(I){return !!I;};}if(u==""&&(/^[*$^]=$/).test(A)){E=function(){return false;};}if(!E){E=function(I){return I&&H.test(I);
|
||||
};}if(!o.attributes){o.attributes=[];}o.attributes.push({key:B,operator:A,value:u,test:E});}}}}}return"";}var d=(this.Slick||{});d.parse=function(o){return e(o);
|
||||
};d.escapeRegExp=f;if(!this.Slick){this.Slick=d;}}).apply((typeof exports!="undefined")?exports:this);(function(){var j={},l={},b=Object.prototype.toString;
|
||||
j.isNativeCode=function(c){return(/\{\s*\[native code\]\s*\}/).test(""+c);};j.isXML=function(c){return(!!c.xmlVersion)||(!!c.xml)||(b.call(c)=="[object XMLDocument]")||(c.nodeType==9&&c.documentElement.nodeName!="HTML");
|
||||
};j.setDocument=function(w){var t=w.nodeType;if(t==9){}else{if(t){w=w.ownerDocument;}else{if(w.navigator){w=w.document;}else{return;}}}if(this.document===w){return;
|
||||
}this.document=w;var y=w.documentElement,u=this.getUIDXML(y),o=l[u],A;if(o){for(A in o){this[A]=o[A];}return;}o=l[u]={};o.root=y;o.isXMLDocument=this.isXML(w);
|
||||
o.brokenStarGEBTN=o.starSelectsClosedQSA=o.idGetsName=o.brokenMixedCaseQSA=o.brokenGEBCN=o.brokenCheckedQSA=o.brokenEmptyAttributeQSA=o.isHTMLDocument=o.nativeMatchesSelector=false;
|
||||
var m,n,x,q,r;var s,c="slick_uniqueid";var z=w.createElement("div");var p=w.body||w.getElementsByTagName("body")[0]||y;p.appendChild(z);try{z.innerHTML='<a id="'+c+'"></a>';
|
||||
o.isHTMLDocument=!!w.getElementById(c);}catch(v){}if(o.isHTMLDocument){z.style.display="none";z.appendChild(w.createComment(""));n=(z.getElementsByTagName("*").length>1);
|
||||
try{z.innerHTML="foo</foo>";s=z.getElementsByTagName("*");m=(s&&!!s.length&&s[0].nodeName.charAt(0)=="/");}catch(v){}o.brokenStarGEBTN=n||m;try{z.innerHTML='<a name="'+c+'"></a><b id="'+c+'"></b>';
|
||||
o.idGetsName=w.getElementById(c)===z.firstChild;}catch(v){}if(z.getElementsByClassName){try{z.innerHTML='<a class="f"></a><a class="b"></a>';z.getElementsByClassName("b").length;
|
||||
z.firstChild.className="b";q=(z.getElementsByClassName("b").length!=2);}catch(v){}try{z.innerHTML='<a class="a"></a><a class="f b a"></a>';x=(z.getElementsByClassName("a").length!=2);
|
||||
}catch(v){}o.brokenGEBCN=q||x;}if(z.querySelectorAll){try{z.innerHTML="foo</foo>";s=z.querySelectorAll("*");o.starSelectsClosedQSA=(s&&!!s.length&&s[0].nodeName.charAt(0)=="/");
|
||||
}catch(v){}try{z.innerHTML='<a class="MiX"></a>';o.brokenMixedCaseQSA=!z.querySelectorAll(".MiX").length;}catch(v){}try{z.innerHTML='<select><option selected="selected">a</option></select>';
|
||||
o.brokenCheckedQSA=(z.querySelectorAll(":checked").length==0);}catch(v){}try{z.innerHTML='<a class=""></a>';o.brokenEmptyAttributeQSA=(z.querySelectorAll('[class*=""]').length!=0);
|
||||
}catch(v){}}try{z.innerHTML='<form action="s"><input id="action"/></form>';r=(z.firstChild.getAttribute("action")!="s");}catch(v){}o.nativeMatchesSelector=y.matchesSelector||y.mozMatchesSelector||y.webkitMatchesSelector;
|
||||
if(o.nativeMatchesSelector){try{o.nativeMatchesSelector.call(y,":slick");o.nativeMatchesSelector=null;}catch(v){}}}try{y.slick_expando=1;delete y.slick_expando;
|
||||
o.getUID=this.getUIDHTML;}catch(v){o.getUID=this.getUIDXML;}p.removeChild(z);z=s=p=null;o.getAttribute=(o.isHTMLDocument&&r)?function(D,B){var E=this.attributeGetters[B];
|
||||
if(E){return E.call(D);}var C=D.getAttributeNode(B);return(C)?C.nodeValue:null;}:function(C,B){var D=this.attributeGetters[B];return(D)?D.call(C):C.getAttribute(B);
|
||||
};o.hasAttribute=(y&&this.isNativeCode(y.hasAttribute))?function(C,B){return C.hasAttribute(B);}:function(C,B){C=C.getAttributeNode(B);return !!(C&&(C.specified||C.nodeValue));
|
||||
};o.contains=(y&&this.isNativeCode(y.contains))?function(B,C){return B.contains(C);}:(y&&y.compareDocumentPosition)?function(B,C){return B===C||!!(B.compareDocumentPosition(C)&16);
|
||||
}:function(B,C){if(C){do{if(C===B){return true;}}while((C=C.parentNode));}return false;};o.documentSorter=(y.compareDocumentPosition)?function(C,B){if(!C.compareDocumentPosition||!B.compareDocumentPosition){return 0;
|
||||
}return C.compareDocumentPosition(B)&4?-1:C===B?0:1;}:("sourceIndex" in y)?function(C,B){if(!C.sourceIndex||!B.sourceIndex){return 0;}return C.sourceIndex-B.sourceIndex;
|
||||
}:(w.createRange)?function(E,C){if(!E.ownerDocument||!C.ownerDocument){return 0;}var D=E.ownerDocument.createRange(),B=C.ownerDocument.createRange();D.setStart(E,0);
|
||||
D.setEnd(E,0);B.setStart(C,0);B.setEnd(C,0);return D.compareBoundaryPoints(Range.START_TO_END,B);}:null;y=null;for(A in o){this[A]=o[A];}};var e=/^([#.]?)((?:[\w-]+|\*))$/,g=/\[.+[*$^]=(?:""|'')?\]/,f={};
|
||||
j.search=function(q,D,O,v){var B=this.found=(v)?null:(O||[]);if(!q){return B;}else{if(q.navigator){q=q.document;}else{if(!q.nodeType){return B;}}}var z,N,s=this.uniques={},y=!!(O&&O.length),c=(q.nodeType==9);
|
||||
if(this.document!==(c?q:q.ownerDocument)){this.setDocument(q);}if(y){for(N=B.length;N--;){s[this.getUID(B[N])]=true;}}if(typeof D=="string"){var C=D.match(e);
|
||||
simpleSelectors:if(C){var K=C[1],V=C[2],I,G;if(!K){if(V=="*"&&this.brokenStarGEBTN){break simpleSelectors;}G=q.getElementsByTagName(V);if(v){return G[0]||null;
|
||||
}for(N=0;I=G[N++];){if(!(y&&s[this.getUID(I)])){B.push(I);}}}else{if(K=="#"){if(!this.isHTMLDocument||!c){break simpleSelectors;}I=q.getElementById(V);
|
||||
if(!I){return B;}if(this.idGetsName&&I.getAttributeNode("id").nodeValue!=V){break simpleSelectors;}if(v){return I||null;}if(!(y&&s[this.getUID(I)])){B.push(I);
|
||||
}}else{if(K=="."){if(!this.isHTMLDocument||((!q.getElementsByClassName||this.brokenGEBCN)&&q.querySelectorAll)){break simpleSelectors;}if(q.getElementsByClassName&&!this.brokenGEBCN){G=q.getElementsByClassName(V);
|
||||
if(v){return G[0]||null;}for(N=0;I=G[N++];){if(!(y&&s[this.getUID(I)])){B.push(I);}}}else{var u=new RegExp("(^|\\s)"+d.escapeRegExp(V)+"(\\s|$)");G=q.getElementsByTagName("*");
|
||||
for(N=0;I=G[N++];){className=I.className;if(!(className&&u.test(className))){continue;}if(v){return I;}if(!(y&&s[this.getUID(I)])){B.push(I);}}}}}}if(y){this.sort(B);
|
||||
}return(v)?null:B;}querySelector:if(q.querySelectorAll){if(!this.isHTMLDocument||this.brokenMixedCaseQSA||f[D]||(this.brokenCheckedQSA&&D.indexOf(":checked")>-1)||(this.brokenEmptyAttributeQSA&&g.test(D))||d.disableQSA){break querySelector;
|
||||
}var A=D;if(!c){var M=q.getAttribute("id"),p="slickid__";q.setAttribute("id",p);A="#"+p+" "+A;}try{if(v){return q.querySelector(A)||null;}else{G=q.querySelectorAll(A);
|
||||
}}catch(P){f[D]=1;break querySelector;}finally{if(!c){if(M){q.setAttribute("id",M);}else{q.removeAttribute("id");}}}if(this.starSelectsClosedQSA){for(N=0;
|
||||
I=G[N++];){if(I.nodeName>"@"&&!(y&&s[this.getUID(I)])){B.push(I);}}}else{for(N=0;I=G[N++];){if(!(y&&s[this.getUID(I)])){B.push(I);}}}if(y){this.sort(B);
|
||||
}return B;}z=this.Slick.parse(D);if(!z.length){return B;}}else{if(D==null){return B;}else{if(D.Slick){z=D;}else{if(this.contains(q.documentElement||q,D)){(B)?B.push(D):B=D;
|
||||
return B;}else{return B;}}}}this.posNTH={};this.posNTHLast={};this.posNTHType={};this.posNTHTypeLast={};this.push=(!y&&(v||(z.length==1&&z.expressions[0].length==1)))?this.pushArray:this.pushUID;
|
||||
if(B==null){B=[];}var L,H,F;var J,U,E,T,Q,x,t;var w,r,o,R,S=z.expressions;search:for(N=0;(r=S[N]);N++){for(L=0;(o=r[L]);L++){J="combinator:"+o.combinator;
|
||||
if(!this[J]){continue search;}U=(this.isXMLDocument)?o.tag:o.tag.toUpperCase();E=o.id;T=o.classList;Q=o.classes;x=o.attributes;t=o.pseudos;R=(L===(r.length-1));
|
||||
this.bitUniques={};if(R){this.uniques=s;this.found=B;}else{this.uniques={};this.found=[];}if(L===0){this[J](q,U,E,Q,x,t,T);if(v&&R&&B.length){break search;
|
||||
}}else{if(v&&R){for(H=0,F=w.length;H<F;H++){this[J](w[H],U,E,Q,x,t,T);if(B.length){break search;}}}else{for(H=0,F=w.length;H<F;H++){this[J](w[H],U,E,Q,x,t,T);
|
||||
}}}w=this.found;}}if(y||(z.expressions.length>1)){this.sort(B);}return(v)?(B[0]||null):B;};j.uidx=1;j.uidk="slick-uniqueid";j.getUIDXML=function(m){var c=m.getAttribute(this.uidk);
|
||||
if(!c){c=this.uidx++;m.setAttribute(this.uidk,c);}return c;};j.getUIDHTML=function(c){return c.uniqueNumber||(c.uniqueNumber=this.uidx++);};j.sort=function(c){if(!this.documentSorter){return c;
|
||||
}c.sort(this.documentSorter);return c;};j.cacheNTH={};j.matchNTH=/^([+-]?\d*)?([a-z]+)?([+-]\d+)?$/;j.parseNTHArgument=function(p){var n=p.match(this.matchNTH);
|
||||
if(!n){return false;}var o=n[2]||false;var m=n[1]||1;if(m=="-"){m=-1;}var c=+n[3]||0;n=(o=="n")?{a:m,b:c}:(o=="odd")?{a:2,b:1}:(o=="even")?{a:2,b:0}:{a:0,b:m};
|
||||
return(this.cacheNTH[p]=n);};j.createNTHPseudo=function(o,m,c,n){return function(r,p){var t=this.getUID(r);if(!this[c][t]){var z=r.parentNode;if(!z){return false;
|
||||
}var q=z[o],s=1;if(n){var y=r.nodeName;do{if(q.nodeName!=y){continue;}this[c][this.getUID(q)]=s++;}while((q=q[m]));}else{do{if(q.nodeType!=1){continue;
|
||||
}this[c][this.getUID(q)]=s++;}while((q=q[m]));}}p=p||"n";var u=this.cacheNTH[p]||this.parseNTHArgument(p);if(!u){return false;}var x=u.a,w=u.b,v=this[c][t];
|
||||
if(x==0){return w==v;}if(x>0){if(v<w){return false;}}else{if(w<v){return false;}}return((v-w)%x)==0;};};j.pushArray=function(o,c,q,n,m,p){if(this.matchSelector(o,c,q,n,m,p)){this.found.push(o);
|
||||
}};j.pushUID=function(p,c,r,o,m,q){var n=this.getUID(p);if(!this.uniques[n]&&this.matchSelector(p,c,r,o,m,q)){this.uniques[n]=true;this.found.push(p);}};
|
||||
j.matchNode=function(m,n){if(this.isHTMLDocument&&this.nativeMatchesSelector){try{return this.nativeMatchesSelector.call(m,n.replace(/\[([^=]+)=\s*([^'"\]]+?)\s*\]/g,'[$1="$2"]'));
|
||||
}catch(u){}}var t=this.Slick.parse(n);if(!t){return true;}var r=t.expressions,p,s=0,q;for(q=0;(currentExpression=r[q]);q++){if(currentExpression.length==1){var o=currentExpression[0];
|
||||
if(this.matchSelector(m,(this.isXMLDocument)?o.tag:o.tag.toUpperCase(),o.id,o.classes,o.attributes,o.pseudos)){return true;}s++;}}if(s==t.length){return false;
|
||||
}var c=this.search(this.document,t),v;for(q=0;v=c[q++];){if(v===m){return true;}}return false;};j.matchPseudo=function(p,c,o){var m="pseudo:"+c;if(this[m]){return this[m](p,o);
|
||||
}var n=this.getAttribute(p,c);return(o)?o==n:!!n;};j.matchSelector=function(n,u,c,o,p,r){if(u){var s=(this.isXMLDocument)?n.nodeName:n.nodeName.toUpperCase();
|
||||
if(u=="*"){if(s<"@"){return false;}}else{if(s!=u){return false;}}}if(c&&n.getAttribute("id")!=c){return false;}var q,m,t;if(o){for(q=o.length;q--;){t=n.getAttribute("class")||n.className;
|
||||
if(!(t&&o[q].regexp.test(t))){return false;}}}if(p){for(q=p.length;q--;){m=p[q];if(m.operator?!m.test(this.getAttribute(n,m.key)):!this.hasAttribute(n,m.key)){return false;
|
||||
}}}if(r){for(q=r.length;q--;){m=r[q];if(!this.matchPseudo(n,m.key,m.value)){return false;}}}return true;};var i={" ":function(p,v,m,q,r,t,o){var s,u,n;
|
||||
if(this.isHTMLDocument){getById:if(m){u=this.document.getElementById(m);if((!u&&p.all)||(this.idGetsName&&u&&u.getAttributeNode("id").nodeValue!=m)){n=p.all[m];
|
||||
if(!n){return;}if(!n[0]){n=[n];}for(s=0;u=n[s++];){var c=u.getAttributeNode("id");if(c&&c.nodeValue==m){this.push(u,v,null,q,r,t);break;}}return;}if(!u){if(this.contains(this.root,p)){return;
|
||||
}else{break getById;}}else{if(this.document!==p&&!this.contains(p,u)){return;}}this.push(u,v,null,q,r,t);return;}getByClass:if(q&&p.getElementsByClassName&&!this.brokenGEBCN){n=p.getElementsByClassName(o.join(" "));
|
||||
if(!(n&&n.length)){break getByClass;}for(s=0;u=n[s++];){this.push(u,v,m,null,r,t);}return;}}getByTag:{n=p.getElementsByTagName(v);if(!(n&&n.length)){break getByTag;
|
||||
}if(!this.brokenStarGEBTN){v=null;}for(s=0;u=n[s++];){this.push(u,v,m,q,r,t);}}},">":function(o,c,q,n,m,p){if((o=o.firstChild)){do{if(o.nodeType==1){this.push(o,c,q,n,m,p);
|
||||
}}while((o=o.nextSibling));}},"+":function(o,c,q,n,m,p){while((o=o.nextSibling)){if(o.nodeType==1){this.push(o,c,q,n,m,p);break;}}},"^":function(o,c,q,n,m,p){o=o.firstChild;
|
||||
if(o){if(o.nodeType==1){this.push(o,c,q,n,m,p);}else{this["combinator:+"](o,c,q,n,m,p);}}},"~":function(p,c,r,o,m,q){while((p=p.nextSibling)){if(p.nodeType!=1){continue;
|
||||
}var n=this.getUID(p);if(this.bitUniques[n]){break;}this.bitUniques[n]=true;this.push(p,c,r,o,m,q);}},"++":function(o,c,q,n,m,p){this["combinator:+"](o,c,q,n,m,p);
|
||||
this["combinator:!+"](o,c,q,n,m,p);},"~~":function(o,c,q,n,m,p){this["combinator:~"](o,c,q,n,m,p);this["combinator:!~"](o,c,q,n,m,p);},"!":function(o,c,q,n,m,p){while((o=o.parentNode)){if(o!==this.document){this.push(o,c,q,n,m,p);
|
||||
}}},"!>":function(o,c,q,n,m,p){o=o.parentNode;if(o!==this.document){this.push(o,c,q,n,m,p);}},"!+":function(o,c,q,n,m,p){while((o=o.previousSibling)){if(o.nodeType==1){this.push(o,c,q,n,m,p);
|
||||
break;}}},"!^":function(o,c,q,n,m,p){o=o.lastChild;if(o){if(o.nodeType==1){this.push(o,c,q,n,m,p);}else{this["combinator:!+"](o,c,q,n,m,p);}}},"!~":function(p,c,r,o,m,q){while((p=p.previousSibling)){if(p.nodeType!=1){continue;
|
||||
}var n=this.getUID(p);if(this.bitUniques[n]){break;}this.bitUniques[n]=true;this.push(p,c,r,o,m,q);}}};for(var h in i){j["combinator:"+h]=i[h];}var k={empty:function(c){var m=c.firstChild;
|
||||
return !(m&&m.nodeType==1)&&!(c.innerText||c.textContent||"").length;},not:function(c,m){return !this.matchNode(c,m);},contains:function(c,m){return(c.innerText||c.textContent||"").indexOf(m)>-1;
|
||||
},"first-child":function(c){while((c=c.previousSibling)){if(c.nodeType==1){return false;}}return true;},"last-child":function(c){while((c=c.nextSibling)){if(c.nodeType==1){return false;
|
||||
}}return true;},"only-child":function(n){var m=n;while((m=m.previousSibling)){if(m.nodeType==1){return false;}}var c=n;while((c=c.nextSibling)){if(c.nodeType==1){return false;
|
||||
}}return true;},"nth-child":j.createNTHPseudo("firstChild","nextSibling","posNTH"),"nth-last-child":j.createNTHPseudo("lastChild","previousSibling","posNTHLast"),"nth-of-type":j.createNTHPseudo("firstChild","nextSibling","posNTHType",true),"nth-last-of-type":j.createNTHPseudo("lastChild","previousSibling","posNTHTypeLast",true),index:function(m,c){return this["pseudo:nth-child"](m,""+c+1);
|
||||
},even:function(c){return this["pseudo:nth-child"](c,"2n");},odd:function(c){return this["pseudo:nth-child"](c,"2n+1");},"first-of-type":function(c){var m=c.nodeName;
|
||||
while((c=c.previousSibling)){if(c.nodeName==m){return false;}}return true;},"last-of-type":function(c){var m=c.nodeName;while((c=c.nextSibling)){if(c.nodeName==m){return false;
|
||||
}}return true;},"only-of-type":function(n){var m=n,o=n.nodeName;while((m=m.previousSibling)){if(m.nodeName==o){return false;}}var c=n;while((c=c.nextSibling)){if(c.nodeName==o){return false;
|
||||
}}return true;},enabled:function(c){return !c.disabled;},disabled:function(c){return c.disabled;},checked:function(c){return c.checked||c.selected;},focus:function(c){return this.isHTMLDocument&&this.document.activeElement===c&&(c.href||c.type||this.hasAttribute(c,"tabindex"));
|
||||
},root:function(c){return(c===this.root);},selected:function(c){return c.selected;}};for(var a in k){j["pseudo:"+a]=k[a];}j.attributeGetters={"class":function(){return this.getAttribute("class")||this.className;
|
||||
},"for":function(){return("htmlFor" in this)?this.htmlFor:this.getAttribute("for");},href:function(){return("href" in this)?this.getAttribute("href",2):this.getAttribute("href");
|
||||
},style:function(){return(this.style)?this.style.cssText:this.getAttribute("style");},tabindex:function(){var c=this.getAttributeNode("tabindex");return(c&&c.specified)?c.nodeValue:null;
|
||||
},type:function(){return this.getAttribute("type");}};var d=j.Slick=(this.Slick||{});d.version="1.1.5";d.search=function(m,n,c){return j.search(m,n,c);
|
||||
};d.find=function(c,m){return j.search(c,m,null,true);};d.contains=function(c,m){j.setDocument(c);return j.contains(c,m);};d.getAttribute=function(m,c){return j.getAttribute(m,c);
|
||||
};d.match=function(m,c){if(!(m&&c)){return false;}if(!c||c===m){return true;}j.setDocument(m);return j.matchNode(m,c);};d.defineAttributeGetter=function(c,m){j.attributeGetters[c]=m;
|
||||
return this;};d.lookupAttributeGetter=function(c){return j.attributeGetters[c];};d.definePseudo=function(c,m){j["pseudo:"+c]=function(o,n){return m.call(o,n);
|
||||
};return this;};d.lookupPseudo=function(c){var m=j["pseudo:"+c];if(m){return function(n){return m.call(this,n);};}return null;};d.override=function(m,c){j.override(m,c);
|
||||
return this;};d.isXML=j.isXML;d.uidOf=function(c){return j.getUIDHTML(c);};if(!this.Slick){this.Slick=d;}}).apply((typeof exports!="undefined")?exports:this);
|
||||
var Element=function(b,g){var h=Element.Constructors[b];if(h){return h(g);}if(typeof b!="string"){return document.id(b).set(g);}if(!g){g={};}if(!(/^[\w-]+$/).test(b)){var e=Slick.parse(b).expressions[0][0];
|
||||
b=(e.tag=="*")?"div":e.tag;if(e.id&&g.id==null){g.id=e.id;}var d=e.attributes;if(d){for(var f=0,c=d.length;f<c;f++){var a=d[f];if(a.value!=null&&a.operator=="="&&g[a.key]==null){g[a.key]=a.value;
|
||||
}}}if(e.classList&&g["class"]==null){g["class"]=e.classList.join(" ");}}return document.newElement(b,g);};if(Browser.Element){Element.prototype=Browser.Element.prototype;
|
||||
}new Type("Element",Element).mirror(function(a){if(Array.prototype[a]){return;}var b={};b[a]=function(){var h=[],e=arguments,j=true;for(var g=0,d=this.length;
|
||||
g<d;g++){var f=this[g],c=h[g]=f[a].apply(f,e);j=(j&&typeOf(c)=="element");}return(j)?new Elements(h):h;};Elements.implement(b);});if(!Browser.Element){Element.parent=Object;
|
||||
Element.Prototype={"$family":Function.from("element").hide()};Element.mirror(function(a,b){Element.Prototype[a]=b;});}Element.Constructors={};Element.Constructors=new Hash;
|
||||
var IFrame=new Type("IFrame",function(){var e=Array.link(arguments,{properties:Type.isObject,iframe:function(f){return(f!=null);}});var c=e.properties||{},b;
|
||||
if(e.iframe){b=document.id(e.iframe);}var d=c.onload||function(){};delete c.onload;c.id=c.name=[c.id,c.name,b?(b.id||b.name):"IFrame_"+String.uniqueID()].pick();
|
||||
b=new Element(b||"iframe",c);var a=function(){d.call(b.contentWindow);};if(window.frames[c.id]){a();}else{b.addListener("load",a);}return b;});var Elements=this.Elements=function(a){if(a&&a.length){var e={},d;
|
||||
for(var c=0;d=a[c++];){var b=Slick.uidOf(d);if(!e[b]){e[b]=true;this.push(d);}}}};Elements.prototype={length:0};Elements.parent=Array;new Type("Elements",Elements).implement({filter:function(a,b){if(!a){return this;
|
||||
}return new Elements(Array.filter(this,(typeOf(a)=="string")?function(c){return c.match(a);}:a,b));}.protect(),push:function(){var d=this.length;for(var b=0,a=arguments.length;
|
||||
b<a;b++){var c=document.id(arguments[b]);if(c){this[d++]=c;}}return(this.length=d);}.protect(),unshift:function(){var b=[];for(var c=0,a=arguments.length;
|
||||
c<a;c++){var d=document.id(arguments[c]);if(d){b.push(d);}}return Array.prototype.unshift.apply(this,b);}.protect(),concat:function(){var b=new Elements(this);
|
||||
for(var c=0,a=arguments.length;c<a;c++){var d=arguments[c];if(Type.isEnumerable(d)){b.append(d);}else{b.push(d);}}return b;}.protect(),append:function(c){for(var b=0,a=c.length;
|
||||
b<a;b++){this.push(c[b]);}return this;}.protect(),empty:function(){while(this.length){delete this[--this.length];}return this;}.protect()});Elements.alias("extend","append");
|
||||
(function(){var g=Array.prototype.splice,b={"0":0,"1":1,length:2};g.call(b,1,1);if(b[1]==1){Elements.implement("splice",function(){var e=this.length;g.apply(this,arguments);
|
||||
while(e>=this.length){delete this[e--];}return this;}.protect());}Elements.implement(Array.prototype);Array.mirror(Elements);var f;try{var a=document.createElement("<input name=x>");
|
||||
f=(a.name=="x");}catch(c){}var d=function(e){return(""+e).replace(/&/g,"&").replace(/"/g,""");};Document.implement({newElement:function(e,h){if(h&&h.checked!=null){h.defaultChecked=h.checked;
|
||||
}if(f&&h){e="<"+e;if(h.name){e+=' name="'+d(h.name)+'"';}if(h.type){e+=' type="'+d(h.type)+'"';}e+=">";delete h.name;delete h.type;}return this.id(this.createElement(e)).set(h);
|
||||
}});})();Document.implement({newTextNode:function(a){return this.createTextNode(a);},getDocument:function(){return this;},getWindow:function(){return this.window;
|
||||
},id:(function(){var a={string:function(d,c,b){d=Slick.find(b,"#"+d.replace(/(\W)/g,"\\$1"));return(d)?a.element(d,c):null;},element:function(b,c){$uid(b);
|
||||
if(!c&&!b.$family&&!(/^(?:object|embed)$/i).test(b.tagName)){Object.append(b,Element.Prototype);}return b;},object:function(c,d,b){if(c.toElement){return a.element(c.toElement(b),d);
|
||||
}return null;}};a.textnode=a.whitespace=a.window=a.document=function(b){return b;};return function(c,e,d){if(c&&c.$family&&c.uid){return c;}var b=typeOf(c);
|
||||
return(a[b])?a[b](c,e,d||document):null;};})()});if(window.$==null){Window.implement("$",function(a,b){return document.id(a,b,this.document);});}Window.implement({getDocument:function(){return this.document;
|
||||
},getWindow:function(){return this;}});[Document,Element].invoke("implement",{getElements:function(a){return Slick.search(this,a,new Elements);},getElement:function(a){return document.id(Slick.find(this,a));
|
||||
}});(function(b,d,a){this.Selectors={};var e=this.Selectors.Pseudo=new Hash();var c=function(){for(var f in e){if(e.hasOwnProperty(f)){Slick.definePseudo(f,e[f]);
|
||||
delete e[f];}}};Slick.search=function(g,h,f){c();return b.call(this,g,h,f);};Slick.find=function(f,g){c();return d.call(this,f,g);};Slick.match=function(g,f){c();
|
||||
return a.call(this,g,f);};})(Slick.search,Slick.find,Slick.match);if(window.$$==null){Window.implement("$$",function(a){var f=new Elements;if(arguments.length==1&&typeof a=="string"){return Slick.search(this.document,a,f);
|
||||
}var c=Array.flatten(arguments);for(var d=0,b=c.length;d<b;d++){var e=c[d];switch(typeOf(e)){case"element":f.push(e);break;case"string":Slick.search(this.document,e,f);
|
||||
}}return f;});}if(window.$$==null){Window.implement("$$",function(a){if(arguments.length==1){if(typeof a=="string"){return Slick.search(this.document,a,new Elements);
|
||||
}else{if(Type.isEnumerable(a)){return new Elements(a);}}}return new Elements(arguments);});}(function(){var k={},i={};var n={input:"checked",option:"selected",textarea:"value"};
|
||||
var e=function(p){return(i[p]||(i[p]={}));};var j=function(q){var p=q.uid;if(q.removeEvents){q.removeEvents();}if(q.clearAttributes){q.clearAttributes();
|
||||
}if(p!=null){delete k[p];delete i[p];}return q;};var o=["defaultValue","accessKey","cellPadding","cellSpacing","colSpan","frameBorder","maxLength","readOnly","rowSpan","tabIndex","useMap"];
|
||||
var d=["compact","nowrap","ismap","declare","noshade","checked","disabled","readOnly","multiple","selected","noresize","defer","defaultChecked"];var g={html:"innerHTML","class":"className","for":"htmlFor",text:(function(){var p=document.createElement("div");
|
||||
return(p.textContent==null)?"innerText":"textContent";})()};var m=["type"];var h=["value","defaultValue"];var l=/^(?:href|src|usemap)$/i;d=d.associate(d);
|
||||
o=o.associate(o.map(String.toLowerCase));m=m.associate(m);Object.append(g,h.associate(h));var c={before:function(q,p){var r=p.parentNode;if(r){r.insertBefore(q,p);
|
||||
}},after:function(q,p){var r=p.parentNode;if(r){r.insertBefore(q,p.nextSibling);}},bottom:function(q,p){p.appendChild(q);},top:function(q,p){p.insertBefore(q,p.firstChild);
|
||||
}};c.inside=c.bottom;Object.each(c,function(q,r){r=r.capitalize();var p={};p["inject"+r]=function(s){q(this,document.id(s,true));return this;};p["grab"+r]=function(s){q(document.id(s,true),this);
|
||||
return this;};Element.implement(p);});var b=function(s,r){if(!s){return r;}s=Object.clone(Slick.parse(s));var q=s.expressions;for(var p=q.length;p--;){q[p][0].combinator=r;
|
||||
}return s;};Element.implement({set:function(r,q){var p=Element.Properties[r];(p&&p.set)?p.set.call(this,q):this.setProperty(r,q);}.overloadSetter(),get:function(q){var p=Element.Properties[q];
|
||||
return(p&&p.get)?p.get.apply(this):this.getProperty(q);}.overloadGetter(),erase:function(q){var p=Element.Properties[q];(p&&p.erase)?p.erase.apply(this):this.removeProperty(q);
|
||||
return this;},setProperty:function(q,r){q=o[q]||q;if(r==null){return this.removeProperty(q);}var p=g[q];(p)?this[p]=r:(d[q])?this[q]=!!r:this.setAttribute(q,""+r);
|
||||
return this;},setProperties:function(p){for(var q in p){this.setProperty(q,p[q]);}return this;},getProperty:function(q){q=o[q]||q;var p=g[q]||m[q];return(p)?this[p]:(d[q])?!!this[q]:(l.test(q)?this.getAttribute(q,2):(p=this.getAttributeNode(q))?p.nodeValue:null)||null;
|
||||
},getProperties:function(){var p=Array.from(arguments);return p.map(this.getProperty,this).associate(p);},removeProperty:function(q){q=o[q]||q;var p=g[q];
|
||||
(p)?this[p]="":(d[q])?this[q]=false:this.removeAttribute(q);return this;},removeProperties:function(){Array.each(arguments,this.removeProperty,this);return this;
|
||||
},hasClass:function(p){return this.className.clean().contains(p," ");},addClass:function(p){if(!this.hasClass(p)){this.className=(this.className+" "+p).clean();
|
||||
}return this;},removeClass:function(p){this.className=this.className.replace(new RegExp("(^|\\s)"+p+"(?:\\s|$)"),"$1");return this;},toggleClass:function(p,q){if(q==null){q=!this.hasClass(p);
|
||||
}return(q)?this.addClass(p):this.removeClass(p);},adopt:function(){var s=this,p,u=Array.flatten(arguments),t=u.length;if(t>1){s=p=document.createDocumentFragment();
|
||||
}for(var r=0;r<t;r++){var q=document.id(u[r],true);if(q){s.appendChild(q);}}if(p){this.appendChild(p);}return this;},appendText:function(q,p){return this.grab(this.getDocument().newTextNode(q),p);
|
||||
},grab:function(q,p){c[p||"bottom"](document.id(q,true),this);return this;},inject:function(q,p){c[p||"bottom"](this,document.id(q,true));return this;},replaces:function(p){p=document.id(p,true);
|
||||
p.parentNode.replaceChild(this,p);return this;},wraps:function(q,p){q=document.id(q,true);return this.replaces(q).grab(q,p);},getPrevious:function(p){return document.id(Slick.find(this,b(p,"!~")));
|
||||
},getAllPrevious:function(p){return Slick.search(this,b(p,"!~"),new Elements);},getNext:function(p){return document.id(Slick.find(this,b(p,"~")));},getAllNext:function(p){return Slick.search(this,b(p,"~"),new Elements);
|
||||
},getFirst:function(p){return document.id(Slick.search(this,b(p,">"))[0]);},getLast:function(p){return document.id(Slick.search(this,b(p,">")).getLast());
|
||||
},getParent:function(p){return document.id(Slick.find(this,b(p,"!")));},getParents:function(p){return Slick.search(this,b(p,"!"),new Elements);},getSiblings:function(p){return Slick.search(this,b(p,"~~"),new Elements);
|
||||
},getChildren:function(p){return Slick.search(this,b(p,">"),new Elements);},getWindow:function(){return this.ownerDocument.window;},getDocument:function(){return this.ownerDocument;
|
||||
},getElementById:function(p){return document.id(Slick.find(this,"#"+(""+p).replace(/(\W)/g,"\\$1")));},getSelected:function(){this.selectedIndex;return new Elements(Array.from(this.options).filter(function(p){return p.selected;
|
||||
}));},toQueryString:function(){var p=[];this.getElements("input, select, textarea").each(function(r){var q=r.type;if(!r.name||r.disabled||q=="submit"||q=="reset"||q=="file"||q=="image"){return;
|
||||
}var s=(r.get("tag")=="select")?r.getSelected().map(function(t){return document.id(t).get("value");}):((q=="radio"||q=="checkbox")&&!r.checked)?null:r.get("value");
|
||||
Array.from(s).each(function(t){if(typeof t!="undefined"){p.push(encodeURIComponent(r.name)+"="+encodeURIComponent(t));}});});return p.join("&");},destroy:function(){var p=j(this).getElementsByTagName("*");
|
||||
Array.each(p,j);Element.dispose(this);return null;},empty:function(){Array.from(this.childNodes).each(Element.dispose);return this;},dispose:function(){return(this.parentNode)?this.parentNode.removeChild(this):this;
|
||||
},match:function(p){return !p||Slick.match(this,p);}});var a=function(t,s,q){if(!q){t.setAttributeNode(document.createAttribute("id"));}if(t.clearAttributes){t.clearAttributes();
|
||||
t.mergeAttributes(s);t.removeAttribute("uid");if(t.options){var u=t.options,p=s.options;for(var r=u.length;r--;){u[r].selected=p[r].selected;}}}var v=n[s.tagName.toLowerCase()];
|
||||
if(v&&s[v]){t[v]=s[v];}};Element.implement("clone",function(r,p){r=r!==false;var w=this.cloneNode(r),q;if(r){var s=w.getElementsByTagName("*"),u=this.getElementsByTagName("*");
|
||||
for(q=s.length;q--;){a(s[q],u[q],p);}}a(w,this,p);if(Browser.ie){var t=w.getElementsByTagName("object"),v=this.getElementsByTagName("object");for(q=t.length;
|
||||
q--;){t[q].outerHTML=v[q].outerHTML;}}return document.id(w);});var f={contains:function(p){return Slick.contains(this,p);}};if(!document.contains){Document.implement(f);
|
||||
}if(!document.createElement("div").contains){Element.implement(f);}Element.implement("hasChild",function(p){return this!==p&&this.contains(p);});[Element,Window,Document].invoke("implement",{addListener:function(s,r){if(s=="unload"){var p=r,q=this;
|
||||
r=function(){q.removeListener("unload",r);p();};}else{k[$uid(this)]=this;}if(this.addEventListener){this.addEventListener(s,r,!!arguments[2]);}else{this.attachEvent("on"+s,r);
|
||||
}return this;},removeListener:function(q,p){if(this.removeEventListener){this.removeEventListener(q,p,!!arguments[2]);}else{this.detachEvent("on"+q,p);
|
||||
}return this;},retrieve:function(q,p){var s=e($uid(this)),r=s[q];if(p!=null&&r==null){r=s[q]=p;}return r!=null?r:null;},store:function(q,p){var r=e($uid(this));
|
||||
r[q]=p;return this;},eliminate:function(p){var q=e($uid(this));delete q[p];return this;}});if(window.attachEvent&&!window.addEventListener){window.addListener("unload",function(){Object.each(k,j);
|
||||
if(window.CollectGarbage){CollectGarbage();}});}})();Element.Properties={};Element.Properties=new Hash;Element.Properties.style={set:function(a){this.style.cssText=a;
|
||||
},get:function(){return this.style.cssText;},erase:function(){this.style.cssText="";}};Element.Properties.tag={get:function(){return this.tagName.toLowerCase();
|
||||
}};(function(a){if(a!=null){Element.Properties.maxlength=Element.Properties.maxLength={get:function(){var b=this.getAttribute("maxLength");return b==a?null:b;
|
||||
}};}})(document.createElement("input").getAttribute("maxLength"));Element.Properties.html=(function(){var c=Function.attempt(function(){var e=document.createElement("table");
|
||||
e.innerHTML="<tr><td></td></tr>";});var d=document.createElement("div");var a={table:[1,"<table>","</table>"],select:[1,"<select>","</select>"],tbody:[2,"<table><tbody>","</tbody></table>"],tr:[3,"<table><tbody><tr>","</tr></tbody></table>"]};
|
||||
a.thead=a.tfoot=a.tbody;var b={set:function(){var f=Array.flatten(arguments).join("");var g=(!c&&a[this.get("tag")]);if(g){var h=d;h.innerHTML=g[1]+f+g[2];
|
||||
for(var e=g[0];e--;){h=h.firstChild;}this.empty().adopt(h.childNodes);}else{this.innerHTML=f;}}};b.erase=b.set;return b;})();(function(){var c=document.html;
|
||||
Element.Properties.styles={set:function(f){this.setStyles(f);}};var e=(c.style.opacity!=null);var d=/alpha\(opacity=([\d.]+)\)/i;var b=function(g,f){if(!g.currentStyle||!g.currentStyle.hasLayout){g.style.zoom=1;
|
||||
}if(e){g.style.opacity=f;}else{f=(f==1)?"":"alpha(opacity="+f*100+")";var h=g.style.filter||g.getComputedStyle("filter")||"";g.style.filter=d.test(h)?h.replace(d,f):h+f;
|
||||
}};Element.Properties.opacity={set:function(g){var f=this.style.visibility;if(g==0&&f!="hidden"){this.style.visibility="hidden";}else{if(g!=0&&f!="visible"){this.style.visibility="visible";
|
||||
}}b(this,g);},get:(e)?function(){var f=this.style.opacity||this.getComputedStyle("opacity");return(f=="")?1:f;}:function(){var f,g=(this.style.filter||this.getComputedStyle("filter"));
|
||||
if(g){f=g.match(d);}return(f==null||g==null)?1:(f[1]/100);}};var a=(c.style.cssFloat==null)?"styleFloat":"cssFloat";Element.implement({getComputedStyle:function(h){if(this.currentStyle){return this.currentStyle[h.camelCase()];
|
||||
}var g=Element.getDocument(this).defaultView,f=g?g.getComputedStyle(this,null):null;return(f)?f.getPropertyValue((h==a)?"float":h.hyphenate()):null;},setOpacity:function(f){b(this,f);
|
||||
return this;},getOpacity:function(){return this.get("opacity");},setStyle:function(g,f){switch(g){case"opacity":return this.set("opacity",parseFloat(f));
|
||||
case"float":g=a;}g=g.camelCase();if(typeOf(f)!="string"){var h=(Element.Styles[g]||"@").split(" ");f=Array.from(f).map(function(k,j){if(!h[j]){return"";
|
||||
}return(typeOf(k)=="number")?h[j].replace("@",Math.round(k)):k;}).join(" ");}else{if(f==String(Number(f))){f=Math.round(f);}}this.style[g]=f;return this;
|
||||
},getStyle:function(l){switch(l){case"opacity":return this.get("opacity");case"float":l=a;}l=l.camelCase();var f=this.style[l];if(!f||l=="zIndex"){f=[];
|
||||
for(var k in Element.ShortStyles){if(l!=k){continue;}for(var j in Element.ShortStyles[k]){f.push(this.getStyle(j));}return f.join(" ");}f=this.getComputedStyle(l);
|
||||
}if(f){f=String(f);var h=f.match(/rgba?\([\d\s,]+\)/);if(h){f=f.replace(h[0],h[0].rgbToHex());}}if(Browser.opera||(Browser.ie&&isNaN(parseFloat(f)))){if((/^(height|width)$/).test(l)){var g=(l=="width")?["left","right"]:["top","bottom"],i=0;
|
||||
g.each(function(m){i+=this.getStyle("border-"+m+"-width").toInt()+this.getStyle("padding-"+m).toInt();},this);return this["offset"+l.capitalize()]-i+"px";
|
||||
}if(Browser.opera&&String(f).indexOf("px")!=-1){return f;}if((/^border(.+)Width|margin|padding/).test(l)){return"0px";}}return f;},setStyles:function(g){for(var f in g){this.setStyle(f,g[f]);
|
||||
}return this;},getStyles:function(){var f={};Array.flatten(arguments).each(function(g){f[g]=this.getStyle(g);},this);return f;}});Element.Styles={left:"@px",top:"@px",bottom:"@px",right:"@px",width:"@px",height:"@px",maxWidth:"@px",maxHeight:"@px",minWidth:"@px",minHeight:"@px",backgroundColor:"rgb(@, @, @)",backgroundPosition:"@px @px",color:"rgb(@, @, @)",fontSize:"@px",letterSpacing:"@px",lineHeight:"@px",clip:"rect(@px @px @px @px)",margin:"@px @px @px @px",padding:"@px @px @px @px",border:"@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)",borderWidth:"@px @px @px @px",borderStyle:"@ @ @ @",borderColor:"rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)",zIndex:"@",zoom:"@",fontWeight:"@",textIndent:"@px",opacity:"@"};
|
||||
Element.Styles=new Hash(Element.Styles);Element.ShortStyles={margin:{},padding:{},border:{},borderWidth:{},borderStyle:{},borderColor:{}};["Top","Right","Bottom","Left"].each(function(l){var k=Element.ShortStyles;
|
||||
var g=Element.Styles;["margin","padding"].each(function(m){var n=m+l;k[m][n]=g[n]="@px";});var j="border"+l;k.border[j]=g[j]="@px @ rgb(@, @, @)";var i=j+"Width",f=j+"Style",h=j+"Color";
|
||||
k[j]={};k.borderWidth[i]=k[j][i]=g[i]="@px";k.borderStyle[f]=k[j][f]=g[f]="@";k.borderColor[h]=k[j][h]=g[h]="rgb(@, @, @)";});}).call(this);(function(){Element.Properties.events={set:function(b){this.addEvents(b);
|
||||
}};[Element,Window,Document].invoke("implement",{addEvent:function(f,h){var i=this.retrieve("events",{});if(!i[f]){i[f]={keys:[],values:[]};}if(i[f].keys.contains(h)){return this;
|
||||
}i[f].keys.push(h);var g=f,b=Element.Events[f],d=h,j=this;if(b){if(b.onAdd){b.onAdd.call(this,h);}if(b.condition){d=function(k){if(b.condition.call(this,k)){return h.call(this,k);
|
||||
}return true;};}g=b.base||g;}var e=function(){return h.call(j);};var c=Element.NativeEvents[g];if(c){if(c==2){e=function(k){k=new Event(k,j.getWindow());
|
||||
if(d.call(j,k)===false){k.stop();}};}this.addListener(g,e,arguments[2]);}i[f].values.push(e);return this;},removeEvent:function(e,d){var c=this.retrieve("events");
|
||||
if(!c||!c[e]){return this;}var h=c[e];var b=h.keys.indexOf(d);if(b==-1){return this;}var g=h.values[b];delete h.keys[b];delete h.values[b];var f=Element.Events[e];
|
||||
if(f){if(f.onRemove){f.onRemove.call(this,d);}e=f.base||e;}return(Element.NativeEvents[e])?this.removeListener(e,g,arguments[2]):this;},addEvents:function(b){for(var c in b){this.addEvent(c,b[c]);
|
||||
}return this;},removeEvents:function(b){var d;if(typeOf(b)=="object"){for(d in b){this.removeEvent(d,b[d]);}return this;}var c=this.retrieve("events");
|
||||
if(!c){return this;}if(!b){for(d in c){this.removeEvents(d);}this.eliminate("events");}else{if(c[b]){c[b].keys.each(function(e){this.removeEvent(b,e);},this);
|
||||
delete c[b];}}return this;},fireEvent:function(e,c,b){var d=this.retrieve("events");if(!d||!d[e]){return this;}c=Array.from(c);d[e].keys.each(function(f){if(b){f.delay(b,this,c);
|
||||
}else{f.apply(this,c);}},this);return this;},cloneEvents:function(e,d){e=document.id(e);var c=e.retrieve("events");if(!c){return this;}if(!d){for(var b in c){this.cloneEvents(e,b);
|
||||
}}else{if(c[d]){c[d].keys.each(function(f){this.addEvent(d,f);},this);}}return this;}});Element.NativeEvents={click:2,dblclick:2,mouseup:2,mousedown:2,contextmenu:2,mousewheel:2,DOMMouseScroll:2,mouseover:2,mouseout:2,mousemove:2,selectstart:2,selectend:2,keydown:2,keypress:2,keyup:2,orientationchange:2,touchstart:2,touchmove:2,touchend:2,touchcancel:2,gesturestart:2,gesturechange:2,gestureend:2,focus:2,blur:2,change:2,reset:2,select:2,submit:2,load:2,unload:1,beforeunload:2,resize:1,move:1,DOMContentLoaded:1,readystatechange:1,error:1,abort:1,scroll:1};
|
||||
var a=function(b){var c=b.relatedTarget;if(c==null){return true;}if(!c){return false;}return(c!=this&&c.prefix!="xul"&&typeOf(this)!="document"&&!this.contains(c));
|
||||
};Element.Events={mouseenter:{base:"mouseover",condition:a},mouseleave:{base:"mouseout",condition:a},mousewheel:{base:(Browser.firefox)?"DOMMouseScroll":"mousewheel"}};
|
||||
Element.Events=new Hash(Element.Events);}).call(this);(function(){var h=document.createElement("div"),e=document.createElement("div");h.style.height="0";
|
||||
h.appendChild(e);var d=(e.offsetParent===h);h=e=null;var l=function(m){return k(m,"position")!="static"||a(m);};var i=function(m){return l(m)||(/^(?:table|td|th)$/i).test(m.tagName);
|
||||
};Element.implement({scrollTo:function(m,n){if(a(this)){this.getWindow().scrollTo(m,n);}else{this.scrollLeft=m;this.scrollTop=n;}return this;},getSize:function(){if(a(this)){return this.getWindow().getSize();
|
||||
}return{x:this.offsetWidth,y:this.offsetHeight};},getScrollSize:function(){if(a(this)){return this.getWindow().getScrollSize();}return{x:this.scrollWidth,y:this.scrollHeight};
|
||||
},getScroll:function(){if(a(this)){return this.getWindow().getScroll();}return{x:this.scrollLeft,y:this.scrollTop};},getScrolls:function(){var n=this.parentNode,m={x:0,y:0};
|
||||
while(n&&!a(n)){m.x+=n.scrollLeft;m.y+=n.scrollTop;n=n.parentNode;}return m;},getOffsetParent:d?function(){var m=this;if(a(m)||k(m,"position")=="fixed"){return null;
|
||||
}var n=(k(m,"position")=="static")?i:l;while((m=m.parentNode)){if(n(m)){return m;}}return null;}:function(){var m=this;if(a(m)||k(m,"position")=="fixed"){return null;
|
||||
}try{return m.offsetParent;}catch(n){}return null;},getOffsets:function(){if(this.getBoundingClientRect&&!Browser.Platform.ios){var r=this.getBoundingClientRect(),o=document.id(this.getDocument().documentElement),q=o.getScroll(),t=this.getScrolls(),s=(k(this,"position")=="fixed");
|
||||
return{x:r.left.toInt()+t.x+((s)?0:q.x)-o.clientLeft,y:r.top.toInt()+t.y+((s)?0:q.y)-o.clientTop};}var n=this,m={x:0,y:0};if(a(this)){return m;}while(n&&!a(n)){m.x+=n.offsetLeft;
|
||||
m.y+=n.offsetTop;if(Browser.firefox){if(!c(n)){m.x+=b(n);m.y+=g(n);}var p=n.parentNode;if(p&&k(p,"overflow")!="visible"){m.x+=b(p);m.y+=g(p);}}else{if(n!=this&&Browser.safari){m.x+=b(n);
|
||||
m.y+=g(n);}}n=n.offsetParent;}if(Browser.firefox&&!c(this)){m.x-=b(this);m.y-=g(this);}return m;},getPosition:function(p){if(a(this)){return{x:0,y:0};}var q=this.getOffsets(),n=this.getScrolls();
|
||||
var m={x:q.x-n.x,y:q.y-n.y};if(p&&(p=document.id(p))){var o=p.getPosition();return{x:m.x-o.x-b(p),y:m.y-o.y-g(p)};}return m;},getCoordinates:function(o){if(a(this)){return this.getWindow().getCoordinates();
|
||||
}var m=this.getPosition(o),n=this.getSize();var p={left:m.x,top:m.y,width:n.x,height:n.y};p.right=p.left+p.width;p.bottom=p.top+p.height;return p;},computePosition:function(m){return{left:m.x-j(this,"margin-left"),top:m.y-j(this,"margin-top")};
|
||||
},setPosition:function(m){return this.setStyles(this.computePosition(m));}});[Document,Window].invoke("implement",{getSize:function(){var m=f(this);return{x:m.clientWidth,y:m.clientHeight};
|
||||
},getScroll:function(){var n=this.getWindow(),m=f(this);return{x:n.pageXOffset||m.scrollLeft,y:n.pageYOffset||m.scrollTop};},getScrollSize:function(){var o=f(this),n=this.getSize(),m=this.getDocument().body;
|
||||
return{x:Math.max(o.scrollWidth,m.scrollWidth,n.x),y:Math.max(o.scrollHeight,m.scrollHeight,n.y)};},getPosition:function(){return{x:0,y:0};},getCoordinates:function(){var m=this.getSize();
|
||||
return{top:0,left:0,bottom:m.y,right:m.x,height:m.y,width:m.x};}});var k=Element.getComputedStyle;function j(m,n){return k(m,n).toInt()||0;}function c(m){return k(m,"-moz-box-sizing")=="border-box";
|
||||
}function g(m){return j(m,"border-top-width");}function b(m){return j(m,"border-left-width");}function a(m){return(/^(?:body|html)$/i).test(m.tagName);
|
||||
}function f(m){var n=m.getDocument();return(!n.compatMode||n.compatMode=="CSS1Compat")?n.html:n.body;}}).call(this);Element.alias({position:"setPosition"});
|
||||
[Window,Document,Element].invoke("implement",{getHeight:function(){return this.getSize().y;},getWidth:function(){return this.getSize().x;},getScrollTop:function(){return this.getScroll().y;
|
||||
},getScrollLeft:function(){return this.getScroll().x;},getScrollHeight:function(){return this.getScrollSize().y;},getScrollWidth:function(){return this.getScrollSize().x;
|
||||
},getTop:function(){return this.getPosition().y;},getLeft:function(){return this.getPosition().x;}});(function(){var f=this.Fx=new Class({Implements:[Chain,Events,Options],options:{fps:60,unit:false,duration:500,frames:null,frameSkip:true,link:"ignore"},initialize:function(g){this.subject=this.subject||this;
|
||||
this.setOptions(g);},getTransition:function(){return function(g){return -(Math.cos(Math.PI*g)-1)/2;};},step:function(g){if(this.options.frameSkip){var h=(this.time!=null)?(g-this.time):0,i=h/this.frameInterval;
|
||||
this.time=g;this.frame+=i;}else{this.frame++;}if(this.frame<this.frames){var j=this.transition(this.frame/this.frames);this.set(this.compute(this.from,this.to,j));
|
||||
}else{this.frame=this.frames;this.set(this.compute(this.from,this.to,1));this.stop();}},set:function(g){return g;},compute:function(i,h,g){return f.compute(i,h,g);
|
||||
},check:function(){if(!this.isRunning()){return true;}switch(this.options.link){case"cancel":this.cancel();return true;case"chain":this.chain(this.caller.pass(arguments,this));
|
||||
return false;}return false;},start:function(k,j){if(!this.check(k,j)){return this;}this.from=k;this.to=j;this.frame=(this.options.frameSkip)?0:-1;this.time=null;
|
||||
this.transition=this.getTransition();var i=this.options.frames,h=this.options.fps,g=this.options.duration;this.duration=f.Durations[g]||g.toInt();this.frameInterval=1000/h;
|
||||
this.frames=i||Math.round(this.duration/this.frameInterval);this.fireEvent("start",this.subject);b.call(this,h);return this;},stop:function(){if(this.isRunning()){this.time=null;
|
||||
d.call(this,this.options.fps);if(this.frames==this.frame){this.fireEvent("complete",this.subject);if(!this.callChain()){this.fireEvent("chainComplete",this.subject);
|
||||
}}else{this.fireEvent("stop",this.subject);}}return this;},cancel:function(){if(this.isRunning()){this.time=null;d.call(this,this.options.fps);this.frame=this.frames;
|
||||
this.fireEvent("cancel",this.subject).clearChain();}return this;},pause:function(){if(this.isRunning()){this.time=null;d.call(this,this.options.fps);}return this;
|
||||
},resume:function(){if((this.frame<this.frames)&&!this.isRunning()){b.call(this,this.options.fps);}return this;},isRunning:function(){var g=e[this.options.fps];
|
||||
return g&&g.contains(this);}});f.compute=function(i,h,g){return(h-i)*g+i;};f.Durations={"short":250,normal:500,"long":1000};var e={},c={};var a=function(){var h=Date.now();
|
||||
for(var j=this.length;j--;){var g=this[j];if(g){g.step(h);}}};var b=function(h){var g=e[h]||(e[h]=[]);g.push(this);if(!c[h]){c[h]=a.periodical(Math.round(1000/h),g);
|
||||
}};var d=function(h){var g=e[h];if(g){g.erase(this);if(!g.length&&c[h]){delete e[h];c[h]=clearInterval(c[h]);}}};}).call(this);Fx.CSS=new Class({Extends:Fx,prepare:function(c,d,b){b=Array.from(b);
|
||||
if(b[1]==null){b[1]=b[0];b[0]=c.getStyle(d);}var a=b.map(this.parse);return{from:a[0],to:a[1]};},parse:function(a){a=Function.from(a)();a=(typeof a=="string")?a.split(" "):Array.from(a);
|
||||
return a.map(function(c){c=String(c);var b=false;Object.each(Fx.CSS.Parsers,function(f,e){if(b){return;}var d=f.parse(c);if(d||d===0){b={value:d,parser:f};
|
||||
}});b=b||{value:c,parser:Fx.CSS.Parsers.String};return b;});},compute:function(d,c,b){var a=[];(Math.min(d.length,c.length)).times(function(e){a.push({value:d[e].parser.compute(d[e].value,c[e].value,b),parser:d[e].parser});
|
||||
});a.$family=Function.from("fx:css:value");return a;},serve:function(c,b){if(typeOf(c)!="fx:css:value"){c=this.parse(c);}var a=[];c.each(function(d){a=a.concat(d.parser.serve(d.value,b));
|
||||
});return a;},render:function(a,d,c,b){a.setStyle(d,this.serve(c,b));},search:function(a){if(Fx.CSS.Cache[a]){return Fx.CSS.Cache[a];}var c={},b=new RegExp("^"+a.escapeRegExp()+"$");
|
||||
Array.each(document.styleSheets,function(f,e){var d=f.href;if(d&&d.contains("://")&&!d.contains(document.domain)){return;}var g=f.rules||f.cssRules;Array.each(g,function(k,h){if(!k.style){return;
|
||||
}var j=(k.selectorText)?k.selectorText.replace(/^\w+/,function(i){return i.toLowerCase();}):null;if(!j||!b.test(j)){return;}Object.each(Element.Styles,function(l,i){if(!k.style[i]||Element.ShortStyles[i]){return;
|
||||
}l=String(k.style[i]);c[i]=((/^rgb/).test(l))?l.rgbToHex():l;});});});return Fx.CSS.Cache[a]=c;}});Fx.CSS.Cache={};Fx.CSS.Parsers={Color:{parse:function(a){if(a.match(/^#[0-9a-f]{3,6}$/i)){return a.hexToRgb(true);
|
||||
}return((a=a.match(/(\d+),\s*(\d+),\s*(\d+)/)))?[a[1],a[2],a[3]]:false;},compute:function(c,b,a){return c.map(function(e,d){return Math.round(Fx.compute(c[d],b[d],a));
|
||||
});},serve:function(a){return a.map(Number);}},Number:{parse:parseFloat,compute:Fx.compute,serve:function(b,a){return(a)?b+a:b;}},String:{parse:Function.from(false),compute:function(b,a){return a;
|
||||
},serve:function(a){return a;}}};Fx.CSS.Parsers=new Hash(Fx.CSS.Parsers);Fx.Tween=new Class({Extends:Fx.CSS,initialize:function(b,a){this.element=this.subject=document.id(b);
|
||||
this.parent(a);},set:function(b,a){if(arguments.length==1){a=b;b=this.property||this.options.property;}this.render(this.element,b,a,this.options.unit);
|
||||
return this;},start:function(c,e,d){if(!this.check(c,e,d)){return this;}var b=Array.flatten(arguments);this.property=this.options.property||b.shift();var a=this.prepare(this.element,this.property,b);
|
||||
return this.parent(a.from,a.to);}});Element.Properties.tween={set:function(a){this.get("tween").cancel().setOptions(a);return this;},get:function(){var a=this.retrieve("tween");
|
||||
if(!a){a=new Fx.Tween(this,{link:"cancel"});this.store("tween",a);}return a;}};Element.implement({tween:function(a,c,b){this.get("tween").start(arguments);
|
||||
return this;},fade:function(c){var e=this.get("tween"),d="opacity",a;c=[c,"toggle"].pick();switch(c){case"in":e.start(d,1);break;case"out":e.start(d,0);
|
||||
break;case"show":e.set(d,1);break;case"hide":e.set(d,0);break;case"toggle":var b=this.retrieve("fade:flag",this.get("opacity")==1);e.start(d,(b)?0:1);this.store("fade:flag",!b);
|
||||
a=true;break;default:e.start(d,arguments);}if(!a){this.eliminate("fade:flag");}return this;},highlight:function(c,a){if(!a){a=this.retrieve("highlight:original",this.getStyle("background-color"));
|
||||
a=(a=="transparent")?"#fff":a;}var b=this.get("tween");b.start("background-color",c||"#ffff88",a).chain(function(){this.setStyle("background-color",this.retrieve("highlight:original"));
|
||||
b.callChain();}.bind(this));return this;}});Fx.Morph=new Class({Extends:Fx.CSS,initialize:function(b,a){this.element=this.subject=document.id(b);this.parent(a);
|
||||
},set:function(a){if(typeof a=="string"){a=this.search(a);}for(var b in a){this.render(this.element,b,a[b],this.options.unit);}return this;},compute:function(e,d,c){var a={};
|
||||
for(var b in e){a[b]=this.parent(e[b],d[b],c);}return a;},start:function(b){if(!this.check(b)){return this;}if(typeof b=="string"){b=this.search(b);}var e={},d={};
|
||||
for(var c in b){var a=this.prepare(this.element,c,b[c]);e[c]=a.from;d[c]=a.to;}return this.parent(e,d);}});Element.Properties.morph={set:function(a){this.get("morph").cancel().setOptions(a);
|
||||
return this;},get:function(){var a=this.retrieve("morph");if(!a){a=new Fx.Morph(this,{link:"cancel"});this.store("morph",a);}return a;}};Element.implement({morph:function(a){this.get("morph").start(a);
|
||||
return this;}});Fx.implement({getTransition:function(){var a=this.options.transition||Fx.Transitions.Sine.easeInOut;if(typeof a=="string"){var b=a.split(":");
|
||||
a=Fx.Transitions;a=a[b[0]]||a[b[0].capitalize()];if(b[1]){a=a["ease"+b[1].capitalize()+(b[2]?b[2].capitalize():"")];}}return a;}});Fx.Transition=function(c,b){b=Array.from(b);
|
||||
var a=function(d){return c(d,b);};return Object.append(a,{easeIn:a,easeOut:function(d){return 1-c(1-d,b);},easeInOut:function(d){return(d<=0.5?c(2*d,b):(2-c(2*(1-d),b)))/2;
|
||||
}});};Fx.Transitions={linear:function(a){return a;}};Fx.Transitions=new Hash(Fx.Transitions);Fx.Transitions.extend=function(a){for(var b in a){Fx.Transitions[b]=new Fx.Transition(a[b]);
|
||||
}};Fx.Transitions.extend({Pow:function(b,a){return Math.pow(b,a&&a[0]||6);},Expo:function(a){return Math.pow(2,8*(a-1));},Circ:function(a){return 1-Math.sin(Math.acos(a));
|
||||
},Sine:function(a){return 1-Math.cos(a*Math.PI/2);},Back:function(b,a){a=a&&a[0]||1.618;return Math.pow(b,2)*((a+1)*b-a);},Bounce:function(f){var e;for(var d=0,c=1;
|
||||
1;d+=c,c/=2){if(f>=(7-4*d)/11){e=c*c-Math.pow((11-6*d-11*f)/4,2);break;}}return e;},Elastic:function(b,a){return Math.pow(2,10*--b)*Math.cos(20*b*Math.PI*(a&&a[0]||1)/3);
|
||||
}});["Quad","Cubic","Quart","Quint"].each(function(b,a){Fx.Transitions[b]=new Fx.Transition(function(c){return Math.pow(c,a+2);});});(function(){var d=function(){},a=("onprogress" in new Browser.Request);
|
||||
var c=this.Request=new Class({Implements:[Chain,Events,Options],options:{url:"",data:"",headers:{"X-Requested-With":"XMLHttpRequest",Accept:"text/javascript, text/html, application/xml, text/xml, */*"},async:true,format:false,method:"post",link:"ignore",isSuccess:null,emulation:true,urlEncoded:true,encoding:"utf-8",evalScripts:false,evalResponse:false,timeout:0,noCache:false},initialize:function(e){this.xhr=new Browser.Request();
|
||||
this.setOptions(e);this.headers=this.options.headers;},onStateChange:function(){var e=this.xhr;if(e.readyState!=4||!this.running){return;}this.running=false;
|
||||
this.status=0;Function.attempt(function(){var f=e.status;this.status=(f==1223)?204:f;}.bind(this));e.onreadystatechange=d;if(a){e.onprogress=e.onloadstart=d;
|
||||
}clearTimeout(this.timer);this.response={text:this.xhr.responseText||"",xml:this.xhr.responseXML};if(this.options.isSuccess.call(this,this.status)){this.success(this.response.text,this.response.xml);
|
||||
}else{this.failure();}},isSuccess:function(){var e=this.status;return(e>=200&&e<300);},isRunning:function(){return !!this.running;},processScripts:function(e){if(this.options.evalResponse||(/(ecma|java)script/).test(this.getHeader("Content-type"))){return Browser.exec(e);
|
||||
}return e.stripScripts(this.options.evalScripts);},success:function(f,e){this.onSuccess(this.processScripts(f),e);},onSuccess:function(){this.fireEvent("complete",arguments).fireEvent("success",arguments).callChain();
|
||||
},failure:function(){this.onFailure();},onFailure:function(){this.fireEvent("complete").fireEvent("failure",this.xhr);},loadstart:function(e){this.fireEvent("loadstart",[e,this.xhr]);
|
||||
},progress:function(e){this.fireEvent("progress",[e,this.xhr]);},timeout:function(){this.fireEvent("timeout",this.xhr);},setHeader:function(e,f){this.headers[e]=f;
|
||||
return this;},getHeader:function(e){return Function.attempt(function(){return this.xhr.getResponseHeader(e);}.bind(this));},check:function(){if(!this.running){return true;
|
||||
}switch(this.options.link){case"cancel":this.cancel();return true;case"chain":this.chain(this.caller.pass(arguments,this));return false;}return false;},send:function(o){if(!this.check(o)){return this;
|
||||
}this.options.isSuccess=this.options.isSuccess||this.isSuccess;this.running=true;var l=typeOf(o);if(l=="string"||l=="element"){o={data:o};}var h=this.options;
|
||||
o=Object.append({data:h.data,url:h.url,method:h.method},o);var j=o.data,f=String(o.url),e=o.method.toLowerCase();switch(typeOf(j)){case"element":j=document.id(j).toQueryString();
|
||||
break;case"object":case"hash":j=Object.toQueryString(j);}if(this.options.format){var m="format="+this.options.format;j=(j)?m+"&"+j:m;}if(this.options.emulation&&!["get","post"].contains(e)){var k="_method="+e;
|
||||
j=(j)?k+"&"+j:k;e="post";}if(this.options.urlEncoded&&["post","put"].contains(e)){var g=(this.options.encoding)?"; charset="+this.options.encoding:"";this.headers["Content-type"]="application/x-www-form-urlencoded"+g;
|
||||
}if(!f){f=document.location.pathname;}var i=f.lastIndexOf("/");if(i>-1&&(i=f.indexOf("#"))>-1){f=f.substr(0,i);}if(this.options.noCache){f+=(f.contains("?")?"&":"?")+String.uniqueID();
|
||||
}if(j&&e=="get"){f+=(f.contains("?")?"&":"?")+j;j=null;}var n=this.xhr;if(a){n.onloadstart=this.loadstart.bind(this);n.onprogress=this.progress.bind(this);
|
||||
}n.open(e.toUpperCase(),f,this.options.async,this.options.user,this.options.password);if(this.options.user&&"withCredentials" in n){n.withCredentials=true;
|
||||
}n.onreadystatechange=this.onStateChange.bind(this);Object.each(this.headers,function(q,p){try{n.setRequestHeader(p,q);}catch(r){this.fireEvent("exception",[p,q]);
|
||||
}},this);this.fireEvent("request");n.send(j);if(!this.options.async){this.onStateChange();}if(this.options.timeout){this.timer=this.timeout.delay(this.options.timeout,this);
|
||||
}return this;},cancel:function(){if(!this.running){return this;}this.running=false;var e=this.xhr;e.abort();clearTimeout(this.timer);e.onreadystatechange=d;
|
||||
if(a){e.onprogress=e.onloadstart=d;}this.xhr=new Browser.Request();this.fireEvent("cancel");return this;}});var b={};["get","post","put","delete","GET","POST","PUT","DELETE"].each(function(e){b[e]=function(g){var f={method:e};
|
||||
if(g!=null){f.data=g;}return this.send(f);};});c.implement(b);Element.Properties.send={set:function(e){var f=this.get("send").cancel();f.setOptions(e);
|
||||
return this;},get:function(){var e=this.retrieve("send");if(!e){e=new c({data:this,link:"cancel",method:this.get("method")||"post",url:this.get("action")});
|
||||
this.store("send",e);}return e;}};Element.implement({send:function(e){var f=this.get("send");f.send({data:this,url:e||f.options.url});return this;}});})();
|
||||
Request.HTML=new Class({Extends:Request,options:{update:false,append:false,evalScripts:true,filter:false,headers:{Accept:"text/html, application/xml, text/xml, */*"}},success:function(e){var d=this.options,b=this.response;
|
||||
b.html=e.stripScripts(function(f){b.javascript=f;});var c=b.html.match(/<body[^>]*>([\s\S]*?)<\/body>/i);if(c){b.html=c[1];}var a=new Element("div").set("html",b.html);
|
||||
b.tree=a.childNodes;b.elements=a.getElements("*");if(d.filter){b.tree=b.elements.filter(d.filter);}if(d.update){document.id(d.update).empty().set("html",b.html);
|
||||
}else{if(d.append){document.id(d.append).adopt(a.getChildren());}}if(d.evalScripts){Browser.exec(b.javascript);}this.onSuccess(b.tree,b.elements,b.html,b.javascript);
|
||||
}});Element.Properties.load={set:function(a){var b=this.get("load").cancel();b.setOptions(a);return this;},get:function(){var a=this.retrieve("load");if(!a){a=new Request.HTML({data:this,link:"cancel",update:this,method:"get"});
|
||||
this.store("load",a);}return a;}};Element.implement({load:function(){this.get("load").send(Array.link(arguments,{data:Type.isObject,url:Type.isString}));
|
||||
return this;}});if(typeof JSON=="undefined"){this.JSON={};}JSON=new Hash({stringify:JSON.stringify,parse:JSON.parse});(function(){var special={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"};
|
||||
var escape=function(chr){return special[chr]||"\\u"+("0000"+chr.charCodeAt(0).toString(16)).slice(-4);};JSON.validate=function(string){string=string.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"");
|
||||
return(/^[\],:{}\s]*$/).test(string);};JSON.encode=JSON.stringify?function(obj){return JSON.stringify(obj);}:function(obj){if(obj&&obj.toJSON){obj=obj.toJSON();
|
||||
}switch(typeOf(obj)){case"string":return'"'+obj.replace(/[\x00-\x1f\\"]/g,escape)+'"';case"array":return"["+obj.map(JSON.encode).clean()+"]";case"object":case"hash":var string=[];
|
||||
Object.each(obj,function(value,key){var json=JSON.encode(value);if(json){string.push(JSON.encode(key)+":"+json);}});return"{"+string+"}";case"number":case"boolean":return""+obj;
|
||||
case"null":return"null";}return null;};JSON.decode=function(string,secure){if(!string||typeOf(string)!="string"){return null;}if(secure||JSON.secure){if(JSON.parse){return JSON.parse(string);
|
||||
}if(!JSON.validate(string)){throw new Error("JSON could not decode the input; security is enabled and the value is not secure.");}}return eval("("+string+")");
|
||||
};}).call(this);Request.JSON=new Class({Extends:Request,options:{secure:true},initialize:function(a){this.parent(a);Object.append(this.headers,{Accept:"application/json","X-Request":"JSON"});
|
||||
},success:function(c){var b;try{b=this.response.json=JSON.decode(c,this.options.secure);}catch(a){this.fireEvent("error",[c,a]);return;}if(b==null){this.onFailure();
|
||||
}else{this.onSuccess(b,c);}}});var Cookie=new Class({Implements:Options,options:{path:"/",domain:false,duration:false,secure:false,document:document,encode:true},initialize:function(b,a){this.key=b;
|
||||
this.setOptions(a);},write:function(b){if(this.options.encode){b=encodeURIComponent(b);}if(this.options.domain){b+="; domain="+this.options.domain;}if(this.options.path){b+="; path="+this.options.path;
|
||||
}if(this.options.duration){var a=new Date();a.setTime(a.getTime()+this.options.duration*24*60*60*1000);b+="; expires="+a.toGMTString();}if(this.options.secure){b+="; secure";
|
||||
}this.options.document.cookie=this.key+"="+b;return this;},read:function(){var a=this.options.document.cookie.match("(?:^|;)\\s*"+this.key.escapeRegExp()+"=([^;]*)");
|
||||
return(a)?decodeURIComponent(a[1]):null;},dispose:function(){new Cookie(this.key,Object.merge({},this.options,{duration:-1})).write("");return this;}});
|
||||
Cookie.write=function(b,c,a){return new Cookie(b,a).write(c);};Cookie.read=function(a){return new Cookie(a).read();};Cookie.dispose=function(b,a){return new Cookie(b,a).dispose();
|
||||
};(function(j,l){var m,g,f=[],c,b,n=true;try{n=j.frameElement!=null;}catch(i){}var h=function(){clearTimeout(b);if(m){return;}Browser.loaded=m=true;l.removeListener("DOMContentLoaded",h).removeListener("readystatechange",a);
|
||||
l.fireEvent("domready");j.fireEvent("domready");};var a=function(){for(var e=f.length;e--;){if(f[e]()){h();return true;}}return false;};var k=function(){clearTimeout(b);
|
||||
if(!a()){b=setTimeout(k,10);}};l.addListener("DOMContentLoaded",h);var d=l.createElement("div");if(d.doScroll&&!n){f.push(function(){try{d.doScroll();return true;
|
||||
}catch(o){}return false;});c=true;}if(l.readyState){f.push(function(){var e=l.readyState;return(e=="loaded"||e=="complete");});}if("onreadystatechange" in l){l.addListener("readystatechange",a);
|
||||
}else{c=true;}if(c){k();}Element.Events.domready={onAdd:function(e){if(m){e.call(this);}}};Element.Events.load={base:"load",onAdd:function(e){if(g&&this==j){e.call(this);
|
||||
}},condition:function(){if(this==j){h();delete Element.Events.load;}return true;}};j.addEvent("load",function(){g=true;});})(window,document);(function(){var Swiff=this.Swiff=new Class({Implements:Options,options:{id:null,height:1,width:1,container:null,properties:{},params:{quality:"high",allowScriptAccess:"always",wMode:"window",swLiveConnect:true},callBacks:{},vars:{}},toElement:function(){return this.object;
|
||||
},initialize:function(path,options){this.instance="Swiff_"+String.uniqueID();this.setOptions(options);options=this.options;var id=this.id=options.id||this.instance;
|
||||
var container=document.id(options.container);Swiff.CallBacks[this.instance]={};var params=options.params,vars=options.vars,callBacks=options.callBacks;
|
||||
var properties=Object.append({height:options.height,width:options.width},options.properties);var self=this;for(var callBack in callBacks){Swiff.CallBacks[this.instance][callBack]=(function(option){return function(){return option.apply(self.object,arguments);
|
||||
};})(callBacks[callBack]);vars[callBack]="Swiff.CallBacks."+this.instance+"."+callBack;}params.flashVars=Object.toQueryString(vars);if(Browser.ie){properties.classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
|
||||
params.movie=path;}else{properties.type="application/x-shockwave-flash";}properties.data=path;var build='<object id="'+id+'"';for(var property in properties){build+=" "+property+'="'+properties[property]+'"';
|
||||
}build+=">";for(var param in params){if(params[param]){build+='<param name="'+param+'" value="'+params[param]+'" />';}}build+="</object>";this.object=((container)?container.empty():new Element("div")).set("html",build).firstChild;
|
||||
},replaces:function(element){element=document.id(element,true);element.parentNode.replaceChild(this.toElement(),element);return this;},inject:function(element){document.id(element,true).appendChild(this.toElement());
|
||||
return this;},remote:function(){return Swiff.remote.apply(Swiff,[this.toElement()].append(arguments));}});Swiff.CallBacks={};Swiff.remote=function(obj,fn){var rs=obj.CallFunction('<invoke name="'+fn+'" returntype="javascript">'+__flash__argumentsToXML(arguments,2)+"</invoke>");
|
||||
return eval(rs);};}).call(this);
|
||||
@@ -0,0 +1,102 @@
|
||||
(function($) {
|
||||
var Notify = function(element, options) {
|
||||
this.$element = $(element);
|
||||
this.options = $.extend({}, $.fn.notify.defaults, options);
|
||||
};
|
||||
|
||||
Notify.prototype = {
|
||||
constructor: Notify,
|
||||
|
||||
build_box: function(bid) {
|
||||
if (bid == undefined) {
|
||||
bid = "notifybox";
|
||||
}
|
||||
var div = $("<div class='alert' />", {
|
||||
id: bid,
|
||||
click: $.proxy(this.destroy_box, this)
|
||||
});
|
||||
|
||||
return div;
|
||||
},
|
||||
|
||||
destroy_box: function(evt) {
|
||||
evt.preventDefault();
|
||||
this.$element.hide().remove();
|
||||
},
|
||||
|
||||
set_position: function(box) {
|
||||
box.css({
|
||||
position: "absolute",
|
||||
top: this.options.top_position,
|
||||
left: "50%",
|
||||
marginLeft: '-' + (box.outerWidth() / 2) + 'px'
|
||||
});
|
||||
},
|
||||
|
||||
set_message: function(box, value) {
|
||||
var content = '<a class="close" data-dismiss="alert">×</a>' + value;
|
||||
|
||||
box.html(content);
|
||||
},
|
||||
|
||||
show: function(klass, message, timer) {
|
||||
var nbox = this.build_box();
|
||||
|
||||
if (klass != "normal") {
|
||||
nbox.addClass("alert-" + klass);
|
||||
}
|
||||
this.set_message(nbox, message);
|
||||
this.set_position(nbox);
|
||||
this.$element.append(nbox);
|
||||
if (timer != undefined) {
|
||||
window.setTimeout(function() {
|
||||
$('.alert').alert('close');
|
||||
}, timer);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
success: function(message, timer) {
|
||||
return this.show.apply(this, ["success", message, timer]);
|
||||
},
|
||||
|
||||
info: function(message, timer) {
|
||||
return this.show.apply(this, ["info", message, timer]);
|
||||
},
|
||||
|
||||
error: function(message, timer) {
|
||||
return this.show.apply(this, ["error", message, timer]);
|
||||
},
|
||||
|
||||
warning: function(message, timer) {
|
||||
return this.show.apply(this, ["warning", message, timer]);
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.notify = function(method) {
|
||||
var args = arguments;
|
||||
|
||||
return this.each(function() {
|
||||
var $this = $(this),
|
||||
data = $this.data('notify'),
|
||||
options = typeof method === "object" && method;
|
||||
|
||||
if (!data) {
|
||||
$this.data('notify', new Notify(this, options));
|
||||
data = $this.data('notify');
|
||||
}
|
||||
if (typeof method === "string") {
|
||||
data[method].apply(data, Array.prototype.slice.call(args, 1));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.notify.defaults = {
|
||||
top_position: 50
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,67 +0,0 @@
|
||||
window.addEvent('domready', function() {
|
||||
var tip = new Tips($$(".Tips"));
|
||||
|
||||
var current_role = "";
|
||||
var current_sizes = "";
|
||||
var accordion = new Accordion('h3.atStart', 'div.atStart', {
|
||||
opacity: true,
|
||||
onActive: function(toggler, element){
|
||||
toggler.setStyle('color', '#ff3300');
|
||||
current_role = element.get("id");
|
||||
current_sizes = element.get("rel");
|
||||
},
|
||||
|
||||
onBackground: function(toggler, element) {
|
||||
toggler.setStyle('color', '#222');
|
||||
}
|
||||
}, $('accordion'));
|
||||
|
||||
SqueezeBox.assign($("content").getElements('a[class=boxed]'), {
|
||||
parse: 'rel'
|
||||
});
|
||||
|
||||
$$("a[name=addperm]").addEvent("click", function(evt) {
|
||||
evt.stop();
|
||||
var sizes = current_sizes.split(" ");
|
||||
var addperm_url = evt.target.get("href") + "?role=" + current_role;
|
||||
|
||||
SqueezeBox.open(addperm_url, {
|
||||
size: {x: parseInt(sizes[0]), y: parseInt(sizes[1])},
|
||||
handler: 'iframe'
|
||||
});
|
||||
});
|
||||
|
||||
$$("a[name=delperms]").addEvent("click", function(evt) {
|
||||
evt.stop();
|
||||
var selection = $(current_role).getElements("input[id=selection]:checked");
|
||||
if (selection.length == 0) {
|
||||
return;
|
||||
}
|
||||
if (!confirm(gettext("Remove this selection?"))) {
|
||||
return;
|
||||
}
|
||||
var sr_selection = "";
|
||||
selection.each(function(item) {
|
||||
if (sr_selection != "") {
|
||||
sr_selection += ",";
|
||||
}
|
||||
sr_selection += item.get("value");
|
||||
});
|
||||
new Request.JSON({
|
||||
url : evt.target.get("href"),
|
||||
onSuccess: function(response) {
|
||||
if (response.status == "ok") {
|
||||
$(current_role).set("html", response.content);
|
||||
infobox.info(response.message);
|
||||
} else {
|
||||
infobox.error(response.message);
|
||||
}
|
||||
infobox.hide(2);
|
||||
|
||||
}
|
||||
}).send({
|
||||
method: "get",
|
||||
data: "role=" + current_role + "&selection=" + sr_selection
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,15 +0,0 @@
|
||||
window.addEvent('domready', function() {
|
||||
var tip = new Tips($$(".Tips"));
|
||||
var accordion = new Accordion('h3.atStart', 'div.atStart', {
|
||||
opacity: true,
|
||||
onActive: function(toggler, element){
|
||||
toggler.setStyle('color', '#ff3300');
|
||||
},
|
||||
|
||||
onBackground: function(toggler, element){
|
||||
toggler.setStyle('color', '#222');
|
||||
}
|
||||
}, $('accordion'));
|
||||
|
||||
saveparams("uparams_form", gettext("Preferences saved"));
|
||||
});
|
||||
@@ -1,15 +0,0 @@
|
||||
window.addEvent('domready', function() {
|
||||
var tip = new Tips($$(".Tips"));
|
||||
|
||||
var accordion = new Accordion('h3.atStart', 'div.atStart', {
|
||||
opacity: true,
|
||||
onActive: function(toggler, element){
|
||||
toggler.setStyle('color', '#ff3300');
|
||||
},
|
||||
|
||||
onBackground: function(toggler, element){
|
||||
toggler.setStyle('color', '#222');
|
||||
}
|
||||
}, $('accordion'));
|
||||
saveparams("params_form", gettext("Parameters saved"));
|
||||
});
|
||||
@@ -2,6 +2,43 @@
|
||||
* Collection of functions that are accessible to every page.
|
||||
*/
|
||||
|
||||
function modalbox(e, css) {
|
||||
e.preventDefault();
|
||||
var href = $(this).attr('href');
|
||||
var modalcb = $(this).attr('modalcb');
|
||||
|
||||
if (href.indexOf('#') == 0) {
|
||||
$(href).modal('open');
|
||||
return;
|
||||
}
|
||||
$.get(href, function(data) {
|
||||
if (typeof data === "object") {
|
||||
if (data.status == "ko" && data.respmsg) {
|
||||
$("body").notify("error", data.respmsg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
var $div = $('<div id="modalbox" class="modal fade" >' + data + '</div>')
|
||||
.modal()
|
||||
.one('shown', function() {
|
||||
if (modalcb != undefined) {
|
||||
eval(modalcb + '()');
|
||||
}
|
||||
})
|
||||
.on('hidden', function() {
|
||||
$("#modalbox").remove();
|
||||
});
|
||||
|
||||
if (css != undefined) {
|
||||
$div.css(css);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function modalbox_autowidth(e) {
|
||||
modalbox.apply(this, [e, {width: 'auto'}]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple function that redirect ajax requests to the login page if
|
||||
* the status code received with a response is equal to 278.
|
||||
@@ -16,20 +53,90 @@ function ajax_login_redirect() {
|
||||
this.xhr.getResponseHeader("Location").replace(/\?.*$/, params);
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple shorcut do create a bootstrap alert box (error mode)
|
||||
*/
|
||||
function build_error_alert(msg) {
|
||||
return $('<div class="alert alert-error"> \
|
||||
<a class="close" data-dismiss="alert" href="#">×</a>' + msg + "</div>");
|
||||
}
|
||||
|
||||
/*
|
||||
* '.keys()' method support for old browsers :p
|
||||
*/
|
||||
if (!Object.keys) {
|
||||
Object.keys = function (obj) {
|
||||
var keys = [],
|
||||
k;
|
||||
for (k in obj) {
|
||||
if (Object.prototype.hasOwnProperty.call(obj, k)) {
|
||||
keys.push(k);
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple function that sends a form using an 'ajax' post request.
|
||||
*
|
||||
* The function is intended to be used in a modal environment.
|
||||
*/
|
||||
function simple_ajax_form_post(e, options) {
|
||||
e.preventDefault();
|
||||
var $form = $("form");
|
||||
var defaults = {reload_on_success: true, reload_mode: 'full'};
|
||||
var opts = $.extend({}, defaults, options);
|
||||
var args = $form.serialize();
|
||||
|
||||
if (options.extradata != undefined) {
|
||||
args += "&" + options.extradata;
|
||||
}
|
||||
|
||||
$.post($form.attr("action"), args, function(data) {
|
||||
if (data.status == "ok") {
|
||||
if (opts.success_cb != undefined) {
|
||||
opts.success_cb(data);
|
||||
}
|
||||
$("#modalbox").modal('hide');
|
||||
if (opts.reload_on_success) {
|
||||
if (opts.reload_mode == 'full') {
|
||||
window.location.reload();
|
||||
} else {
|
||||
history.update(true);
|
||||
}
|
||||
}
|
||||
if (data.respmsg) {
|
||||
$("body").notify('success', data.respmsg, 2000);
|
||||
}
|
||||
} else {
|
||||
if (data.content != "") {
|
||||
$('.modal').html(data.content);
|
||||
}
|
||||
if (data.respmsg) {
|
||||
$('.modal-body').prepend(build_error_alert(data.respmsg));
|
||||
}
|
||||
if (opts.error_cb != undefined) {
|
||||
opts.error_cb();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple wrapper around Request.JSON. We just ensure that
|
||||
* redirections are correctly catched. (on session timeout for
|
||||
* example)
|
||||
*/
|
||||
Request.JSON.mdb = new Class({
|
||||
Extends: Request.JSON,
|
||||
// Request.JSON.mdb = new Class({
|
||||
// Extends: Request.JSON,
|
||||
|
||||
options: {
|
||||
format: "json",
|
||||
onComplete: ajax_login_redirect,
|
||||
onFailure: function(xhr) {
|
||||
$(document.body).setStyle("overflow", "auto");
|
||||
$(document.body).set("html", xhr.responseText);
|
||||
}
|
||||
}
|
||||
});
|
||||
// options: {
|
||||
// format: "json",
|
||||
// onComplete: ajax_login_redirect,
|
||||
// onFailure: function(xhr) {
|
||||
// $(document.body).setStyle("overflow", "auto");
|
||||
// $(document.body).set("html", xhr.responseText);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
@@ -1,59 +0,0 @@
|
||||
{% extends "layout_simple.html" %}
|
||||
{% load i18n %}
|
||||
{% block html_head %}
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/Autocompleter.css" />
|
||||
<script src="{{ MEDIA_URL }}js/form.js" type="text/javascript"></script>
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/Observer.js"></script>
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/Autocompleter.js"></script>
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/Autocompleter.Request.js"></script>
|
||||
<script type="text/javascript">
|
||||
window.addEvent("domready", function() {
|
||||
var form = new Form({resptarget: "formcontainer"});
|
||||
|
||||
$("createfrom").addEvent("change", function(evt) {
|
||||
var url = "";
|
||||
var styles = null;
|
||||
var from = this.get("value");
|
||||
|
||||
evt.stop();
|
||||
if (from == "create") {
|
||||
url = "{% url admin.views.create_domain_admin %}";
|
||||
styles = {height: 380};
|
||||
} else {
|
||||
url = "{% url admin.views.domain_admin_promotion %}";
|
||||
styles = {height: 200};
|
||||
}
|
||||
var size = {y: styles.height};
|
||||
new Request.JSON.mdb({
|
||||
url: url,
|
||||
onSuccess: function(response) {
|
||||
$("formcontainer").set("html", response.content);
|
||||
form.init_help_messages();
|
||||
if (from == "promote") {
|
||||
new Autocompleter.Request.JSON("id_name",
|
||||
"{% url admin.views.search_account %}", {
|
||||
postVar: "search",
|
||||
minLength: 3,
|
||||
onComplete: ajax_login_redirect
|
||||
});
|
||||
}
|
||||
$(parent.document).getElement('iframe').setStyles(styles);
|
||||
parent.SqueezeBox.resize(size);
|
||||
}
|
||||
}).get();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="title"><h1>{{ title }}</h1></div>
|
||||
{% if error %}<div class="error">{{ error }}</div>{% endif %}
|
||||
<div class="center">
|
||||
<select id="createfrom">
|
||||
<option value="none">{% trans "Choose" %}</option>
|
||||
<option value="create">{% trans "Create a new account" %}</option>
|
||||
<option value="promote">{% trans "Promote an existing account" %}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div id="formcontainer"></div>
|
||||
{% endblock %}
|
||||
@@ -1,25 +0,0 @@
|
||||
{% extends "layout_simple.html" %}
|
||||
{% load i18n %}
|
||||
{% block html_head %}
|
||||
<script src="{{ MEDIA_URL }}js/form.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
window.addEvent("domready", function() {
|
||||
var form = new Form();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="title"><h1>{{ title }}</h1></div>
|
||||
{% if error %}<div class="error">{{ error }}</div>{% endif %}
|
||||
{% if not addurl %}
|
||||
{% url admin.views.add_permission as addurl %}
|
||||
{% endif %}
|
||||
<form action="{{ addurl }}" method="POST" id="permform" name="permform">
|
||||
<input type="hidden" name="role" id="role" value="{{ role }}" />
|
||||
{% include "common/genericform.html" %}
|
||||
<div class="spacer"></div>
|
||||
<div class="lastrow" align="center">
|
||||
<input type="submit" name="submit" value="{{ submit_label }}" />
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -1,22 +0,0 @@
|
||||
{% extends "layout_simple.html" %}
|
||||
{% block html_head %}
|
||||
<script src="{{ MEDIA_URL }}js/form.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
window.addEvent("domready", function() {
|
||||
var form = new Form();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="title"><h1>{{ title }}</h1></div>
|
||||
<div class="error">{% if error %}{{ error }}{% endif %}</div>
|
||||
<form action="{{ action }}" enctype="{{ enctype }}"
|
||||
method="POST" id="{{ formid }}" name="{{ formid }}">
|
||||
{% include "common/genericform.html" %}
|
||||
{% block extrafields %}{% endblock %}
|
||||
<div class="spacer"></div>
|
||||
<div class="lastrow" align="center">
|
||||
<input type="submit" name="submit" value="{{ submit_label }}" />
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -1,9 +0,0 @@
|
||||
{% load i18n %}
|
||||
<form action="{% url admin.views.create_domain_admin %}" method="POST"
|
||||
id="permform" name="permform">
|
||||
{% include "common/genericform.html" %}
|
||||
<div class="spacer"></div>
|
||||
<div class="lastrow" align="center">
|
||||
<input type="submit" name="submit" value="{% trans 'Create' %}" />
|
||||
</div>
|
||||
</form>
|
||||
@@ -0,0 +1,7 @@
|
||||
{% extends "common/generic_modal_form.html" %}
|
||||
{% load libextras %}
|
||||
{% block formbody %}
|
||||
{% render_field form.email %}
|
||||
{% render_fields_group form "recipients" %}
|
||||
{% render_field form.enabled %}
|
||||
{% endblock %}
|
||||
@@ -1,10 +0,0 @@
|
||||
{% load i18n %}
|
||||
<form action="{% url admin.views.domain_admin_promotion %}" method="POST"
|
||||
id="permform" name="permform">
|
||||
<input type="hidden" name="role" id="role" value="{{ role }}" />
|
||||
{% include "common/genericform.html" %}
|
||||
<div class="spacer"></div>
|
||||
<div class="lastrow" align="center">
|
||||
<input type="submit" name="submit" value="{% trans 'Promote' %}" />
|
||||
</div>
|
||||
</form>
|
||||
@@ -0,0 +1,8 @@
|
||||
{% extends "common/generic_modal_form.html" %}
|
||||
{% load libextras %}
|
||||
{% block formbody %}
|
||||
{% render_field form.name %}
|
||||
{% render_field form.quota %}
|
||||
{% render_fields_group form "aliases" %}
|
||||
{% render_field form.enabled %}
|
||||
{% endblock %}
|
||||
@@ -1,11 +1,17 @@
|
||||
{% extends "admin/listing.html" %}
|
||||
{% load i18n admin_extras libextras %}
|
||||
{% block html_head %}
|
||||
{{ block.super }}
|
||||
<script type="text/javascript">
|
||||
window.addEvent('domready', function() {
|
||||
{% url admin.views.mailboxes as view_url %}
|
||||
bindRows("{{ view_url }}", "{{ current_page }}");
|
||||
{{ block.super }}
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$("a[name=deldomain]").confirm({
|
||||
question: gettext("Delete this domain?"),
|
||||
checkboxes: {keepdir: gettext("Do not delete domain directory")}
|
||||
});
|
||||
|
||||
{% url admin.views.mailboxes as view_url %}
|
||||
//bindRows("{{ view_url }}", "{{ current_page }}");
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block leftcol %}<div class="well sidebar-nav">{% domains_menu "domains" user %}</div>{% endblock %}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
{% extends "nlayout.html" %}
|
||||
{% load i18n admin_extras libextras %}
|
||||
{% block html_head %}
|
||||
<script src="{{ MEDIA_URL }}js/confirmation.js" type="text/javascript"></script>
|
||||
<script src="{{ MEDIA_URL }}js/domains.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
window.addEvent("domready", function() {
|
||||
new Domains("{% url index %}"{% if deloptions %}, { {% join deloptions %} } {% endif %});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block middletitle %}
|
||||
{% block pagetitle %}{% endblock %}{% if domain and domain != "global" %} ({% trans "for" %} {{ domain.name }}){% endif %}
|
||||
{% endblock %}
|
||||
{% block menu %}{% domains_menu selection user domid %}{% endblock %}
|
||||
{% block content %}
|
||||
{% if messages %}
|
||||
{% display_messages messages %}
|
||||
{% endif %}
|
||||
<div id="subcontent">
|
||||
{% block subcontent %}{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -1,13 +1,7 @@
|
||||
{% extends "admin/settings_header.html" %}
|
||||
{% block menu %}
|
||||
{% load admin_extras %}
|
||||
{% settings_menu "extensions" user %}
|
||||
{% endblock %}
|
||||
{% block setcontent %}
|
||||
{% load i18n %}
|
||||
{% block apparea %}
|
||||
<form method="POST" action="{% url admin.views.saveextensions %}">
|
||||
{{ extensions|safe }}
|
||||
<br />
|
||||
<input type="submit" name="apply" value="{% trans "Apply" %}" />
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{% extends "twocols.html" %}
|
||||
{% block html_head %}
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/admin.js"></script>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,34 @@
|
||||
{% extends "admin/listing.html" %}
|
||||
{% load admin_extras libextras %}
|
||||
{% block html_head %}
|
||||
{{ block.super }}
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/creation_wizard.js"></script>
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/autocompleter.js"></script>
|
||||
<script type="text/javascript">
|
||||
function get_domains_list(container) {
|
||||
$.getJSON("{% url modoboa.admin.views.domains_list %}", function(data) {
|
||||
container.value = data;
|
||||
});
|
||||
}
|
||||
|
||||
function get_account_list(container) {
|
||||
$.getJSON("{% url modoboa.admin.views.accounts_list %}", function(data) {
|
||||
container.value = data;
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$("a[name=delaccount]").confirm({
|
||||
question: gettext("Delete this account?"),
|
||||
checkboxes: {keepdir: gettext("Do not delete mailbox directory")}
|
||||
});
|
||||
$("a[name=deldlist]").confirm({
|
||||
question: gettext("Delete this list?")
|
||||
});
|
||||
$("#pagination_bar").find(".disabled").click(function(e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block leftcol %}<div class="well sidebar-nav">{% identities_menu user %}</div>{% endblock %}
|
||||