Merge branch 'auth'

This commit is contained in:
Felipe Martin 2016-10-26 15:35:42 +02:00
commit d02a171ee2
No known key found for this signature in database
GPG Key ID: 648659A0525A81EA
263 changed files with 36698 additions and 17557 deletions

2
.gitignore vendored
View File

@ -72,3 +72,5 @@ media/
bower_components/
node_modules/
amiibofindr/static/css
*~

View File

@ -12,6 +12,7 @@ import reversion
# amiibo
from .models import (
Collection, Amiibo,
AmiiboFigure, AmiiboCard,
AmiiboShop,
AmiiboPrice, AmiiboPriceHistory
)
@ -22,9 +23,9 @@ class ColectionResource(resources.ModelResource):
model = Collection
class AmiiboResource(resources.ModelResource):
class AmiiboFigureResource(resources.ModelResource):
class Meta:
model = Amiibo
model = AmiiboFigure
class AmiiboShopResource(resources.ModelResource):
@ -32,18 +33,23 @@ class AmiiboShopResource(resources.ModelResource):
model = AmiiboShop
class AmiiboCardResource(resources.ModelResource):
class Meta:
model = AmiiboCard
class CollectionAdmin(ImportExportModelAdmin, reversion.VersionAdmin):
resource_class = ColectionResource
list_display = ('name_eu', 'amiibo_number', 'have_cards', )
list_display = ('name_eu', 'amiibo_number', )
def amiibo_number(self, obj):
return obj.amiibos.count()
amiibo_number.short_description = 'Amiibos'
class AmiiboAdmin(ImportExportModelAdmin, reversion.VersionAdmin):
resource_class = AmiiboResource
class AmiiboFigureAdmin(ImportExportModelAdmin, reversion.VersionAdmin):
resource_class = AmiiboFigureResource
list_display_links = ('name_eu', )
list_display = ('statue_image', 'name_eu', 'collection',)
@ -63,11 +69,12 @@ class AmiiboAdmin(ImportExportModelAdmin, reversion.VersionAdmin):
class AmiiboCardAdmin(ImportExportModelAdmin, reversion.VersionAdmin):
resource_class = AmiiboResource
resource_class = AmiiboCardResource
list_display_links = ('name_eu', )
list_display = ('image_image', 'name_eu', 'collection', 'dice', 'rps', )
search_fields = ('collection__name_eu', 'name_eu', 'name_us',)
list_display = ('image_image', 'name_eu', 'collection',)
search_fields = ('collection__name_eu', 'name_eu', 'name_us',
'model_number')
def image_image(self, obj):
if obj.image:
@ -79,10 +86,13 @@ class AmiiboCardAdmin(ImportExportModelAdmin, reversion.VersionAdmin):
class AmiiboShopAdmin(ImportExportModelAdmin, reversion.VersionAdmin):
resource_class = AmiiboShopResource
list_display = ('amiibo', 'shop', 'check_price')
list_filter = ('amiibo', 'shop', )
list_display = ('amiibos_names', 'shop_name', 'shop', 'check_price')
list_filter = ('shop', 'shop_name', )
list_editable = ('check_price', )
filter_horizontal = ('amiibo', )
def amiibos_names(self, obj):
return ", ".join(obj.amiibo.all().values_list('name_eu', flat=True))
class AmiiboPriceAdmin(reversion.VersionAdmin):
@ -94,7 +104,8 @@ class AmiiboPriceHistoryAdmin(admin.ModelAdmin):
admin.site.register(Collection, CollectionAdmin)
admin.site.register(Amiibo, AmiiboAdmin)
admin.site.register(AmiiboFigure, AmiiboFigureAdmin)
admin.site.register(AmiiboCard, AmiiboCardAdmin)
admin.site.register(AmiiboShop, AmiiboShopAdmin)
admin.site.register(AmiiboPrice, AmiiboPriceAdmin)
admin.site.register(AmiiboPriceHistory, AmiiboPriceHistoryAdmin)

View File

@ -1,13 +1,16 @@
# coding: utf-8
# amiibo
from .models import Collection, AmiiboPrice
from .models import Collection, AmiiboPrice, AmiiboCard, UserAmiibo
def collections(request):
return {
'COLLECTIONS_FIGURES': Collection.objects.all().order_by('name_eu'),
'COLLECTIONS_CARDS': Collection.objects.filter(have_cards=True).order_by('name_eu'),
'COLLECTIONS_CARDS': Collection.objects.filter(pk__in=
AmiiboCard.objects.all().distinct('collection').order_by('collection')\
.values_list('collection__id', flat=True)
)
}
@ -16,3 +19,22 @@ def currencies(request):
'CURRENCIES': AmiiboPrice.objects.all().distinct('currency')\
.values_list('currency', flat=True)
}
def user_amiibo(request):
owned = []
wishlisted = []
trading = []
if request.user.is_authenticated():
owned = UserAmiibo.objects.filter(own=True,
user_id=request.user.pk).values_list('_amiibo__id', flat=True)
wishlisted = UserAmiibo.objects.filter(want=True,
user_id=request.user.pk).values_list('_amiibo__id', flat=True)
trading = UserAmiibo.objects.filter(trade=True,
user_id=request.user.pk).values_list('_amiibo__id', flat=True)
return {
'USER_AMIIBO_OWNED': owned,
'USER_AMIIBO_WISHLIST': wishlisted,
'USER_AMIIBO_TRADE': trading
}

View File

@ -30,7 +30,7 @@ def post_check_price_change(sender, instance, created, **kwargs):
amiibo_price_changed.send(
sender=instance.__class__,
instance=instance,
amiibo=instance.amiibo_shop.amiibo,
amiibo=instance.amiibo_shop.amiibo.first(),
old_stock=instance.old_stock,
old_price=instance.old_price,
new_price=instance.price

View File

@ -0,0 +1,166 @@
# coding: utf-8
from __future__ import unicode_literals
import requests
from django.core.files.base import ContentFile
from django.core.management.base import BaseCommand
from django.utils.text import slugify
from amiibofindr.apps.amiibo.models import AmiiboCard, Collection
CARD_IMAGES = """
/amiibo-cards/assets/img/cards/NVL-C-MAAA-USZ-F0(0)001.png
/amiibo-cards/assets/img/cards/NVL-C-MAAB-USZ-F0(0)002.png
/amiibo-cards/assets/img/cards/NVL-C-MAAC-USZ-F0(0)003.png
/amiibo-cards/assets/img/cards/NVL-C-MAAD-USZ-F0(0)004.png
/amiibo-cards/assets/img/cards/NVL-C-MAAE-USZ-F0(0)005.png
/amiibo-cards/assets/img/cards/NVL-C-MAAF-USZ-F0(0)006.png
/amiibo-cards/assets/img/cards/NVL-C-MAAG-USZ-F0(0)007.png
/amiibo-cards/assets/img/cards/NVL-C-MAAH-USZ-F0(0)008.png
/amiibo-cards/assets/img/cards/NVL-C-MAAJ-USZ-F0(0)009.png
/amiibo-cards/assets/img/cards/NVL-C-MAAK-USZ-F0(0)010.png
/amiibo-cards/assets/img/cards/NVL-C-MAAL-USZ-F0(0)011.png
/amiibo-cards/assets/img/cards/NVL-C-MAAM-USZ-F0(0)012.png
/amiibo-cards/assets/img/cards/NVL-C-MAAN-USZ-F0(0)013.png
/amiibo-cards/assets/img/cards/NVL-C-MAAP-USZ-F0(0)014.png
/amiibo-cards/assets/img/cards/NVL-C-MAAQ-USZ-F0(0)015.png
/amiibo-cards/assets/img/cards/NVL-C-MAAR-USZ-F0(0)016.png
/amiibo-cards/assets/img/cards/NVL-C-MAAS-USZ-F0(0)017.png
/amiibo-cards/assets/img/cards/NVL-C-MAAT-USZ-F0(0)018.png
/amiibo-cards/assets/img/cards/NVL-C-MAAU-USZ-F0(0)019.png
/amiibo-cards/assets/img/cards/NVL-C-MAAV-USZ-F0(0)020.png
/amiibo-cards/assets/img/cards/NVL-C-MAAW-USZ-F0(0)021.png
/amiibo-cards/assets/img/cards/NVL-C-MAAX-USZ-F0(0)022.png
/amiibo-cards/assets/img/cards/NVL-C-MAAY-USZ-F0(0)023.png
/amiibo-cards/assets/img/cards/NVL-C-MAAZ-USZ-F0(0)024.png
/amiibo-cards/assets/img/cards/NVL-C-MABA-USZ-F0(0)025.png
/amiibo-cards/assets/img/cards/NVL-C-MABB-USZ-F0(0)026.png
/amiibo-cards/assets/img/cards/NVL-C-MABC-USZ-F0(0)027.png
/amiibo-cards/assets/img/cards/NVL-C-MABD-USZ-F0(0)028.png
/amiibo-cards/assets/img/cards/NVL-C-MABE-USZ-F0(0)029.png
/amiibo-cards/assets/img/cards/NVL-C-MABF-USZ-F0(0)030.png
/amiibo-cards/assets/img/cards/NVL-C-MABG-USZ-F0(0)031.png
/amiibo-cards/assets/img/cards/NVL-C-MABH-USZ-F0(0)032.png
/amiibo-cards/assets/img/cards/NVL-C-MABJ-USZ-F0(0)033.png
/amiibo-cards/assets/img/cards/NVL-C-MABK-USZ-F0(0)034.png
/amiibo-cards/assets/img/cards/NVL-C-MABL-USZ-F0(0)035.png
/amiibo-cards/assets/img/cards/NVL-C-MABM-USZ-F0(0)036.png
/amiibo-cards/assets/img/cards/NVL-C-MABN-USZ-F0(0)037.png
/amiibo-cards/assets/img/cards/NVL-C-MABP-USZ-F0(0)038.png
/amiibo-cards/assets/img/cards/NVL-C-MABQ-USZ-F0(0)039.png
/amiibo-cards/assets/img/cards/NVL-C-MABR-USZ-F0(0)040.png
/amiibo-cards/assets/img/cards/NVL-C-MABS-USZ-F0(0)041.png
/amiibo-cards/assets/img/cards/NVL-C-MABT-USZ-F0(0)042.png
/amiibo-cards/assets/img/cards/NVL-C-MABU-USZ-F0(0)043.png
/amiibo-cards/assets/img/cards/NVL-C-MABV-USZ-F0(0)044.png
/amiibo-cards/assets/img/cards/NVL-C-MABW-USZ-F0(0)045.png
/amiibo-cards/assets/img/cards/NVL-C-MABX-USZ-F0(0)046.png
/amiibo-cards/assets/img/cards/NVL-C-MABY-USZ-F0(0)047.png
/amiibo-cards/assets/img/cards/NVL-C-MABZ-USZ-F0(0)048.png
/amiibo-cards/assets/img/cards/NVL-C-MACA-USZ-F0(0)049.png
/amiibo-cards/assets/img/cards/NVL-C-MACB-USZ-F0(0)050.png
/amiibo-cards/assets/img/cards/NVL-C-MACC-USZ-F0(0)051.png
/amiibo-cards/assets/img/cards/NVL-C-MACD-USZ-F0(0)052.png
/amiibo-cards/assets/img/cards/NVL-C-MACE-USZ-F0(0)053.png
/amiibo-cards/assets/img/cards/NVL-C-MACF-USZ-F0(0)054.png
/amiibo-cards/assets/img/cards/NVL-C-MACG-USZ-F0(0)055.png
/amiibo-cards/assets/img/cards/NVL-C-MACH-USZ-F0(0)056.png
/amiibo-cards/assets/img/cards/NVL-C-MACJ-USZ-F0(0)057.png
/amiibo-cards/assets/img/cards/NVL-C-MACK-USZ-F0(0)058.png
/amiibo-cards/assets/img/cards/NVL-C-MACL-USZ-F0(0)059.png
/amiibo-cards/assets/img/cards/NVL-C-MACM-USZ-F0(0)060.png
/amiibo-cards/assets/img/cards/NVL-C-MACN-USZ-F0(0)061.png
/amiibo-cards/assets/img/cards/NVL-C-MACP-USZ-F0(0)062.png
/amiibo-cards/assets/img/cards/NVL-C-MACQ-USZ-F0(0)063.png
/amiibo-cards/assets/img/cards/NVL-C-MACR-USZ-F0(0)064.png
/amiibo-cards/assets/img/cards/NVL-C-MACS-USZ-F0(0)065.png
/amiibo-cards/assets/img/cards/NVL-C-MACT-USZ-F0(0)066.png
/amiibo-cards/assets/img/cards/NVL-C-MACU-USZ-F0(0)067.png
/amiibo-cards/assets/img/cards/NVL-C-MACV-USZ-F0(0)068.png
/amiibo-cards/assets/img/cards/NVL-C-MACW-USZ-F0(0)069.png
/amiibo-cards/assets/img/cards/NVL-C-MACX-USZ-F0(0)070.png
/amiibo-cards/assets/img/cards/NVL-C-MACY-USZ-F0(0)071.png
/amiibo-cards/assets/img/cards/NVL-C-MACZ-USZ-F0(0)072.png
/amiibo-cards/assets/img/cards/NVL-C-MADA-USZ-F0(0)073.png
/amiibo-cards/assets/img/cards/NVL-C-MADB-USZ-F0(0)074.png
/amiibo-cards/assets/img/cards/NVL-C-MADC-USZ-F0(0)075.png
/amiibo-cards/assets/img/cards/NVL-C-MADD-USZ-F0(0)076.png
/amiibo-cards/assets/img/cards/NVL-C-MADE-USZ-F0(0)077.png
/amiibo-cards/assets/img/cards/NVL-C-MADF-USZ-F0(0)078.png
/amiibo-cards/assets/img/cards/NVL-C-MADG-USZ-F0(0)079.png
/amiibo-cards/assets/img/cards/NVL-C-MADH-USZ-F0(0)080.png
/amiibo-cards/assets/img/cards/NVL-C-MADJ-USZ-F0(0)081.png
/amiibo-cards/assets/img/cards/NVL-C-MADK-USZ-F0(0)082.png
/amiibo-cards/assets/img/cards/NVL-C-MADL-USZ-F0(0)083.png
/amiibo-cards/assets/img/cards/NVL-C-MADM-USZ-F0(0)084.png
/amiibo-cards/assets/img/cards/NVL-C-MADN-USZ-F0(0)085.png
/amiibo-cards/assets/img/cards/NVL-C-MADP-USZ-F0(0)086.png
/amiibo-cards/assets/img/cards/NVL-C-MADQ-USZ-F0(0)087.png
/amiibo-cards/assets/img/cards/NVL-C-MADR-USZ-F0(0)088.png
/amiibo-cards/assets/img/cards/NVL-C-MADS-USZ-F0(0)089.png
/amiibo-cards/assets/img/cards/NVL-C-MADT-USZ-F0(0)090.png
/amiibo-cards/assets/img/cards/NVL-C-MADU-USZ-F0(0)091.png
/amiibo-cards/assets/img/cards/NVL-C-MADV-USZ-F0(0)092.png
/amiibo-cards/assets/img/cards/NVL-C-MADW-USZ-F0(0)093.png
/amiibo-cards/assets/img/cards/NVL-C-MADX-USZ-F0(0)094.png
/amiibo-cards/assets/img/cards/NVL-C-MADY-USZ-F0(0)095.png
/amiibo-cards/assets/img/cards/NVL-C-MADZ-USZ-F0(0)096.png
/amiibo-cards/assets/img/cards/NVL-C-MAEA-USZ-F0(0)097.png
/amiibo-cards/assets/img/cards/NVL-C-MAEB-USZ-F0(0)098.png
/amiibo-cards/assets/img/cards/NVL-C-MAEC-USZ-F0(0)099.png
/amiibo-cards/assets/img/cards/NVL-C-MAED-USZ-F0(0)100.png
""".split('\n')
class Command(BaseCommand):
collection_slug = 'animal-crossing'
url = 'https://api.import.io/store/data/d7057867-dd48-4f5a-80ba-7051daf72bf4/_query?input/webpage/url=http%3A%2F%2Fanimalcrossingworld.com%2Fanimal-crossing-happy-home-designer-amiibo-cards%2F&_user=4519bdcf-aa0b-4b78-b014-e51476ba977c&_apikey=4519bdcfaa0b4b78b014e51476ba977c42d9d75fd621c0ccd433708c1f742487e763cb6a68202c4a5c7aa32c3ef0c99bc18dbc96548bc0c4fd1470abd0418732c82cf53dba34076decc64b68c504026e'
dice = {
'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6,
}
card_image_domain = 'http://animal-crossing.com'
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36',
}
def handle_image(self, image_url):
image = requests.get(image_url, headers=self.headers)
f = ContentFile(image.content, image_url.split('/')[-1])
return f
def handle(self, *args, **kwargs):
collection = Collection.objects.get(slug=self.collection_slug)
data = requests.get(self.url).json()
for item in data['results']:
amiibo, created = AmiiboCard.objects.get_or_create(
collection_id=collection.pk,
collection_number=int(item['number_number'])
)
print(' => {} {}'.format(collection.slug, amiibo.collection_number))
amiibo.type = AmiiboCard.CARD
if created:
amiibo.name_en = item['name_value']
amiibo.name_eu = amiibo.name_en
amiibo.name_us = amiibo.name_en
# amiibo.collection_number = int(item['number_number'])
amiibo.collection = collection
# amiibo.image = self.handle_image(item['cardphoto_link'])
else:
if amiibo.image:
amiibo.image.delete()
amiibo.image = self.handle_image('{}{}'.format(self.card_image_domain,
CARD_IMAGES[int(item['number_number'])]))
amiibo.dice = self.dice[item['dice_value'].lower()]
amiibo.rps = item['rps_value'].lower()
amiibo.card_type = item['type_value'].lower()
amiibo.slug = slugify(amiibo.name_en)
amiibo.save()

View File

@ -13,6 +13,16 @@ from amiibofindr.apps.shop.crawlers import Crawler
class Command(BaseCommand):
def update_product(self, product, region):
amiibo_shop = AmiiboShop.objects.get(
item_id=product['shop_product_id'],
shop__flag_code=region[0]
)
if amiibo_shop.shop_name != product['title']:
amiibo_shop.shop_name = product['title']
amiibo_shop.save()
amiibo_shop.update_price(product['price'], product['currency'])
def handle(self, *args, **kwargs):
regions = Shop.objects.all()\
.order_by('flag_code')\
@ -25,9 +35,8 @@ class Command(BaseCommand):
check_price=True).values_list('item_id', flat=True)
amazon = Crawler(region[1])
products = amazon.fetch_batch(item_codes)
for product in products:
amiibo_shop = AmiiboShop.objects.get(
item_id=product['shop_product_id'],
shop__flag_code=region[0]
)
amiibo_shop.update_price(product['price'], product['currency'])
try:
for product in products:
self.update_product(product, region)
except TypeError:
self.update_product(product, region)

View File

@ -1,48 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import amiibofindr.apps.amiibo.models
class Migration(migrations.Migration):
dependencies = [
('amiibo', '0018_amiiboshop_check_price'),
]
operations = [
migrations.CreateModel(
name='AmiiboCard',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('number', models.IntegerField(default=1)),
('name', models.CharField(max_length=60)),
('name_en', models.CharField(max_length=64, null=True, blank=True)),
('name_es', models.CharField(max_length=64, null=True, blank=True)),
('name_fr', models.CharField(max_length=64, null=True, blank=True)),
('name_it', models.CharField(max_length=64, null=True, blank=True)),
('name_de', models.CharField(max_length=64, null=True, blank=True)),
('name_eu', models.CharField(max_length=64, null=True, blank=True)),
('name_jp', models.CharField(max_length=64, null=True, blank=True)),
('name_us', models.CharField(max_length=64, null=True, blank=True)),
('slug', models.SlugField(max_length=60)),
('image', models.ImageField(upload_to=amiibofindr.apps.amiibo.models.image_card_upload)),
('dice', models.IntegerField(default=1)),
('rps', models.CharField(default=1, max_length=1, choices=[(1, b'Rock'), (2, b'Paper'), (3, b'Scissors')])),
],
options={
'ordering': ('collection', 'number', 'name'),
},
),
migrations.AddField(
model_name='collection',
name='have_cards',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='amiibocard',
name='collection',
field=models.ForeignKey(related_name='cards_qs', to='amiibo.Collection'),
),
]

View File

@ -7,7 +7,7 @@ from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('amiibo', '0019_auto_20150827_1825'),
('amiibo', '0018_amiiboshop_check_price'),
]
operations = [

View File

@ -0,0 +1,137 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import amiibofindr.apps.amiibo.models
BACKUP = {}
def backup_images(apps, schema_editor):
Amiibo = apps.get_model("amiibo", "Amiibo")
for amiibo in Amiibo.objects.all():
BACKUP[amiibo.pk] = {
'box': amiibo.box,
'statue': amiibo.statue,
}
def restore_images(apps, schema_editor):
AmiiboFigure = apps.get_model("amiibo", "AmiiboFigure")
for pk, images in BACKUP.items():
amiibo = AmiiboFigure.objects.get(pk=pk)
amiibo.box = images['box']
amiibo.statue = images['statue']
amiibo.save()
def convert_all_to_figures(apps, schema_editor):
Amiibo = apps.get_model('amiibo', 'Amiibo')
AmiiboFigure = apps.get_model('amiibo', 'AmiiboFigure')
for amiibo in Amiibo.objects.all():
figure = AmiiboFigure(amiibo_ptr=amiibo)
for key, value in amiibo.__dict__.items():
figure.__dict__[key] = value
figure.save()
class Migration(migrations.Migration):
dependencies = [
('amiibo', '0020_amiiboshop_type'),
]
operations = [
# From removed migrations
migrations.RunSQL("DROP TABLE amiibo_amiibocard;"),
migrations.RunSQL("ALTER TABLE amiibo_collection DROP COLUMN have_cards;"),
# Fresh start
migrations.RunPython(backup_images),
migrations.RemoveField(
model_name='amiibo',
name='box',
),
migrations.RemoveField(
model_name='amiibo',
name='statue',
),
migrations.AddField(
model_name='amiibo',
name='link_de',
field=models.CharField(max_length=64, null=True, blank=True),
),
migrations.AddField(
model_name='amiibo',
name='link_en',
field=models.CharField(max_length=64, null=True, blank=True),
),
migrations.AddField(
model_name='amiibo',
name='link_es',
field=models.CharField(max_length=64, null=True, blank=True),
),
migrations.AddField(
model_name='amiibo',
name='link_fr',
field=models.CharField(max_length=64, null=True, blank=True),
),
migrations.AddField(
model_name='amiibo',
name='link_it',
field=models.CharField(max_length=64, null=True, blank=True),
),
migrations.AddField(
model_name='amiibo',
name='name_de',
field=models.CharField(max_length=64, null=True, blank=True),
),
migrations.AddField(
model_name='amiibo',
name='name_en',
field=models.CharField(max_length=64, null=True, blank=True),
),
migrations.AddField(
model_name='amiibo',
name='name_es',
field=models.CharField(max_length=64, null=True, blank=True),
),
migrations.AddField(
model_name='amiibo',
name='name_fr',
field=models.CharField(max_length=64, null=True, blank=True),
),
migrations.AddField(
model_name='amiibo',
name='name_it',
field=models.CharField(max_length=64, null=True, blank=True),
),
migrations.AddField(
model_name='amiibo',
name='type',
field=models.CharField(default=b'figure', max_length=9, choices=[(b'figure', b'Figure'), (b'card', b'Card')]),
),
migrations.CreateModel(
name='AmiiboCard',
fields=[
('amiibo_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='amiibo.Amiibo')),
('image', models.ImageField(upload_to=amiibofindr.apps.amiibo.models.image_card_upload)),
('dice', models.IntegerField(default=1)),
('rps', models.CharField(default=1, max_length=1, choices=[(1, b'Rock'), (2, b'Paper'), (3, b'Scissors')])),
],
options={
'ordering': ('collection', 'collection_number', 'name_eu'),
},
bases=('amiibo.amiibo',),
),
migrations.CreateModel(
name='AmiiboFigure',
fields=[
('amiibo_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='amiibo.Amiibo')),
('statue', models.ImageField(upload_to=amiibofindr.apps.amiibo.models.image_statue_upload)),
('box', models.ImageField(null=True, upload_to=amiibofindr.apps.amiibo.models.image_box_upload, blank=True)),
],
bases=('amiibo.amiibo',),
),
migrations.RunPython(convert_all_to_figures),
migrations.RunPython(restore_images),
]

View File

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('amiibo', '0021_auto_20150907_2143'),
]
operations = [
migrations.CreateModel(
name='UserAmiibo',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('want', models.BooleanField(default=False)),
('have', models.BooleanField(default=False)),
('trade', models.BooleanField(default=False)),
('date', models.DateTimeField(auto_now=True)),
('_amiibo', models.ForeignKey(to='amiibo.Amiibo')),
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import amiibofindr.apps.amiibo.models
class Migration(migrations.Migration):
dependencies = [
('amiibo', '0022_useramiibo'),
]
operations = [
migrations.AddField(
model_name='amiiboshop',
name='image',
field=models.ImageField(null=True, upload_to=amiibofindr.apps.amiibo.models.shop_item_upload, blank=True),
),
]

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('amiibo', '0023_amiiboshop_image'),
]
operations = [
migrations.RenameField(
model_name='useramiibo',
old_name='have',
new_name='own',
),
]

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('amiibo', '0024_auto_20150908_2114'),
]
operations = [
migrations.AddField(
model_name='amiibocard',
name='card_type',
field=models.CharField(default=b'special', max_length=12),
),
]

View File

@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('amiibo', '0025_amiibocard_card_type'),
]
operations = [
migrations.AddField(
model_name='collection',
name='name_de',
field=models.CharField(max_length=64, null=True, blank=True),
),
migrations.AddField(
model_name='collection',
name='name_en',
field=models.CharField(max_length=64, null=True, blank=True),
),
migrations.AddField(
model_name='collection',
name='name_es',
field=models.CharField(max_length=64, null=True, blank=True),
),
migrations.AddField(
model_name='collection',
name='name_fr',
field=models.CharField(max_length=64, null=True, blank=True),
),
migrations.AddField(
model_name='collection',
name='name_it',
field=models.CharField(max_length=64, null=True, blank=True),
),
]

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('amiibo', '0026_auto_20150909_2331'),
]
operations = [
migrations.AlterField(
model_name='amiibocard',
name='rps',
field=models.CharField(default=b'rock', max_length=1, choices=[(b'rock', b'Rock'), (b'paper', b'Paper'), (b'scissors', b'Scissors')]),
),
]

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('amiibo', '0027_auto_20150910_0021'),
]
operations = [
migrations.AlterField(
model_name='amiibocard',
name='rps',
field=models.CharField(default=b'rock', max_length=12, choices=[(b'rock', b'Rock'), (b'paper', b'Paper'), (b'scissors', b'Scissors')]),
),
]

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('amiibo', '0028_auto_20150910_0021'),
]
operations = [
migrations.AddField(
model_name='amiiboshop',
name='shop_name',
field=models.CharField(max_length=255, null=True, blank=True),
),
]

View File

@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
BACKUP = {}
def backup(apps, schema_editor):
AmiiboShop = apps.get_model("amiibo", "AmiiboShop")
for shop in AmiiboShop.objects.all():
BACKUP[shop.pk] = {
'amiibo_id': shop.amiibo_id,
}
def restore(apps, schema_editor):
AmiiboShop = apps.get_model("amiibo", "AmiiboShop")
Amiibo = apps.get_model("amiibo", "Amiibo")
for pk, info in BACKUP.items():
a = AmiiboShop.objects.get(pk=pk)
a.amiibo.add(Amiibo.objects.get(pk=int(info['amiibo_id'])))
a.save()
class Migration(migrations.Migration):
dependencies = [
('amiibo', '0029_amiiboshop_shop_name'),
]
operations = [
migrations.RunPython(backup),
migrations.RemoveField(
model_name='amiiboshop',
name='amiibo',
),
migrations.AddField(
model_name='amiiboshop',
name='amiibo',
field=models.ManyToManyField(related_name='shops_set', to='amiibo.Amiibo'),
),
migrations.RunPython(restore),
]

View File

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
def convert(apps, schema_editor):
Amiibo = apps.get_model("amiibo", "Amiibo")
for amiibo in Amiibo.objects.all():
amiibo.name_en = amiibo.name_eu
amiibo.save()
class Migration(migrations.Migration):
dependencies = [
('amiibo', '0030_auto_20150910_2116'),
]
operations = [
migrations.RunPython(convert),
]

View File

