public push
This commit is contained in:
parent
a8bea19a87
commit
f38d02b40f
|
|
@ -3,7 +3,7 @@ class Admin::AllPageController < ApplicationController
|
|||
layout 'admin'
|
||||
def index
|
||||
@all_pages = AllPage.where('type_of != 3')
|
||||
@published_pages = PublishedPage.where('type_of = 1 OR type_of = 2').order('priority ASC')
|
||||
get_pp_pages
|
||||
end
|
||||
|
||||
def show
|
||||
|
|
@ -64,8 +64,27 @@ class Admin::AllPageController < ApplicationController
|
|||
redirect_to action: 'index'
|
||||
end
|
||||
|
||||
def change_priority
|
||||
def pp_priority_up
|
||||
pp_this = PublishedPage.find(params[:id])
|
||||
pp_this_prio = pp_this.priority
|
||||
pp_last = PublishedPage.where('(type_of = 1 OR type_of = 2) AND priority < ?', pp_this_prio).order('priority DESC').first
|
||||
pp_this.priority = pp_last.priority
|
||||
pp_this.save
|
||||
pp_last.priority = pp_this_prio
|
||||
pp_last.save
|
||||
|
||||
get_pp_pages
|
||||
end
|
||||
|
||||
def pp_priority_down
|
||||
pp_this = PublishedPage.find(params[:id])
|
||||
pp_this_prio = pp_this.priority
|
||||
pp_last = PublishedPage.where('(type_of = 1 OR type_of = 2) AND priority > ?', pp_this_prio).order('priority ASC').first
|
||||
pp_this.priority = pp_last.priority
|
||||
pp_this.save
|
||||
pp_last.priority = pp_this_prio
|
||||
pp_last.save
|
||||
get_pp_pages
|
||||
end
|
||||
|
||||
def publish
|
||||
|
|
@ -121,6 +140,12 @@ class Admin::AllPageController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def get_pp_pages
|
||||
@published_pages = PublishedPage.where('type_of = 1 OR type_of = 2').order('priority ASC')
|
||||
@pp_first = PublishedPage.where('type_of = 1 OR type_of = 2').order('priority ASC').first
|
||||
@pp_last = PublishedPage.where('type_of = 1 OR type_of = 2').order('priority DESC').first
|
||||
end
|
||||
|
||||
private
|
||||
def all_page_params
|
||||
params.require(:all_page).permit(:name, :article_id, :title, :type_of, :full_text)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,26 @@ class Admin::HomeController < ApplicationController
|
|||
before_action :authenticate_admin!
|
||||
layout 'admin'
|
||||
def index
|
||||
@adm = Admin.all
|
||||
@admin = current_admin
|
||||
end
|
||||
|
||||
def change_pass
|
||||
@admin = current_admin
|
||||
if params[:admin][:password].blank?
|
||||
params[:admin].delete(:password)
|
||||
params[:admin].delete(:password_confirmation)
|
||||
end
|
||||
if @admin.update(admin_params)
|
||||
bypass_sign_in(@admin)
|
||||
redirect_to action: 'index'
|
||||
else
|
||||
render "index"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def admin_params
|
||||
params.require(:admin).permit(:description, :password, :password_confirmation)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,6 +6,10 @@ class AllPage < ApplicationRecord
|
|||
has_one :published_page
|
||||
before_destroy :b_destroy
|
||||
|
||||
def should_generate_new_friendly_id?
|
||||
slug.blank? || title_changed?
|
||||
end
|
||||
|
||||
PAGE_TYPES = {
|
||||
1 => 'Strona zwykła',
|
||||
2 => 'Strona z listą wpisów',
|
||||
|
|
|
|||
|
|
@ -4,11 +4,17 @@ class PublishedPage < ApplicationRecord
|
|||
belongs_to :all_page
|
||||
belongs_to :article, optional: true
|
||||
|
||||
|
||||
def should_generate_new_friendly_id?
|
||||
slug.blank? || title_changed?
|
||||
end
|
||||
|
||||
def published
|
||||
true
|
||||
end
|
||||
def created_name
|
||||
Admin.find(self.created_by).description
|
||||
admin = Admin.find(self.created_by)
|
||||
admin.blank? ? 'nieznany' : admin.description
|
||||
end
|
||||
|
||||
def created_date
|
||||
|
|
|
|||
|
|
@ -1,31 +1,29 @@
|
|||
<ul id="sortable">
|
||||
<% for pp in @published_pages %>
|
||||
<li data-id="<%= pp.id %>" data-name="<%= pp.name %>" class="ui-state-default"><%= pp.name %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<pre id="serialize_output2"></pre>
|
||||
<% content_for :footer_scripts do %>
|
||||
<%= javascript_include_tag 'jquery-sortable' %>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$( "#sortable" ).sortable({
|
||||
placeholder: "ui-state-highlight"
|
||||
});
|
||||
$( "#sortable" ).disableSelection();
|
||||
/*
|
||||
var group = $("ol.sorting_pages").sortable({
|
||||
group: 'sorting_pages',
|
||||
delay: 500,
|
||||
onDrop: function ($item, container, _super) {
|
||||
var data = group.sortable("serialize").get();
|
||||
<table class="table table-bordered">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th style="width: 80px"></th>
|
||||
<th>Nazwa</th>
|
||||
</tr>
|
||||
<% for pp in @published_pages %>
|
||||
<tr>
|
||||
<td>
|
||||
<% if !@pp_first.blank? && @pp_first.id == pp.id %>
|
||||
<%= link_to raw('<i class="fa fa-caret-square-o-up"></i>'), '#', class: 'btn btn-xs btn-success', remote: true, title: 'Do góry', disabled: 'disabled' %>
|
||||
<% else %>
|
||||
<%= link_to raw('<i class="fa fa-caret-square-o-up"></i>'), {controller: '/admin/all_page', action: 'pp_priority_up', id: pp.id}, class: 'btn btn-xs btn-success', remote: true, title: 'Do góry' %>
|
||||
<% end %>
|
||||
<% if !@pp_last.blank? && @pp_last.id == pp.id %>
|
||||
<%= link_to raw('<i class="fa fa-caret-square-o-down"></i>'), '#', class: 'btn btn-xs btn-primary', remote: true, title: 'W dół', disabled: 'disabled' %>
|
||||
|
||||
var jsonString = JSON.stringify(data, null, ' ');
|
||||
<% else %>
|
||||
<%= link_to raw('<i class="fa fa-caret-square-o-down"></i>'), {controller: '/admin/all_page', action: 'pp_priority_down', id: pp.id}, class: 'btn btn-xs btn-primary', remote: true, title: 'W dół' %>
|
||||
<% end %>
|
||||
|
||||
$('#serialize_output2').text(jsonString);
|
||||
_super($item, container);
|
||||
}
|
||||
});
|
||||
*/
|
||||
});
|
||||
</script>
|
||||
<% end %>
|
||||
</td>
|
||||
<td>
|
||||
<%= pp.name %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% if false %>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box">
|
||||
|
|
@ -21,10 +20,9 @@
|
|||
|
||||
</div>
|
||||
<!-- /.box-header -->
|
||||
<div class="box-body">
|
||||
<div class="box-body" id="pp_priority">
|
||||
<%= render 'published_pages_priority' %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
$('#pp_priority').html('<%= escape_javascript(render('/admin/all_page/published_pages_priority')) %>');
|
||||
|
|
@ -0,0 +1 @@
|
|||
$('#pp_priority').html('<%= escape_javascript(render('/admin/all_page/published_pages_priority')) %>');
|
||||
|
|
@ -1 +1,44 @@
|
|||
<p>ToDo - Zmiana hasła, do logowania</p>
|
||||
<div class="row">
|
||||
<!-- left column -->
|
||||
<div class="col-md-6">
|
||||
<!-- general form elements -->
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">Zmiana danych</h3>
|
||||
</div>
|
||||
<!-- /.box-header -->
|
||||
<!-- form start -->
|
||||
<%= form_tag({controller: '/admin/home', action: :change_pass}) do %>
|
||||
<div class="box-body">
|
||||
<% if @admin.errors.any? %>
|
||||
<%= raw errors_to_html(@admin.errors) %>
|
||||
<% end %>
|
||||
<div class="form-group">
|
||||
<label>Opis</label>
|
||||
<%= text_field :admin, :description, class: "form-control", placeholder: 'Opis' %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Nowe Hasło</label>
|
||||
<%= password_field :admin, :password, class: "form-control", placeholder: 'Nowe Hasło' %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Powrtórz Nowe Hasło</label>
|
||||
<%= password_field :admin, :password_confirmation, class: "form-control", placeholder: 'Powtórz Nowe Hasło' %>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.box-body -->
|
||||
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary">Zapisz</button>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<!-- /.box -->
|
||||
|
||||
</div>
|
||||
<!--/.col (left) -->
|
||||
<!-- right column -->
|
||||
<div class="col-md-6">
|
||||
</div>
|
||||
<!--/.col (right) -->
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<title>Ubezpieczenie - Należności - Panel Administracyjny</title>
|
||||
<%= csrf_meta_tags %>
|
||||
<%= favicon_link_tag %>
|
||||
<link rel="shortcut icon" type="image/x-icon" href="/assets/favicon.ico">
|
||||
<%= stylesheet_link_tag 'application','bootstrap_lte' , 'font-awesome' , media: 'all', 'data-turbolinks-track': 'reload' %>
|
||||
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic" rel='stylesheet' type='text/css'>
|
||||
<%= stylesheet_link_tag 'AdminLTE', 'skin-blue', 'summernote' %>
|
||||
|
|
@ -41,11 +41,6 @@
|
|||
<span><%= current_admin.email %></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li class="user-footer">
|
||||
<div class="pull-right">
|
||||
<a href="#" class="btn btn-default btn-flat">Profil</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="user-footer">
|
||||
<div class="pull-right">
|
||||
<% if admin_signed_in? %>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<title><%= @page.blank? ? 'Ubezpieczenie-Należności' : "Ubezpieczenie-Należności: #{@page.title}" %></title>
|
||||
<%= csrf_meta_tags %>
|
||||
<%= favicon_link_tag %>
|
||||
<link rel="shortcut icon" type="image/x-icon" href="/assets/favicon.ico">
|
||||
<%= stylesheet_link_tag 'application','bootstrap' , 'font-awesome' , media: 'all', 'data-turbolinks-track': 'reload' %>
|
||||
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>
|
||||
<link href='https://fonts.googleapis.com/css?family=Merriweather:400,300,300italic,400italic,700,700italic,900,900italic' rel='stylesheet' type='text/css'>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<title>Ubezpieczenie-Należności - Panel Administracyjny</title>
|
||||
<%= csrf_meta_tags %>
|
||||
<%= favicon_link_tag %>
|
||||
<link rel="shortcut icon" type="image/x-icon" href="/assets/favicon.ico">
|
||||
<%= stylesheet_link_tag 'application','bootstrap_lte' , 'font-awesome' , media: 'all', 'data-turbolinks-track': 'reload' %>
|
||||
<link href='href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic"' rel='stylesheet' type='text/css'>
|
||||
<%= stylesheet_link_tag 'AdminLTE' %>
|
||||
|
|
|
|||
|
|
@ -13,12 +13,12 @@ default: &default
|
|||
adapter: mysql2
|
||||
encoding: utf8
|
||||
pool: 5
|
||||
username: simplecrm_usr
|
||||
password: CKScvDDtFzdwB4ep
|
||||
host: 51.254.143.84
|
||||
|
||||
development:
|
||||
<<: *default
|
||||
username: simplecrm_usr
|
||||
password: CKScvDDtFzdwB4ep
|
||||
database: simplecrm
|
||||
|
||||
# Warning: The database defined as "test" will be erased and
|
||||
|
|
@ -28,27 +28,9 @@ test:
|
|||
<<: *default
|
||||
database: simplecrm_test
|
||||
|
||||
# As with config/secrets.yml, you never want to store sensitive information,
|
||||
# like your database password, in your source code. If your source code is
|
||||
# ever seen by anyone, they now have access to your database.
|
||||
#
|
||||
# Instead, provide the password as a unix environment variable when you boot
|
||||
# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
|
||||
# for a full rundown on how to provide these environment variables in a
|
||||
# production deployment.
|
||||
#
|
||||
# On Heroku and other platform providers, you may have a full connection URL
|
||||
# available as an environment variable. For example:
|
||||
#
|
||||
# DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase"
|
||||
#
|
||||
# You can use this database configuration with:
|
||||
#
|
||||
# production:
|
||||
# url: <%= ENV['DATABASE_URL'] %>
|
||||
#
|
||||
|
||||
production:
|
||||
<<: *default
|
||||
database: SimpleCrm_production
|
||||
username: SimpleCrm
|
||||
password: <%= ENV['SIMPLECRM_DATABASE_PASSWORD'] %>
|
||||
database: simplecms_prod
|
||||
username: simplecms_prod_u
|
||||
password: xUTSz79pDWbIGcOC
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ Rails.application.configure do
|
|||
|
||||
# Disable serving static files from the `/public` folder by default since
|
||||
# Apache or NGINX already handles this.
|
||||
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
|
||||
config.public_file_server.enabled = true
|
||||
|
||||
# Compress JavaScripts and CSS.
|
||||
config.assets.js_compressor = :uglifier
|
||||
|
|
@ -29,7 +29,6 @@ Rails.application.configure do
|
|||
|
||||
# Do not fallback to assets pipeline if a precompiled asset is missed.
|
||||
config.assets.compile = false
|
||||
|
||||
# `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb
|
||||
|
||||
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ Devise.setup do |config|
|
|||
# one (and only one) @ exists in the given string. This is mainly
|
||||
# to give user feedback and not to assert the e-mail validity.
|
||||
config.email_regexp = /\A[^@\s]+@[^@\s]+\z/
|
||||
|
||||
config.secret_key = 'c2fbed1053014665f1fe026c590e7b9fa1c6b8475f9c141e831a4450613c3aeabfda00f6e654aa97f2b0db25d6e85ddf1794fc35d3d0b87304077b67dc2b5977'
|
||||
# ==> Configuration for :timeoutable
|
||||
# The time you want to timeout the user session without activity. After this
|
||||
# time the user will be asked for credentials again. Default is 30 minutes.
|
||||
|
|
|
|||
|
|
@ -6,10 +6,12 @@ Rails.application.routes.draw do
|
|||
resources :all_page
|
||||
end
|
||||
root 'home#index'
|
||||
post 'home/change_pass'
|
||||
resources :home
|
||||
get 'all_page/publish'
|
||||
get 'all_page/unpublish'
|
||||
get 'all_page/change_priority'
|
||||
get 'all_page/pp_priority_up'
|
||||
get 'all_page/pp_priority_down'
|
||||
resources :all_page
|
||||
resources :article
|
||||
end
|
||||
|
|
|
|||
|
|
@ -29,4 +29,4 @@ test:
|
|||
# and move the `production:` environment over there.
|
||||
|
||||
production:
|
||||
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
|
||||
secret_key_base: 05e298e4816f190c8b91a0467192930db4228fc57fef6db32aa78d13887ceb797f02ca14576133bc2d337895157f8dd93464d2ebe1c91cb0fbd66883052d4b09
|
||||
|
|
|
|||
40
db/schema.rb
40
db/schema.rb
|
|
@ -14,6 +14,7 @@ ActiveRecord::Schema.define(version: 20180119145343) do
|
|||
|
||||
create_table "admins", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci" do |t|
|
||||
t.string "email", default: "", null: false
|
||||
t.string "description", limit: 80
|
||||
t.string "encrypted_password", default: "", null: false
|
||||
t.string "reset_password_token"
|
||||
t.datetime "reset_password_sent_at"
|
||||
|
|
@ -33,6 +34,27 @@ ActiveRecord::Schema.define(version: 20180119145343) do
|
|||
t.index ["unlock_token"], name: "index_admins_on_unlock_token", unique: true
|
||||
end
|
||||
|
||||
create_table "all_pages", id: :integer, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci" do |t|
|
||||
t.string "name", limit: 40, null: false
|
||||
t.string "title", null: false
|
||||
t.string "slug", null: false
|
||||
t.string "meta_description"
|
||||
t.boolean "nofollow", default: false
|
||||
t.integer "type_of", null: false
|
||||
t.integer "article_id"
|
||||
t.text "small_text"
|
||||
t.text "full_text", limit: 16777215
|
||||
t.timestamp "updated_at"
|
||||
t.integer "updated_by"
|
||||
t.boolean "published", default: false, null: false
|
||||
end
|
||||
|
||||
create_table "articles", id: :integer, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci" do |t|
|
||||
t.string "name", null: false
|
||||
t.timestamp "updated_at"
|
||||
t.integer "updated_by"
|
||||
end
|
||||
|
||||
create_table "friendly_id_slugs", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci" do |t|
|
||||
t.string "slug", null: false
|
||||
t.integer "sluggable_id", null: false
|
||||
|
|
@ -45,4 +67,22 @@ ActiveRecord::Schema.define(version: 20180119145343) do
|
|||
t.index ["sluggable_type"], name: "index_friendly_id_slugs_on_sluggable_type"
|
||||
end
|
||||
|
||||
create_table "published_pages", id: :integer, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci" do |t|
|
||||
t.string "name", limit: 40, null: false
|
||||
t.string "title", null: false
|
||||
t.string "slug", null: false
|
||||
t.string "meta_description"
|
||||
t.integer "all_page_id", null: false
|
||||
t.boolean "nofollow", default: false, null: false
|
||||
t.integer "type_of", null: false
|
||||
t.integer "article_id"
|
||||
t.integer "priority", default: 0, null: false
|
||||
t.text "small_text"
|
||||
t.text "full_text", limit: 16777215
|
||||
t.timestamp "created_at"
|
||||
t.integer "created_by"
|
||||
t.timestamp "updated_at"
|
||||
t.integer "updated_by"
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,3 +5,10 @@
|
|||
#
|
||||
# movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
|
||||
# Character.create(name: 'Luke', movie: movies.first)
|
||||
|
||||
admin = Admin.new
|
||||
admin.email = 'kontakt.ubezpieczenie@gmail.com'
|
||||
admin.password = 'qazxsw123'
|
||||
admin.password_confirmation = 'qazxsw123'
|
||||
admin.description = 'Ubezpieczenie Naleznosci'
|
||||
admin.save!
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,601 @@
|
|||
(function() {
|
||||
var context = this;
|
||||
|
||||
(function() {
|
||||
(function() {
|
||||
var slice = [].slice;
|
||||
|
||||
this.ActionCable = {
|
||||
INTERNAL: {
|
||||
"message_types": {
|
||||
"welcome": "welcome",
|
||||
"ping": "ping",
|
||||
"confirmation": "confirm_subscription",
|
||||
"rejection": "reject_subscription"
|
||||
},
|
||||
"default_mount_path": "/cable",
|
||||
"protocols": ["actioncable-v1-json", "actioncable-unsupported"]
|
||||
},
|
||||
WebSocket: window.WebSocket,
|
||||
logger: window.console,
|
||||
createConsumer: function(url) {
|
||||
var ref;
|
||||
if (url == null) {
|
||||
url = (ref = this.getConfig("url")) != null ? ref : this.INTERNAL.default_mount_path;
|
||||
}
|
||||
return new ActionCable.Consumer(this.createWebSocketURL(url));
|
||||
},
|
||||
getConfig: function(name) {
|
||||
var element;
|
||||
element = document.head.querySelector("meta[name='action-cable-" + name + "']");
|
||||
return element != null ? element.getAttribute("content") : void 0;
|
||||
},
|
||||
createWebSocketURL: function(url) {
|
||||
var a;
|
||||
if (url && !/^wss?:/i.test(url)) {
|
||||
a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.href = a.href;
|
||||
a.protocol = a.protocol.replace("http", "ws");
|
||||
return a.href;
|
||||
} else {
|
||||
return url;
|
||||
}
|
||||
},
|
||||
startDebugging: function() {
|
||||
return this.debugging = true;
|
||||
},
|
||||
stopDebugging: function() {
|
||||
return this.debugging = null;
|
||||
},
|
||||
log: function() {
|
||||
var messages, ref;
|
||||
messages = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
||||
if (this.debugging) {
|
||||
messages.push(Date.now());
|
||||
return (ref = this.logger).log.apply(ref, ["[ActionCable]"].concat(slice.call(messages)));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
}).call(context);
|
||||
|
||||
var ActionCable = context.ActionCable;
|
||||
|
||||
(function() {
|
||||
(function() {
|
||||
var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
|
||||
|
||||
ActionCable.ConnectionMonitor = (function() {
|
||||
var clamp, now, secondsSince;
|
||||
|
||||
ConnectionMonitor.pollInterval = {
|
||||
min: 3,
|
||||
max: 30
|
||||
};
|
||||
|
||||
ConnectionMonitor.staleThreshold = 6;
|
||||
|
||||
function ConnectionMonitor(connection) {
|
||||
this.connection = connection;
|
||||
this.visibilityDidChange = bind(this.visibilityDidChange, this);
|
||||
this.reconnectAttempts = 0;
|
||||
}
|
||||
|
||||
ConnectionMonitor.prototype.start = function() {
|
||||
if (!this.isRunning()) {
|
||||
this.startedAt = now();
|
||||
delete this.stoppedAt;
|
||||
this.startPolling();
|
||||
document.addEventListener("visibilitychange", this.visibilityDidChange);
|
||||
return ActionCable.log("ConnectionMonitor started. pollInterval = " + (this.getPollInterval()) + " ms");
|
||||
}
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.stop = function() {
|
||||
if (this.isRunning()) {
|
||||
this.stoppedAt = now();
|
||||
this.stopPolling();
|
||||
document.removeEventListener("visibilitychange", this.visibilityDidChange);
|
||||
return ActionCable.log("ConnectionMonitor stopped");
|
||||
}
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.isRunning = function() {
|
||||
return (this.startedAt != null) && (this.stoppedAt == null);
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.recordPing = function() {
|
||||
return this.pingedAt = now();
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.recordConnect = function() {
|
||||
this.reconnectAttempts = 0;
|
||||
this.recordPing();
|
||||
delete this.disconnectedAt;
|
||||
return ActionCable.log("ConnectionMonitor recorded connect");
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.recordDisconnect = function() {
|
||||
this.disconnectedAt = now();
|
||||
return ActionCable.log("ConnectionMonitor recorded disconnect");
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.startPolling = function() {
|
||||
this.stopPolling();
|
||||
return this.poll();
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.stopPolling = function() {
|
||||
return clearTimeout(this.pollTimeout);
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.poll = function() {
|
||||
return this.pollTimeout = setTimeout((function(_this) {
|
||||
return function() {
|
||||
_this.reconnectIfStale();
|
||||
return _this.poll();
|
||||
};
|
||||
})(this), this.getPollInterval());
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.getPollInterval = function() {
|
||||
var interval, max, min, ref;
|
||||
ref = this.constructor.pollInterval, min = ref.min, max = ref.max;
|
||||
interval = 5 * Math.log(this.reconnectAttempts + 1);
|
||||
return Math.round(clamp(interval, min, max) * 1000);
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.reconnectIfStale = function() {
|
||||
if (this.connectionIsStale()) {
|
||||
ActionCable.log("ConnectionMonitor detected stale connection. reconnectAttempts = " + this.reconnectAttempts + ", pollInterval = " + (this.getPollInterval()) + " ms, time disconnected = " + (secondsSince(this.disconnectedAt)) + " s, stale threshold = " + this.constructor.staleThreshold + " s");
|
||||
this.reconnectAttempts++;
|
||||
if (this.disconnectedRecently()) {
|
||||
return ActionCable.log("ConnectionMonitor skipping reopening recent disconnect");
|
||||
} else {
|
||||
ActionCable.log("ConnectionMonitor reopening");
|
||||
return this.connection.reopen();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.connectionIsStale = function() {
|
||||
var ref;
|
||||
return secondsSince((ref = this.pingedAt) != null ? ref : this.startedAt) > this.constructor.staleThreshold;
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.disconnectedRecently = function() {
|
||||
return this.disconnectedAt && secondsSince(this.disconnectedAt) < this.constructor.staleThreshold;
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.visibilityDidChange = function() {
|
||||
if (document.visibilityState === "visible") {
|
||||
return setTimeout((function(_this) {
|
||||
return function() {
|
||||
if (_this.connectionIsStale() || !_this.connection.isOpen()) {
|
||||
ActionCable.log("ConnectionMonitor reopening stale connection on visibilitychange. visbilityState = " + document.visibilityState);
|
||||
return _this.connection.reopen();
|
||||
}
|
||||
};
|
||||
})(this), 200);
|
||||
}
|
||||
};
|
||||
|
||||
now = function() {
|
||||
return new Date().getTime();
|
||||
};
|
||||
|
||||
secondsSince = function(time) {
|
||||
return (now() - time) / 1000;
|
||||
};
|
||||
|
||||
clamp = function(number, min, max) {
|
||||
return Math.max(min, Math.min(max, number));
|
||||
};
|
||||
|
||||
return ConnectionMonitor;
|
||||
|
||||
})();
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var i, message_types, protocols, ref, supportedProtocols, unsupportedProtocol,
|
||||
slice = [].slice,
|
||||
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
|
||||
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||||
|
||||
ref = ActionCable.INTERNAL, message_types = ref.message_types, protocols = ref.protocols;
|
||||
|
||||
supportedProtocols = 2 <= protocols.length ? slice.call(protocols, 0, i = protocols.length - 1) : (i = 0, []), unsupportedProtocol = protocols[i++];
|
||||
|
||||
ActionCable.Connection = (function() {
|
||||
Connection.reopenDelay = 500;
|
||||
|
||||
function Connection(consumer) {
|
||||
this.consumer = consumer;
|
||||
this.open = bind(this.open, this);
|
||||
this.subscriptions = this.consumer.subscriptions;
|
||||
this.monitor = new ActionCable.ConnectionMonitor(this);
|
||||
this.disconnected = true;
|
||||
}
|
||||
|
||||
Connection.prototype.send = function(data) {
|
||||
if (this.isOpen()) {
|
||||
this.webSocket.send(JSON.stringify(data));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
Connection.prototype.open = function() {
|
||||
if (this.isActive()) {
|
||||
ActionCable.log("Attempted to open WebSocket, but existing socket is " + (this.getState()));
|
||||
return false;
|
||||
} else {
|
||||
ActionCable.log("Opening WebSocket, current state is " + (this.getState()) + ", subprotocols: " + protocols);
|
||||
if (this.webSocket != null) {
|
||||
this.uninstallEventHandlers();
|
||||
}
|
||||
this.webSocket = new ActionCable.WebSocket(this.consumer.url, protocols);
|
||||
this.installEventHandlers();
|
||||
this.monitor.start();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
Connection.prototype.close = function(arg) {
|
||||
var allowReconnect, ref1;
|
||||
allowReconnect = (arg != null ? arg : {
|
||||
allowReconnect: true
|
||||
}).allowReconnect;
|
||||
if (!allowReconnect) {
|
||||
this.monitor.stop();
|
||||
}
|
||||
if (this.isActive()) {
|
||||
return (ref1 = this.webSocket) != null ? ref1.close() : void 0;
|
||||
}
|
||||
};
|
||||
|
||||
Connection.prototype.reopen = function() {
|
||||
var error;
|
||||
ActionCable.log("Reopening WebSocket, current state is " + (this.getState()));
|
||||
if (this.isActive()) {
|
||||
try {
|
||||
return this.close();
|
||||
} catch (error1) {
|
||||
error = error1;
|
||||
return ActionCable.log("Failed to reopen WebSocket", error);
|
||||
} finally {
|
||||
ActionCable.log("Reopening WebSocket in " + this.constructor.reopenDelay + "ms");
|
||||
setTimeout(this.open, this.constructor.reopenDelay);
|
||||
}
|
||||
} else {
|
||||
return this.open();
|
||||
}
|
||||
};
|
||||
|
||||
Connection.prototype.getProtocol = function() {
|
||||
var ref1;
|
||||
return (ref1 = this.webSocket) != null ? ref1.protocol : void 0;
|
||||
};
|
||||
|
||||
Connection.prototype.isOpen = function() {
|
||||
return this.isState("open");
|
||||
};
|
||||
|
||||
Connection.prototype.isActive = function() {
|
||||
return this.isState("open", "connecting");
|
||||
};
|
||||
|
||||
Connection.prototype.isProtocolSupported = function() {
|
||||
var ref1;
|
||||
return ref1 = this.getProtocol(), indexOf.call(supportedProtocols, ref1) >= 0;
|
||||
};
|
||||
|
||||
Connection.prototype.isState = function() {
|
||||
var ref1, states;
|
||||
states = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
||||
return ref1 = this.getState(), indexOf.call(states, ref1) >= 0;
|
||||
};
|
||||
|
||||
Connection.prototype.getState = function() {
|
||||
var ref1, state, value;
|
||||
for (state in WebSocket) {
|
||||
value = WebSocket[state];
|
||||
if (value === ((ref1 = this.webSocket) != null ? ref1.readyState : void 0)) {
|
||||
return state.toLowerCase();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
Connection.prototype.installEventHandlers = function() {
|
||||
var eventName, handler;
|
||||
for (eventName in this.events) {
|
||||
handler = this.events[eventName].bind(this);
|
||||
this.webSocket["on" + eventName] = handler;
|
||||
}
|
||||
};
|
||||
|
||||
Connection.prototype.uninstallEventHandlers = function() {
|
||||
var eventName;
|
||||
for (eventName in this.events) {
|
||||
this.webSocket["on" + eventName] = function() {};
|
||||
}
|
||||
};
|
||||
|
||||
Connection.prototype.events = {
|
||||
message: function(event) {
|
||||
var identifier, message, ref1, type;
|
||||
if (!this.isProtocolSupported()) {
|
||||
return;
|
||||
}
|
||||
ref1 = JSON.parse(event.data), identifier = ref1.identifier, message = ref1.message, type = ref1.type;
|
||||
switch (type) {
|
||||
case message_types.welcome:
|
||||
this.monitor.recordConnect();
|
||||
return this.subscriptions.reload();
|
||||
case message_types.ping:
|
||||
return this.monitor.recordPing();
|
||||
case message_types.confirmation:
|
||||
return this.subscriptions.notify(identifier, "connected");
|
||||
case message_types.rejection:
|
||||
return this.subscriptions.reject(identifier);
|
||||
default:
|
||||
return this.subscriptions.notify(identifier, "received", message);
|
||||
}
|
||||
},
|
||||
open: function() {
|
||||
ActionCable.log("WebSocket onopen event, using '" + (this.getProtocol()) + "' subprotocol");
|
||||
this.disconnected = false;
|
||||
if (!this.isProtocolSupported()) {
|
||||
ActionCable.log("Protocol is unsupported. Stopping monitor and disconnecting.");
|
||||
return this.close({
|
||||
allowReconnect: false
|
||||
});
|
||||
}
|
||||
},
|
||||
close: function(event) {
|
||||
ActionCable.log("WebSocket onclose event");
|
||||
if (this.disconnected) {
|
||||
return;
|
||||
}
|
||||
this.disconnected = true;
|
||||
this.monitor.recordDisconnect();
|
||||
return this.subscriptions.notifyAll("disconnected", {
|
||||
willAttemptReconnect: this.monitor.isRunning()
|
||||
});
|
||||
},
|
||||
error: function() {
|
||||
return ActionCable.log("WebSocket onerror event");
|
||||
}
|
||||
};
|
||||
|
||||
return Connection;
|
||||
|
||||
})();
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var slice = [].slice;
|
||||
|
||||
ActionCable.Subscriptions = (function() {
|
||||
function Subscriptions(consumer) {
|
||||
this.consumer = consumer;
|
||||
this.subscriptions = [];
|
||||
}
|
||||
|
||||
Subscriptions.prototype.create = function(channelName, mixin) {
|
||||
var channel, params, subscription;
|
||||
channel = channelName;
|
||||
params = typeof channel === "object" ? channel : {
|
||||
channel: channel
|
||||
};
|
||||
subscription = new ActionCable.Subscription(this.consumer, params, mixin);
|
||||
return this.add(subscription);
|
||||
};
|
||||
|
||||
Subscriptions.prototype.add = function(subscription) {
|
||||
this.subscriptions.push(subscription);
|
||||
this.consumer.ensureActiveConnection();
|
||||
this.notify(subscription, "initialized");
|
||||
this.sendCommand(subscription, "subscribe");
|
||||
return subscription;
|
||||
};
|
||||
|
||||
Subscriptions.prototype.remove = function(subscription) {
|
||||
this.forget(subscription);
|
||||
if (!this.findAll(subscription.identifier).length) {
|
||||
this.sendCommand(subscription, "unsubscribe");
|
||||
}
|
||||
return subscription;
|
||||
};
|
||||
|
||||
Subscriptions.prototype.reject = function(identifier) {
|
||||
var i, len, ref, results, subscription;
|
||||
ref = this.findAll(identifier);
|
||||
results = [];
|
||||
for (i = 0, len = ref.length; i < len; i++) {
|
||||
subscription = ref[i];
|
||||
this.forget(subscription);
|
||||
this.notify(subscription, "rejected");
|
||||
results.push(subscription);
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
Subscriptions.prototype.forget = function(subscription) {
|
||||
var s;
|
||||
this.subscriptions = (function() {
|
||||
var i, len, ref, results;
|
||||
ref = this.subscriptions;
|
||||
results = [];
|
||||
for (i = 0, len = ref.length; i < len; i++) {
|
||||
s = ref[i];
|
||||
if (s !== subscription) {
|
||||
results.push(s);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}).call(this);
|
||||
return subscription;
|
||||
};
|
||||
|
||||
Subscriptions.prototype.findAll = function(identifier) {
|
||||
var i, len, ref, results, s;
|
||||
ref = this.subscriptions;
|
||||
results = [];
|
||||
for (i = 0, len = ref.length; i < len; i++) {
|
||||
s = ref[i];
|
||||
if (s.identifier === identifier) {
|
||||
results.push(s);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
Subscriptions.prototype.reload = function() {
|
||||
var i, len, ref, results, subscription;
|
||||
ref = this.subscriptions;
|
||||
results = [];
|
||||
for (i = 0, len = ref.length; i < len; i++) {
|
||||
subscription = ref[i];
|
||||
results.push(this.sendCommand(subscription, "subscribe"));
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
Subscriptions.prototype.notifyAll = function() {
|
||||
var args, callbackName, i, len, ref, results, subscription;
|
||||
callbackName = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
||||
ref = this.subscriptions;
|
||||
results = [];
|
||||
for (i = 0, len = ref.length; i < len; i++) {
|
||||
subscription = ref[i];
|
||||
results.push(this.notify.apply(this, [subscription, callbackName].concat(slice.call(args))));
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
Subscriptions.prototype.notify = function() {
|
||||
var args, callbackName, i, len, results, subscription, subscriptions;
|
||||
subscription = arguments[0], callbackName = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : [];
|
||||
if (typeof subscription === "string") {
|
||||
subscriptions = this.findAll(subscription);
|
||||
} else {
|
||||
subscriptions = [subscription];
|
||||
}
|
||||
results = [];
|
||||
for (i = 0, len = subscriptions.length; i < len; i++) {
|
||||
subscription = subscriptions[i];
|
||||
results.push(typeof subscription[callbackName] === "function" ? subscription[callbackName].apply(subscription, args) : void 0);
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
Subscriptions.prototype.sendCommand = function(subscription, command) {
|
||||
var identifier;
|
||||
identifier = subscription.identifier;
|
||||
return this.consumer.send({
|
||||
command: command,
|
||||
identifier: identifier
|
||||
});
|
||||
};
|
||||
|
||||
return Subscriptions;
|
||||
|
||||
})();
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
ActionCable.Subscription = (function() {
|
||||
var extend;
|
||||
|
||||
function Subscription(consumer, params, mixin) {
|
||||
this.consumer = consumer;
|
||||
if (params == null) {
|
||||
params = {};
|
||||
}
|
||||
this.identifier = JSON.stringify(params);
|
||||
extend(this, mixin);
|
||||
}
|
||||
|
||||
Subscription.prototype.perform = function(action, data) {
|
||||
if (data == null) {
|
||||
data = {};
|
||||
}
|
||||
data.action = action;
|
||||
return this.send(data);
|
||||
};
|
||||
|
||||
Subscription.prototype.send = function(data) {
|
||||
return this.consumer.send({
|
||||
command: "message",
|
||||
identifier: this.identifier,
|
||||
data: JSON.stringify(data)
|
||||
});
|
||||
};
|
||||
|
||||
Subscription.prototype.unsubscribe = function() {
|
||||
return this.consumer.subscriptions.remove(this);
|
||||
};
|
||||
|
||||
extend = function(object, properties) {
|
||||
var key, value;
|
||||
if (properties != null) {
|
||||
for (key in properties) {
|
||||
value = properties[key];
|
||||
object[key] = value;
|
||||
}
|
||||
}
|
||||
return object;
|
||||
};
|
||||
|
||||
return Subscription;
|
||||
|
||||
})();
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
ActionCable.Consumer = (function() {
|
||||
function Consumer(url) {
|
||||
this.url = url;
|
||||
this.subscriptions = new ActionCable.Subscriptions(this);
|
||||
this.connection = new ActionCable.Connection(this);
|
||||
}
|
||||
|
||||
Consumer.prototype.send = function(data) {
|
||||
return this.connection.send(data);
|
||||
};
|
||||
|
||||
Consumer.prototype.connect = function() {
|
||||
return this.connection.open();
|
||||
};
|
||||
|
||||
Consumer.prototype.disconnect = function() {
|
||||
return this.connection.close({
|
||||
allowReconnect: false
|
||||
});
|
||||
};
|
||||
|
||||
Consumer.prototype.ensureActiveConnection = function() {
|
||||
if (!this.connection.isActive()) {
|
||||
return this.connection.open();
|
||||
}
|
||||
};
|
||||
|
||||
return Consumer;
|
||||
|
||||
})();
|
||||
|
||||
}).call(this);
|
||||
}).call(this);
|
||||
|
||||
if (typeof module === "object" && module.exports) {
|
||||
module.exports = ActionCable;
|
||||
} else if (typeof define === "function" && define.amd) {
|
||||
define(ActionCable);
|
||||
}
|
||||
}).call(this);
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
||||
* listed below.
|
||||
*
|
||||
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
|
||||
* vendor/assets/stylesheets directory can be referenced here using a relative path.
|
||||
*
|
||||
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
||||
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
||||
* files in this directory. Styles in this file should be added after the last require_* statement.
|
||||
* It is generally better to create a new file per style scope.
|
||||
*
|
||||
|
||||
*/
|
||||
|
||||
Binary file not shown.
|
|
@ -0,0 +1,701 @@
|
|||
/*
|
||||
Unobtrusive JavaScript
|
||||
https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts
|
||||
Released under the MIT license
|
||||
*/
|
||||
|
||||
|
||||
(function() {
|
||||
var context = this;
|
||||
|
||||
(function() {
|
||||
(function() {
|
||||
this.Rails = {
|
||||
linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote]:not([disabled]), a[data-disable-with], a[data-disable]',
|
||||
buttonClickSelector: {
|
||||
selector: 'button[data-remote]:not([form]), button[data-confirm]:not([form])',
|
||||
exclude: 'form button'
|
||||
},
|
||||
inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]',
|
||||
formSubmitSelector: 'form',
|
||||
formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])',
|
||||
formDisableSelector: 'input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled',
|
||||
formEnableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled',
|
||||
fileInputSelector: 'input[name][type=file]:not([disabled])',
|
||||
linkDisableSelector: 'a[data-disable-with], a[data-disable]',
|
||||
buttonDisableSelector: 'button[data-remote][data-disable-with], button[data-remote][data-disable]'
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
}).call(context);
|
||||
|
||||
var Rails = context.Rails;
|
||||
|
||||
(function() {
|
||||
(function() {
|
||||
var expando, m;
|
||||
|
||||
m = Element.prototype.matches || Element.prototype.matchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.webkitMatchesSelector;
|
||||
|
||||
Rails.matches = function(element, selector) {
|
||||
if (selector.exclude != null) {
|
||||
return m.call(element, selector.selector) && !m.call(element, selector.exclude);
|
||||
} else {
|
||||
return m.call(element, selector);
|
||||
}
|
||||
};
|
||||
|
||||
expando = '_ujsData';
|
||||
|
||||
Rails.getData = function(element, key) {
|
||||
var ref;
|
||||
return (ref = element[expando]) != null ? ref[key] : void 0;
|
||||
};
|
||||
|
||||
Rails.setData = function(element, key, value) {
|
||||
if (element[expando] == null) {
|
||||
element[expando] = {};
|
||||
}
|
||||
return element[expando][key] = value;
|
||||
};
|
||||
|
||||
Rails.$ = function(selector) {
|
||||
return Array.prototype.slice.call(document.querySelectorAll(selector));
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var $, csrfParam, csrfToken;
|
||||
|
||||
$ = Rails.$;
|
||||
|
||||
csrfToken = Rails.csrfToken = function() {
|
||||
var meta;
|
||||
meta = document.querySelector('meta[name=csrf-token]');
|
||||
return meta && meta.content;
|
||||
};
|
||||
|
||||
csrfParam = Rails.csrfParam = function() {
|
||||
var meta;
|
||||
meta = document.querySelector('meta[name=csrf-param]');
|
||||
return meta && meta.content;
|
||||
};
|
||||
|
||||
Rails.CSRFProtection = function(xhr) {
|
||||
var token;
|
||||
token = csrfToken();
|
||||
if (token != null) {
|
||||
return xhr.setRequestHeader('X-CSRF-Token', token);
|
||||
}
|
||||
};
|
||||
|
||||
Rails.refreshCSRFTokens = function() {
|
||||
var param, token;
|
||||
token = csrfToken();
|
||||
param = csrfParam();
|
||||
if ((token != null) && (param != null)) {
|
||||
return $('form input[name="' + param + '"]').forEach(function(input) {
|
||||
return input.value = token;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var CustomEvent, fire, matches;
|
||||
|
||||
matches = Rails.matches;
|
||||
|
||||
CustomEvent = window.CustomEvent;
|
||||
|
||||
if (typeof CustomEvent !== 'function') {
|
||||
CustomEvent = function(event, params) {
|
||||
var evt;
|
||||
evt = document.createEvent('CustomEvent');
|
||||
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
|
||||
return evt;
|
||||
};
|
||||
CustomEvent.prototype = window.Event.prototype;
|
||||
}
|
||||
|
||||
fire = Rails.fire = function(obj, name, data) {
|
||||
var event;
|
||||
event = new CustomEvent(name, {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
detail: data
|
||||
});
|
||||
obj.dispatchEvent(event);
|
||||
return !event.defaultPrevented;
|
||||
};
|
||||
|
||||
Rails.stopEverything = function(e) {
|
||||
fire(e.target, 'ujs:everythingStopped');
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return e.stopImmediatePropagation();
|
||||
};
|
||||
|
||||
Rails.delegate = function(element, selector, eventType, handler) {
|
||||
return element.addEventListener(eventType, function(e) {
|
||||
var target;
|
||||
target = e.target;
|
||||
while (!(!(target instanceof Element) || matches(target, selector))) {
|
||||
target = target.parentNode;
|
||||
}
|
||||
if (target instanceof Element && handler.call(target, e) === false) {
|
||||
e.preventDefault();
|
||||
return e.stopPropagation();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var AcceptHeaders, CSRFProtection, createXHR, fire, prepareOptions, processResponse;
|
||||
|
||||
CSRFProtection = Rails.CSRFProtection, fire = Rails.fire;
|
||||
|
||||
AcceptHeaders = {
|
||||
'*': '*/*',
|
||||
text: 'text/plain',
|
||||
html: 'text/html',
|
||||
xml: 'application/xml, text/xml',
|
||||
json: 'application/json, text/javascript',
|
||||
script: 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript'
|
||||
};
|
||||
|
||||
Rails.ajax = function(options) {
|
||||
var xhr;
|
||||
options = prepareOptions(options);
|
||||
xhr = createXHR(options, function() {
|
||||
var response;
|
||||
response = processResponse(xhr.response, xhr.getResponseHeader('Content-Type'));
|
||||
if (Math.floor(xhr.status / 100) === 2) {
|
||||
if (typeof options.success === "function") {
|
||||
options.success(response, xhr.statusText, xhr);
|
||||
}
|
||||
} else {
|
||||
if (typeof options.error === "function") {
|
||||
options.error(response, xhr.statusText, xhr);
|
||||
}
|
||||
}
|
||||
return typeof options.complete === "function" ? options.complete(xhr, xhr.statusText) : void 0;
|
||||
});
|
||||
if (typeof options.beforeSend === "function") {
|
||||
options.beforeSend(xhr, options);
|
||||
}
|
||||
if (xhr.readyState === XMLHttpRequest.OPENED) {
|
||||
return xhr.send(options.data);
|
||||
} else {
|
||||
return fire(document, 'ajaxStop');
|
||||
}
|
||||
};
|
||||
|
||||
prepareOptions = function(options) {
|
||||
options.url = options.url || location.href;
|
||||
options.type = options.type.toUpperCase();
|
||||
if (options.type === 'GET' && options.data) {
|
||||
if (options.url.indexOf('?') < 0) {
|
||||
options.url += '?' + options.data;
|
||||
} else {
|
||||
options.url += '&' + options.data;
|
||||
}
|
||||
}
|
||||
if (AcceptHeaders[options.dataType] == null) {
|
||||
options.dataType = '*';
|
||||
}
|
||||
options.accept = AcceptHeaders[options.dataType];
|
||||
if (options.dataType !== '*') {
|
||||
options.accept += ', */*; q=0.01';
|
||||
}
|
||||
return options;
|
||||
};
|
||||
|
||||
createXHR = function(options, done) {
|
||||
var xhr;
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open(options.type, options.url, true);
|
||||
xhr.setRequestHeader('Accept', options.accept);
|
||||
if (typeof options.data === 'string') {
|
||||
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
|
||||
}
|
||||
if (!options.crossDomain) {
|
||||
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
||||
}
|
||||
CSRFProtection(xhr);
|
||||
xhr.withCredentials = !!options.withCredentials;
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState === XMLHttpRequest.DONE) {
|
||||
return done(xhr);
|
||||
}
|
||||
};
|
||||
return xhr;
|
||||
};
|
||||
|
||||
processResponse = function(response, type) {
|
||||
var parser, script;
|
||||
if (typeof response === 'string' && typeof type === 'string') {
|
||||
if (type.match(/\bjson\b/)) {
|
||||
try {
|
||||
response = JSON.parse(response);
|
||||
} catch (error) {}
|
||||
} else if (type.match(/\b(?:java|ecma)script\b/)) {
|
||||
script = document.createElement('script');
|
||||
script.text = response;
|
||||
document.head.appendChild(script).parentNode.removeChild(script);
|
||||
} else if (type.match(/\b(xml|html|svg)\b/)) {
|
||||
parser = new DOMParser();
|
||||
type = type.replace(/;.+/, '');
|
||||
try {
|
||||
response = parser.parseFromString(response, type);
|
||||
} catch (error) {}
|
||||
}
|
||||
}
|
||||
return response;
|
||||
};
|
||||
|
||||
Rails.href = function(element) {
|
||||
return element.href;
|
||||
};
|
||||
|
||||
Rails.isCrossDomain = function(url) {
|
||||
var e, originAnchor, urlAnchor;
|
||||
originAnchor = document.createElement('a');
|
||||
originAnchor.href = location.href;
|
||||
urlAnchor = document.createElement('a');
|
||||
try {
|
||||
urlAnchor.href = url;
|
||||
return !(((!urlAnchor.protocol || urlAnchor.protocol === ':') && !urlAnchor.host) || (originAnchor.protocol + '//' + originAnchor.host === urlAnchor.protocol + '//' + urlAnchor.host));
|
||||
} catch (error) {
|
||||
e = error;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var matches, toArray;
|
||||
|
||||
matches = Rails.matches;
|
||||
|
||||
toArray = function(e) {
|
||||
return Array.prototype.slice.call(e);
|
||||
};
|
||||
|
||||
Rails.serializeElement = function(element, additionalParam) {
|
||||
var inputs, params;
|
||||
inputs = [element];
|
||||
if (matches(element, 'form')) {
|
||||
inputs = toArray(element.elements);
|
||||
}
|
||||
params = [];
|
||||
inputs.forEach(function(input) {
|
||||
if (!input.name) {
|
||||
return;
|
||||
}
|
||||
if (matches(input, 'select')) {
|
||||
return toArray(input.options).forEach(function(option) {
|
||||
if (option.selected) {
|
||||
return params.push({
|
||||
name: input.name,
|
||||
value: option.value
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (input.checked || ['radio', 'checkbox', 'submit'].indexOf(input.type) === -1) {
|
||||
return params.push({
|
||||
name: input.name,
|
||||
value: input.value
|
||||
});
|
||||
}
|
||||
});
|
||||
if (additionalParam) {
|
||||
params.push(additionalParam);
|
||||
}
|
||||
return params.map(function(param) {
|
||||
if (param.name != null) {
|
||||
return (encodeURIComponent(param.name)) + "=" + (encodeURIComponent(param.value));
|
||||
} else {
|
||||
return param;
|
||||
}
|
||||
}).join('&');
|
||||
};
|
||||
|
||||
Rails.formElements = function(form, selector) {
|
||||
if (matches(form, 'form')) {
|
||||
return toArray(form.elements).filter(function(el) {
|
||||
return matches(el, selector);
|
||||
});
|
||||
} else {
|
||||
return toArray(form.querySelectorAll(selector));
|
||||
}
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var allowAction, fire, stopEverything;
|
||||
|
||||
fire = Rails.fire, stopEverything = Rails.stopEverything;
|
||||
|
||||
Rails.handleConfirm = function(e) {
|
||||
if (!allowAction(this)) {
|
||||
return stopEverything(e);
|
||||
}
|
||||
};
|
||||
|
||||
allowAction = function(element) {
|
||||
var answer, callback, message;
|
||||
message = element.getAttribute('data-confirm');
|
||||
if (!message) {
|
||||
return true;
|
||||
}
|
||||
answer = false;
|
||||
if (fire(element, 'confirm')) {
|
||||
try {
|
||||
answer = confirm(message);
|
||||
} catch (error) {}
|
||||
callback = fire(element, 'confirm:complete', [answer]);
|
||||
}
|
||||
return answer && callback;
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var disableFormElement, disableFormElements, disableLinkElement, enableFormElement, enableFormElements, enableLinkElement, formElements, getData, matches, setData, stopEverything;
|
||||
|
||||
matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, stopEverything = Rails.stopEverything, formElements = Rails.formElements;
|
||||
|
||||
Rails.handleDisabledElement = function(e) {
|
||||
var element;
|
||||
element = this;
|
||||
if (element.disabled) {
|
||||
return stopEverything(e);
|
||||
}
|
||||
};
|
||||
|
||||
Rails.enableElement = function(e) {
|
||||
var element;
|
||||
element = e instanceof Event ? e.target : e;
|
||||
if (matches(element, Rails.linkDisableSelector)) {
|
||||
return enableLinkElement(element);
|
||||
} else if (matches(element, Rails.buttonDisableSelector) || matches(element, Rails.formEnableSelector)) {
|
||||
return enableFormElement(element);
|
||||
} else if (matches(element, Rails.formSubmitSelector)) {
|
||||
return enableFormElements(element);
|
||||
}
|
||||
};
|
||||
|
||||
Rails.disableElement = function(e) {
|
||||
var element;
|
||||
element = e instanceof Event ? e.target : e;
|
||||
if (matches(element, Rails.linkDisableSelector)) {
|
||||
return disableLinkElement(element);
|
||||
} else if (matches(element, Rails.buttonDisableSelector) || matches(element, Rails.formDisableSelector)) {
|
||||
return disableFormElement(element);
|
||||
} else if (matches(element, Rails.formSubmitSelector)) {
|
||||
return disableFormElements(element);
|
||||
}
|
||||
};
|
||||
|
||||
disableLinkElement = function(element) {
|
||||
var replacement;
|
||||
replacement = element.getAttribute('data-disable-with');
|
||||
if (replacement != null) {
|
||||
setData(element, 'ujs:enable-with', element.innerHTML);
|
||||
element.innerHTML = replacement;
|
||||
}
|
||||
element.addEventListener('click', stopEverything);
|
||||
return setData(element, 'ujs:disabled', true);
|
||||
};
|
||||
|
||||
enableLinkElement = function(element) {
|
||||
var originalText;
|
||||
originalText = getData(element, 'ujs:enable-with');
|
||||
if (originalText != null) {
|
||||
element.innerHTML = originalText;
|
||||
setData(element, 'ujs:enable-with', null);
|
||||
}
|
||||
element.removeEventListener('click', stopEverything);
|
||||
return setData(element, 'ujs:disabled', null);
|
||||
};
|
||||
|
||||
disableFormElements = function(form) {
|
||||
return formElements(form, Rails.formDisableSelector).forEach(disableFormElement);
|
||||
};
|
||||
|
||||
disableFormElement = function(element) {
|
||||
var replacement;
|
||||
replacement = element.getAttribute('data-disable-with');
|
||||
if (replacement != null) {
|
||||
if (matches(element, 'button')) {
|
||||
setData(element, 'ujs:enable-with', element.innerHTML);
|
||||
element.innerHTML = replacement;
|
||||
} else {
|
||||
setData(element, 'ujs:enable-with', element.value);
|
||||
element.value = replacement;
|
||||
}
|
||||
}
|
||||
element.disabled = true;
|
||||
return setData(element, 'ujs:disabled', true);
|
||||
};
|
||||
|
||||
enableFormElements = function(form) {
|
||||
return formElements(form, Rails.formEnableSelector).forEach(enableFormElement);
|
||||
};
|
||||
|
||||
enableFormElement = function(element) {
|
||||
var originalText;
|
||||
originalText = getData(element, 'ujs:enable-with');
|
||||
if (originalText != null) {
|
||||
if (matches(element, 'button')) {
|
||||
element.innerHTML = originalText;
|
||||
} else {
|
||||
element.value = originalText;
|
||||
}
|
||||
setData(element, 'ujs:enable-with', null);
|
||||
}
|
||||
element.disabled = false;
|
||||
return setData(element, 'ujs:disabled', null);
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var stopEverything;
|
||||
|
||||
stopEverything = Rails.stopEverything;
|
||||
|
||||
Rails.handleMethod = function(e) {
|
||||
var csrfParam, csrfToken, form, formContent, href, link, method;
|
||||
link = this;
|
||||
method = link.getAttribute('data-method');
|
||||
if (!method) {
|
||||
return;
|
||||
}
|
||||
href = Rails.href(link);
|
||||
csrfToken = Rails.csrfToken();
|
||||
csrfParam = Rails.csrfParam();
|
||||
form = document.createElement('form');
|
||||
formContent = "<input name='_method' value='" + method + "' type='hidden' />";
|
||||
if ((csrfParam != null) && (csrfToken != null) && !Rails.isCrossDomain(href)) {
|
||||
formContent += "<input name='" + csrfParam + "' value='" + csrfToken + "' type='hidden' />";
|
||||
}
|
||||
formContent += '<input type="submit" />';
|
||||
form.method = 'post';
|
||||
form.action = href;
|
||||
form.target = link.target;
|
||||
form.innerHTML = formContent;
|
||||
form.style.display = 'none';
|
||||
document.body.appendChild(form);
|
||||
form.querySelector('[type="submit"]').click();
|
||||
return stopEverything(e);
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var ajax, fire, getData, isCrossDomain, isRemote, matches, serializeElement, setData, stopEverything,
|
||||
slice = [].slice;
|
||||
|
||||
matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, fire = Rails.fire, stopEverything = Rails.stopEverything, ajax = Rails.ajax, isCrossDomain = Rails.isCrossDomain, serializeElement = Rails.serializeElement;
|
||||
|
||||
isRemote = function(element) {
|
||||
var value;
|
||||
value = element.getAttribute('data-remote');
|
||||
return (value != null) && value !== 'false';
|
||||
};
|
||||
|
||||
Rails.handleRemote = function(e) {
|
||||
var button, data, dataType, element, method, url, withCredentials;
|
||||
element = this;
|
||||
if (!isRemote(element)) {
|
||||
return true;
|
||||
}
|
||||
if (!fire(element, 'ajax:before')) {
|
||||
fire(element, 'ajax:stopped');
|
||||
return false;
|
||||
}
|
||||
withCredentials = element.getAttribute('data-with-credentials');
|
||||
dataType = element.getAttribute('data-type') || 'script';
|
||||
if (matches(element, Rails.formSubmitSelector)) {
|
||||
button = getData(element, 'ujs:submit-button');
|
||||
method = getData(element, 'ujs:submit-button-formmethod') || element.method;
|
||||
url = getData(element, 'ujs:submit-button-formaction') || element.getAttribute('action') || location.href;
|
||||
if (method.toUpperCase() === 'GET') {
|
||||
url = url.replace(/\?.*$/, '');
|
||||
}
|
||||
if (element.enctype === 'multipart/form-data') {
|
||||
data = new FormData(element);
|
||||
if (button != null) {
|
||||
data.append(button.name, button.value);
|
||||
}
|
||||
} else {
|
||||
data = serializeElement(element, button);
|
||||
}
|
||||
setData(element, 'ujs:submit-button', null);
|
||||
setData(element, 'ujs:submit-button-formmethod', null);
|
||||
setData(element, 'ujs:submit-button-formaction', null);
|
||||
} else if (matches(element, Rails.buttonClickSelector) || matches(element, Rails.inputChangeSelector)) {
|
||||
method = element.getAttribute('data-method');
|
||||
url = element.getAttribute('data-url');
|
||||
data = serializeElement(element, element.getAttribute('data-params'));
|
||||
} else {
|
||||
method = element.getAttribute('data-method');
|
||||
url = Rails.href(element);
|
||||
data = element.getAttribute('data-params');
|
||||
}
|
||||
ajax({
|
||||
type: method || 'GET',
|
||||
url: url,
|
||||
data: data,
|
||||
dataType: dataType,
|
||||
beforeSend: function(xhr, options) {
|
||||
if (fire(element, 'ajax:beforeSend', [xhr, options])) {
|
||||
return fire(element, 'ajax:send', [xhr]);
|
||||
} else {
|
||||
fire(element, 'ajax:stopped');
|
||||
return xhr.abort();
|
||||
}
|
||||
},
|
||||
success: function() {
|
||||
var args;
|
||||
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
||||
return fire(element, 'ajax:success', args);
|
||||
},
|
||||
error: function() {
|
||||
var args;
|
||||
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
||||
return fire(element, 'ajax:error', args);
|
||||
},
|
||||
complete: function() {
|
||||
var args;
|
||||
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
||||
return fire(element, 'ajax:complete', args);
|
||||
},
|
||||
crossDomain: isCrossDomain(url),
|
||||
withCredentials: (withCredentials != null) && withCredentials !== 'false'
|
||||
});
|
||||
return stopEverything(e);
|
||||
};
|
||||
|
||||
Rails.formSubmitButtonClick = function(e) {
|
||||
var button, form;
|
||||
button = this;
|
||||
form = button.form;
|
||||
if (!form) {
|
||||
return;
|
||||
}
|
||||
if (button.name) {
|
||||
setData(form, 'ujs:submit-button', {
|
||||
name: button.name,
|
||||
value: button.value
|
||||
});
|
||||
}
|
||||
setData(form, 'ujs:formnovalidate-button', button.formNoValidate);
|
||||
setData(form, 'ujs:submit-button-formaction', button.getAttribute('formaction'));
|
||||
return setData(form, 'ujs:submit-button-formmethod', button.getAttribute('formmethod'));
|
||||
};
|
||||
|
||||
Rails.handleMetaClick = function(e) {
|
||||
var data, link, metaClick, method;
|
||||
link = this;
|
||||
method = (link.getAttribute('data-method') || 'GET').toUpperCase();
|
||||
data = link.getAttribute('data-params');
|
||||
metaClick = e.metaKey || e.ctrlKey;
|
||||
if (metaClick && method === 'GET' && !data) {
|
||||
return e.stopImmediatePropagation();
|
||||
}
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var $, CSRFProtection, delegate, disableElement, enableElement, fire, formSubmitButtonClick, getData, handleConfirm, handleDisabledElement, handleMetaClick, handleMethod, handleRemote, refreshCSRFTokens;
|
||||
|
||||
fire = Rails.fire, delegate = Rails.delegate, getData = Rails.getData, $ = Rails.$, refreshCSRFTokens = Rails.refreshCSRFTokens, CSRFProtection = Rails.CSRFProtection, enableElement = Rails.enableElement, disableElement = Rails.disableElement, handleDisabledElement = Rails.handleDisabledElement, handleConfirm = Rails.handleConfirm, handleRemote = Rails.handleRemote, formSubmitButtonClick = Rails.formSubmitButtonClick, handleMetaClick = Rails.handleMetaClick, handleMethod = Rails.handleMethod;
|
||||
|
||||
if ((typeof jQuery !== "undefined" && jQuery !== null) && (jQuery.ajax != null) && !jQuery.rails) {
|
||||
jQuery.rails = Rails;
|
||||
jQuery.ajaxPrefilter(function(options, originalOptions, xhr) {
|
||||
if (!options.crossDomain) {
|
||||
return CSRFProtection(xhr);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Rails.start = function() {
|
||||
if (window._rails_loaded) {
|
||||
throw new Error('rails-ujs has already been loaded!');
|
||||
}
|
||||
window.addEventListener('pageshow', function() {
|
||||
$(Rails.formEnableSelector).forEach(function(el) {
|
||||
if (getData(el, 'ujs:disabled')) {
|
||||
return enableElement(el);
|
||||
}
|
||||
});
|
||||
return $(Rails.linkDisableSelector).forEach(function(el) {
|
||||
if (getData(el, 'ujs:disabled')) {
|
||||
return enableElement(el);
|
||||
}
|
||||
});
|
||||
});
|
||||
delegate(document, Rails.linkDisableSelector, 'ajax:complete', enableElement);
|
||||
delegate(document, Rails.linkDisableSelector, 'ajax:stopped', enableElement);
|
||||
delegate(document, Rails.buttonDisableSelector, 'ajax:complete', enableElement);
|
||||
delegate(document, Rails.buttonDisableSelector, 'ajax:stopped', enableElement);
|
||||
delegate(document, Rails.linkClickSelector, 'click', handleDisabledElement);
|
||||
delegate(document, Rails.linkClickSelector, 'click', handleConfirm);
|
||||
delegate(document, Rails.linkClickSelector, 'click', handleMetaClick);
|
||||
delegate(document, Rails.linkClickSelector, 'click', disableElement);
|
||||
delegate(document, Rails.linkClickSelector, 'click', handleRemote);
|
||||
delegate(document, Rails.linkClickSelector, 'click', handleMethod);
|
||||
delegate(document, Rails.buttonClickSelector, 'click', handleDisabledElement);
|
||||
delegate(document, Rails.buttonClickSelector, 'click', handleConfirm);
|
||||
delegate(document, Rails.buttonClickSelector, 'click', disableElement);
|
||||
delegate(document, Rails.buttonClickSelector, 'click', handleRemote);
|
||||
delegate(document, Rails.inputChangeSelector, 'change', handleDisabledElement);
|
||||
delegate(document, Rails.inputChangeSelector, 'change', handleConfirm);
|
||||
delegate(document, Rails.inputChangeSelector, 'change', handleRemote);
|
||||
delegate(document, Rails.formSubmitSelector, 'submit', handleDisabledElement);
|
||||
delegate(document, Rails.formSubmitSelector, 'submit', handleConfirm);
|
||||
delegate(document, Rails.formSubmitSelector, 'submit', handleRemote);
|
||||
delegate(document, Rails.formSubmitSelector, 'submit', function(e) {
|
||||
return setTimeout((function() {
|
||||
return disableElement(e);
|
||||
}), 13);
|
||||
});
|
||||
delegate(document, Rails.formSubmitSelector, 'ajax:send', disableElement);
|
||||
delegate(document, Rails.formSubmitSelector, 'ajax:complete', enableElement);
|
||||
delegate(document, Rails.formInputClickSelector, 'click', handleDisabledElement);
|
||||
delegate(document, Rails.formInputClickSelector, 'click', handleConfirm);
|
||||
delegate(document, Rails.formInputClickSelector, 'click', formSubmitButtonClick);
|
||||
document.addEventListener('DOMContentLoaded', refreshCSRFTokens);
|
||||
return window._rails_loaded = true;
|
||||
};
|
||||
|
||||
if (window.Rails === Rails && fire(document, 'rails:attachBindings')) {
|
||||
Rails.start();
|
||||
}
|
||||
|
||||
}).call(this);
|
||||
}).call(this);
|
||||
|
||||
if (typeof module === "object" && module.exports) {
|
||||
module.exports = Rails;
|
||||
} else if (typeof define === "function" && define.amd) {
|
||||
define(Rails);
|
||||
}
|
||||
}).call(this);
|
||||
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
||||
// listed below.
|
||||
//
|
||||
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's
|
||||
// vendor/assets/javascripts directory can be referenced here using a relative path.
|
||||
//
|
||||
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
||||
// compiled file. JavaScript code in this file should be added after the last require_* statement.
|
||||
//
|
||||
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
||||
// about supported directives.
|
||||
//
|
||||
|
||||
// require turbolinks
|
||||
;
|
||||
Binary file not shown.
3852
public/assets/bootstrap-371cae0dea6c5623d01d5b388b7eba550d1aaf6a2319c1e89754a5b57b74e020.js
vendored
Normal file
3852
public/assets/bootstrap-371cae0dea6c5623d01d5b388b7eba550d1aaf6a2319c1e89754a5b57b74e020.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
8375
public/assets/bootstrap-670ea68a62bbd6fb187f6535cf13d49359c1320d04e0b2f7e342b54c4e7d4209.css
vendored
Normal file
8375
public/assets/bootstrap-670ea68a62bbd6fb187f6535cf13d49359c1320d04e0b2f7e342b54c4e7d4209.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
1568
public/assets/bootstrap-grid-d8b25e4a6a6ed7a0a0b5f9b5ad526457327a1696eb6ade1248471d2ed76ffdd9.css
vendored
Normal file
1568
public/assets/bootstrap-grid-d8b25e4a6a6ed7a0a0b5f9b5ad526457327a1696eb6ade1248471d2ed76ffdd9.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
343
public/assets/bootstrap-reboot-d67427bd60b33875e775708241af638018cb2440389f595a40b89f7cbe5a34e1.css
vendored
Normal file
343
public/assets/bootstrap-reboot-d67427bd60b33875e775708241af638018cb2440389f595a40b89f7cbe5a34e1.css
vendored
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
/*!
|
||||
* Bootstrap Reboot v4.0.0-beta.2 (https://getbootstrap.com)
|
||||
* Copyright 2011-2017 The Bootstrap Authors
|
||||
* Copyright 2011-2017 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||
*/
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
line-height: 1.15;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-ms-overflow-style: scrollbar;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
@-ms-viewport {
|
||||
width: device-width;
|
||||
}
|
||||
|
||||
article, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
color: #212529;
|
||||
text-align: left;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
[tabindex="-1"]:focus {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
hr {
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
abbr[title],
|
||||
abbr[data-original-title] {
|
||||
text-decoration: underline;
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted;
|
||||
cursor: help;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
address {
|
||||
margin-bottom: 1rem;
|
||||
font-style: normal;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
dl {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
ol ol,
|
||||
ul ul,
|
||||
ol ul,
|
||||
ul ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: .5rem;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
position: relative;
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -.5em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #007bff;
|
||||
text-decoration: none;
|
||||
background-color: transparent;
|
||||
-webkit-text-decoration-skip: objects;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #0056b3;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:not([href]):not([tabindex]) {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:not([href]):not([tabindex]):focus, a:not([href]):not([tabindex]):hover {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:not([href]):not([tabindex]):focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
pre,
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
overflow: auto;
|
||||
-ms-overflow-style: scrollbar;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
img {
|
||||
vertical-align: middle;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
a,
|
||||
area,
|
||||
button,
|
||||
[role="button"],
|
||||
input:not([type="range"]),
|
||||
label,
|
||||
select,
|
||||
summary,
|
||||
textarea {
|
||||
-ms-touch-action: manipulation;
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
caption {
|
||||
padding-top: 0.75rem;
|
||||
padding-bottom: 0.75rem;
|
||||
color: #868e96;
|
||||
text-align: left;
|
||||
caption-side: bottom;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: inherit;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
button:focus {
|
||||
outline: 1px dotted;
|
||||
outline: 5px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
optgroup,
|
||||
textarea {
|
||||
margin: 0;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
button,
|
||||
input {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
button,
|
||||
html [type="button"],
|
||||
[type="reset"],
|
||||
[type="submit"] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
button::-moz-focus-inner,
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||
[type="submit"]::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
input[type="radio"],
|
||||
input[type="checkbox"] {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
input[type="date"],
|
||||
input[type="time"],
|
||||
input[type="datetime-local"],
|
||||
input[type="month"] {
|
||||
-webkit-appearance: listbox;
|
||||
}
|
||||
|
||||
textarea {
|
||||
overflow: auto;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
padding: 0;
|
||||
margin-bottom: .5rem;
|
||||
font-size: 1.5rem;
|
||||
line-height: inherit;
|
||||
color: inherit;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
[type="number"]::-webkit-inner-spin-button,
|
||||
[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
[type="search"] {
|
||||
outline-offset: -2px;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
[type="search"]::-webkit-search-cancel-button,
|
||||
[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
output {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
/*# sourceMappingURL=bootstrap-reboot.css.map */
|
||||
Binary file not shown.
6289
public/assets/bootstrap.bundle-4f30629ce63151a8b165223afe4ffaf656e061757ce71bee7630352e055c34a7.js
vendored
Normal file
6289
public/assets/bootstrap.bundle-4f30629ce63151a8b165223afe4ffaf656e061757ce71bee7630352e055c34a7.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
6758
public/assets/bootstrap_lte-47449653e273cb34b0c9481fcc04ac56528892093a5318f39754b3bd2c6695f7.css
vendored
Normal file
6758
public/assets/bootstrap_lte-47449653e273cb34b0c9481fcc04ac56528892093a5318f39754b3bd2c6695f7.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
2378
public/assets/bootstrap_lte-b38817c3e3a3049abb1fc08dd6ae448b23330f8453226efdb074710209474f75.js
vendored
Normal file
2378
public/assets/bootstrap_lte-b38817c3e3a3049abb1fc08dd6ae448b23330f8453226efdb074710209474f75.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,614 @@
|
|||
(function() {
|
||||
var context = this;
|
||||
|
||||
(function() {
|
||||
(function() {
|
||||
var slice = [].slice;
|
||||
|
||||
this.ActionCable = {
|
||||
INTERNAL: {
|
||||
"message_types": {
|
||||
"welcome": "welcome",
|
||||
"ping": "ping",
|
||||
"confirmation": "confirm_subscription",
|
||||
"rejection": "reject_subscription"
|
||||
},
|
||||
"default_mount_path": "/cable",
|
||||
"protocols": ["actioncable-v1-json", "actioncable-unsupported"]
|
||||
},
|
||||
WebSocket: window.WebSocket,
|
||||
logger: window.console,
|
||||
createConsumer: function(url) {
|
||||
var ref;
|
||||
if (url == null) {
|
||||
url = (ref = this.getConfig("url")) != null ? ref : this.INTERNAL.default_mount_path;
|
||||
}
|
||||
return new ActionCable.Consumer(this.createWebSocketURL(url));
|
||||
},
|
||||
getConfig: function(name) {
|
||||
var element;
|
||||
element = document.head.querySelector("meta[name='action-cable-" + name + "']");
|
||||
return element != null ? element.getAttribute("content") : void 0;
|
||||
},
|
||||
createWebSocketURL: function(url) {
|
||||
var a;
|
||||
if (url && !/^wss?:/i.test(url)) {
|
||||
a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.href = a.href;
|
||||
a.protocol = a.protocol.replace("http", "ws");
|
||||
return a.href;
|
||||
} else {
|
||||
return url;
|
||||
}
|
||||
},
|
||||
startDebugging: function() {
|
||||
return this.debugging = true;
|
||||
},
|
||||
stopDebugging: function() {
|
||||
return this.debugging = null;
|
||||
},
|
||||
log: function() {
|
||||
var messages, ref;
|
||||
messages = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
||||
if (this.debugging) {
|
||||
messages.push(Date.now());
|
||||
return (ref = this.logger).log.apply(ref, ["[ActionCable]"].concat(slice.call(messages)));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
}).call(context);
|
||||
|
||||
var ActionCable = context.ActionCable;
|
||||
|
||||
(function() {
|
||||
(function() {
|
||||
var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
|
||||
|
||||
ActionCable.ConnectionMonitor = (function() {
|
||||
var clamp, now, secondsSince;
|
||||
|
||||
ConnectionMonitor.pollInterval = {
|
||||
min: 3,
|
||||
max: 30
|
||||
};
|
||||
|
||||
ConnectionMonitor.staleThreshold = 6;
|
||||
|
||||
function ConnectionMonitor(connection) {
|
||||
this.connection = connection;
|
||||
this.visibilityDidChange = bind(this.visibilityDidChange, this);
|
||||
this.reconnectAttempts = 0;
|
||||
}
|
||||
|
||||
ConnectionMonitor.prototype.start = function() {
|
||||
if (!this.isRunning()) {
|
||||
this.startedAt = now();
|
||||
delete this.stoppedAt;
|
||||
this.startPolling();
|
||||
document.addEventListener("visibilitychange", this.visibilityDidChange);
|
||||
return ActionCable.log("ConnectionMonitor started. pollInterval = " + (this.getPollInterval()) + " ms");
|
||||
}
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.stop = function() {
|
||||
if (this.isRunning()) {
|
||||
this.stoppedAt = now();
|
||||
this.stopPolling();
|
||||
document.removeEventListener("visibilitychange", this.visibilityDidChange);
|
||||
return ActionCable.log("ConnectionMonitor stopped");
|
||||
}
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.isRunning = function() {
|
||||
return (this.startedAt != null) && (this.stoppedAt == null);
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.recordPing = function() {
|
||||
return this.pingedAt = now();
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.recordConnect = function() {
|
||||
this.reconnectAttempts = 0;
|
||||
this.recordPing();
|
||||
delete this.disconnectedAt;
|
||||
return ActionCable.log("ConnectionMonitor recorded connect");
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.recordDisconnect = function() {
|
||||
this.disconnectedAt = now();
|
||||
return ActionCable.log("ConnectionMonitor recorded disconnect");
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.startPolling = function() {
|
||||
this.stopPolling();
|
||||
return this.poll();
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.stopPolling = function() {
|
||||
return clearTimeout(this.pollTimeout);
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.poll = function() {
|
||||
return this.pollTimeout = setTimeout((function(_this) {
|
||||
return function() {
|
||||
_this.reconnectIfStale();
|
||||
return _this.poll();
|
||||
};
|
||||
})(this), this.getPollInterval());
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.getPollInterval = function() {
|
||||
var interval, max, min, ref;
|
||||
ref = this.constructor.pollInterval, min = ref.min, max = ref.max;
|
||||
interval = 5 * Math.log(this.reconnectAttempts + 1);
|
||||
return Math.round(clamp(interval, min, max) * 1000);
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.reconnectIfStale = function() {
|
||||
if (this.connectionIsStale()) {
|
||||
ActionCable.log("ConnectionMonitor detected stale connection. reconnectAttempts = " + this.reconnectAttempts + ", pollInterval = " + (this.getPollInterval()) + " ms, time disconnected = " + (secondsSince(this.disconnectedAt)) + " s, stale threshold = " + this.constructor.staleThreshold + " s");
|
||||
this.reconnectAttempts++;
|
||||
if (this.disconnectedRecently()) {
|
||||
return ActionCable.log("ConnectionMonitor skipping reopening recent disconnect");
|
||||
} else {
|
||||
ActionCable.log("ConnectionMonitor reopening");
|
||||
return this.connection.reopen();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.connectionIsStale = function() {
|
||||
var ref;
|
||||
return secondsSince((ref = this.pingedAt) != null ? ref : this.startedAt) > this.constructor.staleThreshold;
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.disconnectedRecently = function() {
|
||||
return this.disconnectedAt && secondsSince(this.disconnectedAt) < this.constructor.staleThreshold;
|
||||
};
|
||||
|
||||
ConnectionMonitor.prototype.visibilityDidChange = function() {
|
||||
if (document.visibilityState === "visible") {
|
||||
return setTimeout((function(_this) {
|
||||
return function() {
|
||||
if (_this.connectionIsStale() || !_this.connection.isOpen()) {
|
||||
ActionCable.log("ConnectionMonitor reopening stale connection on visibilitychange. visbilityState = " + document.visibilityState);
|
||||
return _this.connection.reopen();
|
||||
}
|
||||
};
|
||||
})(this), 200);
|
||||
}
|
||||
};
|
||||
|
||||
now = function() {
|
||||
return new Date().getTime();
|
||||
};
|
||||
|
||||
secondsSince = function(time) {
|
||||
return (now() - time) / 1000;
|
||||
};
|
||||
|
||||
clamp = function(number, min, max) {
|
||||
return Math.max(min, Math.min(max, number));
|
||||
};
|
||||
|
||||
return ConnectionMonitor;
|
||||
|
||||
})();
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var i, message_types, protocols, ref, supportedProtocols, unsupportedProtocol,
|
||||
slice = [].slice,
|
||||
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
|
||||
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||||
|
||||
ref = ActionCable.INTERNAL, message_types = ref.message_types, protocols = ref.protocols;
|
||||
|
||||
supportedProtocols = 2 <= protocols.length ? slice.call(protocols, 0, i = protocols.length - 1) : (i = 0, []), unsupportedProtocol = protocols[i++];
|
||||
|
||||
ActionCable.Connection = (function() {
|
||||
Connection.reopenDelay = 500;
|
||||
|
||||
function Connection(consumer) {
|
||||
this.consumer = consumer;
|
||||
this.open = bind(this.open, this);
|
||||
this.subscriptions = this.consumer.subscriptions;
|
||||
this.monitor = new ActionCable.ConnectionMonitor(this);
|
||||
this.disconnected = true;
|
||||
}
|
||||
|
||||
Connection.prototype.send = function(data) {
|
||||
if (this.isOpen()) {
|
||||
this.webSocket.send(JSON.stringify(data));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
Connection.prototype.open = function() {
|
||||
if (this.isActive()) {
|
||||
ActionCable.log("Attempted to open WebSocket, but existing socket is " + (this.getState()));
|
||||
return false;
|
||||
} else {
|
||||
ActionCable.log("Opening WebSocket, current state is " + (this.getState()) + ", subprotocols: " + protocols);
|
||||
if (this.webSocket != null) {
|
||||
this.uninstallEventHandlers();
|
||||
}
|
||||
this.webSocket = new ActionCable.WebSocket(this.consumer.url, protocols);
|
||||
this.installEventHandlers();
|
||||
this.monitor.start();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
Connection.prototype.close = function(arg) {
|
||||
var allowReconnect, ref1;
|
||||
allowReconnect = (arg != null ? arg : {
|
||||
allowReconnect: true
|
||||
}).allowReconnect;
|
||||
if (!allowReconnect) {
|
||||
this.monitor.stop();
|
||||
}
|
||||
if (this.isActive()) {
|
||||
return (ref1 = this.webSocket) != null ? ref1.close() : void 0;
|
||||
}
|
||||
};
|
||||
|
||||
Connection.prototype.reopen = function() {
|
||||
var error;
|
||||
ActionCable.log("Reopening WebSocket, current state is " + (this.getState()));
|
||||
if (this.isActive()) {
|
||||
try {
|
||||
return this.close();
|
||||
} catch (error1) {
|
||||
error = error1;
|
||||
return ActionCable.log("Failed to reopen WebSocket", error);
|
||||
} finally {
|
||||
ActionCable.log("Reopening WebSocket in " + this.constructor.reopenDelay + "ms");
|
||||
setTimeout(this.open, this.constructor.reopenDelay);
|
||||
}
|
||||
} else {
|
||||
return this.open();
|
||||
}
|
||||
};
|
||||
|
||||
Connection.prototype.getProtocol = function() {
|
||||
var ref1;
|
||||
return (ref1 = this.webSocket) != null ? ref1.protocol : void 0;
|
||||
};
|
||||
|
||||
Connection.prototype.isOpen = function() {
|
||||
return this.isState("open");
|
||||
};
|
||||
|
||||
Connection.prototype.isActive = function() {
|
||||
return this.isState("open", "connecting");
|
||||
};
|
||||
|
||||
Connection.prototype.isProtocolSupported = function() {
|
||||
var ref1;
|
||||
return ref1 = this.getProtocol(), indexOf.call(supportedProtocols, ref1) >= 0;
|
||||
};
|
||||
|
||||
Connection.prototype.isState = function() {
|
||||
var ref1, states;
|
||||
states = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
||||
return ref1 = this.getState(), indexOf.call(states, ref1) >= 0;
|
||||
};
|
||||
|
||||
Connection.prototype.getState = function() {
|
||||
var ref1, state, value;
|
||||
for (state in WebSocket) {
|
||||
value = WebSocket[state];
|
||||
if (value === ((ref1 = this.webSocket) != null ? ref1.readyState : void 0)) {
|
||||
return state.toLowerCase();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
Connection.prototype.installEventHandlers = function() {
|
||||
var eventName, handler;
|
||||
for (eventName in this.events) {
|
||||
handler = this.events[eventName].bind(this);
|
||||
this.webSocket["on" + eventName] = handler;
|
||||
}
|
||||
};
|
||||
|
||||
Connection.prototype.uninstallEventHandlers = function() {
|
||||
var eventName;
|
||||
for (eventName in this.events) {
|
||||
this.webSocket["on" + eventName] = function() {};
|
||||
}
|
||||
};
|
||||
|
||||
Connection.prototype.events = {
|
||||
message: function(event) {
|
||||
var identifier, message, ref1, type;
|
||||
if (!this.isProtocolSupported()) {
|
||||
return;
|
||||
}
|
||||
ref1 = JSON.parse(event.data), identifier = ref1.identifier, message = ref1.message, type = ref1.type;
|
||||
switch (type) {
|
||||
case message_types.welcome:
|
||||
this.monitor.recordConnect();
|
||||
return this.subscriptions.reload();
|
||||
case message_types.ping:
|
||||
return this.monitor.recordPing();
|
||||
case message_types.confirmation:
|
||||
return this.subscriptions.notify(identifier, "connected");
|
||||
case message_types.rejection:
|
||||
return this.subscriptions.reject(identifier);
|
||||
default:
|
||||
return this.subscriptions.notify(identifier, "received", message);
|
||||
}
|
||||
},
|
||||
open: function() {
|
||||
ActionCable.log("WebSocket onopen event, using '" + (this.getProtocol()) + "' subprotocol");
|
||||
this.disconnected = false;
|
||||
if (!this.isProtocolSupported()) {
|
||||
ActionCable.log("Protocol is unsupported. Stopping monitor and disconnecting.");
|
||||
return this.close({
|
||||
allowReconnect: false
|
||||
});
|
||||
}
|
||||
},
|
||||
close: function(event) {
|
||||
ActionCable.log("WebSocket onclose event");
|
||||
if (this.disconnected) {
|
||||
return;
|
||||
}
|
||||
this.disconnected = true;
|
||||
this.monitor.recordDisconnect();
|
||||
return this.subscriptions.notifyAll("disconnected", {
|
||||
willAttemptReconnect: this.monitor.isRunning()
|
||||
});
|
||||
},
|
||||
error: function() {
|
||||
return ActionCable.log("WebSocket onerror event");
|
||||
}
|
||||
};
|
||||
|
||||
return Connection;
|
||||
|
||||
})();
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var slice = [].slice;
|
||||
|
||||
ActionCable.Subscriptions = (function() {
|
||||
function Subscriptions(consumer) {
|
||||
this.consumer = consumer;
|
||||
this.subscriptions = [];
|
||||
}
|
||||
|
||||
Subscriptions.prototype.create = function(channelName, mixin) {
|
||||
var channel, params, subscription;
|
||||
channel = channelName;
|
||||
params = typeof channel === "object" ? channel : {
|
||||
channel: channel
|
||||
};
|
||||
subscription = new ActionCable.Subscription(this.consumer, params, mixin);
|
||||
return this.add(subscription);
|
||||
};
|
||||
|
||||
Subscriptions.prototype.add = function(subscription) {
|
||||
this.subscriptions.push(subscription);
|
||||
this.consumer.ensureActiveConnection();
|
||||
this.notify(subscription, "initialized");
|
||||
this.sendCommand(subscription, "subscribe");
|
||||
return subscription;
|
||||
};
|
||||
|
||||
Subscriptions.prototype.remove = function(subscription) {
|
||||
this.forget(subscription);
|
||||
if (!this.findAll(subscription.identifier).length) {
|
||||
this.sendCommand(subscription, "unsubscribe");
|
||||
}
|
||||
return subscription;
|
||||
};
|
||||
|
||||
Subscriptions.prototype.reject = function(identifier) {
|
||||
var i, len, ref, results, subscription;
|
||||
ref = this.findAll(identifier);
|
||||
results = [];
|
||||
for (i = 0, len = ref.length; i < len; i++) {
|
||||
subscription = ref[i];
|
||||
this.forget(subscription);
|
||||
this.notify(subscription, "rejected");
|
||||
results.push(subscription);
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
Subscriptions.prototype.forget = function(subscription) {
|
||||
var s;
|
||||
this.subscriptions = (function() {
|
||||
var i, len, ref, results;
|
||||
ref = this.subscriptions;
|
||||
results = [];
|
||||
for (i = 0, len = ref.length; i < len; i++) {
|
||||
s = ref[i];
|
||||
if (s !== subscription) {
|
||||
results.push(s);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}).call(this);
|
||||
return subscription;
|
||||
};
|
||||
|
||||
Subscriptions.prototype.findAll = function(identifier) {
|
||||
var i, len, ref, results, s;
|
||||
ref = this.subscriptions;
|
||||
results = [];
|
||||
for (i = 0, len = ref.length; i < len; i++) {
|
||||
s = ref[i];
|
||||
if (s.identifier === identifier) {
|
||||
results.push(s);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
Subscriptions.prototype.reload = function() {
|
||||
var i, len, ref, results, subscription;
|
||||
ref = this.subscriptions;
|
||||
results = [];
|
||||
for (i = 0, len = ref.length; i < len; i++) {
|
||||
subscription = ref[i];
|
||||
results.push(this.sendCommand(subscription, "subscribe"));
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
Subscriptions.prototype.notifyAll = function() {
|
||||
var args, callbackName, i, len, ref, results, subscription;
|
||||
callbackName = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
||||
ref = this.subscriptions;
|
||||
results = [];
|
||||
for (i = 0, len = ref.length; i < len; i++) {
|
||||
subscription = ref[i];
|
||||
results.push(this.notify.apply(this, [subscription, callbackName].concat(slice.call(args))));
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
Subscriptions.prototype.notify = function() {
|
||||
var args, callbackName, i, len, results, subscription, subscriptions;
|
||||
subscription = arguments[0], callbackName = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : [];
|
||||
if (typeof subscription === "string") {
|
||||
subscriptions = this.findAll(subscription);
|
||||
} else {
|
||||
subscriptions = [subscription];
|
||||
}
|
||||
results = [];
|
||||
for (i = 0, len = subscriptions.length; i < len; i++) {
|
||||
subscription = subscriptions[i];
|
||||
results.push(typeof subscription[callbackName] === "function" ? subscription[callbackName].apply(subscription, args) : void 0);
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
Subscriptions.prototype.sendCommand = function(subscription, command) {
|
||||
var identifier;
|
||||
identifier = subscription.identifier;
|
||||
return this.consumer.send({
|
||||
command: command,
|
||||
identifier: identifier
|
||||
});
|
||||
};
|
||||
|
||||
return Subscriptions;
|
||||
|
||||
})();
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
ActionCable.Subscription = (function() {
|
||||
var extend;
|
||||
|
||||
function Subscription(consumer, params, mixin) {
|
||||
this.consumer = consumer;
|
||||
if (params == null) {
|
||||
params = {};
|
||||
}
|
||||
this.identifier = JSON.stringify(params);
|
||||
extend(this, mixin);
|
||||
}
|
||||
|
||||
Subscription.prototype.perform = function(action, data) {
|
||||
if (data == null) {
|
||||
data = {};
|
||||
}
|
||||
data.action = action;
|
||||
return this.send(data);
|
||||
};
|
||||
|
||||
Subscription.prototype.send = function(data) {
|
||||
return this.consumer.send({
|
||||
command: "message",
|
||||
identifier: this.identifier,
|
||||
data: JSON.stringify(data)
|
||||
});
|
||||
};
|
||||
|
||||
Subscription.prototype.unsubscribe = function() {
|
||||
return this.consumer.subscriptions.remove(this);
|
||||
};
|
||||
|
||||
extend = function(object, properties) {
|
||||
var key, value;
|
||||
if (properties != null) {
|
||||
for (key in properties) {
|
||||
value = properties[key];
|
||||
object[key] = value;
|
||||
}
|
||||
}
|
||||
return object;
|
||||
};
|
||||
|
||||
return Subscription;
|
||||
|
||||
})();
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
ActionCable.Consumer = (function() {
|
||||
function Consumer(url) {
|
||||
this.url = url;
|
||||
this.subscriptions = new ActionCable.Subscriptions(this);
|
||||
this.connection = new ActionCable.Connection(this);
|
||||
}
|
||||
|
||||
Consumer.prototype.send = function(data) {
|
||||
return this.connection.send(data);
|
||||
};
|
||||
|
||||
Consumer.prototype.connect = function() {
|
||||
return this.connection.open();
|
||||
};
|
||||
|
||||
Consumer.prototype.disconnect = function() {
|
||||
return this.connection.close({
|
||||
allowReconnect: false
|
||||
});
|
||||
};
|
||||
|
||||
Consumer.prototype.ensureActiveConnection = function() {
|
||||
if (!this.connection.isActive()) {
|
||||
return this.connection.open();
|
||||
}
|
||||
};
|
||||
|
||||
return Consumer;
|
||||
|
||||
})();
|
||||
|
||||
}).call(this);
|
||||
}).call(this);
|
||||
|
||||
if (typeof module === "object" && module.exports) {
|
||||
module.exports = ActionCable;
|
||||
} else if (typeof define === "function" && define.amd) {
|
||||
define(ActionCable);
|
||||
}
|
||||
}).call(this);
|
||||
// Action Cable provides the framework to deal with WebSockets in Rails.
|
||||
// You can generate new channels where WebSocket features live using the `rails generate channel` command.
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
(function() {
|
||||
this.App || (this.App = {});
|
||||
|
||||
App.cable = ActionCable.createConsumer();
|
||||
|
||||
}).call(this);
|
||||
Binary file not shown.
|
|
@ -0,0 +1,42 @@
|
|||
(function($) {
|
||||
"use strict"; // Start of use strict
|
||||
|
||||
// Floating label headings for the contact form
|
||||
$("body").on("input propertychange", ".floating-label-form-group", function(e) {
|
||||
$(this).toggleClass("floating-label-form-group-with-value", !!$(e.target).val());
|
||||
}).on("focus", ".floating-label-form-group", function() {
|
||||
$(this).addClass("floating-label-form-group-with-focus");
|
||||
}).on("blur", ".floating-label-form-group", function() {
|
||||
$(this).removeClass("floating-label-form-group-with-focus");
|
||||
});
|
||||
|
||||
// Show the navbar when the page is scrolled up
|
||||
var MQL = 992;
|
||||
|
||||
//primary navigation slide-in effect
|
||||
if ($(window).width() > MQL) {
|
||||
var headerHeight = $('#mainNav').height();
|
||||
$(window).on('scroll', {
|
||||
previousTop: 0
|
||||
},
|
||||
function() {
|
||||
var currentTop = $(window).scrollTop();
|
||||
//check if user is scrolling up
|
||||
if (currentTop < this.previousTop) {
|
||||
//if scrolling up...
|
||||
if (currentTop > 0 && $('#mainNav').hasClass('is-fixed')) {
|
||||
$('#mainNav').addClass('is-visible');
|
||||
} else {
|
||||
$('#mainNav').removeClass('is-visible is-fixed');
|
||||
}
|
||||
} else if (currentTop > this.previousTop) {
|
||||
//if scrolling down...
|
||||
$('#mainNav').removeClass('is-visible');
|
||||
if (currentTop > headerHeight && !$('#mainNav').hasClass('is-fixed')) $('#mainNav').addClass('is-fixed');
|
||||
}
|
||||
this.previousTop = currentTop;
|
||||
});
|
||||
}
|
||||
|
||||
})(jQuery); // End of use strict
|
||||
;
|
||||
Binary file not shown.
|
|
@ -0,0 +1,420 @@
|
|||
body {
|
||||
font-size: 20px;
|
||||
color: #212529;
|
||||
font-family: 'Lora', 'Times New Roman', serif;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 1.5;
|
||||
margin: 30px 0;
|
||||
}
|
||||
|
||||
p a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-weight: 800;
|
||||
font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #212529;
|
||||
-webkit-transition: all 0.2s;
|
||||
-moz-transition: all 0.2s;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
a:focus, a:hover {
|
||||
color: #0085A1;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
font-style: italic;
|
||||
color: #868e96;
|
||||
}
|
||||
|
||||
.section-heading {
|
||||
font-size: 36px;
|
||||
font-weight: 700;
|
||||
margin-top: 60px;
|
||||
}
|
||||
|
||||
.caption {
|
||||
font-size: 14px;
|
||||
font-style: italic;
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
border-bottom-right-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
}
|
||||
|
||||
::-moz-selection {
|
||||
color: #fff;
|
||||
background: #0085A1;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
::selection {
|
||||
color: #fff;
|
||||
background: #0085A1;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
img::selection {
|
||||
color: #fff;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
img::-moz-selection {
|
||||
color: #fff;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
#mainNav {
|
||||
position: absolute;
|
||||
border-bottom: 1px solid #e9ecef;
|
||||
background-color: white;
|
||||
font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
#mainNav .navbar-brand {
|
||||
font-weight: 800;
|
||||
color: #343a40;
|
||||
}
|
||||
|
||||
#mainNav .navbar-toggler {
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
padding: 13px;
|
||||
text-transform: uppercase;
|
||||
color: #343a40;
|
||||
}
|
||||
|
||||
#mainNav .navbar-nav > li.nav-item > a {
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 992px) {
|
||||
#mainNav {
|
||||
border-bottom: 1px solid transparent;
|
||||
background: transparent;
|
||||
}
|
||||
#mainNav .navbar-brand {
|
||||
padding: 10px 20px;
|
||||
color: #fff;
|
||||
}
|
||||
#mainNav .navbar-brand:focus, #mainNav .navbar-brand:hover {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
#mainNav .navbar-nav > li.nav-item > a {
|
||||
padding: 10px 20px;
|
||||
color: #fff;
|
||||
}
|
||||
#mainNav .navbar-nav > li.nav-item > a:focus, #mainNav .navbar-nav > li.nav-item > a:hover {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 992px) {
|
||||
#mainNav {
|
||||
-webkit-transition: background-color 0.2s;
|
||||
-moz-transition: background-color 0.2s;
|
||||
transition: background-color 0.2s;
|
||||
/* Force Hardware Acceleration in WebKit */
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
-moz-transform: translate3d(0, 0, 0);
|
||||
-ms-transform: translate3d(0, 0, 0);
|
||||
-o-transform: translate3d(0, 0, 0);
|
||||
transform: translate3d(0, 0, 0);
|
||||
-webkit-backface-visibility: hidden;
|
||||
}
|
||||
#mainNav.is-fixed {
|
||||
/* when the user scrolls down, we hide the header right above the viewport */
|
||||
position: fixed;
|
||||
top: -67px;
|
||||
-webkit-transition: -webkit-transform 0.2s;
|
||||
-moz-transition: -moz-transform 0.2s;
|
||||
transition: transform 0.2s;
|
||||
border-bottom: 1px solid white;
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
#mainNav.is-fixed .navbar-brand {
|
||||
color: #212529;
|
||||
}
|
||||
#mainNav.is-fixed .navbar-brand:focus, #mainNav.is-fixed .navbar-brand:hover {
|
||||
color: #0085A1;
|
||||
}
|
||||
#mainNav.is-fixed .navbar-nav > li.nav-item > a {
|
||||
color: #212529;
|
||||
}
|
||||
#mainNav.is-fixed .navbar-nav > li.nav-item > a:focus, #mainNav.is-fixed .navbar-nav > li.nav-item > a:hover {
|
||||
color: #0085A1;
|
||||
}
|
||||
#mainNav.is-visible {
|
||||
/* if the user changes the scrolling direction, we show the header */
|
||||
-webkit-transform: translate3d(0, 100%, 0);
|
||||
-moz-transform: translate3d(0, 100%, 0);
|
||||
-ms-transform: translate3d(0, 100%, 0);
|
||||
-o-transform: translate3d(0, 100%, 0);
|
||||
transform: translate3d(0, 100%, 0);
|
||||
}
|
||||
}
|
||||
|
||||
header.masthead {
|
||||
margin-bottom: 50px;
|
||||
background: no-repeat center center;
|
||||
background-color: #868e96;
|
||||
background-attachment: scroll;
|
||||
position: relative;
|
||||
-webkit-background-size: cover;
|
||||
-moz-background-size: cover;
|
||||
-o-background-size: cover;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
header.masthead .overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: #212529;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
header.masthead .page-heading,
|
||||
header.masthead .post-heading,
|
||||
header.masthead .site-heading {
|
||||
padding: 200px 0 150px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
header.masthead .page-heading,
|
||||
header.masthead .post-heading,
|
||||
header.masthead .site-heading {
|
||||
padding: 200px 0;
|
||||
}
|
||||
}
|
||||
|
||||
header.masthead .page-heading,
|
||||
header.masthead .site-heading {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
header.masthead .page-heading h1,
|
||||
header.masthead .site-heading h1 {
|
||||
font-size: 50px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
header.masthead .page-heading .subheading,
|
||||
header.masthead .site-heading .subheading {
|
||||
font-size: 24px;
|
||||
font-weight: 300;
|
||||
line-height: 1.1;
|
||||
display: block;
|
||||
margin: 10px 0 0;
|
||||
font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
header.masthead .page-heading h1,
|
||||
header.masthead .site-heading h1 {
|
||||
font-size: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
header.masthead .post-heading h1 {
|
||||
font-size: 35px;
|
||||
}
|
||||
|
||||
header.masthead .post-heading .meta,
|
||||
header.masthead .post-heading .subheading {
|
||||
line-height: 1.1;
|
||||
display: block;
|
||||
}
|
||||
|
||||
header.masthead .post-heading .subheading {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
margin: 10px 0 30px;
|
||||
font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
header.masthead .post-heading .meta {
|
||||
font-size: 20px;
|
||||
font-weight: 300;
|
||||
font-style: italic;
|
||||
font-family: 'Lora', 'Times New Roman', serif;
|
||||
}
|
||||
|
||||
header.masthead .post-heading .meta a {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
header.masthead .post-heading h1 {
|
||||
font-size: 55px;
|
||||
}
|
||||
header.masthead .post-heading .subheading {
|
||||
font-size: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.post-preview > a {
|
||||
color: #212529;
|
||||
}
|
||||
|
||||
.post-preview > a:focus, .post-preview > a:hover {
|
||||
text-decoration: none;
|
||||
color: #0085A1;
|
||||
}
|
||||
|
||||
.post-preview > a > .post-title {
|
||||
font-size: 30px;
|
||||
margin-top: 30px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.post-preview > a > .post-subtitle {
|
||||
font-weight: 300;
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
||||
.post-preview > .post-meta {
|
||||
font-size: 18px;
|
||||
font-style: italic;
|
||||
margin-top: 0;
|
||||
color: #868e96;
|
||||
}
|
||||
|
||||
.post-preview > .post-meta > a {
|
||||
text-decoration: none;
|
||||
color: #212529;
|
||||
}
|
||||
|
||||
.post-preview > .post-meta > a:focus, .post-preview > .post-meta > a:hover {
|
||||
text-decoration: underline;
|
||||
color: #0085A1;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
.post-preview > a > .post-title {
|
||||
font-size: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
.floating-label-form-group {
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
margin-bottom: 0;
|
||||
padding-bottom: 0.5em;
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
}
|
||||
|
||||
.floating-label-form-group input,
|
||||
.floating-label-form-group textarea {
|
||||
font-size: 1.5em;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding: 0;
|
||||
resize: none;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
background: none;
|
||||
box-shadow: none !important;
|
||||
font-family: 'Lora', 'Times New Roman', serif;
|
||||
}
|
||||
|
||||
.floating-label-form-group input::-webkit-input-placeholder,
|
||||
.floating-label-form-group textarea::-webkit-input-placeholder {
|
||||
color: #868e96;
|
||||
font-family: 'Lora', 'Times New Roman', serif;
|
||||
}
|
||||
|
||||
.floating-label-form-group label {
|
||||
font-size: 0.85em;
|
||||
line-height: 1.764705882em;
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
top: 2em;
|
||||
display: block;
|
||||
margin: 0;
|
||||
-webkit-transition: top 0.3s ease, opacity 0.3s ease;
|
||||
-moz-transition: top 0.3s ease, opacity 0.3s ease;
|
||||
-ms-transition: top 0.3s ease, opacity 0.3s ease;
|
||||
transition: top 0.3s ease, opacity 0.3s ease;
|
||||
vertical-align: middle;
|
||||
vertical-align: baseline;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.floating-label-form-group .help-block {
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.floating-label-form-group-with-value label {
|
||||
top: 0;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.floating-label-form-group-with-focus label {
|
||||
color: #0085A1;
|
||||
}
|
||||
|
||||
form .form-group:first-child .floating-label-form-group {
|
||||
border-top: 1px solid #dee2e6;
|
||||
}
|
||||
|
||||
footer {
|
||||
padding: 50px 0 65px;
|
||||
}
|
||||
|
||||
footer .list-inline {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
footer .copyright {
|
||||
font-size: 14px;
|
||||
margin-bottom: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn {
|
||||
font-size: 14px;
|
||||
font-weight: 800;
|
||||
padding: 15px 25px;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
border-radius: 0;
|
||||
font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #0085A1;
|
||||
border-color: #0085A1;
|
||||
}
|
||||
|
||||
.btn-primary:hover, .btn-primary:focus, .btn-primary:active {
|
||||
color: #fff;
|
||||
background-color: #00657b !important;
|
||||
border-color: #00657b !important;
|
||||
}
|
||||
|
||||
.btn-lg {
|
||||
font-size: 16px;
|
||||
padding: 25px 35px;
|
||||
}
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
|
|
@ -0,0 +1,76 @@
|
|||
$(function() {
|
||||
|
||||
$("#contactForm input,#contactForm textarea").jqBootstrapValidation({
|
||||
preventSubmit: true,
|
||||
submitError: function($form, event, errors) {
|
||||
// additional error messages or events
|
||||
},
|
||||
submitSuccess: function($form, event) {
|
||||
event.preventDefault(); // prevent default submit behaviour
|
||||
// get values from FORM
|
||||
var name = $("input#name").val();
|
||||
var email = $("input#email").val();
|
||||
var message = $("textarea#message").val();
|
||||
var recaptcha_confirm = $("#g-recaptcha-response").val();
|
||||
var firstName = name; // For Success/Failure Message
|
||||
// Check for white space in name for Success/Fail message
|
||||
if (firstName.indexOf(' ') >= 0) {
|
||||
firstName = name.split(' ').slice(0, -1).join(' ');
|
||||
}
|
||||
$this = $("#sendMessageButton");
|
||||
$this.prop("disabled", true); // Disable submit button until AJAX call is complete to prevent duplicate messages
|
||||
$.ajax({
|
||||
url: "/site/send_email",
|
||||
type: "POST",
|
||||
beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))},
|
||||
data: {
|
||||
name: name,
|
||||
email: email,
|
||||
message: message,
|
||||
'g-recaptcha-response': recaptcha_confirm
|
||||
},
|
||||
cache: false,
|
||||
success: function() {
|
||||
// Success message
|
||||
$('#success').html("<div class='alert alert-success'>");
|
||||
$('#success > .alert-success').html("<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>×")
|
||||
.append("</button>");
|
||||
$('#success > .alert-success')
|
||||
.append("<strong>Wiadomość została wysłana. </strong>");
|
||||
$('#success > .alert-success')
|
||||
.append('</div>');
|
||||
//clear all fields
|
||||
$('#contactForm').trigger("reset");
|
||||
},
|
||||
error: function() {
|
||||
// Fail message
|
||||
$('#success').html("<div class='alert alert-danger'>");
|
||||
$('#success > .alert-danger').html("<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>×")
|
||||
.append("</button>");
|
||||
$('#success > .alert-danger').append($("<strong>").text("Wygląda na to, że serwer nie odpowiada. Proszę spróbuj później."));
|
||||
$('#success > .alert-danger').append('</div>');
|
||||
//clear all fields
|
||||
$('#contactForm').trigger("reset");
|
||||
},
|
||||
complete: function() {
|
||||
setTimeout(function() {
|
||||
$this.prop("disabled", false); // Re-enable submit button when AJAX call is complete
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
},
|
||||
filter: function() {
|
||||
return $(this).is(":visible");
|
||||
},
|
||||
});
|
||||
|
||||
$("a[data-toggle=\"tab\"]").click(function(e) {
|
||||
e.preventDefault();
|
||||
$(this).tab("show");
|
||||
});
|
||||
});
|
||||
|
||||
/*When clicking on Full hide fail/success boxes */
|
||||
$('#name').focus(function() {
|
||||
$('#success').html('');
|
||||
});
|
||||
Binary file not shown.
|
|
@ -0,0 +1,383 @@
|
|||
/*!
|
||||
* Start Bootstrap - Creative v4.0.0-beta.2 (https://startbootstrap.com/template-overviews/creative)
|
||||
* Copyright 2013-2017 Start Bootstrap
|
||||
* Licensed under MIT (https://github.com/BlackrockDigital/startbootstrap-creative/blob/master/LICENSE)
|
||||
*/
|
||||
|
||||
body,
|
||||
html {
|
||||
width: 100%;
|
||||
height: 100%; }
|
||||
|
||||
body {
|
||||
font-family: 'Merriweather', 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
|
||||
hr.mini {
|
||||
max-width: 50px;
|
||||
border-width: 3px;
|
||||
border-color: #40a5f0; }
|
||||
|
||||
hr.light {
|
||||
border-color: #fff; }
|
||||
|
||||
a {
|
||||
color: #40a5f0;
|
||||
-webkit-transition: all 0.2s;
|
||||
-moz-transition: all 0.2s;
|
||||
transition: all 0.2s; }
|
||||
a:hover {
|
||||
color: #40a5f0; }
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif; }
|
||||
|
||||
.bg-primary {
|
||||
background-color: #40a5f0 !important; }
|
||||
|
||||
.bg-dark {
|
||||
background-color: #212529 !important; }
|
||||
|
||||
.text-faded {
|
||||
color: rgba(255, 255, 255, 0.7); }
|
||||
|
||||
section {
|
||||
padding: 1rem 0; }
|
||||
|
||||
.section-heading {
|
||||
margin-top: 0; }
|
||||
|
||||
::-moz-selection {
|
||||
color: #fff;
|
||||
background: #212529;
|
||||
text-shadow: none; }
|
||||
|
||||
::selection {
|
||||
color: #fff;
|
||||
background: #212529;
|
||||
text-shadow: none; }
|
||||
|
||||
img::selection {
|
||||
color: #fff;
|
||||
background: transparent; }
|
||||
|
||||
img::-moz-selection {
|
||||
color: #fff;
|
||||
background: transparent; }
|
||||
|
||||
body {
|
||||
-webkit-tap-highlight-color: #212529; }
|
||||
|
||||
#mainNav {
|
||||
border-bottom: 1px solid rgba(33, 37, 41, 0.1);
|
||||
background-color: #8D8D8D;
|
||||
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
|
||||
-webkit-transition: all 0.2s;
|
||||
-moz-transition: all 0.2s;
|
||||
transition: all 0.2s; }
|
||||
#mainNav .navbar-brand {
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
color: #40a5f0;
|
||||
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif; }
|
||||
#mainNav .navbar-brand:focus, #mainNav .navbar-brand:hover {
|
||||
color: #40a5f0; }
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link,
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus {
|
||||
font-size: .9rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
color: #212529; }
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link:hover,
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus:hover {
|
||||
color: #40a5f0; }
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link.active,
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus.active {
|
||||
color: #40a5f0 !important;
|
||||
background-color: transparent; }
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link.active:hover,
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus.active:hover {
|
||||
background-color: transparent; }
|
||||
@media (min-width: 992px) {
|
||||
#mainNav {
|
||||
border-color: transparent;
|
||||
background-color: transparent; }
|
||||
#mainNav .navbar-brand {
|
||||
color: rgba(255, 255, 255, 0.7); }
|
||||
#mainNav .navbar-brand:focus, #mainNav .navbar-brand:hover {
|
||||
color: #fff; }
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link {
|
||||
padding: 0.5rem 1rem; }
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link,
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus {
|
||||
color: rgba(255, 255, 255, 0.7); }
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link:hover,
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus:hover {
|
||||
color: #fff; }
|
||||
#mainNav.navbar-shrink {
|
||||
border-bottom: 1px solid rgba(33, 37, 41, 0.1);
|
||||
background-color: #cec9c9; }
|
||||
#mainNav.navbar-shrink .navbar-brand {
|
||||
color: #40a5f0; }
|
||||
#mainNav.navbar-shrink .navbar-brand:focus, #mainNav.navbar-shrink .navbar-brand:hover {
|
||||
color: #40a5f0; }
|
||||
#mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link,
|
||||
#mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link:focus {
|
||||
color: #212529; }
|
||||
#mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link:hover,
|
||||
#mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link:focus:hover {
|
||||
color: #40a5f0; } }
|
||||
header.title {
|
||||
padding-top: 4rem;
|
||||
}
|
||||
header.masthead {
|
||||
padding-top: 10rem;
|
||||
padding-bottom: calc(10rem - 56px);
|
||||
background-image: url("finanse.jpeg");
|
||||
/*background-position: center center;*/
|
||||
-webkit-background-size: cover;
|
||||
-moz-background-size: cover;
|
||||
-o-background-size: cover;
|
||||
background-size: cover; }
|
||||
header.masthead hr.mini {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 30px; }
|
||||
header.masthead h1 {
|
||||
font-size: 2rem; }
|
||||
header.masthead p {
|
||||
font-weight: 300; }
|
||||
@media (min-width: 768px) {
|
||||
header.masthead p {
|
||||
font-size: 1.15rem; } }
|
||||
@media (min-width: 992px) {
|
||||
header.masthead {
|
||||
height: 100vh;
|
||||
min-height: 650px;
|
||||
padding-top: 0;
|
||||
margin-top: 50px;
|
||||
padding-bottom: 0; }
|
||||
header.masthead h1 {
|
||||
font-size: 3rem; } }
|
||||
@media (min-width: 1200px) {
|
||||
header.masthead h1 {
|
||||
font-size: 4rem; } }
|
||||
|
||||
.service-box {
|
||||
max-width: 400px; }
|
||||
|
||||
.portfolio-box {
|
||||
position: relative;
|
||||
display: block;
|
||||
max-width: 650px;
|
||||
margin: 0 auto; }
|
||||
.portfolio-box .portfolio-box-caption {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
opacity: 0;
|
||||
color: #fff;
|
||||
background: rgba(240, 95, 64, 0.9);
|
||||
-webkit-transition: all 0.2s;
|
||||
-moz-transition: all 0.2s;
|
||||
transition: all 0.2s; }
|
||||
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
width: 100%;
|
||||
transform: translateY(-50%);
|
||||
text-align: center; }
|
||||
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category,
|
||||
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name {
|
||||
padding: 0 15px;
|
||||
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif; }
|
||||
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase; }
|
||||
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name {
|
||||
font-size: 18px; }
|
||||
.portfolio-box:hover .portfolio-box-caption {
|
||||
opacity: 1; }
|
||||
.portfolio-box:focus {
|
||||
outline: none; }
|
||||
@media (min-width: 768px) {
|
||||
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category {
|
||||
font-size: 16px; }
|
||||
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name {
|
||||
font-size: 22px; } }
|
||||
|
||||
.text-primary {
|
||||
color: #40a5f0 !important; }
|
||||
|
||||
.btn {
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
border: none;
|
||||
border-radius: 300px;
|
||||
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif; }
|
||||
|
||||
.btn-xl {
|
||||
padding: 1rem 2rem; }
|
||||
|
||||
.btn-primary {
|
||||
background-color: #40a5f0;
|
||||
border-color: #40a5f0; }
|
||||
.btn-primary:hover, .btn-primary:focus, .btn-primary:active {
|
||||
color: #fff;
|
||||
background-color: #4080F0 !important; }
|
||||
.btn-primary:active, .btn-primary:focus {
|
||||
box-shadow: 0 0 0 0.2rem rgba(240, 95, 64, 0.5) !important; }
|
||||
.post-preview > a {
|
||||
color: #212529;
|
||||
}
|
||||
|
||||
.post-preview > a:focus, .post-preview > a:hover {
|
||||
text-decoration: none;
|
||||
color: #0085A1;
|
||||
}
|
||||
|
||||
.post-preview > a > .post-title {
|
||||
font-weight: 800;
|
||||
font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
font-size: 30px;
|
||||
margin-top: 30px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.post-preview > a > .post-subtitle {
|
||||
font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
font-weight: 300;
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
||||
.post-preview > .post-meta {
|
||||
font-size: 18px;
|
||||
font-style: italic;
|
||||
margin-top: 0;
|
||||
color: #868e96;
|
||||
}
|
||||
|
||||
.post-preview > .post-meta > a {
|
||||
text-decoration: none;
|
||||
color: #212529;
|
||||
}
|
||||
|
||||
.post-preview > .post-meta > a:focus, .post-preview > .post-meta > a:hover {
|
||||
text-decoration: underline;
|
||||
color: #0085A1;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
.post-preview > a > .post-title {
|
||||
font-size: 36px;
|
||||
}
|
||||
}
|
||||
header.contacthead {
|
||||
margin-bottom: 50px;
|
||||
background: no-repeat center center;
|
||||
background-color: #868e96;
|
||||
background-attachment: scroll;
|
||||
position: relative;
|
||||
-webkit-background-size: cover;
|
||||
-moz-background-size: cover;
|
||||
-o-background-size: cover;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
header.contacthead .overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: #212529;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
header.contacthead .page-heading,
|
||||
header.contacthead .post-heading,
|
||||
header.contacthead .site-heading {
|
||||
padding: 200px 0 150px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
header.contacthead .page-heading,
|
||||
header.contacthead .post-heading,
|
||||
header.contacthead .site-heading {
|
||||
padding: 200px 0;
|
||||
}
|
||||
}
|
||||
|
||||
header.contacthead .page-heading,
|
||||
header.contacthead .site-heading {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
header.contacthead .page-heading h1,
|
||||
header.contacthead .site-heading h1 {
|
||||
font-size: 50px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
header.contacthead .page-heading .subheading,
|
||||
header.contacthead .site-heading .subheading {
|
||||
font-size: 24px;
|
||||
font-weight: 300;
|
||||
line-height: 1.1;
|
||||
display: block;
|
||||
margin: 10px 0 0;
|
||||
font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
header.contacthead .page-heading h1,
|
||||
header.contacthead .site-heading h1 {
|
||||
font-size: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
header.contacthead .post-heading h1 {
|
||||
font-size: 35px;
|
||||
}
|
||||
|
||||
header.contacthead .post-heading .meta,
|
||||
header.contacthead .post-heading .subheading {
|
||||
line-height: 1.1;
|
||||
display: block;
|
||||
}
|
||||
|
||||
header.contacthead .post-heading .subheading {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
margin: 10px 0 30px;
|
||||
font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
header.contacthead .post-heading .meta {
|
||||
font-size: 20px;
|
||||
font-weight: 300;
|
||||
font-style: italic;
|
||||
font-family: 'Lora', 'Times New Roman', serif;
|
||||
}
|
||||
|
||||
header.contacthead .post-heading .meta a {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
header.contacthead .post-heading h1 {
|
||||
font-size: 55px;
|
||||
}
|
||||
header.contacthead .post-heading .subheading {
|
||||
font-size: 30px;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
|
@ -0,0 +1,26 @@
|
|||
(function($) {
|
||||
"use strict"; // Start of use strict
|
||||
|
||||
// Smooth scrolling using jQuery easing
|
||||
$('a.js-scroll-trigger[href*="#"]:not([href="#"])').click(function() {
|
||||
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
|
||||
var target = $(this.hash);
|
||||
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
|
||||
if (target.length) {
|
||||
$('html, body').animate({
|
||||
scrollTop: (target.offset().top - 57)
|
||||
}, 1000, "easeInOutExpo");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Closes responsive menu when a scroll trigger link is clicked
|
||||
$('.js-scroll-trigger').click(function() {
|
||||
$('.navbar-collapse').collapse('hide');
|
||||
});
|
||||
|
||||
// Activate scrollspy to add active class to navbar items on scroll
|
||||
|
||||
})(jQuery); // End of use strict
|
||||
;
|
||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 434 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 123 KiB |
|
|
@ -0,0 +1,4 @@
|
|||
(function() {
|
||||
|
||||
|
||||
}).call(this);
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
|
|
@ -0,0 +1,938 @@
|
|||
/* jqBootstrapValidation
|
||||
* A plugin for automating validation on Twitter Bootstrap formatted forms.
|
||||
*
|
||||
* v1.3.6
|
||||
*
|
||||
* License: MIT <http://opensource.org/licenses/mit-license.php> - see LICENSE file
|
||||
*
|
||||
* http://ReactiveRaven.github.com/jqBootstrapValidation/
|
||||
*/
|
||||
|
||||
|
||||
(function($) {
|
||||
|
||||
var createdElements = [];
|
||||
|
||||
var defaults = {
|
||||
options: {
|
||||
prependExistingHelpBlock: false,
|
||||
sniffHtml: true, // sniff for 'required', 'maxlength', etc
|
||||
preventSubmit: true, // stop the form submit event from firing if validation fails
|
||||
submitError: false, // function called if there is an error when trying to submit
|
||||
submitSuccess: false, // function called just before a successful submit event is sent to the server
|
||||
semanticallyStrict: false, // set to true to tidy up generated HTML output
|
||||
autoAdd: {
|
||||
helpBlocks: true
|
||||
},
|
||||
filter: function() {
|
||||
// return $(this).is(":visible"); // only validate elements you can see
|
||||
return true; // validate everything
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init: function(options) {
|
||||
|
||||
var settings = $.extend(true, {}, defaults);
|
||||
|
||||
settings.options = $.extend(true, settings.options, options);
|
||||
|
||||
var $siblingElements = this;
|
||||
|
||||
var uniqueForms = $.unique(
|
||||
$siblingElements.map(function() {
|
||||
return $(this).parents("form")[0];
|
||||
}).toArray()
|
||||
);
|
||||
|
||||
$(uniqueForms).bind("submit", function(e) {
|
||||
var $form = $(this);
|
||||
var warningsFound = 0;
|
||||
var $inputs = $form.find("input,textarea,select").not("[type=submit],[type=image]").filter(settings.options.filter);
|
||||
$inputs.trigger("submit.validation").trigger("validationLostFocus.validation");
|
||||
|
||||
$inputs.each(function(i, el) {
|
||||
var $this = $(el),
|
||||
$controlGroup = $this.parents(".form-group").first();
|
||||
if (
|
||||
$controlGroup.hasClass("warning")
|
||||
) {
|
||||
$controlGroup.removeClass("warning").addClass("error");
|
||||
warningsFound++;
|
||||
}
|
||||
});
|
||||
|
||||
$inputs.trigger("validationLostFocus.validation");
|
||||
|
||||
if (warningsFound) {
|
||||
if (settings.options.preventSubmit) {
|
||||
e.preventDefault();
|
||||
}
|
||||
$form.addClass("error");
|
||||
if ($.isFunction(settings.options.submitError)) {
|
||||
settings.options.submitError($form, e, $inputs.jqBootstrapValidation("collectErrors", true));
|
||||
}
|
||||
} else {
|
||||
$form.removeClass("error");
|
||||
if ($.isFunction(settings.options.submitSuccess)) {
|
||||
settings.options.submitSuccess($form, e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return this.each(function() {
|
||||
|
||||
// Get references to everything we're interested in
|
||||
var $this = $(this),
|
||||
$controlGroup = $this.parents(".form-group").first(),
|
||||
$helpBlock = $controlGroup.find(".help-block").first(),
|
||||
$form = $this.parents("form").first(),
|
||||
validatorNames = [];
|
||||
|
||||
// create message container if not exists
|
||||
if (!$helpBlock.length && settings.options.autoAdd && settings.options.autoAdd.helpBlocks) {
|
||||
$helpBlock = $('<div class="help-block" />');
|
||||
$controlGroup.find('.controls').append($helpBlock);
|
||||
createdElements.push($helpBlock[0]);
|
||||
}
|
||||
|
||||
// =============================================================
|
||||
// SNIFF HTML FOR VALIDATORS
|
||||
// =============================================================
|
||||
|
||||
// *snort sniff snuffle*
|
||||
|
||||
if (settings.options.sniffHtml) {
|
||||
var message = "";
|
||||
// ---------------------------------------------------------
|
||||
// PATTERN
|
||||
// ---------------------------------------------------------
|
||||
if ($this.attr("pattern") !== undefined) {
|
||||
message = "Not in the expected format<!-- data-validation-pattern-message to override -->";
|
||||
if ($this.data("validationPatternMessage")) {
|
||||
message = $this.data("validationPatternMessage");
|
||||
}
|
||||
$this.data("validationPatternMessage", message);
|
||||
$this.data("validationPatternRegex", $this.attr("pattern"));
|
||||
}
|
||||
// ---------------------------------------------------------
|
||||
// MAX
|
||||
// ---------------------------------------------------------
|
||||
if ($this.attr("max") !== undefined || $this.attr("aria-valuemax") !== undefined) {
|
||||
var max = ($this.attr("max") !== undefined ? $this.attr("max") : $this.attr("aria-valuemax"));
|
||||
message = "Too high: Maximum of '" + max + "'<!-- data-validation-max-message to override -->";
|
||||
if ($this.data("validationMaxMessage")) {
|
||||
message = $this.data("validationMaxMessage");
|
||||
}
|
||||
$this.data("validationMaxMessage", message);
|
||||
$this.data("validationMaxMax", max);
|
||||
}
|
||||
// ---------------------------------------------------------
|
||||
// MIN
|
||||
// ---------------------------------------------------------
|
||||
if ($this.attr("min") !== undefined || $this.attr("aria-valuemin") !== undefined) {
|
||||
var min = ($this.attr("min") !== undefined ? $this.attr("min") : $this.attr("aria-valuemin"));
|
||||
message = "Too low: Minimum of '" + min + "'<!-- data-validation-min-message to override -->";
|
||||
if ($this.data("validationMinMessage")) {
|
||||
message = $this.data("validationMinMessage");
|
||||
}
|
||||
$this.data("validationMinMessage", message);
|
||||
$this.data("validationMinMin", min);
|
||||
}
|
||||
// ---------------------------------------------------------
|
||||
// MAXLENGTH
|
||||
// ---------------------------------------------------------
|
||||
if ($this.attr("maxlength") !== undefined) {
|
||||
message = "Too long: Maximum of '" + $this.attr("maxlength") + "' characters<!-- data-validation-maxlength-message to override -->";
|
||||
if ($this.data("validationMaxlengthMessage")) {
|
||||
message = $this.data("validationMaxlengthMessage");
|
||||
}
|
||||
$this.data("validationMaxlengthMessage", message);
|
||||
$this.data("validationMaxlengthMaxlength", $this.attr("maxlength"));
|
||||
}
|
||||
// ---------------------------------------------------------
|
||||
// MINLENGTH
|
||||
// ---------------------------------------------------------
|
||||
if ($this.attr("minlength") !== undefined) {
|
||||
message = "Too short: Minimum of '" + $this.attr("minlength") + "' characters<!-- data-validation-minlength-message to override -->";
|
||||
if ($this.data("validationMinlengthMessage")) {
|
||||
message = $this.data("validationMinlengthMessage");
|
||||
}
|
||||
$this.data("validationMinlengthMessage", message);
|
||||
$this.data("validationMinlengthMinlength", $this.attr("minlength"));
|
||||
}
|
||||
// ---------------------------------------------------------
|
||||
// REQUIRED
|
||||
// ---------------------------------------------------------
|
||||
if ($this.attr("required") !== undefined || $this.attr("aria-required") !== undefined) {
|
||||
message = settings.builtInValidators.required.message;
|
||||
if ($this.data("validationRequiredMessage")) {
|
||||
message = $this.data("validationRequiredMessage");
|
||||
}
|
||||
$this.data("validationRequiredMessage", message);
|
||||
}
|
||||
// ---------------------------------------------------------
|
||||
// NUMBER
|
||||
// ---------------------------------------------------------
|
||||
if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "number") {
|
||||
message = settings.builtInValidators.number.message;
|
||||
if ($this.data("validationNumberMessage")) {
|
||||
message = $this.data("validationNumberMessage");
|
||||
}
|
||||
$this.data("validationNumberMessage", message);
|
||||
}
|
||||
// ---------------------------------------------------------
|
||||
// EMAIL
|
||||
// ---------------------------------------------------------
|
||||
if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "email") {
|
||||
message = "Not a valid email address<!-- data-validator-validemail-message to override -->";
|
||||
if ($this.data("validationValidemailMessage")) {
|
||||
message = $this.data("validationValidemailMessage");
|
||||
} else if ($this.data("validationEmailMessage")) {
|
||||
message = $this.data("validationEmailMessage");
|
||||
}
|
||||
$this.data("validationValidemailMessage", message);
|
||||
}
|
||||
// ---------------------------------------------------------
|
||||
// MINCHECKED
|
||||
// ---------------------------------------------------------
|
||||
if ($this.attr("minchecked") !== undefined) {
|
||||
message = "Not enough options checked; Minimum of '" + $this.attr("minchecked") + "' required<!-- data-validation-minchecked-message to override -->";
|
||||
if ($this.data("validationMincheckedMessage")) {
|
||||
message = $this.data("validationMincheckedMessage");
|
||||
}
|
||||
$this.data("validationMincheckedMessage", message);
|
||||
$this.data("validationMincheckedMinchecked", $this.attr("minchecked"));
|
||||
}
|
||||
// ---------------------------------------------------------
|
||||
// MAXCHECKED
|
||||
// ---------------------------------------------------------
|
||||
if ($this.attr("maxchecked") !== undefined) {
|
||||
message = "Too many options checked; Maximum of '" + $this.attr("maxchecked") + "' required<!-- data-validation-maxchecked-message to override -->";
|
||||
if ($this.data("validationMaxcheckedMessage")) {
|
||||
message = $this.data("validationMaxcheckedMessage");
|
||||
}
|
||||
$this.data("validationMaxcheckedMessage", message);
|
||||
$this.data("validationMaxcheckedMaxchecked", $this.attr("maxchecked"));
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================
|
||||
// COLLECT VALIDATOR NAMES
|
||||
// =============================================================
|
||||
|
||||
// Get named validators
|
||||
if ($this.data("validation") !== undefined) {
|
||||
validatorNames = $this.data("validation").split(",");
|
||||
}
|
||||
|
||||
// Get extra ones defined on the element's data attributes
|
||||
$.each($this.data(), function(i, el) {
|
||||
var parts = i.replace(/([A-Z])/g, ",$1").split(",");
|
||||
if (parts[0] === "validation" && parts[1]) {
|
||||
validatorNames.push(parts[1]);
|
||||
}
|
||||
});
|
||||
|
||||
// =============================================================
|
||||
// NORMALISE VALIDATOR NAMES
|
||||
// =============================================================
|
||||
|
||||
var validatorNamesToInspect = validatorNames;
|
||||
var newValidatorNamesToInspect = [];
|
||||
|
||||
do // repeatedly expand 'shortcut' validators into their real validators
|
||||
{
|
||||
// Uppercase only the first letter of each name
|
||||
$.each(validatorNames, function(i, el) {
|
||||
validatorNames[i] = formatValidatorName(el);
|
||||
});
|
||||
|
||||
// Remove duplicate validator names
|
||||
validatorNames = $.unique(validatorNames);
|
||||
|
||||
// Pull out the new validator names from each shortcut
|
||||
newValidatorNamesToInspect = [];
|
||||
$.each(validatorNamesToInspect, function(i, el) {
|
||||
if ($this.data("validation" + el + "Shortcut") !== undefined) {
|
||||
// Are these custom validators?
|
||||
// Pull them out!
|
||||
$.each($this.data("validation" + el + "Shortcut").split(","), function(i2, el2) {
|
||||
newValidatorNamesToInspect.push(el2);
|
||||
});
|
||||
} else if (settings.builtInValidators[el.toLowerCase()]) {
|
||||
// Is this a recognised built-in?
|
||||
// Pull it out!
|
||||
var validator = settings.builtInValidators[el.toLowerCase()];
|
||||
if (validator.type.toLowerCase() === "shortcut") {
|
||||
$.each(validator.shortcut.split(","), function(i, el) {
|
||||
el = formatValidatorName(el);
|
||||
newValidatorNamesToInspect.push(el);
|
||||
validatorNames.push(el);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
validatorNamesToInspect = newValidatorNamesToInspect;
|
||||
|
||||
} while (validatorNamesToInspect.length > 0)
|
||||
|
||||
// =============================================================
|
||||
// SET UP VALIDATOR ARRAYS
|
||||
// =============================================================
|
||||
|
||||
var validators = {};
|
||||
|
||||
$.each(validatorNames, function(i, el) {
|
||||
// Set up the 'override' message
|
||||
var message = $this.data("validation" + el + "Message");
|
||||
var hasOverrideMessage = (message !== undefined);
|
||||
var foundValidator = false;
|
||||
message =
|
||||
(
|
||||
message ?
|
||||
message :
|
||||
"'" + el + "' validation failed <!-- Add attribute 'data-validation-" + el.toLowerCase() + "-message' to input to change this message -->"
|
||||
);
|
||||
|
||||
$.each(
|
||||
settings.validatorTypes,
|
||||
function(validatorType, validatorTemplate) {
|
||||
if (validators[validatorType] === undefined) {
|
||||
validators[validatorType] = [];
|
||||
}
|
||||
if (!foundValidator && $this.data("validation" + el + formatValidatorName(validatorTemplate.name)) !== undefined) {
|
||||
validators[validatorType].push(
|
||||
$.extend(
|
||||
true, {
|
||||
name: formatValidatorName(validatorTemplate.name),
|
||||
message: message
|
||||
},
|
||||
validatorTemplate.init($this, el)
|
||||
)
|
||||
);
|
||||
foundValidator = true;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (!foundValidator && settings.builtInValidators[el.toLowerCase()]) {
|
||||
|
||||
var validator = $.extend(true, {}, settings.builtInValidators[el.toLowerCase()]);
|
||||
if (hasOverrideMessage) {
|
||||
validator.message = message;
|
||||
}
|
||||
var validatorType = validator.type.toLowerCase();
|
||||
|
||||
if (validatorType === "shortcut") {
|
||||
foundValidator = true;
|
||||
} else {
|
||||
$.each(
|
||||
settings.validatorTypes,
|
||||
function(validatorTemplateType, validatorTemplate) {
|
||||
if (validators[validatorTemplateType] === undefined) {
|
||||
validators[validatorTemplateType] = [];
|
||||
}
|
||||
if (!foundValidator && validatorType === validatorTemplateType.toLowerCase()) {
|
||||
$this.data("validation" + el + formatValidatorName(validatorTemplate.name), validator[validatorTemplate.name.toLowerCase()]);
|
||||
validators[validatorType].push(
|
||||
$.extend(
|
||||
validator,
|
||||
validatorTemplate.init($this, el)
|
||||
)
|
||||
);
|
||||
foundValidator = true;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundValidator) {
|
||||
$.error("Cannot find validation info for '" + el + "'");
|
||||
}
|
||||
});
|
||||
|
||||
// =============================================================
|
||||
// STORE FALLBACK VALUES
|
||||
// =============================================================
|
||||
|
||||
$helpBlock.data(
|
||||
"original-contents",
|
||||
(
|
||||
$helpBlock.data("original-contents") ?
|
||||
$helpBlock.data("original-contents") :
|
||||
$helpBlock.html()
|
||||
)
|
||||
);
|
||||
|
||||
$helpBlock.data(
|
||||
"original-role",
|
||||
(
|
||||
$helpBlock.data("original-role") ?
|
||||
$helpBlock.data("original-role") :
|
||||
$helpBlock.attr("role")
|
||||
)
|
||||
);
|
||||
|
||||
$controlGroup.data(
|
||||
"original-classes",
|
||||
(
|
||||
$controlGroup.data("original-clases") ?
|
||||
$controlGroup.data("original-classes") :
|
||||
$controlGroup.attr("class")
|
||||
)
|
||||
);
|
||||
|
||||
$this.data(
|
||||
"original-aria-invalid",
|
||||
(
|
||||
$this.data("original-aria-invalid") ?
|
||||
$this.data("original-aria-invalid") :
|
||||
$this.attr("aria-invalid")
|
||||
)
|
||||
);
|
||||
|
||||
// =============================================================
|
||||
// VALIDATION
|
||||
// =============================================================
|
||||
|
||||
$this.bind(
|
||||
"validation.validation",
|
||||
function(event, params) {
|
||||
|
||||
var value = getValue($this);
|
||||
|
||||
// Get a list of the errors to apply
|
||||
var errorsFound = [];
|
||||
|
||||
$.each(validators, function(validatorType, validatorTypeArray) {
|
||||
if (value || value.length || (params && params.includeEmpty) || (!!settings.validatorTypes[validatorType].blockSubmit && params && !!params.submitting)) {
|
||||
$.each(validatorTypeArray, function(i, validator) {
|
||||
if (settings.validatorTypes[validatorType].validate($this, value, validator)) {
|
||||
errorsFound.push(validator.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return errorsFound;
|
||||
}
|
||||
);
|
||||
|
||||
$this.bind(
|
||||
"getValidators.validation",
|
||||
function() {
|
||||
return validators;
|
||||
}
|
||||
);
|
||||
|
||||
// =============================================================
|
||||
// WATCH FOR CHANGES
|
||||
// =============================================================
|
||||
$this.bind(
|
||||
"submit.validation",
|
||||
function() {
|
||||
return $this.triggerHandler("change.validation", {
|
||||
submitting: true
|
||||
});
|
||||
}
|
||||
);
|
||||
$this.bind(
|
||||
[
|
||||
"keyup",
|
||||
"focus",
|
||||
"blur",
|
||||
"click",
|
||||
"keydown",
|
||||
"keypress",
|
||||
"change"
|
||||
].join(".validation ") + ".validation",
|
||||
function(e, params) {
|
||||
|
||||
var value = getValue($this);
|
||||
|
||||
var errorsFound = [];
|
||||
|
||||
$controlGroup.find("input,textarea,select").each(function(i, el) {
|
||||
var oldCount = errorsFound.length;
|
||||
$.each($(el).triggerHandler("validation.validation", params), function(j, message) {
|
||||
errorsFound.push(message);
|
||||
});
|
||||
if (errorsFound.length > oldCount) {
|
||||
$(el).attr("aria-invalid", "true");
|
||||
} else {
|
||||
var original = $this.data("original-aria-invalid");
|
||||
$(el).attr("aria-invalid", (original !== undefined ? original : false));
|
||||
}
|
||||
});
|
||||
|
||||
$form.find("input,select,textarea").not($this).not("[name=\"" + $this.attr("name") + "\"]").trigger("validationLostFocus.validation");
|
||||
|
||||
errorsFound = $.unique(errorsFound.sort());
|
||||
|
||||
// Were there any errors?
|
||||
if (errorsFound.length) {
|
||||
// Better flag it up as a warning.
|
||||
$controlGroup.removeClass("success error").addClass("warning");
|
||||
|
||||
// How many errors did we find?
|
||||
if (settings.options.semanticallyStrict && errorsFound.length === 1) {
|
||||
// Only one? Being strict? Just output it.
|
||||
$helpBlock.html(errorsFound[0] +
|
||||
(settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : ""));
|
||||
} else {
|
||||
// Multiple? Being sloppy? Glue them together into an UL.
|
||||
$helpBlock.html("<ul role=\"alert\"><li>" + errorsFound.join("</li><li>") + "</li></ul>" +
|
||||
(settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : ""));
|
||||
}
|
||||
} else {
|
||||
$controlGroup.removeClass("warning error success");
|
||||
if (value.length > 0) {
|
||||
$controlGroup.addClass("success");
|
||||
}
|
||||
$helpBlock.html($helpBlock.data("original-contents"));
|
||||
}
|
||||
|
||||
if (e.type === "blur") {
|
||||
$controlGroup.removeClass("success");
|
||||
}
|
||||
}
|
||||
);
|
||||
$this.bind("validationLostFocus.validation", function() {
|
||||
$controlGroup.removeClass("success");
|
||||
});
|
||||
});
|
||||
},
|
||||
destroy: function() {
|
||||
|
||||
return this.each(
|
||||
function() {
|
||||
|
||||
var
|
||||
$this = $(this),
|
||||
$controlGroup = $this.parents(".form-group").first(),
|
||||
$helpBlock = $controlGroup.find(".help-block").first();
|
||||
|
||||
// remove our events
|
||||
$this.unbind('.validation'); // events are namespaced.
|
||||
// reset help text
|
||||
$helpBlock.html($helpBlock.data("original-contents"));
|
||||
// reset classes
|
||||
$controlGroup.attr("class", $controlGroup.data("original-classes"));
|
||||
// reset aria
|
||||
$this.attr("aria-invalid", $this.data("original-aria-invalid"));
|
||||
// reset role
|
||||
$helpBlock.attr("role", $this.data("original-role"));
|
||||
// remove all elements we created
|
||||
if (createdElements.indexOf($helpBlock[0]) > -1) {
|
||||
$helpBlock.remove();
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
},
|
||||
collectErrors: function(includeEmpty) {
|
||||
|
||||
var errorMessages = {};
|
||||
this.each(function(i, el) {
|
||||
var $el = $(el);
|
||||
var name = $el.attr("name");
|
||||
var errors = $el.triggerHandler("validation.validation", {
|
||||
includeEmpty: true
|
||||
});
|
||||
errorMessages[name] = $.extend(true, errors, errorMessages[name]);
|
||||
});
|
||||
|
||||
$.each(errorMessages, function(i, el) {
|
||||
if (el.length === 0) {
|
||||
delete errorMessages[i];
|
||||
}
|
||||
});
|
||||
|
||||
return errorMessages;
|
||||
|
||||
},
|
||||
hasErrors: function() {
|
||||
|
||||
var errorMessages = [];
|
||||
|
||||
this.each(function(i, el) {
|
||||
errorMessages = errorMessages.concat(
|
||||
$(el).triggerHandler("getValidators.validation") ? $(el).triggerHandler("validation.validation", {
|
||||
submitting: true
|
||||
}) : []
|
||||
);
|
||||
});
|
||||
|
||||
return (errorMessages.length > 0);
|
||||
},
|
||||
override: function(newDefaults) {
|
||||
defaults = $.extend(true, defaults, newDefaults);
|
||||
}
|
||||
},
|
||||
validatorTypes: {
|
||||
callback: {
|
||||
name: "callback",
|
||||
init: function($this, name) {
|
||||
return {
|
||||
validatorName: name,
|
||||
callback: $this.data("validation" + name + "Callback"),
|
||||
lastValue: $this.val(),
|
||||
lastValid: true,
|
||||
lastFinished: true
|
||||
};
|
||||
},
|
||||
validate: function($this, value, validator) {
|
||||
if (validator.lastValue === value && validator.lastFinished) {
|
||||
return !validator.lastValid;
|
||||
}
|
||||
|
||||
if (validator.lastFinished === true) {
|
||||
validator.lastValue = value;
|
||||
validator.lastValid = true;
|
||||
validator.lastFinished = false;
|
||||
|
||||
var rrjqbvValidator = validator;
|
||||
var rrjqbvThis = $this;
|
||||
executeFunctionByName(
|
||||
validator.callback,
|
||||
window,
|
||||
$this,
|
||||
value,
|
||||
function(data) {
|
||||
if (rrjqbvValidator.lastValue === data.value) {
|
||||
rrjqbvValidator.lastValid = data.valid;
|
||||
if (data.message) {
|
||||
rrjqbvValidator.message = data.message;
|
||||
}
|
||||
rrjqbvValidator.lastFinished = true;
|
||||
rrjqbvThis.data("validation" + rrjqbvValidator.validatorName + "Message", rrjqbvValidator.message);
|
||||
// Timeout is set to avoid problems with the events being considered 'already fired'
|
||||
setTimeout(function() {
|
||||
rrjqbvThis.trigger("change.validation");
|
||||
}, 1); // doesn't need a long timeout, just long enough for the event bubble to burst
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
},
|
||||
ajax: {
|
||||
name: "ajax",
|
||||
init: function($this, name) {
|
||||
return {
|
||||
validatorName: name,
|
||||
url: $this.data("validation" + name + "Ajax"),
|
||||
lastValue: $this.val(),
|
||||
lastValid: true,
|
||||
lastFinished: true
|
||||
};
|
||||
},
|
||||
validate: function($this, value, validator) {
|
||||
if ("" + validator.lastValue === "" + value && validator.lastFinished === true) {
|
||||
return validator.lastValid === false;
|
||||
}
|
||||
|
||||
if (validator.lastFinished === true) {
|
||||
validator.lastValue = value;
|
||||
validator.lastValid = true;
|
||||
validator.lastFinished = false;
|
||||
$.ajax({
|
||||
url: validator.url,
|
||||
data: "value=" + value + "&field=" + $this.attr("name"),
|
||||
dataType: "json",
|
||||
success: function(data) {
|
||||
if ("" + validator.lastValue === "" + data.value) {
|
||||
validator.lastValid = !!(data.valid);
|
||||
if (data.message) {
|
||||
validator.message = data.message;
|
||||
}
|
||||
validator.lastFinished = true;
|
||||
$this.data("validation" + validator.validatorName + "Message", validator.message);
|
||||
// Timeout is set to avoid problems with the events being considered 'already fired'
|
||||
setTimeout(function() {
|
||||
$this.trigger("change.validation");
|
||||
}, 1); // doesn't need a long timeout, just long enough for the event bubble to burst
|
||||
}
|
||||
},
|
||||
failure: function() {
|
||||
validator.lastValid = true;
|
||||
validator.message = "ajax call failed";
|
||||
validator.lastFinished = true;
|
||||
$this.data("validation" + validator.validatorName + "Message", validator.message);
|
||||
// Timeout is set to avoid problems with the events being considered 'already fired'
|
||||
setTimeout(function() {
|
||||
$this.trigger("change.validation");
|
||||
}, 1); // doesn't need a long timeout, just long enough for the event bubble to burst
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
},
|
||||
regex: {
|
||||
name: "regex",
|
||||
init: function($this, name) {
|
||||
return {
|
||||
regex: regexFromString($this.data("validation" + name + "Regex"))
|
||||
};
|
||||
},
|
||||
validate: function($this, value, validator) {
|
||||
return (!validator.regex.test(value) && !validator.negative) ||
|
||||
(validator.regex.test(value) && validator.negative);
|
||||
}
|
||||
},
|
||||
required: {
|
||||
name: "required",
|
||||
init: function($this, name) {
|
||||
return {};
|
||||
},
|
||||
validate: function($this, value, validator) {
|
||||
return !!(value.length === 0 && !validator.negative) ||
|
||||
!!(value.length > 0 && validator.negative);
|
||||
},
|
||||
blockSubmit: true
|
||||
},
|
||||
match: {
|
||||
name: "match",
|
||||
init: function($this, name) {
|
||||
var element = $this.parents("form").first().find("[name=\"" + $this.data("validation" + name + "Match") + "\"]").first();
|
||||
element.bind("validation.validation", function() {
|
||||
$this.trigger("change.validation", {
|
||||
submitting: true
|
||||
});
|
||||
});
|
||||
return {
|
||||
"element": element
|
||||
};
|
||||
},
|
||||
validate: function($this, value, validator) {
|
||||
return (value !== validator.element.val() && !validator.negative) ||
|
||||
(value === validator.element.val() && validator.negative);
|
||||
},
|
||||
blockSubmit: true
|
||||
},
|
||||
max: {
|
||||
name: "max",
|
||||
init: function($this, name) {
|
||||
return {
|
||||
max: $this.data("validation" + name + "Max")
|
||||
};
|
||||
},
|
||||
validate: function($this, value, validator) {
|
||||
return (parseFloat(value, 10) > parseFloat(validator.max, 10) && !validator.negative) ||
|
||||
(parseFloat(value, 10) <= parseFloat(validator.max, 10) && validator.negative);
|
||||
}
|
||||
},
|
||||
min: {
|
||||
name: "min",
|
||||
init: function($this, name) {
|
||||
return {
|
||||
min: $this.data("validation" + name + "Min")
|
||||
};
|
||||
},
|
||||
validate: function($this, value, validator) {
|
||||
return (parseFloat(value) < parseFloat(validator.min) && !validator.negative) ||
|
||||
(parseFloat(value) >= parseFloat(validator.min) && validator.negative);
|
||||
}
|
||||
},
|
||||
maxlength: {
|
||||
name: "maxlength",
|
||||
init: function($this, name) {
|
||||
return {
|
||||
maxlength: $this.data("validation" + name + "Maxlength")
|
||||
};
|
||||
},
|
||||
validate: function($this, value, validator) {
|
||||
return ((value.length > validator.maxlength) && !validator.negative) ||
|
||||
((value.length <= validator.maxlength) && validator.negative);
|
||||
}
|
||||
},
|
||||
minlength: {
|
||||
name: "minlength",
|
||||
init: function($this, name) {
|
||||
return {
|
||||
minlength: $this.data("validation" + name + "Minlength")
|
||||
};
|
||||
},
|
||||
validate: function($this, value, validator) {
|
||||
return ((value.length < validator.minlength) && !validator.negative) ||
|
||||
((value.length >= validator.minlength) && validator.negative);
|
||||
}
|
||||
},
|
||||
maxchecked: {
|
||||
name: "maxchecked",
|
||||
init: function($this, name) {
|
||||
var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]");
|
||||
elements.bind("click.validation", function() {
|
||||
$this.trigger("change.validation", {
|
||||
includeEmpty: true
|
||||
});
|
||||
});
|
||||
return {
|
||||
maxchecked: $this.data("validation" + name + "Maxchecked"),
|
||||
elements: elements
|
||||
};
|
||||
},
|
||||
validate: function($this, value, validator) {
|
||||
return (validator.elements.filter(":checked").length > validator.maxchecked && !validator.negative) ||
|
||||
(validator.elements.filter(":checked").length <= validator.maxchecked && validator.negative);
|
||||
},
|
||||
blockSubmit: true
|
||||
},
|
||||
minchecked: {
|
||||
name: "minchecked",
|
||||
init: function($this, name) {
|
||||
var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]");
|
||||
elements.bind("click.validation", function() {
|
||||
$this.trigger("change.validation", {
|
||||
includeEmpty: true
|
||||
});
|
||||
});
|
||||
return {
|
||||
minchecked: $this.data("validation" + name + "Minchecked"),
|
||||
elements: elements
|
||||
};
|
||||
},
|
||||
validate: function($this, value, validator) {
|
||||
return (validator.elements.filter(":checked").length < validator.minchecked && !validator.negative) ||
|
||||
(validator.elements.filter(":checked").length >= validator.minchecked && validator.negative);
|
||||
},
|
||||
blockSubmit: true
|
||||
}
|
||||
},
|
||||
builtInValidators: {
|
||||
email: {
|
||||
name: "Email",
|
||||
type: "shortcut",
|
||||
shortcut: "validemail"
|
||||
},
|
||||
validemail: {
|
||||
name: "Validemail",
|
||||
type: "regex",
|
||||
regex: "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\.[A-Za-z]{2,4}",
|
||||
message: "Not a valid email address<!-- data-validator-validemail-message to override -->"
|
||||
},
|
||||
passwordagain: {
|
||||
name: "Passwordagain",
|
||||
type: "match",
|
||||
match: "password",
|
||||
message: "Does not match the given password<!-- data-validator-paswordagain-message to override -->"
|
||||
},
|
||||
positive: {
|
||||
name: "Positive",
|
||||
type: "shortcut",
|
||||
shortcut: "number,positivenumber"
|
||||
},
|
||||
negative: {
|
||||
name: "Negative",
|
||||
type: "shortcut",
|
||||
shortcut: "number,negativenumber"
|
||||
},
|
||||
number: {
|
||||
name: "Number",
|
||||
type: "regex",
|
||||
regex: "([+-]?\\\d+(\\\.\\\d*)?([eE][+-]?[0-9]+)?)?",
|
||||
message: "Must be a number<!-- data-validator-number-message to override -->"
|
||||
},
|
||||
integer: {
|
||||
name: "Integer",
|
||||
type: "regex",
|
||||
regex: "[+-]?\\\d+",
|
||||
message: "No decimal places allowed<!-- data-validator-integer-message to override -->"
|
||||
},
|
||||
positivenumber: {
|
||||
name: "Positivenumber",
|
||||
type: "min",
|
||||
min: 0,
|
||||
message: "Must be a positive number<!-- data-validator-positivenumber-message to override -->"
|
||||
},
|
||||
negativenumber: {
|
||||
name: "Negativenumber",
|
||||
type: "max",
|
||||
max: 0,
|
||||
message: "Must be a negative number<!-- data-validator-negativenumber-message to override -->"
|
||||
},
|
||||
required: {
|
||||
name: "Required",
|
||||
type: "required",
|
||||
message: "This is required<!-- data-validator-required-message to override -->"
|
||||
},
|
||||
checkone: {
|
||||
name: "Checkone",
|
||||
type: "minchecked",
|
||||
minchecked: 1,
|
||||
message: "Check at least one option<!-- data-validation-checkone-message to override -->"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var formatValidatorName = function(name) {
|
||||
return name
|
||||
.toLowerCase()
|
||||
.replace(
|
||||
/(^|\s)([a-z])/g,
|
||||
function(m, p1, p2) {
|
||||
return p1 + p2.toUpperCase();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
var getValue = function($this) {
|
||||
// Extract the value we're talking about
|
||||
var value = $this.val();
|
||||
var type = $this.attr("type");
|
||||
if (type === "checkbox") {
|
||||
value = ($this.is(":checked") ? value : "");
|
||||
}
|
||||
if (type === "radio") {
|
||||
value = ($('input[name="' + $this.attr("name") + '"]:checked').length > 0 ? value : "");
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
function regexFromString(inputstring) {
|
||||
return new RegExp("^" + inputstring + "$");
|
||||
}
|
||||
|
||||
/**
|
||||
* Thanks to Jason Bunting via StackOverflow.com
|
||||
*
|
||||
* http://stackoverflow.com/questions/359788/how-to-execute-a-javascript-function-when-i-have-its-name-as-a-string#answer-359910
|
||||
* Short link: http://tinyurl.com/executeFunctionByName
|
||||
**/
|
||||
function executeFunctionByName(functionName, context /*, args*/ ) {
|
||||
var args = Array.prototype.slice.call(arguments).splice(2);
|
||||
var namespaces = functionName.split(".");
|
||||
var func = namespaces.pop();
|
||||
for (var i = 0; i < namespaces.length; i++) {
|
||||
context = context[namespaces[i]];
|
||||
}
|
||||
return context[func].apply(this, args);
|
||||
}
|
||||
|
||||
$.fn.jqBootstrapValidation = function(method) {
|
||||
|
||||
if (defaults.methods[method]) {
|
||||
return defaults.methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
||||
} else if (typeof method === 'object' || !method) {
|
||||
return defaults.methods.init.apply(this, arguments);
|
||||
} else {
|
||||
$.error('Method ' + method + ' does not exist on jQuery.jqBootstrapValidation');
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$.jqBootstrapValidation = function(options) {
|
||||
$(":input").not("[type=image],[type=submit]").jqBootstrapValidation.apply(this, arguments);
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
Binary file not shown.
10254
public/assets/jquery-06c43429d1047ce3f355da574d8a9750209971b8b1b8f264f91f5518c5fcc060.js
vendored
Normal file
10254
public/assets/jquery-06c43429d1047ce3f355da574d8a9750209971b8b1b8f264f91f5518c5fcc060.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
694
public/assets/jquery-sortable-9171d22af575ea4a1a1c7199d810c1184a904047992596dc7b9ea74251ed7962.js
vendored
Normal file
694
public/assets/jquery-sortable-9171d22af575ea4a1a1c7199d810c1184a904047992596dc7b9ea74251ed7962.js
vendored
Normal file
|
|
@ -0,0 +1,694 @@
|
|||
/* ===================================================
|
||||
* jquery-sortable.js v0.9.13
|
||||
* http://johnny.github.com/jquery-sortable/
|
||||
* ===================================================
|
||||
* Copyright (c) 2012 Jonas von Andrian
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ========================================================== */
|
||||
|
||||
|
||||
|
||||
!function ( $, window, pluginName, undefined){
|
||||
var containerDefaults = {
|
||||
// If true, items can be dragged from this container
|
||||
drag: true,
|
||||
// If true, items can be droped onto this container
|
||||
drop: true,
|
||||
// Exclude items from being draggable, if the
|
||||
// selector matches the item
|
||||
exclude: "",
|
||||
// If true, search for nested containers within an item.If you nest containers,
|
||||
// either the original selector with which you call the plugin must only match the top containers,
|
||||
// or you need to specify a group (see the bootstrap nav example)
|
||||
nested: true,
|
||||
// If true, the items are assumed to be arranged vertically
|
||||
vertical: true
|
||||
}, // end container defaults
|
||||
groupDefaults = {
|
||||
// This is executed after the placeholder has been moved.
|
||||
// $closestItemOrContainer contains the closest item, the placeholder
|
||||
// has been put at or the closest empty Container, the placeholder has
|
||||
// been appended to.
|
||||
afterMove: function ($placeholder, container, $closestItemOrContainer) {
|
||||
},
|
||||
// The exact css path between the container and its items, e.g. "> tbody"
|
||||
containerPath: "",
|
||||
// The css selector of the containers
|
||||
containerSelector: "ol, ul",
|
||||
// Distance the mouse has to travel to start dragging
|
||||
distance: 0,
|
||||
// Time in milliseconds after mousedown until dragging should start.
|
||||
// This option can be used to prevent unwanted drags when clicking on an element.
|
||||
delay: 0,
|
||||
// The css selector of the drag handle
|
||||
handle: "",
|
||||
// The exact css path between the item and its subcontainers.
|
||||
// It should only match the immediate items of a container.
|
||||
// No item of a subcontainer should be matched. E.g. for ol>div>li the itemPath is "> div"
|
||||
itemPath: "",
|
||||
// The css selector of the items
|
||||
itemSelector: "li",
|
||||
// The class given to "body" while an item is being dragged
|
||||
bodyClass: "dragging",
|
||||
// The class giving to an item while being dragged
|
||||
draggedClass: "dragged",
|
||||
// Check if the dragged item may be inside the container.
|
||||
// Use with care, since the search for a valid container entails a depth first search
|
||||
// and may be quite expensive.
|
||||
isValidTarget: function ($item, container) {
|
||||
return true
|
||||
},
|
||||
// Executed before onDrop if placeholder is detached.
|
||||
// This happens if pullPlaceholder is set to false and the drop occurs outside a container.
|
||||
onCancel: function ($item, container, _super, event) {
|
||||
},
|
||||
// Executed at the beginning of a mouse move event.
|
||||
// The Placeholder has not been moved yet.
|
||||
onDrag: function ($item, position, _super, event) {
|
||||
$item.css(position)
|
||||
},
|
||||
// Called after the drag has been started,
|
||||
// that is the mouse button is being held down and
|
||||
// the mouse is moving.
|
||||
// The container is the closest initialized container.
|
||||
// Therefore it might not be the container, that actually contains the item.
|
||||
onDragStart: function ($item, container, _super, event) {
|
||||
$item.css({
|
||||
height: $item.outerHeight(),
|
||||
width: $item.outerWidth()
|
||||
})
|
||||
$item.addClass(container.group.options.draggedClass)
|
||||
$("body").addClass(container.group.options.bodyClass)
|
||||
},
|
||||
// Called when the mouse button is being released
|
||||
onDrop: function ($item, container, _super, event) {
|
||||
$item.removeClass(container.group.options.draggedClass).removeAttr("style")
|
||||
$("body").removeClass(container.group.options.bodyClass)
|
||||
},
|
||||
// Called on mousedown. If falsy value is returned, the dragging will not start.
|
||||
// Ignore if element clicked is input, select or textarea
|
||||
onMousedown: function ($item, _super, event) {
|
||||
if (!event.target.nodeName.match(/^(input|select|textarea)$/i)) {
|
||||
event.preventDefault()
|
||||
return true
|
||||
}
|
||||
},
|
||||
// The class of the placeholder (must match placeholder option markup)
|
||||
placeholderClass: "placeholder",
|
||||
// Template for the placeholder. Can be any valid jQuery input
|
||||
// e.g. a string, a DOM element.
|
||||
// The placeholder must have the class "placeholder"
|
||||
placeholder: '<li class="placeholder"></li>',
|
||||
// If true, the position of the placeholder is calculated on every mousemove.
|
||||
// If false, it is only calculated when the mouse is above a container.
|
||||
pullPlaceholder: true,
|
||||
// Specifies serialization of the container group.
|
||||
// The pair $parent/$children is either container/items or item/subcontainers.
|
||||
serialize: function ($parent, $children, parentIsContainer) {
|
||||
var result = $.extend({}, $parent.data())
|
||||
|
||||
if(parentIsContainer)
|
||||
return [$children]
|
||||
else if ($children[0]){
|
||||
result.children = $children
|
||||
}
|
||||
|
||||
delete result.subContainers
|
||||
delete result.sortable
|
||||
|
||||
return result
|
||||
},
|
||||
// Set tolerance while dragging. Positive values decrease sensitivity,
|
||||
// negative values increase it.
|
||||
tolerance: 0
|
||||
}, // end group defaults
|
||||
containerGroups = {},
|
||||
groupCounter = 0,
|
||||
emptyBox = {
|
||||
left: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
right:0
|
||||
},
|
||||
eventNames = {
|
||||
start: "touchstart.sortable mousedown.sortable",
|
||||
drop: "touchend.sortable touchcancel.sortable mouseup.sortable",
|
||||
drag: "touchmove.sortable mousemove.sortable",
|
||||
scroll: "scroll.sortable"
|
||||
},
|
||||
subContainerKey = "subContainers"
|
||||
|
||||
/*
|
||||
* a is Array [left, right, top, bottom]
|
||||
* b is array [left, top]
|
||||
*/
|
||||
function d(a,b) {
|
||||
var x = Math.max(0, a[0] - b[0], b[0] - a[1]),
|
||||
y = Math.max(0, a[2] - b[1], b[1] - a[3])
|
||||
return x+y;
|
||||
}
|
||||
|
||||
function setDimensions(array, dimensions, tolerance, useOffset) {
|
||||
var i = array.length,
|
||||
offsetMethod = useOffset ? "offset" : "position"
|
||||
tolerance = tolerance || 0
|
||||
|
||||
while(i--){
|
||||
var el = array[i].el ? array[i].el : $(array[i]),
|
||||
// use fitting method
|
||||
pos = el[offsetMethod]()
|
||||
pos.left += parseInt(el.css('margin-left'), 10)
|
||||
pos.top += parseInt(el.css('margin-top'),10)
|
||||
dimensions[i] = [
|
||||
pos.left - tolerance,
|
||||
pos.left + el.outerWidth() + tolerance,
|
||||
pos.top - tolerance,
|
||||
pos.top + el.outerHeight() + tolerance
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
function getRelativePosition(pointer, element) {
|
||||
var offset = element.offset()
|
||||
return {
|
||||
left: pointer.left - offset.left,
|
||||
top: pointer.top - offset.top
|
||||
}
|
||||
}
|
||||
|
||||
function sortByDistanceDesc(dimensions, pointer, lastPointer) {
|
||||
pointer = [pointer.left, pointer.top]
|
||||
lastPointer = lastPointer && [lastPointer.left, lastPointer.top]
|
||||
|
||||
var dim,
|
||||
i = dimensions.length,
|
||||
distances = []
|
||||
|
||||
while(i--){
|
||||
dim = dimensions[i]
|
||||
distances[i] = [i,d(dim,pointer), lastPointer && d(dim, lastPointer)]
|
||||
}
|
||||
distances = distances.sort(function (a,b) {
|
||||
return b[1] - a[1] || b[2] - a[2] || b[0] - a[0]
|
||||
})
|
||||
|
||||
// last entry is the closest
|
||||
return distances
|
||||
}
|
||||
|
||||
function ContainerGroup(options) {
|
||||
this.options = $.extend({}, groupDefaults, options)
|
||||
this.containers = []
|
||||
|
||||
if(!this.options.rootGroup){
|
||||
this.scrollProxy = $.proxy(this.scroll, this)
|
||||
this.dragProxy = $.proxy(this.drag, this)
|
||||
this.dropProxy = $.proxy(this.drop, this)
|
||||
this.placeholder = $(this.options.placeholder)
|
||||
|
||||
if(!options.isValidTarget)
|
||||
this.options.isValidTarget = undefined
|
||||
}
|
||||
}
|
||||
|
||||
ContainerGroup.get = function (options) {
|
||||
if(!containerGroups[options.group]) {
|
||||
if(options.group === undefined)
|
||||
options.group = groupCounter ++
|
||||
|
||||
containerGroups[options.group] = new ContainerGroup(options)
|
||||
}
|
||||
|
||||
return containerGroups[options.group]
|
||||
}
|
||||
|
||||
ContainerGroup.prototype = {
|
||||
dragInit: function (e, itemContainer) {
|
||||
this.$document = $(itemContainer.el[0].ownerDocument)
|
||||
|
||||
// get item to drag
|
||||
var closestItem = $(e.target).closest(this.options.itemSelector);
|
||||
// using the length of this item, prevents the plugin from being started if there is no handle being clicked on.
|
||||
// this may also be helpful in instantiating multidrag.
|
||||
if (closestItem.length) {
|
||||
this.item = closestItem;
|
||||
this.itemContainer = itemContainer;
|
||||
if (this.item.is(this.options.exclude) || !this.options.onMousedown(this.item, groupDefaults.onMousedown, e)) {
|
||||
return;
|
||||
}
|
||||
this.setPointer(e);
|
||||
this.toggleListeners('on');
|
||||
this.setupDelayTimer();
|
||||
this.dragInitDone = true;
|
||||
}
|
||||
},
|
||||
drag: function (e) {
|
||||
if(!this.dragging){
|
||||
if(!this.distanceMet(e) || !this.delayMet)
|
||||
return
|
||||
|
||||
this.options.onDragStart(this.item, this.itemContainer, groupDefaults.onDragStart, e)
|
||||
this.item.before(this.placeholder)
|
||||
this.dragging = true
|
||||
}
|
||||
|
||||
this.setPointer(e)
|
||||
// place item under the cursor
|
||||
this.options.onDrag(this.item,
|
||||
getRelativePosition(this.pointer, this.item.offsetParent()),
|
||||
groupDefaults.onDrag,
|
||||
e)
|
||||
|
||||
var p = this.getPointer(e),
|
||||
box = this.sameResultBox,
|
||||
t = this.options.tolerance
|
||||
|
||||
if(!box || box.top - t > p.top || box.bottom + t < p.top || box.left - t > p.left || box.right + t < p.left)
|
||||
if(!this.searchValidTarget()){
|
||||
this.placeholder.detach()
|
||||
this.lastAppendedItem = undefined
|
||||
}
|
||||
},
|
||||
drop: function (e) {
|
||||
this.toggleListeners('off')
|
||||
|
||||
this.dragInitDone = false
|
||||
|
||||
if(this.dragging){
|
||||
// processing Drop, check if placeholder is detached
|
||||
if(this.placeholder.closest("html")[0]){
|
||||
this.placeholder.before(this.item).detach()
|
||||
} else {
|
||||
this.options.onCancel(this.item, this.itemContainer, groupDefaults.onCancel, e)
|
||||
}
|
||||
this.options.onDrop(this.item, this.getContainer(this.item), groupDefaults.onDrop, e)
|
||||
|
||||
// cleanup
|
||||
this.clearDimensions()
|
||||
this.clearOffsetParent()
|
||||
this.lastAppendedItem = this.sameResultBox = undefined
|
||||
this.dragging = false
|
||||
}
|
||||
},
|
||||
searchValidTarget: function (pointer, lastPointer) {
|
||||
if(!pointer){
|
||||
pointer = this.relativePointer || this.pointer
|
||||
lastPointer = this.lastRelativePointer || this.lastPointer
|
||||
}
|
||||
|
||||
var distances = sortByDistanceDesc(this.getContainerDimensions(),
|
||||
pointer,
|
||||
lastPointer),
|
||||
i = distances.length
|
||||
|
||||
while(i--){
|
||||
var index = distances[i][0],
|
||||
distance = distances[i][1]
|
||||
|
||||
if(!distance || this.options.pullPlaceholder){
|
||||
var container = this.containers[index]
|
||||
if(!container.disabled){
|
||||
if(!this.$getOffsetParent()){
|
||||
var offsetParent = container.getItemOffsetParent()
|
||||
pointer = getRelativePosition(pointer, offsetParent)
|
||||
lastPointer = getRelativePosition(lastPointer, offsetParent)
|
||||
}
|
||||
if(container.searchValidTarget(pointer, lastPointer))
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
if(this.sameResultBox)
|
||||
this.sameResultBox = undefined
|
||||
},
|
||||
movePlaceholder: function (container, item, method, sameResultBox) {
|
||||
var lastAppendedItem = this.lastAppendedItem
|
||||
if(!sameResultBox && lastAppendedItem && lastAppendedItem[0] === item[0])
|
||||
return;
|
||||
|
||||
item[method](this.placeholder)
|
||||
this.lastAppendedItem = item
|
||||
this.sameResultBox = sameResultBox
|
||||
this.options.afterMove(this.placeholder, container, item)
|
||||
},
|
||||
getContainerDimensions: function () {
|
||||
if(!this.containerDimensions)
|
||||
setDimensions(this.containers, this.containerDimensions = [], this.options.tolerance, !this.$getOffsetParent())
|
||||
return this.containerDimensions
|
||||
},
|
||||
getContainer: function (element) {
|
||||
return element.closest(this.options.containerSelector).data(pluginName)
|
||||
},
|
||||
$getOffsetParent: function () {
|
||||
if(this.offsetParent === undefined){
|
||||
var i = this.containers.length - 1,
|
||||
offsetParent = this.containers[i].getItemOffsetParent()
|
||||
|
||||
if(!this.options.rootGroup){
|
||||
while(i--){
|
||||
if(offsetParent[0] != this.containers[i].getItemOffsetParent()[0]){
|
||||
// If every container has the same offset parent,
|
||||
// use position() which is relative to this parent,
|
||||
// otherwise use offset()
|
||||
// compare #setDimensions
|
||||
offsetParent = false
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.offsetParent = offsetParent
|
||||
}
|
||||
return this.offsetParent
|
||||
},
|
||||
setPointer: function (e) {
|
||||
var pointer = this.getPointer(e)
|
||||
|
||||
if(this.$getOffsetParent()){
|
||||
var relativePointer = getRelativePosition(pointer, this.$getOffsetParent())
|
||||
this.lastRelativePointer = this.relativePointer
|
||||
this.relativePointer = relativePointer
|
||||
}
|
||||
|
||||
this.lastPointer = this.pointer
|
||||
this.pointer = pointer
|
||||
},
|
||||
distanceMet: function (e) {
|
||||
var currentPointer = this.getPointer(e)
|
||||
return (Math.max(
|
||||
Math.abs(this.pointer.left - currentPointer.left),
|
||||
Math.abs(this.pointer.top - currentPointer.top)
|
||||
) >= this.options.distance)
|
||||
},
|
||||
getPointer: function(e) {
|
||||
var o = e.originalEvent || e.originalEvent.touches && e.originalEvent.touches[0]
|
||||
return {
|
||||
left: e.pageX || o.pageX,
|
||||
top: e.pageY || o.pageY
|
||||
}
|
||||
},
|
||||
setupDelayTimer: function () {
|
||||
var that = this
|
||||
this.delayMet = !this.options.delay
|
||||
|
||||
// init delay timer if needed
|
||||
if (!this.delayMet) {
|
||||
clearTimeout(this._mouseDelayTimer);
|
||||
this._mouseDelayTimer = setTimeout(function() {
|
||||
that.delayMet = true
|
||||
}, this.options.delay)
|
||||
}
|
||||
},
|
||||
scroll: function (e) {
|
||||
this.clearDimensions()
|
||||
this.clearOffsetParent() // TODO is this needed?
|
||||
},
|
||||
toggleListeners: function (method) {
|
||||
var that = this,
|
||||
events = ['drag','drop','scroll']
|
||||
|
||||
$.each(events,function (i,event) {
|
||||
that.$document[method](eventNames[event], that[event + 'Proxy'])
|
||||
})
|
||||
},
|
||||
clearOffsetParent: function () {
|
||||
this.offsetParent = undefined
|
||||
},
|
||||
// Recursively clear container and item dimensions
|
||||
clearDimensions: function () {
|
||||
this.traverse(function(object){
|
||||
object._clearDimensions()
|
||||
})
|
||||
},
|
||||
traverse: function(callback) {
|
||||
callback(this)
|
||||
var i = this.containers.length
|
||||
while(i--){
|
||||
this.containers[i].traverse(callback)
|
||||
}
|
||||
},
|
||||
_clearDimensions: function(){
|
||||
this.containerDimensions = undefined
|
||||
},
|
||||
_destroy: function () {
|
||||
containerGroups[this.options.group] = undefined
|
||||
}
|
||||
}
|
||||
|
||||
function Container(element, options) {
|
||||
this.el = element
|
||||
this.options = $.extend( {}, containerDefaults, options)
|
||||
|
||||
this.group = ContainerGroup.get(this.options)
|
||||
this.rootGroup = this.options.rootGroup || this.group
|
||||
this.handle = this.rootGroup.options.handle || this.rootGroup.options.itemSelector
|
||||
|
||||
var itemPath = this.rootGroup.options.itemPath
|
||||
this.target = itemPath ? this.el.find(itemPath) : this.el
|
||||
|
||||
this.target.on(eventNames.start, this.handle, $.proxy(this.dragInit, this))
|
||||
|
||||
if(this.options.drop)
|
||||
this.group.containers.push(this)
|
||||
}
|
||||
|
||||
Container.prototype = {
|
||||
dragInit: function (e) {
|
||||
var rootGroup = this.rootGroup
|
||||
|
||||
if( !this.disabled &&
|
||||
!rootGroup.dragInitDone &&
|
||||
this.options.drag &&
|
||||
this.isValidDrag(e)) {
|
||||
rootGroup.dragInit(e, this)
|
||||
}
|
||||
},
|
||||
isValidDrag: function(e) {
|
||||
return e.which == 1 ||
|
||||
e.type == "touchstart" && e.originalEvent.touches.length == 1
|
||||
},
|
||||
searchValidTarget: function (pointer, lastPointer) {
|
||||
var distances = sortByDistanceDesc(this.getItemDimensions(),
|
||||
pointer,
|
||||
lastPointer),
|
||||
i = distances.length,
|
||||
rootGroup = this.rootGroup,
|
||||
validTarget = !rootGroup.options.isValidTarget ||
|
||||
rootGroup.options.isValidTarget(rootGroup.item, this)
|
||||
|
||||
if(!i && validTarget){
|
||||
rootGroup.movePlaceholder(this, this.target, "append")
|
||||
return true
|
||||
} else
|
||||
while(i--){
|
||||
var index = distances[i][0],
|
||||
distance = distances[i][1]
|
||||
if(!distance && this.hasChildGroup(index)){
|
||||
var found = this.getContainerGroup(index).searchValidTarget(pointer, lastPointer)
|
||||
if(found)
|
||||
return true
|
||||
}
|
||||
else if(validTarget){
|
||||
this.movePlaceholder(index, pointer)
|
||||
return true
|
||||
}
|
||||
}
|
||||
},
|
||||
movePlaceholder: function (index, pointer) {
|
||||
var item = $(this.items[index]),
|
||||
dim = this.itemDimensions[index],
|
||||
method = "after",
|
||||
width = item.outerWidth(),
|
||||
height = item.outerHeight(),
|
||||
offset = item.offset(),
|
||||
sameResultBox = {
|
||||
left: offset.left,
|
||||
right: offset.left + width,
|
||||
top: offset.top,
|
||||
bottom: offset.top + height
|
||||
}
|
||||
if(this.options.vertical){
|
||||
var yCenter = (dim[2] + dim[3]) / 2,
|
||||
inUpperHalf = pointer.top <= yCenter
|
||||
if(inUpperHalf){
|
||||
method = "before"
|
||||
sameResultBox.bottom -= height / 2
|
||||
} else
|
||||
sameResultBox.top += height / 2
|
||||
} else {
|
||||
var xCenter = (dim[0] + dim[1]) / 2,
|
||||
inLeftHalf = pointer.left <= xCenter
|
||||
if(inLeftHalf){
|
||||
method = "before"
|
||||
sameResultBox.right -= width / 2
|
||||
} else
|
||||
sameResultBox.left += width / 2
|
||||
}
|
||||
if(this.hasChildGroup(index))
|
||||
sameResultBox = emptyBox
|
||||
this.rootGroup.movePlaceholder(this, item, method, sameResultBox)
|
||||
},
|
||||
getItemDimensions: function () {
|
||||
if(!this.itemDimensions){
|
||||
this.items = this.$getChildren(this.el, "item").filter(
|
||||
":not(." + this.group.options.placeholderClass + ", ." + this.group.options.draggedClass + ")"
|
||||
).get()
|
||||
setDimensions(this.items, this.itemDimensions = [], this.options.tolerance)
|
||||
}
|
||||
return this.itemDimensions
|
||||
},
|
||||
getItemOffsetParent: function () {
|
||||
var offsetParent,
|
||||
el = this.el
|
||||
// Since el might be empty we have to check el itself and
|
||||
// can not do something like el.children().first().offsetParent()
|
||||
if(el.css("position") === "relative" || el.css("position") === "absolute" || el.css("position") === "fixed")
|
||||
offsetParent = el
|
||||
else
|
||||
offsetParent = el.offsetParent()
|
||||
return offsetParent
|
||||
},
|
||||
hasChildGroup: function (index) {
|
||||
return this.options.nested && this.getContainerGroup(index)
|
||||
},
|
||||
getContainerGroup: function (index) {
|
||||
var childGroup = $.data(this.items[index], subContainerKey)
|
||||
if( childGroup === undefined){
|
||||
var childContainers = this.$getChildren(this.items[index], "container")
|
||||
childGroup = false
|
||||
|
||||
if(childContainers[0]){
|
||||
var options = $.extend({}, this.options, {
|
||||
rootGroup: this.rootGroup,
|
||||
group: groupCounter ++
|
||||
})
|
||||
childGroup = childContainers[pluginName](options).data(pluginName).group
|
||||
}
|
||||
$.data(this.items[index], subContainerKey, childGroup)
|
||||
}
|
||||
return childGroup
|
||||
},
|
||||
$getChildren: function (parent, type) {
|
||||
var options = this.rootGroup.options,
|
||||
path = options[type + "Path"],
|
||||
selector = options[type + "Selector"]
|
||||
|
||||
parent = $(parent)
|
||||
if(path)
|
||||
parent = parent.find(path)
|
||||
|
||||
return parent.children(selector)
|
||||
},
|
||||
_serialize: function (parent, isContainer) {
|
||||
var that = this,
|
||||
childType = isContainer ? "item" : "container",
|
||||
|
||||
children = this.$getChildren(parent, childType).not(this.options.exclude).map(function () {
|
||||
return that._serialize($(this), !isContainer)
|
||||
}).get()
|
||||
|
||||
return this.rootGroup.options.serialize(parent, children, isContainer)
|
||||
},
|
||||
traverse: function(callback) {
|
||||
$.each(this.items || [], function(item){
|
||||
var group = $.data(this, subContainerKey)
|
||||
if(group)
|
||||
group.traverse(callback)
|
||||
});
|
||||
|
||||
callback(this)
|
||||
},
|
||||
_clearDimensions: function () {
|
||||
this.itemDimensions = undefined
|
||||
},
|
||||
_destroy: function() {
|
||||
var that = this;
|
||||
|
||||
this.target.off(eventNames.start, this.handle);
|
||||
this.el.removeData(pluginName)
|
||||
|
||||
if(this.options.drop)
|
||||
this.group.containers = $.grep(this.group.containers, function(val){
|
||||
return val != that
|
||||
})
|
||||
|
||||
$.each(this.items || [], function(){
|
||||
$.removeData(this, subContainerKey)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var API = {
|
||||
enable: function() {
|
||||
this.traverse(function(object){
|
||||
object.disabled = false
|
||||
})
|
||||
},
|
||||
disable: function (){
|
||||
this.traverse(function(object){
|
||||
object.disabled = true
|
||||
})
|
||||
},
|
||||
serialize: function () {
|
||||
return this._serialize(this.el, true)
|
||||
},
|
||||
refresh: function() {
|
||||
this.traverse(function(object){
|
||||
object._clearDimensions()
|
||||
})
|
||||
},
|
||||
destroy: function () {
|
||||
this.traverse(function(object){
|
||||
object._destroy();
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
$.extend(Container.prototype, API)
|
||||
|
||||
/**
|
||||
* jQuery API
|
||||
*
|
||||
* Parameters are
|
||||
* either options on init
|
||||
* or a method name followed by arguments to pass to the method
|
||||
*/
|
||||
$.fn[pluginName] = function(methodOrOptions) {
|
||||
var args = Array.prototype.slice.call(arguments, 1)
|
||||
|
||||
return this.map(function(){
|
||||
var $t = $(this),
|
||||
object = $t.data(pluginName)
|
||||
|
||||
if(object && API[methodOrOptions])
|
||||
return API[methodOrOptions].apply(object, args) || this
|
||||
else if(!object && (methodOrOptions === undefined ||
|
||||
typeof methodOrOptions === "object"))
|
||||
$t.data(pluginName, new Container($t, methodOrOptions))
|
||||
|
||||
return this
|
||||
});
|
||||
};
|
||||
|
||||
}(jQuery, window, 'sortable');
|
||||
Binary file not shown.
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* jQuery Easing v1.4.1 - http://gsgd.co.uk/sandbox/jquery/easing/
|
||||
* Open source under the BSD License.
|
||||
* Copyright © 2008 George McGinley Smith
|
||||
* All rights reserved.
|
||||
* https://raw.github.com/gdsmith/jquery-easing/master/LICENSE
|
||||
*/
|
||||
|
||||
|
||||
(function (factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define(['jquery'], function ($) {
|
||||
return factory($);
|
||||
});
|
||||
} else if (typeof module === "object" && typeof module.exports === "object") {
|
||||
exports = factory(require('jquery'));
|
||||
} else {
|
||||
factory(jQuery);
|
||||
}
|
||||
})(function($){
|
||||
|
||||
// Preserve the original jQuery "swing" easing as "jswing"
|
||||
$.easing.jswing = $.easing.swing;
|
||||
|
||||
var pow = Math.pow,
|
||||
sqrt = Math.sqrt,
|
||||
sin = Math.sin,
|
||||
cos = Math.cos,
|
||||
PI = Math.PI,
|
||||
c1 = 1.70158,
|
||||
c2 = c1 * 1.525,
|
||||
c3 = c1 + 1,
|
||||
c4 = ( 2 * PI ) / 3,
|
||||
c5 = ( 2 * PI ) / 4.5;
|
||||
|
||||
// x is the fraction of animation progress, in the range 0..1
|
||||
function bounceOut(x) {
|
||||
var n1 = 7.5625,
|
||||
d1 = 2.75;
|
||||
if ( x < 1/d1 ) {
|
||||
return n1*x*x;
|
||||
} else if ( x < 2/d1 ) {
|
||||
return n1*(x-=(1.5/d1))*x + 0.75;
|
||||
} else if ( x < 2.5/d1 ) {
|
||||
return n1*(x-=(2.25/d1))*x + 0.9375;
|
||||
} else {
|
||||
return n1*(x-=(2.625/d1))*x + 0.984375;
|
||||
}
|
||||
}
|
||||
|
||||
$.extend( $.easing,
|
||||
{
|
||||
def: 'easeOutQuad',
|
||||
swing: function (x) {
|
||||
return $.easing[$.easing.def](x);
|
||||
},
|
||||
easeInQuad: function (x) {
|
||||
return x * x;
|
||||
},
|
||||
easeOutQuad: function (x) {
|
||||
return 1 - ( 1 - x ) * ( 1 - x );
|
||||
},
|
||||
easeInOutQuad: function (x) {
|
||||
return x < 0.5 ?
|
||||
2 * x * x :
|
||||
1 - pow( -2 * x + 2, 2 ) / 2;
|
||||
},
|
||||
easeInCubic: function (x) {
|
||||
return x * x * x;
|
||||
},
|
||||
easeOutCubic: function (x) {
|
||||
return 1 - pow( 1 - x, 3 );
|
||||
},
|
||||
easeInOutCubic: function (x) {
|
||||
return x < 0.5 ?
|
||||
4 * x * x * x :
|
||||
1 - pow( -2 * x + 2, 3 ) / 2;
|
||||
},
|
||||
easeInQuart: function (x) {
|
||||
return x * x * x * x;
|
||||
},
|
||||
easeOutQuart: function (x) {
|
||||
return 1 - pow( 1 - x, 4 );
|
||||
},
|
||||
easeInOutQuart: function (x) {
|
||||
return x < 0.5 ?
|
||||
8 * x * x * x * x :
|
||||
1 - pow( -2 * x + 2, 4 ) / 2;
|
||||
},
|
||||
easeInQuint: function (x) {
|
||||
return x * x * x * x * x;
|
||||
},
|
||||
easeOutQuint: function (x) {
|
||||
return 1 - pow( 1 - x, 5 );
|
||||
},
|
||||
easeInOutQuint: function (x) {
|
||||
return x < 0.5 ?
|
||||
16 * x * x * x * x * x :
|
||||
1 - pow( -2 * x + 2, 5 ) / 2;
|
||||
},
|
||||
easeInSine: function (x) {
|
||||
return 1 - cos( x * PI/2 );
|
||||
},
|
||||
easeOutSine: function (x) {
|
||||
return sin( x * PI/2 );
|
||||
},
|
||||
easeInOutSine: function (x) {
|
||||
return -( cos( PI * x ) - 1 ) / 2;
|
||||
},
|
||||
easeInExpo: function (x) {
|
||||
return x === 0 ? 0 : pow( 2, 10 * x - 10 );
|
||||
},
|
||||
easeOutExpo: function (x) {
|
||||
return x === 1 ? 1 : 1 - pow( 2, -10 * x );
|
||||
},
|
||||
easeInOutExpo: function (x) {
|
||||
return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ?
|
||||
pow( 2, 20 * x - 10 ) / 2 :
|
||||
( 2 - pow( 2, -20 * x + 10 ) ) / 2;
|
||||
},
|
||||
easeInCirc: function (x) {
|
||||
return 1 - sqrt( 1 - pow( x, 2 ) );
|
||||
},
|
||||
easeOutCirc: function (x) {
|
||||
return sqrt( 1 - pow( x - 1, 2 ) );
|
||||
},
|
||||
easeInOutCirc: function (x) {
|
||||
return x < 0.5 ?
|
||||
( 1 - sqrt( 1 - pow( 2 * x, 2 ) ) ) / 2 :
|
||||
( sqrt( 1 - pow( -2 * x + 2, 2 ) ) + 1 ) / 2;
|
||||
},
|
||||
easeInElastic: function (x) {
|
||||
return x === 0 ? 0 : x === 1 ? 1 :
|
||||
-pow( 2, 10 * x - 10 ) * sin( ( x * 10 - 10.75 ) * c4 );
|
||||
},
|
||||
easeOutElastic: function (x) {
|
||||
return x === 0 ? 0 : x === 1 ? 1 :
|
||||
pow( 2, -10 * x ) * sin( ( x * 10 - 0.75 ) * c4 ) + 1;
|
||||
},
|
||||
easeInOutElastic: function (x) {
|
||||
return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ?
|
||||
-( pow( 2, 20 * x - 10 ) * sin( ( 20 * x - 11.125 ) * c5 )) / 2 :
|
||||
pow( 2, -20 * x + 10 ) * sin( ( 20 * x - 11.125 ) * c5 ) / 2 + 1;
|
||||
},
|
||||
easeInBack: function (x) {
|
||||
return c3 * x * x * x - c1 * x * x;
|
||||
},
|
||||
easeOutBack: function (x) {
|
||||
return 1 + c3 * pow( x - 1, 3 ) + c1 * pow( x - 1, 2 );
|
||||
},
|
||||
easeInOutBack: function (x) {
|
||||
return x < 0.5 ?
|
||||
( pow( 2 * x, 2 ) * ( ( c2 + 1 ) * 2 * x - c2 ) ) / 2 :
|
||||
( pow( 2 * x - 2, 2 ) *( ( c2 + 1 ) * ( x * 2 - 2 ) + c2 ) + 2 ) / 2;
|
||||
},
|
||||
easeInBounce: function (x) {
|
||||
return 1 - bounceOut( 1 - x );
|
||||
},
|
||||
easeOutBounce: bounceOut,
|
||||
easeInOutBounce: function (x) {
|
||||
return x < 0.5 ?
|
||||
( 1 - bounceOut( 1 - 2 * x ) ) / 2 :
|
||||
( 1 + bounceOut( 2 * x - 1 ) ) / 2;
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
Binary file not shown.
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
|
||||
Binary file not shown.
|
|
@ -0,0 +1,626 @@
|
|||
/* Notify.js - http://notifyjs.com/ Copyright (c) 2015 MIT */
|
||||
|
||||
(function (factory) {
|
||||
// UMD start
|
||||
// https://github.com/umdjs/umd/blob/master/jqueryPluginCommonjs.js
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
// Node/CommonJS
|
||||
module.exports = function( root, jQuery ) {
|
||||
if ( jQuery === undefined ) {
|
||||
// require('jQuery') returns a factory that requires window to
|
||||
// build a jQuery instance, we normalize how we use modules
|
||||
// that require this pattern but the window provided is a noop
|
||||
// if it's defined (how jquery works)
|
||||
if ( typeof window !== 'undefined' ) {
|
||||
jQuery = require('jquery');
|
||||
}
|
||||
else {
|
||||
jQuery = require('jquery')(root);
|
||||
}
|
||||
}
|
||||
factory(jQuery);
|
||||
return jQuery;
|
||||
};
|
||||
} else {
|
||||
// Browser globals
|
||||
factory(jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
//IE8 indexOf polyfill
|
||||
var indexOf = [].indexOf || function(item) {
|
||||
for (var i = 0, l = this.length; i < l; i++) {
|
||||
if (i in this && this[i] === item) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
var pluginName = "notify";
|
||||
var pluginClassName = pluginName + "js";
|
||||
var blankFieldName = pluginName + "!blank";
|
||||
|
||||
var positions = {
|
||||
t: "top",
|
||||
m: "middle",
|
||||
b: "bottom",
|
||||
l: "left",
|
||||
c: "center",
|
||||
r: "right"
|
||||
};
|
||||
var hAligns = ["l", "c", "r"];
|
||||
var vAligns = ["t", "m", "b"];
|
||||
var mainPositions = ["t", "b", "l", "r"];
|
||||
var opposites = {
|
||||
t: "b",
|
||||
m: null,
|
||||
b: "t",
|
||||
l: "r",
|
||||
c: null,
|
||||
r: "l"
|
||||
};
|
||||
|
||||
var parsePosition = function(str) {
|
||||
var pos;
|
||||
pos = [];
|
||||
$.each(str.split(/\W+/), function(i, word) {
|
||||
var w;
|
||||
w = word.toLowerCase().charAt(0);
|
||||
if (positions[w]) {
|
||||
return pos.push(w);
|
||||
}
|
||||
});
|
||||
return pos;
|
||||
};
|
||||
|
||||
var styles = {};
|
||||
|
||||
var coreStyle = {
|
||||
name: "core",
|
||||
html: "<div class=\"" + pluginClassName + "-wrapper\">\n <div class=\"" + pluginClassName + "-arrow\"></div>\n <div class=\"" + pluginClassName + "-container\"></div>\n</div>",
|
||||
css: "." + pluginClassName + "-corner {\n position: fixed;\n margin: 5px;\n z-index: 1050;\n}\n\n." + pluginClassName + "-corner ." + pluginClassName + "-wrapper,\n." + pluginClassName + "-corner ." + pluginClassName + "-container {\n position: relative;\n display: block;\n height: inherit;\n width: inherit;\n margin: 3px;\n}\n\n." + pluginClassName + "-wrapper {\n z-index: 1;\n position: absolute;\n display: inline-block;\n height: 0;\n width: 0;\n}\n\n." + pluginClassName + "-container {\n display: none;\n z-index: 1;\n position: absolute;\n}\n\n." + pluginClassName + "-hidable {\n cursor: pointer;\n}\n\n[data-notify-text],[data-notify-html] {\n position: relative;\n}\n\n." + pluginClassName + "-arrow {\n position: absolute;\n z-index: 2;\n width: 0;\n height: 0;\n}"
|
||||
};
|
||||
|
||||
var stylePrefixes = {
|
||||
"border-radius": ["-webkit-", "-moz-"]
|
||||
};
|
||||
|
||||
var getStyle = function(name) {
|
||||
return styles[name];
|
||||
};
|
||||
|
||||
var removeStyle = function(name) {
|
||||
if (!name) {
|
||||
throw "Missing Style name";
|
||||
}
|
||||
if (styles[name]) {
|
||||
delete styles[name];
|
||||
}
|
||||
};
|
||||
|
||||
var addStyle = function(name, def) {
|
||||
if (!name) {
|
||||
throw "Missing Style name";
|
||||
}
|
||||
if (!def) {
|
||||
throw "Missing Style definition";
|
||||
}
|
||||
if (!def.html) {
|
||||
throw "Missing Style HTML";
|
||||
}
|
||||
//remove existing style
|
||||
var existing = styles[name];
|
||||
if (existing && existing.cssElem) {
|
||||
if (window.console) {
|
||||
console.warn(pluginName + ": overwriting style '" + name + "'");
|
||||
}
|
||||
styles[name].cssElem.remove();
|
||||
}
|
||||
def.name = name;
|
||||
styles[name] = def;
|
||||
var cssText = "";
|
||||
if (def.classes) {
|
||||
$.each(def.classes, function(className, props) {
|
||||
cssText += "." + pluginClassName + "-" + def.name + "-" + className + " {\n";
|
||||
$.each(props, function(name, val) {
|
||||
if (stylePrefixes[name]) {
|
||||
$.each(stylePrefixes[name], function(i, prefix) {
|
||||
return cssText += " " + prefix + name + ": " + val + ";\n";
|
||||
});
|
||||
}
|
||||
return cssText += " " + name + ": " + val + ";\n";
|
||||
});
|
||||
return cssText += "}\n";
|
||||
});
|
||||
}
|
||||
if (def.css) {
|
||||
cssText += "/* styles for " + def.name + " */\n" + def.css;
|
||||
}
|
||||
if (cssText) {
|
||||
def.cssElem = insertCSS(cssText);
|
||||
def.cssElem.attr("id", "notify-" + def.name);
|
||||
}
|
||||
var fields = {};
|
||||
var elem = $(def.html);
|
||||
findFields("html", elem, fields);
|
||||
findFields("text", elem, fields);
|
||||
def.fields = fields;
|
||||
};
|
||||
|
||||
var insertCSS = function(cssText) {
|
||||
var e, elem, error;
|
||||
elem = createElem("style");
|
||||
elem.attr("type", 'text/css');
|
||||
$("head").append(elem);
|
||||
try {
|
||||
elem.html(cssText);
|
||||
} catch (_) {
|
||||
elem[0].styleSheet.cssText = cssText;
|
||||
}
|
||||
return elem;
|
||||
};
|
||||
|
||||
var findFields = function(type, elem, fields) {
|
||||
var attr;
|
||||
if (type !== "html") {
|
||||
type = "text";
|
||||
}
|
||||
attr = "data-notify-" + type;
|
||||
return find(elem, "[" + attr + "]").each(function() {
|
||||
var name;
|
||||
name = $(this).attr(attr);
|
||||
if (!name) {
|
||||
name = blankFieldName;
|
||||
}
|
||||
fields[name] = type;
|
||||
});
|
||||
};
|
||||
|
||||
var find = function(elem, selector) {
|
||||
if (elem.is(selector)) {
|
||||
return elem;
|
||||
} else {
|
||||
return elem.find(selector);
|
||||
}
|
||||
};
|
||||
|
||||
var pluginOptions = {
|
||||
clickToHide: true,
|
||||
autoHide: true,
|
||||
autoHideDelay: 5000,
|
||||
arrowShow: true,
|
||||
arrowSize: 5,
|
||||
breakNewLines: true,
|
||||
elementPosition: "bottom",
|
||||
globalPosition: "top right",
|
||||
style: "bootstrap",
|
||||
className: "error",
|
||||
showAnimation: "slideDown",
|
||||
showDuration: 400,
|
||||
hideAnimation: "slideUp",
|
||||
hideDuration: 200,
|
||||
gap: 5
|
||||
};
|
||||
|
||||
var inherit = function(a, b) {
|
||||
var F;
|
||||
F = function() {};
|
||||
F.prototype = a;
|
||||
return $.extend(true, new F(), b);
|
||||
};
|
||||
|
||||
var defaults = function(opts) {
|
||||
return $.extend(pluginOptions, opts);
|
||||
};
|
||||
|
||||
var createElem = function(tag) {
|
||||
return $("<" + tag + "></" + tag + ">");
|
||||
};
|
||||
|
||||
var globalAnchors = {};
|
||||
|
||||
var getAnchorElement = function(element) {
|
||||
var radios;
|
||||
if (element.is('[type=radio]')) {
|
||||
radios = element.parents('form:first').find('[type=radio]').filter(function(i, e) {
|
||||
return $(e).attr("name") === element.attr("name");
|
||||
});
|
||||
element = radios.first();
|
||||
}
|
||||
return element;
|
||||
};
|
||||
|
||||
var incr = function(obj, pos, val) {
|
||||
var opp, temp;
|
||||
if (typeof val === "string") {
|
||||
val = parseInt(val, 10);
|
||||
} else if (typeof val !== "number") {
|
||||
return;
|
||||
}
|
||||
if (isNaN(val)) {
|
||||
return;
|
||||
}
|
||||
opp = positions[opposites[pos.charAt(0)]];
|
||||
temp = pos;
|
||||
if (obj[opp] !== undefined) {
|
||||
pos = positions[opp.charAt(0)];
|
||||
val = -val;
|
||||
}
|
||||
if (obj[pos] === undefined) {
|
||||
obj[pos] = val;
|
||||
} else {
|
||||
obj[pos] += val;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
var realign = function(alignment, inner, outer) {
|
||||
if (alignment === "l" || alignment === "t") {
|
||||
return 0;
|
||||
} else if (alignment === "c" || alignment === "m") {
|
||||
return outer / 2 - inner / 2;
|
||||
} else if (alignment === "r" || alignment === "b") {
|
||||
return outer - inner;
|
||||
}
|
||||
throw "Invalid alignment";
|
||||
};
|
||||
|
||||
var encode = function(text) {
|
||||
encode.e = encode.e || createElem("div");
|
||||
return encode.e.text(text).html();
|
||||
};
|
||||
|
||||
function Notification(elem, data, options) {
|
||||
if (typeof options === "string") {
|
||||
options = {
|
||||
className: options
|
||||
};
|
||||
}
|
||||
this.options = inherit(pluginOptions, $.isPlainObject(options) ? options : {});
|
||||
this.loadHTML();
|
||||
this.wrapper = $(coreStyle.html);
|
||||
if (this.options.clickToHide) {
|
||||
this.wrapper.addClass(pluginClassName + "-hidable");
|
||||
}
|
||||
this.wrapper.data(pluginClassName, this);
|
||||
this.arrow = this.wrapper.find("." + pluginClassName + "-arrow");
|
||||
this.container = this.wrapper.find("." + pluginClassName + "-container");
|
||||
this.container.append(this.userContainer);
|
||||
if (elem && elem.length) {
|
||||
this.elementType = elem.attr("type");
|
||||
this.originalElement = elem;
|
||||
this.elem = getAnchorElement(elem);
|
||||
this.elem.data(pluginClassName, this);
|
||||
this.elem.before(this.wrapper);
|
||||
}
|
||||
this.container.hide();
|
||||
this.run(data);
|
||||
}
|
||||
|
||||
Notification.prototype.loadHTML = function() {
|
||||
var style;
|
||||
style = this.getStyle();
|
||||
this.userContainer = $(style.html);
|
||||
this.userFields = style.fields;
|
||||
};
|
||||
|
||||
Notification.prototype.show = function(show, userCallback) {
|
||||
var args, callback, elems, fn, hidden;
|
||||
callback = (function(_this) {
|
||||
return function() {
|
||||
if (!show && !_this.elem) {
|
||||
_this.destroy();
|
||||
}
|
||||
if (userCallback) {
|
||||
return userCallback();
|
||||
}
|
||||
};
|
||||
})(this);
|
||||
hidden = this.container.parent().parents(':hidden').length > 0;
|
||||
elems = this.container.add(this.arrow);
|
||||
args = [];
|
||||
if (hidden && show) {
|
||||
fn = "show";
|
||||
} else if (hidden && !show) {
|
||||
fn = "hide";
|
||||
} else if (!hidden && show) {
|
||||
fn = this.options.showAnimation;
|
||||
args.push(this.options.showDuration);
|
||||
} else if (!hidden && !show) {
|
||||
fn = this.options.hideAnimation;
|
||||
args.push(this.options.hideDuration);
|
||||
} else {
|
||||
return callback();
|
||||
}
|
||||
args.push(callback);
|
||||
return elems[fn].apply(elems, args);
|
||||
};
|
||||
|
||||
Notification.prototype.setGlobalPosition = function() {
|
||||
var p = this.getPosition();
|
||||
var pMain = p[0];
|
||||
var pAlign = p[1];
|
||||
var main = positions[pMain];
|
||||
var align = positions[pAlign];
|
||||
var key = pMain + "|" + pAlign;
|
||||
var anchor = globalAnchors[key];
|
||||
if (!anchor || !document.body.contains(anchor[0])) {
|
||||
anchor = globalAnchors[key] = createElem("div");
|
||||
var css = {};
|
||||
css[main] = 0;
|
||||
if (align === "middle") {
|
||||
css.top = '45%';
|
||||
} else if (align === "center") {
|
||||
css.left = '45%';
|
||||
} else {
|
||||
css[align] = 0;
|
||||
}
|
||||
anchor.css(css).addClass(pluginClassName + "-corner");
|
||||
$("body").append(anchor);
|
||||
}
|
||||
return anchor.prepend(this.wrapper);
|
||||
};
|
||||
|
||||
Notification.prototype.setElementPosition = function() {
|
||||
var arrowColor, arrowCss, arrowSize, color, contH, contW, css, elemH, elemIH, elemIW, elemPos, elemW, gap, j, k, len, len1, mainFull, margin, opp, oppFull, pAlign, pArrow, pMain, pos, posFull, position, ref, wrapPos;
|
||||
position = this.getPosition();
|
||||
pMain = position[0];
|
||||
pAlign = position[1];
|
||||
pArrow = position[2];
|
||||
elemPos = this.elem.position();
|
||||
elemH = this.elem.outerHeight();
|
||||
elemW = this.elem.outerWidth();
|
||||
elemIH = this.elem.innerHeight();
|
||||
elemIW = this.elem.innerWidth();
|
||||
wrapPos = this.wrapper.position();
|
||||
contH = this.container.height();
|
||||
contW = this.container.width();
|
||||
mainFull = positions[pMain];
|
||||
opp = opposites[pMain];
|
||||
oppFull = positions[opp];
|
||||
css = {};
|
||||
css[oppFull] = pMain === "b" ? elemH : pMain === "r" ? elemW : 0;
|
||||
incr(css, "top", elemPos.top - wrapPos.top);
|
||||
incr(css, "left", elemPos.left - wrapPos.left);
|
||||
ref = ["top", "left"];
|
||||
for (j = 0, len = ref.length; j < len; j++) {
|
||||
pos = ref[j];
|
||||
margin = parseInt(this.elem.css("margin-" + pos), 10);
|
||||
if (margin) {
|
||||
incr(css, pos, margin);
|
||||
}
|
||||
}
|
||||
gap = Math.max(0, this.options.gap - (this.options.arrowShow ? arrowSize : 0));
|
||||
incr(css, oppFull, gap);
|
||||
if (!this.options.arrowShow) {
|
||||
this.arrow.hide();
|
||||
} else {
|
||||
arrowSize = this.options.arrowSize;
|
||||
arrowCss = $.extend({}, css);
|
||||
arrowColor = this.userContainer.css("border-color") || this.userContainer.css("border-top-color") || this.userContainer.css("background-color") || "white";
|
||||
for (k = 0, len1 = mainPositions.length; k < len1; k++) {
|
||||
pos = mainPositions[k];
|
||||
posFull = positions[pos];
|
||||
if (pos === opp) {
|
||||
continue;
|
||||
}
|
||||
color = posFull === mainFull ? arrowColor : "transparent";
|
||||
arrowCss["border-" + posFull] = arrowSize + "px solid " + color;
|
||||
}
|
||||
incr(css, positions[opp], arrowSize);
|
||||
if (indexOf.call(mainPositions, pAlign) >= 0) {
|
||||
incr(arrowCss, positions[pAlign], arrowSize * 2);
|
||||
}
|
||||
}
|
||||
if (indexOf.call(vAligns, pMain) >= 0) {
|
||||
incr(css, "left", realign(pAlign, contW, elemW));
|
||||
if (arrowCss) {
|
||||
incr(arrowCss, "left", realign(pAlign, arrowSize, elemIW));
|
||||
}
|
||||
} else if (indexOf.call(hAligns, pMain) >= 0) {
|
||||
incr(css, "top", realign(pAlign, contH, elemH));
|
||||
if (arrowCss) {
|
||||
incr(arrowCss, "top", realign(pAlign, arrowSize, elemIH));
|
||||
}
|
||||
}
|
||||
if (this.container.is(":visible")) {
|
||||
css.display = "block";
|
||||
}
|
||||
this.container.removeAttr("style").css(css);
|
||||
if (arrowCss) {
|
||||
return this.arrow.removeAttr("style").css(arrowCss);
|
||||
}
|
||||
};
|
||||
|
||||
Notification.prototype.getPosition = function() {
|
||||
var pos, ref, ref1, ref2, ref3, ref4, ref5, text;
|
||||
text = this.options.position || (this.elem ? this.options.elementPosition : this.options.globalPosition);
|
||||
pos = parsePosition(text);
|
||||
if (pos.length === 0) {
|
||||
pos[0] = "b";
|
||||
}
|
||||
if (ref = pos[0], indexOf.call(mainPositions, ref) < 0) {
|
||||
throw "Must be one of [" + mainPositions + "]";
|
||||
}
|
||||
if (pos.length === 1 || ((ref1 = pos[0], indexOf.call(vAligns, ref1) >= 0) && (ref2 = pos[1], indexOf.call(hAligns, ref2) < 0)) || ((ref3 = pos[0], indexOf.call(hAligns, ref3) >= 0) && (ref4 = pos[1], indexOf.call(vAligns, ref4) < 0))) {
|
||||
pos[1] = (ref5 = pos[0], indexOf.call(hAligns, ref5) >= 0) ? "m" : "l";
|
||||
}
|
||||
if (pos.length === 2) {
|
||||
pos[2] = pos[1];
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
||||
Notification.prototype.getStyle = function(name) {
|
||||
var style;
|
||||
if (!name) {
|
||||
name = this.options.style;
|
||||
}
|
||||
if (!name) {
|
||||
name = "default";
|
||||
}
|
||||
style = styles[name];
|
||||
if (!style) {
|
||||
throw "Missing style: " + name;
|
||||
}
|
||||
return style;
|
||||
};
|
||||
|
||||
Notification.prototype.updateClasses = function() {
|
||||
var classes, style;
|
||||
classes = ["base"];
|
||||
if ($.isArray(this.options.className)) {
|
||||
classes = classes.concat(this.options.className);
|
||||
} else if (this.options.className) {
|
||||
classes.push(this.options.className);
|
||||
}
|
||||
style = this.getStyle();
|
||||
classes = $.map(classes, function(n) {
|
||||
return pluginClassName + "-" + style.name + "-" + n;
|
||||
}).join(" ");
|
||||
return this.userContainer.attr("class", classes);
|
||||
};
|
||||
|
||||
Notification.prototype.run = function(data, options) {
|
||||
var d, datas, name, type, value;
|
||||
if ($.isPlainObject(options)) {
|
||||
$.extend(this.options, options);
|
||||
} else if ($.type(options) === "string") {
|
||||
this.options.className = options;
|
||||
}
|
||||
if (this.container && !data) {
|
||||
this.show(false);
|
||||
return;
|
||||
} else if (!this.container && !data) {
|
||||
return;
|
||||
}
|
||||
datas = {};
|
||||
if ($.isPlainObject(data)) {
|
||||
datas = data;
|
||||
} else {
|
||||
datas[blankFieldName] = data;
|
||||
}
|
||||
for (name in datas) {
|
||||
d = datas[name];
|
||||
type = this.userFields[name];
|
||||
if (!type) {
|
||||
continue;
|
||||
}
|
||||
if (type === "text") {
|
||||
d = encode(d);
|
||||
if (this.options.breakNewLines) {
|
||||
d = d.replace(/\n/g, '<br/>');
|
||||
}
|
||||
}
|
||||
value = name === blankFieldName ? '' : '=' + name;
|
||||
find(this.userContainer, "[data-notify-" + type + value + "]").html(d);
|
||||
}
|
||||
this.updateClasses();
|
||||
if (this.elem) {
|
||||
this.setElementPosition();
|
||||
} else {
|
||||
this.setGlobalPosition();
|
||||
}
|
||||
this.show(true);
|
||||
if (this.options.autoHide) {
|
||||
clearTimeout(this.autohideTimer);
|
||||
this.autohideTimer = setTimeout(this.show.bind(this, false), this.options.autoHideDelay);
|
||||
}
|
||||
};
|
||||
|
||||
Notification.prototype.destroy = function() {
|
||||
this.wrapper.data(pluginClassName, null);
|
||||
this.wrapper.remove();
|
||||
};
|
||||
|
||||
$[pluginName] = function(elem, data, options) {
|
||||
if ((elem && elem.nodeName) || elem.jquery) {
|
||||
$(elem)[pluginName](data, options);
|
||||
} else {
|
||||
options = data;
|
||||
data = elem;
|
||||
new Notification(null, data, options);
|
||||
}
|
||||
return elem;
|
||||
};
|
||||
|
||||
$.fn[pluginName] = function(data, options) {
|
||||
$(this).each(function() {
|
||||
var prev = getAnchorElement($(this)).data(pluginClassName);
|
||||
if (prev) {
|
||||
prev.destroy();
|
||||
}
|
||||
var curr = new Notification($(this), data, options);
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
$.extend($[pluginName], {
|
||||
defaults: defaults,
|
||||
addStyle: addStyle,
|
||||
removeStyle: removeStyle,
|
||||
pluginOptions: pluginOptions,
|
||||
getStyle: getStyle,
|
||||
insertCSS: insertCSS
|
||||
});
|
||||
|
||||
//always include the default bootstrap style
|
||||
addStyle("bootstrap", {
|
||||
html: "<div>\n<span data-notify-text></span>\n</div>",
|
||||
classes: {
|
||||
base: {
|
||||
"font-weight": "bold",
|
||||
"padding": "8px 15px 8px 14px",
|
||||
"text-shadow": "0 1px 0 rgba(255, 255, 255, 0.5)",
|
||||
"background-color": "#fcf8e3",
|
||||
"border": "1px solid #fbeed5",
|
||||
"border-radius": "4px",
|
||||
"white-space": "nowrap",
|
||||
"padding-left": "25px",
|
||||
"background-repeat": "no-repeat",
|
||||
"background-position": "3px 7px"
|
||||
},
|
||||
error: {
|
||||
"color": "#B94A48",
|
||||
"background-color": "#F2DEDE",
|
||||
"border-color": "#EED3D7",
|
||||
"background-image": "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAtRJREFUeNqkVc1u00AQHq+dOD+0poIQfkIjalW0SEGqRMuRnHos3DjwAH0ArlyQeANOOSMeAA5VjyBxKBQhgSpVUKKQNGloFdw4cWw2jtfMOna6JOUArDTazXi/b3dm55socPqQhFka++aHBsI8GsopRJERNFlY88FCEk9Yiwf8RhgRyaHFQpPHCDmZG5oX2ui2yilkcTT1AcDsbYC1NMAyOi7zTX2Agx7A9luAl88BauiiQ/cJaZQfIpAlngDcvZZMrl8vFPK5+XktrWlx3/ehZ5r9+t6e+WVnp1pxnNIjgBe4/6dAysQc8dsmHwPcW9C0h3fW1hans1ltwJhy0GxK7XZbUlMp5Ww2eyan6+ft/f2FAqXGK4CvQk5HueFz7D6GOZtIrK+srupdx1GRBBqNBtzc2AiMr7nPplRdKhb1q6q6zjFhrklEFOUutoQ50xcX86ZlqaZpQrfbBdu2R6/G19zX6XSgh6RX5ubyHCM8nqSID6ICrGiZjGYYxojEsiw4PDwMSL5VKsC8Yf4VRYFzMzMaxwjlJSlCyAQ9l0CW44PBADzXhe7xMdi9HtTrdYjFYkDQL0cn4Xdq2/EAE+InCnvADTf2eah4Sx9vExQjkqXT6aAERICMewd/UAp/IeYANM2joxt+q5VI+ieq2i0Wg3l6DNzHwTERPgo1ko7XBXj3vdlsT2F+UuhIhYkp7u7CarkcrFOCtR3H5JiwbAIeImjT/YQKKBtGjRFCU5IUgFRe7fF4cCNVIPMYo3VKqxwjyNAXNepuopyqnld602qVsfRpEkkz+GFL1wPj6ySXBpJtWVa5xlhpcyhBNwpZHmtX8AGgfIExo0ZpzkWVTBGiXCSEaHh62/PoR0p/vHaczxXGnj4bSo+G78lELU80h1uogBwWLf5YlsPmgDEd4M236xjm+8nm4IuE/9u+/PH2JXZfbwz4zw1WbO+SQPpXfwG/BBgAhCNZiSb/pOQAAAAASUVORK5CYII=)"
|
||||
},
|
||||
success: {
|
||||
"color": "#468847",
|
||||
"background-color": "#DFF0D8",
|
||||
"border-color": "#D6E9C6",
|
||||
"background-image": "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAutJREFUeNq0lctPE0Ecx38zu/RFS1EryqtgJFA08YCiMZIAQQ4eRG8eDGdPJiYeTIwHTfwPiAcvXIwXLwoXPaDxkWgQ6islKlJLSQWLUraPLTv7Gme32zoF9KSTfLO7v53vZ3d/M7/fIth+IO6INt2jjoA7bjHCJoAlzCRw59YwHYjBnfMPqAKWQYKjGkfCJqAF0xwZjipQtA3MxeSG87VhOOYegVrUCy7UZM9S6TLIdAamySTclZdYhFhRHloGYg7mgZv1Zzztvgud7V1tbQ2twYA34LJmF4p5dXF1KTufnE+SxeJtuCZNsLDCQU0+RyKTF27Unw101l8e6hns3u0PBalORVVVkcaEKBJDgV3+cGM4tKKmI+ohlIGnygKX00rSBfszz/n2uXv81wd6+rt1orsZCHRdr1Imk2F2Kob3hutSxW8thsd8AXNaln9D7CTfA6O+0UgkMuwVvEFFUbbAcrkcTA8+AtOk8E6KiQiDmMFSDqZItAzEVQviRkdDdaFgPp8HSZKAEAL5Qh7Sq2lIJBJwv2scUqkUnKoZgNhcDKhKg5aH+1IkcouCAdFGAQsuWZYhOjwFHQ96oagWgRoUov1T9kRBEODAwxM2QtEUl+Wp+Ln9VRo6BcMw4ErHRYjH4/B26AlQoQQTRdHWwcd9AH57+UAXddvDD37DmrBBV34WfqiXPl61g+vr6xA9zsGeM9gOdsNXkgpEtTwVvwOklXLKm6+/p5ezwk4B+j6droBs2CsGa/gNs6RIxazl4Tc25mpTgw/apPR1LYlNRFAzgsOxkyXYLIM1V8NMwyAkJSctD1eGVKiq5wWjSPdjmeTkiKvVW4f2YPHWl3GAVq6ymcyCTgovM3FzyRiDe2TaKcEKsLpJvNHjZgPNqEtyi6mZIm4SRFyLMUsONSSdkPeFtY1n0mczoY3BHTLhwPRy9/lzcziCw9ACI+yql0VLzcGAZbYSM5CCSZg1/9oc/nn7+i8N9p/8An4JMADxhH+xHfuiKwAAAABJRU5ErkJggg==)"
|
||||
},
|
||||
info: {
|
||||
"color": "#3A87AD",
|
||||
"background-color": "#D9EDF7",
|
||||
"border-color": "#BCE8F1",
|
||||
"background-image": "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QYFAhkSsdes/QAAA8dJREFUOMvVlGtMW2UYx//POaWHXg6lLaW0ypAtw1UCgbniNOLcVOLmAjHZolOYlxmTGXVZdAnRfXQm+7SoU4mXaOaiZsEpC9FkiQs6Z6bdCnNYruM6KNBw6YWewzl9z+sHImEWv+vz7XmT95f/+3/+7wP814v+efDOV3/SoX3lHAA+6ODeUFfMfjOWMADgdk+eEKz0pF7aQdMAcOKLLjrcVMVX3xdWN29/GhYP7SvnP0cWfS8caSkfHZsPE9Fgnt02JNutQ0QYHB2dDz9/pKX8QjjuO9xUxd/66HdxTeCHZ3rojQObGQBcuNjfplkD3b19Y/6MrimSaKgSMmpGU5WevmE/swa6Oy73tQHA0Rdr2Mmv/6A1n9w9suQ7097Z9lM4FlTgTDrzZTu4StXVfpiI48rVcUDM5cmEksrFnHxfpTtU/3BFQzCQF/2bYVoNbH7zmItbSoMj40JSzmMyX5qDvriA7QdrIIpA+3cdsMpu0nXI8cV0MtKXCPZev+gCEM1S2NHPvWfP/hL+7FSr3+0p5RBEyhEN5JCKYr8XnASMT0xBNyzQGQeI8fjsGD39RMPk7se2bd5ZtTyoFYXftF6y37gx7NeUtJJOTFlAHDZLDuILU3j3+H5oOrD3yWbIztugaAzgnBKJuBLpGfQrS8wO4FZgV+c1IxaLgWVU0tMLEETCos4xMzEIv9cJXQcyagIwigDGwJgOAtHAwAhisQUjy0ORGERiELgG4iakkzo4MYAxcM5hAMi1WWG1yYCJIcMUaBkVRLdGeSU2995TLWzcUAzONJ7J6FBVBYIggMzmFbvdBV44Corg8vjhzC+EJEl8U1kJtgYrhCzgc/vvTwXKSib1paRFVRVORDAJAsw5FuTaJEhWM2SHB3mOAlhkNxwuLzeJsGwqWzf5TFNdKgtY5qHp6ZFf67Y/sAVadCaVY5YACDDb3Oi4NIjLnWMw2QthCBIsVhsUTU9tvXsjeq9+X1d75/KEs4LNOfcdf/+HthMnvwxOD0wmHaXr7ZItn2wuH2SnBzbZAbPJwpPx+VQuzcm7dgRCB57a1uBzUDRL4bfnI0RE0eaXd9W89mpjqHZnUI5Hh2l2dkZZUhOqpi2qSmpOmZ64Tuu9qlz/SEXo6MEHa3wOip46F1n7633eekV8ds8Wxjn37Wl63VVa+ej5oeEZ/82ZBETJjpJ1Rbij2D3Z/1trXUvLsblCK0XfOx0SX2kMsn9dX+d+7Kf6h8o4AIykuffjT8L20LU+w4AZd5VvEPY+XpWqLV327HR7DzXuDnD8r+ovkBehJ8i+y8YAAAAASUVORK5CYII=)"
|
||||
},
|
||||
warn: {
|
||||
"color": "#C09853",
|
||||
"background-color": "#FCF8E3",
|
||||
"border-color": "#FBEED5",
|
||||
"background-image": "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAMAAAC6V+0/AAABJlBMVEXr6eb/2oD/wi7/xjr/0mP/ykf/tQD/vBj/3o7/uQ//vyL/twebhgD/4pzX1K3z8e349vK6tHCilCWbiQymn0jGworr6dXQza3HxcKkn1vWvV/5uRfk4dXZ1bD18+/52YebiAmyr5S9mhCzrWq5t6ufjRH54aLs0oS+qD751XqPhAybhwXsujG3sm+Zk0PTwG6Shg+PhhObhwOPgQL4zV2nlyrf27uLfgCPhRHu7OmLgAafkyiWkD3l49ibiAfTs0C+lgCniwD4sgDJxqOilzDWowWFfAH08uebig6qpFHBvH/aw26FfQTQzsvy8OyEfz20r3jAvaKbhgG9q0nc2LbZxXanoUu/u5WSggCtp1anpJKdmFz/zlX/1nGJiYmuq5Dx7+sAAADoPUZSAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfdBgUBGhh4aah5AAAAlklEQVQY02NgoBIIE8EUcwn1FkIXM1Tj5dDUQhPU502Mi7XXQxGz5uVIjGOJUUUW81HnYEyMi2HVcUOICQZzMMYmxrEyMylJwgUt5BljWRLjmJm4pI1hYp5SQLGYxDgmLnZOVxuooClIDKgXKMbN5ggV1ACLJcaBxNgcoiGCBiZwdWxOETBDrTyEFey0jYJ4eHjMGWgEAIpRFRCUt08qAAAAAElFTkSuQmCC)"
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$(function() {
|
||||
insertCSS(coreStyle.css).attr("id", "core-notify");
|
||||
$(document).on("click", "." + pluginClassName + "-hidable", function(e) {
|
||||
$(this).trigger("notify-hide");
|
||||
});
|
||||
$(document).on("notify-hide", "." + pluginClassName + "-wrapper", function(e) {
|
||||
var elem = $(this).data(pluginClassName);
|
||||
if(elem) {
|
||||
elem.show(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}));
|
||||
Binary file not shown.
|
|
@ -0,0 +1,686 @@
|
|||
/*
|
||||
Unobtrusive JavaScript
|
||||
https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts
|
||||
Released under the MIT license
|
||||
*/
|
||||
|
||||
|
||||
(function() {
|
||||
var context = this;
|
||||
|
||||
(function() {
|
||||
(function() {
|
||||
this.Rails = {
|
||||
linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote]:not([disabled]), a[data-disable-with], a[data-disable]',
|
||||
buttonClickSelector: {
|
||||
selector: 'button[data-remote]:not([form]), button[data-confirm]:not([form])',
|
||||
exclude: 'form button'
|
||||
},
|
||||
inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]',
|
||||
formSubmitSelector: 'form',
|
||||
formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])',
|
||||
formDisableSelector: 'input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled',
|
||||
formEnableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled',
|
||||
fileInputSelector: 'input[name][type=file]:not([disabled])',
|
||||
linkDisableSelector: 'a[data-disable-with], a[data-disable]',
|
||||
buttonDisableSelector: 'button[data-remote][data-disable-with], button[data-remote][data-disable]'
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
}).call(context);
|
||||
|
||||
var Rails = context.Rails;
|
||||
|
||||
(function() {
|
||||
(function() {
|
||||
var expando, m;
|
||||
|
||||
m = Element.prototype.matches || Element.prototype.matchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.webkitMatchesSelector;
|
||||
|
||||
Rails.matches = function(element, selector) {
|
||||
if (selector.exclude != null) {
|
||||
return m.call(element, selector.selector) && !m.call(element, selector.exclude);
|
||||
} else {
|
||||
return m.call(element, selector);
|
||||
}
|
||||
};
|
||||
|
||||
expando = '_ujsData';
|
||||
|
||||
Rails.getData = function(element, key) {
|
||||
var ref;
|
||||
return (ref = element[expando]) != null ? ref[key] : void 0;
|
||||
};
|
||||
|
||||
Rails.setData = function(element, key, value) {
|
||||
if (element[expando] == null) {
|
||||
element[expando] = {};
|
||||
}
|
||||
return element[expando][key] = value;
|
||||
};
|
||||
|
||||
Rails.$ = function(selector) {
|
||||
return Array.prototype.slice.call(document.querySelectorAll(selector));
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var $, csrfParam, csrfToken;
|
||||
|
||||
$ = Rails.$;
|
||||
|
||||
csrfToken = Rails.csrfToken = function() {
|
||||
var meta;
|
||||
meta = document.querySelector('meta[name=csrf-token]');
|
||||
return meta && meta.content;
|
||||
};
|
||||
|
||||
csrfParam = Rails.csrfParam = function() {
|
||||
var meta;
|
||||
meta = document.querySelector('meta[name=csrf-param]');
|
||||
return meta && meta.content;
|
||||
};
|
||||
|
||||
Rails.CSRFProtection = function(xhr) {
|
||||
var token;
|
||||
token = csrfToken();
|
||||
if (token != null) {
|
||||
return xhr.setRequestHeader('X-CSRF-Token', token);
|
||||
}
|
||||
};
|
||||
|
||||
Rails.refreshCSRFTokens = function() {
|
||||
var param, token;
|
||||
token = csrfToken();
|
||||
param = csrfParam();
|
||||
if ((token != null) && (param != null)) {
|
||||
return $('form input[name="' + param + '"]').forEach(function(input) {
|
||||
return input.value = token;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var CustomEvent, fire, matches;
|
||||
|
||||
matches = Rails.matches;
|
||||
|
||||
CustomEvent = window.CustomEvent;
|
||||
|
||||
if (typeof CustomEvent !== 'function') {
|
||||
CustomEvent = function(event, params) {
|
||||
var evt;
|
||||
evt = document.createEvent('CustomEvent');
|
||||
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
|
||||
return evt;
|
||||
};
|
||||
CustomEvent.prototype = window.Event.prototype;
|
||||
}
|
||||
|
||||
fire = Rails.fire = function(obj, name, data) {
|
||||
var event;
|
||||
event = new CustomEvent(name, {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
detail: data
|
||||
});
|
||||
obj.dispatchEvent(event);
|
||||
return !event.defaultPrevented;
|
||||
};
|
||||
|
||||
Rails.stopEverything = function(e) {
|
||||
fire(e.target, 'ujs:everythingStopped');
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return e.stopImmediatePropagation();
|
||||
};
|
||||
|
||||
Rails.delegate = function(element, selector, eventType, handler) {
|
||||
return element.addEventListener(eventType, function(e) {
|
||||
var target;
|
||||
target = e.target;
|
||||
while (!(!(target instanceof Element) || matches(target, selector))) {
|
||||
target = target.parentNode;
|
||||
}
|
||||
if (target instanceof Element && handler.call(target, e) === false) {
|
||||
e.preventDefault();
|
||||
return e.stopPropagation();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var AcceptHeaders, CSRFProtection, createXHR, fire, prepareOptions, processResponse;
|
||||
|
||||
CSRFProtection = Rails.CSRFProtection, fire = Rails.fire;
|
||||
|
||||
AcceptHeaders = {
|
||||
'*': '*/*',
|
||||
text: 'text/plain',
|
||||
html: 'text/html',
|
||||
xml: 'application/xml, text/xml',
|
||||
json: 'application/json, text/javascript',
|
||||
script: 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript'
|
||||
};
|
||||
|
||||
Rails.ajax = function(options) {
|
||||
var xhr;
|
||||
options = prepareOptions(options);
|
||||
xhr = createXHR(options, function() {
|
||||
var response;
|
||||
response = processResponse(xhr.response, xhr.getResponseHeader('Content-Type'));
|
||||
if (Math.floor(xhr.status / 100) === 2) {
|
||||
if (typeof options.success === "function") {
|
||||
options.success(response, xhr.statusText, xhr);
|
||||
}
|
||||
} else {
|
||||
if (typeof options.error === "function") {
|
||||
options.error(response, xhr.statusText, xhr);
|
||||
}
|
||||
}
|
||||
return typeof options.complete === "function" ? options.complete(xhr, xhr.statusText) : void 0;
|
||||
});
|
||||
if (typeof options.beforeSend === "function") {
|
||||
options.beforeSend(xhr, options);
|
||||
}
|
||||
if (xhr.readyState === XMLHttpRequest.OPENED) {
|
||||
return xhr.send(options.data);
|
||||
} else {
|
||||
return fire(document, 'ajaxStop');
|
||||
}
|
||||
};
|
||||
|
||||
prepareOptions = function(options) {
|
||||
options.url = options.url || location.href;
|
||||
options.type = options.type.toUpperCase();
|
||||
if (options.type === 'GET' && options.data) {
|
||||
if (options.url.indexOf('?') < 0) {
|
||||
options.url += '?' + options.data;
|
||||
} else {
|
||||
options.url += '&' + options.data;
|
||||
}
|
||||
}
|
||||
if (AcceptHeaders[options.dataType] == null) {
|
||||
options.dataType = '*';
|
||||
}
|
||||
options.accept = AcceptHeaders[options.dataType];
|
||||
if (options.dataType !== '*') {
|
||||
options.accept += ', */*; q=0.01';
|
||||
}
|
||||
return options;
|
||||
};
|
||||
|
||||
createXHR = function(options, done) {
|
||||
var xhr;
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open(options.type, options.url, true);
|
||||
xhr.setRequestHeader('Accept', options.accept);
|
||||
if (typeof options.data === 'string') {
|
||||
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
|
||||
}
|
||||
if (!options.crossDomain) {
|
||||
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
||||
}
|
||||
CSRFProtection(xhr);
|
||||
xhr.withCredentials = !!options.withCredentials;
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState === XMLHttpRequest.DONE) {
|
||||
return done(xhr);
|
||||
}
|
||||
};
|
||||
return xhr;
|
||||
};
|
||||
|
||||
processResponse = function(response, type) {
|
||||
var parser, script;
|
||||
if (typeof response === 'string' && typeof type === 'string') {
|
||||
if (type.match(/\bjson\b/)) {
|
||||
try {
|
||||
response = JSON.parse(response);
|
||||
} catch (error) {}
|
||||
} else if (type.match(/\b(?:java|ecma)script\b/)) {
|
||||
script = document.createElement('script');
|
||||
script.text = response;
|
||||
document.head.appendChild(script).parentNode.removeChild(script);
|
||||
} else if (type.match(/\b(xml|html|svg)\b/)) {
|
||||
parser = new DOMParser();
|
||||
type = type.replace(/;.+/, '');
|
||||
try {
|
||||
response = parser.parseFromString(response, type);
|
||||
} catch (error) {}
|
||||
}
|
||||
}
|
||||
return response;
|
||||
};
|
||||
|
||||
Rails.href = function(element) {
|
||||
return element.href;
|
||||
};
|
||||
|
||||
Rails.isCrossDomain = function(url) {
|
||||
var e, originAnchor, urlAnchor;
|
||||
originAnchor = document.createElement('a');
|
||||
originAnchor.href = location.href;
|
||||
urlAnchor = document.createElement('a');
|
||||
try {
|
||||
urlAnchor.href = url;
|
||||
return !(((!urlAnchor.protocol || urlAnchor.protocol === ':') && !urlAnchor.host) || (originAnchor.protocol + '//' + originAnchor.host === urlAnchor.protocol + '//' + urlAnchor.host));
|
||||
} catch (error) {
|
||||
e = error;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var matches, toArray;
|
||||
|
||||
matches = Rails.matches;
|
||||
|
||||
toArray = function(e) {
|
||||
return Array.prototype.slice.call(e);
|
||||
};
|
||||
|
||||
Rails.serializeElement = function(element, additionalParam) {
|
||||
var inputs, params;
|
||||
inputs = [element];
|
||||
if (matches(element, 'form')) {
|
||||
inputs = toArray(element.elements);
|
||||
}
|
||||
params = [];
|
||||
inputs.forEach(function(input) {
|
||||
if (!input.name) {
|
||||
return;
|
||||
}
|
||||
if (matches(input, 'select')) {
|
||||
return toArray(input.options).forEach(function(option) {
|
||||
if (option.selected) {
|
||||
return params.push({
|
||||
name: input.name,
|
||||
value: option.value
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (input.checked || ['radio', 'checkbox', 'submit'].indexOf(input.type) === -1) {
|
||||
return params.push({
|
||||
name: input.name,
|
||||
value: input.value
|
||||
});
|
||||
}
|
||||
});
|
||||
if (additionalParam) {
|
||||
params.push(additionalParam);
|
||||
}
|
||||
return params.map(function(param) {
|
||||
if (param.name != null) {
|
||||
return (encodeURIComponent(param.name)) + "=" + (encodeURIComponent(param.value));
|
||||
} else {
|
||||
return param;
|
||||
}
|
||||
}).join('&');
|
||||
};
|
||||
|
||||
Rails.formElements = function(form, selector) {
|
||||
if (matches(form, 'form')) {
|
||||
return toArray(form.elements).filter(function(el) {
|
||||
return matches(el, selector);
|
||||
});
|
||||
} else {
|
||||
return toArray(form.querySelectorAll(selector));
|
||||
}
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var allowAction, fire, stopEverything;
|
||||
|
||||
fire = Rails.fire, stopEverything = Rails.stopEverything;
|
||||
|
||||
Rails.handleConfirm = function(e) {
|
||||
if (!allowAction(this)) {
|
||||
return stopEverything(e);
|
||||
}
|
||||
};
|
||||
|
||||
allowAction = function(element) {
|
||||
var answer, callback, message;
|
||||
message = element.getAttribute('data-confirm');
|
||||
if (!message) {
|
||||
return true;
|
||||
}
|
||||
answer = false;
|
||||
if (fire(element, 'confirm')) {
|
||||
try {
|
||||
answer = confirm(message);
|
||||
} catch (error) {}
|
||||
callback = fire(element, 'confirm:complete', [answer]);
|
||||
}
|
||||
return answer && callback;
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var disableFormElement, disableFormElements, disableLinkElement, enableFormElement, enableFormElements, enableLinkElement, formElements, getData, matches, setData, stopEverything;
|
||||
|
||||
matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, stopEverything = Rails.stopEverything, formElements = Rails.formElements;
|
||||
|
||||
Rails.handleDisabledElement = function(e) {
|
||||
var element;
|
||||
element = this;
|
||||
if (element.disabled) {
|
||||
return stopEverything(e);
|
||||
}
|
||||
};
|
||||
|
||||
Rails.enableElement = function(e) {
|
||||
var element;
|
||||
element = e instanceof Event ? e.target : e;
|
||||
if (matches(element, Rails.linkDisableSelector)) {
|
||||
return enableLinkElement(element);
|
||||
} else if (matches(element, Rails.buttonDisableSelector) || matches(element, Rails.formEnableSelector)) {
|
||||
return enableFormElement(element);
|
||||
} else if (matches(element, Rails.formSubmitSelector)) {
|
||||
return enableFormElements(element);
|
||||
}
|
||||
};
|
||||
|
||||
Rails.disableElement = function(e) {
|
||||
var element;
|
||||
element = e instanceof Event ? e.target : e;
|
||||
if (matches(element, Rails.linkDisableSelector)) {
|
||||
return disableLinkElement(element);
|
||||
} else if (matches(element, Rails.buttonDisableSelector) || matches(element, Rails.formDisableSelector)) {
|
||||
return disableFormElement(element);
|
||||
} else if (matches(element, Rails.formSubmitSelector)) {
|
||||
return disableFormElements(element);
|
||||
}
|
||||
};
|
||||
|
||||
disableLinkElement = function(element) {
|
||||
var replacement;
|
||||
replacement = element.getAttribute('data-disable-with');
|
||||
if (replacement != null) {
|
||||
setData(element, 'ujs:enable-with', element.innerHTML);
|
||||
element.innerHTML = replacement;
|
||||
}
|
||||
element.addEventListener('click', stopEverything);
|
||||
return setData(element, 'ujs:disabled', true);
|
||||
};
|
||||
|
||||
enableLinkElement = function(element) {
|
||||
var originalText;
|
||||
originalText = getData(element, 'ujs:enable-with');
|
||||
if (originalText != null) {
|
||||
element.innerHTML = originalText;
|
||||
setData(element, 'ujs:enable-with', null);
|
||||
}
|
||||
element.removeEventListener('click', stopEverything);
|
||||
return setData(element, 'ujs:disabled', null);
|
||||
};
|
||||
|
||||
disableFormElements = function(form) {
|
||||
return formElements(form, Rails.formDisableSelector).forEach(disableFormElement);
|
||||
};
|
||||
|
||||
disableFormElement = function(element) {
|
||||
var replacement;
|
||||
replacement = element.getAttribute('data-disable-with');
|
||||
if (replacement != null) {
|
||||
if (matches(element, 'button')) {
|
||||
setData(element, 'ujs:enable-with', element.innerHTML);
|
||||
element.innerHTML = replacement;
|
||||
} else {
|
||||
setData(element, 'ujs:enable-with', element.value);
|
||||
element.value = replacement;
|
||||
}
|
||||
}
|
||||
element.disabled = true;
|
||||
return setData(element, 'ujs:disabled', true);
|
||||
};
|
||||
|
||||
enableFormElements = function(form) {
|
||||
return formElements(form, Rails.formEnableSelector).forEach(enableFormElement);
|
||||
};
|
||||
|
||||
enableFormElement = function(element) {
|
||||
var originalText;
|
||||
originalText = getData(element, 'ujs:enable-with');
|
||||
if (originalText != null) {
|
||||
if (matches(element, 'button')) {
|
||||
element.innerHTML = originalText;
|
||||
} else {
|
||||
element.value = originalText;
|
||||
}
|
||||
setData(element, 'ujs:enable-with', null);
|
||||
}
|
||||
element.disabled = false;
|
||||
return setData(element, 'ujs:disabled', null);
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var stopEverything;
|
||||
|
||||
stopEverything = Rails.stopEverything;
|
||||
|
||||
Rails.handleMethod = function(e) {
|
||||
var csrfParam, csrfToken, form, formContent, href, link, method;
|
||||
link = this;
|
||||
method = link.getAttribute('data-method');
|
||||
if (!method) {
|
||||
return;
|
||||
}
|
||||
href = Rails.href(link);
|
||||
csrfToken = Rails.csrfToken();
|
||||
csrfParam = Rails.csrfParam();
|
||||
form = document.createElement('form');
|
||||
formContent = "<input name='_method' value='" + method + "' type='hidden' />";
|
||||
if ((csrfParam != null) && (csrfToken != null) && !Rails.isCrossDomain(href)) {
|
||||
formContent += "<input name='" + csrfParam + "' value='" + csrfToken + "' type='hidden' />";
|
||||
}
|
||||
formContent += '<input type="submit" />';
|
||||
form.method = 'post';
|
||||
form.action = href;
|
||||
form.target = link.target;
|
||||
form.innerHTML = formContent;
|
||||
form.style.display = 'none';
|
||||
document.body.appendChild(form);
|
||||
form.querySelector('[type="submit"]').click();
|
||||
return stopEverything(e);
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var ajax, fire, getData, isCrossDomain, isRemote, matches, serializeElement, setData, stopEverything,
|
||||
slice = [].slice;
|
||||
|
||||
matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, fire = Rails.fire, stopEverything = Rails.stopEverything, ajax = Rails.ajax, isCrossDomain = Rails.isCrossDomain, serializeElement = Rails.serializeElement;
|
||||
|
||||
isRemote = function(element) {
|
||||
var value;
|
||||
value = element.getAttribute('data-remote');
|
||||
return (value != null) && value !== 'false';
|
||||
};
|
||||
|
||||
Rails.handleRemote = function(e) {
|
||||
var button, data, dataType, element, method, url, withCredentials;
|
||||
element = this;
|
||||
if (!isRemote(element)) {
|
||||
return true;
|
||||
}
|
||||
if (!fire(element, 'ajax:before')) {
|
||||
fire(element, 'ajax:stopped');
|
||||
return false;
|
||||
}
|
||||
withCredentials = element.getAttribute('data-with-credentials');
|
||||
dataType = element.getAttribute('data-type') || 'script';
|
||||
if (matches(element, Rails.formSubmitSelector)) {
|
||||
button = getData(element, 'ujs:submit-button');
|
||||
method = getData(element, 'ujs:submit-button-formmethod') || element.method;
|
||||
url = getData(element, 'ujs:submit-button-formaction') || element.getAttribute('action') || location.href;
|
||||
if (method.toUpperCase() === 'GET') {
|
||||
url = url.replace(/\?.*$/, '');
|
||||
}
|
||||
if (element.enctype === 'multipart/form-data') {
|
||||
data = new FormData(element);
|
||||
if (button != null) {
|
||||
data.append(button.name, button.value);
|
||||
}
|
||||
} else {
|
||||
data = serializeElement(element, button);
|
||||
}
|
||||
setData(element, 'ujs:submit-button', null);
|
||||
setData(element, 'ujs:submit-button-formmethod', null);
|
||||
setData(element, 'ujs:submit-button-formaction', null);
|
||||
} else if (matches(element, Rails.buttonClickSelector) || matches(element, Rails.inputChangeSelector)) {
|
||||
method = element.getAttribute('data-method');
|
||||
url = element.getAttribute('data-url');
|
||||
data = serializeElement(element, element.getAttribute('data-params'));
|
||||
} else {
|
||||
method = element.getAttribute('data-method');
|
||||
url = Rails.href(element);
|
||||
data = element.getAttribute('data-params');
|
||||
}
|
||||
ajax({
|
||||
type: method || 'GET',
|
||||
url: url,
|
||||
data: data,
|
||||
dataType: dataType,
|
||||
beforeSend: function(xhr, options) {
|
||||
if (fire(element, 'ajax:beforeSend', [xhr, options])) {
|
||||
return fire(element, 'ajax:send', [xhr]);
|
||||
} else {
|
||||
fire(element, 'ajax:stopped');
|
||||
return xhr.abort();
|
||||
}
|
||||
},
|
||||
success: function() {
|
||||
var args;
|
||||
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
||||
return fire(element, 'ajax:success', args);
|
||||
},
|
||||
error: function() {
|
||||
var args;
|
||||
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
||||
return fire(element, 'ajax:error', args);
|
||||
},
|
||||
complete: function() {
|
||||
var args;
|
||||
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
||||
return fire(element, 'ajax:complete', args);
|
||||
},
|
||||
crossDomain: isCrossDomain(url),
|
||||
withCredentials: (withCredentials != null) && withCredentials !== 'false'
|
||||
});
|
||||
return stopEverything(e);
|
||||
};
|
||||
|
||||
Rails.formSubmitButtonClick = function(e) {
|
||||
var button, form;
|
||||
button = this;
|
||||
form = button.form;
|
||||
if (!form) {
|
||||
return;
|
||||
}
|
||||
if (button.name) {
|
||||
setData(form, 'ujs:submit-button', {
|
||||
name: button.name,
|
||||
value: button.value
|
||||
});
|
||||
}
|
||||
setData(form, 'ujs:formnovalidate-button', button.formNoValidate);
|
||||
setData(form, 'ujs:submit-button-formaction', button.getAttribute('formaction'));
|
||||
return setData(form, 'ujs:submit-button-formmethod', button.getAttribute('formmethod'));
|
||||
};
|
||||
|
||||
Rails.handleMetaClick = function(e) {
|
||||
var data, link, metaClick, method;
|
||||
link = this;
|
||||
method = (link.getAttribute('data-method') || 'GET').toUpperCase();
|
||||
data = link.getAttribute('data-params');
|
||||
metaClick = e.metaKey || e.ctrlKey;
|
||||
if (metaClick && method === 'GET' && !data) {
|
||||
return e.stopImmediatePropagation();
|
||||
}
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
(function() {
|
||||
var $, CSRFProtection, delegate, disableElement, enableElement, fire, formSubmitButtonClick, getData, handleConfirm, handleDisabledElement, handleMetaClick, handleMethod, handleRemote, refreshCSRFTokens;
|
||||
|
||||
fire = Rails.fire, delegate = Rails.delegate, getData = Rails.getData, $ = Rails.$, refreshCSRFTokens = Rails.refreshCSRFTokens, CSRFProtection = Rails.CSRFProtection, enableElement = Rails.enableElement, disableElement = Rails.disableElement, handleDisabledElement = Rails.handleDisabledElement, handleConfirm = Rails.handleConfirm, handleRemote = Rails.handleRemote, formSubmitButtonClick = Rails.formSubmitButtonClick, handleMetaClick = Rails.handleMetaClick, handleMethod = Rails.handleMethod;
|
||||
|
||||
if ((typeof jQuery !== "undefined" && jQuery !== null) && (jQuery.ajax != null) && !jQuery.rails) {
|
||||
jQuery.rails = Rails;
|
||||
jQuery.ajaxPrefilter(function(options, originalOptions, xhr) {
|
||||
if (!options.crossDomain) {
|
||||
return CSRFProtection(xhr);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Rails.start = function() {
|
||||
if (window._rails_loaded) {
|
||||
throw new Error('rails-ujs has already been loaded!');
|
||||
}
|
||||
window.addEventListener('pageshow', function() {
|
||||
$(Rails.formEnableSelector).forEach(function(el) {
|
||||
if (getData(el, 'ujs:disabled')) {
|
||||
return enableElement(el);
|
||||
}
|
||||
});
|
||||
return $(Rails.linkDisableSelector).forEach(function(el) {
|
||||
if (getData(el, 'ujs:disabled')) {
|
||||
return enableElement(el);
|
||||
}
|
||||
});
|
||||
});
|
||||
delegate(document, Rails.linkDisableSelector, 'ajax:complete', enableElement);
|
||||
delegate(document, Rails.linkDisableSelector, 'ajax:stopped', enableElement);
|
||||
delegate(document, Rails.buttonDisableSelector, 'ajax:complete', enableElement);
|
||||
delegate(document, Rails.buttonDisableSelector, 'ajax:stopped', enableElement);
|
||||
delegate(document, Rails.linkClickSelector, 'click', handleDisabledElement);
|
||||
delegate(document, Rails.linkClickSelector, 'click', handleConfirm);
|
||||
delegate(document, Rails.linkClickSelector, 'click', handleMetaClick);
|
||||
delegate(document, Rails.linkClickSelector, 'click', disableElement);
|
||||
delegate(document, Rails.linkClickSelector, 'click', handleRemote);
|
||||
delegate(document, Rails.linkClickSelector, 'click', handleMethod);
|
||||
delegate(document, Rails.buttonClickSelector, 'click', handleDisabledElement);
|
||||
delegate(document, Rails.buttonClickSelector, 'click', handleConfirm);
|
||||
delegate(document, Rails.buttonClickSelector, 'click', disableElement);
|
||||
delegate(document, Rails.buttonClickSelector, 'click', handleRemote);
|
||||
delegate(document, Rails.inputChangeSelector, 'change', handleDisabledElement);
|
||||
delegate(document, Rails.inputChangeSelector, 'change', handleConfirm);
|
||||
delegate(document, Rails.inputChangeSelector, 'change', handleRemote);
|
||||
delegate(document, Rails.formSubmitSelector, 'submit', handleDisabledElement);
|
||||
delegate(document, Rails.formSubmitSelector, 'submit', handleConfirm);
|
||||
delegate(document, Rails.formSubmitSelector, 'submit', handleRemote);
|
||||
delegate(document, Rails.formSubmitSelector, 'submit', function(e) {
|
||||
return setTimeout((function() {
|
||||
return disableElement(e);
|
||||
}), 13);
|
||||
});
|
||||
delegate(document, Rails.formSubmitSelector, 'ajax:send', disableElement);
|
||||
delegate(document, Rails.formSubmitSelector, 'ajax:complete', enableElement);
|
||||
delegate(document, Rails.formInputClickSelector, 'click', handleDisabledElement);
|
||||
delegate(document, Rails.formInputClickSelector, 'click', handleConfirm);
|
||||
delegate(document, Rails.formInputClickSelector, 'click', formSubmitButtonClick);
|
||||
document.addEventListener('DOMContentLoaded', refreshCSRFTokens);
|
||||
return window._rails_loaded = true;
|
||||
};
|
||||
|
||||
if (window.Rails === Rails && fire(document, 'rails:attachBindings')) {
|
||||
Rails.start();
|
||||
}
|
||||
|
||||
}).call(this);
|
||||
}).call(this);
|
||||
|
||||
if (typeof module === "object" && module.exports) {
|
||||
module.exports = Rails;
|
||||
} else if (typeof define === "function" && define.amd) {
|
||||
define(Rails);
|
||||
}
|
||||
}).call(this);
|
||||
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue