Merge branch 'develop'
paypal, pikpay and gift support
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
|
||||
gem 'rails_admin'
|
||||
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
||||
gem 'rails', '4.2.0'
|
||||
@@ -25,8 +24,11 @@ gem 'jbuilder', '~> 2.0'
|
||||
# bundle exec rake doc:rails generates the API under doc/api.
|
||||
gem 'sdoc', '~> 0.4.0', group: :doc
|
||||
|
||||
gem 'tzinfo-data'
|
||||
|
||||
gem "nokogiri", ">= 1.6.6"
|
||||
# great server
|
||||
gem 'puma'
|
||||
gem 'puma', '~> 2.15.3'
|
||||
|
||||
# for uploading images
|
||||
gem 'cloudinary'
|
||||
|
||||
@@ -79,6 +79,7 @@ GEM
|
||||
execjs (2.2.2)
|
||||
faraday (0.9.1)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ffi (1.9.10-x64-mingw32)
|
||||
font-awesome-rails (4.3.0.0)
|
||||
railties (>= 3.2, < 5.0)
|
||||
globalid (0.3.0)
|
||||
@@ -111,11 +112,13 @@ GEM
|
||||
multipart-post (2.0.0)
|
||||
nested_form (0.3.2)
|
||||
netrc (0.10.2)
|
||||
nokogiri (1.6.5)
|
||||
nokogiri (1.6.6.2)
|
||||
mini_portile (~> 0.6.0)
|
||||
nokogiri (1.6.6.2-x64-mingw32)
|
||||
mini_portile (~> 0.6.0)
|
||||
pg (0.18.1)
|
||||
puma (2.10.2)
|
||||
rack (>= 1.1, < 2.0)
|
||||
pg (0.18.1-x64-mingw32)
|
||||
puma (2.15.3)
|
||||
rack (1.6.0)
|
||||
rack-pjax (0.8.0)
|
||||
nokogiri (~> 1.5)
|
||||
@@ -167,6 +170,10 @@ GEM
|
||||
rest-client (1.7.2)
|
||||
mime-types (>= 1.16, < 3.0)
|
||||
netrc (~> 0.7)
|
||||
rest-client (1.7.2-x64-mingw32)
|
||||
ffi (~> 1.9)
|
||||
mime-types (>= 1.16, < 3.0)
|
||||
netrc (~> 0.7)
|
||||
safe_yaml (1.0.4)
|
||||
sass (3.4.9)
|
||||
sass-rails (5.0.1)
|
||||
@@ -199,6 +206,8 @@ GEM
|
||||
coffee-rails
|
||||
tzinfo (1.2.2)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo-data (1.2015.7)
|
||||
tzinfo (>= 1.0.0)
|
||||
uglifier (2.7.0)
|
||||
execjs (>= 0.3.0)
|
||||
json (>= 1.8.0)
|
||||
@@ -210,6 +219,7 @@ GEM
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
x64-mingw32
|
||||
|
||||
DEPENDENCIES
|
||||
active_scaffold!
|
||||
@@ -220,8 +230,9 @@ DEPENDENCIES
|
||||
jbuilder (~> 2.0)
|
||||
jquery-rails
|
||||
jquery-ui-rails
|
||||
nokogiri (>= 1.6.6)
|
||||
pg
|
||||
puma
|
||||
puma (~> 2.15.3)
|
||||
rails (= 4.2.0)
|
||||
rails_admin
|
||||
sass-rails (~> 5.0)
|
||||
@@ -229,8 +240,9 @@ DEPENDENCIES
|
||||
spring
|
||||
tabulous
|
||||
turbolinks
|
||||
tzinfo-data
|
||||
uglifier (>= 1.3.0)
|
||||
web-console (~> 2.0)
|
||||
|
||||
BUNDLED WITH
|
||||
1.10.3
|
||||
1.10.6
|
||||
|
||||
5
back-office/app/constraints/check_items_constraint.rb
Normal file
5
back-office/app/constraints/check_items_constraint.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class CheckItemsConstraint
|
||||
def self.matches?(request)
|
||||
request.params[:commit] == 'Check'
|
||||
end
|
||||
end
|
||||
5
back-office/app/constraints/delete_items_constraint.rb
Normal file
5
back-office/app/constraints/delete_items_constraint.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class DeleteItemsConstraint
|
||||
def self.matches?(request)
|
||||
request.params[:commit] == 'Delete Items'
|
||||
end
|
||||
end
|
||||
@@ -15,4 +15,80 @@ class ItemsController < ApplicationController
|
||||
@missing_from_database = (@codes_to_check_array - items_to_check) || []
|
||||
@missing_from_codes = (items_to_check - @codes_to_check_array) || []
|
||||
end
|
||||
|
||||
def delete_items
|
||||
@suppliers = Supplier.order(:name).all
|
||||
@selected_supplier = Supplier.find_by_id(params[:supplier_id])
|
||||
@items = @selected_supplier.try(:items) || []
|
||||
@codes_to_check = params[:codes] || ""
|
||||
@codes_to_check_array = @codes_to_check.split("\n").reject { |code| code.strip.blank? }.map(&:strip)
|
||||
items_to_check = @items.map { |i| i.code.strip }
|
||||
|
||||
@items_for_delete = items_to_check & @codes_to_check_array
|
||||
Item.where(:code => @items_for_delete).destroy_all
|
||||
|
||||
@not_deleted_items = (@codes_to_check_array - @items_for_delete) || []
|
||||
|
||||
render :template => "items/check_availability"
|
||||
end
|
||||
|
||||
def export_import
|
||||
@tasks = [ ["Validate items", "validate_items"],
|
||||
["Import items", "import_items"],
|
||||
["Update prices", "update_prices"] ]
|
||||
|
||||
@task = "validate_items"
|
||||
end
|
||||
|
||||
def export_import_post
|
||||
@tasks = [ ["Validate items", "validate_items"],
|
||||
["Import items", "import_items"],
|
||||
["Update prices", "update_prices"] ]
|
||||
|
||||
@task = params[:task]
|
||||
|
||||
@csv_content = params[:csv_content]
|
||||
|
||||
@error_message = ""
|
||||
@output = []
|
||||
|
||||
if params[:csv_content] == ""
|
||||
@error_message = "Format of CSV is wrong (CSV content is empty)"
|
||||
else
|
||||
begin
|
||||
csv_parsed = CSV.parse(params[:csv_content])
|
||||
rescue CSV::MalformedCSVError => er
|
||||
@error_message = "Format of CSV is wrong (#{er.message})"
|
||||
end
|
||||
|
||||
unless csv_parsed.nil?
|
||||
csv_file = ItemsHelper::create_csv(csv_parsed)
|
||||
|
||||
begin
|
||||
ENV["INPUT"] = csv_file.path
|
||||
|
||||
case @task
|
||||
when 'validate_items'
|
||||
@output = ItemsHelper::execute_command("rake ribica:validate_items -f #{Rails.root}/Rakefile")
|
||||
@output.collect{|x| x.sub! "\n", "" }
|
||||
when 'import_items'
|
||||
@output = ItemsHelper::execute_command("rake ribica:import_items -f #{Rails.root}/Rakefile")
|
||||
@output.collect{|x| x.sub! "\n", "" }
|
||||
%x(rake ribica:reindex -f #{Rails.root}/Rakefile) unless RakeTasksHelper::is_error_occurred @output
|
||||
when 'update_prices'
|
||||
@output = ItemsHelper::execute_command("rake ribica:update_prices -f #{Rails.root}/Rakefile")
|
||||
%x(rake ribica:reindex -f #{Rails.root}/Rakefile) unless RakeTasksHelper::is_error_occurred @output
|
||||
else
|
||||
@error_message = "There is no such task"
|
||||
end
|
||||
ensure
|
||||
csv_file.unlink
|
||||
end
|
||||
end
|
||||
|
||||
@output = @output.join("<br/>")
|
||||
end
|
||||
|
||||
render :template => "items/export_import"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
module ItemsHelper
|
||||
def self.create_csv(data)
|
||||
file = Tempfile.new([Rails.root.join('tmp/').to_s, ".csv"], "")
|
||||
csv = CSV.new(file)
|
||||
data.each do |row|
|
||||
csv << row
|
||||
end
|
||||
|
||||
file.rewind
|
||||
file.close
|
||||
file
|
||||
end
|
||||
|
||||
def self.execute_command(command)
|
||||
buffer = []
|
||||
Open3.popen3(command) do |stdin, stdout, stderr|
|
||||
begin
|
||||
while line = stdout.readline
|
||||
buffer << line
|
||||
end
|
||||
rescue
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
buffer
|
||||
end
|
||||
end
|
||||
|
||||
9
back-office/app/helpers/rake_tasks_helper.rb
Normal file
9
back-office/app/helpers/rake_tasks_helper.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
module RakeTasksHelper
|
||||
def self.task_error_message
|
||||
"Rake task execution error"
|
||||
end
|
||||
|
||||
def self.is_error_occurred(buffer)
|
||||
buffer.include? self.task_error_message
|
||||
end
|
||||
end
|
||||
@@ -5,7 +5,9 @@ class Cart < ActiveRecord::Base
|
||||
belongs_to :delivery_destination
|
||||
|
||||
def delivery_cost
|
||||
place = Place.by_code_or_default(delivery_destination.place)
|
||||
place = delivery_destination.gift ? Place.by_code_or_default(delivery_destination.recipient_place)
|
||||
: Place.by_code_or_default(delivery_destination.place)
|
||||
|
||||
if delivery_destination.instant_delivery
|
||||
place.instant_delivery_price
|
||||
else
|
||||
@@ -21,5 +23,4 @@ class Cart < ActiveRecord::Base
|
||||
def confirmed_at
|
||||
delivery_destination.updated_at.in_time_zone('Europe/Sarajevo')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,2 +1,14 @@
|
||||
class DeliveryDestination < ActiveRecord::Base
|
||||
class DeliveryDestination < ActiveRecord::Base
|
||||
def get_payment_string
|
||||
case self.payment_method
|
||||
when 'cash_on_delivery'
|
||||
'Prilikom preuzimanja'
|
||||
when 'paypal'
|
||||
'Paypal'
|
||||
when 'pikpay'
|
||||
'Pikpay'
|
||||
else
|
||||
'Nepoznato'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -124,12 +124,13 @@ class Item < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
puts "Nonexistent codes: "
|
||||
puts nonexistent_codes.join("\n")
|
||||
puts "#{nonexistent_codes.join("\n")}"
|
||||
end
|
||||
|
||||
def we_must_earn_money
|
||||
if list_price.to_f <= current_input_price.to_f
|
||||
errors[:list_price] << "#{code} Ulazna cijena veca od izlazne"
|
||||
puts "#{code} Ulazna cijena veca od izlazne"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
.tg td{ }
|
||||
.tg th{ }
|
||||
</style>
|
||||
<%
|
||||
<%
|
||||
dd = @record.delivery_destination
|
||||
c = @record
|
||||
%>
|
||||
<p>
|
||||
<p><strong>Ime:</strong> <%= dd.name %><br /><br /></p>
|
||||
|
||||
<p><strong>Adresa:</strong><br />
|
||||
<p><strong>Adresa:</strong><br />
|
||||
<%= dd.address %><br />
|
||||
<%= dd.place.to_s.strip %> <%= Place.name_from_code(dd.place.to_s) %><br />
|
||||
Bosna i Hercegovina<br /><br />
|
||||
@@ -22,15 +22,27 @@ Bosna i Hercegovina<br /><br />
|
||||
<p><strong>Telefon: </strong> +387 <%= dd.phone %><br /><br />
|
||||
</p>
|
||||
|
||||
<p><strong>Plaćanje: </strong><%= dd.get_payment_string %></p><br />
|
||||
|
||||
<p><strong>Napomena: </strong><br />
|
||||
<%= dd.note %><br /><br />
|
||||
</p>
|
||||
</p>
|
||||
|
||||
<% if dd.gift %>
|
||||
<p><strong>Ovo je poklon</strong><br /><br />
|
||||
<p><strong>Ime primaoca: </strong><%= dd.recipient_name %><br />
|
||||
<p><strong>Adresa primaoca: </strong><%= dd.recipient_address %><br />
|
||||
<p><strong>Postanski broj primaoca: </strong><%= dd.recipient_postal_code %><br />
|
||||
<p><strong>Grad primaoca: </strong><%= dd.recipient_place %><br />
|
||||
<p><strong>Email primaoca: </strong><%= dd.recipient_email %><br />
|
||||
<p><strong>Telefon primaoca: </strong><%= dd.recipient_phone %><br /><br />
|
||||
<% end %>
|
||||
|
||||
<p>
|
||||
<strong>Naručeno:</strong> <%= c.confirmed_at.in_time_zone("Europe/Sarajevo").strftime("%A %d.%m.%Y. %H:%M") %>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
</p>
|
||||
<% if dd.instant_delivery %>
|
||||
<p style="font-size: 120%;">
|
||||
@@ -47,7 +59,7 @@ OVO JE NARUDŽBA ZA INSTANT DOSTAVU
|
||||
<th style="text-align: right; ">Total</th>
|
||||
</tr>
|
||||
<% @record.item_in_carts.each do |iic| %>
|
||||
<tr>
|
||||
<tr>
|
||||
<td class="tg-031e"><%= iic.item.code %></td>
|
||||
<td class="tg-031e"><%= iic.item.name %></td>
|
||||
<td style="text-align: right; "><%= iic.count %></td>
|
||||
@@ -70,15 +82,6 @@ OVO JE NARUDŽBA ZA INSTANT DOSTAVU
|
||||
<td style="text-align: right; "><%= money(c.total) %></td>
|
||||
</tr>
|
||||
<tr><td><strong> </strong></td></tr>
|
||||
|
||||
|
||||
</table>
|
||||
<br /><br />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,33 +2,48 @@
|
||||
<p><label for="supplier_id">Supplier: </label>
|
||||
<%= select_tag "supplier_id", options_from_collection_for_select(@suppliers, "id", "name", @selected_supplier.try(:id)) %></p>
|
||||
|
||||
<p><label for="codes">
|
||||
<p><label for="codes">
|
||||
Codes to check:
|
||||
</label><br />
|
||||
<%= text_area_tag "codes", @codes_to_check, rows: 20, columns: 50 %></p>
|
||||
|
||||
<p><%= submit_tag "Check" %></p>
|
||||
<p><%= submit_tag "Delete Items" %></p>
|
||||
<% end %>
|
||||
|
||||
<div>
|
||||
<h2> In database: <%= @items.length %>, in file: <%= @codes_to_check_array.length %> </h2>
|
||||
</div>
|
||||
<% if controller.action_name == 'delete_items' %>
|
||||
|
||||
<h2> Delete successful </h2>
|
||||
|
||||
<% if @not_deleted_items.length > 0 %>
|
||||
<p>Not deleted items</p>
|
||||
<% @not_deleted_items.each do |code| %>
|
||||
<%= code %><br />
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% else %>
|
||||
|
||||
<div>
|
||||
<h2> In database: <%= @items.length %>, in file: <%= @codes_to_check_array.length %> </h2>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2>Not in database (<%= @missing_from_database.length %>): </h2>
|
||||
<br />
|
||||
<% @missing_from_database.each do |code| %>
|
||||
<%= code %><br />
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2>Not in file (<%= @missing_from_codes.length %>): </h2>
|
||||
<br />
|
||||
<% @missing_from_codes.each do |code| %>
|
||||
<%= code %><br />
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2>Not in database (<%= @missing_from_database.length %>): </h2>
|
||||
<br />
|
||||
<% @missing_from_database.each do |code| %>
|
||||
<%= code %><br />
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2>Not in file (<%= @missing_from_codes.length %>): </h2>
|
||||
<br />
|
||||
<% @missing_from_codes.each do |code| %>
|
||||
<%= code %><br />
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
21
back-office/app/views/items/export_import.html.erb
Normal file
21
back-office/app/views/items/export_import.html.erb
Normal file
@@ -0,0 +1,21 @@
|
||||
<%= form_tag('./export_import') do %>
|
||||
<p><label for="codes">
|
||||
CSV content goes here:
|
||||
</label><br />
|
||||
<textarea id="csv_content" name="csv_content" rows=20 style="width: 100%"><%= @csv_content %></textarea></p>
|
||||
|
||||
<p><label for="task">Task: </label>
|
||||
<%= select_tag "task", options_for_select(@tasks, @task) %></p>
|
||||
|
||||
<p><%= submit_tag "Run task" %></p>
|
||||
|
||||
<% if !@error_message.nil? && @error_message != "" %>
|
||||
<div>Error message: <span style="color: red"><%= @error_message %></span></div>
|
||||
<% end %>
|
||||
|
||||
<br />
|
||||
<p><label for="output_area">Output area: </label>
|
||||
<div id="output_area" style="width: 100%;height: 14em;outline: 1px solid #A9A9A9; overflow: scroll"><%= unless @output.nil?
|
||||
@output.html_safe end %>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -1,6 +1,8 @@
|
||||
require File.expand_path('../boot', __FILE__)
|
||||
|
||||
require 'rails/all'
|
||||
require 'rake'
|
||||
require 'open3'
|
||||
|
||||
# Require the gems listed in Gemfile, including any gems
|
||||
# you've limited to :test, :development, or :production.
|
||||
@@ -25,5 +27,3 @@ module Ribicabackoffice
|
||||
config.assets.precompile += %w(*.svg *.eot *.woff *.ttf *.gif *.png *.ico)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ RailsAdmin.config do |config|
|
||||
config.navigation_static_links = {
|
||||
'Orders to Confirm' => './reports/orders_to_confirm',
|
||||
'Items to Order' => './backreports/items_to_order',
|
||||
'Check availability' => './items/check_availability'
|
||||
'Check availability' => './items/check_availability',
|
||||
'Export/import' => './items/export_import'
|
||||
}
|
||||
end
|
||||
|
||||
@@ -15,12 +15,15 @@ Rails.application.routes.draw do
|
||||
resources :multi_media_descriptions do as_routes end
|
||||
resources :sections do as_routes end
|
||||
resources :media_types do as_routes end
|
||||
resources :items do
|
||||
collection do
|
||||
resources :items do
|
||||
collection do
|
||||
get 'check_availability'
|
||||
post 'check_availability'
|
||||
post 'check_availability' => 'items#check_availability', constraints: CheckItemsConstraint
|
||||
post 'check_availability' => 'items#delete_items', constraints: DeleteItemsConstraint
|
||||
get 'export_import'
|
||||
post 'export_import' => 'items#export_import_post'
|
||||
end
|
||||
as_routes
|
||||
as_routes
|
||||
end
|
||||
resources :units do as_routes end
|
||||
resources :sub_categories do as_routes end
|
||||
|
||||
@@ -223,6 +223,7 @@ def import_single_item(row, index, logger)
|
||||
success = true
|
||||
rescue Exception => e
|
||||
logger.error "Could not import item on row number #{index} (#{row[lookup[:name_on_ribica]]}), reason: #{e}"
|
||||
puts "Could not import item on row number #{index} (#{row[lookup[:name_on_ribica]]}), reason: #{e}"
|
||||
success = false
|
||||
end
|
||||
|
||||
@@ -242,14 +243,15 @@ def do_import(validate_only)
|
||||
input_file = ENV['INPUT']
|
||||
if input_file.to_s == ""
|
||||
puts "Input file is missing! Please provide input file in form INPUT=somefile.csv"
|
||||
puts RakeTasksHelper.task_error_message
|
||||
return
|
||||
end
|
||||
|
||||
lookup = get_column_lookup
|
||||
path = Rails.root.join(input_file)
|
||||
|
||||
log_filename = "import.log"
|
||||
log_filename = "import_validate.log" if validate_only
|
||||
log_filename = Rails.root.join("import.log")
|
||||
log_filename = Rails.root.join("import_validate.log") if validate_only
|
||||
|
||||
logger = Logger.new(log_filename)
|
||||
|
||||
@@ -274,6 +276,7 @@ def do_import(validate_only)
|
||||
if should_rollback
|
||||
puts "Import failed, please check the import log file for error details."
|
||||
logger.info "Rolling back because of errors"
|
||||
puts RakeTasksHelper.task_error_message
|
||||
end
|
||||
|
||||
raise ActiveRecord::Rollback
|
||||
@@ -281,8 +284,11 @@ def do_import(validate_only)
|
||||
end
|
||||
rescue Exception => e
|
||||
puts "Import failed, please check the import log file for error details."
|
||||
puts "Error while importing: #{e}"
|
||||
logger.error "Error while importing: #{e}"
|
||||
puts RakeTasksHelper.task_error_message
|
||||
end
|
||||
puts "Import done"
|
||||
logger.info "Import done"
|
||||
end
|
||||
|
||||
@@ -359,7 +365,7 @@ namespace :ribica do
|
||||
begin
|
||||
es_client.indices.delete index: 'ribica'
|
||||
rescue
|
||||
logger.warn "Ribica index could not be deleted. Continuing with indexing operation..."
|
||||
Rails.logger.warn "Ribica index could not be deleted. Continuing with indexing operation..."
|
||||
end
|
||||
|
||||
# now index items
|
||||
|
||||
@@ -24,6 +24,7 @@ GEM
|
||||
backports (3.6.6)
|
||||
bcrypt (3.1.10)
|
||||
bcrypt (3.1.10-java)
|
||||
bcrypt (3.1.10-x64-mingw32)
|
||||
builder (3.2.2)
|
||||
celluloid (0.16.0)
|
||||
timers (~> 4.0.0)
|
||||
@@ -39,12 +40,14 @@ GEM
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ffi (1.9.10)
|
||||
ffi (1.9.10-java)
|
||||
ffi (1.9.10-x64-mingw32)
|
||||
hitimes (1.2.3)
|
||||
hitimes (1.2.3-java)
|
||||
i18n (0.7.0)
|
||||
jdbc-postgres (9.4.1200)
|
||||
jruby-openssl (0.9.11-java)
|
||||
json (1.8.3)
|
||||
json (1.8.3-java)
|
||||
listen (2.10.1)
|
||||
celluloid (~> 0.16.0)
|
||||
rb-fsevent (>= 0.9.3)
|
||||
@@ -71,6 +74,10 @@ GEM
|
||||
rest-client (1.7.3)
|
||||
mime-types (>= 1.16, < 3.0)
|
||||
netrc (~> 0.7)
|
||||
rest-client (1.7.3-x64-mingw32)
|
||||
ffi (~> 1.9)
|
||||
mime-types (>= 1.16, < 3.0)
|
||||
netrc (~> 0.7)
|
||||
ruby-trello (1.2.1)
|
||||
activemodel (>= 3.2.0)
|
||||
addressable (~> 2.3)
|
||||
@@ -96,6 +103,7 @@ GEM
|
||||
tilt (>= 1.3, < 3)
|
||||
smtpapi (0.1.0)
|
||||
thread_safe (0.3.5)
|
||||
thread_safe (0.3.5-java)
|
||||
tilt (2.0.1)
|
||||
timers (4.0.4)
|
||||
hitimes
|
||||
@@ -106,6 +114,7 @@ GEM
|
||||
PLATFORMS
|
||||
java
|
||||
ruby
|
||||
x64-mingw32
|
||||
|
||||
DEPENDENCIES
|
||||
activerecord
|
||||
@@ -125,4 +134,4 @@ DEPENDENCIES
|
||||
xxhash (~> 0.3.0)
|
||||
|
||||
BUNDLED WITH
|
||||
1.10.3
|
||||
1.10.6
|
||||
|
||||
@@ -14,11 +14,11 @@ require 'sendgrid-ruby'
|
||||
|
||||
Trello.configure do |config|
|
||||
# API key generated by visiting https://trello.com/1/appKey/generate
|
||||
config.developer_public_key = "f13dd6c2dcc65f48b9a56c6d420e32e7"
|
||||
config.developer_public_key = RibicaConfig::TRELLO_DEVELOPER_PUBLIC_KEY
|
||||
|
||||
# Member token
|
||||
# larry-price.com/blog/2014/03/18/connecting-to-the-trello-api/
|
||||
config.member_token = "e8e1885d794dbc4d9d8d1ae586a84e580be224b2737254de6064d7d7219f3064"
|
||||
config.member_token = RibicaConfig::TRELLO_MEMBER_TOKEN
|
||||
end
|
||||
|
||||
Dir[File.dirname(__FILE__) + '/models/*.rb'].each {|file| require file }
|
||||
@@ -37,9 +37,11 @@ before do
|
||||
'Access-Control-Expose-Headers' => 'X-Total-Count',
|
||||
'Access-Control-Allow-Credentials' => 'true'
|
||||
|
||||
request.body.rewind
|
||||
json_string = request.body.read
|
||||
@json_params = JSON.parse json_string if json_string.length > 1
|
||||
unless Helper::do_not_parse_as_json.include? env['PATH_INFO']
|
||||
request.body.rewind
|
||||
json_string = request.body.read
|
||||
@json_params = JSON.parse json_string if json_string.length > 1
|
||||
end
|
||||
|
||||
if request.request_method == 'OPTIONS'
|
||||
halt 200
|
||||
|
||||
@@ -10,3 +10,23 @@ ActiveRecord::Base.establish_connection(
|
||||
:database => db.path[1..-1],
|
||||
:encoding => 'utf8'
|
||||
)
|
||||
|
||||
|
||||
module RibicaConfig
|
||||
ROOT_ADDRESS = "https://ribica.ba"
|
||||
SENDGRID_API_USER = "ribica"
|
||||
SENDGRID_API_KEY = "(enter key here)"
|
||||
|
||||
BACKOFFICE_ORDER_EMAIL_TO = "narudzbe@ribica.ba"
|
||||
BACKOFFICE_ORDER_EMAIL_FROM = "draga@ribica.ba"
|
||||
BACKOFFICE_ORDER_EMAIL_FROM_NAME = "Prodavnica Ribica"
|
||||
|
||||
# API key generated by visiting https://trello.com/1/appKey/generate
|
||||
TRELLO_DEVELOPER_PUBLIC_KEY = "f13dd6c2dcc65f48b9a56c6d420e32e7"
|
||||
# Member token
|
||||
# larry-price.com/blog/2014/03/18/connecting-to-the-trello-api/
|
||||
TRELLO_MEMBER_TOKEN = "(enter token here)"
|
||||
TRELLO_BOARD_NAME = "FqDO1eFL"
|
||||
|
||||
BAM_TO_EURO_CONVERSION_RATE = 0.51
|
||||
end
|
||||
|
||||
@@ -44,7 +44,9 @@ end
|
||||
|
||||
update_delivery_destination = ->() {
|
||||
cart = Cart.just_find(anonymous_id, logged_in_user_id)
|
||||
allowed_keys = ["name", "address", "place", "postal_code", "phone", "email", "note"]
|
||||
allowed_keys = ["name", "address", "place", "postal_code", "phone", "email", "note", "payment_method", "gift",
|
||||
"recipient_name", "recipient_address", "recipient_place", "recipient_postal_code", "recipient_phone", "recipient_email"]
|
||||
|
||||
params = @json_params.reject { |key,_| !allowed_keys.include?(key) }
|
||||
cart.delivery_destination.update_attributes(params)
|
||||
cart.delivery_destination.save!
|
||||
@@ -53,11 +55,10 @@ update_delivery_destination = ->() {
|
||||
put '/cart/delivery_destination', &update_delivery_destination
|
||||
post '/cart/delivery_destination', &update_delivery_destination
|
||||
|
||||
|
||||
def report_to_trello(cart)
|
||||
Thread.new do
|
||||
Thread.new do
|
||||
@cart = cart
|
||||
board = Trello::Board.find('FqDO1eFL')
|
||||
board = Trello::Board.find(RibicaConfig.TRELLO_BOARD_NAME)
|
||||
list = board.lists.first
|
||||
card = Trello::Card.new
|
||||
card.list_id = list.id
|
||||
@@ -69,18 +70,18 @@ def report_to_trello(cart)
|
||||
end
|
||||
|
||||
def send_order_email(cart)
|
||||
Thread.new do
|
||||
Thread.new do
|
||||
client = SendGrid::Client.new(
|
||||
api_user: "ribica",
|
||||
api_key: "plava*kutija*svjetlo*torba07"
|
||||
api_user: RibicaConfig.SENDGRID_API_USER,
|
||||
api_key: RibicaConfig.SENDGRID_API_KEY
|
||||
)
|
||||
|
||||
email = SendGrid::Mail.new do |m|
|
||||
m.to = "narudzbe@ribica.ba"
|
||||
m.from = "draga@ribica.ba"
|
||||
m.to = RibicaConfig.BACKOFFICE_ORDER_EMAIL_TO
|
||||
m.from = RibicaConfig.BACKOFFICE_ORDER_EMAIL_FROM
|
||||
m.from_name = "Prodavnica Ribica"
|
||||
m.subject = "Nova Narudžba: #{cart.id}"
|
||||
m.html = "Mušterija naručila nešto. <br /> Pogledati https://www.ribica.ba/backoffice/carts/#{cart.id}"
|
||||
m.html = "Mušterija naručila nešto. <br /> Pogledati #{RibicaConfig.ROOT_ADDRESS}/backoffice/carts/#{cart.id}"
|
||||
end
|
||||
client.send(email)
|
||||
end
|
||||
@@ -101,3 +102,44 @@ post '/cart/confirmation' do
|
||||
send_order_email(cart)
|
||||
"OK".to_json
|
||||
end
|
||||
|
||||
post '/payment/confirmation' do
|
||||
data = JSON.parse params[:custom]
|
||||
|
||||
puts "Data #{data.inspect}"
|
||||
|
||||
anonymous = data["anonymous_id_string"]
|
||||
user = data["user_id"]
|
||||
user ||= -1
|
||||
user = user.to_i
|
||||
|
||||
cart = Cart.just_find(anonymous, user)
|
||||
if cart.item_in_carts.length > 0
|
||||
cart.ordered = true
|
||||
cart.save!
|
||||
end
|
||||
|
||||
Cart.find_or_create(anonymous, user)
|
||||
report_to_trello(cart)
|
||||
send_order_email(cart)
|
||||
"OK".to_json
|
||||
end
|
||||
|
||||
get '/pikpay/confirmation' do
|
||||
anonymous = params["anonymous_id_string"]
|
||||
user = params["user_id"]
|
||||
user ||= -1
|
||||
user = user.to_i
|
||||
|
||||
cart = Cart.just_find(anonymous, user)
|
||||
if cart.item_in_carts.length > 0
|
||||
cart.ordered = true
|
||||
cart.save!
|
||||
end
|
||||
|
||||
Cart.find_or_create(anonymous, user)
|
||||
report_to_trello(cart)
|
||||
send_order_email(cart)
|
||||
|
||||
redirect "#{RibicaConfig::ROOT_ADDRESS}/hvala"
|
||||
end
|
||||
|
||||
@@ -1,35 +1,45 @@
|
||||
get '/search' do
|
||||
es_client = Elasticsearch::Client.new log: true
|
||||
q = params[:q]
|
||||
|
||||
# for now we do the basic query
|
||||
results = es_client.search index: 'ribica', type: 'items', body: { query: { match: { _all: q } } }
|
||||
ids = results["hits"]["hits"].map do |r|
|
||||
r["_id"]
|
||||
results = { }
|
||||
|
||||
begin
|
||||
es_client = Elasticsearch::Client.new log: true
|
||||
q = params[:q]
|
||||
|
||||
# for now we do the basic query
|
||||
results = es_client.search index: 'ribica', type: 'items', body: { query: { match: { _all: q } } }
|
||||
rescue Exception => error
|
||||
puts error.inspect
|
||||
results = { "hits" => {"hits" => [ {"_id" => Item.first.id, "_score" => 2 }, {"_id" => Item.last.id, "_score" => 1 } ]}}
|
||||
end
|
||||
|
||||
ids = results["hits"]["hits"].map do |r|
|
||||
r["_id"]
|
||||
end
|
||||
|
||||
ids_with_score = {}
|
||||
results["hits"]["hits"].each do |r|
|
||||
ids_with_score[r["_id"].to_i] = {:score => r["_score"], :item => nil}
|
||||
ids_with_score[r["_id"].to_i] = {:score => r["_score"], :item => nil}
|
||||
end
|
||||
|
||||
|
||||
if ids.length > 0
|
||||
res = Item.where(:id => ids).to_a
|
||||
# make sure we have correct relevance order, since `where in` does not guarantee order
|
||||
res.each do |ii|
|
||||
ids_with_score[ii.id][:item] = ii
|
||||
end
|
||||
final = []
|
||||
ids_with_score.each do |k,v|
|
||||
final << v
|
||||
end
|
||||
final.sort_by! {|v| -v[:score]}
|
||||
res = Item.where(:id => ids).to_a
|
||||
# make sure we have correct relevance order, since `where in` does not guarantee order
|
||||
res.each do |ii|
|
||||
ids_with_score[ii.id][:item] = ii
|
||||
end
|
||||
final = []
|
||||
ids_with_score.each do |k,v|
|
||||
final << v
|
||||
end
|
||||
final.sort_by! {|v| -v[:score]}
|
||||
|
||||
final = final.map do |f|
|
||||
f[:item]
|
||||
end
|
||||
prepare_items_for_mass_display(final)
|
||||
final = final.map do |f|
|
||||
f[:item]
|
||||
end
|
||||
prepare_items_for_mass_display(final)
|
||||
else
|
||||
[].to_json
|
||||
[].to_json
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddPaymentMethodToDeliveryDestination < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :delivery_destinations, :payment_method, :string
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddGiftToDeliveryDestination < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :delivery_destinations, :gift, :boolean, default: false
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,10 @@
|
||||
class AddRecipientDestinationToDeliveryDestination < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :delivery_destinations, :recipient_name, :string
|
||||
add_column :delivery_destinations, :recipient_address, :string
|
||||
add_column :delivery_destinations, :recipient_place, :string
|
||||
add_column :delivery_destinations, :recipient_postal_code, :string
|
||||
add_column :delivery_destinations, :recipient_phone, :string
|
||||
add_column :delivery_destinations, :recipient_email, :string
|
||||
end
|
||||
end
|
||||
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20151124061357) do
|
||||
ActiveRecord::Schema.define(version: 20160122145944) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
@@ -67,6 +67,14 @@ ActiveRecord::Schema.define(version: 20151124061357) do
|
||||
t.integer "user_id"
|
||||
t.string "anonymous_id_string"
|
||||
t.boolean "instant_delivery", default: false
|
||||
t.string "payment_method"
|
||||
t.boolean "gift", default: false
|
||||
t.string "recipient_name"
|
||||
t.string "recipient_address"
|
||||
t.string "recipient_place"
|
||||
t.string "recipient_postal_code"
|
||||
t.string "recipient_phone"
|
||||
t.string "recipient_email"
|
||||
end
|
||||
|
||||
create_table "delivery_time_estimations", force: :cascade do |t|
|
||||
|
||||
@@ -2,4 +2,16 @@ class Helper
|
||||
def self.money(amount)
|
||||
sprintf('%.2f KM', amount.to_f)
|
||||
end
|
||||
end
|
||||
|
||||
def self.get_bam_to_euro_conversion_rate
|
||||
RibicaConfig::BAM_TO_EURO_CONVERSION_RATE
|
||||
end
|
||||
|
||||
def self.bam_to_euro(amount)
|
||||
self.get_bam_to_euro_conversion_rate * amount
|
||||
end
|
||||
|
||||
def self.do_not_parse_as_json
|
||||
['/payment/confirmation']
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class Cart < ActiveRecord::Base
|
||||
has_many :item_in_carts, -> { order "created_at" }
|
||||
has_many :item_in_carts, -> { order "created_at" }
|
||||
belongs_to :delivery_destination
|
||||
|
||||
def self.find_or_create(anonymous_id, user_id)
|
||||
@@ -74,7 +74,7 @@ class Cart < ActiveRecord::Base
|
||||
|
||||
def title
|
||||
number = id
|
||||
name = delivery_destination.name
|
||||
name = delivery_destination.name
|
||||
value = Helper.money(total)
|
||||
phone = "0#{delivery_destination.phone}"
|
||||
"BR: #{number} za #{name} (#{phone}) - #{value}"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
class DeliveryDestination < ActiveRecord::Base
|
||||
class DeliveryDestination < ActiveRecord::Base
|
||||
has_one :cart
|
||||
belongs_to :user
|
||||
|
||||
@@ -6,9 +6,32 @@ class DeliveryDestination < ActiveRecord::Base
|
||||
dd = DeliveryDestination.where(["user_id is not null and user_id = ?", user_id]).order("id desc").first
|
||||
dd ||= DeliveryDestination.where(["anonymous_id_string is not null and anonymous_id_string = ?", anonymous_id]).order("id desc").first
|
||||
dd ||= DeliveryDestination.new({user_id: user_id, anonymous_id_string: anonymous_id })
|
||||
|
||||
dd.payment_method ||= "cash_on_delivery"
|
||||
dd.gift = false
|
||||
dd.recipient_name = ""
|
||||
dd.recipient_phone = ""
|
||||
dd.recipient_email = ""
|
||||
dd.recipient_address = ""
|
||||
dd.recipient_place = ""
|
||||
dd.recipient_postal_code = ""
|
||||
|
||||
attributes = dd.as_json
|
||||
attributes.delete("id")
|
||||
result = DeliveryDestination.create!(attributes)
|
||||
return result
|
||||
end
|
||||
|
||||
def get_payment_string
|
||||
case self.payment_method
|
||||
when 'cash_on_delivery'
|
||||
'Prilikom preuzimanja'
|
||||
when 'paypal'
|
||||
'Paypal'
|
||||
when 'pikpay'
|
||||
'Pikpay'
|
||||
else
|
||||
'Nepoznato'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
|
||||
<%
|
||||
<%
|
||||
dd = @cart.delivery_destination
|
||||
c = @cart
|
||||
%>
|
||||
|
||||
**Ime:** <%= dd.name %>
|
||||
**Ime:** <%= dd.name %>
|
||||
|
||||
**Adresa:**
|
||||
<%= dd.address %>
|
||||
@@ -17,9 +17,23 @@ Bosna i Hercegovina
|
||||
|
||||
**Telefon: ** +387 <%= dd.phone %>
|
||||
|
||||
**Plaćanje: ** <%= dd.get_payment_string %>
|
||||
|
||||
**Napomena: **
|
||||
<%= dd.note %>
|
||||
|
||||
<% if dd.gift %>
|
||||
**Poklon **
|
||||
|
||||
**Name: **<%= dd.recipient_name %>
|
||||
**Postal code: **<%= dd.recipient_postal_code %>
|
||||
**Place: **<%= dd.recipient_place %>
|
||||
**Address: **<%= dd.recipient_address %>
|
||||
**Phone: **<%= dd.recipient_phone %>
|
||||
**Email: **<%= dd.recipient_email %>
|
||||
<% end %>
|
||||
|
||||
<% if dd.instant_delivery %>
|
||||
|
||||
**Naručeno:** <%= @cart.updated_at.in_time_zone("Europe/Sarajevo").strftime("%A %d.%m.%Y. %H:%M") %>
|
||||
|
||||
@@ -37,16 +51,7 @@ Bosna i Hercegovina
|
||||
|
||||
Dostava
|
||||
1 x <%= Helper.money(c.delivery_cost) %> = <%= Helper.money(c.delivery_cost) %>
|
||||
|
||||
|
||||
**UKUPNO:** <%= Helper.money(c.total) %>
|
||||
|
||||
[Pogledati OVAJ LINK](https://www.ribica.ba/backoffice/carts/<%= @cart.id %>)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -75,4 +75,4 @@ var CartActions = {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = CartActions;
|
||||
module.exports = CartActions;
|
||||
|
||||
@@ -5,25 +5,54 @@ var React = require('react'),
|
||||
NavigationActions = require('../../actions/navigationActions'),
|
||||
SingleItem = require('../items/singleItem'),
|
||||
Globals = require('../../globals'),
|
||||
CartTotal = require('./cartTotal'),
|
||||
CartTotal = require('./cartTotal'),
|
||||
LinkBanner = require('../linkBanner/linkBanner'),
|
||||
RibicaFormError = require('../shared/ribicaFormError');
|
||||
|
||||
PaymentSelect = require('../payment/paymentSelect'),
|
||||
RibicaFormError = require('../shared/ribicaFormError'),
|
||||
PaypalButton = require('../payment/paypalButton'),
|
||||
PikpayButton = require('../payment/pikpayButton'),
|
||||
CashOnDeliveryButton = require('../payment/cashOnDeliveryButton');
|
||||
|
||||
var Router = require('react-router');
|
||||
|
||||
|
||||
var CheckoutPage = React.createClass({
|
||||
|
||||
render: function() {
|
||||
var choosePayment = (
|
||||
<div className="payment-btn">
|
||||
<PaymentSelect deliveryDestination={this.state.deliveryDestination}
|
||||
amount={CartStore.getAmount()}
|
||||
deliveryCost={CartStore.getDeliveryCost(false)}
|
||||
disabled={!this.state.isDeliveryDestinationValid}
|
||||
cashOnDeliveryDisabled={!this.state.isDeliveryDestinationValid || this.state.deliveryDestination.get('gift')}
|
||||
onCashClick={this._onOrderClick}
|
||||
cartId={this.state.cart.get('id')}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
var last_used_payment;
|
||||
if(this.state.deliveryDestination.get('payment_method') == 'paypal') {
|
||||
last_used_payment = (
|
||||
<PaypalButton disabled={!this.state.isDeliveryDestinationValid} onSubmitPaypal={this._handleOnSubmitPaypal} deliveryDestination={this.state.deliveryDestination} amount={CartStore.getAmount()} deliveryCost={CartStore.getDeliveryCost(false)} cartId={this.state.cart.get('id')}/>
|
||||
);
|
||||
} else if(this.state.deliveryDestination.get('payment_method') == 'pikpay') {
|
||||
last_used_payment = (
|
||||
<PikpayButton amount={CartStore.getAmount()} deliveryCost={CartStore.getDeliveryCost(false)} disabled={!this.state.isDeliveryDestinationValid} deliveryDestination={this.state.deliveryDestination} cartId={this.state.cart.get('id')}/>
|
||||
);
|
||||
} else {
|
||||
last_used_payment = (
|
||||
<CashOnDeliveryButton onCashClick={this._onOrderClick} disabled={!this.state.isDeliveryDestinationValid || this.state.deliveryDestination.get('gift')} cartId={this.state.cart.get('id')}/>
|
||||
);
|
||||
}
|
||||
|
||||
var supportedPlaceOptions = CartStore.getSupportedPlaces().map ( function (p) { return (<option value={p.code}>{p.placeLabel}</option>)});
|
||||
|
||||
|
||||
var content = (
|
||||
<div className="checkout-page center">
|
||||
<div className="form-horizontal checkout_form_margin">
|
||||
<fieldset>
|
||||
<legend>Dostava</legend>
|
||||
<legend>Podaci o naručiocu</legend>
|
||||
<div className="form-group ">
|
||||
|
||||
<label className="col-md-4 control-label" htmlFor="name">Prezime i Ime</label>
|
||||
@@ -41,15 +70,15 @@ var CheckoutPage = React.createClass({
|
||||
<span className="help-block">adresa na koju će roba biti isporučena</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="form-group ">
|
||||
<label className="col-md-4 control-label" htmlFor="place">Mjesto</label>
|
||||
<div className="col-md-4">
|
||||
<RibicaFormError componentName="place" errorMessagesObject={this.state.deliveryDestinationErrors} />
|
||||
<select id="place" name="place" className="form-control" value={this.state.deliveryDestination.get('place')} onChange={this._onFieldChange} >
|
||||
|
||||
{supportedPlaceOptions}
|
||||
|
||||
|
||||
{supportedPlaceOptions}
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -78,22 +107,88 @@ var CheckoutPage = React.createClass({
|
||||
<textarea className="form-control" id="note" name="note" value={this.state.deliveryDestination.get('note')} onChange={this._onFieldChange} ></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group ">
|
||||
<label className="col-md-4 control-label" htmlFor="order"></label>
|
||||
<div className="col-md-8">
|
||||
<div> Roba: <CartTotal items={this.state.items} itemCounts={this.state.itemCounts} /><br />
|
||||
<span className={this.state.deliveryDestinationErrors['place'] ? 'hidden' : 'shown'}>
|
||||
Dostava: <CartTotal deliveryCosts={this.state.deliveryCosts} /><br />
|
||||
Ukupno: <CartTotal items={this.state.items} itemCounts={this.state.itemCounts} deliveryCosts={this.state.deliveryCosts} />
|
||||
<div className="form-group">
|
||||
<label className="col-md-4 control-label" htmlFor="order"></label>
|
||||
<div className="col-md-8">
|
||||
<div> Roba: <CartTotal items={this.state.items} itemCounts={this.state.itemCounts} /><br />
|
||||
<span className={this.state.deliveryDestinationErrors[this.state.deliveryCostsTarget] ? 'hidden' : 'shown'}>
|
||||
Dostava: <CartTotal deliveryCosts={this.state.deliveryCosts} /><br />
|
||||
Ukupno: <CartTotal items={this.state.items} itemCounts={this.state.itemCounts} deliveryCosts={this.state.deliveryCosts} />
|
||||
</span>
|
||||
</div>
|
||||
<div><button id="order" name="order" className="mybutton" disabled={!this.state.isDeliveryDestinationValid} onClick={this._onOrderClick}>Završi narudžbu</button></div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div className="checkbox">
|
||||
<label><input type="checkbox" name="gift" checked={this.state.deliveryDestination.get('gift')} onChange={this._onFieldChange} />Poklon</label>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
</div>
|
||||
|
||||
|
||||
</fieldset>
|
||||
|
||||
<fieldset className={this.state.deliveryDestination.get('gift') ? 'shown' : 'hidden'}>
|
||||
<legend>Podaci o dostavi</legend>
|
||||
|
||||
|
||||
<div className="form-group ">
|
||||
|
||||
<label className="col-md-4 control-label" htmlFor="recipient_name">Prezime i Ime</label>
|
||||
<div className="col-md-4">
|
||||
<RibicaFormError componentName="recipient_name" errorMessagesObject={this.state.deliveryDestinationErrors} />
|
||||
<input id="recipient_name" name="recipient_name" type="text" placeholder="Prezime Ime" className="form-control input-md" required="" value={this.state.deliveryDestination.get('recipient_name')} onChange={this._onFieldChange} />
|
||||
<span className="help-block">ime osobe koja prima pošiljku</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group ">
|
||||
<label className="col-md-4 control-label" htmlFor="recipient_address">Adresa</label>
|
||||
<div className="col-md-4">
|
||||
<RibicaFormError componentName="recipient_address" errorMessagesObject={this.state.deliveryDestinationErrors} />
|
||||
<input id="recipient_address" name="recipient_address" type="text" placeholder="Ulica i broj" className="form-control input-md" required="" value={this.state.deliveryDestination.get('recipient_address')} onChange={this._onFieldChange} />
|
||||
<span className="help-block">adresa na koju će roba biti isporučena</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="form-group ">
|
||||
<label className="col-md-4 control-label" htmlFor="recipient_place">Mjesto</label>
|
||||
<div className="col-md-4">
|
||||
<RibicaFormError componentName="recipient_place" errorMessagesObject={this.state.deliveryDestinationErrors} />
|
||||
<select id="recipient_place" name="recipient_place" className="form-control" value={this.state.deliveryDestination.get('recipient_place')} onChange={this._onFieldChange} >
|
||||
|
||||
{supportedPlaceOptions}
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group ">
|
||||
<label className="col-md-4 control-label" htmlFor="recipient_phone">Telefon</label>
|
||||
<div className="col-md-4">
|
||||
<RibicaFormError componentName="recipient_phone" errorMessagesObject={this.state.deliveryDestinationErrors} />
|
||||
<div className="input-group">
|
||||
<span className="input-group-addon">+387 </span>
|
||||
<input id="recipient_phone" name="recipient_phone" className="form-control" placeholder="061 222 333" type="text" required="" value={this.state.deliveryDestination.get('recipient_phone')} onChange={this._onFieldChange} />
|
||||
</div>
|
||||
<p className="help-block">broj mobitela - mora biti sa jedne od mreža u BiH</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group ">
|
||||
<label className="col-md-4 control-label" htmlFor="recipient_email">E - mail</label>
|
||||
<div className="col-md-4">
|
||||
<RibicaFormError componentName="recipient_email" errorMessagesObject={this.state.deliveryDestinationErrors} />
|
||||
<input id="recipient_email" name="recipient_email" type="text" placeholder="ime@nekimail.com" className="form-control input-md" required="" value={this.state.deliveryDestination.get('recipient_email')} onChange={this._onFieldChange} />
|
||||
<span className="help-block">E - mail adresa na koju će vam biti poslano obavještenje o narudžbi</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</fieldset>
|
||||
|
||||
<div className="payment-select-container">
|
||||
{choosePayment}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
if(CartStore.isAddressColapsed()) {
|
||||
|
||||
@@ -109,16 +204,27 @@ var CheckoutPage = React.createClass({
|
||||
Ukupno: <CartTotal items={this.state.items} itemCounts={this.state.itemCounts} deliveryCosts={this.state.deliveryCosts} />
|
||||
|
||||
</p>
|
||||
<p>
|
||||
<button id="order" name="order" className="mybutton" disabled={!this.state.isDeliveryDestinationValid} onClick={this._onOrderClick}>Završi narudžbu</button> ili <button className="btn btn-default" onClick={this._onUncolapseClick}>Promijeni adresu</button>
|
||||
</p>
|
||||
|
||||
<div className="hidden-xs">
|
||||
<button className="btn btn-default gift-btn" onClick={this._onGiftBtnClicked}>Poklon</button>
|
||||
<br />
|
||||
|
||||
<p className="collapsed-address-container">{last_used_payment} ili <button className="btn btn-default" onClick={this._onUncolapseClick}>Promijeni način plaćanja ili adresu</button></p>
|
||||
</div>
|
||||
|
||||
<div className="collapsed-address-container-mobile btn-group-vertical visible-xs">
|
||||
<button className="btn btn-default" onClick={this._onGiftBtnClicked}>Poklon</button>
|
||||
{last_used_payment}
|
||||
<button className="btn btn-default" onClick={this._onUncolapseClick}>Promijeni način plaćanja ili adresu</button>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="col-md-4 control-label" htmlFor="order"></label>
|
||||
<div className="col-md-8">
|
||||
<div> </div>
|
||||
<div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>);
|
||||
}
|
||||
|
||||
@@ -144,10 +250,15 @@ var CheckoutPage = React.createClass({
|
||||
|
||||
},
|
||||
_onFieldChange: function (event) {
|
||||
CartActions.changeDeliveryDestinationProperty(event.target.name, event.target.value);
|
||||
if(event.target.name === "gift") {
|
||||
CartActions.changeDeliveryDestinationProperty(event.target.name, $(event.target).is(':checked'));
|
||||
} else {
|
||||
CartActions.changeDeliveryDestinationProperty(event.target.name, event.target.value);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
_onOrderClick: function (event) {
|
||||
CartActions.changeDeliveryDestinationProperty("payment_method", "cash_on_delivery");
|
||||
CartActions.confirmDelivery();
|
||||
},
|
||||
|
||||
@@ -155,6 +266,16 @@ var CheckoutPage = React.createClass({
|
||||
CartActions.setAddressColapsed(false);
|
||||
},
|
||||
|
||||
_onGiftBtnClicked: function (event) {
|
||||
CartActions.changeDeliveryDestinationProperty('gift', true);
|
||||
CartActions.setAddressColapsed(false);
|
||||
},
|
||||
|
||||
_handleOnSubmitPaypal: function(event) {
|
||||
CartActions.changeDeliveryDestinationProperty('payment_method', 'paypal');
|
||||
return false;
|
||||
},
|
||||
|
||||
getInitialState: function () {
|
||||
return CartStore.getWholeCartState();
|
||||
}
|
||||
@@ -162,4 +283,4 @@ var CheckoutPage = React.createClass({
|
||||
});
|
||||
|
||||
|
||||
module.exports = CheckoutPage;
|
||||
module.exports = CheckoutPage;
|
||||
|
||||
17
front-ui/app/components/payment/cashOnDeliveryButton.js
Normal file
17
front-ui/app/components/payment/cashOnDeliveryButton.js
Normal file
@@ -0,0 +1,17 @@
|
||||
var React = require('react');
|
||||
var ItemActions = require('../../actions/itemActions');
|
||||
var NavigationActions = require('../../actions/navigationActions');
|
||||
var NavigationStore = require('../../stores/navigationStore');
|
||||
|
||||
var Globals = require('../../globals');
|
||||
var Router = require('react-router');
|
||||
|
||||
var CashOnDeliveryButton = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<button type="button" className="btn mybutton payment-btn" disabled={this.props.disabled} onClick={this.props.onCashClick}>Plati prilikom preuzimanja</button>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = CashOnDeliveryButton;
|
||||
36
front-ui/app/components/payment/paymentSelect.js
Normal file
36
front-ui/app/components/payment/paymentSelect.js
Normal file
@@ -0,0 +1,36 @@
|
||||
var React = require('react');
|
||||
var ItemActions = require('../../actions/itemActions');
|
||||
var NavigationActions = require('../../actions/navigationActions');
|
||||
var NavigationStore = require('../../stores/navigationStore');
|
||||
|
||||
var Globals = require('../../globals');
|
||||
var Router = require('react-router');
|
||||
var PaypalButton = require('./paypalButton');
|
||||
var PikpaylButton = require('./pikpayButton');
|
||||
var CashOnDeliveryButton = require('./cashOnDeliveryButton');
|
||||
|
||||
var PaymentSelect = React.createClass({
|
||||
render: function() {
|
||||
var cashOnDeliveryBtn = ( <CashOnDeliveryButton onCashClick={this.props.onCashClick} disabled={this.props.cashOnDeliveryDisabled} cartId={this.props.cartId}/> );
|
||||
var pikpayBtn = ( <PikpaylButton amount={this.props.amount} deliveryCost={this.props.deliveryCost} disabled={this.props.disabled} deliveryDestination={this.props.deliveryDestination} cartId={this.props.cartId}/> );
|
||||
var paypalBtn = ( <PaypalButton disabled={this.props.disabled} deliveryDestination={this.props.deliveryDestination} amount={this.props.amount} deliveryCost={this.props.deliveryCost} cartId={this.props.cartId}/> );
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="payment_select btn-group payment-select-desktop hidden-xs">
|
||||
{cashOnDeliveryBtn}
|
||||
{pikpayBtn}
|
||||
{paypalBtn}
|
||||
</div>
|
||||
|
||||
<div className="payment_select btn-group-vertical payment-select-mobile visible-xs">
|
||||
{cashOnDeliveryBtn}
|
||||
{pikpayBtn}
|
||||
{paypalBtn}
|
||||
</div>
|
||||
</div>);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
module.exports = PaymentSelect;
|
||||
62
front-ui/app/components/payment/paypalButton.js
Normal file
62
front-ui/app/components/payment/paypalButton.js
Normal file
@@ -0,0 +1,62 @@
|
||||
var React = require('react');
|
||||
var ItemActions = require('../../actions/itemActions');
|
||||
var NavigationActions = require('../../actions/navigationActions');
|
||||
var NavigationStore = require('../../stores/navigationStore');
|
||||
var CartStore = require('../../stores/cartStore');
|
||||
var CartActions = require('../../actions/cartActions');
|
||||
|
||||
var Globals = require('../../globals');
|
||||
var Router = require('react-router');
|
||||
|
||||
var PaypalButton = React.createClass({
|
||||
render: function() {
|
||||
var deliveryDestination = JSON.stringify(
|
||||
{
|
||||
'anonymous_id_string': this.props.deliveryDestination.get('anonymous_id_string'),
|
||||
'user_id': this.props.deliveryDestination.get('user_id')
|
||||
});
|
||||
var amount = Globals.ConvertToEuro(this.props.amount);
|
||||
var deliveryCost = Globals.ConvertToEuro(this.props.deliveryCost);
|
||||
var root = location.protocol + '//' + location.host;
|
||||
var return_url = root + "/hvala";
|
||||
var cancel_return_url = root + "/dostava";
|
||||
var notifyUrl = Globals.IsUrlAbsolute(Globals.ApiUrl) ? Globals.ApiUrl : root + Globals.ApiUrl;
|
||||
notifyUrl += "/payment/confirmation";
|
||||
|
||||
return (
|
||||
<button onClick={this._onPaypalClick} disabled={this.props.disabled} type="button" className="btn mybutton payment-btn">Paypal
|
||||
<form id="paypal_form" className="hidden" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
|
||||
<input type="hidden" name="cmd" value="_xclick" />
|
||||
<input type="hidden" name="business" value={Globals.PaypalId} />
|
||||
<input type="hidden" name="lc" value="BA" />
|
||||
<input type="hidden" name="item_name" value="Item" />
|
||||
<input type="hidden" name="item_number" value={this.props.cartId} />
|
||||
<input type="hidden" name="amount" value={amount} />
|
||||
<input type="hidden" name="currency_code" value="EUR" />
|
||||
<input type="hidden" name="button_subtype" value="services" />
|
||||
<input type="hidden" name="no_note" value="0" />
|
||||
<input type="hidden" name="cn" value="Napomena:" />
|
||||
<input type="hidden" name="no_shipping" value="1" />
|
||||
<input type="hidden" name="rm" value="1" />
|
||||
<input type="hidden" name="return" value={return_url} />
|
||||
<input type="hidden" name="cancel_return" value={cancel_return_url} />
|
||||
<input type="hidden" name="shipping" value={deliveryCost} />
|
||||
<input type="hidden" name="bn" value="PP-BuyNowBF:btn_buynowCC_LG.gif:NonHosted" />
|
||||
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynowCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" />
|
||||
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1" />
|
||||
<input name="notify_url" value={notifyUrl} type="hidden" />
|
||||
<input name="custom" value={deliveryDestination} type="hidden" />
|
||||
</form>
|
||||
</button>
|
||||
);
|
||||
},
|
||||
_onPaypalClick: function(e) {
|
||||
CartActions.changeDeliveryDestinationProperty('payment_method', 'paypal');
|
||||
CartStore.saveDeliveryDestinationAnd(function() {
|
||||
$("#paypal_form").submit();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
module.exports = PaypalButton;
|
||||
64
front-ui/app/components/payment/pikpayButton.js
Normal file
64
front-ui/app/components/payment/pikpayButton.js
Normal file
@@ -0,0 +1,64 @@
|
||||
var React = require('react');
|
||||
var ItemActions = require('../../actions/itemActions');
|
||||
var NavigationActions = require('../../actions/navigationActions');
|
||||
var NavigationStore = require('../../stores/navigationStore');
|
||||
var CartStore = require('../../stores/cartStore');
|
||||
var CartActions = require('../../actions/cartActions');
|
||||
|
||||
var Globals = require('../../globals');
|
||||
var Router = require('react-router');
|
||||
var sha1 = require('sha1');
|
||||
|
||||
var PikpayButton = React.createClass({
|
||||
render: function() {
|
||||
var total = this.props.amount + this.props.deliveryCost;
|
||||
total = total.toFixed(2) * 100;
|
||||
var order_info = "Info";
|
||||
var order_number = this.props.cartId;
|
||||
var key = Globals.PikpayKey;
|
||||
var authenticity_token = Globals.PikpayAuthenticityToken;
|
||||
var digest = sha1(key + order_number + total + "BAM");
|
||||
var rebate_digest = sha1(key + order_number + total + total + "BAM");
|
||||
var deliveryDestination = this.props.deliveryDestination;
|
||||
var city = CartStore.getNameOfThePlace(deliveryDestination.get('place'));
|
||||
var custom = JSON.stringify(
|
||||
{
|
||||
'anonymous_id_string': deliveryDestination.get('anonymous_id_string'),
|
||||
'user_id': deliveryDestination.get('user_id')
|
||||
});
|
||||
|
||||
return (<span></span> /*
|
||||
<button type="button" onClick={this._onPikpayClick} disabled={this.props.disabled} className="btn mybutton payment-btn">Plati karticom
|
||||
<form id="pikpay_form" action={Globals.PikpayFormUrl} method="post" target="_top">
|
||||
<input type="hidden" name="ch_full_name" value={deliveryDestination.get('name')} />
|
||||
<input type="hidden" name="ch_address" value={deliveryDestination.get('address')} />
|
||||
<input type="hidden" name="ch_city" value={city} />
|
||||
<input type="hidden" name="ch_zip" value={deliveryDestination.get('place')} />
|
||||
<input type="hidden" name="ch_country" value="Bosna i Hercegovina" />
|
||||
<input type="hidden" name="ch_phone" value={deliveryDestination.get('phone')} />
|
||||
<input type="hidden" name="ch_email" value={deliveryDestination.get('email')} />
|
||||
|
||||
<input type="hidden" name="order_info" value={order_info} />
|
||||
<input type="hidden" name="order_number" value={order_number} />
|
||||
<input type="hidden" name="amount" value={total} />
|
||||
<input type="hidden" name="currency" value="BAM" />
|
||||
<input type="hidden" name="original_amount" value={total} />
|
||||
<input type="hidden" name="language" value="hr" />
|
||||
<input type="hidden" name="transaction_type" value="authorize" />
|
||||
<input type="hidden" name="authenticity_token" value={authenticity_token} />
|
||||
<input type="hidden" name="digest" value={digest} />
|
||||
<input type="hidden" name="rebate_digest" value={rebate_digest} />
|
||||
<input type="hidden" name="custom_params" value={custom} />
|
||||
</form>
|
||||
</button> */
|
||||
);
|
||||
},
|
||||
_onPikpayClick: function(e) {
|
||||
CartActions.changeDeliveryDestinationProperty('payment_method', 'pikpay');
|
||||
CartStore.saveDeliveryDestinationAnd(function() {
|
||||
$("#pikpay_form").submit();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = PikpayButton;
|
||||
@@ -34,7 +34,8 @@ var SearchBox = React.createClass({
|
||||
},
|
||||
onKeyPress: function(e) {
|
||||
var enterKeyCode = 13;
|
||||
if(e.which == enterKeyCode) {
|
||||
var whichKey = e.key || e.which;
|
||||
if(whichKey == enterKeyCode) {
|
||||
this.doSearch();
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
.checkout_form_margin {
|
||||
margin-right: 10px !important;
|
||||
margin-left: 10px !important;
|
||||
|
||||
}
|
||||
|
||||
.payment-select-container {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.payment-select-desktop .payment-btn {
|
||||
margin-right: 10px !important;;
|
||||
}
|
||||
|
||||
.payment-select-mobile .payment-btn {
|
||||
margin-bottom: 6px !important;
|
||||
}
|
||||
|
||||
.collapsed-address-container .mybutton {
|
||||
margin-top: 0px !important;
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.collapsed-address-container-mobile button {
|
||||
margin-bottom: 6px !important;
|
||||
margin-left: 10% !important;
|
||||
margin-right: 10% !important;
|
||||
width: 80% !important;
|
||||
}
|
||||
|
||||
.gift-btn {
|
||||
width: 200px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
@@ -1,95 +1,77 @@
|
||||
@import url(http://fonts.googleapis.com/css?family=Roboto:400,300italic,300,100italic,100,400italic,500,500italic,700italic,700,900,900italic);
|
||||
|
||||
/* site */
|
||||
|
||||
html {
|
||||
overflow-y: scroll;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
body{
|
||||
background: url("https://res.cloudinary.com/du5pdibul/image/upload/v1428813560/bg_prp6pz.jpg") fixed 100% 100% ;
|
||||
background-size: cover ;
|
||||
background-position: center ;
|
||||
background-repeat: no-repeat;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
|
||||
background: url("https://res.cloudinary.com/du5pdibul/image/upload/v1428813560/bg_prp6pz.jpg") fixed 100% 100% ;
|
||||
background-size: cover ;
|
||||
background-position: center ;
|
||||
background-repeat: no-repeat;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
}
|
||||
|
||||
#left-nave {
|
||||
|
||||
background: blue;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
height: 100%;
|
||||
width: 250px;
|
||||
|
||||
}
|
||||
.beba{
|
||||
background: url("https://res.cloudinary.com/du5pdibul/image/upload/v1428813559/beba-bg_wip7kj.png");
|
||||
background-size: cover;
|
||||
background: url("https://res.cloudinary.com/du5pdibul/image/upload/v1428813559/beba-bg_wip7kj.png");
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
html, body { height: 100%; width: 100%; margin: 0; }
|
||||
|
||||
h1 h2 h3 h4 h5{
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
}
|
||||
|
||||
.col-centered{
|
||||
float: none;
|
||||
margin: 5% auto;
|
||||
float: none;
|
||||
margin: 5% auto;
|
||||
}
|
||||
|
||||
|
||||
.mybutton{
|
||||
background-color: #00a8a8;
|
||||
padding: 6px 11px !important;
|
||||
border-radius: 3px;
|
||||
margin-top: 8px;
|
||||
border: solid #06c3c3 1px;
|
||||
color: #ffffff !important;
|
||||
background-color: #00a8a8;
|
||||
padding: 6px 11px !important;
|
||||
border-radius: 3px;
|
||||
margin-top: 8px;
|
||||
border: solid #06c3c3 1px;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
|
||||
.mybutton:hover {
|
||||
background-color: #06c3c3 !important;
|
||||
padding: 6px 11px !important;
|
||||
color: black !important;
|
||||
border-radius: 3px;
|
||||
margin-top: 8px;
|
||||
border: solid #06c3c3 1px;
|
||||
color: #ffffff !important;
|
||||
background-color: #06c3c3 !important;
|
||||
padding: 6px 11px !important;
|
||||
color: black !important;
|
||||
border-radius: 3px;
|
||||
margin-top: 8px;
|
||||
border: solid #06c3c3 1px;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
.add-to-cart-button {
|
||||
background-color: #00a8a8;
|
||||
padding: 6px 11px !important;
|
||||
border-radius: 3px;
|
||||
border: solid #06c3c3 1px;
|
||||
color: #ffffff !important;
|
||||
background-color: #00a8a8;
|
||||
padding: 6px 11px !important;
|
||||
border-radius: 3px;
|
||||
border: solid #06c3c3 1px;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
.add-to-cart-button:hover {
|
||||
background-color: #06c3c3 !important;
|
||||
padding: 6px 11px !important;
|
||||
color: black !important;
|
||||
border-radius: 3px;
|
||||
border: solid #06c3c3 1px;
|
||||
color: #ffffff !important;
|
||||
background-color: #06c3c3 !important;
|
||||
padding: 6px 11px !important;
|
||||
color: black !important;
|
||||
border-radius: 3px;
|
||||
border: solid #06c3c3 1px;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
a{
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-weight: bold;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-weight: bold;
|
||||
}
|
||||
.mynav li{
|
||||
display: inline-block;
|
||||
display: inline-block;
|
||||
}
|
||||
.mynav {
|
||||
margin-top: 6px;
|
||||
|
||||
text-align: center;
|
||||
text-align: center;
|
||||
}
|
||||
.mynav a{
|
||||
text-decoration: none;
|
||||
@@ -108,27 +90,24 @@ text-decoration: none;
|
||||
color: #06c3c3;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.mynav li .mybutton {
|
||||
background-color: #00a8a8;
|
||||
padding: 4px 10px !important;
|
||||
margin-top: 6px;
|
||||
display: block;
|
||||
border-radius: 3px;
|
||||
border: solid #06c3c3 1px;
|
||||
color: #ffffff;
|
||||
background-color: #00a8a8;
|
||||
padding: 4px 10px !important;
|
||||
margin-top: 6px;
|
||||
display: block;
|
||||
border-radius: 3px;
|
||||
border: solid #06c3c3 1px;
|
||||
color: #ffffff;
|
||||
}
|
||||
.mynav li .mybutton:hover {
|
||||
background-color: #06c3c3;
|
||||
padding: 4px 10px !important;
|
||||
margin-top: 6px;
|
||||
display: block;
|
||||
border-radius: 3px;
|
||||
border: solid #06c3c3 1px;
|
||||
color: #ffffff;
|
||||
background-color: #06c3c3;
|
||||
padding: 4px 10px !important;
|
||||
margin-top: 6px;
|
||||
display: block;
|
||||
border-radius: 3px;
|
||||
border: solid #06c3c3 1px;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
|
||||
.productbox{
|
||||
cursor: pointer;
|
||||
-moz-box-shadow: 1px 2px 2px #cccccc;
|
||||
@@ -143,219 +122,181 @@ margin-bottom: 35px;
|
||||
height: auto;
|
||||
border-bottom: solid gray 1px;
|
||||
width: 100%;
|
||||
|
||||
|
||||
}
|
||||
.productbox div{
|
||||
padding: 4px 10px;
|
||||
|
||||
|
||||
}
|
||||
.productbox a{
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
|
||||
|
||||
text-decoration: none;
|
||||
}
|
||||
.productbox a:hover{
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
text-decoration: none;
|
||||
text-decoration: underline;
|
||||
|
||||
}
|
||||
.productbox div span{
|
||||
color: black;
|
||||
|
||||
|
||||
|
||||
}
|
||||
#beba{
|
||||
padding-left: 45px;
|
||||
padding-right: 45px;
|
||||
margin-left: -23px;
|
||||
margin-right: -23px;
|
||||
|
||||
padding-left: 45px;
|
||||
padding-right: 45px;
|
||||
margin-left: -23px;
|
||||
margin-right: -23px;
|
||||
}
|
||||
#beba:hover{
|
||||
background: url("https://res.cloudinary.com/du5pdibul/image/upload/v1428813559/beba-bg_wip7kj.png");
|
||||
background-position: center ;
|
||||
background-size: 100% 100%;
|
||||
color: white;
|
||||
background-repeat: no-repeat;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
#dijete:hover{
|
||||
background: url("https://res.cloudinary.com/du5pdibul/image/upload/v1428813559/dijete-bg_gff80o.png");
|
||||
background-position: center ;
|
||||
background-size: 100% 100%;
|
||||
color: white;
|
||||
background-repeat: no-repeat;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
#dijete:hover a{
|
||||
|
||||
color: white;
|
||||
|
||||
}
|
||||
#mama:hover{
|
||||
background: url("https://res.cloudinary.com/du5pdibul/image/upload/v1428813559/mama-bg_rqbnuo.png");
|
||||
background-position: center ;
|
||||
background-size: 100% 100%;
|
||||
color: white;
|
||||
background-repeat: no-repeat;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
#mama:hover a{
|
||||
|
||||
color: white;
|
||||
|
||||
}
|
||||
#madeinbih:hover{
|
||||
background: url("https://res.cloudinary.com/du5pdibul/image/upload/v1428813559/made-in-bih-bg_uusqpm.png");
|
||||
background-position: center ;
|
||||
background-size: 100% 100%;
|
||||
color: white;
|
||||
background-repeat: no-repeat;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
#madeinbih:hover a{
|
||||
|
||||
color: white;
|
||||
|
||||
}
|
||||
#onama:hover{
|
||||
background: url("https://res.cloudinary.com/du5pdibul/image/upload/v1428813559/made-in-bih-bg_uusqpm.png");
|
||||
background-position: center ;
|
||||
background-size: 100% 100%;
|
||||
color: white;
|
||||
background-repeat: no-repeat;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
#onama:hover a{
|
||||
|
||||
color: white;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#marka:hover{
|
||||
background: url("https://res.cloudinary.com/du5pdibul/image/upload/v1428813559/marka-bg_cy8hpe.png");
|
||||
background-position: center ;
|
||||
background-size: 100% 100%;
|
||||
color: white;
|
||||
background-repeat: no-repeat;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
#marka:hover a{
|
||||
|
||||
color: white;
|
||||
|
||||
}
|
||||
#akcija:hover{
|
||||
background: url("https://res.cloudinary.com/du5pdibul/image/upload/v1428813559/akcija-bg_xtawus.png");
|
||||
background-position: center ;
|
||||
background-size: 100% 100%;
|
||||
color: white;
|
||||
background-repeat: no-repeat;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
#akcija:hover a{
|
||||
|
||||
color: white;
|
||||
|
||||
}
|
||||
|
||||
.mydropdown li:hover .sub-menu {
|
||||
visibility: visible;
|
||||
display: block;
|
||||
visibility: visible;
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
.mydropdown:hover .dropdown-menu {
|
||||
display: block;
|
||||
visibility: visible;
|
||||
display: block;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.navbar-default{
|
||||
color: black;
|
||||
background-color: white;
|
||||
border-color: lightgray;
|
||||
}
|
||||
.navbar-default .navbar-nav > li > a{
|
||||
color:black;
|
||||
|
||||
color:black;
|
||||
}
|
||||
|
||||
.navbar-default .navbar-nav > li{
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
.navbar-default .navbar-nav > li > a:focus{
|
||||
background-color: rgba(255, 255, 255, 0.6) !important;
|
||||
-moz-box-shadow: 0px 0px 2px #999;
|
||||
background-color: rgba(255, 255, 255, 0.6) !important;
|
||||
-moz-box-shadow: 0px 0px 2px #999;
|
||||
-webkit-box-shadow: 0px 0px 2px #999;
|
||||
box-shadow: 0px 0px 2px #999;
|
||||
|
||||
border: none !important;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.navbar-default .navbar-nav > .dropdown > a .caret{
|
||||
border-top-color: #fff;
|
||||
border-bottom-color: #fff;
|
||||
border-top-color: #fff;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
.navbar-default .navbar-brand{
|
||||
color:#fff;
|
||||
color:#fff;
|
||||
}
|
||||
.menu-large {
|
||||
position: static !important;
|
||||
position: static !important;
|
||||
}
|
||||
.megamenu{
|
||||
padding: 20px 0px;
|
||||
width:94%;
|
||||
margin-left: 3%;
|
||||
border-top: none !important;
|
||||
-moz-box-shadow: 0px 1px 2px #999;
|
||||
padding: 20px 0px;
|
||||
width:94%;
|
||||
margin-left: 3%;
|
||||
border-top: none !important;
|
||||
-moz-box-shadow: 0px 1px 2px #999;
|
||||
-webkit-box-shadow: 0px 1px 2px #999;
|
||||
box-shadow: 0px 1px 2px #999;
|
||||
}
|
||||
.megamenu> li > ul {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.megamenu> li > ul > li {
|
||||
list-style: none;
|
||||
padding-left: 10px;
|
||||
list-style: none;
|
||||
padding-left: 10px;
|
||||
}
|
||||
.megamenu> li > ul > li > a {
|
||||
display: block;
|
||||
padding: 3px 20px;
|
||||
clear: both;
|
||||
font-weight: normal;
|
||||
line-height: 1.428571429;
|
||||
color: black;
|
||||
white-space: normal;
|
||||
display: block;
|
||||
padding: 3px 20px;
|
||||
clear: both;
|
||||
font-weight: normal;
|
||||
line-height: 1.428571429;
|
||||
color: black;
|
||||
white-space: normal;
|
||||
}
|
||||
.megamenu> li ul > li > a:hover,
|
||||
.megamenu> li ul > li > a:focus {
|
||||
text-decoration: none;
|
||||
color: #262626;
|
||||
background-color: #f5f5f5;
|
||||
text-decoration: none;
|
||||
color: #262626;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.megamenu.disabled > a,
|
||||
.megamenu.disabled > a:hover,
|
||||
.megamenu.disabled > a:focus {
|
||||
color: #999999;
|
||||
color: #999999;
|
||||
}
|
||||
.megamenu.disabled > a:hover,
|
||||
.megamenu.disabled > a:focus {
|
||||
text-decoration: none;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
cursor: not-allowed;
|
||||
text-decoration: none;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.megamenu.dropdown-header {
|
||||
color: #428bca;
|
||||
font-size: 18px;
|
||||
|
||||
color: #428bca;
|
||||
font-size: 18px;
|
||||
}
|
||||
.dropdown-header p {
|
||||
border-bottom: solid 1.5px lightgray !important;
|
||||
@@ -363,193 +304,188 @@ margin-bottom: 2px;
|
||||
text-transform: uppercase;
|
||||
color: black;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
}
|
||||
.mycart{
|
||||
position: absolute;
|
||||
position: absolute;
|
||||
background: url("https://res.cloudinary.com/du5pdibul/image/upload/v1428813559/cart-icon_p9u63r.png");
|
||||
background-position: center center;
|
||||
background-size: cover;
|
||||
|
||||
background-repeat: no-repeat;
|
||||
width: 42px;
|
||||
height: 44px;
|
||||
padding-bottom: 0px;
|
||||
right:-14px;
|
||||
bottom: -15px;
|
||||
text-align: right;
|
||||
|
||||
background-repeat: no-repeat;
|
||||
width: 42px;
|
||||
height: 44px;
|
||||
padding-bottom: 0px;
|
||||
right:-14px;
|
||||
bottom: -15px;
|
||||
text-align: right;
|
||||
}
|
||||
.mycart div {
|
||||
text-align: right;
|
||||
text-align: right;
|
||||
}
|
||||
.mycart span{
|
||||
position: absolute;
|
||||
left: 13.4px;
|
||||
top: 4px;
|
||||
color: #ffffff;
|
||||
|
||||
}
|
||||
.mycart span:hover{
|
||||
|
||||
color: white;
|
||||
}
|
||||
#myhome{
|
||||
border-bottom: solid #06c3c3 1px;
|
||||
border-bottom: solid #06c3c3 1px;
|
||||
}
|
||||
#myhome-hover:hover {
|
||||
border-bottom: solid #06c3c3 1px;
|
||||
|
||||
#myhome-hover:hover {
|
||||
border-bottom: solid #06c3c3 1px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.sidebar ul{
|
||||
list-style: none;
|
||||
list-style: none;
|
||||
}
|
||||
.sidebar li{
|
||||
margin-left:10px;
|
||||
margin-bottom: 5px;
|
||||
color:black;
|
||||
padding: 10px;
|
||||
border-bottom: solid 1px lightgray;
|
||||
|
||||
margin-left:10px;
|
||||
margin-bottom: 5px;
|
||||
color:black;
|
||||
padding: 10px;
|
||||
border-bottom: solid 1px lightgray;
|
||||
}
|
||||
.sidebar li a{
|
||||
text-decoration: none;
|
||||
color:black;
|
||||
color:black;
|
||||
}
|
||||
.sidebar li a:hover{
|
||||
|
||||
color:#06c3c3;
|
||||
color:#06c3c3;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.megamenu{
|
||||
margin-left: 0 ;
|
||||
margin-right: 0 ;
|
||||
}
|
||||
.megamenu> li {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.megamenu> li:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.megamenu.dropdown-header {
|
||||
padding: 3px 15px !important;
|
||||
|
||||
}
|
||||
.navbar-nav .open .dropdown-menu .dropdown-header{
|
||||
color:#fff;
|
||||
}
|
||||
.megamenu{
|
||||
margin-left: 0 ;
|
||||
margin-right: 0 ;
|
||||
}
|
||||
.megamenu> li {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.megamenu> li:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.megamenu.dropdown-header {
|
||||
padding: 3px 15px !important;
|
||||
}
|
||||
.navbar-nav .open .dropdown-menu .dropdown-header{
|
||||
color:#fff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
.navbar-header {
|
||||
float: none;
|
||||
}
|
||||
.navbar-toggle {
|
||||
display: block;
|
||||
|
||||
}
|
||||
.navbar-collapse {
|
||||
|
||||
box-shadow: inset 0 1px 0 rgba(255,255,255,0.1);
|
||||
border-top:none !important;
|
||||
}
|
||||
.navbar-collapse.collapse {
|
||||
display: none!important;
|
||||
}
|
||||
|
||||
.navbar-nav>li {
|
||||
float: none;
|
||||
|
||||
}
|
||||
.navbar-nav>ul {
|
||||
margin-bottom: 0px;
|
||||
|
||||
}
|
||||
.navbar-nav>li>a {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
|
||||
}
|
||||
.navbar-text {
|
||||
float: none;
|
||||
margin: 15px 0;
|
||||
}
|
||||
/* since 3.1.0 */
|
||||
.navbar-collapse.collapse.in {
|
||||
display: block!important;
|
||||
}
|
||||
.collapsing {
|
||||
overflow: hidden!important;
|
||||
}
|
||||
.navbar-header {
|
||||
float: none;
|
||||
}
|
||||
.navbar-toggle {
|
||||
display: block;
|
||||
}
|
||||
.navbar-collapse {
|
||||
box-shadow: inset 0 1px 0 rgba(255,255,255,0.1);
|
||||
border-top:none !important;
|
||||
}
|
||||
.navbar-collapse.collapse {
|
||||
display: none!important;
|
||||
}
|
||||
.navbar-nav>li {
|
||||
float: none;
|
||||
}
|
||||
.navbar-nav>ul {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
.navbar-nav>li>a {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.navbar-text {
|
||||
float: none;
|
||||
margin: 15px 0;
|
||||
}
|
||||
/* since 3.1.0 */
|
||||
.navbar-collapse.collapse.in {
|
||||
display: block!important;
|
||||
}
|
||||
.collapsing {
|
||||
overflow: hidden!important;
|
||||
}
|
||||
}
|
||||
|
||||
.error-message {
|
||||
color: red;
|
||||
color: red;
|
||||
}
|
||||
|
||||
.white_button{
|
||||
background-color: #f9f9f9;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
padding-bottom: 7px;
|
||||
/*display: block;*/
|
||||
border-radius: 1px;
|
||||
margin-top: 8px;
|
||||
border: solid #cccccc 1px;
|
||||
color: #4d4d4d !important;
|
||||
font-size: 16px;
|
||||
background-color: #f9f9f9;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
padding-bottom: 7px;
|
||||
/*display: block;*/
|
||||
border-radius: 1px;
|
||||
margin-top: 8px;
|
||||
border: solid #cccccc 1px;
|
||||
color: #4d4d4d !important;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
background-color: #efefef;
|
||||
border-radius: 0px;
|
||||
border: 1px solid #cccccc;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
background-color: #efefef;
|
||||
border-radius: 0px;
|
||||
border: 1px solid #cccccc;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.search-button {
|
||||
background-color: #f9f9f9;
|
||||
color: #31b8b8;
|
||||
border: 1px solid #cccccc;
|
||||
border-radius: 0px;
|
||||
margin-left: 5px;
|
||||
background-color: #f9f9f9;
|
||||
color: #31b8b8;
|
||||
border: 1px solid #cccccc;
|
||||
border-radius: 0px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.qty-box {
|
||||
background-color: #efefef;
|
||||
border-radius: 0px;
|
||||
border: 1px solid #cccccc;
|
||||
background-color: #efefef;
|
||||
border-radius: 0px;
|
||||
border: 1px solid #cccccc;
|
||||
}
|
||||
|
||||
.left-inner-addon {
|
||||
position: relative;
|
||||
position: relative;
|
||||
}
|
||||
.left-inner-addon input {
|
||||
padding-left: 30px;
|
||||
padding-left: 30px;
|
||||
}
|
||||
.left-inner-addon i {
|
||||
position: absolute;
|
||||
padding: 10px 12px;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
padding: 10px 12px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.cart-title {
|
||||
font-size: 29px;
|
||||
color: #06c3c3;
|
||||
font-size: 29px;
|
||||
color: #06c3c3;
|
||||
}
|
||||
|
||||
.footer {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
bottom: 20px;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
bottom: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.message {
|
||||
font-size: 130%;
|
||||
text-align: left;
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.payment {
|
||||
box-sizing: border-box;
|
||||
color: rgb(102, 102, 102);
|
||||
display: block;
|
||||
font-family: Helvetica, arial, nimbussansl, liberationsans, freesans, clean, sans-serif, 'Segoe UI Emoji', 'Segoe UI Symbol';
|
||||
font-size: 13px;
|
||||
font-style: normal;
|
||||
font-variant: normal;
|
||||
font-weight: normal;
|
||||
height: 36px;
|
||||
line-height: 18.2px;
|
||||
width: 708px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.message {
|
||||
@@ -568,3 +504,4 @@ text-decoration: none;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
var conversionRate = 0.51;
|
||||
|
||||
module.exports = {
|
||||
ApiUrl: '@@apiEndpoint',
|
||||
DefaultPageSize: 24,
|
||||
ItemGroupIdOfStartPage: "1",
|
||||
ItemGroupIdOfEmptyCartPage: "1",
|
||||
BamToEuroConversionRate: conversionRate,
|
||||
FormatCurrency: function(amount_s) {
|
||||
var amount = parseFloat(amount_s);
|
||||
return (amount.toFixed(2) + " KM")
|
||||
@@ -11,7 +14,19 @@ module.exports = {
|
||||
var amount = parseFloat(amount_s);
|
||||
return (amount.toFixed(2) + "%")
|
||||
},
|
||||
ConvertToEuro: function(amount_s) {
|
||||
amount = amount_s * conversionRate;
|
||||
return amount.toFixed(2);
|
||||
},
|
||||
IsUrlAbsolute: function(url) {
|
||||
var r = new RegExp('^(?:[a-z]+:)?//', 'i');
|
||||
return r.test(url);
|
||||
},
|
||||
MaxNumberOfItemsToBeAdded: 1000,
|
||||
PaypalId: "W7GKS2Q9ZGLGY",
|
||||
PikpayFormUrl: "https://ipgtest.pikpay.ba/form",
|
||||
PikpayAuthenticityToken: "1bb1eea16bd6492c01262636897c0c2e3291a1ab",
|
||||
PikpayKey: "Ribica",
|
||||
|
||||
Slugify: function(text) {
|
||||
return text.toString().toLowerCase()
|
||||
|
||||
@@ -14,9 +14,9 @@ var DeliveryDestination = Backbone.Model.extend({
|
||||
},
|
||||
|
||||
url: Globals.ApiUrl + '/cart/delivery_destination',
|
||||
defaults: {
|
||||
defaults: {
|
||||
count: 0
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = DeliveryDestination;
|
||||
module.exports = DeliveryDestination;
|
||||
|
||||
@@ -48,8 +48,8 @@ var router = Router.create({
|
||||
location: Router.HistoryLocation
|
||||
});
|
||||
|
||||
router.run(function (Handler, state) {
|
||||
|
||||
router.run(function (Handler, state) {
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ var DeliveryDestination = require('../models/deliveryDestination');
|
||||
var OrderConfirmation = require('../models/orderConfirmation');
|
||||
var Place = require('../models/place');
|
||||
var Validation = require('../utils/validation');
|
||||
var Cart = require('../models/cart');
|
||||
|
||||
var _ = require('underscore');
|
||||
|
||||
@@ -23,11 +24,12 @@ var _deliveryDestination = new DeliveryDestination();
|
||||
var _deliveryDestinationErrors = {};
|
||||
var _deliveryCosts = new Place({
|
||||
postalCode: _deliveryDestination.get('place')
|
||||
})
|
||||
});
|
||||
|
||||
var _cart = new Cart();
|
||||
|
||||
var _addressColapsed = false;
|
||||
|
||||
|
||||
var supportedPlaces = [{
|
||||
"code": "-12",
|
||||
"placeLabel": "Izaberite mjesto"
|
||||
@@ -37,7 +39,7 @@ var supportedPlaces = [{
|
||||
}, {
|
||||
"code": " 71000",
|
||||
"placeLabel": "Sarajevo"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": " 78000",
|
||||
"placeLabel": "Banja Luka"
|
||||
@@ -50,7 +52,7 @@ var supportedPlaces = [{
|
||||
{
|
||||
"code": " 88000",
|
||||
"placeLabel": "Mostar"
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
"code": " 72000",
|
||||
@@ -2569,30 +2571,31 @@ var nameOfThePlace = function(code) {
|
||||
}
|
||||
|
||||
var loadCart = function() {
|
||||
_cart.fetch({success: function() {
|
||||
_itemsInCart.fetch({
|
||||
success: function() {
|
||||
states = {}
|
||||
for (var i = 0; i < _itemsInCart.models.length; i++) {
|
||||
var itemInCart = _itemsInCart.models[i];
|
||||
states[itemInCart.get('item_id')] = itemInCart;
|
||||
}
|
||||
_itemsForDisplay.fetch({
|
||||
success: function() {
|
||||
CartActions.dataLoaded();
|
||||
|
||||
_itemsInCart.fetch({
|
||||
success: function() {
|
||||
states = {}
|
||||
for (var i = 0; i < _itemsInCart.models.length; i++) {
|
||||
var itemInCart = _itemsInCart.models[i];
|
||||
states[itemInCart.get('item_id')] = itemInCart;
|
||||
}
|
||||
_itemsForDisplay.fetch({
|
||||
success: function() {
|
||||
CartActions.dataLoaded();
|
||||
|
||||
_deliveryDestination.fetch({
|
||||
success: function() {
|
||||
validateDeliveryDestinationForm();
|
||||
collapseAddressIfNeeded();
|
||||
fetchPlace();
|
||||
CartActions.dataLoaded();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
_deliveryDestination.fetch({
|
||||
success: function() {
|
||||
validateDeliveryDestinationForm();
|
||||
collapseAddressIfNeeded();
|
||||
fetchPlace();
|
||||
CartActions.dataLoaded();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}});
|
||||
|
||||
_cartDataLoadCalled = true;
|
||||
};
|
||||
@@ -2606,8 +2609,10 @@ var collapseAddressIfNeeded = function() {
|
||||
}
|
||||
|
||||
var fetchPlace = function() {
|
||||
postalCode = _deliveryDestination.get('gift') ? _deliveryDestination.get('recipient_place') : _deliveryDestination.get('place');
|
||||
|
||||
_deliveryCosts = new Place({
|
||||
postalCode: _deliveryDestination.get('place')
|
||||
postalCode: postalCode
|
||||
})
|
||||
_deliveryCosts.fetch({
|
||||
success: function() {
|
||||
@@ -2696,13 +2701,13 @@ var addNItems = function(item, count) {
|
||||
var changeDeliveryDestinationProperty = function(property, value) {
|
||||
_deliveryDestination.set(property, value);
|
||||
|
||||
if (property === 'place') {
|
||||
if (property === 'place' || property === 'recipient_place' || property === 'gift') {
|
||||
fetchPlace();
|
||||
}
|
||||
|
||||
validateDeliveryDestinationForm();
|
||||
};
|
||||
|
||||
|
||||
var confirmOrder = function() {
|
||||
|
||||
var oc = new OrderConfirmation({
|
||||
@@ -2719,14 +2724,20 @@ var confirmOrder = function() {
|
||||
});
|
||||
};
|
||||
|
||||
var saveDeliveryDestinationAnd = function(successCallback) {
|
||||
_deliveryDestination.save(null, {
|
||||
success: function() {
|
||||
successCallback();
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
var saveDeliveryDestination = function() {
|
||||
_deliveryDestination.save(null, {
|
||||
success: function() {
|
||||
|
||||
confirmOrder();
|
||||
}
|
||||
})
|
||||
success: function() {
|
||||
confirmOrder();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var validateDeliveryDestinationForm = function() {
|
||||
@@ -2757,7 +2768,34 @@ var validateDeliveryDestinationForm = function() {
|
||||
_deliveryDestinationErrors['place'] = "Mjesto mora biti izabrano";
|
||||
}
|
||||
|
||||
if(_deliveryDestination.get('gift')) {
|
||||
if (Validation.safeString(_deliveryDestination.get('recipient_name')).search(nameRegex) < 0) {
|
||||
_deliveryDestinationErrors['recipient_name'] = "I prezime i ime su obavezni";
|
||||
}
|
||||
|
||||
if (Validation.safeString(_deliveryDestination.get('recipient_address')).search(addressRegex) < 0) {
|
||||
_deliveryDestinationErrors['recipient_address'] = "Adresa mora biti ispravna";
|
||||
}
|
||||
|
||||
if (_deliveryDestination.get('recipient_email') && Validation.safeString(_deliveryDestination.get('recipient_email')).search(emailRegex) < 0) {
|
||||
_deliveryDestinationErrors['recipient_email'] = "Email mora biti ispravno upisan";
|
||||
}
|
||||
|
||||
if (Validation.safeString(_deliveryDestination.get('recipient_phone')).search(phoneRegex) < 0) {
|
||||
_deliveryDestinationErrors['recipient_phone'] = "Telefon mora biti ispravan";
|
||||
}
|
||||
|
||||
if (Validation.safeString(_deliveryDestination.get('recipient_place')).search(placeRegex) < 0) {
|
||||
_deliveryDestinationErrors['recipient_place'] = "Mjesto mora biti izabrano";
|
||||
}
|
||||
}
|
||||
|
||||
var requiredFields = ["name", "email", "place", 'address', 'phone'];
|
||||
|
||||
if(_deliveryDestination.get('gift')) {
|
||||
requiredFields = requiredFields.concat(["recipient_name", "recipient_place", 'recipient_address', 'recipient_phone']);
|
||||
}
|
||||
|
||||
for (var i in requiredFields) {
|
||||
var value = _deliveryDestination.get(requiredFields[i]);
|
||||
if (value === undefined || value === null || value === "") {
|
||||
@@ -2768,10 +2806,14 @@ var validateDeliveryDestinationForm = function() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
var isDeliveryDestinationValid = function() {
|
||||
return Object.getOwnPropertyNames(_deliveryDestinationErrors).length === 0;
|
||||
}
|
||||
return Object.getOwnPropertyNames(_deliveryDestinationErrors).length === 0;
|
||||
}
|
||||
|
||||
var getDeliveryCostTarget = function() {
|
||||
return _deliveryDestination.get("gift") ? "recipient_place" : "place";
|
||||
}
|
||||
|
||||
// Extend CartStore with EventEmitter to add eventing capabilities
|
||||
var CartStore = _.extend({}, EventEmitter.prototype, {
|
||||
|
||||
@@ -2792,6 +2834,29 @@ var CartStore = _.extend({}, EventEmitter.prototype, {
|
||||
return supportedPlaces;
|
||||
},
|
||||
|
||||
getAmount: function() {
|
||||
var counts = states;
|
||||
|
||||
var total = 0;
|
||||
|
||||
if (counts && _itemsForDisplay) {
|
||||
var items = _itemsForDisplay.models;
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var item = items[i];
|
||||
var count = counts[item.get('id')].get('count');
|
||||
var price = item.get('list_price');
|
||||
total += (price * count)
|
||||
};
|
||||
}
|
||||
|
||||
return total;
|
||||
},
|
||||
|
||||
getDeliveryCost: function(instantDelivery) {
|
||||
return instantDelivery ? Number(_deliveryCosts.get('instant_delivery_price'))
|
||||
: Number(_deliveryCosts.get('delivery_price'));
|
||||
},
|
||||
|
||||
getWholeCartState: function() {
|
||||
|
||||
var numberOfItems = 0;
|
||||
@@ -2813,7 +2878,10 @@ var CartStore = _.extend({}, EventEmitter.prototype, {
|
||||
deliveryDestinationErrors: _deliveryDestinationErrors,
|
||||
isDeliveryDestinationValid: isDeliveryDestinationValid(),
|
||||
deliveryCosts: _deliveryCosts,
|
||||
destinationValid: isDeliveryDestinationValid()
|
||||
destinationValid: isDeliveryDestinationValid(),
|
||||
address_colapsed: _addressColapsed,
|
||||
deliveryCostsTarget: getDeliveryCostTarget(),
|
||||
cart: _cart
|
||||
};
|
||||
return state;
|
||||
},
|
||||
@@ -2850,6 +2918,14 @@ var CartStore = _.extend({}, EventEmitter.prototype, {
|
||||
address.push(_deliveryDestination.get('email'))
|
||||
|
||||
return address;
|
||||
},
|
||||
|
||||
getNameOfThePlace: function(code) {
|
||||
return nameOfThePlace(code);
|
||||
},
|
||||
|
||||
saveDeliveryDestinationAnd: function(successCallback) {
|
||||
saveDeliveryDestinationAnd(successCallback);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>ribica.ba - ispunjava zelje</title>
|
||||
<title>ribica.ba - prvi online shop sa dostavom u BiH za mame i bebe - kupite igracke, pelene i ostalo</title>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
"react": "~0.12.2",
|
||||
"react-google-analytics": "^0.2.0",
|
||||
"react-router": "~0.11.6",
|
||||
"sha1": "^1.1.1",
|
||||
"superagent": "~0.21.0"
|
||||
}
|
||||
}
|
||||
|
||||
23
node_modules/ga-react-router/README.md
generated
vendored
23
node_modules/ga-react-router/README.md
generated
vendored
@@ -1,23 +0,0 @@
|
||||
# Google analytics for react-router
|
||||
|
||||
## How to use
|
||||
|
||||
1. `npm install ga-react-router`
|
||||
2. In your `webpack.config.js` add `new webpack.DefinePlugin({GA_TRACKING_CODE: JSON.stringify('XXXXXXXX')})`
|
||||
3. Use analytics in your `Router.run` code.
|
||||
|
||||
## Example
|
||||
|
||||
```js
|
||||
'use strict';
|
||||
var React = require('react');
|
||||
var Router = require('react-router');
|
||||
var analytics = require('ga-react-router');
|
||||
|
||||
var routes = require('./routes');
|
||||
|
||||
Router.run(routes, Router.HistoryLocation, function(Handler, state) {
|
||||
React.render(<Handler />, document.getElementById('content'));
|
||||
analytics(state);
|
||||
});
|
||||
```
|
||||
50
node_modules/ga-react-router/package.json
generated
vendored
50
node_modules/ga-react-router/package.json
generated
vendored
@@ -1,50 +0,0 @@
|
||||
{
|
||||
"name": "ga-react-router",
|
||||
"version": "1.3.0",
|
||||
"description": "Google analytics component for react-router",
|
||||
"main": "src/index.js",
|
||||
"peerDependencies": {
|
||||
"react-router": "0.11.x - 0.13.x"
|
||||
},
|
||||
"author": {
|
||||
"name": "Thomas Coopman @tcoopman"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+ssh://git@github.com/tcoopman/ga-react-router.git"
|
||||
},
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT",
|
||||
"url": "http://www.opensource.org/licenses/mit-license.php"
|
||||
}
|
||||
],
|
||||
"gitHead": "bd1a0c6d97aef76c38690de4278dec63da13fe9c",
|
||||
"bugs": {
|
||||
"url": "https://github.com/tcoopman/ga-react-router/issues"
|
||||
},
|
||||
"homepage": "https://github.com/tcoopman/ga-react-router#readme",
|
||||
"_id": "ga-react-router@1.3.0",
|
||||
"scripts": {},
|
||||
"_shasum": "28f51f27d5b0339db55499adf82265033cedc939",
|
||||
"_from": "ga-react-router@*",
|
||||
"_npmVersion": "2.8.3",
|
||||
"_nodeVersion": "1.8.1",
|
||||
"_npmUser": {
|
||||
"name": "tcoopman",
|
||||
"email": "thomas.coopman@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "tcoopman",
|
||||
"email": "thomas.coopman@gmail.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "28f51f27d5b0339db55499adf82265033cedc939",
|
||||
"tarball": "http://registry.npmjs.org/ga-react-router/-/ga-react-router-1.3.0.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/ga-react-router/-/ga-react-router-1.3.0.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
}
|
||||
31
node_modules/ga-react-router/src/ga.js
generated
vendored
31
node_modules/ga-react-router/src/ga.js
generated
vendored
@@ -1,31 +0,0 @@
|
||||
'use strict';
|
||||
if(typeof window !== 'undefined' && typeof GA_TRACKING_CODE !== 'undefined') {
|
||||
(function(window, document, script, url, r, tag, firstScriptTag) {
|
||||
window['GoogleAnalyticsObject']=r;
|
||||
window[r] = window[r] || function() {
|
||||
(window[r].q = window[r].q || []).push(arguments)
|
||||
};
|
||||
window[r].l = 1*new Date();
|
||||
tag = document.createElement(script),
|
||||
firstScriptTag = document.getElementsByTagName(script)[0];
|
||||
tag.async = 1;
|
||||
tag.src = url;
|
||||
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
|
||||
})(
|
||||
window,
|
||||
document,
|
||||
'script',
|
||||
'//www.google-analytics.com/analytics.js',
|
||||
'ga'
|
||||
);
|
||||
|
||||
var ga = window.ga;
|
||||
|
||||
ga('create', GA_TRACKING_CODE, 'auto');
|
||||
|
||||
module.exports = function() {
|
||||
return window.ga.apply(window.ga, arguments);
|
||||
};
|
||||
} else {
|
||||
module.exports = function() {console.log(arguments)};
|
||||
}
|
||||
12
node_modules/ga-react-router/src/index.js
generated
vendored
12
node_modules/ga-react-router/src/index.js
generated
vendored
@@ -1,12 +0,0 @@
|
||||
'use strict';
|
||||
var ga = require('./ga');
|
||||
|
||||
|
||||
function analytics(state) {
|
||||
ga('send', 'pageview', {
|
||||
'page': state.path
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
module.exports = analytics;
|
||||
140
node_modules/react-router/README.md
generated
vendored
140
node_modules/react-router/README.md
generated
vendored
@@ -1,140 +0,0 @@
|
||||
[](https://www.npmjs.org/package/react-router)
|
||||
[](https://travis-ci.org/rackt/react-router)
|
||||
[](https://david-dm.org/rackt/react-router)
|
||||
[](https://gitter.im/rackt/react-router?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
React Router
|
||||
============
|
||||
|
||||
A complete routing library for React.
|
||||
|
||||
Docs
|
||||
----
|
||||
|
||||
- [Guide: Overview](/docs/guides/overview.md)
|
||||
- [API](/docs/api/)
|
||||
|
||||
Important Notes
|
||||
---------------
|
||||
|
||||
### SemVer
|
||||
|
||||
Before our `1.0` release, breaking API changes will cause a bump to
|
||||
`0.x`. For example, `0.4.1` and `0.4.8` will have the same API, but
|
||||
`0.5.0` will have breaking changes.
|
||||
|
||||
Please refer to the [upgrade guide](/UPGRADE_GUIDE.md) and
|
||||
[changelog](/CHANGELOG.md) when upgrading.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
```sh
|
||||
npm install react-router
|
||||
# or
|
||||
bower install react-router
|
||||
```
|
||||
|
||||
This library is written with CommonJS modules. If you are using
|
||||
browserify, webpack, or similar, you can consume it like anything else
|
||||
installed from npm.
|
||||
|
||||
There is also a global build available on bower, find the library on
|
||||
`window.ReactRouter`.
|
||||
|
||||
The library is also available on the popular CDN [cdnjs](https://cdnjs.com/libraries/react-router).
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Nested views mapped to nested routes
|
||||
- Modular construction of route hierarchy
|
||||
- Sync and async transition hooks
|
||||
- Transition abort / redirect / retry
|
||||
- Dynamic segments
|
||||
- Query parameters
|
||||
- Links with automatic `.active` class when their route is active
|
||||
- Multiple root routes
|
||||
- Hash or HTML5 history (with fallback) URLs
|
||||
- Declarative Redirect routes
|
||||
- Declarative NotFound routes
|
||||
- Browser scroll behavior with transitions
|
||||
|
||||
Check out the `examples` directory to see how simple previously complex UI
|
||||
and workflows are to create.
|
||||
|
||||
What's it look like?
|
||||
--------------------
|
||||
|
||||
```js
|
||||
var routes = (
|
||||
<Route handler={App} path="/">
|
||||
<DefaultRoute handler={Home} />
|
||||
<Route name="about" handler={About} />
|
||||
<Route name="users" handler={Users}>
|
||||
<Route name="recent-users" path="recent" handler={RecentUsers} />
|
||||
<Route name="user" path="/user/:userId" handler={User} />
|
||||
<NotFoundRoute handler={UserRouteNotFound}/>
|
||||
</Route>
|
||||
<NotFoundRoute handler={NotFound}/>
|
||||
<Redirect from="company" to="about" />
|
||||
</Route>
|
||||
);
|
||||
|
||||
Router.run(routes, function (Handler) {
|
||||
React.render(<Handler/>, document.body);
|
||||
});
|
||||
|
||||
// Or, if you'd like to use the HTML5 history API for cleaner URLs:
|
||||
|
||||
Router.run(routes, Router.HistoryLocation, function (Handler) {
|
||||
React.render(<Handler/>, document.body);
|
||||
});
|
||||
```
|
||||
|
||||
See more in the [overview guide](/docs/guides/overview.md).
|
||||
|
||||
Benefits of this Approach
|
||||
-------------------------
|
||||
|
||||
1. **Incredible screen-creation productivity** - There is only one
|
||||
use-case when a user visits a route: render something. Every user
|
||||
interface has layers (or nesting) whether it's a simple navbar or
|
||||
multiple levels of master-detail. Coupling nested routes to these
|
||||
nested views gets rid of a ton of work for the developer to wire all
|
||||
of it together when the user switches routes. Adding new screens
|
||||
could not get faster.
|
||||
|
||||
2. **Immediate understanding of application structure** - When routes
|
||||
are declared in one place, developers can easily construct a mental
|
||||
image of the application. It's essentially a sitemap. There's not a
|
||||
better way to get so much information about your app this quickly.
|
||||
|
||||
3. **Code tractability** - When a developer gets a ticket to fix a bug
|
||||
at as specific url they simply 1) look at the route config, then 2)
|
||||
go find the handler for that route. Every entry point into your
|
||||
application is represented by these routes.
|
||||
|
||||
4. **URLs are your first thought, not an after-thought** - With React
|
||||
Router, you don't get UI on the page without configuring a url first.
|
||||
Fortunately, it's wildly productive this way, too.
|
||||
|
||||
Related Modules
|
||||
---------------
|
||||
|
||||
- [rnr-constrained-route](https://github.com/bjyoungblood/rnr-constrained-route) - validate paths
|
||||
and parameters on route handlers.
|
||||
- [react-router-bootstrap](https://github.com/mtscout6/react-router-bootstrap) - Integration with [react-bootstrap](https://github.com/react-bootstrap/react-bootstrap) components.
|
||||
- [react-router-proxy-loader](https://github.com/odysseyscience/react-router-proxy-loader) - A Webpack loader to dynamically load react-router components on-demand
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
Please see [CONTRIBUTING](CONTRIBUTING.md)
|
||||
|
||||
Thanks, Ember
|
||||
-------------
|
||||
|
||||
This library is highly inspired by the Ember.js routing API. In general,
|
||||
it's a translation of the Ember router api to React. Huge thanks to the
|
||||
Ember team for solving the hardest part already.
|
||||
9
node_modules/react-router/lib/Cancellation.js
generated
vendored
9
node_modules/react-router/lib/Cancellation.js
generated
vendored
@@ -1,9 +0,0 @@
|
||||
/**
|
||||
* Represents a cancellation caused by navigating away
|
||||
* before the previous transition has fully resolved.
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
function Cancellation() {}
|
||||
|
||||
module.exports = Cancellation;
|
||||
30
node_modules/react-router/lib/History.js
generated
vendored
30
node_modules/react-router/lib/History.js
generated
vendored
@@ -1,30 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var invariant = require('react/lib/invariant');
|
||||
var canUseDOM = require('react/lib/ExecutionEnvironment').canUseDOM;
|
||||
|
||||
var History = {
|
||||
|
||||
/**
|
||||
* The current number of entries in the history.
|
||||
*
|
||||
* Note: This property is read-only.
|
||||
*/
|
||||
length: 1,
|
||||
|
||||
/**
|
||||
* Sends the browser back one entry in the history.
|
||||
*/
|
||||
back: function back() {
|
||||
invariant(canUseDOM, 'Cannot use History.back without a DOM');
|
||||
|
||||
// Do this first so that History.length will
|
||||
// be accurate in location change listeners.
|
||||
History.length -= 1;
|
||||
|
||||
window.history.back();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports = History;
|
||||
75
node_modules/react-router/lib/Match.js
generated
vendored
75
node_modules/react-router/lib/Match.js
generated
vendored
@@ -1,75 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } };
|
||||
|
||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||
|
||||
/* jshint -W084 */
|
||||
var PathUtils = require('./PathUtils');
|
||||
|
||||
function deepSearch(route, pathname, query) {
|
||||
// Check the subtree first to find the most deeply-nested match.
|
||||
var childRoutes = route.childRoutes;
|
||||
if (childRoutes) {
|
||||
var match, childRoute;
|
||||
for (var i = 0, len = childRoutes.length; i < len; ++i) {
|
||||
childRoute = childRoutes[i];
|
||||
|
||||
if (childRoute.isDefault || childRoute.isNotFound) continue; // Check these in order later.
|
||||
|
||||
if (match = deepSearch(childRoute, pathname, query)) {
|
||||
// A route in the subtree matched! Add this route and we're done.
|
||||
match.routes.unshift(route);
|
||||
return match;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No child routes matched; try the default route.
|
||||
var defaultRoute = route.defaultRoute;
|
||||
if (defaultRoute && (params = PathUtils.extractParams(defaultRoute.path, pathname))) {
|
||||
return new Match(pathname, params, query, [route, defaultRoute]);
|
||||
} // Does the "not found" route match?
|
||||
var notFoundRoute = route.notFoundRoute;
|
||||
if (notFoundRoute && (params = PathUtils.extractParams(notFoundRoute.path, pathname))) {
|
||||
return new Match(pathname, params, query, [route, notFoundRoute]);
|
||||
} // Last attempt: check this route.
|
||||
var params = PathUtils.extractParams(route.path, pathname);
|
||||
if (params) {
|
||||
return new Match(pathname, params, query, [route]);
|
||||
}return null;
|
||||
}
|
||||
|
||||
var Match = (function () {
|
||||
function Match(pathname, params, query, routes) {
|
||||
_classCallCheck(this, Match);
|
||||
|
||||
this.pathname = pathname;
|
||||
this.params = params;
|
||||
this.query = query;
|
||||
this.routes = routes;
|
||||
}
|
||||
|
||||
_createClass(Match, null, [{
|
||||
key: 'findMatch',
|
||||
|
||||
/**
|
||||
* Attempts to match depth-first a route in the given route's
|
||||
* subtree against the given path and returns the match if it
|
||||
* succeeds, null if no match can be made.
|
||||
*/
|
||||
value: function findMatch(routes, path) {
|
||||
var pathname = PathUtils.withoutQuery(path);
|
||||
var query = PathUtils.extractQuery(path);
|
||||
var match = null;
|
||||
|
||||
for (var i = 0, len = routes.length; match == null && i < len; ++i) match = deepSearch(routes[i], pathname, query);
|
||||
|
||||
return match;
|
||||
}
|
||||
}]);
|
||||
|
||||
return Match;
|
||||
})();
|
||||
|
||||
module.exports = Match;
|
||||
70
node_modules/react-router/lib/Navigation.js
generated
vendored
70
node_modules/react-router/lib/Navigation.js
generated
vendored
@@ -1,70 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var PropTypes = require('./PropTypes');
|
||||
|
||||
/**
|
||||
* A mixin for components that modify the URL.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* var MyLink = React.createClass({
|
||||
* mixins: [ Router.Navigation ],
|
||||
* handleClick(event) {
|
||||
* event.preventDefault();
|
||||
* this.transitionTo('aRoute', { the: 'params' }, { the: 'query' });
|
||||
* },
|
||||
* render() {
|
||||
* return (
|
||||
* <a onClick={this.handleClick}>Click me!</a>
|
||||
* );
|
||||
* }
|
||||
* });
|
||||
*/
|
||||
var Navigation = {
|
||||
|
||||
contextTypes: {
|
||||
router: PropTypes.router.isRequired
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an absolute URL path created from the given route
|
||||
* name, URL parameters, and query values.
|
||||
*/
|
||||
makePath: function makePath(to, params, query) {
|
||||
return this.context.router.makePath(to, params, query);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a string that may safely be used as the href of a
|
||||
* link to the route with the given name.
|
||||
*/
|
||||
makeHref: function makeHref(to, params, query) {
|
||||
return this.context.router.makeHref(to, params, query);
|
||||
},
|
||||
|
||||
/**
|
||||
* Transitions to the URL specified in the arguments by pushing
|
||||
* a new URL onto the history stack.
|
||||
*/
|
||||
transitionTo: function transitionTo(to, params, query) {
|
||||
this.context.router.transitionTo(to, params, query);
|
||||
},
|
||||
|
||||
/**
|
||||
* Transitions to the URL specified in the arguments by replacing
|
||||
* the current URL in the history stack.
|
||||
*/
|
||||
replaceWith: function replaceWith(to, params, query) {
|
||||
this.context.router.replaceWith(to, params, query);
|
||||
},
|
||||
|
||||
/**
|
||||
* Transitions to the previous URL.
|
||||
*/
|
||||
goBack: function goBack() {
|
||||
return this.context.router.goBack();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports = Navigation;
|
||||
153
node_modules/react-router/lib/PathUtils.js
generated
vendored
153
node_modules/react-router/lib/PathUtils.js
generated
vendored
@@ -1,153 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var invariant = require('react/lib/invariant');
|
||||
var assign = require('object-assign');
|
||||
var qs = require('qs');
|
||||
|
||||
var paramCompileMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$]*)|[*.()\[\]\\+|{}^$]/g;
|
||||
var paramInjectMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$?]*[?]?)|[*]/g;
|
||||
var paramInjectTrailingSlashMatcher = /\/\/\?|\/\?\/|\/\?/g;
|
||||
var queryMatcher = /\?(.*)$/;
|
||||
|
||||
var _compiledPatterns = {};
|
||||
|
||||
function compilePattern(pattern) {
|
||||
if (!(pattern in _compiledPatterns)) {
|
||||
var paramNames = [];
|
||||
var source = pattern.replace(paramCompileMatcher, function (match, paramName) {
|
||||
if (paramName) {
|
||||
paramNames.push(paramName);
|
||||
return '([^/?#]+)';
|
||||
} else if (match === '*') {
|
||||
paramNames.push('splat');
|
||||
return '(.*?)';
|
||||
} else {
|
||||
return '\\' + match;
|
||||
}
|
||||
});
|
||||
|
||||
_compiledPatterns[pattern] = {
|
||||
matcher: new RegExp('^' + source + '$', 'i'),
|
||||
paramNames: paramNames
|
||||
};
|
||||
}
|
||||
|
||||
return _compiledPatterns[pattern];
|
||||
}
|
||||
|
||||
var PathUtils = {
|
||||
|
||||
/**
|
||||
* Returns true if the given path is absolute.
|
||||
*/
|
||||
isAbsolute: function isAbsolute(path) {
|
||||
return path.charAt(0) === '/';
|
||||
},
|
||||
|
||||
/**
|
||||
* Joins two URL paths together.
|
||||
*/
|
||||
join: function join(a, b) {
|
||||
return a.replace(/\/*$/, '/') + b;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an array of the names of all parameters in the given pattern.
|
||||
*/
|
||||
extractParamNames: function extractParamNames(pattern) {
|
||||
return compilePattern(pattern).paramNames;
|
||||
},
|
||||
|
||||
/**
|
||||
* Extracts the portions of the given URL path that match the given pattern
|
||||
* and returns an object of param name => value pairs. Returns null if the
|
||||
* pattern does not match the given path.
|
||||
*/
|
||||
extractParams: function extractParams(pattern, path) {
|
||||
var _compilePattern = compilePattern(pattern);
|
||||
|
||||
var matcher = _compilePattern.matcher;
|
||||
var paramNames = _compilePattern.paramNames;
|
||||
|
||||
var match = path.match(matcher);
|
||||
|
||||
if (!match) {
|
||||
return null;
|
||||
}var params = {};
|
||||
|
||||
paramNames.forEach(function (paramName, index) {
|
||||
params[paramName] = match[index + 1];
|
||||
});
|
||||
|
||||
return params;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a version of the given route path with params interpolated. Throws
|
||||
* if there is a dynamic segment of the route path for which there is no param.
|
||||
*/
|
||||
injectParams: function injectParams(pattern, params) {
|
||||
params = params || {};
|
||||
|
||||
var splatIndex = 0;
|
||||
|
||||
return pattern.replace(paramInjectMatcher, function (match, paramName) {
|
||||
paramName = paramName || 'splat';
|
||||
|
||||
// If param is optional don't check for existence
|
||||
if (paramName.slice(-1) === '?') {
|
||||
paramName = paramName.slice(0, -1);
|
||||
|
||||
if (params[paramName] == null) return '';
|
||||
} else {
|
||||
invariant(params[paramName] != null, 'Missing "%s" parameter for path "%s"', paramName, pattern);
|
||||
}
|
||||
|
||||
var segment;
|
||||
if (paramName === 'splat' && Array.isArray(params[paramName])) {
|
||||
segment = params[paramName][splatIndex++];
|
||||
|
||||
invariant(segment != null, 'Missing splat # %s for path "%s"', splatIndex, pattern);
|
||||
} else {
|
||||
segment = params[paramName];
|
||||
}
|
||||
|
||||
return segment;
|
||||
}).replace(paramInjectTrailingSlashMatcher, '/');
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an object that is the result of parsing any query string contained
|
||||
* in the given path, null if the path contains no query string.
|
||||
*/
|
||||
extractQuery: function extractQuery(path) {
|
||||
var match = path.match(queryMatcher);
|
||||
return match && qs.parse(match[1]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a version of the given path without the query string.
|
||||
*/
|
||||
withoutQuery: function withoutQuery(path) {
|
||||
return path.replace(queryMatcher, '');
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a version of the given path with the parameters in the given
|
||||
* query merged into the query string.
|
||||
*/
|
||||
withQuery: function withQuery(path, query) {
|
||||
var existingQuery = PathUtils.extractQuery(path);
|
||||
|
||||
if (existingQuery) query = query ? assign(existingQuery, query) : existingQuery;
|
||||
|
||||
var queryString = qs.stringify(query, { arrayFormat: 'brackets' });
|
||||
|
||||
if (queryString) {
|
||||
return PathUtils.withoutQuery(path) + '?' + queryString;
|
||||
}return PathUtils.withoutQuery(path);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports = PathUtils;
|
||||
31
node_modules/react-router/lib/PropTypes.js
generated
vendored
31
node_modules/react-router/lib/PropTypes.js
generated
vendored
@@ -1,31 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var assign = require('react/lib/Object.assign');
|
||||
var ReactPropTypes = require('react').PropTypes;
|
||||
var Route = require('./Route');
|
||||
|
||||
var PropTypes = assign({}, ReactPropTypes, {
|
||||
|
||||
/**
|
||||
* Indicates that a prop should be falsy.
|
||||
*/
|
||||
falsy: function falsy(props, propName, componentName) {
|
||||
if (props[propName]) {
|
||||
return new Error('<' + componentName + '> should not have a "' + propName + '" prop');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Indicates that a prop should be a Route object.
|
||||
*/
|
||||
route: ReactPropTypes.instanceOf(Route),
|
||||
|
||||
/**
|
||||
* Indicates that a prop should be a Router object.
|
||||
*/
|
||||
//router: ReactPropTypes.instanceOf(Router) // TODO
|
||||
router: ReactPropTypes.func
|
||||
|
||||
});
|
||||
|
||||
module.exports = PropTypes;
|
||||
12
node_modules/react-router/lib/Redirect.js
generated
vendored
12
node_modules/react-router/lib/Redirect.js
generated
vendored
@@ -1,12 +0,0 @@
|
||||
/**
|
||||
* Encapsulates a redirect to the given route.
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
function Redirect(to, params, query) {
|
||||
this.to = to;
|
||||
this.params = params;
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
module.exports = Redirect;
|
||||
200
node_modules/react-router/lib/Route.js
generated
vendored
200
node_modules/react-router/lib/Route.js
generated
vendored
@@ -1,200 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } };
|
||||
|
||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||
|
||||
var assign = require('react/lib/Object.assign');
|
||||
var invariant = require('react/lib/invariant');
|
||||
var warning = require('react/lib/warning');
|
||||
var PathUtils = require('./PathUtils');
|
||||
|
||||
var _currentRoute;
|
||||
|
||||
var Route = (function () {
|
||||
function Route(name, path, ignoreScrollBehavior, isDefault, isNotFound, onEnter, onLeave, handler) {
|
||||
_classCallCheck(this, Route);
|
||||
|
||||
this.name = name;
|
||||
this.path = path;
|
||||
this.paramNames = PathUtils.extractParamNames(this.path);
|
||||
this.ignoreScrollBehavior = !!ignoreScrollBehavior;
|
||||
this.isDefault = !!isDefault;
|
||||
this.isNotFound = !!isNotFound;
|
||||
this.onEnter = onEnter;
|
||||
this.onLeave = onLeave;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
_createClass(Route, [{
|
||||
key: 'appendChild',
|
||||
|
||||
/**
|
||||
* Appends the given route to this route's child routes.
|
||||
*/
|
||||
value: function appendChild(route) {
|
||||
invariant(route instanceof Route, 'route.appendChild must use a valid Route');
|
||||
|
||||
if (!this.childRoutes) this.childRoutes = [];
|
||||
|
||||
this.childRoutes.push(route);
|
||||
}
|
||||
}, {
|
||||
key: 'toString',
|
||||
value: function toString() {
|
||||
var string = '<Route';
|
||||
|
||||
if (this.name) string += ' name="' + this.name + '"';
|
||||
|
||||
string += ' path="' + this.path + '">';
|
||||
|
||||
return string;
|
||||
}
|
||||
}], [{
|
||||
key: 'createRoute',
|
||||
|
||||
/**
|
||||
* Creates and returns a new route. Options may be a URL pathname string
|
||||
* with placeholders for named params or an object with any of the following
|
||||
* properties:
|
||||
*
|
||||
* - name The name of the route. This is used to lookup a
|
||||
* route relative to its parent route and should be
|
||||
* unique among all child routes of the same parent
|
||||
* - path A URL pathname string with optional placeholders
|
||||
* that specify the names of params to extract from
|
||||
* the URL when the path matches. Defaults to `/${name}`
|
||||
* when there is a name given, or the path of the parent
|
||||
* route, or /
|
||||
* - ignoreScrollBehavior True to make this route (and all descendants) ignore
|
||||
* the scroll behavior of the router
|
||||
* - isDefault True to make this route the default route among all
|
||||
* its siblings
|
||||
* - isNotFound True to make this route the "not found" route among
|
||||
* all its siblings
|
||||
* - onEnter A transition hook that will be called when the
|
||||
* router is going to enter this route
|
||||
* - onLeave A transition hook that will be called when the
|
||||
* router is going to leave this route
|
||||
* - handler A React component that will be rendered when
|
||||
* this route is active
|
||||
* - parentRoute The parent route to use for this route. This option
|
||||
* is automatically supplied when creating routes inside
|
||||
* the callback to another invocation of createRoute. You
|
||||
* only ever need to use this when declaring routes
|
||||
* independently of one another to manually piece together
|
||||
* the route hierarchy
|
||||
*
|
||||
* The callback may be used to structure your route hierarchy. Any call to
|
||||
* createRoute, createDefaultRoute, createNotFoundRoute, or createRedirect
|
||||
* inside the callback automatically uses this route as its parent.
|
||||
*/
|
||||
value: function createRoute(options, callback) {
|
||||
options = options || {};
|
||||
|
||||
if (typeof options === 'string') options = { path: options };
|
||||
|
||||
var parentRoute = _currentRoute;
|
||||
|
||||
if (parentRoute) {
|
||||
warning(options.parentRoute == null || options.parentRoute === parentRoute, 'You should not use parentRoute with createRoute inside another route\'s child callback; it is ignored');
|
||||
} else {
|
||||
parentRoute = options.parentRoute;
|
||||
}
|
||||
|
||||
var name = options.name;
|
||||
var path = options.path || name;
|
||||
|
||||
if (path && !(options.isDefault || options.isNotFound)) {
|
||||
if (PathUtils.isAbsolute(path)) {
|
||||
if (parentRoute) {
|
||||
invariant(path === parentRoute.path || parentRoute.paramNames.length === 0, 'You cannot nest path "%s" inside "%s"; the parent requires URL parameters', path, parentRoute.path);
|
||||
}
|
||||
} else if (parentRoute) {
|
||||
// Relative paths extend their parent.
|
||||
path = PathUtils.join(parentRoute.path, path);
|
||||
} else {
|
||||
path = '/' + path;
|
||||
}
|
||||
} else {
|
||||
path = parentRoute ? parentRoute.path : '/';
|
||||
}
|
||||
|
||||
if (options.isNotFound && !/\*$/.test(path)) path += '*'; // Auto-append * to the path of not found routes.
|
||||
|
||||
var route = new Route(name, path, options.ignoreScrollBehavior, options.isDefault, options.isNotFound, options.onEnter, options.onLeave, options.handler);
|
||||
|
||||
if (parentRoute) {
|
||||
if (route.isDefault) {
|
||||
invariant(parentRoute.defaultRoute == null, '%s may not have more than one default route', parentRoute);
|
||||
|
||||
parentRoute.defaultRoute = route;
|
||||
} else if (route.isNotFound) {
|
||||
invariant(parentRoute.notFoundRoute == null, '%s may not have more than one not found route', parentRoute);
|
||||
|
||||
parentRoute.notFoundRoute = route;
|
||||
}
|
||||
|
||||
parentRoute.appendChild(route);
|
||||
}
|
||||
|
||||
// Any routes created in the callback
|
||||
// use this route as their parent.
|
||||
if (typeof callback === 'function') {
|
||||
var currentRoute = _currentRoute;
|
||||
_currentRoute = route;
|
||||
callback.call(route, route);
|
||||
_currentRoute = currentRoute;
|
||||
}
|
||||
|
||||
return route;
|
||||
}
|
||||
}, {
|
||||
key: 'createDefaultRoute',
|
||||
|
||||
/**
|
||||
* Creates and returns a route that is rendered when its parent matches
|
||||
* the current URL.
|
||||
*/
|
||||
value: function createDefaultRoute(options) {
|
||||
return Route.createRoute(assign({}, options, { isDefault: true }));
|
||||
}
|
||||
}, {
|
||||
key: 'createNotFoundRoute',
|
||||
|
||||
/**
|
||||
* Creates and returns a route that is rendered when its parent matches
|
||||
* the current URL but none of its siblings do.
|
||||
*/
|
||||
value: function createNotFoundRoute(options) {
|
||||
return Route.createRoute(assign({}, options, { isNotFound: true }));
|
||||
}
|
||||
}, {
|
||||
key: 'createRedirect',
|
||||
|
||||
/**
|
||||
* Creates and returns a route that automatically redirects the transition
|
||||
* to another route. In addition to the normal options to createRoute, this
|
||||
* function accepts the following options:
|
||||
*
|
||||
* - from An alias for the `path` option. Defaults to *
|
||||
* - to The path/route/route name to redirect to
|
||||
* - params The params to use in the redirect URL. Defaults
|
||||
* to using the current params
|
||||
* - query The query to use in the redirect URL. Defaults
|
||||
* to using the current query
|
||||
*/
|
||||
value: function createRedirect(options) {
|
||||
return Route.createRoute(assign({}, options, {
|
||||
path: options.path || options.from || '*',
|
||||
onEnter: function onEnter(transition, params, query) {
|
||||
transition.redirect(options.to, options.params || params, options.query || query);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}]);
|
||||
|
||||
return Route;
|
||||
})();
|
||||
|
||||
module.exports = Route;
|
||||
75
node_modules/react-router/lib/ScrollHistory.js
generated
vendored
75
node_modules/react-router/lib/ScrollHistory.js
generated
vendored
@@ -1,75 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var invariant = require('react/lib/invariant');
|
||||
var canUseDOM = require('react/lib/ExecutionEnvironment').canUseDOM;
|
||||
var getWindowScrollPosition = require('./getWindowScrollPosition');
|
||||
|
||||
function shouldUpdateScroll(state, prevState) {
|
||||
if (!prevState) {
|
||||
return true;
|
||||
} // Don't update scroll position when only the query has changed.
|
||||
if (state.pathname === prevState.pathname) {
|
||||
return false;
|
||||
}var routes = state.routes;
|
||||
var prevRoutes = prevState.routes;
|
||||
|
||||
var sharedAncestorRoutes = routes.filter(function (route) {
|
||||
return prevRoutes.indexOf(route) !== -1;
|
||||
});
|
||||
|
||||
return !sharedAncestorRoutes.some(function (route) {
|
||||
return route.ignoreScrollBehavior;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the router with the ability to manage window scroll position
|
||||
* according to its scroll behavior.
|
||||
*/
|
||||
var ScrollHistory = {
|
||||
|
||||
statics: {
|
||||
|
||||
/**
|
||||
* Records curent scroll position as the last known position for the given URL path.
|
||||
*/
|
||||
recordScrollPosition: function recordScrollPosition(path) {
|
||||
if (!this.scrollHistory) this.scrollHistory = {};
|
||||
|
||||
this.scrollHistory[path] = getWindowScrollPosition();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the last known scroll position for the given URL path.
|
||||
*/
|
||||
getScrollPosition: function getScrollPosition(path) {
|
||||
if (!this.scrollHistory) this.scrollHistory = {};
|
||||
|
||||
return this.scrollHistory[path] || null;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
componentWillMount: function componentWillMount() {
|
||||
invariant(this.constructor.getScrollBehavior() == null || canUseDOM, 'Cannot use scroll behavior without a DOM');
|
||||
},
|
||||
|
||||
componentDidMount: function componentDidMount() {
|
||||
this._updateScroll();
|
||||
},
|
||||
|
||||
componentDidUpdate: function componentDidUpdate(prevProps, prevState) {
|
||||
this._updateScroll(prevState);
|
||||
},
|
||||
|
||||
_updateScroll: function _updateScroll(prevState) {
|
||||
if (!shouldUpdateScroll(this.state, prevState)) {
|
||||
return;
|
||||
}var scrollBehavior = this.constructor.getScrollBehavior();
|
||||
|
||||
if (scrollBehavior) scrollBehavior.updateScrollPosition(this.constructor.getScrollPosition(this.state.path), this.state.action);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports = ScrollHistory;
|
||||
74
node_modules/react-router/lib/State.js
generated
vendored
74
node_modules/react-router/lib/State.js
generated
vendored
@@ -1,74 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var PropTypes = require('./PropTypes');
|
||||
|
||||
/**
|
||||
* A mixin for components that need to know the path, routes, URL
|
||||
* params and query that are currently active.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* var AboutLink = React.createClass({
|
||||
* mixins: [ Router.State ],
|
||||
* render() {
|
||||
* var className = this.props.className;
|
||||
*
|
||||
* if (this.isActive('about'))
|
||||
* className += ' is-active';
|
||||
*
|
||||
* return React.DOM.a({ className: className }, this.props.children);
|
||||
* }
|
||||
* });
|
||||
*/
|
||||
var State = {
|
||||
|
||||
contextTypes: {
|
||||
router: PropTypes.router.isRequired
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the current URL path.
|
||||
*/
|
||||
getPath: function getPath() {
|
||||
return this.context.router.getCurrentPath();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the current URL path without the query string.
|
||||
*/
|
||||
getPathname: function getPathname() {
|
||||
return this.context.router.getCurrentPathname();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an object of the URL params that are currently active.
|
||||
*/
|
||||
getParams: function getParams() {
|
||||
return this.context.router.getCurrentParams();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an object of the query params that are currently active.
|
||||
*/
|
||||
getQuery: function getQuery() {
|
||||
return this.context.router.getCurrentQuery();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an array of the routes that are currently active.
|
||||
*/
|
||||
getRoutes: function getRoutes() {
|
||||
return this.context.router.getCurrentRoutes();
|
||||
},
|
||||
|
||||
/**
|
||||
* A helper method to determine if a given route, params, and query
|
||||
* are active.
|
||||
*/
|
||||
isActive: function isActive(to, params, query) {
|
||||
return this.context.router.isActive(to, params, query);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports = State;
|
||||
171
node_modules/react-router/lib/TestUtils.js
generated
vendored
171
node_modules/react-router/lib/TestUtils.js
generated
vendored
@@ -1,171 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var RouteHandler = require('./components/RouteHandler');
|
||||
var PropTypes = require('./PropTypes');
|
||||
|
||||
exports.Nested = React.createClass({
|
||||
displayName: 'Nested',
|
||||
|
||||
render: function render() {
|
||||
return React.createElement(
|
||||
'div',
|
||||
null,
|
||||
React.createElement(
|
||||
'h1',
|
||||
{ className: 'Nested' },
|
||||
'Nested'
|
||||
),
|
||||
React.createElement(RouteHandler, null)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
exports.Foo = React.createClass({
|
||||
displayName: 'Foo',
|
||||
|
||||
render: function render() {
|
||||
return React.createElement(
|
||||
'div',
|
||||
{ className: 'Foo' },
|
||||
'Foo'
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
exports.Bar = React.createClass({
|
||||
displayName: 'Bar',
|
||||
|
||||
render: function render() {
|
||||
return React.createElement(
|
||||
'div',
|
||||
{ className: 'Bar' },
|
||||
'Bar'
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
exports.Baz = React.createClass({
|
||||
displayName: 'Baz',
|
||||
|
||||
render: function render() {
|
||||
return React.createElement(
|
||||
'div',
|
||||
{ className: 'Baz' },
|
||||
'Baz'
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
exports.Async = React.createClass({
|
||||
displayName: 'Async',
|
||||
|
||||
statics: {
|
||||
delay: 10,
|
||||
|
||||
willTransitionTo: function willTransitionTo(transition, params, query, callback) {
|
||||
setTimeout(callback, exports.Async.delay);
|
||||
}
|
||||
},
|
||||
|
||||
render: function render() {
|
||||
return React.createElement(
|
||||
'div',
|
||||
{ className: 'Async' },
|
||||
'Async'
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
exports.RedirectToFoo = React.createClass({
|
||||
displayName: 'RedirectToFoo',
|
||||
|
||||
statics: {
|
||||
willTransitionTo: function willTransitionTo(transition) {
|
||||
transition.redirect('/foo');
|
||||
}
|
||||
},
|
||||
|
||||
render: function render() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
exports.RedirectToFooAsync = React.createClass({
|
||||
displayName: 'RedirectToFooAsync',
|
||||
|
||||
statics: {
|
||||
delay: 10,
|
||||
|
||||
willTransitionTo: function willTransitionTo(transition, params, query, callback) {
|
||||
setTimeout(function () {
|
||||
transition.redirect('/foo');
|
||||
callback();
|
||||
}, exports.RedirectToFooAsync.delay);
|
||||
}
|
||||
},
|
||||
|
||||
render: function render() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
exports.Abort = React.createClass({
|
||||
displayName: 'Abort',
|
||||
|
||||
statics: {
|
||||
willTransitionTo: function willTransitionTo(transition) {
|
||||
transition.abort();
|
||||
}
|
||||
},
|
||||
|
||||
render: function render() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
exports.AbortAsync = React.createClass({
|
||||
displayName: 'AbortAsync',
|
||||
|
||||
statics: {
|
||||
delay: 10,
|
||||
|
||||
willTransitionTo: function willTransitionTo(transition, params, query, callback) {
|
||||
setTimeout(function () {
|
||||
transition.abort();
|
||||
callback();
|
||||
}, exports.AbortAsync.delay);
|
||||
}
|
||||
},
|
||||
|
||||
render: function render() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
exports.EchoFooProp = React.createClass({
|
||||
displayName: 'EchoFooProp',
|
||||
|
||||
render: function render() {
|
||||
return React.createElement(
|
||||
'div',
|
||||
null,
|
||||
this.props.foo
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
exports.EchoBarParam = React.createClass({
|
||||
displayName: 'EchoBarParam',
|
||||
|
||||
contextTypes: {
|
||||
router: PropTypes.router.isRequired
|
||||
},
|
||||
render: function render() {
|
||||
return React.createElement(
|
||||
'div',
|
||||
{ className: 'EchoBarParam' },
|
||||
this.context.router.getCurrentParams().bar
|
||||
);
|
||||
}
|
||||
});
|
||||
75
node_modules/react-router/lib/Transition.js
generated
vendored
75
node_modules/react-router/lib/Transition.js
generated
vendored
@@ -1,75 +0,0 @@
|
||||
/* jshint -W058 */
|
||||
|
||||
'use strict';
|
||||
|
||||
var Cancellation = require('./Cancellation');
|
||||
var Redirect = require('./Redirect');
|
||||
|
||||
/**
|
||||
* Encapsulates a transition to a given path.
|
||||
*
|
||||
* The willTransitionTo and willTransitionFrom handlers receive
|
||||
* an instance of this class as their first argument.
|
||||
*/
|
||||
function Transition(path, retry) {
|
||||
this.path = path;
|
||||
this.abortReason = null;
|
||||
// TODO: Change this to router.retryTransition(transition)
|
||||
this.retry = retry.bind(this);
|
||||
}
|
||||
|
||||
Transition.prototype.abort = function (reason) {
|
||||
if (this.abortReason == null) this.abortReason = reason || 'ABORT';
|
||||
};
|
||||
|
||||
Transition.prototype.redirect = function (to, params, query) {
|
||||
this.abort(new Redirect(to, params, query));
|
||||
};
|
||||
|
||||
Transition.prototype.cancel = function () {
|
||||
this.abort(new Cancellation());
|
||||
};
|
||||
|
||||
Transition.from = function (transition, routes, components, callback) {
|
||||
routes.reduce(function (callback, route, index) {
|
||||
return function (error) {
|
||||
if (error || transition.abortReason) {
|
||||
callback(error);
|
||||
} else if (route.onLeave) {
|
||||
try {
|
||||
route.onLeave(transition, components[index], callback);
|
||||
|
||||
// If there is no callback in the argument list, call it automatically.
|
||||
if (route.onLeave.length < 3) callback();
|
||||
} catch (e) {
|
||||
callback(e);
|
||||
}
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
}, callback)();
|
||||
};
|
||||
|
||||
Transition.to = function (transition, routes, params, query, callback) {
|
||||
routes.reduceRight(function (callback, route) {
|
||||
return function (error) {
|
||||
if (error || transition.abortReason) {
|
||||
callback(error);
|
||||
} else if (route.onEnter) {
|
||||
try {
|
||||
route.onEnter(transition, params, query, callback);
|
||||
|
||||
// If there is no callback in the argument list, call it automatically.
|
||||
if (route.onEnter.length < 4) callback();
|
||||
} catch (e) {
|
||||
callback(e);
|
||||
}
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
}, callback)();
|
||||
};
|
||||
|
||||
module.exports = Transition;
|
||||
25
node_modules/react-router/lib/actions/LocationActions.js
generated
vendored
25
node_modules/react-router/lib/actions/LocationActions.js
generated
vendored
@@ -1,25 +0,0 @@
|
||||
/**
|
||||
* Actions that modify the URL.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var LocationActions = {
|
||||
|
||||
/**
|
||||
* Indicates a new location is being pushed to the history stack.
|
||||
*/
|
||||
PUSH: 'push',
|
||||
|
||||
/**
|
||||
* Indicates the current location should be replaced.
|
||||
*/
|
||||
REPLACE: 'replace',
|
||||
|
||||
/**
|
||||
* Indicates the most recent entry should be removed from the history stack.
|
||||
*/
|
||||
POP: 'pop'
|
||||
|
||||
};
|
||||
|
||||
module.exports = LocationActions;
|
||||
29
node_modules/react-router/lib/behaviors/ImitateBrowserBehavior.js
generated
vendored
29
node_modules/react-router/lib/behaviors/ImitateBrowserBehavior.js
generated
vendored
@@ -1,29 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var LocationActions = require('../actions/LocationActions');
|
||||
|
||||
/**
|
||||
* A scroll behavior that attempts to imitate the default behavior
|
||||
* of modern browsers.
|
||||
*/
|
||||
var ImitateBrowserBehavior = {
|
||||
|
||||
updateScrollPosition: function updateScrollPosition(position, actionType) {
|
||||
switch (actionType) {
|
||||
case LocationActions.PUSH:
|
||||
case LocationActions.REPLACE:
|
||||
window.scrollTo(0, 0);
|
||||
break;
|
||||
case LocationActions.POP:
|
||||
if (position) {
|
||||
window.scrollTo(position.x, position.y);
|
||||
} else {
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports = ImitateBrowserBehavior;
|
||||
15
node_modules/react-router/lib/behaviors/ScrollToTopBehavior.js
generated
vendored
15
node_modules/react-router/lib/behaviors/ScrollToTopBehavior.js
generated
vendored
@@ -1,15 +0,0 @@
|
||||
/**
|
||||
* A scroll behavior that always scrolls to the top of the page
|
||||
* after a transition.
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
var ScrollToTopBehavior = {
|
||||
|
||||
updateScrollPosition: function updateScrollPosition() {
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports = ScrollToTopBehavior;
|
||||
108
node_modules/react-router/lib/components/ActiveHandler.js
generated
vendored
108
node_modules/react-router/lib/components/ActiveHandler.js
generated
vendored
@@ -1,108 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } };
|
||||
|
||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||
|
||||
var _inherits = function (subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
|
||||
|
||||
var React = require('react');
|
||||
var ContextWrapper = require('./ContextWrapper');
|
||||
var assign = require('react/lib/Object.assign');
|
||||
var PropTypes = require('../PropTypes');
|
||||
|
||||
var REF_NAME = '__routeHandler__';
|
||||
|
||||
/**
|
||||
* A <RouteHandler> component renders the active child route handler
|
||||
* when routes are nested.
|
||||
*/
|
||||
|
||||
var RouteHandler = (function (_React$Component) {
|
||||
function RouteHandler() {
|
||||
_classCallCheck(this, RouteHandler);
|
||||
|
||||
if (_React$Component != null) {
|
||||
_React$Component.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
_inherits(RouteHandler, _React$Component);
|
||||
|
||||
_createClass(RouteHandler, [{
|
||||
key: 'getChildContext',
|
||||
value: function getChildContext() {
|
||||
return {
|
||||
routeDepth: this.context.routeDepth + 1
|
||||
};
|
||||
}
|
||||
}, {
|
||||
key: 'componentDidMount',
|
||||
value: function componentDidMount() {
|
||||
this._updateRouteComponent(this.refs[REF_NAME]);
|
||||
}
|
||||
}, {
|
||||
key: 'componentDidUpdate',
|
||||
value: function componentDidUpdate() {
|
||||
this._updateRouteComponent(this.refs[REF_NAME]);
|
||||
}
|
||||
}, {
|
||||
key: 'componentWillUnmount',
|
||||
value: function componentWillUnmount() {
|
||||
this._updateRouteComponent(null);
|
||||
}
|
||||
}, {
|
||||
key: '_updateRouteComponent',
|
||||
value: function _updateRouteComponent(component) {
|
||||
this.context.router.setRouteComponentAtDepth(this.getRouteDepth(), component);
|
||||
}
|
||||
}, {
|
||||
key: 'getRouteDepth',
|
||||
value: function getRouteDepth() {
|
||||
return this.context.routeDepth;
|
||||
}
|
||||
}, {
|
||||
key: 'createChildRouteHandler',
|
||||
value: function createChildRouteHandler(props) {
|
||||
var route = this.context.router.getRouteAtDepth(this.getRouteDepth());
|
||||
|
||||
if (route == null) {
|
||||
return null;
|
||||
}var childProps = assign({}, props || this.props, {
|
||||
ref: REF_NAME,
|
||||
params: this.context.router.getCurrentParams(),
|
||||
query: this.context.router.getCurrentQuery()
|
||||
});
|
||||
|
||||
return React.createElement(route.handler, childProps);
|
||||
}
|
||||
}, {
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
var handler = this.createChildRouteHandler();
|
||||
// <script/> for things like <CSSTransitionGroup/> that don't like null
|
||||
return handler ? React.createElement(
|
||||
ContextWrapper,
|
||||
null,
|
||||
handler
|
||||
) : React.createElement('script', null);
|
||||
}
|
||||
}]);
|
||||
|
||||
return RouteHandler;
|
||||
})(React.Component);
|
||||
|
||||
// TODO: Include these in the above class definition
|
||||
// once we can use ES7 property initializers.
|
||||
// https://github.com/babel/babel/issues/619
|
||||
|
||||
RouteHandler.contextTypes = {
|
||||
routeDepth: PropTypes.number.isRequired,
|
||||
router: PropTypes.router.isRequired
|
||||
};
|
||||
|
||||
RouteHandler.childContextTypes = {
|
||||
routeDepth: PropTypes.number.isRequired
|
||||
};
|
||||
|
||||
module.exports = RouteHandler;
|
||||
38
node_modules/react-router/lib/components/ContextWrapper.js
generated
vendored
38
node_modules/react-router/lib/components/ContextWrapper.js
generated
vendored
@@ -1,38 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } };
|
||||
|
||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||
|
||||
var _inherits = function (subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
|
||||
|
||||
/**
|
||||
* This component is necessary to get around a context warning
|
||||
* present in React 0.13.0. It sovles this by providing a separation
|
||||
* between the "owner" and "parent" contexts.
|
||||
*/
|
||||
|
||||
var React = require('react');
|
||||
|
||||
var ContextWrapper = (function (_React$Component) {
|
||||
function ContextWrapper() {
|
||||
_classCallCheck(this, ContextWrapper);
|
||||
|
||||
if (_React$Component != null) {
|
||||
_React$Component.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
_inherits(ContextWrapper, _React$Component);
|
||||
|
||||
_createClass(ContextWrapper, [{
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
return this.props.children;
|
||||
}
|
||||
}]);
|
||||
|
||||
return ContextWrapper;
|
||||
})(React.Component);
|
||||
|
||||
module.exports = ContextWrapper;
|
||||
47
node_modules/react-router/lib/components/DefaultRoute.js
generated
vendored
47
node_modules/react-router/lib/components/DefaultRoute.js
generated
vendored
@@ -1,47 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } };
|
||||
|
||||
var _inherits = function (subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
|
||||
|
||||
var PropTypes = require('../PropTypes');
|
||||
var RouteHandler = require('./RouteHandler');
|
||||
var Route = require('./Route');
|
||||
|
||||
/**
|
||||
* A <DefaultRoute> component is a special kind of <Route> that
|
||||
* renders when its parent matches but none of its siblings do.
|
||||
* Only one such route may be used at any given level in the
|
||||
* route hierarchy.
|
||||
*/
|
||||
|
||||
var DefaultRoute = (function (_Route) {
|
||||
function DefaultRoute() {
|
||||
_classCallCheck(this, DefaultRoute);
|
||||
|
||||
if (_Route != null) {
|
||||
_Route.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
_inherits(DefaultRoute, _Route);
|
||||
|
||||
return DefaultRoute;
|
||||
})(Route);
|
||||
|
||||
// TODO: Include these in the above class definition
|
||||
// once we can use ES7 property initializers.
|
||||
// https://github.com/babel/babel/issues/619
|
||||
|
||||
DefaultRoute.propTypes = {
|
||||
name: PropTypes.string,
|
||||
path: PropTypes.falsy,
|
||||
children: PropTypes.falsy,
|
||||
handler: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
DefaultRoute.defaultProps = {
|
||||
handler: RouteHandler
|
||||
};
|
||||
|
||||
module.exports = DefaultRoute;
|
||||
135
node_modules/react-router/lib/components/Link.js
generated
vendored
135
node_modules/react-router/lib/components/Link.js
generated
vendored
@@ -1,135 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } };
|
||||
|
||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||
|
||||
var _inherits = function (subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
|
||||
|
||||
var React = require('react');
|
||||
var assign = require('react/lib/Object.assign');
|
||||
var PropTypes = require('../PropTypes');
|
||||
|
||||
function isLeftClickEvent(event) {
|
||||
return event.button === 0;
|
||||
}
|
||||
|
||||
function isModifiedEvent(event) {
|
||||
return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* <Link> components are used to create an <a> element that links to a route.
|
||||
* When that route is active, the link gets an "active" class name (or the
|
||||
* value of its `activeClassName` prop).
|
||||
*
|
||||
* For example, assuming you have the following route:
|
||||
*
|
||||
* <Route name="showPost" path="/posts/:postID" handler={Post}/>
|
||||
*
|
||||
* You could use the following component to link to that route:
|
||||
*
|
||||
* <Link to="showPost" params={{ postID: "123" }} />
|
||||
*
|
||||
* In addition to params, links may pass along query string parameters
|
||||
* using the `query` prop.
|
||||
*
|
||||
* <Link to="showPost" params={{ postID: "123" }} query={{ show:true }}/>
|
||||
*/
|
||||
|
||||
var Link = (function (_React$Component) {
|
||||
function Link() {
|
||||
_classCallCheck(this, Link);
|
||||
|
||||
if (_React$Component != null) {
|
||||
_React$Component.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
_inherits(Link, _React$Component);
|
||||
|
||||
_createClass(Link, [{
|
||||
key: 'handleClick',
|
||||
value: function handleClick(event) {
|
||||
var allowTransition = true;
|
||||
var clickResult;
|
||||
|
||||
if (this.props.onClick) clickResult = this.props.onClick(event);
|
||||
|
||||
if (isModifiedEvent(event) || !isLeftClickEvent(event)) {
|
||||
return;
|
||||
}if (clickResult === false || event.defaultPrevented === true) allowTransition = false;
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
if (allowTransition) this.context.router.transitionTo(this.props.to, this.props.params, this.props.query);
|
||||
}
|
||||
}, {
|
||||
key: 'getHref',
|
||||
|
||||
/**
|
||||
* Returns the value of the "href" attribute to use on the DOM element.
|
||||
*/
|
||||
value: function getHref() {
|
||||
return this.context.router.makeHref(this.props.to, this.props.params, this.props.query);
|
||||
}
|
||||
}, {
|
||||
key: 'getClassName',
|
||||
|
||||
/**
|
||||
* Returns the value of the "class" attribute to use on the DOM element, which contains
|
||||
* the value of the activeClassName property when this <Link> is active.
|
||||
*/
|
||||
value: function getClassName() {
|
||||
var className = this.props.className;
|
||||
|
||||
if (this.getActiveState()) className += ' ' + this.props.activeClassName;
|
||||
|
||||
return className;
|
||||
}
|
||||
}, {
|
||||
key: 'getActiveState',
|
||||
value: function getActiveState() {
|
||||
return this.context.router.isActive(this.props.to, this.props.params, this.props.query);
|
||||
}
|
||||
}, {
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
var props = assign({}, this.props, {
|
||||
href: this.getHref(),
|
||||
className: this.getClassName(),
|
||||
onClick: this.handleClick.bind(this)
|
||||
});
|
||||
|
||||
if (props.activeStyle && this.getActiveState()) props.style = props.activeStyle;
|
||||
|
||||
return React.DOM.a(props, this.props.children);
|
||||
}
|
||||
}]);
|
||||
|
||||
return Link;
|
||||
})(React.Component);
|
||||
|
||||
// TODO: Include these in the above class definition
|
||||
// once we can use ES7 property initializers.
|
||||
// https://github.com/babel/babel/issues/619
|
||||
|
||||
Link.contextTypes = {
|
||||
router: PropTypes.router.isRequired
|
||||
};
|
||||
|
||||
Link.propTypes = {
|
||||
activeClassName: PropTypes.string.isRequired,
|
||||
to: PropTypes.oneOfType([PropTypes.string, PropTypes.route]).isRequired,
|
||||
params: PropTypes.object,
|
||||
query: PropTypes.object,
|
||||
activeStyle: PropTypes.object,
|
||||
onClick: PropTypes.func
|
||||
};
|
||||
|
||||
Link.defaultProps = {
|
||||
activeClassName: 'active',
|
||||
className: ''
|
||||
};
|
||||
|
||||
module.exports = Link;
|
||||
48
node_modules/react-router/lib/components/NotFoundRoute.js
generated
vendored
48
node_modules/react-router/lib/components/NotFoundRoute.js
generated
vendored
@@ -1,48 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } };
|
||||
|
||||
var _inherits = function (subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
|
||||
|
||||
var PropTypes = require('../PropTypes');
|
||||
var RouteHandler = require('./RouteHandler');
|
||||
var Route = require('./Route');
|
||||
|
||||
/**
|
||||
* A <NotFoundRoute> is a special kind of <Route> that
|
||||
* renders when the beginning of its parent's path matches
|
||||
* but none of its siblings do, including any <DefaultRoute>.
|
||||
* Only one such route may be used at any given level in the
|
||||
* route hierarchy.
|
||||
*/
|
||||
|
||||
var NotFoundRoute = (function (_Route) {
|
||||
function NotFoundRoute() {
|
||||
_classCallCheck(this, NotFoundRoute);
|
||||
|
||||
if (_Route != null) {
|
||||
_Route.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
_inherits(NotFoundRoute, _Route);
|
||||
|
||||
return NotFoundRoute;
|
||||
})(Route);
|
||||
|
||||
// TODO: Include these in the above class definition
|
||||
// once we can use ES7 property initializers.
|
||||
// https://github.com/babel/babel/issues/619
|
||||
|
||||
NotFoundRoute.propTypes = {
|
||||
name: PropTypes.string,
|
||||
path: PropTypes.falsy,
|
||||
children: PropTypes.falsy,
|
||||
handler: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
NotFoundRoute.defaultProps = {
|
||||
handler: RouteHandler
|
||||
};
|
||||
|
||||
module.exports = NotFoundRoute;
|
||||
43
node_modules/react-router/lib/components/Redirect.js
generated
vendored
43
node_modules/react-router/lib/components/Redirect.js
generated
vendored
@@ -1,43 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } };
|
||||
|
||||
var _inherits = function (subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
|
||||
|
||||
var PropTypes = require('../PropTypes');
|
||||
var Route = require('./Route');
|
||||
|
||||
/**
|
||||
* A <Redirect> component is a special kind of <Route> that always
|
||||
* redirects to another route when it matches.
|
||||
*/
|
||||
|
||||
var Redirect = (function (_Route) {
|
||||
function Redirect() {
|
||||
_classCallCheck(this, Redirect);
|
||||
|
||||
if (_Route != null) {
|
||||
_Route.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
_inherits(Redirect, _Route);
|
||||
|
||||
return Redirect;
|
||||
})(Route);
|
||||
|
||||
// TODO: Include these in the above class definition
|
||||
// once we can use ES7 property initializers.
|
||||
// https://github.com/babel/babel/issues/619
|
||||
|
||||
Redirect.propTypes = {
|
||||
path: PropTypes.string,
|
||||
from: PropTypes.string, // Alias for path.
|
||||
to: PropTypes.string,
|
||||
handler: PropTypes.falsy
|
||||
};
|
||||
|
||||
// Redirects should not have a default handler
|
||||
Redirect.defaultProps = {};
|
||||
|
||||
module.exports = Redirect;
|
||||
91
node_modules/react-router/lib/components/Route.js
generated
vendored
91
node_modules/react-router/lib/components/Route.js
generated
vendored
@@ -1,91 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } };
|
||||
|
||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||
|
||||
var _inherits = function (subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
|
||||
|
||||
var React = require('react');
|
||||
var invariant = require('react/lib/invariant');
|
||||
var PropTypes = require('../PropTypes');
|
||||
var RouteHandler = require('./RouteHandler');
|
||||
|
||||
/**
|
||||
* <Route> components specify components that are rendered to the page when the
|
||||
* URL matches a given pattern.
|
||||
*
|
||||
* Routes are arranged in a nested tree structure. When a new URL is requested,
|
||||
* the tree is searched depth-first to find a route whose path matches the URL.
|
||||
* When one is found, all routes in the tree that lead to it are considered
|
||||
* "active" and their components are rendered into the DOM, nested in the same
|
||||
* order as they are in the tree.
|
||||
*
|
||||
* The preferred way to configure a router is using JSX. The XML-like syntax is
|
||||
* a great way to visualize how routes are laid out in an application.
|
||||
*
|
||||
* var routes = [
|
||||
* <Route handler={App}>
|
||||
* <Route name="login" handler={Login}/>
|
||||
* <Route name="logout" handler={Logout}/>
|
||||
* <Route name="about" handler={About}/>
|
||||
* </Route>
|
||||
* ];
|
||||
*
|
||||
* Router.run(routes, function (Handler) {
|
||||
* React.render(<Handler/>, document.body);
|
||||
* });
|
||||
*
|
||||
* Handlers for Route components that contain children can render their active
|
||||
* child route using a <RouteHandler> element.
|
||||
*
|
||||
* var App = React.createClass({
|
||||
* render: function () {
|
||||
* return (
|
||||
* <div class="application">
|
||||
* <RouteHandler/>
|
||||
* </div>
|
||||
* );
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* If no handler is provided for the route, it will render a matched child route.
|
||||
*/
|
||||
|
||||
var Route = (function (_React$Component) {
|
||||
function Route() {
|
||||
_classCallCheck(this, Route);
|
||||
|
||||
if (_React$Component != null) {
|
||||
_React$Component.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
_inherits(Route, _React$Component);
|
||||
|
||||
_createClass(Route, [{
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
invariant(false, '%s elements are for router configuration only and should not be rendered', this.constructor.name);
|
||||
}
|
||||
}]);
|
||||
|
||||
return Route;
|
||||
})(React.Component);
|
||||
|
||||
// TODO: Include these in the above class definition
|
||||
// once we can use ES7 property initializers.
|
||||
// https://github.com/babel/babel/issues/619
|
||||
|
||||
Route.propTypes = {
|
||||
name: PropTypes.string,
|
||||
path: PropTypes.string,
|
||||
handler: PropTypes.func,
|
||||
ignoreScrollBehavior: PropTypes.bool
|
||||
};
|
||||
|
||||
Route.defaultProps = {
|
||||
handler: RouteHandler
|
||||
};
|
||||
|
||||
module.exports = Route;
|
||||
108
node_modules/react-router/lib/components/RouteHandler.js
generated
vendored
108
node_modules/react-router/lib/components/RouteHandler.js
generated
vendored
@@ -1,108 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } };
|
||||
|
||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||
|
||||
var _inherits = function (subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
|
||||
|
||||
var React = require('react');
|
||||
var ContextWrapper = require('./ContextWrapper');
|
||||
var assign = require('react/lib/Object.assign');
|
||||
var PropTypes = require('../PropTypes');
|
||||
|
||||
var REF_NAME = '__routeHandler__';
|
||||
|
||||
/**
|
||||
* A <RouteHandler> component renders the active child route handler
|
||||
* when routes are nested.
|
||||
*/
|
||||
|
||||
var RouteHandler = (function (_React$Component) {
|
||||
function RouteHandler() {
|
||||
_classCallCheck(this, RouteHandler);
|
||||
|
||||
if (_React$Component != null) {
|
||||
_React$Component.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
_inherits(RouteHandler, _React$Component);
|
||||
|
||||
_createClass(RouteHandler, [{
|
||||
key: 'getChildContext',
|
||||
value: function getChildContext() {
|
||||
return {
|
||||
routeDepth: this.context.routeDepth + 1
|
||||
};
|
||||
}
|
||||
}, {
|
||||
key: 'componentDidMount',
|
||||
value: function componentDidMount() {
|
||||
this._updateRouteComponent(this.refs[REF_NAME]);
|
||||
}
|
||||
}, {
|
||||
key: 'componentDidUpdate',
|
||||
value: function componentDidUpdate() {
|
||||
this._updateRouteComponent(this.refs[REF_NAME]);
|
||||
}
|
||||
}, {
|
||||
key: 'componentWillUnmount',
|
||||
value: function componentWillUnmount() {
|
||||
this._updateRouteComponent(null);
|
||||
}
|
||||
}, {
|
||||
key: '_updateRouteComponent',
|
||||
value: function _updateRouteComponent(component) {
|
||||
this.context.router.setRouteComponentAtDepth(this.getRouteDepth(), component);
|
||||
}
|
||||
}, {
|
||||
key: 'getRouteDepth',
|
||||
value: function getRouteDepth() {
|
||||
return this.context.routeDepth;
|
||||
}
|
||||
}, {
|
||||
key: 'createChildRouteHandler',
|
||||
value: function createChildRouteHandler(props) {
|
||||
var route = this.context.router.getRouteAtDepth(this.getRouteDepth());
|
||||
|
||||
if (route == null) {
|
||||
return null;
|
||||
}var childProps = assign({}, props || this.props, {
|
||||
ref: REF_NAME,
|
||||
params: this.context.router.getCurrentParams(),
|
||||
query: this.context.router.getCurrentQuery()
|
||||
});
|
||||
|
||||
return React.createElement(route.handler, childProps);
|
||||
}
|
||||
}, {
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
var handler = this.createChildRouteHandler();
|
||||
// <script/> for things like <CSSTransitionGroup/> that don't like null
|
||||
return handler ? React.createElement(
|
||||
ContextWrapper,
|
||||
null,
|
||||
handler
|
||||
) : React.createElement('script', null);
|
||||
}
|
||||
}]);
|
||||
|
||||
return RouteHandler;
|
||||
})(React.Component);
|
||||
|
||||
// TODO: Include these in the above class definition
|
||||
// once we can use ES7 property initializers.
|
||||
// https://github.com/babel/babel/issues/619
|
||||
|
||||
RouteHandler.contextTypes = {
|
||||
routeDepth: PropTypes.number.isRequired,
|
||||
router: PropTypes.router.isRequired
|
||||
};
|
||||
|
||||
RouteHandler.childContextTypes = {
|
||||
routeDepth: PropTypes.number.isRequired
|
||||
};
|
||||
|
||||
module.exports = RouteHandler;
|
||||
514
node_modules/react-router/lib/createRouter.js
generated
vendored
514
node_modules/react-router/lib/createRouter.js
generated
vendored
@@ -1,514 +0,0 @@
|
||||
/* jshint -W058 */
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var warning = require('react/lib/warning');
|
||||
var invariant = require('react/lib/invariant');
|
||||
var canUseDOM = require('react/lib/ExecutionEnvironment').canUseDOM;
|
||||
var LocationActions = require('./actions/LocationActions');
|
||||
var ImitateBrowserBehavior = require('./behaviors/ImitateBrowserBehavior');
|
||||
var HashLocation = require('./locations/HashLocation');
|
||||
var HistoryLocation = require('./locations/HistoryLocation');
|
||||
var RefreshLocation = require('./locations/RefreshLocation');
|
||||
var StaticLocation = require('./locations/StaticLocation');
|
||||
var ScrollHistory = require('./ScrollHistory');
|
||||
var createRoutesFromReactChildren = require('./createRoutesFromReactChildren');
|
||||
var isReactChildren = require('./isReactChildren');
|
||||
var Transition = require('./Transition');
|
||||
var PropTypes = require('./PropTypes');
|
||||
var Redirect = require('./Redirect');
|
||||
var History = require('./History');
|
||||
var Cancellation = require('./Cancellation');
|
||||
var Match = require('./Match');
|
||||
var Route = require('./Route');
|
||||
var supportsHistory = require('./supportsHistory');
|
||||
var PathUtils = require('./PathUtils');
|
||||
|
||||
/**
|
||||
* The default location for new routers.
|
||||
*/
|
||||
var DEFAULT_LOCATION = canUseDOM ? HashLocation : '/';
|
||||
|
||||
/**
|
||||
* The default scroll behavior for new routers.
|
||||
*/
|
||||
var DEFAULT_SCROLL_BEHAVIOR = canUseDOM ? ImitateBrowserBehavior : null;
|
||||
|
||||
function hasProperties(object, properties) {
|
||||
for (var propertyName in properties) if (properties.hasOwnProperty(propertyName) && object[propertyName] !== properties[propertyName]) {
|
||||
return false;
|
||||
}return true;
|
||||
}
|
||||
|
||||
function hasMatch(routes, route, prevParams, nextParams, prevQuery, nextQuery) {
|
||||
return routes.some(function (r) {
|
||||
if (r !== route) return false;
|
||||
|
||||
var paramNames = route.paramNames;
|
||||
var paramName;
|
||||
|
||||
// Ensure that all params the route cares about did not change.
|
||||
for (var i = 0, len = paramNames.length; i < len; ++i) {
|
||||
paramName = paramNames[i];
|
||||
|
||||
if (nextParams[paramName] !== prevParams[paramName]) return false;
|
||||
}
|
||||
|
||||
// Ensure the query hasn't changed.
|
||||
return hasProperties(prevQuery, nextQuery) && hasProperties(nextQuery, prevQuery);
|
||||
});
|
||||
}
|
||||
|
||||
function addRoutesToNamedRoutes(routes, namedRoutes) {
|
||||
var route;
|
||||
for (var i = 0, len = routes.length; i < len; ++i) {
|
||||
route = routes[i];
|
||||
|
||||
if (route.name) {
|
||||
invariant(namedRoutes[route.name] == null, 'You may not have more than one route named "%s"', route.name);
|
||||
|
||||
namedRoutes[route.name] = route;
|
||||
}
|
||||
|
||||
if (route.childRoutes) addRoutesToNamedRoutes(route.childRoutes, namedRoutes);
|
||||
}
|
||||
}
|
||||
|
||||
function routeIsActive(activeRoutes, routeName) {
|
||||
return activeRoutes.some(function (route) {
|
||||
return route.name === routeName;
|
||||
});
|
||||
}
|
||||
|
||||
function paramsAreActive(activeParams, params) {
|
||||
for (var property in params) if (String(activeParams[property]) !== String(params[property])) {
|
||||
return false;
|
||||
}return true;
|
||||
}
|
||||
|
||||
function queryIsActive(activeQuery, query) {
|
||||
for (var property in query) if (String(activeQuery[property]) !== String(query[property])) {
|
||||
return false;
|
||||
}return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a new router using the given options. A router
|
||||
* is a ReactComponent class that knows how to react to changes in the
|
||||
* URL and keep the contents of the page in sync.
|
||||
*
|
||||
* Options may be any of the following:
|
||||
*
|
||||
* - routes (required) The route config
|
||||
* - location The location to use. Defaults to HashLocation when
|
||||
* the DOM is available, "/" otherwise
|
||||
* - scrollBehavior The scroll behavior to use. Defaults to ImitateBrowserBehavior
|
||||
* when the DOM is available, null otherwise
|
||||
* - onError A function that is used to handle errors
|
||||
* - onAbort A function that is used to handle aborted transitions
|
||||
*
|
||||
* When rendering in a server-side environment, the location should simply
|
||||
* be the URL path that was used in the request, including the query string.
|
||||
*/
|
||||
function createRouter(options) {
|
||||
options = options || {};
|
||||
|
||||
if (isReactChildren(options)) options = { routes: options };
|
||||
|
||||
var mountedComponents = [];
|
||||
var location = options.location || DEFAULT_LOCATION;
|
||||
var scrollBehavior = options.scrollBehavior || DEFAULT_SCROLL_BEHAVIOR;
|
||||
var state = {};
|
||||
var nextState = {};
|
||||
var pendingTransition = null;
|
||||
var dispatchHandler = null;
|
||||
|
||||
if (typeof location === 'string') location = new StaticLocation(location);
|
||||
|
||||
if (location instanceof StaticLocation) {
|
||||
warning(!canUseDOM || process.env.NODE_ENV === 'test', 'You should not use a static location in a DOM environment because ' + 'the router will not be kept in sync with the current URL');
|
||||
} else {
|
||||
invariant(canUseDOM || location.needsDOM === false, 'You cannot use %s without a DOM', location);
|
||||
}
|
||||
|
||||
// Automatically fall back to full page refreshes in
|
||||
// browsers that don't support the HTML history API.
|
||||
if (location === HistoryLocation && !supportsHistory()) location = RefreshLocation;
|
||||
|
||||
var Router = React.createClass({
|
||||
|
||||
displayName: 'Router',
|
||||
|
||||
statics: {
|
||||
|
||||
isRunning: false,
|
||||
|
||||
cancelPendingTransition: function cancelPendingTransition() {
|
||||
if (pendingTransition) {
|
||||
pendingTransition.cancel();
|
||||
pendingTransition = null;
|
||||
}
|
||||
},
|
||||
|
||||
clearAllRoutes: function clearAllRoutes() {
|
||||
Router.cancelPendingTransition();
|
||||
Router.namedRoutes = {};
|
||||
Router.routes = [];
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds routes to this router from the given children object (see ReactChildren).
|
||||
*/
|
||||
addRoutes: function addRoutes(routes) {
|
||||
if (isReactChildren(routes)) routes = createRoutesFromReactChildren(routes);
|
||||
|
||||
addRoutesToNamedRoutes(routes, Router.namedRoutes);
|
||||
|
||||
Router.routes.push.apply(Router.routes, routes);
|
||||
},
|
||||
|
||||
/**
|
||||
* Replaces routes of this router from the given children object (see ReactChildren).
|
||||
*/
|
||||
replaceRoutes: function replaceRoutes(routes) {
|
||||
Router.clearAllRoutes();
|
||||
Router.addRoutes(routes);
|
||||
Router.refresh();
|
||||
},
|
||||
|
||||
/**
|
||||
* Performs a match of the given path against this router and returns an object
|
||||
* with the { routes, params, pathname, query } that match. Returns null if no
|
||||
* match can be made.
|
||||
*/
|
||||
match: function match(path) {
|
||||
return Match.findMatch(Router.routes, path);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an absolute URL path created from the given route
|
||||
* name, URL parameters, and query.
|
||||
*/
|
||||
makePath: function makePath(to, params, query) {
|
||||
var path;
|
||||
if (PathUtils.isAbsolute(to)) {
|
||||
path = to;
|
||||
} else {
|
||||
var route = to instanceof Route ? to : Router.namedRoutes[to];
|
||||
|
||||
invariant(route instanceof Route, 'Cannot find a route named "%s"', to);
|
||||
|
||||
path = route.path;
|
||||
}
|
||||
|
||||
return PathUtils.withQuery(PathUtils.injectParams(path, params), query);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a string that may safely be used as the href of a link
|
||||
* to the route with the given name, URL parameters, and query.
|
||||
*/
|
||||
makeHref: function makeHref(to, params, query) {
|
||||
var path = Router.makePath(to, params, query);
|
||||
return location === HashLocation ? '#' + path : path;
|
||||
},
|
||||
|
||||
/**
|
||||
* Transitions to the URL specified in the arguments by pushing
|
||||
* a new URL onto the history stack.
|
||||
*/
|
||||
transitionTo: function transitionTo(to, params, query) {
|
||||
var path = Router.makePath(to, params, query);
|
||||
|
||||
if (pendingTransition) {
|
||||
// Replace so pending location does not stay in history.
|
||||
location.replace(path);
|
||||
} else {
|
||||
location.push(path);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Transitions to the URL specified in the arguments by replacing
|
||||
* the current URL in the history stack.
|
||||
*/
|
||||
replaceWith: function replaceWith(to, params, query) {
|
||||
location.replace(Router.makePath(to, params, query));
|
||||
},
|
||||
|
||||
/**
|
||||
* Transitions to the previous URL if one is available. Returns true if the
|
||||
* router was able to go back, false otherwise.
|
||||
*
|
||||
* Note: The router only tracks history entries in your application, not the
|
||||
* current browser session, so you can safely call this function without guarding
|
||||
* against sending the user back to some other site. However, when using
|
||||
* RefreshLocation (which is the fallback for HistoryLocation in browsers that
|
||||
* don't support HTML5 history) this method will *always* send the client back
|
||||
* because we cannot reliably track history length.
|
||||
*/
|
||||
goBack: function goBack() {
|
||||
if (History.length > 1 || location === RefreshLocation) {
|
||||
location.pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
warning(false, 'goBack() was ignored because there is no router history');
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
handleAbort: options.onAbort || function (abortReason) {
|
||||
if (location instanceof StaticLocation) throw new Error('Unhandled aborted transition! Reason: ' + abortReason);
|
||||
|
||||
if (abortReason instanceof Cancellation) {
|
||||
return;
|
||||
} else if (abortReason instanceof Redirect) {
|
||||
location.replace(Router.makePath(abortReason.to, abortReason.params, abortReason.query));
|
||||
} else {
|
||||
location.pop();
|
||||
}
|
||||
},
|
||||
|
||||
handleError: options.onError || function (error) {
|
||||
// Throw so we don't silently swallow async errors.
|
||||
throw error; // This error probably originated in a transition hook.
|
||||
},
|
||||
|
||||
handleLocationChange: function handleLocationChange(change) {
|
||||
Router.dispatch(change.path, change.type);
|
||||
},
|
||||
|
||||
/**
|
||||
* Performs a transition to the given path and calls callback(error, abortReason)
|
||||
* when the transition is finished. If both arguments are null the router's state
|
||||
* was updated. Otherwise the transition did not complete.
|
||||
*
|
||||
* In a transition, a router first determines which routes are involved by beginning
|
||||
* with the current route, up the route tree to the first parent route that is shared
|
||||
* with the destination route, and back down the tree to the destination route. The
|
||||
* willTransitionFrom hook is invoked on all route handlers we're transitioning away
|
||||
* from, in reverse nesting order. Likewise, the willTransitionTo hook is invoked on
|
||||
* all route handlers we're transitioning to.
|
||||
*
|
||||
* Both willTransitionFrom and willTransitionTo hooks may either abort or redirect the
|
||||
* transition. To resolve asynchronously, they may use the callback argument. If no
|
||||
* hooks wait, the transition is fully synchronous.
|
||||
*/
|
||||
dispatch: function dispatch(path, action) {
|
||||
Router.cancelPendingTransition();
|
||||
|
||||
var prevPath = state.path;
|
||||
var isRefreshing = action == null;
|
||||
|
||||
if (prevPath === path && !isRefreshing) {
|
||||
return;
|
||||
} // Nothing to do!
|
||||
|
||||
// Record the scroll position as early as possible to
|
||||
// get it before browsers try update it automatically.
|
||||
if (prevPath && action === LocationActions.PUSH) Router.recordScrollPosition(prevPath);
|
||||
|
||||
var match = Router.match(path);
|
||||
|
||||
warning(match != null, 'No route matches path "%s". Make sure you have <Route path="%s"> somewhere in your routes', path, path);
|
||||
|
||||
if (match == null) match = {};
|
||||
|
||||
var prevRoutes = state.routes || [];
|
||||
var prevParams = state.params || {};
|
||||
var prevQuery = state.query || {};
|
||||
|
||||
var nextRoutes = match.routes || [];
|
||||
var nextParams = match.params || {};
|
||||
var nextQuery = match.query || {};
|
||||
|
||||
var fromRoutes, toRoutes;
|
||||
if (prevRoutes.length) {
|
||||
fromRoutes = prevRoutes.filter(function (route) {
|
||||
return !hasMatch(nextRoutes, route, prevParams, nextParams, prevQuery, nextQuery);
|
||||
});
|
||||
|
||||
toRoutes = nextRoutes.filter(function (route) {
|
||||
return !hasMatch(prevRoutes, route, prevParams, nextParams, prevQuery, nextQuery);
|
||||
});
|
||||
} else {
|
||||
fromRoutes = [];
|
||||
toRoutes = nextRoutes;
|
||||
}
|
||||
|
||||
var transition = new Transition(path, Router.replaceWith.bind(Router, path));
|
||||
pendingTransition = transition;
|
||||
|
||||
var fromComponents = mountedComponents.slice(prevRoutes.length - fromRoutes.length);
|
||||
|
||||
Transition.from(transition, fromRoutes, fromComponents, function (error) {
|
||||
if (error || transition.abortReason) return dispatchHandler.call(Router, error, transition); // No need to continue.
|
||||
|
||||
Transition.to(transition, toRoutes, nextParams, nextQuery, function (error) {
|
||||
dispatchHandler.call(Router, error, transition, {
|
||||
path: path,
|
||||
action: action,
|
||||
pathname: match.pathname,
|
||||
routes: nextRoutes,
|
||||
params: nextParams,
|
||||
query: nextQuery
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Starts this router and calls callback(router, state) when the route changes.
|
||||
*
|
||||
* If the router's location is static (i.e. a URL path in a server environment)
|
||||
* the callback is called only once. Otherwise, the location should be one of the
|
||||
* Router.*Location objects (e.g. Router.HashLocation or Router.HistoryLocation).
|
||||
*/
|
||||
run: function run(callback) {
|
||||
invariant(!Router.isRunning, 'Router is already running');
|
||||
|
||||
dispatchHandler = function (error, transition, newState) {
|
||||
if (error) Router.handleError(error);
|
||||
|
||||
if (pendingTransition !== transition) return;
|
||||
|
||||
pendingTransition = null;
|
||||
|
||||
if (transition.abortReason) {
|
||||
Router.handleAbort(transition.abortReason);
|
||||
} else {
|
||||
callback.call(Router, Router, nextState = newState);
|
||||
}
|
||||
};
|
||||
|
||||
if (!(location instanceof StaticLocation)) {
|
||||
if (location.addChangeListener) location.addChangeListener(Router.handleLocationChange);
|
||||
|
||||
Router.isRunning = true;
|
||||
}
|
||||
|
||||
// Bootstrap using the current path.
|
||||
Router.refresh();
|
||||
},
|
||||
|
||||
refresh: function refresh() {
|
||||
Router.dispatch(location.getCurrentPath(), null);
|
||||
},
|
||||
|
||||
stop: function stop() {
|
||||
Router.cancelPendingTransition();
|
||||
|
||||
if (location.removeChangeListener) location.removeChangeListener(Router.handleLocationChange);
|
||||
|
||||
Router.isRunning = false;
|
||||
},
|
||||
|
||||
getLocation: function getLocation() {
|
||||
return location;
|
||||
},
|
||||
|
||||
getScrollBehavior: function getScrollBehavior() {
|
||||
return scrollBehavior;
|
||||
},
|
||||
|
||||
getRouteAtDepth: function getRouteAtDepth(routeDepth) {
|
||||
var routes = state.routes;
|
||||
return routes && routes[routeDepth];
|
||||
},
|
||||
|
||||
setRouteComponentAtDepth: function setRouteComponentAtDepth(routeDepth, component) {
|
||||
mountedComponents[routeDepth] = component;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the current URL path + query string.
|
||||
*/
|
||||
getCurrentPath: function getCurrentPath() {
|
||||
return state.path;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the current URL path without the query string.
|
||||
*/
|
||||
getCurrentPathname: function getCurrentPathname() {
|
||||
return state.pathname;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an object of the currently active URL parameters.
|
||||
*/
|
||||
getCurrentParams: function getCurrentParams() {
|
||||
return state.params;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an object of the currently active query parameters.
|
||||
*/
|
||||
getCurrentQuery: function getCurrentQuery() {
|
||||
return state.query;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an array of the currently active routes.
|
||||
*/
|
||||
getCurrentRoutes: function getCurrentRoutes() {
|
||||
return state.routes;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the given route, params, and query are active.
|
||||
*/
|
||||
isActive: function isActive(to, params, query) {
|
||||
if (PathUtils.isAbsolute(to)) {
|
||||
return to === state.path;
|
||||
}return routeIsActive(state.routes, to) && paramsAreActive(state.params, params) && (query == null || queryIsActive(state.query, query));
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
mixins: [ScrollHistory],
|
||||
|
||||
propTypes: {
|
||||
children: PropTypes.falsy
|
||||
},
|
||||
|
||||
childContextTypes: {
|
||||
routeDepth: PropTypes.number.isRequired,
|
||||
router: PropTypes.router.isRequired
|
||||
},
|
||||
|
||||
getChildContext: function getChildContext() {
|
||||
return {
|
||||
routeDepth: 1,
|
||||
router: Router
|
||||
};
|
||||
},
|
||||
|
||||
getInitialState: function getInitialState() {
|
||||
return state = nextState;
|
||||
},
|
||||
|
||||
componentWillReceiveProps: function componentWillReceiveProps() {
|
||||
this.setState(state = nextState);
|
||||
},
|
||||
|
||||
componentWillUnmount: function componentWillUnmount() {
|
||||
Router.stop();
|
||||
},
|
||||
|
||||
render: function render() {
|
||||
var route = Router.getRouteAtDepth(0);
|
||||
return route ? React.createElement(route.handler, this.props) : null;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Router.clearAllRoutes();
|
||||
|
||||
if (options.routes) Router.addRoutes(options.routes);
|
||||
|
||||
return Router;
|
||||
}
|
||||
|
||||
module.exports = createRouter;
|
||||
81
node_modules/react-router/lib/createRoutesFromReactChildren.js
generated
vendored
81
node_modules/react-router/lib/createRoutesFromReactChildren.js
generated
vendored
@@ -1,81 +0,0 @@
|
||||
/* jshint -W084 */
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var assign = require('react/lib/Object.assign');
|
||||
var warning = require('react/lib/warning');
|
||||
var DefaultRoute = require('./components/DefaultRoute');
|
||||
var NotFoundRoute = require('./components/NotFoundRoute');
|
||||
var Redirect = require('./components/Redirect');
|
||||
var Route = require('./Route');
|
||||
|
||||
function checkPropTypes(componentName, propTypes, props) {
|
||||
componentName = componentName || 'UnknownComponent';
|
||||
|
||||
for (var propName in propTypes) {
|
||||
if (propTypes.hasOwnProperty(propName)) {
|
||||
var error = propTypes[propName](props, propName, componentName);
|
||||
|
||||
if (error instanceof Error) warning(false, error.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createRouteOptions(props) {
|
||||
var options = assign({}, props);
|
||||
var handler = options.handler;
|
||||
|
||||
if (handler) {
|
||||
options.onEnter = handler.willTransitionTo;
|
||||
options.onLeave = handler.willTransitionFrom;
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
function createRouteFromReactElement(element) {
|
||||
if (!React.isValidElement(element)) {
|
||||
return;
|
||||
}var type = element.type;
|
||||
var props = assign({}, type.defaultProps, element.props);
|
||||
|
||||
if (type.propTypes) checkPropTypes(type.displayName, type.propTypes, props);
|
||||
|
||||
if (type === DefaultRoute) {
|
||||
return Route.createDefaultRoute(createRouteOptions(props));
|
||||
}if (type === NotFoundRoute) {
|
||||
return Route.createNotFoundRoute(createRouteOptions(props));
|
||||
}if (type === Redirect) {
|
||||
return Route.createRedirect(createRouteOptions(props));
|
||||
}return Route.createRoute(createRouteOptions(props), function () {
|
||||
if (props.children) createRoutesFromReactChildren(props.children);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns an array of routes created from the given
|
||||
* ReactChildren, all of which should be one of <Route>, <DefaultRoute>,
|
||||
* <NotFoundRoute>, or <Redirect>, e.g.:
|
||||
*
|
||||
* var { createRoutesFromReactChildren, Route, Redirect } = require('react-router');
|
||||
*
|
||||
* var routes = createRoutesFromReactChildren(
|
||||
* <Route path="/" handler={App}>
|
||||
* <Route name="user" path="/user/:userId" handler={User}>
|
||||
* <Route name="task" path="tasks/:taskId" handler={Task}/>
|
||||
* <Redirect from="todos/:taskId" to="task"/>
|
||||
* </Route>
|
||||
* </Route>
|
||||
* );
|
||||
*/
|
||||
function createRoutesFromReactChildren(children) {
|
||||
var routes = [];
|
||||
|
||||
React.Children.forEach(children, function (child) {
|
||||
if (child = createRouteFromReactElement(child)) routes.push(child);
|
||||
});
|
||||
|
||||
return routes;
|
||||
}
|
||||
|
||||
module.exports = createRoutesFromReactChildren;
|
||||
18
node_modules/react-router/lib/getWindowScrollPosition.js
generated
vendored
18
node_modules/react-router/lib/getWindowScrollPosition.js
generated
vendored
@@ -1,18 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var invariant = require('react/lib/invariant');
|
||||
var canUseDOM = require('react/lib/ExecutionEnvironment').canUseDOM;
|
||||
|
||||
/**
|
||||
* Returns the current scroll position of the window as { x, y }.
|
||||
*/
|
||||
function getWindowScrollPosition() {
|
||||
invariant(canUseDOM, 'Cannot get current scroll position without a DOM');
|
||||
|
||||
return {
|
||||
x: window.pageXOffset || document.documentElement.scrollLeft,
|
||||
y: window.pageYOffset || document.documentElement.scrollTop
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = getWindowScrollPosition;
|
||||
31
node_modules/react-router/lib/index.js
generated
vendored
31
node_modules/react-router/lib/index.js
generated
vendored
@@ -1,31 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
exports.DefaultRoute = require('./components/DefaultRoute');
|
||||
exports.Link = require('./components/Link');
|
||||
exports.NotFoundRoute = require('./components/NotFoundRoute');
|
||||
exports.Redirect = require('./components/Redirect');
|
||||
exports.Route = require('./components/Route');
|
||||
exports.ActiveHandler = require('./components/RouteHandler');
|
||||
exports.RouteHandler = exports.ActiveHandler;
|
||||
|
||||
exports.HashLocation = require('./locations/HashLocation');
|
||||
exports.HistoryLocation = require('./locations/HistoryLocation');
|
||||
exports.RefreshLocation = require('./locations/RefreshLocation');
|
||||
exports.StaticLocation = require('./locations/StaticLocation');
|
||||
exports.TestLocation = require('./locations/TestLocation');
|
||||
|
||||
exports.ImitateBrowserBehavior = require('./behaviors/ImitateBrowserBehavior');
|
||||
exports.ScrollToTopBehavior = require('./behaviors/ScrollToTopBehavior');
|
||||
|
||||
exports.History = require('./History');
|
||||
exports.Navigation = require('./Navigation');
|
||||
exports.State = require('./State');
|
||||
|
||||
exports.createRoute = require('./Route').createRoute;
|
||||
exports.createDefaultRoute = require('./Route').createDefaultRoute;
|
||||
exports.createNotFoundRoute = require('./Route').createNotFoundRoute;
|
||||
exports.createRedirect = require('./Route').createRedirect;
|
||||
exports.createRoutesFromReactChildren = require('./createRoutesFromReactChildren');
|
||||
|
||||
exports.create = require('./createRouter');
|
||||
exports.run = require('./runRouter');
|
||||
13
node_modules/react-router/lib/isReactChildren.js
generated
vendored
13
node_modules/react-router/lib/isReactChildren.js
generated
vendored
@@ -1,13 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
|
||||
function isValidChild(object) {
|
||||
return object == null || React.isValidElement(object);
|
||||
}
|
||||
|
||||
function isReactChildren(object) {
|
||||
return isValidChild(object) || Array.isArray(object) && object.every(isValidChild);
|
||||
}
|
||||
|
||||
module.exports = isReactChildren;
|
||||
111
node_modules/react-router/lib/locations/HashLocation.js
generated
vendored
111
node_modules/react-router/lib/locations/HashLocation.js
generated
vendored
@@ -1,111 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var LocationActions = require('../actions/LocationActions');
|
||||
var History = require('../History');
|
||||
|
||||
var _listeners = [];
|
||||
var _isListening = false;
|
||||
var _actionType;
|
||||
|
||||
function notifyChange(type) {
|
||||
if (type === LocationActions.PUSH) History.length += 1;
|
||||
|
||||
var change = {
|
||||
path: HashLocation.getCurrentPath(),
|
||||
type: type
|
||||
};
|
||||
|
||||
_listeners.forEach(function (listener) {
|
||||
listener.call(HashLocation, change);
|
||||
});
|
||||
}
|
||||
|
||||
function ensureSlash() {
|
||||
var path = HashLocation.getCurrentPath();
|
||||
|
||||
if (path.charAt(0) === '/') {
|
||||
return true;
|
||||
}HashLocation.replace('/' + path);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function onHashChange() {
|
||||
if (ensureSlash()) {
|
||||
// If we don't have an _actionType then all we know is the hash
|
||||
// changed. It was probably caused by the user clicking the Back
|
||||
// button, but may have also been the Forward button or manual
|
||||
// manipulation. So just guess 'pop'.
|
||||
var curActionType = _actionType;
|
||||
_actionType = null;
|
||||
notifyChange(curActionType || LocationActions.POP);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Location that uses `window.location.hash`.
|
||||
*/
|
||||
var HashLocation = {
|
||||
|
||||
addChangeListener: function addChangeListener(listener) {
|
||||
_listeners.push(listener);
|
||||
|
||||
// Do this BEFORE listening for hashchange.
|
||||
ensureSlash();
|
||||
|
||||
if (!_isListening) {
|
||||
if (window.addEventListener) {
|
||||
window.addEventListener('hashchange', onHashChange, false);
|
||||
} else {
|
||||
window.attachEvent('onhashchange', onHashChange);
|
||||
}
|
||||
|
||||
_isListening = true;
|
||||
}
|
||||
},
|
||||
|
||||
removeChangeListener: function removeChangeListener(listener) {
|
||||
_listeners = _listeners.filter(function (l) {
|
||||
return l !== listener;
|
||||
});
|
||||
|
||||
if (_listeners.length === 0) {
|
||||
if (window.removeEventListener) {
|
||||
window.removeEventListener('hashchange', onHashChange, false);
|
||||
} else {
|
||||
window.removeEvent('onhashchange', onHashChange);
|
||||
}
|
||||
|
||||
_isListening = false;
|
||||
}
|
||||
},
|
||||
|
||||
push: function push(path) {
|
||||
_actionType = LocationActions.PUSH;
|
||||
window.location.hash = path;
|
||||
},
|
||||
|
||||
replace: function replace(path) {
|
||||
_actionType = LocationActions.REPLACE;
|
||||
window.location.replace(window.location.pathname + window.location.search + '#' + path);
|
||||
},
|
||||
|
||||
pop: function pop() {
|
||||
_actionType = LocationActions.POP;
|
||||
History.back();
|
||||
},
|
||||
|
||||
getCurrentPath: function getCurrentPath() {
|
||||
return decodeURI(
|
||||
// We can't use window.location.hash here because it's not
|
||||
// consistent across browsers - Firefox will pre-decode it!
|
||||
window.location.href.split('#')[1] || '');
|
||||
},
|
||||
|
||||
toString: function toString() {
|
||||
return '<HashLocation>';
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports = HashLocation;
|
||||
86
node_modules/react-router/lib/locations/HistoryLocation.js
generated
vendored
86
node_modules/react-router/lib/locations/HistoryLocation.js
generated
vendored
@@ -1,86 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var LocationActions = require('../actions/LocationActions');
|
||||
var History = require('../History');
|
||||
|
||||
var _listeners = [];
|
||||
var _isListening = false;
|
||||
|
||||
function notifyChange(type) {
|
||||
var change = {
|
||||
path: HistoryLocation.getCurrentPath(),
|
||||
type: type
|
||||
};
|
||||
|
||||
_listeners.forEach(function (listener) {
|
||||
listener.call(HistoryLocation, change);
|
||||
});
|
||||
}
|
||||
|
||||
function onPopState(event) {
|
||||
if (event.state === undefined) {
|
||||
return;
|
||||
} // Ignore extraneous popstate events in WebKit.
|
||||
|
||||
notifyChange(LocationActions.POP);
|
||||
}
|
||||
|
||||
/**
|
||||
* A Location that uses HTML5 history.
|
||||
*/
|
||||
var HistoryLocation = {
|
||||
|
||||
addChangeListener: function addChangeListener(listener) {
|
||||
_listeners.push(listener);
|
||||
|
||||
if (!_isListening) {
|
||||
if (window.addEventListener) {
|
||||
window.addEventListener('popstate', onPopState, false);
|
||||
} else {
|
||||
window.attachEvent('onpopstate', onPopState);
|
||||
}
|
||||
|
||||
_isListening = true;
|
||||
}
|
||||
},
|
||||
|
||||
removeChangeListener: function removeChangeListener(listener) {
|
||||
_listeners = _listeners.filter(function (l) {
|
||||
return l !== listener;
|
||||
});
|
||||
|
||||
if (_listeners.length === 0) {
|
||||
if (window.addEventListener) {
|
||||
window.removeEventListener('popstate', onPopState, false);
|
||||
} else {
|
||||
window.removeEvent('onpopstate', onPopState);
|
||||
}
|
||||
|
||||
_isListening = false;
|
||||
}
|
||||
},
|
||||
|
||||
push: function push(path) {
|
||||
window.history.pushState({ path: path }, '', path);
|
||||
History.length += 1;
|
||||
notifyChange(LocationActions.PUSH);
|
||||
},
|
||||
|
||||
replace: function replace(path) {
|
||||
window.history.replaceState({ path: path }, '', path);
|
||||
notifyChange(LocationActions.REPLACE);
|
||||
},
|
||||
|
||||
pop: History.back,
|
||||
|
||||
getCurrentPath: function getCurrentPath() {
|
||||
return decodeURI(window.location.pathname + window.location.search);
|
||||
},
|
||||
|
||||
toString: function toString() {
|
||||
return '<HistoryLocation>';
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports = HistoryLocation;
|
||||
31
node_modules/react-router/lib/locations/RefreshLocation.js
generated
vendored
31
node_modules/react-router/lib/locations/RefreshLocation.js
generated
vendored
@@ -1,31 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var HistoryLocation = require('./HistoryLocation');
|
||||
var History = require('../History');
|
||||
|
||||
/**
|
||||
* A Location that uses full page refreshes. This is used as
|
||||
* the fallback for HistoryLocation in browsers that do not
|
||||
* support the HTML5 history API.
|
||||
*/
|
||||
var RefreshLocation = {
|
||||
|
||||
push: function push(path) {
|
||||
window.location = path;
|
||||
},
|
||||
|
||||
replace: function replace(path) {
|
||||
window.location.replace(path);
|
||||
},
|
||||
|
||||
pop: History.back,
|
||||
|
||||
getCurrentPath: HistoryLocation.getCurrentPath,
|
||||
|
||||
toString: function toString() {
|
||||
return '<RefreshLocation>';
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports = RefreshLocation;
|
||||
49
node_modules/react-router/lib/locations/StaticLocation.js
generated
vendored
49
node_modules/react-router/lib/locations/StaticLocation.js
generated
vendored
@@ -1,49 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } };
|
||||
|
||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||
|
||||
var invariant = require('react/lib/invariant');
|
||||
|
||||
function throwCannotModify() {
|
||||
invariant(false, 'You cannot modify a static location');
|
||||
}
|
||||
|
||||
/**
|
||||
* A location that only ever contains a single path. Useful in
|
||||
* stateless environments like servers where there is no path history,
|
||||
* only the path that was used in the request.
|
||||
*/
|
||||
|
||||
var StaticLocation = (function () {
|
||||
function StaticLocation(path) {
|
||||
_classCallCheck(this, StaticLocation);
|
||||
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
_createClass(StaticLocation, [{
|
||||
key: 'getCurrentPath',
|
||||
value: function getCurrentPath() {
|
||||
return this.path;
|
||||
}
|
||||
}, {
|
||||
key: 'toString',
|
||||
value: function toString() {
|
||||
return '<StaticLocation path="' + this.path + '">';
|
||||
}
|
||||
}]);
|
||||
|
||||
return StaticLocation;
|
||||
})();
|
||||
|
||||
// TODO: Include these in the above class definition
|
||||
// once we can use ES7 property initializers.
|
||||
// https://github.com/babel/babel/issues/619
|
||||
|
||||
StaticLocation.prototype.push = throwCannotModify;
|
||||
StaticLocation.prototype.replace = throwCannotModify;
|
||||
StaticLocation.prototype.pop = throwCannotModify;
|
||||
|
||||
module.exports = StaticLocation;
|
||||
94
node_modules/react-router/lib/locations/TestLocation.js
generated
vendored
94
node_modules/react-router/lib/locations/TestLocation.js
generated
vendored
@@ -1,94 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } };
|
||||
|
||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||
|
||||
var invariant = require('react/lib/invariant');
|
||||
var LocationActions = require('../actions/LocationActions');
|
||||
var History = require('../History');
|
||||
|
||||
/**
|
||||
* A location that is convenient for testing and does not require a DOM.
|
||||
*/
|
||||
|
||||
var TestLocation = (function () {
|
||||
function TestLocation(history) {
|
||||
_classCallCheck(this, TestLocation);
|
||||
|
||||
this.history = history || [];
|
||||
this.listeners = [];
|
||||
this._updateHistoryLength();
|
||||
}
|
||||
|
||||
_createClass(TestLocation, [{
|
||||
key: 'needsDOM',
|
||||
get: function () {
|
||||
return false;
|
||||
}
|
||||
}, {
|
||||
key: '_updateHistoryLength',
|
||||
value: function _updateHistoryLength() {
|
||||
History.length = this.history.length;
|
||||
}
|
||||
}, {
|
||||
key: '_notifyChange',
|
||||
value: function _notifyChange(type) {
|
||||
var change = {
|
||||
path: this.getCurrentPath(),
|
||||
type: type
|
||||
};
|
||||
|
||||
for (var i = 0, len = this.listeners.length; i < len; ++i) this.listeners[i].call(this, change);
|
||||
}
|
||||
}, {
|
||||
key: 'addChangeListener',
|
||||
value: function addChangeListener(listener) {
|
||||
this.listeners.push(listener);
|
||||
}
|
||||
}, {
|
||||
key: 'removeChangeListener',
|
||||
value: function removeChangeListener(listener) {
|
||||
this.listeners = this.listeners.filter(function (l) {
|
||||
return l !== listener;
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'push',
|
||||
value: function push(path) {
|
||||
this.history.push(path);
|
||||
this._updateHistoryLength();
|
||||
this._notifyChange(LocationActions.PUSH);
|
||||
}
|
||||
}, {
|
||||
key: 'replace',
|
||||
value: function replace(path) {
|
||||
invariant(this.history.length, 'You cannot replace the current path with no history');
|
||||
|
||||
this.history[this.history.length - 1] = path;
|
||||
|
||||
this._notifyChange(LocationActions.REPLACE);
|
||||
}
|
||||
}, {
|
||||
key: 'pop',
|
||||
value: function pop() {
|
||||
this.history.pop();
|
||||
this._updateHistoryLength();
|
||||
this._notifyChange(LocationActions.POP);
|
||||
}
|
||||
}, {
|
||||
key: 'getCurrentPath',
|
||||
value: function getCurrentPath() {
|
||||
return this.history[this.history.length - 1];
|
||||
}
|
||||
}, {
|
||||
key: 'toString',
|
||||
value: function toString() {
|
||||
return '<TestLocation>';
|
||||
}
|
||||
}]);
|
||||
|
||||
return TestLocation;
|
||||
})();
|
||||
|
||||
module.exports = TestLocation;
|
||||
50
node_modules/react-router/lib/runRouter.js
generated
vendored
50
node_modules/react-router/lib/runRouter.js
generated
vendored
@@ -1,50 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var createRouter = require('./createRouter');
|
||||
|
||||
/**
|
||||
* A high-level convenience method that creates, configures, and
|
||||
* runs a router in one shot. The method signature is:
|
||||
*
|
||||
* Router.run(routes[, location ], callback);
|
||||
*
|
||||
* Using `window.location.hash` to manage the URL, you could do:
|
||||
*
|
||||
* Router.run(routes, function (Handler) {
|
||||
* React.render(<Handler/>, document.body);
|
||||
* });
|
||||
*
|
||||
* Using HTML5 history and a custom "cursor" prop:
|
||||
*
|
||||
* Router.run(routes, Router.HistoryLocation, function (Handler) {
|
||||
* React.render(<Handler cursor={cursor}/>, document.body);
|
||||
* });
|
||||
*
|
||||
* Returns the newly created router.
|
||||
*
|
||||
* Note: If you need to specify further options for your router such
|
||||
* as error/abort handling or custom scroll behavior, use Router.create
|
||||
* instead.
|
||||
*
|
||||
* var router = Router.create(options);
|
||||
* router.run(function (Handler) {
|
||||
* // ...
|
||||
* });
|
||||
*/
|
||||
function runRouter(routes, location, callback) {
|
||||
if (typeof location === 'function') {
|
||||
callback = location;
|
||||
location = null;
|
||||
}
|
||||
|
||||
var router = createRouter({
|
||||
routes: routes,
|
||||
location: location
|
||||
});
|
||||
|
||||
router.run(callback);
|
||||
|
||||
return router;
|
||||
}
|
||||
|
||||
module.exports = runRouter;
|
||||
16
node_modules/react-router/lib/supportsHistory.js
generated
vendored
16
node_modules/react-router/lib/supportsHistory.js
generated
vendored
@@ -1,16 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
function supportsHistory() {
|
||||
/*! taken from modernizr
|
||||
* https://github.com/Modernizr/Modernizr/blob/master/LICENSE
|
||||
* https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js
|
||||
* changed to avoid false negatives for Windows Phones: https://github.com/rackt/react-router/issues/586
|
||||
*/
|
||||
var ua = navigator.userAgent;
|
||||
if ((ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && ua.indexOf('Mobile Safari') !== -1 && ua.indexOf('Chrome') === -1 && ua.indexOf('Windows Phone') === -1) {
|
||||
return false;
|
||||
}
|
||||
return window.history && 'pushState' in window.history;
|
||||
}
|
||||
|
||||
module.exports = supportsHistory;
|
||||
26
node_modules/react-router/node_modules/object-assign/index.js
generated
vendored
26
node_modules/react-router/node_modules/object-assign/index.js
generated
vendored
@@ -1,26 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
function ToObject(val) {
|
||||
if (val == null) {
|
||||
throw new TypeError('Object.assign cannot be called with null or undefined');
|
||||
}
|
||||
|
||||
return Object(val);
|
||||
}
|
||||
|
||||
module.exports = Object.assign || function (target, source) {
|
||||
var from;
|
||||
var keys;
|
||||
var to = ToObject(target);
|
||||
|
||||
for (var s = 1; s < arguments.length; s++) {
|
||||
from = arguments[s];
|
||||
keys = Object.keys(Object(from));
|
||||
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
to[keys[i]] = from[keys[i]];
|
||||
}
|
||||
}
|
||||
|
||||
return to;
|
||||
};
|
||||
21
node_modules/react-router/node_modules/object-assign/license
generated
vendored
21
node_modules/react-router/node_modules/object-assign/license
generated
vendored
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
68
node_modules/react-router/node_modules/object-assign/package.json
generated
vendored
68
node_modules/react-router/node_modules/object-assign/package.json
generated
vendored
@@ -1,68 +0,0 @@
|
||||
{
|
||||
"name": "object-assign",
|
||||
"version": "2.1.1",
|
||||
"description": "ES6 Object.assign() ponyfill",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/sindresorhus/object-assign.git"
|
||||
},
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "http://sindresorhus.com"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"keywords": [
|
||||
"object",
|
||||
"assign",
|
||||
"extend",
|
||||
"properties",
|
||||
"es6",
|
||||
"ecmascript",
|
||||
"harmony",
|
||||
"ponyfill",
|
||||
"prollyfill",
|
||||
"polyfill",
|
||||
"shim",
|
||||
"browser"
|
||||
],
|
||||
"devDependencies": {
|
||||
"mocha": "*"
|
||||
},
|
||||
"gitHead": "4cd0365f5a78dd369473ca0bbd31f7b234148c42",
|
||||
"bugs": {
|
||||
"url": "https://github.com/sindresorhus/object-assign/issues"
|
||||
},
|
||||
"homepage": "https://github.com/sindresorhus/object-assign",
|
||||
"_id": "object-assign@2.1.1",
|
||||
"_shasum": "43c36e5d569ff8e4816c4efa8be02d26967c18aa",
|
||||
"_from": "object-assign@>=2.0.0 <3.0.0",
|
||||
"_npmVersion": "2.10.1",
|
||||
"_nodeVersion": "0.12.4",
|
||||
"_npmUser": {
|
||||
"name": "sindresorhus",
|
||||
"email": "sindresorhus@gmail.com"
|
||||
},
|
||||
"dist": {
|
||||
"shasum": "43c36e5d569ff8e4816c4efa8be02d26967c18aa",
|
||||
"tarball": "http://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "sindresorhus",
|
||||
"email": "sindresorhus@gmail.com"
|
||||
}
|
||||
],
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
}
|
||||
51
node_modules/react-router/node_modules/object-assign/readme.md
generated
vendored
51
node_modules/react-router/node_modules/object-assign/readme.md
generated
vendored
@@ -1,51 +0,0 @@
|
||||
# object-assign [](https://travis-ci.org/sindresorhus/object-assign)
|
||||
|
||||
> ES6 [`Object.assign()`](http://www.2ality.com/2014/01/object-assign.html) ponyfill
|
||||
|
||||
> Ponyfill: A polyfill that doesn't overwrite the native method
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
$ npm install --save object-assign
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var objectAssign = require('object-assign');
|
||||
|
||||
objectAssign({foo: 0}, {bar: 1});
|
||||
//=> {foo: 0, bar: 1}
|
||||
|
||||
// multiple sources
|
||||
objectAssign({foo: 0}, {bar: 1}, {baz: 2});
|
||||
//=> {foo: 0, bar: 1, baz: 2}
|
||||
|
||||
// overwrites equal keys
|
||||
objectAssign({foo: 0}, {foo: 1}, {foo: 2});
|
||||
//=> {foo: 2}
|
||||
|
||||
// ignores null and undefined sources
|
||||
objectAssign({foo: 0}, null, {bar: 1}, undefined);
|
||||
//=> {foo: 0, bar: 1}
|
||||
```
|
||||
|
||||
|
||||
## API
|
||||
|
||||
### objectAssign(target, source, [source, ...])
|
||||
|
||||
Assigns enumerable own properties of `source` objects to the `target` object and returns the `target` object. Additional `source` objects will overwrite previous ones.
|
||||
|
||||
|
||||
## Resources
|
||||
|
||||
- [ES6 spec - Object.assign](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign)
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Sindre Sorhus](http://sindresorhus.com)
|
||||
1
node_modules/react-router/node_modules/qs/.jshintignore
generated
vendored
1
node_modules/react-router/node_modules/qs/.jshintignore
generated
vendored
@@ -1 +0,0 @@
|
||||
node_modules
|
||||
10
node_modules/react-router/node_modules/qs/.jshintrc
generated
vendored
10
node_modules/react-router/node_modules/qs/.jshintrc
generated
vendored
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"node": true,
|
||||
|
||||
"curly": true,
|
||||
"latedef": true,
|
||||
"quotmark": true,
|
||||
"undef": true,
|
||||
"unused": true,
|
||||
"trailing": true
|
||||
}
|
||||
18
node_modules/react-router/node_modules/qs/.npmignore
generated
vendored
18
node_modules/react-router/node_modules/qs/.npmignore
generated
vendored
@@ -1,18 +0,0 @@
|
||||
.idea
|
||||
*.iml
|
||||
npm-debug.log
|
||||
dump.rdb
|
||||
node_modules
|
||||
results.tap
|
||||
results.xml
|
||||
npm-shrinkwrap.json
|
||||
config.json
|
||||
.DS_Store
|
||||
*/.DS_Store
|
||||
*/*/.DS_Store
|
||||
._*
|
||||
*/._*
|
||||
*/*/._*
|
||||
coverage.*
|
||||
lib-cov
|
||||
complexity.md
|
||||
6
node_modules/react-router/node_modules/qs/.travis.yml
generated
vendored
6
node_modules/react-router/node_modules/qs/.travis.yml
generated
vendored
@@ -1,6 +0,0 @@
|
||||
language: node_js
|
||||
|
||||
node_js:
|
||||
- 0.10
|
||||
- 0.12
|
||||
- iojs
|
||||
68
node_modules/react-router/node_modules/qs/CHANGELOG.md
generated
vendored
68
node_modules/react-router/node_modules/qs/CHANGELOG.md
generated
vendored
@@ -1,68 +0,0 @@
|
||||
|
||||
## [**2.3.3**](https://github.com/hapijs/qs/issues?milestone=18&state=open)
|
||||
- [**#59**](https://github.com/hapijs/qs/issues/59) make sure array indexes are >= 0, closes #57
|
||||
- [**#58**](https://github.com/hapijs/qs/issues/58) make qs usable for browser loader
|
||||
|
||||
## [**2.3.2**](https://github.com/hapijs/qs/issues?milestone=17&state=closed)
|
||||
- [**#55**](https://github.com/hapijs/qs/issues/55) allow merging a string into an object
|
||||
|
||||
## [**2.3.1**](https://github.com/hapijs/qs/issues?milestone=16&state=closed)
|
||||
- [**#52**](https://github.com/hapijs/qs/issues/52) Return "undefined" and "false" instead of throwing "TypeError".
|
||||
|
||||
## [**2.3.0**](https://github.com/hapijs/qs/issues?milestone=15&state=closed)
|
||||
- [**#50**](https://github.com/hapijs/qs/issues/50) add option to omit array indices, closes #46
|
||||
|
||||
## [**2.2.5**](https://github.com/hapijs/qs/issues?milestone=14&state=closed)
|
||||
- [**#39**](https://github.com/hapijs/qs/issues/39) Is there an alternative to Buffer.isBuffer?
|
||||
- [**#49**](https://github.com/hapijs/qs/issues/49) refactor utils.merge, fixes #45
|
||||
- [**#41**](https://github.com/hapijs/qs/issues/41) avoid browserifying Buffer, for #39
|
||||
|
||||
## [**2.2.4**](https://github.com/hapijs/qs/issues?milestone=13&state=closed)
|
||||
- [**#38**](https://github.com/hapijs/qs/issues/38) how to handle object keys beginning with a number
|
||||
|
||||
## [**2.2.3**](https://github.com/hapijs/qs/issues?milestone=12&state=closed)
|
||||
- [**#37**](https://github.com/hapijs/qs/issues/37) parser discards first empty value in array
|
||||
- [**#36**](https://github.com/hapijs/qs/issues/36) Update to lab 4.x
|
||||
|
||||
## [**2.2.2**](https://github.com/hapijs/qs/issues?milestone=11&state=closed)
|
||||
- [**#33**](https://github.com/hapijs/qs/issues/33) Error when plain object in a value
|
||||
- [**#34**](https://github.com/hapijs/qs/issues/34) use Object.prototype.hasOwnProperty.call instead of obj.hasOwnProperty
|
||||
- [**#24**](https://github.com/hapijs/qs/issues/24) Changelog? Semver?
|
||||
|
||||
## [**2.2.1**](https://github.com/hapijs/qs/issues?milestone=10&state=closed)
|
||||
- [**#32**](https://github.com/hapijs/qs/issues/32) account for circular references properly, closes #31
|
||||
- [**#31**](https://github.com/hapijs/qs/issues/31) qs.parse stackoverflow on circular objects
|
||||
|
||||
## [**2.2.0**](https://github.com/hapijs/qs/issues?milestone=9&state=closed)
|
||||
- [**#26**](https://github.com/hapijs/qs/issues/26) Don't use Buffer global if it's not present
|
||||
- [**#30**](https://github.com/hapijs/qs/issues/30) Bug when merging non-object values into arrays
|
||||
- [**#29**](https://github.com/hapijs/qs/issues/29) Don't call Utils.clone at the top of Utils.merge
|
||||
- [**#23**](https://github.com/hapijs/qs/issues/23) Ability to not limit parameters?
|
||||
|
||||
## [**2.1.0**](https://github.com/hapijs/qs/issues?milestone=8&state=closed)
|
||||
- [**#22**](https://github.com/hapijs/qs/issues/22) Enable using a RegExp as delimiter
|
||||
|
||||
## [**2.0.0**](https://github.com/hapijs/qs/issues?milestone=7&state=closed)
|
||||
- [**#18**](https://github.com/hapijs/qs/issues/18) Why is there arrayLimit?
|
||||
- [**#20**](https://github.com/hapijs/qs/issues/20) Configurable parametersLimit
|
||||
- [**#21**](https://github.com/hapijs/qs/issues/21) make all limits optional, for #18, for #20
|
||||
|
||||
## [**1.2.2**](https://github.com/hapijs/qs/issues?milestone=6&state=closed)
|
||||
- [**#19**](https://github.com/hapijs/qs/issues/19) Don't overwrite null values
|
||||
|
||||
## [**1.2.1**](https://github.com/hapijs/qs/issues?milestone=5&state=closed)
|
||||
- [**#16**](https://github.com/hapijs/qs/issues/16) ignore non-string delimiters
|
||||
- [**#15**](https://github.com/hapijs/qs/issues/15) Close code block
|
||||
|
||||
## [**1.2.0**](https://github.com/hapijs/qs/issues?milestone=4&state=closed)
|
||||
- [**#12**](https://github.com/hapijs/qs/issues/12) Add optional delim argument
|
||||
- [**#13**](https://github.com/hapijs/qs/issues/13) fix #11: flattened keys in array are now correctly parsed
|
||||
|
||||
## [**1.1.0**](https://github.com/hapijs/qs/issues?milestone=3&state=closed)
|
||||
- [**#7**](https://github.com/hapijs/qs/issues/7) Empty values of a POST array disappear after being submitted
|
||||
- [**#9**](https://github.com/hapijs/qs/issues/9) Should not omit equals signs (=) when value is null
|
||||
- [**#6**](https://github.com/hapijs/qs/issues/6) Minor grammar fix in README
|
||||
|
||||
## [**1.0.2**](https://github.com/hapijs/qs/issues?milestone=2&state=closed)
|
||||
- [**#5**](https://github.com/hapijs/qs/issues/5) array holes incorrectly copied into object on large index
|
||||
|
||||
1
node_modules/react-router/node_modules/qs/CONTRIBUTING.md
generated
vendored
1
node_modules/react-router/node_modules/qs/CONTRIBUTING.md
generated
vendored
@@ -1 +0,0 @@
|
||||
Please view our [hapijs contributing guide](https://github.com/hapijs/hapi/blob/master/CONTRIBUTING.md).
|
||||
28
node_modules/react-router/node_modules/qs/LICENSE
generated
vendored
28
node_modules/react-router/node_modules/qs/LICENSE
generated
vendored
@@ -1,28 +0,0 @@
|
||||
Copyright (c) 2014 Nathan LaFreniere and other contributors.
|
||||
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 names of any contributors 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS 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.
|
||||
|
||||
* * *
|
||||
|
||||
The complete list of contributors can be found at: https://github.com/hapijs/qs/graphs/contributors
|
||||
8
node_modules/react-router/node_modules/qs/Makefile
generated
vendored
8
node_modules/react-router/node_modules/qs/Makefile
generated
vendored
@@ -1,8 +0,0 @@
|
||||
test:
|
||||
@node node_modules/lab/bin/lab -a code -L
|
||||
test-cov:
|
||||
@node node_modules/lab/bin/lab -a code -t 100 -L
|
||||
test-cov-html:
|
||||
@node node_modules/lab/bin/lab -a code -L -r html -o coverage.html
|
||||
|
||||
.PHONY: test test-cov test-cov-html
|
||||
233
node_modules/react-router/node_modules/qs/README.md
generated
vendored
233
node_modules/react-router/node_modules/qs/README.md
generated
vendored
@@ -1,233 +0,0 @@
|
||||
# qs
|
||||
|
||||
A querystring parsing and stringifying library with some added security.
|
||||
|
||||
[](http://travis-ci.org/hapijs/qs)
|
||||
|
||||
Lead Maintainer: [Nathan LaFreniere](https://github.com/nlf)
|
||||
|
||||
The **qs** module was originally created and maintained by [TJ Holowaychuk](https://github.com/visionmedia/node-querystring).
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
var Qs = require('qs');
|
||||
|
||||
var obj = Qs.parse('a=c'); // { a: 'c' }
|
||||
var str = Qs.stringify(obj); // 'a=c'
|
||||
```
|
||||
|
||||
### Parsing Objects
|
||||
|
||||
```javascript
|
||||
Qs.parse(string, [options]);
|
||||
```
|
||||
|
||||
**qs** allows you to create nested objects within your query strings, by surrounding the name of sub-keys with square brackets `[]`.
|
||||
For example, the string `'foo[bar]=baz'` converts to:
|
||||
|
||||
```javascript
|
||||
{
|
||||
foo: {
|
||||
bar: 'baz'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
URI encoded strings work too:
|
||||
|
||||
```javascript
|
||||
Qs.parse('a%5Bb%5D=c');
|
||||
// { a: { b: 'c' } }
|
||||
```
|
||||
|
||||
You can also nest your objects, like `'foo[bar][baz]=foobarbaz'`:
|
||||
|
||||
```javascript
|
||||
{
|
||||
foo: {
|
||||
bar: {
|
||||
baz: 'foobarbaz'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
By default, when nesting objects **qs** will only parse up to 5 children deep. This means if you attempt to parse a string like
|
||||
`'a[b][c][d][e][f][g][h][i]=j'` your resulting object will be:
|
||||
|
||||
```javascript
|
||||
{
|
||||
a: {
|
||||
b: {
|
||||
c: {
|
||||
d: {
|
||||
e: {
|
||||
f: {
|
||||
'[g][h][i]': 'j'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This depth can be overridden by passing a `depth` option to `Qs.parse(string, [options])`:
|
||||
|
||||
```javascript
|
||||
Qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1 });
|
||||
// { a: { b: { '[c][d][e][f][g][h][i]': 'j' } } }
|
||||
```
|
||||
|
||||
The depth limit helps mitigate abuse when **qs** is used to parse user input, and it is recommended to keep it a reasonably small number.
|
||||
|
||||
For similar reasons, by default **qs** will only parse up to 1000 parameters. This can be overridden by passing a `parameterLimit` option:
|
||||
|
||||
```javascript
|
||||
Qs.parse('a=b&c=d', { parameterLimit: 1 });
|
||||
// { a: 'b' }
|
||||
```
|
||||
|
||||
An optional delimiter can also be passed:
|
||||
|
||||
```javascript
|
||||
Qs.parse('a=b;c=d', { delimiter: ';' });
|
||||
// { a: 'b', c: 'd' }
|
||||
```
|
||||
|
||||
Delimiters can be a regular expression too:
|
||||
|
||||
```javascript
|
||||
Qs.parse('a=b;c=d,e=f', { delimiter: /[;,]/ });
|
||||
// { a: 'b', c: 'd', e: 'f' }
|
||||
```
|
||||
|
||||
### Parsing Arrays
|
||||
|
||||
**qs** can also parse arrays using a similar `[]` notation:
|
||||
|
||||
```javascript
|
||||
Qs.parse('a[]=b&a[]=c');
|
||||
// { a: ['b', 'c'] }
|
||||
```
|
||||
|
||||
You may specify an index as well:
|
||||
|
||||
```javascript
|
||||
Qs.parse('a[1]=c&a[0]=b');
|
||||
// { a: ['b', 'c'] }
|
||||
```
|
||||
|
||||
Note that the only difference between an index in an array and a key in an object is that the value between the brackets must be a number
|
||||
to create an array. When creating arrays with specific indices, **qs** will compact a sparse array to only the existing values preserving
|
||||
their order:
|
||||
|
||||
```javascript
|
||||
Qs.parse('a[1]=b&a[15]=c');
|
||||
// { a: ['b', 'c'] }
|
||||
```
|
||||
|
||||
Note that an empty string is also a value, and will be preserved:
|
||||
|
||||
```javascript
|
||||
Qs.parse('a[]=&a[]=b');
|
||||
// { a: ['', 'b'] }
|
||||
Qs.parse('a[0]=b&a[1]=&a[2]=c');
|
||||
// { a: ['b', '', 'c'] }
|
||||
```
|
||||
|
||||
**qs** will also limit specifying indices in an array to a maximum index of `20`. Any array members with an index of greater than `20` will
|
||||
instead be converted to an object with the index as the key:
|
||||
|
||||
```javascript
|
||||
Qs.parse('a[100]=b');
|
||||
// { a: { '100': 'b' } }
|
||||
```
|
||||
|
||||
This limit can be overridden by passing an `arrayLimit` option:
|
||||
|
||||
```javascript
|
||||
Qs.parse('a[1]=b', { arrayLimit: 0 });
|
||||
// { a: { '1': 'b' } }
|
||||
```
|
||||
|
||||
To disable array parsing entirely, set `arrayLimit` to `-1`.
|
||||
|
||||
If you mix notations, **qs** will merge the two items into an object:
|
||||
|
||||
```javascript
|
||||
Qs.parse('a[0]=b&a[b]=c');
|
||||
// { a: { '0': 'b', b: 'c' } }
|
||||
```
|
||||
|
||||
You can also create arrays of objects:
|
||||
|
||||
```javascript
|
||||
Qs.parse('a[][b]=c');
|
||||
// { a: [{ b: 'c' }] }
|
||||
```
|
||||
|
||||
### Stringifying
|
||||
|
||||
```javascript
|
||||
Qs.stringify(object, [options]);
|
||||
```
|
||||
|
||||
When stringifying, **qs** always URI encodes output. Objects are stringified as you would expect:
|
||||
|
||||
```javascript
|
||||
Qs.stringify({ a: 'b' });
|
||||
// 'a=b'
|
||||
Qs.stringify({ a: { b: 'c' } });
|
||||
// 'a%5Bb%5D=c'
|
||||
```
|
||||
|
||||
Examples beyond this point will be shown as though the output is not URI encoded for clarity. Please note that the return values in these cases *will* be URI encoded during real usage.
|
||||
|
||||
When arrays are stringified, by default they are given explicit indices:
|
||||
|
||||
```javascript
|
||||
Qs.stringify({ a: ['b', 'c', 'd'] });
|
||||
// 'a[0]=b&a[1]=c&a[2]=d'
|
||||
```
|
||||
|
||||
You may override this by setting the `indices` option to `false`:
|
||||
|
||||
```javascript
|
||||
Qs.stringify({ a: ['b', 'c', 'd'] }, { indices: false });
|
||||
// 'a=b&a=c&a=d'
|
||||
```
|
||||
|
||||
You may use the `arrayFormat` option to specify the format of the output array
|
||||
|
||||
```javascript
|
||||
Qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' })
|
||||
// 'a[0]=b&a[1]=c'
|
||||
Qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' })
|
||||
// 'a[]=b&a[]=c'
|
||||
Qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })
|
||||
// 'a=b&a=c'
|
||||
```
|
||||
|
||||
Empty strings and null values will omit the value, but the equals sign (=) remains in place:
|
||||
|
||||
```javascript
|
||||
Qs.stringify({ a: '' });
|
||||
// 'a='
|
||||
```
|
||||
|
||||
Properties that are set to `undefined` will be omitted entirely:
|
||||
|
||||
```javascript
|
||||
Qs.stringify({ a: null, b: undefined });
|
||||
// 'a='
|
||||
```
|
||||
|
||||
The delimiter may be overridden with stringify as well:
|
||||
|
||||
```javascript
|
||||
Qs.stringify({ a: 'b', c: 'd' }, { delimiter: ';' });
|
||||
// 'a=b;c=d'
|
||||
```
|
||||
1
node_modules/react-router/node_modules/qs/index.js
generated
vendored
1
node_modules/react-router/node_modules/qs/index.js
generated
vendored
@@ -1 +0,0 @@
|
||||
module.exports = require('./lib/');
|
||||
15
node_modules/react-router/node_modules/qs/lib/index.js
generated
vendored
15
node_modules/react-router/node_modules/qs/lib/index.js
generated
vendored
@@ -1,15 +0,0 @@
|
||||
// Load modules
|
||||
|
||||
var Stringify = require('./stringify');
|
||||
var Parse = require('./parse');
|
||||
|
||||
|
||||
// Declare internals
|
||||
|
||||
var internals = {};
|
||||
|
||||
|
||||
module.exports = {
|
||||
stringify: Stringify,
|
||||
parse: Parse
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user