@ -1,16 +1,16 @@
# coding: utf-8
# python
import os
# django
from django.apps import apps
from django.conf import settings
from django.core.urlresolvers import reverse
from django.db import models
from django.utils.text import slugify
from django.utils.translation import ugettext_lazy as _, get_language
# 3rd party
from amazonify import amazonify
# project
from amiibofindr.apps.shop.crawlers import Crawler
@ -28,29 +28,63 @@ def image_box_upload(self, filename):
def image_card_upload(self, filename):
name, extension = os.path.splitext(filename)
return 'amiibos/{}/card-{}-{}{}'.format(
self.collection.slug, self.number, self.slug, extension)
return 'amiibos/c/{}/{}_{}{}'.format(
self.collection.pk, self.collection_number, self.pk, extension)
def shop_item_upload(self, filename):
name, extension = os.path.splitext(filename)
return 'amiibos/si/{}_{}{}'.format(
self.shop.pk, self.pk, extension)
#
# Models
class Collection(models.Model):
slug = models.SlugField(max_length=128)
name_en = models.CharField(max_length=64, blank=True, null=True)
name_es = models.CharField(max_length=64, blank=True, null=True)
name_fr = models.CharField(max_length=64, blank=True, null=True)
name_it = models.CharField(max_length=64, blank=True, null=True)
name_de = models.CharField(max_length=64, blank=True, null=True)
name_eu = models.CharField(max_length=128)
name_jp = models.CharField(max_length=128, blank=True, null=True)
name_us = models.CharField(max_length=128, blank=True, null=True)
have_cards = models.BooleanField(default=False)
@models.permalink
def get_absolute_url(self):
return ('amiibo:figures-list', (slugify(self.name), self.pk))
def get_absolute_url_figures(self):
return reverse('amiibo:figures-list', args=(slugify(self.name), self.pk))
def get_absolute_url_cards(self):
return reverse('amiibo:cards-list', args=(slugify(self.name), self.pk))
@property
def amiibos(self):
return self.amiibos_qs.all()
@models.permalink
def get_absolute_url(self):
return ('amiibo:collection', [self.slug])
@property
def figures(self):
return AmiiboFigure.objects.filter(collection_id=self.pk)
@property
def cards(self):
return AmiiboCard.objects.filter(collection_id=self.pk)
@property
def name(self):
name = getattr(self, 'name_{}'.format(get_language()), None)
if name:
return name
if self.name_en:
return self.name_en
return self.name_eu
def __unicode__(self):
@ -58,75 +92,21 @@ class Collection(models.Model):
class Amiibo(models.Model):
FIGURE = 'figure'
CARD = 'card'
AMIIBO_TYPES = (
(FIGURE, 'Figure'),
(CARD, 'Card'),
)
collection = models.ForeignKey(Collection, related_name='amiibos_qs')
collection_number = models.IntegerField(blank=True, null=True)
type = models.CharField(max_length=9, default=FIGURE, choices=AMIIBO_TYPES)
model_number = models.CharField(max_length=20, blank=True, null=True)
slug = models.SlugField(max_length=64)
statue = models.ImageField(upload_to=image_statue_upload)
box = models.ImageField(upload_to=image_box_upload, blank=True, null=True)
name_eu = models.CharField(max_length=64, blank=True, null=True)
name_jp = models.CharField(max_length=64, blank=True, null=True)
name_us = models.CharField(max_length=64, blank=True, null=True)
# Links
link_eu = models.CharField(max_length=255, blank=True, null=True)
link_jp = models.CharField(max_length=255, blank=True, null=True)
link_us = models.CharField(max_length=255, blank=True, null=True)
release_date = models.DateField(null=True, blank=True)
visible = models.BooleanField(default=True)
def get_all_names(self):
result = u''
for key, value in self.__dict__.items():
if u'name_' in key and self.__dict__[key]:
result += u' {}'.format(self.__dict__[key])
return result
@models.permalink
def get_absolute_url(self):
return ('amiibo:amiibo', [self.collection.slug, self.slug])
@property
def image_box(self):
return 'images/amiibo/{}/{}-box.jpg'.format(
self.collection.slug, self.slug
)
@property
def image_statue(self):
return 'images/amiibo/{}/{}.png'.format(
self.collection.slug, self.slug
)
def __unicode__(self):
return unicode(self.name_eu) or u''
@property
def name(self):
return self.name_eu
class AmiiboCard(models.Model):
ROCK = 1
PAPER = 2
SCISSORS = 3
RPS_CHOICES = (
(ROCK, 'Rock'),
(PAPER, 'Paper'),
(SCISSORS, 'Scissors'),
)
collection = models.ForeignKey(Collection, related_name='cards_qs')
number = models.IntegerField(default=1)
name = models.CharField(max_length=60)
name_en = models.CharField(max_length=64, blank=True, null=True)
name_es = models.CharField(max_length=64, blank=True, null=True)
name_fr = models.CharField(max_length=64, blank=True, null=True)
@ -137,16 +117,157 @@ class AmiiboCard(models.Model):
name_jp = models.CharField(max_length=64, blank=True, null=True)
name_us = models.CharField(max_length=64, blank=True, null=True)
slug = models.SlugField(max_length=60)
image = models.ImageField(upload_to=image_card_upload)
dice = models.IntegerField(default=1)
rps = models.CharField(choices=RPS_CHOICES, default=ROCK, max_length=1)
# Links
link_en = models.CharField(max_length=64, blank=True, null=True)
link_es = models.CharField(max_length=64, blank=True, null=True)
link_fr = models.CharField(max_length=64, blank=True, null=True)
link_it = models.CharField(max_length=64, blank=True, null=True)
link_de = models.CharField(max_length=64, blank=True, null=True)
class Meta:
ordering = ('collection', 'number', 'name', )
link_eu = models.CharField(max_length=255, blank=True, null=True)
link_jp = models.CharField(max_length=255, blank=True, null=True)
link_us = models.CharField(max_length=255, blank=True, null=True)
release_date = models.DateField(null=True, blank=True)
visible = models.BooleanField(default=True)
_types = {
'figure': 'amiibo.AmiiboFigure',
'card': 'amiibo.AmiiboCard',
}
def as_type(self):
""" Returns the amiibo as the correct type model """
# TODO: Improve this, because queries. Change to a manager.
model = apps.get_model(self._types[self.type])
return model.objects.get(pk=self.pk)
def get_all_names(self):
result = u''
for key, value in self.__dict__.items():
if u'name_' in key and self.__dict__[key]:
result += u' {}'.format(self.__dict__[key])
return result
@property
def is_card(self):
return self.type == self.CARD
@property
def is_figure(self):
return self.type == self.FIGURE
def __unicode__(self):
return u"{} {}".format(self.number, self.name)
return unicode(self.name_eu) or u''
@property
def name(self):
name = getattr(self, 'name_{}'.format(get_language()), None)
if name:
return name
if self.name_en:
return self.name_en
return self.name_eu
class AmiiboFigure(Amiibo):
statue = models.ImageField(upload_to=image_statue_upload)
box = models.ImageField(upload_to=image_box_upload, blank=True, null=True)
@models.permalink
def get_absolute_url(self):
return ('amiibo:figure-detail', [self.collection.slug, slugify(self.name), self.pk])
@property
def image_box(self):
return 'images/amiibo/{}/{}-box.jpg'.format(
self.collection.slug, self.slug
)
@property
def image(self):
return self.statue
@property
def image_statue(self):
return 'images/amiibo/{}/{}.png'.format(
self.collection.slug, self.slug
)
class AmiiboCard(Amiibo):
ROCK = 'rock'
PAPER = 'paper'
SCISSORS = 'scissors'
RPS_CHOICES = (
(ROCK, _('Rock')),
(PAPER, _('Paper')),
(SCISSORS, _('Scissors')),
)
CARD_TYPE_CHOICES = (
('alligator', _('Alligator')),
('anteater', _('Anteater')),
('bear', _('Bear')),
('bird', _('Bird')),
('bull', _('Bull')),
('cat', _('Cat')),
('chicken', _('Chicken')),
('cow', _('Cow')),
('cub', _('Cub')),
('deer', _('Deer')),
('dog', _('Dog')),
('duck', _('Duck')),
('eagle', _('Eagle')),
('elephant', _('Elephant')),
('frog', _('Frog')),
('goat', _('Goat')),
('gorilla', _('Gorilla')),
('hamster', _('Hamster')),
('hippo', _('Hippo')),
('horse', _('Horse')),
('kangaroo', _('Kangaroo')),
('koala', _('Koala')),
('lion', _('Lion')),
('monkey', _('Monkey')),
('mouse', _('Mouse')),
('octopus', _('Octopus')),
('ostrich', _('Ostrich')),
('penguin', _('Penguin')),
('pig', _('Pig')),
('rabbit', _('Rabbit')),
('rhino', _('Rhino')),
('sheep', _('Sheep')),
('special', _('Special')),
('squirrel', _('Squirrel')),
('tiger', _('Tiger')),
('wolf', _('Wolf')),
)
image = models.ImageField(upload_to=image_card_upload)
card_type = models.CharField(max_length=12, default='special')
dice = models.IntegerField(default=1)
rps = models.CharField(choices=RPS_CHOICES, default=ROCK, max_length=12)
class Meta:
ordering = ('collection', 'collection_number', 'name_eu', )
def get_card_type_display(self):
return dict(self.CARD_TYPE_CHOICES)[self.card_type]
@models.permalink
def get_absolute_url(self):
return ('amiibo:card-detail',
[slugify(self.collection.name), slugify(self.name), self.pk])
def __unicode__(self):
return u"{} {}".format(self.collection_number, self.slug)
class AmiiboShop(models.Model):
@ -158,12 +279,15 @@ class AmiiboShop(models.Model):
(PACK, 'Pack'),
)
amiibo = models.ForeignKey(Amiibo, related_name='shops_set')
amiibo = models.ManyToManyField(Amiibo, related_name='shops_set')
shop = models.ForeignKey('shop.Shop', related_name='amiibos_set')
type = models.CharField(choices=ITEM_TYPES, default=FIGURE, max_length=1)
url = models.TextField()
item_id = models.CharField(max_length=64)
check_price = models.BooleanField(default=True)
shop_name = models.CharField(max_length=255, blank=True, null=True)
image = models.ImageField(upload_to=shop_item_upload,
null=True, blank=True)
class Meta:
ordering = ('shop__name', )
@ -194,7 +318,7 @@ class AmiiboShop(models.Model):
return self.type == self.PACK
def __unicode__(self):
return u'{} in {}'.format(self.amiibo.name, self.shop.name)
return u'{} in {}'.format(self.shop_name, self.shop.name)
class AmiiboPrice(models.Model):
@ -258,3 +382,17 @@ class AmiiboPriceHistory(models.Model):
self.diff, self.currency,
self.date
)
class UserAmiibo(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
_amiibo = models.ForeignKey(Amiibo)
want = models.BooleanField(default=False)
own = models.BooleanField(default=False)
trade = models.BooleanField(default=False)
date = models.DateTimeField(auto_now=True)
@property
def amiibo(self):
return self._amiibo.as_type()

View File

@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-
from . import models
def is_owned_by(amiibo, user):
relation, created = models.UserAmiibo.objects.get_or_create(
_amiibo=amiibo, user=user)
return relation.own
def user_add_owned(user, amiibo):
relation, created = models.UserAmiibo.objects.get_or_create(
_amiibo=amiibo, user=user)
relation.own = True
relation.want = False
relation.save()
def user_remove_owned(user, amiibo):
relation, created = models.UserAmiibo.objects.get_or_create(
_amiibo=amiibo, user=user)
relation.own = False
relation.trade = False
relation.save()
def user_add_wishlist(user, amiibo):
relation, created = models.UserAmiibo.objects.get_or_create(
_amiibo=amiibo, user=user)
relation.own = False
relation.want = True
relation.save()
def user_remove_wishlist(user, amiibo):
relation, created = models.UserAmiibo.objects.get_or_create(
_amiibo=amiibo, user=user)
relation.want = False
relation.save()
def user_add_trade(user, amiibo):
relation, created = models.UserAmiibo.objects.get_or_create(
_amiibo=amiibo, user=user)
relation.trade = True
relation.save()
def user_remove_trade(user, amiibo):
relation, created = models.UserAmiibo.objects.get_or_create(
_amiibo=amiibo, user=user)
relation.trade = False
relation.save()
def user_toggle_trade(user, amiibo):
relation, created = models.UserAmiibo.objects.get_or_create(
_amiibo=amiibo, user=user)
relation.trade = not relation.trade
relation.save()

View File

@ -2,18 +2,39 @@
# django
from django.conf.urls import url, patterns
from django.utils.translation import ugettext_lazy as _
# home
from .views import AmiiboView, CollectionView
from .views import (
AmiiboView, AmiiboCardView, AmiiboFigureView,
CollectionView, CollectionCardView, CollectionFigureView,
UserAmiiboView
)
urlpatterns = patterns(
'',
url(r'^(?P<collection>[\w\d\-]+)/$',
CollectionView.as_view(),
name='collection'),
url(r'^(?P<collection>[\w\d\-]+)/(?P<amiibo>[\w\d\-]+)$',
AmiiboView.as_view(),
name='amiibo'),
url(_('^cards$'),
CollectionCardView.as_view(),
name='cards-all'),
url(_(r'^figures$'),
CollectionFigureView.as_view(),
name='figures-all'),
url(_(r'^cards/(?P<dummy>[\w\d\-]+)?\-(?P<collection>\d+)$'),
CollectionCardView.as_view(),
name='cards-list'),
url(_(r'^figures/(?P<dummy>[\w\d\-]+)?\-(?P<collection>\d+)$'),
CollectionFigureView.as_view(),
name='figures-list'),
url(_(r'^cards/(?P<collection>[\w\d\-]+)?/(?P<dummy>[\w\d\-]+)?-(?P<amiibo>[\w\d\-]+)$'),
AmiiboCardView.as_view(),
name='card-detail'),
url(_(r'^figures/(?P<collection>[\w\d\-]+)?/(?P<dummy>[\w\d\-]+)?-(?P<amiibo>[\w\d\-]+)$'),
AmiiboFigureView.as_view(),
name='figure-detail'),
url(_(r'^amiibo/(?P<amiibo>\d+)/(?P<action>[\w\+\-\=]+)$'),
UserAmiiboView.as_view(),
name='user-action'),
)

View File

@ -1,39 +1,146 @@
# coding: utf-8
# -*- coding: utf-8 -*-
# django
from django.http import HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
from django.views.generic.base import View
# amiibo
from amiibofindr.apps.amiibo.models import Collection, Amiibo
from .models import (
Collection, Amiibo,
AmiiboFigure, AmiiboCard,
UserAmiibo
)
from . import services
class CollectionView(View):
template = 'amiibo/collection.html'
type = Amiibo.FIGURE
model = AmiiboFigure
section = 'collection'
def get(self, request, collection='all'):
if collection != 'all':
collection = get_object_or_404(Collection, slug=collection)
amiibo_list = collection.amiibos
def get(self, request, collection=None, dummy=None):
if collection:
collection = get_object_or_404(Collection, pk=collection)
if self.type == self.model.FIGURE:
amiibo_list = collection.figures.filter(visible=True)
elif self.type == self.model.CARD:
amiibo_list = collection.cards.filter(visible=True)
else:
amiibo_list = collection.amiibo.filter(visible=True)
else:
collection = None
amiibo_list = Amiibo.objects.all().order_by('name_eu')
amiibo_list = self.model.objects.filter(visible=True)
return render(request, self.template, {
'selected_collection': collection,
'amiibo_list': amiibo_list,
'item': collection,
'section': self.section,
})
class AmiiboView(View):
template = 'amiibo/amiibo.html'
class CollectionFigureView(CollectionView):
type = Amiibo.FIGURE
model = AmiiboFigure
def get(self, request, collection=None, amiibo=None):
amiibo_obj = get_object_or_404(Amiibo,
slug=amiibo,
collection__slug=collection)
class CollectionCardView(CollectionView):
template = 'amiibo/collection-cards.html'
type = Amiibo.CARD
model = AmiiboCard
class AmiiboView(View):
section = 'amiibo'
def get(self, request, collection=None, amiibo=None, dummy=None):
amiibo_obj = get_object_or_404(self.model,
pk=amiibo,
# collection__slug=collection,
type=self.type)
return render(request, self.template, {
'selected_collection': amiibo_obj.collection,
'amiibo': amiibo_obj,
'item': amiibo_obj,
'section': self.section,
'users_trading': UserAmiibo.objects.filter(
trade=True, _amiibo_id=amiibo_obj.pk
).order_by('user__username'),
})
class AmiiboFigureView(AmiiboView):
template = 'amiibo/amiibo-figure.html'
type = Amiibo.FIGURE
model = AmiiboFigure
class AmiiboCardView(AmiiboView):
template = 'amiibo/amiibo-card.html'
type = Amiibo.CARD
model = AmiiboCard
class UserAmiiboView(View):
actions = {
'+owned': 'add_owned',
'-owned': 'remove_owned',
'+wishlist': 'add_wishlist',
'-wishlist': 'remove_wishlist',
'+trade': 'add_trade',
'-trade': 'remove_trade',
'+-trade': 'toggle_trade',
}
ajax = {
'detail': 'amiibo/widgets/relation_header_buttons.html',
'list': 'amiibo/widgets/amiibo-card.html',
}
def get(self, request, amiibo, action):
obj = get_object_or_404(Amiibo, pk=amiibo)
amiibo = obj.as_type()
if action in self.actions:
method = getattr(self, self.actions[action], None)
if method:
result = method(request, amiibo)
if result:
return result
# Handle templating
request_from = request.GET.get('from', None)
if request_from in self.ajax:
return render(request, self.ajax[request_from],
{ 'amiibo': amiibo, 'request': request })
return HttpResponseRedirect(amiibo.as_type().get_absolute_url())
def add_wishlist(self, request, amiibo):
services.user_add_wishlist(request.user, amiibo)
# TODO: Add message
def remove_wishlist(self, request, amiibo):
services.user_remove_wishlist(request.user, amiibo)
# TODO: Add message
def add_trade(self, request, amiibo):
if services.is_owned_by(amiibo, request.user):
services.user_add_trade(request.user, amiibo)
# TODO: Add message
def remove_trade(self, request, amiibo):
if services.is_owned_by(amiibo, request.user):
services.user_remove_trade(request.user, amiibo)
# TODO: Add message
def toggle_trade(self, request, amiibo):
if services.is_owned_by(amiibo, request.user):
services.user_toggle_trade(request.user, amiibo)
# TODO: Add message
def add_owned(self, request, amiibo):
services.user_add_owned(request.user, amiibo)
# TODO: Add message
def remove_owned(self, request, amiibo):
services.user_remove_owned(request.user, amiibo)
# TODO: Add message

View File

@ -1,9 +1,9 @@
# coding: utf-8
# py3
from __future__ import unicode_literals
# django
from django.utils.translation import activate, deactivate, get_language
from django.core.urlresolvers import resolve, reverse_lazy
from django.conf import settings
@ -18,3 +18,31 @@ def files(request):
'MEDIA_URL': settings.MEDIA_URL,
'STATIC_URL': settings.STATIC_URL,
}
def i18n(request):
lang = get_language()
result = []
try:
res = resolve(request.path)
for lang_code, name in settings.LANGUAGES:
activate(lang_code)
this = {
'code': lang_code,
'name': name,
'url': reverse_lazy(res.view_name, args=res.args, kwargs=res.kwargs)
}
result.append(this)
deactivate()
activate(lang)
except:
for lang_code, name in settings.LANGUAGES:
this = {
'code': lang_code,
'name': name,
'url': '/{}/'.format(lang_code)
}
result.append(this)
return {
'LANGUAGES': result
}

View File

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
from django.conf import settings
from django.utils.translation import activate
class LanguageMiddleware:
def process_request(self, request):
languages = dict(settings.LANGUAGES)
accept_language = request.META.get('HTTP_ACCEPT_LANGUAGE', '')
if not accept_language:
return None
lang = accept_language.split(',')[0]
if '-' in lang:
lang = lang.split('-')[0]
if lang in languages:
activate(lang)
return None

View File

@ -9,5 +9,5 @@ from .views import HomeView
urlpatterns = patterns(
'',
url(r'^$', HomeView.as_view()),
url(r'^$', HomeView.as_view(), name='home'),
)

View File

@ -1,11 +1,11 @@
# coding: utf-8
# -*- coding: utf-8 -*-
# django
from django.views.generic.base import View
from django.shortcuts import redirect
from django.core.urlresolvers import reverse
from django.shortcuts import render
class HomeView(View):
template = 'home/home.html'
def get(self, request):
return redirect(reverse('amiibo:collection', args=['all']))
return render(request, self.template, {})

View File

@ -11,8 +11,8 @@ from .models import AmiiboNotification
class AmiiboNotificationAdmin(reversion.VersionAdmin):
list_display = ('amiibo', 'max_price', 'interval', 'shops_list', 'last_notification',)
list_editable = ('interval', )
list_display = ('amiibo', 'max_price', 'interval', 'shops_list', 'notify_twitter', 'last_notification',)
list_editable = ('interval', 'notify_twitter', )
filter_horizontal = ('shops', )
def shops_list(self, obj):

View File

View File

View File

@ -0,0 +1,13 @@
# -*- coding: utf-8 -*-
import hashlib
from django import template
register = template.Library()
@register.simple_tag
def gravatar(user, size=200):
return 'https://www.gravatar.com/avatar/{}?s={}&d=mm'.format(
hashlib.md5(user.email).hexdigest(),
size
)

View File

@ -0,0 +1,20 @@
# coding: utf-8
# django
from django.conf.urls import url, patterns
from django.utils.translation import ugettext_lazy as _
# home
from .views import ProfileView
urlpatterns = patterns(
'',
url(_(r'^profile/(?P<username>[\w\d\-]+)/$'),
ProfileView.as_view(),
name='main'),
url(_(r'^profile/(?P<username>[\w\d\-]+)/(?P<type>\w+)/(?P<relation>\w+)/$'),
ProfileView.as_view(),
name='main-filter'),
)

View File

@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
from django.contrib.auth import get_user_model
from django.views.generic.base import View
from django.shortcuts import render, get_object_or_404
from amiibofindr.apps.amiibo.models import UserAmiibo, AmiiboFigure, AmiiboCard
class ProfileView(View):
template = 'profile/main.html'
types = {
'figures': ('figure', AmiiboFigure),
'cards': ('card', AmiiboCard),
}
relations = ('own', 'want', 'trade', )
def get(self, request, username, type='figures', relation='own'):
user = get_object_or_404(get_user_model(), username=username)
relation_filter = {relation: True}
amiibo_pks = UserAmiibo.objects.filter(
user=user,
_amiibo__type=self.types[type][0],
**relation_filter
).values_list('_amiibo__id', flat=True)
amiibo_list = self.types[type][1].objects.filter(pk__in=amiibo_pks)
return render(request, self.template, {
'this_user': user,
'amiibo_list': amiibo_list,
'type': type,
'relation': relation,
'stats': {
'figures_count': UserAmiibo.objects.filter(
user=user, _amiibo__type='figure', own=True).count(),
'cards_count': UserAmiibo.objects.filter(
user=user, _amiibo__type='card', own=True).count(),
}
})

View File

@ -3,6 +3,7 @@
# py
from __future__ import unicode_literals
from time import sleep
import urllib2
# third party
from amazon.api import AmazonAPI
@ -26,26 +27,36 @@ class AmazonBaseCrawler(object):
region=self.region
)
def parse_product(self, product):
price_and_currency = product.price_and_currency
price = price_and_currency[0]
currency = price_and_currency[1]
if currency == 'JPY':
price = float(price)*100
print(self.region, product.asin, price, currency, product.title)
return {
'shop_product_id': product.asin,
'price': price,
'currency': currency,
'title': product.title,
}
def fetch_batch(self, product_ids):
result = []
for chunk_product_ids in chunks(product_ids, self.max_batch_lookup):
products = self.amazon.lookup(ItemId=','.join(chunk_product_ids))
for product in products:
price_and_currency = product.price_and_currency
price = price_and_currency[0]
currency = price_and_currency[1]
if currency == 'JPY':
price = float(price)*100
print(self.region, product.asin, price, currency)
result.append({
'shop_product_id': product.asin,
'price': price,
'currency': currency,
})
try:
products = self.amazon.lookup(ItemId=','.join(chunk_product_ids))
except urllib2.HTTPError:
return result
try:
for product in products:
result.append(self.parse_product(product))
except TypeError:
result.append(self.parse_product(products))
sleep(1)
return result

View File

@ -0,0 +1,989 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-10-11 10:53+0200\n"
"PO-Revision-Date: 2015-10-11 10:54+0200\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 1.8.5\n"
#: amiibofindr/apps/amiibo/models.py:208
msgid "Rock"
msgstr "Piedra"
#: amiibofindr/apps/amiibo/models.py:209
msgid "Paper"
msgstr "Papel"
#: amiibofindr/apps/amiibo/models.py:210
msgid "Scissors"
msgstr "Tijera"
#: amiibofindr/apps/amiibo/models.py:214
msgid "Alligator"
msgstr "Caimán"
#: amiibofindr/apps/amiibo/models.py:215
msgid "Anteater"
msgstr "Oso hormiguero"
#: amiibofindr/apps/amiibo/models.py:216
msgid "Bear"
msgstr "Oso"
#: amiibofindr/apps/amiibo/models.py:217
msgid "Bird"
msgstr "Pájaro"
#: amiibofindr/apps/amiibo/models.py:218
msgid "Bull"
msgstr "Toro"
#: amiibofindr/apps/amiibo/models.py:219
msgid "Cat"
msgstr "Gato"
#: amiibofindr/apps/amiibo/models.py:220
msgid "Chicken"
msgstr "Gallina"
#: amiibofindr/apps/amiibo/models.py:221
msgid "Cow"
msgstr "Vaca"
#: amiibofindr/apps/amiibo/models.py:222
msgid "Cub"
msgstr "Cachorro"
#: amiibofindr/apps/amiibo/models.py:223
msgid "Deer"
msgstr "Ciervo"
#: amiibofindr/apps/amiibo/models.py:224
msgid "Dog"
msgstr "Perro"
#: amiibofindr/apps/amiibo/models.py:225
msgid "Duck"
msgstr "Pato"
#: amiibofindr/apps/amiibo/models.py:226
msgid "Eagle"
msgstr "Águila"
#: amiibofindr/apps/amiibo/models.py:227
msgid "Elephant"
msgstr "Elefante"
#: amiibofindr/apps/amiibo/models.py:228
msgid "Frog"
msgstr "Rana"
#: amiibofindr/apps/amiibo/models.py:229
msgid "Goat"
msgstr "Cabra"
#: amiibofindr/apps/amiibo/models.py:230
msgid "Gorilla"
msgstr "Gorila"
#: amiibofindr/apps/amiibo/models.py:231
msgid "Hamster"
msgstr "Hamster"
#: amiibofindr/apps/amiibo/models.py:232
msgid "Hippo"
msgstr "Hipopótamo"
#: amiibofindr/apps/amiibo/models.py:233
msgid "Horse"
msgstr "Caballo"
#: amiibofindr/apps/amiibo/models.py:234
msgid "Kangaroo"
msgstr "Canguro"
#: amiibofindr/apps/amiibo/models.py:235
msgid "Koala"
msgstr "Koala"
#: amiibofindr/apps/amiibo/models.py:236
msgid "Lion"
msgstr "León"
#: amiibofindr/apps/amiibo/models.py:237
msgid "Monkey"
msgstr "Mono"
#: amiibofindr/apps/amiibo/models.py:238
msgid "Mouse"
msgstr "Ratón"
#: amiibofindr/apps/amiibo/models.py:239
msgid "Octopus"
msgstr "Pulpo"
#: amiibofindr/apps/amiibo/models.py:240
msgid "Ostrich"
msgstr "Avestruz"
#: amiibofindr/apps/amiibo/models.py:241
msgid "Penguin"
msgstr "Pinguino"
#: amiibofindr/apps/amiibo/models.py:242
msgid "Pig"
msgstr "Cerdo"
#: amiibofindr/apps/amiibo/models.py:243
msgid "Rabbit"
msgstr "Conejo"
#: amiibofindr/apps/amiibo/models.py:244
msgid "Rhino"
msgstr "Rinoceronte"
#: amiibofindr/apps/amiibo/models.py:245
msgid "Sheep"
msgstr "Oveja"
#: amiibofindr/apps/amiibo/models.py:246
msgid "Special"
msgstr "Especial"
#: amiibofindr/apps/amiibo/models.py:247
msgid "Squirrel"
msgstr "Ardilla"
#: amiibofindr/apps/amiibo/models.py:248
msgid "Tiger"
msgstr "Tigre"
#: amiibofindr/apps/amiibo/models.py:249
msgid "Wolf"
msgstr "Lobo"
#: amiibofindr/apps/amiibo/urls.py:16
msgid "^cards$"
msgstr "^tarjetas$"
#: amiibofindr/apps/amiibo/urls.py:19
msgid "^figures$"
msgstr "^figuras$"
#: amiibofindr/apps/amiibo/urls.py:23
msgid "^cards/(?P<dummy>[\\w\\d\\-]+)?\\-(?P<collection>\\d+)$"
msgstr "^tarjetas/(?P<dummy>[\\w\\d\\-]+)?\\-(?P<collection>\\d+)$"
#: amiibofindr/apps/amiibo/urls.py:26
msgid "^figures/(?P<dummy>[\\w\\d\\-]+)?\\-(?P<collection>\\d+)$"
msgstr "^figuras/(?P<dummy>[\\w\\d\\-]+)?\\-(?P<collection>\\d+)$"
#: amiibofindr/apps/amiibo/urls.py:30
msgid ""
"^cards/(?P<collection>[\\w\\d\\-]+)?/(?P<dummy>[\\w\\d\\-]+)?-(?P<amiibo>[\\w"
"\\d\\-]+)$"
msgstr ""
"^tarjetas/(?P<collection>[\\w\\d\\-]+)?/(?P<dummy>[\\w\\d\\-]+)?-(?"
"P<amiibo>[\\w\\d\\-]+)$"
#: amiibofindr/apps/amiibo/urls.py:33
msgid ""
"^figures/(?P<collection>[\\w\\d\\-]+)?/(?P<dummy>[\\w\\d\\-]+)?-(?"
"P<amiibo>[\\w\\d\\-]+)$"
msgstr ""
"^figuras/(?P<collection>[\\w\\d\\-]+)?/(?P<dummy>[\\w\\d\\-]+)?-(?"
"P<amiibo>[\\w\\d\\-]+)$"
#: amiibofindr/apps/amiibo/urls.py:37
msgid "^amiibo/(?P<amiibo>\\d+)/(?P<action>[\\w\\+\\-\\=]+)$"
msgstr "^amiibo/(?P<amiibo>\\d+)/(?P<action>[\\w\\+\\-\\=]+)$"
#: amiibofindr/apps/profile/urls.py:13
msgid "^profile/(?P<username>[\\w\\d\\-]+)/$"
msgstr "^perfil/(?P<username>[\\w\\d\\-]+)/$"
#: amiibofindr/apps/profile/urls.py:16
msgid "^profile/(?P<username>[\\w\\d\\-]+)/(?P<type>\\w+)/(?P<relation>\\w+)/$"
msgstr "^perfil/(?P<username>[\\w\\d\\-]+)/(?P<type>\\w+)/(?P<relation>\\w+)/$"
#: amiibofindr/templates/404.html:10
msgid "Not found!"
msgstr "No encontrado."
#: amiibofindr/templates/404.html:12
#, python-format
msgid ""
"\n"
"\t\t\t\tOoooopsie. We didn't find what you're looking for. <a href="
"\"%(url_home)s\">Go back to the home page</a>.\n"
"\t\t\t"
msgstr ""
"\n"
"Ooops. No hemos podido encontrar lo que estabas buscando. <a "
"href=“%(url_home)s”>Volver a la home</a>."
#: amiibofindr/templates/500.html:9
msgid "Server error"
msgstr "Error de servidor"
#: amiibofindr/templates/500.html:12
#, python-format
msgid ""
"\n"
"\t\t\t\tThere was a server issue. Our developers have been informed of this. "
"Please try refreshing the page or <a href=\"%(url_home)s\">go back to the "
"home page</a>.\n"
"\t\t\t"
msgstr ""
"\n"
"Ha habido un problema en nuestro servidor. Nuestros desarrolladores han sido "
"informados. Por favor, prueba refrescando la página o <a "
"href=“%(url_home)s”>vuelve a la home</a>."
#: amiibofindr/templates/_layout.html:5
msgid "all"
msgstr "todas"
#: amiibofindr/templates/_layout.html:37 amiibofindr/templates/_layout.html:108
#: amiibofindr/templates/profile/main.html:25
#: amiibofindr/templates/profile/main.html:78
msgid "Figures"
msgstr "Figuras"
#: amiibofindr/templates/_layout.html:40 amiibofindr/templates/_layout.html:51
#: amiibofindr/templates/_layout.html:110
#: amiibofindr/templates/_layout.html:119
msgid "All"
msgstr "Todas"
#: amiibofindr/templates/_layout.html:48 amiibofindr/templates/_layout.html:117
#: amiibofindr/templates/profile/main.html:33
#: amiibofindr/templates/profile/main.html:79
msgid "Cards"
msgstr "Tarjetas"
#: amiibofindr/templates/_layout.html:63 amiibofindr/templates/_layout.html:92
msgid "My public profile"
msgstr "Mi perfil público"
#: amiibofindr/templates/_layout.html:64 amiibofindr/templates/_layout.html:93
#: amiibofindr/templates/account/password_reset_from_key.html:49
msgid "Change password"
msgstr "Cambiar contraseña"
#: amiibofindr/templates/_layout.html:65 amiibofindr/templates/_layout.html:95
msgid "Social accounts"
msgstr "Redes sociales"
#: amiibofindr/templates/_layout.html:66 amiibofindr/templates/_layout.html:94
msgid "Emails"
msgstr "Emails"
#: amiibofindr/templates/_layout.html:68 amiibofindr/templates/_layout.html:96
msgid "Log out"
msgstr "Cerrar sesión"
#: amiibofindr/templates/_layout.html:72 amiibofindr/templates/_layout.html:102
#: amiibofindr/templates/home/home.html:90
msgid "Login"
msgstr "Iniciar sesión"
#: amiibofindr/templates/_layout.html:73 amiibofindr/templates/_layout.html:103
#: amiibofindr/templates/home/home.html:88
msgid "Register"
msgstr "Registrarse"
#: amiibofindr/templates/_layout.html:147
msgid "Select desired currency"
msgstr "Seleccionar moneda"
#: amiibofindr/templates/_layout.html:152
msgid "No convert"
msgstr "Sin conversión"
#: amiibofindr/templates/_layout.html:156
msgid "Language"
msgstr "Idioma"
#: amiibofindr/templates/account/email.html:5
msgid "Account"
msgstr "Mi cuenta"
#: amiibofindr/templates/account/email.html:10
msgid "E-mail Addresses"
msgstr "Cuentas de email"
#: amiibofindr/templates/account/email.html:15
msgid "The following e-mail addresses are associated with your account:"
msgstr "Los siguientes emails están asociados a tu cuenta:"
#: amiibofindr/templates/account/email.html:37
msgid "Verified"
msgstr "Verificada"
#: amiibofindr/templates/account/email.html:39
msgid "Unverified"
msgstr "Sin verificar"
#: amiibofindr/templates/account/email.html:42
msgid "Primary"
msgstr "Primaria"
#: amiibofindr/templates/account/email.html:51
msgid "Make Primary"
msgstr "Hacer primaria"
#: amiibofindr/templates/account/email.html:53
msgid "Re-send Verification"
msgstr "Re-enviar verificación"
#: amiibofindr/templates/account/email.html:55
#: amiibofindr/templates/socialaccount/connections.html:46
msgid "Remove"
msgstr "Eliminar"
#: amiibofindr/templates/account/email.html:60
msgid "Warning:"
msgstr "Alerta:"
#: amiibofindr/templates/account/email.html:60
msgid ""
"You currently do not have any e-mail address set up. You should really add "
"an e-mail address so you can receive notifications, reset your password, etc."
msgstr ""
"Actualmente no tienes ningún email asociado a tu cuenta. Deberías añadir uno "
"para que puedas recibir notificaciones, restablecer tu contraseña, etc."
#: amiibofindr/templates/account/email.html:63
msgid "Add E-mail Address"
msgstr "Añadir una dirección de email"
#: amiibofindr/templates/account/email.html:83
msgid "Add E-mail"
msgstr "Añadir email"
#: amiibofindr/templates/account/email/email_confirmation_message.txt:1
#, python-format
msgid ""
"Hello from %(site_name)s!\n"
"\n"
"You're receiving this e-mail because user %(user_display)s at "
"%(site_domain)s has given yours as an e-mail address to connect their "
"account.\n"
"\n"
"To confirm this is correct, go to %(activate_url)s\n"
msgstr ""
"¡Hola desde %(site_name)s!\n"
"\n"
"Recibes este correo electrónico porque el usuario %(user_display)s en "
"%(site_domain)s nos ha dado esta dirección para vincular su cuenta. \n"
"\n"
"Para confirmar que esto es correcto, por favor accede a este enlace: "
"%(activate_url)s\n"
#: amiibofindr/templates/account/email/email_confirmation_message.txt:7
#, python-format
msgid ""
"Thank you from %(site_name)s!\n"
"%(site_domain)s"
msgstr ""
"¡Un saludo desde %(site_name)s!\n"
"%(site_domain)s"
#: amiibofindr/templates/account/email/email_confirmation_subject.txt:3
msgid "Please Confirm Your E-mail Address"
msgstr "Por favor confirma tu correo electrónico"
#: amiibofindr/templates/account/email/password_reset_key_message.txt:1
#, python-format
msgid ""
"Hello from %(site_name)s!\n"
"\n"
"You're receiving this e-mail because you or someone else has requested a "
"password for your user account at %(site_domain)s.\n"
"It can be safely ignored if you did not request a password reset. Click the "
"link below to reset your password."
msgstr ""
"¡Hola desde %(site_name)s!\n"
"\n"
"Recibes este correo porque tu u otra persona ha solicitado la recuperación "
"de tu cuenta en %(site_domain)s.\n"
"Sigue el enlace a continuación para continuar con el restablecimiento de tu "
"contraseña."
#: amiibofindr/templates/account/email/password_reset_key_message.txt:8
#, python-format
msgid "In case you forgot, your username is %(username)s."
msgstr ""
"En el caso de que te hayas olvidado, tu nombre de usuario es %(username)s."
#: amiibofindr/templates/account/email/password_reset_key_message.txt:10
#, python-format
msgid ""
"Thank you for using %(site_name)s!\n"
"%(site_domain)s"
msgstr ""
"¡Gracias por usar %(site_name)s!\n"
"%(site_domain)s"
#: amiibofindr/templates/account/email/password_reset_key_subject.txt:3
msgid "Password Reset E-mail"
msgstr "Correo electrónico"
#: amiibofindr/templates/account/email_confirm.html:6
#: amiibofindr/templates/account/email_confirm.html:12
#: amiibofindr/templates/account/email_confirmed.html:6
#: amiibofindr/templates/account/email_confirmed.html:12
#: amiibofindr/templates/email_confirm.html:6
#: amiibofindr/templates/email_confirm.html:12
msgid "Confirm E-mail Address"
msgstr "Confirmar correo electrónico"
#: amiibofindr/templates/account/email_confirm.html:19
#: amiibofindr/templates/email_confirm.html:19
#, python-format
msgid ""
"Please confirm that <a href=\"mailto:%(email)s\">%(email)s</a> is an e-mail "
"address for user %(user_display)s."
msgstr ""
"Por favor confirma que el correo electrónico <a href=\"mailto:%(email)s\">"
"%(email)s</a> es del usuario %(user_display)s."
#: amiibofindr/templates/account/email_confirm.html:23
#: amiibofindr/templates/email_confirm.html:23
msgid "Confirm"
msgstr "Confirmar"
#: amiibofindr/templates/account/email_confirm.html:30
#: amiibofindr/templates/email_confirm.html:30
#, python-format
msgid ""
"This e-mail confirmation link expired or is invalid. Please <a href="
"\"%(email_url)s\">issue a new e-mail confirmation request</a>."
msgstr ""
"Este enlace de activación de correo electrónico ha expirado. Por favor <a "
"href=\"%(email_url)s\">pide una nueva confirmación</a>."
#: amiibofindr/templates/account/email_confirmed.html:17
#, python-format
msgid ""
"You have confirmed that <a href=\"mailto:%(email)s\">%(email)s</a> is an e-"
"mail address for user %(user_display)s."
msgstr ""
"Has confirmado el correo electrónico <a href=\"mailto:%(email)s\">%(email)s</"
"a> para el usuario %(user_display)s."
#: amiibofindr/templates/account/login.html:6
#: amiibofindr/templates/account/login.html:13
#: amiibofindr/templates/account/login.html:99
msgid "Sign In"
msgstr "Iniciar sesión"
#: amiibofindr/templates/account/login.html:17
#, python-format
msgid ""
"Please sign in with one\n"
" of your existing social accounts. Or, <a href=\"%(signup_url)s"
"\">sign up</a>\n"
" for a %(site_name)s account and sign in below."
msgstr ""
"Por favor inicia sesión con una de tus redes sociales. O, <a href="
"\"%(signup_url)s\">registrate</a> para crear una cuenta en %(site_name)s e "
"inicia sesión más abajo."
#: amiibofindr/templates/account/login.html:46
#, python-format
msgid ""
"If you have not created an account yet, then please\n"
" <a href=\"%(signup_url)s\">sign up</a> first."
msgstr ""
"Si aún no has creado una cuenta, por favor, <a href=\"%(signup_url)s"
"\">regístrate</a> primero."
#: amiibofindr/templates/account/login.html:51
msgid "If you already have an account, please sign in here:"
msgstr "Si ya tienes una cuenta, inicia sesión aquí:"
#: amiibofindr/templates/account/login.html:89
msgid "Remember me"
msgstr "Recordarme"
#: amiibofindr/templates/account/login.html:98
msgid "Forgot Password?"
msgstr "He olvidado mi contraseña"
#: amiibofindr/templates/account/messages/cannot_delete_primary_email.txt:2
#, python-format
msgid "You cannot remove your primary e-mail address (%(email)s)."
msgstr "No puedes eliminar tu dirección de correo primaria (%(email)s)."
#: amiibofindr/templates/account/messages/email_confirmation_sent.txt:2
#, python-format
msgid "Confirmation e-mail sent to %(email)s."
msgstr "Correo electrónico de confirmación enviado a %(email)s."
#: amiibofindr/templates/account/messages/email_confirmed.txt:2
#, python-format
msgid "You have confirmed %(email)s."
msgstr "El correo %(email)s ha sido confirmado."
#: amiibofindr/templates/account/messages/email_deleted.txt:2
#, python-format
msgid "Removed e-mail address %(email)s."
msgstr "El correo electronico %(email)s ha sido eliminado."
#: amiibofindr/templates/account/messages/logged_in.txt:4
#, python-format
msgid "Successfully signed in as %(name)s."
msgstr "Hola %(name)s, has iniciado sesión satisfactoriamente."
#: amiibofindr/templates/account/messages/logged_out.txt:2
msgid "You have signed out."
msgstr "Has cerrado sesión."
#: amiibofindr/templates/account/messages/password_changed.txt:2
msgid "Password successfully changed."
msgstr "Tu contraseña ha sido cambiada."
#: amiibofindr/templates/account/messages/password_set.txt:2
msgid "Password successfully set."
msgstr "Tu contraseña ha sido fijada."
#: amiibofindr/templates/account/messages/primary_email_set.txt:2
msgid "Primary e-mail address set."
msgstr "Establecido tu correo electrónico primario."
#: amiibofindr/templates/account/messages/unverified_primary_email.txt:2
msgid "Your primary e-mail address must be verified."
msgstr "Tu dirección de correo electrónico primaria debe ser verificada."
#: amiibofindr/templates/account/password_change.html:5
#: amiibofindr/templates/account/password_change.html:10
#: amiibofindr/templates/account/password_reset_from_key.html:5
#: amiibofindr/templates/account/password_reset_from_key.html:10
#: amiibofindr/templates/account/password_reset_from_key_done.html:5
#: amiibofindr/templates/account/password_reset_from_key_done.html:10
msgid "Change Password"
msgstr "Cambiar contraseña"
#: amiibofindr/templates/account/password_change.html:56
#: amiibofindr/templates/account/password_set.html:56
msgid "Set password"
msgstr "Establecer una contraseña"
#: amiibofindr/templates/account/password_reset.html:6
#: amiibofindr/templates/account/password_reset.html:11
#: amiibofindr/templates/account/password_reset_done.html:6
#: amiibofindr/templates/account/password_reset_done.html:11
msgid "Password Reset"
msgstr "Respetar mi contraseña"
#: amiibofindr/templates/account/password_reset.html:18
msgid "Go back to the homepage"
msgstr "Volver a la página principal"
#: amiibofindr/templates/account/password_reset.html:20
msgid ""
"Have you forgotten your password? Enter your e-mail address below, and we'll "
"send you an e-mail allowing you to reset it."
msgstr ""
"¿Has olvidado tu contraseña? Introduce tu dirección de correo y te "
"enviaremos instrucciones de como restablecerla."
#: amiibofindr/templates/account/password_reset.html:36
msgid "Reset My Password"
msgstr "Restablecer mi contraseña"
#: amiibofindr/templates/account/password_reset.html:39
msgid "Please contact us if you have any trouble resetting your password."
msgstr ""
"Por favor contacta con nosotros si tienes algún problema restablecer tu "
"contraseña."
#: amiibofindr/templates/account/password_reset_done.html:19
msgid ""
"We have sent you an e-mail. Please contact us if you do not receive it "
"within a few minutes."
msgstr ""
"Te hemos enviado un correo electrónico. Contacta con nosotros si no lo has "
"recibido en unos minutos."
#: amiibofindr/templates/account/password_reset_from_key.html:10
msgid "Bad Token"
msgstr "Token invalido"
#: amiibofindr/templates/account/password_reset_from_key.html:15
#, python-format
msgid ""
"The password reset link was invalid, possibly because it has already been "
"used. Please request a <a href=\"%(passwd_reset_url)s\">new password reset</"
"a>."
msgstr ""
"El enlace para restablecer tu contraseña es invalido, probablemente porque "
"ya haya sido usado. Por favor, <a href=\"%(passwd_reset_url)s\">vuelve a "
"restablecer tu contraseña</a>."
#: amiibofindr/templates/account/password_reset_from_key.html:53
#: amiibofindr/templates/account/password_reset_from_key_done.html:12
msgid "Your password is now changed."
msgstr "Tu contraseña ha sido cambiada."
#: amiibofindr/templates/account/password_set.html:5
#: amiibofindr/templates/account/password_set.html:10
msgid "Set Password"
msgstr "Establecer contraseña"
#: amiibofindr/templates/account/signup.html:5
msgid "Signup"
msgstr "Registrarse"
#: amiibofindr/templates/account/signup.html:10
#: amiibofindr/templates/account/signup.html:77
msgid "Sign Up"
msgstr "Registrarse"
#: amiibofindr/templates/account/signup.html:14
#, python-format
msgid ""
"Already have an account? Then please <a href=\"%(login_url)s\">sign in</a>."
msgstr "¿Ya tienes una cuenta? <a href=\"%(login_url)s\">Inicia sesión</a>."
#: amiibofindr/templates/amiibo/amiibo-card.html:11
msgid "Number"
msgstr "Numero"
#: amiibofindr/templates/amiibo/amiibo-card.html:15
msgid "Type"
msgstr "Tipo"
#: amiibofindr/templates/amiibo/amiibo-card.html:19
msgid "RPS"
msgstr "PPT"
#: amiibofindr/templates/amiibo/amiibo-card.html:23
msgid "Dice"
msgstr "Dado"
#: amiibofindr/templates/amiibo/amiibo-figure.html:9
#: amiibofindr/templates/amiibo/amiibo-figure.html:11
#: amiibofindr/templates/amiibo/amiibo-figure.html:12
#, python-format
msgid "%(amiibo)s amiibo from %(collection)s in "
msgstr "%(amiibo)s amiibo de %(collection)s en "
#: amiibofindr/templates/amiibo/amiibo-figure.html:59
msgid "Shops"
msgstr "Tiendas"
#: amiibofindr/templates/amiibo/amiibo-figure.html:60
msgid "Users trading"
msgstr "Usuarios para cambio"
#: amiibofindr/templates/amiibo/amiibo-figure.html:74
msgid "Buy now for"
msgstr "Comprar ahora por"
#: amiibofindr/templates/amiibo/amiibo-figure.html:81
msgid "No stock"
msgstr "Sin stock"
#: amiibofindr/templates/amiibo/amiibo-figure.html:89
msgid "Updated"
msgstr "Actualizado"
#: amiibofindr/templates/amiibo/amiibo-figure.html:92
msgid "This item had never been in stock"
msgstr "Este articulo nunca ha estado en stock"
#: amiibofindr/templates/amiibo/amiibo-figure.html:98
msgid "This is a pack of various items"
msgstr "Este es un pack que contiene varios artículos"
#: amiibofindr/templates/amiibo/amiibo-figure.html:108
msgid "No shops :("
msgstr "Sin tiendas :("
#: amiibofindr/templates/amiibo/amiibo-figure.html:128
msgid "No user have this amiibo available for trade :("
msgstr "Ningún usuario tiene disponible este amiibo para cambio :("
#: amiibofindr/templates/amiibo/collection-cards.html:9
#: amiibofindr/templates/amiibo/collection.html:29
msgid "Search..."
msgstr "Buscar…"
#: amiibofindr/templates/amiibo/collection.html:4
#: amiibofindr/templates/amiibo/collection.html:6
#: amiibofindr/templates/amiibo/collection.html:7
#, python-format
msgid "%(collection)s amiibos in "
msgstr "Amiibos de %(collection)s en "
#: amiibofindr/templates/amiibo/collection.html:18
msgid "All amiibo"
msgstr "Todos los amiibo"
#: amiibofindr/templates/amiibo/widgets/relation_header_buttons.html:9
msgid "Available for trade"
msgstr "Disponible para cambio"
#: amiibofindr/templates/amiibo/widgets/relation_header_buttons.html:12
msgid "I do not have it"
msgstr "No lo tengo"
#: amiibofindr/templates/amiibo/widgets/relation_header_buttons.html:17
msgid "I do not want this"
msgstr "No lo quiero"
#: amiibofindr/templates/amiibo/widgets/relation_header_buttons.html:20
#: amiibofindr/templates/amiibo/widgets/relation_header_buttons.html:32
msgid "I want this"
msgstr "Lo quiero"
#: amiibofindr/templates/amiibo/widgets/relation_header_buttons.html:22
#: amiibofindr/templates/amiibo/widgets/relation_header_buttons.html:33
#: amiibofindr/templates/home/home.html:89
msgid "or"
msgstr "o"
#: amiibofindr/templates/amiibo/widgets/relation_header_buttons.html:24
#: amiibofindr/templates/amiibo/widgets/relation_header_buttons.html:34
msgid "I have this"
msgstr "Lo tengo"
#: amiibofindr/templates/amiibo/widgets/relation_header_buttons.html:37
msgid "Register and star collecting amiibo!"
msgstr "¡Regístrate y empieza a coleccionar Amiibo!"
#: amiibofindr/templates/home/home.html:9
msgid "Welcome to amiibofindr!"
msgstr "¡Bienvenido a Amiibofindr!"
#: amiibofindr/templates/home/home.html:11
msgid ""
"Welcome to the latest version of the site, with tons of new features for you!"
msgstr ""
"¡Bienvenido a la nueva versión del sitio, con muchas novedades para ti!"
#: amiibofindr/templates/home/home.html:12
msgid "Why stay with us? there are some reasons..."
msgstr "¿Por qué nosotros? Aquí te dejamos algunas razones…"
#: amiibofindr/templates/home/home.html:21
msgid "Keep track of what you have and what you want"
msgstr "Lo que tienes y lo que quieres"
#: amiibofindr/templates/home/home.html:22
msgid ""
"Here, you can easily check what amiibo you have or want. Just enter an "
"amiibo description and click one of the buttons, yes, that easy! "
msgstr ""
"Aquí puedes comprobar fácilmente que amibos tienes… ¡y cuales quieres! Solo "
"ve al amiibo y pulsa uno de los dos botones, ¡así de fácil!"
#: amiibofindr/templates/home/home.html:29
msgid "Repeated stuff? No problem! Trade it!"
msgstr "¿Repes? ¡Sin problema! ¡Intercambia!"
#: amiibofindr/templates/home/home.html:30
msgid ""
"Just mark an amiibo as tradeable to show everyone you have one -or more- "
"spare, show some contact information and let the offers come through!"
msgstr ""
"Tan solo tienes que marcar tu amiibo como disponible para mostrar a todos "
"que tienes uno (o más). ¡Deja información de contacto para recibir las "
"ofertas!"
#: amiibofindr/templates/home/home.html:37
msgid "Collect from ANYWHERE"
msgstr "Colecciona desde cualquier sitio"
#: amiibofindr/templates/home/home.html:38
msgid ""
"Lots of stuff to mark as collected or wanted? No problem! You can check your "
"owned amiibo from everywhere on the site, detail, lists or even other users "
"collections."
msgstr ""
"¿Tienes demasiadas cosas en tu colección? ¡No hay problema! Puedes marcar "
"que amibos tienes o quieres desde cualquier parte de la web. Detalles, "
"listados… incluso desde los perfiles de otros usuarios."
#: amiibofindr/templates/home/home.html:45
msgid "Don't lose sight with color coding"
msgstr "No te pierdas con nuestro código de colores"
#: amiibofindr/templates/home/home.html:46
msgid ""
"When logged in, you will see what amiibo you have, want or want to trade. "
"Even when on lists or looking another person's amiibo list."
msgstr ""
"Cuando inicies sesión sabrás de un vistazo que amiibo tienes, quieres o "
"intercambias. ¡Incluso cuando estés mirando la lista de otro usuario!"
#: amiibofindr/templates/home/home.html:53
msgid "Public profiles"
msgstr "Perfiles públicos"
#: amiibofindr/templates/home/home.html:54
msgid ""
"You will get a unique URL where you have all you collected, wanted and "
"traded amiibo. For free! This way you will never forget what you have "
"available."
msgstr ""
"Dispondrás de una dirección web única para ti donde estarán visibles los "
"amiibo que quieres, tienes e intercambias. ¡Gratis! De esta manera nunca "
"olvidaras lo que tienes."
#: amiibofindr/templates/home/home.html:61
msgid "Always at the best price"
msgstr "Siempre al mejor precio"
#: amiibofindr/templates/home/home.html:62
msgid ""
"We know sometimes the most wanted amiibo is difficult to find, so we keep "
"track of online shops for you to get the best prices. And we will be adding "
"more and more!"
msgstr ""
"Sabemos que a veces el amiibo que más deseamos es el más difícil de "
"encontrar así que nosotros monitorizamos tiendas para obtener los mejores "
"precios, e iremos añadiendo más y más."
#: amiibofindr/templates/home/home.html:69
msgid "EUR, GBP, JPY, USD..."
msgstr "EUR, GBP, JPY, USD..."
#: amiibofindr/templates/home/home.html:70
msgid ""
"Because not everyone can do math to convert from currencies on the fly, you "
"can select your desired currency to get an approximate conversion in real "
"time. Easy!"
msgstr ""
"Porque no todo el mundo es bueno con las matemáticas, si te pierdes con "
"monedas extranjeras puedes seleccionar tu preferida para ver todos los "
"precios con ella, ¡así de fácil!"
#: amiibofindr/templates/home/home.html:77
msgid "Even from mobile phones"
msgstr "Incluso desde el móvil"
#: amiibofindr/templates/home/home.html:78
msgid ""
"The site is viewable from mobile phones too! This way you will know what "
"amiibo are you mising... from anywhere!"
msgstr ""
"¡La web se adapta a dispositivos móviles! De esta manera siempre podrás "
"saber que amiibos te faltan… ¡desde cualquier parte!"
#: amiibofindr/templates/home/home.html:82
msgid "And the most important reason of all?"
msgstr "¿Y cual es la razón más importante de todas?"
#: amiibofindr/templates/home/home.html:84
msgid ""
"We are collectors too! We like amiibo and we do this for fun on our spare "
"time."
msgstr ""
"¡Nosotros también somos coleccionistas! Nos gustan los amiibo y hacemos esto "
"por diversión en nuestro tiempo libre."
#: amiibofindr/templates/home/home.html:85
msgid "We'd like to continue with this journey, and you to be helping us."
msgstr "Nos gustaría seguir con ello, ¡y que tu te apuntes!"
#: amiibofindr/templates/home/home.html:93
msgid ""
"And remember that we all make this better. You want your favourite shop "
"added? We're missing some HUGE feature you'd like to see? Just want to get "
"in touch? Feel free! You have our contact details at the bottom."
msgstr ""
"Y recuerda que somos todos los que hacemos esto mejor. ¿Quieres tu tienda "
"favorita añadida? ¿Nos falta algo muy importante que te hará la vida mas "
"fácil? ¿Solo quieres hablar un rato? ¡Contacta con nosotros!"
#: amiibofindr/templates/profile/main.html:15
#: amiibofindr/templates/profile/main.html:63
msgid "Look at my amiibo collection!"
msgstr "¡Mira mi colección de #amiibo!"
#: amiibofindr/templates/profile/main.html:43
msgid "Contact me in:"
msgstr "Contáctame en:"
#: amiibofindr/templates/profile/main.html:62
msgid "Want everyone to see your collection? Spread the word!"
msgstr "¿Quieres presumir de colección? ¡Difunde la palabra!"
#: amiibofindr/templates/profile/main.html:71
msgid "Have it"
msgstr "Lo tiene"
#: amiibofindr/templates/profile/main.html:72
msgid "Want it"
msgstr "Lo quiere"
#: amiibofindr/templates/profile/main.html:73
msgid "Trade it"
msgstr "Lo cambia"
#: amiibofindr/templates/profile/main.html:91
msgid "Oooops, seems this user have nothing for that."
msgstr "Ups, ¡parece que no tiene nada por aquí!"
#: amiibofindr/templates/socialaccount/connections.html:5
#: amiibofindr/templates/socialaccount/connections.html:10
msgid "Account Connections"
msgstr "Conexiones con mi cuenta"
#: amiibofindr/templates/socialaccount/connections.html:14
msgid ""
"You can sign in to your account using any of the following third party "
"accounts:"
msgstr ""
"Puedes iniciar sesión en tu cuenta usando una de las siguientes redes "
"sociales:"
#: amiibofindr/templates/socialaccount/connections.html:51
msgid ""
"You currently have no social network accounts connected to this account."
msgstr "No tienes redes sociales asociadas a tu cuenta."
#: amiibofindr/templates/socialaccount/connections.html:55
msgid "Add a 3rd Party Account"
msgstr "Asociar una red social"
#: amiibofindr/templates/socialaccount/messages/account_connected.txt:2
msgid "The social account has been connected."
msgstr "La red social ha sido vinculada."
#: amiibofindr/templates/socialaccount/messages/account_connected_other.txt:2
msgid "The social account is already connected to a different account."
msgstr "Esta red social esta vinculada a otra cuenta del sitio."
#: amiibofindr/templates/socialaccount/messages/account_disconnected.txt:2
msgid "The social account has been disconnected."
msgstr "La red social ha sido desvinculada."
#: amiibofindr/urls.py:36
msgid "^account/"
msgstr "^mi-cuenta/"
#~ msgid "Here you can browse over %(username)s's collection"
#~ msgstr "Aquí puedes ver la colección de %(username)s"
#~ msgid "^(?P<collection>[\\w\\d\\-]+)/(?P<amiibo>[\\w\\d\\-]+)$"
#~ msgstr "^(?P<collection>[\\w\\d\\-]+)/(?P<amiibo>[\\w\\d\\-]+)$"
#~ msgid "Price"
#~ msgstr "Precio"

