Fixed comments (kinda)

This commit is contained in:
Fergal Moran
2013-12-16 22:31:35 +00:00
parent 234c36be5c
commit cbb88e0b3a
59 changed files with 18643 additions and 12768 deletions

View File

@@ -52,7 +52,7 @@ CACHE_ROOT = localsettings.CACHE_ROOT
STATIC_URL = localsettings.STATIC_URL if hasattr(localsettings, 'STATIC_URL') else '/static/'
if DEBUG:
MEDIA_URL = '/media/'
MEDIA_URL = localsettings.MEDIA_URL if hasattr(localsettings, 'MEDIA_URL') else '/media/'
else:
MEDIA_URL = localsettings.MEDIA_URL if hasattr(localsettings, 'MEDIA_URL') else '/static/'
@@ -222,7 +222,9 @@ PIPELINE_CSS = {
INTERNAL_IPS = ('127.0.0.1', '86.44.166.21', '192.168.1.111')
GOOGLE_ANALYTICS_CODE = localsettings.GOOGLE_ANALYTICS_CODE
TASTYPIE_DATETIME_FORMATTING = 'rfc-2822'
TASTYPIE_ALLOW_MISSING_SLASH = True
SENDFILE_BACKEND = localsettings.SENDFILE_BACKEND
SENDFILE_ROOT = os.path.join(MEDIA_ROOT, 'mixes')

View File

@@ -2,9 +2,9 @@ from tastypie import fields
from tastypie.authentication import Authentication
from tastypie.authorization import Authorization
from tastypie.exceptions import ImmediateHttpResponse
from tastypie.http import HttpForbidden, HttpBadRequest
from tastypie.http import HttpBadRequest, HttpMethodNotAllowed, HttpUnauthorized, HttpApplicationError, HttpNotImplemented
from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource
from spa.models import Mix
from spa.models import Mix, UserProfile
from spa.models.comment import Comment
@@ -21,32 +21,34 @@ class CommentResource(BackboneCompatibleResource):
authentication = Authentication()
always_return_data = True
def dehydrate(self, bundle):
if bundle.obj.user is not None:
bundle.data['avatar_image'] = bundle.obj.user.get_profile().get_avatar_image()
bundle.data['user_url'] = bundle.obj.user.get_profile().get_absolute_url()
bundle.data['user_name'] = bundle.obj.user.get_profile().get_nice_name()
else:
bundle.data['avatar_image'] = UserProfile.get_default_avatar_image()
bundle.data['user_url'] = "/"
bundle.data['user_name'] = "Anonymouse"
return bundle
def obj_create(self, bundle, **kwargs):
bundle.data['user'] = bundle.request.user
del bundle.data['avatar_image']
del bundle.data['user_url']
del bundle.data['user_name']
try:
if 'mix_id' in bundle.data:
mix = Mix.objects.get(pk=bundle.data['mix_id'])
mix = Mix.objects.get_by_id_or_slug(bundle.data['mix_id'])
if mix is not None:
return super(CommentResource, self).obj_create(bundle, user=bundle.request.user, mix=mix)
if bundle.request.user.is_authenticated():
return super(CommentResource, self).obj_create(bundle, user=bundle.request.user or None, mix=mix)
else:
return super(CommentResource, self).obj_create(bundle, mix=mix)
else:
return HttpBadRequest("Unable to find mix for supplied mix_id (candidate fields are slug & id).")
return HttpBadRequest("Missing mix_id field.")
except ImmediateHttpResponse, e:
self.logger.error("Error creating comment (%s)" % e.message)
return HttpUnauthorized("Git tae fuck!")
except Exception, e:
self.logger.error("Error creating comment (%s)" % e.message)
pass
raise ImmediateHttpResponse(
HttpBadRequest("Unable to hydrate comment from supplied data.")
)
def obj_update(self, bundle, skip_errors=False, **kwargs):
del bundle.data['avatar_image']
del bundle.data['user_url']
del bundle.data['user_name']
return super(CommentResource, self).obj_update(bundle, bundle.request)
def dehydrate(self, bundle):
bundle.data['avatar_image'] = bundle.obj.user.get_profile().get_small_profile_image()
bundle.data['user_url'] = bundle.obj.user.get_absolute_url()
bundle.data['user_name'] = bundle.obj.user.get_profile().get_nice_name() or bundle.obj.user.get_profile().display_name
return bundle
return HttpApplicationError("Unable to hydrate comment from supplied data.")

View File

@@ -164,9 +164,6 @@ class MixResource(BackboneCompatibleResource):
return semi_filtered
def hydrate_favourited(self, bundle):
return bundle
def dehydrate_mix_image(self, bundle):
return bundle.obj.get_image_url(size="160x110")

View File

@@ -0,0 +1,233 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Changing field 'Comment.user'
db.alter_column(u'spa_comment', 'user_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True))
def backwards(self, orm):
# Changing field 'Comment.user'
db.alter_column(u'spa_comment', 'user_id', self.gf('django.db.models.fields.related.ForeignKey')(default=-1, to=orm['auth.User']))
models = {
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'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': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
u'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'}),
u'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'})
},
'spa._lookup': {
'Meta': {'object_name': '_Lookup'},
'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'spa.activity': {
'Meta': {'object_name': 'Activity'},
'date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']", 'null': 'True', 'blank': 'True'})
},
'spa.activitydownload': {
'Meta': {'object_name': 'ActivityDownload', '_ormbases': ['spa.Activity']},
u'activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa.Activity']", 'unique': 'True', 'primary_key': 'True'}),
'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_downloads'", 'to': "orm['spa.Mix']"})
},
'spa.activityfavourite': {
'Meta': {'object_name': 'ActivityFavourite', '_ormbases': ['spa.Activity']},
u'activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa.Activity']", 'unique': 'True', 'primary_key': 'True'}),
'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_favourites'", 'to': "orm['spa.Mix']"})
},
'spa.activityfollow': {
'Meta': {'object_name': 'ActivityFollow', '_ormbases': ['spa.Activity']},
u'activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa.Activity']", 'unique': 'True', 'primary_key': 'True'}),
'to_user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_follow'", 'to': "orm['spa.UserProfile']"})
},
'spa.activitylike': {
'Meta': {'object_name': 'ActivityLike', '_ormbases': ['spa.Activity']},
u'activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa.Activity']", 'unique': 'True', 'primary_key': 'True'}),
'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_likes'", 'to': "orm['spa.Mix']"})
},
'spa.activityplay': {
'Meta': {'object_name': 'ActivityPlay', '_ormbases': ['spa.Activity']},
u'activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa.Activity']", 'unique': 'True', 'primary_key': 'True'}),
'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_plays'", 'to': "orm['spa.Mix']"})
},
'spa.chatmessage': {
'Meta': {'object_name': 'ChatMessage'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'message': ('django.db.models.fields.TextField', [], {}),
'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'chat_messages'", 'null': 'True', 'to': "orm['spa.UserProfile']"})
},
'spa.comment': {
'Meta': {'object_name': 'Comment'},
'comment': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'mix': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'comments'", 'null': 'True', 'to': "orm['spa.Mix']"}),
'time_index': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'})
},
'spa.event': {
'Meta': {'object_name': 'Event'},
'attendees': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'attendees'", 'symmetrical': 'False', 'to': u"orm['auth.User']"}),
'date_created': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2013, 11, 27, 0, 0)'}),
'event_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2013, 11, 27, 0, 0)'}),
'event_description': ('tinymce.models.HTMLField', [], {}),
'event_recurrence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Recurrence']"}),
'event_time': ('django.db.models.fields.TimeField', [], {'default': 'datetime.datetime(2013, 11, 27, 0, 0)'}),
'event_title': ('django.db.models.fields.CharField', [], {'max_length': '250'}),
'event_venue': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Venue']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'spa.genre': {
'Meta': {'object_name': 'Genre'},
'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'})
},
'spa.label': {
'Meta': {'object_name': 'Label'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'spa.mix': {
'Meta': {'object_name': 'Mix'},
'description': ('django.db.models.fields.TextField', [], {}),
'download_allowed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'duration': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'favourites': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'favourites'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['spa.UserProfile']"}),
'genres': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['spa.Genre']", 'symmetrical': 'False'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_featured': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'likes': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'likes'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['spa.UserProfile']"}),
'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}),
'mix_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '1024', 'blank': 'True'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
'uid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '38', 'blank': 'True'}),
'upload_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2013, 11, 27, 0, 0)'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'mixes'", 'to': "orm['spa.UserProfile']"}),
'waveform_generated': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
},
'spa.notification': {
'Meta': {'object_name': 'Notification'},
'accepted_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'from_user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'notifications'", 'null': 'True', 'to': "orm['spa.UserProfile']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'notification_text': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
'notification_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
'target': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}),
'to_user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'to_notications'", 'to': "orm['spa.UserProfile']"}),
'verb': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'})
},
'spa.purchaselink': {
'Meta': {'object_name': 'PurchaseLink'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'provider': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'track': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'purchase_link'", 'to': "orm['spa.Tracklist']"}),
'url': ('django.db.models.fields.URLField', [], {'max_length': '200'})
},
'spa.recurrence': {
'Meta': {'object_name': 'Recurrence', '_ormbases': ['spa._Lookup']},
u'_lookup_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Lookup']", 'unique': 'True', 'primary_key': 'True'})
},
'spa.release': {
'Meta': {'object_name': 'Release'},
'embed_code': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'release_artist': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'release_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2013, 11, 27, 0, 0)'}),
'release_description': ('django.db.models.fields.TextField', [], {}),
'release_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}),
'release_label': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Label']"}),
'release_title': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"})
},
'spa.releaseaudio': {
'Meta': {'object_name': 'ReleaseAudio'},
'description': ('django.db.models.fields.TextField', [], {}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
'release': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'release_audio'", 'null': 'True', 'to': "orm['spa.Release']"})
},
'spa.tracklist': {
'Meta': {'object_name': 'Tracklist'},
'artist': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'index': ('django.db.models.fields.SmallIntegerField', [], {}),
'label': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tracklist'", 'to': "orm['spa.Mix']"}),
'remixer': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'timeindex': ('django.db.models.fields.TimeField', [], {'null': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
},
'spa.userprofile': {
'Meta': {'object_name': 'UserProfile'},
'activity_sharing': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'activity_sharing_networks': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'avatar_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '1024', 'blank': 'True'}),
'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'social'", 'max_length': '15'}),
'city': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'country': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'}),
'display_name': ('django.db.models.fields.CharField', [], {'max_length': '35', 'blank': 'True'}),
'following': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'followers'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['spa.UserProfile']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'last_known_session': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
'slug': ('django.db.models.fields.SlugField', [], {'default': 'None', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'userprofile'", 'unique': 'True', 'to': u"orm['auth.User']"})
},
'spa.venue': {
'Meta': {'object_name': 'Venue'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
'venue_address': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
'venue_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}),
'venue_name': ('django.db.models.fields.CharField', [], {'max_length': '250'})
}
}
complete_apps = ['spa']

View File

@@ -37,7 +37,7 @@ class Activity(_BaseModel):
notification.from_user = self.user
notification.to_user = self.get_target_user()
notification.notification_text = "%s %s %s" % (
self.user.get_nice_name() or "Anonymous", self.get_verb_past(), self.get_object_name_for_notification())
self.user.get_nice_name() or "Anonymouse", self.get_verb_past(), self.get_object_name_for_notification())
notification.notification_url = self.get_object_url()
notification.verb = self.get_verb_past()

View File

@@ -8,7 +8,7 @@ class Comment(_BaseModel):
class Meta:
app_label = 'spa'
user = models.ForeignKey(User, editable=False)
user = models.ForeignKey(User, editable=False, null=True, blank=True)
mix = models.ForeignKey(Mix, editable=False, null=True, blank=True, related_name='comments')
comment = models.CharField(max_length=1024)
date_created = models.DateTimeField(auto_now=True)

View File

@@ -2,10 +2,13 @@ import os
import rfc822
from datetime import datetime
import urlparse
from logilab.common.registry import ObjectNotFound
from psycopg2.errorcodes import OBJECT_NOT_IN_PREREQUISITE_STATE
from sorl.thumbnail import get_thumbnail
from django.contrib.sites.models import Site
from django.db import models
from core.utils import url
from core.utils.audio import Mp3FileNotFoundException
from core.utils.audio.mp3 import mp3_length, tag_mp3
from core.utils.url import unique_slugify
from spa.models.activity import ActivityDownload, ActivityPlay
@@ -28,11 +31,23 @@ def mix_image_name(instance, filename):
class MixManager(models.Manager):
pass
def get_by_id_or_slug(self, id_or_slug):
"""
Tries to get a mix using the slug first
If this fails then try getting by id
"""
try:
return super(MixManager, self).get(slug=id_or_slug)
except ObjectNotFound:
return super(MixManager, self).get(slug=id_or_slug)
class Mix(_BaseModel):
class Meta:
app_label = 'spa'
objects = MixManager()
title = models.CharField(max_length=150)
description = models.TextField()
upload_date = models.DateTimeField(default=datetime.now())
@@ -64,7 +79,11 @@ class Mix(_BaseModel):
#Check for the unlikely event that the waveform has been generated
if os.path.isfile(self.get_waveform_path()):
self.waveform_generated = True
self.duration = mp3_length(self.get_absolute_path())
try:
self.duration = mp3_length(self.get_absolute_path())
except Mp3FileNotFoundException:
#Not really bothered about this in save as it can be called before we have an mp3
pass
super(Mix, self).save(force_insert, force_update, using, update_fields)
@@ -112,7 +131,6 @@ class Mix(_BaseModel):
def get_waveform_url(self):
if self.waveform_generated and os.path.exists(self.get_waveform_path()):
waveform_root = localsettings.WAVEFORM_URL if hasattr(localsettings,
'WAVEFORM_URL') else "%swaveforms" % settings.MEDIA_URL
ret = "%s/%s.%s" % (waveform_root, self.uid, "png")
@@ -130,7 +148,7 @@ class Mix(_BaseModel):
name, extension = os.path.splitext(self.mix_image.file.name)
return os.path.join(settings.MEDIA_ROOT, 'mix-images', "%s.%s", (self.uid, extension))
def get_image_url(self, size='160x160'):
def get_image_url(self, size='160x160', default=''):
try:
ret = get_thumbnail(self.mix_image, size, crop='center')
return "%s/%s" % (settings.MEDIA_URL, ret.name)

View File

@@ -226,5 +226,5 @@ class UserProfile(_BaseModel):
@classmethod
def get_default_moniker(cls):
return "Anonymous"
return "Anonymouse"

View File

@@ -13,14 +13,14 @@ register = template.Library()
@register.filter
def nice_name(user):
if user == "":
return "Anonymous"
return "Anonymouse"
if user.is_authenticated():
profile = user.get_profile()
if profile is not None:
if profile.display_name <> "":
return profile.display_name
else:
return "Anonymous"
return "Anonymouse"
return user.get_full_name() or user.username

View File

@@ -75,11 +75,6 @@ define ['backbone', 'marionette', 'vent', 'utils',
no: ->
console.log("Controller: mixDeleteNO!!")
@listenTo vent, "mix:comment", (model, comment) ->
console.log "App(vent): mix:favourite"
model.save 'favourited', !model.get('favourited'), patch: true
true
@listenTo vent, "user:follow", (model)->
console.log "App(vent): user:follow"
user = new UserItem({id: com.podnoms.settings.currentUser })

View File

@@ -86,13 +86,6 @@
}
});
});
this.listenTo(vent, "mix:comment", function(model, comment) {
console.log("App(vent): mix:favourite");
model.save('favourited', !model.get('favourited'), {
patch: true
});
return true;
});
this.listenTo(vent, "user:follow", function(model) {
var target, user,
_this = this;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.3.3
// Generated by CoffeeScript 1.4.0
(function() {
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__hasProp = {}.hasOwnProperty,

View File

@@ -1,6 +1,6 @@
define(['backbone', 'backbone.relational'], function (Backbone) {
define(['backbone', 'backbone-associations'], function (Backbone) {
var TastypieModel = Backbone.RelationalModel.extend({
var TastypieModel = Backbone.AssociatedModel.extend({
base_url: function () {
var temp_url = Backbone.Model.prototype.url.call(this);
return (temp_url.charAt(temp_url.length - 1) == '/' ? temp_url : temp_url + '/');

View File

@@ -1,11 +1,11 @@
define ['app', 'marionette', 'vent', 'utils'
'views/mix/mixListLayout', 'views/mix/mixListView', 'views/mix/mixDetailView'
'views/mix/mixEditView', 'views/user/userProfileView', 'views/user/userListView', 'views/user/userEditView',
'models/mix/mixItem', 'models/mix/mixCollection', 'models/user/userItem'],
'models/mix/mixCollection', 'models/mix/mixItem', 'models/user/userItem'],
(App, Marionette, vent, utils,
MixListLayout, MixListView, MixDetailView,
MixEditView, UserProfileView, UserListView, UserEditView,
MixItem, MixCollection, UserItem)->
MixCollection, MixItem, UserItem)->
class DssController extends Marionette.Controller
initialize: ->

View File

@@ -3,7 +3,7 @@
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['app', 'marionette', 'vent', 'utils', 'views/mix/mixListLayout', 'views/mix/mixListView', 'views/mix/mixDetailView', 'views/mix/mixEditView', 'views/user/userProfileView', 'views/user/userListView', 'views/user/userEditView', 'models/mix/mixItem', 'models/mix/mixCollection', 'models/user/userItem'], function(App, Marionette, vent, utils, MixListLayout, MixListView, MixDetailView, MixEditView, UserProfileView, UserListView, UserEditView, MixItem, MixCollection, UserItem) {
define(['app', 'marionette', 'vent', 'utils', 'views/mix/mixListLayout', 'views/mix/mixListView', 'views/mix/mixDetailView', 'views/mix/mixEditView', 'views/user/userProfileView', 'views/user/userListView', 'views/user/userEditView', 'models/mix/mixCollection', 'models/mix/mixItem', 'models/user/userItem'], function(App, Marionette, vent, utils, MixListLayout, MixListView, MixDetailView, MixEditView, UserProfileView, UserListView, UserEditView, MixCollection, MixItem, UserItem) {
var DssController;
DssController = (function(_super) {

View File

@@ -1,18 +1,18 @@
// Generated by CoffeeScript 1.6.2
// Generated by CoffeeScript 1.4.0
(function() {
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['app.lib/dssView', 'utils', 'ace-editable', 'lib/bootstrap-typeahead'], function(DssView, utils) {
var EditableView, _ref;
var EditableView;
EditableView = (function(_super) {
__extends(EditableView, _super);
function EditableView() {
this.setupImageEditable = __bind(this.setupImageEditable, this); _ref = EditableView.__super__.constructor.apply(this, arguments);
return _ref;
this.setupImageEditable = __bind(this.setupImageEditable, this);
return EditableView.__super__.constructor.apply(this, arguments);
}
EditableView.prototype.events = {
@@ -22,7 +22,6 @@
EditableView.prototype.changeSelect = function(evt) {
var changed, obj, objInst, value;
changed = evt.currentTarget;
if (id) {
value = $(evt.currentTarget).val();
@@ -34,7 +33,6 @@
EditableView.prototype.changed = function(evt) {
var changed, obj, objInst, value;
return;
changed = evt.currentTarget;
if (changed.id) {
@@ -54,7 +52,6 @@
EditableView.prototype._bakeForm = function(el, lookups) {
var labels, mapped, model;
model = this.model;
labels = void 0;
mapped = void 0;
@@ -107,7 +104,6 @@
EditableView.prototype._saveChanges = function() {
var args, error, _results;
args = arguments;
if (!this.model.isValid()) {
if (this.model.errors) {
@@ -128,9 +124,7 @@
};
EditableView.prototype.setupImageEditable = function(options) {
var e,
_this = this;
var _this = this;
$.fn.editable.defaults.mode = 'inline';
try {
if (/msie\s*(8|7|6)/.test(navigator.userAgent.toLowerCase())) {
@@ -170,15 +164,13 @@
});
}
});
} catch (_error) {
e = _error;
} catch (e) {
return console.log(e);
}
};
EditableView.prototype.uploadImage = function(options) {
var $form, deferred, e, fd, file_input, files, iframe_id;
var $form, deferred, fd, file_input, files, iframe_id;
$form = options.el.next().find(".editableform:eq(0)");
file_input = $form.find("input[type=file]:eq(0)");
if (!("FormData" in window)) {
@@ -196,7 +188,6 @@
$form.get(0).submit();
setTimeout((function() {
var iframe;
iframe = document.getElementById(iframe_id);
if (iframe != null) {
iframe.src = "about:blank";
@@ -211,8 +202,7 @@
fd = null;
try {
fd = new FormData($form.get(0));
} catch (_error) {
e = _error;
} catch (e) {
fd = new FormData();
$.each($form.serializeArray(), function(index, item) {
return fd.append(item.name, item.value);
@@ -238,7 +228,6 @@
data: fd,
xhr: function() {
var req;
req = $.ajaxSettings.xhr();
return req;
},

View File

@@ -1,5 +1,6 @@
// Generated by CoffeeScript 1.6.2
// Generated by CoffeeScript 1.4.0
(function() {
define(['marionette'], function() {
return new Backbone.Wreqr.EventAggregator;
});

View File

@@ -1,14 +1,12 @@
// Generated by CoffeeScript 1.6.2
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['marionette'], function(Marionette) {
var PanningRegion, getPrefixedCssProp, _ref;
var PanningRegion, getPrefixedCssProp;
getPrefixedCssProp = function(baseProp) {
var str;
str = Modernizr.prefixed(baseProp);
str = str.replace(/([A-Z])/g, function(str, m1) {
return "-" + m1.toLowerCase();
@@ -16,18 +14,17 @@
return str;
};
PanningRegion = (function(_super) {
__extends(PanningRegion, _super);
function PanningRegion() {
_ref = PanningRegion.__super__.constructor.apply(this, arguments);
return _ref;
return PanningRegion.__super__.constructor.apply(this, arguments);
}
PanningRegion.prototype.el = "#content";
PanningRegion.prototype.initialize = function() {
var transEndEventNames;
transEndEventNames = {
WebkitTransition: "webkitTransitionEnd",
MozTransition: "transitionend",
@@ -43,7 +40,6 @@
PanningRegion.prototype.transitionToView = function(newView, type) {
var self, view;
self = this;
view = this.currentView;
if (!view || view.isClosed) {
@@ -53,7 +49,6 @@
Marionette.triggerMethod.call(this, "willTransition", view);
newView.on("render", function() {
var $background, newViewMatrix, translation, worldBgMatrix, worldContentMatrix;
self.$el.off(self.transEndEventName);
translation = void 0;
if (type === "slide") {

View File

@@ -41,18 +41,36 @@ define ['jquery', 'bootstrap', 'toastr'], ($, bootstrap, toastr) ->
@modal "/dlg/PlayCountLoginAlert"
true
toastOptions: ->
toastr.options =
closeButton: true
debug: false
positionClass: "toast-bottom-left"
onclick: null
showDuration: "300"
hideDuration: "1000"
timeOut: "5000"
extendedTimeOut: "1000"
showEasing: "swing"
hideEasing: "linear"
showMethod: "fadeIn"
hideMethod: "fadeOut"
showError: (title, message) ->
@toastOptions()
toastr.error message, title
showWarning: (title, message) ->
@toastOptions()
toastr.warning message, title
showMessage: (title, message) ->
toastOptions()
toastr.success message, title
showAlert: (title, message) ->
@showMessage title, message
showMessage: (title, message) ->
toastr.success message, title
generateGuid: ->
"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace /[xy]/g, (c) ->
r = Math.random() * 16 | 0

View File

@@ -58,18 +58,37 @@
}
return true;
},
toastOptions: function() {
return toastr.options = {
closeButton: true,
debug: false,
positionClass: "toast-bottom-left",
onclick: null,
showDuration: "300",
hideDuration: "1000",
timeOut: "5000",
extendedTimeOut: "1000",
showEasing: "swing",
hideEasing: "linear",
showMethod: "fadeIn",
hideMethod: "fadeOut"
};
},
showError: function(title, message) {
this.toastOptions();
return toastr.error(message, title);
},
showWarning: function(title, message) {
this.toastOptions();
return toastr.warning(message, title);
},
showMessage: function(title, message) {
toastOptions();
return toastr.success(message, title);
},
showAlert: function(title, message) {
return this.showMessage(title, message);
},
showMessage: function(title, message) {
return toastr.success(message, title);
},
generateGuid: function() {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
var r, v;

View File

@@ -1,17 +1,16 @@
// Generated by CoffeeScript 1.6.2
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['backbone', 'vent', 'models/activity/activityItem', 'app.lib/backbone.dss.model.collection'], function(Backbone, vent, ActivityItem, DssCollection) {
var ActivityCollection, _ref;
var ActivityCollection;
ActivityCollection = (function(_super) {
__extends(ActivityCollection, _super);
function ActivityCollection() {
_ref = ActivityCollection.__super__.constructor.apply(this, arguments);
return _ref;
return ActivityCollection.__super__.constructor.apply(this, arguments);
}
ActivityCollection.prototype.model = ActivityItem;
@@ -20,10 +19,8 @@
ActivityCollection.prototype.initialize = function() {
var _this = this;
return this.listenTo(vent, "model:activity:new", function(url) {
var item;
console.log("ActivityCollection: activity:new");
item = new ActivityItem();
return item.fetch({

View File

@@ -1,17 +1,16 @@
// Generated by CoffeeScript 1.6.2
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['backbone', 'moment'], function(Backbone, moment) {
var ActivityItem, _ref;
var ActivityItem;
ActivityItem = (function(_super) {
__extends(ActivityItem, _super);
function ActivityItem() {
_ref = ActivityItem.__super__.constructor.apply(this, arguments);
return _ref;
return ActivityItem.__super__.constructor.apply(this, arguments);
}
ActivityItem.prototype.urlRoot = com.podnoms.settings.urlRoot + "activity/";

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.3.3
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

View File

@@ -1,11 +1,6 @@
define ['app.lib/backbone.dss.model'], \
(DSSModel) ->
class CommentItem extends DSSModel
urlRoot: com.podnoms.settings.urlRoot + "comments/"
defaults:
avatar_image: com.podnoms.settings.avatarImage
user_name: com.podnoms.settings.userName
user_url: com.podnoms.settings.userUrl
date_created: ""
define ['backbone', 'backbone-associations'],
(Backbone) ->
class CommentItem extends Backbone.Model
urlRoot: com.podnoms.settings.urlRoot + "comments"
CommentItem
CommentItem

View File

@@ -1,31 +1,23 @@
// Generated by CoffeeScript 1.6.2
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['app.lib/backbone.dss.model'], function(DSSModel) {
var CommentItem, _ref;
define(['backbone', 'backbone-associations'], function(Backbone) {
var CommentItem;
CommentItem = (function(_super) {
__extends(CommentItem, _super);
function CommentItem() {
_ref = CommentItem.__super__.constructor.apply(this, arguments);
return _ref;
return CommentItem.__super__.constructor.apply(this, arguments);
}
CommentItem.prototype.urlRoot = com.podnoms.settings.urlRoot + "comments/";
CommentItem.prototype.defaults = {
avatar_image: com.podnoms.settings.avatarImage,
user_name: com.podnoms.settings.userName,
user_url: com.podnoms.settings.userUrl,
date_created: ""
};
CommentItem.prototype.urlRoot = com.podnoms.settings.urlRoot + "comments";
return CommentItem;
})(DSSModel);
})(Backbone.Model);
return CommentItem;
});

View File

@@ -1,16 +1,29 @@
define ['models/comment/commentCollection', 'models/comment/commentItem', 'app.lib/backbone.dss.model'], \
(CommentCollection, CommentItem, DSSModel) ->
class MixItem extends DSSModel
urlRoot: com.podnoms.settings.urlRoot + "mix/"
"""
relations: [
type: Backbone.HasMany
key: "comments"
relatedModel: CommentItem
collectionType: CommentCollection
reverseRelation:
key: "hasItems"
includeInJSON: "id"
]
"""
define ['utils', 'vent', 'models/comment/commentCollection', 'models/comment/commentItem', 'app.lib/backbone.dss.model'],
(utils, vent, CommentCollection, CommentItem, DssModel) ->
class MixItem extends DssModel
urlRoot: com.podnoms.settings.urlRoot + "mix/"
relations: [
type: Backbone.Many #nature of the relation
key: "comments" #attribute of Model
relatedModel: CommentItem #AssociatedModel for attribute key
]
addComment: (comment, success, error) ->
c = undefined
if comment
c = @get("comments").create(
comment: comment
mix_id: @get("slug")
)
c.save null,
success: ->
success()
error: ->
error()
else
error "Comment cannot be empty"
MixItem

View File

@@ -1,27 +1,55 @@
// Generated by CoffeeScript 1.6.2
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['models/comment/commentCollection', 'models/comment/commentItem', 'app.lib/backbone.dss.model'], function(CommentCollection, CommentItem, DSSModel) {
var MixItem, _ref;
define(['utils', 'vent', 'models/comment/commentCollection', 'models/comment/commentItem', 'app.lib/backbone.dss.model'], function(utils, vent, CommentCollection, CommentItem, DssModel) {
var MixItem;
return MixItem = (function(_super) {
MixItem = (function(_super) {
__extends(MixItem, _super);
function MixItem() {
_ref = MixItem.__super__.constructor.apply(this, arguments);
return _ref;
return MixItem.__super__.constructor.apply(this, arguments);
}
MixItem.prototype.urlRoot = com.podnoms.settings.urlRoot + "mix/";
"relations: [\n type: Backbone.HasMany\n key: \"comments\"\n relatedModel: CommentItem\n collectionType: CommentCollection\n reverseRelation:\n key: \"hasItems\"\n includeInJSON: \"id\"\n ]";
MixItem.prototype.relations = [
{
type: Backbone.Many,
key: "comments",
relatedModel: CommentItem
}
];
MixItem.prototype.addComment = function(comment, success, error) {
var c;
c = void 0;
if (comment) {
c = this.get("comments").create({
comment: comment,
mix_id: this.get("slug")
});
return c.save(null, {
success: function() {
return success();
},
error: function() {
return error();
}
});
} else {
return error("Comment cannot be empty");
}
};
MixItem;
return MixItem;
})(DSSModel);
return MixItem;
})(DssModel);
});
}).call(this);

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.3.3
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

View File

@@ -1,17 +1,16 @@
// Generated by CoffeeScript 1.6.2
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['backbone', 'models/user/userItem', 'app.lib/backbone.dss.model.collection'], function(Backbone, UserItem, DssCollection) {
var UserCollection, _ref;
var UserCollection;
UserCollection = (function(_super) {
__extends(UserCollection, _super);
function UserCollection() {
_ref = UserCollection.__super__.constructor.apply(this, arguments);
return _ref;
return UserCollection.__super__.constructor.apply(this, arguments);
}
UserCollection.prototype.page = 0;

View File

@@ -1,17 +1,16 @@
// Generated by CoffeeScript 1.6.2
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['app.lib/backbone.dss.model'], function(DssModel) {
var UserItem, _ref;
var UserItem;
UserItem = (function(_super) {
__extends(UserItem, _super);
function UserItem() {
_ref = UserItem.__super__.constructor.apply(this, arguments);
return _ref;
return UserItem.__super__.constructor.apply(this, arguments);
}
UserItem.prototype.urlRoot = com.podnoms.settings.urlRoot + "user/";

View File

@@ -1,17 +1,16 @@
// Generated by CoffeeScript 1.6.2
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['marionette', 'text!/tpl/ActivityListItemView'], function(Marionette, Template) {
var ActivityItemView, _ref;
var ActivityItemView;
return ActivityItemView = (function(_super) {
__extends(ActivityItemView, _super);
function ActivityItemView() {
_ref = ActivityItemView.__super__.constructor.apply(this, arguments);
return _ref;
return ActivityItemView.__super__.constructor.apply(this, arguments);
}
ActivityItemView.prototype.template = _.template(Template);

View File

@@ -1,17 +1,16 @@
// Generated by CoffeeScript 1.6.2
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['marionette', 'models/activity/activityCollection', 'views/activity/activityItemView', 'text!/tpl/ActivityListView'], function(Marionette, ActivityCollection, ActivityItemView, Template) {
var ActivityListView, _ref;
var ActivityListView;
ActivityListView = (function(_super) {
__extends(ActivityListView, _super);
function ActivityListView() {
_ref = ActivityListView.__super__.constructor.apply(this, arguments);
return _ref;
return ActivityListView.__super__.constructor.apply(this, arguments);
}
ActivityListView.prototype.template = _.template(Template);
@@ -31,7 +30,6 @@
ActivityListView.prototype.appendHtml = function(collectionView, itemView, index) {
var children, childrenContainer;
childrenContainer = (collectionView.itemViewContainer ? collectionView.$(collectionView.itemViewContainer) : collectionView.$el);
children = childrenContainer.children();
if (children.size() <= index) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.3.3
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

View File

@@ -1,17 +1,16 @@
// Generated by CoffeeScript 1.6.2
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['marionette', 'text!/tpl/CommentItemView'], function(Marionette, Template) {
var CommentItemView, _ref;
var CommentItemView;
CommentItemView = (function(_super) {
__extends(CommentItemView, _super);
function CommentItemView() {
_ref = CommentItemView.__super__.constructor.apply(this, arguments);
return _ref;
return CommentItemView.__super__.constructor.apply(this, arguments);
}
CommentItemView.prototype.template = _.template(Template);

View File

@@ -1,34 +1,58 @@
define ['marionette',
'utils',
'models/mix/mixItem',
'models/comment/commentItem',
'models/comment/commentCollection',
'views/comment/commentListView',
'views/mix/mixItemView',
'text!/tpl/MixDetailView',
'vent'],
(Marionette,
MixItem,
CommentItem,
MixItemView,
Template,
vent) ->
class MixDetailView extends Marionette.Layout
(Marionette, utils, MixItem, CommentItem, CommentsCollection, CommentsListView, MixItemView, Template, vent) ->
class MixDetailView extends Marionette.Layout
template: _.template(Template)
regions:{
mix: "#mix"
comments: "#comments"
}
ui:
commentText: '#comment-text'
events:
"click #btn-add-comment": "addComment"
template: _.template(Template)
regions:
mix: "#mix"
comments: "#comments"
ui:
commentText: '#comment-text'
events:
"click #btn-add-comment": "addComment"
initialize: ->
@model.on('nested-change', @modelChanged)
addComment: ->
comment = "123"
onRender: ->
view = new MixItemView({tagName: "div", className: "mix-listing audio-listing-single", model: @model})
@mix.show view
@renderComments()
onRender: ->
view = new MixItemView({tagName: "div", className: "mix-listing audio-listing-single", model: @model})
@mix.show(view)
true
renderComments: ->
console.log "MixDetailView: Rendering comments"
comments = new CommentsCollection()
comments.url = @model.get("resource_uri") + "/comments/"
comments.mix_id = @model.id
comments.mix = @model
comments.fetch success: (data) ->
content = new CommentsListView(collection: comments).render()
$("#comments", @el).html content.el
true
true
MixDetailView
modelChanged: =>
console.log("MixDetailView: modelChanged")
@render()
addComment: ->
activeTab = $("ul#mix-tab li.active", @el)
comment = @ui.commentText.val()
@model.addComment comment, (=>
@ui.commentText.val ""
utils.showMessage "Comment saved.."
activeTab.tab().show()
), (error) =>
utils.showError "Woops \n" + error
$('#comment-input').addClass('has-error')
$('#comment-text').focus()
MixDetailView

View File

@@ -1,15 +1,17 @@
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['marionette', 'models/mix/mixItem', 'models/comment/commentItem', 'views/mix/mixItemView', 'text!/tpl/MixDetailView', 'vent'], function(Marionette, MixItem, CommentItem, MixItemView, Template, vent) {
define(['marionette', 'utils', 'models/mix/mixItem', 'models/comment/commentItem', 'models/comment/commentCollection', 'views/comment/commentListView', 'views/mix/mixItemView', 'text!/tpl/MixDetailView', 'vent'], function(Marionette, utils, MixItem, CommentItem, CommentsCollection, CommentsListView, MixItemView, Template, vent) {
var MixDetailView;
MixDetailView = (function(_super) {
return MixDetailView = (function(_super) {
__extends(MixDetailView, _super);
function MixDetailView() {
this.modelChanged = __bind(this.modelChanged, this);
return MixDetailView.__super__.constructor.apply(this, arguments);
}
@@ -28,9 +30,8 @@
"click #btn-add-comment": "addComment"
};
MixDetailView.prototype.addComment = function() {
var comment;
return comment = "123";
MixDetailView.prototype.initialize = function() {
return this.model.on('nested-change', this.modelChanged);
};
MixDetailView.prototype.onRender = function() {
@@ -41,13 +42,54 @@
model: this.model
});
this.mix.show(view);
return this.renderComments();
};
MixDetailView.prototype.renderComments = function() {
var comments;
console.log("MixDetailView: Rendering comments");
comments = new CommentsCollection();
comments.url = this.model.get("resource_uri") + "/comments/";
comments.mix_id = this.model.id;
comments.mix = this.model;
comments.fetch({
success: function(data) {
var content;
content = new CommentsListView({
collection: comments
}).render();
$("#comments", this.el).html(content.el);
return true;
}
});
return true;
};
MixDetailView.prototype.modelChanged = function() {
console.log("MixDetailView: modelChanged");
return this.render();
};
MixDetailView.prototype.addComment = function() {
var activeTab, comment,
_this = this;
activeTab = $("ul#mix-tab li.active", this.el);
comment = this.ui.commentText.val();
this.model.addComment(comment, (function() {
_this.ui.commentText.val("");
utils.showMessage("Comment saved..");
return activeTab.tab().show();
}), function(error) {
utils.showError("Woops \n" + error);
$('#comment-input').addClass('has-error');
return $('#comment-text').focus();
});
return MixDetailView;
};
return MixDetailView;
})(Marionette.Layout);
return MixDetailView;
});
}).call(this);

View File

@@ -1,10 +1,6 @@
define ['moment', 'app', 'vent', 'marionette', 'utils',
'models/comment/commentCollection',
'views/comment/commentListView',
'text!/tpl/MixListItemView'],
(moment, App, vent, Marionette, utils,
CommentsCollection,
CommentsListView,
Template) ->
class MixItemView extends Marionette.ItemView
template: _.template(Template)
@@ -31,6 +27,7 @@ define ['moment', 'app', 'vent', 'marionette', 'utils',
initialize: =>
@listenTo(@model, 'change:favourited', @render)
@listenTo(@model, 'change:liked', @render)
@listenTo(@model, 'nested-change', @render)
@listenTo(vent, 'mix:play', @mixPlay)
@listenTo(vent, 'mix:pause', @mixPause)
true
@@ -40,10 +37,7 @@ define ['moment', 'app', 'vent', 'marionette', 'utils',
if @model.get('duration')
$('#player-duration-' + id, this.el).text(@model.secondsToHms('duration'))
@renderGenres()
@renderComments()
return
onShow: ->
@@ -60,17 +54,6 @@ define ['moment', 'app', 'vent', 'marionette', 'utils',
true
true
renderComments: =>
comments = new CommentsCollection()
comments.url = @model.get("resource_uri") + "comments/"
comments.mix_id = @model.id
comments.mix = @model
comments.fetch success: (data) ->
content = new CommentsListView(collection: comments).render()
$("#comments", @el).html content.el
true
true
doStart: =>
console.log("MixItemView: mixStart")
this.ui.playButton

View File

@@ -4,7 +4,7 @@
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['moment', 'app', 'vent', 'marionette', 'utils', 'models/comment/commentCollection', 'views/comment/commentListView', 'text!/tpl/MixListItemView'], function(moment, App, vent, Marionette, utils, CommentsCollection, CommentsListView, Template) {
define(['moment', 'app', 'vent', 'marionette', 'utils', 'text!/tpl/MixListItemView'], function(moment, App, vent, Marionette, utils, Template) {
var MixItemView;
MixItemView = (function(_super) {
@@ -13,8 +13,6 @@
function MixItemView() {
this.doStart = __bind(this.doStart, this);
this.renderComments = __bind(this.renderComments, this);
this.renderGenres = __bind(this.renderGenres, this);
this.onRender = __bind(this.onRender, this);
@@ -49,6 +47,7 @@
MixItemView.prototype.initialize = function() {
this.listenTo(this.model, 'change:favourited', this.render);
this.listenTo(this.model, 'change:liked', this.render);
this.listenTo(this.model, 'nested-change', this.render);
this.listenTo(vent, 'mix:play', this.mixPlay);
this.listenTo(vent, 'mix:pause', this.mixPause);
return true;
@@ -61,7 +60,6 @@
$('#player-duration-' + id, this.el).text(this.model.secondsToHms('duration'));
}
this.renderGenres();
this.renderComments();
};
MixItemView.prototype.onShow = function() {
@@ -82,25 +80,6 @@
return true;
};
MixItemView.prototype.renderComments = function() {
var comments;
comments = new CommentsCollection();
comments.url = this.model.get("resource_uri") + "comments/";
comments.mix_id = this.model.id;
comments.mix = this.model;
comments.fetch({
success: function(data) {
var content;
content = new CommentsListView({
collection: comments
}).render();
$("#comments", this.el).html(content.el);
return true;
}
});
return true;
};
MixItemView.prototype.doStart = function() {
console.log("MixItemView: mixStart");
this.ui.playButton.toggleClass('play-button-small-start', false).toggleClass('play-button-small-resume', false).toggleClass('play-button-small-pause', true);

View File

@@ -1,17 +1,16 @@
// Generated by CoffeeScript 1.6.2
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['marionette', 'text!/tpl/NotificationsItemView'], function(Marionette, Template) {
var NotificationsItemView, _ref;
var NotificationsItemView;
return NotificationsItemView = (function(_super) {
__extends(NotificationsItemView, _super);
function NotificationsItemView() {
_ref = NotificationsItemView.__super__.constructor.apply(this, arguments);
return _ref;
return NotificationsItemView.__super__.constructor.apply(this, arguments);
}
NotificationsItemView.prototype.template = _.template(Template);

View File

@@ -1,17 +1,16 @@
// Generated by CoffeeScript 1.6.2
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['underscore', 'backbone', 'marionette', 'vent', 'views/activity/activityListView', 'views/widgets/nowPlayingView', 'text!/tpl/SidebarView'], function(_, Backbone, Marionette, vent, ActivityListView, NowPlayingView, Template) {
var SidebarView, _ref;
var SidebarView;
SidebarView = (function(_super) {
__extends(SidebarView, _super);
function SidebarView() {
_ref = SidebarView.__super__.constructor.apply(this, arguments);
return _ref;
return SidebarView.__super__.constructor.apply(this, arguments);
}
SidebarView.prototype.template = _.template(Template);
@@ -44,7 +43,6 @@
SidebarView.prototype.liveStarted = function() {
var _this = this;
console.log("SidebarView: livePlay");
$.getJSON("ajax/live_now_playing/", function(data) {
$(_this.topRegion.el).show();

View File

@@ -1,17 +1,16 @@
// Generated by CoffeeScript 1.6.2
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['app', 'utils', 'moment', 'marionette', 'vent', 'app.lib/editableView', 'models/user/userItem', 'text!/tpl/UserProfileView', 'ace-editable', 'wysiwyg'], function(App, utils, moment, Marionette, vent, EditableView, UserItem, Template) {
var UserProfileView, _ref;
var UserProfileView;
UserProfileView = (function(_super) {
__extends(UserProfileView, _super);
function UserProfileView() {
_ref = UserProfileView.__super__.constructor.apply(this, arguments);
return _ref;
return UserProfileView.__super__.constructor.apply(this, arguments);
}
UserProfileView.prototype.template = _.template(Template);
@@ -24,7 +23,6 @@
UserProfileView.prototype.onDomRefresh = function() {
var _this = this;
console.log("UserProfileView: initialize");
this.setupImageEditable({
el: $("#avatar", this.el),

View File

@@ -1,17 +1,16 @@
// Generated by CoffeeScript 1.6.2
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['marionette', 'vent', 'text!/tpl/NowPlayingView'], function(Marionette, vent, Template) {
var NowPlayingView, _ref;
var NowPlayingView;
NowPlayingView = (function(_super) {
__extends(NowPlayingView, _super);
function NowPlayingView() {
_ref = NowPlayingView.__super__.constructor.apply(this, arguments);
return _ref;
return NowPlayingView.__super__.constructor.apply(this, arguments);
}
NowPlayingView.prototype.template = _.template(Template);

View File

@@ -1,17 +1,16 @@
// Generated by CoffeeScript 1.6.2
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['jquery', 'underscore', 'marionette', 'vent', 'text!/tpl/SearchView', 'text!/tpl/SearchResultView', 'lib/bootstrap-typeahead'], function($, _, Marionette, vent, Template, SearchResultView) {
var SearchView, _ref;
var SearchView;
SearchView = (function(_super) {
__extends(SearchView, _super);
function SearchView() {
_ref = SearchView.__super__.constructor.apply(this, arguments);
return _ref;
return SearchView.__super__.constructor.apply(this, arguments);
}
SearchView.prototype.template = _.template(Template);
@@ -23,7 +22,6 @@
SearchView.prototype.engine = {
compile: function(template) {
var compiled;
compiled = _.template(template);
return {
render: function(context) {
@@ -35,7 +33,6 @@
SearchView.prototype.onShow = function() {
var t;
if (typeof typeahead !== "undefined" && typeahead !== null) {
t = $('#search-text', this.el).typeahead({
name: "search",

File diff suppressed because it is too large Load Diff

View File

@@ -6,169 +6,169 @@ ace.config = {
}
ace.settings = {
is : function(item, status) {
//such as ace.settings.is('navbar', 'fixed')
return (ace.data.get('settings', item+'-'+status) == 1)
},
exists : function(item, status) {
return (ace.data.get('settings', item+'-'+status) !== null)
},
set : function(item, status) {
ace.data.set('settings', item+'-'+status, 1)
},
unset : function(item, status) {
ace.data.set('settings', item+'-'+status, -1)
},
remove : function(item, status) {
ace.data.remove('settings', item+'-'+status)
},
is : function(item, status) {
//such as ace.settings.is('navbar', 'fixed')
return (ace.data.get('settings', item+'-'+status) == 1)
},
exists : function(item, status) {
return (ace.data.get('settings', item+'-'+status) !== null)
},
set : function(item, status) {
ace.data.set('settings', item+'-'+status, 1)
},
unset : function(item, status) {
ace.data.set('settings', item+'-'+status, -1)
},
remove : function(item, status) {
ace.data.remove('settings', item+'-'+status)
},
navbar_fixed : function(fix) {
fix = fix || false;
if(!fix && ace.settings.is('sidebar', 'fixed')) {
ace.settings.sidebar_fixed(false);
}
navbar_fixed : function(fix) {
fix = fix || false;
if(!fix && ace.settings.is('sidebar', 'fixed')) {
ace.settings.sidebar_fixed(false);
}
var navbar = document.getElementById('navbar');
if(fix) {
if(!ace.hasClass(navbar , 'navbar-fixed-top')) ace.addClass(navbar , 'navbar-fixed-top');
if(!ace.hasClass(document.body , 'navbar-fixed')) ace.addClass(document.body , 'navbar-fixed');
var navbar = document.getElementById('navbar');
if(fix) {
if(!ace.hasClass(navbar , 'navbar-fixed-top')) ace.addClass(navbar , 'navbar-fixed-top');
if(!ace.hasClass(document.body , 'navbar-fixed')) ace.addClass(document.body , 'navbar-fixed');
ace.settings.set('navbar', 'fixed');
} else {
ace.removeClass(navbar , 'navbar-fixed-top');
ace.removeClass(document.body , 'navbar-fixed');
ace.settings.set('navbar', 'fixed');
} else {
ace.removeClass(navbar , 'navbar-fixed-top');
ace.removeClass(document.body , 'navbar-fixed');
ace.settings.unset('navbar', 'fixed');
}
ace.settings.unset('navbar', 'fixed');
}
document.getElementById('ace-settings-navbar').checked = fix;
},
document.getElementById('ace-settings-navbar').checked = fix;
},
breadcrumbs_fixed : function(fix) {
fix = fix || false;
if(fix && !ace.settings.is('sidebar', 'fixed')) {
ace.settings.sidebar_fixed(true);
}
breadcrumbs_fixed : function(fix) {
fix = fix || false;
if(fix && !ace.settings.is('sidebar', 'fixed')) {
ace.settings.sidebar_fixed(true);
}
var breadcrumbs = document.getElementById('breadcrumbs');
if(fix) {
if(!ace.hasClass(breadcrumbs , 'breadcrumbs-fixed')) ace.addClass(breadcrumbs , 'breadcrumbs-fixed');
if(!ace.hasClass(document.body , 'breadcrumbs-fixed')) ace.addClass(document.body , 'breadcrumbs-fixed');
var breadcrumbs = document.getElementById('breadcrumbs');
if(fix) {
if(!ace.hasClass(breadcrumbs , 'breadcrumbs-fixed')) ace.addClass(breadcrumbs , 'breadcrumbs-fixed');
if(!ace.hasClass(document.body , 'breadcrumbs-fixed')) ace.addClass(document.body , 'breadcrumbs-fixed');
ace.settings.set('breadcrumbs', 'fixed');
} else {
ace.removeClass(breadcrumbs , 'breadcrumbs-fixed');
ace.removeClass(document.body , 'breadcrumbs-fixed');
ace.settings.set('breadcrumbs', 'fixed');
} else {
ace.removeClass(breadcrumbs , 'breadcrumbs-fixed');
ace.removeClass(document.body , 'breadcrumbs-fixed');
ace.settings.unset('breadcrumbs', 'fixed');
}
document.getElementById('ace-settings-breadcrumbs').checked = fix;
},
ace.settings.unset('breadcrumbs', 'fixed');
}
document.getElementById('ace-settings-breadcrumbs').checked = fix;
},
sidebar_fixed : function(fix) {
fix = fix || false;
if(!fix && ace.settings.is('breadcrumbs', 'fixed')) {
ace.settings.breadcrumbs_fixed(false);
}
sidebar_fixed : function(fix) {
fix = fix || false;
if(!fix && ace.settings.is('breadcrumbs', 'fixed')) {
ace.settings.breadcrumbs_fixed(false);
}
if( fix && !ace.settings.is('navbar', 'fixed') ) {
ace.settings.navbar_fixed(true);
}
if( fix && !ace.settings.is('navbar', 'fixed') ) {
ace.settings.navbar_fixed(true);
}
var sidebar = document.getElementById('sidebar');
if(fix) {
if( !ace.hasClass(sidebar , 'sidebar-fixed') ) ace.addClass(sidebar , 'sidebar-fixed');
ace.settings.set('sidebar', 'fixed');
} else {
ace.removeClass(sidebar , 'sidebar-fixed');
ace.settings.unset('sidebar', 'fixed');
}
document.getElementById('ace-settings-sidebar').checked = fix;
},
var sidebar = document.getElementById('sidebar');
if(fix) {
if( !ace.hasClass(sidebar , 'sidebar-fixed') ) ace.addClass(sidebar , 'sidebar-fixed');
ace.settings.set('sidebar', 'fixed');
} else {
ace.removeClass(sidebar , 'sidebar-fixed');
ace.settings.unset('sidebar', 'fixed');
}
document.getElementById('ace-settings-sidebar').checked = fix;
},
main_container_fixed : function(inside) {
inside = inside || false;
main_container_fixed : function(inside) {
inside = inside || false;
var main_container = document.getElementById('main-container');
var navbar_container = document.getElementById('navbar-container');
if(inside) {
if( !ace.hasClass(main_container , 'container') ) ace.addClass(main_container , 'container');
if( !ace.hasClass(navbar_container , 'container') ) ace.addClass(navbar_container , 'container');
ace.settings.set('main-container', 'fixed');
} else {
ace.removeClass(main_container , 'container');
ace.removeClass(navbar_container , 'container');
ace.settings.unset('main-container', 'fixed');
}
document.getElementById('ace-settings-add-container').checked = inside;
var main_container = document.getElementById('main-container');
var navbar_container = document.getElementById('navbar-container');
if(inside) {
if( !ace.hasClass(main_container , 'container') ) ace.addClass(main_container , 'container');
if( !ace.hasClass(navbar_container , 'container') ) ace.addClass(navbar_container , 'container');
ace.settings.set('main-container', 'fixed');
} else {
ace.removeClass(main_container , 'container');
ace.removeClass(navbar_container , 'container');
ace.settings.unset('main-container', 'fixed');
}
document.getElementById('ace-settings-add-container').checked = inside;
if(navigator.userAgent.match(/webkit/i)) {
//webkit has a problem redrawing and moving around the sidebar background in realtime
//so we do this, to force redraw
//there will be no problems with webkit if the ".container" class is statically put inside HTML code.
var sidebar = document.getElementById('sidebar')
ace.toggleClass(sidebar , 'menu-min')
setTimeout(function() { ace.toggleClass(sidebar , 'menu-min') } , 0)
}
},
if(navigator.userAgent.match(/webkit/i)) {
//webkit has a problem redrawing and moving around the sidebar background in realtime
//so we do this, to force redraw
//there will be no problems with webkit if the ".container" class is statically put inside HTML code.
var sidebar = document.getElementById('sidebar')
ace.toggleClass(sidebar , 'menu-min')
setTimeout(function() { ace.toggleClass(sidebar , 'menu-min') } , 0)
}
},
sidebar_collapsed : function(collpase) {
collpase = collpase || false;
sidebar_collapsed : function(collpase) {
collpase = collpase || false;
var sidebar = document.getElementById('sidebar');
var icon = document.getElementById('sidebar-collapse').querySelector('[class*="icon-"]');
var $icon1 = icon.getAttribute('data-icon1');//the icon for expanded state
var $icon2 = icon.getAttribute('data-icon2');//the icon for collapsed state
var sidebar = document.getElementById('sidebar');
var icon = document.getElementById('sidebar-collapse').querySelector('[class*="icon-"]');
var $icon1 = icon.getAttribute('data-icon1');//the icon for expanded state
var $icon2 = icon.getAttribute('data-icon2');//the icon for collapsed state
if(collpase) {
ace.addClass(sidebar , 'menu-min');
ace.removeClass(icon , $icon1);
ace.addClass(icon , $icon2);
if(collpase) {
ace.addClass(sidebar , 'menu-min');
ace.removeClass(icon , $icon1);
ace.addClass(icon , $icon2);
ace.settings.set('sidebar', 'collapsed');
} else {
ace.removeClass(sidebar , 'menu-min');
ace.removeClass(icon , $icon2);
ace.addClass(icon , $icon1);
ace.settings.set('sidebar', 'collapsed');
} else {
ace.removeClass(sidebar , 'menu-min');
ace.removeClass(icon , $icon2);
ace.addClass(icon , $icon1);
ace.settings.unset('sidebar', 'collapsed');
}
ace.settings.unset('sidebar', 'collapsed');
}
},
/**
select_skin : function(skin) {
}
*/
},
/**
select_skin : function(skin) {
}
*/
}
//check the status of something
ace.settings.check = function(item, val) {
if(! ace.settings.exists(item, val) ) return;//no such setting specified
var status = ace.settings.is(item, val);//is breadcrumbs-fixed? or is sidebar-collapsed? etc
if(! ace.settings.exists(item, val) ) return;//no such setting specified
var status = ace.settings.is(item, val);//is breadcrumbs-fixed? or is sidebar-collapsed? etc
var mustHaveClass = {
'navbar-fixed' : 'navbar-fixed-top',
'sidebar-fixed' : 'sidebar-fixed',
'breadcrumbs-fixed' : 'breadcrumbs-fixed',
'sidebar-collapsed' : 'menu-min',
'main-container-fixed' : 'container'
}
var mustHaveClass = {
'navbar-fixed' : 'navbar-fixed-top',
'sidebar-fixed' : 'sidebar-fixed',
'breadcrumbs-fixed' : 'breadcrumbs-fixed',
'sidebar-collapsed' : 'menu-min',
'main-container-fixed' : 'container'
}
//if an element doesn't have a specified class, but saved settings say it should, then add it
//for example, sidebar isn't .fixed, but user fixed it on a previous page
//or if an element has a specified class, but saved settings say it shouldn't, then remove it
//for example, sidebar by default is minimized (.menu-min hard coded), but user expanded it and now shouldn't have 'menu-min' class
//if an element doesn't have a specified class, but saved settings say it should, then add it
//for example, sidebar isn't .fixed, but user fixed it on a previous page
//or if an element has a specified class, but saved settings say it shouldn't, then remove it
//for example, sidebar by default is minimized (.menu-min hard coded), but user expanded it and now shouldn't have 'menu-min' class
var target = document.getElementById(item);//#navbar, #sidebar, #breadcrumbs
if(status != ace.hasClass(target , mustHaveClass[item+'-'+val])) {
ace.settings[item.replace('-','_')+'_'+val](status);//call the relevant function to mage the changes
}
var target = document.getElementById(item);//#navbar, #sidebar, #breadcrumbs
if(status != ace.hasClass(target , mustHaveClass[item+'-'+val])) {
ace.settings[item.replace('-','_')+'_'+val](status);//call the relevant function to mage the changes
}
}
@@ -181,93 +181,93 @@ ace.settings.check = function(item, val) {
//method == 2, use cookies
//method not specified, use localStorage if available, otherwise cookies
ace.data_storage = function(method, undefined) {
var prefix = 'ace.';
var prefix = 'ace.';
var storage = null;
var type = 0;
var storage = null;
var type = 0;
if((method == 1 || method === undefined) && 'localStorage' in window && window['localStorage'] !== null) {
storage = ace.storage;
type = 1;
}
else if(storage == null && (method == 2 || method === undefined) && 'cookie' in document && document['cookie'] !== null) {
storage = ace.cookie;
type = 2;
}
if((method == 1 || method === undefined) && 'localStorage' in window && window['localStorage'] !== null) {
storage = ace.storage;
type = 1;
}
else if(storage == null && (method == 2 || method === undefined) && 'cookie' in document && document['cookie'] !== null) {
storage = ace.cookie;
type = 2;
}
//var data = {}
this.set = function(namespace, key, value, undefined) {
if(!storage) return;
//var data = {}
this.set = function(namespace, key, value, undefined) {
if(!storage) return;
if(value === undefined) {//no namespace here?
value = key;
key = namespace;
if(value === undefined) {//no namespace here?
value = key;
key = namespace;
if(value == null) storage.remove(prefix+key)
else {
if(type == 1)
storage.set(prefix+key, value)
else if(type == 2)
storage.set(prefix+key, value, ace.config.cookie_expiry)
}
}
else {
if(type == 1) {//localStorage
if(value == null) storage.remove(prefix+namespace+'.'+key)
else storage.set(prefix+namespace+'.'+key, value);
}
else if(type == 2) {//cookie
var val = storage.get(prefix+namespace);
var tmp = val ? JSON.parse(val) : {};
if(value == null) storage.remove(prefix+key)
else {
if(type == 1)
storage.set(prefix+key, value)
else if(type == 2)
storage.set(prefix+key, value, ace.config.cookie_expiry)
}
}
else {
if(type == 1) {//localStorage
if(value == null) storage.remove(prefix+namespace+'.'+key)
else storage.set(prefix+namespace+'.'+key, value);
}
else if(type == 2) {//cookie
var val = storage.get(prefix+namespace);
var tmp = val ? JSON.parse(val) : {};
if(value == null) {
delete tmp[key];//remove
if(ace.sizeof(tmp) == 0) {//no other elements in this cookie, so delete it
storage.remove(prefix+namespace);
return;
}
}
if(value == null) {
delete tmp[key];//remove
if(ace.sizeof(tmp) == 0) {//no other elements in this cookie, so delete it
storage.remove(prefix+namespace);
return;
}
}
else {
tmp[key] = value;
}
else {
tmp[key] = value;
}
storage.set(prefix+namespace , JSON.stringify(tmp), ace.config.cookie_expiry)
}
}
}
storage.set(prefix+namespace , JSON.stringify(tmp), ace.config.cookie_expiry)
}
}
}
this.get = function(namespace, key, undefined) {
if(!storage) return null;
this.get = function(namespace, key, undefined) {
if(!storage) return null;
if(key === undefined) {//no namespace here?
key = namespace;
return storage.get(prefix+key);
}
else {
if(type == 1) {//localStorage
return storage.get(prefix+namespace+'.'+key);
}
else if(type == 2) {//cookie
var val = storage.get(prefix+namespace);
var tmp = val ? JSON.parse(val) : {};
return key in tmp ? tmp[key] : null;
}
}
}
if(key === undefined) {//no namespace here?
key = namespace;
return storage.get(prefix+key);
}
else {
if(type == 1) {//localStorage
return storage.get(prefix+namespace+'.'+key);
}
else if(type == 2) {//cookie
var val = storage.get(prefix+namespace);
var tmp = val ? JSON.parse(val) : {};
return key in tmp ? tmp[key] : null;
}
}
}
this.remove = function(namespace, key, undefined) {
if(!storage) return;
this.remove = function(namespace, key, undefined) {
if(!storage) return;
if(key === undefined) {
key = namespace
this.set(key, null);
}
else {
this.set(namespace, key, null);
}
}
if(key === undefined) {
key = namespace
this.set(key, null);
}
else {
this.set(namespace, key, null);
}
}
}
@@ -276,84 +276,84 @@ ace.data_storage = function(method, undefined) {
//cookie storage
ace.cookie = {
// The following functions are from Cookie.js class in TinyMCE, Moxiecode, used under LGPL.
// The following functions are from Cookie.js class in TinyMCE, Moxiecode, used under LGPL.
/**
* Get a cookie.
*/
get : function(name) {
var cookie = document.cookie, e, p = name + "=", b;
/**
* Get a cookie.
*/
get : function(name) {
var cookie = document.cookie, e, p = name + "=", b;
if ( !cookie )
return;
if ( !cookie )
return;
b = cookie.indexOf("; " + p);
b = cookie.indexOf("; " + p);
if ( b == -1 ) {
b = cookie.indexOf(p);
if ( b == -1 ) {
b = cookie.indexOf(p);
if ( b != 0 )
return null;
if ( b != 0 )
return null;
} else {
b += 2;
}
} else {
b += 2;
}
e = cookie.indexOf(";", b);
e = cookie.indexOf(";", b);
if ( e == -1 )
e = cookie.length;
if ( e == -1 )
e = cookie.length;
return decodeURIComponent( cookie.substring(b + p.length, e) );
},
return decodeURIComponent( cookie.substring(b + p.length, e) );
},
/**
* Set a cookie.
*
* The 'expires' arg can be either a JS Date() object set to the expiration date (back-compat)
* or the number of seconds until expiration
*/
set : function(name, value, expires, path, domain, secure) {
var d = new Date();
/**
* Set a cookie.
*
* The 'expires' arg can be either a JS Date() object set to the expiration date (back-compat)
* or the number of seconds until expiration
*/
set : function(name, value, expires, path, domain, secure) {
var d = new Date();
if ( typeof(expires) == 'object' && expires.toGMTString ) {
expires = expires.toGMTString();
} else if ( parseInt(expires, 10) ) {
d.setTime( d.getTime() + ( parseInt(expires, 10) * 1000 ) ); // time must be in miliseconds
expires = d.toGMTString();
} else {
expires = '';
}
if ( typeof(expires) == 'object' && expires.toGMTString ) {
expires = expires.toGMTString();
} else if ( parseInt(expires, 10) ) {
d.setTime( d.getTime() + ( parseInt(expires, 10) * 1000 ) ); // time must be in miliseconds
expires = d.toGMTString();
} else {
expires = '';
}
document.cookie = name + "=" + encodeURIComponent(value) +
((expires) ? "; expires=" + expires : "") +
((path) ? "; path=" + path : "") +
((domain) ? "; domain=" + domain : "") +
((secure) ? "; secure" : "");
},
document.cookie = name + "=" + encodeURIComponent(value) +
((expires) ? "; expires=" + expires : "") +
((path) ? "; path=" + path : "") +
((domain) ? "; domain=" + domain : "") +
((secure) ? "; secure" : "");
},
/**
* Remove a cookie.
*
* This is done by setting it to an empty value and setting the expiration time in the past.
*/
remove : function(name, path) {
this.set(name, '', -1000, path);
}
/**
* Remove a cookie.
*
* This is done by setting it to an empty value and setting the expiration time in the past.
*/
remove : function(name, path) {
this.set(name, '', -1000, path);
}
};
//local storage
ace.storage = {
get: function(key) {
return window['localStorage'].getItem(key);
},
set: function(key, value) {
window['localStorage'].setItem(key , value);
},
remove: function(key) {
window['localStorage'].removeItem(key);
}
get: function(key) {
return window['localStorage'].getItem(key);
},
set: function(key, value) {
window['localStorage'].setItem(key , value);
},
remove: function(key) {
window['localStorage'].removeItem(key);
}
};
@@ -364,34 +364,34 @@ ace.storage = {
//count the number of properties in an object
//useful for getting the number of elements in an associative array
ace.sizeof = function(obj) {
var size = 0;
for(var key in obj) if(obj.hasOwnProperty(key)) size++;
return size;
var size = 0;
for(var key in obj) if(obj.hasOwnProperty(key)) size++;
return size;
}
//because jQuery may not be loaded at this stage, we use our own toggleClass
ace.hasClass = function(elem, className) {
return (" " + elem.className + " ").indexOf(" " + className + " ") > -1;
return (" " + elem.className + " ").indexOf(" " + className + " ") > -1;
}
ace.addClass = function(elem, className) {
if (!ace.hasClass(elem, className)) {
var currentClass = elem.className;
elem.className = currentClass + (currentClass.length? " " : "") + className;
var currentClass = elem.className;
elem.className = currentClass + (currentClass.length? " " : "") + className;
}
}
ace.removeClass = function(elem, className) {ace.replaceClass(elem, className);}
ace.replaceClass = function(elem, className, newClass) {
var classToRemove = new RegExp(("(^|\\s)" + className + "(\\s|$)"), "i");
elem.className = elem.className.replace(classToRemove, function (match, p1, p2) {
return newClass? (p1 + newClass + p2) : " ";
}).replace(/^\s+|\s+$/g, "");
var classToRemove = new RegExp(("(^|\\s)" + className + "(\\s|$)"), "i");
elem.className = elem.className.replace(classToRemove, function (match, p1, p2) {
return newClass? (p1 + newClass + p2) : " ";
}).replace(/^\s+|\s+$/g, "");
}
ace.toggleClass = function(elem, className) {
if(ace.hasClass(elem, className))
ace.removeClass(elem, className);
else ace.addClass(elem, className);
if(ace.hasClass(elem, className))
ace.removeClass(elem, className);
else ace.addClass(elem, className);
}

View File

@@ -1,85 +1,85 @@
if(! ('ace' in window) ) window['ace'] = {}
jQuery(function($) {
//at some places we try to use 'tap' event instead of 'click' if jquery mobile plugin is available
window['ace'].click_event = $.fn.tap ? "tap" : "click";
//at some places we try to use 'tap' event instead of 'click' if jquery mobile plugin is available
window['ace'].click_event = $.fn.tap ? "tap" : "click";
});
ace.handle_side_menu = function($) {
$('#menu-toggler').on(ace.click_event, function() {
$('#sidebar').toggleClass('display');
$(this).toggleClass('display');
return false;
});
//mini
var $minimized = $('#sidebar').hasClass('menu-min');
$('#sidebar-collapse').on(ace.click_event, function(){
$minimized = $('#sidebar').hasClass('menu-min');
ace.settings.sidebar_collapsed(!$minimized);//@ ace-extra.js
});
$('#menu-toggler').on(ace.click_event, function() {
$('#sidebar').toggleClass('display');
$(this).toggleClass('display');
return false;
});
//mini
var $minimized = $('#sidebar').hasClass('menu-min');
$('#sidebar-collapse').on(ace.click_event, function(){
$minimized = $('#sidebar').hasClass('menu-min');
ace.settings.sidebar_collapsed(!$minimized);//@ ace-extra.js
});
var touch = "ontouchend" in document;
//opening submenu
$('.nav-list').on(ace.click_event, function(e){
//check to see if we have clicked on an element which is inside a .dropdown-toggle element?!
//if so, it means we should toggle a submenu
var link_element = $(e.target).closest('a');
if(!link_element || link_element.length == 0) return;//if not clicked inside a link element
var touch = "ontouchend" in document;
//opening submenu
$('.nav-list').on(ace.click_event, function(e){
//check to see if we have clicked on an element which is inside a .dropdown-toggle element?!
//if so, it means we should toggle a submenu
var link_element = $(e.target).closest('a');
if(!link_element || link_element.length == 0) return;//if not clicked inside a link element
$minimized = $('#sidebar').hasClass('menu-min');
$minimized = $('#sidebar').hasClass('menu-min');
if(! link_element.hasClass('dropdown-toggle') ) {//it doesn't have a submenu return
//just one thing before we return
//if sidebar is collapsed(minimized) and we click on a first level menu item
//and the click is on the icon, not on the menu text then let's cancel event and cancel navigation
//Good for touch devices, that when the icon is tapped to see the menu text, navigation is cancelled
//navigation is only done when menu text is tapped
if($minimized && ace.click_event == "tap" &&
link_element.get(0).parentNode.parentNode == this /*.nav-list*/ )//i.e. only level-1 links
{
var text = link_element.find('.menu-text').get(0);
if( e.target != text && !$.contains(text , e.target) )//not clicking on the text or its children
return false;
}
if(! link_element.hasClass('dropdown-toggle') ) {//it doesn't have a submenu return
//just one thing before we return
//if sidebar is collapsed(minimized) and we click on a first level menu item
//and the click is on the icon, not on the menu text then let's cancel event and cancel navigation
//Good for touch devices, that when the icon is tapped to see the menu text, navigation is cancelled
//navigation is only done when menu text is tapped
if($minimized && ace.click_event == "tap" &&
link_element.get(0).parentNode.parentNode == this /*.nav-list*/ )//i.e. only level-1 links
{
var text = link_element.find('.menu-text').get(0);
if( e.target != text && !$.contains(text , e.target) )//not clicking on the text or its children
return false;
}
return;
}
//
var sub = link_element.next().get(0);
return;
}
//
var sub = link_element.next().get(0);
//if we are opening this submenu, close all other submenus except the ".active" one
if(! $(sub).is(':visible') ) {//if not open and visible, let's open it and make it visible
var parent_ul = $(sub.parentNode).closest('ul');
if($minimized && parent_ul.hasClass('nav-list')) return;
//if we are opening this submenu, close all other submenus except the ".active" one
if(! $(sub).is(':visible') ) {//if not open and visible, let's open it and make it visible
var parent_ul = $(sub.parentNode).closest('ul');
if($minimized && parent_ul.hasClass('nav-list')) return;
parent_ul.find('> .open > .submenu').each(function(){
//close all other open submenus except for the active one
if(this != sub && !$(this.parentNode).hasClass('active')) {
$(this).slideUp(200).parent().removeClass('open');
parent_ul.find('> .open > .submenu').each(function(){
//close all other open submenus except for the active one
if(this != sub && !$(this.parentNode).hasClass('active')) {
$(this).slideUp(200).parent().removeClass('open');
//uncomment the following line to close all submenus on deeper levels when closing a submenu
//$(this).find('.open > .submenu').slideUp(0).parent().removeClass('open');
}
});
} else {
//uncomment the following line to close all submenus on deeper levels when closing a submenu
//$(sub).find('.open > .submenu').slideUp(0).parent().removeClass('open');
}
//uncomment the following line to close all submenus on deeper levels when closing a submenu
//$(this).find('.open > .submenu').slideUp(0).parent().removeClass('open');
}
});
} else {
//uncomment the following line to close all submenus on deeper levels when closing a submenu
//$(sub).find('.open > .submenu').slideUp(0).parent().removeClass('open');
}
if($minimized && $(sub.parentNode.parentNode).hasClass('nav-list')) return false;
if($minimized && $(sub.parentNode.parentNode).hasClass('nav-list')) return false;
$(sub).slideToggle(200).parent().toggleClass('open');
return false;
})
$(sub).slideToggle(200).parent().toggleClass('open');
return false;
})
}
ace.general_things = function($) {
$('.ace-nav [class*="icon-animated-"]').closest('a').on('click', function(){
var icon = $(this).find('[class*="icon-animated-"]').eq(0);
var $match = icon.attr('class').match(/icon\-animated\-([\d\w]+)/);
icon.removeClass($match[0]);
$(this).off('click');
var icon = $(this).find('[class*="icon-animated-"]').eq(0);
var $match = icon.attr('class').match(/icon\-animated\-([\d\w]+)/);
icon.removeClass($match[0]);
$(this).off('click');
});
$('.nav-list .badge[title],.nav-list .label[title]').tooltip({'placement':'right'});
@@ -89,73 +89,73 @@ ace.general_things = function($) {
//simple settings
$('#ace-settings-btn').on(ace.click_event, function(){
$(this).toggleClass('open');
$('#ace-settings-box').toggleClass('open');
$(this).toggleClass('open');
$('#ace-settings-box').toggleClass('open');
});
$('#ace-settings-navbar').on('click', function(){
ace.settings.navbar_fixed(this.checked);//@ ace-extra.js
ace.settings.navbar_fixed(this.checked);//@ ace-extra.js
}).each(function(){this.checked = ace.settings.is('navbar', 'fixed')})
$('#ace-settings-sidebar').on('click', function(){
ace.settings.sidebar_fixed(this.checked);//@ ace-extra.js
ace.settings.sidebar_fixed(this.checked);//@ ace-extra.js
}).each(function(){this.checked = ace.settings.is('sidebar', 'fixed')})
$('#ace-settings-breadcrumbs').on('click', function(){
ace.settings.breadcrumbs_fixed(this.checked);//@ ace-extra.js
ace.settings.breadcrumbs_fixed(this.checked);//@ ace-extra.js
}).each(function(){this.checked = ace.settings.is('breadcrumbs', 'fixed')})
$('#ace-settings-add-container').on('click', function(){
ace.settings.main_container_fixed(this.checked);//@ ace-extra.js
ace.settings.main_container_fixed(this.checked);//@ ace-extra.js
}).each(function(){this.checked = ace.settings.is('main-container', 'fixed')})
//Switching to RTL (right to left) Mode
$('#ace-settings-rtl').removeAttr('checked').on('click', function(){
ace.switch_direction(jQuery);
ace.switch_direction(jQuery);
});
$('#btn-scroll-up').on(ace.click_event, function(){
var duration = Math.min(400, Math.max(100, parseInt($('html').scrollTop() / 3)));
$('html,body').animate({scrollTop: 0}, duration);
return false;
var duration = Math.min(400, Math.max(100, parseInt($('html').scrollTop() / 3)));
$('html,body').animate({scrollTop: 0}, duration);
return false;
});
try {
$('#skin-colorpicker').ace_colorpicker();
$('#skin-colorpicker').ace_colorpicker();
} catch(e) {}
$('#skin-colorpicker').on('change', function(){
var skin_class = $(this).find('option:selected').data('skin');
var skin_class = $(this).find('option:selected').data('skin');
var body = $(document.body);
body.removeClass('skin-1 skin-2 skin-3');
var body = $(document.body);
body.removeClass('skin-1 skin-2 skin-3');
if(skin_class != 'default') body.addClass(skin_class);
if(skin_class != 'default') body.addClass(skin_class);
if(skin_class == 'skin-1') {
$('.ace-nav > li.grey').addClass('dark');
}
else {
$('.ace-nav > li.grey').removeClass('dark');
}
if(skin_class == 'skin-1') {
$('.ace-nav > li.grey').addClass('dark');
}
else {
$('.ace-nav > li.grey').removeClass('dark');
}
if(skin_class == 'skin-2') {
$('.ace-nav > li').addClass('no-border margin-1');
$('.ace-nav > li:not(:last-child)').addClass('light-pink').find('> a > [class*="icon-"]').addClass('pink').end().eq(0).find('.badge').addClass('badge-warning');
}
else {
$('.ace-nav > li').removeClass('no-border margin-1');
$('.ace-nav > li:not(:last-child)').removeClass('light-pink').find('> a > [class*="icon-"]').removeClass('pink').end().eq(0).find('.badge').removeClass('badge-warning');
}
if(skin_class == 'skin-2') {
$('.ace-nav > li').addClass('no-border margin-1');
$('.ace-nav > li:not(:last-child)').addClass('light-pink').find('> a > [class*="icon-"]').addClass('pink').end().eq(0).find('.badge').addClass('badge-warning');
}
else {
$('.ace-nav > li').removeClass('no-border margin-1');
$('.ace-nav > li:not(:last-child)').removeClass('light-pink').find('> a > [class*="icon-"]').removeClass('pink').end().eq(0).find('.badge').removeClass('badge-warning');
}
if(skin_class == 'skin-3') {
$('.ace-nav > li.grey').addClass('red').find('.badge').addClass('badge-yellow');
} else {
$('.ace-nav > li.grey').removeClass('red').find('.badge').removeClass('badge-yellow');
}
if(skin_class == 'skin-3') {
$('.ace-nav > li.grey').addClass('red').find('.badge').addClass('badge-yellow');
} else {
$('.ace-nav > li.grey').removeClass('red').find('.badge').removeClass('badge-yellow');
}
});
};
@@ -163,224 +163,224 @@ ace.general_things = function($) {
ace.widget_boxes = function($) {
$(document).on('hide.bs.collapse show.bs.collapse', function (ev) {
var hidden_id = ev.target.getAttribute('id')
$('[href*="#'+ hidden_id+'"]').find('[class*="icon-"]').each(function(){
var $icon = $(this)
$(document).on('hide.bs.collapse show.bs.collapse', function (ev) {
var hidden_id = ev.target.getAttribute('id')
$('[href*="#'+ hidden_id+'"]').find('[class*="icon-"]').each(function(){
var $icon = $(this)
var $match
var $icon_down = null
var $icon_up = null
if( ($icon_down = $icon.attr('data-icon-show')) ) {
$icon_up = $icon.attr('data-icon-hide')
}
else if( $match = $icon.attr('class').match(/icon\-(.*)\-(up|down)/) ) {
$icon_down = 'icon-'+$match[1]+'-down'
$icon_up = 'icon-'+$match[1]+'-up'
}
var $match
var $icon_down = null
var $icon_up = null
if( ($icon_down = $icon.attr('data-icon-show')) ) {
$icon_up = $icon.attr('data-icon-hide')
}
else if( $match = $icon.attr('class').match(/icon\-(.*)\-(up|down)/) ) {
$icon_down = 'icon-'+$match[1]+'-down'
$icon_up = 'icon-'+$match[1]+'-up'
}
if($icon_down) {
if(ev.type == 'show') $icon.removeClass($icon_down).addClass($icon_up)
else $icon.removeClass($icon_up).addClass($icon_down)
if($icon_down) {
if(ev.type == 'show') $icon.removeClass($icon_down).addClass($icon_up)
else $icon.removeClass($icon_up).addClass($icon_down)
return false;//ignore other icons that match, one is enough
}
return false;//ignore other icons that match, one is enough
}
});
});
});
});
$(document).on('click.ace.widget', '[data-action]', function (ev) {
ev.preventDefault();
$(document).on('click.ace.widget', '[data-action]', function (ev) {
ev.preventDefault();
var $this = $(this);
var $action = $this.data('action');
var $box = $this.closest('.widget-box');
var $this = $(this);
var $action = $this.data('action');
var $box = $this.closest('.widget-box');
if($box.hasClass('ui-sortable-helper')) return;
if($box.hasClass('ui-sortable-helper')) return;
if($action == 'collapse') {
var event_name = $box.hasClass('collapsed') ? 'show' : 'hide';
var event_complete_name = event_name == 'show' ? 'shown' : 'hidden';
if($action == 'collapse') {
var event_name = $box.hasClass('collapsed') ? 'show' : 'hide';
var event_complete_name = event_name == 'show' ? 'shown' : 'hidden';
var event
$box.trigger(event = $.Event(event_name+'.ace.widget'))
if (event.isDefaultPrevented()) return
var event
$box.trigger(event = $.Event(event_name+'.ace.widget'))
if (event.isDefaultPrevented()) return
var $body = $box.find('.widget-body');
var $icon = $this.find('[class*=icon-]').eq(0);
var $match = $icon.attr('class').match(/icon\-(.*)\-(up|down)/);
var $icon_down = 'icon-'+$match[1]+'-down';
var $icon_up = 'icon-'+$match[1]+'-up';
var $body = $box.find('.widget-body');
var $icon = $this.find('[class*=icon-]').eq(0);
var $match = $icon.attr('class').match(/icon\-(.*)\-(up|down)/);
var $icon_down = 'icon-'+$match[1]+'-down';
var $icon_up = 'icon-'+$match[1]+'-up';
var $body_inner = $body.find('.widget-body-inner')
if($body_inner.length == 0) {
$body = $body.wrapInner('<div class="widget-body-inner"></div>').find(':first-child').eq(0);
} else $body = $body_inner.eq(0);
var $body_inner = $body.find('.widget-body-inner')
if($body_inner.length == 0) {
$body = $body.wrapInner('<div class="widget-body-inner"></div>').find(':first-child').eq(0);
} else $body = $body_inner.eq(0);
var expandSpeed = 300;
var collapseSpeed = 200;
var expandSpeed = 300;
var collapseSpeed = 200;
if( event_name == 'show' ) {
if($icon) $icon.addClass($icon_up).removeClass($icon_down);
$box.removeClass('collapsed');
$body.slideUp(0 , function(){$body.slideDown(expandSpeed, function(){$box.trigger(event = $.Event(event_complete_name+'.ace.widget'))})});
}
else {
if($icon) $icon.addClass($icon_down).removeClass($icon_up);
$body.slideUp(collapseSpeed, function(){$box.addClass('collapsed');$box.trigger(event = $.Event(event_complete_name+'.ace.widget'))});
}
if( event_name == 'show' ) {
if($icon) $icon.addClass($icon_up).removeClass($icon_down);
$box.removeClass('collapsed');
$body.slideUp(0 , function(){$body.slideDown(expandSpeed, function(){$box.trigger(event = $.Event(event_complete_name+'.ace.widget'))})});
}
else {
if($icon) $icon.addClass($icon_down).removeClass($icon_up);
$body.slideUp(collapseSpeed, function(){$box.addClass('collapsed');$box.trigger(event = $.Event(event_complete_name+'.ace.widget'))});
}
}
else if($action == 'close') {
var event
$box.trigger(event = $.Event('close.ace.widget'))
if (event.isDefaultPrevented()) return
}
else if($action == 'close') {
var event
$box.trigger(event = $.Event('close.ace.widget'))
if (event.isDefaultPrevented()) return
var closeSpeed = parseInt($this.data('close-speed')) || 300;
$box.hide(closeSpeed , function(){$box.trigger(event = $.Event('closed.ace.widget'));$box.remove();});
}
else if($action == 'reload') {
var event
$box.trigger(event = $.Event('reload.ace.widget'))
if (event.isDefaultPrevented()) return
var closeSpeed = parseInt($this.data('close-speed')) || 300;
$box.hide(closeSpeed , function(){$box.trigger(event = $.Event('closed.ace.widget'));$box.remove();});
}
else if($action == 'reload') {
var event
$box.trigger(event = $.Event('reload.ace.widget'))
if (event.isDefaultPrevented()) return
$this.blur();
$this.blur();
var $remove = false;
if($box.css('position') == 'static') {$remove = true; $box.addClass('position-relative');}
$box.append('<div class="widget-box-overlay"><i class="icon-spinner icon-spin icon-2x white"></i></div>');
var $remove = false;
if($box.css('position') == 'static') {$remove = true; $box.addClass('position-relative');}
$box.append('<div class="widget-box-overlay"><i class="icon-spinner icon-spin icon-2x white"></i></div>');
$box.one('reloaded.ace.widget', function() {
$box.find('.widget-box-overlay').remove();
if($remove) $box.removeClass('position-relative');
});
$box.one('reloaded.ace.widget', function() {
$box.find('.widget-box-overlay').remove();
if($remove) $box.removeClass('position-relative');
});
}
else if($action == 'settings') {
var event = $.Event('settings.ace.widget')
$box.trigger(event)
}
}
else if($action == 'settings') {
var event = $.Event('settings.ace.widget')
$box.trigger(event)
}
});
});
};
ace.widget_reload_handler = function($) {
//***default action for reload in this demo
//you should remove this and add your own handler for each specific .widget-box
//when data is finished loading or processing is done you can call $box.trigger('reloaded.ace.widget')
$(document).on('reload.ace.widget', '.widget-box', function (ev) {
var $box = $(this);
//trigger the reloaded event after 1-2 seconds
setTimeout(function() {
$box.trigger('reloaded.ace.widget');
}, parseInt(Math.random() * 1000 + 1000));
});
//***default action for reload in this demo
//you should remove this and add your own handler for each specific .widget-box
//when data is finished loading or processing is done you can call $box.trigger('reloaded.ace.widget')
$(document).on('reload.ace.widget', '.widget-box', function (ev) {
var $box = $(this);
//trigger the reloaded event after 1-2 seconds
setTimeout(function() {
$box.trigger('reloaded.ace.widget');
}, parseInt(Math.random() * 1000 + 1000));
});
//you may want to do something like this:
/**
$('#my-widget-box').on('reload.ace.widget', function(){
//load new data
//when finished trigger "reloaded"
$(this).trigger('reloaded.ace.widget');
});
*/
//you may want to do something like this:
/**
$('#my-widget-box').on('reload.ace.widget', function(){
//load new data
//when finished trigger "reloaded"
$(this).trigger('reloaded.ace.widget');
});
*/
};
//search box's dropdown autocomplete
ace.enable_search_ahead = function($) {
ace.variable_US_STATES = ["Alabama","Alaska","Arizona","Arkansas","California","Colorado","Connecticut","Delaware","Florida","Georgia","Hawaii","Idaho","Illinois","Indiana","Iowa","Kansas","Kentucky","Louisiana","Maine","Maryland","Massachusetts","Michigan","Minnesota","Mississippi","Missouri","Montana","Nebraska","Nevada","New Hampshire","New Jersey","New Mexico","New York","North Dakota","North Carolina","Ohio","Oklahoma","Oregon","Pennsylvania","Rhode Island","South Carolina","South Dakota","Tennessee","Texas","Utah","Vermont","Virginia","Washington","West Virginia","Wisconsin","Wyoming"]
ace.variable_US_STATES = ["Alabama","Alaska","Arizona","Arkansas","California","Colorado","Connecticut","Delaware","Florida","Georgia","Hawaii","Idaho","Illinois","Indiana","Iowa","Kansas","Kentucky","Louisiana","Maine","Maryland","Massachusetts","Michigan","Minnesota","Mississippi","Missouri","Montana","Nebraska","Nevada","New Hampshire","New Jersey","New Mexico","New York","North Dakota","North Carolina","Ohio","Oklahoma","Oregon","Pennsylvania","Rhode Island","South Carolina","South Dakota","Tennessee","Texas","Utah","Vermont","Virginia","Washington","West Virginia","Wisconsin","Wyoming"]
try {
$('#nav-search-input').typeahead({
source: ace.variable_US_STATES,
updater:function (item) {
$('#nav-search-input').focus();
return item;
}
});
} catch(e) {}
try {
$('#nav-search-input').typeahead({
source: ace.variable_US_STATES,
updater:function (item) {
$('#nav-search-input').focus();
return item;
}
});
} catch(e) {}
};
ace.switch_direction = function($) {
var $body = $(document.body);
$body
.toggleClass('rtl')
//toggle pull-right class on dropdown-menu
.find('.dropdown-menu:not(.datepicker-dropdown,.colorpicker)').toggleClass('pull-right')
.end()
//swap pull-left & pull-right
.find('.pull-right:not(.dropdown-menu,blockquote,.profile-skills .pull-right)').removeClass('pull-right').addClass('tmp-rtl-pull-right')
.end()
.find('.pull-left:not(.dropdown-submenu,.profile-skills .pull-left)').removeClass('pull-left').addClass('pull-right')
.end()
.find('.tmp-rtl-pull-right').removeClass('tmp-rtl-pull-right').addClass('pull-left')
.end()
var $body = $(document.body);
$body
.toggleClass('rtl')
//toggle pull-right class on dropdown-menu
.find('.dropdown-menu:not(.datepicker-dropdown,.colorpicker)').toggleClass('pull-right')
.end()
//swap pull-left & pull-right
.find('.pull-right:not(.dropdown-menu,blockquote,.profile-skills .pull-right)').removeClass('pull-right').addClass('tmp-rtl-pull-right')
.end()
.find('.pull-left:not(.dropdown-submenu,.profile-skills .pull-left)').removeClass('pull-left').addClass('pull-right')
.end()
.find('.tmp-rtl-pull-right').removeClass('tmp-rtl-pull-right').addClass('pull-left')
.end()
.find('.chosen-container').toggleClass('chosen-rtl')
.end()
.find('.chosen-container').toggleClass('chosen-rtl')
.end()
function swap_classes(class1, class2) {
$body
.find('.'+class1).removeClass(class1).addClass('tmp-rtl-'+class1)
.end()
.find('.'+class2).removeClass(class2).addClass(class1)
.end()
.find('.tmp-rtl-'+class1).removeClass('tmp-rtl-'+class1).addClass(class2)
}
function swap_styles(style1, style2, elements) {
elements.each(function(){
var e = $(this);
var tmp = e.css(style2);
e.css(style2 , e.css(style1));
e.css(style1 , tmp);
});
}
function swap_classes(class1, class2) {
$body
.find('.'+class1).removeClass(class1).addClass('tmp-rtl-'+class1)
.end()
.find('.'+class2).removeClass(class2).addClass(class1)
.end()
.find('.tmp-rtl-'+class1).removeClass('tmp-rtl-'+class1).addClass(class2)
}
function swap_styles(style1, style2, elements) {
elements.each(function(){
var e = $(this);
var tmp = e.css(style2);
e.css(style2 , e.css(style1));
e.css(style1 , tmp);
});
}
swap_classes('align-left', 'align-right');
swap_classes('no-padding-left', 'no-padding-right');
swap_classes('arrowed', 'arrowed-right');
swap_classes('arrowed-in', 'arrowed-in-right');
swap_classes('messagebar-item-left', 'messagebar-item-right');//for inbox page
swap_classes('align-left', 'align-right');
swap_classes('no-padding-left', 'no-padding-right');
swap_classes('arrowed', 'arrowed-right');
swap_classes('arrowed-in', 'arrowed-in-right');
swap_classes('messagebar-item-left', 'messagebar-item-right');//for inbox page
//redraw the traffic pie chart on homepage with a different parameter
var placeholder = $('#piechart-placeholder');
if(placeholder.size() > 0) {
var pos = $(document.body).hasClass('rtl') ? 'nw' : 'ne';//draw on north-west or north-east?
placeholder.data('draw').call(placeholder.get(0) , placeholder, placeholder.data('chart'), pos);
}
//redraw the traffic pie chart on homepage with a different parameter
var placeholder = $('#piechart-placeholder');
if(placeholder.size() > 0) {
var pos = $(document.body).hasClass('rtl') ? 'nw' : 'ne';//draw on north-west or north-east?
placeholder.data('draw').call(placeholder.get(0) , placeholder, placeholder.data('chart'), pos);
}
};
jQuery(function($) {
//ace.click_event defined in ace-elements.js
ace.handle_side_menu(jQuery);
//ace.click_event defined in ace-elements.js
ace.handle_side_menu(jQuery);
ace.enable_search_ahead(jQuery);
ace.enable_search_ahead(jQuery);
ace.general_things(jQuery);//and settings
ace.general_things(jQuery);//and settings
ace.widget_boxes(jQuery);
ace.widget_reload_handler(jQuery);//this is for demo only, you can remove and have your own function, please see examples/widget.html
ace.widget_boxes(jQuery);
ace.widget_reload_handler(jQuery);//this is for demo only, you can remove and have your own function, please see examples/widget.html
/**
//make sidebar scrollbar when it is fixed and some parts of it is out of view
//>> you should include jquery-ui and slimscroll javascript files in your file
//>> you can call this function when sidebar is clicked to be fixed
$('.nav-list').slimScroll({
height: '400px',
distance:0,
size : '6px'
});
*/
/**
//make sidebar scrollbar when it is fixed and some parts of it is out of view
//>> you should include jquery-ui and slimscroll javascript files in your file
//>> you can call this function when sidebar is clicked to be fixed
$('.nav-list').slimScroll({
height: '400px',
distance:0,
size : '6px'
});
*/
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
/**
* Created by fergalm on 11/12/13.
*/

View File

@@ -0,0 +1,574 @@
//
// Backbone-associations.js 0.5.4
//
// (c) 2013 Dhruva Ray, Jaynti Kanani, Persistent Systems Ltd.
// Backbone-associations may be freely distributed under the MIT license.
// For all details and documentation:
// https://github.com/dhruvaray/backbone-associations/
//
// Initial Setup
// --------------
(function () {
"use strict";
// Save a reference to the global object (`window` in the browser, `exports`
// on the server).
var root = this;
// The top-level namespace. All public Backbone classes and modules will be attached to this.
// Exported for the browser and CommonJS.
var _, Backbone, BackboneModel, BackboneCollection, ModelProto,
CollectionProto, defaultEvents, AssociatedModel, pathChecker,
collectionEvents, delimiters, pathSeparator;
if (typeof exports !== 'undefined') {
_ = require('underscore');
Backbone = require('backbone');
if (typeof module !== 'undefined' && module.exports) {
module.exports = Backbone;
}
exports = Backbone;
} else {
_ = root._;
Backbone = root.Backbone;
}
// Create local reference `Model` prototype.
BackboneModel = Backbone.Model;
BackboneCollection = Backbone.Collection;
ModelProto = BackboneModel.prototype;
CollectionProto = BackboneCollection.prototype;
// Built-in Backbone `events`.
defaultEvents = ["change", "add", "remove", "reset", "sort", "destroy"];
collectionEvents = ["reset", "sort"];
Backbone.Associations = {
VERSION: "0.5.4"
};
// Define `getter` and `setter` for `separator`
var getSeparator = function() {
return pathSeparator;
};
// Define `setSeperator`
var setSeparator = function(value) {
if (!_.isString(value) || _.size(value) < 1) {
value = ".";
}
// set private properties
pathSeparator = value;
pathChecker = new RegExp("[\\" + pathSeparator + "\\[\\]]+", "g");
delimiters = new RegExp("[^\\" + pathSeparator + "\\[\\]]+", "g");
};
try {
// Define `SEPERATOR` property to Backbone.Associations
Object.defineProperty(Backbone.Associations, 'SEPARATOR', {
enumerable: true,
get: getSeparator,
set: setSeparator
});
} catch (e) {}
// Backbone.AssociatedModel
// --------------
//Add `Many` and `One` relations to Backbone Object.
Backbone.Associations.Many = Backbone.Many = "Many";
Backbone.Associations.One = Backbone.One = "One";
Backbone.Associations.Self = Backbone.Self = "Self";
// Set default separator
Backbone.Associations.SEPARATOR = ".";
Backbone.Associations.getSeparator = getSeparator;
Backbone.Associations.setSeparator = setSeparator;
setSeparator();
// Define `AssociatedModel` (Extends Backbone.Model).
AssociatedModel = Backbone.AssociatedModel = Backbone.Associations.AssociatedModel = BackboneModel.extend({
// Define relations with Associated Model.
relations:undefined,
// Define `Model` property which can keep track of already fired `events`,
// and prevent redundant event to be triggered in case of cyclic model graphs.
_proxyCalls:undefined,
// Get the value of an attribute.
get:function (attr) {
var obj = ModelProto.get.call(this, attr);
return obj ? obj : this._getAttr.apply(this, arguments);
},
// Set a hash of model attributes on the Backbone Model.
set:function (key, value, options) {
var attributes, result;
// Duplicate backbone's behavior to allow separate key/value parameters,
// instead of a single 'attributes' object.
if (_.isObject(key) || key == null) {
attributes = key;
options = value;
} else {
attributes = {};
attributes[key] = value;
}
result = this._set(attributes, options);
// Trigger events which have been blocked until the entire object graph is updated.
this._processPendingEvents();
return result;
},
// Works with an attribute hash and options + fully qualified paths
_set:function (attributes, options) {
var attr, modelMap, modelId, obj, result = this;
if (!attributes) return this;
for (attr in attributes) {
//Create a map for each unique object whose attributes we want to set
modelMap || (modelMap = {});
if (attr.match(pathChecker)) {
var pathTokens = getPathArray(attr), initials = _.initial(pathTokens),
last = pathTokens[pathTokens.length - 1],
parentModel = this.get(initials);
if (parentModel instanceof AssociatedModel) {
obj = modelMap[parentModel.cid] || (modelMap[parentModel.cid] = {'model':parentModel, 'data':{}});
obj.data[last] = attributes[attr];
}
} else {
obj = modelMap[this.cid] || (modelMap[this.cid] = {'model':this, 'data':{}});
obj.data[attr] = attributes[attr];
}
}
if (modelMap) {
for (modelId in modelMap) {
obj = modelMap[modelId];
this._setAttr.call(obj.model, obj.data, options) || (result = false);
}
} else {
result = this._setAttr.call(this, attributes, options);
}
return result;
},
// Set a hash of model attributes on the object,
// fire Backbone `event` with options.
// It maintains relations between models during the set operation.
// It also bubbles up child events to the parent.
_setAttr:function (attributes, options) {
var attr;
// Extract attributes and options.
options || (options = {});
if (options.unset) for (attr in attributes) attributes[attr] = void 0;
this.parents = this.parents || [];
if (this.relations) {
// Iterate over `this.relations` and `set` model and collection values
// if `relations` are available.
_.each(this.relations, function (relation) {
var relationKey = relation.key,
relatedModel = relation.relatedModel,
collectionType = relation.collectionType,
map = relation.map,
currVal = this.attributes[relationKey],
idKey = currVal && currVal.idAttribute,
val, relationOptions, data, relationValue, newCtx = false;
// Call function if relatedModel is implemented as a function
if (relatedModel && !(relatedModel.prototype instanceof BackboneModel))
relatedModel = _.isFunction(relatedModel) ?
relatedModel.call(this, relation, attributes) :
relatedModel;
// Get class if relation and map is stored as a string.
if (relatedModel && _.isString(relatedModel)) {
relatedModel = (relatedModel === Backbone.Self) ? this.constructor : map2Scope(relatedModel);
}
collectionType && _.isString(collectionType) && (collectionType = map2Scope(collectionType));
map && _.isString(map) && (map = map2Scope(map));
// Merge in `options` specific to this relation.
relationOptions = relation.options ? _.extend({}, relation.options, options) : options;
if ((!relatedModel) && (!collectionType))
throw new Error('specify either a relatedModel or collectionType');
if (attributes[relationKey]) {
// Get value of attribute with relation key in `val`.
val = _.result(attributes, relationKey);
// Map `val` if a transformation function is provided.
val = map ? map.call(this, val, collectionType ? collectionType : relatedModel) : val;
// If `relation.type` is `Backbone.Many`,
// Create `Backbone.Collection` with passed data and perform Backbone `set`.
if (relation.type === Backbone.Many) {
// `collectionType` of defined `relation` should be instance of `Backbone.Collection`.
if (collectionType && !collectionType.prototype instanceof BackboneCollection) {
throw new Error('collectionType must inherit from Backbone.Collection');
}
if (currVal) {
// Setting this flag will prevent events from firing immediately. That way clients
// will not get events until the entire object graph is updated.
currVal._deferEvents = true;
// Use Backbone.Collection's `reset` or smart `set` method
currVal[relationOptions.reset ? 'reset' : 'set'](
val instanceof BackboneCollection ? val.models : val, relationOptions);
data = currVal;
} else {
newCtx = true;
if (val instanceof BackboneCollection) {
data = val;
} else {
data = collectionType ? new collectionType() : this._createCollection(relatedModel);
data[relationOptions.reset ? 'reset' : 'set'](val, relationOptions);
}
}
} else if (relation.type === Backbone.One) {
if (!relatedModel)
throw new Error('specify a relatedModel for Backbone.One type');
if (!(relatedModel.prototype instanceof Backbone.AssociatedModel))
throw new Error('specify an AssociatedModel for Backbone.One type');
data = val instanceof AssociatedModel ? val : new relatedModel(val, relationOptions);
//Is the passed in data for the same key?
if (currVal && data.attributes[idKey] &&
currVal.attributes[idKey] === data.attributes[idKey]) {
// Setting this flag will prevent events from firing immediately. That way clients
// will not get events until the entire object graph is updated.
currVal._deferEvents = true;
// Perform the traditional `set` operation
currVal._set(val instanceof AssociatedModel ? val.attributes : val, relationOptions);
data = currVal;
} else {
newCtx = true;
}
} else {
throw new Error('type attribute must be specified and have the values Backbone.One or Backbone.Many');
}
attributes[relationKey] = data;
relationValue = data;
// Add proxy events to respective parents.
// Only add callback if not defined or new Ctx has been identified.
if (newCtx || (relationValue && !relationValue._proxyCallback)) {
relationValue._proxyCallback = function () {
return this._bubbleEvent.call(this, relationKey, relationValue, arguments);
};
relationValue.on("all", relationValue._proxyCallback, this);
}
}
//Distinguish between the value of undefined versus a set no-op
if (attributes.hasOwnProperty(relationKey)) {
//Maintain reverse pointers - a.k.a parents
var updated = attributes[relationKey];
var original = this.attributes[relationKey];
if (updated) {
updated.parents = updated.parents || [];
(_.indexOf(updated.parents, this) == -1) && updated.parents.push(this);
} else if (original && original.parents.length > 0) { // New value is undefined
original.parents = _.difference(original.parents, [this]);
// Don't bubble to this parent anymore
original._proxyCallback && original.off("all", original._proxyCallback, this);
}
}
}, this);
}
// Return results for `BackboneModel.set`.
return ModelProto.set.call(this, attributes, options);
},
// Bubble-up event to `parent` Model
_bubbleEvent:function (relationKey, relationValue, eventArguments) {
var args = eventArguments,
opt = args[0].split(":"),
eventType = opt[0],
catch_all = args[0] == "nested-change",
eventObject = args[1],
colObject = args[2],
indexEventObject = -1,
_proxyCalls = relationValue._proxyCalls,
cargs,
eventPath,
basecolEventPath,
isDefaultEvent = _.indexOf(defaultEvents, eventType) !== -1;
//Short circuit the listen in to the nested-graph event
if (catch_all) return;
// Change the event name to a fully qualified path.
_.size(opt) > 1 && (eventPath = opt[1]);
if (_.indexOf(collectionEvents, eventType) !== -1) {
colObject = eventObject;
}
// Find the specific object in the collection which has changed.
if (relationValue instanceof BackboneCollection && isDefaultEvent && eventObject) {
var pathTokens = getPathArray(eventPath),
initialTokens = _.initial(pathTokens), colModel;
colModel = relationValue.find(function (model) {
if (eventObject === model) return true;
if (!model) return false;
var changedModel = model.get(initialTokens);
if ((changedModel instanceof AssociatedModel || changedModel instanceof BackboneCollection)
&& eventObject === changedModel)
return true;
changedModel = model.get(pathTokens);
if ((changedModel instanceof AssociatedModel || changedModel instanceof BackboneCollection)
&& eventObject === changedModel)
return true;
if (changedModel instanceof BackboneCollection && colObject
&& colObject === changedModel)
return true;
});
colModel && (indexEventObject = relationValue.indexOf(colModel));
}
// Manipulate `eventPath`.
eventPath = relationKey + ((indexEventObject !== -1 && (eventType === "change" || eventPath)) ?
"[" + indexEventObject + "]" : "") + (eventPath ? pathSeparator + eventPath : "");
// Short circuit collection * events
if (/\[\*\]/g.test(eventPath)) return this;
basecolEventPath = eventPath.replace(/\[\d+\]/g, '[*]');
cargs = [];
cargs.push.apply(cargs, args);
cargs[0] = eventType + ":" + eventPath;
// If event has been already triggered as result of same source `eventPath`,
// no need to re-trigger event to prevent cycle.
_proxyCalls = relationValue._proxyCalls = (_proxyCalls || {});
if (this._isEventAvailable.call(this, _proxyCalls, eventPath)) return this;
// Add `eventPath` in `_proxyCalls` to keep track of already triggered `event`.
_proxyCalls[eventPath] = true;
// Set up previous attributes correctly.
if ("change" === eventType) {
this._previousAttributes[relationKey] = relationValue._previousAttributes;
this.changed[relationKey] = relationValue;
}
// Bubble up event to parent `model` with new changed arguments.
this.trigger.apply(this, cargs);
//Only fire for change. Not change:attribute
if ("change" === eventType && this.get(eventPath) != args[2]) {
var ncargs = ["nested-change", eventPath, args[1]];
args[2] && ncargs.push(args[2]); //args[2] will be options if present
this.trigger.apply(this, ncargs);
}
// Remove `eventPath` from `_proxyCalls`,
// if `eventPath` and `_proxyCalls` are available,
// which allow event to be triggered on for next operation of `set`.
if (_proxyCalls && eventPath) delete _proxyCalls[eventPath];
// Create a collection modified event with wild-card
if (eventPath !== basecolEventPath) {
cargs[0] = eventType + ":" + basecolEventPath;
this.trigger.apply(this, cargs);
}
return this;
},
// Has event been fired from this source. Used to prevent event recursion in cyclic graphs
_isEventAvailable:function (_proxyCalls, path) {
return _.find(_proxyCalls, function (value, eventKey) {
return path.indexOf(eventKey, path.length - eventKey.length) !== -1;
});
},
// Returns New `collection` of type `relation.relatedModel`.
_createCollection:function (type) {
var collection, relatedModel = type;
_.isString(relatedModel) && (relatedModel = map2Scope(relatedModel));
// Creates new `Backbone.Collection` and defines model class.
if (relatedModel && (relatedModel.prototype instanceof AssociatedModel) || _.isFunction(relatedModel)) {
collection = new BackboneCollection();
collection.model = relatedModel;
} else {
throw new Error('type must inherit from Backbone.AssociatedModel');
}
return collection;
},
// Process all pending events after the entire object graph has been updated
_processPendingEvents:function () {
if (!this._processedEvents) {
this._processedEvents = true;
this._deferEvents = false;
// Trigger all pending events
_.each(this._pendingEvents, function (e) {
e.c.trigger.apply(e.c, e.a);
});
this._pendingEvents = [];
// Traverse down the object graph and call process pending events on sub-trees
_.each(this.relations, function (relation) {
var val = this.attributes[relation.key];
val && val._processPendingEvents();
}, this);
delete this._processedEvents;
}
},
// Override trigger to defer events in the object graph.
trigger:function (name) {
// Defer event processing
if (this._deferEvents) {
this._pendingEvents = this._pendingEvents || [];
// Maintain a queue of pending events to trigger after the entire object graph is updated.
this._pendingEvents.push({c:this, a:arguments});
} else {
ModelProto.trigger.apply(this, arguments);
}
},
// The JSON representation of the model.
toJSON:function (options) {
var json = {}, aJson;
json[this.idAttribute] = this.id;
if (!this.visited) {
this.visited = true;
// Get json representation from `BackboneModel.toJSON`.
json = ModelProto.toJSON.apply(this, arguments);
// If `this.relations` is defined, iterate through each `relation`
// and added it's json representation to parents' json representation.
if (this.relations) {
_.each(this.relations, function (relation) {
var attr = this.attributes[relation.key];
if (attr) {
aJson = attr.toJSON ? attr.toJSON(options) : attr;
json[relation.key] = _.isArray(aJson) ? _.compact(aJson) : aJson;
}
}, this);
}
delete this.visited;
}
return json;
},
// Create a new model with identical attributes to this one.
clone:function () {
return new this.constructor(this.toJSON());
},
// Call this if you want to set an `AssociatedModel` to a falsy value like undefined/null directly.
// Not calling this will leak memory and have wrong parents.
// See test case "parent relations"
cleanup:function () {
_.each(this.relations, function (relation) {
var val = this.attributes[relation.key];
val && (val.parents = _.difference(val.parents, [this]));
}, this);
this.off();
},
// Navigate the path to the leaf object in the path to query for the attribute value
_getAttr:function (path) {
var result = this,
//Tokenize the path
attrs = getPathArray(path),
key,
i;
if (_.size(attrs) < 1) return;
for (i = 0; i < attrs.length; i++) {
key = attrs[i];
if (!result) break;
//Navigate the path to get to the result
result = result instanceof BackboneCollection
? (isNaN(key) ? undefined : result.at(key))
: result.attributes[key];
}
return result;
}
});
// Tokenize the fully qualified event path
var getPathArray = function (path) {
if (path === '') return [''];
return _.isString(path) ? (path.match(delimiters)) : path || [];
};
var map2Scope = function (path) {
return _.reduce(path.split(pathSeparator), function (memo, elem) {
return memo[elem];
}, root);
};
//Infer the relation from the collection's parents and find the appropriate map for the passed in `models`
var map2models = function (parents, target, models) {
var relation, surrogate;
//Iterate over collection's parents
_.find(parents, function (parent) {
//Iterate over relations
relation = _.find(parent.relations, function (rel) {
return parent.get(rel.key) === target;
}, this);
if (relation) {
surrogate = parent;//surrogate for transformation
return true;//break;
}
}, this);
//If we found a relation and it has a mapping function
if (relation && relation.map) {
return relation.map.call(surrogate, models, target);
}
return models;
};
var proxies = {};
// Proxy Backbone collection methods
_.each(['set', 'remove', 'reset'], function (method) {
proxies[method] = BackboneCollection.prototype[method];
CollectionProto[method] = function (models, options) {
//Short-circuit if this collection doesn't hold `AssociatedModels`
if (this.model.prototype instanceof AssociatedModel && this.parents) {
//Find a map function if available and perform a transformation
arguments[0] = map2models(this.parents, this, models);
}
return proxies[method].apply(this, arguments);
}
});
// Override trigger to defer events in the object graph.
proxies['trigger'] = CollectionProto['trigger'];
CollectionProto['trigger'] = function (name) {
if (this._deferEvents) {
this._pendingEvents = this._pendingEvents || [];
// Maintain a queue of pending events to trigger after the entire object graph is updated.
this._pendingEvents.push({c:this, a:arguments});
} else {
proxies['trigger'].apply(this, arguments);
}
};
// Attach process pending event functionality on collections as well. Re-use from `AssociatedModel`
CollectionProto._processPendingEvents = AssociatedModel.prototype._processPendingEvents;
}).call(this);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -2,205 +2,205 @@
/*global jQuery, $, FileReader*/
/*jslint browser:true*/
(function ($) {
'use strict';
var readFileIntoDataUrl = function (fileInfo) {
var loader = $.Deferred(),
fReader = new FileReader();
fReader.onload = function (e) {
loader.resolve(e.target.result);
};
fReader.onerror = loader.reject;
fReader.onprogress = loader.notify;
fReader.readAsDataURL(fileInfo);
return loader.promise();
};
$.fn.cleanHtml = function () {
var html = $(this).html();
return html && html.replace(/(<br>|\s|<div><br><\/div>|&nbsp;)*$/, '');
};
$.fn.wysiwyg = function (userOptions) {
var editor = this,
selectedRange,
options,
toolbarBtnSelector,
updateToolbar = function () {
if (options.activeToolbarClass) {
$(options.toolbarSelector).find(toolbarBtnSelector).each(function () {
try {
var command = $(this).data(options.commandRole);
if (document.queryCommandState(command)) {
$(this).addClass(options.activeToolbarClass);
} else {
$(this).removeClass(options.activeToolbarClass);
}
} catch(e){}
});
}
},
execCommand = function (commandWithArgs, valueArg) {
var commandArr = commandWithArgs.split(' '),
command = commandArr.shift(),
args = commandArr.join(' ') + (valueArg || '');
document.execCommand(command, 0, args);
updateToolbar();
},
bindHotkeys = function (hotKeys) {
$.each(hotKeys, function (hotkey, command) {
editor.keydown(hotkey, function (e) {
if (editor.attr('contenteditable') && editor.is(':visible')) {
e.preventDefault();
e.stopPropagation();
execCommand(command);
}
}).keyup(hotkey, function (e) {
if (editor.attr('contenteditable') && editor.is(':visible')) {
e.preventDefault();
e.stopPropagation();
}
});
});
},
getCurrentRange = function () {
try {
var sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
return sel.getRangeAt(0);
}
} catch(e){}
},
saveSelection = function () {
selectedRange = getCurrentRange();
},
restoreSelection = function () {
try {
var selection = window.getSelection();
if (selectedRange) {
try {
selection.removeAllRanges();
} catch (ex) {
document.body.createTextRange().select();
document.selection.empty();
}
'use strict';
var readFileIntoDataUrl = function (fileInfo) {
var loader = $.Deferred(),
fReader = new FileReader();
fReader.onload = function (e) {
loader.resolve(e.target.result);
};
fReader.onerror = loader.reject;
fReader.onprogress = loader.notify;
fReader.readAsDataURL(fileInfo);
return loader.promise();
};
$.fn.cleanHtml = function () {
var html = $(this).html();
return html && html.replace(/(<br>|\s|<div><br><\/div>|&nbsp;)*$/, '');
};
$.fn.wysiwyg = function (userOptions) {
var editor = this,
selectedRange,
options,
toolbarBtnSelector,
updateToolbar = function () {
if (options.activeToolbarClass) {
$(options.toolbarSelector).find(toolbarBtnSelector).each(function () {
try {
var command = $(this).data(options.commandRole);
if (document.queryCommandState(command)) {
$(this).addClass(options.activeToolbarClass);
} else {
$(this).removeClass(options.activeToolbarClass);
}
} catch(e){}
});
}
},
execCommand = function (commandWithArgs, valueArg) {
var commandArr = commandWithArgs.split(' '),
command = commandArr.shift(),
args = commandArr.join(' ') + (valueArg || '');
document.execCommand(command, 0, args);
updateToolbar();
},
bindHotkeys = function (hotKeys) {
$.each(hotKeys, function (hotkey, command) {
editor.keydown(hotkey, function (e) {
if (editor.attr('contenteditable') && editor.is(':visible')) {
e.preventDefault();
e.stopPropagation();
execCommand(command);
}
}).keyup(hotkey, function (e) {
if (editor.attr('contenteditable') && editor.is(':visible')) {
e.preventDefault();
e.stopPropagation();
}
});
});
},
getCurrentRange = function () {
try {
var sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
return sel.getRangeAt(0);
}
} catch(e){}
},
saveSelection = function () {
selectedRange = getCurrentRange();
},
restoreSelection = function () {
try {
var selection = window.getSelection();
if (selectedRange) {
try {
selection.removeAllRanges();
} catch (ex) {
document.body.createTextRange().select();
document.selection.empty();
}
selection.addRange(selectedRange);
}
} catch(e){}
},
insertFiles = function (files) {
editor.focus();
$.each(files, function (idx, fileInfo) {
if (/^image\//.test(fileInfo.type)) {
$.when(readFileIntoDataUrl(fileInfo)).done(function (dataUrl) {
execCommand('insertimage', dataUrl);
}).fail(function (e) {
options.fileUploadError("file-reader", e);
});
} else {
options.fileUploadError("unsupported-file-type", fileInfo.type);
}
});
},
markSelection = function (input, color) {
restoreSelection();
if (document.queryCommandSupported('hiliteColor')) {
document.execCommand('hiliteColor', 0, color || 'transparent');
}
saveSelection();
input.data(options.selectionMarker, color);
},
bindToolbar = function (toolbar, options) {
toolbar.find(toolbarBtnSelector).click(function () {
restoreSelection();
editor.focus();
execCommand($(this).data(options.commandRole));
saveSelection();
});
toolbar.find('[data-toggle=dropdown]').click(restoreSelection);
selection.addRange(selectedRange);
}
} catch(e){}
},
insertFiles = function (files) {
editor.focus();
$.each(files, function (idx, fileInfo) {
if (/^image\//.test(fileInfo.type)) {
$.when(readFileIntoDataUrl(fileInfo)).done(function (dataUrl) {
execCommand('insertimage', dataUrl);
}).fail(function (e) {
options.fileUploadError("file-reader", e);
});
} else {
options.fileUploadError("unsupported-file-type", fileInfo.type);
}
});
},
markSelection = function (input, color) {
restoreSelection();
if (document.queryCommandSupported('hiliteColor')) {
document.execCommand('hiliteColor', 0, color || 'transparent');
}
saveSelection();
input.data(options.selectionMarker, color);
},
bindToolbar = function (toolbar, options) {
toolbar.find(toolbarBtnSelector).click(function () {
restoreSelection();
editor.focus();
execCommand($(this).data(options.commandRole));
saveSelection();
});
toolbar.find('[data-toggle=dropdown]').click(restoreSelection);
toolbar.find('input[type=text][data-' + options.commandRole + ']').on('webkitspeechchange change', function () {
var newValue = this.value; /* ugly but prevents fake double-calls due to selection restoration */
this.value = '';
restoreSelection();
if (newValue) {
editor.focus();
execCommand($(this).data(options.commandRole), newValue);
}
saveSelection();
}).on('focus', function () {
var input = $(this);
if (!input.data(options.selectionMarker)) {
markSelection(input, options.selectionColor);
input.focus();
}
}).on('blur', function () {
var input = $(this);
if (input.data(options.selectionMarker)) {
markSelection(input, false);
}
});
toolbar.find('input[type=file][data-' + options.commandRole + ']').change(function () {
restoreSelection();
if (this.type === 'file' && this.files && this.files.length > 0) {
insertFiles(this.files);
}
saveSelection();
this.value = '';
});
},
initFileDrops = function () {
editor.on('dragenter dragover', false)
.on('drop', function (e) {
var dataTransfer = e.originalEvent.dataTransfer;
e.stopPropagation();
e.preventDefault();
if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) {
insertFiles(dataTransfer.files);
}
});
};
options = $.extend({}, $.fn.wysiwyg.defaults, userOptions);
toolbarBtnSelector = 'a[data-' + options.commandRole + '],button[data-' + options.commandRole + '],input[type=button][data-' + options.commandRole + ']';
bindHotkeys(options.hotKeys);
if (options.dragAndDropImages) {
initFileDrops();
}
bindToolbar($(options.toolbarSelector), options);
editor.attr('contenteditable', true)
.on('mouseup keyup mouseout', function () {
saveSelection();
updateToolbar();
});
$(window).bind('touchend', function (e) {
var isInside = (editor.is(e.target) || editor.has(e.target).length > 0),
currentRange = getCurrentRange(),
clear = currentRange && (currentRange.startContainer === currentRange.endContainer && currentRange.startOffset === currentRange.endOffset);
if (!clear || isInside) {
saveSelection();
updateToolbar();
}
});
return this;
};
$.fn.wysiwyg.defaults = {
hotKeys: {
'ctrl+b meta+b': 'bold',
'ctrl+i meta+i': 'italic',
'ctrl+u meta+u': 'underline',
'ctrl+z meta+z': 'undo',
'ctrl+y meta+y meta+shift+z': 'redo',
'ctrl+l meta+l': 'justifyleft',
'ctrl+r meta+r': 'justifyright',
'ctrl+e meta+e': 'justifycenter',
'ctrl+j meta+j': 'justifyfull',
'shift+tab': 'outdent',
'tab': 'indent'
},
toolbarSelector: '[data-role=editor-toolbar]',
commandRole: 'edit',
activeToolbarClass: 'btn-info',
selectionMarker: 'edit-focus-marker',
selectionColor: 'darkgrey',
dragAndDropImages: true,
fileUploadError: function (reason, detail) { console.log("File upload error", reason, detail); }
};
toolbar.find('input[type=text][data-' + options.commandRole + ']').on('webkitspeechchange change', function () {
var newValue = this.value; /* ugly but prevents fake double-calls due to selection restoration */
this.value = '';
restoreSelection();
if (newValue) {
editor.focus();
execCommand($(this).data(options.commandRole), newValue);
}
saveSelection();
}).on('focus', function () {
var input = $(this);
if (!input.data(options.selectionMarker)) {
markSelection(input, options.selectionColor);
input.focus();
}
}).on('blur', function () {
var input = $(this);
if (input.data(options.selectionMarker)) {
markSelection(input, false);
}
});
toolbar.find('input[type=file][data-' + options.commandRole + ']').change(function () {
restoreSelection();
if (this.type === 'file' && this.files && this.files.length > 0) {
insertFiles(this.files);
}
saveSelection();
this.value = '';
});
},
initFileDrops = function () {
editor.on('dragenter dragover', false)
.on('drop', function (e) {
var dataTransfer = e.originalEvent.dataTransfer;
e.stopPropagation();
e.preventDefault();
if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) {
insertFiles(dataTransfer.files);
}
});
};
options = $.extend({}, $.fn.wysiwyg.defaults, userOptions);
toolbarBtnSelector = 'a[data-' + options.commandRole + '],button[data-' + options.commandRole + '],input[type=button][data-' + options.commandRole + ']';
bindHotkeys(options.hotKeys);
if (options.dragAndDropImages) {
initFileDrops();
}
bindToolbar($(options.toolbarSelector), options);
editor.attr('contenteditable', true)
.on('mouseup keyup mouseout', function () {
saveSelection();
updateToolbar();
});
$(window).bind('touchend', function (e) {
var isInside = (editor.is(e.target) || editor.has(e.target).length > 0),
currentRange = getCurrentRange(),
clear = currentRange && (currentRange.startContainer === currentRange.endContainer && currentRange.startOffset === currentRange.endOffset);
if (!clear || isInside) {
saveSelection();
updateToolbar();
}
});
return this;
};
$.fn.wysiwyg.defaults = {
hotKeys: {
'ctrl+b meta+b': 'bold',
'ctrl+i meta+i': 'italic',
'ctrl+u meta+u': 'underline',
'ctrl+z meta+z': 'undo',
'ctrl+y meta+y meta+shift+z': 'redo',
'ctrl+l meta+l': 'justifyleft',
'ctrl+r meta+r': 'justifyright',
'ctrl+e meta+e': 'justifycenter',
'ctrl+j meta+j': 'justifyfull',
'shift+tab': 'outdent',
'tab': 'indent'
},
toolbarSelector: '[data-role=editor-toolbar]',
commandRole: 'edit',
activeToolbarClass: 'btn-info',
selectionMarker: 'edit-focus-marker',
selectionColor: 'darkgrey',
dragAndDropImages: true,
fileUploadError: function (reason, detail) { console.log("File upload error", reason, detail); }
};
}(window.jQuery));

View File

@@ -17,97 +17,97 @@
(function(jQuery){
jQuery.hotkeys = {
version: "0.8",
jQuery.hotkeys = {
version: "0.8",
specialKeys: {
8: "backspace", 9: "tab", 10: "return", 13: "return", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause",
20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home",
37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "del",
96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7",
104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".", 111 : "/",
112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8",
120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scroll", 186: ";", 191: "/",
220: "\\", 222: "'", 224: "meta"
},
specialKeys: {
8: "backspace", 9: "tab", 10: "return", 13: "return", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause",
20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home",
37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "del",
96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7",
104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".", 111 : "/",
112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8",
120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scroll", 186: ";", 191: "/",
220: "\\", 222: "'", 224: "meta"
},
shiftNums: {
"`": "~", "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&",
"8": "*", "9": "(", "0": ")", "-": "_", "=": "+", ";": ": ", "'": "\"", ",": "<",
".": ">", "/": "?", "\\": "|"
}
};
shiftNums: {
"`": "~", "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&",
"8": "*", "9": "(", "0": ")", "-": "_", "=": "+", ";": ": ", "'": "\"", ",": "<",
".": ">", "/": "?", "\\": "|"
}
};
function keyHandler( handleObj ) {
if (typeof handleObj.data == 'undefined') return;
function keyHandler( handleObj ) {
if (typeof handleObj.data == 'undefined') return;
if ( typeof handleObj.data === "string" ) {
handleObj.data = { keys: handleObj.data };
}
if ( typeof handleObj.data === "string" ) {
handleObj.data = { keys: handleObj.data };
}
// Only care when a possible input has been specified
if ( !handleObj.data || !handleObj.data.keys || typeof handleObj.data.keys !== "string" ) {
return;
}
// Only care when a possible input has been specified
if ( !handleObj.data || !handleObj.data.keys || typeof handleObj.data.keys !== "string" ) {
return;
}
var origHandler = handleObj.handler,
keys = handleObj.data.keys.toLowerCase().split(" "),
textAcceptingInputTypes = ["text", "password", "number", "email", "url", "range", "date", "month", "week", "time", "datetime", "datetime-local", "search", "color", "tel"];
var origHandler = handleObj.handler,
keys = handleObj.data.keys.toLowerCase().split(" "),
textAcceptingInputTypes = ["text", "password", "number", "email", "url", "range", "date", "month", "week", "time", "datetime", "datetime-local", "search", "color", "tel"];
handleObj.handler = function( event ) {
// Don't fire in text-accepting inputs that we didn't directly bind to
if ( this !== event.target && (/textarea|select/i.test( event.target.nodeName ) ||
jQuery.inArray(event.target.type, textAcceptingInputTypes) > -1 ) ) {
return;
}
handleObj.handler = function( event ) {
// Don't fire in text-accepting inputs that we didn't directly bind to
if ( this !== event.target && (/textarea|select/i.test( event.target.nodeName ) ||
jQuery.inArray(event.target.type, textAcceptingInputTypes) > -1 ) ) {
return;
}
var special = jQuery.hotkeys.specialKeys[ event.keyCode ],
// character codes are available only in keypress
character = (event.type === "keydown" || event.type === "keypress") && String.fromCharCode( event.which ).toLowerCase()
modif = "", possible = {};
var special = jQuery.hotkeys.specialKeys[ event.keyCode ],
// character codes are available only in keypress
character = (event.type === "keydown" || event.type === "keypress") && String.fromCharCode( event.which ).toLowerCase()
modif = "", possible = {};
// check combinations (alt|ctrl|shift+anything)
if ( event.altKey && special !== "alt" ) {
modif += "alt+";
}
// check combinations (alt|ctrl|shift+anything)
if ( event.altKey && special !== "alt" ) {
modif += "alt+";
}
if ( event.ctrlKey && special !== "ctrl" ) {
modif += "ctrl+";
}
if ( event.ctrlKey && special !== "ctrl" ) {
modif += "ctrl+";
}
// TODO: Need to make sure this works consistently across platforms
if ( event.metaKey && !event.ctrlKey && special !== "meta" ) {
modif += "meta+";
}
// TODO: Need to make sure this works consistently across platforms
if ( event.metaKey && !event.ctrlKey && special !== "meta" ) {
modif += "meta+";
}
if ( event.shiftKey && special !== "shift" ) {
modif += "shift+";
}
if ( event.shiftKey && special !== "shift" ) {
modif += "shift+";
}
if ( special ) {
possible[ modif + special ] = true;
}
if ( special ) {
possible[ modif + special ] = true;
}
if ( character ) {
possible[ modif + character ] = true;
possible[ modif + jQuery.hotkeys.shiftNums[ character ] ] = true;
if ( character ) {
possible[ modif + character ] = true;
possible[ modif + jQuery.hotkeys.shiftNums[ character ] ] = true;
// "$" can be triggered as "Shift+4" or "Shift+$" or just "$"
if ( modif === "shift+" ) {
possible[ jQuery.hotkeys.shiftNums[ character ] ] = true;
}
}
// "$" can be triggered as "Shift+4" or "Shift+$" or just "$"
if ( modif === "shift+" ) {
possible[ jQuery.hotkeys.shiftNums[ character ] ] = true;
}
}
for ( var i = 0, l = keys.length; i < l; i++ ) {
if ( possible[ keys[i] ] ) {
return origHandler.apply( this, arguments );
}
}
};
}
for ( var i = 0, l = keys.length; i < l; i++ ) {
if ( possible[ keys[i] ] ) {
return origHandler.apply( this, arguments );
}
}
};
}
jQuery.each([ "keydown", "keyup", "keypress" ], function() {
jQuery.event.special[ this ] = { add: keyHandler };
});
jQuery.each([ "keydown", "keyup", "keypress" ], function() {
jQuery.event.special[ this ] = { add: keyHandler };
});
})( this.jQuery );

14480
static/js/lib/jquery.js vendored

File diff suppressed because it is too large Load Diff

View File

@@ -20,511 +20,511 @@
}(function( $, undefined ) {
var uuid = 0,
slice = Array.prototype.slice,
_cleanData = $.cleanData;
slice = Array.prototype.slice,
_cleanData = $.cleanData;
$.cleanData = function( elems ) {
for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
try {
$( elem ).triggerHandler( "remove" );
// http://bugs.jquery.com/ticket/8235
} catch( e ) {}
}
_cleanData( elems );
for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
try {
$( elem ).triggerHandler( "remove" );
// http://bugs.jquery.com/ticket/8235
} catch( e ) {}
}
_cleanData( elems );
};
$.widget = function( name, base, prototype ) {
var fullName, existingConstructor, constructor, basePrototype,
// proxiedPrototype allows the provided prototype to remain unmodified
// so that it can be used as a mixin for multiple widgets (#8876)
proxiedPrototype = {},
namespace = name.split( "." )[ 0 ];
var fullName, existingConstructor, constructor, basePrototype,
// proxiedPrototype allows the provided prototype to remain unmodified
// so that it can be used as a mixin for multiple widgets (#8876)
proxiedPrototype = {},
namespace = name.split( "." )[ 0 ];
name = name.split( "." )[ 1 ];
fullName = namespace + "-" + name;
name = name.split( "." )[ 1 ];
fullName = namespace + "-" + name;
if ( !prototype ) {
prototype = base;
base = $.Widget;
}
if ( !prototype ) {
prototype = base;
base = $.Widget;
}
// create selector for plugin
$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
return !!$.data( elem, fullName );
};
// create selector for plugin
$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
return !!$.data( elem, fullName );
};
$[ namespace ] = $[ namespace ] || {};
existingConstructor = $[ namespace ][ name ];
constructor = $[ namespace ][ name ] = function( options, element ) {
// allow instantiation without "new" keyword
if ( !this._createWidget ) {
return new constructor( options, element );
}
$[ namespace ] = $[ namespace ] || {};
existingConstructor = $[ namespace ][ name ];
constructor = $[ namespace ][ name ] = function( options, element ) {
// allow instantiation without "new" keyword
if ( !this._createWidget ) {
return new constructor( options, element );
}
// allow instantiation without initializing for simple inheritance
// must use "new" keyword (the code above always passes args)
if ( arguments.length ) {
this._createWidget( options, element );
}
};
// extend with the existing constructor to carry over any static properties
$.extend( constructor, existingConstructor, {
version: prototype.version,
// copy the object used to create the prototype in case we need to
// redefine the widget later
_proto: $.extend( {}, prototype ),
// track widgets that inherit from this widget in case this widget is
// redefined after a widget inherits from it
_childConstructors: []
});
// allow instantiation without initializing for simple inheritance
// must use "new" keyword (the code above always passes args)
if ( arguments.length ) {
this._createWidget( options, element );
}
};
// extend with the existing constructor to carry over any static properties
$.extend( constructor, existingConstructor, {
version: prototype.version,
// copy the object used to create the prototype in case we need to
// redefine the widget later
_proto: $.extend( {}, prototype ),
// track widgets that inherit from this widget in case this widget is
// redefined after a widget inherits from it
_childConstructors: []
});
basePrototype = new base();
// we need to make the options hash a property directly on the new instance
// otherwise we'll modify the options hash on the prototype that we're
// inheriting from
basePrototype.options = $.widget.extend( {}, basePrototype.options );
$.each( prototype, function( prop, value ) {
if ( !$.isFunction( value ) ) {
proxiedPrototype[ prop ] = value;
return;
}
proxiedPrototype[ prop ] = (function() {
var _super = function() {
return base.prototype[ prop ].apply( this, arguments );
},
_superApply = function( args ) {
return base.prototype[ prop ].apply( this, args );
};
return function() {
var __super = this._super,
__superApply = this._superApply,
returnValue;
basePrototype = new base();
// we need to make the options hash a property directly on the new instance
// otherwise we'll modify the options hash on the prototype that we're
// inheriting from
basePrototype.options = $.widget.extend( {}, basePrototype.options );
$.each( prototype, function( prop, value ) {
if ( !$.isFunction( value ) ) {
proxiedPrototype[ prop ] = value;
return;
}
proxiedPrototype[ prop ] = (function() {
var _super = function() {
return base.prototype[ prop ].apply( this, arguments );
},
_superApply = function( args ) {
return base.prototype[ prop ].apply( this, args );
};
return function() {
var __super = this._super,
__superApply = this._superApply,
returnValue;
this._super = _super;
this._superApply = _superApply;
this._super = _super;
this._superApply = _superApply;
returnValue = value.apply( this, arguments );
returnValue = value.apply( this, arguments );
this._super = __super;
this._superApply = __superApply;
this._super = __super;
this._superApply = __superApply;
return returnValue;
};
})();
});
constructor.prototype = $.widget.extend( basePrototype, {
// TODO: remove support for widgetEventPrefix
// always use the name + a colon as the prefix, e.g., draggable:start
// don't prefix for widgets that aren't DOM-based
widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
}, proxiedPrototype, {
constructor: constructor,
namespace: namespace,
widgetName: name,
widgetFullName: fullName
});
return returnValue;
};
})();
});
constructor.prototype = $.widget.extend( basePrototype, {
// TODO: remove support for widgetEventPrefix
// always use the name + a colon as the prefix, e.g., draggable:start
// don't prefix for widgets that aren't DOM-based
widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
}, proxiedPrototype, {
constructor: constructor,
namespace: namespace,
widgetName: name,
widgetFullName: fullName
});
// If this widget is being redefined then we need to find all widgets that
// are inheriting from it and redefine all of them so that they inherit from
// the new version of this widget. We're essentially trying to replace one
// level in the prototype chain.
if ( existingConstructor ) {
$.each( existingConstructor._childConstructors, function( i, child ) {
var childPrototype = child.prototype;
// If this widget is being redefined then we need to find all widgets that
// are inheriting from it and redefine all of them so that they inherit from
// the new version of this widget. We're essentially trying to replace one
// level in the prototype chain.
if ( existingConstructor ) {
$.each( existingConstructor._childConstructors, function( i, child ) {
var childPrototype = child.prototype;
// redefine the child widget using the same prototype that was
// originally used, but inherit from the new version of the base
$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
});
// remove the list of existing child constructors from the old constructor
// so the old child constructors can be garbage collected
delete existingConstructor._childConstructors;
} else {
base._childConstructors.push( constructor );
}
// redefine the child widget using the same prototype that was
// originally used, but inherit from the new version of the base
$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
});
// remove the list of existing child constructors from the old constructor
// so the old child constructors can be garbage collected
delete existingConstructor._childConstructors;
} else {
base._childConstructors.push( constructor );
}
$.widget.bridge( name, constructor );
$.widget.bridge( name, constructor );
};
$.widget.extend = function( target ) {
var input = slice.call( arguments, 1 ),
inputIndex = 0,
inputLength = input.length,
key,
value;
for ( ; inputIndex < inputLength; inputIndex++ ) {
for ( key in input[ inputIndex ] ) {
value = input[ inputIndex ][ key ];
if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
// Clone objects
if ( $.isPlainObject( value ) ) {
target[ key ] = $.isPlainObject( target[ key ] ) ?
$.widget.extend( {}, target[ key ], value ) :
// Don't extend strings, arrays, etc. with objects
$.widget.extend( {}, value );
// Copy everything else by reference
} else {
target[ key ] = value;
}
}
}
}
return target;
var input = slice.call( arguments, 1 ),
inputIndex = 0,
inputLength = input.length,
key,
value;
for ( ; inputIndex < inputLength; inputIndex++ ) {
for ( key in input[ inputIndex ] ) {
value = input[ inputIndex ][ key ];
if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
// Clone objects
if ( $.isPlainObject( value ) ) {
target[ key ] = $.isPlainObject( target[ key ] ) ?
$.widget.extend( {}, target[ key ], value ) :
// Don't extend strings, arrays, etc. with objects
$.widget.extend( {}, value );
// Copy everything else by reference
} else {
target[ key ] = value;
}
}
}
}
return target;
};
$.widget.bridge = function( name, object ) {
var fullName = object.prototype.widgetFullName || name;
$.fn[ name ] = function( options ) {
var isMethodCall = typeof options === "string",
args = slice.call( arguments, 1 ),
returnValue = this;
var fullName = object.prototype.widgetFullName || name;
$.fn[ name ] = function( options ) {
var isMethodCall = typeof options === "string",
args = slice.call( arguments, 1 ),
returnValue = this;
// allow multiple hashes to be passed on init
options = !isMethodCall && args.length ?
$.widget.extend.apply( null, [ options ].concat(args) ) :
options;
// allow multiple hashes to be passed on init
options = !isMethodCall && args.length ?
$.widget.extend.apply( null, [ options ].concat(args) ) :
options;
if ( isMethodCall ) {
this.each(function() {
var methodValue,
instance = $.data( this, fullName );
if ( !instance ) {
return $.error( "cannot call methods on " + name + " prior to initialization; " +
"attempted to call method '" + options + "'" );
}
if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
return $.error( "no such method '" + options + "' for " + name + " widget instance" );
}
methodValue = instance[ options ].apply( instance, args );
if ( methodValue !== instance && methodValue !== undefined ) {
returnValue = methodValue && methodValue.jquery ?
returnValue.pushStack( methodValue.get() ) :
methodValue;
return false;
}
});
} else {
this.each(function() {
var instance = $.data( this, fullName );
if ( instance ) {
instance.option( options || {} )._init();
} else {
$.data( this, fullName, new object( options, this ) );
}
});
}
if ( isMethodCall ) {
this.each(function() {
var methodValue,
instance = $.data( this, fullName );
if ( !instance ) {
return $.error( "cannot call methods on " + name + " prior to initialization; " +
"attempted to call method '" + options + "'" );
}
if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
return $.error( "no such method '" + options + "' for " + name + " widget instance" );
}
methodValue = instance[ options ].apply( instance, args );
if ( methodValue !== instance && methodValue !== undefined ) {
returnValue = methodValue && methodValue.jquery ?
returnValue.pushStack( methodValue.get() ) :
methodValue;
return false;
}
});
} else {
this.each(function() {
var instance = $.data( this, fullName );
if ( instance ) {
instance.option( options || {} )._init();
} else {
$.data( this, fullName, new object( options, this ) );
}
});
}
return returnValue;
};
return returnValue;
};
};
$.Widget = function( /* options, element */ ) {};
$.Widget._childConstructors = [];
$.Widget.prototype = {
widgetName: "widget",
widgetEventPrefix: "",
defaultElement: "<div>",
options: {
disabled: false,
widgetName: "widget",
widgetEventPrefix: "",
defaultElement: "<div>",
options: {
disabled: false,
// callbacks
create: null
},
_createWidget: function( options, element ) {
element = $( element || this.defaultElement || this )[ 0 ];
this.element = $( element );
this.uuid = uuid++;
this.eventNamespace = "." + this.widgetName + this.uuid;
this.options = $.widget.extend( {},
this.options,
this._getCreateOptions(),
options );
// callbacks
create: null
},
_createWidget: function( options, element ) {
element = $( element || this.defaultElement || this )[ 0 ];
this.element = $( element );
this.uuid = uuid++;
this.eventNamespace = "." + this.widgetName + this.uuid;
this.options = $.widget.extend( {},
this.options,
this._getCreateOptions(),
options );
this.bindings = $();
this.hoverable = $();
this.focusable = $();
this.bindings = $();
this.hoverable = $();
this.focusable = $();
if ( element !== this ) {
$.data( element, this.widgetFullName, this );
this._on( true, this.element, {
remove: function( event ) {
if ( event.target === element ) {
this.destroy();
}
}
});
this.document = $( element.style ?
// element within the document
element.ownerDocument :
// element is window or document
element.document || element );
this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
}
if ( element !== this ) {
$.data( element, this.widgetFullName, this );
this._on( true, this.element, {
remove: function( event ) {
if ( event.target === element ) {
this.destroy();
}
}
});
this.document = $( element.style ?
// element within the document
element.ownerDocument :
// element is window or document
element.document || element );
this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
}
this._create();
this._trigger( "create", null, this._getCreateEventData() );
this._init();
},
_getCreateOptions: $.noop,
_getCreateEventData: $.noop,
_create: $.noop,
_init: $.noop,
this._create();
this._trigger( "create", null, this._getCreateEventData() );
this._init();
},
_getCreateOptions: $.noop,
_getCreateEventData: $.noop,
_create: $.noop,
_init: $.noop,
destroy: function() {
this._destroy();
// we can probably remove the unbind calls in 2.0
// all event bindings should go through this._on()
this.element
.unbind( this.eventNamespace )
// 1.9 BC for #7810
// TODO remove dual storage
.removeData( this.widgetName )
.removeData( this.widgetFullName )
// support: jquery <1.6.3
// http://bugs.jquery.com/ticket/9413
.removeData( $.camelCase( this.widgetFullName ) );
this.widget()
.unbind( this.eventNamespace )
.removeAttr( "aria-disabled" )
.removeClass(
this.widgetFullName + "-disabled " +
"ui-state-disabled" );
destroy: function() {
this._destroy();
// we can probably remove the unbind calls in 2.0
// all event bindings should go through this._on()
this.element
.unbind( this.eventNamespace )
// 1.9 BC for #7810
// TODO remove dual storage
.removeData( this.widgetName )
.removeData( this.widgetFullName )
// support: jquery <1.6.3
// http://bugs.jquery.com/ticket/9413
.removeData( $.camelCase( this.widgetFullName ) );
this.widget()
.unbind( this.eventNamespace )
.removeAttr( "aria-disabled" )
.removeClass(
this.widgetFullName + "-disabled " +
"ui-state-disabled" );
// clean up events and states
this.bindings.unbind( this.eventNamespace );
this.hoverable.removeClass( "ui-state-hover" );
this.focusable.removeClass( "ui-state-focus" );
},
_destroy: $.noop,
// clean up events and states
this.bindings.unbind( this.eventNamespace );
this.hoverable.removeClass( "ui-state-hover" );
this.focusable.removeClass( "ui-state-focus" );
},
_destroy: $.noop,
widget: function() {
return this.element;
},
widget: function() {
return this.element;
},
option: function( key, value ) {
var options = key,
parts,
curOption,
i;
option: function( key, value ) {
var options = key,
parts,
curOption,
i;
if ( arguments.length === 0 ) {
// don't return a reference to the internal hash
return $.widget.extend( {}, this.options );
}
if ( arguments.length === 0 ) {
// don't return a reference to the internal hash
return $.widget.extend( {}, this.options );
}
if ( typeof key === "string" ) {
// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
options = {};
parts = key.split( "." );
key = parts.shift();
if ( parts.length ) {
curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
for ( i = 0; i < parts.length - 1; i++ ) {
curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
curOption = curOption[ parts[ i ] ];
}
key = parts.pop();
if ( value === undefined ) {
return curOption[ key ] === undefined ? null : curOption[ key ];
}
curOption[ key ] = value;
} else {
if ( value === undefined ) {
return this.options[ key ] === undefined ? null : this.options[ key ];
}
options[ key ] = value;
}
}
if ( typeof key === "string" ) {
// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
options = {};
parts = key.split( "." );
key = parts.shift();
if ( parts.length ) {
curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
for ( i = 0; i < parts.length - 1; i++ ) {
curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
curOption = curOption[ parts[ i ] ];
}
key = parts.pop();
if ( value === undefined ) {
return curOption[ key ] === undefined ? null : curOption[ key ];
}
curOption[ key ] = value;
} else {
if ( value === undefined ) {
return this.options[ key ] === undefined ? null : this.options[ key ];
}
options[ key ] = value;
}
}
this._setOptions( options );
this._setOptions( options );
return this;
},
_setOptions: function( options ) {
var key;
return this;
},
_setOptions: function( options ) {
var key;
for ( key in options ) {
this._setOption( key, options[ key ] );
}
for ( key in options ) {
this._setOption( key, options[ key ] );
}
return this;
},
_setOption: function( key, value ) {
this.options[ key ] = value;
return this;
},
_setOption: function( key, value ) {
this.options[ key ] = value;
if ( key === "disabled" ) {
this.widget()
.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
.attr( "aria-disabled", value );
this.hoverable.removeClass( "ui-state-hover" );
this.focusable.removeClass( "ui-state-focus" );
}
if ( key === "disabled" ) {
this.widget()
.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
.attr( "aria-disabled", value );
this.hoverable.removeClass( "ui-state-hover" );
this.focusable.removeClass( "ui-state-focus" );
}
return this;
},
return this;
},
enable: function() {
return this._setOption( "disabled", false );
},
disable: function() {
return this._setOption( "disabled", true );
},
enable: function() {
return this._setOption( "disabled", false );
},
disable: function() {
return this._setOption( "disabled", true );
},
_on: function( suppressDisabledCheck, element, handlers ) {
var delegateElement,
instance = this;
_on: function( suppressDisabledCheck, element, handlers ) {
var delegateElement,
instance = this;
// no suppressDisabledCheck flag, shuffle arguments
if ( typeof suppressDisabledCheck !== "boolean" ) {
handlers = element;
element = suppressDisabledCheck;
suppressDisabledCheck = false;
}
// no suppressDisabledCheck flag, shuffle arguments
if ( typeof suppressDisabledCheck !== "boolean" ) {
handlers = element;
element = suppressDisabledCheck;
suppressDisabledCheck = false;
}
// no element argument, shuffle and use this.element
if ( !handlers ) {
handlers = element;
element = this.element;
delegateElement = this.widget();
} else {
// accept selectors, DOM elements
element = delegateElement = $( element );
this.bindings = this.bindings.add( element );
}
// no element argument, shuffle and use this.element
if ( !handlers ) {
handlers = element;
element = this.element;
delegateElement = this.widget();
} else {
// accept selectors, DOM elements
element = delegateElement = $( element );
this.bindings = this.bindings.add( element );
}
$.each( handlers, function( event, handler ) {
function handlerProxy() {
// allow widgets to customize the disabled handling
// - disabled as an array instead of boolean
// - disabled class as method for disabling individual parts
if ( !suppressDisabledCheck &&
( instance.options.disabled === true ||
$( this ).hasClass( "ui-state-disabled" ) ) ) {
return;
}
return ( typeof handler === "string" ? instance[ handler ] : handler )
.apply( instance, arguments );
}
$.each( handlers, function( event, handler ) {
function handlerProxy() {
// allow widgets to customize the disabled handling
// - disabled as an array instead of boolean
// - disabled class as method for disabling individual parts
if ( !suppressDisabledCheck &&
( instance.options.disabled === true ||
$( this ).hasClass( "ui-state-disabled" ) ) ) {
return;
}
return ( typeof handler === "string" ? instance[ handler ] : handler )
.apply( instance, arguments );
}
// copy the guid so direct unbinding works
if ( typeof handler !== "string" ) {
handlerProxy.guid = handler.guid =
handler.guid || handlerProxy.guid || $.guid++;
}
// copy the guid so direct unbinding works
if ( typeof handler !== "string" ) {
handlerProxy.guid = handler.guid =
handler.guid || handlerProxy.guid || $.guid++;
}
var match = event.match( /^(\w+)\s*(.*)$/ ),
eventName = match[1] + instance.eventNamespace,
selector = match[2];
if ( selector ) {
delegateElement.delegate( selector, eventName, handlerProxy );
} else {
element.bind( eventName, handlerProxy );
}
});
},
var match = event.match( /^(\w+)\s*(.*)$/ ),
eventName = match[1] + instance.eventNamespace,
selector = match[2];
if ( selector ) {
delegateElement.delegate( selector, eventName, handlerProxy );
} else {
element.bind( eventName, handlerProxy );
}
});
},
_off: function( element, eventName ) {
eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
element.unbind( eventName ).undelegate( eventName );
},
_off: function( element, eventName ) {
eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
element.unbind( eventName ).undelegate( eventName );
},
_delay: function( handler, delay ) {
function handlerProxy() {
return ( typeof handler === "string" ? instance[ handler ] : handler )
.apply( instance, arguments );
}
var instance = this;
return setTimeout( handlerProxy, delay || 0 );
},
_delay: function( handler, delay ) {
function handlerProxy() {
return ( typeof handler === "string" ? instance[ handler ] : handler )
.apply( instance, arguments );
}
var instance = this;
return setTimeout( handlerProxy, delay || 0 );
},
_hoverable: function( element ) {
this.hoverable = this.hoverable.add( element );
this._on( element, {
mouseenter: function( event ) {
$( event.currentTarget ).addClass( "ui-state-hover" );
},
mouseleave: function( event ) {
$( event.currentTarget ).removeClass( "ui-state-hover" );
}
});
},
_hoverable: function( element ) {
this.hoverable = this.hoverable.add( element );
this._on( element, {
mouseenter: function( event ) {
$( event.currentTarget ).addClass( "ui-state-hover" );
},
mouseleave: function( event ) {
$( event.currentTarget ).removeClass( "ui-state-hover" );
}
});
},
_focusable: function( element ) {
this.focusable = this.focusable.add( element );
this._on( element, {
focusin: function( event ) {
$( event.currentTarget ).addClass( "ui-state-focus" );
},
focusout: function( event ) {
$( event.currentTarget ).removeClass( "ui-state-focus" );
}
});
},
_focusable: function( element ) {
this.focusable = this.focusable.add( element );
this._on( element, {
focusin: function( event ) {
$( event.currentTarget ).addClass( "ui-state-focus" );
},
focusout: function( event ) {
$( event.currentTarget ).removeClass( "ui-state-focus" );
}
});
},
_trigger: function( type, event, data ) {
var prop, orig,
callback = this.options[ type ];
_trigger: function( type, event, data ) {
var prop, orig,
callback = this.options[ type ];
data = data || {};
event = $.Event( event );
event.type = ( type === this.widgetEventPrefix ?
type :
this.widgetEventPrefix + type ).toLowerCase();
// the original event may come from any element
// so we need to reset the target on the new event
event.target = this.element[ 0 ];
data = data || {};
event = $.Event( event );
event.type = ( type === this.widgetEventPrefix ?
type :
this.widgetEventPrefix + type ).toLowerCase();
// the original event may come from any element
// so we need to reset the target on the new event
event.target = this.element[ 0 ];
// copy original event properties over to the new event
orig = event.originalEvent;
if ( orig ) {
for ( prop in orig ) {
if ( !( prop in event ) ) {
event[ prop ] = orig[ prop ];
}
}
}
// copy original event properties over to the new event
orig = event.originalEvent;
if ( orig ) {
for ( prop in orig ) {
if ( !( prop in event ) ) {
event[ prop ] = orig[ prop ];
}
}
}
this.element.trigger( event, data );
return !( $.isFunction( callback ) &&
callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
event.isDefaultPrevented() );
}
this.element.trigger( event, data );
return !( $.isFunction( callback ) &&
callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
event.isDefaultPrevented() );
}
};
$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
if ( typeof options === "string" ) {
options = { effect: options };
}
var hasOptions,
effectName = !options ?
method :
options === true || typeof options === "number" ?
defaultEffect :
options.effect || defaultEffect;
options = options || {};
if ( typeof options === "number" ) {
options = { duration: options };
}
hasOptions = !$.isEmptyObject( options );
options.complete = callback;
if ( options.delay ) {
element.delay( options.delay );
}
if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
element[ method ]( options );
} else if ( effectName !== method && element[ effectName ] ) {
element[ effectName ]( options.duration, options.easing, callback );
} else {
element.queue(function( next ) {
$( this )[ method ]();
if ( callback ) {
callback.call( element[ 0 ] );
}
next();
});
}
};
$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
if ( typeof options === "string" ) {
options = { effect: options };
}
var hasOptions,
effectName = !options ?
method :
options === true || typeof options === "number" ?
defaultEffect :
options.effect || defaultEffect;
options = options || {};
if ( typeof options === "number" ) {
options = { duration: options };
}
hasOptions = !$.isEmptyObject( options );
options.complete = callback;
if ( options.delay ) {
element.delay( options.delay );
}
if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
element[ method ]( options );
} else if ( effectName !== method && element[ effectName ] ) {
element[ effectName ]( options.duration, options.easing, callback );
} else {
element.queue(function( next ) {
$( this )[ method ]();
if ( callback ) {
callback.call( element[ 0 ] );
}
next();
});
}
};
});
}));

View File

@@ -19,23 +19,23 @@ CONDITIONS OF ANY KIND, either express or implied. See the Apache License and th
the specific language governing permissions and limitations under the Apache License and the GPL License.
*/
(function ($) {
if(typeof $.fn.each2 == "undefined"){
$.fn.extend({
/*
* 4-10 times faster .each replacement
* use it carefully, as it overrides jQuery context of element on each iteration
*/
each2 : function (c) {
var j = $([0]), i = -1, l = this.length;
while (
++i < l
&& (j.context = j[0] = this[i])
&& c.call(j[0], i, j) !== false //"this"=DOM, i=index, j=jQuery object
);
return this;
}
});
}
if(typeof $.fn.each2 == "undefined"){
$.fn.extend({
/*
* 4-10 times faster .each replacement
* use it carefully, as it overrides jQuery context of element on each iteration
*/
each2 : function (c) {
var j = $([0]), i = -1, l = this.length;
while (
++i < l
&& (j.context = j[0] = this[i])
&& c.call(j[0], i, j) !== false //"this"=DOM, i=index, j=jQuery object
);
return this;
}
});
}
})(jQuery);
(function ($, undefined) {
@@ -182,7 +182,7 @@ the specific language governing permissions and limitations under the Apache Lic
* the elements under the pointer are scrolled.
*/
function installFilteredMouseMove(element) {
element.bind("mousemove", function (e) {
element.bind("mousemove", function (e) {
var lastpos = lastMousePosition;
if (lastpos === undefined || lastpos.x !== e.pageX || lastpos.y !== e.pageY) {
$(e.target).trigger("mousemove-filtered", e);
@@ -243,21 +243,21 @@ the specific language governing permissions and limitations under the Apache Lic
function measureTextWidth(e) {
if (!sizer){
var style = e[0].currentStyle || window.getComputedStyle(e[0], null);
sizer = $("<div></div>").css({
position: "absolute",
left: "-10000px",
top: "-10000px",
display: "none",
fontSize: style.fontSize,
fontFamily: style.fontFamily,
fontStyle: style.fontStyle,
fontWeight: style.fontWeight,
letterSpacing: style.letterSpacing,
textTransform: style.textTransform,
whiteSpace: "nowrap"
});
$("body").append(sizer);
var style = e[0].currentStyle || window.getComputedStyle(e[0], null);
sizer = $("<div></div>").css({
position: "absolute",
left: "-10000px",
top: "-10000px",
display: "none",
fontSize: style.fontSize,
fontFamily: style.fontFamily,
fontStyle: style.fontStyle,
fontWeight: style.fontWeight,
letterSpacing: style.letterSpacing,
textTransform: style.textTransform,
whiteSpace: "nowrap"
});
$("body").append(sizer);
}
sizer.text(e.val());
return sizer.width();
@@ -1135,7 +1135,7 @@ the specific language governing permissions and limitations under the Apache Lic
highlightUnderEvent: function (event) {
var el = $(event.target).closest(".select2-result-selectable");
if (el.length > 0 && !el.is(".select2-highlighted")) {
var choices = this.results.find('.select2-result-selectable');
var choices = this.results.find('.select2-result-selectable');
this.highlight(choices.index(el));
} else if (el.length == 0) {
// if we are over an unselectable item remove al highlights
@@ -1219,8 +1219,8 @@ the specific language governing permissions and limitations under the Apache Lic
if (opts.maximumSelectionSize >=1) {
data = this.data();
if ($.isArray(data) && data.length >= opts.maximumSelectionSize && checkFormatter(opts.formatSelectionTooBig, "formatSelectionTooBig")) {
render("<li class='select2-selection-limit'>" + opts.formatSelectionTooBig(opts.maximumSelectionSize) + "</li>");
return;
render("<li class='select2-selection-limit'>" + opts.formatSelectionTooBig(opts.maximumSelectionSize) + "</li>");
return;
}
}
@@ -1399,7 +1399,7 @@ the specific language governing permissions and limitations under the Apache Lic
// single
createContainer: function () {
createContainer: function () {
var container = $("<div></div>", {
"class": "select2-container"
}).html([
@@ -1789,7 +1789,7 @@ the specific language governing permissions and limitations under the Apache Lic
" <ul class='select2-results'>" ,
" </ul>" ,
"</div>"].join(""));
return container;
return container;
},
// multi
@@ -1984,7 +1984,7 @@ the specific language governing permissions and limitations under the Apache Lic
this.parent.opening.apply(this, arguments);
this.clearPlaceholder();
this.resizeSearch();
this.resizeSearch();
this.focusSearch();
},
@@ -2171,7 +2171,7 @@ the specific language governing permissions and limitations under the Apache Lic
resizeSearch: function () {
var minimumWidth, left, maxWidth, containerLeft, searchWidth,
sideBorderPadding = getSideBorderPadding(this.search);
sideBorderPadding = getSideBorderPadding(this.search);
minimumWidth = measureTextWidth(this.search) + 10;

View File

@@ -6,7 +6,7 @@ requirejs.config({
site: 'app/site',
jquery: 'lib/jquery',
backbone: 'lib/backbone',
'backbone.relational': 'lib/backbone.relational',
'backbone-associations': 'lib/backbone.associations',
'backbone.syphon': 'lib/backbone.syphon',
marionette: 'lib/backbone.marionette',
bootstrap: 'lib/bootstrap',
@@ -59,6 +59,10 @@ requirejs.config({
exports: 'Backbone',
deps: ['jquery', 'underscore']
},
'backbone-associations': {
exports: 'Backbone.AssociatedModel',
deps: ['backbone']
},
bootstrap: {
exports: 'bootstrap',
deps: ['jquery']

View File

@@ -5,7 +5,7 @@
</div>
<div class="row well-sm">
<section id="mix-comment">
<div class="input-group">
<div class="input-group" id="comment-input">
<span class="input-group-btn">
<button class="btn btn-sm btn-default"
id="btn-add-comment"
@@ -14,20 +14,20 @@
Add comment!
</button>
</span>
<input class="form-control input-mask-date" type="text" id="comment-text" name="new-comment">
<input class="form-control" type="text" id="comment-text" name="new-comment">
</div>
</section>
</div>
<div class="row">
<section id="mix-detail-section">
<ul id="mix-tab" class="nav nav-tabs" data-tabs="tabs">
<li class="active">
<li class="active" id="tab-description">
<a data-bypass="true" href="#description" data-toggle="tab">
<i class="orange icon-terminal bigger-120"></i>
Description
</a>
</li>
<li>
<li id="tab-comments">
<a data-bypass="true" href="#comments" data-toggle="tab">
<i class="orange icon-comments bigger-120"></i>
Comments