mirror of
https://github.com/humhub/humhub.git
synced 2025-01-17 22:28:51 +01:00
Merge branch 'v1.2-dev' of github.com:humhub/humhub into v1.2-dev
This commit is contained in:
commit
2565b0c180
@ -238,7 +238,7 @@ class Theme extends \yii\base\Theme
|
||||
public function parseThemeVariables($lessFileName)
|
||||
{
|
||||
// Parse default values
|
||||
$variables = $this->parseLessVariables(Yii::getAlias('@web-static/less/'.$lessFileName));
|
||||
$variables = $this->parseLessVariables(Yii::getAlias('@webroot-static/less/'.$lessFileName));
|
||||
|
||||
// Overwrite theme values
|
||||
return \yii\helpers\ArrayHelper::merge($variables, $this->parseLessVariables($this->getBasePath() . '/less/'.$lessFileName));
|
||||
|
@ -82,11 +82,6 @@ class View extends \yii\web\View
|
||||
*/
|
||||
public function renderAjaxContent($content)
|
||||
{
|
||||
// Make sure not to load add these asset, especially the bootstrap asset could overwrite the theme.
|
||||
unset($this->assetBundles['yii\bootstrap\BootstrapAsset']);
|
||||
unset($this->assetBundles['yii\web\JqueryAsset']);
|
||||
unset($this->assetBundles['yii\web\YiiAsset']);
|
||||
|
||||
ob_start();
|
||||
ob_implicit_flush(false);
|
||||
|
||||
@ -94,12 +89,48 @@ class View extends \yii\web\View
|
||||
$this->head();
|
||||
$this->beginBody();
|
||||
echo $content;
|
||||
$this->unregisterAjaxAssets();
|
||||
$this->endBody();
|
||||
$this->endPage(true);
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function renderAjax($view, $params = array(), $context = null)
|
||||
{
|
||||
|
||||
$viewFile = $this->findViewFile($view, $context);
|
||||
|
||||
ob_start();
|
||||
ob_implicit_flush(false);
|
||||
|
||||
$this->beginPage();
|
||||
$this->head();
|
||||
$this->beginBody();
|
||||
echo $this->renderFile($viewFile, $params, $context);
|
||||
$this->unregisterAjaxAssets();
|
||||
$this->endBody();
|
||||
|
||||
|
||||
$this->endPage(true);
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters standard assets on ajax requests
|
||||
*/
|
||||
protected function unregisterAjaxAssets()
|
||||
{
|
||||
unset($this->assetBundles['yii\bootstrap\BootstrapAsset']);
|
||||
unset($this->assetBundles['yii\web\JqueryAsset']);
|
||||
unset($this->assetBundles['yii\web\YiiAsset']);
|
||||
unset($this->assetBundles['all']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
@ -199,12 +230,12 @@ class View extends \yii\web\View
|
||||
if (Yii::$app->request->isAjax) {
|
||||
return parent::endBody();
|
||||
}
|
||||
|
||||
|
||||
// Since the JsConfig accesses user queries it fails before installation.
|
||||
if(Yii::$app->params['installed']) {
|
||||
if (Yii::$app->params['installed']) {
|
||||
\humhub\widgets\CoreJsConfig::widget();
|
||||
}
|
||||
|
||||
|
||||
// Add LayoutAddons and jsConfig registered by addons
|
||||
echo \humhub\widgets\LayoutAddons::widget();
|
||||
$this->flushJsConfig();
|
||||
|
@ -2,7 +2,7 @@
|
||||
/**
|
||||
* This file is generated by the "yii asset" command.
|
||||
* DO NOT MODIFY THIS FILE DIRECTLY.
|
||||
* @version 2017-02-03 12:23:54
|
||||
* @version 2017-02-03 13:13:44
|
||||
*/
|
||||
return [
|
||||
'all' => [
|
||||
@ -10,10 +10,10 @@ return [
|
||||
'basePath' => '@webroot-static',
|
||||
'baseUrl' => '@web-static',
|
||||
'js' => [
|
||||
'js/all-fb75e1229373f42b293ffad4928f215a.js',
|
||||
'js/all-63209f2aef3c4f786466b9a653335973.js',
|
||||
],
|
||||
'css' => [
|
||||
'css/all-117fe17f6823c356207416c918cc26b9.css',
|
||||
'css/all-f848b7bc64a107d6f74b3f5694c4d2a6.css',
|
||||
],
|
||||
'sourcePath' => null,
|
||||
'depends' => [],
|
||||
|
@ -31,8 +31,8 @@ return [
|
||||
],
|
||||
// Asset manager configuration:
|
||||
'assetManager' => [
|
||||
'basePath' => '@webroot/assets',
|
||||
'baseUrl' => '@web/assets',
|
||||
'basePath' => '@webroot-static/assets',
|
||||
'baseUrl' => '@web-static/assets',
|
||||
'bundles' => [
|
||||
'yii\bootstrap\BootstrapPluginAsset' => [
|
||||
'js' => ['js/bootstrap.min.js'],
|
||||
|
@ -226,7 +226,7 @@ $config = [
|
||||
'tour' => [
|
||||
'acceptableNames' => ['interface', 'administration', 'profile', 'spaces']
|
||||
],
|
||||
'enablePjax' => false,
|
||||
'enablePjax' => true,
|
||||
]
|
||||
];
|
||||
|
||||
|
@ -6,7 +6,6 @@ Getting Started
|
||||
* [Overview](overview.md)
|
||||
* [Git/Composer Installation](git-installation.md)
|
||||
* [Development Environment](environment.md)
|
||||
* [Coding Standards](coding-standards.md)
|
||||
|
||||
|
||||
Module Development
|
||||
@ -30,3 +29,8 @@ Special Topics
|
||||
* [Streams](stream.md)
|
||||
* [Permissions](permissions.md)
|
||||
* [Widgets](widgets.md)
|
||||
|
||||
Core Development
|
||||
----------------
|
||||
* [Build assets](core-build-assets.md)
|
||||
* [Coding Standards](core-coding-standards.md)
|
||||
|
@ -7,15 +7,11 @@ class m160205_205540_foreign_keys extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
$this->addForeignKey('fk_content-user_id', 'content', 'user_id', 'user', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->addForeignKey('fk_wall_entry-wall_id', 'wall_entry', 'wall_id', 'wall', 'id', 'CASCADE', 'CASCADE');
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
//echo "m160205_205540_foreign_keys cannot be reverted.\n";
|
||||
|
||||
$this->dropForeignKey('fk_content-user_id', 'content');
|
||||
$this->dropForeignKey('fk_wall_entry-wall_id', 'wall');
|
||||
return true;
|
||||
}
|
||||
|
@ -8,37 +8,44 @@ class m160415_180332_wall_remove extends Migration
|
||||
|
||||
public function up()
|
||||
{
|
||||
$this->addColumn('content', 'show_in_stream', $this->boolean()->defaultValue(true));
|
||||
$this->addColumn('content', 'stream_sort_date', $this->dateTime());
|
||||
|
||||
/**
|
||||
* Allow restart of this migration
|
||||
*/
|
||||
try {
|
||||
$this->addColumn('content', 'show_in_stream', $this->boolean()->defaultValue(true));
|
||||
$this->addColumn('content', 'stream_sort_date', $this->dateTime());
|
||||
} catch (Exception $ex) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate stream_updated_at attribute
|
||||
*/
|
||||
$this->update('content', [
|
||||
'stream_sort_date' => new Expression('(SELECT updated_at FROM wall_entry WHERE wall_entry.content_id=content.id LIMIT 1)')
|
||||
], [
|
||||
'IS', 'stream_sort_date', new Expression('NULL')
|
||||
]);
|
||||
/*
|
||||
$this->db->createCommand('UPDATE content LEFT JOIN wall_entry ON wall_entry.content_id=content.id
|
||||
SET content.stream_sort_date=wall_entry.updated_at
|
||||
WHERE content.stream_sort_date IS NULL')->excute();
|
||||
*/
|
||||
|
||||
$this->update('content', ['stream_sort_date' => new Expression('created_at')], ['IS', 'stream_sort_date', new Expression('NULL')]);
|
||||
|
||||
/**
|
||||
* Populate show_in_stream attribute
|
||||
*/
|
||||
$this->update('content', [
|
||||
'show_in_stream' => 0
|
||||
], [
|
||||
'IS', new Expression('(SELECT wall_entry.id FROM wall_entry WHERE wall_entry.content_id=content.id LIMIT 1)'), new Expression('NULL')
|
||||
]);
|
||||
/*
|
||||
$this->db->createCommand('UPDATE content LEFT JOIN wall_entry ON wall_entry.content_id=content.id
|
||||
SET content.show_in_stream=0
|
||||
WHERE wall_entry.id IS NULL')->excute();
|
||||
*/
|
||||
|
||||
|
||||
|
||||
$this->dropForeignKey('fk_space-wall_id', 'space');
|
||||
$this->dropForeignKey('fk_wall_entry-wall_id', 'wall_entry');
|
||||
|
||||
|
||||
$this->dropColumn('user', 'wall_id');
|
||||
$this->dropColumn('space', 'wall_id');
|
||||
$this->dropColumn('contentcontainer', 'wall_id');
|
||||
|
||||
|
||||
$this->dropTable('wall_entry');
|
||||
$this->dropTable('wall');
|
||||
}
|
||||
|
@ -5,10 +5,15 @@ use yii\db\Migration;
|
||||
|
||||
class m160205_203955_foreign_keys extends Migration
|
||||
{
|
||||
|
||||
public function up()
|
||||
{
|
||||
$this->addForeignKey('fk_like-created_by', 'like', 'created_by', 'user', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->addForeignKey('fk_like-target_user_id', 'like', 'target_user_id', 'user', 'id', 'CASCADE', 'CASCADE');
|
||||
try {
|
||||
$this->addForeignKey('fk_like-created_by', 'like', 'created_by', 'user', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->addForeignKey('fk_like-target_user_id', 'like', 'target_user_id', 'user', 'id', 'CASCADE', 'CASCADE');
|
||||
} catch (Exception $ex) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function down()
|
||||
@ -20,13 +25,13 @@ class m160205_203955_foreign_keys extends Migration
|
||||
}
|
||||
|
||||
/*
|
||||
// Use safeUp/safeDown to run migration code within a transaction
|
||||
public function safeUp()
|
||||
{
|
||||
}
|
||||
// Use safeUp/safeDown to run migration code within a transaction
|
||||
public function safeUp()
|
||||
{
|
||||
}
|
||||
|
||||
public function safeDown()
|
||||
{
|
||||
}
|
||||
*/
|
||||
public function safeDown()
|
||||
{
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ use humhub\modules\content\models\Content;
|
||||
*/
|
||||
class NotificationManager
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array Target configuration.
|
||||
@ -53,16 +54,15 @@ class NotificationManager
|
||||
public function sendBulk(BaseNotification $notification, $users)
|
||||
{
|
||||
$recepients = $this->filterRecepients($notification, $users);
|
||||
|
||||
foreach($recepients as $recepient) {
|
||||
|
||||
foreach ($recepients as $recepient) {
|
||||
$notification->saveRecord($recepient);
|
||||
}
|
||||
|
||||
foreach ($this->getTargets() as $target) {
|
||||
$target->sendBulk($notification, $recepients);
|
||||
foreach ($this->getTargets() as $target) {
|
||||
$target->send($notification, $recepient);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Filters out duplicates and the originator of the notification itself.
|
||||
*
|
||||
@ -82,7 +82,6 @@ class NotificationManager
|
||||
return $filteredUsers;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends the given $notification to all enabled targets of a single user.
|
||||
*
|
||||
@ -91,10 +90,10 @@ class NotificationManager
|
||||
*/
|
||||
public function send(BaseNotification $notification, User $user)
|
||||
{
|
||||
if($notification->isOriginator($user)) {
|
||||
if ($notification->isOriginator($user)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$notification->saveRecord($user);
|
||||
foreach ($this->getTargets($user) as $target) {
|
||||
$target->send($notification, $user);
|
||||
@ -258,23 +257,23 @@ class NotificationManager
|
||||
['not in', 'object_id', $spaceIds]
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Defines the enable_html5_desktop_notifications setting for the given user or global if no user is given.
|
||||
*
|
||||
* @param type $value
|
||||
* @param User $user
|
||||
*/
|
||||
public function setDesktopNoficationSettings($value = 0, User $user = null)
|
||||
public function setDesktopNoficationSettings($value = 0, User $user = null)
|
||||
{
|
||||
$module = Yii::$app->getModule('notification');
|
||||
$settingManager = ($user) ? $module->settings->user($user) : $module->settings;
|
||||
$settingManager->set('enable_html5_desktop_notifications', $value);
|
||||
}
|
||||
|
||||
public function getDesktopNoficationSettings(User $user = null)
|
||||
|
||||
public function getDesktopNoficationSettings(User $user = null)
|
||||
{
|
||||
if($user) {
|
||||
if ($user) {
|
||||
return Yii::$app->getModule('notification')->settings->user($user)->getInherit('enable_html5_desktop_notifications');
|
||||
} else {
|
||||
return Yii::$app->getModule('notification')->settings->get('enable_html5_desktop_notifications');
|
||||
|
@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
use yii\db\Schema;
|
||||
use yii\db\Migration;
|
||||
|
||||
class m160205_203933_foreign_keys extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
$this->addForeignKey('fk_post-created_by', 'post', 'created_by', 'user', 'id', 'CASCADE', 'CASCADE');
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->dropForeignKey('fk_post-created_by', 'post');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
// Use safeUp/safeDown to run migration code within a transaction
|
||||
public function safeUp()
|
||||
{
|
||||
}
|
||||
|
||||
public function safeDown()
|
||||
{
|
||||
}
|
||||
*/
|
||||
}
|
@ -10,7 +10,6 @@ class m160205_203913_foreign_keys extends Migration
|
||||
$this->addForeignKey('fk_space_membership-user_id', 'space_membership', 'user_id', 'user', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->addForeignKey('fk_space_membership-space_id', 'space_membership', 'space_id', 'space', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->addForeignKey('fk_space_module-space_id', 'space_module', 'space_id', 'space', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->addForeignKey('fk_space_setting-space_id', 'space_setting', 'space_id', 'space', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->addForeignKey('fk_space-wall_id', 'space', 'wall_id', 'wall', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->addForeignKey('fk_space_module-module_id', 'space_module', 'module_id', 'module_enabled', 'module_id', 'CASCADE', 'CASCADE');
|
||||
}
|
||||
@ -20,7 +19,6 @@ class m160205_203913_foreign_keys extends Migration
|
||||
$this->dropForeignKey('fk_space_membership-user_id', 'space_membership');
|
||||
$this->dropForeignKey('fk_space_membership-space_id', 'space_membership');
|
||||
$this->dropForeignKey('fk_space_module-space_id', 'space_module');
|
||||
$this->dropForeignKey('fk_space_setting-space_id', 'space_setting');
|
||||
$this->dropForeignKey('fk_space-wall_id', 'space');
|
||||
$this->dropForeignKey('fk_space_module-module_id', 'space_module');
|
||||
|
||||
|
@ -42,26 +42,8 @@ class SpaceChooserItem extends Widget
|
||||
public function run()
|
||||
{
|
||||
|
||||
$data = '';
|
||||
$badge = '';
|
||||
|
||||
/*if ($this->isMember && $this->space->isSpaceOwner()) {
|
||||
$badge = '<i class="fa fa-key badge-space pull-right type tt" title="' . Yii::t('SpaceModule.widgets_views_spaceChooserItem', 'Owner') . '" aria-hidden="true"></i>';
|
||||
$data = 'data-space-owner';
|
||||
}*/
|
||||
|
||||
if($this->isMember) {
|
||||
$badge = '<i class="fa fa-users badge-space pull-right type tt" title="' . Yii::t('SpaceModule.widgets_spaceChooserItem', 'You are a member of this space') . '" aria-hidden="true"></i>';
|
||||
$data = 'data-space-member';
|
||||
} else if($this->isFollowing) {
|
||||
$badge = '<i class="fa fa-star badge-space pull-right type tt" title="' . Yii::t('SpaceModule.widgets_spaceChooserItem', 'You are following this space') . '" aria-hidden="true"></i>';
|
||||
$data = 'data-space-following';
|
||||
} else if($this->space->isArchived()) {
|
||||
$badge = '<i class="fa fa-history badge-space pull-right type tt" title="' . Yii::t('SpaceModule.widgets_spaceChooserItem', 'This space is archived') . '" aria-hidden="true"></i>';
|
||||
$data = 'data-space-archived';
|
||||
} else {
|
||||
$data = 'data-space-none';
|
||||
}
|
||||
$data = $this->getDataAttribute();
|
||||
$badge = $this->getBadge();
|
||||
|
||||
return $this->render('spaceChooserItem', [
|
||||
'space' => $this->space,
|
||||
@ -72,4 +54,27 @@ class SpaceChooserItem extends Widget
|
||||
]);
|
||||
}
|
||||
|
||||
public function getBadge()
|
||||
{
|
||||
if ($this->isMember) {
|
||||
return '<i class="fa fa-users badge-space pull-right type tt" title="' . Yii::t('SpaceModule.widgets_spaceChooserItem', 'You are a member of this space') . '" aria-hidden="true"></i>';
|
||||
} else if ($this->isFollowing) {
|
||||
return '<i class="fa fa-star badge-space pull-right type tt" title="' . Yii::t('SpaceModule.widgets_spaceChooserItem', 'You are following this space') . '" aria-hidden="true"></i>';
|
||||
} else if ($this->space->isArchived()) {
|
||||
return '<i class="fa fa-history badge-space pull-right type tt" title="' . Yii::t('SpaceModule.widgets_spaceChooserItem', 'This space is archived') . '" aria-hidden="true"></i>';
|
||||
}
|
||||
}
|
||||
|
||||
public function getDataAttribute()
|
||||
{
|
||||
if ($this->isMember) {
|
||||
return 'data-space-member';
|
||||
} else if ($this->isFollowing) {
|
||||
return 'data-space-following';
|
||||
} else if ($this->space->isArchived()) {
|
||||
return 'data-space-archived';
|
||||
} else {
|
||||
return 'data-space-none';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -278,6 +278,13 @@ abstract class Stream extends Action
|
||||
if ($underlyingObject === null) {
|
||||
throw new Exception('Could not get contents underlying object!');
|
||||
}
|
||||
|
||||
// Fix for newly created content
|
||||
if ($content->created_at instanceof \yii\db\Expression) {
|
||||
$content->created_at = date('Y-m-d G:i:s');
|
||||
$content->updated_at = $content->created_at;
|
||||
}
|
||||
|
||||
$underlyingObject->populateRelation('content', $content);
|
||||
$result['output'] = Yii::$app->controller->renderAjax('@humhub/modules/content/views/layouts/wallEntry', [
|
||||
'entry' => $content,
|
||||
|
@ -9,15 +9,12 @@ class m160205_203840_foreign_keys extends Migration
|
||||
{
|
||||
$this->addForeignKey('fk_user_follow-user_id', 'user_follow', 'user_id', 'user', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->addForeignKey('fk_group-space_id', 'group', 'space_id', 'space', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->addForeignKey('fk_group_admin-user_id', 'group_admin', 'user_id', 'user', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->addForeignKey('fk_group_admin-group_id', 'group_admin', 'group_id', 'group', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->addForeignKey('fk_group_permission-group_id', 'group_permission', 'group_id', 'group', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->addForeignKey('fk_user_mentioning-user_id', 'user_mentioning', 'user_id', 'user', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->addForeignKey('fk_user_module-user_id', 'user_module', 'user_id', 'user', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->addForeignKey('fk_user_password-user_id', 'user_password', 'user_id', 'user', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->addForeignKey('fk_profile-user_id', 'profile', 'user_id', 'user', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->addForeignKey('fk_profile_field-profile_field_category_id', 'profile_field', 'profile_field_category_id', 'profile_field_category', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->addForeignKey('fk_user_setting-user_id', 'user_setting', 'user_id', 'user', 'id', 'CASCADE', 'CASCADE');
|
||||
$this->addForeignKey('fk_user_http_session-user_id', 'user_http_session', 'user_id', 'user', 'id', 'CASCADE', 'CASCADE');
|
||||
}
|
||||
|
||||
@ -25,15 +22,12 @@ class m160205_203840_foreign_keys extends Migration
|
||||
{
|
||||
$this->dropForeignKey('fk_follow-user_id', 'user_follow');
|
||||
$this->dropForeignKey('fk_group-space_id', 'group');
|
||||
$this->dropForeignKey('fk_group_admin-user_id', 'group_admin');
|
||||
$this->dropForeignKey('fk_group_admin-group_id', 'group_admin');
|
||||
$this->dropForeignKey('fk_group_permission-group_id', 'group_permission');
|
||||
$this->dropForeignKey('fk_user_mentioning-user_id', 'user_mentioning');
|
||||
$this->dropForeignKey('fk_user_module-user_id', 'user_module');
|
||||
$this->dropForeignKey('fk_user_password-user_id', 'user_password');
|
||||
$this->dropForeignKey('fk_profile-user_id', 'profile');
|
||||
$this->dropForeignKey('fk_profile_field-profile_field_category_id', 'profile_field');
|
||||
$this->dropForeignKey('fk_user_setting-user_id', 'user_setting');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -30,6 +30,9 @@ Yii::setAlias('@root', $config['humhub_root']);
|
||||
Yii::setAlias('@humhubTests', $config['humhub_root'] . '/protected/humhub/tests');
|
||||
Yii::setAlias('@humhub', $config['humhub_root'] . '/protected/humhub');
|
||||
|
||||
Yii::setAlias('@web-static', '/static');
|
||||
Yii::setAlias('@webroot-static', '@root/static');
|
||||
|
||||
// Load all supporting test classes needed for test execution
|
||||
\Codeception\Util\Autoload::addNamespace('', Yii::getAlias('@humhubTests/codeception/_support'));
|
||||
\Codeception\Util\Autoload::addNamespace('', Yii::getAlias('@tests/codeception/fixtures'));
|
||||
|
240
static/assets/173682e7/js/humhub.notification.js
Normal file
240
static/assets/173682e7/js/humhub.notification.js
Normal file
@ -0,0 +1,240 @@
|
||||
/**
|
||||
* @link https://www.humhub.org/
|
||||
* @copyright Copyright (c) 2017 HumHub GmbH & Co. KG
|
||||
* @license https://www.humhub.com/licences
|
||||
*/
|
||||
humhub.module('notification', function (module, require, $) {
|
||||
var util = require('util');
|
||||
var object = util.object;
|
||||
var string = util.string;
|
||||
var Widget = require('ui.widget').Widget;
|
||||
var event = require('event');
|
||||
var client = require('client');
|
||||
var status = require('ui.status');
|
||||
|
||||
module.initOnPjaxLoad = true;
|
||||
|
||||
var NotificationDropDown = function (node, options) {
|
||||
Widget.call(this, node, options);
|
||||
};
|
||||
|
||||
object.inherits(NotificationDropDown, Widget);
|
||||
|
||||
NotificationDropDown.prototype.init = function (update) {
|
||||
this.isOpen = false;
|
||||
this.lastEntryLoaded = false;
|
||||
this.lastEntryId = 0;
|
||||
this.originalTitle = document.title;
|
||||
this.initDropdown();
|
||||
this.handleResult(update);
|
||||
//this.sendDesktopNotifications(update);
|
||||
|
||||
var that = this;
|
||||
event.on('humhub.modules.notification.live.NewNotification', function (evt, events, update) {
|
||||
var count = (that.$.data('notification-count')) ? parseInt(that.$.data('notification-count')) + events.length : events.length;
|
||||
that.updateCount(count);
|
||||
that.sendDesktopNotifications(events, update.lastSessionTime);
|
||||
});
|
||||
};
|
||||
|
||||
NotificationDropDown.prototype.initDropdown = function () {
|
||||
this.$entryList = this.$.find('ul.media-list');
|
||||
this.$dropdown = this.$.find('#dropdown-notifications');
|
||||
|
||||
var that = this;
|
||||
this.$entryList.scroll(function () {
|
||||
var containerHeight = that.$entryList.height();
|
||||
var scrollHeight = that.$entryList.prop("scrollHeight");
|
||||
var currentScrollPosition = that.$entryList.scrollTop();
|
||||
|
||||
// load more activites if current scroll position is near scroll height
|
||||
if (currentScrollPosition >= (scrollHeight - containerHeight - 1)) {
|
||||
if (!that.lastEntryLoaded) {
|
||||
that.loadEntries();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
NotificationDropDown.prototype.toggle = function (evt) {
|
||||
// Always reset the loading settings so we reload the whole dropdown.
|
||||
this.lastEntryLoaded = false;
|
||||
this.lastEntryId = 0;
|
||||
|
||||
// Since the handler will be called before the bootstrap trigger it's an open event if the dropdown is not visible yet
|
||||
this.isOpen = !this.$dropdown.is(':visible');
|
||||
if (this.isOpen) {
|
||||
this.$entryList.empty().hide();
|
||||
this.loadEntries();
|
||||
}
|
||||
};
|
||||
|
||||
NotificationDropDown.prototype.loadEntries = function () {
|
||||
if (this.loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
var that = this;
|
||||
this.loader();
|
||||
client.get(module.config.loadEntriesUrl, {data: {from: this.lastEntryId}})
|
||||
.then($.proxy(this.handleResult, this))
|
||||
.catch(_errorHandler)
|
||||
.finally(function () {
|
||||
that.loader(false);
|
||||
that.loading = false;
|
||||
});
|
||||
};
|
||||
|
||||
NotificationDropDown.prototype.handleResult = function (response) {
|
||||
if (!response.counter) {
|
||||
this.$entryList.append(string.template(module.templates.placeholder, {'text': module.text('placeholder')}));
|
||||
} else {
|
||||
this.lastEntryId = response.lastEntryId;
|
||||
this.$entryList.append(response.output);
|
||||
$('span.time').timeago();
|
||||
}
|
||||
|
||||
this.updateCount(parseInt(response.newNotifications));
|
||||
this.lastEntryLoaded = (response.counter < 6);
|
||||
this.$entryList.fadeIn('fast');
|
||||
};
|
||||
|
||||
NotificationDropDown.prototype.updateCount = function ($count) {
|
||||
if(this.$.data('notification-count') === $count) {
|
||||
return;
|
||||
}
|
||||
|
||||
$('#badge-notifications').hide();
|
||||
if (!$count) {
|
||||
$('#mark-seen-link').hide();
|
||||
$('#icon-notifications .fa').removeClass("animated swing");
|
||||
} else {
|
||||
updateTitle($count);
|
||||
$('#badge-notifications').html($count);
|
||||
$('#mark-seen-link').show();
|
||||
$('#badge-notifications').fadeIn('fast');
|
||||
|
||||
// Clone icon to retrigger animation
|
||||
var $icon = $('#icon-notifications .fa');
|
||||
var $clone = $icon.clone();
|
||||
$clone.addClass("animated swing");
|
||||
$icon.replaceWith($clone);
|
||||
}
|
||||
|
||||
this.$.data('notification-count', $count);
|
||||
};
|
||||
|
||||
NotificationDropDown.prototype.sendDesktopNotifications = function (response, lastSessionTime) {
|
||||
if (!response) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.text) { // Single Notification
|
||||
module.sendDesktopNotifiaction(response.text);
|
||||
} else if (response.notifications) { // Multiple Notifications
|
||||
var $notifications = response.notifications;
|
||||
for (var i = 0; i < $notifications.length; i++) {
|
||||
module.sendDesktopNotifiaction($notifications[i]);
|
||||
}
|
||||
} else if (object.isArray(response)) { // Live events
|
||||
$.each(response, function (i, liveEvent) {
|
||||
if(lastSessionTime && lastSessionTime > liveEvent.data.ts) {
|
||||
return; // continue
|
||||
}
|
||||
|
||||
if (liveEvent.data && liveEvent.data.text) {
|
||||
module.sendDesktopNotifiaction(liveEvent.data.text);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
var sendDesktopNotifiaction = function (body, icon) {
|
||||
icon = icon || module.config.icon;
|
||||
if (body && body.length) {
|
||||
notify.createNotification("Notification", {body: body, icon: icon});
|
||||
}
|
||||
};
|
||||
|
||||
var _errorHandler = function (e) {
|
||||
module.log.error(e, true);
|
||||
};
|
||||
|
||||
NotificationDropDown.prototype.loader = function (show) {
|
||||
if (show !== false) {
|
||||
this.$.find('#loader_notifications').show();
|
||||
} else {
|
||||
this.$.find('#loader_notifications').hide();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
NotificationDropDown.prototype.markAsSeen = function (evt) {
|
||||
return client.post(evt).then(function (response) {
|
||||
$('#badge-notifications').hide();
|
||||
$('#mark-seen-link').hide();
|
||||
updateTitle(false);
|
||||
}).catch(function (e) {
|
||||
module.log.error(e, true);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Global action handler (used in overview page).
|
||||
*
|
||||
* @param {type} evt
|
||||
* @returns {undefined}
|
||||
*/
|
||||
var markAsSeen = function(evt) {
|
||||
var widget = NotificationDropDown.instance('#notification_widget');
|
||||
widget.markAsSeen(evt).then(function() {
|
||||
location.reload();
|
||||
});
|
||||
};
|
||||
|
||||
var updateTitle = function ($count) {
|
||||
if ($count) {
|
||||
document.title = '(' + $count + ') ' + status.getState().title;
|
||||
} else if ($count === false) {
|
||||
document.title = status.getState().title;
|
||||
}
|
||||
};
|
||||
|
||||
module.templates = {
|
||||
placeholder: '<li class="placeholder">{text}</li>'
|
||||
};
|
||||
|
||||
var init = function ($pjax) {
|
||||
updateTitle($('#notification_widget').data('notification-count'));
|
||||
initOverviewPage();
|
||||
if (!$pjax) {
|
||||
$("#dropdown-notifications ul.media-list").niceScroll({
|
||||
cursorwidth: "7",
|
||||
cursorborder: "",
|
||||
cursorcolor: "#555",
|
||||
cursoropacitymax: "0.2",
|
||||
nativeparentscrolling: false,
|
||||
railpadding: {top: 0, right: 3, left: 0, bottom: 0}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
var initOverviewPage = function () {
|
||||
if ($('#notification_overview_list').length) {
|
||||
if (!$('#notification_overview_list li.new').length) {
|
||||
$('#notification_overview_markseen').hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.export({
|
||||
init: init,
|
||||
markAsSeen: markAsSeen,
|
||||
sendDesktopNotifiaction: sendDesktopNotifiaction,
|
||||
NotificationDropDown: NotificationDropDown
|
||||
});
|
||||
});
|
||||
|
177
static/assets/19a6ecfd/js/humhub.comment.js
Normal file
177
static/assets/19a6ecfd/js/humhub.comment.js
Normal file
@ -0,0 +1,177 @@
|
||||
humhub.module('comment', function(module, require, $) {
|
||||
var Content = require('content').Content;
|
||||
var Widget = require('ui.widget').Widget;
|
||||
var object = require('util').object;
|
||||
var client = require('client');
|
||||
var loader = require('ui.loader');
|
||||
var additions = require('ui.additions');
|
||||
|
||||
var Form = function(node, options) {
|
||||
Widget.call(this, node, options);
|
||||
};
|
||||
|
||||
object.inherits(Form, Widget);
|
||||
|
||||
Form.prototype.submit = function(evt) {
|
||||
var that = this;
|
||||
client.submit(evt, {dataType: 'html'}).then(function(response) {
|
||||
that.addComment(response.html);
|
||||
that.getInput().val('').trigger('autosize.resize');
|
||||
that.getRichtext().$.addClass('atwho-placeholder').focus();
|
||||
that.getUpload().reset();
|
||||
}).catch(function(err) {
|
||||
module.log.error(err, true);
|
||||
});
|
||||
};
|
||||
|
||||
Form.prototype.getRichtext = function() {
|
||||
return Widget.instance(this.$.find('div.humhub-ui-richtext'));
|
||||
};
|
||||
|
||||
Form.prototype.addComment = function(html) {
|
||||
var $html = $(html).hide();
|
||||
additions.applyTo($html);
|
||||
this.getCommentsContainer().append($html);
|
||||
$html.fadeIn();
|
||||
};
|
||||
|
||||
Form.prototype.getUpload = function(html) {
|
||||
return Widget.instance(this.$.find('[name="files[]"]'));
|
||||
};
|
||||
|
||||
Form.prototype.getCommentsContainer = function(html) {
|
||||
return this.$.siblings('.comment');
|
||||
};
|
||||
|
||||
Form.prototype.getInput = function() {
|
||||
return this.$.find('textarea');
|
||||
};
|
||||
|
||||
var Comment = function(node) {
|
||||
Content.call(this, node);
|
||||
additions.observe(this.$);
|
||||
};
|
||||
|
||||
object.inherits(Comment, Content);
|
||||
|
||||
Comment.prototype.edit = function(evt) {
|
||||
this.loader();
|
||||
var that = this;
|
||||
client.post(evt, {dataType: 'html'}).then(function(response) {
|
||||
that.$.find('.comment_edit_content').replaceWith(response.html);
|
||||
that.getRichtext().focus();
|
||||
that.$.find('.comment-cancel-edit-link').show();
|
||||
that.$.find('.comment-edit-link').hide();
|
||||
}).finally(function() {
|
||||
that.loader(false);
|
||||
});
|
||||
};
|
||||
|
||||
Comment.prototype.getRichtext = function() {
|
||||
return Widget.instance(this.$.find('div.humhub-ui-richtext'));
|
||||
};
|
||||
|
||||
Comment.prototype.delete = function() {
|
||||
this.super('delete', {modal: module.config.modal.delteConfirm}).then(function($confirm) {
|
||||
if($confirm) {
|
||||
module.log.success('success.delete');
|
||||
}
|
||||
}).catch(function(err) {
|
||||
module.log.error(err, true);
|
||||
});
|
||||
};
|
||||
|
||||
Comment.prototype.editSubmit = function(evt) {
|
||||
var that = this;
|
||||
client.submit(evt, {dataType: 'html'}).then(function(response) {
|
||||
that.replace(response.html);
|
||||
that.highlight();
|
||||
that.$.find('.comment-cancel-edit-link').hide();
|
||||
that.$.find('.comment-edit-link').show();
|
||||
module.log.success('success.saved');
|
||||
}).catch(function(err) {
|
||||
module.log.error(err, true);
|
||||
});
|
||||
};
|
||||
|
||||
Comment.prototype.replace = function(content) {
|
||||
var id = this.$.attr('id');
|
||||
this.$.replaceWith(content);
|
||||
this.$ = $('#' + id);
|
||||
additions.observe(this.$, true);
|
||||
};
|
||||
|
||||
Comment.prototype.cancelEdit = function(evt) {
|
||||
var that = this;
|
||||
this.loader();
|
||||
client.html(evt).then(function(response) {
|
||||
that.replace(response.html);
|
||||
that.$.find('.comment-cancel-edit-link').hide();
|
||||
that.$.find('.comment-edit-link').show();
|
||||
}).catch(function(err) {
|
||||
module.log.error(err, true);
|
||||
}).finally(function() {
|
||||
that.loader(false);
|
||||
});
|
||||
};
|
||||
|
||||
Comment.prototype.highlight = function() {
|
||||
additions.highlight(this.$.find('.comment-message'));
|
||||
};
|
||||
|
||||
Comment.prototype.loader = function($show) {
|
||||
var $loader = this.$.find('.comment-entry-loader');
|
||||
if($show === false) {
|
||||
this.$.find('.preferences').show();
|
||||
loader.reset($loader);
|
||||
return;
|
||||
}
|
||||
|
||||
loader.set($loader, {
|
||||
'size': '8px',
|
||||
'css': {
|
||||
padding: '2px',
|
||||
width: '60px'
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
this.$.find('.preferences').hide();
|
||||
};
|
||||
|
||||
var showAll = function(evt) {
|
||||
client.post(evt, {dataType:'html'}).then(function(response) {
|
||||
var $container = evt.$trigger.parent();
|
||||
$container.html(response.html);
|
||||
}).catch(function(err) {
|
||||
module.log.error(err, true);
|
||||
});
|
||||
};
|
||||
|
||||
var init = function() {
|
||||
$(document).on('mouseover', '.comment .media', function() {
|
||||
var $this = $(this);
|
||||
var element = $this.find('.preferences');
|
||||
if(!loader.is($this.find('.comment-entry-loader'))) {
|
||||
element.show();
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('mouseout', '.comment .media', function() {
|
||||
// find dropdown menu
|
||||
var element = $(this).find('.preferences');
|
||||
|
||||
// hide dropdown if it's not open
|
||||
if(!element.find('li').hasClass('open')) {
|
||||
element.hide();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.export({
|
||||
init: init,
|
||||
Comment: Comment,
|
||||
Form: Form,
|
||||
showAll: showAll
|
||||
});
|
||||
});
|
314
static/assets/1af6739c/CHANGELOG.md
Normal file
314
static/assets/1af6739c/CHANGELOG.md
Normal file
@ -0,0 +1,314 @@
|
||||
### v1.5.0
|
||||
|
||||
add `headerTpl` settings
|
||||
|
||||
* 7a41d93 - #375 from vcekov/fix_scroll_position - Valentin Cekov
|
||||
* ecbf34f - #373 from vcekov/val/fix_key_navigation_interefence_with_mouse - Valentin Cekov
|
||||
* b68cf84 - #364 from WorktileTech/master - Harold.Luo
|
||||
* f836f04 - #372 from vcekov/fix_caret_for_space_after_@ - Harold.Luo
|
||||
* 06cf6bb - Properly set caret position after failed match - Valentin Cekov
|
||||
* c9ed2e2 - support header template. - htz
|
||||
|
||||
### v1.4.0
|
||||
|
||||
#### Contenteditable
|
||||
|
||||
Pressing `Backspace` will turn the inserted element back to the origin query 'moment'.
|
||||
|
||||
* 84edc9f - skip inserted element when moving left or right - ichord
|
||||
* 25a61d3 - the jQuery npm package is now called jquery. Fixes #338 - Mick Staugaard
|
||||
* 03ed71f - Merge pull request #351 from mociepka/master - Harold.Luo
|
||||
* ae00dc3 - Point main script in package json - Michał Ociepka
|
||||
* c5f31f5 - Merge branch 'dev' into HEAD - ichord
|
||||
* c399397 - fix contenteditable cursor bug when typing "a" into query - ichord
|
||||
* 7f4295a - fix previous replacements get clobbered when re-intering the inserted element - ichord
|
||||
* f00fabd - Merge pull request #354 from lvegerano/master - Harold.Luo
|
||||
* a42065e - Adds guard to event and dist file - Luis Vegerano
|
||||
* e4aaa30 - Add option to disable loopUp on click - Luis Vegerano
|
||||
* c9b7609 - Fix bug where callbacks would run before reaching minLen. Fixes #329. - Mike Leone
|
||||
* f8692dc - Add support for minLen. Connects to issue #316. - Mike Leone
|
||||
* fd7d298 - FIX: the value of `isSelecting` - ichord
|
||||
* c374c93 - FIX: IME typing error - ichord
|
||||
|
||||
### v1.3.0
|
||||
|
||||
* 7f2189d - fix #294 inserts "" suffix in contenteditable
|
||||
* bae95d9 - add `tabSelectsMatch` setting to make tab selection optional
|
||||
* e966aba - Merge pull request #298 from kkirsche/patch-1 - Harold.Luo
|
||||
* 9f78239 - Remove moot `version` property from bower.json - Kevin Kirsche
|
||||
|
||||
### v1.2.0
|
||||
|
||||
db09ac7 -> 886613f
|
||||
|
||||
* 886613f - add `$.fn.atwho.debug = false` to trigger debug mode
|
||||
* 6567af9 - Enable default events when nothing is highlighted - Teemu
|
||||
* 752ad4a - Add scrollDuration option. - Takuru
|
||||
* bf17d43 - add parameter to allow for a spacebar in the middle of a search so that you can match a first + last name, for example - Feather Knee
|
||||
* a1d5fe7 - add `reposition` API - ichord
|
||||
* 9bcb06e - add "onInsert", "onDispaly" arguments to `tplEval` - ichord
|
||||
* db09ac7 - add `hide` api - ichord
|
||||
|
||||
### v1.1.0
|
||||
|
||||
* lisafeather/displyTplCallBack - #259
|
||||
* ADD: `editableAtwhoQueryAttrs` options
|
||||
* Added setting for 'spaceSelectsMatch' (default false/off)
|
||||
|
||||
### v1.0.0
|
||||
|
||||
**The naming convention are using camel case**.
|
||||
It means that every callback and setting's name are switched from underscope_naming to CamelNaming.
|
||||
Sorry about this.
|
||||
|
||||
Future version's naming will follow the rules of http://semver.org constantly.
|
||||
|
||||
#### Options:
|
||||
|
||||
* Replaced `tpl` with `displayTpl`: display template of dropdown menu items.
|
||||
In previous versions, At.js will fetch the value of `data-value` to insert; It stops doing it.
|
||||
Please use the `insertTpl` option to manage the content to insert instead.
|
||||
The default value is `"<li>${name}</li>"`
|
||||
* The `insertTpl` option will be used in *textarea* as well.
|
||||
The default value is `"${atwho-at}${name}"`
|
||||
|
||||
#### Callbacks:
|
||||
|
||||
* Added `afterMatchFailed` callback to *contentEditable*
|
||||
It will be invoked after fail to match any query and stopping matching.
|
||||
Open *examples/hashtas.html* to examine how it work.
|
||||
* Removed `inserting_wrapper` callback to *contentEditable*
|
||||
|
||||
#### Internal changes:
|
||||
|
||||
* refactor the `Controller`
|
||||
Introduced `EditableController` class to control actions of `contenteditable` element.
|
||||
Introduced `TextareaController` class to control actions of `textarea` element.
|
||||
Both of them are inherit from the `Controller` class.
|
||||
|
||||
* Refactored contentEditable mode
|
||||
Inserted content are wrapped in a span: `<span class=".atwho-inserted"/>`
|
||||
Querying content are wrapped in a span: `<span class=".atwho-query"/>`
|
||||
|
||||
* Bring back auto-discovery to iframe.
|
||||
* Fix wrong offset in iframe
|
||||
* Replaced `iframeStandalone` with `iframeAdRoot`
|
||||
* All processed events are preventing default and stopping propagation.
|
||||
|
||||
### v0.5.2
|
||||
|
||||
* e1f6566 - fix error that doesn't display mention list on new line
|
||||
* 8fe3a54 - can insert multiple node from `inserting_wrapper`
|
||||
* 4080151 - scroll to top after showing
|
||||
* 01555f8 - scroll long dropdown list
|
||||
* 1b8999d - Add spm support
|
||||
* f2b8e9c - change name in package.json
|
||||
* b61bfdc - search on click
|
||||
* b1efd09 - Fixes error with selecting always first item on the list on iOS WebView when using https://github.com/ftlabs/fastclick
|
||||
* 7ed2890 - Allow accented characters in matcher
|
||||
|
||||
### v0.5.1
|
||||
|
||||
* 219de3d - fix Goes off screen / gets cropped if there isn't enough room
|
||||
* 1100c5b - No longer inherits text colour from document
|
||||
* ce60958 - on more boolean argument for `setIframe` api to work cross-document issues #199
|
||||
|
||||
### v0.5.0
|
||||
|
||||
* 593893c - refactor inserting of contenteditable
|
||||
Adding `inserting_wrapper` for customize wrapping inserting content.
|
||||
Not to insert item as a block in Firefox. check out issue #109.
|
||||
Removing `getInsertedItems`, `getInsertedIDs` API. You have to collect them on your own.
|
||||
* 4d3fb8f - have to set IFRAME manually
|
||||
* 1f13a16 - change space_after to suffix
|
||||
* b099ebb - fix caret position error after inserting
|
||||
* 2c47d7a - fix #178 hide view while clicking somewhere else
|
||||
|
||||
### v0.4.12
|
||||
|
||||
* eeafab1 - fix error: will always call hidden atwho event
|
||||
* b0f6ceb - Highlighter finds the first occurrence
|
||||
* da256db - Adds possibility of having empty prefix (at keyword) in controllers
|
||||
* b884225 - add `space_after` option
|
||||
* 65d6273 - Passes esc/tab/return keyup events through to emitted hide event
|
||||
|
||||
### v0.4.11
|
||||
|
||||
* bf938db - add `delay` setting, support delay searching
|
||||
* a0b5a6f - fix bug: terminate if query out of max_len
|
||||
* 01d6d5b - add css min file
|
||||
|
||||
### v0.4.10
|
||||
|
||||
* update jquery dependence version
|
||||
|
||||
### v0.4.9
|
||||
|
||||
* f317bd7 not lowercase query, add `highlight_first` option
|
||||
|
||||
### v0.4.8
|
||||
|
||||
* 79bbef4 destroy atwho view container dom
|
||||
* 0372d65 update bower and component keywords
|
||||
* 52a41f5 add optional `before_repostion` callback
|
||||
* cc1c239 Fixes #143 - ichord
|
||||
|
||||
### v0.4.7
|
||||
|
||||
* resolved #133, #135, #137.
|
||||
* add `beforeDestroy` event
|
||||
* wouldn't concat `caret.js` into `dist/js/jquery.atwho.js` any more.
|
||||
* seperate `jquery.atwho.coffee` into pieces.
|
||||
* seperate testing.
|
||||
|
||||
### v0.4.6
|
||||
|
||||
* 2d9ab23 fix `wrong document` error in IE iframe
|
||||
|
||||
### v0.4.5
|
||||
|
||||
* 664a765 support iframe
|
||||
|
||||
### v0.4.4
|
||||
|
||||
* 9ac7e75 - improve contentEditable for IE 8
|
||||
|
||||
It's still some bugs in IE 8, just DON'T use it
|
||||
I don't want to spend more time on IE 8.
|
||||
So it would be the ending fixup. And i will still leave related code for
|
||||
a while maybe in case anyone want to help to improve it.
|
||||
Just encourge your users to upgrate the browers or just switch to a
|
||||
batter one please !!
|
||||
|
||||
* a8371b3 - move project page to master from gh-pages.
|
||||
* 24b6225 - fix bugs #122
|
||||
* 645e030 - update Caret.js to v0.0.5
|
||||
|
||||
### v0.4.3
|
||||
|
||||
* e8e7561 update `Caret.js` to `v0.0.4`
|
||||
|
||||
### v0.4.2
|
||||
|
||||
* 4169b74 - binding data storage to the inputor. issues #121
|
||||
* 11d053f - reduse querying twice. issues#112
|
||||
|
||||
### v0.4.1
|
||||
|
||||
* b7721be - fix bug at view id was not been assign. close issues #99
|
||||
* 407f069 - fix bug: Can not autofocus after click the at-list in FireFox. #95
|
||||
* 917f033 - fix bug: click do not work in div-contenteditable. close issues #93
|
||||
|
||||
### v0.4.0
|
||||
|
||||
* update `Caret.js` to `v0.0.2`
|
||||
* `contenteditable` support !!
|
||||
* change content of default item template `tpl`
|
||||
* new rule to insert the `at` : will always remove the `at` from inputor but will add it back from `tpl` in default.
|
||||
so, if you are using your own `tpl` and want to show the `at` char, you have to do it yourself.
|
||||
* add `insert_tpl` setting for `contenteditable`.
|
||||
it will insert `data-value` of li element that eval from `tpl` in default.
|
||||
* new APIs for `contenteditable`: `getInsertedItemsWithIDs`, `getInsertedItems`, `getInsertedIDs`
|
||||
|
||||
### 2013-08-07 - v0.3.2
|
||||
|
||||
* bower
|
||||
* remove `Caret.js` codes and add it as bower dependencies
|
||||
* remove `display_flag` settings.
|
||||
* add `start_with_space` settings, default `true`
|
||||
* change `super_call` function to `call_default`
|
||||
|
||||
### 2013-04-28
|
||||
|
||||
* release new api `load`, `run`
|
||||
* add `alias` setting for `load` data or as the view's id
|
||||
* matching key with a space before it
|
||||
* register key in settings `{at: "@", data: []}` instead of being a argument
|
||||
* `max_len` setting for max length to search
|
||||
* change the default matcher regrex rule: occur at start of line or after whitespace
|
||||
* will not sort the datay without valid query string
|
||||
|
||||
### 2013-04-23
|
||||
|
||||
* group all data handlers as `Model` class.
|
||||
* All callbacks's context would be current `Controller`
|
||||
|
||||
### 2013-04-05
|
||||
|
||||
* `data` setting will be used to load data either local or remote. If it's String as URL it will preload data from remote by launch a ajax request (every times At.js call `reg` to update settings)
|
||||
|
||||
* remove default `remote_filter` from callbacks list.
|
||||
* add `get_data` and `save_data` function to contoller. They are used to get and save whole data for At.js
|
||||
* `save_data` will invoke `data_refactor` everytime
|
||||
|
||||
* will filter local data which is set in `settings` first and if it get nothing then call `remote_filter` if it's exists in callbacks list that is set by user.
|
||||
|
||||
### 2013-04
|
||||
|
||||
* remove ability of changing common setting after inputor binded
|
||||
* can fix list view after matched query in IE now.
|
||||
* separated core function (get offset of inputor) as a jquery plugins.
|
||||
|
||||
### v0.2.0 - 2012-12
|
||||
|
||||
**No more testing in IEs browsers.**
|
||||
|
||||
#### Note
|
||||
The name `atWho` was changed to `atwho`.
|
||||
|
||||
#### New features
|
||||
|
||||
* Customer data handlers(matcher, filter, sorter) and template renders(highlight, template eval) by a group of configurable callbacks.
|
||||
* Support **AMD**
|
||||
|
||||
#### Removed features
|
||||
|
||||
* Filter by local data and remote (by ajax) data at the same time.
|
||||
* Caching
|
||||
* Mouse event
|
||||
|
||||
#### Changed settings
|
||||
|
||||
`-` mean removed option
|
||||
`+` mean new added option
|
||||
The one that start without `-` or `+` mean not change.
|
||||
|
||||
* `-` data: [],
|
||||
* `+` data: null,
|
||||
|
||||
* `-` choose: "data-value",
|
||||
* `+` search_key: "name",
|
||||
|
||||
* `-` callback: null,
|
||||
* `+` callbacks: DEFAULT_CALLBACKS,
|
||||
|
||||
* `+` display_timeout: 300,
|
||||
|
||||
* `-` tpl: _DEFAULT_TPL
|
||||
* `+` tpl: DEFAULT_TPL
|
||||
|
||||
* `-` cache: false
|
||||
|
||||
Not change settings
|
||||
|
||||
* cache: true,
|
||||
* limit: 5,
|
||||
* display_flag: true,
|
||||
|
||||
### v0.1.7
|
||||
|
||||
同步 `jquery-atwho-rails` gem 的版本号
|
||||
这会是 `v0.1` 的固定版本. 不再有新功能更新.
|
||||
|
||||
###v0.1.2 2012-3-23
|
||||
* box showing above instead of bottom when it get close to the bottom of window
|
||||
* coffeescript here is.
|
||||
* every registered character able to have thire own options such as template(`tpl`)
|
||||
* every inputor (textarea, input) able to have their own registered character and different behavior
|
||||
even the same character to other inputor
|
||||
|
||||
###v0.1.0
|
||||
* 可以監聽多個字符
|
||||
multiple char listening.
|
||||
* 顯示缺省列表.
|
||||
show default list.
|
37
static/assets/1af6739c/CONTRIBUTING.md
Normal file
37
static/assets/1af6739c/CONTRIBUTING.md
Normal file
@ -0,0 +1,37 @@
|
||||
## Contributing
|
||||
|
||||
### Code style
|
||||
|
||||
**Two** space indent
|
||||
|
||||
### Modifying the code
|
||||
First, ensure that you have the latest [Node.js](http://nodejs.org/) and [npm](http://npmjs.org/) installed.
|
||||
|
||||
Test that gulp is installed globally by running `grunt -v` at the command-line. If gulp isn't installed globally, run `npm install -g gulp` to install the latest version.
|
||||
|
||||
* Fork and clone the repo.
|
||||
* Run `npm install` and `bower install` to install all dev dependencies (including grunt).
|
||||
* Modify the `*.coffee` file.
|
||||
* Run `gulp` to build this project.
|
||||
|
||||
Assuming that you don't see any red, you're ready to go. Just be sure to run `gulp` after making any changes, to ensure that nothing is broken.
|
||||
|
||||
### Submitting pull requests
|
||||
|
||||
1. Create a new branch, please don't work in your `master` branch directly.
|
||||
1. Add failing tests for the change you want to make. Run `gulp` to see the tests fail.
|
||||
1. Fix stuff.
|
||||
1. Run `gulp` to see if the tests pass. Repeat steps 2-4 until done.
|
||||
1. Open `_SpecRunner.html` unit test file(s) in actual browser to ensure tests pass everywhere.
|
||||
1. Update the documentation to reflect any changes.
|
||||
1. Push to your fork and submit a pull request.
|
||||
|
||||
### notes
|
||||
|
||||
Please don't edit files in the `dist` subdirectory and *.js files in `src` as they are generated via gulp.
|
||||
You'll find source code in the `src` subdirectory!
|
||||
use `bower install` or `component install` to install dependencies first.
|
||||
|
||||
|
||||
### PhantomJS
|
||||
While gulp can run the included unit tests via [PhantomJS](http://phantomjs.org/), this shouldn't be considered a substitute for the real thing. Please be sure to test the `_SpecRunner.html` unit test file(s) in _actual_ browsers.
|
22
static/assets/1af6739c/LICENSE-MIT
Normal file
22
static/assets/1af6739c/LICENSE-MIT
Normal file
@ -0,0 +1,22 @@
|
||||
Copyright (c) 2013 chord.luo@gmail.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
67
static/assets/1af6739c/README.md
Normal file
67
static/assets/1af6739c/README.md
Normal file
@ -0,0 +1,67 @@
|
||||
**An autocompletion library to autocomplete mentions, smileys etc. just like on Github!**
|
||||
[![Build Status](https://travis-ci.org/ichord/At.js.png)](https://travis-ci.org/ichord/At.js)
|
||||
|
||||
#### Notice
|
||||
|
||||
At.js now **depends on** [Caret.js](https://github.com/ichord/Caret.js).
|
||||
Please read [**CHANGELOG.md**](CHANGELOG.md) for more details if you are going to update to new version.
|
||||
|
||||
### Demo
|
||||
http://ichord.github.com/At.js
|
||||
|
||||
### Documentation
|
||||
https://github.com/ichord/At.js/wiki
|
||||
|
||||
### Compatibility
|
||||
|
||||
* `textarea` - Chrome, Safari, Firefox, IE7+ (maybe IE6)
|
||||
* `contentEditable` - Chrome, Safari, Firefox, IE9+
|
||||
|
||||
### Features Preview
|
||||
|
||||
* Support IE 7+ for **textarea**.
|
||||
* Supports HTML5 [**contentEditable**](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_Editable) elements (NOT including IE 8)
|
||||
* Can listen to any character and not just '@'. Can set up multiple listeners for different characters with different behavior and data
|
||||
* Listener events can be bound to multiple inputors.
|
||||
* Format returned data using templates
|
||||
* Keyboard controls in addition to mouse
|
||||
- `Tab` or `Enter` keys select the value
|
||||
- `Up` and `Down` navigate between values (and `Ctrl-P` and `Ctrl-N` also)
|
||||
- `Right` and `left` will re-search the keyword.
|
||||
* Custom data handlers and template renderers using a group of configurable callbacks
|
||||
* Supports AMD
|
||||
|
||||
### Requirements
|
||||
|
||||
* jQuery >= 1.7.0.
|
||||
* [Caret.js](https://github.com/ichord/Caret.js)
|
||||
(You can use `Component` or `Bower` to install it.)
|
||||
|
||||
### Integrating with your Application
|
||||
|
||||
Simply include the following files in your HTML and you are good to go.
|
||||
|
||||
```html
|
||||
<link href="css/jquery.atwho.css" rel="stylesheet">
|
||||
<script src="http://code.jquery.com/jquery.js"></script>
|
||||
<script src="js/jquery.caret.js"></script>
|
||||
<script src="js/jquery.atwho.js"></script>
|
||||
```
|
||||
|
||||
```javascript
|
||||
$('#inputor').atwho({
|
||||
at: "@",
|
||||
data:['Peter', 'Tom', 'Anne']
|
||||
})
|
||||
```
|
||||
|
||||
#### Bower & Component
|
||||
For installing using Bower you can use `jquery.atwho` and for Component please use `ichord/At.js`.
|
||||
|
||||
#### Rails
|
||||
You can include At.js in your `Rails` application using the gem [jquery-atwho-rails](https://github.com/ichord/jquery-atwho-rails).
|
||||
|
||||
### Core Team Members
|
||||
|
||||
* [@ichord](https://twitter.com/_ichord) (twitter)
|
||||
|
32
static/assets/1af6739c/bower.json
Normal file
32
static/assets/1af6739c/bower.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "At.js",
|
||||
"version": "1.5.1",
|
||||
"main": [
|
||||
"dist/js/jquery.atwho.js",
|
||||
"dist/css/jquery.atwho.css"
|
||||
],
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"components",
|
||||
"libs",
|
||||
"spec"
|
||||
],
|
||||
"dependencies": {
|
||||
"jquery": ">=1.7.0",
|
||||
"Caret.js": "~0.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jasmine-jquery": "~2.0.2"
|
||||
},
|
||||
"keywords": [
|
||||
"mention",
|
||||
"mentions",
|
||||
"autocomplete",
|
||||
"autocompletion",
|
||||
"autosuggest",
|
||||
"autosuggestion",
|
||||
"atjs",
|
||||
"at.js"
|
||||
]
|
||||
}
|
32
static/assets/1af6739c/component.json
Normal file
32
static/assets/1af6739c/component.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "At.js",
|
||||
"repo": "ichord/At.js",
|
||||
"description": "Add Github like mentions autocomplete to your application.",
|
||||
"version": "1.5.1",
|
||||
"demo": "http://ichord.github.com/At.js",
|
||||
"dependencies": {
|
||||
"ichord/Caret.js": "~0.2.2",
|
||||
"component/jquery": ">= 1.7.0"
|
||||
},
|
||||
"main": [
|
||||
"dist/js/jquery.atwho.js"
|
||||
],
|
||||
"scripts": [
|
||||
"dist/js/jquery.atwho.js"
|
||||
],
|
||||
"styles": [
|
||||
"dist/css/jquery.atwho.css"
|
||||
],
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"mentions",
|
||||
"ui",
|
||||
"mentions",
|
||||
"autocomplete",
|
||||
"autocompletion",
|
||||
"autosuggest",
|
||||
"autosuggestion",
|
||||
"atjs",
|
||||
"at.js"
|
||||
]
|
||||
}
|
72
static/assets/1af6739c/dist/css/jquery.atwho.css
vendored
Normal file
72
static/assets/1af6739c/dist/css/jquery.atwho.css
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
.atwho-view {
|
||||
position:absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: none;
|
||||
margin-top: 18px;
|
||||
background: white;
|
||||
color: black;
|
||||
border: 1px solid #DDD;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 0 5px rgba(0,0,0,0.1);
|
||||
min-width: 120px;
|
||||
z-index: 11110 !important;
|
||||
}
|
||||
|
||||
.atwho-view .atwho-header {
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
cursor: pointer;
|
||||
border-bottom: solid 1px #eaeff1;
|
||||
color: #6f8092;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.atwho-view .atwho-header .small {
|
||||
color: #6f8092;
|
||||
float: right;
|
||||
padding-top: 2px;
|
||||
margin-right: -5px;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.atwho-view .atwho-header:hover {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.atwho-view .cur {
|
||||
background: #3366FF;
|
||||
color: white;
|
||||
}
|
||||
.atwho-view .cur small {
|
||||
color: white;
|
||||
}
|
||||
.atwho-view strong {
|
||||
color: #3366FF;
|
||||
}
|
||||
.atwho-view .cur strong {
|
||||
color: white;
|
||||
font:bold;
|
||||
}
|
||||
.atwho-view ul {
|
||||
/* width: 100px; */
|
||||
list-style:none;
|
||||
padding:0;
|
||||
margin:auto;
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.atwho-view ul li {
|
||||
display: block;
|
||||
padding: 5px 10px;
|
||||
border-bottom: 1px solid #DDD;
|
||||
cursor: pointer;
|
||||
/* border-top: 1px solid #C8C8C8; */
|
||||
}
|
||||
.atwho-view small {
|
||||
font-size: smaller;
|
||||
color: #777;
|
||||
font-weight: normal;
|
||||
}
|
1
static/assets/1af6739c/dist/css/jquery.atwho.min.css
vendored
Normal file
1
static/assets/1af6739c/dist/css/jquery.atwho.min.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
.atwho-view{position:absolute;top:0;left:0;display:none;margin-top:18px;background:#fff;color:#000;border:1px solid #DDD;border-radius:3px;box-shadow:0 0 5px rgba(0,0,0,.1);min-width:120px;z-index:11110!important}.atwho-view .atwho-header{padding:5px;margin:5px;cursor:pointer;border-bottom:solid 1px #eaeff1;color:#6f8092;font-size:11px;font-weight:700}.atwho-view .atwho-header .small{color:#6f8092;float:right;padding-top:2px;margin-right:-5px;font-size:12px;font-weight:400}.atwho-view .atwho-header:hover{cursor:default}.atwho-view .cur{background:#36F;color:#fff}.atwho-view .cur small{color:#fff}.atwho-view strong{color:#36F}.atwho-view .cur strong{color:#fff;font:700}.atwho-view ul{list-style:none;padding:0;margin:auto;max-height:200px;overflow-y:auto}.atwho-view ul li{display:block;padding:5px 10px;border-bottom:1px solid #DDD;cursor:pointer}.atwho-view small{font-size:smaller;color:#777;font-weight:400}
|
1213
static/assets/1af6739c/dist/js/jquery.atwho.js
vendored
Normal file
1213
static/assets/1af6739c/dist/js/jquery.atwho.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
static/assets/1af6739c/dist/js/jquery.atwho.min.js
vendored
Normal file
1
static/assets/1af6739c/dist/js/jquery.atwho.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Data Iframe</title>
|
||||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="http://ichord.github.io/Caret.js/src/jquery.caret.js"></script>
|
||||
<script type="text/javascript" src="../../dist/js/jquery.atwho.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
var names = ["Jacob","Isabella","Ethan","Emma","Michael","Olivia","Alexander","Sophia","William","Ava","Joshua","Emily","Daniel","Madison","Jayden","Abigail","Noah","Chloe","你好","你你你"];
|
||||
|
||||
var names = $.map(names,function(value,i) {
|
||||
return {'id':i,'name':value,'email':value+"@email.com"};
|
||||
});
|
||||
|
||||
viewFrame = parent.frames.viewFrame
|
||||
var at_config = {
|
||||
at: "@",
|
||||
data: names,
|
||||
displayTpl: "<li>${name} <small>${email}</small></li>"
|
||||
}
|
||||
$(viewFrame.document.body)
|
||||
.atwho('setIframe', viewFrame.frameElement, true)
|
||||
.atwho(at_config);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
90
static/assets/1af6739c/examples/cross_document/index.html
Normal file
90
static/assets/1af6739c/examples/cross_document/index.html
Normal file
@ -0,0 +1,90 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="x-ua-compatible" content="IE=Edge"/>
|
||||
<title>At.js</title>
|
||||
<style type="text/css">
|
||||
html, body {
|
||||
background:#F9F9F9;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font: 14px/1.6 "Lucida Grande", "Helvetica", sans-serif;
|
||||
color: #333;
|
||||
}
|
||||
h1,h2,h3,h4 {
|
||||
font-family: 'PT Sans', sans-serif;
|
||||
line-height: 40px;
|
||||
color: inherit;
|
||||
font-weight: bold;
|
||||
margin: 10px 0;
|
||||
text-rendering: optimizelegibility;
|
||||
}
|
||||
h2,h3 {
|
||||
color: gray;
|
||||
}
|
||||
strong {
|
||||
color: #424242;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #4183C4;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.wrapper {
|
||||
width: 750px;
|
||||
padding: 20px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
header {
|
||||
margin-top:70px;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
header h1 {
|
||||
text-align: center;
|
||||
font-size: 75px;
|
||||
}
|
||||
h1 i {
|
||||
color: rgb(182, 180, 180);
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.inputor {
|
||||
height: 260px;
|
||||
width: 90%;
|
||||
border: 1px solid #dadada;
|
||||
border-radius: 4px;
|
||||
padding: 5px 8px;
|
||||
outline: 0 none;
|
||||
margin: 10px 0;
|
||||
background: white;
|
||||
font-size: inherit;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.inputor:focus {
|
||||
border: 1px solid rgb(6, 150, 247);
|
||||
}
|
||||
|
||||
footer {
|
||||
margin: 30px 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="container wrapper">
|
||||
<header>
|
||||
<h1>At<i>.js</i></h1>
|
||||
</header>
|
||||
<div id="main">
|
||||
<h2>Cross-Document</h2>
|
||||
<iframe name="dataFrame" src="dataFrame.html" style="display:none;"></iframe>
|
||||
<iframe name="viewFrame" class="inputor" src="viewFrame.html"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>View Iframe</title>
|
||||
<link rel="stylesheet" href="../../dist/css/jquery.atwho.css" />
|
||||
</head>
|
||||
<body contenteditable=true style="height: 100%;">
|
||||
<p>hello!</p>
|
||||
</body>
|
||||
</html>
|
61
static/assets/1af6739c/examples/hashtags.html
Normal file
61
static/assets/1af6739c/examples/hashtags.html
Normal file
@ -0,0 +1,61 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="x-ua-compatible" content="IE=Edge"/>
|
||||
<title>At.js</title>
|
||||
<link rel="stylesheet" href="../dist/css/jquery.atwho.css" />
|
||||
<link rel="stylesheet" href="./style.css" />
|
||||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="http://ichord.github.io/Caret.js/src/jquery.caret.js"></script>
|
||||
<!-- // <script type="text/javascript" src="../bower_components/jquery/dist/jquery.js"></script> -->
|
||||
<!-- // <script type="text/javascript" src="../bower_components/Caret.js/dist/jquery.caret.js"></script> -->
|
||||
<script type="text/javascript" src="../dist/js/jquery.atwho.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
var jeremy = decodeURI("J%C3%A9r%C3%A9my") // Jérémy
|
||||
var tags = ["Jacob","Isabella","Ethan","Emma","Michael","Olivia","Alexander","Sophia","William","Ava","Joshua","Emily","Daniel","Madison","Jayden","Abigail","Noah","Chloe","你好","你你你", jeremy];
|
||||
$('#editable').atwho({
|
||||
at: "#",
|
||||
data: tags,
|
||||
limit: 200,
|
||||
callbacks: {
|
||||
afterMatchFailed: function(at, el) {
|
||||
// 32 is spacebar
|
||||
if (at == '#') {
|
||||
tags.push(el.text().trim().slice(1));
|
||||
this.model.save(tags);
|
||||
this.insert(el.text().trim());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<style type="text/css">
|
||||
/*override atwho's style*/
|
||||
.atwho-inserted {
|
||||
color: #4183C4;
|
||||
}
|
||||
.atwho-query {
|
||||
color: #4183C4;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container wrapper">
|
||||
<header>
|
||||
<h3>Type `#` to autocomplete tags</h3>
|
||||
</header>
|
||||
<div id="main">
|
||||
<div id="editable" class="inputor" contentEditable="true"></div>
|
||||
<footer>
|
||||
<h2>
|
||||
-> <a class="github" href="https://github.com/ichord/At.js">Fork me on GitHub!</a>
|
||||
</h2>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
44
static/assets/1af6739c/examples/medium-editor.html
Normal file
44
static/assets/1af6739c/examples/medium-editor.html
Normal file
@ -0,0 +1,44 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="x-ua-compatible" content="IE=Edge"/>
|
||||
<title>At.js</title>
|
||||
<link rel="stylesheet" href="../dist/css/jquery.atwho.css" />
|
||||
<link rel="stylesheet" type="text/css" href="http://dfimg.com/medium-editor/dist/css/medium-editor.css">
|
||||
<link rel="stylesheet" type="text/css" href="http://dfimg.com/medium-editor/dist/css/themes/default.css">
|
||||
<link rel="stylesheet" href="./style.css" />
|
||||
<!-- // <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> -->
|
||||
<!-- // <script type="text/javascript" src="http://ichord.github.io/Caret.js/src/jquery.caret.js"></script> -->
|
||||
<script type="text/javascript" src="../bower_components/jquery/dist/jquery.js"></script>
|
||||
<script type="text/javascript" src="../bower_components/Caret.js/dist/jquery.caret.js"></script>
|
||||
<script type="text/javascript" src="../dist/js/jquery.atwho.js"></script>
|
||||
<script src="http://dfimg.com/medium-editor/dist/js/medium-editor.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
var jeremy = decodeURI("J%C3%A9r%C3%A9my") // Jérémy
|
||||
var names = ["Jacob","Isabella","Ethan","Emma","Michael","Olivia","Alexander","Sophia","William","Ava","Joshua","Emily","Daniel","Madison","Jayden","Abigail","Noah","Chloe","你好","你你你", jeremy];
|
||||
var editor = new MediumEditor('#editor');
|
||||
$('#editor').atwho({at: "@", data: names});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container wrapper">
|
||||
<header>
|
||||
<h3>Example for medium-editor</h3>
|
||||
</header>
|
||||
<div id="main">
|
||||
<div id="editor" contentEditable>Easy! You should check out MoxieManager!</div>
|
||||
<footer>
|
||||
<h2>
|
||||
-> <a class="github" href="https://github.com/ichord/At.js">Fork me on GitHub!</a>
|
||||
</h2>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
57
static/assets/1af6739c/examples/style.css
Normal file
57
static/assets/1af6739c/examples/style.css
Normal file
@ -0,0 +1,57 @@
|
||||
html, body {
|
||||
background:#F9F9F9;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font: 14px/1.6 "Lucida Grande", "Helvetica", sans-serif;
|
||||
color: #333;
|
||||
}
|
||||
h1,h2,h3,h4 {
|
||||
font-family: 'PT Sans', sans-serif;
|
||||
line-height: 40px;
|
||||
color: inherit;
|
||||
font-weight: bold;
|
||||
margin: 10px 0;
|
||||
text-rendering: optimizelegibility;
|
||||
}
|
||||
h2,h3 {
|
||||
color: gray;
|
||||
}
|
||||
strong {
|
||||
color: #424242;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #4183C4;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.wrapper {
|
||||
width: 750px;
|
||||
padding: 20px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
header {
|
||||
margin-top:30px;
|
||||
}
|
||||
|
||||
.inputor {
|
||||
height: 160px;
|
||||
width: 90%;
|
||||
border: 1px solid #dadada;
|
||||
border-radius: 4px;
|
||||
padding: 5px 8px;
|
||||
outline: 0 none;
|
||||
margin: 10px 0;
|
||||
background: white;
|
||||
font-size: inherit;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.inputor:focus {
|
||||
border: 1px solid rgb(6, 150, 247);
|
||||
}
|
||||
|
||||
footer {
|
||||
margin: 30px 0;
|
||||
}
|
53
static/assets/1af6739c/examples/tinyMCE.html
Normal file
53
static/assets/1af6739c/examples/tinyMCE.html
Normal file
@ -0,0 +1,53 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="x-ua-compatible" content="IE=Edge"/>
|
||||
<title>At.js</title>
|
||||
<link rel="stylesheet" href="../dist/css/jquery.atwho.css" />
|
||||
<link rel="stylesheet" href="./style.css" />
|
||||
<!-- // <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> -->
|
||||
<!-- // <script type="text/javascript" src="http://ichord.github.io/Caret.js/src/jquery.caret.js"></script> -->
|
||||
<script type="text/javascript" src="../bower_components/jquery/dist/jquery.js"></script>
|
||||
<script type="text/javascript" src="../bower_components/Caret.js/dist/jquery.caret.js"></script>
|
||||
<script type="text/javascript" src="../dist/js/jquery.atwho.js"></script>
|
||||
<script src="http://tinymce.cachefly.net/4.1/tinymce.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
var jeremy = decodeURI("J%C3%A9r%C3%A9my") // Jérémy
|
||||
var names = ["Jacob","Isabella","Ethan","Emma","Michael","Olivia","Alexander","Sophia","William","Ava","Joshua","Emily","Daniel","Madison","Jayden","Abigail","Noah","Chloe","你好","你你你", jeremy];
|
||||
tinymce.init({
|
||||
selector: "#editor",
|
||||
init_instance_callback: function(editor) {
|
||||
$(editor.contentDocument.activeElement).atwho({at: "@", data: names});
|
||||
},
|
||||
setup: function(editor) {
|
||||
editor.on('keydown', function(e) {
|
||||
if(e.keyCode == 13 && $(editor.contentDocument.activeElement).atwho('isSelecting'))
|
||||
return false
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container wrapper">
|
||||
<header>
|
||||
<h3>Example for tinyMCE editor</h3>
|
||||
</header>
|
||||
<div id="main">
|
||||
<textarea id="editor">Easy! You should check out MoxieManager!</textarea>
|
||||
<footer>
|
||||
<h2>
|
||||
-> <a class="github" href="https://github.com/ichord/At.js">Fork me on GitHub!</a>
|
||||
</h2>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
45
static/assets/1af6739c/examples/ueditor.html
Normal file
45
static/assets/1af6739c/examples/ueditor.html
Normal file
@ -0,0 +1,45 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" href="http://ueditor.baidu.com/ueditor/themes/default/css/ueditor.css" />
|
||||
<link rel="stylesheet" href="../dist/css/jquery.atwho.css" />
|
||||
|
||||
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
|
||||
<script type="text/javascript" src="http://ichord.github.io/Caret.js/src/jquery.caret.js"></script>
|
||||
<script type="text/javascript" src="../dist/js/jquery.atwho.js"></script>
|
||||
|
||||
<title>ueditor</title>
|
||||
</head>
|
||||
<body>
|
||||
<script id="container" name="content" type="text/plain">
|
||||
test
|
||||
</script>
|
||||
<script src="http://ueditor.baidu.com/ueditor/ueditor.config.js"></script>
|
||||
<script src="http://ueditor.baidu.com/ueditor/ueditor.all.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
var ue = UE.getEditor('container');
|
||||
$(function(){
|
||||
var at_config = {
|
||||
at: "@",
|
||||
data:['Peter', 'Tom', 'Anne', 'zhangsan', 'lisi', 'wangwu', 'laoliu', 'libai', 'dupu', 'xiaozhou'],
|
||||
limit: 20
|
||||
}
|
||||
|
||||
var ue = UE.getEditor('container',{
|
||||
contextMenu:[],
|
||||
//focus时自动清空初始化时的内容
|
||||
autoClearinitialContent:true,
|
||||
//关闭字数统计
|
||||
wordCount:false,
|
||||
//关闭elementPath
|
||||
elementPathEnabled:false,
|
||||
});
|
||||
ue.addListener('ready', function(editor){
|
||||
$(this.document.body).atwho(at_config);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
103
static/assets/1af6739c/gulpfile.js
Normal file
103
static/assets/1af6739c/gulpfile.js
Normal file
@ -0,0 +1,103 @@
|
||||
var gulp = require('gulp'),
|
||||
coffee = require('gulp-coffee'),
|
||||
concat = require('gulp-concat'),
|
||||
umd = require('gulp-umd'),
|
||||
uglify = require('gulp-uglify'),
|
||||
rename = require("gulp-rename"),
|
||||
cssmin = require('gulp-cssmin'),
|
||||
jasmine = require('gulp-jasmine-phantom'),
|
||||
bump = require('gulp-bump'),
|
||||
header = require('gulp-header'),
|
||||
debug = require('gulp-debug'),
|
||||
util = require('gulp-util');
|
||||
|
||||
var name = 'jquery.atwho';
|
||||
|
||||
gulp.task('coffee', function() {
|
||||
gulp.src('src/*.coffee')
|
||||
.pipe(coffee({bare: true}).on('error', util.log))
|
||||
.pipe(gulp.dest('./build/js'));
|
||||
});
|
||||
|
||||
gulp.task('concat', function() {
|
||||
fileList = [
|
||||
'build/js/default.js',
|
||||
'build/js/app.js',
|
||||
'build/js/controller.js',
|
||||
'build/js/textareaController.js',
|
||||
'build/js/editableController.js',
|
||||
'build/js/model.js',
|
||||
'build/js/view.js',
|
||||
'build/js/api.js'
|
||||
]
|
||||
gulp.src(fileList)
|
||||
.pipe(concat(name + ".js"))
|
||||
.pipe(gulp.dest('build'));
|
||||
});
|
||||
|
||||
gulp.task('umd', function() {
|
||||
gulp.src('build/' + name + ".js")
|
||||
.pipe(umd({template: "umd.template.js"}))
|
||||
.pipe(gulp.dest('build/js'));
|
||||
});
|
||||
|
||||
gulp.task('bump', function() {
|
||||
gulp.src(['bower.json', 'component.json', 'package.json'])
|
||||
.pipe(bump({version: "1.5.1"}))
|
||||
.pipe(gulp.dest('./'));
|
||||
});
|
||||
|
||||
gulp.task("mark", function() {
|
||||
var pkg = require('./package.json');
|
||||
var banner = ['/**',
|
||||
' * <%= pkg.name %> - <%= pkg.version %>',
|
||||
' * Copyright (c) <%= year %> <%= pkg.author.name %> <<%= pkg.author.email %>>;',
|
||||
' * Homepage: <%= pkg.homepage %>',
|
||||
' * License: <%= pkg.license %>',
|
||||
' */',
|
||||
''].join('\n');
|
||||
|
||||
gulp.src('build/js/' + name + '.js')
|
||||
.pipe(header(banner, { pkg : pkg, year: (new Date).getFullYear()}))
|
||||
.pipe(gulp.dest('dist/js/'))
|
||||
});
|
||||
|
||||
gulp.task('compress', function() {
|
||||
gulp.src('dist/js/' + name + '.js')
|
||||
.pipe(uglify())
|
||||
.pipe(rename({suffix: '.min'}))
|
||||
.pipe(gulp.dest('dist/js'));
|
||||
|
||||
gulp.src('src/jquery.atwho.css').pipe(gulp.dest('dist/css'))
|
||||
gulp.src('dist/css/' + name + '.css')
|
||||
.pipe(cssmin())
|
||||
.pipe(rename({suffix: '.min'}))
|
||||
.pipe(gulp.dest('dist/css'));
|
||||
});
|
||||
|
||||
gulp.task('test', function () {
|
||||
gulp.src('spec/**/*.coffee')
|
||||
.pipe(coffee({bare: true}).on('error', util.log))
|
||||
.pipe(debug({title: "compiled specs"}))
|
||||
.pipe(gulp.dest('spec/build'))
|
||||
|
||||
gulp.src('spec/build/javascripts/*.spec.js')
|
||||
.pipe(jasmine({
|
||||
integration: true,
|
||||
specHtml: "specRunner.html"
|
||||
/* TODO: have to add css to spec
|
||||
vendor: [
|
||||
'bower_components/jquery/dist/jquery.js',
|
||||
'bower_components/Caret.js/dist/jquery.caret.js',
|
||||
'dist/js/jquery.atwho.js',
|
||||
'node_modules/jasmine-jquery/lib/*.js',
|
||||
'node_modules/jasmine-ajax/lib/*.js',
|
||||
'spec/helpers/*.js',
|
||||
'spec/build/spec_helper.js'
|
||||
],
|
||||
*/
|
||||
}));
|
||||
});
|
||||
|
||||
gulp.task('compile', ['coffee', 'umd', 'concat']);
|
||||
gulp.task('default', ['compile', 'bump', 'mark', 'compress']);
|
205
static/assets/1af6739c/index.html
Normal file
205
static/assets/1af6739c/index.html
Normal file
@ -0,0 +1,205 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="x-ua-compatible" content="IE=Edge"/>
|
||||
<title>At.js</title>
|
||||
<link rel="stylesheet" href="dist/css/jquery.atwho.css" />
|
||||
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
|
||||
<script type="text/javascript" src="https://ichord.github.io/Caret.js/src/jquery.caret.js"></script>
|
||||
<!-- <script type="text/javascript" src="bower_components/jquery/dist/jquery.js"></script> -->
|
||||
<!-- <script type="text/javascript" src="bower_components/Caret.js/dist/jquery.caret.js"></script> -->
|
||||
<script type="text/javascript" src="dist/js/jquery.atwho.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
$.fn.atwho.debug = true
|
||||
var emojis = [
|
||||
"smile", "iphone", "girl", "smiley", "heart", "kiss", "copyright", "coffee",
|
||||
"a", "ab", "airplane", "alien", "ambulance", "angel", "anger", "angry",
|
||||
"arrow_forward", "arrow_left", "arrow_lower_left", "arrow_lower_right",
|
||||
"arrow_right", "arrow_up", "arrow_upper_left", "arrow_upper_right",
|
||||
"art", "astonished", "atm", "b", "baby", "baby_chick", "baby_symbol",
|
||||
"balloon", "bamboo", "bank", "barber", "baseball", "basketball", "bath",
|
||||
"bear", "beer", "beers", "beginner", "bell", "bento", "bike", "bikini",
|
||||
"bird", "birthday", "black_square", "blue_car", "blue_heart", "blush",
|
||||
"boar", "boat", "bomb", "book", "boot", "bouquet", "bow", "bowtie",
|
||||
"boy", "bread", "briefcase", "broken_heart", "bug", "bulb",
|
||||
"person_with_blond_hair", "phone", "pig", "pill", "pisces", "plus1",
|
||||
"point_down", "point_left", "point_right", "point_up", "point_up_2",
|
||||
"police_car", "poop", "post_office", "postbox", "pray", "princess",
|
||||
"punch", "purple_heart", "question", "rabbit", "racehorse", "radio",
|
||||
"up", "us", "v", "vhs", "vibration_mode", "virgo", "vs", "walking",
|
||||
"warning", "watermelon", "wave", "wc", "wedding", "whale", "wheelchair",
|
||||
"white_square", "wind_chime", "wink", "wink2", "wolf", "woman",
|
||||
"womans_hat", "womens", "x", "yellow_heart", "zap", "zzz", "+1",
|
||||
"-1"
|
||||
]
|
||||
var jeremy = decodeURI("J%C3%A9r%C3%A9my") // Jérémy
|
||||
var names = ["Jacob","Isabella","Ethan","Emma","Michael","Olivia","Alexander","Sophia","William","Ava","Joshua","Emily","Daniel","Madison","Jayden","Abigail","Noah","Chloe","你好","你你你", jeremy, "가"];
|
||||
|
||||
var names = $.map(names,function(value,i) {
|
||||
return {'id':i,'name':value,'email':value+"@email.com"};
|
||||
});
|
||||
var emojis = $.map(emojis, function(value, i) {return {key: value, name:value}});
|
||||
|
||||
var at_config = {
|
||||
at: "@",
|
||||
data: names,
|
||||
headerTpl: '<div class="atwho-header">Member List<small>↑ ↓ </small></div>',
|
||||
insertTpl: '${name}',
|
||||
displayTpl: "<li>${name} <small>${email}</small></li>",
|
||||
limit: 200
|
||||
}
|
||||
var emoji_config = {
|
||||
at: ":",
|
||||
data: emojis,
|
||||
displayTpl: "<li>${name} <img src='https://assets-cdn.github.com/images/icons/emoji/${key}.png' height='20' width='20' /></li>",
|
||||
insertTpl: ':${key}:',
|
||||
delay: 400
|
||||
}
|
||||
$inputor = $('#inputor').atwho(at_config).atwho(emoji_config);
|
||||
$inputor.caret('pos', 47);
|
||||
$inputor.focus().atwho('run');
|
||||
|
||||
emoji_config.insertTpl = "<img src='https://assets-cdn.github.com/images/icons/emoji/${name}.png' height='20' width='20' />"
|
||||
$('#editable').atwho(at_config).atwho(emoji_config);
|
||||
|
||||
ifr = $('#iframe1')[0]
|
||||
doc = ifr.contentDocument || iframe.contentWindow.document
|
||||
if ((ifrBody = doc.body) == null) {
|
||||
// For IE
|
||||
doc.write("<body></body>")
|
||||
ifrBody = doc.body
|
||||
}
|
||||
ifrBody.contentEditable = true
|
||||
ifrBody.id = 'ifrBody'
|
||||
ifrBody.innerHTML = 'For <strong>WYSIWYG</strong> which using <strong>iframe</strong> such as <strong>ckeditor</strong>'
|
||||
$(ifrBody).atwho('setIframe', ifr).atwho(at_config)
|
||||
});
|
||||
|
||||
</script>
|
||||
<!--link href='http://fonts.googleapis.com/css?family=Dosis:400,700|Bubblegum+Sans|Overlock:400,900|PT+Sans:400,700|PT+Sans+Narrow:400,700|Magra|Asap:400,700|Share:400,700&subset=latin,latin-ext' rel='stylesheet' type='text/css' -->
|
||||
<link href='http://fonts.googleapis.com/css?family=PT+Sans:400,700' rel='stylesheet' type='text/css'>
|
||||
|
||||
<style type="text/css">
|
||||
html, body {
|
||||
background:#F9F9F9;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font: 14px/1.6 "Lucida Grande", "Helvetica", sans-serif;
|
||||
color: #333;
|
||||
}
|
||||
h1,h2,h3,h4 {
|
||||
font-family: 'PT Sans', sans-serif;
|
||||
line-height: 40px;
|
||||
color: inherit;
|
||||
font-weight: bold;
|
||||
margin: 10px 0;
|
||||
text-rendering: optimizelegibility;
|
||||
}
|
||||
h2,h3 {
|
||||
color: gray;
|
||||
}
|
||||
strong {
|
||||
color: #424242;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #4183C4;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.wrapper {
|
||||
width: 750px;
|
||||
padding: 20px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
header {
|
||||
margin-top:70px;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
header h1 {
|
||||
text-align: center;
|
||||
font-size: 75px;
|
||||
}
|
||||
h1 i {
|
||||
color: rgb(182, 180, 180);
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.inputor {
|
||||
height: 160px;
|
||||
width: 90%;
|
||||
border: 1px solid #dadada;
|
||||
border-radius: 4px;
|
||||
padding: 5px 8px;
|
||||
outline: 0 none;
|
||||
margin: 10px 0;
|
||||
background: white;
|
||||
font-size: inherit;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.inputor:focus {
|
||||
border: 1px solid rgb(6, 150, 247);
|
||||
}
|
||||
|
||||
ul.doc {
|
||||
list-style:none;
|
||||
}
|
||||
ul.doc li {
|
||||
display:inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
footer {
|
||||
margin: 30px 0;
|
||||
}
|
||||
|
||||
.github {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="container wrapper">
|
||||
<!-- <a id="github" href="https://github.com/ichord/At.js" target="_blank"><img style="position: absolute; top: 0; right: 0; border: 0; z-index:999" src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a> -->
|
||||
|
||||
<header>
|
||||
<h1>At<i>.js</i></h1>
|
||||
</header>
|
||||
<div id="main">
|
||||
<div>
|
||||
<textarea id="inputor" class="inputor">At.js, a github-like autocomplete library :s</textarea>
|
||||
</div>
|
||||
|
||||
<div id="editable" class="inputor" contentEditable="true">
|
||||
<p>
|
||||
<b>And!!</b> it support <b style="font-size: 20px">ContentEditable</b> mode too!!
|
||||
<img src="https://assets-cdn.github.com/images/icons/emoji/smile.png" height="20" width="20">
|
||||
<img src="https://assets-cdn.github.com/images/icons/emoji/smiley.png" height="20" width="20">
|
||||
<img src="https://assets-cdn.github.com/images/icons/emoji/coffee.png" height="20" width="20">
|
||||
</p>
|
||||
<p>
|
||||
<b>Try here now!</b><img src="https://assets-cdn.github.com/images/icons/emoji/point_right.png" height="20" width="20">
|
||||
<b>:h</b>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="inputor" style="overflow: hidden">
|
||||
<iframe src="" id="iframe1" style="width: 100%; height: 100%; border: 0px;"></iframe>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<h2>
|
||||
-> <a class="github" href="https://github.com/ichord/At.js">Fork me on GitHub!</a>
|
||||
</h2>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
54
static/assets/1af6739c/package.json
Normal file
54
static/assets/1af6739c/package.json
Normal file
@ -0,0 +1,54 @@
|
||||
{
|
||||
"name": "at.js",
|
||||
"main": "dist/js/jquery.atwho.js",
|
||||
"author": {
|
||||
"name": "chord.luo",
|
||||
"email": "chord.luo@gmail.com"
|
||||
},
|
||||
"homepage": "http://ichord.github.com/At.js",
|
||||
"license": "MIT",
|
||||
"version": "1.5.1",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ichord/At.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "gulp test"
|
||||
},
|
||||
"dependencies": {
|
||||
"gulp-bump": "^1.0.0",
|
||||
"gulp-header": "^1.7.1",
|
||||
"jquery": "^1.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gulp": "^3.9.0",
|
||||
"gulp-coffee": "^2.3.1",
|
||||
"gulp-concat": "^2.6.0",
|
||||
"gulp-cssmin": "^0.1.7",
|
||||
"gulp-debug": "^2.1.2",
|
||||
"gulp-jasmine": "^2.2.1",
|
||||
"gulp-jasmine-phantom": "^2.0.1",
|
||||
"gulp-rename": "^1.2.2",
|
||||
"gulp-uglify": "^1.5.1",
|
||||
"gulp-umd": "^0.2.0",
|
||||
"gulp-util": "^3.0.7",
|
||||
"jasmine-ajax": "^3.2.0",
|
||||
"jasmine-jquery": "^2.1.1",
|
||||
"phantomjs": "^1.9.19"
|
||||
},
|
||||
"spm": {
|
||||
"main": "dist/js/jquery.atwho.js",
|
||||
"dependencies": {
|
||||
"jquery": ">=1.7.2",
|
||||
"caret.js": "~0.2.2"
|
||||
},
|
||||
"ignore": [
|
||||
"examples",
|
||||
"spec",
|
||||
"src"
|
||||
]
|
||||
}
|
||||
}
|
31
static/assets/1af6739c/specRunner.html
Normal file
31
static/assets/1af6739c/specRunner.html
Normal file
@ -0,0 +1,31 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="node_modules/gulp-jasmine-phantom/vendor/jasmine-2.0/jasmine.css" />
|
||||
<link rel="stylesheet" type="text/css" href="dist/css/jquery.atwho.css" />
|
||||
<script type="text/javascript" src="node_modules/gulp-jasmine-phantom/vendor/jasmine-2.0/jasmine.js"></script>
|
||||
<script type="text/javascript" src="node_modules/gulp-jasmine-phantom/vendor/jasmine-2.0/jasmine-html.js"></script>
|
||||
<script type="text/javascript" src="node_modules/gulp-jasmine-phantom/vendor/jasmine-2.0/console.js"></script>
|
||||
<script type="text/javascript" src="node_modules/gulp-jasmine-phantom/vendor/jasmine-2.0/boot.js"></script>
|
||||
<script type="text/javascript" src="bower_components/jquery/dist/jquery.js"></script>
|
||||
<script type="text/javascript" src="bower_components/Caret.js/dist/jquery.caret.js"></script>
|
||||
<script type="text/javascript" src="dist/js/jquery.atwho.js"></script>
|
||||
<script type="text/javascript" src="node_modules/jasmine-jquery/lib/jasmine-jquery.js"></script>
|
||||
<script type="text/javascript" src="node_modules/jasmine-ajax/lib/mock-ajax.js"></script>
|
||||
<script type="text/javascript" src="spec/helpers/noConflict.js"></script>
|
||||
<script type="text/javascript" src="spec/build/spec_helper.js"></script>
|
||||
<script type="text/javascript" src="spec/build/javascripts/apis.spec.js"></script>
|
||||
<script type="text/javascript" src="spec/build/javascripts/content_editable.spec.js"></script>
|
||||
<script type="text/javascript" src="spec/build/javascripts/custom_callbacks.spec.js"></script>
|
||||
<script type="text/javascript" src="spec/build/javascripts/default_callbacks.spec.js"></script>
|
||||
<script type="text/javascript" src="spec/build/javascripts/events.spec.js"></script>
|
||||
<script type="text/javascript" src="spec/build/javascripts/iframe.spec.js"></script>
|
||||
<script type="text/javascript" src="spec/build/javascripts/settings.spec.js"></script>
|
||||
<script type="text/javascript" src="spec/build/javascripts/view.spec.js"></script>
|
||||
|
||||
<script type"text/javascript" src="node_modules/gulp-jasmine-phantom/lib/specRunner.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
58
static/assets/1af6739c/src/api.coffee
Normal file
58
static/assets/1af6739c/src/api.coffee
Normal file
@ -0,0 +1,58 @@
|
||||
Api =
|
||||
# load a flag's data
|
||||
#
|
||||
# @params at[String] the flag
|
||||
# @params data [Array] data to storage.
|
||||
load: (at, data) -> c.model.load data if c = this.controller(at)
|
||||
isSelecting: () -> !!this.controller()?.view.visible()
|
||||
hide: () -> this.controller()?.view.hide()
|
||||
reposition: () ->
|
||||
if c = this.controller()
|
||||
c.view.reposition(c.rect())
|
||||
setIframe: (iframe, asRoot) -> this.setupRootElement(iframe, asRoot); null;
|
||||
run: -> this.dispatch()
|
||||
destroy: ->
|
||||
this.shutdown()
|
||||
@$inputor.data('atwho', null)
|
||||
|
||||
$.fn.atwho = (method) ->
|
||||
_args = arguments
|
||||
result = null
|
||||
this.filter('textarea, input, [contenteditable=""], [contenteditable=true]').each ->
|
||||
if not app = ($this = $ this).data "atwho"
|
||||
$this.data 'atwho', (app = new App this)
|
||||
if typeof method is 'object' || !method
|
||||
app.reg method.at, method
|
||||
else if Api[method] and app
|
||||
result = Api[method].apply app, Array::slice.call(_args, 1)
|
||||
else
|
||||
$.error "Method #{method} does not exist on jQuery.atwho"
|
||||
if result? then result else this
|
||||
|
||||
$.fn.atwho.default =
|
||||
at: undefined
|
||||
alias: undefined
|
||||
data: null
|
||||
displayTpl: "<li>${name}</li>"
|
||||
insertTpl: "${atwho-at}${name}"
|
||||
headerTpl: null
|
||||
callbacks: DEFAULT_CALLBACKS
|
||||
searchKey: "name"
|
||||
suffix: undefined
|
||||
hideWithoutSuffix: no
|
||||
startWithSpace: yes
|
||||
acceptSpaceBar: false
|
||||
highlightFirst: yes
|
||||
limit: 5
|
||||
maxLen: 20
|
||||
minLen: 0
|
||||
displayTimeout: 300
|
||||
delay: null
|
||||
spaceSelectsMatch: no
|
||||
tabSelectsMatch: yes
|
||||
editableAtwhoQueryAttrs: {}
|
||||
scrollDuration: 150
|
||||
suspendOnComposing: true
|
||||
lookUpOnClick: true
|
||||
|
||||
$.fn.atwho.debug = false
|
158
static/assets/1af6739c/src/app.coffee
Normal file
158
static/assets/1af6739c/src/app.coffee
Normal file
@ -0,0 +1,158 @@
|
||||
# At.js central contoller(searching, matching, evaluating and rendering.)
|
||||
class App
|
||||
|
||||
# @param inputor [HTML DOM Object] `input` or `textarea`
|
||||
constructor: (inputor) ->
|
||||
@currentFlag = null
|
||||
@controllers = {}
|
||||
@aliasMaps = {}
|
||||
@$inputor = $(inputor)
|
||||
this.setupRootElement()
|
||||
this.listen()
|
||||
|
||||
createContainer: (doc) ->
|
||||
@$el?.remove()
|
||||
$ doc.body
|
||||
.append @$el = $ "<div class='atwho-container'></div>"
|
||||
|
||||
setupRootElement: (iframe, asRoot=false) ->
|
||||
if iframe
|
||||
@window = iframe.contentWindow
|
||||
@document = iframe.contentDocument || @window.document
|
||||
@iframe = iframe
|
||||
else
|
||||
@document = @$inputor[0].ownerDocument
|
||||
@window = @document.defaultView || @document.parentWindow
|
||||
try
|
||||
@iframe = @window.frameElement
|
||||
catch error
|
||||
@iframe = null
|
||||
if $.fn.atwho.debug
|
||||
throw new Error """
|
||||
iframe auto-discovery is failed.
|
||||
Please use `setIframe` to set the target iframe manually.
|
||||
#{error}
|
||||
"""
|
||||
this.createContainer if @iframeAsRoot = asRoot then @document else document
|
||||
|
||||
controller: (at) ->
|
||||
if @aliasMaps[at]
|
||||
current = @controllers[@aliasMaps[at]]
|
||||
else
|
||||
for currentFlag, c of @controllers
|
||||
if currentFlag is at
|
||||
current = c
|
||||
break
|
||||
|
||||
if current then current else @controllers[@currentFlag]
|
||||
|
||||
setContextFor: (at) ->
|
||||
@currentFlag = at
|
||||
this
|
||||
|
||||
# At.js can register multiple at char (flag) to every inputor such as "@" and ":"
|
||||
# Along with their own `settings` so that it works differently.
|
||||
# After register, we still can update their `settings` such as updating `data`
|
||||
#
|
||||
# @param flag [String] at char (flag)
|
||||
# @param settings [Hash] the settings
|
||||
reg: (flag, setting) ->
|
||||
controller = @controllers[flag] ||=
|
||||
if @$inputor.is '[contentEditable]'
|
||||
new EditableController this, flag
|
||||
else
|
||||
new TextareaController this, flag
|
||||
# TODO: it will produce rubbish alias map, reduse this.
|
||||
@aliasMaps[setting.alias] = flag if setting.alias
|
||||
controller.init setting
|
||||
this
|
||||
|
||||
# binding jQuery events of `inputor`'s
|
||||
listen: ->
|
||||
@$inputor
|
||||
.on 'compositionstart', (e) =>
|
||||
this.controller()?.view.hide()
|
||||
@isComposing = true
|
||||
null
|
||||
.on 'compositionend', (e) =>
|
||||
@isComposing = false
|
||||
setTimeout((e) => @dispatch(e))
|
||||
null
|
||||
.on 'keyup.atwhoInner', (e) =>
|
||||
this.onKeyup(e)
|
||||
.on 'keydown.atwhoInner', (e) =>
|
||||
this.onKeydown(e)
|
||||
.on 'blur.atwhoInner', (e) =>
|
||||
if c = this.controller()
|
||||
c.expectedQueryCBId = null
|
||||
c.view.hide(e,c.getOpt("displayTimeout"))
|
||||
.on 'click.atwhoInner', (e) =>
|
||||
this.dispatch e
|
||||
.on 'scroll.atwhoInner', do =>
|
||||
# make returned handler handle the very first call properly
|
||||
lastScrollTop = @$inputor.scrollTop()
|
||||
(e) =>
|
||||
currentScrollTop = e.target.scrollTop
|
||||
if lastScrollTop != currentScrollTop
|
||||
@controller()?.view.hide(e)
|
||||
lastScrollTop = currentScrollTop
|
||||
true # ensure we don't stop bubbling
|
||||
|
||||
shutdown: ->
|
||||
for _, c of @controllers
|
||||
c.destroy()
|
||||
delete @controllers[_]
|
||||
@$inputor.off '.atwhoInner'
|
||||
@$el.remove()
|
||||
|
||||
dispatch: (e) ->
|
||||
c.lookUp(e) for _, c of @controllers
|
||||
|
||||
onKeyup: (e) ->
|
||||
switch e.keyCode
|
||||
when KEY_CODE.ESC
|
||||
e.preventDefault()
|
||||
this.controller()?.view.hide()
|
||||
when KEY_CODE.DOWN, KEY_CODE.UP, KEY_CODE.CTRL, KEY_CODE.ENTER
|
||||
$.noop()
|
||||
when KEY_CODE.P, KEY_CODE.N
|
||||
this.dispatch e if not e.ctrlKey
|
||||
else
|
||||
this.dispatch e
|
||||
# coffeescript will return everywhere!!
|
||||
return
|
||||
|
||||
onKeydown: (e) ->
|
||||
# return if not (view = this.controller().view).visible()
|
||||
view = this.controller()?.view
|
||||
return if not (view and view.visible())
|
||||
switch e.keyCode
|
||||
when KEY_CODE.ESC
|
||||
e.preventDefault()
|
||||
view.hide(e)
|
||||
when KEY_CODE.UP
|
||||
e.preventDefault()
|
||||
view.prev()
|
||||
when KEY_CODE.DOWN
|
||||
e.preventDefault()
|
||||
view.next()
|
||||
when KEY_CODE.P
|
||||
return if not e.ctrlKey
|
||||
e.preventDefault()
|
||||
view.prev()
|
||||
when KEY_CODE.N
|
||||
return if not e.ctrlKey
|
||||
e.preventDefault()
|
||||
view.next()
|
||||
when KEY_CODE.TAB, KEY_CODE.ENTER, KEY_CODE.SPACE
|
||||
return if not view.visible()
|
||||
return if not this.controller().getOpt('spaceSelectsMatch') and e.keyCode == KEY_CODE.SPACE
|
||||
return if not this.controller().getOpt('tabSelectsMatch') and e.keyCode == KEY_CODE.TAB
|
||||
if view.highlighted()
|
||||
e.preventDefault()
|
||||
view.choose(e)
|
||||
else
|
||||
view.hide(e)
|
||||
else
|
||||
$.noop()
|
||||
return
|
142
static/assets/1af6739c/src/controller.coffee
Normal file
142
static/assets/1af6739c/src/controller.coffee
Normal file
@ -0,0 +1,142 @@
|
||||
class Controller
|
||||
uid: ->
|
||||
(Math.random().toString(16)+"000000000").substr(2,8) + (new Date().getTime())
|
||||
|
||||
constructor: (@app, @at) ->
|
||||
@$inputor = @app.$inputor
|
||||
@id = @$inputor[0].id || this.uid()
|
||||
@expectedQueryCBId = null
|
||||
|
||||
@setting = null
|
||||
@query = null
|
||||
@pos = 0
|
||||
@range = null
|
||||
if (@$el = $("#atwho-ground-#{@id}", @app.$el)).length == 0
|
||||
@app.$el.append @$el = $("<div id='atwho-ground-#{@id}'></div>")
|
||||
|
||||
@model = new Model(this)
|
||||
@view = new View(this)
|
||||
|
||||
init: (setting) ->
|
||||
@setting = $.extend {}, @setting || $.fn.atwho.default, setting
|
||||
@view.init()
|
||||
@model.reload @setting.data
|
||||
|
||||
destroy: ->
|
||||
this.trigger 'beforeDestroy'
|
||||
@model.destroy()
|
||||
@view.destroy()
|
||||
@$el.remove()
|
||||
|
||||
callDefault: (funcName, args...) ->
|
||||
try
|
||||
DEFAULT_CALLBACKS[funcName].apply this, args
|
||||
catch error
|
||||
$.error "#{error} Or maybe At.js doesn't have function #{funcName}"
|
||||
|
||||
# Delegate custom `jQueryEvent` to the inputor
|
||||
# This function will add `atwho` as namespace to every jQuery event
|
||||
# and pass current context as the last param to it.
|
||||
#
|
||||
# @example
|
||||
# this.trigger "roll_n_rock", [1,2,3,4]
|
||||
#
|
||||
# $inputor.on "rool_n_rock", (e, one, two, three, four) ->
|
||||
# console.log one, two, three, four
|
||||
#
|
||||
# @param name [String] Event name
|
||||
# @param data [Array] data to callback
|
||||
trigger: (name, data=[]) ->
|
||||
data.push this
|
||||
alias = this.getOpt('alias')
|
||||
eventName = if alias then "#{name}-#{alias}.atwho" else "#{name}.atwho"
|
||||
@$inputor.trigger eventName, data
|
||||
|
||||
# Get callback either in settings which was set by plugin user or in default callbacks list.
|
||||
#
|
||||
# @param funcName [String] callback's name
|
||||
# @return [Function] The callback.
|
||||
callbacks: (funcName)->
|
||||
this.getOpt("callbacks")[funcName] || DEFAULT_CALLBACKS[funcName]
|
||||
|
||||
# Because different registered at chars have different settings.
|
||||
# so we should give their own for them.
|
||||
#
|
||||
# @param at [String] setting's at name
|
||||
# @param default_value [?] return this if nothing is returned from current settings.
|
||||
# @return [?] setting's value
|
||||
getOpt: (at, default_value) ->
|
||||
try
|
||||
@setting[at]
|
||||
catch e
|
||||
null
|
||||
|
||||
insertContentFor: ($li) ->
|
||||
tpl = this.getOpt('insertTpl')
|
||||
data = $.extend {}, $li.data('item-data'), {'atwho-at': @at}
|
||||
this.callbacks("tplEval").call(this, tpl, data, "onInsert")
|
||||
|
||||
# Render list view
|
||||
#
|
||||
# @param data [Array] The data
|
||||
renderView: (data) ->
|
||||
searchKey = this.getOpt("searchKey")
|
||||
data = this.callbacks("sorter").call(this, @query.text, data[0..1000] , searchKey)
|
||||
@view.render data[0...this.getOpt('limit')]
|
||||
|
||||
@arrayToDefaultHash: (data) ->
|
||||
return data if not $.isArray data
|
||||
for item in data
|
||||
if $.isPlainObject item then item else name:item
|
||||
|
||||
# Searching!
|
||||
lookUp: (e) ->
|
||||
return if e && e.type == 'click' && !@getOpt('lookUpOnClick')
|
||||
return if @getOpt('suspendOnComposing') and @app.isComposing
|
||||
query = @catchQuery e
|
||||
if not query
|
||||
@expectedQueryCBId = null
|
||||
return query
|
||||
@app.setContextFor @at
|
||||
if wait = this.getOpt('delay')
|
||||
@_delayLookUp query, wait
|
||||
else
|
||||
@_lookUp query
|
||||
query
|
||||
|
||||
_delayLookUp: (query, wait) ->
|
||||
now = if Date.now then Date.now() else new Date().getTime()
|
||||
@previousCallTime ||= now
|
||||
remaining = wait - (now - @previousCallTime)
|
||||
if 0 < remaining < wait
|
||||
@previousCallTime = now
|
||||
@_stopDelayedCall()
|
||||
@delayedCallTimeout = setTimeout(=>
|
||||
@previousCallTime = 0
|
||||
@delayedCallTimeout = null
|
||||
@_lookUp query
|
||||
, wait)
|
||||
else
|
||||
@_stopDelayedCall()
|
||||
@previousCallTime = 0 if @previousCallTime isnt now
|
||||
@_lookUp query
|
||||
|
||||
_stopDelayedCall: ->
|
||||
if @delayedCallTimeout
|
||||
clearTimeout @delayedCallTimeout
|
||||
@delayedCallTimeout = null
|
||||
|
||||
_generateQueryCBId: ->
|
||||
return {};
|
||||
|
||||
_lookUp: (query) ->
|
||||
_callback = (queryCBId, data) ->
|
||||
# ensure only the latest instance of this function perform actions
|
||||
if queryCBId isnt @expectedQueryCBId
|
||||
return
|
||||
if data and data.length > 0
|
||||
this.renderView @constructor.arrayToDefaultHash data
|
||||
else
|
||||
@view.hide()
|
||||
@expectedQueryCBId = @_generateQueryCBId()
|
||||
@model.query query.text, $.proxy(_callback, this, @expectedQueryCBId)
|
147
static/assets/1af6739c/src/default.coffee
Normal file
147
static/assets/1af6739c/src/default.coffee
Normal file
@ -0,0 +1,147 @@
|
||||
KEY_CODE =
|
||||
ESC: 27
|
||||
TAB: 9
|
||||
ENTER: 13
|
||||
CTRL: 17
|
||||
A: 65
|
||||
P: 80
|
||||
N: 78
|
||||
LEFT: 37
|
||||
UP:38
|
||||
RIGHT: 39
|
||||
DOWN: 40
|
||||
BACKSPACE: 8
|
||||
SPACE: 32
|
||||
|
||||
# Functions set for handling and rendering the data.
|
||||
# Others developers can override these methods to tweak At.js such as matcher.
|
||||
# We can override them in `callbacks` settings.
|
||||
#
|
||||
# @mixin
|
||||
#
|
||||
# The context of these functions is `$.atwho.Controller` object and they are called in this sequences:
|
||||
#
|
||||
# [beforeSave, matcher, filter, remoteFilter, sorter, tplEvl, highlighter, beforeInsert, afterMatchFailed]
|
||||
#
|
||||
DEFAULT_CALLBACKS =
|
||||
|
||||
# It would be called to restructure the data before At.js invokes `Model#save` to save data
|
||||
# By default, At.js will convert it to a Hash Array.
|
||||
#
|
||||
# @param data [Array] data to refacotor.
|
||||
# @return [Array] Data after refactor.
|
||||
beforeSave: (data) ->
|
||||
Controller.arrayToDefaultHash data
|
||||
|
||||
# It would be called to match the `flag`.
|
||||
# It will match at start of line or after whitespace
|
||||
#
|
||||
# @param flag [String] current `flag` ("@", etc)
|
||||
# @param subtext [String] Text from start to current caret position.
|
||||
# @param should_startWithSpace [boolean] accept white space as beginning of match.
|
||||
# @param acceptSpaceBar [boolean] accept a space bar in the center of match,
|
||||
# so you can match a first and last name, for ex.
|
||||
#
|
||||
# @return [String | null] Matched result.
|
||||
matcher: (flag, subtext, should_startWithSpace, acceptSpaceBar) ->
|
||||
# escape RegExp
|
||||
flag = flag.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")
|
||||
flag = '(?:^|\\s)' + flag if should_startWithSpace
|
||||
|
||||
# À
|
||||
_a = decodeURI("%C3%80")
|
||||
# ÿ
|
||||
_y = decodeURI("%C3%BF")
|
||||
space = if acceptSpaceBar then "\ " else ""
|
||||
regexp = new RegExp "#{flag}([A-Za-z#{_a}-#{_y}0-9_#{space}\'\.\+\-]*)$|#{flag}([^\\x00-\\xff]*)$",'gi'
|
||||
match = regexp.exec subtext
|
||||
if match then match[2] || match[1] else null
|
||||
|
||||
# ---------------------
|
||||
|
||||
# Filter data by matched string.
|
||||
#
|
||||
# @param query [String] Matched string.
|
||||
# @param data [Array] data list
|
||||
# @param searchKey [String] at char for searching.
|
||||
#
|
||||
# @return [Array] result data.
|
||||
filter: (query, data, searchKey) ->
|
||||
# !!null #=> false; !!undefined #=> false; !!'' #=> false;
|
||||
_results = []
|
||||
for item in data
|
||||
_results.push item if ~new String(item[searchKey]).toLowerCase().indexOf query.toLowerCase()
|
||||
_results
|
||||
|
||||
# If a function is given, At.js will invoke it if local filter can not find any data
|
||||
#
|
||||
# @param params [String] matched query
|
||||
# @param callback [Function] callback to render page.
|
||||
remoteFilter: null
|
||||
# remoteFilter: (query, callback) ->
|
||||
# $.ajax url,
|
||||
# data: params
|
||||
# success: (data) ->
|
||||
# callback(data)
|
||||
|
||||
# Sorter data of course.
|
||||
#
|
||||
# @param query [String] matched string
|
||||
# @param items [Array] data that was refactored
|
||||
# @param searchKey [String] at char to search
|
||||
#
|
||||
# @return [Array] sorted data
|
||||
sorter: (query, items, searchKey) ->
|
||||
return items unless query
|
||||
|
||||
_results = []
|
||||
for item in items
|
||||
item.atwho_order = new String(item[searchKey]).toLowerCase().indexOf query.toLowerCase()
|
||||
_results.push item if item.atwho_order > -1
|
||||
|
||||
_results.sort (a,b) -> a.atwho_order - b.atwho_order
|
||||
|
||||
# Evaluate the template either as a string or as a function
|
||||
# this allows someone to pass in a set of data that needs a
|
||||
# different template for different data results
|
||||
#
|
||||
# @param tpl [function] the template function or string
|
||||
# @param map [Hash] Data map to eval.
|
||||
tplEval: (tpl, map) ->
|
||||
template = tpl
|
||||
try
|
||||
template = tpl(map) unless typeof tpl == 'string'
|
||||
template.replace /\$\{([^\}]*)\}/g, (tag, key, pos) -> map[key]
|
||||
catch error
|
||||
""
|
||||
|
||||
|
||||
# Highlight the `matched query` string.
|
||||
#
|
||||
# @param li [String] HTML String after eval.
|
||||
# @param query [String] matched query.
|
||||
#
|
||||
# @return [String] highlighted string.
|
||||
highlighter: (li, query) ->
|
||||
return li if not query
|
||||
regexp = new RegExp(">\\s*([^\<]*?)(" + query.replace("+","\\+") + ")([^\<]*)\\s*<", 'ig')
|
||||
li.replace regexp, (str, $1, $2, $3) -> '> '+$1+'<strong>' + $2 + '</strong>'+$3+' <'
|
||||
|
||||
# What to do before inserting item's value into inputor.
|
||||
#
|
||||
# @param value [String] content to insert
|
||||
# @param $li [jQuery Object] the chosen item
|
||||
# @param e [event Object] from the user selection (keyDown or click)
|
||||
beforeInsert: (value, $li, e) ->
|
||||
value
|
||||
|
||||
# You can adjust the menu's offset here.
|
||||
#
|
||||
# @param offset [Hash] offset will be applied to menu
|
||||
# beforeReposition: (offset) ->
|
||||
# offset.left += 10
|
||||
# offset.top += 10
|
||||
# offset
|
||||
beforeReposition: (offset) -> offset
|
||||
|
||||
afterMatchFailed: (at, el) ->
|
169
static/assets/1af6739c/src/editableController.coffee
Normal file
169
static/assets/1af6739c/src/editableController.coffee
Normal file
@ -0,0 +1,169 @@
|
||||
class EditableController extends Controller
|
||||
|
||||
_getRange: ->
|
||||
sel = @app.window.getSelection()
|
||||
sel.getRangeAt(0) if sel.rangeCount > 0
|
||||
|
||||
_setRange: (position, node, range=@_getRange()) ->
|
||||
return unless range and node
|
||||
node = $(node)[0]
|
||||
if position == 'after'
|
||||
range.setEndAfter node
|
||||
range.setStartAfter node
|
||||
else
|
||||
range.setEndBefore node
|
||||
range.setStartBefore node
|
||||
range.collapse false
|
||||
@_clearRange range
|
||||
|
||||
_clearRange: (range=@_getRange()) ->
|
||||
sel = @app.window.getSelection()
|
||||
#ctrl+a remove defaults using the flag
|
||||
if !@ctrl_a_pressed?
|
||||
sel.removeAllRanges()
|
||||
sel.addRange range
|
||||
|
||||
_movingEvent: (e) ->
|
||||
e.type == 'click' or e.which in [KEY_CODE.RIGHT, KEY_CODE.LEFT, KEY_CODE.UP, KEY_CODE.DOWN]
|
||||
|
||||
_unwrap: (node) ->
|
||||
node = $(node).unwrap().get 0
|
||||
if (next = node.nextSibling) and next.nodeValue
|
||||
node.nodeValue += next.nodeValue
|
||||
$(next).remove()
|
||||
node
|
||||
|
||||
catchQuery: (e) ->
|
||||
return unless range = @_getRange()
|
||||
return unless range.collapsed
|
||||
|
||||
if e.which == KEY_CODE.ENTER
|
||||
($query = $(range.startContainer).closest '.atwho-query')
|
||||
.contents().unwrap()
|
||||
$query.remove() if $query.is ':empty'
|
||||
($query = $ ".atwho-query", @app.document)
|
||||
.text $query.text()
|
||||
.contents().last().unwrap()
|
||||
@_clearRange()
|
||||
return
|
||||
|
||||
# absorb range
|
||||
# The range at the end of an element is not inside in firefox but not others browsers including IE.
|
||||
# To normolize them, we have to move the range inside the element while deleting content or moving caret right after .atwho-inserted
|
||||
if /firefox/i.test(navigator.userAgent)
|
||||
if $(range.startContainer).is @$inputor
|
||||
@_clearRange()
|
||||
return
|
||||
if e.which == KEY_CODE.BACKSPACE and range.startContainer.nodeType == document.ELEMENT_NODE \
|
||||
and (offset = range.startOffset - 1) >= 0
|
||||
_range = range.cloneRange()
|
||||
_range.setStart range.startContainer, offset
|
||||
if $(_range.cloneContents()).contents().last().is '.atwho-inserted'
|
||||
inserted = $(range.startContainer).contents().get(offset)
|
||||
@_setRange 'after', $(inserted).contents().last()
|
||||
else if e.which == KEY_CODE.LEFT and range.startContainer.nodeType == document.TEXT_NODE
|
||||
$inserted = $ range.startContainer.previousSibling
|
||||
if $inserted.is('.atwho-inserted') and range.startOffset == 0
|
||||
@_setRange 'after', $inserted.contents().last()
|
||||
|
||||
# modifying inserted element
|
||||
$(range.startContainer)
|
||||
.closest '.atwho-inserted'
|
||||
.addClass 'atwho-query'
|
||||
.siblings().removeClass 'atwho-query'
|
||||
|
||||
if ($query = $ ".atwho-query", @app.document).length > 0 \
|
||||
and $query.is(':empty') and $query.text().length == 0
|
||||
$query.remove()
|
||||
|
||||
if not @_movingEvent e
|
||||
$query.removeClass 'atwho-inserted'
|
||||
|
||||
if $query.length > 0
|
||||
switch e.which
|
||||
when KEY_CODE.LEFT
|
||||
@_setRange 'before', $query.get(0), range
|
||||
$query.removeClass 'atwho-query'
|
||||
return
|
||||
when KEY_CODE.RIGHT
|
||||
@_setRange 'after', $query.get(0).nextSibling, range
|
||||
$query.removeClass 'atwho-query'
|
||||
return
|
||||
|
||||
# matching
|
||||
if $query.length > 0 and query_content = $query.attr('data-atwho-at-query')
|
||||
$query.empty().html(query_content).attr('data-atwho-at-query', null)
|
||||
@_setRange 'after', $query.get(0), range
|
||||
_range = range.cloneRange()
|
||||
_range.setStart range.startContainer, 0
|
||||
matched = @callbacks("matcher").call(this, @at, _range.toString(), @getOpt('startWithSpace'), @getOpt("acceptSpaceBar"))
|
||||
isString = typeof matched is 'string'
|
||||
|
||||
# wrapping query with .atwho-query
|
||||
if $query.length == 0 and isString \
|
||||
and (index = range.startOffset - @at.length - matched.length) >= 0
|
||||
range.setStart range.startContainer, index
|
||||
$query = $ '<span/>', @app.document
|
||||
.attr @getOpt "editableAtwhoQueryAttrs"
|
||||
.addClass 'atwho-query'
|
||||
range.surroundContents $query.get 0
|
||||
lastNode = $query.contents().last().get(0)
|
||||
if lastNode
|
||||
if /firefox/i.test navigator.userAgent
|
||||
range.setStart lastNode, lastNode.length
|
||||
range.setEnd lastNode, lastNode.length
|
||||
@_clearRange range
|
||||
else
|
||||
@_setRange 'after', lastNode, range
|
||||
|
||||
return if isString and matched.length < @getOpt('minLen', 0)
|
||||
|
||||
# handle the matched result
|
||||
if isString and matched.length <= @getOpt('maxLen', 20)
|
||||
query = text: matched, el: $query
|
||||
@trigger "matched", [@at, query.text]
|
||||
@query = query
|
||||
else
|
||||
@view.hide()
|
||||
@query = el: $query
|
||||
if $query.text().indexOf(this.at) >= 0
|
||||
if @_movingEvent(e) and $query.hasClass 'atwho-inserted'
|
||||
$query.removeClass('atwho-query')
|
||||
else if false != @callbacks('afterMatchFailed').call this, @at, $query
|
||||
@_setRange "after", @_unwrap $query.text($query.text()).contents().first()
|
||||
null
|
||||
|
||||
# Get offset of current at char(`flag`)
|
||||
#
|
||||
# @return [Hash] the offset which look likes this: {top: y, left: x, bottom: bottom}
|
||||
rect: ->
|
||||
rect = @query.el.offset()
|
||||
return unless rect
|
||||
if @app.iframe and not @app.iframeAsRoot
|
||||
iframeOffset = ($iframe = $ @app.iframe).offset()
|
||||
rect.left += iframeOffset.left - @$inputor.scrollLeft()
|
||||
rect.top += iframeOffset.top - @$inputor.scrollTop()
|
||||
rect.bottom = rect.top + @query.el.height()
|
||||
rect
|
||||
|
||||
# Insert value of `data-value` attribute of chosen item into inputor
|
||||
#
|
||||
# @param content [String] string to insert
|
||||
insert: (content, $li) ->
|
||||
@$inputor.focus() unless @$inputor.is ':focus'
|
||||
suffix = if (suffix = @getOpt 'suffix') == "" then suffix else suffix or "\u00A0"
|
||||
data = $li.data('item-data')
|
||||
@query.el
|
||||
.removeClass 'atwho-query'
|
||||
.addClass 'atwho-inserted'
|
||||
.html content
|
||||
.attr 'data-atwho-at-query', "" + data['atwho-at'] + @query.text
|
||||
.attr 'contenteditable', "false"
|
||||
if range = @_getRange()
|
||||
if @query.el.length
|
||||
range.setEndAfter @query.el[0]
|
||||
range.collapse false
|
||||
range.insertNode suffixNode = @app.document.createTextNode "" + suffix
|
||||
@_setRange 'after', suffixNode, range
|
||||
@$inputor.focus() unless @$inputor.is ':focus'
|
||||
@$inputor.change()
|
72
static/assets/1af6739c/src/jquery.atwho.css
Normal file
72
static/assets/1af6739c/src/jquery.atwho.css
Normal file
@ -0,0 +1,72 @@
|
||||
.atwho-view {
|
||||
position:absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: none;
|
||||
margin-top: 18px;
|
||||
background: white;
|
||||
color: black;
|
||||
border: 1px solid #DDD;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 0 5px rgba(0,0,0,0.1);
|
||||
min-width: 120px;
|
||||
z-index: 11110 !important;
|
||||
}
|
||||
|
||||
.atwho-view .atwho-header {
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
cursor: pointer;
|
||||
border-bottom: solid 1px #eaeff1;
|
||||
color: #6f8092;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.atwho-view .atwho-header .small {
|
||||
color: #6f8092;
|
||||
float: right;
|
||||
padding-top: 2px;
|
||||
margin-right: -5px;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.atwho-view .atwho-header:hover {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.atwho-view .cur {
|
||||
background: #3366FF;
|
||||
color: white;
|
||||
}
|
||||
.atwho-view .cur small {
|
||||
color: white;
|
||||
}
|
||||
.atwho-view strong {
|
||||
color: #3366FF;
|
||||
}
|
||||
.atwho-view .cur strong {
|
||||
color: white;
|
||||
font:bold;
|
||||
}
|
||||
.atwho-view ul {
|
||||
/* width: 100px; */
|
||||
list-style:none;
|
||||
padding:0;
|
||||
margin:auto;
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.atwho-view ul li {
|
||||
display: block;
|
||||
padding: 5px 10px;
|
||||
border-bottom: 1px solid #DDD;
|
||||
cursor: pointer;
|
||||
/* border-top: 1px solid #C8C8C8; */
|
||||
}
|
||||
.atwho-view small {
|
||||
font-size: smaller;
|
||||
color: #777;
|
||||
font-weight: normal;
|
||||
}
|
59
static/assets/1af6739c/src/model.coffee
Normal file
59
static/assets/1af6739c/src/model.coffee
Normal file
@ -0,0 +1,59 @@
|
||||
# Class to process data
|
||||
class Model
|
||||
|
||||
constructor: (@context) ->
|
||||
@at = @context.at
|
||||
# NOTE: bind data storage to inputor maybe App class can handle it.
|
||||
@storage = @context.$inputor
|
||||
|
||||
destroy: ->
|
||||
@storage.data(@at, null)
|
||||
|
||||
saved: ->
|
||||
this.fetch() > 0
|
||||
|
||||
# fetch data from storage by query.
|
||||
# will invoke `callback` to return data
|
||||
#
|
||||
# @param query [String] catched string for searching
|
||||
# @param callback [Function] for receiving data
|
||||
query: (query, callback) ->
|
||||
data = this.fetch()
|
||||
searchKey = @context.getOpt("searchKey")
|
||||
data = @context.callbacks('filter').call(@context, query, data, searchKey) || []
|
||||
_remoteFilter = @context.callbacks('remoteFilter')
|
||||
if data.length > 0 or (!_remoteFilter and data.length == 0)
|
||||
callback data
|
||||
else
|
||||
_remoteFilter.call(@context, query, callback)
|
||||
|
||||
# get or set current data which would be shown on the list view.
|
||||
#
|
||||
# @param data [Array] set data
|
||||
# @return [Array|undefined] current data that are showing on the list view.
|
||||
fetch: ->
|
||||
@storage.data(@at) || []
|
||||
|
||||
# save special flag's data to storage
|
||||
#
|
||||
# @param data [Array] data to save
|
||||
save: (data) ->
|
||||
@storage.data @at, @context.callbacks("beforeSave").call(@context, data || [])
|
||||
|
||||
# load data. It wouldn't load for a second time if it has been loaded.
|
||||
#
|
||||
# @param data [Array] data to load
|
||||
load: (data) ->
|
||||
this._load(data) unless this.saved() or not data
|
||||
|
||||
reload: (data) ->
|
||||
this._load(data)
|
||||
|
||||
# load data from local or remote with callback
|
||||
#
|
||||
# @param data [Array|String] data to load.
|
||||
_load: (data) ->
|
||||
if typeof data is "string"
|
||||
$.ajax(data, dataType: "json").done (data) => this.save(data)
|
||||
else
|
||||
this.save data
|
51
static/assets/1af6739c/src/textareaController.coffee
Normal file
51
static/assets/1af6739c/src/textareaController.coffee
Normal file
@ -0,0 +1,51 @@
|
||||
class TextareaController extends Controller
|
||||
# Catch query string behind the at char
|
||||
#
|
||||
# @return [Hash] Info of the query. Look likes this: {'text': "hello", 'headPos': 0, 'endPos': 0}
|
||||
catchQuery: ->
|
||||
content = @$inputor.val()
|
||||
caretPos = @$inputor.caret('pos', {iframe: @app.iframe})
|
||||
subtext = content.slice(0, caretPos)
|
||||
query = this.callbacks("matcher").call(this, @at, subtext, this.getOpt('startWithSpace'), @getOpt("acceptSpaceBar"))
|
||||
isString = typeof query is 'string'
|
||||
|
||||
return if isString and query.length < this.getOpt('minLen', 0)
|
||||
|
||||
if isString and query.length <= this.getOpt('maxLen', 20)
|
||||
start = caretPos - query.length
|
||||
end = start + query.length
|
||||
@pos = start
|
||||
query = {'text': query, 'headPos': start, 'endPos': end}
|
||||
this.trigger "matched", [@at, query.text]
|
||||
else
|
||||
query = null
|
||||
@view.hide()
|
||||
|
||||
@query = query
|
||||
|
||||
# Get offset of current at char(`flag`)
|
||||
#
|
||||
# @return [Hash] the offset which look likes this: {top: y, left: x, bottom: bottom}
|
||||
rect: ->
|
||||
return if not c = @$inputor.caret('offset', @pos - 1, {iframe: @app.iframe})
|
||||
if @app.iframe and not @app.iframeAsRoot
|
||||
iframeOffset = $(@app.iframe).offset()
|
||||
c.left += iframeOffset.left
|
||||
c.top += iframeOffset.top
|
||||
scaleBottom = if @app.document.selection then 0 else 2
|
||||
{left: c.left, top: c.top, bottom: c.top + c.height + scaleBottom}
|
||||
|
||||
# Insert value of `data-value` attribute of chosen item into inputor
|
||||
#
|
||||
# @param content [String] string to insert
|
||||
insert: (content, $li) ->
|
||||
$inputor = @$inputor
|
||||
source = $inputor.val()
|
||||
startStr = source.slice 0, Math.max(@query.headPos - @at.length, 0)
|
||||
suffix = if (suffix = @getOpt 'suffix') == "" then suffix else suffix or " "
|
||||
content += suffix
|
||||
text = "#{startStr}#{content}#{source.slice @query['endPos'] || 0}"
|
||||
$inputor.val text
|
||||
$inputor.caret('pos', startStr.length + content.length, {iframe: @app.iframe})
|
||||
$inputor.focus() unless $inputor.is ':focus'
|
||||
$inputor.change()
|
136
static/assets/1af6739c/src/view.coffee
Normal file
136
static/assets/1af6739c/src/view.coffee
Normal file
@ -0,0 +1,136 @@
|
||||
# View class to control how At.js's view showing.
|
||||
# All classes share the same DOM view.
|
||||
class View
|
||||
|
||||
# @param controller [Object] The Controller.
|
||||
constructor: (@context) ->
|
||||
@$el = $("<div class='atwho-view'><ul class='atwho-view-ul'></ul></div>")
|
||||
@$elUl = @$el.children();
|
||||
@timeoutID = null
|
||||
# create HTML DOM of list view if it does not exist
|
||||
@context.$el.append(@$el)
|
||||
this.bindEvent()
|
||||
|
||||
init: ->
|
||||
id = @context.getOpt("alias") || @context.at.charCodeAt(0)
|
||||
header_tpl = this.context.getOpt("headerTpl")
|
||||
if (header_tpl && this.$el.children().length == 1)
|
||||
this.$el.prepend(header_tpl)
|
||||
@$el.attr('id': "at-view-#{id}")
|
||||
|
||||
destroy: ->
|
||||
@$el.remove()
|
||||
|
||||
bindEvent: ->
|
||||
$menu = @$el.find('ul')
|
||||
lastCoordX = 0
|
||||
lastCoordY = 0
|
||||
$menu.on 'mousemove.atwho-view','li', (e) =>
|
||||
# If the mouse hasn't actually moved then exit.
|
||||
return if lastCoordX == e.clientX and lastCoordY == e.clientY
|
||||
lastCoordX = e.clientX
|
||||
lastCoordY = e.clientY
|
||||
$cur = $(e.currentTarget)
|
||||
return if $cur.hasClass('cur')
|
||||
$menu.find('.cur').removeClass 'cur'
|
||||
$cur.addClass 'cur'
|
||||
.on 'click.atwho-view', 'li', (e) =>
|
||||
$menu.find('.cur').removeClass 'cur'
|
||||
$(e.currentTarget).addClass 'cur'
|
||||
this.choose(e)
|
||||
e.preventDefault()
|
||||
|
||||
# Check if view is visible
|
||||
#
|
||||
# @return [Boolean]
|
||||
visible: ->
|
||||
$.expr.filters.visible(@$el[0])
|
||||
|
||||
highlighted: ->
|
||||
@$el.find(".cur").length > 0
|
||||
|
||||
choose: (e) ->
|
||||
if ($li = @$el.find ".cur").length
|
||||
content = @context.insertContentFor $li
|
||||
|
||||
@context._stopDelayedCall()
|
||||
@context.insert @context.callbacks("beforeInsert").call(@context, content, $li, e), $li
|
||||
@context.trigger "inserted", [$li, e]
|
||||
this.hide(e)
|
||||
@stopShowing = yes if @context.getOpt("hideWithoutSuffix")
|
||||
|
||||
reposition: (rect) ->
|
||||
_window = if @context.app.iframeAsRoot then @context.app.window else window
|
||||
if rect.bottom + @$el.height() - $(_window).scrollTop() > $(_window).height()
|
||||
rect.bottom = rect.top - @$el.height()
|
||||
if rect.left > overflowOffset = $(_window).width() - @$el.width() - 5
|
||||
rect.left = overflowOffset
|
||||
offset = {left:rect.left, top:rect.bottom}
|
||||
@context.callbacks("beforeReposition")?.call(@context, offset)
|
||||
@$el.offset offset
|
||||
@context.trigger "reposition", [offset]
|
||||
|
||||
next: ->
|
||||
cur = @$el.find('.cur').removeClass('cur')
|
||||
next = cur.next()
|
||||
next = @$el.find('li:first') if not next.length
|
||||
next.addClass 'cur'
|
||||
nextEl = next[0]
|
||||
offset = nextEl.offsetTop + nextEl.offsetHeight + (if nextEl.nextSibling then nextEl.nextSibling.offsetHeight else 0)
|
||||
@scrollTop Math.max(0, offset - this.$el.height())
|
||||
|
||||
prev: ->
|
||||
cur = @$el.find('.cur').removeClass('cur')
|
||||
prev = cur.prev()
|
||||
prev = @$el.find('li:last') if not prev.length
|
||||
prev.addClass 'cur'
|
||||
prevEl = prev[0]
|
||||
offset = prevEl.offsetTop + prevEl.offsetHeight + (if prevEl.nextSibling then prevEl.nextSibling.offsetHeight else 0)
|
||||
@scrollTop Math.max(0, offset - this.$el.height())
|
||||
|
||||
scrollTop: (scrollTop) ->
|
||||
scrollDuration = @context.getOpt('scrollDuration')
|
||||
if scrollDuration
|
||||
@$elUl.animate {scrollTop: scrollTop}, scrollDuration
|
||||
else
|
||||
@$elUl.scrollTop(scrollTop)
|
||||
|
||||
show: ->
|
||||
if @stopShowing
|
||||
@stopShowing = false
|
||||
return
|
||||
if not this.visible()
|
||||
@$el.show()
|
||||
@$el.scrollTop 0
|
||||
@context.trigger 'shown'
|
||||
this.reposition(rect) if rect = @context.rect()
|
||||
|
||||
hide: (e, time) ->
|
||||
return if not this.visible()
|
||||
if isNaN(time)
|
||||
@$el.hide()
|
||||
@context.trigger 'hidden', [e]
|
||||
else
|
||||
callback = => this.hide()
|
||||
clearTimeout @timeoutID
|
||||
@timeoutID = setTimeout callback, time
|
||||
|
||||
# render list view
|
||||
render: (list) ->
|
||||
if not ($.isArray(list) and list.length > 0)
|
||||
this.hide()
|
||||
return
|
||||
|
||||
@$el.find('ul').empty()
|
||||
$ul = @$el.find('ul')
|
||||
tpl = @context.getOpt('displayTpl')
|
||||
|
||||
for item in list
|
||||
item = $.extend {}, item, {'atwho-at': @context.at}
|
||||
li = @context.callbacks("tplEval").call(@context, tpl, item, "onDisplay")
|
||||
$li = $ @context.callbacks("highlighter").call(@context, li, @context.query.text)
|
||||
$li.data("item-data", item)
|
||||
$ul.append $li
|
||||
|
||||
this.show()
|
||||
$ul.find("li:first").addClass "cur" if @context.getOpt('highlightFirst')
|
17
static/assets/1af6739c/umd.template.js
Normal file
17
static/assets/1af6739c/umd.template.js
Normal file
@ -0,0 +1,17 @@
|
||||
(function (root, factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module unless amdModuleId is set
|
||||
define(["jquery"], function (a0) {
|
||||
return (factory(a0));
|
||||
});
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node. Does not work with strict CommonJS, but
|
||||
// only CommonJS-like environments that support module.exports,
|
||||
// like Node.
|
||||
module.exports = factory(require("jquery"));
|
||||
} else {
|
||||
factory(jQuery);
|
||||
}
|
||||
}(this, function ($) {
|
||||
<%= contents %>
|
||||
}));
|
64
static/assets/2744f39c/bower.json
Normal file
64
static/assets/2744f39c/bower.json
Normal file
@ -0,0 +1,64 @@
|
||||
{
|
||||
"name": "blueimp-file-upload",
|
||||
"version": "9.11.2",
|
||||
"title": "jQuery File Upload",
|
||||
"description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images.",
|
||||
"keywords": [
|
||||
"jquery",
|
||||
"file",
|
||||
"upload",
|
||||
"widget",
|
||||
"multiple",
|
||||
"selection",
|
||||
"drag",
|
||||
"drop",
|
||||
"progress",
|
||||
"preview",
|
||||
"cross-domain",
|
||||
"cross-site",
|
||||
"chunk",
|
||||
"resume",
|
||||
"gae",
|
||||
"go",
|
||||
"python",
|
||||
"php",
|
||||
"bootstrap"
|
||||
],
|
||||
"homepage": "https://github.com/blueimp/jQuery-File-Upload",
|
||||
"author": {
|
||||
"name": "Sebastian Tschan",
|
||||
"url": "https://blueimp.net"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "Sebastian Tschan",
|
||||
"url": "https://blueimp.net"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/blueimp/jQuery-File-Upload.git"
|
||||
},
|
||||
"bugs": "https://github.com/blueimp/jQuery-File-Upload/issues",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jquery": ">=1.6",
|
||||
"blueimp-tmpl": ">=2.5.4",
|
||||
"blueimp-load-image": ">=1.13.0",
|
||||
"blueimp-canvas-to-blob": ">=2.1.1"
|
||||
},
|
||||
"main": [
|
||||
"js/jquery.fileupload.js"
|
||||
],
|
||||
"ignore": [
|
||||
"/*.*",
|
||||
"/cors",
|
||||
"css/demo-ie8.css",
|
||||
"css/demo.css",
|
||||
"css/style.css",
|
||||
"js/app.js",
|
||||
"js/main.js",
|
||||
"server",
|
||||
"test"
|
||||
]
|
||||
}
|
22
static/assets/2744f39c/css/jquery.fileupload-noscript.css
Normal file
22
static/assets/2744f39c/css/jquery.fileupload-noscript.css
Normal file
@ -0,0 +1,22 @@
|
||||
@charset "UTF-8";
|
||||
/*
|
||||
* jQuery File Upload Plugin NoScript CSS
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
.fileinput-button input {
|
||||
position: static;
|
||||
opacity: 1;
|
||||
filter: none;
|
||||
font-size: inherit;
|
||||
direction: inherit;
|
||||
}
|
||||
.fileinput-button span {
|
||||
display: none;
|
||||
}
|
17
static/assets/2744f39c/css/jquery.fileupload-ui-noscript.css
Normal file
17
static/assets/2744f39c/css/jquery.fileupload-ui-noscript.css
Normal file
@ -0,0 +1,17 @@
|
||||
@charset "UTF-8";
|
||||
/*
|
||||
* jQuery File Upload UI Plugin NoScript CSS
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2012, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
.fileinput-button i,
|
||||
.fileupload-buttonbar .delete,
|
||||
.fileupload-buttonbar .toggle {
|
||||
display: none;
|
||||
}
|
57
static/assets/2744f39c/css/jquery.fileupload-ui.css
Normal file
57
static/assets/2744f39c/css/jquery.fileupload-ui.css
Normal file
@ -0,0 +1,57 @@
|
||||
@charset "UTF-8";
|
||||
/*
|
||||
* jQuery File Upload UI Plugin CSS
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2010, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
.fileupload-buttonbar .btn,
|
||||
.fileupload-buttonbar .toggle {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.progress-animated .progress-bar,
|
||||
.progress-animated .bar {
|
||||
background: url("../img/progressbar.gif") !important;
|
||||
filter: none;
|
||||
}
|
||||
.fileupload-process {
|
||||
float: right;
|
||||
display: none;
|
||||
}
|
||||
.fileupload-processing .fileupload-process,
|
||||
.files .processing .preview {
|
||||
display: block;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: url("../img/loading.gif") center no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
.files audio,
|
||||
.files video {
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.fileupload-buttonbar .toggle,
|
||||
.files .toggle,
|
||||
.files .btn span {
|
||||
display: none;
|
||||
}
|
||||
.files .name {
|
||||
width: 80px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.files audio,
|
||||
.files video {
|
||||
max-width: 80px;
|
||||
}
|
||||
.files img,
|
||||
.files canvas {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
37
static/assets/2744f39c/css/jquery.fileupload.css
Normal file
37
static/assets/2744f39c/css/jquery.fileupload.css
Normal file
@ -0,0 +1,37 @@
|
||||
@charset "UTF-8";
|
||||
/*
|
||||
* jQuery File Upload Plugin CSS
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
.fileinput-button {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
}
|
||||
.fileinput-button input {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
margin: 0;
|
||||
opacity: 0;
|
||||
-ms-filter: 'alpha(opacity=0)';
|
||||
font-size: 200px;
|
||||
direction: ltr;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Fixes for IE < 8 */
|
||||
@media screen\9 {
|
||||
.fileinput-button input {
|
||||
filter: alpha(opacity=0);
|
||||
font-size: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
BIN
static/assets/2744f39c/img/loading.gif
Normal file
BIN
static/assets/2744f39c/img/loading.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
BIN
static/assets/2744f39c/img/progressbar.gif
Normal file
BIN
static/assets/2744f39c/img/progressbar.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
120
static/assets/2744f39c/js/cors/jquery.postmessage-transport.js
Normal file
120
static/assets/2744f39c/js/cors/jquery.postmessage-transport.js
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* jQuery postMessage Transport Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2011, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, require, window, document */
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
'use strict';
|
||||
|
||||
var counter = 0,
|
||||
names = [
|
||||
'accepts',
|
||||
'cache',
|
||||
'contents',
|
||||
'contentType',
|
||||
'crossDomain',
|
||||
'data',
|
||||
'dataType',
|
||||
'headers',
|
||||
'ifModified',
|
||||
'mimeType',
|
||||
'password',
|
||||
'processData',
|
||||
'timeout',
|
||||
'traditional',
|
||||
'type',
|
||||
'url',
|
||||
'username'
|
||||
],
|
||||
convert = function (p) {
|
||||
return p;
|
||||
};
|
||||
|
||||
$.ajaxSetup({
|
||||
converters: {
|
||||
'postmessage text': convert,
|
||||
'postmessage json': convert,
|
||||
'postmessage html': convert
|
||||
}
|
||||
});
|
||||
|
||||
$.ajaxTransport('postmessage', function (options) {
|
||||
if (options.postMessage && window.postMessage) {
|
||||
var iframe,
|
||||
loc = $('<a>').prop('href', options.postMessage)[0],
|
||||
target = loc.protocol + '//' + loc.host,
|
||||
xhrUpload = options.xhr().upload;
|
||||
return {
|
||||
send: function (_, completeCallback) {
|
||||
counter += 1;
|
||||
var message = {
|
||||
id: 'postmessage-transport-' + counter
|
||||
},
|
||||
eventName = 'message.' + message.id;
|
||||
iframe = $(
|
||||
'<iframe style="display:none;" src="' +
|
||||
options.postMessage + '" name="' +
|
||||
message.id + '"></iframe>'
|
||||
).bind('load', function () {
|
||||
$.each(names, function (i, name) {
|
||||
message[name] = options[name];
|
||||
});
|
||||
message.dataType = message.dataType.replace('postmessage ', '');
|
||||
$(window).bind(eventName, function (e) {
|
||||
e = e.originalEvent;
|
||||
var data = e.data,
|
||||
ev;
|
||||
if (e.origin === target && data.id === message.id) {
|
||||
if (data.type === 'progress') {
|
||||
ev = document.createEvent('Event');
|
||||
ev.initEvent(data.type, false, true);
|
||||
$.extend(ev, data);
|
||||
xhrUpload.dispatchEvent(ev);
|
||||
} else {
|
||||
completeCallback(
|
||||
data.status,
|
||||
data.statusText,
|
||||
{postmessage: data.result},
|
||||
data.headers
|
||||
);
|
||||
iframe.remove();
|
||||
$(window).unbind(eventName);
|
||||
}
|
||||
}
|
||||
});
|
||||
iframe[0].contentWindow.postMessage(
|
||||
message,
|
||||
target
|
||||
);
|
||||
}).appendTo(document.body);
|
||||
},
|
||||
abort: function () {
|
||||
if (iframe) {
|
||||
iframe.remove();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
}));
|
89
static/assets/2744f39c/js/cors/jquery.xdr-transport.js
Normal file
89
static/assets/2744f39c/js/cors/jquery.xdr-transport.js
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* jQuery XDomainRequest Transport Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2011, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*
|
||||
* Based on Julian Aubourg's ajaxHooks xdr.js:
|
||||
* https://github.com/jaubourg/ajaxHooks/
|
||||
*/
|
||||
|
||||
/* global define, require, window, XDomainRequest */
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
'use strict';
|
||||
if (window.XDomainRequest && !$.support.cors) {
|
||||
$.ajaxTransport(function (s) {
|
||||
if (s.crossDomain && s.async) {
|
||||
if (s.timeout) {
|
||||
s.xdrTimeout = s.timeout;
|
||||
delete s.timeout;
|
||||
}
|
||||
var xdr;
|
||||
return {
|
||||
send: function (headers, completeCallback) {
|
||||
var addParamChar = /\?/.test(s.url) ? '&' : '?';
|
||||
function callback(status, statusText, responses, responseHeaders) {
|
||||
xdr.onload = xdr.onerror = xdr.ontimeout = $.noop;
|
||||
xdr = null;
|
||||
completeCallback(status, statusText, responses, responseHeaders);
|
||||
}
|
||||
xdr = new XDomainRequest();
|
||||
// XDomainRequest only supports GET and POST:
|
||||
if (s.type === 'DELETE') {
|
||||
s.url = s.url + addParamChar + '_method=DELETE';
|
||||
s.type = 'POST';
|
||||
} else if (s.type === 'PUT') {
|
||||
s.url = s.url + addParamChar + '_method=PUT';
|
||||
s.type = 'POST';
|
||||
} else if (s.type === 'PATCH') {
|
||||
s.url = s.url + addParamChar + '_method=PATCH';
|
||||
s.type = 'POST';
|
||||
}
|
||||
xdr.open(s.type, s.url);
|
||||
xdr.onload = function () {
|
||||
callback(
|
||||
200,
|
||||
'OK',
|
||||
{text: xdr.responseText},
|
||||
'Content-Type: ' + xdr.contentType
|
||||
);
|
||||
};
|
||||
xdr.onerror = function () {
|
||||
callback(404, 'Not Found');
|
||||
};
|
||||
if (s.xdrTimeout) {
|
||||
xdr.ontimeout = function () {
|
||||
callback(0, 'timeout');
|
||||
};
|
||||
xdr.timeout = s.xdrTimeout;
|
||||
}
|
||||
xdr.send((s.hasContent && s.data) || null);
|
||||
},
|
||||
abort: function () {
|
||||
if (xdr) {
|
||||
xdr.onerror = $.noop();
|
||||
xdr.abort();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
}));
|
425
static/assets/2744f39c/js/jquery.fileupload-angular.js
vendored
Normal file
425
static/assets/2744f39c/js/jquery.fileupload-angular.js
vendored
Normal file
@ -0,0 +1,425 @@
|
||||
/*
|
||||
* jQuery File Upload AngularJS Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* jshint nomen:false */
|
||||
/* global define, angular */
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define([
|
||||
'jquery',
|
||||
'angular',
|
||||
'./jquery.fileupload-image',
|
||||
'./jquery.fileupload-audio',
|
||||
'./jquery.fileupload-video',
|
||||
'./jquery.fileupload-validate'
|
||||
], factory);
|
||||
} else {
|
||||
factory();
|
||||
}
|
||||
}(function () {
|
||||
'use strict';
|
||||
|
||||
angular.module('blueimp.fileupload', [])
|
||||
|
||||
// The fileUpload service provides configuration options
|
||||
// for the fileUpload directive and default handlers for
|
||||
// File Upload events:
|
||||
.provider('fileUpload', function () {
|
||||
var scopeEvalAsync = function (expression) {
|
||||
var scope = angular.element(this)
|
||||
.fileupload('option', 'scope');
|
||||
// Schedule a new $digest cycle if not already inside of one
|
||||
// and evaluate the given expression:
|
||||
scope.$evalAsync(expression);
|
||||
},
|
||||
addFileMethods = function (scope, data) {
|
||||
var files = data.files,
|
||||
file = files[0];
|
||||
angular.forEach(files, function (file, index) {
|
||||
file._index = index;
|
||||
file.$state = function () {
|
||||
return data.state();
|
||||
};
|
||||
file.$processing = function () {
|
||||
return data.processing();
|
||||
};
|
||||
file.$progress = function () {
|
||||
return data.progress();
|
||||
};
|
||||
file.$response = function () {
|
||||
return data.response();
|
||||
};
|
||||
});
|
||||
file.$submit = function () {
|
||||
if (!file.error) {
|
||||
return data.submit();
|
||||
}
|
||||
};
|
||||
file.$cancel = function () {
|
||||
return data.abort();
|
||||
};
|
||||
},
|
||||
$config;
|
||||
$config = this.defaults = {
|
||||
handleResponse: function (e, data) {
|
||||
var files = data.result && data.result.files;
|
||||
if (files) {
|
||||
data.scope.replace(data.files, files);
|
||||
} else if (data.errorThrown ||
|
||||
data.textStatus === 'error') {
|
||||
data.files[0].error = data.errorThrown ||
|
||||
data.textStatus;
|
||||
}
|
||||
},
|
||||
add: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var scope = data.scope,
|
||||
filesCopy = [];
|
||||
angular.forEach(data.files, function (file) {
|
||||
filesCopy.push(file);
|
||||
});
|
||||
scope.$parent.$applyAsync(function () {
|
||||
addFileMethods(scope, data);
|
||||
var method = scope.option('prependFiles') ?
|
||||
'unshift' : 'push';
|
||||
Array.prototype[method].apply(scope.queue, data.files);
|
||||
});
|
||||
data.process(function () {
|
||||
return scope.process(data);
|
||||
}).always(function () {
|
||||
scope.$parent.$applyAsync(function () {
|
||||
addFileMethods(scope, data);
|
||||
scope.replace(filesCopy, data.files);
|
||||
});
|
||||
}).then(function () {
|
||||
if ((scope.option('autoUpload') ||
|
||||
data.autoUpload) &&
|
||||
data.autoUpload !== false) {
|
||||
data.submit();
|
||||
}
|
||||
});
|
||||
},
|
||||
done: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that = this;
|
||||
data.scope.$apply(function () {
|
||||
data.handleResponse.call(that, e, data);
|
||||
});
|
||||
},
|
||||
fail: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that = this,
|
||||
scope = data.scope;
|
||||
if (data.errorThrown === 'abort') {
|
||||
scope.clear(data.files);
|
||||
return;
|
||||
}
|
||||
scope.$apply(function () {
|
||||
data.handleResponse.call(that, e, data);
|
||||
});
|
||||
},
|
||||
stop: scopeEvalAsync,
|
||||
processstart: scopeEvalAsync,
|
||||
processstop: scopeEvalAsync,
|
||||
getNumberOfFiles: function () {
|
||||
var scope = this.scope;
|
||||
return scope.queue.length - scope.processing();
|
||||
},
|
||||
dataType: 'json',
|
||||
autoUpload: false
|
||||
};
|
||||
this.$get = [
|
||||
function () {
|
||||
return {
|
||||
defaults: $config
|
||||
};
|
||||
}
|
||||
];
|
||||
})
|
||||
|
||||
// Format byte numbers to readable presentations:
|
||||
.provider('formatFileSizeFilter', function () {
|
||||
var $config = {
|
||||
// Byte units following the IEC format
|
||||
// http://en.wikipedia.org/wiki/Kilobyte
|
||||
units: [
|
||||
{size: 1000000000, suffix: ' GB'},
|
||||
{size: 1000000, suffix: ' MB'},
|
||||
{size: 1000, suffix: ' KB'}
|
||||
]
|
||||
};
|
||||
this.defaults = $config;
|
||||
this.$get = function () {
|
||||
return function (bytes) {
|
||||
if (!angular.isNumber(bytes)) {
|
||||
return '';
|
||||
}
|
||||
var unit = true,
|
||||
i = 0,
|
||||
prefix,
|
||||
suffix;
|
||||
while (unit) {
|
||||
unit = $config.units[i];
|
||||
prefix = unit.prefix || '';
|
||||
suffix = unit.suffix || '';
|
||||
if (i === $config.units.length - 1 || bytes >= unit.size) {
|
||||
return prefix + (bytes / unit.size).toFixed(2) + suffix;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
|
||||
// The FileUploadController initializes the fileupload widget and
|
||||
// provides scope methods to control the File Upload functionality:
|
||||
.controller('FileUploadController', [
|
||||
'$scope', '$element', '$attrs', '$window', 'fileUpload',
|
||||
function ($scope, $element, $attrs, $window, fileUpload) {
|
||||
var uploadMethods = {
|
||||
progress: function () {
|
||||
return $element.fileupload('progress');
|
||||
},
|
||||
active: function () {
|
||||
return $element.fileupload('active');
|
||||
},
|
||||
option: function (option, data) {
|
||||
if (arguments.length === 1) {
|
||||
return $element.fileupload('option', option);
|
||||
}
|
||||
$element.fileupload('option', option, data);
|
||||
},
|
||||
add: function (data) {
|
||||
return $element.fileupload('add', data);
|
||||
},
|
||||
send: function (data) {
|
||||
return $element.fileupload('send', data);
|
||||
},
|
||||
process: function (data) {
|
||||
return $element.fileupload('process', data);
|
||||
},
|
||||
processing: function (data) {
|
||||
return $element.fileupload('processing', data);
|
||||
}
|
||||
};
|
||||
$scope.disabled = !$window.jQuery.support.fileInput;
|
||||
$scope.queue = $scope.queue || [];
|
||||
$scope.clear = function (files) {
|
||||
var queue = this.queue,
|
||||
i = queue.length,
|
||||
file = files,
|
||||
length = 1;
|
||||
if (angular.isArray(files)) {
|
||||
file = files[0];
|
||||
length = files.length;
|
||||
}
|
||||
while (i) {
|
||||
i -= 1;
|
||||
if (queue[i] === file) {
|
||||
return queue.splice(i, length);
|
||||
}
|
||||
}
|
||||
};
|
||||
$scope.replace = function (oldFiles, newFiles) {
|
||||
var queue = this.queue,
|
||||
file = oldFiles[0],
|
||||
i,
|
||||
j;
|
||||
for (i = 0; i < queue.length; i += 1) {
|
||||
if (queue[i] === file) {
|
||||
for (j = 0; j < newFiles.length; j += 1) {
|
||||
queue[i + j] = newFiles[j];
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
$scope.applyOnQueue = function (method) {
|
||||
var list = this.queue.slice(0),
|
||||
i,
|
||||
file;
|
||||
for (i = 0; i < list.length; i += 1) {
|
||||
file = list[i];
|
||||
if (file[method]) {
|
||||
file[method]();
|
||||
}
|
||||
}
|
||||
};
|
||||
$scope.submit = function () {
|
||||
this.applyOnQueue('$submit');
|
||||
};
|
||||
$scope.cancel = function () {
|
||||
this.applyOnQueue('$cancel');
|
||||
};
|
||||
// Add upload methods to the scope:
|
||||
angular.extend($scope, uploadMethods);
|
||||
// The fileupload widget will initialize with
|
||||
// the options provided via "data-"-parameters,
|
||||
// as well as those given via options object:
|
||||
$element.fileupload(angular.extend(
|
||||
{scope: $scope},
|
||||
fileUpload.defaults
|
||||
)).on('fileuploadadd', function (e, data) {
|
||||
data.scope = $scope;
|
||||
}).on('fileuploadfail', function (e, data) {
|
||||
if (data.errorThrown === 'abort') {
|
||||
return;
|
||||
}
|
||||
if (data.dataType &&
|
||||
data.dataType.indexOf('json') === data.dataType.length - 4) {
|
||||
try {
|
||||
data.result = angular.fromJson(data.jqXHR.responseText);
|
||||
} catch (ignore) {}
|
||||
}
|
||||
}).on([
|
||||
'fileuploadadd',
|
||||
'fileuploadsubmit',
|
||||
'fileuploadsend',
|
||||
'fileuploaddone',
|
||||
'fileuploadfail',
|
||||
'fileuploadalways',
|
||||
'fileuploadprogress',
|
||||
'fileuploadprogressall',
|
||||
'fileuploadstart',
|
||||
'fileuploadstop',
|
||||
'fileuploadchange',
|
||||
'fileuploadpaste',
|
||||
'fileuploaddrop',
|
||||
'fileuploaddragover',
|
||||
'fileuploadchunksend',
|
||||
'fileuploadchunkdone',
|
||||
'fileuploadchunkfail',
|
||||
'fileuploadchunkalways',
|
||||
'fileuploadprocessstart',
|
||||
'fileuploadprocess',
|
||||
'fileuploadprocessdone',
|
||||
'fileuploadprocessfail',
|
||||
'fileuploadprocessalways',
|
||||
'fileuploadprocessstop'
|
||||
].join(' '), function (e, data) {
|
||||
$scope.$parent.$applyAsync(function () {
|
||||
if ($scope.$emit(e.type, data).defaultPrevented) {
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
}).on('remove', function () {
|
||||
// Remove upload methods from the scope,
|
||||
// when the widget is removed:
|
||||
var method;
|
||||
for (method in uploadMethods) {
|
||||
if (uploadMethods.hasOwnProperty(method)) {
|
||||
delete $scope[method];
|
||||
}
|
||||
}
|
||||
});
|
||||
// Observe option changes:
|
||||
$scope.$watch(
|
||||
$attrs.fileUpload,
|
||||
function (newOptions) {
|
||||
if (newOptions) {
|
||||
$element.fileupload('option', newOptions);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
])
|
||||
|
||||
// Provide File Upload progress feedback:
|
||||
.controller('FileUploadProgressController', [
|
||||
'$scope', '$attrs', '$parse',
|
||||
function ($scope, $attrs, $parse) {
|
||||
var fn = $parse($attrs.fileUploadProgress),
|
||||
update = function () {
|
||||
var progress = fn($scope);
|
||||
if (!progress || !progress.total) {
|
||||
return;
|
||||
}
|
||||
$scope.num = Math.floor(
|
||||
progress.loaded / progress.total * 100
|
||||
);
|
||||
};
|
||||
update();
|
||||
$scope.$watch(
|
||||
$attrs.fileUploadProgress + '.loaded',
|
||||
function (newValue, oldValue) {
|
||||
if (newValue !== oldValue) {
|
||||
update();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
])
|
||||
|
||||
// Display File Upload previews:
|
||||
.controller('FileUploadPreviewController', [
|
||||
'$scope', '$element', '$attrs',
|
||||
function ($scope, $element, $attrs) {
|
||||
$scope.$watch(
|
||||
$attrs.fileUploadPreview + '.preview',
|
||||
function (preview) {
|
||||
$element.empty();
|
||||
if (preview) {
|
||||
$element.append(preview);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
])
|
||||
|
||||
.directive('fileUpload', function () {
|
||||
return {
|
||||
controller: 'FileUploadController',
|
||||
scope: true
|
||||
};
|
||||
})
|
||||
|
||||
.directive('fileUploadProgress', function () {
|
||||
return {
|
||||
controller: 'FileUploadProgressController',
|
||||
scope: true
|
||||
};
|
||||
})
|
||||
|
||||
.directive('fileUploadPreview', function () {
|
||||
return {
|
||||
controller: 'FileUploadPreviewController'
|
||||
};
|
||||
})
|
||||
|
||||
// Enhance the HTML5 download attribute to
|
||||
// allow drag&drop of files to the desktop:
|
||||
.directive('download', function () {
|
||||
return function (scope, elm) {
|
||||
elm.on('dragstart', function (e) {
|
||||
try {
|
||||
e.originalEvent.dataTransfer.setData(
|
||||
'DownloadURL',
|
||||
[
|
||||
'application/octet-stream',
|
||||
elm.prop('download'),
|
||||
elm.prop('href')
|
||||
].join(':')
|
||||
);
|
||||
} catch (ignore) {}
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
}));
|
112
static/assets/2744f39c/js/jquery.fileupload-audio.js
vendored
Normal file
112
static/assets/2744f39c/js/jquery.fileupload-audio.js
vendored
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* jQuery File Upload Audio Preview Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* jshint nomen:false */
|
||||
/* global define, require, window, document */
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define([
|
||||
'jquery',
|
||||
'load-image',
|
||||
'./jquery.fileupload-process'
|
||||
], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(
|
||||
require('jquery'),
|
||||
require('load-image')
|
||||
);
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(
|
||||
window.jQuery,
|
||||
window.loadImage
|
||||
);
|
||||
}
|
||||
}(function ($, loadImage) {
|
||||
'use strict';
|
||||
|
||||
// Prepend to the default processQueue:
|
||||
$.blueimp.fileupload.prototype.options.processQueue.unshift(
|
||||
{
|
||||
action: 'loadAudio',
|
||||
// Use the action as prefix for the "@" options:
|
||||
prefix: true,
|
||||
fileTypes: '@',
|
||||
maxFileSize: '@',
|
||||
disabled: '@disableAudioPreview'
|
||||
},
|
||||
{
|
||||
action: 'setAudio',
|
||||
name: '@audioPreviewName',
|
||||
disabled: '@disableAudioPreview'
|
||||
}
|
||||
);
|
||||
|
||||
// The File Upload Audio Preview plugin extends the fileupload widget
|
||||
// with audio preview functionality:
|
||||
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
|
||||
|
||||
options: {
|
||||
// The regular expression for the types of audio files to load,
|
||||
// matched against the file type:
|
||||
loadAudioFileTypes: /^audio\/.*$/
|
||||
},
|
||||
|
||||
_audioElement: document.createElement('audio'),
|
||||
|
||||
processActions: {
|
||||
|
||||
// Loads the audio file given via data.files and data.index
|
||||
// as audio element if the browser supports playing it.
|
||||
// Accepts the options fileTypes (regular expression)
|
||||
// and maxFileSize (integer) to limit the files to load:
|
||||
loadAudio: function (data, options) {
|
||||
if (options.disabled) {
|
||||
return data;
|
||||
}
|
||||
var file = data.files[data.index],
|
||||
url,
|
||||
audio;
|
||||
if (this._audioElement.canPlayType &&
|
||||
this._audioElement.canPlayType(file.type) &&
|
||||
($.type(options.maxFileSize) !== 'number' ||
|
||||
file.size <= options.maxFileSize) &&
|
||||
(!options.fileTypes ||
|
||||
options.fileTypes.test(file.type))) {
|
||||
url = loadImage.createObjectURL(file);
|
||||
if (url) {
|
||||
audio = this._audioElement.cloneNode(false);
|
||||
audio.src = url;
|
||||
audio.controls = true;
|
||||
data.audio = audio;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
// Sets the audio element as a property of the file object:
|
||||
setAudio: function (data, options) {
|
||||
if (data.audio && !options.disabled) {
|
||||
data.files[data.index][options.name || 'preview'] = data.audio;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}));
|
321
static/assets/2744f39c/js/jquery.fileupload-image.js
vendored
Normal file
321
static/assets/2744f39c/js/jquery.fileupload-image.js
vendored
Normal file
@ -0,0 +1,321 @@
|
||||
/*
|
||||
* jQuery File Upload Image Preview & Resize Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* jshint nomen:false */
|
||||
/* global define, require, window, Blob */
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define([
|
||||
'jquery',
|
||||
'load-image',
|
||||
'load-image-meta',
|
||||
'load-image-exif',
|
||||
'load-image-ios',
|
||||
'canvas-to-blob',
|
||||
'./jquery.fileupload-process'
|
||||
], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(
|
||||
require('jquery'),
|
||||
require('load-image')
|
||||
);
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(
|
||||
window.jQuery,
|
||||
window.loadImage
|
||||
);
|
||||
}
|
||||
}(function ($, loadImage) {
|
||||
'use strict';
|
||||
|
||||
// Prepend to the default processQueue:
|
||||
$.blueimp.fileupload.prototype.options.processQueue.unshift(
|
||||
{
|
||||
action: 'loadImageMetaData',
|
||||
disableImageHead: '@',
|
||||
disableExif: '@',
|
||||
disableExifThumbnail: '@',
|
||||
disableExifSub: '@',
|
||||
disableExifGps: '@',
|
||||
disabled: '@disableImageMetaDataLoad'
|
||||
},
|
||||
{
|
||||
action: 'loadImage',
|
||||
// Use the action as prefix for the "@" options:
|
||||
prefix: true,
|
||||
fileTypes: '@',
|
||||
maxFileSize: '@',
|
||||
noRevoke: '@',
|
||||
disabled: '@disableImageLoad'
|
||||
},
|
||||
{
|
||||
action: 'resizeImage',
|
||||
// Use "image" as prefix for the "@" options:
|
||||
prefix: 'image',
|
||||
maxWidth: '@',
|
||||
maxHeight: '@',
|
||||
minWidth: '@',
|
||||
minHeight: '@',
|
||||
crop: '@',
|
||||
orientation: '@',
|
||||
forceResize: '@',
|
||||
disabled: '@disableImageResize'
|
||||
},
|
||||
{
|
||||
action: 'saveImage',
|
||||
quality: '@imageQuality',
|
||||
type: '@imageType',
|
||||
disabled: '@disableImageResize'
|
||||
},
|
||||
{
|
||||
action: 'saveImageMetaData',
|
||||
disabled: '@disableImageMetaDataSave'
|
||||
},
|
||||
{
|
||||
action: 'resizeImage',
|
||||
// Use "preview" as prefix for the "@" options:
|
||||
prefix: 'preview',
|
||||
maxWidth: '@',
|
||||
maxHeight: '@',
|
||||
minWidth: '@',
|
||||
minHeight: '@',
|
||||
crop: '@',
|
||||
orientation: '@',
|
||||
thumbnail: '@',
|
||||
canvas: '@',
|
||||
disabled: '@disableImagePreview'
|
||||
},
|
||||
{
|
||||
action: 'setImage',
|
||||
name: '@imagePreviewName',
|
||||
disabled: '@disableImagePreview'
|
||||
},
|
||||
{
|
||||
action: 'deleteImageReferences',
|
||||
disabled: '@disableImageReferencesDeletion'
|
||||
}
|
||||
);
|
||||
|
||||
// The File Upload Resize plugin extends the fileupload widget
|
||||
// with image resize functionality:
|
||||
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
|
||||
|
||||
options: {
|
||||
// The regular expression for the types of images to load:
|
||||
// matched against the file type:
|
||||
loadImageFileTypes: /^image\/(gif|jpeg|png|svg\+xml)$/,
|
||||
// The maximum file size of images to load:
|
||||
loadImageMaxFileSize: 10000000, // 10MB
|
||||
// The maximum width of resized images:
|
||||
imageMaxWidth: 1920,
|
||||
// The maximum height of resized images:
|
||||
imageMaxHeight: 1080,
|
||||
// Defines the image orientation (1-8) or takes the orientation
|
||||
// value from Exif data if set to true:
|
||||
imageOrientation: false,
|
||||
// Define if resized images should be cropped or only scaled:
|
||||
imageCrop: false,
|
||||
// Disable the resize image functionality by default:
|
||||
disableImageResize: true,
|
||||
// The maximum width of the preview images:
|
||||
previewMaxWidth: 80,
|
||||
// The maximum height of the preview images:
|
||||
previewMaxHeight: 80,
|
||||
// Defines the preview orientation (1-8) or takes the orientation
|
||||
// value from Exif data if set to true:
|
||||
previewOrientation: true,
|
||||
// Create the preview using the Exif data thumbnail:
|
||||
previewThumbnail: true,
|
||||
// Define if preview images should be cropped or only scaled:
|
||||
previewCrop: false,
|
||||
// Define if preview images should be resized as canvas elements:
|
||||
previewCanvas: true
|
||||
},
|
||||
|
||||
processActions: {
|
||||
|
||||
// Loads the image given via data.files and data.index
|
||||
// as img element, if the browser supports the File API.
|
||||
// Accepts the options fileTypes (regular expression)
|
||||
// and maxFileSize (integer) to limit the files to load:
|
||||
loadImage: function (data, options) {
|
||||
if (options.disabled) {
|
||||
return data;
|
||||
}
|
||||
var that = this,
|
||||
file = data.files[data.index],
|
||||
dfd = $.Deferred();
|
||||
if (($.type(options.maxFileSize) === 'number' &&
|
||||
file.size > options.maxFileSize) ||
|
||||
(options.fileTypes &&
|
||||
!options.fileTypes.test(file.type)) ||
|
||||
!loadImage(
|
||||
file,
|
||||
function (img) {
|
||||
if (img.src) {
|
||||
data.img = img;
|
||||
}
|
||||
dfd.resolveWith(that, [data]);
|
||||
},
|
||||
options
|
||||
)) {
|
||||
return data;
|
||||
}
|
||||
return dfd.promise();
|
||||
},
|
||||
|
||||
// Resizes the image given as data.canvas or data.img
|
||||
// and updates data.canvas or data.img with the resized image.
|
||||
// Also stores the resized image as preview property.
|
||||
// Accepts the options maxWidth, maxHeight, minWidth,
|
||||
// minHeight, canvas and crop:
|
||||
resizeImage: function (data, options) {
|
||||
if (options.disabled || !(data.canvas || data.img)) {
|
||||
return data;
|
||||
}
|
||||
options = $.extend({canvas: true}, options);
|
||||
var that = this,
|
||||
dfd = $.Deferred(),
|
||||
img = (options.canvas && data.canvas) || data.img,
|
||||
resolve = function (newImg) {
|
||||
if (newImg && (newImg.width !== img.width ||
|
||||
newImg.height !== img.height ||
|
||||
options.forceResize)) {
|
||||
data[newImg.getContext ? 'canvas' : 'img'] = newImg;
|
||||
}
|
||||
data.preview = newImg;
|
||||
dfd.resolveWith(that, [data]);
|
||||
},
|
||||
thumbnail;
|
||||
if (data.exif) {
|
||||
if (options.orientation === true) {
|
||||
options.orientation = data.exif.get('Orientation');
|
||||
}
|
||||
if (options.thumbnail) {
|
||||
thumbnail = data.exif.get('Thumbnail');
|
||||
if (thumbnail) {
|
||||
loadImage(thumbnail, resolve, options);
|
||||
return dfd.promise();
|
||||
}
|
||||
}
|
||||
// Prevent orienting the same image twice:
|
||||
if (data.orientation) {
|
||||
delete options.orientation;
|
||||
} else {
|
||||
data.orientation = options.orientation;
|
||||
}
|
||||
}
|
||||
if (img) {
|
||||
resolve(loadImage.scale(img, options));
|
||||
return dfd.promise();
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
// Saves the processed image given as data.canvas
|
||||
// inplace at data.index of data.files:
|
||||
saveImage: function (data, options) {
|
||||
if (!data.canvas || options.disabled) {
|
||||
return data;
|
||||
}
|
||||
var that = this,
|
||||
file = data.files[data.index],
|
||||
dfd = $.Deferred();
|
||||
if (data.canvas.toBlob) {
|
||||
data.canvas.toBlob(
|
||||
function (blob) {
|
||||
if (!blob.name) {
|
||||
if (file.type === blob.type) {
|
||||
blob.name = file.name;
|
||||
} else if (file.name) {
|
||||
blob.name = file.name.replace(
|
||||
/\.\w+$/,
|
||||
'.' + blob.type.substr(6)
|
||||
);
|
||||
}
|
||||
}
|
||||
// Don't restore invalid meta data:
|
||||
if (file.type !== blob.type) {
|
||||
delete data.imageHead;
|
||||
}
|
||||
// Store the created blob at the position
|
||||
// of the original file in the files list:
|
||||
data.files[data.index] = blob;
|
||||
dfd.resolveWith(that, [data]);
|
||||
},
|
||||
options.type || file.type,
|
||||
options.quality
|
||||
);
|
||||
} else {
|
||||
return data;
|
||||
}
|
||||
return dfd.promise();
|
||||
},
|
||||
|
||||
loadImageMetaData: function (data, options) {
|
||||
if (options.disabled) {
|
||||
return data;
|
||||
}
|
||||
var that = this,
|
||||
dfd = $.Deferred();
|
||||
loadImage.parseMetaData(data.files[data.index], function (result) {
|
||||
$.extend(data, result);
|
||||
dfd.resolveWith(that, [data]);
|
||||
}, options);
|
||||
return dfd.promise();
|
||||
},
|
||||
|
||||
saveImageMetaData: function (data, options) {
|
||||
if (!(data.imageHead && data.canvas &&
|
||||
data.canvas.toBlob && !options.disabled)) {
|
||||
return data;
|
||||
}
|
||||
var file = data.files[data.index],
|
||||
blob = new Blob([
|
||||
data.imageHead,
|
||||
// Resized images always have a head size of 20 bytes,
|
||||
// including the JPEG marker and a minimal JFIF header:
|
||||
this._blobSlice.call(file, 20)
|
||||
], {type: file.type});
|
||||
blob.name = file.name;
|
||||
data.files[data.index] = blob;
|
||||
return data;
|
||||
},
|
||||
|
||||
// Sets the resized version of the image as a property of the
|
||||
// file object, must be called after "saveImage":
|
||||
setImage: function (data, options) {
|
||||
if (data.preview && !options.disabled) {
|
||||
data.files[data.index][options.name || 'preview'] = data.preview;
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
deleteImageReferences: function (data, options) {
|
||||
if (!options.disabled) {
|
||||
delete data.img;
|
||||
delete data.canvas;
|
||||
delete data.preview;
|
||||
delete data.imageHead;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}));
|
155
static/assets/2744f39c/js/jquery.fileupload-jquery-ui.js
Normal file
155
static/assets/2744f39c/js/jquery.fileupload-jquery-ui.js
Normal file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* jQuery File Upload jQuery UI Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* jshint nomen:false */
|
||||
/* global define, require, window */
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['jquery', './jquery.fileupload-ui'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
'use strict';
|
||||
|
||||
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
|
||||
|
||||
options: {
|
||||
processdone: function (e, data) {
|
||||
data.context.find('.start').button('enable');
|
||||
},
|
||||
progress: function (e, data) {
|
||||
if (data.context) {
|
||||
data.context.find('.progress').progressbar(
|
||||
'option',
|
||||
'value',
|
||||
parseInt(data.loaded / data.total * 100, 10)
|
||||
);
|
||||
}
|
||||
},
|
||||
progressall: function (e, data) {
|
||||
var $this = $(this);
|
||||
$this.find('.fileupload-progress')
|
||||
.find('.progress').progressbar(
|
||||
'option',
|
||||
'value',
|
||||
parseInt(data.loaded / data.total * 100, 10)
|
||||
).end()
|
||||
.find('.progress-extended').each(function () {
|
||||
$(this).html(
|
||||
($this.data('blueimp-fileupload') ||
|
||||
$this.data('fileupload'))
|
||||
._renderExtendedProgress(data)
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_renderUpload: function (func, files) {
|
||||
var node = this._super(func, files),
|
||||
showIconText = $(window).width() > 480;
|
||||
node.find('.progress').empty().progressbar();
|
||||
node.find('.start').button({
|
||||
icons: {primary: 'ui-icon-circle-arrow-e'},
|
||||
text: showIconText
|
||||
});
|
||||
node.find('.cancel').button({
|
||||
icons: {primary: 'ui-icon-cancel'},
|
||||
text: showIconText
|
||||
});
|
||||
if (node.hasClass('fade')) {
|
||||
node.hide();
|
||||
}
|
||||
return node;
|
||||
},
|
||||
|
||||
_renderDownload: function (func, files) {
|
||||
var node = this._super(func, files),
|
||||
showIconText = $(window).width() > 480;
|
||||
node.find('.delete').button({
|
||||
icons: {primary: 'ui-icon-trash'},
|
||||
text: showIconText
|
||||
});
|
||||
if (node.hasClass('fade')) {
|
||||
node.hide();
|
||||
}
|
||||
return node;
|
||||
},
|
||||
|
||||
_startHandler: function (e) {
|
||||
$(e.currentTarget).button('disable');
|
||||
this._super(e);
|
||||
},
|
||||
|
||||
_transition: function (node) {
|
||||
var deferred = $.Deferred();
|
||||
if (node.hasClass('fade')) {
|
||||
node.fadeToggle(
|
||||
this.options.transitionDuration,
|
||||
this.options.transitionEasing,
|
||||
function () {
|
||||
deferred.resolveWith(node);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
deferred.resolveWith(node);
|
||||
}
|
||||
return deferred;
|
||||
},
|
||||
|
||||
_create: function () {
|
||||
this._super();
|
||||
this.element
|
||||
.find('.fileupload-buttonbar')
|
||||
.find('.fileinput-button').each(function () {
|
||||
var input = $(this).find('input:file').detach();
|
||||
$(this)
|
||||
.button({icons: {primary: 'ui-icon-plusthick'}})
|
||||
.append(input);
|
||||
})
|
||||
.end().find('.start')
|
||||
.button({icons: {primary: 'ui-icon-circle-arrow-e'}})
|
||||
.end().find('.cancel')
|
||||
.button({icons: {primary: 'ui-icon-cancel'}})
|
||||
.end().find('.delete')
|
||||
.button({icons: {primary: 'ui-icon-trash'}})
|
||||
.end().find('.progress').progressbar();
|
||||
},
|
||||
|
||||
_destroy: function () {
|
||||
this.element
|
||||
.find('.fileupload-buttonbar')
|
||||
.find('.fileinput-button').each(function () {
|
||||
var input = $(this).find('input:file').detach();
|
||||
$(this)
|
||||
.button('destroy')
|
||||
.append(input);
|
||||
})
|
||||
.end().find('.start')
|
||||
.button('destroy')
|
||||
.end().find('.cancel')
|
||||
.button('destroy')
|
||||
.end().find('.delete')
|
||||
.button('destroy')
|
||||
.end().find('.progress').progressbar('destroy');
|
||||
this._super();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}));
|
175
static/assets/2744f39c/js/jquery.fileupload-process.js
vendored
Normal file
175
static/assets/2744f39c/js/jquery.fileupload-process.js
vendored
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* jQuery File Upload Processing Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2012, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* jshint nomen:false */
|
||||
/* global define, require, window */
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define([
|
||||
'jquery',
|
||||
'./jquery.fileupload'
|
||||
], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(
|
||||
window.jQuery
|
||||
);
|
||||
}
|
||||
}(function ($) {
|
||||
'use strict';
|
||||
|
||||
var originalAdd = $.blueimp.fileupload.prototype.options.add;
|
||||
|
||||
// The File Upload Processing plugin extends the fileupload widget
|
||||
// with file processing functionality:
|
||||
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
|
||||
|
||||
options: {
|
||||
// The list of processing actions:
|
||||
processQueue: [
|
||||
/*
|
||||
{
|
||||
action: 'log',
|
||||
type: 'debug'
|
||||
}
|
||||
*/
|
||||
],
|
||||
add: function (e, data) {
|
||||
var $this = $(this);
|
||||
data.process(function () {
|
||||
return $this.fileupload('process', data);
|
||||
});
|
||||
originalAdd.call(this, e, data);
|
||||
}
|
||||
},
|
||||
|
||||
processActions: {
|
||||
/*
|
||||
log: function (data, options) {
|
||||
console[options.type](
|
||||
'Processing "' + data.files[data.index].name + '"'
|
||||
);
|
||||
}
|
||||
*/
|
||||
},
|
||||
|
||||
_processFile: function (data, originalData) {
|
||||
var that = this,
|
||||
dfd = $.Deferred().resolveWith(that, [data]),
|
||||
chain = dfd.promise();
|
||||
this._trigger('process', null, data);
|
||||
$.each(data.processQueue, function (i, settings) {
|
||||
var func = function (data) {
|
||||
if (originalData.errorThrown) {
|
||||
return $.Deferred()
|
||||
.rejectWith(that, [originalData]).promise();
|
||||
}
|
||||
return that.processActions[settings.action].call(
|
||||
that,
|
||||
data,
|
||||
settings
|
||||
);
|
||||
};
|
||||
chain = chain.pipe(func, settings.always && func);
|
||||
});
|
||||
chain
|
||||
.done(function () {
|
||||
that._trigger('processdone', null, data);
|
||||
that._trigger('processalways', null, data);
|
||||
})
|
||||
.fail(function () {
|
||||
that._trigger('processfail', null, data);
|
||||
that._trigger('processalways', null, data);
|
||||
});
|
||||
return chain;
|
||||
},
|
||||
|
||||
// Replaces the settings of each processQueue item that
|
||||
// are strings starting with an "@", using the remaining
|
||||
// substring as key for the option map,
|
||||
// e.g. "@autoUpload" is replaced with options.autoUpload:
|
||||
_transformProcessQueue: function (options) {
|
||||
var processQueue = [];
|
||||
$.each(options.processQueue, function () {
|
||||
var settings = {},
|
||||
action = this.action,
|
||||
prefix = this.prefix === true ? action : this.prefix;
|
||||
$.each(this, function (key, value) {
|
||||
if ($.type(value) === 'string' &&
|
||||
value.charAt(0) === '@') {
|
||||
settings[key] = options[
|
||||
value.slice(1) || (prefix ? prefix +
|
||||
key.charAt(0).toUpperCase() + key.slice(1) : key)
|
||||
];
|
||||
} else {
|
||||
settings[key] = value;
|
||||
}
|
||||
|
||||
});
|
||||
processQueue.push(settings);
|
||||
});
|
||||
options.processQueue = processQueue;
|
||||
},
|
||||
|
||||
// Returns the number of files currently in the processsing queue:
|
||||
processing: function () {
|
||||
return this._processing;
|
||||
},
|
||||
|
||||
// Processes the files given as files property of the data parameter,
|
||||
// returns a Promise object that allows to bind callbacks:
|
||||
process: function (data) {
|
||||
var that = this,
|
||||
options = $.extend({}, this.options, data);
|
||||
if (options.processQueue && options.processQueue.length) {
|
||||
this._transformProcessQueue(options);
|
||||
if (this._processing === 0) {
|
||||
this._trigger('processstart');
|
||||
}
|
||||
$.each(data.files, function (index) {
|
||||
var opts = index ? $.extend({}, options) : options,
|
||||
func = function () {
|
||||
if (data.errorThrown) {
|
||||
return $.Deferred()
|
||||
.rejectWith(that, [data]).promise();
|
||||
}
|
||||
return that._processFile(opts, data);
|
||||
};
|
||||
opts.index = index;
|
||||
that._processing += 1;
|
||||
that._processingQueue = that._processingQueue.pipe(func, func)
|
||||
.always(function () {
|
||||
that._processing -= 1;
|
||||
if (that._processing === 0) {
|
||||
that._trigger('processstop');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
return this._processingQueue;
|
||||
},
|
||||
|
||||
_create: function () {
|
||||
this._super();
|
||||
this._processing = 0;
|
||||
this._processingQueue = $.Deferred().resolveWith(this)
|
||||
.promise();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}));
|
710
static/assets/2744f39c/js/jquery.fileupload-ui.js
vendored
Normal file
710
static/assets/2744f39c/js/jquery.fileupload-ui.js
vendored
Normal file
@ -0,0 +1,710 @@
|
||||
/*
|
||||
* jQuery File Upload User Interface Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2010, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* jshint nomen:false */
|
||||
/* global define, require, window */
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define([
|
||||
'jquery',
|
||||
'tmpl',
|
||||
'./jquery.fileupload-image',
|
||||
'./jquery.fileupload-audio',
|
||||
'./jquery.fileupload-video',
|
||||
'./jquery.fileupload-validate'
|
||||
], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(
|
||||
require('jquery'),
|
||||
require('tmpl')
|
||||
);
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(
|
||||
window.jQuery,
|
||||
window.tmpl
|
||||
);
|
||||
}
|
||||
}(function ($, tmpl) {
|
||||
'use strict';
|
||||
|
||||
$.blueimp.fileupload.prototype._specialOptions.push(
|
||||
'filesContainer',
|
||||
'uploadTemplateId',
|
||||
'downloadTemplateId'
|
||||
);
|
||||
|
||||
// The UI version extends the file upload widget
|
||||
// and adds complete user interface interaction:
|
||||
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
|
||||
|
||||
options: {
|
||||
// By default, files added to the widget are uploaded as soon
|
||||
// as the user clicks on the start buttons. To enable automatic
|
||||
// uploads, set the following option to true:
|
||||
autoUpload: false,
|
||||
// The ID of the upload template:
|
||||
uploadTemplateId: 'template-upload',
|
||||
// The ID of the download template:
|
||||
downloadTemplateId: 'template-download',
|
||||
// The container for the list of files. If undefined, it is set to
|
||||
// an element with class "files" inside of the widget element:
|
||||
filesContainer: undefined,
|
||||
// By default, files are appended to the files container.
|
||||
// Set the following option to true, to prepend files instead:
|
||||
prependFiles: false,
|
||||
// The expected data type of the upload response, sets the dataType
|
||||
// option of the $.ajax upload requests:
|
||||
dataType: 'json',
|
||||
|
||||
// Error and info messages:
|
||||
messages: {
|
||||
unknownError: 'Unknown error'
|
||||
},
|
||||
|
||||
// Function returning the current number of files,
|
||||
// used by the maxNumberOfFiles validation:
|
||||
getNumberOfFiles: function () {
|
||||
return this.filesContainer.children()
|
||||
.not('.processing').length;
|
||||
},
|
||||
|
||||
// Callback to retrieve the list of files from the server response:
|
||||
getFilesFromResponse: function (data) {
|
||||
if (data.result && $.isArray(data.result.files)) {
|
||||
return data.result.files;
|
||||
}
|
||||
return [];
|
||||
},
|
||||
|
||||
// The add callback is invoked as soon as files are added to the fileupload
|
||||
// widget (via file input selection, drag & drop or add API call).
|
||||
// See the basic file upload widget for more information:
|
||||
add: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var $this = $(this),
|
||||
that = $this.data('blueimp-fileupload') ||
|
||||
$this.data('fileupload'),
|
||||
options = that.options;
|
||||
data.context = that._renderUpload(data.files)
|
||||
.data('data', data)
|
||||
.addClass('processing');
|
||||
options.filesContainer[
|
||||
options.prependFiles ? 'prepend' : 'append'
|
||||
](data.context);
|
||||
that._forceReflow(data.context);
|
||||
that._transition(data.context);
|
||||
data.process(function () {
|
||||
return $this.fileupload('process', data);
|
||||
}).always(function () {
|
||||
data.context.each(function (index) {
|
||||
$(this).find('.size').text(
|
||||
that._formatFileSize(data.files[index].size)
|
||||
);
|
||||
}).removeClass('processing');
|
||||
that._renderPreviews(data);
|
||||
}).done(function () {
|
||||
data.context.find('.start').prop('disabled', false);
|
||||
if ((that._trigger('added', e, data) !== false) &&
|
||||
(options.autoUpload || data.autoUpload) &&
|
||||
data.autoUpload !== false) {
|
||||
data.submit();
|
||||
}
|
||||
}).fail(function () {
|
||||
if (data.files.error) {
|
||||
data.context.each(function (index) {
|
||||
var error = data.files[index].error;
|
||||
if (error) {
|
||||
$(this).find('.error').text(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// Callback for the start of each file upload request:
|
||||
send: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that = $(this).data('blueimp-fileupload') ||
|
||||
$(this).data('fileupload');
|
||||
if (data.context && data.dataType &&
|
||||
data.dataType.substr(0, 6) === 'iframe') {
|
||||
// Iframe Transport does not support progress events.
|
||||
// In lack of an indeterminate progress bar, we set
|
||||
// the progress to 100%, showing the full animated bar:
|
||||
data.context
|
||||
.find('.progress').addClass(
|
||||
!$.support.transition && 'progress-animated'
|
||||
)
|
||||
.attr('aria-valuenow', 100)
|
||||
.children().first().css(
|
||||
'width',
|
||||
'100%'
|
||||
);
|
||||
}
|
||||
return that._trigger('sent', e, data);
|
||||
},
|
||||
// Callback for successful uploads:
|
||||
done: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that = $(this).data('blueimp-fileupload') ||
|
||||
$(this).data('fileupload'),
|
||||
getFilesFromResponse = data.getFilesFromResponse ||
|
||||
that.options.getFilesFromResponse,
|
||||
files = getFilesFromResponse(data),
|
||||
template,
|
||||
deferred;
|
||||
if (data.context) {
|
||||
data.context.each(function (index) {
|
||||
var file = files[index] ||
|
||||
{error: 'Empty file upload result'};
|
||||
deferred = that._addFinishedDeferreds();
|
||||
that._transition($(this)).done(
|
||||
function () {
|
||||
var node = $(this);
|
||||
template = that._renderDownload([file])
|
||||
.replaceAll(node);
|
||||
that._forceReflow(template);
|
||||
that._transition(template).done(
|
||||
function () {
|
||||
data.context = $(this);
|
||||
that._trigger('completed', e, data);
|
||||
that._trigger('finished', e, data);
|
||||
deferred.resolve();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
} else {
|
||||
template = that._renderDownload(files)[
|
||||
that.options.prependFiles ? 'prependTo' : 'appendTo'
|
||||
](that.options.filesContainer);
|
||||
that._forceReflow(template);
|
||||
deferred = that._addFinishedDeferreds();
|
||||
that._transition(template).done(
|
||||
function () {
|
||||
data.context = $(this);
|
||||
that._trigger('completed', e, data);
|
||||
that._trigger('finished', e, data);
|
||||
deferred.resolve();
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
// Callback for failed (abort or error) uploads:
|
||||
fail: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that = $(this).data('blueimp-fileupload') ||
|
||||
$(this).data('fileupload'),
|
||||
template,
|
||||
deferred;
|
||||
if (data.context) {
|
||||
data.context.each(function (index) {
|
||||
if (data.errorThrown !== 'abort') {
|
||||
var file = data.files[index];
|
||||
file.error = file.error || data.errorThrown ||
|
||||
data.i18n('unknownError');
|
||||
deferred = that._addFinishedDeferreds();
|
||||
that._transition($(this)).done(
|
||||
function () {
|
||||
var node = $(this);
|
||||
template = that._renderDownload([file])
|
||||
.replaceAll(node);
|
||||
that._forceReflow(template);
|
||||
that._transition(template).done(
|
||||
function () {
|
||||
data.context = $(this);
|
||||
that._trigger('failed', e, data);
|
||||
that._trigger('finished', e, data);
|
||||
deferred.resolve();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
deferred = that._addFinishedDeferreds();
|
||||
that._transition($(this)).done(
|
||||
function () {
|
||||
$(this).remove();
|
||||
that._trigger('failed', e, data);
|
||||
that._trigger('finished', e, data);
|
||||
deferred.resolve();
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
} else if (data.errorThrown !== 'abort') {
|
||||
data.context = that._renderUpload(data.files)[
|
||||
that.options.prependFiles ? 'prependTo' : 'appendTo'
|
||||
](that.options.filesContainer)
|
||||
.data('data', data);
|
||||
that._forceReflow(data.context);
|
||||
deferred = that._addFinishedDeferreds();
|
||||
that._transition(data.context).done(
|
||||
function () {
|
||||
data.context = $(this);
|
||||
that._trigger('failed', e, data);
|
||||
that._trigger('finished', e, data);
|
||||
deferred.resolve();
|
||||
}
|
||||
);
|
||||
} else {
|
||||
that._trigger('failed', e, data);
|
||||
that._trigger('finished', e, data);
|
||||
that._addFinishedDeferreds().resolve();
|
||||
}
|
||||
},
|
||||
// Callback for upload progress events:
|
||||
progress: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var progress = Math.floor(data.loaded / data.total * 100);
|
||||
if (data.context) {
|
||||
data.context.each(function () {
|
||||
$(this).find('.progress')
|
||||
.attr('aria-valuenow', progress)
|
||||
.children().first().css(
|
||||
'width',
|
||||
progress + '%'
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
// Callback for global upload progress events:
|
||||
progressall: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var $this = $(this),
|
||||
progress = Math.floor(data.loaded / data.total * 100),
|
||||
globalProgressNode = $this.find('.fileupload-progress'),
|
||||
extendedProgressNode = globalProgressNode
|
||||
.find('.progress-extended');
|
||||
if (extendedProgressNode.length) {
|
||||
extendedProgressNode.html(
|
||||
($this.data('blueimp-fileupload') || $this.data('fileupload'))
|
||||
._renderExtendedProgress(data)
|
||||
);
|
||||
}
|
||||
globalProgressNode
|
||||
.find('.progress')
|
||||
.attr('aria-valuenow', progress)
|
||||
.children().first().css(
|
||||
'width',
|
||||
progress + '%'
|
||||
);
|
||||
},
|
||||
// Callback for uploads start, equivalent to the global ajaxStart event:
|
||||
start: function (e) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that = $(this).data('blueimp-fileupload') ||
|
||||
$(this).data('fileupload');
|
||||
that._resetFinishedDeferreds();
|
||||
that._transition($(this).find('.fileupload-progress')).done(
|
||||
function () {
|
||||
that._trigger('started', e);
|
||||
}
|
||||
);
|
||||
},
|
||||
// Callback for uploads stop, equivalent to the global ajaxStop event:
|
||||
stop: function (e) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that = $(this).data('blueimp-fileupload') ||
|
||||
$(this).data('fileupload'),
|
||||
deferred = that._addFinishedDeferreds();
|
||||
$.when.apply($, that._getFinishedDeferreds())
|
||||
.done(function () {
|
||||
that._trigger('stopped', e);
|
||||
});
|
||||
that._transition($(this).find('.fileupload-progress')).done(
|
||||
function () {
|
||||
$(this).find('.progress')
|
||||
.attr('aria-valuenow', '0')
|
||||
.children().first().css('width', '0%');
|
||||
$(this).find('.progress-extended').html(' ');
|
||||
deferred.resolve();
|
||||
}
|
||||
);
|
||||
},
|
||||
processstart: function (e) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
$(this).addClass('fileupload-processing');
|
||||
},
|
||||
processstop: function (e) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
$(this).removeClass('fileupload-processing');
|
||||
},
|
||||
// Callback for file deletion:
|
||||
destroy: function (e, data) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that = $(this).data('blueimp-fileupload') ||
|
||||
$(this).data('fileupload'),
|
||||
removeNode = function () {
|
||||
that._transition(data.context).done(
|
||||
function () {
|
||||
$(this).remove();
|
||||
that._trigger('destroyed', e, data);
|
||||
}
|
||||
);
|
||||
};
|
||||
if (data.url) {
|
||||
data.dataType = data.dataType || that.options.dataType;
|
||||
$.ajax(data).done(removeNode).fail(function () {
|
||||
that._trigger('destroyfailed', e, data);
|
||||
});
|
||||
} else {
|
||||
removeNode();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_resetFinishedDeferreds: function () {
|
||||
this._finishedUploads = [];
|
||||
},
|
||||
|
||||
_addFinishedDeferreds: function (deferred) {
|
||||
if (!deferred) {
|
||||
deferred = $.Deferred();
|
||||
}
|
||||
this._finishedUploads.push(deferred);
|
||||
return deferred;
|
||||
},
|
||||
|
||||
_getFinishedDeferreds: function () {
|
||||
return this._finishedUploads;
|
||||
},
|
||||
|
||||
// Link handler, that allows to download files
|
||||
// by drag & drop of the links to the desktop:
|
||||
_enableDragToDesktop: function () {
|
||||
var link = $(this),
|
||||
url = link.prop('href'),
|
||||
name = link.prop('download'),
|
||||
type = 'application/octet-stream';
|
||||
link.bind('dragstart', function (e) {
|
||||
try {
|
||||
e.originalEvent.dataTransfer.setData(
|
||||
'DownloadURL',
|
||||
[type, name, url].join(':')
|
||||
);
|
||||
} catch (ignore) {}
|
||||
});
|
||||
},
|
||||
|
||||
_formatFileSize: function (bytes) {
|
||||
if (typeof bytes !== 'number') {
|
||||
return '';
|
||||
}
|
||||
if (bytes >= 1000000000) {
|
||||
return (bytes / 1000000000).toFixed(2) + ' GB';
|
||||
}
|
||||
if (bytes >= 1000000) {
|
||||
return (bytes / 1000000).toFixed(2) + ' MB';
|
||||
}
|
||||
return (bytes / 1000).toFixed(2) + ' KB';
|
||||
},
|
||||
|
||||
_formatBitrate: function (bits) {
|
||||
if (typeof bits !== 'number') {
|
||||
return '';
|
||||
}
|
||||
if (bits >= 1000000000) {
|
||||
return (bits / 1000000000).toFixed(2) + ' Gbit/s';
|
||||
}
|
||||
if (bits >= 1000000) {
|
||||
return (bits / 1000000).toFixed(2) + ' Mbit/s';
|
||||
}
|
||||
if (bits >= 1000) {
|
||||
return (bits / 1000).toFixed(2) + ' kbit/s';
|
||||
}
|
||||
return bits.toFixed(2) + ' bit/s';
|
||||
},
|
||||
|
||||
_formatTime: function (seconds) {
|
||||
var date = new Date(seconds * 1000),
|
||||
days = Math.floor(seconds / 86400);
|
||||
days = days ? days + 'd ' : '';
|
||||
return days +
|
||||
('0' + date.getUTCHours()).slice(-2) + ':' +
|
||||
('0' + date.getUTCMinutes()).slice(-2) + ':' +
|
||||
('0' + date.getUTCSeconds()).slice(-2);
|
||||
},
|
||||
|
||||
_formatPercentage: function (floatValue) {
|
||||
return (floatValue * 100).toFixed(2) + ' %';
|
||||
},
|
||||
|
||||
_renderExtendedProgress: function (data) {
|
||||
return this._formatBitrate(data.bitrate) + ' | ' +
|
||||
this._formatTime(
|
||||
(data.total - data.loaded) * 8 / data.bitrate
|
||||
) + ' | ' +
|
||||
this._formatPercentage(
|
||||
data.loaded / data.total
|
||||
) + ' | ' +
|
||||
this._formatFileSize(data.loaded) + ' / ' +
|
||||
this._formatFileSize(data.total);
|
||||
},
|
||||
|
||||
_renderTemplate: function (func, files) {
|
||||
if (!func) {
|
||||
return $();
|
||||
}
|
||||
var result = func({
|
||||
files: files,
|
||||
formatFileSize: this._formatFileSize,
|
||||
options: this.options
|
||||
});
|
||||
if (result instanceof $) {
|
||||
return result;
|
||||
}
|
||||
return $(this.options.templatesContainer).html(result).children();
|
||||
},
|
||||
|
||||
_renderPreviews: function (data) {
|
||||
data.context.find('.preview').each(function (index, elm) {
|
||||
$(elm).append(data.files[index].preview);
|
||||
});
|
||||
},
|
||||
|
||||
_renderUpload: function (files) {
|
||||
return this._renderTemplate(
|
||||
this.options.uploadTemplate,
|
||||
files
|
||||
);
|
||||
},
|
||||
|
||||
_renderDownload: function (files) {
|
||||
return this._renderTemplate(
|
||||
this.options.downloadTemplate,
|
||||
files
|
||||
).find('a[download]').each(this._enableDragToDesktop).end();
|
||||
},
|
||||
|
||||
_startHandler: function (e) {
|
||||
e.preventDefault();
|
||||
var button = $(e.currentTarget),
|
||||
template = button.closest('.template-upload'),
|
||||
data = template.data('data');
|
||||
button.prop('disabled', true);
|
||||
if (data && data.submit) {
|
||||
data.submit();
|
||||
}
|
||||
},
|
||||
|
||||
_cancelHandler: function (e) {
|
||||
e.preventDefault();
|
||||
var template = $(e.currentTarget)
|
||||
.closest('.template-upload,.template-download'),
|
||||
data = template.data('data') || {};
|
||||
data.context = data.context || template;
|
||||
if (data.abort) {
|
||||
data.abort();
|
||||
} else {
|
||||
data.errorThrown = 'abort';
|
||||
this._trigger('fail', e, data);
|
||||
}
|
||||
},
|
||||
|
||||
_deleteHandler: function (e) {
|
||||
e.preventDefault();
|
||||
var button = $(e.currentTarget);
|
||||
this._trigger('destroy', e, $.extend({
|
||||
context: button.closest('.template-download'),
|
||||
type: 'DELETE'
|
||||
}, button.data()));
|
||||
},
|
||||
|
||||
_forceReflow: function (node) {
|
||||
return $.support.transition && node.length &&
|
||||
node[0].offsetWidth;
|
||||
},
|
||||
|
||||
_transition: function (node) {
|
||||
var dfd = $.Deferred();
|
||||
if ($.support.transition && node.hasClass('fade') && node.is(':visible')) {
|
||||
node.bind(
|
||||
$.support.transition.end,
|
||||
function (e) {
|
||||
// Make sure we don't respond to other transitions events
|
||||
// in the container element, e.g. from button elements:
|
||||
if (e.target === node[0]) {
|
||||
node.unbind($.support.transition.end);
|
||||
dfd.resolveWith(node);
|
||||
}
|
||||
}
|
||||
).toggleClass('in');
|
||||
} else {
|
||||
node.toggleClass('in');
|
||||
dfd.resolveWith(node);
|
||||
}
|
||||
return dfd;
|
||||
},
|
||||
|
||||
_initButtonBarEventHandlers: function () {
|
||||
var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'),
|
||||
filesList = this.options.filesContainer;
|
||||
this._on(fileUploadButtonBar.find('.start'), {
|
||||
click: function (e) {
|
||||
e.preventDefault();
|
||||
filesList.find('.start').click();
|
||||
}
|
||||
});
|
||||
this._on(fileUploadButtonBar.find('.cancel'), {
|
||||
click: function (e) {
|
||||
e.preventDefault();
|
||||
filesList.find('.cancel').click();
|
||||
}
|
||||
});
|
||||
this._on(fileUploadButtonBar.find('.delete'), {
|
||||
click: function (e) {
|
||||
e.preventDefault();
|
||||
filesList.find('.toggle:checked')
|
||||
.closest('.template-download')
|
||||
.find('.delete').click();
|
||||
fileUploadButtonBar.find('.toggle')
|
||||
.prop('checked', false);
|
||||
}
|
||||
});
|
||||
this._on(fileUploadButtonBar.find('.toggle'), {
|
||||
change: function (e) {
|
||||
filesList.find('.toggle').prop(
|
||||
'checked',
|
||||
$(e.currentTarget).is(':checked')
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_destroyButtonBarEventHandlers: function () {
|
||||
this._off(
|
||||
this.element.find('.fileupload-buttonbar')
|
||||
.find('.start, .cancel, .delete'),
|
||||
'click'
|
||||
);
|
||||
this._off(
|
||||
this.element.find('.fileupload-buttonbar .toggle'),
|
||||
'change.'
|
||||
);
|
||||
},
|
||||
|
||||
_initEventHandlers: function () {
|
||||
this._super();
|
||||
this._on(this.options.filesContainer, {
|
||||
'click .start': this._startHandler,
|
||||
'click .cancel': this._cancelHandler,
|
||||
'click .delete': this._deleteHandler
|
||||
});
|
||||
this._initButtonBarEventHandlers();
|
||||
},
|
||||
|
||||
_destroyEventHandlers: function () {
|
||||
this._destroyButtonBarEventHandlers();
|
||||
this._off(this.options.filesContainer, 'click');
|
||||
this._super();
|
||||
},
|
||||
|
||||
_enableFileInputButton: function () {
|
||||
this.element.find('.fileinput-button input')
|
||||
.prop('disabled', false)
|
||||
.parent().removeClass('disabled');
|
||||
},
|
||||
|
||||
_disableFileInputButton: function () {
|
||||
this.element.find('.fileinput-button input')
|
||||
.prop('disabled', true)
|
||||
.parent().addClass('disabled');
|
||||
},
|
||||
|
||||
_initTemplates: function () {
|
||||
var options = this.options;
|
||||
options.templatesContainer = this.document[0].createElement(
|
||||
options.filesContainer.prop('nodeName')
|
||||
);
|
||||
if (tmpl) {
|
||||
if (options.uploadTemplateId) {
|
||||
options.uploadTemplate = tmpl(options.uploadTemplateId);
|
||||
}
|
||||
if (options.downloadTemplateId) {
|
||||
options.downloadTemplate = tmpl(options.downloadTemplateId);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_initFilesContainer: function () {
|
||||
var options = this.options;
|
||||
if (options.filesContainer === undefined) {
|
||||
options.filesContainer = this.element.find('.files');
|
||||
} else if (!(options.filesContainer instanceof $)) {
|
||||
options.filesContainer = $(options.filesContainer);
|
||||
}
|
||||
},
|
||||
|
||||
_initSpecialOptions: function () {
|
||||
this._super();
|
||||
this._initFilesContainer();
|
||||
this._initTemplates();
|
||||
},
|
||||
|
||||
_create: function () {
|
||||
this._super();
|
||||
this._resetFinishedDeferreds();
|
||||
if (!$.support.fileInput) {
|
||||
this._disableFileInputButton();
|
||||
}
|
||||
},
|
||||
|
||||
enable: function () {
|
||||
var wasDisabled = false;
|
||||
if (this.options.disabled) {
|
||||
wasDisabled = true;
|
||||
}
|
||||
this._super();
|
||||
if (wasDisabled) {
|
||||
this.element.find('input, button').prop('disabled', false);
|
||||
this._enableFileInputButton();
|
||||
}
|
||||
},
|
||||
|
||||
disable: function () {
|
||||
if (!this.options.disabled) {
|
||||
this.element.find('input, button').prop('disabled', true);
|
||||
this._disableFileInputButton();
|
||||
}
|
||||
this._super();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}));
|
122
static/assets/2744f39c/js/jquery.fileupload-validate.js
vendored
Normal file
122
static/assets/2744f39c/js/jquery.fileupload-validate.js
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* jQuery File Upload Validation Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, require, window */
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define([
|
||||
'jquery',
|
||||
'./jquery.fileupload-process'
|
||||
], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(
|
||||
window.jQuery
|
||||
);
|
||||
}
|
||||
}(function ($) {
|
||||
'use strict';
|
||||
|
||||
// Append to the default processQueue:
|
||||
$.blueimp.fileupload.prototype.options.processQueue.push(
|
||||
{
|
||||
action: 'validate',
|
||||
// Always trigger this action,
|
||||
// even if the previous action was rejected:
|
||||
always: true,
|
||||
// Options taken from the global options map:
|
||||
acceptFileTypes: '@',
|
||||
maxFileSize: '@',
|
||||
minFileSize: '@',
|
||||
maxNumberOfFiles: '@',
|
||||
disabled: '@disableValidation'
|
||||
}
|
||||
);
|
||||
|
||||
// The File Upload Validation plugin extends the fileupload widget
|
||||
// with file validation functionality:
|
||||
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
|
||||
|
||||
options: {
|
||||
/*
|
||||
// The regular expression for allowed file types, matches
|
||||
// against either file type or file name:
|
||||
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
|
||||
// The maximum allowed file size in bytes:
|
||||
maxFileSize: 10000000, // 10 MB
|
||||
// The minimum allowed file size in bytes:
|
||||
minFileSize: undefined, // No minimal file size
|
||||
// The limit of files to be uploaded:
|
||||
maxNumberOfFiles: 10,
|
||||
*/
|
||||
|
||||
// Function returning the current number of files,
|
||||
// has to be overriden for maxNumberOfFiles validation:
|
||||
getNumberOfFiles: $.noop,
|
||||
|
||||
// Error and info messages:
|
||||
messages: {
|
||||
maxNumberOfFiles: 'Maximum number of files exceeded',
|
||||
acceptFileTypes: 'File type not allowed',
|
||||
maxFileSize: 'File is too large',
|
||||
minFileSize: 'File is too small'
|
||||
}
|
||||
},
|
||||
|
||||
processActions: {
|
||||
|
||||
validate: function (data, options) {
|
||||
if (options.disabled) {
|
||||
return data;
|
||||
}
|
||||
var dfd = $.Deferred(),
|
||||
settings = this.options,
|
||||
file = data.files[data.index],
|
||||
fileSize;
|
||||
if (options.minFileSize || options.maxFileSize) {
|
||||
fileSize = file.size;
|
||||
}
|
||||
if ($.type(options.maxNumberOfFiles) === 'number' &&
|
||||
(settings.getNumberOfFiles() || 0) + data.files.length >
|
||||
options.maxNumberOfFiles) {
|
||||
file.error = settings.i18n('maxNumberOfFiles');
|
||||
} else if (options.acceptFileTypes &&
|
||||
!(options.acceptFileTypes.test(file.type) ||
|
||||
options.acceptFileTypes.test(file.name))) {
|
||||
file.error = settings.i18n('acceptFileTypes');
|
||||
} else if (fileSize > options.maxFileSize) {
|
||||
file.error = settings.i18n('maxFileSize');
|
||||
} else if ($.type(fileSize) === 'number' &&
|
||||
fileSize < options.minFileSize) {
|
||||
file.error = settings.i18n('minFileSize');
|
||||
} else {
|
||||
delete file.error;
|
||||
}
|
||||
if (file.error || data.files.error) {
|
||||
data.files.error = true;
|
||||
dfd.rejectWith(this, [data]);
|
||||
} else {
|
||||
dfd.resolveWith(this, [data]);
|
||||
}
|
||||
return dfd.promise();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}));
|
112
static/assets/2744f39c/js/jquery.fileupload-video.js
vendored
Normal file
112
static/assets/2744f39c/js/jquery.fileupload-video.js
vendored
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* jQuery File Upload Video Preview Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* jshint nomen:false */
|
||||
/* global define, require, window, document */
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define([
|
||||
'jquery',
|
||||
'load-image',
|
||||
'./jquery.fileupload-process'
|
||||
], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(
|
||||
require('jquery'),
|
||||
require('load-image')
|
||||
);
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(
|
||||
window.jQuery,
|
||||
window.loadImage
|
||||
);
|
||||
}
|
||||
}(function ($, loadImage) {
|
||||
'use strict';
|
||||
|
||||
// Prepend to the default processQueue:
|
||||
$.blueimp.fileupload.prototype.options.processQueue.unshift(
|
||||
{
|
||||
action: 'loadVideo',
|
||||
// Use the action as prefix for the "@" options:
|
||||
prefix: true,
|
||||
fileTypes: '@',
|
||||
maxFileSize: '@',
|
||||
disabled: '@disableVideoPreview'
|
||||
},
|
||||
{
|
||||
action: 'setVideo',
|
||||
name: '@videoPreviewName',
|
||||
disabled: '@disableVideoPreview'
|
||||
}
|
||||
);
|
||||
|
||||
// The File Upload Video Preview plugin extends the fileupload widget
|
||||
// with video preview functionality:
|
||||
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
|
||||
|
||||
options: {
|
||||
// The regular expression for the types of video files to load,
|
||||
// matched against the file type:
|
||||
loadVideoFileTypes: /^video\/.*$/
|
||||
},
|
||||
|
||||
_videoElement: document.createElement('video'),
|
||||
|
||||
processActions: {
|
||||
|
||||
// Loads the video file given via data.files and data.index
|
||||
// as video element if the browser supports playing it.
|
||||
// Accepts the options fileTypes (regular expression)
|
||||
// and maxFileSize (integer) to limit the files to load:
|
||||
loadVideo: function (data, options) {
|
||||
if (options.disabled) {
|
||||
return data;
|
||||
}
|
||||
var file = data.files[data.index],
|
||||
url,
|
||||
video;
|
||||
if (this._videoElement.canPlayType &&
|
||||
this._videoElement.canPlayType(file.type) &&
|
||||
($.type(options.maxFileSize) !== 'number' ||
|
||||
file.size <= options.maxFileSize) &&
|
||||
(!options.fileTypes ||
|
||||
options.fileTypes.test(file.type))) {
|
||||
url = loadImage.createObjectURL(file);
|
||||
if (url) {
|
||||
video = this._videoElement.cloneNode(false);
|
||||
video.src = url;
|
||||
video.controls = true;
|
||||
data.video = video;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
// Sets the video element as a property of the file object:
|
||||
setVideo: function (data, options) {
|
||||
if (data.video && !options.disabled) {
|
||||
data.files[data.index][options.name || 'preview'] = data.video;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}));
|
1477
static/assets/2744f39c/js/jquery.fileupload.js
vendored
Normal file
1477
static/assets/2744f39c/js/jquery.fileupload.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
217
static/assets/2744f39c/js/jquery.iframe-transport.js
Normal file
217
static/assets/2744f39c/js/jquery.iframe-transport.js
Normal file
@ -0,0 +1,217 @@
|
||||
/*
|
||||
* jQuery Iframe Transport Plugin
|
||||
* https://github.com/blueimp/jQuery-File-Upload
|
||||
*
|
||||
* Copyright 2011, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, require, window, document */
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
'use strict';
|
||||
|
||||
// Helper variable to create unique names for the transport iframes:
|
||||
var counter = 0;
|
||||
|
||||
// The iframe transport accepts four additional options:
|
||||
// options.fileInput: a jQuery collection of file input fields
|
||||
// options.paramName: the parameter name for the file form data,
|
||||
// overrides the name property of the file input field(s),
|
||||
// can be a string or an array of strings.
|
||||
// options.formData: an array of objects with name and value properties,
|
||||
// equivalent to the return data of .serializeArray(), e.g.:
|
||||
// [{name: 'a', value: 1}, {name: 'b', value: 2}]
|
||||
// options.initialIframeSrc: the URL of the initial iframe src,
|
||||
// by default set to "javascript:false;"
|
||||
$.ajaxTransport('iframe', function (options) {
|
||||
if (options.async) {
|
||||
// javascript:false as initial iframe src
|
||||
// prevents warning popups on HTTPS in IE6:
|
||||
/*jshint scripturl: true */
|
||||
var initialIframeSrc = options.initialIframeSrc || 'javascript:false;',
|
||||
/*jshint scripturl: false */
|
||||
form,
|
||||
iframe,
|
||||
addParamChar;
|
||||
return {
|
||||
send: function (_, completeCallback) {
|
||||
form = $('<form style="display:none;"></form>');
|
||||
form.attr('accept-charset', options.formAcceptCharset);
|
||||
addParamChar = /\?/.test(options.url) ? '&' : '?';
|
||||
// XDomainRequest only supports GET and POST:
|
||||
if (options.type === 'DELETE') {
|
||||
options.url = options.url + addParamChar + '_method=DELETE';
|
||||
options.type = 'POST';
|
||||
} else if (options.type === 'PUT') {
|
||||
options.url = options.url + addParamChar + '_method=PUT';
|
||||
options.type = 'POST';
|
||||
} else if (options.type === 'PATCH') {
|
||||
options.url = options.url + addParamChar + '_method=PATCH';
|
||||
options.type = 'POST';
|
||||
}
|
||||
// IE versions below IE8 cannot set the name property of
|
||||
// elements that have already been added to the DOM,
|
||||
// so we set the name along with the iframe HTML markup:
|
||||
counter += 1;
|
||||
iframe = $(
|
||||
'<iframe src="' + initialIframeSrc +
|
||||
'" name="iframe-transport-' + counter + '"></iframe>'
|
||||
).bind('load', function () {
|
||||
var fileInputClones,
|
||||
paramNames = $.isArray(options.paramName) ?
|
||||
options.paramName : [options.paramName];
|
||||
iframe
|
||||
.unbind('load')
|
||||
.bind('load', function () {
|
||||
var response;
|
||||
// Wrap in a try/catch block to catch exceptions thrown
|
||||
// when trying to access cross-domain iframe contents:
|
||||
try {
|
||||
response = iframe.contents();
|
||||
// Google Chrome and Firefox do not throw an
|
||||
// exception when calling iframe.contents() on
|
||||
// cross-domain requests, so we unify the response:
|
||||
if (!response.length || !response[0].firstChild) {
|
||||
throw new Error();
|
||||
}
|
||||
} catch (e) {
|
||||
response = undefined;
|
||||
}
|
||||
// The complete callback returns the
|
||||
// iframe content document as response object:
|
||||
completeCallback(
|
||||
200,
|
||||
'success',
|
||||
{'iframe': response}
|
||||
);
|
||||
// Fix for IE endless progress bar activity bug
|
||||
// (happens on form submits to iframe targets):
|
||||
$('<iframe src="' + initialIframeSrc + '"></iframe>')
|
||||
.appendTo(form);
|
||||
window.setTimeout(function () {
|
||||
// Removing the form in a setTimeout call
|
||||
// allows Chrome's developer tools to display
|
||||
// the response result
|
||||
form.remove();
|
||||
}, 0);
|
||||
});
|
||||
form
|
||||
.prop('target', iframe.prop('name'))
|
||||
.prop('action', options.url)
|
||||
.prop('method', options.type);
|
||||
if (options.formData) {
|
||||
$.each(options.formData, function (index, field) {
|
||||
$('<input type="hidden"/>')
|
||||
.prop('name', field.name)
|
||||
.val(field.value)
|
||||
.appendTo(form);
|
||||
});
|
||||
}
|
||||
if (options.fileInput && options.fileInput.length &&
|
||||
options.type === 'POST') {
|
||||
fileInputClones = options.fileInput.clone();
|
||||
// Insert a clone for each file input field:
|
||||
options.fileInput.after(function (index) {
|
||||
return fileInputClones[index];
|
||||
});
|
||||
if (options.paramName) {
|
||||
options.fileInput.each(function (index) {
|
||||
$(this).prop(
|
||||
'name',
|
||||
paramNames[index] || options.paramName
|
||||
);
|
||||
});
|
||||
}
|
||||
// Appending the file input fields to the hidden form
|
||||
// removes them from their original location:
|
||||
form
|
||||
.append(options.fileInput)
|
||||
.prop('enctype', 'multipart/form-data')
|
||||
// enctype must be set as encoding for IE:
|
||||
.prop('encoding', 'multipart/form-data');
|
||||
// Remove the HTML5 form attribute from the input(s):
|
||||
options.fileInput.removeAttr('form');
|
||||
}
|
||||
form.submit();
|
||||
// Insert the file input fields at their original location
|
||||
// by replacing the clones with the originals:
|
||||
if (fileInputClones && fileInputClones.length) {
|
||||
options.fileInput.each(function (index, input) {
|
||||
var clone = $(fileInputClones[index]);
|
||||
// Restore the original name and form properties:
|
||||
$(input)
|
||||
.prop('name', clone.prop('name'))
|
||||
.attr('form', clone.attr('form'));
|
||||
clone.replaceWith(input);
|
||||
});
|
||||
}
|
||||
});
|
||||
form.append(iframe).appendTo(document.body);
|
||||
},
|
||||
abort: function () {
|
||||
if (iframe) {
|
||||
// javascript:false as iframe src aborts the request
|
||||
// and prevents warning popups on HTTPS in IE6.
|
||||
// concat is used to avoid the "Script URL" JSLint error:
|
||||
iframe
|
||||
.unbind('load')
|
||||
.prop('src', initialIframeSrc);
|
||||
}
|
||||
if (form) {
|
||||
form.remove();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// The iframe transport returns the iframe content document as response.
|
||||
// The following adds converters from iframe to text, json, html, xml
|
||||
// and script.
|
||||
// Please note that the Content-Type for JSON responses has to be text/plain
|
||||
// or text/html, if the browser doesn't include application/json in the
|
||||
// Accept header, else IE will show a download dialog.
|
||||
// The Content-Type for XML responses on the other hand has to be always
|
||||
// application/xml or text/xml, so IE properly parses the XML response.
|
||||
// See also
|
||||
// https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation
|
||||
$.ajaxSetup({
|
||||
converters: {
|
||||
'iframe text': function (iframe) {
|
||||
return iframe && $(iframe[0].body).text();
|
||||
},
|
||||
'iframe json': function (iframe) {
|
||||
return iframe && $.parseJSON($(iframe[0].body).text());
|
||||
},
|
||||
'iframe html': function (iframe) {
|
||||
return iframe && $(iframe[0].body).html();
|
||||
},
|
||||
'iframe xml': function (iframe) {
|
||||
var xmlDoc = iframe && iframe[0];
|
||||
return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc :
|
||||
$.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) ||
|
||||
$(xmlDoc.body).html());
|
||||
},
|
||||
'iframe script': function (iframe) {
|
||||
return iframe && $.globalEval($(iframe[0].body).text());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}));
|
572
static/assets/2744f39c/js/vendor/jquery.ui.widget.js
vendored
Normal file
572
static/assets/2744f39c/js/vendor/jquery.ui.widget.js
vendored
Normal file
@ -0,0 +1,572 @@
|
||||
/*! jQuery UI - v1.11.4+CommonJS - 2015-08-28
|
||||
* http://jqueryui.com
|
||||
* Includes: widget.js
|
||||
* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
|
||||
|
||||
(function( factory ) {
|
||||
if ( typeof define === "function" && define.amd ) {
|
||||
|
||||
// AMD. Register as an anonymous module.
|
||||
define([ "jquery" ], factory );
|
||||
|
||||
} else if ( typeof exports === "object" ) {
|
||||
|
||||
// Node/CommonJS
|
||||
factory( require( "jquery" ) );
|
||||
|
||||
} else {
|
||||
|
||||
// Browser globals
|
||||
factory( jQuery );
|
||||
}
|
||||
}(function( $ ) {
|
||||
/*!
|
||||
* jQuery UI Widget 1.11.4
|
||||
* http://jqueryui.com
|
||||
*
|
||||
* Copyright jQuery Foundation and other contributors
|
||||
* Released under the MIT license.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://api.jqueryui.com/jQuery.widget/
|
||||
*/
|
||||
|
||||
|
||||
var widget_uuid = 0,
|
||||
widget_slice = Array.prototype.slice;
|
||||
|
||||
$.cleanData = (function( orig ) {
|
||||
return function( elems ) {
|
||||
var events, elem, i;
|
||||
for ( i = 0; (elem = elems[i]) != null; i++ ) {
|
||||
try {
|
||||
|
||||
// Only trigger remove when necessary to save time
|
||||
events = $._data( elem, "events" );
|
||||
if ( events && events.remove ) {
|
||||
$( elem ).triggerHandler( "remove" );
|
||||
}
|
||||
|
||||
// http://bugs.jquery.com/ticket/8235
|
||||
} catch ( e ) {}
|
||||
}
|
||||
orig( elems );
|
||||
};
|
||||
})( $.cleanData );
|
||||
|
||||
$.widget = function( name, base, prototype ) {
|
||||
var fullName, existingConstructor, constructor, basePrototype,
|
||||
// proxiedPrototype allows the provided prototype to remain unmodified
|
||||
// so that it can be used as a mixin for multiple widgets (#8876)
|
||||
proxiedPrototype = {},
|
||||
namespace = name.split( "." )[ 0 ];
|
||||
|
||||
name = name.split( "." )[ 1 ];
|
||||
fullName = namespace + "-" + name;
|
||||
|
||||
if ( !prototype ) {
|
||||
prototype = base;
|
||||
base = $.Widget;
|
||||
}
|
||||
|
||||
// create selector for plugin
|
||||
$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
|
||||
return !!$.data( elem, fullName );
|
||||
};
|
||||
|
||||
$[ namespace ] = $[ namespace ] || {};
|
||||
existingConstructor = $[ namespace ][ name ];
|
||||
constructor = $[ namespace ][ name ] = function( options, element ) {
|
||||
// allow instantiation without "new" keyword
|
||||
if ( !this._createWidget ) {
|
||||
return new constructor( options, element );
|
||||
}
|
||||
|
||||
// allow instantiation without initializing for simple inheritance
|
||||
// must use "new" keyword (the code above always passes args)
|
||||
if ( arguments.length ) {
|
||||
this._createWidget( options, element );
|
||||
}
|
||||
};
|
||||
// extend with the existing constructor to carry over any static properties
|
||||
$.extend( constructor, existingConstructor, {
|
||||
version: prototype.version,
|
||||
// copy the object used to create the prototype in case we need to
|
||||
// redefine the widget later
|
||||
_proto: $.extend( {}, prototype ),
|
||||
// track widgets that inherit from this widget in case this widget is
|
||||
// redefined after a widget inherits from it
|
||||
_childConstructors: []
|
||||
});
|
||||
|
||||
basePrototype = new base();
|
||||
// we need to make the options hash a property directly on the new instance
|
||||
// otherwise we'll modify the options hash on the prototype that we're
|
||||
// inheriting from
|
||||
basePrototype.options = $.widget.extend( {}, basePrototype.options );
|
||||
$.each( prototype, function( prop, value ) {
|
||||
if ( !$.isFunction( value ) ) {
|
||||
proxiedPrototype[ prop ] = value;
|
||||
return;
|
||||
}
|
||||
proxiedPrototype[ prop ] = (function() {
|
||||
var _super = function() {
|
||||
return base.prototype[ prop ].apply( this, arguments );
|
||||
},
|
||||
_superApply = function( args ) {
|
||||
return base.prototype[ prop ].apply( this, args );
|
||||
};
|
||||
return function() {
|
||||
var __super = this._super,
|
||||
__superApply = this._superApply,
|
||||
returnValue;
|
||||
|
||||
this._super = _super;
|
||||
this._superApply = _superApply;
|
||||
|
||||
returnValue = value.apply( this, arguments );
|
||||
|
||||
this._super = __super;
|
||||
this._superApply = __superApply;
|
||||
|
||||
return returnValue;
|
||||
};
|
||||
})();
|
||||
});
|
||||
constructor.prototype = $.widget.extend( basePrototype, {
|
||||
// TODO: remove support for widgetEventPrefix
|
||||
// always use the name + a colon as the prefix, e.g., draggable:start
|
||||
// don't prefix for widgets that aren't DOM-based
|
||||
widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
|
||||
}, proxiedPrototype, {
|
||||
constructor: constructor,
|
||||
namespace: namespace,
|
||||
widgetName: name,
|
||||
widgetFullName: fullName
|
||||
});
|
||||
|
||||
// If this widget is being redefined then we need to find all widgets that
|
||||
// are inheriting from it and redefine all of them so that they inherit from
|
||||
// the new version of this widget. We're essentially trying to replace one
|
||||
// level in the prototype chain.
|
||||
if ( existingConstructor ) {
|
||||
$.each( existingConstructor._childConstructors, function( i, child ) {
|
||||
var childPrototype = child.prototype;
|
||||
|
||||
// redefine the child widget using the same prototype that was
|
||||
// originally used, but inherit from the new version of the base
|
||||
$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
|
||||
});
|
||||
// remove the list of existing child constructors from the old constructor
|
||||
// so the old child constructors can be garbage collected
|
||||
delete existingConstructor._childConstructors;
|
||||
} else {
|
||||
base._childConstructors.push( constructor );
|
||||
}
|
||||
|
||||
$.widget.bridge( name, constructor );
|
||||
|
||||
return constructor;
|
||||
};
|
||||
|
||||
$.widget.extend = function( target ) {
|
||||
var input = widget_slice.call( arguments, 1 ),
|
||||
inputIndex = 0,
|
||||
inputLength = input.length,
|
||||
key,
|
||||
value;
|
||||
for ( ; inputIndex < inputLength; inputIndex++ ) {
|
||||
for ( key in input[ inputIndex ] ) {
|
||||
value = input[ inputIndex ][ key ];
|
||||
if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
|
||||
// Clone objects
|
||||
if ( $.isPlainObject( value ) ) {
|
||||
target[ key ] = $.isPlainObject( target[ key ] ) ?
|
||||
$.widget.extend( {}, target[ key ], value ) :
|
||||
// Don't extend strings, arrays, etc. with objects
|
||||
$.widget.extend( {}, value );
|
||||
// Copy everything else by reference
|
||||
} else {
|
||||
target[ key ] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
};
|
||||
|
||||
$.widget.bridge = function( name, object ) {
|
||||
var fullName = object.prototype.widgetFullName || name;
|
||||
$.fn[ name ] = function( options ) {
|
||||
var isMethodCall = typeof options === "string",
|
||||
args = widget_slice.call( arguments, 1 ),
|
||||
returnValue = this;
|
||||
|
||||
if ( isMethodCall ) {
|
||||
this.each(function() {
|
||||
var methodValue,
|
||||
instance = $.data( this, fullName );
|
||||
if ( options === "instance" ) {
|
||||
returnValue = instance;
|
||||
return false;
|
||||
}
|
||||
if ( !instance ) {
|
||||
return $.error( "cannot call methods on " + name + " prior to initialization; " +
|
||||
"attempted to call method '" + options + "'" );
|
||||
}
|
||||
if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
|
||||
return $.error( "no such method '" + options + "' for " + name + " widget instance" );
|
||||
}
|
||||
methodValue = instance[ options ].apply( instance, args );
|
||||
if ( methodValue !== instance && methodValue !== undefined ) {
|
||||
returnValue = methodValue && methodValue.jquery ?
|
||||
returnValue.pushStack( methodValue.get() ) :
|
||||
methodValue;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
||||
// Allow multiple hashes to be passed on init
|
||||
if ( args.length ) {
|
||||
options = $.widget.extend.apply( null, [ options ].concat(args) );
|
||||
}
|
||||
|
||||
this.each(function() {
|
||||
var instance = $.data( this, fullName );
|
||||
if ( instance ) {
|
||||
instance.option( options || {} );
|
||||
if ( instance._init ) {
|
||||
instance._init();
|
||||
}
|
||||
} else {
|
||||
$.data( this, fullName, new object( options, this ) );
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
};
|
||||
};
|
||||
|
||||
$.Widget = function( /* options, element */ ) {};
|
||||
$.Widget._childConstructors = [];
|
||||
|
||||
$.Widget.prototype = {
|
||||
widgetName: "widget",
|
||||
widgetEventPrefix: "",
|
||||
defaultElement: "<div>",
|
||||
options: {
|
||||
disabled: false,
|
||||
|
||||
// callbacks
|
||||
create: null
|
||||
},
|
||||
_createWidget: function( options, element ) {
|
||||
element = $( element || this.defaultElement || this )[ 0 ];
|
||||
this.element = $( element );
|
||||
this.uuid = widget_uuid++;
|
||||
this.eventNamespace = "." + this.widgetName + this.uuid;
|
||||
|
||||
this.bindings = $();
|
||||
this.hoverable = $();
|
||||
this.focusable = $();
|
||||
|
||||
if ( element !== this ) {
|
||||
$.data( element, this.widgetFullName, this );
|
||||
this._on( true, this.element, {
|
||||
remove: function( event ) {
|
||||
if ( event.target === element ) {
|
||||
this.destroy();
|
||||
}
|
||||
}
|
||||
});
|
||||
this.document = $( element.style ?
|
||||
// element within the document
|
||||
element.ownerDocument :
|
||||
// element is window or document
|
||||
element.document || element );
|
||||
this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
|
||||
}
|
||||
|
||||
this.options = $.widget.extend( {},
|
||||
this.options,
|
||||
this._getCreateOptions(),
|
||||
options );
|
||||
|
||||
this._create();
|
||||
this._trigger( "create", null, this._getCreateEventData() );
|
||||
this._init();
|
||||
},
|
||||
_getCreateOptions: $.noop,
|
||||
_getCreateEventData: $.noop,
|
||||
_create: $.noop,
|
||||
_init: $.noop,
|
||||
|
||||
destroy: function() {
|
||||
this._destroy();
|
||||
// we can probably remove the unbind calls in 2.0
|
||||
// all event bindings should go through this._on()
|
||||
this.element
|
||||
.unbind( this.eventNamespace )
|
||||
.removeData( this.widgetFullName )
|
||||
// support: jquery <1.6.3
|
||||
// http://bugs.jquery.com/ticket/9413
|
||||
.removeData( $.camelCase( this.widgetFullName ) );
|
||||
this.widget()
|
||||
.unbind( this.eventNamespace )
|
||||
.removeAttr( "aria-disabled" )
|
||||
.removeClass(
|
||||
this.widgetFullName + "-disabled " +
|
||||
"ui-state-disabled" );
|
||||
|
||||
// clean up events and states
|
||||
this.bindings.unbind( this.eventNamespace );
|
||||
this.hoverable.removeClass( "ui-state-hover" );
|
||||
this.focusable.removeClass( "ui-state-focus" );
|
||||
},
|
||||
_destroy: $.noop,
|
||||
|
||||
widget: function() {
|
||||
return this.element;
|
||||
},
|
||||
|
||||
option: function( key, value ) {
|
||||
var options = key,
|
||||
parts,
|
||||
curOption,
|
||||
i;
|
||||
|
||||
if ( arguments.length === 0 ) {
|
||||
// don't return a reference to the internal hash
|
||||
return $.widget.extend( {}, this.options );
|
||||
}
|
||||
|
||||
if ( typeof key === "string" ) {
|
||||
// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
|
||||
options = {};
|
||||
parts = key.split( "." );
|
||||
key = parts.shift();
|
||||
if ( parts.length ) {
|
||||
curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
|
||||
for ( i = 0; i < parts.length - 1; i++ ) {
|
||||
curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
|
||||
curOption = curOption[ parts[ i ] ];
|
||||
}
|
||||
key = parts.pop();
|
||||
if ( arguments.length === 1 ) {
|
||||
return curOption[ key ] === undefined ? null : curOption[ key ];
|
||||
}
|
||||
curOption[ key ] = value;
|
||||
} else {
|
||||
if ( arguments.length === 1 ) {
|
||||
return this.options[ key ] === undefined ? null : this.options[ key ];
|
||||
}
|
||||
options[ key ] = value;
|
||||
}
|
||||
}
|
||||
|
||||
this._setOptions( options );
|
||||
|
||||
return this;
|
||||
},
|
||||
_setOptions: function( options ) {
|
||||
var key;
|
||||
|
||||
for ( key in options ) {
|
||||
this._setOption( key, options[ key ] );
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
_setOption: function( key, value ) {
|
||||
this.options[ key ] = value;
|
||||
|
||||
if ( key === "disabled" ) {
|
||||
this.widget()
|
||||
.toggleClass( this.widgetFullName + "-disabled", !!value );
|
||||
|
||||
// If the widget is becoming disabled, then nothing is interactive
|
||||
if ( value ) {
|
||||
this.hoverable.removeClass( "ui-state-hover" );
|
||||
this.focusable.removeClass( "ui-state-focus" );
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
enable: function() {
|
||||
return this._setOptions({ disabled: false });
|
||||
},
|
||||
disable: function() {
|
||||
return this._setOptions({ disabled: true });
|
||||
},
|
||||
|
||||
_on: function( suppressDisabledCheck, element, handlers ) {
|
||||
var delegateElement,
|
||||
instance = this;
|
||||
|
||||
// no suppressDisabledCheck flag, shuffle arguments
|
||||
if ( typeof suppressDisabledCheck !== "boolean" ) {
|
||||
handlers = element;
|
||||
element = suppressDisabledCheck;
|
||||
suppressDisabledCheck = false;
|
||||
}
|
||||
|
||||
// no element argument, shuffle and use this.element
|
||||
if ( !handlers ) {
|
||||
handlers = element;
|
||||
element = this.element;
|
||||
delegateElement = this.widget();
|
||||
} else {
|
||||
element = delegateElement = $( element );
|
||||
this.bindings = this.bindings.add( element );
|
||||
}
|
||||
|
||||
$.each( handlers, function( event, handler ) {
|
||||
function handlerProxy() {
|
||||
// allow widgets to customize the disabled handling
|
||||
// - disabled as an array instead of boolean
|
||||
// - disabled class as method for disabling individual parts
|
||||
if ( !suppressDisabledCheck &&
|
||||
( instance.options.disabled === true ||
|
||||
$( this ).hasClass( "ui-state-disabled" ) ) ) {
|
||||
return;
|
||||
}
|
||||
return ( typeof handler === "string" ? instance[ handler ] : handler )
|
||||
.apply( instance, arguments );
|
||||
}
|
||||
|
||||
// copy the guid so direct unbinding works
|
||||
if ( typeof handler !== "string" ) {
|
||||
handlerProxy.guid = handler.guid =
|
||||
handler.guid || handlerProxy.guid || $.guid++;
|
||||
}
|
||||
|
||||
var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
|
||||
eventName = match[1] + instance.eventNamespace,
|
||||
selector = match[2];
|
||||
if ( selector ) {
|
||||
delegateElement.delegate( selector, eventName, handlerProxy );
|
||||
} else {
|
||||
element.bind( eventName, handlerProxy );
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_off: function( element, eventName ) {
|
||||
eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
|
||||
this.eventNamespace;
|
||||
element.unbind( eventName ).undelegate( eventName );
|
||||
|
||||
// Clear the stack to avoid memory leaks (#10056)
|
||||
this.bindings = $( this.bindings.not( element ).get() );
|
||||
this.focusable = $( this.focusable.not( element ).get() );
|
||||
this.hoverable = $( this.hoverable.not( element ).get() );
|
||||
},
|
||||
|
||||
_delay: function( handler, delay ) {
|
||||
function handlerProxy() {
|
||||
return ( typeof handler === "string" ? instance[ handler ] : handler )
|
||||
.apply( instance, arguments );
|
||||
}
|
||||
var instance = this;
|
||||
return setTimeout( handlerProxy, delay || 0 );
|
||||
},
|
||||
|
||||
_hoverable: function( element ) {
|
||||
this.hoverable = this.hoverable.add( element );
|
||||
this._on( element, {
|
||||
mouseenter: function( event ) {
|
||||
$( event.currentTarget ).addClass( "ui-state-hover" );
|
||||
},
|
||||
mouseleave: function( event ) {
|
||||
$( event.currentTarget ).removeClass( "ui-state-hover" );
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_focusable: function( element ) {
|
||||
this.focusable = this.focusable.add( element );
|
||||
this._on( element, {
|
||||
focusin: function( event ) {
|
||||
$( event.currentTarget ).addClass( "ui-state-focus" );
|
||||
},
|
||||
focusout: function( event ) {
|
||||
$( event.currentTarget ).removeClass( "ui-state-focus" );
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_trigger: function( type, event, data ) {
|
||||
var prop, orig,
|
||||
callback = this.options[ type ];
|
||||
|
||||
data = data || {};
|
||||
event = $.Event( event );
|
||||
event.type = ( type === this.widgetEventPrefix ?
|
||||
type :
|
||||
this.widgetEventPrefix + type ).toLowerCase();
|
||||
// the original event may come from any element
|
||||
// so we need to reset the target on the new event
|
||||
event.target = this.element[ 0 ];
|
||||
|
||||
// copy original event properties over to the new event
|
||||
orig = event.originalEvent;
|
||||
if ( orig ) {
|
||||
for ( prop in orig ) {
|
||||
if ( !( prop in event ) ) {
|
||||
event[ prop ] = orig[ prop ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.element.trigger( event, data );
|
||||
return !( $.isFunction( callback ) &&
|
||||
callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
|
||||
event.isDefaultPrevented() );
|
||||
}
|
||||
};
|
||||
|
||||
$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
|
||||
$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
|
||||
if ( typeof options === "string" ) {
|
||||
options = { effect: options };
|
||||
}
|
||||
var hasOptions,
|
||||
effectName = !options ?
|
||||
method :
|
||||
options === true || typeof options === "number" ?
|
||||
defaultEffect :
|
||||
options.effect || defaultEffect;
|
||||
options = options || {};
|
||||
if ( typeof options === "number" ) {
|
||||
options = { duration: options };
|
||||
}
|
||||
hasOptions = !$.isEmptyObject( options );
|
||||
options.complete = callback;
|
||||
if ( options.delay ) {
|
||||
element.delay( options.delay );
|
||||
}
|
||||
if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
|
||||
element[ method ]( options );
|
||||
} else if ( effectName !== method && element[ effectName ] ) {
|
||||
element[ effectName ]( options.duration, options.easing, callback );
|
||||
} else {
|
||||
element.queue(function( next ) {
|
||||
$( this )[ method ]();
|
||||
if ( callback ) {
|
||||
callback.call( element[ 0 ] );
|
||||
}
|
||||
next();
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var widget = $.widget;
|
||||
|
||||
|
||||
|
||||
}));
|
9814
static/assets/375d1217/jquery.js
vendored
Normal file
9814
static/assets/375d1217/jquery.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4
static/assets/375d1217/jquery.min.js
vendored
Normal file
4
static/assets/375d1217/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
static/assets/375d1217/jquery.min.map
Normal file
1
static/assets/375d1217/jquery.min.map
Normal file
File diff suppressed because one or more lines are too long
33
static/assets/4d2c673/js/humhub.content.container.js
Normal file
33
static/assets/4d2c673/js/humhub.content.container.js
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* This module provides an api for handling content objects e.g. Posts, Polls...
|
||||
*
|
||||
* @type undefined|Function
|
||||
*/
|
||||
|
||||
humhub.module('content.container', function (module, require, $) {
|
||||
var client = require('client');
|
||||
var additions = require('ui.additions');
|
||||
|
||||
var follow = function(evt) {
|
||||
var containerId = evt.$trigger.data('content-container-id');
|
||||
client.post(evt).then(function(response) {
|
||||
additions.switchButtons(evt.$trigger, $('[data-content-container-id="'+containerId+'"].unfollowButton'));
|
||||
}).catch(function(e) {
|
||||
module.log.error(e, true);
|
||||
});
|
||||
};
|
||||
|
||||
var unfollow = function(evt) {
|
||||
var containerId = evt.$trigger.data('content-container-id');
|
||||
client.post(evt).then(function(response) {
|
||||
additions.switchButtons(evt.$trigger, $('[data-content-container-id="'+containerId+'"].followButton'));
|
||||
}).catch(function(e) {
|
||||
module.log.error(e, true);
|
||||
});
|
||||
};
|
||||
|
||||
module.export({
|
||||
follow: follow,
|
||||
unfollow: unfollow
|
||||
});
|
||||
});
|
164
static/assets/4d2c673/js/humhub.content.form.js
Normal file
164
static/assets/4d2c673/js/humhub.content.form.js
Normal file
@ -0,0 +1,164 @@
|
||||
/**
|
||||
* Core module for managing Streams and StreamItems
|
||||
* @type Function
|
||||
*/
|
||||
humhub.module('content.form', function(module, require, $) {
|
||||
|
||||
var CREATE_FORM_ROOT_SELECTOR = '#contentFormBody';
|
||||
|
||||
var object = require('util').object;
|
||||
var client = require('client');
|
||||
var event = require('event');
|
||||
var Widget = require('ui.widget').Widget;
|
||||
|
||||
var instance;
|
||||
|
||||
var CreateForm = function(node) {
|
||||
Widget.call(this, node);
|
||||
};
|
||||
|
||||
object.inherits(CreateForm, Widget);
|
||||
|
||||
CreateForm.prototype.init = function() {
|
||||
this.$.hide();
|
||||
|
||||
// Hide options by default
|
||||
$('.contentForm_options').hide();
|
||||
$('#contentFormError').hide();
|
||||
|
||||
this.setDefaultVisibility();
|
||||
|
||||
this.$.fadeIn('fast');
|
||||
|
||||
if(!module.config['disabled']) {
|
||||
// Remove info text from the textinput
|
||||
$('#contentFormBody').on('click.humhub:content:form dragover.humhub:content:form', function() {
|
||||
// Hide options by default
|
||||
$('.contentForm_options').fadeIn();
|
||||
});
|
||||
} else {
|
||||
$('#contentFormBody').find('.humhub-ui-richtext').trigger('disable');
|
||||
}
|
||||
};
|
||||
|
||||
CreateForm.prototype.actions = function() {
|
||||
return ['submit', 'notifyUser', 'changeVisibility'];
|
||||
};
|
||||
|
||||
CreateForm.prototype.submit = function(evt) {
|
||||
this.$.find("#contentFormError, .preferences, .fileinput-button").hide();
|
||||
this.$.find("#contentFormError li").remove();
|
||||
|
||||
var that = this;
|
||||
evt.block = 'manual';
|
||||
client.submit(evt).then(function(response) {
|
||||
that.$.find(".preferences, .fileinput-button").show();
|
||||
$('.contentForm_options .preferences, .fileinput-button').show();
|
||||
if(!response.errors) {
|
||||
event.trigger('humhub:modules:content:newEntry', response.output);
|
||||
that.resetForm();
|
||||
} else {
|
||||
that.handleError(response);
|
||||
}
|
||||
}).finally(function() {
|
||||
evt.finish();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Todo: this is post form only, this needs to be added to post module perhaps by calling $form.trigger('humhub:form:clear');
|
||||
* @returns {undefined}
|
||||
*/
|
||||
CreateForm.prototype.resetForm = function() {
|
||||
// Reset Form (Empty State)
|
||||
$('.contentForm_options').hide();
|
||||
var $contentForm = $('.contentForm');
|
||||
$contentForm.filter(':text').val('');
|
||||
$contentForm.filter('textarea').val('').trigger('autosize.resize');
|
||||
$contentForm.attr('checked', false);
|
||||
|
||||
this.resetNotifyUser();
|
||||
this.setDefaultVisibility();
|
||||
this.resetFilePreview();
|
||||
|
||||
$('#public').attr('checked', false);
|
||||
$('#contentFormBody').find('.humhub-ui-richtext').trigger('clear');
|
||||
};
|
||||
|
||||
CreateForm.prototype.resetNotifyUser = function() {
|
||||
$('#notifyUserContainer').hide();
|
||||
Widget.instance('#notifyUserInput').reset();
|
||||
};
|
||||
|
||||
CreateForm.prototype.resetFilePreview = function() {
|
||||
Widget.instance($('#contentFormFiles_preview')).reset();
|
||||
};
|
||||
|
||||
CreateForm.prototype.handleError = function(response) {
|
||||
$('#contentFormError').show();
|
||||
$.each(response.errors, function(fieldName, errorMessage) {
|
||||
// Mark Fields as Error
|
||||
var fieldId = 'contentForm_' + fieldName;
|
||||
$('#' + fieldId).addClass('error');
|
||||
$.each(errorMessage, function(key, msg) {
|
||||
$('#contentFormError').append('<li><i class=\"icon-warning-sign\"></i> ' + msg + '</li>');
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
CreateForm.prototype.getForm = function() {
|
||||
return this.$.find('form:visible');
|
||||
};
|
||||
|
||||
CreateForm.prototype.changeVisibility = function() {
|
||||
if(!$('#contentForm_visibility').prop('checked')) {
|
||||
this.setPublicVisibility();
|
||||
} else {
|
||||
this.setPrivateVisibility();
|
||||
}
|
||||
};
|
||||
|
||||
CreateForm.prototype.setDefaultVisibility = function() {
|
||||
if(module.config['defaultVisibility']) {
|
||||
this.setPublicVisibility();
|
||||
} else {
|
||||
this.setPrivateVisibility();
|
||||
}
|
||||
};
|
||||
|
||||
CreateForm.prototype.setPublicVisibility = function() {
|
||||
$('#contentForm_visibility').prop("checked", true);
|
||||
$('#contentForm_visibility_entry').html('<i class="fa fa-lock"></i>' + module.text(['makePrivate']));
|
||||
$('.label-public').removeClass('hidden');
|
||||
};
|
||||
|
||||
CreateForm.prototype.setPrivateVisibility = function() {
|
||||
$('#contentForm_visibility').prop("checked", false);
|
||||
$('#contentForm_visibility_entry').html('<i class="fa fa-unlock"></i>' + module.text(['makePublic']));
|
||||
$('.label-public').addClass('hidden');
|
||||
};
|
||||
|
||||
CreateForm.prototype.notifyUser = function() {
|
||||
$('#notifyUserContainer').show();
|
||||
Widget.instance('#notifyUserInput').focus();
|
||||
};
|
||||
|
||||
var init = function() {
|
||||
var $root = $(CREATE_FORM_ROOT_SELECTOR);
|
||||
if($root.length) {
|
||||
instance = Widget.instance($root);
|
||||
}
|
||||
};
|
||||
|
||||
var unload = function() {
|
||||
instance = undefined;
|
||||
}
|
||||
|
||||
module.export({
|
||||
CreateForm: CreateForm,
|
||||
instance: instance,
|
||||
init: init,
|
||||
initOnPjaxLoad: true,
|
||||
unload: unload
|
||||
});
|
||||
});
|
145
static/assets/4d2c673/js/humhub.content.js
Normal file
145
static/assets/4d2c673/js/humhub.content.js
Normal file
@ -0,0 +1,145 @@
|
||||
/**
|
||||
* This module provides an api for handling content objects e.g. Posts, Polls...
|
||||
*
|
||||
* @type undefined|Function
|
||||
*/
|
||||
|
||||
humhub.module('content', function(module, require, $) {
|
||||
var client = require('client');
|
||||
var util = require('util');
|
||||
var object = util.object;
|
||||
var string = util.string;
|
||||
var actions = require('action');
|
||||
var Component = actions.Component;
|
||||
var event = require('event');
|
||||
var modal = require('ui.modal');
|
||||
|
||||
var DATA_CONTENT_KEY = "content-key";
|
||||
var DATA_CONTENT_EDIT_URL = "content-edit-url";
|
||||
var DATA_CONTENT_SAVE_SELECTOR = "[data-content-save]";
|
||||
var DATA_CONTENT_DELETE_URL = "content-delete-url";
|
||||
|
||||
|
||||
Component.addSelector('content-component');
|
||||
|
||||
var Content = function(container) {
|
||||
Component.call(this, container);
|
||||
};
|
||||
|
||||
object.inherits(Content, Component);
|
||||
|
||||
Content.getNodeByKey = function(key) {
|
||||
return $('[data-content-key="' + key + '"]');
|
||||
};
|
||||
|
||||
Content.prototype.actions = function() {
|
||||
return ['create', 'edit', 'delete'];
|
||||
};
|
||||
|
||||
Content.prototype.getKey = function() {
|
||||
return this.$.data(DATA_CONTENT_KEY);
|
||||
};
|
||||
|
||||
Content.prototype.create = function(addContentHandler) {
|
||||
//Note that this Content won't have an id, so the backend will create an instance
|
||||
if(this.hasAction('create')) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.edit(addContentHandler);
|
||||
};
|
||||
|
||||
Content.prototype.edit = function(successHandler) {
|
||||
// Currently there is no need for a default implementation
|
||||
};
|
||||
|
||||
Content.prototype.delete = function(options) {
|
||||
options = options || {};
|
||||
var that = this;
|
||||
return new Promise(function(resolve, reject) {
|
||||
if(!that.hasAction('delete')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var modalOptions = options.modal || module.config.modal.deleteConfirm;
|
||||
|
||||
modal.confirm(modalOptions).then(function($confirmed) {
|
||||
if(!$confirmed) {
|
||||
resolve(false);
|
||||
}
|
||||
|
||||
that.loader();
|
||||
var deleteUrl = that.data(DATA_CONTENT_DELETE_URL);
|
||||
if(deleteUrl) {
|
||||
client.post(deleteUrl, {
|
||||
data: {id: that.getKey()}
|
||||
}).then(function(response) {
|
||||
that.remove().then(function() {
|
||||
resolve(true);
|
||||
});
|
||||
}).catch(function(err) {
|
||||
reject(err);
|
||||
}).finally(function() {
|
||||
that.loader(false);
|
||||
});
|
||||
} else {
|
||||
reject('Content delete was called, but no url could be determined for ' + that.base);
|
||||
that.loader(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract loader function which can be used to activate or deactivate a
|
||||
* loader within a content entry.
|
||||
*
|
||||
* If $show is undefined or true the loader animation should be rendered
|
||||
* otherwise it should be remved.
|
||||
*
|
||||
* @param {type} $show
|
||||
* @returns {undefined}
|
||||
*/
|
||||
Content.prototype.loader = function($show) {
|
||||
// Has to be overwritten by content type
|
||||
};
|
||||
|
||||
Content.prototype.remove = function() {
|
||||
var that = this;
|
||||
return new Promise(function(resolve, reject) {
|
||||
that.$.animate({height: 'toggle', opacity: 'toggle'}, 'fast', function() {
|
||||
that.$.remove();
|
||||
event.trigger('humhub:modules:content:afterRemove', that);
|
||||
resolve(that);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Content.prototype.permalink = function(evt) {
|
||||
var options = module.config.modal.permalink;
|
||||
options.permalink = evt.$trigger.data('content-permalink');
|
||||
|
||||
modal.global.set({
|
||||
header: options.head,
|
||||
body: string.template(module.templates.permalinkBody, options),
|
||||
footer: string.template(module.templates.permalinkFooter, options)
|
||||
}).show();
|
||||
|
||||
modal.global.$.find('textarea').focus().select();
|
||||
|
||||
// Make sure the modal is closed when pjax loads
|
||||
event.one('humhub:ready', function() {
|
||||
modal.global.close();
|
||||
});
|
||||
};
|
||||
|
||||
var templates = {
|
||||
permalinkBody : '<textarea rows="3" class="form-control permalink-txt" spellcheck="false" readonly>{permalink}</textarea><p class="help-block">{info}</p>',
|
||||
permalinkFooter : '<a href="#" data-modal-close class="btn btn-default">{buttonClose}</a><a href="{permalink}" class="btn btn-primary" data-ui-loader>{buttonOpen}</a>'
|
||||
};
|
||||
|
||||
module.export({
|
||||
Content: Content,
|
||||
templates: templates
|
||||
});
|
||||
});
|
74
static/assets/575ffb1/nprogress.css
Normal file
74
static/assets/575ffb1/nprogress.css
Normal file
@ -0,0 +1,74 @@
|
||||
/* Make clicks pass-through */
|
||||
#nprogress {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#nprogress .bar {
|
||||
background: #29d;
|
||||
|
||||
position: fixed;
|
||||
z-index: 1031;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
/* Fancy blur effect */
|
||||
#nprogress .peg {
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
width: 100px;
|
||||
height: 100%;
|
||||
box-shadow: 0 0 10px #29d, 0 0 5px #29d;
|
||||
opacity: 1.0;
|
||||
|
||||
-webkit-transform: rotate(3deg) translate(0px, -4px);
|
||||
-ms-transform: rotate(3deg) translate(0px, -4px);
|
||||
transform: rotate(3deg) translate(0px, -4px);
|
||||
}
|
||||
|
||||
/* Remove these to get rid of the spinner */
|
||||
#nprogress .spinner {
|
||||
display: block;
|
||||
position: fixed;
|
||||
z-index: 1031;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
}
|
||||
|
||||
#nprogress .spinner-icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
box-sizing: border-box;
|
||||
|
||||
border: solid 2px transparent;
|
||||
border-top-color: #29d;
|
||||
border-left-color: #29d;
|
||||
border-radius: 50%;
|
||||
|
||||
-webkit-animation: nprogress-spinner 400ms linear infinite;
|
||||
animation: nprogress-spinner 400ms linear infinite;
|
||||
}
|
||||
|
||||
.nprogress-custom-parent {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nprogress-custom-parent #nprogress .spinner,
|
||||
.nprogress-custom-parent #nprogress .bar {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
@-webkit-keyframes nprogress-spinner {
|
||||
0% { -webkit-transform: rotate(0deg); }
|
||||
100% { -webkit-transform: rotate(360deg); }
|
||||
}
|
||||
@keyframes nprogress-spinner {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
476
static/assets/575ffb1/nprogress.js
Normal file
476
static/assets/575ffb1/nprogress.js
Normal file
@ -0,0 +1,476 @@
|
||||
/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress
|
||||
* @license MIT */
|
||||
|
||||
;(function(root, factory) {
|
||||
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
module.exports = factory();
|
||||
} else {
|
||||
root.NProgress = factory();
|
||||
}
|
||||
|
||||
})(this, function() {
|
||||
var NProgress = {};
|
||||
|
||||
NProgress.version = '0.2.0';
|
||||
|
||||
var Settings = NProgress.settings = {
|
||||
minimum: 0.08,
|
||||
easing: 'ease',
|
||||
positionUsing: '',
|
||||
speed: 200,
|
||||
trickle: true,
|
||||
trickleRate: 0.02,
|
||||
trickleSpeed: 800,
|
||||
showSpinner: true,
|
||||
barSelector: '[role="bar"]',
|
||||
spinnerSelector: '[role="spinner"]',
|
||||
parent: 'body',
|
||||
template: '<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates configuration.
|
||||
*
|
||||
* NProgress.configure({
|
||||
* minimum: 0.1
|
||||
* });
|
||||
*/
|
||||
NProgress.configure = function(options) {
|
||||
var key, value;
|
||||
for (key in options) {
|
||||
value = options[key];
|
||||
if (value !== undefined && options.hasOwnProperty(key)) Settings[key] = value;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Last number.
|
||||
*/
|
||||
|
||||
NProgress.status = null;
|
||||
|
||||
/**
|
||||
* Sets the progress bar status, where `n` is a number from `0.0` to `1.0`.
|
||||
*
|
||||
* NProgress.set(0.4);
|
||||
* NProgress.set(1.0);
|
||||
*/
|
||||
|
||||
NProgress.set = function(n) {
|
||||
var started = NProgress.isStarted();
|
||||
|
||||
n = clamp(n, Settings.minimum, 1);
|
||||
NProgress.status = (n === 1 ? null : n);
|
||||
|
||||
var progress = NProgress.render(!started),
|
||||
bar = progress.querySelector(Settings.barSelector),
|
||||
speed = Settings.speed,
|
||||
ease = Settings.easing;
|
||||
|
||||
progress.offsetWidth; /* Repaint */
|
||||
|
||||
queue(function(next) {
|
||||
// Set positionUsing if it hasn't already been set
|
||||
if (Settings.positionUsing === '') Settings.positionUsing = NProgress.getPositioningCSS();
|
||||
|
||||
// Add transition
|
||||
css(bar, barPositionCSS(n, speed, ease));
|
||||
|
||||
if (n === 1) {
|
||||
// Fade out
|
||||
css(progress, {
|
||||
transition: 'none',
|
||||
opacity: 1
|
||||
});
|
||||
progress.offsetWidth; /* Repaint */
|
||||
|
||||
setTimeout(function() {
|
||||
css(progress, {
|
||||
transition: 'all ' + speed + 'ms linear',
|
||||
opacity: 0
|
||||
});
|
||||
setTimeout(function() {
|
||||
NProgress.remove();
|
||||
next();
|
||||
}, speed);
|
||||
}, speed);
|
||||
} else {
|
||||
setTimeout(next, speed);
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
NProgress.isStarted = function() {
|
||||
return typeof NProgress.status === 'number';
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows the progress bar.
|
||||
* This is the same as setting the status to 0%, except that it doesn't go backwards.
|
||||
*
|
||||
* NProgress.start();
|
||||
*
|
||||
*/
|
||||
NProgress.start = function() {
|
||||
if (!NProgress.status) NProgress.set(0);
|
||||
|
||||
var work = function() {
|
||||
setTimeout(function() {
|
||||
if (!NProgress.status) return;
|
||||
NProgress.trickle();
|
||||
work();
|
||||
}, Settings.trickleSpeed);
|
||||
};
|
||||
|
||||
if (Settings.trickle) work();
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hides the progress bar.
|
||||
* This is the *sort of* the same as setting the status to 100%, with the
|
||||
* difference being `done()` makes some placebo effect of some realistic motion.
|
||||
*
|
||||
* NProgress.done();
|
||||
*
|
||||
* If `true` is passed, it will show the progress bar even if its hidden.
|
||||
*
|
||||
* NProgress.done(true);
|
||||
*/
|
||||
|
||||
NProgress.done = function(force) {
|
||||
if (!force && !NProgress.status) return this;
|
||||
|
||||
return NProgress.inc(0.3 + 0.5 * Math.random()).set(1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Increments by a random amount.
|
||||
*/
|
||||
|
||||
NProgress.inc = function(amount) {
|
||||
var n = NProgress.status;
|
||||
|
||||
if (!n) {
|
||||
return NProgress.start();
|
||||
} else {
|
||||
if (typeof amount !== 'number') {
|
||||
amount = (1 - n) * clamp(Math.random() * n, 0.1, 0.95);
|
||||
}
|
||||
|
||||
n = clamp(n + amount, 0, 0.994);
|
||||
return NProgress.set(n);
|
||||
}
|
||||
};
|
||||
|
||||
NProgress.trickle = function() {
|
||||
return NProgress.inc(Math.random() * Settings.trickleRate);
|
||||
};
|
||||
|
||||
/**
|
||||
* Waits for all supplied jQuery promises and
|
||||
* increases the progress as the promises resolve.
|
||||
*
|
||||
* @param $promise jQUery Promise
|
||||
*/
|
||||
(function() {
|
||||
var initial = 0, current = 0;
|
||||
|
||||
NProgress.promise = function($promise) {
|
||||
if (!$promise || $promise.state() === "resolved") {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (current === 0) {
|
||||
NProgress.start();
|
||||
}
|
||||
|
||||
initial++;
|
||||
current++;
|
||||
|
||||
$promise.always(function() {
|
||||
current--;
|
||||
if (current === 0) {
|
||||
initial = 0;
|
||||
NProgress.done();
|
||||
} else {
|
||||
NProgress.set((initial - current) / initial);
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
/**
|
||||
* (Internal) renders the progress bar markup based on the `template`
|
||||
* setting.
|
||||
*/
|
||||
|
||||
NProgress.render = function(fromStart) {
|
||||
if (NProgress.isRendered()) return document.getElementById('nprogress');
|
||||
|
||||
addClass(document.documentElement, 'nprogress-busy');
|
||||
|
||||
var progress = document.createElement('div');
|
||||
progress.id = 'nprogress';
|
||||
progress.innerHTML = Settings.template;
|
||||
|
||||
var bar = progress.querySelector(Settings.barSelector),
|
||||
perc = fromStart ? '-100' : toBarPerc(NProgress.status || 0),
|
||||
parent = document.querySelector(Settings.parent),
|
||||
spinner;
|
||||
|
||||
css(bar, {
|
||||
transition: 'all 0 linear',
|
||||
transform: 'translate3d(' + perc + '%,0,0)'
|
||||
});
|
||||
|
||||
if (!Settings.showSpinner) {
|
||||
spinner = progress.querySelector(Settings.spinnerSelector);
|
||||
spinner && removeElement(spinner);
|
||||
}
|
||||
|
||||
if (parent != document.body) {
|
||||
addClass(parent, 'nprogress-custom-parent');
|
||||
}
|
||||
|
||||
parent.appendChild(progress);
|
||||
return progress;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the element. Opposite of render().
|
||||
*/
|
||||
|
||||
NProgress.remove = function() {
|
||||
removeClass(document.documentElement, 'nprogress-busy');
|
||||
removeClass(document.querySelector(Settings.parent), 'nprogress-custom-parent');
|
||||
var progress = document.getElementById('nprogress');
|
||||
progress && removeElement(progress);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the progress bar is rendered.
|
||||
*/
|
||||
|
||||
NProgress.isRendered = function() {
|
||||
return !!document.getElementById('nprogress');
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine which positioning CSS rule to use.
|
||||
*/
|
||||
|
||||
NProgress.getPositioningCSS = function() {
|
||||
// Sniff on document.body.style
|
||||
var bodyStyle = document.body.style;
|
||||
|
||||
// Sniff prefixes
|
||||
var vendorPrefix = ('WebkitTransform' in bodyStyle) ? 'Webkit' :
|
||||
('MozTransform' in bodyStyle) ? 'Moz' :
|
||||
('msTransform' in bodyStyle) ? 'ms' :
|
||||
('OTransform' in bodyStyle) ? 'O' : '';
|
||||
|
||||
if (vendorPrefix + 'Perspective' in bodyStyle) {
|
||||
// Modern browsers with 3D support, e.g. Webkit, IE10
|
||||
return 'translate3d';
|
||||
} else if (vendorPrefix + 'Transform' in bodyStyle) {
|
||||
// Browsers without 3D support, e.g. IE9
|
||||
return 'translate';
|
||||
} else {
|
||||
// Browsers without translate() support, e.g. IE7-8
|
||||
return 'margin';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function clamp(n, min, max) {
|
||||
if (n < min) return min;
|
||||
if (n > max) return max;
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) converts a percentage (`0..1`) to a bar translateX
|
||||
* percentage (`-100%..0%`).
|
||||
*/
|
||||
|
||||
function toBarPerc(n) {
|
||||
return (-1 + n) * 100;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* (Internal) returns the correct CSS for changing the bar's
|
||||
* position given an n percentage, and speed and ease from Settings
|
||||
*/
|
||||
|
||||
function barPositionCSS(n, speed, ease) {
|
||||
var barCSS;
|
||||
|
||||
if (Settings.positionUsing === 'translate3d') {
|
||||
barCSS = { transform: 'translate3d('+toBarPerc(n)+'%,0,0)' };
|
||||
} else if (Settings.positionUsing === 'translate') {
|
||||
barCSS = { transform: 'translate('+toBarPerc(n)+'%,0)' };
|
||||
} else {
|
||||
barCSS = { 'margin-left': toBarPerc(n)+'%' };
|
||||
}
|
||||
|
||||
barCSS.transition = 'all '+speed+'ms '+ease;
|
||||
|
||||
return barCSS;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Queues a function to be executed.
|
||||
*/
|
||||
|
||||
var queue = (function() {
|
||||
var pending = [];
|
||||
|
||||
function next() {
|
||||
var fn = pending.shift();
|
||||
if (fn) {
|
||||
fn(next);
|
||||
}
|
||||
}
|
||||
|
||||
return function(fn) {
|
||||
pending.push(fn);
|
||||
if (pending.length == 1) next();
|
||||
};
|
||||
})();
|
||||
|
||||
/**
|
||||
* (Internal) Applies css properties to an element, similar to the jQuery
|
||||
* css method.
|
||||
*
|
||||
* While this helper does assist with vendor prefixed property names, it
|
||||
* does not perform any manipulation of values prior to setting styles.
|
||||
*/
|
||||
|
||||
var css = (function() {
|
||||
var cssPrefixes = [ 'Webkit', 'O', 'Moz', 'ms' ],
|
||||
cssProps = {};
|
||||
|
||||
function camelCase(string) {
|
||||
return string.replace(/^-ms-/, 'ms-').replace(/-([\da-z])/gi, function(match, letter) {
|
||||
return letter.toUpperCase();
|
||||
});
|
||||
}
|
||||
|
||||
function getVendorProp(name) {
|
||||
var style = document.body.style;
|
||||
if (name in style) return name;
|
||||
|
||||
var i = cssPrefixes.length,
|
||||
capName = name.charAt(0).toUpperCase() + name.slice(1),
|
||||
vendorName;
|
||||
while (i--) {
|
||||
vendorName = cssPrefixes[i] + capName;
|
||||
if (vendorName in style) return vendorName;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
function getStyleProp(name) {
|
||||
name = camelCase(name);
|
||||
return cssProps[name] || (cssProps[name] = getVendorProp(name));
|
||||
}
|
||||
|
||||
function applyCss(element, prop, value) {
|
||||
prop = getStyleProp(prop);
|
||||
element.style[prop] = value;
|
||||
}
|
||||
|
||||
return function(element, properties) {
|
||||
var args = arguments,
|
||||
prop,
|
||||
value;
|
||||
|
||||
if (args.length == 2) {
|
||||
for (prop in properties) {
|
||||
value = properties[prop];
|
||||
if (value !== undefined && properties.hasOwnProperty(prop)) applyCss(element, prop, value);
|
||||
}
|
||||
} else {
|
||||
applyCss(element, args[1], args[2]);
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
/**
|
||||
* (Internal) Determines if an element or space separated list of class names contains a class name.
|
||||
*/
|
||||
|
||||
function hasClass(element, name) {
|
||||
var list = typeof element == 'string' ? element : classList(element);
|
||||
return list.indexOf(' ' + name + ' ') >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Adds a class to an element.
|
||||
*/
|
||||
|
||||
function addClass(element, name) {
|
||||
var oldList = classList(element),
|
||||
newList = oldList + name;
|
||||
|
||||
if (hasClass(oldList, name)) return;
|
||||
|
||||
// Trim the opening space.
|
||||
element.className = newList.substring(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Removes a class from an element.
|
||||
*/
|
||||
|
||||
function removeClass(element, name) {
|
||||
var oldList = classList(element),
|
||||
newList;
|
||||
|
||||
if (!hasClass(element, name)) return;
|
||||
|
||||
// Replace the class name.
|
||||
newList = oldList.replace(' ' + name + ' ', ' ');
|
||||
|
||||
// Trim the opening and closing spaces.
|
||||
element.className = newList.substring(1, newList.length - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Gets a space separated list of the class names on the element.
|
||||
* The list is wrapped with a single space on each end to facilitate finding
|
||||
* matches within the list.
|
||||
*/
|
||||
|
||||
function classList(element) {
|
||||
return (' ' + (element.className || '') + ' ').replace(/\s+/gi, ' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Removes an element from the DOM.
|
||||
*/
|
||||
|
||||
function removeElement(element) {
|
||||
element && element.parentNode && element.parentNode.removeChild(element);
|
||||
}
|
||||
|
||||
return NProgress;
|
||||
});
|
||||
|
4
static/assets/575ffb1/support/extras.css
Normal file
4
static/assets/575ffb1/support/extras.css
Normal file
@ -0,0 +1,4 @@
|
||||
/* Make the entire page show a busy cursor */
|
||||
.nprogress-busy body {
|
||||
cursor: wait;
|
||||
}
|
15
static/assets/61314fef/js/humhub.user.js
Normal file
15
static/assets/61314fef/js/humhub.user.js
Normal file
@ -0,0 +1,15 @@
|
||||
humhub.module('user', function(module, require, $) {
|
||||
|
||||
var isGuest = function() {
|
||||
return module.config.isGuest;
|
||||
};
|
||||
|
||||
var guid = function() {
|
||||
return module.config.guid;
|
||||
};
|
||||
|
||||
module.export({
|
||||
isGuest: isGuest,
|
||||
guid: guid
|
||||
});
|
||||
});
|
31
static/assets/61314fef/js/humhub.user.picker.js
Normal file
31
static/assets/61314fef/js/humhub.user.picker.js
Normal file
@ -0,0 +1,31 @@
|
||||
humhub.module('user.picker', function(module, require, $) {
|
||||
var object = require('util').object;
|
||||
var Picker = require('ui.picker').Picker;
|
||||
|
||||
var UserPicker = function(node, options) {
|
||||
Picker.call(this, node, options);
|
||||
};
|
||||
|
||||
object.inherits(UserPicker, Picker);
|
||||
|
||||
UserPicker.prototype.selectSelf = function() {
|
||||
var userConfig = require('config').get('user');
|
||||
if (userConfig && !userConfig.isGuest) {
|
||||
this.select(userConfig.guid, userConfig.text, userConfig.image);
|
||||
}
|
||||
};
|
||||
|
||||
var actionSelectSelf = function(event) {
|
||||
var picker = UserPicker.instance(event.$target);
|
||||
if (picker instanceof UserPicker) {
|
||||
picker.selectSelf();
|
||||
} else {
|
||||
module.log.error('Tried self select on non picker node!', true);
|
||||
}
|
||||
};
|
||||
|
||||
module.export({
|
||||
UserPicker: UserPicker,
|
||||
actionSelectSelf: actionSelectSelf
|
||||
});
|
||||
});
|
7
static/assets/65c6a4b7/HELP-US-OUT.txt
Normal file
7
static/assets/65c6a4b7/HELP-US-OUT.txt
Normal file
@ -0,0 +1,7 @@
|
||||
I hope you love Font Awesome. If you've found it useful, please do me a favor and check out my latest project,
|
||||
Fort Awesome (https://fortawesome.com). It makes it easy to put the perfect icons on your website. Choose from our awesome,
|
||||
comprehensive icon sets or copy and paste your own.
|
||||
|
||||
Please. Check it out.
|
||||
|
||||
-Dave Gandy
|
22
static/assets/65c6a4b7/bower.json
Normal file
22
static/assets/65c6a4b7/bower.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "font-awesome",
|
||||
"description": "Font Awesome",
|
||||
"keywords": [],
|
||||
"homepage": "http://fontawesome.io",
|
||||
"dependencies": {},
|
||||
"devDependencies": {},
|
||||
"license": ["OFL-1.1", "MIT", "CC-BY-3.0"],
|
||||
"main": [
|
||||
"less/font-awesome.less",
|
||||
"scss/font-awesome.scss"
|
||||
],
|
||||
"ignore": [
|
||||
"*/.*",
|
||||
"*.json",
|
||||
"src",
|
||||
"*.yml",
|
||||
"Gemfile",
|
||||
"Gemfile.lock",
|
||||
"*.md"
|
||||
]
|
||||
}
|
2337
static/assets/65c6a4b7/css/font-awesome.css
vendored
Normal file
2337
static/assets/65c6a4b7/css/font-awesome.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7
static/assets/65c6a4b7/css/font-awesome.css.map
Normal file
7
static/assets/65c6a4b7/css/font-awesome.css.map
Normal file
File diff suppressed because one or more lines are too long
4
static/assets/65c6a4b7/css/font-awesome.min.css
vendored
Normal file
4
static/assets/65c6a4b7/css/font-awesome.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
static/assets/65c6a4b7/fonts/FontAwesome.otf
Normal file
BIN
static/assets/65c6a4b7/fonts/FontAwesome.otf
Normal file
Binary file not shown.
BIN
static/assets/65c6a4b7/fonts/fontawesome-webfont.eot
Normal file
BIN
static/assets/65c6a4b7/fonts/fontawesome-webfont.eot
Normal file
Binary file not shown.
2671
static/assets/65c6a4b7/fonts/fontawesome-webfont.svg
Normal file
2671
static/assets/65c6a4b7/fonts/fontawesome-webfont.svg
Normal file
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 434 KiB |
BIN
static/assets/65c6a4b7/fonts/fontawesome-webfont.ttf
Normal file
BIN
static/assets/65c6a4b7/fonts/fontawesome-webfont.ttf
Normal file
Binary file not shown.
BIN
static/assets/65c6a4b7/fonts/fontawesome-webfont.woff
Normal file
BIN
static/assets/65c6a4b7/fonts/fontawesome-webfont.woff
Normal file
Binary file not shown.
BIN
static/assets/65c6a4b7/fonts/fontawesome-webfont.woff2
Normal file
BIN
static/assets/65c6a4b7/fonts/fontawesome-webfont.woff2
Normal file
Binary file not shown.
34
static/assets/65c6a4b7/less/animated.less
Normal file
34
static/assets/65c6a4b7/less/animated.less
Normal file
@ -0,0 +1,34 @@
|
||||
// Animated Icons
|
||||
// --------------------------
|
||||
|
||||
.@{fa-css-prefix}-spin {
|
||||
-webkit-animation: fa-spin 2s infinite linear;
|
||||
animation: fa-spin 2s infinite linear;
|
||||
}
|
||||
|
||||
.@{fa-css-prefix}-pulse {
|
||||
-webkit-animation: fa-spin 1s infinite steps(8);
|
||||
animation: fa-spin 1s infinite steps(8);
|
||||
}
|
||||
|
||||
@-webkit-keyframes fa-spin {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fa-spin {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
25
static/assets/65c6a4b7/less/bordered-pulled.less
Normal file
25
static/assets/65c6a4b7/less/bordered-pulled.less
Normal file
@ -0,0 +1,25 @@
|
||||
// Bordered & Pulled
|
||||
// -------------------------
|
||||
|
||||
.@{fa-css-prefix}-border {
|
||||
padding: .2em .25em .15em;
|
||||
border: solid .08em @fa-border-color;
|
||||
border-radius: .1em;
|
||||
}
|
||||
|
||||
.@{fa-css-prefix}-pull-left { float: left; }
|
||||
.@{fa-css-prefix}-pull-right { float: right; }
|
||||
|
||||
.@{fa-css-prefix} {
|
||||
&.@{fa-css-prefix}-pull-left { margin-right: .3em; }
|
||||
&.@{fa-css-prefix}-pull-right { margin-left: .3em; }
|
||||
}
|
||||
|
||||
/* Deprecated as of 4.4.0 */
|
||||
.pull-right { float: right; }
|
||||
.pull-left { float: left; }
|
||||
|
||||
.@{fa-css-prefix} {
|
||||
&.pull-left { margin-right: .3em; }
|
||||
&.pull-right { margin-left: .3em; }
|
||||
}
|
12
static/assets/65c6a4b7/less/core.less
Normal file
12
static/assets/65c6a4b7/less/core.less
Normal file
@ -0,0 +1,12 @@
|
||||
// Base Class Definition
|
||||
// -------------------------
|
||||
|
||||
.@{fa-css-prefix} {
|
||||
display: inline-block;
|
||||
font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
|
||||
font-size: inherit; // can't have font-size inherit on line above, so need to override
|
||||
text-rendering: auto; // optimizelegibility throws things off #1094
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
}
|
6
static/assets/65c6a4b7/less/fixed-width.less
Normal file
6
static/assets/65c6a4b7/less/fixed-width.less
Normal file
@ -0,0 +1,6 @@
|
||||
// Fixed Width Icons
|
||||
// -------------------------
|
||||
.@{fa-css-prefix}-fw {
|
||||
width: (18em / 14);
|
||||
text-align: center;
|
||||
}
|
18
static/assets/65c6a4b7/less/font-awesome.less
vendored
Normal file
18
static/assets/65c6a4b7/less/font-awesome.less
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
/*!
|
||||
* Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
|
||||
* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
|
||||
*/
|
||||
|
||||
@import "variables.less";
|
||||
@import "mixins.less";
|
||||
@import "path.less";
|
||||
@import "core.less";
|
||||
@import "larger.less";
|
||||
@import "fixed-width.less";
|
||||
@import "list.less";
|
||||
@import "bordered-pulled.less";
|
||||
@import "animated.less";
|
||||
@import "rotated-flipped.less";
|
||||
@import "stacked.less";
|
||||
@import "icons.less";
|
||||
@import "screen-reader.less";
|
789
static/assets/65c6a4b7/less/icons.less
Normal file
789
static/assets/65c6a4b7/less/icons.less
Normal file
@ -0,0 +1,789 @@
|
||||
/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
|
||||
readers do not read off random characters that represent icons */
|
||||
|
||||
.@{fa-css-prefix}-glass:before { content: @fa-var-glass; }
|
||||
.@{fa-css-prefix}-music:before { content: @fa-var-music; }
|
||||
.@{fa-css-prefix}-search:before { content: @fa-var-search; }
|
||||
.@{fa-css-prefix}-envelope-o:before { content: @fa-var-envelope-o; }
|
||||
.@{fa-css-prefix}-heart:before { content: @fa-var-heart; }
|
||||
.@{fa-css-prefix}-star:before { content: @fa-var-star; }
|
||||
.@{fa-css-prefix}-star-o:before { content: @fa-var-star-o; }
|
||||
.@{fa-css-prefix}-user:before { content: @fa-var-user; }
|
||||
.@{fa-css-prefix}-film:before { content: @fa-var-film; }
|
||||
.@{fa-css-prefix}-th-large:before { content: @fa-var-th-large; }
|
||||
.@{fa-css-prefix}-th:before { content: @fa-var-th; }
|
||||
.@{fa-css-prefix}-th-list:before { content: @fa-var-th-list; }
|
||||
.@{fa-css-prefix}-check:before { content: @fa-var-check; }
|
||||
.@{fa-css-prefix}-remove:before,
|
||||
.@{fa-css-prefix}-close:before,
|
||||
.@{fa-css-prefix}-times:before { content: @fa-var-times; }
|
||||
.@{fa-css-prefix}-search-plus:before { content: @fa-var-search-plus; }
|
||||
.@{fa-css-prefix}-search-minus:before { content: @fa-var-search-minus; }
|
||||
.@{fa-css-prefix}-power-off:before { content: @fa-var-power-off; }
|
||||
.@{fa-css-prefix}-signal:before { content: @fa-var-signal; }
|
||||
.@{fa-css-prefix}-gear:before,
|
||||
.@{fa-css-prefix}-cog:before { content: @fa-var-cog; }
|
||||
.@{fa-css-prefix}-trash-o:before { content: @fa-var-trash-o; }
|
||||
.@{fa-css-prefix}-home:before { content: @fa-var-home; }
|
||||
.@{fa-css-prefix}-file-o:before { content: @fa-var-file-o; }
|
||||
.@{fa-css-prefix}-clock-o:before { content: @fa-var-clock-o; }
|
||||
.@{fa-css-prefix}-road:before { content: @fa-var-road; }
|
||||
.@{fa-css-prefix}-download:before { content: @fa-var-download; }
|
||||
.@{fa-css-prefix}-arrow-circle-o-down:before { content: @fa-var-arrow-circle-o-down; }
|
||||
.@{fa-css-prefix}-arrow-circle-o-up:before { content: @fa-var-arrow-circle-o-up; }
|
||||
.@{fa-css-prefix}-inbox:before { content: @fa-var-inbox; }
|
||||
.@{fa-css-prefix}-play-circle-o:before { content: @fa-var-play-circle-o; }
|
||||
.@{fa-css-prefix}-rotate-right:before,
|
||||
.@{fa-css-prefix}-repeat:before { content: @fa-var-repeat; }
|
||||
.@{fa-css-prefix}-refresh:before { content: @fa-var-refresh; }
|
||||
.@{fa-css-prefix}-list-alt:before { content: @fa-var-list-alt; }
|
||||
.@{fa-css-prefix}-lock:before { content: @fa-var-lock; }
|
||||
.@{fa-css-prefix}-flag:before { content: @fa-var-flag; }
|
||||
.@{fa-css-prefix}-headphones:before { content: @fa-var-headphones; }
|
||||
.@{fa-css-prefix}-volume-off:before { content: @fa-var-volume-off; }
|
||||
.@{fa-css-prefix}-volume-down:before { content: @fa-var-volume-down; }
|
||||
.@{fa-css-prefix}-volume-up:before { content: @fa-var-volume-up; }
|
||||
.@{fa-css-prefix}-qrcode:before { content: @fa-var-qrcode; }
|
||||
.@{fa-css-prefix}-barcode:before { content: @fa-var-barcode; }
|
||||
.@{fa-css-prefix}-tag:before { content: @fa-var-tag; }
|
||||
.@{fa-css-prefix}-tags:before { content: @fa-var-tags; }
|
||||
.@{fa-css-prefix}-book:before { content: @fa-var-book; }
|
||||
.@{fa-css-prefix}-bookmark:before { content: @fa-var-bookmark; }
|
||||
.@{fa-css-prefix}-print:before { content: @fa-var-print; }
|
||||
.@{fa-css-prefix}-camera:before { content: @fa-var-camera; }
|
||||
.@{fa-css-prefix}-font:before { content: @fa-var-font; }
|
||||
.@{fa-css-prefix}-bold:before { content: @fa-var-bold; }
|
||||
.@{fa-css-prefix}-italic:before { content: @fa-var-italic; }
|
||||
.@{fa-css-prefix}-text-height:before { content: @fa-var-text-height; }
|
||||
.@{fa-css-prefix}-text-width:before { content: @fa-var-text-width; }
|
||||
.@{fa-css-prefix}-align-left:before { content: @fa-var-align-left; }
|
||||
.@{fa-css-prefix}-align-center:before { content: @fa-var-align-center; }
|
||||
.@{fa-css-prefix}-align-right:before { content: @fa-var-align-right; }
|
||||
.@{fa-css-prefix}-align-justify:before { content: @fa-var-align-justify; }
|
||||
.@{fa-css-prefix}-list:before { content: @fa-var-list; }
|
||||
.@{fa-css-prefix}-dedent:before,
|
||||
.@{fa-css-prefix}-outdent:before { content: @fa-var-outdent; }
|
||||
.@{fa-css-prefix}-indent:before { content: @fa-var-indent; }
|
||||
.@{fa-css-prefix}-video-camera:before { content: @fa-var-video-camera; }
|
||||
.@{fa-css-prefix}-photo:before,
|
||||
.@{fa-css-prefix}-image:before,
|
||||
.@{fa-css-prefix}-picture-o:before { content: @fa-var-picture-o; }
|
||||
.@{fa-css-prefix}-pencil:before { content: @fa-var-pencil; }
|
||||
.@{fa-css-prefix}-map-marker:before { content: @fa-var-map-marker; }
|
||||
.@{fa-css-prefix}-adjust:before { content: @fa-var-adjust; }
|
||||
.@{fa-css-prefix}-tint:before { content: @fa-var-tint; }
|
||||
.@{fa-css-prefix}-edit:before,
|
||||
.@{fa-css-prefix}-pencil-square-o:before { content: @fa-var-pencil-square-o; }
|
||||
.@{fa-css-prefix}-share-square-o:before { content: @fa-var-share-square-o; }
|
||||
.@{fa-css-prefix}-check-square-o:before { content: @fa-var-check-square-o; }
|
||||
.@{fa-css-prefix}-arrows:before { content: @fa-var-arrows; }
|
||||
.@{fa-css-prefix}-step-backward:before { content: @fa-var-step-backward; }
|
||||
.@{fa-css-prefix}-fast-backward:before { content: @fa-var-fast-backward; }
|
||||
.@{fa-css-prefix}-backward:before { content: @fa-var-backward; }
|
||||
.@{fa-css-prefix}-play:before { content: @fa-var-play; }
|
||||
.@{fa-css-prefix}-pause:before { content: @fa-var-pause; }
|
||||
.@{fa-css-prefix}-stop:before { content: @fa-var-stop; }
|
||||
.@{fa-css-prefix}-forward:before { content: @fa-var-forward; }
|
||||
.@{fa-css-prefix}-fast-forward:before { content: @fa-var-fast-forward; }
|
||||
.@{fa-css-prefix}-step-forward:before { content: @fa-var-step-forward; }
|
||||
.@{fa-css-prefix}-eject:before { content: @fa-var-eject; }
|
||||
.@{fa-css-prefix}-chevron-left:before { content: @fa-var-chevron-left; }
|
||||
.@{fa-css-prefix}-chevron-right:before { content: @fa-var-chevron-right; }
|
||||
.@{fa-css-prefix}-plus-circle:before { content: @fa-var-plus-circle; }
|
||||
.@{fa-css-prefix}-minus-circle:before { content: @fa-var-minus-circle; }
|
||||
.@{fa-css-prefix}-times-circle:before { content: @fa-var-times-circle; }
|
||||
.@{fa-css-prefix}-check-circle:before { content: @fa-var-check-circle; }
|
||||
.@{fa-css-prefix}-question-circle:before { content: @fa-var-question-circle; }
|
||||
.@{fa-css-prefix}-info-circle:before { content: @fa-var-info-circle; }
|
||||
.@{fa-css-prefix}-crosshairs:before { content: @fa-var-crosshairs; }
|
||||
.@{fa-css-prefix}-times-circle-o:before { content: @fa-var-times-circle-o; }
|
||||
.@{fa-css-prefix}-check-circle-o:before { content: @fa-var-check-circle-o; }
|
||||
.@{fa-css-prefix}-ban:before { content: @fa-var-ban; }
|
||||
.@{fa-css-prefix}-arrow-left:before { content: @fa-var-arrow-left; }
|
||||
.@{fa-css-prefix}-arrow-right:before { content: @fa-var-arrow-right; }
|
||||
.@{fa-css-prefix}-arrow-up:before { content: @fa-var-arrow-up; }
|
||||
.@{fa-css-prefix}-arrow-down:before { content: @fa-var-arrow-down; }
|
||||
.@{fa-css-prefix}-mail-forward:before,
|
||||
.@{fa-css-prefix}-share:before { content: @fa-var-share; }
|
||||
.@{fa-css-prefix}-expand:before { content: @fa-var-expand; }
|
||||
.@{fa-css-prefix}-compress:before { content: @fa-var-compress; }
|
||||
.@{fa-css-prefix}-plus:before { content: @fa-var-plus; }
|
||||
.@{fa-css-prefix}-minus:before { content: @fa-var-minus; }
|
||||
.@{fa-css-prefix}-asterisk:before { content: @fa-var-asterisk; }
|
||||
.@{fa-css-prefix}-exclamation-circle:before { content: @fa-var-exclamation-circle; }
|
||||
.@{fa-css-prefix}-gift:before { content: @fa-var-gift; }
|
||||
.@{fa-css-prefix}-leaf:before { content: @fa-var-leaf; }
|
||||
.@{fa-css-prefix}-fire:before { content: @fa-var-fire; }
|
||||
.@{fa-css-prefix}-eye:before { content: @fa-var-eye; }
|
||||
.@{fa-css-prefix}-eye-slash:before { content: @fa-var-eye-slash; }
|
||||
.@{fa-css-prefix}-warning:before,
|
||||
.@{fa-css-prefix}-exclamation-triangle:before { content: @fa-var-exclamation-triangle; }
|
||||
.@{fa-css-prefix}-plane:before { content: @fa-var-plane; }
|
||||
.@{fa-css-prefix}-calendar:before { content: @fa-var-calendar; }
|
||||
.@{fa-css-prefix}-random:before { content: @fa-var-random; }
|
||||
.@{fa-css-prefix}-comment:before { content: @fa-var-comment; }
|
||||
.@{fa-css-prefix}-magnet:before { content: @fa-var-magnet; }
|
||||
.@{fa-css-prefix}-chevron-up:before { content: @fa-var-chevron-up; }
|
||||
.@{fa-css-prefix}-chevron-down:before { content: @fa-var-chevron-down; }
|
||||
.@{fa-css-prefix}-retweet:before { content: @fa-var-retweet; }
|
||||
.@{fa-css-prefix}-shopping-cart:before { content: @fa-var-shopping-cart; }
|
||||
.@{fa-css-prefix}-folder:before { content: @fa-var-folder; }
|
||||
.@{fa-css-prefix}-folder-open:before { content: @fa-var-folder-open; }
|
||||
.@{fa-css-prefix}-arrows-v:before { content: @fa-var-arrows-v; }
|
||||
.@{fa-css-prefix}-arrows-h:before { content: @fa-var-arrows-h; }
|
||||
.@{fa-css-prefix}-bar-chart-o:before,
|
||||
.@{fa-css-prefix}-bar-chart:before { content: @fa-var-bar-chart; }
|
||||
.@{fa-css-prefix}-twitter-square:before { content: @fa-var-twitter-square; }
|
||||
.@{fa-css-prefix}-facebook-square:before { content: @fa-var-facebook-square; }
|
||||
.@{fa-css-prefix}-camera-retro:before { content: @fa-var-camera-retro; }
|
||||
.@{fa-css-prefix}-key:before { content: @fa-var-key; }
|
||||
.@{fa-css-prefix}-gears:before,
|
||||
.@{fa-css-prefix}-cogs:before { content: @fa-var-cogs; }
|
||||
.@{fa-css-prefix}-comments:before { content: @fa-var-comments; }
|
||||
.@{fa-css-prefix}-thumbs-o-up:before { content: @fa-var-thumbs-o-up; }
|
||||
.@{fa-css-prefix}-thumbs-o-down:before { content: @fa-var-thumbs-o-down; }
|
||||
.@{fa-css-prefix}-star-half:before { content: @fa-var-star-half; }
|
||||
.@{fa-css-prefix}-heart-o:before { content: @fa-var-heart-o; }
|
||||
.@{fa-css-prefix}-sign-out:before { content: @fa-var-sign-out; }
|
||||
.@{fa-css-prefix}-linkedin-square:before { content: @fa-var-linkedin-square; }
|
||||
.@{fa-css-prefix}-thumb-tack:before { content: @fa-var-thumb-tack; }
|
||||
.@{fa-css-prefix}-external-link:before { content: @fa-var-external-link; }
|
||||
.@{fa-css-prefix}-sign-in:before { content: @fa-var-sign-in; }
|
||||
.@{fa-css-prefix}-trophy:before { content: @fa-var-trophy; }
|
||||
.@{fa-css-prefix}-github-square:before { content: @fa-var-github-square; }
|
||||
.@{fa-css-prefix}-upload:before { content: @fa-var-upload; }
|
||||
.@{fa-css-prefix}-lemon-o:before { content: @fa-var-lemon-o; }
|
||||
.@{fa-css-prefix}-phone:before { content: @fa-var-phone; }
|
||||
.@{fa-css-prefix}-square-o:before { content: @fa-var-square-o; }
|
||||
.@{fa-css-prefix}-bookmark-o:before { content: @fa-var-bookmark-o; }
|
||||
.@{fa-css-prefix}-phone-square:before { content: @fa-var-phone-square; }
|
||||
.@{fa-css-prefix}-twitter:before { content: @fa-var-twitter; }
|
||||
.@{fa-css-prefix}-facebook-f:before,
|
||||
.@{fa-css-prefix}-facebook:before { content: @fa-var-facebook; }
|
||||
.@{fa-css-prefix}-github:before { content: @fa-var-github; }
|
||||
.@{fa-css-prefix}-unlock:before { content: @fa-var-unlock; }
|
||||
.@{fa-css-prefix}-credit-card:before { content: @fa-var-credit-card; }
|
||||
.@{fa-css-prefix}-feed:before,
|
||||
.@{fa-css-prefix}-rss:before { content: @fa-var-rss; }
|
||||
.@{fa-css-prefix}-hdd-o:before { content: @fa-var-hdd-o; }
|
||||
.@{fa-css-prefix}-bullhorn:before { content: @fa-var-bullhorn; }
|
||||
.@{fa-css-prefix}-bell:before { content: @fa-var-bell; }
|
||||
.@{fa-css-prefix}-certificate:before { content: @fa-var-certificate; }
|
||||
.@{fa-css-prefix}-hand-o-right:before { content: @fa-var-hand-o-right; }
|
||||
.@{fa-css-prefix}-hand-o-left:before { content: @fa-var-hand-o-left; }
|
||||
.@{fa-css-prefix}-hand-o-up:before { content: @fa-var-hand-o-up; }
|
||||
.@{fa-css-prefix}-hand-o-down:before { content: @fa-var-hand-o-down; }
|
||||
.@{fa-css-prefix}-arrow-circle-left:before { content: @fa-var-arrow-circle-left; }
|
||||
.@{fa-css-prefix}-arrow-circle-right:before { content: @fa-var-arrow-circle-right; }
|
||||
.@{fa-css-prefix}-arrow-circle-up:before { content: @fa-var-arrow-circle-up; }
|
||||
.@{fa-css-prefix}-arrow-circle-down:before { content: @fa-var-arrow-circle-down; }
|
||||
.@{fa-css-prefix}-globe:before { content: @fa-var-globe; }
|
||||
.@{fa-css-prefix}-wrench:before { content: @fa-var-wrench; }
|
||||
.@{fa-css-prefix}-tasks:before { content: @fa-var-tasks; }
|
||||
.@{fa-css-prefix}-filter:before { content: @fa-var-filter; }
|
||||
.@{fa-css-prefix}-briefcase:before { content: @fa-var-briefcase; }
|
||||
.@{fa-css-prefix}-arrows-alt:before { content: @fa-var-arrows-alt; }
|
||||
.@{fa-css-prefix}-group:before,
|
||||
.@{fa-css-prefix}-users:before { content: @fa-var-users; }
|
||||
.@{fa-css-prefix}-chain:before,
|
||||
.@{fa-css-prefix}-link:before { content: @fa-var-link; }
|
||||
.@{fa-css-prefix}-cloud:before { content: @fa-var-cloud; }
|
||||
.@{fa-css-prefix}-flask:before { content: @fa-var-flask; }
|
||||
.@{fa-css-prefix}-cut:before,
|
||||
.@{fa-css-prefix}-scissors:before { content: @fa-var-scissors; }
|
||||
.@{fa-css-prefix}-copy:before,
|
||||
.@{fa-css-prefix}-files-o:before { content: @fa-var-files-o; }
|
||||
.@{fa-css-prefix}-paperclip:before { content: @fa-var-paperclip; }
|
||||
.@{fa-css-prefix}-save:before,
|
||||
.@{fa-css-prefix}-floppy-o:before { content: @fa-var-floppy-o; }
|
||||
.@{fa-css-prefix}-square:before { content: @fa-var-square; }
|
||||
.@{fa-css-prefix}-navicon:before,
|
||||
.@{fa-css-prefix}-reorder:before,
|
||||
.@{fa-css-prefix}-bars:before { content: @fa-var-bars; }
|
||||
.@{fa-css-prefix}-list-ul:before { content: @fa-var-list-ul; }
|
||||
.@{fa-css-prefix}-list-ol:before { content: @fa-var-list-ol; }
|
||||
.@{fa-css-prefix}-strikethrough:before { content: @fa-var-strikethrough; }
|
||||
.@{fa-css-prefix}-underline:before { content: @fa-var-underline; }
|
||||
.@{fa-css-prefix}-table:before { content: @fa-var-table; }
|
||||
.@{fa-css-prefix}-magic:before { content: @fa-var-magic; }
|
||||
.@{fa-css-prefix}-truck:before { content: @fa-var-truck; }
|
||||
.@{fa-css-prefix}-pinterest:before { content: @fa-var-pinterest; }
|
||||
.@{fa-css-prefix}-pinterest-square:before { content: @fa-var-pinterest-square; }
|
||||
.@{fa-css-prefix}-google-plus-square:before { content: @fa-var-google-plus-square; }
|
||||
.@{fa-css-prefix}-google-plus:before { content: @fa-var-google-plus; }
|
||||
.@{fa-css-prefix}-money:before { content: @fa-var-money; }
|
||||
.@{fa-css-prefix}-caret-down:before { content: @fa-var-caret-down; }
|
||||
.@{fa-css-prefix}-caret-up:before { content: @fa-var-caret-up; }
|
||||
.@{fa-css-prefix}-caret-left:before { content: @fa-var-caret-left; }
|
||||
.@{fa-css-prefix}-caret-right:before { content: @fa-var-caret-right; }
|
||||
.@{fa-css-prefix}-columns:before { content: @fa-var-columns; }
|
||||
.@{fa-css-prefix}-unsorted:before,
|
||||
.@{fa-css-prefix}-sort:before { content: @fa-var-sort; }
|
||||
.@{fa-css-prefix}-sort-down:before,
|
||||
.@{fa-css-prefix}-sort-desc:before { content: @fa-var-sort-desc; }
|
||||
.@{fa-css-prefix}-sort-up:before,
|
||||
.@{fa-css-prefix}-sort-asc:before { content: @fa-var-sort-asc; }
|
||||
.@{fa-css-prefix}-envelope:before { content: @fa-var-envelope; }
|
||||
.@{fa-css-prefix}-linkedin:before { content: @fa-var-linkedin; }
|
||||
.@{fa-css-prefix}-rotate-left:before,
|
||||
.@{fa-css-prefix}-undo:before { content: @fa-var-undo; }
|
||||
.@{fa-css-prefix}-legal:before,
|
||||
.@{fa-css-prefix}-gavel:before { content: @fa-var-gavel; }
|
||||
.@{fa-css-prefix}-dashboard:before,
|
||||
.@{fa-css-prefix}-tachometer:before { content: @fa-var-tachometer; }
|
||||
.@{fa-css-prefix}-comment-o:before { content: @fa-var-comment-o; }
|
||||
.@{fa-css-prefix}-comments-o:before { content: @fa-var-comments-o; }
|
||||
.@{fa-css-prefix}-flash:before,
|
||||
.@{fa-css-prefix}-bolt:before { content: @fa-var-bolt; }
|
||||
.@{fa-css-prefix}-sitemap:before { content: @fa-var-sitemap; }
|
||||
.@{fa-css-prefix}-umbrella:before { content: @fa-var-umbrella; }
|
||||
.@{fa-css-prefix}-paste:before,
|
||||
.@{fa-css-prefix}-clipboard:before { content: @fa-var-clipboard; }
|
||||
.@{fa-css-prefix}-lightbulb-o:before { content: @fa-var-lightbulb-o; }
|
||||
.@{fa-css-prefix}-exchange:before { content: @fa-var-exchange; }
|
||||
.@{fa-css-prefix}-cloud-download:before { content: @fa-var-cloud-download; }
|
||||
.@{fa-css-prefix}-cloud-upload:before { content: @fa-var-cloud-upload; }
|
||||
.@{fa-css-prefix}-user-md:before { content: @fa-var-user-md; }
|
||||
.@{fa-css-prefix}-stethoscope:before { content: @fa-var-stethoscope; }
|
||||
.@{fa-css-prefix}-suitcase:before { content: @fa-var-suitcase; }
|
||||
.@{fa-css-prefix}-bell-o:before { content: @fa-var-bell-o; }
|
||||
.@{fa-css-prefix}-coffee:before { content: @fa-var-coffee; }
|
||||
.@{fa-css-prefix}-cutlery:before { content: @fa-var-cutlery; }
|
||||
.@{fa-css-prefix}-file-text-o:before { content: @fa-var-file-text-o; }
|
||||
.@{fa-css-prefix}-building-o:before { content: @fa-var-building-o; }
|
||||
.@{fa-css-prefix}-hospital-o:before { content: @fa-var-hospital-o; }
|
||||
.@{fa-css-prefix}-ambulance:before { content: @fa-var-ambulance; }
|
||||
.@{fa-css-prefix}-medkit:before { content: @fa-var-medkit; }
|
||||
.@{fa-css-prefix}-fighter-jet:before { content: @fa-var-fighter-jet; }
|
||||
.@{fa-css-prefix}-beer:before { content: @fa-var-beer; }
|
||||
.@{fa-css-prefix}-h-square:before { content: @fa-var-h-square; }
|
||||
.@{fa-css-prefix}-plus-square:before { content: @fa-var-plus-square; }
|
||||
.@{fa-css-prefix}-angle-double-left:before { content: @fa-var-angle-double-left; }
|
||||
.@{fa-css-prefix}-angle-double-right:before { content: @fa-var-angle-double-right; }
|
||||
.@{fa-css-prefix}-angle-double-up:before { content: @fa-var-angle-double-up; }
|
||||
.@{fa-css-prefix}-angle-double-down:before { content: @fa-var-angle-double-down; }
|
||||
.@{fa-css-prefix}-angle-left:before { content: @fa-var-angle-left; }
|
||||
.@{fa-css-prefix}-angle-right:before { content: @fa-var-angle-right; }
|
||||
.@{fa-css-prefix}-angle-up:before { content: @fa-var-angle-up; }
|
||||
.@{fa-css-prefix}-angle-down:before { content: @fa-var-angle-down; }
|
||||
.@{fa-css-prefix}-desktop:before { content: @fa-var-desktop; }
|
||||
.@{fa-css-prefix}-laptop:before { content: @fa-var-laptop; }
|
||||
.@{fa-css-prefix}-tablet:before { content: @fa-var-tablet; }
|
||||
.@{fa-css-prefix}-mobile-phone:before,
|
||||
.@{fa-css-prefix}-mobile:before { content: @fa-var-mobile; }
|
||||
.@{fa-css-prefix}-circle-o:before { content: @fa-var-circle-o; }
|
||||
.@{fa-css-prefix}-quote-left:before { content: @fa-var-quote-left; }
|
||||
.@{fa-css-prefix}-quote-right:before { content: @fa-var-quote-right; }
|
||||
.@{fa-css-prefix}-spinner:before { content: @fa-var-spinner; }
|
||||
.@{fa-css-prefix}-circle:before { content: @fa-var-circle; }
|
||||
.@{fa-css-prefix}-mail-reply:before,
|
||||
.@{fa-css-prefix}-reply:before { content: @fa-var-reply; }
|
||||
.@{fa-css-prefix}-github-alt:before { content: @fa-var-github-alt; }
|
||||
.@{fa-css-prefix}-folder-o:before { content: @fa-var-folder-o; }
|
||||
.@{fa-css-prefix}-folder-open-o:before { content: @fa-var-folder-open-o; }
|
||||
.@{fa-css-prefix}-smile-o:before { content: @fa-var-smile-o; }
|
||||
.@{fa-css-prefix}-frown-o:before { content: @fa-var-frown-o; }
|
||||
.@{fa-css-prefix}-meh-o:before { content: @fa-var-meh-o; }
|
||||
.@{fa-css-prefix}-gamepad:before { content: @fa-var-gamepad; }
|
||||
.@{fa-css-prefix}-keyboard-o:before { content: @fa-var-keyboard-o; }
|
||||
.@{fa-css-prefix}-flag-o:before { content: @fa-var-flag-o; }
|
||||
.@{fa-css-prefix}-flag-checkered:before { content: @fa-var-flag-checkered; }
|
||||
.@{fa-css-prefix}-terminal:before { content: @fa-var-terminal; }
|
||||
.@{fa-css-prefix}-code:before { content: @fa-var-code; }
|
||||
.@{fa-css-prefix}-mail-reply-all:before,
|
||||
.@{fa-css-prefix}-reply-all:before { content: @fa-var-reply-all; }
|
||||
.@{fa-css-prefix}-star-half-empty:before,
|
||||
.@{fa-css-prefix}-star-half-full:before,
|
||||
.@{fa-css-prefix}-star-half-o:before { content: @fa-var-star-half-o; }
|
||||
.@{fa-css-prefix}-location-arrow:before { content: @fa-var-location-arrow; }
|
||||
.@{fa-css-prefix}-crop:before { content: @fa-var-crop; }
|
||||
.@{fa-css-prefix}-code-fork:before { content: @fa-var-code-fork; }
|
||||
.@{fa-css-prefix}-unlink:before,
|
||||
.@{fa-css-prefix}-chain-broken:before { content: @fa-var-chain-broken; }
|
||||
.@{fa-css-prefix}-question:before { content: @fa-var-question; }
|
||||
.@{fa-css-prefix}-info:before { content: @fa-var-info; }
|
||||
.@{fa-css-prefix}-exclamation:before { content: @fa-var-exclamation; }
|
||||
.@{fa-css-prefix}-superscript:before { content: @fa-var-superscript; }
|
||||
.@{fa-css-prefix}-subscript:before { content: @fa-var-subscript; }
|
||||
.@{fa-css-prefix}-eraser:before { content: @fa-var-eraser; }
|
||||
.@{fa-css-prefix}-puzzle-piece:before { content: @fa-var-puzzle-piece; }
|
||||
.@{fa-css-prefix}-microphone:before { content: @fa-var-microphone; }
|
||||
.@{fa-css-prefix}-microphone-slash:before { content: @fa-var-microphone-slash; }
|
||||
.@{fa-css-prefix}-shield:before { content: @fa-var-shield; }
|
||||
.@{fa-css-prefix}-calendar-o:before { content: @fa-var-calendar-o; }
|
||||
.@{fa-css-prefix}-fire-extinguisher:before { content: @fa-var-fire-extinguisher; }
|
||||
.@{fa-css-prefix}-rocket:before { content: @fa-var-rocket; }
|
||||
.@{fa-css-prefix}-maxcdn:before { content: @fa-var-maxcdn; }
|
||||
.@{fa-css-prefix}-chevron-circle-left:before { content: @fa-var-chevron-circle-left; }
|
||||
.@{fa-css-prefix}-chevron-circle-right:before { content: @fa-var-chevron-circle-right; }
|
||||
.@{fa-css-prefix}-chevron-circle-up:before { content: @fa-var-chevron-circle-up; }
|
||||
.@{fa-css-prefix}-chevron-circle-down:before { content: @fa-var-chevron-circle-down; }
|
||||
.@{fa-css-prefix}-html5:before { content: @fa-var-html5; }
|
||||
.@{fa-css-prefix}-css3:before { content: @fa-var-css3; }
|
||||
.@{fa-css-prefix}-anchor:before { content: @fa-var-anchor; }
|
||||
.@{fa-css-prefix}-unlock-alt:before { content: @fa-var-unlock-alt; }
|
||||
.@{fa-css-prefix}-bullseye:before { content: @fa-var-bullseye; }
|
||||
.@{fa-css-prefix}-ellipsis-h:before { content: @fa-var-ellipsis-h; }
|
||||
.@{fa-css-prefix}-ellipsis-v:before { content: @fa-var-ellipsis-v; }
|
||||
.@{fa-css-prefix}-rss-square:before { content: @fa-var-rss-square; }
|
||||
.@{fa-css-prefix}-play-circle:before { content: @fa-var-play-circle; }
|
||||
.@{fa-css-prefix}-ticket:before { content: @fa-var-ticket; }
|
||||
.@{fa-css-prefix}-minus-square:before { content: @fa-var-minus-square; }
|
||||
.@{fa-css-prefix}-minus-square-o:before { content: @fa-var-minus-square-o; }
|
||||
.@{fa-css-prefix}-level-up:before { content: @fa-var-level-up; }
|
||||
.@{fa-css-prefix}-level-down:before { content: @fa-var-level-down; }
|
||||
.@{fa-css-prefix}-check-square:before { content: @fa-var-check-square; }
|
||||
.@{fa-css-prefix}-pencil-square:before { content: @fa-var-pencil-square; }
|
||||
.@{fa-css-prefix}-external-link-square:before { content: @fa-var-external-link-square; }
|
||||
.@{fa-css-prefix}-share-square:before { content: @fa-var-share-square; }
|
||||
.@{fa-css-prefix}-compass:before { content: @fa-var-compass; }
|
||||
.@{fa-css-prefix}-toggle-down:before,
|
||||
.@{fa-css-prefix}-caret-square-o-down:before { content: @fa-var-caret-square-o-down; }
|
||||
.@{fa-css-prefix}-toggle-up:before,
|
||||
.@{fa-css-prefix}-caret-square-o-up:before { content: @fa-var-caret-square-o-up; }
|
||||
.@{fa-css-prefix}-toggle-right:before,
|
||||
.@{fa-css-prefix}-caret-square-o-right:before { content: @fa-var-caret-square-o-right; }
|
||||
.@{fa-css-prefix}-euro:before,
|
||||
.@{fa-css-prefix}-eur:before { content: @fa-var-eur; }
|
||||
.@{fa-css-prefix}-gbp:before { content: @fa-var-gbp; }
|
||||
.@{fa-css-prefix}-dollar:before,
|
||||
.@{fa-css-prefix}-usd:before { content: @fa-var-usd; }
|
||||
.@{fa-css-prefix}-rupee:before,
|
||||
.@{fa-css-prefix}-inr:before { content: @fa-var-inr; }
|
||||
.@{fa-css-prefix}-cny:before,
|
||||
.@{fa-css-prefix}-rmb:before,
|
||||
.@{fa-css-prefix}-yen:before,
|
||||
.@{fa-css-prefix}-jpy:before { content: @fa-var-jpy; }
|
||||
.@{fa-css-prefix}-ruble:before,
|
||||
.@{fa-css-prefix}-rouble:before,
|
||||
.@{fa-css-prefix}-rub:before { content: @fa-var-rub; }
|
||||
.@{fa-css-prefix}-won:before,
|
||||
.@{fa-css-prefix}-krw:before { content: @fa-var-krw; }
|
||||
.@{fa-css-prefix}-bitcoin:before,
|
||||
.@{fa-css-prefix}-btc:before { content: @fa-var-btc; }
|
||||
.@{fa-css-prefix}-file:before { content: @fa-var-file; }
|
||||
.@{fa-css-prefix}-file-text:before { content: @fa-var-file-text; }
|
||||
.@{fa-css-prefix}-sort-alpha-asc:before { content: @fa-var-sort-alpha-asc; }
|
||||
.@{fa-css-prefix}-sort-alpha-desc:before { content: @fa-var-sort-alpha-desc; }
|
||||
.@{fa-css-prefix}-sort-amount-asc:before { content: @fa-var-sort-amount-asc; }
|
||||
.@{fa-css-prefix}-sort-amount-desc:before { content: @fa-var-sort-amount-desc; }
|
||||
.@{fa-css-prefix}-sort-numeric-asc:before { content: @fa-var-sort-numeric-asc; }
|
||||
.@{fa-css-prefix}-sort-numeric-desc:before { content: @fa-var-sort-numeric-desc; }
|
||||
.@{fa-css-prefix}-thumbs-up:before { content: @fa-var-thumbs-up; }
|
||||
.@{fa-css-prefix}-thumbs-down:before { content: @fa-var-thumbs-down; }
|
||||
.@{fa-css-prefix}-youtube-square:before { content: @fa-var-youtube-square; }
|
||||
.@{fa-css-prefix}-youtube:before { content: @fa-var-youtube; }
|
||||
.@{fa-css-prefix}-xing:before { content: @fa-var-xing; }
|
||||
.@{fa-css-prefix}-xing-square:before { content: @fa-var-xing-square; }
|
||||
.@{fa-css-prefix}-youtube-play:before { content: @fa-var-youtube-play; }
|
||||
.@{fa-css-prefix}-dropbox:before { content: @fa-var-dropbox; }
|
||||
.@{fa-css-prefix}-stack-overflow:before { content: @fa-var-stack-overflow; }
|
||||
.@{fa-css-prefix}-instagram:before { content: @fa-var-instagram; }
|
||||
.@{fa-css-prefix}-flickr:before { content: @fa-var-flickr; }
|
||||
.@{fa-css-prefix}-adn:before { content: @fa-var-adn; }
|
||||
.@{fa-css-prefix}-bitbucket:before { content: @fa-var-bitbucket; }
|
||||
.@{fa-css-prefix}-bitbucket-square:before { content: @fa-var-bitbucket-square; }
|
||||
.@{fa-css-prefix}-tumblr:before { content: @fa-var-tumblr; }
|
||||
.@{fa-css-prefix}-tumblr-square:before { content: @fa-var-tumblr-square; }
|
||||
.@{fa-css-prefix}-long-arrow-down:before { content: @fa-var-long-arrow-down; }
|
||||
.@{fa-css-prefix}-long-arrow-up:before { content: @fa-var-long-arrow-up; }
|
||||
.@{fa-css-prefix}-long-arrow-left:before { content: @fa-var-long-arrow-left; }
|
||||
.@{fa-css-prefix}-long-arrow-right:before { content: @fa-var-long-arrow-right; }
|
||||
.@{fa-css-prefix}-apple:before { content: @fa-var-apple; }
|
||||
.@{fa-css-prefix}-windows:before { content: @fa-var-windows; }
|
||||
.@{fa-css-prefix}-android:before { content: @fa-var-android; }
|
||||
.@{fa-css-prefix}-linux:before { content: @fa-var-linux; }
|
||||
.@{fa-css-prefix}-dribbble:before { content: @fa-var-dribbble; }
|
||||
.@{fa-css-prefix}-skype:before { content: @fa-var-skype; }
|
||||
.@{fa-css-prefix}-foursquare:before { content: @fa-var-foursquare; }
|
||||
.@{fa-css-prefix}-trello:before { content: @fa-var-trello; }
|
||||
.@{fa-css-prefix}-female:before { content: @fa-var-female; }
|
||||
.@{fa-css-prefix}-male:before { content: @fa-var-male; }
|
||||
.@{fa-css-prefix}-gittip:before,
|
||||
.@{fa-css-prefix}-gratipay:before { content: @fa-var-gratipay; }
|
||||
.@{fa-css-prefix}-sun-o:before { content: @fa-var-sun-o; }
|
||||
.@{fa-css-prefix}-moon-o:before { content: @fa-var-moon-o; }
|
||||
.@{fa-css-prefix}-archive:before { content: @fa-var-archive; }
|
||||
.@{fa-css-prefix}-bug:before { content: @fa-var-bug; }
|
||||
.@{fa-css-prefix}-vk:before { content: @fa-var-vk; }
|
||||
.@{fa-css-prefix}-weibo:before { content: @fa-var-weibo; }
|
||||
.@{fa-css-prefix}-renren:before { content: @fa-var-renren; }
|
||||
.@{fa-css-prefix}-pagelines:before { content: @fa-var-pagelines; }
|
||||
.@{fa-css-prefix}-stack-exchange:before { content: @fa-var-stack-exchange; }
|
||||
.@{fa-css-prefix}-arrow-circle-o-right:before { content: @fa-var-arrow-circle-o-right; }
|
||||
.@{fa-css-prefix}-arrow-circle-o-left:before { content: @fa-var-arrow-circle-o-left; }
|
||||
.@{fa-css-prefix}-toggle-left:before,
|
||||
.@{fa-css-prefix}-caret-square-o-left:before { content: @fa-var-caret-square-o-left; }
|
||||
.@{fa-css-prefix}-dot-circle-o:before { content: @fa-var-dot-circle-o; }
|
||||
.@{fa-css-prefix}-wheelchair:before { content: @fa-var-wheelchair; }
|
||||
.@{fa-css-prefix}-vimeo-square:before { content: @fa-var-vimeo-square; }
|
||||
.@{fa-css-prefix}-turkish-lira:before,
|
||||
.@{fa-css-prefix}-try:before { content: @fa-var-try; }
|
||||
.@{fa-css-prefix}-plus-square-o:before { content: @fa-var-plus-square-o; }
|
||||
.@{fa-css-prefix}-space-shuttle:before { content: @fa-var-space-shuttle; }
|
||||
.@{fa-css-prefix}-slack:before { content: @fa-var-slack; }
|
||||
.@{fa-css-prefix}-envelope-square:before { content: @fa-var-envelope-square; }
|
||||
.@{fa-css-prefix}-wordpress:before { content: @fa-var-wordpress; }
|
||||
.@{fa-css-prefix}-openid:before { content: @fa-var-openid; }
|
||||
.@{fa-css-prefix}-institution:before,
|
||||
.@{fa-css-prefix}-bank:before,
|
||||
.@{fa-css-prefix}-university:before { content: @fa-var-university; }
|
||||
.@{fa-css-prefix}-mortar-board:before,
|
||||
.@{fa-css-prefix}-graduation-cap:before { content: @fa-var-graduation-cap; }
|
||||
.@{fa-css-prefix}-yahoo:before { content: @fa-var-yahoo; }
|
||||
.@{fa-css-prefix}-google:before { content: @fa-var-google; }
|
||||
.@{fa-css-prefix}-reddit:before { content: @fa-var-reddit; }
|
||||
.@{fa-css-prefix}-reddit-square:before { content: @fa-var-reddit-square; }
|
||||
.@{fa-css-prefix}-stumbleupon-circle:before { content: @fa-var-stumbleupon-circle; }
|
||||
.@{fa-css-prefix}-stumbleupon:before { content: @fa-var-stumbleupon; }
|
||||
.@{fa-css-prefix}-delicious:before { content: @fa-var-delicious; }
|
||||
.@{fa-css-prefix}-digg:before { content: @fa-var-digg; }
|
||||
.@{fa-css-prefix}-pied-piper-pp:before { content: @fa-var-pied-piper-pp; }
|
||||
.@{fa-css-prefix}-pied-piper-alt:before { content: @fa-var-pied-piper-alt; }
|
||||
.@{fa-css-prefix}-drupal:before { content: @fa-var-drupal; }
|
||||
.@{fa-css-prefix}-joomla:before { content: @fa-var-joomla; }
|
||||
.@{fa-css-prefix}-language:before { content: @fa-var-language; }
|
||||
.@{fa-css-prefix}-fax:before { content: @fa-var-fax; }
|
||||
.@{fa-css-prefix}-building:before { content: @fa-var-building; }
|
||||
.@{fa-css-prefix}-child:before { content: @fa-var-child; }
|
||||
.@{fa-css-prefix}-paw:before { content: @fa-var-paw; }
|
||||
.@{fa-css-prefix}-spoon:before { content: @fa-var-spoon; }
|
||||
.@{fa-css-prefix}-cube:before { content: @fa-var-cube; }
|
||||
.@{fa-css-prefix}-cubes:before { content: @fa-var-cubes; }
|
||||
.@{fa-css-prefix}-behance:before { content: @fa-var-behance; }
|
||||
.@{fa-css-prefix}-behance-square:before { content: @fa-var-behance-square; }
|
||||
.@{fa-css-prefix}-steam:before { content: @fa-var-steam; }
|
||||
.@{fa-css-prefix}-steam-square:before { content: @fa-var-steam-square; }
|
||||
.@{fa-css-prefix}-recycle:before { content: @fa-var-recycle; }
|
||||
.@{fa-css-prefix}-automobile:before,
|
||||
.@{fa-css-prefix}-car:before { content: @fa-var-car; }
|
||||
.@{fa-css-prefix}-cab:before,
|
||||
.@{fa-css-prefix}-taxi:before { content: @fa-var-taxi; }
|
||||
.@{fa-css-prefix}-tree:before { content: @fa-var-tree; }
|
||||
.@{fa-css-prefix}-spotify:before { content: @fa-var-spotify; }
|
||||
.@{fa-css-prefix}-deviantart:before { content: @fa-var-deviantart; }
|
||||
.@{fa-css-prefix}-soundcloud:before { content: @fa-var-soundcloud; }
|
||||
.@{fa-css-prefix}-database:before { content: @fa-var-database; }
|
||||
.@{fa-css-prefix}-file-pdf-o:before { content: @fa-var-file-pdf-o; }
|
||||
.@{fa-css-prefix}-file-word-o:before { content: @fa-var-file-word-o; }
|
||||
.@{fa-css-prefix}-file-excel-o:before { content: @fa-var-file-excel-o; }
|
||||
.@{fa-css-prefix}-file-powerpoint-o:before { content: @fa-var-file-powerpoint-o; }
|
||||
.@{fa-css-prefix}-file-photo-o:before,
|
||||
.@{fa-css-prefix}-file-picture-o:before,
|
||||
.@{fa-css-prefix}-file-image-o:before { content: @fa-var-file-image-o; }
|
||||
.@{fa-css-prefix}-file-zip-o:before,
|
||||
.@{fa-css-prefix}-file-archive-o:before { content: @fa-var-file-archive-o; }
|
||||
.@{fa-css-prefix}-file-sound-o:before,
|
||||
.@{fa-css-prefix}-file-audio-o:before { content: @fa-var-file-audio-o; }
|
||||
.@{fa-css-prefix}-file-movie-o:before,
|
||||
.@{fa-css-prefix}-file-video-o:before { content: @fa-var-file-video-o; }
|
||||
.@{fa-css-prefix}-file-code-o:before { content: @fa-var-file-code-o; }
|
||||
.@{fa-css-prefix}-vine:before { content: @fa-var-vine; }
|
||||
.@{fa-css-prefix}-codepen:before { content: @fa-var-codepen; }
|
||||
.@{fa-css-prefix}-jsfiddle:before { content: @fa-var-jsfiddle; }
|
||||
.@{fa-css-prefix}-life-bouy:before,
|
||||
.@{fa-css-prefix}-life-buoy:before,
|
||||
.@{fa-css-prefix}-life-saver:before,
|
||||
.@{fa-css-prefix}-support:before,
|
||||
.@{fa-css-prefix}-life-ring:before { content: @fa-var-life-ring; }
|
||||
.@{fa-css-prefix}-circle-o-notch:before { content: @fa-var-circle-o-notch; }
|
||||
.@{fa-css-prefix}-ra:before,
|
||||
.@{fa-css-prefix}-resistance:before,
|
||||
.@{fa-css-prefix}-rebel:before { content: @fa-var-rebel; }
|
||||
.@{fa-css-prefix}-ge:before,
|
||||
.@{fa-css-prefix}-empire:before { content: @fa-var-empire; }
|
||||
.@{fa-css-prefix}-git-square:before { content: @fa-var-git-square; }
|
||||
.@{fa-css-prefix}-git:before { content: @fa-var-git; }
|
||||
.@{fa-css-prefix}-y-combinator-square:before,
|
||||
.@{fa-css-prefix}-yc-square:before,
|
||||
.@{fa-css-prefix}-hacker-news:before { content: @fa-var-hacker-news; }
|
||||
.@{fa-css-prefix}-tencent-weibo:before { content: @fa-var-tencent-weibo; }
|
||||
.@{fa-css-prefix}-qq:before { content: @fa-var-qq; }
|
||||
.@{fa-css-prefix}-wechat:before,
|
||||
.@{fa-css-prefix}-weixin:before { content: @fa-var-weixin; }
|
||||
.@{fa-css-prefix}-send:before,
|
||||
.@{fa-css-prefix}-paper-plane:before { content: @fa-var-paper-plane; }
|
||||
.@{fa-css-prefix}-send-o:before,
|
||||
.@{fa-css-prefix}-paper-plane-o:before { content: @fa-var-paper-plane-o; }
|
||||
.@{fa-css-prefix}-history:before { content: @fa-var-history; }
|
||||
.@{fa-css-prefix}-circle-thin:before { content: @fa-var-circle-thin; }
|
||||
.@{fa-css-prefix}-header:before { content: @fa-var-header; }
|
||||
.@{fa-css-prefix}-paragraph:before { content: @fa-var-paragraph; }
|
||||
.@{fa-css-prefix}-sliders:before { content: @fa-var-sliders; }
|
||||
.@{fa-css-prefix}-share-alt:before { content: @fa-var-share-alt; }
|
||||
.@{fa-css-prefix}-share-alt-square:before { content: @fa-var-share-alt-square; }
|
||||
.@{fa-css-prefix}-bomb:before { content: @fa-var-bomb; }
|
||||
.@{fa-css-prefix}-soccer-ball-o:before,
|
||||
.@{fa-css-prefix}-futbol-o:before { content: @fa-var-futbol-o; }
|
||||
.@{fa-css-prefix}-tty:before { content: @fa-var-tty; }
|
||||
.@{fa-css-prefix}-binoculars:before { content: @fa-var-binoculars; }
|
||||
.@{fa-css-prefix}-plug:before { content: @fa-var-plug; }
|
||||
.@{fa-css-prefix}-slideshare:before { content: @fa-var-slideshare; }
|
||||
.@{fa-css-prefix}-twitch:before { content: @fa-var-twitch; }
|
||||
.@{fa-css-prefix}-yelp:before { content: @fa-var-yelp; }
|
||||
.@{fa-css-prefix}-newspaper-o:before { content: @fa-var-newspaper-o; }
|
||||
.@{fa-css-prefix}-wifi:before { content: @fa-var-wifi; }
|
||||
.@{fa-css-prefix}-calculator:before { content: @fa-var-calculator; }
|
||||
.@{fa-css-prefix}-paypal:before { content: @fa-var-paypal; }
|
||||
.@{fa-css-prefix}-google-wallet:before { content: @fa-var-google-wallet; }
|
||||
.@{fa-css-prefix}-cc-visa:before { content: @fa-var-cc-visa; }
|
||||
.@{fa-css-prefix}-cc-mastercard:before { content: @fa-var-cc-mastercard; }
|
||||
.@{fa-css-prefix}-cc-discover:before { content: @fa-var-cc-discover; }
|
||||
.@{fa-css-prefix}-cc-amex:before { content: @fa-var-cc-amex; }
|
||||
.@{fa-css-prefix}-cc-paypal:before { content: @fa-var-cc-paypal; }
|
||||
.@{fa-css-prefix}-cc-stripe:before { content: @fa-var-cc-stripe; }
|
||||
.@{fa-css-prefix}-bell-slash:before { content: @fa-var-bell-slash; }
|
||||
.@{fa-css-prefix}-bell-slash-o:before { content: @fa-var-bell-slash-o; }
|
||||
.@{fa-css-prefix}-trash:before { content: @fa-var-trash; }
|
||||
.@{fa-css-prefix}-copyright:before { content: @fa-var-copyright; }
|
||||
.@{fa-css-prefix}-at:before { content: @fa-var-at; }
|
||||
.@{fa-css-prefix}-eyedropper:before { content: @fa-var-eyedropper; }
|
||||
.@{fa-css-prefix}-paint-brush:before { content: @fa-var-paint-brush; }
|
||||
.@{fa-css-prefix}-birthday-cake:before { content: @fa-var-birthday-cake; }
|
||||
.@{fa-css-prefix}-area-chart:before { content: @fa-var-area-chart; }
|
||||
.@{fa-css-prefix}-pie-chart:before { content: @fa-var-pie-chart; }
|
||||
.@{fa-css-prefix}-line-chart:before { content: @fa-var-line-chart; }
|
||||
.@{fa-css-prefix}-lastfm:before { content: @fa-var-lastfm; }
|
||||
.@{fa-css-prefix}-lastfm-square:before { content: @fa-var-lastfm-square; }
|
||||
.@{fa-css-prefix}-toggle-off:before { content: @fa-var-toggle-off; }
|
||||
.@{fa-css-prefix}-toggle-on:before { content: @fa-var-toggle-on; }
|
||||
.@{fa-css-prefix}-bicycle:before { content: @fa-var-bicycle; }
|
||||
.@{fa-css-prefix}-bus:before { content: @fa-var-bus; }
|
||||
.@{fa-css-prefix}-ioxhost:before { content: @fa-var-ioxhost; }
|
||||
.@{fa-css-prefix}-angellist:before { content: @fa-var-angellist; }
|
||||
.@{fa-css-prefix}-cc:before { content: @fa-var-cc; }
|
||||
.@{fa-css-prefix}-shekel:before,
|
||||
.@{fa-css-prefix}-sheqel:before,
|
||||
.@{fa-css-prefix}-ils:before { content: @fa-var-ils; }
|
||||
.@{fa-css-prefix}-meanpath:before { content: @fa-var-meanpath; }
|
||||
.@{fa-css-prefix}-buysellads:before { content: @fa-var-buysellads; }
|
||||
.@{fa-css-prefix}-connectdevelop:before { content: @fa-var-connectdevelop; }
|
||||
.@{fa-css-prefix}-dashcube:before { content: @fa-var-dashcube; }
|
||||
.@{fa-css-prefix}-forumbee:before { content: @fa-var-forumbee; }
|
||||
.@{fa-css-prefix}-leanpub:before { content: @fa-var-leanpub; }
|
||||
.@{fa-css-prefix}-sellsy:before { content: @fa-var-sellsy; }
|
||||
.@{fa-css-prefix}-shirtsinbulk:before { content: @fa-var-shirtsinbulk; }
|
||||
.@{fa-css-prefix}-simplybuilt:before { content: @fa-var-simplybuilt; }
|
||||
.@{fa-css-prefix}-skyatlas:before { content: @fa-var-skyatlas; }
|
||||
.@{fa-css-prefix}-cart-plus:before { content: @fa-var-cart-plus; }
|
||||
.@{fa-css-prefix}-cart-arrow-down:before { content: @fa-var-cart-arrow-down; }
|
||||
.@{fa-css-prefix}-diamond:before { content: @fa-var-diamond; }
|
||||
.@{fa-css-prefix}-ship:before { content: @fa-var-ship; }
|
||||
.@{fa-css-prefix}-user-secret:before { content: @fa-var-user-secret; }
|
||||
.@{fa-css-prefix}-motorcycle:before { content: @fa-var-motorcycle; }
|
||||
.@{fa-css-prefix}-street-view:before { content: @fa-var-street-view; }
|
||||
.@{fa-css-prefix}-heartbeat:before { content: @fa-var-heartbeat; }
|
||||
.@{fa-css-prefix}-venus:before { content: @fa-var-venus; }
|
||||
.@{fa-css-prefix}-mars:before { content: @fa-var-mars; }
|
||||
.@{fa-css-prefix}-mercury:before { content: @fa-var-mercury; }
|
||||
.@{fa-css-prefix}-intersex:before,
|
||||
.@{fa-css-prefix}-transgender:before { content: @fa-var-transgender; }
|
||||
.@{fa-css-prefix}-transgender-alt:before { content: @fa-var-transgender-alt; }
|
||||
.@{fa-css-prefix}-venus-double:before { content: @fa-var-venus-double; }
|
||||
.@{fa-css-prefix}-mars-double:before { content: @fa-var-mars-double; }
|
||||
.@{fa-css-prefix}-venus-mars:before { content: @fa-var-venus-mars; }
|
||||
.@{fa-css-prefix}-mars-stroke:before { content: @fa-var-mars-stroke; }
|
||||
.@{fa-css-prefix}-mars-stroke-v:before { content: @fa-var-mars-stroke-v; }
|
||||
.@{fa-css-prefix}-mars-stroke-h:before { content: @fa-var-mars-stroke-h; }
|
||||
.@{fa-css-prefix}-neuter:before { content: @fa-var-neuter; }
|
||||
.@{fa-css-prefix}-genderless:before { content: @fa-var-genderless; }
|
||||
.@{fa-css-prefix}-facebook-official:before { content: @fa-var-facebook-official; }
|
||||
.@{fa-css-prefix}-pinterest-p:before { content: @fa-var-pinterest-p; }
|
||||
.@{fa-css-prefix}-whatsapp:before { content: @fa-var-whatsapp; }
|
||||
.@{fa-css-prefix}-server:before { content: @fa-var-server; }
|
||||
.@{fa-css-prefix}-user-plus:before { content: @fa-var-user-plus; }
|
||||
.@{fa-css-prefix}-user-times:before { content: @fa-var-user-times; }
|
||||
.@{fa-css-prefix}-hotel:before,
|
||||
.@{fa-css-prefix}-bed:before { content: @fa-var-bed; }
|
||||
.@{fa-css-prefix}-viacoin:before { content: @fa-var-viacoin; }
|
||||
.@{fa-css-prefix}-train:before { content: @fa-var-train; }
|
||||
.@{fa-css-prefix}-subway:before { content: @fa-var-subway; }
|
||||
.@{fa-css-prefix}-medium:before { content: @fa-var-medium; }
|
||||
.@{fa-css-prefix}-yc:before,
|
||||
.@{fa-css-prefix}-y-combinator:before { content: @fa-var-y-combinator; }
|
||||
.@{fa-css-prefix}-optin-monster:before { content: @fa-var-optin-monster; }
|
||||
.@{fa-css-prefix}-opencart:before { content: @fa-var-opencart; }
|
||||
.@{fa-css-prefix}-expeditedssl:before { content: @fa-var-expeditedssl; }
|
||||
.@{fa-css-prefix}-battery-4:before,
|
||||
.@{fa-css-prefix}-battery:before,
|
||||
.@{fa-css-prefix}-battery-full:before { content: @fa-var-battery-full; }
|
||||
.@{fa-css-prefix}-battery-3:before,
|
||||
.@{fa-css-prefix}-battery-three-quarters:before { content: @fa-var-battery-three-quarters; }
|
||||
.@{fa-css-prefix}-battery-2:before,
|
||||
.@{fa-css-prefix}-battery-half:before { content: @fa-var-battery-half; }
|
||||
.@{fa-css-prefix}-battery-1:before,
|
||||
.@{fa-css-prefix}-battery-quarter:before { content: @fa-var-battery-quarter; }
|
||||
.@{fa-css-prefix}-battery-0:before,
|
||||
.@{fa-css-prefix}-battery-empty:before { content: @fa-var-battery-empty; }
|
||||
.@{fa-css-prefix}-mouse-pointer:before { content: @fa-var-mouse-pointer; }
|
||||
.@{fa-css-prefix}-i-cursor:before { content: @fa-var-i-cursor; }
|
||||
.@{fa-css-prefix}-object-group:before { content: @fa-var-object-group; }
|
||||
.@{fa-css-prefix}-object-ungroup:before { content: @fa-var-object-ungroup; }
|
||||
.@{fa-css-prefix}-sticky-note:before { content: @fa-var-sticky-note; }
|
||||
.@{fa-css-prefix}-sticky-note-o:before { content: @fa-var-sticky-note-o; }
|
||||
.@{fa-css-prefix}-cc-jcb:before { content: @fa-var-cc-jcb; }
|
||||
.@{fa-css-prefix}-cc-diners-club:before { content: @fa-var-cc-diners-club; }
|
||||
.@{fa-css-prefix}-clone:before { content: @fa-var-clone; }
|
||||
.@{fa-css-prefix}-balance-scale:before { content: @fa-var-balance-scale; }
|
||||
.@{fa-css-prefix}-hourglass-o:before { content: @fa-var-hourglass-o; }
|
||||
.@{fa-css-prefix}-hourglass-1:before,
|
||||
.@{fa-css-prefix}-hourglass-start:before { content: @fa-var-hourglass-start; }
|
||||
.@{fa-css-prefix}-hourglass-2:before,
|
||||
.@{fa-css-prefix}-hourglass-half:before { content: @fa-var-hourglass-half; }
|
||||
.@{fa-css-prefix}-hourglass-3:before,
|
||||
.@{fa-css-prefix}-hourglass-end:before { content: @fa-var-hourglass-end; }
|
||||
.@{fa-css-prefix}-hourglass:before { content: @fa-var-hourglass; }
|
||||
.@{fa-css-prefix}-hand-grab-o:before,
|
||||
.@{fa-css-prefix}-hand-rock-o:before { content: @fa-var-hand-rock-o; }
|
||||
.@{fa-css-prefix}-hand-stop-o:before,
|
||||
.@{fa-css-prefix}-hand-paper-o:before { content: @fa-var-hand-paper-o; }
|
||||
.@{fa-css-prefix}-hand-scissors-o:before { content: @fa-var-hand-scissors-o; }
|
||||
.@{fa-css-prefix}-hand-lizard-o:before { content: @fa-var-hand-lizard-o; }
|
||||
.@{fa-css-prefix}-hand-spock-o:before { content: @fa-var-hand-spock-o; }
|
||||
.@{fa-css-prefix}-hand-pointer-o:before { content: @fa-var-hand-pointer-o; }
|
||||
.@{fa-css-prefix}-hand-peace-o:before { content: @fa-var-hand-peace-o; }
|
||||
.@{fa-css-prefix}-trademark:before { content: @fa-var-trademark; }
|
||||
.@{fa-css-prefix}-registered:before { content: @fa-var-registered; }
|
||||
.@{fa-css-prefix}-creative-commons:before { content: @fa-var-creative-commons; }
|
||||
.@{fa-css-prefix}-gg:before { content: @fa-var-gg; }
|
||||
.@{fa-css-prefix}-gg-circle:before { content: @fa-var-gg-circle; }
|
||||
.@{fa-css-prefix}-tripadvisor:before { content: @fa-var-tripadvisor; }
|
||||
.@{fa-css-prefix}-odnoklassniki:before { content: @fa-var-odnoklassniki; }
|
||||
.@{fa-css-prefix}-odnoklassniki-square:before { content: @fa-var-odnoklassniki-square; }
|
||||
.@{fa-css-prefix}-get-pocket:before { content: @fa-var-get-pocket; }
|
||||
.@{fa-css-prefix}-wikipedia-w:before { content: @fa-var-wikipedia-w; }
|
||||
.@{fa-css-prefix}-safari:before { content: @fa-var-safari; }
|
||||
.@{fa-css-prefix}-chrome:before { content: @fa-var-chrome; }
|
||||
.@{fa-css-prefix}-firefox:before { content: @fa-var-firefox; }
|
||||
.@{fa-css-prefix}-opera:before { content: @fa-var-opera; }
|
||||
.@{fa-css-prefix}-internet-explorer:before { content: @fa-var-internet-explorer; }
|
||||
.@{fa-css-prefix}-tv:before,
|
||||
.@{fa-css-prefix}-television:before { content: @fa-var-television; }
|
||||
.@{fa-css-prefix}-contao:before { content: @fa-var-contao; }
|
||||
.@{fa-css-prefix}-500px:before { content: @fa-var-500px; }
|
||||
.@{fa-css-prefix}-amazon:before { content: @fa-var-amazon; }
|
||||
.@{fa-css-prefix}-calendar-plus-o:before { content: @fa-var-calendar-plus-o; }
|
||||
.@{fa-css-prefix}-calendar-minus-o:before { content: @fa-var-calendar-minus-o; }
|
||||
.@{fa-css-prefix}-calendar-times-o:before { content: @fa-var-calendar-times-o; }
|
||||
.@{fa-css-prefix}-calendar-check-o:before { content: @fa-var-calendar-check-o; }
|
||||
.@{fa-css-prefix}-industry:before { content: @fa-var-industry; }
|
||||
.@{fa-css-prefix}-map-pin:before { content: @fa-var-map-pin; }
|
||||
.@{fa-css-prefix}-map-signs:before { content: @fa-var-map-signs; }
|
||||
.@{fa-css-prefix}-map-o:before { content: @fa-var-map-o; }
|
||||
.@{fa-css-prefix}-map:before { content: @fa-var-map; }
|
||||
.@{fa-css-prefix}-commenting:before { content: @fa-var-commenting; }
|
||||
.@{fa-css-prefix}-commenting-o:before { content: @fa-var-commenting-o; }
|
||||
.@{fa-css-prefix}-houzz:before { content: @fa-var-houzz; }
|
||||
.@{fa-css-prefix}-vimeo:before { content: @fa-var-vimeo; }
|
||||
.@{fa-css-prefix}-black-tie:before { content: @fa-var-black-tie; }
|
||||
.@{fa-css-prefix}-fonticons:before { content: @fa-var-fonticons; }
|
||||
.@{fa-css-prefix}-reddit-alien:before { content: @fa-var-reddit-alien; }
|
||||
.@{fa-css-prefix}-edge:before { content: @fa-var-edge; }
|
||||
.@{fa-css-prefix}-credit-card-alt:before { content: @fa-var-credit-card-alt; }
|
||||
.@{fa-css-prefix}-codiepie:before { content: @fa-var-codiepie; }
|
||||
.@{fa-css-prefix}-modx:before { content: @fa-var-modx; }
|
||||
.@{fa-css-prefix}-fort-awesome:before { content: @fa-var-fort-awesome; }
|
||||
.@{fa-css-prefix}-usb:before { content: @fa-var-usb; }
|
||||
.@{fa-css-prefix}-product-hunt:before { content: @fa-var-product-hunt; }
|
||||
.@{fa-css-prefix}-mixcloud:before { content: @fa-var-mixcloud; }
|
||||
.@{fa-css-prefix}-scribd:before { content: @fa-var-scribd; }
|
||||
.@{fa-css-prefix}-pause-circle:before { content: @fa-var-pause-circle; }
|
||||
.@{fa-css-prefix}-pause-circle-o:before { content: @fa-var-pause-circle-o; }
|
||||
.@{fa-css-prefix}-stop-circle:before { content: @fa-var-stop-circle; }
|
||||
.@{fa-css-prefix}-stop-circle-o:before { content: @fa-var-stop-circle-o; }
|
||||
.@{fa-css-prefix}-shopping-bag:before { content: @fa-var-shopping-bag; }
|
||||
.@{fa-css-prefix}-shopping-basket:before { content: @fa-var-shopping-basket; }
|
||||
.@{fa-css-prefix}-hashtag:before { content: @fa-var-hashtag; }
|
||||
.@{fa-css-prefix}-bluetooth:before { content: @fa-var-bluetooth; }
|
||||
.@{fa-css-prefix}-bluetooth-b:before { content: @fa-var-bluetooth-b; }
|
||||
.@{fa-css-prefix}-percent:before { content: @fa-var-percent; }
|
||||
.@{fa-css-prefix}-gitlab:before { content: @fa-var-gitlab; }
|
||||
.@{fa-css-prefix}-wpbeginner:before { content: @fa-var-wpbeginner; }
|
||||
.@{fa-css-prefix}-wpforms:before { content: @fa-var-wpforms; }
|
||||
.@{fa-css-prefix}-envira:before { content: @fa-var-envira; }
|
||||
.@{fa-css-prefix}-universal-access:before { content: @fa-var-universal-access; }
|
||||
.@{fa-css-prefix}-wheelchair-alt:before { content: @fa-var-wheelchair-alt; }
|
||||
.@{fa-css-prefix}-question-circle-o:before { content: @fa-var-question-circle-o; }
|
||||
.@{fa-css-prefix}-blind:before { content: @fa-var-blind; }
|
||||
.@{fa-css-prefix}-audio-description:before { content: @fa-var-audio-description; }
|
||||
.@{fa-css-prefix}-volume-control-phone:before { content: @fa-var-volume-control-phone; }
|
||||
.@{fa-css-prefix}-braille:before { content: @fa-var-braille; }
|
||||
.@{fa-css-prefix}-assistive-listening-systems:before { content: @fa-var-assistive-listening-systems; }
|
||||
.@{fa-css-prefix}-asl-interpreting:before,
|
||||
.@{fa-css-prefix}-american-sign-language-interpreting:before { content: @fa-var-american-sign-language-interpreting; }
|
||||
.@{fa-css-prefix}-deafness:before,
|
||||
.@{fa-css-prefix}-hard-of-hearing:before,
|
||||
.@{fa-css-prefix}-deaf:before { content: @fa-var-deaf; }
|
||||
.@{fa-css-prefix}-glide:before { content: @fa-var-glide; }
|
||||
.@{fa-css-prefix}-glide-g:before { content: @fa-var-glide-g; }
|
||||
.@{fa-css-prefix}-signing:before,
|
||||
.@{fa-css-prefix}-sign-language:before { content: @fa-var-sign-language; }
|
||||
.@{fa-css-prefix}-low-vision:before { content: @fa-var-low-vision; }
|
||||
.@{fa-css-prefix}-viadeo:before { content: @fa-var-viadeo; }
|
||||
.@{fa-css-prefix}-viadeo-square:before { content: @fa-var-viadeo-square; }
|
||||
.@{fa-css-prefix}-snapchat:before { content: @fa-var-snapchat; }
|
||||
.@{fa-css-prefix}-snapchat-ghost:before { content: @fa-var-snapchat-ghost; }
|
||||
.@{fa-css-prefix}-snapchat-square:before { content: @fa-var-snapchat-square; }
|
||||
.@{fa-css-prefix}-pied-piper:before { content: @fa-var-pied-piper; }
|
||||
.@{fa-css-prefix}-first-order:before { content: @fa-var-first-order; }
|
||||
.@{fa-css-prefix}-yoast:before { content: @fa-var-yoast; }
|
||||
.@{fa-css-prefix}-themeisle:before { content: @fa-var-themeisle; }
|
||||
.@{fa-css-prefix}-google-plus-circle:before,
|
||||
.@{fa-css-prefix}-google-plus-official:before { content: @fa-var-google-plus-official; }
|
||||
.@{fa-css-prefix}-fa:before,
|
||||
.@{fa-css-prefix}-font-awesome:before { content: @fa-var-font-awesome; }
|
||||
.@{fa-css-prefix}-handshake-o:before { content: @fa-var-handshake-o; }
|
||||
.@{fa-css-prefix}-envelope-open:before { content: @fa-var-envelope-open; }
|
||||
.@{fa-css-prefix}-envelope-open-o:before { content: @fa-var-envelope-open-o; }
|
||||
.@{fa-css-prefix}-linode:before { content: @fa-var-linode; }
|
||||
.@{fa-css-prefix}-address-book:before { content: @fa-var-address-book; }
|
||||
.@{fa-css-prefix}-address-book-o:before { content: @fa-var-address-book-o; }
|
||||
.@{fa-css-prefix}-vcard:before,
|
||||
.@{fa-css-prefix}-address-card:before { content: @fa-var-address-card; }
|
||||
.@{fa-css-prefix}-vcard-o:before,
|
||||
.@{fa-css-prefix}-address-card-o:before { content: @fa-var-address-card-o; }
|
||||
.@{fa-css-prefix}-user-circle:before { content: @fa-var-user-circle; }
|
||||
.@{fa-css-prefix}-user-circle-o:before { content: @fa-var-user-circle-o; }
|
||||
.@{fa-css-prefix}-user-o:before { content: @fa-var-user-o; }
|
||||
.@{fa-css-prefix}-id-badge:before { content: @fa-var-id-badge; }
|
||||
.@{fa-css-prefix}-drivers-license:before,
|
||||
.@{fa-css-prefix}-id-card:before { content: @fa-var-id-card; }
|
||||
.@{fa-css-prefix}-drivers-license-o:before,
|
||||
.@{fa-css-prefix}-id-card-o:before { content: @fa-var-id-card-o; }
|
||||
.@{fa-css-prefix}-quora:before { content: @fa-var-quora; }
|
||||
.@{fa-css-prefix}-free-code-camp:before { content: @fa-var-free-code-camp; }
|
||||
.@{fa-css-prefix}-telegram:before { content: @fa-var-telegram; }
|
||||
.@{fa-css-prefix}-thermometer-4:before,
|
||||
.@{fa-css-prefix}-thermometer:before,
|
||||
.@{fa-css-prefix}-thermometer-full:before { content: @fa-var-thermometer-full; }
|
||||
.@{fa-css-prefix}-thermometer-3:before,
|
||||
.@{fa-css-prefix}-thermometer-three-quarters:before { content: @fa-var-thermometer-three-quarters; }
|
||||
.@{fa-css-prefix}-thermometer-2:before,
|
||||
.@{fa-css-prefix}-thermometer-half:before { content: @fa-var-thermometer-half; }
|
||||
.@{fa-css-prefix}-thermometer-1:before,
|
||||
.@{fa-css-prefix}-thermometer-quarter:before { content: @fa-var-thermometer-quarter; }
|
||||
.@{fa-css-prefix}-thermometer-0:before,
|
||||
.@{fa-css-prefix}-thermometer-empty:before { content: @fa-var-thermometer-empty; }
|
||||
.@{fa-css-prefix}-shower:before { content: @fa-var-shower; }
|
||||
.@{fa-css-prefix}-bathtub:before,
|
||||
.@{fa-css-prefix}-s15:before,
|
||||
.@{fa-css-prefix}-bath:before { content: @fa-var-bath; }
|
||||
.@{fa-css-prefix}-podcast:before { content: @fa-var-podcast; }
|
||||
.@{fa-css-prefix}-window-maximize:before { content: @fa-var-window-maximize; }
|
||||
.@{fa-css-prefix}-window-minimize:before { content: @fa-var-window-minimize; }
|
||||
.@{fa-css-prefix}-window-restore:before { content: @fa-var-window-restore; }
|
||||
.@{fa-css-prefix}-times-rectangle:before,
|
||||
.@{fa-css-prefix}-window-close:before { content: @fa-var-window-close; }
|
||||
.@{fa-css-prefix}-times-rectangle-o:before,
|
||||
.@{fa-css-prefix}-window-close-o:before { content: @fa-var-window-close-o; }
|
||||
.@{fa-css-prefix}-bandcamp:before { content: @fa-var-bandcamp; }
|
||||
.@{fa-css-prefix}-grav:before { content: @fa-var-grav; }
|
||||
.@{fa-css-prefix}-etsy:before { content: @fa-var-etsy; }
|
||||
.@{fa-css-prefix}-imdb:before { content: @fa-var-imdb; }
|
||||
.@{fa-css-prefix}-ravelry:before { content: @fa-var-ravelry; }
|
||||
.@{fa-css-prefix}-eercast:before { content: @fa-var-eercast; }
|
||||
.@{fa-css-prefix}-microchip:before { content: @fa-var-microchip; }
|
||||
.@{fa-css-prefix}-snowflake-o:before { content: @fa-var-snowflake-o; }
|
||||
.@{fa-css-prefix}-superpowers:before { content: @fa-var-superpowers; }
|
||||
.@{fa-css-prefix}-wpexplorer:before { content: @fa-var-wpexplorer; }
|
||||
.@{fa-css-prefix}-meetup:before { content: @fa-var-meetup; }
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user