View File

@ -1,3 +1,4 @@
# coding: utf-8
"""
Django settings for amiibofindr project.
@ -33,6 +34,7 @@ ALLOWED_HOSTS = []
INSTALLED_APPS = (
'suit',
'django.contrib.admin',
'django.contrib.sites', # For allauth
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
@ -45,11 +47,21 @@ INSTALLED_APPS = (
'easy_thumbnails',
'django_extensions',
# Auth
'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.twitter',
'allauth.socialaccount.providers.facebook',
'allauth.socialaccount.providers.google',
'allauth.socialaccount.providers.instagram',
# own apps
'amiibofindr.apps.core',
'amiibofindr.apps.amiibo',
'amiibofindr.apps.shop',
'amiibofindr.apps.home',
'amiibofindr.apps.profile',
'amiibofindr.apps.notifications',
)
@ -58,6 +70,8 @@ MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'amiibofindr.apps.core.middleware.LanguageMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
@ -86,6 +100,8 @@ TEMPLATES = [
'amiibofindr.apps.amiibo.context_processors.currencies',
'amiibofindr.apps.core.context_processors.debug',
'amiibofindr.apps.core.context_processors.files',
'amiibofindr.apps.core.context_processors.i18n',
'amiibofindr.apps.amiibo.context_processors.user_amiibo',
],
},
},
@ -108,7 +124,12 @@ DATABASES = {
# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/
LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'en'
LANGUAGES = (
('en', u'English'),
('es', u'Español'),
)
TIME_ZONE = 'Europe/Madrid'
@ -118,6 +139,9 @@ USE_L10N = True
USE_TZ = True
LOCALE_PATHS = (
os.path.join(BASE_DIR, 'locale'),
)
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/
@ -127,3 +151,19 @@ STATICFILES_DIRS = (
)
MEDIA_URL = '/media/'
# Auth
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'allauth.account.auth_backends.AuthenticationBackend',
)
# Sites and social auth
ACCOUNT_LOGOUT_ON_GET = True
ACCOUNT_USERNAME_MIN_LENGTH = 3
SITE_ID = 1
LOGIN_REDIRECT_URL = '/'
LOGIN_URL = '/account/login/'

View File

@ -21,6 +21,8 @@ DATABASES = {
MEDIA_URL = '/media/'
MEDIA_ROOT = '/vagrant/media'
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
try:
from local_settings import *
except ImportError as e:

View File

@ -1,62 +1,67 @@
(function() {
var CollectionSearchComponent = function() {
this.initialize();
};
var CollectionSearchComponent = function() {
this.initialize();
};
CollectionSearchComponent.prototype.initialize = function() {
var self = this;
CollectionSearchComponent.prototype.initialize = function() {
var self = this;
// Required DOM
this.$searchInput = document.querySelector('[data-component="collectionSearchInput"]');
this.$resetButton = document.querySelector('[data-component="collectionSearchReset"]');
this.$collectionList = document.querySelector('[data-component="collectionList"]').children;
// Required DOM
this.$searchInput = document.querySelector('[data-component="collectionSearchInput"]');
this.$resetButton = document.querySelector('[data-component="collectionSearchReset"]');
this.$collectionList = document.querySelector('[data-component="collectionList"]').children;
// Add event handlers
this.$searchInput.addEventListener('keyup', function(event) {
self.search(self.$searchInput.value);
});
// Add event handlers
this.$searchInput.addEventListener('keyup', function(event) {
self.search(self.$searchInput.value);
});
this.$resetButton.addEventListener('click', function(event) {
self.reset();
});
this.$resetButton.addEventListener('click', function(event) {
self.reset();
});
// Focus search input
this.$searchInput.focus();
};
// Focus search input
this.$searchInput.focus();
CollectionSearchComponent.prototype.showItem = function(item) {
item.style.display = 'block';
};
// Trigger search
if (this.$searchInput.value !== '') {
this.search(this.$searchInput.value);
}
};
CollectionSearchComponent.prototype.hideItem = function(item) {
item.style.display = 'none';
};
CollectionSearchComponent.prototype.showItem = function(item) {
item.style.display = 'block';
};
CollectionSearchComponent.prototype.reset = function() {
this.$searchInput.value = '';
CollectionSearchComponent.prototype.hideItem = function(item) {
item.style.display = 'none';
};
for (var index = 0; index < this.$collectionList.length; index++) {
var item = this.$collectionList[index];
this.showItem(item);
}
};
CollectionSearchComponent.prototype.reset = function() {
this.$searchInput.value = '';
CollectionSearchComponent.prototype.search = function(searchQuery) {
if (!searchQuery || searchQuery === null || searchQuery === '') {
this.reset();
return false;
}
for (var index = 0; index < this.$collectionList.length; index++) {
var item = this.$collectionList[index];
this.showItem(item);
}
};
for (var index = 0; index < this.$collectionList.length; index++) {
var item = this.$collectionList[index];
var names = item.getAttribute('data-amiibo-names');
if (names.indexOf(searchQuery.toLowerCase()) === -1) {
this.hideItem(item);
} else {
this.showItem(item);
}
}
};
CollectionSearchComponent.prototype.search = function(searchQuery) {
if (!searchQuery || searchQuery === null || searchQuery === '') {
this.reset();
return false;
}
SimpleViews.register('collection-search', CollectionSearchComponent);
for (var index = 0; index < this.$collectionList.length; index++) {
var item = this.$collectionList[index];
var names = item.getAttribute('data-amiibo-names');
if (names.indexOf(searchQuery.toLowerCase()) === -1) {
this.hideItem(item);
} else {
this.showItem(item);
}
}
};
SimpleViews.register('collection-search', CollectionSearchComponent);
})();

View File

@ -1,23 +1,34 @@
// Handle data-href
$('[data-href]').on('click', function(event) {
location.href = $(this).attr('data-href');
location.href = $(this).attr('data-href');
});
// Enable dropdowns
$('.dropdown').dropdown({transition: 'drop', on: 'hover'});
$('.toggle-menu').on('click', function() {
$('.responsive-menu').toggle(200);
$('.responsive-menu').toggle(200);
})
$(function(){
$('[data-component="silbingPopup"]').popup({
inline: true,
position: 'left center'
});
$('[data-component="silbingPopup"]').popup({
inline: true,
position: 'left center'
});
$('.right.menu.open').on("click",function(e){
e.preventDefault();
$('.ui.vertical.menu').toggle();
});
// Tabs
$('.tabular.menu .item').tab();
$(document).on('click', '[data-toggle]', function(event) {
var $el = event.target;
var $target = $($el.getAttribute('data-toggle'));
$target.slideToggle(200);
});
$('.right.menu.open').on("click",function(e){
e.preventDefault();
$('.ui.vertical.menu').toggle();
});
moment.locale(document.querySelector('html').getAttribute('lang'));
});

View File

@ -1,7 +1,7 @@
(function() {
var MoneyComponent = function() {
this.DEBUG = DEBUG;
this.currency = 'EUR';
this.currency = 'reset';
this.currencies = CURRENCIES;
this.ratesSet = false;
this.initialize();
@ -59,16 +59,30 @@
MoneyComponent.prototype.setCurrency = function(currency) {
var self = this;
if (this.currencies.indexOf(currency) !== -1) {
if (this.currencies.indexOf(currency) !== -1 || currency === 'reset') {
if (this.DEBUG) console.log('[money] set user currency: ' + currency)
$('[data-currency-change]').removeClass('underlined');
$('[data-currency-change="' + currency + '"]').addClass('underlined');
window.localStorage.setItem('currency', currency);
$('[data-currency-change]').removeClass('active');
$('[data-currency-change="' + currency + '"]').addClass('active');
this.currency = currency;
this.convertPrices();
if (currency === 'reset') {
window.localStorage.removeItem('currency');
this.resetConversion();
} else {
window.localStorage.setItem('currency', currency);
this.convertPrices();
}
}
};
MoneyComponent.prototype.resetConversion = function() {
var self = this;
[].forEach.call(document.querySelectorAll('[data-money]'), function(item) {
var price = item.getAttribute('data-price');
var currency = item.getAttribute('data-currency');
item.innerHTML = price + ' ' + currency;
});
}
MoneyComponent.prototype.convertPrices = function() {
var self = this;
if (!this.ratesSet) {

View File

@ -0,0 +1,63 @@
(function() {
var RelationComponent = function() {
this.relationsQuerySelector = '[data-handle="relation"]';
this.initialize();
};
RelationComponent.prototype.initialize = function() {
var self = this;
// Prepare handlers
var linkHandler = function(event) {
event.preventDefault();
event.stopPropagation();
var target = event.target;
// Handles clicking in the icon
if (event.target.href === undefined)
target = event.target.parentNode
self.click(target);
};
$(document).on('click', this.relationsQuerySelector + ' a', linkHandler);
};
RelationComponent.prototype.click = function(element) {
var $link = element;
var href = $link.href;
var $buttons = $(element).closest('[data-amiibo]');
var from = $buttons.attr('data-from');
var amiiboId = $buttons.attr('data-amiibo');
var loader = $buttons.closest('[data-loader="' + amiiboId + '"]');
this.doGet(href, from, loader, $buttons);
};
RelationComponent.prototype.doGet = function(href, from, loader, container) {
var self = this;
// loader.addClass('loading');
// If list, the entire card is the container
if (from === "list") container = loader;
$.ajax({
url: href,
data: { from: from },
success: function(result) {
self.handleResult(loader, from, container, result);
}
});
};
RelationComponent.prototype.handleResult = function(loader, from, container, result) {
if (from === 'list') {
container.replaceWith(result);
} else {
container.html(result)
}
// loader.removeClass('loading');
};
SimpleViews.register('relation', RelationComponent);
})();

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -1,5 +1,5 @@
// Semantic-UI
@import "../semantic/semantic.css";
@import "../semantic/semantic.min.css";
.price-converted {
@ -30,4 +30,28 @@
.navbar {
margin-top: 10px !important;
}
.nowrap {
white-space: nowrap;
}
.no-margin-bottom {
margin-bottom: 0 !important;
}
.relation-buttons {
position: absolute;
left: 6px;
right: 6px;
bottom: 6px;
width: 100%;
text-align: center;
z-index: 30;
}
.menu.fixzindex { z-index: 61 !important; }
.ui.tabular.menu .item {
cursor: pointer;
}

View File

@ -1,9 +1,9 @@
/*!
* # Semantic UI 1.12.3 - Accordion
* # Semantic UI 2.1.3 - Accordion
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2014 Contributors
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
@ -17,7 +17,6 @@
.ui.accordion,
.ui.accordion .accordion {
max-width: 100%;
font-size: 1em;
}
.ui.accordion .accordion {
margin: 1em 0em 0em;
@ -35,7 +34,7 @@
padding: 0.5em 0em;
font-family: 'Lato', 'Helvetica Neue', Arial, Helvetica, sans-serif;
font-size: 1em;
color: rgba(0, 0, 0, 0.8);
color: rgba(0, 0, 0, 0.87);
}
/* Content */
@ -47,7 +46,7 @@
/* Default Styling */
.ui.accordion:not(.styled) .title ~ .content:not(.ui),
.ui.accordion:not(.styled) .accordion .title ~ .content:not(.ui) {
margin: 0em;
margin: '';
padding: 0.5em 0em 1em;
}
.ui.accordion:not(.styled) .title ~ .content:not(.ui):last-child {
@ -65,8 +64,8 @@
margin: 0em 0.25rem 0em 0rem;
padding: 0em;
font-size: 1em;
-webkit-transition: -webkit-transform 0.2s ease, opacity 0.2s ease;
transition: transform 0.2s ease, opacity 0.2s ease;
-webkit-transition: -webkit-transform 0.1s ease, opacity 0.1s ease;
transition: transform 0.1s ease, opacity 0.1s ease;
vertical-align: baseline;
-webkit-transform: none;
-ms-transform: none;
@ -85,7 +84,7 @@
}
.ui.accordion.menu .item .title > .dropdown.icon {
float: right;
margin: 0.165em 0em 0em 1em;
margin: 0.21425em 0em 0em 1em;
-webkit-transform: rotate(180deg);
-ms-transform: rotate(180deg);
transform: rotate(180deg);
@ -129,9 +128,9 @@
}
.ui.styled.accordion,
.ui.styled.accordion .accordion {
border-radius: 0.2857rem;
border-radius: 0.28571429rem;
background: #ffffff;
box-shadow: 0px 1px 2px 0 rgba(0, 0, 0, 0.05), 0px 0px 0px 1px rgba(39, 41, 43, 0.15);
box-shadow: 0px 1px 2px 0 rgba(34, 36, 38, 0.15), 0px 0px 0px 1px rgba(34, 36, 38, 0.15);
}
.ui.styled.accordion .title,
.ui.styled.accordion .accordion .title {
@ -139,9 +138,9 @@
padding: 0.75em 1em;
color: rgba(0, 0, 0, 0.4);
font-weight: bold;
border-top: 1px solid rgba(39, 41, 43, 0.15);
-webkit-transition: background 0.2s ease, color 0.2s ease;
transition: background 0.2s ease, color 0.2s ease;
border-top: 1px solid rgba(34, 36, 38, 0.15);
-webkit-transition: background 0.1s ease, color 0.1s ease;
transition: background 0.1s ease, color 0.1s ease;
}
.ui.styled.accordion > .title:first-child,
.ui.styled.accordion .accordion .title:first-child {
@ -165,22 +164,22 @@
.ui.styled.accordion .accordion .title:hover,
.ui.styled.accordion .accordion .active.title {
background: transparent;
color: rgba(0, 0, 0, 0.8);
color: rgba(0, 0, 0, 0.87);
}
.ui.styled.accordion .accordion .title:hover,
.ui.styled.accordion .accordion .active.title {
background: transparent;
color: rgba(0, 0, 0, 0.8);
color: rgba(0, 0, 0, 0.87);
}
/* Active */
.ui.styled.accordion .active.title {
background: transparent;
color: rgba(0, 0, 0, 0.8);
color: rgba(0, 0, 0, 0.95);
}
.ui.styled.accordion .accordion .active.title {
background: transparent;
color: rgba(0, 0, 0, 0.8);
color: rgba(0, 0, 0, 0.95);
}
@ -218,7 +217,7 @@
---------------*/
.ui.inverted.accordion .title:not(.ui) {
color: #ffffff;
color: rgba(255, 255, 255, 0.9);
}

View File

@ -1,9 +1,9 @@
/*!
* # Semantic UI 1.12.3 - Accordion
* # Semantic UI 2.1.3 - Accordion
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2014 Contributors
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
@ -63,7 +63,9 @@ $.fn.accordion = function(parameters) {
initialize: function() {
module.debug('Initializing', $module);
module.bind.events();
module.observeChanges();
if(settings.observeChanges) {
module.observeChanges();
}
module.instantiate();
},
@ -105,7 +107,7 @@ $.fn.accordion = function(parameters) {
events: function() {
module.debug('Binding delegated events');
$module
.on('click' + eventNamespace, selector.trigger, module.event.click)
.on(settings.on + eventNamespace, selector.trigger, module.event.click)
;
}
},
@ -153,54 +155,59 @@ $.fn.accordion = function(parameters) {
$activeContent = $activeTitle.next($content),
isAnimating = $activeContent.hasClass(className.animating),
isActive = $activeContent.hasClass(className.active),
isUnopen = (!isActive && !isAnimating)
isOpen = (isActive || isAnimating)
;
if(isUnopen) {
module.debug('Opening accordion content', $activeTitle);
if(settings.exclusive) {
module.closeOthers.call($activeTitle);
}
$activeTitle
.addClass(className.active)
;
$activeContent.addClass(className.animating);
if(settings.animateChildren) {
if($.fn.transition !== undefined && $module.transition('is supported')) {
$activeContent
.children()
.transition({
animation : 'fade in',
queue : false,
useFailSafe : true,
debug : settings.debug,
verbose : settings.verbose,
duration : settings.duration
})
;
}
else {
$activeContent
.children()
.stop(true)
.animate({
opacity: 1
}, settings.duration, module.resetOpacity)
;
}
}
$activeContent
.stop(true)
.slideDown(settings.duration, settings.easing, function() {
$activeContent
.removeClass(className.animating)
.addClass(className.active)
;
module.reset.display.call(this);
settings.onOpen.call(this);
settings.onChange.call(this);
})
;
if(isOpen) {
module.debug('Accordion already open, skipping', $activeContent);
return;
}
module.debug('Opening accordion content', $activeTitle);
settings.onOpening.call($activeContent);
if(settings.exclusive) {
module.closeOthers.call($activeTitle);
}
$activeTitle
.addClass(className.active)
;
$activeContent
.stop(true, true)
.addClass(className.animating)
;
if(settings.animateChildren) {
if($.fn.transition !== undefined && $module.transition('is supported')) {
$activeContent
.children()
.transition({
animation : 'fade in',
queue : false,
useFailSafe : true,
debug : settings.debug,
verbose : settings.verbose,
duration : settings.duration
})
;
}
else {
$activeContent
.children()
.stop(true, true)
.animate({
opacity: 1
}, settings.duration, module.resetOpacity)
;
}
}
$activeContent
.slideDown(settings.duration, settings.easing, function() {
$activeContent
.removeClass(className.animating)
.addClass(className.active)
;
module.reset.display.call(this);
settings.onOpen.call(this);
settings.onChange.call(this);
})
;
},
close: function(query) {
@ -218,10 +225,12 @@ $.fn.accordion = function(parameters) {
;
if((isActive || isOpening) && !isClosing) {
module.debug('Closing accordion content', $activeContent);
settings.onClosing.call($activeContent);
$activeTitle
.removeClass(className.active)
;
$activeContent
.stop(true, true)
.addClass(className.animating)
;
if(settings.animateChildren) {
@ -241,7 +250,7 @@ $.fn.accordion = function(parameters) {
else {
$activeContent
.children()
.stop(true)
.stop(true, true)
.animate({
opacity: 0
}, settings.duration, module.resetOpacity)
@ -249,7 +258,6 @@ $.fn.accordion = function(parameters) {
}
}
$activeContent
.stop(true)
.slideUp(settings.duration, settings.easing, function() {
$activeContent
.removeClass(className.animating)
@ -291,6 +299,10 @@ $.fn.accordion = function(parameters) {
$openTitles
.removeClass(className.active)
;
$openContents
.removeClass(className.animating)
.stop(true, true)
;
if(settings.animateChildren) {
if($.fn.transition !== undefined && $module.transition('is supported')) {
$openContents
@ -307,7 +319,7 @@ $.fn.accordion = function(parameters) {
else {
$openContents
.children()
.stop()
.stop(true, true)
.animate({
opacity: 0
}, settings.duration, module.resetOpacity)
@ -315,7 +327,6 @@ $.fn.accordion = function(parameters) {
}
}
$openContents
.stop()
.slideUp(settings.duration , settings.easing, function() {
$(this).removeClass(className.active);
module.reset.display.call(this);
@ -422,7 +433,7 @@ $.fn.accordion = function(parameters) {
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 100);
module.performance.timer = setTimeout(module.performance.display, 500);
},
display: function() {
var
@ -534,20 +545,27 @@ $.fn.accordion.settings = {
namespace : 'accordion',
debug : false,
verbose : true,
verbose : false,
performance : true,
exclusive : true,
collapsible : true,
closeNested : false,
animateChildren : true,
on : 'click', // event on title that opens accordion
duration : 350,
easing : 'easeOutQuad',
observeChanges : true, // whether accordion should automatically refresh on DOM insertion
onOpen : function(){},
onClose : function(){},
onChange : function(){},
exclusive : true, // whether a single accordion content panel should be open at once
collapsible : true, // whether accordion content can be closed
closeNested : false, // whether nested content should be closed when a panel is closed
animateChildren : true, // whether children opacity should be animated
duration : 350, // duration of animation
easing : 'easeOutQuad', // easing equation for animation
onOpening : function(){}, // callback before open animation
onOpen : function(){}, // callback after open animation
onClosing : function(){}, // callback before closing animation
onClose : function(){}, // callback after closing animation
onChange : function(){}, // callback after closing or opening animation
error: {
method : 'The method you called is not defined'

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*!
* # Semantic UI 1.12.3 - Ad
* # Semantic UI 2.1.3 - Ad
* http://github.com/semantic-org/semantic-ui/
*
*
@ -240,7 +240,7 @@
}
.ui.test.ad {
position: relative;
background: #333333;
background: #545454;
}
.ui.test.ad:after {
position: absolute;
@ -257,7 +257,7 @@
font-weight: bold;
}
.ui.mobile.test.ad:after {
font-size: 0.85714em;
font-size: 0.85714286em;
}
.ui.test.ad[data-text]:after {
content: attr(data-text);

View File

@ -1,5 +1,5 @@
/*!
* # Semantic UI 1.12.3 - Ad
* # Semantic UI 2.1.3 - Ad
* http://github.com/semantic-org/semantic-ui/
*
*
@ -7,4 +7,4 @@
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/.ui.ad{display:block;overflow:hidden;margin:1em 0}.ui.ad:first-child,.ui.ad:last-child{margin:0}.ui.ad iframe{margin:0;padding:0;border:none;overflow:hidden}.ui.leaderboard.ad{width:728px;height:90px}.ui[class*="medium rectangle"].ad{width:300px;height:250px}.ui[class*="large rectangle"].ad{width:336px;height:280px}.ui[class*="half page"].ad{width:300px;height:600px}.ui.square.ad{width:250px;height:250px}.ui[class*="small square"].ad{width:200px;height:200px}.ui[class*="small rectangle"].ad{width:180px;height:150px}.ui[class*="vertical rectangle"].ad{width:240px;height:400px}.ui.button.ad{width:120px;height:90px}.ui[class*="square button"].ad{width:125px;height:125px}.ui[class*="small button"].ad{width:120px;height:60px}.ui.skyscraper.ad{width:120px;height:600px}.ui[class*="wide skyscraper"].ad{width:160px}.ui.banner.ad{width:468px;height:60px}.ui[class*="vertical banner"].ad{width:120px;height:240px}.ui[class*="top banner"].ad{width:930px;height:180px}.ui[class*="half banner"].ad{width:234px;height:60px}.ui[class*="large leaderboard"].ad{width:970px;height:90px}.ui.billboard.ad{width:970px;height:250px}.ui.panorama.ad{width:980px;height:120px}.ui.netboard.ad{width:580px;height:400px}.ui[class*="large mobile banner"].ad{width:320px;height:100px}.ui[class*="mobile leaderboard"].ad{width:320px;height:50px}.ui.mobile.ad{display:none}@media only screen and (max-width:767px){.ui.mobile.ad{display:block}}.ui.centered.ad{margin-left:auto;margin-right:auto}.ui.test.ad{position:relative;background:#333}.ui.test.ad:after{position:absolute;top:50%;left:50%;width:100%;text-align:center;-webkit-transform:translateX(-50%) translateY(-50%);-ms-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);content:'Ad';color:#fff;font-size:1em;font-weight:700}.ui.mobile.test.ad:after{font-size:.85714em}.ui.test.ad[data-text]:after{content:attr(data-text)}
*/.ui.ad{display:block;overflow:hidden;margin:1em 0}.ui.ad:first-child,.ui.ad:last-child{margin:0}.ui.ad iframe{margin:0;padding:0;border:none;overflow:hidden}.ui.leaderboard.ad{width:728px;height:90px}.ui[class*="medium rectangle"].ad{width:300px;height:250px}.ui[class*="large rectangle"].ad{width:21pc;height:280px}.ui[class*="half page"].ad{width:300px;height:600px}.ui.square.ad{width:250px;height:250px}.ui[class*="small square"].ad{width:200px;height:200px}.ui[class*="small rectangle"].ad{width:180px;height:150px}.ui[class*="vertical rectangle"].ad{width:15pc;height:25pc}.ui.button.ad{width:90pt;height:90px}.ui[class*="square button"].ad{width:125px;height:125px}.ui[class*="small button"].ad{width:90pt;height:60px}.ui.skyscraper.ad{width:90pt;height:600px}.ui[class*="wide skyscraper"].ad{width:10pc}.ui.banner.ad{width:468px;height:60px}.ui[class*="vertical banner"].ad{width:90pt;height:15pc}.ui[class*="top banner"].ad{width:930px;height:180px}.ui[class*="half banner"].ad{width:234px;height:60px}.ui[class*="large leaderboard"].ad{width:970px;height:90px}.ui.billboard.ad{width:970px;height:250px}.ui.panorama.ad{width:980px;height:90pt}.ui.netboard.ad{width:580px;height:25pc}.ui[class*="large mobile banner"].ad{width:20pc;height:75pt}.ui[class*="mobile leaderboard"].ad{width:20pc;height:50px}.ui.mobile.ad{display:none}@media only screen and (max-width:767px){.ui.mobile.ad{display:block}}.ui.centered.ad{margin-left:auto;margin-right:auto}.ui.test.ad{position:relative;background:#545454}.ui.test.ad:after{position:absolute;top:50%;left:50%;width:100%;text-align:center;-webkit-transform:translateX(-50%) translateY(-50%);-ms-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);content:'Ad';color:#fff;font-size:1em;font-weight:700}.ui.mobile.test.ad:after{font-size:.85714286em}.ui.test.ad[data-text]:after{content:attr(data-text)}

View File

@ -1,9 +1,9 @@
/*!
* # Semantic UI 1.12.3 - API
* # Semantic UI 2.1.3 - API
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2014 Contributors
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
@ -63,10 +63,11 @@ $.api = $.fn.api = function(parameters) {
requestSettings,
url,
data,
requestStartTime,
// standard module
element = this,
context = $context.get(),
context = $context[0],
instance = $module.data(moduleNamespace),
module
;
@ -74,21 +75,8 @@ $.api = $.fn.api = function(parameters) {
module = {
initialize: function() {
var
triggerEvent = module.get.event()
;
// bind events
if(!methodInvoked) {
if( triggerEvent ) {
module.debug('Attaching API events to element', triggerEvent);
$module
.on(triggerEvent + eventNamespace, module.event.trigger)
;
}
else if(settings.on == 'now') {
module.debug('Querying API now', triggerEvent);
module.query();
}
module.bind.events();
}
module.instantiate();
},
@ -109,16 +97,87 @@ $.api = $.fn.api = function(parameters) {
;
},
bind: {
events: function() {
var
triggerEvent = module.get.event()
;
if( triggerEvent ) {
module.verbose('Attaching API events to element', triggerEvent);
$module
.on(triggerEvent + eventNamespace, module.event.trigger)
;
}
else if(settings.on == 'now') {
module.debug('Querying API endpoint immediately');
module.query();
}
}
},
decode: {
json: function(response) {
if(response !== undefined && typeof response == 'string') {
try {
response = JSON.parse(response);
}
catch(e) {
// isnt json string
}
}
return response;
}
},
read: {
cachedResponse: function(url) {
var
response
;
if(window.Storage === undefined) {
module.error(error.noStorage);
return;
}
response = sessionStorage.getItem(url);
module.debug('Using cached response', url, response);
response = module.decode.json(response);
return false;
}
},
write: {
cachedResponse: function(url, response) {
if(response && response === '') {
module.debug('Response empty, not caching', response);
return;
}
if(window.Storage === undefined) {
module.error(error.noStorage);
return;
}
if( $.isPlainObject(response) ) {
response = JSON.stringify(response);
}
sessionStorage.setItem(url, response);
module.verbose('Storing cached response for url', url, response);
}
},
query: function() {
if(module.is.disabled()) {
module.debug('Element is disabled API request aborted');
return;
}
// determine if an api event already occurred
if(module.is.loading() && settings.throttle === 0 ) {
module.debug('Cancelling request, previous request is still pending');
return;
if(module.is.loading()) {
if(settings.interruptRequests) {
module.debug('Interrupting previous request');
module.abort();
}
else {
module.debug('Cancelling request, previous request is still pending');
return;
}
}
// pass element metadata to url (value, text)
@ -127,17 +186,12 @@ $.api = $.fn.api = function(parameters) {
}
// Add form content
if(settings.serializeForm !== false || $context.is('form')) {
if(settings.serializeForm == 'json') {
$.extend(true, settings.data, module.get.formData());
}
else {
settings.data = module.get.formData();
}
if(settings.serializeForm) {
settings.data = module.add.formData(settings.data);
}
// call beforesend and get any settings changes
requestSettings = module.get.settings();
requestSettings = module.get.settings();
// check if before send cancelled request
if(requestSettings === false) {
@ -149,31 +203,22 @@ $.api = $.fn.api = function(parameters) {
module.cancelled = false;
}
if(settings.url) {
// override with url if specified
module.debug('Using specified url', url);
url = module.add.urlData( settings.url );
}
else {
// otherwise find url from api endpoints
url = module.add.urlData( module.get.templateURL() );
module.debug('Added URL Data to url', url);
// get url
url = module.get.templatedURL();
if(!url && !module.is.mocked()) {
module.error(error.missingURL);
return;
}
// exit conditions reached, missing url parameters
if( !url ) {
if( module.is.form() ) {
url = $module.attr('action') || '';
module.debug('No url or action specified, defaulting to form action', url);
}
else {
module.error(error.missingURL, settings.action);
return;
}
// replace variables
url = module.add.urlData( url );
// missing url parameters
if( !url && !module.is.mocked()) {
return;
}
// add loading state
module.set.loading();
// look for jQuery ajax parameters in settings
ajaxSettings = $.extend(true, {}, settings, {
@ -187,39 +232,86 @@ $.api = $.fn.api = function(parameters) {
});
module.debug('Querying URL', ajaxSettings.url);
module.debug('Sending data', data, ajaxSettings.method);
module.verbose('Using AJAX settings', ajaxSettings);
if( module.is.loading() ) {
// throttle additional requests
module.timer = setTimeout(function() {
module.request = module.create.request();
module.xhr = module.create.xhr();
settings.onRequest.call(context, module.request, module.xhr);
}, settings.throttle);
if(settings.cache === 'local' && module.read.cachedResponse(url)) {
module.debug('Response returned from local cache');
module.request = module.create.request();
module.request.resolveWith(context, [ module.read.cachedResponse(url) ]);
return;
}
if( !settings.throttle ) {
module.debug('Sending request', data, ajaxSettings.method);
module.send.request();
}
else {
// immediately on first request
module.request = module.create.request();
module.xhr = module.create.xhr();
settings.onRequest.call(context, module.request, module.xhr);
if(!settings.throttleFirstRequest && !module.timer) {
module.debug('Sending request', data, ajaxSettings.method);
module.send.request();
module.timer = setTimeout(function(){}, settings.throttle);
}
else {
module.debug('Throttling request', settings.throttle);
clearTimeout(module.timer);
module.timer = setTimeout(function() {
if(module.timer) {
delete module.timer;
}
module.debug('Sending throttled request', data, ajaxSettings.method);
module.send.request();
}, settings.throttle);
}
}
},
should: {
removeError: function() {
return ( settings.hideError === true || (settings.hideError === 'auto' && !module.is.form()) );
}
},
is: {
disabled: function() {
return ($module.filter(settings.filter).length > 0);
return ($module.filter(selector.disabled).length > 0);
},
form: function() {
return $module.is('form');
return $module.is('form') || $context.is('form');
},
mocked: function() {
return (settings.mockResponse || settings.mockResponseAsync);
},
input: function() {
return $module.is('input');
},
loading: function() {
return (module.request && module.request.state() == 'pending');
},
abortedRequest: function(xhr) {
if(xhr && xhr.readyState !== undefined && xhr.readyState === 0) {
module.verbose('XHR request determined to be aborted');
return true;
}
else {
module.verbose('XHR request was not aborted');
return false;
}
},
validResponse: function(response) {
if( (settings.dataType !== 'json' && settings.dataType !== 'jsonp') || !$.isFunction(settings.successTest) ) {
module.verbose('Response is not JSON, skipping validation', settings.successTest, response);
return true;
}
module.debug('Checking JSON returned success', settings.successTest, response);
if( settings.successTest(response) ) {
module.debug('Response passed success test', response);
return true;
}
else {
module.debug('Response failed success test', response);
return false;
}
}
},
@ -272,6 +364,10 @@ $.api = $.fn.api = function(parameters) {
}
else {
module.verbose('Found required variable', variable, value);
value = (settings.encodeParameters)
? module.get.urlEncodedValue(value)
: value
;
url = url.replace(templatedString, value);
}
});
@ -311,6 +407,48 @@ $.api = $.fn.api = function(parameters) {
}
}
return url;
},
formData: function(data) {
var
canSerialize = ($.fn.serializeObject !== undefined),
formData = (canSerialize)
? $form.serializeObject()
: $form.serialize(),
hasOtherData
;
data = data || settings.data;
hasOtherData = $.isPlainObject(data);
if(hasOtherData) {
if(canSerialize) {
module.debug('Extending existing data with form data', data, formData);
data = $.extend(true, {}, data, formData);
}
else {
module.error(error.missingSerialize);
module.debug('Cant extend data. Replacing data with form data', data, formData);
data = formData;
}
}
else {
module.debug('Adding form data', formData);
data = formData;
}
return data;
}
},
send: {
request: function() {
module.set.loading();
module.request = module.create.request();
if( module.is.mocked() ) {
module.mockedXHR = module.create.mockedXHR();
}
else {
module.xhr = module.create.xhr();
}
settings.onRequest.call(context, module.request, module.xhr);
}
},
@ -323,130 +461,192 @@ $.api = $.fn.api = function(parameters) {
},
xhr: {
always: function() {
// calculate if loading time was below minimum threshold
// nothing special
},
done: function(response) {
done: function(response, textStatus, xhr) {
var
context = this,
elapsedTime = (new Date().getTime() - time),
timeLeft = (settings.loadingDuration - elapsedTime)
context = this,
elapsedTime = (new Date().getTime() - requestStartTime),
timeLeft = (settings.loadingDuration - elapsedTime),
translatedResponse = ( $.isFunction(settings.onResponse) )
? settings.onResponse.call(context, $.extend(true, {}, response))
: false
;
timeLeft = (timeLeft > 0)
? timeLeft
: 0
;
if(translatedResponse) {
module.debug('Modified API response in onResponse callback', settings.onResponse, translatedResponse, response);
response = translatedResponse;
}
if(timeLeft > 0) {
module.debug('Response completed early delaying state change by', timeLeft);
}
setTimeout(function() {
module.request.resolveWith(context, [response]);
if( module.is.validResponse(response) ) {
module.request.resolveWith(context, [response, xhr]);
}
else {
module.request.rejectWith(context, [xhr, 'invalid']);
}
}, timeLeft);
},
fail: function(xhr, status, httpMessage) {
var
context = this,
elapsedTime = (new Date().getTime() - time),
elapsedTime = (new Date().getTime() - requestStartTime),
timeLeft = (settings.loadingDuration - elapsedTime)
;
timeLeft = (timeLeft > 0)
? timeLeft
: 0
;
// page triggers abort on navigation, dont show error
if(timeLeft > 0) {
module.debug('Response completed early delaying state change by', timeLeft);
}
setTimeout(function() {
if(status !== 'abort') {
module.request.rejectWith(context, [xhr, status, httpMessage]);
if( module.is.abortedRequest(xhr) ) {
module.request.rejectWith(context, [xhr, 'aborted', httpMessage]);
}
else {
module.reset();
module.request.rejectWith(context, [xhr, 'error', status, httpMessage]);
}
}, timeLeft);
}
},
request: {
complete: function(response) {
module.remove.loading();
settings.onComplete.call(context, response, $module);
},
done: function(response) {
module.debug('API Response Received', response);
if(settings.dataType == 'json') {
if( $.isFunction(settings.successTest) ) {
module.debug('Checking JSON returned success', settings.successTest, response);
if( settings.successTest(response) ) {
settings.onSuccess.call(context, response, $module);
}
else {
module.debug('JSON test specified by user and response failed', response);
settings.onFailure.call(context, response, $module);
}
}
else {
settings.onSuccess.call(context, response, $module);
}
}
else {
settings.onSuccess.call(context, response, $module);
done: function(response, xhr) {
module.debug('Successful API Response', response);
if(settings.cache === 'local' && url) {
module.write.cachedResponse(url, response);
module.debug('Saving server response locally', module.cache);
}
settings.onSuccess.call(context, response, $module, xhr);
},
error: function(xhr, status, httpMessage) {
complete: function(firstParameter, secondParameter) {
var
errorMessage = (settings.error[status] !== undefined)
? settings.error[status]
: httpMessage,
xhr,
response
;
// let em know unless request aborted
if(xhr !== undefined) {
// readyState 4 = done, anything less is not really sent
if(xhr.readyState !== undefined && xhr.readyState == 4) {
// if http status code returned and json returned error, look for it
// have to guess callback parameters based on request success
if( module.was.succesful() ) {
response = firstParameter;
xhr = secondParameter;
}
else {
xhr = firstParameter;
response = module.get.responseFromXHR(xhr);
}
module.remove.loading();
settings.onComplete.call(context, response, $module, xhr);
},
fail: function(xhr, status, httpMessage) {
var
// pull response from xhr if available
response = module.get.responseFromXHR(xhr),
errorMessage = module.get.errorFromRequest(response, status, httpMessage)
;
if(status == 'aborted') {
module.debug('XHR Aborted (Most likely caused by page navigation or CORS Policy)', status, httpMessage);
settings.onAbort.call(context, status, $module, xhr);
}
else if(status == 'invalid') {
module.debug('JSON did not pass success test. A server-side error has most likely occurred', response);
}
else if(status == 'error') {
if(xhr !== undefined) {
module.debug('XHR produced a server error', status, httpMessage);
// make sure we have an error to display to console
if( xhr.status != 200 && httpMessage !== undefined && httpMessage !== '') {
module.error(error.statusMessage + httpMessage, ajaxSettings.url);
}
else {
if(status == 'error' && settings.dataType == 'json') {
try {
response = $.parseJSON(xhr.responseText);
if(response && response.error !== undefined) {
errorMessage = response.error;
}
}
catch(e) {
module.error(error.JSONParse);
}
}
}
module.remove.loading();
module.set.error();
// show error state only for duration specified in settings
if(settings.errorDuration) {
setTimeout(module.remove.error, settings.errorDuration);
}
module.debug('API Request error:', errorMessage);
settings.onError.call(context, errorMessage, $module);
}
else {
settings.onAbort.call(context, errorMessage, $module);
module.debug('Request Aborted (Most likely caused by page change or CORS Policy)', status, httpMessage);
settings.onError.call(context, errorMessage, $module, xhr);
}
}
if(settings.errorDuration && status !== 'aborted') {
module.debug('Adding error state');
module.set.error();
if( module.should.removeError() ) {
setTimeout(module.remove.error, settings.errorDuration);
}
}
module.debug('API Request failed', errorMessage, xhr);
settings.onFailure.call(context, response, $module, xhr);
}
}
},
create: {
request: function() {
// api request promise
return $.Deferred()
.always(module.event.request.complete)
.done(module.event.request.done)
.fail(module.event.request.error)
.fail(module.event.request.fail)
;
},
mockedXHR: function () {
var
// xhr does not simulate these properties of xhr but must return them
textStatus = false,
status = false,
httpMessage = false,
asyncCallback,
response,
mockedXHR
;
mockedXHR = $.Deferred()
.always(module.event.xhr.complete)
.done(module.event.xhr.done)
.fail(module.event.xhr.fail)
;
if(settings.mockResponse) {
if( $.isFunction(settings.mockResponse) ) {
module.debug('Using mocked callback returning response', settings.mockResponse);
response = settings.mockResponse.call(context, settings);
}
else {
module.debug('Using specified response', settings.mockResponse);
response = settings.mockResponse;
}
// simulating response
mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]);
}
else if( $.isFunction(settings.mockResponseAsync) ) {
asyncCallback = function(response) {
module.debug('Async callback returned response', response);
if(response) {
mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]);
}
else {
mockedXHR.rejectWith(context, [{ responseText: response }, status, httpMessage]);
}
};
module.debug('Using async mocked response', settings.mockResponseAsync);
settings.mockResponseAsync.call(context, settings, asyncCallback);
}
return mockedXHR;
},
xhr: function() {
return $.ajax(ajaxSettings)
var
xhr
;
// ajax request promise
xhr = $.ajax(ajaxSettings)
.always(module.event.xhr.always)
.done(module.event.xhr.done)
.fail(module.event.xhr.fail)
;
module.verbose('Created server request', xhr);
return xhr;
}
},
@ -458,6 +658,7 @@ $.api = $.fn.api = function(parameters) {
loading: function() {
module.verbose('Adding loading state to element', $context);
$context.addClass(className.loading);
requestStartTime = new Date().getTime();
}
},
@ -473,6 +674,22 @@ $.api = $.fn.api = function(parameters) {
},
get: {
responseFromXHR: function(xhr) {
return $.isPlainObject(xhr)
? (settings.dataType == 'json' || settings.dataType == 'jsonp')
? module.decode.json(xhr.responseText)
: xhr.responseText
: false
;
},
errorFromRequest: function(response, status, httpMessage) {
return ($.isPlainObject(response) && response.error !== undefined)
? response.error // use json error message
: (settings.error[status] !== undefined) // use server error message
? settings.error[status]
: httpMessage
;
},
request: function() {
return module.request || false;
},
@ -483,7 +700,7 @@ $.api = $.fn.api = function(parameters) {
var
runSettings
;
runSettings = settings.beforeSend.call($module, settings);
runSettings = settings.beforeSend.call(context, settings);
if(runSettings) {
if(runSettings.success !== undefined) {
module.debug('Legacy success callback detected', runSettings);
@ -509,6 +726,19 @@ $.api = $.fn.api = function(parameters) {
: settings
;
},
urlEncodedValue: function(value) {
var
decodedValue = window.decodeURIComponent(value),
encodedValue = window.encodeURIComponent(value),
alreadyEncoded = (decodedValue !== value)
;
if(alreadyEncoded) {
module.debug('URL value is already encoded, avoiding double encoding', value);
return value;
}
module.verbose('Encoding value using encodeURIComponent', value, encodedValue);
return encodedValue;
},
defaultData: function() {
var
data = {}
@ -551,34 +781,24 @@ $.api = $.fn.api = function(parameters) {
return settings.on;
}
},
formData: function() {
var
formData
;
if($module.serializeObject !== undefined) {
formData = $form.serializeObject();
}
else {
module.error(error.missingSerialize);
formData = $form.serialize();
}
module.debug('Retrieved form data', formData);
return formData;
},
templateURL: function(action) {
var
url
;
templatedURL: function(action) {
action = action || $module.data(metadata.action) || settings.action || false;
url = $module.data(metadata.url) || settings.url || false;
if(url) {
module.debug('Using specified url', url);
return url;
}
if(action) {
module.debug('Looking up url for action', action, settings.api);
if(settings.api[action] !== undefined) {
url = settings.api[action];
module.debug('Found template url', url);
}
else if( !module.is.form() ) {
if(settings.api[action] === undefined && !module.is.mocked()) {
module.error(error.missingAction, settings.action, settings.api);
return;
}
url = settings.api[action];
}
else if( module.is.form() ) {
url = $module.attr('action') || $context.attr('action') || false;
module.debug('No url or action specified, defaulting to form action', url);
}
return url;
}
@ -591,7 +811,6 @@ $.api = $.fn.api = function(parameters) {
if( xhr && xhr.state() !== 'resolved') {
module.debug('Cancelling API request');
xhr.abort();
module.request.rejectWith(settings.apiSettings);
}
},
@ -670,7 +889,7 @@ $.api = $.fn.api = function(parameters) {
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 100);
module.performance.timer = setTimeout(module.performance.display, 500);
},
display: function() {
var
@ -780,49 +999,94 @@ $.api = $.fn.api = function(parameters) {
$.api.settings = {
name : 'API',
namespace : 'api',
name : 'API',
namespace : 'api',
debug : true,
verbose : false,
performance : true,
debug : false,
verbose : false,
performance : true,
// object containing all templates endpoints
api : {},
// whether to cache responses
cache : true,
// whether new requests should abort previous requests
interruptRequests : true,
// event binding
on : 'auto',
filter : '.disabled',
stateContext : false,
on : 'auto',
// state
loadingDuration : 0,
errorDuration : 2000,
// context for applying state classes
stateContext : false,
// templating
action : false,
url : false,
base : '',
// duration for loading state
loadingDuration : 0,
// data
urlData : {},
// whether to hide errors after a period of time
hideError : 'auto',
// ui
defaultData : true,
serializeForm : false,
throttle : 0,
// duration for error state
errorDuration : 2000,
// jQ ajax
method : 'get',
data : {},
dataType : 'json',
// whether parameters should be encoded with encodeURIComponent
encodeParameters : true,
// callbacks
// API action to use
action : false,
// templated URL to use
url : false,
// base URL to apply to all endpoints
base : '',
// data that will
urlData : {},
// whether to add default data to url data
defaultData : true,
// whether to serialize closest form
serializeForm : false,
// how long to wait before request should occur
throttle : 0,
// whether to throttle first request or only repeated
throttleFirstRequest : true,
// standard ajax settings
method : 'get',
data : {},
dataType : 'json',
// mock response
mockResponse : false,
mockResponseAsync : false,
// callbacks before request
beforeSend : function(settings) { return settings; },
beforeXHR : function(xhr) {},
onRequest : function(promise, xhr) {},
// after request
onResponse : false, // function(response) { },
// response was successful, if JSON passed validation
onSuccess : function(response, $module) {},
// request finished without aborting
onComplete : function(response, $module) {},
onFailure : function(errorMessage, $module) {},
// failed JSON success test
onFailure : function(response, $module) {},
// server error
onError : function(errorMessage, $module) {},
// request aborted
onAbort : function(errorMessage, $module) {},
successTest : false,
@ -836,9 +1100,10 @@ $.api.settings = {
legacyParameters : 'You are using legacy API success callback names',
method : 'The method you called is not defined',
missingAction : 'API action used but no url was defined',
missingSerialize : 'Required dependency jquery-serialize-object missing, using basic serialize',
missingSerialize : 'jquery-serialize-object is required to add form data to an existing data object',
missingURL : 'No URL specified for api event',
noReturnedValue : 'The beforeSend callback must return a settings object, beforeSend ignored.',
noStorage : 'Caching respopnses locally requires session storage',
parseError : 'There was an error parsing your request',
requiredParameter : 'Missing a required URL parameter: ',
statusMessage : 'Server gave an error: ',
@ -846,8 +1111,8 @@ $.api.settings = {
},
regExp : {
required: /\{\$*[A-z0-9]+\}/g,
optional: /\{\/\$*[A-z0-9]+\}/g,
required : /\{\$*[A-z0-9]+\}/g,
optional : /\{\/\$*[A-z0-9]+\}/g,
},
className: {
@ -856,16 +1121,16 @@ $.api.settings = {
},
selector: {
form: 'form'
disabled : '.disabled',
form : 'form'
},
metadata: {
action : 'action'
action : 'action',
url : 'url'
}
};
$.api.settings.api = {};
})( jQuery, window , document );
})( jQuery, window , document );

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,9 @@
/*!
* # Semantic UI 1.12.3 - Breadcrumb
* # Semantic UI 2.1.3 - Breadcrumb
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2014 Contributors
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
@ -15,8 +15,9 @@
*******************************/
.ui.breadcrumb {
margin: 1em 0em;
line-height: 1;
display: inline-block;
margin: 0em 0em;
vertical-align: middle;
}
.ui.breadcrumb:first-child {
@ -35,19 +36,19 @@
/* Divider */
.ui.breadcrumb .divider {
display: inline-block;
opacity: 0.5;
margin: 0em 0.2rem 0em;
font-size: 0.9em;
opacity: 0.7;
margin: 0em 0.21428571rem 0em;
font-size: 0.92857143em;
color: rgba(0, 0, 0, 0.4);
vertical-align: baseline;
}
/* Link */
.ui.breadcrumb a {
color: #009fda;
color: #4183c4;
}
.ui.breadcrumb a:hover {
color: #00b2f3;
color: #1e70bf;
}
/* Icon Divider */
@ -69,7 +70,7 @@
/* Loose Coupling */
.ui.breadcrumb.segment {
display: inline-block;
padding: 0.5em 1em;
padding: 0.71428571em 1em;
}
@ -87,28 +88,28 @@
*******************************/
.ui.mini.breadcrumb {
font-size: 0.65em;
font-size: 0.71428571rem;
}
.ui.tiny.breadcrumb {
font-size: 0.7em;
font-size: 0.85714286rem;
}
.ui.small.breadcrumb {
font-size: 0.75em;
font-size: 0.92857143rem;
}
.ui.breadcrumb {
font-size: 1em;
font-size: 1rem;
}
.ui.large.breadcrumb {
font-size: 1.1em;
font-size: 1.14285714rem;
}
.ui.big.breadcrumb {
font-size: 1.05em;
font-size: 1.28571429rem;
}
.ui.huge.breadcrumb {
font-size: 1.3em;
font-size: 1.42857143rem;
}
.ui.massive.breadcrumb {
font-size: 1.5em;
font-size: 1.71428571rem;
}

View File

@ -1,10 +1,10 @@
/*!
* # Semantic UI 1.12.3 - Breadcrumb
* # Semantic UI 2.1.3 - Breadcrumb
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2014 Contributors
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/.ui.breadcrumb{margin:1em 0;display:inline-block;vertical-align:middle}.ui.breadcrumb:first-child{margin-top:0}.ui.breadcrumb:last-child{margin-bottom:0}.ui.breadcrumb .divider{display:inline-block;opacity:.5;margin:0 .2rem;font-size:.9em;color:rgba(0,0,0,.4);vertical-align:baseline}.ui.breadcrumb a{color:#009fda}.ui.breadcrumb a:hover{color:#00b2f3}.ui.breadcrumb .icon.divider{font-size:.85714286em;vertical-align:baseline}.ui.breadcrumb a.section{cursor:pointer}.ui.breadcrumb .section{display:inline-block;margin:0;padding:0}.ui.breadcrumb.segment{display:inline-block;padding:.5em 1em}.ui.breadcrumb .active.section{font-weight:700}.ui.mini.breadcrumb{font-size:.65em}.ui.tiny.breadcrumb{font-size:.7em}.ui.small.breadcrumb{font-size:.75em}.ui.breadcrumb{font-size:1em}.ui.large.breadcrumb{font-size:1.1em}.ui.big.breadcrumb{font-size:1.05em}.ui.huge.breadcrumb{font-size:1.3em}.ui.massive.breadcrumb{font-size:1.5em}
*/.ui.breadcrumb{line-height:1;display:inline-block;margin:0;vertical-align:middle}.ui.breadcrumb:first-child{margin-top:0}.ui.breadcrumb:last-child{margin-bottom:0}.ui.breadcrumb .divider{display:inline-block;opacity:.7;margin:0 .21428571rem;font-size:.92857143em;color:rgba(0,0,0,.4);vertical-align:baseline}.ui.breadcrumb a{color:#4183c4}.ui.breadcrumb a:hover{color:#1e70bf}.ui.breadcrumb .icon.divider{font-size:.85714286em;vertical-align:baseline}.ui.breadcrumb a.section{cursor:pointer}.ui.breadcrumb .section{display:inline-block;margin:0;padding:0}.ui.breadcrumb.segment{display:inline-block;padding:.71428571em 1em}.ui.breadcrumb .active.section{font-weight:700}.ui.mini.breadcrumb{font-size:.71428571rem}.ui.tiny.breadcrumb{font-size:.85714286rem}.ui.small.breadcrumb{font-size:.92857143rem}.ui.breadcrumb{font-size:1rem}.ui.large.breadcrumb{font-size:1.14285714rem}.ui.big.breadcrumb{font-size:1.28571429rem}.ui.huge.breadcrumb{font-size:1.42857143rem}.ui.massive.breadcrumb{font-size:1.71428571rem}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,9 @@
/*!
* # Semantic UI 1.12.3 - Item
* # Semantic UI 2.1.3 - Item
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2014 Contributorss
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
@ -37,10 +37,10 @@
background: #ffffff;
padding: 0em;
border: none;
border-radius: 0.2857rem;
box-shadow: 0px 3px 0px 0px #d4d4d5, 0px 0px 0px 1px #d4d4d5;
-webkit-transition: box-shadow 0.2s ease;
transition: box-shadow 0.2s ease;
border-radius: 0.28571429rem;
box-shadow: 0px 1px 3px 0px #d4d4d5, 0px 0px 0px 1px #d4d4d5;
-webkit-transition: box-shadow 0.1s ease, -webkit-transform 0.1s ease;
transition: box-shadow 0.1s ease, transform 0.1s ease;
z-index: '';
}
.ui.card {
@ -102,11 +102,16 @@
.ui.cards > .card > :first-child,
.ui.card > :first-child {
border-radius: 0.2857rem 0.2857rem 0em 0em !important;
border-radius: 0.28571429rem 0.28571429rem 0em 0em !important;
border-top: none !important;
}
.ui.cards > .card > :last-child,
.ui.card > :last-child {
border-radius: 0em 0em 0.2857rem 0.2857rem !important;
border-radius: 0em 0em 0.28571429rem 0.28571429rem !important;
}
.ui.cards > .card > :only-child,
.ui.card > :only-child {
border-radius: 0.28571429rem !important;
}
/*--------------
@ -115,12 +120,12 @@
.ui.cards > .card > .image,
.ui.card > .image {
position: relative;
display: block;
-webkit-box-flex: 0;
-webkit-flex: 0 0 auto;
-ms-flex: 0 0 auto;
flex: 0 0 auto;
position: relative;
padding: 0em;
background: rgba(0, 0, 0, 0.05);
}
@ -129,12 +134,11 @@
display: block;
width: 100%;
height: auto;
border-radius: 0.2857rem 0.2857rem 0em 0em;
border: none;
border-radius: inherit;
}
.ui.cards > .card > .image:only-child > img,
.ui.card > .image:only-child > img {
border-radius: 0.2857rem;
.ui.cards > .card > .image:not(.ui) > img,
.ui.card > .image:not(.ui) > img {
border: none;
}
/*--------------
@ -147,12 +151,13 @@
-webkit-flex-grow: 1;
-ms-flex-positive: 1;
flex-grow: 1;
border: none;
border-top: 1px solid rgba(34, 36, 38, 0.1);
background: none;
margin: 0em;
padding: 1em 1em;
box-shadow: none;
font-size: 1em;
border: none;
border-radius: 0em;
}
.ui.cards > .card > .content:after,
@ -167,7 +172,7 @@
.ui.cards > .card > .content > .header,
.ui.card > .content > .header {
display: block;
margin: 0em;
margin: '';
font-family: 'Lato', 'Helvetica Neue', Arial, Helvetica, sans-serif;
color: rgba(0, 0, 0, 0.85);
}
@ -176,9 +181,9 @@
.ui.cards > .card > .content > .header:not(.ui),
.ui.card > .content > .header:not(.ui) {
font-weight: bold;
font-size: 1.2em;
margin-top: -0.165em;
line-height: 1.33em;
font-size: 1.28571429em;
margin-top: -0.21425em;
line-height: 1.2857em;
}
.ui.cards > .card > .content > .meta + .description,
.ui.cards > .card > .content > .header + .description,
@ -187,9 +192,9 @@
margin-top: 0.5em;
}
/*--------------
Floated
---------------*/
/*----------------
Floated Content
-----------------*/
.ui.cards > .card [class*="left floated"],
.ui.card [class*="left floated"] {
@ -225,14 +230,14 @@
.ui.card .content img {
display: inline-block;
vertical-align: middle;
width: auto;
width: '';
}
.ui.cards > .card img.avatar,
.ui.cards > .card .avatar img,
.ui.card img.avatar,
.ui.card .avatar img {
width: 2.5em;
height: 2.5em;
width: 2em;
height: 2em;
border-radius: 500rem;
}
@ -243,7 +248,7 @@
.ui.cards > .card > .content > .description,
.ui.card > .content > .description {
clear: both;
color: rgba(0, 0, 0, 0.5);
color: rgba(0, 0, 0, 0.68);
}
/*--------------
@ -265,7 +270,7 @@
.ui.cards > .card .meta,
.ui.card .meta {
font-size: 0.9em;
font-size: 1em;
color: rgba(0, 0, 0, 0.4);
}
.ui.cards > .card .meta *,
@ -291,8 +296,8 @@
.ui.cards > .card > .content a:not(.ui),
.ui.card > .content a:not(.ui) {
color: '';
-webkit-transition: color 0.2s ease;
transition: color 0.2s ease;
-webkit-transition: color 0.1s ease;
transition: color 0.1s ease;
}
.ui.cards > .card > .content a:not(.ui):hover,
.ui.card > .content a:not(.ui):hover {
@ -306,7 +311,7 @@
}
.ui.cards > .card > .content > a.header:hover,
.ui.card > .content > a.header:hover {
color: #00b2f3;
color: #1e70bf;
}
/* Meta */
@ -316,19 +321,19 @@
}
.ui.cards > .card .meta > a:not(.ui):hover,
.ui.card .meta > a:not(.ui):hover {
color: rgba(0, 0, 0, 0.8);
color: rgba(0, 0, 0, 0.87);
}
/*--------------
Buttons
---------------*/
.ui.cards > .card > .buttons:last-child,
.ui.card > .buttons:last-child,
.ui.cards > .card > .button:last-child,
.ui.card > .button:last-child {
margin: 0em 0em -1px;
width: 100%;
.ui.cards > .card > .buttons,
.ui.card > .buttons,
.ui.cards > .card > .button,
.ui.card > .button {
margin: 0px -1px;
width: calc(100% + 2px );
}
/*--------------
@ -354,8 +359,8 @@
.ui.card > .content .star.icon {
cursor: pointer;
opacity: 0.75;
-webkit-transition: color 0.2s ease;
transition: color 0.2s ease;
-webkit-transition: color 0.1s ease;
transition: color 0.1s ease;
}
.ui.cards > .card > .content .star.icon:hover,
.ui.card > .content .star.icon:hover {
@ -375,8 +380,8 @@
.ui.card > .content .like.icon {
cursor: pointer;
opacity: 0.75;
-webkit-transition: color 0.2s ease;
transition: color 0.2s ease;
-webkit-transition: color 0.1s ease;
transition: color 0.1s ease;
}
.ui.cards > .card > .content .like.icon:hover,
.ui.card > .content .like.icon:hover {
@ -400,6 +405,7 @@
-webkit-flex-grow: 0;
-ms-flex-positive: 0;
flex-grow: 0;
border-top: 1px solid rgba(0, 0, 0, 0.05) !important;
position: static;
background: none;
width: auto;
@ -409,9 +415,8 @@
left: 0em;
color: rgba(0, 0, 0, 0.4);
box-shadow: none;
-webkit-transition: color 0.2s ease;
transition: color 0.2s ease;
border-top: 1px solid rgba(0, 0, 0, 0.05);
-webkit-transition: color 0.1s ease;
transition: color 0.1s ease;
}
.ui.cards > .card > .extra a:not(.ui),
.ui.card > .extra a:not(.ui) {
@ -419,7 +424,7 @@
}
.ui.cards > .card > .extra a:not(.ui):hover,
.ui.card > .extra a:not(.ui):hover {
color: #00b2f3;
color: #1e70bf;
}
@ -428,6 +433,21 @@
*******************************/
/*-------------------
Centered
--------------------*/
.ui.centered.cards {
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
}
.ui.centered.card {
margin-left: auto;
margin-right: auto;
}
/*-------------------
Fluid
--------------------*/
@ -441,112 +461,187 @@
Link
--------------------*/
.ui.cards a.card,
.ui.link.cards .card,
a.ui.card,
.ui.link.card {
-webkit-transform: none;
-ms-transform: none;
transform: none;
}
.ui.cards a.card:hover,
.ui.link.cards .card:hover,
a.ui.card:hover,
.ui.link.card:hover {
cursor: pointer;
z-index: 5;
background: '';
background: #ffffff;
border: none;
box-shadow: 0px 3px 0px 0px #bebebf, 0px 0px 0px 1px rgba(39, 41, 43, 0.3);
box-shadow: 0px 1px 3px 0px #bcbdbd, 0px 0px 0px 1px #d4d4d5;
-webkit-transform: translateY(-3px);
-ms-transform: translateY(-3px);
transform: translateY(-3px);
}
/*-------------------
Colors
--------------------*/
.ui.black.cards > .card,
.ui.cards > .black.card,
.ui.black.card {
box-shadow: 0px 3px 0px 0px #1b1c1d, 0px 0px 0px 1px #d4d4d5;
}
.ui.blue.cards > .card,
.ui.cards > .blue.card,
.ui.blue.card {
box-shadow: 0px 3px 0px 0px #3b83c0, 0px 0px 0px 1px #d4d4d5;
}
.ui.green.cards > .card,
.ui.cards > .green.card,
.ui.green.card {
box-shadow: 0px 3px 0px 0px #5bbd72, 0px 0px 0px 1px #d4d4d5;
}
.ui.orange.cards > .card,
.ui.cards > .orange.card,
.ui.orange.card {
box-shadow: 0px 3px 0px 0px #e07b53, 0px 0px 0px 1px #d4d4d5;
}
.ui.pink.cards > .card,
.ui.cards > .pink.card,
.ui.pink.card {
box-shadow: 0px 3px 0px 0px #d9499a, 0px 0px 0px 1px #d4d4d5;
}
.ui.purple.cards > .card,
.ui.cards > .purple.card,
.ui.purple.card {
box-shadow: 0px 3px 0px 0px #564f8a, 0px 0px 0px 1px #d4d4d5;
}
/* Red */
.ui.red.cards > .card,
.ui.cards > .red.card,
.ui.red.card {
box-shadow: 0px 3px 0px 0px #d95c5c, 0px 0px 0px 1px #d4d4d5;
}
.ui.teal.cards > .card,
.ui.cards > .teal.card,
.ui.teal.card {
box-shadow: 0px 3px 0px 0px #00b5ad, 0px 0px 0px 1px #d4d4d5;
}
.ui.yellow.cards > .card,
.ui.cards > .yellow.card,
.ui.yellow.card {
box-shadow: 0px 3px 0px 0px #f2c61f, 0px 0px 0px 1px #d4d4d5;
}
/* Hover */
.ui.black.cards > .card:hover,
.ui.cards > .black.card:hover,
.ui.black.card:hover {
box-shadow: 0px 3px 0px 0px #1b1c1d, 0px 0px 0px 1px #d4d4d5;
}
.ui.blue.cards > .card:hover,
.ui.cards > .blue.card:hover,
.ui.blue.card:hover {
box-shadow: 0px 3px 0px 0px #458ac6, 0px 0px 0px 1px #d4d4d5;
}
.ui.green.cards > .card:hover,
.ui.cards > .green.card:hover,
.ui.green.card:hover {
box-shadow: 0px 3px 0px 0px #66c17b, 0px 0px 0px 1px #d4d4d5;
}
.ui.orange.cards > .card:hover,
.ui.cards > .orange.card:hover,
.ui.orange.card:hover {
box-shadow: 0px 3px 0px 0px #e28560, 0px 0px 0px 1px #d4d4d5;
}
.ui.pink.cards > .card:hover,
.ui.cards > .pink.card:hover,
.ui.pink.card:hover {
box-shadow: 0px 3px 0px 0px #dc56a1, 0px 0px 0px 1px #d4d4d5;
}
.ui.purple.cards > .card:hover,
.ui.cards > .purple.card:hover,
.ui.purple.card:hover {
box-shadow: 0px 3px 0px 0px #5c5594, 0px 0px 0px 1px #d4d4d5;
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #db2828, 0px 1px 3px 0px #d4d4d5;
}
.ui.red.cards > .card:hover,
.ui.cards > .red.card:hover,
.ui.red.card:hover {
box-shadow: 0px 3px 0px 0px #dc6868, 0px 0px 0px 1px #d4d4d5;
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #d01919, 0px 1px 3px 0px #bcbdbd;
}
.ui.teal.cards > .card:hover,
.ui.cards > .teal.card:hover,
.ui.teal.card:hover {
box-shadow: 0px 3px 0px 0px #00c4bc, 0px 0px 0px 1px #d4d4d5;
/* Orange */
.ui.orange.cards > .card,
.ui.cards > .orange.card,
.ui.orange.card {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #f2711c, 0px 1px 3px 0px #d4d4d5;
}
.ui.orange.cards > .card:hover,
.ui.cards > .orange.card:hover,
.ui.orange.card:hover {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #f26202, 0px 1px 3px 0px #bcbdbd;
}
/* Yellow */
.ui.yellow.cards > .card,
.ui.cards > .yellow.card,
.ui.yellow.card {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #fbbd08, 0px 1px 3px 0px #d4d4d5;
}
.ui.yellow.cards > .card:hover,
.ui.cards > .yellow.card:hover,
.ui.yellow.card:hover {
box-shadow: 0px 3px 0px 0px #f3ca2d, 0px 0px 0px 1px #d4d4d5;
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #eaae00, 0px 1px 3px 0px #bcbdbd;
}
/* Olive */
.ui.olive.cards > .card,
.ui.cards > .olive.card,
.ui.olive.card {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #b5cc18, 0px 1px 3px 0px #d4d4d5;
}
.ui.olive.cards > .card:hover,
.ui.cards > .olive.card:hover,
.ui.olive.card:hover {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #a7bd0d, 0px 1px 3px 0px #bcbdbd;
}
/* Green */
.ui.green.cards > .card,
.ui.cards > .green.card,
.ui.green.card {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #21ba45, 0px 1px 3px 0px #d4d4d5;
}
.ui.green.cards > .card:hover,
.ui.cards > .green.card:hover,
.ui.green.card:hover {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #16ab39, 0px 1px 3px 0px #bcbdbd;
}
/* Teal */
.ui.teal.cards > .card,
.ui.cards > .teal.card,
.ui.teal.card {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #00b5ad, 0px 1px 3px 0px #d4d4d5;
}
.ui.teal.cards > .card:hover,
.ui.cards > .teal.card:hover,
.ui.teal.card:hover {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #009c95, 0px 1px 3px 0px #bcbdbd;
}
/* Blue */
.ui.blue.cards > .card,
.ui.cards > .blue.card,
.ui.blue.card {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #2185d0, 0px 1px 3px 0px #d4d4d5;
}
.ui.blue.cards > .card:hover,
.ui.cards > .blue.card:hover,
.ui.blue.card:hover {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #1678c2, 0px 1px 3px 0px #bcbdbd;
}
/* Violet */
.ui.violet.cards > .card,
.ui.cards > .violet.card,
.ui.violet.card {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #6435c9, 0px 1px 3px 0px #d4d4d5;
}
.ui.violet.cards > .card:hover,
.ui.cards > .violet.card:hover,
.ui.violet.card:hover {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #5829bb, 0px 1px 3px 0px #bcbdbd;
}
/* Purple */
.ui.purple.cards > .card,
.ui.cards > .purple.card,
.ui.purple.card {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #a333c8, 0px 1px 3px 0px #d4d4d5;
}
.ui.purple.cards > .card:hover,
.ui.cards > .purple.card:hover,
.ui.purple.card:hover {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #9627ba, 0px 1px 3px 0px #bcbdbd;
}
/* Pink */
.ui.pink.cards > .card,
.ui.cards > .pink.card,
.ui.pink.card {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #e03997, 0px 1px 3px 0px #d4d4d5;
}
.ui.pink.cards > .card:hover,
.ui.cards > .pink.card:hover,
.ui.pink.card:hover {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #e61a8d, 0px 1px 3px 0px #bcbdbd;
}
/* Brown */
.ui.brown.cards > .card,
.ui.cards > .brown.card,
.ui.brown.card {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #a5673f, 0px 1px 3px 0px #d4d4d5;
}
.ui.brown.cards > .card:hover,
.ui.cards > .brown.card:hover,
.ui.brown.card:hover {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #975b33, 0px 1px 3px 0px #bcbdbd;
}
/* Grey */
.ui.grey.cards > .card,
.ui.cards > .grey.card,
.ui.grey.card {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #767676, 0px 1px 3px 0px #d4d4d5;
}
.ui.grey.cards > .card:hover,
.ui.cards > .grey.card:hover,
.ui.grey.card:hover {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #838383, 0px 1px 3px 0px #bcbdbd;
}
/* Black */
.ui.black.cards > .card,
.ui.cards > .black.card,
.ui.black.card {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #1b1c1d, 0px 1px 3px 0px #d4d4d5;
}
.ui.black.cards > .card:hover,
.ui.cards > .black.card:hover,
.ui.black.card:hover {
box-shadow: 0px 0px 0px 1px #d4d4d5, 0px 2px 0px 0px #27292a, 0px 1px 3px 0px #bcbdbd;
}
/*--------------
@ -565,120 +660,84 @@ a.ui.card:hover,
margin-right: -1em;
}
.ui.two.cards > .card {
width: -webkit-calc( 50% - 2em );
width: calc( 50% - 2em );
margin-left: 1em;
margin-right: 1em;
}
.ui.two.cards > .card:nth-child(2n+1) {
clear: left;
}
.ui.three.cards {
margin-left: -1em;
margin-right: -1em;
}
.ui.three.cards > .card {
width: -webkit-calc( 33.33333333% - 2em );
width: calc( 33.33333333% - 2em );
margin-left: 1em;
margin-right: 1em;
}
.ui.three.cards > .card:nth-child(3n+1) {
clear: left;
}
.ui.four.cards {
margin-left: -0.75em;
margin-right: -0.75em;
}
.ui.four.cards > .card {
width: -webkit-calc( 25% - 1.5em );
width: calc( 25% - 1.5em );
margin-left: 0.75em;
margin-right: 0.75em;
}
.ui.four.cards > .card:nth-child(4n+1) {
clear: left;
}
.ui.five.cards {
margin-left: -0.75em;
margin-right: -0.75em;
}
.ui.five.cards > .card {
width: -webkit-calc( 20% - 1.5em );
width: calc( 20% - 1.5em );
margin-left: 0.75em;
margin-right: 0.75em;
}
.ui.five.cards > .card:nth-child(5n+1) {
clear: left;
}
.ui.six.cards {
margin-left: -0.75em;
margin-right: -0.75em;
}
.ui.six.cards > .card {
width: -webkit-calc( 16.66666667% - 1.5em );
width: calc( 16.66666667% - 1.5em );
margin-left: 0.75em;
margin-right: 0.75em;
}
.ui.six.cards > .card:nth-child(6n+1) {
clear: left;
}
.ui.seven.cards {
margin-left: -0.5em;
margin-right: -0.5em;
}
.ui.seven.cards > .card {
width: -webkit-calc( 14.28571429% - 1em );
width: calc( 14.28571429% - 1em );
margin-left: 0.5em;
margin-right: 0.5em;
}
.ui.seven.cards > .card:nth-child(7n+1) {
clear: left;
}
.ui.eight.cards {
margin-left: -0.5em;
margin-right: -0.5em;
}
.ui.eight.cards > .card {
width: -webkit-calc( 12.5% - 1em );
width: calc( 12.5% - 1em );
margin-left: 0.5em;
margin-right: 0.5em;
font-size: 11px;
}
.ui.eight.cards > .card:nth-child(8n+1) {
clear: left;
}
.ui.nine.cards {
margin-left: -0.5em;
margin-right: -0.5em;
}
.ui.nine.cards > .card {
width: -webkit-calc( 11.11111111% - 1em );
width: calc( 11.11111111% - 1em );
margin-left: 0.5em;
margin-right: 0.5em;
font-size: 10px;
}
.ui.nine.cards > .card:nth-child(9n+1) {
clear: left;
}
.ui.ten.cards {
margin-left: -0.5em;
margin-right: -0.5em;
}
.ui.ten.cards > .card {
width: -webkit-calc( 10% - 1em );
width: calc( 10% - 1em );
margin-left: 0.5em;
margin-right: 0.5em;
}
.ui.ten.cards > .card:nth-child(10n+1) {
clear: left;
}
/*-------------------
Doubling
@ -701,7 +760,6 @@ a.ui.card:hover,
margin-right: -1em;
}
.ui.three.doubling.cards .card {
width: -webkit-calc( 50% - 2em );
width: calc( 50% - 2em );
margin-left: 1em;
margin-right: 1em;
@ -711,7 +769,6 @@ a.ui.card:hover,
margin-right: -1em;
}
.ui.four.doubling.cards .card {
width: -webkit-calc( 50% - 2em );
width: calc( 50% - 2em );
margin-left: 1em;
margin-right: 1em;
@ -721,7 +778,6 @@ a.ui.card:hover,
margin-right: -1em;
}
.ui.five.doubling.cards .card {
width: -webkit-calc( 50% - 2em );
width: calc( 50% - 2em );
margin-left: 1em;
margin-right: 1em;
@ -731,7 +787,6 @@ a.ui.card:hover,
margin-right: -1em;
}
.ui.six.doubling.cards .card {
width: -webkit-calc( 50% - 2em );
width: calc( 50% - 2em );
margin-left: 1em;
margin-right: 1em;
@ -741,7 +796,6 @@ a.ui.card:hover,
margin-right: -1em;
}
.ui.seven.doubling.cards .card {
width: -webkit-calc( 33.33333333% - 2em );
width: calc( 33.33333333% - 2em );
margin-left: 1em;
margin-right: 1em;
@ -751,7 +805,6 @@ a.ui.card:hover,
margin-right: -1em;
}
.ui.eight.doubling.cards .card {
width: -webkit-calc( 33.33333333% - 2em );
width: calc( 33.33333333% - 2em );
margin-left: 1em;
margin-right: 1em;
@ -761,7 +814,6 @@ a.ui.card:hover,
margin-right: -1em;
}
.ui.nine.doubling.cards .card {
width: -webkit-calc( 33.33333333% - 2em );
width: calc( 33.33333333% - 2em );
margin-left: 1em;
margin-right: 1em;
@ -771,7 +823,6 @@ a.ui.card:hover,
margin-right: -1em;
}
.ui.ten.doubling.cards .card {
width: -webkit-calc( 33.33333333% - 2em );
width: calc( 33.33333333% - 2em );
margin-left: 1em;
margin-right: 1em;
@ -794,7 +845,6 @@ a.ui.card:hover,
margin-right: -1em;
}
.ui.three.doubling.cards .card {
width: -webkit-calc( 50% - 2em );
width: calc( 50% - 2em );
margin-left: 1em;
margin-right: 1em;
@ -804,7 +854,6 @@ a.ui.card:hover,
margin-right: -1em;
}
.ui.four.doubling.cards .card {
width: -webkit-calc( 50% - 2em );
width: calc( 50% - 2em );
margin-left: 1em;
margin-right: 1em;
@ -814,7 +863,6 @@ a.ui.card:hover,
margin-right: -1em;
}
.ui.five.doubling.cards .card {
width: -webkit-calc( 33.33333333% - 2em );
width: calc( 33.33333333% - 2em );
margin-left: 1em;
margin-right: 1em;
@ -824,7 +872,6 @@ a.ui.card:hover,
margin-right: -1em;
}
.ui.six.doubling.cards .card {
width: -webkit-calc( 33.33333333% - 2em );
width: calc( 33.33333333% - 2em );
margin-left: 1em;
margin-right: 1em;
@ -834,7 +881,6 @@ a.ui.card:hover,
margin-right: -1em;
}
.ui.eight.doubling.cards .card {
width: -webkit-calc( 33.33333333% - 2em );
width: calc( 33.33333333% - 2em );
margin-left: 1em;
margin-right: 1em;
@ -844,7 +890,6 @@ a.ui.card:hover,
margin-right: -0.75em;
}
.ui.eight.doubling.cards .card {
width: -webkit-calc( 25% - 1.5em );
width: calc( 25% - 1.5em );
margin-left: 0.75em;
margin-right: 0.75em;
@ -854,7 +899,6 @@ a.ui.card:hover,
margin-right: -0.75em;
}
.ui.nine.doubling.cards .card {
width: -webkit-calc( 25% - 1.5em );
width: calc( 25% - 1.5em );
margin-left: 0.75em;
margin-right: 0.75em;
@ -864,7 +908,6 @@ a.ui.card:hover,
margin-right: -0.75em;
}
.ui.ten.doubling.cards .card {
width: -webkit-calc( 20% - 1.5em );
width: calc( 20% - 1.5em );
margin-left: 0.75em;
margin-right: 0.75em;
@ -887,7 +930,6 @@ a.ui.card:hover,
height: auto !important;
margin: 1em 1em;
padding: 0 !important;
width: -webkit-calc( 100% - 2em ) !important;
width: calc( 100% - 2em ) !important;
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,9 @@
/*!
* # Semantic UI 1.12.3 - Checkbox
* # Semantic UI 2.1.3 - Checkbox
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2014 Contributors
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
@ -41,9 +41,12 @@ $.fn.checkbox = function(parameters) {
moduleNamespace = 'module-' + namespace,
$module = $(this),
$label = $(this).find(selector.label).first(),
$input = $(this).find(selector.input),
$label = $(this).children(selector.label),
$input = $(this).children(selector.input),
input = $input[0],
initialLoad = false,
shortcutPressed = false,
instance = $module.data(moduleNamespace),
observer,
@ -57,23 +60,14 @@ $.fn.checkbox = function(parameters) {
module.verbose('Initializing checkbox', settings);
module.create.label();
module.add.events();
module.bind.events();
module.set.tabbable();
module.hide.input();
if( module.is.checked() ) {
module.set.checked();
if(settings.fireOnInit) {
settings.onChecked.call($input.get());
}
}
else {
module.remove.checked();
if(settings.fireOnInit) {
settings.onUnchecked.call($input.get());
}
}
module.observeChanges();
module.instantiate();
module.setup();
},
instantiate: function() {
@ -86,16 +80,55 @@ $.fn.checkbox = function(parameters) {
destroy: function() {
module.verbose('Destroying module');
module.remove.events();
$module
.removeData(moduleNamespace)
;
module.unbind.events();
module.show.input();
$module.removeData(moduleNamespace);
},
fix: {
reference: function() {
if( $module.is(selector.input) ) {
module.debug('Behavior called on <input> adjusting invoked element');
$module = $module.closest(selector.checkbox);
module.refresh();
}
}
},
setup: function() {
module.set.initialLoad();
if( module.is.indeterminate() ) {
module.debug('Initial value is indeterminate');
module.indeterminate();
}
else if( module.is.checked() ) {
module.debug('Initial value is checked');
module.check();
}
else {
module.debug('Initial value is unchecked');
module.uncheck();
}
module.remove.initialLoad();
},
refresh: function() {
$module = $(element);
$label = $(element).find(selector.label).first();
$input = $(element).find(selector.input);
$label = $module.children(selector.label);
$input = $module.children(selector.input);
input = $input[0];
},
hide: {
input: function() {
module.verbose('Modfying <input> z-index to be unselectable');
$input.addClass(className.hidden);
}
},
show: {
input: function() {
module.verbose('Modfying <input> z-index to be selectable');
$input.removeClass(className.hidden);
}
},
observeChanges: function() {
@ -132,6 +165,22 @@ $.fn.checkbox = function(parameters) {
},
event: {
click: function(event) {
var
$target = $(event.target)
;
if( $target.is(selector.input) ) {
module.verbose('Using default check action on initialized checkbox');
return;
}
if( $target.is(selector.link) ) {
module.debug('Clicking link inside checkbox, skipping toggle');
return;
}
module.toggle();
$input.focus();
event.preventDefault();
},
keydown: function(event) {
var
key = event.which,
@ -141,35 +190,195 @@ $.fn.checkbox = function(parameters) {
escape : 27
}
;
if( key == keyCode.escape) {
if(key == keyCode.escape) {
module.verbose('Escape key pressed blurring field');
$module
.blur()
;
$input.blur();
shortcutPressed = true;
}
if(!event.ctrlKey && (key == keyCode.enter || key == keyCode.space)) {
module.verbose('Enter key pressed, toggling checkbox');
module.toggle.call(this);
else if(!event.ctrlKey && ( key == keyCode.space || key == keyCode.enter) ) {
module.verbose('Enter/space key pressed, toggling checkbox');
module.toggle();
shortcutPressed = true;
}
else {
shortcutPressed = false;
}
},
keyup: function(event) {
if(shortcutPressed) {
event.preventDefault();
}
}
},
check: function() {
if( !module.should.allowCheck() ) {
return;
}
module.debug('Checking checkbox', $input);
module.set.checked();
if( !module.should.ignoreCallbacks() ) {
settings.onChecked.call(input);
settings.onChange.call(input);
}
},
uncheck: function() {
if( !module.should.allowUncheck() ) {
return;
}
module.debug('Unchecking checkbox');
module.set.unchecked();
if( !module.should.ignoreCallbacks() ) {
settings.onUnchecked.call(input);
settings.onChange.call(input);
}
},
indeterminate: function() {
if( module.should.allowIndeterminate() ) {
module.debug('Checkbox is already indeterminate');
return;
}
module.debug('Making checkbox indeterminate');
module.set.indeterminate();
if( !module.should.ignoreCallbacks() ) {
settings.onIndeterminate.call(input);
settings.onChange.call(input);
}
},
determinate: function() {
if( module.should.allowDeterminate() ) {
module.debug('Checkbox is already determinate');
return;
}
module.debug('Making checkbox determinate');
module.set.determinate();
if( !module.should.ignoreCallbacks() ) {
settings.onDeterminate.call(input);
settings.onChange.call(input);
}
},
enable: function() {
if( module.is.enabled() ) {
module.debug('Checkbox is already enabled');
return;
}
module.debug('Enabling checkbox');
module.set.enabled();
settings.onEnable.call(input);
},
disable: function() {
if( module.is.disabled() ) {
module.debug('Checkbox is already disabled');
return;
}
module.debug('Disabling checkbox');
module.set.disabled();
settings.onDisable.call(input);
},
get: {
radios: function() {
var
name = module.get.name()
;
return $('input[name="' + name + '"]').closest(selector.checkbox);
},
otherRadios: function() {
return module.get.radios().not($module);
},
name: function() {
return $input.attr('name');
}
},
is: {
initialLoad: function() {
return initialLoad;
},
radio: function() {
return $module.hasClass(className.radio);
return ($input.hasClass(className.radio) || $input.attr('type') == 'radio');
},
indeterminate: function() {
return $input.prop('indeterminate') !== undefined && $input.prop('indeterminate');
},
checked: function() {
return $input.prop('checked') !== undefined && $input.prop('checked');
},
disabled: function() {
return $input.prop('disabled') !== undefined && $input.prop('disabled');
},
enabled: function() {
return !module.is.disabled();
},
determinate: function() {
return !module.is.indeterminate();
},
unchecked: function() {
return !module.is.checked();
}
},
should: {
allowCheck: function() {
if(module.is.determinate() && module.is.checked() && !module.should.forceCallbacks() ) {
module.debug('Should not allow check, checkbox is already checked');
return false;
}
if(settings.beforeChecked.apply(input) === false) {
module.debug('Should not allow check, beforeChecked cancelled');
return false;
}
return true;
},
allowUncheck: function() {
if(module.is.determinate() && module.is.unchecked() && !module.should.forceCallbacks() ) {
module.debug('Should not allow uncheck, checkbox is already unchecked');
return false;
}
if(settings.beforeUnchecked.apply(input) === false) {
module.debug('Should not allow uncheck, beforeUnchecked cancelled');
return false;
}
return true;
},
allowIndeterminate: function() {
if(module.is.indeterminate() && !module.should.forceCallbacks() ) {
module.debug('Should not allow indeterminate, checkbox is already indeterminate');
return false;
}
if(settings.beforeIndeterminate.apply(input) === false) {
module.debug('Should not allow indeterminate, beforeIndeterminate cancelled');
return false;
}
return true;
},
allowDeterminate: function() {
if(module.is.determinate() && !module.should.forceCallbacks() ) {
module.debug('Should not allow determinate, checkbox is already determinate');
return false;
}
if(settings.beforeDeterminate.apply(input) === false) {
module.debug('Should not allow determinate, beforeDeterminate cancelled');
return false;
}
return true;
},
forceCallbacks: function() {
return (module.is.initialLoad() && settings.fireOnInit);
},
ignoreCallbacks: function() {
return (initialLoad && !settings.fireOnInit);
}
},
can: {
change: function() {
return !( $module.hasClass(className.disabled) || $module.hasClass(className.readOnly) || $input.prop('disabled') );
return !( $module.hasClass(className.disabled) || $module.hasClass(className.readOnly) || $input.prop('disabled') || $input.prop('readonly') );
},
uncheck: function() {
return (typeof settings.uncheckable === 'boolean')
@ -180,18 +389,127 @@ $.fn.checkbox = function(parameters) {
},
set: {
checked: function() {
$module.addClass(className.checked);
initialLoad: function() {
initialLoad = true;
},
tab: function() {
checked: function() {
module.verbose('Setting class to checked');
$module
.removeClass(className.indeterminate)
.addClass(className.checked)
;
if( module.is.radio() ) {
module.uncheckOthers();
}
if(!module.is.indeterminate() && module.is.checked()) {
module.debug('Input is already checked, skipping input property change');
return;
}
module.verbose('Setting state to checked', input);
$input
.prop('indeterminate', false)
.prop('checked', true)
;
module.trigger.change();
},
unchecked: function() {
module.verbose('Removing checked class');
$module
.removeClass(className.indeterminate)
.removeClass(className.checked)
;
if(!module.is.indeterminate() && module.is.unchecked() ) {
module.debug('Input is already unchecked');
return;
}
module.debug('Setting state to unchecked');
$input
.prop('indeterminate', false)
.prop('checked', false)
;
module.trigger.change();
},
indeterminate: function() {
module.verbose('Setting class to indeterminate');
$module
.addClass(className.indeterminate)
;
if( module.is.indeterminate() ) {
module.debug('Input is already indeterminate, skipping input property change');
return;
}
module.debug('Setting state to indeterminate');
$input
.prop('indeterminate', true)
;
module.trigger.change();
},
determinate: function() {
module.verbose('Removing indeterminate class');
$module
.removeClass(className.indeterminate)
;
if( module.is.determinate() ) {
module.debug('Input is already determinate, skipping input property change');
return;
}
module.debug('Setting state to determinate');
$input
.prop('indeterminate', false)
;
},
disabled: function() {
module.verbose('Setting class to disabled');
$module
.addClass(className.disabled)
;
if( module.is.disabled() ) {
module.debug('Input is already disabled, skipping input property change');
return;
}
module.debug('Setting state to disabled');
$input
.prop('disabled', 'disabled')
;
module.trigger.change();
},
enabled: function() {
module.verbose('Removing disabled class');
$module.removeClass(className.disabled);
if( module.is.enabled() ) {
module.debug('Input is already enabled, skipping input property change');
return;
}
module.debug('Setting state to enabled');
$input
.prop('disabled', false)
;
module.trigger.change();
},
tabbable: function() {
module.verbose('Adding tabindex to checkbox');
if( $input.attr('tabindex') === undefined) {
$input
.attr('tabindex', 0)
;
$input.attr('tabindex', 0);
}
}
},
remove: {
initialLoad: function() {
initialLoad = false;
}
},
trigger: {
change: function() {
module.verbose('Triggering change event from programmatic change');
$input
.trigger('change')
;
}
},
create: {
label: function() {
if($input.prevAll(selector.label).length > 0) {
@ -211,84 +529,47 @@ $.fn.checkbox = function(parameters) {
}
},
add: {
bind: {
events: function() {
module.verbose('Attaching checkbox events');
$module
.on('click' + eventNamespace, module.toggle)
.on('click' + eventNamespace, module.event.click)
.on('keydown' + eventNamespace, selector.input, module.event.keydown)
.on('keyup' + eventNamespace, selector.input, module.event.keyup)
;
}
},
remove: {
checked: function() {
$module.removeClass(className.checked);
},
unbind: {
events: function() {
module.debug('Removing events');
$module
.off(eventNamespace)
.removeData(moduleNamespace)
;
$input
.off(eventNamespace, module.event.keydown)
;
$label
.off(eventNamespace)
;
}
},
enable: function() {
module.debug('Enabling checkbox functionality');
$module.removeClass(className.disabled);
$input.prop('disabled', false);
settings.onEnabled.call($input.get());
},
disable: function() {
module.debug('Disabling checkbox functionality');
$module.addClass(className.disabled);
$input.prop('disabled', 'disabled');
settings.onDisabled.call($input.get());
},
check: function() {
module.debug('Enabling checkbox', $input);
$input
.prop('checked', true)
.trigger('change')
uncheckOthers: function() {
var
$radios = module.get.otherRadios()
;
module.set.checked();
$input.trigger('blur');
settings.onChange.call($input.get());
settings.onChecked.call($input.get());
module.debug('Unchecking other radios', $radios);
$radios.removeClass(className.checked);
},
uncheck: function() {
module.debug('Disabling checkbox');
$input
.prop('checked', false)
.trigger('change')
;
module.remove.checked();
$input.trigger('blur');
settings.onChange.call($input.get());
settings.onUnchecked.call($input.get());
},
toggle: function(event) {
toggle: function() {
if( !module.can.change() ) {
console.log(module.can.change());
module.debug('Checkbox is read-only or disabled, ignoring toggle');
if(!module.is.radio()) {
module.debug('Checkbox is read-only or disabled, ignoring toggle');
}
return;
}
module.verbose('Determining new checkbox state');
if( module.is.unchecked() ) {
if( module.is.indeterminate() || module.is.unchecked() ) {
module.debug('Currently unchecked');
module.check();
}
else if( module.is.checked() && module.can.uncheck() ) {
module.debug('Currently checked');
module.uncheck();
}
},
@ -361,7 +642,7 @@ $.fn.checkbox = function(parameters) {
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 100);
module.performance.timer = setTimeout(module.performance.display, 500);
},
display: function() {
var
@ -471,37 +752,51 @@ $.fn.checkbox = function(parameters) {
$.fn.checkbox.settings = {
name : 'Checkbox',
namespace : 'checkbox',
name : 'Checkbox',
namespace : 'checkbox',
debug : false,
verbose : true,
performance : true,
debug : false,
verbose : true,
performance : true,
// delegated event context
uncheckable : 'auto',
fireOnInit : true,
uncheckable : 'auto',
fireOnInit : false,
onChange : function(){},
onChecked : function(){},
onUnchecked : function(){},
onEnabled : function(){},
onDisabled : function(){},
onChange : function(){},
className : {
checked : 'checked',
disabled : 'disabled',
radio : 'radio',
readOnly : 'read-only'
beforeChecked : function(){},
beforeUnchecked : function(){},
beforeDeterminate : function(){},
beforeIndeterminate : function(){},
onChecked : function(){},
onUnchecked : function(){},
onDeterminate : function() {},
onIndeterminate : function() {},
onEnabled : function(){},
onDisabled : function(){},
className : {
checked : 'checked',
indeterminate : 'indeterminate',
disabled : 'disabled',
hidden : 'hidden',
radio : 'radio',
readOnly : 'read-only'
},
error : {
method : 'The method you called is not defined'
method : 'The method you called is not defined'
},
selector : {
input : 'input[type="checkbox"], input[type="radio"]',
label : 'label'
checkbox : '.ui.checkbox',
label : 'label, .box',
input : 'input[type="checkbox"], input[type="radio"]',
link : 'a[href]'
}
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,274 @@
/*!
* # Semantic UI 2.0.0 - Colorize
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/
;(function ( $, window, document, undefined ) {
"use strict";
$.fn.colorize = function(parameters) {
var
settings = ( $.isPlainObject(parameters) )
? $.extend(true, {}, $.fn.colorize.settings, parameters)
: $.extend({}, $.fn.colorize.settings),
// hoist arguments
moduleArguments = arguments || false
;
$(this)
.each(function(instanceIndex) {
var
$module = $(this),
mainCanvas = $('<canvas />')[0],
imageCanvas = $('<canvas />')[0],
overlayCanvas = $('<canvas />')[0],
backgroundImage = new Image(),
// defs
mainContext,
imageContext,
overlayContext,
image,
imageName,
width,
height,
// shortucts
colors = settings.colors,
paths = settings.paths,
namespace = settings.namespace,
error = settings.error,
// boilerplate
instance = $module.data('module-' + namespace),
module
;
module = {
checkPreconditions: function() {
module.debug('Checking pre-conditions');
if( !$.isPlainObject(colors) || $.isEmptyObject(colors) ) {
module.error(error.undefinedColors);
return false;
}
return true;
},
async: function(callback) {
if(settings.async) {
setTimeout(callback, 0);
}
else {
callback();
}
},
getMetadata: function() {
module.debug('Grabbing metadata');
image = $module.data('image') || settings.image || undefined;
imageName = $module.data('name') || settings.name || instanceIndex;
width = settings.width || $module.width();
height = settings.height || $module.height();
if(width === 0 || height === 0) {
module.error(error.undefinedSize);
}
},
initialize: function() {
module.debug('Initializing with colors', colors);
if( module.checkPreconditions() ) {
module.async(function() {
module.getMetadata();
module.canvas.create();
module.draw.image(function() {
module.draw.colors();
module.canvas.merge();
});
$module
.data('module-' + namespace, module)
;
});
}
},
redraw: function() {
module.debug('Redrawing image');
module.async(function() {
module.canvas.clear();
module.draw.colors();
module.canvas.merge();
});
},
change: {
color: function(colorName, color) {
module.debug('Changing color', colorName);
if(colors[colorName] === undefined) {
module.error(error.missingColor);
return false;
}
colors[colorName] = color;
module.redraw();
}
},
canvas: {
create: function() {
module.debug('Creating canvases');
mainCanvas.width = width;
mainCanvas.height = height;
imageCanvas.width = width;
imageCanvas.height = height;
overlayCanvas.width = width;
overlayCanvas.height = height;
mainContext = mainCanvas.getContext('2d');
imageContext = imageCanvas.getContext('2d');
overlayContext = overlayCanvas.getContext('2d');
$module
.append( mainCanvas )
;
mainContext = $module.children('canvas')[0].getContext('2d');
},
clear: function(context) {
module.debug('Clearing canvas');
overlayContext.fillStyle = '#FFFFFF';
overlayContext.fillRect(0, 0, width, height);
},
merge: function() {
if( !$.isFunction(mainContext.blendOnto) ) {
module.error(error.missingPlugin);
return;
}
mainContext.putImageData( imageContext.getImageData(0, 0, width, height), 0, 0);
overlayContext.blendOnto(mainContext, 'multiply');
}
},
draw: {
image: function(callback) {
module.debug('Drawing image');
callback = callback || function(){};
if(image) {
backgroundImage.src = image;
backgroundImage.onload = function() {
imageContext.drawImage(backgroundImage, 0, 0);
callback();
};
}
else {
module.error(error.noImage);
callback();
}
},
colors: function() {
module.debug('Drawing color overlays', colors);
$.each(colors, function(colorName, color) {
settings.onDraw(overlayContext, imageName, colorName, color);
});
}
},
debug: function(message, variableName) {
if(settings.debug) {
if(variableName !== undefined) {
console.info(settings.name + ': ' + message, variableName);
}
else {
console.info(settings.name + ': ' + message);
}
}
},
error: function(errorMessage) {
console.warn(settings.name + ': ' + errorMessage);
},
invoke: function(methodName, context, methodArguments) {
var
method
;
methodArguments = methodArguments || Array.prototype.slice.call( arguments, 2 );
if(typeof methodName == 'string' && instance !== undefined) {
methodName = methodName.split('.');
$.each(methodName, function(index, name) {
if( $.isPlainObject( instance[name] ) ) {
instance = instance[name];
return true;
}
else if( $.isFunction( instance[name] ) ) {
method = instance[name];
return true;
}
module.error(settings.error.method);
return false;
});
}
return ( $.isFunction( method ) )
? method.apply(context, methodArguments)
: false
;
}
};
if(instance !== undefined && moduleArguments) {
// simpler than invoke realizing to invoke itself (and losing scope due prototype.call()
if(moduleArguments[0] == 'invoke') {
moduleArguments = Array.prototype.slice.call( moduleArguments, 1 );
}
return module.invoke(moduleArguments[0], this, Array.prototype.slice.call( moduleArguments, 1 ) );
}
// initializing
module.initialize();
})
;
return this;
};
$.fn.colorize.settings = {
name : 'Image Colorizer',
debug : true,
namespace : 'colorize',
onDraw : function(overlayContext, imageName, colorName, color) {},
// whether to block execution while updating canvas
async : true,
// object containing names and default values of color regions
colors : {},
metadata: {
image : 'image',
name : 'name'
},
error: {
noImage : 'No tracing image specified',
undefinedColors : 'No default colors specified.',
missingColor : 'Attempted to change color that does not exist',
missingPlugin : 'Blend onto plug-in must be included',
undefinedHeight : 'The width or height of image canvas could not be automatically determined. Please specify a height.'
}
};
})( jQuery, window , document );

View File

@ -0,0 +1,11 @@
/*!
* # Semantic UI 2.0.0 - Colorize
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/
!function(e,n,i,t){"use strict";e.fn.colorize=function(n){var i=e.isPlainObject(n)?e.extend(!0,{},e.fn.colorize.settings,n):e.extend({},e.fn.colorize.settings),o=arguments||!1;return e(this).each(function(n){var a,r,c,s,d,g,u,l,m=e(this),f=e("<canvas />")[0],h=e("<canvas />")[0],p=e("<canvas />")[0],v=new Image,w=i.colors,b=(i.paths,i.namespace),y=i.error,C=m.data("module-"+b);return l={checkPreconditions:function(){return l.debug("Checking pre-conditions"),!e.isPlainObject(w)||e.isEmptyObject(w)?(l.error(y.undefinedColors),!1):!0},async:function(e){i.async?setTimeout(e,0):e()},getMetadata:function(){l.debug("Grabbing metadata"),s=m.data("image")||i.image||t,d=m.data("name")||i.name||n,g=i.width||m.width(),u=i.height||m.height(),(0===g||0===u)&&l.error(y.undefinedSize)},initialize:function(){l.debug("Initializing with colors",w),l.checkPreconditions()&&l.async(function(){l.getMetadata(),l.canvas.create(),l.draw.image(function(){l.draw.colors(),l.canvas.merge()}),m.data("module-"+b,l)})},redraw:function(){l.debug("Redrawing image"),l.async(function(){l.canvas.clear(),l.draw.colors(),l.canvas.merge()})},change:{color:function(e,n){return l.debug("Changing color",e),w[e]===t?(l.error(y.missingColor),!1):(w[e]=n,void l.redraw())}},canvas:{create:function(){l.debug("Creating canvases"),f.width=g,f.height=u,h.width=g,h.height=u,p.width=g,p.height=u,a=f.getContext("2d"),r=h.getContext("2d"),c=p.getContext("2d"),m.append(f),a=m.children("canvas")[0].getContext("2d")},clear:function(e){l.debug("Clearing canvas"),c.fillStyle="#FFFFFF",c.fillRect(0,0,g,u)},merge:function(){return e.isFunction(a.blendOnto)?(a.putImageData(r.getImageData(0,0,g,u),0,0),void c.blendOnto(a,"multiply")):void l.error(y.missingPlugin)}},draw:{image:function(e){l.debug("Drawing image"),e=e||function(){},s?(v.src=s,v.onload=function(){r.drawImage(v,0,0),e()}):(l.error(y.noImage),e())},colors:function(){l.debug("Drawing color overlays",w),e.each(w,function(e,n){i.onDraw(c,d,e,n)})}},debug:function(e,n){i.debug&&(n!==t?console.info(i.name+": "+e,n):console.info(i.name+": "+e))},error:function(e){console.warn(i.name+": "+e)},invoke:function(n,o,a){var r;return a=a||Array.prototype.slice.call(arguments,2),"string"==typeof n&&C!==t&&(n=n.split("."),e.each(n,function(n,t){return e.isPlainObject(C[t])?(C=C[t],!0):e.isFunction(C[t])?(r=C[t],!0):(l.error(i.error.method),!1)})),e.isFunction(r)?r.apply(o,a):!1}},C!==t&&o?("invoke"==o[0]&&(o=Array.prototype.slice.call(o,1)),l.invoke(o[0],this,Array.prototype.slice.call(o,1))):void l.initialize()}),this},e.fn.colorize.settings={name:"Image Colorizer",debug:!0,namespace:"colorize",onDraw:function(e,n,i,t){},async:!0,colors:{},metadata:{image:"image",name:"name"},error:{noImage:"No tracing image specified",undefinedColors:"No default colors specified.",missingColor:"Attempted to change color that does not exist",missingPlugin:"Blend onto plug-in must be included",undefinedHeight:"The width or height of image canvas could not be automatically determined. Please specify a height."}}}(jQuery,window,document);

View File

@ -1,9 +1,9 @@
/*!
* # Semantic UI 1.12.3 - Comment
* # Semantic UI 2.1.3 - Comment
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2014 Contributorss
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
@ -106,14 +106,14 @@
.ui.comments .comment .author {
font-size: 1em;
color: rgba(0, 0, 0, 0.8);
color: rgba(0, 0, 0, 0.87);
font-weight: bold;
}
.ui.comments .comment a.author {
cursor: pointer;
}
.ui.comments .comment a.author:hover {
color: #00b2f3;
color: #1e70bf;
}
/*--------------
@ -142,7 +142,7 @@
margin: 0.25em 0em 0.5em;
font-size: 1em;
word-wrap: break-word;
color: rgba(0, 0, 0, 0.8);
color: rgba(0, 0, 0, 0.87);
line-height: 1.3;
}
@ -207,7 +207,7 @@
.ui.threaded.comments .comment .comments {
margin: -1.5em 0 -1em 1.25em;
padding: 3em 0em 2em 2.25em;
box-shadow: -1px 0px 0px rgba(39, 41, 43, 0.15);
box-shadow: -1px 0px 0px rgba(34, 36, 38, 0.15);
}
/*--------------------

View File

@ -1,10 +1,10 @@
/*!
* # Semantic UI 1.12.3 - Comment
* # Semantic UI 2.1.3 - Comment
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2014 Contributorss
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/.ui.comments{margin:1.5em 0;max-width:650px}.ui.comments:first-child{margin-top:0}.ui.comments:last-child{margin-bottom:0}.ui.comments .comment{position:relative;background:0 0;margin:.5em 0 0;padding:.5em 0 0;border:none;border-top:none;line-height:1.2}.ui.comments .comment:first-child{margin-top:0;padding-top:0}.ui.comments .comment .comments{margin:0 0 .5em .5em;padding:1em 0 1em 1em}.ui.comments .comment .comments:before{position:absolute;top:0;left:0}.ui.comments .comment .comments .comment{border:none;border-top:none;background:0 0}.ui.comments .comment .avatar{display:block;width:2.5em;height:auto;float:left;margin:.2em 0 0}.ui.comments .comment .avatar img,.ui.comments .comment img.avatar{display:block;margin:0 auto;width:100%;height:100%;border-radius:.25rem}.ui.comments .comment>.content{display:block}.ui.comments .comment>.avatar~.content{margin-left:3.5em}.ui.comments .comment .author{font-size:1em;color:rgba(0,0,0,.8);font-weight:700}.ui.comments .comment a.author{cursor:pointer}.ui.comments .comment a.author:hover{color:#00b2f3}.ui.comments .comment .metadata{display:inline-block;margin-left:.5em;color:rgba(0,0,0,.4);font-size:.875em}.ui.comments .comment .metadata>*{display:inline-block;margin:0 .5em 0 0}.ui.comments .comment .metadata>:last-child{margin-right:0}.ui.comments .comment .text{margin:.25em 0 .5em;font-size:1em;word-wrap:break-word;color:rgba(0,0,0,.8);line-height:1.3}.ui.comments .comment .actions{font-size:.875em}.ui.comments .comment .actions a{cursor:pointer;display:inline-block;margin:0 .75em 0 0;color:rgba(0,0,0,.4)}.ui.comments .comment .actions a:last-child{margin-right:0}.ui.comments .comment .actions a.active,.ui.comments .comment .actions a:hover{color:rgba(0,0,0,.8)}.ui.comments>.reply.form{margin-top:1em}.ui.comments .comment .reply.form{width:100%;margin-top:1em}.ui.comments .reply.form textarea{font-size:1em;height:12em}.ui.collapsed.comments,.ui.comments .collapsed.comment,.ui.comments .collapsed.comments{display:none}.ui.threaded.comments .comment .comments{margin:-1.5em 0 -1em 1.25em;padding:3em 0 2em 2.25em;box-shadow:-1px 0 0 rgba(39,41,43,.15)}.ui.minimal.comments .comment .actions{opacity:0;position:absolute;top:0;right:0;left:auto;-webkit-transition:opacity .2s ease;transition:opacity .2s ease;-webkit-transition-delay:.1s;transition-delay:.1s}.ui.minimal.comments .comment>.content:hover>.actions{opacity:1}.ui.small.comments{font-size:.9em}.ui.comments{font-size:1em}.ui.large.comments{font-size:1.1em}.ui.huge.comments{font-size:1.2em}
*/.ui.comments{margin:1.5em 0;max-width:650px}.ui.comments:first-child{margin-top:0}.ui.comments:last-child{margin-bottom:0}.ui.comments .comment{position:relative;background:0 0;margin:.5em 0 0;padding:.5em 0 0;border:none;border-top:none;line-height:1.2}.ui.comments .comment:first-child{margin-top:0;padding-top:0}.ui.comments .comment .comments{margin:0 0 .5em .5em;padding:1em 0 1em 1em}.ui.comments .comment .comments:before{position:absolute;top:0;left:0}.ui.comments .comment .comments .comment{border:none;border-top:none;background:0 0}.ui.comments .comment .avatar{display:block;width:2.5em;height:auto;float:left;margin:.2em 0 0}.ui.comments .comment .avatar img,.ui.comments .comment img.avatar{display:block;margin:0 auto;width:100%;height:100%;border-radius:.25rem}.ui.comments .comment>.content{display:block}.ui.comments .comment>.avatar~.content{margin-left:3.5em}.ui.comments .comment .author{font-size:1em;color:rgba(0,0,0,.87);font-weight:700}.ui.comments .comment a.author{cursor:pointer}.ui.comments .comment a.author:hover{color:#1e70bf}.ui.comments .comment .metadata{display:inline-block;margin-left:.5em;color:rgba(0,0,0,.4);font-size:.875em}.ui.comments .comment .metadata>*{display:inline-block;margin:0 .5em 0 0}.ui.comments .comment .metadata>:last-child{margin-right:0}.ui.comments .comment .text{margin:.25em 0 .5em;font-size:1em;word-wrap:break-word;color:rgba(0,0,0,.87);line-height:1.3}.ui.comments .comment .actions{font-size:.875em}.ui.comments .comment .actions a{cursor:pointer;display:inline-block;margin:0 .75em 0 0;color:rgba(0,0,0,.4)}.ui.comments .comment .actions a:last-child{margin-right:0}.ui.comments .comment .actions a.active,.ui.comments .comment .actions a:hover{color:rgba(0,0,0,.8)}.ui.comments>.reply.form{margin-top:1em}.ui.comments .comment .reply.form{width:100%;margin-top:1em}.ui.comments .reply.form textarea{font-size:1em;height:12em}.ui.collapsed.comments,.ui.comments .collapsed.comment,.ui.comments .collapsed.comments{display:none}.ui.threaded.comments .comment .comments{margin:-1.5em 0 -1em 1.25em;padding:3em 0 2em 2.25em;box-shadow:-1px 0 0 rgba(34,36,38,.15)}.ui.minimal.comments .comment .actions{opacity:0;position:absolute;top:0;right:0;left:auto;-webkit-transition:opacity .2s ease;transition:opacity .2s ease;-webkit-transition-delay:.1s;transition-delay:.1s}.ui.minimal.comments .comment>.content:hover>.actions{opacity:1}.ui.small.comments{font-size:.9em}.ui.comments{font-size:1em}.ui.large.comments{font-size:1.1em}.ui.huge.comments{font-size:1.2em}

View File

@ -0,0 +1,149 @@
/*!
* # Semantic UI 2.1.3 - Container
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/
/*******************************
Container
*******************************/
/* All Sizes */
.ui.container {
display: block;
max-width: 100% !important;
}
/* Mobile */
@media only screen and (max-width: 767px) {
.ui.container {
width: auto !important;
margin-left: 1em !important;
margin-right: 1em !important;
}
.ui.grid.container {
width: auto !important;
}
.ui.relaxed.grid.container {
width: auto !important;
}
.ui.very.relaxed.grid.container {
width: auto !important;
}
}
/* Tablet */
@media only screen and (min-width: 768px) and (max-width: 991px) {
.ui.container {
width: 723px;
margin-left: auto !important;
margin-right: auto !important;
}
.ui.grid.container {
width: calc( 723px + 2rem ) !important;
}
.ui.relaxed.grid.container {
width: calc( 723px + 3rem ) !important;
}
.ui.very.relaxed.grid.container {
width: calc( 723px + 5rem ) !important;
}
}
/* Small Monitor */
@media only screen and (min-width: 992px) and (max-width: 1199px) {
.ui.container {
width: 933px;
margin-left: auto !important;
margin-right: auto !important;
}
.ui.grid.container {
width: calc( 933px + 2rem ) !important;
}
.ui.relaxed.grid.container {
width: calc( 933px + 3rem ) !important;
}
.ui.very.relaxed.grid.container {
width: calc( 933px + 5rem ) !important;
}
}
/* Large Monitor */
@media only screen and (min-width: 1200px) {
.ui.container {
width: 1127px;
margin-left: auto !important;
margin-right: auto !important;
}
.ui.grid.container {
width: calc( 1127px + 2rem ) !important;
}
.ui.relaxed.grid.container {
width: calc( 1127px + 3rem ) !important;
}
.ui.very.relaxed.grid.container {
width: calc( 1127px + 5rem ) !important;
}
}
/*******************************
Types
*******************************/
/* Text Container */
.ui.text.container {
font-family: 'Lato', 'Helvetica Neue', Arial, Helvetica, sans-serif;
max-width: 700px !important;
line-height: 1.5;
}
.ui.text.container {
font-size: 1.14285714rem;
}
/* Fluid */
.ui.fluid.container {
width: 100%;
}
/*******************************
Variations
*******************************/
.ui[class*="left aligned"].container {
text-align: left;
}
.ui[class*="center aligned"].container {
text-align: center;
}
.ui[class*="right aligned"].container {
text-align: right;
}
.ui.justified.container {
text-align: justify;
-webkit-hyphens: auto;
-moz-hyphens: auto;
-ms-hyphens: auto;
hyphens: auto;
}
/*******************************
Theme Overrides
*******************************/
/*******************************
Site Overrides
*******************************/

View File

@ -0,0 +1,10 @@
/*!
* # Semantic UI 2.1.3 - Container
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/.ui.container{display:block;max-width:100%!important}@media only screen and (max-width:767px){.ui.container{width:auto!important;margin-left:1em!important;margin-right:1em!important}.ui.grid.container,.ui.relaxed.grid.container,.ui.very.relaxed.grid.container{width:auto!important}}@media only screen and (min-width:768px) and (max-width:991px){.ui.container{width:723px;margin-left:auto!important;margin-right:auto!important}.ui.grid.container{width:calc(723px + 2rem)!important}.ui.relaxed.grid.container{width:calc(723px + 3rem)!important}.ui.very.relaxed.grid.container{width:calc(723px + 5rem)!important}}@media only screen and (min-width:992px) and (max-width:1199px){.ui.container{width:933px;margin-left:auto!important;margin-right:auto!important}.ui.grid.container{width:calc(933px + 2rem)!important}.ui.relaxed.grid.container{width:calc(933px + 3rem)!important}.ui.very.relaxed.grid.container{width:calc(933px + 5rem)!important}}@media only screen and (min-width:1200px){.ui.container{width:1127px;margin-left:auto!important;margin-right:auto!important}.ui.grid.container{width:calc(1127px + 2rem)!important}.ui.relaxed.grid.container{width:calc(1127px + 3rem)!important}.ui.very.relaxed.grid.container{width:calc(1127px + 5rem)!important}}.ui.text.container{font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;max-width:700px!important;line-height:1.5;font-size:1.14285714rem}.ui.fluid.container{width:100%}.ui[class*="left aligned"].container{text-align:left}.ui[class*="center aligned"].container{text-align:center}.ui[class*="right aligned"].container{text-align:right}.ui.justified.container{text-align:justify;-webkit-hyphens:auto;-moz-hyphens:auto;-ms-hyphens:auto;hyphens:auto}

View File

@ -1,9 +1,9 @@
/*!
* # Semantic UI 1.12.3 - Dimmer
* # Semantic UI 2.1.3 - Dimmer
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2014 Contributors
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
@ -26,7 +26,7 @@
height: 100%;
text-align: center;
vertical-align: middle;
background: rgba(0, 0, 0, 0.85);
background-color: rgba(0, 0, 0, 0.85);
opacity: 0;
line-height: 1;
-webkit-animation-fill-mode: both;
@ -53,7 +53,7 @@
-ms-user-select: text;
user-select: text;
}
.ui.dimmer > .content > div {
.ui.dimmer > .content > * {
display: table-cell;
vertical-align: middle;
color: #ffffff;
@ -111,15 +111,29 @@ body.dimmed.dimmable {
body.dimmable > .dimmer {
position: fixed;
}
/*
body.dimmable > :not(.dimmer) {
filter: @elementStartFilter;
/*--------------
Blurring
---------------*/
.blurring.dimmable > :not(.dimmer) {
-webkit-filter: blur(0px) grayscale(0);
filter: blur(0px) grayscale(0);
-webkit-transition: 800ms -webkit-filter ease, 800ms filter ease;
transition: 800ms filter ease;
}
body.dimmed.dimmable > :not(.dimmer) {
filter: @elementEndFilter;
transition: @elementTransition;
.blurring.dimmed.dimmable > :not(.dimmer) {
-webkit-filter: blur(5px) grayscale(0.7);
filter: blur(5px) grayscale(0.7);
}
/* Dimmer Color */
.blurring.dimmable > .dimmer {
background-color: rgba(0, 0, 0, 0.6);
}
.blurring.dimmable > .inverted.dimmer {
background-color: rgba(255, 255, 255, 0.6);
}
*/
/*--------------
Aligned
@ -137,7 +151,7 @@ body.dimmed.dimmable > :not(.dimmer) {
---------------*/
.ui.inverted.dimmer {
background: rgba(255, 255, 255, 0.85);
background-color: rgba(255, 255, 255, 0.85);
}
.ui.inverted.dimmer > .content > * {
color: #ffffff;
@ -163,14 +177,14 @@ body.dimmed.dimmable > :not(.dimmer) {
opacity: 1;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.85);
background-color: rgba(0, 0, 0, 0.85);
z-index: 1;
}
.ui.simple.inverted.dimmer {
background: rgba(255, 255, 255, 0);
background-color: rgba(255, 255, 255, 0);
}
.dimmed.dimmable > .ui.simple.inverted.dimmer {
background: rgba(255, 255, 255, 0.85);
background-color: rgba(255, 255, 255, 0.85);
}

View File

@ -1,9 +1,9 @@
/*!
* # Semantic UI 1.12.3 - Dimmer
* # Semantic UI 2.1.3 - Dimmer
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2014 Contributors
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
@ -60,6 +60,7 @@ $.fn.dimmer = function(parameters) {
preinitialize: function() {
if( module.is.dimmer() ) {
$dimmable = $module.parent();
$dimmer = $module;
}
@ -67,10 +68,10 @@ $.fn.dimmer = function(parameters) {
$dimmable = $module;
if( module.has.dimmer() ) {
if(settings.dimmerName) {
$dimmer = $dimmable.children(selector.dimmer).filter('.' + settings.dimmerName);
$dimmer = $dimmable.find(selector.dimmer).filter('.' + settings.dimmerName);
}
else {
$dimmer = $dimmable.children(selector.dimmer);
$dimmer = $dimmable.find(selector.dimmer);
}
}
else {
@ -81,28 +82,8 @@ $.fn.dimmer = function(parameters) {
initialize: function() {
module.debug('Initializing dimmer', settings);
if(settings.on == 'hover') {
$dimmable
.on('mouseenter' + eventNamespace, module.show)
.on('mouseleave' + eventNamespace, module.hide)
;
}
else if(settings.on == 'click') {
$dimmable
.on(clickEvent + eventNamespace, module.toggle)
;
}
if( module.is.page() ) {
module.debug('Setting as a page dimmer', $dimmable);
module.set.pageDimmer();
}
if( module.is.closable() ) {
module.verbose('Adding dimmer close event', $dimmer);
$dimmer
.on(clickEvent + eventNamespace, module.event.click)
;
}
module.bind.events();
module.set.dimmable();
module.instantiate();
},
@ -117,15 +98,46 @@ $.fn.dimmer = function(parameters) {
destroy: function() {
module.verbose('Destroying previous module', $dimmer);
$module
.removeData(moduleNamespace)
;
module.unbind.events();
module.remove.variation();
$dimmable
.off(eventNamespace)
;
$dimmer
.off(eventNamespace)
;
},
bind: {
events: function() {
if(settings.on == 'hover') {
$dimmable
.on('mouseenter' + eventNamespace, module.show)
.on('mouseleave' + eventNamespace, module.hide)
;
}
else if(settings.on == 'click') {
$dimmable
.on(clickEvent + eventNamespace, module.toggle)
;
}
if( module.is.page() ) {
module.debug('Setting as a page dimmer', $dimmable);
module.set.pageDimmer();
}
if( module.is.closable() ) {
module.verbose('Adding dimmer close event', $dimmer);
$dimmable
.on(clickEvent + eventNamespace, selector.dimmer, module.event.click)
;
}
}
},
unbind: {
events: function() {
$module
.removeData(moduleNamespace)
;
}
},
event: {
@ -313,10 +325,10 @@ $.fn.dimmer = function(parameters) {
has: {
dimmer: function() {
if(settings.dimmerName) {
return ($module.children(selector.dimmer).filter('.' + settings.dimmerName).length > 0);
return ($module.find(selector.dimmer).filter('.' + settings.dimmerName).length > 0);
}
else {
return ( $module.children(selector.dimmer).length > 0 );
return ( $module.find(selector.dimmer).length > 0 );
}
}
},
@ -338,10 +350,10 @@ $.fn.dimmer = function(parameters) {
return settings.closable;
},
dimmer: function() {
return $module.is(selector.dimmer);
return $module.hasClass(className.dimmer);
},
dimmable: function() {
return $module.is(selector.dimmable);
return $module.hasClass(className.dimmable);
},
dimmed: function() {
return $dimmable.hasClass(className.dimmed);
@ -369,11 +381,11 @@ $.fn.dimmer = function(parameters) {
set: {
opacity: function(opacity) {
var
opacity = settings.opacity || opacity,
color = $dimmer.css('background-color'),
colorArray = color.split(','),
isRGBA = (colorArray && colorArray.length == 4)
;
opacity = settings.opacity || opacity;
if(isRGBA) {
colorArray[3] = opacity + ')';
color = colorArray.join(',');
@ -398,6 +410,12 @@ $.fn.dimmer = function(parameters) {
},
disabled: function() {
$dimmer.addClass(className.disabled);
},
variation: function(variation) {
variation = variation || settings.variation;
if(variation) {
$dimmer.addClass(variation);
}
}
},
@ -412,6 +430,12 @@ $.fn.dimmer = function(parameters) {
},
disabled: function() {
$dimmer.removeClass(className.disabled);
},
variation: function(variation) {
variation = variation || settings.variation;
if(variation) {
$dimmer.removeClass(variation);
}
}
},
@ -484,7 +508,7 @@ $.fn.dimmer = function(parameters) {
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 100);
module.performance.timer = setTimeout(module.performance.display, 500);
},
display: function() {
var
@ -603,7 +627,7 @@ $.fn.dimmer.settings = {
namespace : 'dimmer',
debug : false,
verbose : true,
verbose : false,
performance : true,
// name to distinguish between multiple dimmers in context
@ -641,9 +665,20 @@ $.fn.dimmer.settings = {
method : 'The method you called is not defined.'
},
className : {
active : 'active',
animating : 'animating',
dimmable : 'dimmable',
dimmed : 'dimmed',
dimmer : 'dimmer',
disabled : 'disabled',
hide : 'hide',
pageDimmer : 'page',
show : 'show'
},
selector: {
dimmable : '.dimmable',
dimmer : '.ui.dimmer',
dimmer : '> .ui.dimmer',
content : '.ui.dimmer > .content, .ui.dimmer > .content > .center'
},
@ -651,17 +686,6 @@ $.fn.dimmer.settings = {
dimmer: function() {
return $('<div />').attr('class', 'ui dimmer');
}
},
className : {
active : 'active',
animating : 'animating',
dimmable : 'dimmable',
dimmed : 'dimmed',
disabled : 'disabled',
hide : 'hide',
pageDimmer : 'page',
show : 'show'
}
};

View File

@ -1,10 +1,10 @@
/*!
* # Semantic UI 1.12.3 - Dimmer
* # Semantic UI 2.1.3 - Dimmer
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2014 Contributors
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/.dimmable{position:relative}.ui.dimmer{display:none;position:absolute;top:0!important;left:0!important;width:100%;height:100%;text-align:center;vertical-align:middle;background:rgba(0,0,0,.85);opacity:0;line-height:1;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-transition:background-color .5s linear;transition:background-color .5s linear;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;will-change:opacity;z-index:1000}.ui.dimmer>.content{width:100%;height:100%;display:table;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}.ui.dimmer>.content>div{display:table-cell;vertical-align:middle;color:#fff}.ui.segment>.ui.dimmer{border-radius:inherit!important}.animating.dimmable:not(body),.dimmed.dimmable:not(body){overflow:hidden}.dimmed.dimmable>.ui.animating.dimmer,.dimmed.dimmable>.ui.visible.dimmer,.ui.active.dimmer{display:block;opacity:1}.ui.disabled.dimmer{width:0!important;height:0!important}.ui.page.dimmer{position:fixed;-webkit-transform-style:'';transform-style:'';-webkit-perspective:2000px;perspective:2000px;-webkit-transform-origin:center center;-ms-transform-origin:center center;transform-origin:center center}body.animating.in.dimmable,body.dimmed.dimmable{overflow:hidden}body.dimmable>.dimmer{position:fixed}.ui.dimmer>.top.aligned.content>*{vertical-align:top}.ui.dimmer>.bottom.aligned.content>*{vertical-align:bottom}.ui.inverted.dimmer{background:rgba(255,255,255,.85)}.ui.inverted.dimmer>.content>*{color:#fff}.ui.simple.dimmer{display:block;overflow:hidden;opacity:1;width:0;height:0;z-index:-100;background-color:transparent}.dimmed.dimmable>.ui.simple.dimmer{overflow:visible;opacity:1;width:100%;height:100%;background:rgba(0,0,0,.85);z-index:1}.ui.simple.inverted.dimmer{background:rgba(255,255,255,0)}.dimmed.dimmable>.ui.simple.inverted.dimmer{background:rgba(255,255,255,.85)}
*/.dimmable{position:relative}.ui.dimmer{display:none;position:absolute;top:0!important;left:0!important;width:100%;height:100%;text-align:center;vertical-align:middle;background-color:rgba(0,0,0,.85);opacity:0;line-height:1;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-transition:background-color .5s linear;transition:background-color .5s linear;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;will-change:opacity;z-index:1000}.ui.dimmer>.content{width:100%;height:100%;display:table;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}.ui.dimmer>.content>*{display:table-cell;vertical-align:middle;color:#fff}.ui.segment>.ui.dimmer{border-radius:inherit!important}.animating.dimmable:not(body),.dimmed.dimmable:not(body){overflow:hidden}.dimmed.dimmable>.ui.animating.dimmer,.dimmed.dimmable>.ui.visible.dimmer,.ui.active.dimmer{display:block;opacity:1}.ui.disabled.dimmer{width:0!important;height:0!important}.ui.page.dimmer{position:fixed;-webkit-transform-style:'';transform-style:'';-webkit-perspective:125pc;perspective:125pc;-webkit-transform-origin:center center;-ms-transform-origin:center center;transform-origin:center center}body.animating.in.dimmable,body.dimmed.dimmable{overflow:hidden}body.dimmable>.dimmer{position:fixed}.blurring.dimmable>:not(.dimmer){-webkit-filter:blur(0) grayscale(0);filter:blur(0) grayscale(0);-webkit-transition:.8s -webkit-filter ease,.8s filter ease;transition:.8s filter ease}.blurring.dimmed.dimmable>:not(.dimmer){-webkit-filter:blur(5px) grayscale(.7);filter:blur(5px) grayscale(.7)}.blurring.dimmable>.dimmer{background-color:rgba(0,0,0,.6)}.blurring.dimmable>.inverted.dimmer{background-color:rgba(255,255,255,.6)}.ui.dimmer>.top.aligned.content>*{vertical-align:top}.ui.dimmer>.bottom.aligned.content>*{vertical-align:bottom}.ui.inverted.dimmer{background-color:rgba(255,255,255,.85)}.ui.inverted.dimmer>.content>*{color:#fff}.ui.simple.dimmer{display:block;overflow:hidden;opacity:1;width:0;height:0%;z-index:-100;background-color:transparent}.dimmed.dimmable>.ui.simple.dimmer{overflow:visible;opacity:1;width:100%;height:100%;background-color:rgba(0,0,0,.85);z-index:1}.ui.simple.inverted.dimmer{background-color:rgba(255,255,255,0)}.dimmed.dimmable>.ui.simple.inverted.dimmer{background-color:rgba(255,255,255,.85)}

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,9 @@
/*!
* # Semantic UI 1.12.3 - Divider
* # Semantic UI 2.1.3 - Divider
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2014 Contributors
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
@ -34,16 +34,19 @@
---------------*/
.ui.divider:not(.vertical):not(.horizontal) {
border-top: 1px solid rgba(0, 0, 0, 0.1);
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
border-top: 1px solid rgba(34, 36, 38, 0.15);
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
/*--------------
Coupling
---------------*/
.ui.grid > .ui.divider {
font-size: 1rem;
/* Allow divider between each column row */
.ui.grid > .column + .divider,
.ui.grid > .row > .column + .divider {
left: auto;
}
/*--------------
@ -51,7 +54,8 @@
---------------*/
.ui.horizontal.divider {
position: relative;
display: table;
white-space: nowrap;
height: auto;
margin: '';
overflow: hidden;
@ -60,21 +64,18 @@
}
.ui.horizontal.divider:before,
.ui.horizontal.divider:after {
position: absolute;
content: '';
z-index: 3;
width: 50%;
display: table-cell;
position: relative;
top: 50%;
height: 0px;
border-top: 1px solid rgba(0, 0, 0, 0.1);
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
width: 50%;
background-repeat: no-repeat;
}
.ui.horizontal.divider:before {
margin-left: -webkit-calc(-50% - 1em );
margin-left: calc(-50% - 1em );
background-position: right 1em top 50%;
}
.ui.horizontal.divider:after {
margin-left: 1em;
background-position: left 1em top 50%;
}
/*--------------
@ -102,10 +103,9 @@
left: 50%;
content: '';
z-index: 3;
border-left: 1px solid rgba(0, 0, 0, 0.1);
border-right: 1px solid rgba(255, 255, 255, 0.2);
border-left: 1px solid rgba(34, 36, 38, 0.15);
border-right: 1px solid rgba(255, 255, 255, 0.1);
width: 0%;
height: -webkit-calc(100% - 1rem );
height: calc(100% - 1rem );
}
.ui.vertical.divider:before {
@ -120,35 +120,42 @@
@media only screen and (max-width: 767px) {
.ui.stackable.grid .ui.vertical.divider,
.ui.grid .stackable.row .ui.vertical.divider {
position: relative;
margin: 1rem 0rem;
left: 50%;
display: table;
white-space: nowrap;
height: auto;
margin: '';
overflow: hidden;
line-height: 1;
text-align: center;
position: static;
top: 0;
left: 0;
-webkit-transform: none;
-ms-transform: none;
transform: none;
}
.ui.stackable.grid .ui.vertical.divider:before,
.ui.grid .stackable.row .ui.vertical.divider:before,
.ui.stackable.grid .ui.vertical.divider:after,
.ui.grid .stackable.row .ui.vertical.divider:after {
position: absolute;
left: auto;
position: static;
left: 0;
border-left: none;
border-right: none;
content: '';
z-index: 3;
width: 50%;
display: table-cell;
position: relative;
top: 50%;
height: 0px;
border-top: 1px solid rgba(0, 0, 0, 0.1);
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
width: 50%;
background-repeat: no-repeat;
}
.ui.stackable.grid .ui.vertical.divider:before,
.ui.grid .stackable.row .ui.vertical.divider:before {
margin-left: -51%;
background-position: right 1em top 50%;
}
.ui.stackable.grid .ui.vertical.divider:after,
.ui.grid .stackable.row .ui.vertical.divider:after {
margin-left: 1em;
background-position: left 1em top 50%;
}
}
@ -176,6 +183,10 @@
.ui.hidden.divider {
border-color: transparent !important;
}
.ui.hidden.divider:before,
.ui.hidden.divider:after {
display: none;
}
/*--------------
Inverted
@ -189,9 +200,9 @@
.ui.divider.inverted,
.ui.divider.inverted:after,
.ui.divider.inverted:before {
border-top-color: rgba(0, 0, 0, 0.15) !important;
border-top-color: rgba(34, 36, 38, 0.15) !important;
border-left-color: rgba(34, 36, 38, 0.15) !important;
border-bottom-color: rgba(255, 255, 255, 0.15) !important;
border-left-color: rgba(0, 0, 0, 0.15) !important;
border-right-color: rgba(255, 255, 255, 0.15) !important;
}
@ -233,6 +244,18 @@
Theme Overrides
*******************************/
.ui.horizontal.divider:before,
.ui.horizontal.divider:after {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABaAAAAACCAYAAACuTHuKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo1OThBRDY4OUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo1OThBRDY4QUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjU5OEFENjg3Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjU5OEFENjg4Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+VU513gAAADVJREFUeNrs0DENACAQBDBIWLGBJQby/mUcJn5sJXQmOQMAAAAAAJqt+2prAAAAAACg2xdgANk6BEVuJgyMAAAAAElFTkSuQmCC');
}
@media only screen and (max-width: 767px) {
.ui.stackable.grid .ui.vertical.divider:before,
.ui.grid .stackable.row .ui.vertical.divider:before,
.ui.stackable.grid .ui.vertical.divider:after,
.ui.grid .stackable.row .ui.vertical.divider:after {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABaAAAAACCAYAAACuTHuKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo1OThBRDY4OUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo1OThBRDY4QUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjU5OEFENjg3Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjU5OEFENjg4Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+VU513gAAADVJREFUeNrs0DENACAQBDBIWLGBJQby/mUcJn5sJXQmOQMAAAAAAJqt+2prAAAAAACg2xdgANk6BEVuJgyMAAAAAElFTkSuQmCC');
}
}
/*******************************

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,168 @@
/*!
* # Semantic UI 2.1.3 - Video
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/
/*******************************
Types
*******************************/
.ui.embed {
position: relative;
max-width: 100%;
height: 0px;
overflow: hidden;
background: #dcddde;
padding-bottom: 56.25%;
}
/*-----------------
Embedded Content
------------------*/
.ui.embed iframe,
.ui.embed embed,
.ui.embed object {
position: absolute;
border: none;
width: 100%;
height: 100%;
top: 0px;
left: 0px;
margin: 0em;
padding: 0em;
}
/*-----------------
Embed
------------------*/
.ui.embed > .embed {
display: none;
}
/*--------------
Placeholder
---------------*/
.ui.embed > .placeholder {
position: absolute;
cursor: pointer;
top: 0px;
left: 0px;
display: block;
width: 100%;
height: 100%;
background-color: radial-gradient(transparent 45%, rgba(0, 0, 0, 0.3));
}
/*--------------
Icon
---------------*/
.ui.embed > .icon {
cursor: pointer;
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
z-index: 2;
}
.ui.embed > .icon:after {
position: absolute;
top: 0%;
left: 0%;
width: 100%;
height: 100%;
z-index: 3;
content: '';
background: -webkit-radial-gradient(transparent 45%, rgba(0, 0, 0, 0.3));
background: radial-gradient(transparent 45%, rgba(0, 0, 0, 0.3));
opacity: 0.5;
-webkit-transition: opacity 0.5s ease;
transition: opacity 0.5s ease;
}
.ui.embed > .icon:before {
position: absolute;
top: 50%;
left: 50%;
z-index: 4;
-webkit-transform: translateX(-50%) translateY(-50%);
-ms-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
color: #ffffff;
font-size: 6rem;
text-shadow: 0px 2px 10px rgba(34, 36, 38, 0.2);
-webkit-transition: opacity 0.5s ease, color 0.5s ease;
transition: opacity 0.5s ease, color 0.5s ease;
z-index: 10;
}
/*******************************
States
*******************************/
/*--------------
Hover
---------------*/
.ui.embed .icon:hover:after {
background: -webkit-radial-gradient(transparent 45%, rgba(0, 0, 0, 0.3));
background: radial-gradient(transparent 45%, rgba(0, 0, 0, 0.3));
opacity: 1;
}
.ui.embed .icon:hover:before {
color: #ffffff;
}
/*--------------
Active
---------------*/
.ui.active.embed > .icon,
.ui.active.embed > .placeholder {
display: none;
}
.ui.active.embed > .embed {
display: block;
}
/*******************************
Video Overrides
*******************************/
/*******************************
Site Overrides
*******************************/
/*******************************
Variations
*******************************/
.ui.square.embed {
padding-bottom: 100%;
}
.ui[class*="4:3"].embed {
padding-bottom: 75%;
}
.ui[class*="16:9"].embed {
padding-bottom: 56.25%;
}
.ui[class*="21:9"].embed {
padding-bottom: 42.85714286%;
}

View File

@ -0,0 +1,659 @@
/*!
* # Semantic UI 2.1.3 - Video
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/
;(function ($, window, document, undefined) {
"use strict";
$.fn.embed = function(parameters) {
var
$allModules = $(this),
moduleSelector = $allModules.selector || '',
time = new Date().getTime(),
performance = [],
query = arguments[0],
methodInvoked = (typeof query == 'string'),
queryArguments = [].slice.call(arguments, 1),
returnedValue
;
$allModules
.each(function() {
var
settings = ( $.isPlainObject(parameters) )
? $.extend(true, {}, $.fn.embed.settings, parameters)
: $.extend({}, $.fn.embed.settings),
selector = settings.selector,
className = settings.className,
sources = settings.sources,
error = settings.error,
metadata = settings.metadata,
namespace = settings.namespace,
templates = settings.templates,
eventNamespace = '.' + namespace,
moduleNamespace = 'module-' + namespace,
$window = $(window),
$module = $(this),
$placeholder = $module.find(selector.placeholder),
$icon = $module.find(selector.icon),
$embed = $module.find(selector.embed),
element = this,
instance = $module.data(moduleNamespace),
module
;
module = {
initialize: function() {
module.debug('Initializing embed');
module.determine.autoplay();
module.create();
module.bind.events();
module.instantiate();
},
instantiate: function() {
module.verbose('Storing instance of module', module);
instance = module;
$module
.data(moduleNamespace, module)
;
},
destroy: function() {
module.verbose('Destroying previous instance of embed');
module.reset();
$module
.removeData(moduleNamespace)
.off(eventNamespace)
;
},
refresh: function() {
module.verbose('Refreshing selector cache');
$placeholder = $module.find(selector.placeholder);
$icon = $module.find(selector.icon);
$embed = $module.find(selector.embed);
},
bind: {
events: function() {
if( module.has.placeholder() ) {
module.debug('Adding placeholder events');
$module
.on('click' + eventNamespace, selector.placeholder, module.createAndShow)
.on('click' + eventNamespace, selector.icon, module.createAndShow)
;
}
}
},
create: function() {
var
placeholder = module.get.placeholder()
;
if(placeholder) {
module.createPlaceholder();
}
else {
module.createAndShow();
}
},
createPlaceholder: function(placeholder) {
var
icon = module.get.icon(),
url = module.get.url(),
embed = module.generate.embed(url)
;
placeholder = placeholder || module.get.placeholder();
$module.html( templates.placeholder(placeholder, icon) );
module.debug('Creating placeholder for embed', placeholder, icon);
},
createEmbed: function(url) {
module.refresh();
url = url || module.get.url();
$embed = $('<div/>')
.addClass(className.embed)
.html( module.generate.embed(url) )
.appendTo($module)
;
settings.onCreate.call(element, url);
module.debug('Creating embed object', $embed);
},
createAndShow: function() {
module.createEmbed();
module.show();
},
// sets new embed
change: function(source, id, url) {
module.debug('Changing video to ', source, id, url);
$module
.data(metadata.source, source)
.data(metadata.id, id)
.data(metadata.url, url)
;
module.create();
},
// clears embed
reset: function() {
module.debug('Clearing embed and showing placeholder');
module.remove.active();
module.remove.embed();
module.showPlaceholder();
settings.onReset.call(element);
},
// shows current embed
show: function() {
module.debug('Showing embed');
module.set.active();
settings.onDisplay.call(element);
},
hide: function() {
module.debug('Hiding embed');
module.showPlaceholder();
},
showPlaceholder: function() {
module.debug('Showing placeholder image');
module.remove.active();
settings.onPlaceholderDisplay.call(element);
},
get: {
id: function() {
return settings.id || $module.data(metadata.id);
},
placeholder: function() {
return settings.placeholder || $module.data(metadata.placeholder);
},
icon: function() {
return (settings.icon)
? settings.icon
: ($module.data(metadata.icon) !== undefined)
? $module.data(metadata.icon)
: module.determine.icon()
;
},
source: function(url) {
return (settings.source)
? settings.source
: ($module.data(metadata.source) !== undefined)
? $module.data(metadata.source)
: module.determine.source()
;
},
type: function() {
var source = module.get.source();
return (sources[source] !== undefined)
? sources[source].type
: false
;
},
url: function() {
return (settings.url)
? settings.url
: ($module.data(metadata.url) !== undefined)
? $module.data(metadata.url)
: module.determine.url()
;
}
},
determine: {
autoplay: function() {
if(module.should.autoplay()) {
settings.autoplay = true;
}
},
source: function(url) {
var
matchedSource = false
;
url = url || module.get.url();
if(url) {
$.each(sources, function(name, source) {
if(url.search(source.domain) !== -1) {
matchedSource = name;
return false;
}
});
}
return matchedSource;
},
icon: function() {
var
source = module.get.source()
;
return (sources[source] !== undefined)
? sources[source].icon
: false
;
},
url: function() {
var
id = settings.id || $module.data(metadata.id),
source = settings.source || $module.data(metadata.source),
url
;
url = (sources[source] !== undefined)
? sources[source].url.replace('{id}', id)
: false
;
if(url) {
$module.data(metadata.url, url);
}
return url;
}
},
set: {
active: function() {
$module.addClass(className.active);
}
},
remove: {
active: function() {
$module.removeClass(className.active);
},
embed: function() {
$embed.empty();
}
},
encode: {
parameters: function(parameters) {
var
urlString = [],
index
;
for (index in parameters) {
urlString.push( encodeURIComponent(index) + '=' + encodeURIComponent( parameters[index] ) );
}
return urlString.join('&amp;');
}
},
generate: {
embed: function(url) {
module.debug('Generating embed html');
var
source = module.get.source(),
html,
parameters
;
url = module.get.url(url);
if(url) {
parameters = module.generate.parameters(source);
html = templates.iframe(url, parameters);
}
else {
module.error(error.noURL, $module);
}
return html;
},
parameters: function(source, extraParameters) {
var
parameters = (sources[source] && sources[source].parameters !== undefined)
? sources[source].parameters(settings)
: {}
;
extraParameters = extraParameters || settings.parameters;
if(extraParameters) {
parameters = $.extend({}, parameters, extraParameters);
}
parameters = settings.onEmbed(parameters);
return module.encode.parameters(parameters);
}
},
has: {
placeholder: function() {
return settings.placeholder || $module.data(metadata.placeholder);
}
},
should: {
autoplay: function() {
return (settings.autoplay === 'auto')
? (settings.placeholder || $module.data(metadata.placeholder) !== undefined)
: settings.autoplay
;
}
},
is: {
video: function() {
return module.get.type() == 'video';
}
},
setting: function(name, value) {
module.debug('Changing setting', name, value);
if( $.isPlainObject(name) ) {
$.extend(true, settings, name);
}
else if(value !== undefined) {
settings[name] = value;
}
else {
return settings[name];
}
},
internal: function(name, value) {
if( $.isPlainObject(name) ) {
$.extend(true, module, name);
}
else if(value !== undefined) {
module[name] = value;
}
else {
return module[name];
}
},
debug: function() {
if(settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.debug.apply(console, arguments);
}
}
},
verbose: function() {
if(settings.verbose && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.verbose.apply(console, arguments);
}
}
},
error: function() {
module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
module.error.apply(console, arguments);
},
performance: {
log: function(message) {
var
currentTime,
executionTime,
previousTime
;
if(settings.performance) {
currentTime = new Date().getTime();
previousTime = time || currentTime;
executionTime = currentTime - previousTime;
time = currentTime;
performance.push({
'Name' : message[0],
'Arguments' : [].slice.call(message, 1) || '',
'Element' : element,
'Execution Time' : executionTime
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 500);
},
display: function() {
var
title = settings.name + ':',
totalTime = 0
;
time = false;
clearTimeout(module.performance.timer);
$.each(performance, function(index, data) {
totalTime += data['Execution Time'];
});
title += ' ' + totalTime + 'ms';
if(moduleSelector) {
title += ' \'' + moduleSelector + '\'';
}
if($allModules.length > 1) {
title += ' ' + '(' + $allModules.length + ')';
}
if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
console.groupCollapsed(title);
if(console.table) {
console.table(performance);
}
else {
$.each(performance, function(index, data) {
console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
});
}
console.groupEnd();
}
performance = [];
}
},
invoke: function(query, passedArguments, context) {
var
object = instance,
maxDepth,
found,
response
;
passedArguments = passedArguments || queryArguments;
context = element || context;
if(typeof query == 'string' && object !== undefined) {
query = query.split(/[\. ]/);
maxDepth = query.length - 1;
$.each(query, function(depth, value) {
var camelCaseValue = (depth != maxDepth)
? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
: query
;
if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
object = object[camelCaseValue];
}
else if( object[camelCaseValue] !== undefined ) {
found = object[camelCaseValue];
return false;
}
else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
object = object[value];
}
else if( object[value] !== undefined ) {
found = object[value];
return false;
}
else {
module.error(error.method, query);
return false;
}
});
}
if ( $.isFunction( found ) ) {
response = found.apply(context, passedArguments);
}
else if(found !== undefined) {
response = found;
}
if($.isArray(returnedValue)) {
returnedValue.push(response);
}
else if(returnedValue !== undefined) {
returnedValue = [returnedValue, response];
}
else if(response !== undefined) {
returnedValue = response;
}
return found;
}
};
if(methodInvoked) {
if(instance === undefined) {
module.initialize();
}
module.invoke(query);
}
else {
if(instance !== undefined) {
instance.invoke('destroy');
}
module.initialize();
}
})
;
return (returnedValue !== undefined)
? returnedValue
: this
;
};
$.fn.embed.settings = {
name : 'Embed',
namespace : 'embed',
debug : false,
verbose : false,
performance : true,
icon : false,
source : false,
url : false,
id : false,
// standard video settings
autoplay : 'auto',
color : '#444444',
hd : true,
brandedUI : false,
// additional parameters to include with the embed
parameters: false,
onDisplay : function() {},
onPlaceholderDisplay : function() {},
onReset : function() {},
onCreate : function(url) {},
onEmbed : function(parameters) {
return parameters;
},
metadata : {
id : 'id',
icon : 'icon',
placeholder : 'placeholder',
source : 'source',
url : 'url'
},
error : {
noURL : 'No URL specified',
method : 'The method you called is not defined'
},
className : {
active : 'active',
embed : 'embed'
},
selector : {
embed : '.embed',
placeholder : '.placeholder',
icon : '.icon'
},
sources: {
youtube: {
name : 'youtube',
type : 'video',
icon : 'video play',
domain : 'youtube.com',
url : '//www.youtube.com/embed/{id}',
parameters: function(settings) {
return {
autohide : !settings.brandedUI,
autoplay : settings.autoplay,
color : settings.colors || undefined,
hq : settings.hd,
jsapi : settings.api,
modestbranding : !settings.brandedUI
};
}
},
vimeo: {
name : 'vimeo',
type : 'video',
icon : 'video play',
domain : 'vimeo.com',
url : '//player.vimeo.com/video/{id}',
parameters: function(settings) {
return {
api : settings.api,
autoplay : settings.autoplay,
byline : settings.brandedUI,
color : settings.colors || undefined,
portrait : settings.brandedUI,
title : settings.brandedUI
};
}
}
},
templates: {
iframe : function(url, parameters) {
return ''
+ '<iframe src="' + url + '?' + parameters + '"'
+ ' width="100%" height="100%"'
+ ' frameborder="0" scrolling="no" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>'
;
},
placeholder : function(image, icon) {
var
html = ''
;
if(icon) {
html += '<i class="' + icon + ' icon"></i>';
}
if(image) {
html += '<img class="placeholder" src="' + image + '">';
}
return html;
}
},
// NOT YET IMPLEMENTED
api : true,
onPause : function() {},
onPlay : function() {},
onStop : function() {}
};
})( jQuery, window , document );

View File

@ -0,0 +1,10 @@
/*!
* # Semantic UI 2.1.3 - Video
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/.ui.embed{position:relative;max-width:100%;height:0;overflow:hidden;background:#dcddde;padding-bottom:56.25%}.ui.embed embed,.ui.embed iframe,.ui.embed object{position:absolute;border:none;width:100%;height:100%;top:0;left:0;margin:0;padding:0}.ui.embed>.embed{display:none}.ui.embed>.placeholder{position:absolute;cursor:pointer;top:0;left:0;display:block;width:100%;height:100%;background-color:radial-gradient(transparent 45%,rgba(0,0,0,.3))}.ui.embed>.icon{cursor:pointer;position:absolute;top:0;left:0;width:100%;height:100%;z-index:2}.ui.embed>.icon:after{position:absolute;top:0;left:0;width:100%;height:100%;z-index:3;content:'';background:-webkit-radial-gradient(transparent 45%,rgba(0,0,0,.3));background:radial-gradient(transparent 45%,rgba(0,0,0,.3));opacity:.5;-webkit-transition:opacity .5s ease;transition:opacity .5s ease}.ui.embed>.icon:before{position:absolute;top:50%;left:50%;-webkit-transform:translateX(-50%) translateY(-50%);-ms-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);color:#fff;font-size:6rem;text-shadow:0 2px 10px rgba(34,36,38,.2);-webkit-transition:opacity .5s ease,color .5s ease;transition:opacity .5s ease,color .5s ease;z-index:10}.ui.embed .icon:hover:after{background:-webkit-radial-gradient(transparent 45%,rgba(0,0,0,.3));background:radial-gradient(transparent 45%,rgba(0,0,0,.3));opacity:1}.ui.embed .icon:hover:before{color:#fff}.ui.active.embed>.icon,.ui.active.embed>.placeholder{display:none}.ui.active.embed>.embed{display:block}.ui.square.embed{padding-bottom:100%}.ui[class*="4:3"].embed{padding-bottom:75%}.ui[class*="16:9"].embed{padding-bottom:56.25%}.ui[class*="21:9"].embed{padding-bottom:42.85714286%}

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,9 @@
/*!
* # Semantic UI 1.12.3 - Feed
* # Semantic UI 2.1.3 - Feed
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2014 Contributorss
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
@ -21,7 +21,7 @@
margin-top: 0em;
}
.ui.feed:last-child {
margin-top: 0em;
margin-bottom: 0em;
}
@ -32,9 +32,17 @@
/* Event */
.ui.feed > .event {
display: table;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
width: 100%;
padding: 0.5rem 0em;
padding: 0.21428571rem 0em;
margin: 0em;
background: none;
border-top: none;
@ -49,10 +57,16 @@
/* Event Label */
.ui.feed > .event > .label {
display: table-cell;
display: block;
-webkit-box-flex: 0;
-webkit-flex: 0 0 auto;
-ms-flex: 0 0 auto;
flex: 0 0 auto;
width: 2.5em;
height: 2.5em;
vertical-align: top;
height: auto;
-webkit-align-self: stretch;
-ms-flex-item-align: stretch;
align-self: stretch;
text-align: left;
}
.ui.feed > .event > .label .icon {
@ -71,13 +85,24 @@
border-radius: 500rem;
}
.ui.feed > .event > .label + .content {
padding: 0.5em 0em 0.5em 1.25em;
margin: 0.5em 0em 0.35714286em 1.14285714em;
}
/*--------------
Content
---------------*/
/* Content */
.ui.feed > .event > .content {
display: table-cell;
vertical-align: top;
display: block;
-webkit-box-flex: 1;
-webkit-flex: 1 1 auto;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
-webkit-align-self: stretch;
-ms-flex-item-align: stretch;
align-self: stretch;
text-align: left;
word-wrap: break-word;
}
@ -111,14 +136,14 @@
margin: 0em;
font-size: 1em;
font-weight: bold;
color: rgba(0, 0, 0, 0.8);
color: rgba(0, 0, 0, 0.87);
}
/* Summary Image */
.ui.feed > .event > .content .summary img {
display: inline-block;
width: auto;
height: 2em;
height: 10em;
margin: -0.25em 0.25em 0em 0em;
border-radius: 0.25em;
vertical-align: middle;
@ -137,7 +162,7 @@
.ui.feed > .event > .content .user img {
margin: -0.25em 0.25em 0em 0em;
width: auto;
height: 2em;
height: 10em;
vertical-align: middle;
}
@ -151,7 +176,7 @@
display: inline-block;
float: none;
font-weight: normal;
font-size: 0.875em;
font-size: 0.85714286em;
font-style: normal;
margin: 0em 0em 0em 0.5em;
padding: 0em;
@ -166,7 +191,7 @@
margin: 0.5em 0em 0em;
background: none;
padding: 0em;
color: rgba(0, 0, 0, 0.8);
color: rgba(0, 0, 0, 0.87);
}
/* Images */
@ -178,11 +203,11 @@
/* Text */
.ui.feed > .event > .content .extra.text {
padding: 0.5em 1em;
border-left: 3px solid rgba(0, 0, 0, 0.2);
padding: 0em;
border-left: none;
font-size: 1em;
max-width: 500px;
line-height: 1.33;
line-height: 1.4285em;
}
/*--------------
@ -191,7 +216,7 @@
.ui.feed > .event > .content .meta {
display: inline-block;
font-size: 0.875em;
font-size: 0.85714286em;
margin: 0.5em 0em 0em;
background: none;
border: none;
@ -239,13 +264,13 @@
cursor: pointer;
opacity: 1;
color: rgba(0, 0, 0, 0.5);
-webkit-transition: color 0.2s ease;
transition: color 0.2s ease;
-webkit-transition: color 0.1s ease;
transition: color 0.1s ease;
}
.ui.feed > .event > .content .meta a:hover,
.ui.feed > .event > .content .meta a:hover .icon,
.ui.feed > .event > .content .meta > .icon:hover {
color: rgba(0, 0, 0, 0.8);
color: rgba(0, 0, 0, 0.95);
}
@ -254,13 +279,13 @@
*******************************/
.ui.small.feed {
font-size: 0.9em;
font-size: 0.92857143rem;
}
.ui.feed {
font-size: 1em;
font-size: 1rem;
}
.ui.large.feed {
font-size: 1.1em;
font-size: 1.14285714rem;
}

View File

@ -1,10 +1,10 @@
/*!
* # Semantic UI 1.12.3 - Feed
* # Semantic UI 2.1.3 - Feed
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2014 Contributorss
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
*/.ui.feed{margin:1em 0}.ui.feed:first-child,.ui.feed:last-child{margin-top:0}.ui.feed>.event{display:table;width:100%;padding:.5rem 0;margin:0;background:0 0;border-top:none}.ui.feed>.event:first-child{border-top:0;padding-top:0}.ui.feed>.event:last-child{padding-bottom:0}.ui.feed>.event>.label{display:table-cell;width:2.5em;height:2.5em;vertical-align:top;text-align:left}.ui.feed>.event>.label .icon{opacity:1;font-size:1.5em;width:100%;padding:.25em;background:0 0;border:none;border-radius:none;color:rgba(0,0,0,.6)}.ui.feed>.event>.label img{width:100%;height:auto;border-radius:500rem}.ui.feed>.event>.label+.content{padding:.5em 0 .5em 1.25em}.ui.feed>.event>.content{display:table-cell;vertical-align:top;text-align:left;word-wrap:break-word}.ui.feed>.event:last-child>.content{padding-bottom:0}.ui.feed>.event>.content a{cursor:pointer}.ui.feed>.event>.content .date{margin:-.5rem 0 0;padding:0;font-weight:400;font-size:1em;font-style:normal;color:rgba(0,0,0,.4)}.ui.feed>.event>.content .summary{margin:0;font-size:1em;font-weight:700;color:rgba(0,0,0,.8)}.ui.feed>.event>.content .summary img{display:inline-block;width:auto;height:2em;margin:-.25em .25em 0 0;border-radius:.25em;vertical-align:middle}.ui.feed>.event>.content .user{display:inline-block;font-weight:700;margin-right:0;vertical-align:baseline}.ui.feed>.event>.content .user img{margin:-.25em .25em 0 0;width:auto;height:2em;vertical-align:middle}.ui.feed>.event>.content .summary>.date{display:inline-block;float:none;font-weight:400;font-size:.875em;font-style:normal;margin:0 0 0 .5em;padding:0;color:rgba(0,0,0,.4)}.ui.feed>.event>.content .extra{margin:.5em 0 0;background:0 0;padding:0;color:rgba(0,0,0,.8)}.ui.feed>.event>.content .extra.images img{display:inline-block;margin:0 .25em 0 0;width:6em}.ui.feed>.event>.content .extra.text{padding:.5em 1em;border-left:3px solid rgba(0,0,0,.2);font-size:1em;max-width:500px;line-height:1.33}.ui.feed>.event>.content .meta{display:inline-block;font-size:.875em;margin:.5em 0 0;background:0 0;border:none;border-radius:0;box-shadow:none;padding:0;color:rgba(0,0,0,.6)}.ui.feed>.event>.content .meta>*{position:relative;margin-left:.75em}.ui.feed>.event>.content .meta>:after{content:'';color:rgba(0,0,0,.2);top:0;left:-1em;opacity:1;position:absolute;vertical-align:top}.ui.feed>.event>.content .meta .like{color:'';-webkit-transition:.2s color ease;transition:.2s color ease}.ui.feed>.event>.content .meta .like:hover .icon{color:#ff2733}.ui.feed>.event>.content .meta .active.like .icon{color:#ef404a}.ui.feed>.event>.content .meta>:first-child{margin-left:0}.ui.feed>.event>.content .meta>:first-child::after{display:none}.ui.feed>.event>.content .meta a,.ui.feed>.event>.content .meta>.icon{cursor:pointer;opacity:1;color:rgba(0,0,0,.5);-webkit-transition:color .2s ease;transition:color .2s ease}.ui.feed>.event>.content .meta a:hover,.ui.feed>.event>.content .meta a:hover .icon,.ui.feed>.event>.content .meta>.icon:hover{color:rgba(0,0,0,.8)}.ui.small.feed{font-size:.9em}.ui.feed{font-size:1em}.ui.large.feed{font-size:1.1em}
*/.ui.feed{margin:1em 0}.ui.feed:first-child{margin-top:0}.ui.feed:last-child{margin-bottom:0}.ui.feed>.event{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;width:100%;padding:.21428571rem 0;margin:0;background:0 0;border-top:none}.ui.feed>.event:first-child{border-top:0;padding-top:0}.ui.feed>.event:last-child{padding-bottom:0}.ui.feed>.event>.label{display:block;-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;width:2.5em;height:auto;-webkit-align-self:stretch;-ms-flex-item-align:stretch;align-self:stretch;text-align:left}.ui.feed>.event>.label .icon{opacity:1;font-size:1.5em;width:100%;padding:.25em;background:0 0;border:none;border-radius:none;color:rgba(0,0,0,.6)}.ui.feed>.event>.label img{width:100%;height:auto;border-radius:500rem}.ui.feed>.event>.label+.content{margin:.5em 0 .35714286em 1.14285714em}.ui.feed>.event>.content{display:block;-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto;-webkit-align-self:stretch;-ms-flex-item-align:stretch;align-self:stretch;text-align:left;word-wrap:break-word}.ui.feed>.event:last-child>.content{padding-bottom:0}.ui.feed>.event>.content a{cursor:pointer}.ui.feed>.event>.content .date{margin:-.5rem 0 0;padding:0;font-weight:400;font-size:1em;font-style:normal;color:rgba(0,0,0,.4)}.ui.feed>.event>.content .summary{margin:0;font-size:1em;font-weight:700;color:rgba(0,0,0,.87)}.ui.feed>.event>.content .summary img{display:inline-block;width:auto;height:10em;margin:-.25em .25em 0 0;border-radius:.25em;vertical-align:middle}.ui.feed>.event>.content .user{display:inline-block;font-weight:700;margin-right:0;vertical-align:baseline}.ui.feed>.event>.content .user img{margin:-.25em .25em 0 0;width:auto;height:10em;vertical-align:middle}.ui.feed>.event>.content .summary>.date{display:inline-block;float:none;font-weight:400;font-size:.85714286em;font-style:normal;margin:0 0 0 .5em;padding:0;color:rgba(0,0,0,.4)}.ui.feed>.event>.content .extra{margin:.5em 0 0;background:0 0;padding:0;color:rgba(0,0,0,.87)}.ui.feed>.event>.content .extra.images img{display:inline-block;margin:0 .25em 0 0;width:6em}.ui.feed>.event>.content .extra.text{padding:0;border-left:none;font-size:1em;max-width:500px;line-height:1.4285em}.ui.feed>.event>.content .meta{display:inline-block;font-size:.85714286em;margin:.5em 0 0;background:0 0;border:none;border-radius:0;box-shadow:none;padding:0;color:rgba(0,0,0,.6)}.ui.feed>.event>.content .meta>*{position:relative;margin-left:.75em}.ui.feed>.event>.content .meta>:after{content:'';color:rgba(0,0,0,.2);top:0;left:-1em;opacity:1;position:absolute;vertical-align:top}.ui.feed>.event>.content .meta .like{color:'';-webkit-transition:.2s color ease;transition:.2s color ease}.ui.feed>.event>.content .meta .like:hover .icon{color:#ff2733}.ui.feed>.event>.content .meta .active.like .icon{color:#ef404a}.ui.feed>.event>.content .meta>:first-child{margin-left:0}.ui.feed>.event>.content .meta>:first-child::after{display:none}.ui.feed>.event>.content .meta a,.ui.feed>.event>.content .meta>.icon{cursor:pointer;opacity:1;color:rgba(0,0,0,.5);-webkit-transition:color .1s ease;transition:color .1s ease}.ui.feed>.event>.content .meta a:hover,.ui.feed>.event>.content .meta a:hover .icon,.ui.feed>.event>.content .meta>.icon:hover{color:rgba(0,0,0,.95)}.ui.small.feed{font-size:.92857143rem}.ui.feed{font-size:1rem}.ui.large.feed{font-size:1.14285714rem}

View File

@ -1,9 +1,9 @@
/*!
* # Semantic UI 1.12.3 - Flag
* # Semantic UI 2.1.3 - Flag
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2014 Contributors
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,9 @@
/*!
* # Semantic UI 1.12.3 - Form
* # Semantic UI 2.1.3 - Form
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2014 Contributors
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
@ -36,15 +36,18 @@
Field
---------------------*/
.ui.form .fields .field,
.ui.form .field {
clear: both;
margin: 0em 0em 1em;
}
.ui.form .fields:last-child,
.ui.form .field:last-child {
.ui.form .field:last-child,
.ui.form .fields:last-child .field {
margin-bottom: 0em;
}
.ui.form .fields .field {
clear: both;
margin: 0em 0em 1em;
}
/*--------------------
Labels
@ -52,25 +55,9 @@
.ui.form .field > label {
display: block;
margin: 0em 0em 0.2857rem 0em;
color: rgba(0, 0, 0, 0.8);
font-size: 0.9285em;
font-weight: bold;
text-transform: none;
}
.ui.form .grouped.fields > label {
margin: 0em 0em 0.2857rem 0em;
color: rgba(0, 0, 0, 0.8);
font-size: 0.9285em;
font-weight: bold;
text-transform: none;
}
.ui.form .inline.fields > label {
display: inline-block;
vertical-align: middle;
margin: 0em 1em 0em 0em;
color: rgba(0, 0, 0, 0.8);
font-size: 0.9285em;
margin: 0em 0em 0.28571429rem 0em;
color: rgba(0, 0, 0, 0.87);
font-size: 0.92857143em;
font-weight: bold;
text-transform: none;
}
@ -90,11 +77,16 @@
.ui.form input[type="tel"],
.ui.form input[type="time"],
.ui.form input[type="text"],
.ui.form input[type="url"],
.ui.form .ui.input {
.ui.form input[type="url"] {
width: 100%;
vertical-align: top;
}
/* Set max height on unusual input */
.ui.form ::-webkit-datetime-edit,
.ui.form ::-webkit-inner-spin-button {
height: 1.2142em;
}
.ui.form input:not([type]),
.ui.form input[type="date"],
.ui.form input[type="datetime-local"],
@ -112,36 +104,39 @@
-webkit-appearance: none;
tap-highlight-color: rgba(255, 255, 255, 0);
line-height: 1.2142em;
padding: 0.67861em 1em;
padding: 0.67861429em 1em;
font-size: 1em;
background: #ffffff;
border: 1px solid rgba(39, 41, 43, 0.15);
color: rgba(0, 0, 0, 0.8);
border-radius: 0.2857rem;
border: 1px solid rgba(34, 36, 38, 0.15);
color: rgba(0, 0, 0, 0.87);
border-radius: 0.28571429rem;
box-shadow: 0em 0em 0em 0em transparent inset;
-webkit-transition: background-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
transition: background-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
-webkit-transition: color 0.1s ease, border-color 0.1s ease;
transition: color 0.1s ease, border-color 0.1s ease;
}
.ui.textarea,
/* Text Area */
.ui.form textarea {
margin: 0em;
-webkit-appearance: none;
tap-highlight-color: rgba(255, 255, 255, 0);
padding: 0.78571em 1em;
padding: 0.78571429em 1em;
background: #ffffff;
border: 1px solid rgba(39, 41, 43, 0.15);
border: 1px solid rgba(34, 36, 38, 0.15);
outline: none;
color: rgba(0, 0, 0, 0.8);
border-radius: 0.2857rem;
color: rgba(0, 0, 0, 0.87);
border-radius: 0.28571429rem;
box-shadow: 0em 0em 0em 0em transparent inset;
-webkit-transition: background-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
transition: background-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
-webkit-transition: color 0.1s ease, border-color 0.1s ease;
transition: color 0.1s ease, border-color 0.1s ease;
font-size: 1em;
line-height: 1.2857;
resize: vertical;
}
.ui.form textarea:not([rows]) {
height: 12em;
min-height: 8em;
max-height: 24em;
line-height: 1.2857;
resize: vertical;
}
.ui.form textarea,
.ui.form input[type="checkbox"] {
@ -165,32 +160,81 @@
height: auto;
width: 100%;
background: #ffffff;
border: 1px solid rgba(39, 41, 43, 0.15);
border-radius: 0.2857rem;
border: 1px solid rgba(34, 36, 38, 0.15);
border-radius: 0.28571429rem;
box-shadow: 0em 0em 0em 0em transparent inset;
padding: 0.62em 1em;
color: rgba(0, 0, 0, 0.8);
-webkit-transition: background-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
transition: background-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
color: rgba(0, 0, 0, 0.87);
-webkit-transition: color 0.1s ease, border-color 0.1s ease;
transition: color 0.1s ease, border-color 0.1s ease;
}
/*--------------------
Dropdown
---------------------*/
/* Block */
.ui.form .field > .selection.dropdown {
width: 100%;
}
.ui.form .field > .selection.dropdown > .dropdown.icon {
float: right;
}
/* Inline */
.ui.form .inline.fields .field > .selection.dropdown,
.ui.form .inline.field > .selection.dropdown {
width: auto;
}
.ui.form .inline.fields .field > .selection.dropdown > .dropdown.icon,
.ui.form .inline.field > .selection.dropdown > .dropdown.icon {
float: none;
}
/*--------------------
UI Input
---------------------*/
/* Block */
.ui.form .field .ui.input,
.ui.form .fields .field .ui.input,
.ui.form .wide.field .ui.input {
width: 100%;
}
/* Inline */
.ui.form .inline.fields .field:not(.wide) .ui.input,
.ui.form .inline.field:not(.wide) .ui.input {
width: auto;
vertical-align: middle;
}
/* Auto Input */
.ui.form .fields .field .ui.input input,
.ui.form .field .ui.input input {
width: auto;
}
/* Full Width Input */
.ui.form .ten.fields .ui.input input,
.ui.form .nine.fields .ui.input input,
.ui.form .eight.fields .ui.input input,
.ui.form .seven.fields .ui.input input,
.ui.form .six.fields .ui.input input,
.ui.form .five.fields .ui.input input,
.ui.form .four.fields .ui.input input,
.ui.form .three.fields .ui.input input,
.ui.form .two.fields .ui.input input,
.ui.form .wide.field .ui.input input {
-webkit-box-flex: 1;
-webkit-flex: 1 0 auto;
-ms-flex: 1 0 auto;
flex: 1 0 auto;
width: 0px;
}
/*--------------------
Dividers
---------------------*/
@ -220,13 +264,19 @@
---------------------*/
.ui.form .field .prompt.label {
white-space: nowrap;
white-space: normal;
background: #ffffff !important;
border: 1px solid #e0b4b4 !important;
color: #9f3a38 !important;
}
.ui.form .inline.fields .field .prompt,
.ui.form .inline.field .prompt {
margin: -0.5em 0em -0.5em 1em;
vertical-align: top;
margin: -0.25em 0em -0.5em 0.5em;
}
.ui.form .inline.fields .field .prompt:before,
.ui.form .inline.field .prompt:before {
margin-top: -0.3em;
border-width: 0px 0px 1px 1px;
bottom: auto;
right: auto;
top: 50%;
@ -239,6 +289,27 @@
*******************************/
/*--------------------
Autofilled
---------------------*/
.ui.form .field.field input:-webkit-autofill {
box-shadow: 0px 0px 0px 100px #fffff0 inset !important;
border-color: #e5dfa1 !important;
}
/* Focus */
.ui.form .field.field input:-webkit-autofill:focus {
box-shadow: 0px 0px 0px 100px #fffff0 inset !important;
border-color: #d5c315 !important;
}
/* Error */
.ui.form .error.error input:-webkit-autofill {
box-shadow: 0px 0px 0px 100px #fffaf0 inset !important;
border-color: #e0b4b4 !important;
}
/*--------------------
Placeholder
---------------------*/
@ -246,30 +317,42 @@
/* browsers require these rules separate */
.ui.form ::-webkit-input-placeholder {
color: rgba(140, 140, 140, 0.8);
color: rgba(140, 140, 140, 0.87);
}
.ui.form ::-ms-input-placeholder {
color: rgba(140, 140, 140, 0.87);
}
.ui.form ::-moz-placeholder {
color: rgba(140, 140, 140, 0.8);
color: rgba(140, 140, 140, 0.87);
}
.ui.form :focus::-webkit-input-placeholder {
color: rgba(89, 89, 89, 0.8);
color: rgba(89, 89, 89, 0.87);
}
.ui.form :focus::-ms-input-placeholder {
color: rgba(89, 89, 89, 0.87);
}
.ui.form :focus::-moz-placeholder {
color: rgba(89, 89, 89, 0.8);
color: rgba(89, 89, 89, 0.87);
}
/* Error Placeholder */
.ui.form .error ::-webkit-input-placeholder {
color: #e38585;
color: #e7bdbc;
}
.ui.form .error ::-ms-input-placeholder {
color: #e7bdbc;
}
.ui.form .error ::-moz-placeholder {
color: #e38585;
color: #e7bdbc;
}
.ui.form .error :focus::-webkit-input-placeholder {
color: #de7171;
color: #da9796;
}
.ui.form .error :focus::-ms-input-placeholder {
color: #da9796;
}
.ui.form .error :focus::-moz-placeholder {
color: #de7171;
color: #da9796;
}
/*--------------------
@ -287,18 +370,18 @@
.ui.form input[type="time"]:focus,
.ui.form input[type="text"]:focus,
.ui.form input[type="url"]:focus {
color: rgba(0, 0, 0, 0.85);
border-color: rgba(39, 41, 43, 0.3);
border-radius: 0em 0.2857rem 0.2857rem 0em;
color: rgba(0, 0, 0, 0.95);
border-color: #85b7d9;
border-radius: 0.28571429rem;
background: #ffffff;
box-shadow: 1px 0em 0em 0em rgba(39, 41, 43, 0.3) inset;
box-shadow: 0px 0em 0em 0em rgba(34, 36, 38, 0.35) inset;
}
.ui.form textarea:focus {
color: rgba(0, 0, 0, 0.85);
border-color: rgba(39, 41, 43, 0.3);
border-radius: 0em 0.2857rem 0.2857rem 0em;
color: rgba(0, 0, 0, 0.95);
border-color: #85b7d9;
border-radius: 0.28571429rem;
background: #ffffff;
box-shadow: 1px 0em 0em 0em rgba(39, 41, 43, 0.3) inset;
box-shadow: 0px 0em 0em 0em rgba(34, 36, 38, 0.35) inset;
-webkit-appearance: none;
}
@ -308,18 +391,14 @@
/* On Form */
.ui.form.success .success.message {
.ui.form.success .success.message:not(:empty) {
display: block;
}
/*--------------------
Error
---------------------*/
/* On Form */
.ui.form.warning .warning.message {
display: block;
.ui.form.success .icon.success.message:not(:empty) {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
/*--------------------
@ -328,20 +407,42 @@
/* On Form */
.ui.form.error .error.message {
.ui.form.warning .warning.message:not(:empty) {
display: block;
}
.ui.form.warning .icon.warning.message:not(:empty) {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
/*--------------------
Warning
---------------------*/
/* On Form */
.ui.form.error .error.message:not(:empty) {
display: block;
}
.ui.form.error .icon.error.message:not(:empty) {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
/* On Field(s) */
.ui.form .fields.error .field label,
.ui.form .field.error label,
.ui.form .fields.error .field .input,
.ui.form .field.error .input {
color: #d95c5c;
color: #9f3a38;
}
.ui.form .fields.error .field .corner.label,
.ui.form .field.error .corner.label {
border-color: #d95c5c;
border-color: #9f3a38;
color: #ffffff;
}
.ui.form .fields.error .field textarea,
@ -370,11 +471,11 @@
.ui.form .field.error input[type="time"],
.ui.form .field.error input[type="text"],
.ui.form .field.error input[type="url"] {
background: #fff0f0;
border-color: #dbb1b1;
color: #d95c5c;
border-radius: 0em 0.2857rem 0.2857rem 0em;
box-shadow: 2px 0em 0em 0em #d95c5c inset;
background: #fff6f6;
border-color: #e0b4b4;
color: #9f3a38;
border-radius: '';
box-shadow: none;
}
.ui.form .field.error textarea:focus,
.ui.form .field.error select:focus,
@ -389,11 +490,11 @@
.ui.form .field.error input[type="time"]:focus,
.ui.form .field.error input[type="text"]:focus,
.ui.form .field.error input[type="url"]:focus {
background: #fff0f0;
border-color: #dbb1b1;
color: #dc6868;
background: #fff6f6;
border-color: #e0b4b4;
color: #9f3a38;
-webkit-appearance: none;
box-shadow: 2px 0em 0em 0em #dc6868 inset;
box-shadow: none;
}
/* Preserve Native Select Stylings */
@ -410,20 +511,25 @@
.ui.form .field.error .ui.dropdown,
.ui.form .field.error .ui.dropdown .text,
.ui.form .field.error .ui.dropdown .item {
background: #fff0f0;
color: #d95c5c;
background: #fff6f6;
color: #9f3a38;
}
.ui.form .fields.error .field .ui.dropdown,
.ui.form .field.error .ui.dropdown {
border-color: #dbb1b1 !important;
border-color: #e0b4b4 !important;
}
.ui.form .fields.error .field .ui.dropdown:hover,
.ui.form .field.error .ui.dropdown:hover {
border-color: #dbb1b1 !important;
border-color: #e0b4b4 !important;
}
.ui.form .fields.error .field .ui.dropdown:hover .menu,
.ui.form .field.error .ui.dropdown:hover .menu {
border-color: #dbb1b1;
border-color: #e0b4b4;
}
.ui.form .fields.error .field .ui.multiple.selection.dropdown > .label,
.ui.form .field.error .ui.multiple.selection.dropdown > .label {
background-color: #eacbcb;
color: #9f3a38;
}
/* Hover */
@ -432,6 +538,12 @@
background-color: #fbe7e7;
}
/* Selected */
.ui.form .fields.error .field .ui.dropdown .menu .selected.item,
.ui.form .field.error .ui.dropdown .menu .selected.item {
background-color: #fbe7e7;
}
/* Active */
.ui.form .fields.error .field .ui.dropdown .menu .active.item,
.ui.form .field.error .ui.dropdown .menu .active.item {
@ -446,32 +558,34 @@
.ui.form .field.error .checkbox:not(.toggle):not(.slider) label,
.ui.form .fields.error .field .checkbox:not(.toggle):not(.slider) .box,
.ui.form .field.error .checkbox:not(.toggle):not(.slider) .box {
color: #d95c5c;
color: #9f3a38;
}
.ui.form .fields.error .field .checkbox:not(.toggle):not(.slider) label:before,
.ui.form .field.error .checkbox:not(.toggle):not(.slider) label:before,
.ui.form .fields.error .field .checkbox:not(.toggle):not(.slider) .box:before,
.ui.form .field.error .checkbox:not(.toggle):not(.slider) .box:before {
background: #fff0f0;
border-color: #dbb1b1;
background: #fff6f6;
border-color: #e0b4b4;
}
.ui.form .fields.error .field .checkbox label:after,
.ui.form .field.error .checkbox label:after,
.ui.form .fields.error .field .checkbox .box:after,
.ui.form .field.error .checkbox .box:after {
color: #d95c5c;
color: #9f3a38;
}
/*--------------------
Disabled
---------------------*/
.ui.form .field :disabled,
.ui.form .field.disabled {
opacity: 0.5;
.ui.form .disabled.fields .field,
.ui.form .disabled.field,
.ui.form .field :disabled {
pointer-events: none;
opacity: 0.45;
}
.ui.form .field.disabled label {
opacity: 0.5;
opacity: 0.45;
}
.ui.form .field.disabled :disabled {
opacity: 1;
@ -514,7 +628,7 @@
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
border-radius: 500rem;
border-color: #aaaaaa rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1);
border-color: #767676 rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1);
border-style: solid;
border-width: 0.2em;
box-shadow: 0px 0px 0px 1px transparent;
@ -559,7 +673,7 @@
.ui.form .required.field > .checkbox:after {
margin: -0.2em 0em 0em 0.2em;
content: '*';
color: #d95c5c;
color: #db2828;
}
.ui.form .required.fields:not(.grouped) > .field > label:after,
.ui.form .required.fields.grouped > label:after,
@ -590,7 +704,25 @@
.ui.form .inverted.segment .ui.checkbox .box,
.ui.inverted.form .ui.checkbox label,
.ui.inverted.form .ui.checkbox .box {
color: #ffffff;
color: rgba(255, 255, 255, 0.9);
}
/* Inverted Field */
.ui.inverted.form input:not([type]),
.ui.inverted.form input[type="date"],
.ui.inverted.form input[type="datetime-local"],
.ui.inverted.form input[type="email"],
.ui.inverted.form input[type="number"],
.ui.inverted.form input[type="password"],
.ui.inverted.form input[type="search"],
.ui.inverted.form input[type="tel"],
.ui.inverted.form input[type="time"],
.ui.inverted.form input[type="text"],
.ui.inverted.form input[type="url"] {
background: #ffffff;
border-color: rgba(255, 255, 255, 0.1);
color: rgba(0, 0, 0, 0.87);
box-shadow: none;
}
/*--------------------
@ -600,17 +732,22 @@
/* Grouped Vertically */
.ui.form .grouped.fields {
display: block;
margin: 0em 0em 1em;
}
.ui.form .grouped.fields:last-child {
margin-bottom: 0em;
}
.ui.form .grouped.fields > label {
font-size: 0.9285em;
margin: 0em 0em 0.28571429rem 0em;
color: rgba(0, 0, 0, 0.87);
font-size: 0.92857143em;
font-weight: bold;
text-transform: none;
}
.ui.form .grouped.fields .field {
.ui.form .grouped.fields .field,
.ui.form .grouped.inline.fields .field {
display: block;
float: none;
margin: 0.5em 0em;
padding: 0em;
}
@ -622,19 +759,21 @@
/* Split fields */
.ui.form .fields {
clear: both;
}
.ui.form .fields:after {
content: ' ';
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
}
.ui.form .fields > .field {
clear: none;
float: left;
-webkit-box-flex: 0;
-webkit-flex: 0 1 auto;
-ms-flex: 0 1 auto;
flex: 0 1 auto;
padding-left: 0.5em;
padding-right: 0.5em;
}
@ -683,6 +822,11 @@
/* Swap to full width on mobile */
@media only screen and (max-width: 767px) {
.ui.form .fields {
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
}
.ui.form .two.fields > .fields,
.ui.form .two.fields > .field,
.ui.form .three.fields > .fields,
@ -813,48 +957,77 @@
.ui.form .inline.fields {
margin: 0em 0em 1em;
-webkit-box-align: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
}
.ui.form .inline.fields .field {
display: inline-block;
float: none;
margin: 0em 1em 0em 0em;
padding: 0em;
margin: 0em;
padding: 0em 1em 0em 0em;
}
/* Inline Label */
.ui.form .inline.fields > label,
.ui.form .inline.fields .field > label,
.ui.form .inline.fields .field > p,
.ui.form .inline.fields .field > input,
.ui.form .inline.fields .field > .ui.input,
.ui.form .inline.field > label,
.ui.form .inline.field > p,
.ui.form .inline.field > p {
display: inline-block;
width: auto;
margin-top: 0em;
margin-bottom: 0em;
vertical-align: baseline;
font-size: 0.92857143em;
font-weight: bold;
color: rgba(0, 0, 0, 0.87);
text-transform: none;
}
/* Grouped Inline Label */
.ui.form .inline.fields > label {
margin: 0.035714em 1em 0em 0em;
}
/* Inline Input */
.ui.form .inline.fields .field > input,
.ui.form .inline.fields .field > select,
.ui.form .inline.field > input,
.ui.form .inline.field > .ui.input {
.ui.form .inline.field > select {
display: inline-block;
width: auto;
margin-top: 0em;
margin-bottom: 0em;
vertical-align: middle;
font-size: 0.9285em;
}
.ui.form .inline.fields .field > input,
.ui.form .inline.fields .field > .ui.input,
.ui.form .inline.field > input,
.ui.form .inline.field > .ui.input {
font-size: 0.9285em;
}
.ui.form .inline.fields .field > .ui.checkbox label {
padding-left: 1.75em;
font-size: 1em;
}
/* Label */
.ui.form .inline.fields .field > :first-child,
.ui.form .inline.field > :first-child {
margin: 0em 0.2857rem 0em 0em;
margin: 0em 0.85714286em 0em 0em;
}
.ui.form .inline.fields .field > :only-child,
.ui.form .inline.field > :only-child {
margin: 0em;
}
/* Wide */
.ui.form .inline.fields .wide.field {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
}
.ui.form .inline.fields .wide.field > input,
.ui.form .inline.fields .wide.field > select {
width: 100%;
}
/*--------------------
Sizes
---------------------*/
@ -862,22 +1035,22 @@
/* Standard */
.ui.small.form {
font-size: 0.875em;
font-size: 0.92857143rem;
}
/* Medium */
.ui.form {
font-size: auto;
font-size: 1rem;
}
/* Large */
.ui.large.form {
font-size: 1.125em;
font-size: 1.14285714rem;
}
/* Huge */
.ui.huge.form {
font-size: 1.2em;
font-size: 1.42857143rem;
}

View File

@ -1,9 +1,9 @@
/*!
* # Semantic UI 1.12.3 - Form Validation
* # Semantic UI 2.1.3 - Form Validation
* http://github.com/semantic-org/semantic-ui/
*
*
* Copyright 2014 Contributors
* Copyright 2015 Contributors
* Released under the MIT license
* http://opensource.org/licenses/MIT
*
@ -13,60 +13,72 @@
"use strict";
$.fn.form = function(fields, parameters) {
$.fn.form = function(parameters) {
var
$allModules = $(this),
$allModules = $(this),
moduleSelector = $allModules.selector || '',
settings = $.extend(true, {}, $.fn.form.settings, parameters),
validation = $.extend({}, $.fn.form.settings.defaults, fields),
time = new Date().getTime(),
performance = [],
namespace = settings.namespace,
metadata = settings.metadata,
selector = settings.selector,
className = settings.className,
error = settings.error,
eventNamespace = '.' + namespace,
moduleNamespace = 'module-' + namespace,
moduleSelector = $allModules.selector || '',
time = new Date().getTime(),
performance = [],
query = arguments[0],
methodInvoked = (typeof query == 'string'),
queryArguments = [].slice.call(arguments, 1),
query = arguments[0],
legacyParameters = arguments[1],
methodInvoked = (typeof query == 'string'),
queryArguments = [].slice.call(arguments, 1),
returnedValue
;
$allModules
.each(function() {
var
$module = $(this),
$field = $(this).find(selector.field),
$group = $(this).find(selector.group),
$message = $(this).find(selector.message),
$prompt = $(this).find(selector.prompt),
$submit = $(this).find(selector.submit),
$clear = $(this).find(selector.clear),
$reset = $(this).find(selector.reset),
element = this,
formErrors = [],
keyHeldDown = false,
element = this,
instance = $module.data(moduleNamespace),
// set at run-time
$field,
$group,
$message,
$prompt,
$submit,
$clear,
$reset,
settings,
validation,
metadata,
selector,
className,
error,
namespace,
moduleNamespace,
eventNamespace,
instance,
module
;
module = {
initialize: function() {
module.verbose('Initializing form validation', $module, validation, settings);
module.bindEvents();
module.set.defaults();
module.instantiate();
// settings grabbed at run time
module.get.settings();
if(methodInvoked) {
if(instance === undefined) {
module.instantiate();
}
module.invoke(query);
}
else {
module.verbose('Initializing form validation', $module, settings);
module.bindEvents();
module.set.defaults();
module.instantiate();
}
},
instantiate: function() {
@ -87,7 +99,14 @@ $.fn.form = function(fields, parameters) {
refresh: function() {
module.verbose('Refreshing selector cache');
$field = $module.find(selector.field);
$field = $module.find(selector.field);
$group = $module.find(selector.group);
$message = $module.find(selector.message);
$prompt = $module.find(selector.prompt);
$submit = $module.find(selector.submit);
$clear = $module.find(selector.clear);
$reset = $module.find(selector.reset);
},
submit: function() {
@ -100,7 +119,7 @@ $.fn.form = function(fields, parameters) {
attachEvents: function(selector, action) {
action = action || 'submit';
$(selector)
.on('click', function(event) {
.on('click' + eventNamespace, function(event) {
module[action]();
event.preventDefault();
})
@ -108,28 +127,25 @@ $.fn.form = function(fields, parameters) {
},
bindEvents: function() {
if(settings.keyboardShortcuts) {
$field
.on('keydown' + eventNamespace, module.event.field.keydown)
;
}
module.verbose('Attaching form events');
$module
.on('submit' + eventNamespace, module.validate.form)
.on('blur' + eventNamespace, selector.field, module.event.field.blur)
.on('click' + eventNamespace, selector.submit, module.submit)
.on('click' + eventNamespace, selector.reset, module.reset)
.on('click' + eventNamespace, selector.clear, module.clear)
;
$field
.on('blur' + eventNamespace, module.event.field.blur)
;
// attach events to common elements
module.attachEvents($submit, 'submit');
module.attachEvents($reset, 'reset');
module.attachEvents($clear, 'clear');
if(settings.keyboardShortcuts) {
$module
.on('keydown' + eventNamespace, selector.field, module.event.field.keydown)
;
}
$field
.each(function() {
var
type = $(this).prop('type'),
inputEvent = module.get.changeEvent(type)
$input = $(this),
type = $input.prop('type'),
inputEvent = module.get.changeEvent(type, $input)
;
$(this)
.on(inputEvent + eventNamespace, module.event.field.change)
@ -161,7 +177,7 @@ $.fn.form = function(fields, parameters) {
$element.dropdown('clear');
}
else if(isCheckbox) {
$element.checkbox('uncheck');
$field.prop('checked', false);
}
else {
module.verbose('Resetting field value', $field, defaultValue);
@ -179,11 +195,14 @@ $.fn.form = function(fields, parameters) {
$element = $field.parent(),
$fieldGroup = $field.closest($group),
$prompt = $fieldGroup.find(selector.prompt),
defaultValue = $field.data(metadata.defaultValue) || '',
defaultValue = $field.data(metadata.defaultValue),
isCheckbox = $element.is(selector.uiCheckbox),
isDropdown = $element.is(selector.uiDropdown),
isErrored = $fieldGroup.hasClass(className.error)
;
if(defaultValue === undefined) {
return;
}
if(isErrored) {
module.verbose('Resetting error on field', $fieldGroup);
$fieldGroup.removeClass(className.error);
@ -195,12 +214,7 @@ $.fn.form = function(fields, parameters) {
}
else if(isCheckbox) {
module.verbose('Resetting checkbox value', $element, defaultValue);
if(defaultValue === true) {
$element.checkbox('check');
}
else {
$element.checkbox('uncheck');
}
$field.prop('checked', defaultValue);
}
else {
module.verbose('Resetting field value', $field, defaultValue);
@ -210,6 +224,21 @@ $.fn.form = function(fields, parameters) {
;
},
is: {
valid: function() {
var
allValid = true
;
module.verbose('Checking if form is valid');
$.each(validation, function(fieldName, field) {
if( !( module.validate.field(field) ) ) {
allValid = false;
}
});
return allValid;
}
},
removeEvents: function() {
$module
.off(eventNamespace)
@ -243,9 +272,6 @@ $.fn.form = function(fields, parameters) {
;
}
if(!event.ctrlKey && key == keyCode.enter && $field.is(selector.input) && $field.not(selector.checkbox).length > 0 ) {
$submit
.addClass(className.pressed)
;
if(!keyHeldDown) {
$field
.one('keyup' + eventNamespace, module.event.field.keyup)
@ -258,19 +284,19 @@ $.fn.form = function(fields, parameters) {
},
keyup: function() {
keyHeldDown = false;
$submit.removeClass(className.pressed);
},
blur: function() {
var
$field = $(this),
$fieldGroup = $field.closest($group)
$field = $(this),
$fieldGroup = $field.closest($group),
validationRules = module.get.validation($field)
;
if( $fieldGroup.hasClass(className.error) ) {
module.debug('Revalidating field', $field, module.get.validation($field));
module.validate.field( module.get.validation($field) );
module.debug('Revalidating field', $field, validationRules);
module.validate.field( validationRules );
}
else if(settings.on == 'blur' || settings.on == 'change') {
module.validate.field( module.get.validation($field) );
module.validate.field( validationRules );
}
},
change: function() {
@ -291,8 +317,8 @@ $.fn.form = function(fields, parameters) {
},
get: {
changeEvent: function(type) {
if(type == 'checkbox' || type == 'radio' || type == 'hidden') {
changeEvent: function(type, $input) {
if(type == 'checkbox' || type == 'radio' || type == 'hidden' || $input.is('select')) {
return 'change';
}
else {
@ -307,6 +333,52 @@ $.fn.form = function(fields, parameters) {
: 'keyup'
;
},
settings: function() {
var
firstProperty
;
if($.isPlainObject(parameters)) {
var
keys = Object.keys(parameters),
isLegacySettings = (keys.length > 0)
? (parameters[keys[0]].identifier !== undefined && parameters[keys[0]].rules !== undefined)
: false
;
if(isLegacySettings) {
// 1.x (ducktyped)
settings = $.extend(true, {}, $.fn.form.settings, legacyParameters);
validation = $.extend({}, $.fn.form.settings.defaults, parameters);
module.error(settings.error.oldSyntax, element);
module.verbose('Extending settings from legacy parameters', validation, settings);
}
else {
// 2.x
settings = $.extend(true, {}, $.fn.form.settings, parameters);
validation = $.extend({}, $.fn.form.settings.defaults, settings.fields);
module.verbose('Extending settings', validation, settings);
}
}
else {
settings = $.fn.form.settings;
validation = $.fn.form.settings.defaults;
module.verbose('Using default form validation', validation, settings);
}
// shorthand
namespace = settings.namespace;
metadata = settings.metadata;
selector = settings.selector;
className = settings.className;
error = settings.error;
moduleNamespace = 'module-' + namespace;
eventNamespace = '.' + namespace;
// grab instance
instance = $module.data(moduleNamespace);
// refresh selector cache
module.refresh();
},
field: function(identifier) {
module.verbose('Finding field with identifier', identifier);
if( $field.filter('#' + identifier).length > 0 ) {
@ -336,8 +408,11 @@ $.fn.form = function(fields, parameters) {
var
rules
;
if(!validation) {
return false;
}
$.each(validation, function(fieldName, field) {
if( module.get.field(field.identifier).get(0) == $field.get(0) ) {
if( module.get.field(field.identifier)[0] == $field[0] ) {
rules = field;
}
});
@ -380,11 +455,10 @@ $.fn.form = function(fields, parameters) {
}
if(isCheckbox) {
if(isChecked) {
values[name].push(value)
values[name].push(true);
}
else {
module.debug('Omitted unchecked checkbox', $field);
return true;
values[name].push(false);
}
}
else {
@ -402,8 +476,7 @@ $.fn.form = function(fields, parameters) {
values[name] = true;
}
else {
module.debug('Omitted unchecked checkbox', $field);
return true;
values[name] = false;
}
}
else {
@ -420,6 +493,9 @@ $.fn.form = function(fields, parameters) {
field: function(identifier) {
module.verbose('Checking for existence of a field with identifier', identifier);
if(typeof identifier !== 'string') {
module.error(error.identifier, identifier);
}
if( $field.filter('#' + identifier).length > 0 ) {
return true;
}
@ -600,7 +676,6 @@ $.fn.form = function(fields, parameters) {
}
}
});
module.validate.form();
}
},
@ -608,7 +683,7 @@ $.fn.form = function(fields, parameters) {
form: function(event) {
var
allValid = true,
values = module.get.values(),
apiRequest
;
@ -619,15 +694,10 @@ $.fn.form = function(fields, parameters) {
// reset errors
formErrors = [];
$.each(validation, function(fieldName, field) {
if( !( module.validate.field(field) ) ) {
allValid = false;
}
});
if(allValid) {
if( module.is.valid() ) {
module.debug('Form has no validation errors, submitting');
module.set.success();
return settings.onSuccess.call(element, event);
return settings.onSuccess.call(element, event, values);
}
else {
module.debug('Form has errors');
@ -639,7 +709,7 @@ $.fn.form = function(fields, parameters) {
if($module.data('moduleApi') !== undefined) {
event.stopImmediatePropagation();
}
return settings.onFailure.call(element, formErrors);
return settings.onFailure.call(element, formErrors, values);
}
},
@ -685,23 +755,36 @@ $.fn.form = function(fields, parameters) {
var
$field = module.get.field(field.identifier),
type = validation.type,
value = $.trim($field.val() + ''),
bracketRegExp = /\[(.*)\]/i,
bracket = bracketRegExp.exec(type),
value = $field.val(),
bracket = type.match(settings.regExp.bracket),
isValid = true,
rule,
ancillary,
functionType
;
// cast to string avoiding encoding special values
value = (value === undefined || value === '' || value === null)
? ''
: $.trim(value + '')
;
// if bracket notation is used, pass in extra parameters
if(bracket !== undefined && bracket !== null) {
if(bracket) {
ancillary = '' + bracket[1];
functionType = type.replace(bracket[0], '');
isValid = settings.rules[functionType].call(element, value, ancillary);
rule = settings.rules[functionType];
if( !$.isFunction(rule) ) {
module.error(error.noRule, functionType);
return;
}
isValid = rule.call($field, value, ancillary);
}
// normal notation
else {
isValid = settings.rules[type].call($field, value);
rule = settings.rules[type];
if( !$.isFunction(rule) ) {
module.error(error.noRule, type);
return;
}
isValid = rule.call($field, value);
}
return isValid;
}
@ -775,7 +858,7 @@ $.fn.form = function(fields, parameters) {
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 100);
module.performance.timer = setTimeout(module.performance.display, 500);
},
display: function() {
var
@ -863,19 +946,7 @@ $.fn.form = function(fields, parameters) {
return found;
}
};
if(methodInvoked) {
if(instance === undefined) {
module.initialize();
}
module.invoke(query);
}
else {
if(instance !== undefined) {
instance.invoke('destroy');
}
module.initialize();
}
module.initialize();
})
;
@ -891,9 +962,10 @@ $.fn.form.settings = {
namespace : 'form',
debug : false,
verbose : true,
verbose : false,
performance : true,
fields : false,
keyboardShortcuts : true,
on : 'submit',
@ -915,6 +987,17 @@ $.fn.form.settings = {
validate : 'validate'
},
regExp: {
bracket : /\[(.*)\]/i,
decimal : /^\-?\d*(\.\d+)?$/,
email : "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?",
escape : /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,
flags : /^\/(.*)\/(.*)?/,
integer : /^\-?\d+$/,
number : /^\-?\d*(\.\d+)?$/,
url : /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/i
},
selector : {
checkbox : 'input[type="checkbox"], input[type="radio"]',
clear : '.clear',
@ -924,8 +1007,8 @@ $.fn.form.settings = {
message : '.error.message',
prompt : '.prompt.label',
radio : 'input[type="radio"]',
reset : '.reset',
submit : '.submit',
reset : '.reset:not([type="reset"])',
submit : '.submit:not([type="submit"])',
uiCheckbox : '.ui.checkbox',
uiDropdown : '.ui.dropdown'
},
@ -938,7 +1021,10 @@ $.fn.form.settings = {
},
error: {
method : 'The method you called is not defined.'
identifier : 'You must specify a string identifier for each field',
method : 'The method you called is not defined.',
noRule : 'There is no rule matching the one you specified',
oldSyntax : 'Starting in 2.0 forms now only take a single settings object. Validation settings converted to new syntax automatically.'
},
templates: {
@ -958,7 +1044,7 @@ $.fn.form.settings = {
// template that produces label
prompt: function(errors) {
return $('<div/>')
.addClass('ui red pointing prompt label')
.addClass('ui basic red pointing prompt label')
.html(errors[0])
;
}
@ -966,42 +1052,53 @@ $.fn.form.settings = {
rules: {
// is not empty or blank string
empty: function(value) {
return !(value === undefined || '' === value || $.isArray(value) && value.length === 0);
},
// checkbox checked
checked: function() {
return ($(this).filter(':checked').length > 0);
},
// value contains text (insensitive)
contains: function(value, text) {
// escape regex characters
text = text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
return (value.search( new RegExp(text, 'i') ) !== -1);
},
// value contains text (case sensitive)
containsExactly: function(value, text) {
// escape regex characters
text = text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
return (value.search( new RegExp(text) ) !== -1);
},
// is most likely an email
email: function(value){
var
emailRegExp = new RegExp("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", "i")
emailRegExp = new RegExp($.fn.form.settings.regExp.email, 'i')
;
return emailRegExp.test(value);
},
// is not empty or blank string
empty: function(value) {
return !(value === undefined || '' === value);
// value is most likely url
url: function(value) {
return $.fn.form.settings.regExp.url.test(value);
},
// is valid integer
// matches specified regExp
regExp: function(value, regExp) {
var
regExpParts = regExp.match($.fn.form.settings.regExp.flags),
flags
;
// regular expression specified as /baz/gi (flags)
if(regExpParts) {
regExp = (regExpParts.length >= 2)
? regExpParts[1]
: regExp
;
flags = (regExpParts.length >= 3)
? regExpParts[2]
: ''
;
}
return value.match( new RegExp(regExp, flags) );
},
// is valid integer or matches range
integer: function(value, range) {
var
intRegExp = /^\-?\d+$/,
intRegExp = $.fn.form.settings.regExp.integer,
min,
max,
parts
@ -1030,6 +1127,16 @@ $.fn.form.settings = {
);
},
// is valid number (with decimal)
decimal: function(value) {
return $.fn.form.settings.regExp.decimal.test(value);
},
// is valid number
number: function(value) {
return $.fn.form.settings.regExp.number.test(value);
},
// is value (case insensitive)
is: function(value, text) {
text = (typeof text == 'string')
@ -1048,45 +1155,7 @@ $.fn.form.settings = {
return (value == text);
},
// is at least string length
length: function(value, requiredLength) {
return (value !== undefined)
? (value.length >= requiredLength)
: false
;
},
// matches another field
match: function(value, fieldIdentifier) {
// use either id or name of field
var
$form = $(this),
matchingValue
;
if($form.find('#' + fieldIdentifier).length > 0) {
matchingValue = $form.find('#' + fieldIdentifier).val();
}
else if($form.find('[name="' + fieldIdentifier +'"]').length > 0) {
matchingValue = $form.find('[name="' + fieldIdentifier + '"]').val();
}
else if( $form.find('[data-validate="'+ fieldIdentifier +'"]').length > 0 ) {
matchingValue = $form.find('[data-validate="'+ fieldIdentifier +'"]').val();
}
return (matchingValue !== undefined)
? ( value.toString() == matchingValue.toString() )
: false
;
},
// string length is less than max length
maxLength: function(value, maxLength) {
return (value !== undefined)
? (value.length <= maxLength)
: false
;
},
// value is not value (case insensitive)
// value is not another value (case insensitive)
not: function(value, notValue) {
value = (typeof value == 'string')
? value.toLowerCase()
@ -1099,17 +1168,251 @@ $.fn.form.settings = {
return (value != notValue);
},
// value is not value (case sensitive)
// value is not another value (case sensitive)
notExactly: function(value, notValue) {
return (value != notValue);
},
// value is most likely url
url: function(value) {
var
urlRegExp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/
// value contains text (insensitive)
contains: function(value, text) {
// escape regex characters
text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
return (value.search( new RegExp(text, 'i') ) !== -1);
},
// value contains text (case sensitive)
containsExactly: function(value, text) {
// escape regex characters
text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
return (value.search( new RegExp(text) ) !== -1);
},
// value contains text (insensitive)
doesntContain: function(value, text) {
// escape regex characters
text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
return (value.search( new RegExp(text, 'i') ) === -1);
},
// value contains text (case sensitive)
doesntContainExactly: function(value, text) {
// escape regex characters
text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
return (value.search( new RegExp(text) ) === -1);
},
// is at least string length
minLength: function(value, requiredLength) {
return (value !== undefined)
? (value.length >= requiredLength)
: false
;
return urlRegExp.test(value);
},
// see rls notes for 2.0.6 (this is a duplicate of minLength)
length: function(value, requiredLength) {
return (value !== undefined)
? (value.length >= requiredLength)
: false
;
},
// is exactly length
exactLength: function(value, requiredLength) {
return (value !== undefined)
? (value.length == requiredLength)
: false
;
},
// is less than length
maxLength: function(value, maxLength) {
return (value !== undefined)
? (value.length <= maxLength)
: false
;
},
// matches another field
match: function(value, identifier) {
var
$form = $(this),
matchingValue
;
if( $('[data-validate="'+ identifier +'"]').length > 0 ) {
matchingValue = $('[data-validate="'+ identifier +'"]').val();
}
else if($('#' + identifier).length > 0) {
matchingValue = $('#' + identifier).val();
}
else if($('[name="' + identifier +'"]').length > 0) {
matchingValue = $('[name="' + identifier + '"]').val();
}
else if( $('[name="' + identifier +'[]"]').length > 0 ) {
matchingValue = $('[name="' + identifier +'[]"]');
}
return (matchingValue !== undefined)
? ( value.toString() == matchingValue.toString() )
: false
;
},
creditCard: function(cardNumber, cardTypes) {
var
cards = {
visa: {
pattern : /^4/,
length : [16]
},
amex: {
pattern : /^3[47]/,
length : [15]
},
mastercard: {
pattern : /^5[1-5]/,
length : [16]
},
discover: {
pattern : /^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)/,
length : [16]
},
unionPay: {
pattern : /^(62|88)/,
length : [16, 17, 18, 19]
},
jcb: {
pattern : /^35(2[89]|[3-8][0-9])/,
length : [16]
},
maestro: {
pattern : /^(5018|5020|5038|6304|6759|676[1-3])/,
length : [12, 13, 14, 15, 16, 17, 18, 19]
},
dinersClub: {
pattern : /^(30[0-5]|^36)/,
length : [14]
},
laser: {
pattern : /^(6304|670[69]|6771)/,
length : [16, 17, 18, 19]
},
visaElectron: {
pattern : /^(4026|417500|4508|4844|491(3|7))/,
length : [16]
}
},
valid = {},
validCard = false,
requiredTypes = (typeof cardTypes == 'string')
? cardTypes.split(',')
: false,
unionPay,
validation
;
if(typeof cardNumber !== 'string' || cardNumber.length === 0) {
return;
}
// verify card types
if(requiredTypes) {
$.each(requiredTypes, function(index, type){
// verify each card type
validation = cards[type];
if(validation) {
valid = {
length : ($.inArray(cardNumber.length, validation.length) !== -1),
pattern : (cardNumber.search(validation.pattern) !== -1)
};
if(valid.length && valid.pattern) {
validCard = true;
}
}
});
if(!validCard) {
return false;
}
}
// skip luhn for UnionPay
unionPay = {
number : ($.inArray(cardNumber.length, cards.unionPay.length) !== -1),
pattern : (cardNumber.search(cards.unionPay.pattern) !== -1)
};
if(unionPay.number && unionPay.pattern) {
return true;
}
// verify luhn, adapted from <https://gist.github.com/2134376>
var
length = cardNumber.length,
multiple = 0,
producedValue = [
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[0, 2, 4, 6, 8, 1, 3, 5, 7, 9]
],
sum = 0
;
while (length--) {
sum += producedValue[multiple][parseInt(cardNumber.charAt(length), 10)];
multiple ^= 1;
}
return (sum % 10 === 0 && sum > 0);
},
// different than another field
different: function(value, identifier) {
// use either id or name of field
var
$form = $(this),
matchingValue
;
if( $('[data-validate="'+ identifier +'"]').length > 0 ) {
matchingValue = $('[data-validate="'+ identifier +'"]').val();
}
else if($('#' + identifier).length > 0) {
matchingValue = $('#' + identifier).val();
}
else if($('[name="' + identifier +'"]').length > 0) {
matchingValue = $('[name="' + identifier + '"]').val();
}
else if( $('[name="' + identifier +'[]"]').length > 0 ) {
matchingValue = $('[name="' + identifier +'[]"]');
}
return (matchingValue !== undefined)
? ( value.toString() !== matchingValue.toString() )
: false
;
},
exactCount: function(value, exactCount) {
if(exactCount == 0) {
return (value === '');
}
if(exactCount == 1) {
return (value !== '' && value.search(',') === -1);
}
return (value.split(',').length == exactCount);
},
minCount: function(value, minCount) {
if(minCount == 0) {
return true;
}
if(minCount == 1) {
return (value !== '');
}
return (value.split(',').length >= minCount);
},
maxCount: function(value, maxCount) {
if(maxCount == 0) {
return false;
}
if(maxCount == 1) {
return (value.search(',') === -1);
}
return (value.split(',').length <= maxCount);
}
}

Some files were not shown because too many files have changed in this diff Show More