Showing
25 changed files
with
3705 additions
and
1016 deletions
Too many changes to show.
To preserve performance only 25 of 103 files are displayed.
.idea/.generators
deleted
100644 → 0
| 1 | -<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | -<Settings><!--This file was automatically generated by Ruby plugin. | |
| 3 | -You are allowed to: | |
| 4 | -1. Reorder generators | |
| 5 | -2. Remove generators | |
| 6 | -3. Add installed generators | |
| 7 | -To add new installed generators automatically delete this file and reload the project. | |
| 8 | ---><GeneratorsGroup><Generator name="active_record:devise" /><Generator name="assets" /><Generator name="controller" /><Generator name="delayed_job" /><Generator name="delayed_job:active_record" /><Generator name="delayed_job:upgrade" /><Generator name="devise" /><Generator name="devise:controllers" /><Generator name="devise:install" /><Generator name="devise:views" /><Generator name="factory_girl:model" /><Generator name="generator" /><Generator name="helper" /><Generator name="integration_test" /><Generator name="jbuilder" /><Generator name="job" /><Generator name="js:assets" /><Generator name="mailer" /><Generator name="migration" /><Generator name="model" /><Generator name="mongoid:devise" /><Generator name="resource" /><Generator name="responders:install" /><Generator name="responders_controller" /><Generator name="rspec:controller" /><Generator name="rspec:feature" /><Generator name="rspec:helper" /><Generator name="rspec:install" /><Generator name="rspec:integration" /><Generator name="rspec:job" /><Generator name="rspec:mailer" /><Generator name="rspec:model" /><Generator name="rspec:observer" /><Generator name="rspec:request" /><Generator name="rspec:scaffold" /><Generator name="rspec:view" /><Generator name="sass:assets" /><Generator name="scaffold" /><Generator name="scaffold_controller" /><Generator name="scss:assets" /><Generator name="task" /><Generator name="test_unit:generator" /><Generator name="test_unit:job" /><Generator name="test_unit:plugin" /></GeneratorsGroup></Settings> |
.idea/.name
deleted
100644 → 0
| 1 | -kanjai | |
| \ No newline at end of file |
.idea/.rakeTasks
deleted
100644 → 0
| 1 | -<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | -<Settings><!--This file was automatically generated by Ruby plugin. | |
| 3 | -You are allowed to: | |
| 4 | -1. Remove rake task | |
| 5 | -2. Add existing rake tasks | |
| 6 | -To add existing rake tasks automatically delete this file and reload the project. | |
| 7 | ---><RakeGroup description="" fullCmd="" taksId="rake"><RakeGroup description="" fullCmd="" taksId="app"><RakeTask description="List versions of all Rails frameworks and the environment" fullCmd="app:about" taksId="about" /><RakeGroup description="" fullCmd="" taksId="assets"><RakeTask description="Remove old compiled assets" fullCmd="app:assets:clean[keep]" taksId="clean[keep]" /><RakeTask description="Remove compiled assets" fullCmd="app:assets:clobber" taksId="clobber" /><RakeTask description="Load asset compile environment" fullCmd="app:assets:environment" taksId="environment" /><RakeTask description="Compile all the assets named in config.assets.precompile" fullCmd="app:assets:precompile" taksId="precompile" /><RakeTask description="" fullCmd="app:assets:clean" taksId="clean" /></RakeGroup><RakeGroup description="" fullCmd="" taksId="cache_digests"><RakeTask description="Lookup first-level dependencies for TEMPLATE (like messages/show or comments/_comment.html)" fullCmd="app:cache_digests:dependencies" taksId="dependencies" /><RakeTask description="Lookup nested dependencies for TEMPLATE (like messages/show or comments/_comment.html)" fullCmd="app:cache_digests:nested_dependencies" taksId="nested_dependencies" /></RakeGroup><RakeGroup description="" fullCmd="" taksId="db"><RakeTask description="Creates the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:create:all to create all databases in the config)" fullCmd="app:db:create" taksId="create" /><RakeTask description="Drops the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:drop:all to drop all databases in the config)" fullCmd="app:db:drop" taksId="drop" /><RakeGroup description="" fullCmd="" taksId="fixtures"><RakeTask description="Load fixtures into the current environment's database" fullCmd="app:db:fixtures:load" taksId="load" /><RakeTask description="" fullCmd="app:db:fixtures:identify" taksId="identify" /></RakeGroup><RakeTask description="Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)" fullCmd="app:db:migrate" taksId="migrate" /><RakeGroup description="" fullCmd="" taksId="migrate"><RakeTask description="Display status of migrations" fullCmd="app:db:migrate:status" taksId="status" /><RakeTask description="" fullCmd="app:db:migrate:down" taksId="down" /><RakeTask description="" fullCmd="app:db:migrate:redo" taksId="redo" /><RakeTask description="" fullCmd="app:db:migrate:reset" taksId="reset" /><RakeTask description="" fullCmd="app:db:migrate:up" taksId="up" /></RakeGroup><RakeTask description="Rolls the schema back to the previous version (specify steps w/ STEP=n)" fullCmd="app:db:rollback" taksId="rollback" /><RakeGroup description="" fullCmd="" taksId="schema"><RakeGroup description="" fullCmd="" taksId="cache"><RakeTask description="Clear a db/schema_cache.dump file" fullCmd="app:db:schema:cache:clear" taksId="clear" /><RakeTask description="Create a db/schema_cache.dump file" fullCmd="app:db:schema:cache:dump" taksId="dump" /></RakeGroup><RakeTask description="Create a db/schema.rb file that is portable against any DB supported by AR" fullCmd="app:db:schema:dump" taksId="dump" /><RakeTask description="Load a schema.rb file into the database" fullCmd="app:db:schema:load" taksId="load" /><RakeTask description="" fullCmd="app:db:schema:load_if_ruby" taksId="load_if_ruby" /></RakeGroup><RakeTask description="Load the seed data from db/seeds.rb" fullCmd="app:db:seed" taksId="seed" /><RakeTask description="Create the database, load the schema, and initialize with the seed data (use db:reset to also drop the database first)" fullCmd="app:db:setup" taksId="setup" /><RakeGroup description="" fullCmd="" taksId="structure"><RakeTask description="Dump the database structure to db/structure.sql" fullCmd="app:db:structure:dump" taksId="dump" /><RakeTask description="Recreate the databases from the structure.sql file" fullCmd="app:db:structure:load" taksId="load" /><RakeTask description="" fullCmd="app:db:structure:load_if_sql" taksId="load_if_sql" /></RakeGroup><RakeTask description="Retrieves the current schema version number" fullCmd="app:db:version" taksId="version" /><RakeTask description="" fullCmd="app:db:_dump" taksId="_dump" /><RakeTask description="" fullCmd="app:db:abort_if_pending_migrations" taksId="abort_if_pending_migrations" /><RakeTask description="" fullCmd="app:db:charset" taksId="charset" /><RakeTask description="" fullCmd="app:db:collation" taksId="collation" /><RakeGroup description="" fullCmd="" taksId="create"><RakeTask description="" fullCmd="app:db:create:all" taksId="all" /></RakeGroup><RakeGroup description="" fullCmd="" taksId="drop"><RakeTask description="" fullCmd="app:db:drop:all" taksId="all" /></RakeGroup><RakeTask description="" fullCmd="app:db:forward" taksId="forward" /><RakeTask description="" fullCmd="app:db:load_config" taksId="load_config" /><RakeTask description="" fullCmd="app:db:purge" taksId="purge" /><RakeGroup description="" fullCmd="" taksId="purge"><RakeTask description="" fullCmd="app:db:purge:all" taksId="all" /></RakeGroup><RakeTask description="" fullCmd="app:db:reset" taksId="reset" /><RakeGroup description="" fullCmd="" taksId="test"><RakeTask description="" fullCmd="app:db:test:clone" taksId="clone" /><RakeTask description="" fullCmd="app:db:test:clone_schema" taksId="clone_schema" /><RakeTask description="" fullCmd="app:db:test:clone_structure" taksId="clone_structure" /><RakeTask description="" fullCmd="app:db:test:deprecated" taksId="deprecated" /><RakeTask description="" fullCmd="app:db:test:load" taksId="load" /><RakeTask description="" fullCmd="app:db:test:load_schema" taksId="load_schema" /><RakeTask description="" fullCmd="app:db:test:load_structure" taksId="load_structure" /><RakeTask description="" fullCmd="app:db:test:prepare" taksId="prepare" /><RakeTask description="" fullCmd="app:db:test:purge" taksId="purge" /></RakeGroup></RakeGroup><RakeGroup description="" fullCmd="" taksId="doc"><RakeTask description="Generate docs for the app -- also available doc:rails, doc:guides (options: TEMPLATE=/rdoc-template.rb, TITLE="Custom Title")" fullCmd="app:doc:app" taksId="app" /><RakeTask description="" fullCmd="app:doc:clobber" taksId="clobber" /><RakeTask description="" fullCmd="app:doc:clobber_app" taksId="clobber_app" /><RakeTask description="" fullCmd="app:doc:clobber_rails" taksId="clobber_rails" /><RakeTask description="" fullCmd="app:doc:guides" taksId="guides" /><RakeTask description="" fullCmd="app:doc:rails" taksId="rails" /><RakeTask description="" fullCmd="app:doc:reapp" taksId="reapp" /><RakeTask description="" fullCmd="app:doc:rerails" taksId="rerails" /></RakeGroup><RakeGroup description="" fullCmd="" taksId="install"><RakeTask description="This task test soap" fullCmd="app:install:user" taksId="user" /><RakeTask description="" fullCmd="app:install:zip_example" taksId="zip_example" /></RakeGroup><RakeGroup description="" fullCmd="" taksId="jobs"><RakeTask description="Exit with error status if any jobs older than max_age seconds haven't been attempted yet" fullCmd="app:jobs:check[max_age]" taksId="check[max_age]" /><RakeTask description="Clear the delayed_job queue" fullCmd="app:jobs:clear" taksId="clear" /><RakeTask description="Start a delayed_job worker" fullCmd="app:jobs:work" taksId="work" /><RakeTask description="Start a delayed_job worker and exit when all available jobs are complete" fullCmd="app:jobs:workoff" taksId="workoff" /><RakeTask description="" fullCmd="app:jobs:check" taksId="check" /><RakeTask description="" fullCmd="app:jobs:environment_options" taksId="environment_options" /></RakeGroup><RakeGroup description="" fullCmd="" taksId="kanjai"><RakeGroup description="" fullCmd="" taksId="install"><RakeTask description="Copy migrations from kanjai to application" fullCmd="app:kanjai:install:migrations" taksId="migrations" /></RakeGroup></RakeGroup><RakeGroup description="" fullCmd="" taksId="log"><RakeTask description="Truncates all *.log files in log/ to zero bytes (specify which logs with LOGS=test,development)" fullCmd="app:log:clear" taksId="clear" /></RakeGroup><RakeTask description="Prints out your Rack middleware stack" fullCmd="app:middleware" taksId="middleware" /><RakeTask description="Enumerate all annotations (use notes:optimize, :fixme, :todo for focus)" fullCmd="app:notes" taksId="notes" /><RakeGroup description="" fullCmd="" taksId="notes"><RakeTask description="Enumerate a custom annotation, specify with ANNOTATION=CUSTOM" fullCmd="app:notes:custom" taksId="custom" /><RakeTask description="" fullCmd="app:notes:fixme" taksId="fixme" /><RakeTask description="" fullCmd="app:notes:optimize" taksId="optimize" /><RakeTask description="" fullCmd="app:notes:todo" taksId="todo" /></RakeGroup><RakeGroup description="" fullCmd="" taksId="rails"><RakeTask description="Applies the template supplied by LOCATION=(/path/to/template) or URL" fullCmd="app:rails:template" taksId="template" /><RakeTask description="Update configs and some other initially generated files (or use just update:configs or update:bin)" fullCmd="app:rails:update" taksId="update" /><RakeGroup description="" fullCmd="" taksId="templates"><RakeTask description="" fullCmd="app:rails:templates:copy" taksId="copy" /></RakeGroup><RakeGroup description="" fullCmd="" taksId="update"><RakeTask description="" fullCmd="app:rails:update:bin" taksId="bin" /><RakeTask description="" fullCmd="app:rails:update:configs" taksId="configs" /></RakeGroup></RakeGroup><RakeTask description="Print out all defined routes in match order, with names" fullCmd="app:routes" taksId="routes" /><RakeTask description="Generate a cryptographically secure secret key (this is typically used to generate a secret for cookie sessions)" fullCmd="app:secret" taksId="secret" /><RakeTask description="Runs all tests in test folder" fullCmd="app:test" taksId="test" /><RakeGroup description="" fullCmd="" taksId="test"><RakeTask description="Run tests quickly by merging all types and not resetting db" fullCmd="app:test:all" taksId="all" /><RakeGroup description="" fullCmd="" taksId="all"><RakeTask description="Run tests quickly, but also reset db" fullCmd="app:test:all:db" taksId="db" /></RakeGroup><RakeTask description="Run tests quickly, but also reset db" fullCmd="app:test:db" taksId="db" /><RakeTask description="" fullCmd="app:test:controllers" taksId="controllers" /><RakeTask description="" fullCmd="app:test:deprecate_all" taksId="deprecate_all" /><RakeTask description="" fullCmd="app:test:functionals" taksId="functionals" /><RakeTask description="" fullCmd="app:test:generators" taksId="generators" /><RakeTask description="" fullCmd="app:test:helpers" taksId="helpers" /><RakeTask description="" fullCmd="app:test:integration" taksId="integration" /><RakeTask description="" fullCmd="app:test:jobs" taksId="jobs" /><RakeTask description="" fullCmd="app:test:mailers" taksId="mailers" /><RakeTask description="" fullCmd="app:test:models" taksId="models" /><RakeTask description="" fullCmd="app:test:prepare" taksId="prepare" /><RakeTask description="" fullCmd="app:test:run" taksId="run" /><RakeTask description="" fullCmd="app:test:single" taksId="single" /><RakeTask description="" fullCmd="app:test:units" taksId="units" /></RakeGroup><RakeGroup description="" fullCmd="" taksId="time"><RakeGroup description="" fullCmd="" taksId="zones"><RakeTask description="Displays all time zones, also available: time:zones:us, time:zones:local -- filter with OFFSET parameter, e.g., OFFSET=-6" fullCmd="app:time:zones:all" taksId="all" /><RakeTask description="" fullCmd="app:time:zones:local" taksId="local" /><RakeTask description="" fullCmd="app:time:zones:us" taksId="us" /></RakeGroup></RakeGroup><RakeGroup description="" fullCmd="" taksId="tmp"><RakeTask description="Clear session, cache, and socket files from tmp/ (narrow w/ tmp:sessions:clear, tmp:cache:clear, tmp:sockets:clear)" fullCmd="app:tmp:clear" taksId="clear" /><RakeTask description="Creates tmp directories for sessions, cache, sockets, and pids" fullCmd="app:tmp:create" taksId="create" /><RakeGroup description="" fullCmd="" taksId="cache"><RakeTask description="" fullCmd="app:tmp:cache:clear" taksId="clear" /></RakeGroup><RakeGroup description="" fullCmd="" taksId="pids"><RakeTask description="" fullCmd="app:tmp:pids:clear" taksId="clear" /></RakeGroup><RakeGroup description="" fullCmd="" taksId="sessions"><RakeTask description="" fullCmd="app:tmp:sessions:clear" taksId="clear" /></RakeGroup><RakeGroup description="" fullCmd="" taksId="sockets"><RakeTask description="" fullCmd="app:tmp:sockets:clear" taksId="clear" /></RakeGroup></RakeGroup><RakeTask description="" fullCmd="app:default" taksId="default" /><RakeTask description="" fullCmd="app:environment" taksId="environment" /><RakeGroup description="" fullCmd="" taksId="railties"><RakeGroup description="" fullCmd="" taksId="install"><RakeTask description="" fullCmd="app:railties:install:migrations" taksId="migrations" /></RakeGroup></RakeGroup></RakeGroup><RakeTask description="Build kanjai-0.0.25.gem into the pkg directory" fullCmd="build" taksId="build" /><RakeTask description="Remove RDoc HTML files" fullCmd="clobber_rdoc" taksId="clobber_rdoc" /><RakeGroup description="" fullCmd="" taksId="db"><RakeTask description="Create the database from config/database.yml for the current Rails.env (use db:create:all to create all databases in the config)" fullCmd="db:create" taksId="create" /><RakeTask description="Drops the database for the current Rails.env (use db:drop:all to drop all databases)" fullCmd="db:drop" taksId="drop" /><RakeGroup description="" fullCmd="" taksId="fixtures"><RakeTask description="Load fixtures into the current environment's database" fullCmd="db:fixtures:load" taksId="load" /></RakeGroup><RakeTask description="Migrate the database (options: VERSION=x, VERBOSE=false)" fullCmd="db:migrate" taksId="migrate" /><RakeGroup description="" fullCmd="" taksId="migrate"><RakeTask description="Display status of migrations" fullCmd="db:migrate:status" taksId="status" /><RakeTask description="" fullCmd="db:migrate:down" taksId="down" /><RakeTask description="" fullCmd="db:migrate:redo" taksId="redo" /><RakeTask description="" fullCmd="db:migrate:reset" taksId="reset" /><RakeTask description="" fullCmd="db:migrate:up" taksId="up" /></RakeGroup><RakeTask description="Rolls the schema back to the previous version (specify steps w/ STEP=n)" fullCmd="db:rollback" taksId="rollback" /><RakeGroup description="" fullCmd="" taksId="schema"><RakeTask description="Create a db/schema.rb file that can be portably used against any DB supported by AR" fullCmd="db:schema:dump" taksId="dump" /><RakeTask description="Load a schema.rb file into the database" fullCmd="db:schema:load" taksId="load" /></RakeGroup><RakeTask description="Load the seed data from db/seeds.rb" fullCmd="db:seed" taksId="seed" /><RakeTask description="Create the database, load the schema, and initialize with the seed data (use db:reset to also drop the db first)" fullCmd="db:setup" taksId="setup" /><RakeGroup description="" fullCmd="" taksId="structure"><RakeTask description="Dump the database structure to an SQL file" fullCmd="db:structure:dump" taksId="dump" /></RakeGroup><RakeTask description="Retrieves the current schema version number" fullCmd="db:version" taksId="version" /><RakeGroup description="" fullCmd="" taksId="create"><RakeTask description="" fullCmd="db:create:all" taksId="all" /></RakeGroup><RakeGroup description="" fullCmd="" taksId="drop"><RakeTask description="" fullCmd="db:drop:all" taksId="all" /></RakeGroup><RakeTask description="" fullCmd="db:reset" taksId="reset" /></RakeGroup><RakeTask description="Build and install kanjai-0.0.25.gem into system gems" fullCmd="install" taksId="install" /><RakeTask description="Build RDoc HTML files" fullCmd="rdoc" taksId="rdoc" /><RakeTask description="Create tag v0.0.25 and build and push kanjai-0.0.25.gem to Rubygems" fullCmd="release" taksId="release" /><RakeTask description="Rebuild RDoc HTML files" fullCmd="rerdoc" taksId="rerdoc" /><RakeTask description="Report code statistics (KLOCs, etc) from the application or engine" fullCmd="stats" taksId="stats" /><RakeTask description="Run tests" fullCmd="test" taksId="test" /><RakeTask description="" fullCmd="clobber" taksId="clobber" /><RakeTask description="" fullCmd="default" taksId="default" /><RakeTask description="" fullCmd="doc" taksId="doc" /><RakeTask description="" fullCmd="doc/app" taksId="doc/app" /><RakeTask description="" fullCmd="doc/app/created.rid" taksId="doc/app/created.rid" /><RakeTask description="" fullCmd="environment" taksId="environment" /><RakeTask description="" fullCmd="html" taksId="html" /><RakeTask description="" fullCmd="html/created.rid" taksId="html/created.rid" /><RakeTask description="" fullCmd="load_app" taksId="load_app" /><RakeTask description="" fullCmd="rdoc/created.rid" taksId="rdoc/created.rid" /><RakeGroup description="" fullCmd="" taksId="release"><RakeTask description="" fullCmd="release:guard_clean" taksId="guard_clean" /><RakeTask description="" fullCmd="release:rubygem_push" taksId="rubygem_push" /><RakeTask description="" fullCmd="release:source_control_push" taksId="source_control_push" /></RakeGroup><RakeTask description="" fullCmd="tmp" taksId="tmp" /><RakeTask description="" fullCmd="tmp/cache" taksId="tmp/cache" /><RakeTask description="" fullCmd="tmp/cache/assets" taksId="tmp/cache/assets" /><RakeTask description="" fullCmd="tmp/cache/assets/development" taksId="tmp/cache/assets/development" /><RakeTask description="" fullCmd="tmp/cache/assets/production" taksId="tmp/cache/assets/production" /><RakeTask description="" fullCmd="tmp/cache/assets/test" taksId="tmp/cache/assets/test" /><RakeTask description="" fullCmd="tmp/pids" taksId="tmp/pids" /><RakeTask description="" fullCmd="tmp/sessions" taksId="tmp/sessions" /><RakeTask description="" fullCmd="tmp/sockets" taksId="tmp/sockets" /></RakeGroup></Settings> |
.idea/encodings.xml
deleted
100644 → 0
.idea/inspectionProfiles/Project_Default.xml
deleted
100644 → 0
| 1 | -<component name="InspectionProjectProfileManager"> | |
| 2 | - <profile version="1.0" is_locked="false"> | |
| 3 | - <option name="myName" value="Project Default" /> | |
| 4 | - <inspection_tool class="Rubocop" enabled="false" level="WARNING" enabled_by_default="false" /> | |
| 5 | - </profile> | |
| 6 | -</component> | |
| \ No newline at end of file |
.idea/kanjai.iml
deleted
100644 → 0
| 1 | -<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | -<module type="RUBY_MODULE" version="4"> | |
| 3 | - <component name="FacetManager"> | |
| 4 | - <facet type="RailsFacetType" name="Ruby on Rails"> | |
| 5 | - <configuration> | |
| 6 | - <RAILS_FACET_CONFIG_ID NAME="RAILS_FACET_SUPPORT_REMOVED" VALUE="false" /> | |
| 7 | - <RAILS_FACET_CONFIG_ID NAME="RAILS_TESTS_SOURCES_PATCHED" VALUE="true" /> | |
| 8 | - <RAILS_FACET_CONFIG_ID NAME="RAILS_FACET_APPLICATION_ROOT" VALUE="$MODULE_DIR$" /> | |
| 9 | - </configuration> | |
| 10 | - </facet> | |
| 11 | - <facet type="gem" name="Ruby Gem"> | |
| 12 | - <configuration /> | |
| 13 | - </facet> | |
| 14 | - </component> | |
| 15 | - <component name="ModuleRunConfigurationManager"> | |
| 16 | - <shared> | |
| 17 | - <configuration default="false" name="test: kanjai" type="RakeRunConfigurationType" factoryName="Rake"> | |
| 18 | - <module name="kanjai" /> | |
| 19 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="" /> | |
| 20 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="WORK DIR" VALUE="$MODULE_DIR$" /> | |
| 21 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="SHOULD_USE_SDK" VALUE="false" /> | |
| 22 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="ALTERN_SDK_NAME" VALUE="" /> | |
| 23 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="myPassParentEnvs" VALUE="true" /> | |
| 24 | - <envs> | |
| 25 | - <env name="RAILS_ENV" value="test" /> | |
| 26 | - </envs> | |
| 27 | - <EXTENSION ID="BundlerRunConfigurationExtension" bundleExecEnabled="false" /> | |
| 28 | - <EXTENSION ID="JRubyRunConfigurationExtension" NailgunExecEnabled="false" /> | |
| 29 | - <EXTENSION ID="RubyCoverageRunConfigurationExtension" track_test_folders="true" runner="rcov"> | |
| 30 | - <COVERAGE_PATTERN ENABLED="true"> | |
| 31 | - <PATTERN REGEXPS="/.rvm/" INCLUDED="false" /> | |
| 32 | - </COVERAGE_PATTERN> | |
| 33 | - </EXTENSION> | |
| 34 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_NAME" VALUE="test" /> | |
| 35 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_ARGS" VALUE="" /> | |
| 36 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_ATTACHED_TEST_FRAMEWORKS" VALUE=":test_unit " /> | |
| 37 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_TRACE" VALUE="false" /> | |
| 38 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_DRYRUN" VALUE="false" /> | |
| 39 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_PREREQS" VALUE="false" /> | |
| 40 | - <method v="2" /> | |
| 41 | - </configuration> | |
| 42 | - <configuration default="false" name="spec: kanjai" type="RakeRunConfigurationType" factoryName="Rake"> | |
| 43 | - <module name="kanjai" /> | |
| 44 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="" /> | |
| 45 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="WORK DIR" VALUE="$MODULE_DIR$" /> | |
| 46 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="SHOULD_USE_SDK" VALUE="false" /> | |
| 47 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="ALTERN_SDK_NAME" VALUE="" /> | |
| 48 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="myPassParentEnvs" VALUE="true" /> | |
| 49 | - <EXTENSION ID="BundlerRunConfigurationExtension" bundleExecEnabled="false" /> | |
| 50 | - <EXTENSION ID="JRubyRunConfigurationExtension" NailgunExecEnabled="false" /> | |
| 51 | - <EXTENSION ID="RubyCoverageRunConfigurationExtension" track_test_folders="true" runner="rcov"> | |
| 52 | - <COVERAGE_PATTERN ENABLED="true"> | |
| 53 | - <PATTERN REGEXPS="/.rvm/" INCLUDED="false" /> | |
| 54 | - </COVERAGE_PATTERN> | |
| 55 | - </EXTENSION> | |
| 56 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_NAME" VALUE="spec" /> | |
| 57 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_ARGS" VALUE="" /> | |
| 58 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_ATTACHED_TEST_FRAMEWORKS" VALUE=":rspec " /> | |
| 59 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_TRACE" VALUE="false" /> | |
| 60 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_DRYRUN" VALUE="false" /> | |
| 61 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_PREREQS" VALUE="false" /> | |
| 62 | - <method v="2" /> | |
| 63 | - </configuration> | |
| 64 | - <configuration default="false" name="Production: kanjai" type="RailsRunConfigurationType" factoryName="Rails"> | |
| 65 | - <predefined_log_file id="RUBY_RAILS_SERVER" enabled="true" /> | |
| 66 | - <module name="kanjai" /> | |
| 67 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="" /> | |
| 68 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="WORK DIR" VALUE="$MODULE_DIR$" /> | |
| 69 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="SHOULD_USE_SDK" VALUE="false" /> | |
| 70 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="ALTERN_SDK_NAME" VALUE="" /> | |
| 71 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="myPassParentEnvs" VALUE="true" /> | |
| 72 | - <EXTENSION ID="BundlerRunConfigurationExtension" bundleExecEnabled="false" /> | |
| 73 | - <EXTENSION ID="JRubyRunConfigurationExtension" NailgunExecEnabled="false" /> | |
| 74 | - <EXTENSION ID="RubyCoverageRunConfigurationExtension" track_test_folders="true" runner="rcov"> | |
| 75 | - <COVERAGE_PATTERN ENABLED="true"> | |
| 76 | - <PATTERN REGEXPS="/.rvm/" INCLUDED="false" /> | |
| 77 | - </COVERAGE_PATTERN> | |
| 78 | - </EXTENSION> | |
| 79 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="SCRIPT_ARGS" VALUE="" /> | |
| 80 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="PORT" VALUE="3000" /> | |
| 81 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="IP" VALUE="0.0.0.0" /> | |
| 82 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="DUMMY_APP" VALUE="test/dummy" /> | |
| 83 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="RAILS_SERVER_TYPE" VALUE="Default" /> | |
| 84 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="ENVIRONMENT_TYPE" VALUE="production" /> | |
| 85 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="LAUNCH_JS" VALUE="false" /> | |
| 86 | - <method v="2" /> | |
| 87 | - </configuration> | |
| 88 | - <configuration default="false" name="Development: kanjai" type="RailsRunConfigurationType" factoryName="Rails"> | |
| 89 | - <predefined_log_file id="RUBY_RAILS_SERVER" enabled="true" /> | |
| 90 | - <module name="kanjai" /> | |
| 91 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="" /> | |
| 92 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="WORK DIR" VALUE="$MODULE_DIR$" /> | |
| 93 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="SHOULD_USE_SDK" VALUE="false" /> | |
| 94 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="ALTERN_SDK_NAME" VALUE="" /> | |
| 95 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="myPassParentEnvs" VALUE="true" /> | |
| 96 | - <EXTENSION ID="BundlerRunConfigurationExtension" bundleExecEnabled="false" /> | |
| 97 | - <EXTENSION ID="JRubyRunConfigurationExtension" NailgunExecEnabled="false" /> | |
| 98 | - <EXTENSION ID="RubyCoverageRunConfigurationExtension" track_test_folders="true" runner="rcov"> | |
| 99 | - <COVERAGE_PATTERN ENABLED="true"> | |
| 100 | - <PATTERN REGEXPS="/.rvm/" INCLUDED="false" /> | |
| 101 | - </COVERAGE_PATTERN> | |
| 102 | - </EXTENSION> | |
| 103 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="SCRIPT_ARGS" VALUE="" /> | |
| 104 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="PORT" VALUE="3000" /> | |
| 105 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="IP" VALUE="0.0.0.0" /> | |
| 106 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="DUMMY_APP" VALUE="test/dummy" /> | |
| 107 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="RAILS_SERVER_TYPE" VALUE="Default" /> | |
| 108 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="ENVIRONMENT_TYPE" VALUE="development" /> | |
| 109 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="LAUNCH_JS" VALUE="false" /> | |
| 110 | - <method v="2" /> | |
| 111 | - </configuration> | |
| 112 | - </shared> | |
| 113 | - </component> | |
| 114 | - <component name="NewModuleRootManager"> | |
| 115 | - <content url="file://$MODULE_DIR$"> | |
| 116 | - <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" /> | |
| 117 | - </content> | |
| 118 | - <orderEntry type="jdk" jdkName="rbenv: 2.1.3" jdkType="RUBY_SDK" /> | |
| 119 | - <orderEntry type="sourceFolder" forTests="false" /> | |
| 120 | - <orderEntry type="library" scope="PROVIDED" name="actionmailer (v4.2.6, rbenv: 2.1.3) [gem]" level="application" /> | |
| 121 | - <orderEntry type="library" scope="PROVIDED" name="actionpack (v4.2.6, rbenv: 2.1.3) [gem]" level="application" /> | |
| 122 | - <orderEntry type="library" scope="PROVIDED" name="actionview (v4.2.6, rbenv: 2.1.3) [gem]" level="application" /> | |
| 123 | - <orderEntry type="library" scope="PROVIDED" name="activejob (v4.2.6, rbenv: 2.1.3) [gem]" level="application" /> | |
| 124 | - <orderEntry type="library" scope="PROVIDED" name="activemodel (v4.2.6, rbenv: 2.1.3) [gem]" level="application" /> | |
| 125 | - <orderEntry type="library" scope="PROVIDED" name="activerecord (v4.2.6, rbenv: 2.1.3) [gem]" level="application" /> | |
| 126 | - <orderEntry type="library" scope="PROVIDED" name="activesupport (v4.2.6, rbenv: 2.1.3) [gem]" level="application" /> | |
| 127 | - <orderEntry type="library" scope="PROVIDED" name="acts_as_list (v0.9.5, rbenv: 2.1.3) [gem]" level="application" /> | |
| 128 | - <orderEntry type="library" scope="PROVIDED" name="acts_as_tree (v2.7.0, rbenv: 2.1.3) [gem]" level="application" /> | |
| 129 | - <orderEntry type="library" scope="PROVIDED" name="arel (v6.0.4, rbenv: 2.1.3) [gem]" level="application" /> | |
| 130 | - <orderEntry type="library" scope="PROVIDED" name="aws-sdk (v2.6.32, rbenv: 2.1.3) [gem]" level="application" /> | |
| 131 | - <orderEntry type="library" scope="PROVIDED" name="aws-sdk-core (v2.6.32, rbenv: 2.1.3) [gem]" level="application" /> | |
| 132 | - <orderEntry type="library" scope="PROVIDED" name="aws-sdk-resources (v2.6.32, rbenv: 2.1.3) [gem]" level="application" /> | |
| 133 | - <orderEntry type="library" scope="PROVIDED" name="aws-sigv4 (v1.0.2, rbenv: 2.1.3) [gem]" level="application" /> | |
| 134 | - <orderEntry type="library" scope="PROVIDED" name="backport_new_renderer (v1.0.0, rbenv: 2.1.3) [gem]" level="application" /> | |
| 135 | - <orderEntry type="library" scope="PROVIDED" name="bcrypt (v3.1.11, rbenv: 2.1.3) [gem]" level="application" /> | |
| 136 | - <orderEntry type="library" scope="PROVIDED" name="builder (v3.2.2, rbenv: 2.1.3) [gem]" level="application" /> | |
| 137 | - <orderEntry type="library" scope="PROVIDED" name="bundler (v1.9.0, rbenv: 2.1.3) [gem]" level="application" /> | |
| 138 | - <orderEntry type="library" scope="PROVIDED" name="concurrent-ruby (v1.0.5, rbenv: 2.1.3) [gem]" level="application" /> | |
| 139 | - <orderEntry type="library" scope="PROVIDED" name="daemons (v1.2.6, rbenv: 2.1.3) [gem]" level="application" /> | |
| 140 | - <orderEntry type="library" scope="PROVIDED" name="delayed_job (v4.1.4, rbenv: 2.1.3) [gem]" level="application" /> | |
| 141 | - <orderEntry type="library" scope="PROVIDED" name="delayed_job_active_record (v4.1.2, rbenv: 2.1.3) [gem]" level="application" /> | |
| 142 | - <orderEntry type="library" scope="PROVIDED" name="devise (v4.4.0, rbenv: 2.1.3) [gem]" level="application" /> | |
| 143 | - <orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.2.5, rbenv: 2.1.3) [gem]" level="application" /> | |
| 144 | - <orderEntry type="library" scope="PROVIDED" name="erubis (v2.7.0, rbenv: 2.1.3) [gem]" level="application" /> | |
| 145 | - <orderEntry type="library" scope="PROVIDED" name="execjs (v2.7.0, rbenv: 2.1.3) [gem]" level="application" /> | |
| 146 | - <orderEntry type="library" scope="PROVIDED" name="factory_girl (v4.7.0, rbenv: 2.1.3) [gem]" level="application" /> | |
| 147 | - <orderEntry type="library" scope="PROVIDED" name="factory_girl_rails (v4.8.0, rbenv: 2.1.3) [gem]" level="application" /> | |
| 148 | - <orderEntry type="library" scope="PROVIDED" name="ffi (v1.9.14, rbenv: 2.1.3) [gem]" level="application" /> | |
| 149 | - <orderEntry type="library" scope="PROVIDED" name="globalid (v0.4.1, rbenv: 2.1.3) [gem]" level="application" /> | |
| 150 | - <orderEntry type="library" scope="PROVIDED" name="i18n (v0.7.0, rbenv: 2.1.3) [gem]" level="application" /> | |
| 151 | - <orderEntry type="library" scope="PROVIDED" name="jbuilder (v2.7.0, rbenv: 2.1.3) [gem]" level="application" /> | |
| 152 | - <orderEntry type="library" scope="PROVIDED" name="jmespath (v1.3.1, rbenv: 2.1.3) [gem]" level="application" /> | |
| 153 | - <orderEntry type="library" scope="PROVIDED" name="jquery-rails (v3.1.2, rbenv: 2.1.3) [gem]" level="application" /> | |
| 154 | - <orderEntry type="library" scope="PROVIDED" name="json (v1.8.3, rbenv: 2.1.3) [gem]" level="application" /> | |
| 155 | - <orderEntry type="library" scope="PROVIDED" name="libv8 (v3.16.14.19, rbenv: 2.1.3) [gem]" level="application" /> | |
| 156 | - <orderEntry type="library" scope="PROVIDED" name="loofah (v2.0.3, rbenv: 2.1.3) [gem]" level="application" /> | |
| 157 | - <orderEntry type="library" scope="PROVIDED" name="mail (v2.7.0, rbenv: 2.1.3) [gem]" level="application" /> | |
| 158 | - <orderEntry type="library" scope="PROVIDED" name="mini_mime (v1.0.0, rbenv: 2.1.3) [gem]" level="application" /> | |
| 159 | - <orderEntry type="library" scope="PROVIDED" name="mini_portile (v0.5.3, rbenv: 2.1.3) [gem]" level="application" /> | |
| 160 | - <orderEntry type="library" scope="PROVIDED" name="minitest (v5.8.4, rbenv: 2.1.3) [gem]" level="application" /> | |
| 161 | - <orderEntry type="library" scope="PROVIDED" name="multi_json (v1.13.1, rbenv: 2.1.3) [gem]" level="application" /> | |
| 162 | - <orderEntry type="library" scope="PROVIDED" name="nokogiri (v1.6.1, rbenv: 2.1.3) [gem]" level="application" /> | |
| 163 | - <orderEntry type="library" scope="PROVIDED" name="orm_adapter (v0.5.0, rbenv: 2.1.3) [gem]" level="application" /> | |
| 164 | - <orderEntry type="library" scope="PROVIDED" name="pg (v0.17.1, rbenv: 2.1.3) [gem]" level="application" /> | |
| 165 | - <orderEntry type="library" scope="PROVIDED" name="rack (v1.6.4, rbenv: 2.1.3) [gem]" level="application" /> | |
| 166 | - <orderEntry type="library" scope="PROVIDED" name="rack-test (v0.6.3, rbenv: 2.1.3) [gem]" level="application" /> | |
| 167 | - <orderEntry type="library" scope="PROVIDED" name="rails (v4.2.7.1, rbenv: 2.1.3) [gem]" level="application" /> | |
| 168 | - <orderEntry type="library" scope="PROVIDED" name="rails-deprecated_sanitizer (v1.0.3, rbenv: 2.1.3) [gem]" level="application" /> | |
| 169 | - <orderEntry type="library" scope="PROVIDED" name="rails-dom-testing (v1.0.7, rbenv: 2.1.3) [gem]" level="application" /> | |
| 170 | - <orderEntry type="library" scope="PROVIDED" name="rails-html-sanitizer (v1.0.3, rbenv: 2.1.3) [gem]" level="application" /> | |
| 171 | - <orderEntry type="library" scope="PROVIDED" name="rails_12factor (v0.0.3, rbenv: 2.1.3) [gem]" level="application" /> | |
| 172 | - <orderEntry type="library" scope="PROVIDED" name="rails_serve_static_assets (v0.0.5, rbenv: 2.1.3) [gem]" level="application" /> | |
| 173 | - <orderEntry type="library" scope="PROVIDED" name="rails_stdout_logging (v0.0.5, rbenv: 2.1.3) [gem]" level="application" /> | |
| 174 | - <orderEntry type="library" scope="PROVIDED" name="railties (v4.2.6, rbenv: 2.1.3) [gem]" level="application" /> | |
| 175 | - <orderEntry type="library" scope="PROVIDED" name="rake (v11.1.2, rbenv: 2.1.3) [gem]" level="application" /> | |
| 176 | - <orderEntry type="library" scope="PROVIDED" name="rb-fsevent (v0.10.2, rbenv: 2.1.3) [gem]" level="application" /> | |
| 177 | - <orderEntry type="library" scope="PROVIDED" name="rb-inotify (v0.9.10, rbenv: 2.1.3) [gem]" level="application" /> | |
| 178 | - <orderEntry type="library" scope="PROVIDED" name="rdoc (v4.3.0, rbenv: 2.1.3) [gem]" level="application" /> | |
| 179 | - <orderEntry type="library" scope="PROVIDED" name="ref (v2.0.0, rbenv: 2.1.3) [gem]" level="application" /> | |
| 180 | - <orderEntry type="library" scope="PROVIDED" name="responders (v2.4.0, rbenv: 2.1.3) [gem]" level="application" /> | |
| 181 | - <orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.4.4, rbenv: 2.1.3) [gem]" level="application" /> | |
| 182 | - <orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.4.0, rbenv: 2.1.3) [gem]" level="application" /> | |
| 183 | - <orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.4.1, rbenv: 2.1.3) [gem]" level="application" /> | |
| 184 | - <orderEntry type="library" scope="PROVIDED" name="rspec-rails (v3.4.2, rbenv: 2.1.3) [gem]" level="application" /> | |
| 185 | - <orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.4.1, rbenv: 2.1.3) [gem]" level="application" /> | |
| 186 | - <orderEntry type="library" scope="PROVIDED" name="sass (v3.5.5, rbenv: 2.1.3) [gem]" level="application" /> | |
| 187 | - <orderEntry type="library" scope="PROVIDED" name="sass-listen (v4.0.0, rbenv: 2.1.3) [gem]" level="application" /> | |
| 188 | - <orderEntry type="library" scope="PROVIDED" name="sass-rails (v5.0.7, rbenv: 2.1.3) [gem]" level="application" /> | |
| 189 | - <orderEntry type="library" scope="PROVIDED" name="sdoc (v0.4.2, rbenv: 2.1.3) [gem]" level="application" /> | |
| 190 | - <orderEntry type="library" scope="PROVIDED" name="sprockets (v3.7.1, rbenv: 2.1.3) [gem]" level="application" /> | |
| 191 | - <orderEntry type="library" scope="PROVIDED" name="sprockets-rails (v3.2.1, rbenv: 2.1.3) [gem]" level="application" /> | |
| 192 | - <orderEntry type="library" scope="PROVIDED" name="therubyracer (v0.12.2, rbenv: 2.1.3) [gem]" level="application" /> | |
| 193 | - <orderEntry type="library" scope="PROVIDED" name="thor (v0.19.1, rbenv: 2.1.3) [gem]" level="application" /> | |
| 194 | - <orderEntry type="library" scope="PROVIDED" name="thread_safe (v0.3.5, rbenv: 2.1.3) [gem]" level="application" /> | |
| 195 | - <orderEntry type="library" scope="PROVIDED" name="tilt (v2.0.8, rbenv: 2.1.3) [gem]" level="application" /> | |
| 196 | - <orderEntry type="library" scope="PROVIDED" name="tzinfo (v1.2.2, rbenv: 2.1.3) [gem]" level="application" /> | |
| 197 | - <orderEntry type="library" scope="PROVIDED" name="uglifier (v4.1.3, rbenv: 2.1.3) [gem]" level="application" /> | |
| 198 | - <orderEntry type="library" scope="PROVIDED" name="warden (v1.2.7, rbenv: 2.1.3) [gem]" level="application" /> | |
| 199 | - </component> | |
| 200 | - <component name="RModuleSettingsStorage"> | |
| 201 | - <LOAD_PATH number="0" /> | |
| 202 | - <I18N_FOLDERS number="1" string0="$MODULE_DIR$/config/locales" /> | |
| 203 | - </component> | |
| 204 | -</module> | |
| \ No newline at end of file |
.idea/misc.xml
deleted
100644 → 0
.idea/modules.xml
deleted
100644 → 0
| 1 | -<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | -<project version="4"> | |
| 3 | - <component name="ProjectModuleManager"> | |
| 4 | - <modules> | |
| 5 | - <module fileurl="file://$PROJECT_DIR$/.idea/kanjai.iml" filepath="$PROJECT_DIR$/.idea/kanjai.iml" /> | |
| 6 | - </modules> | |
| 7 | - </component> | |
| 8 | -</project> | |
| \ No newline at end of file |
.idea/runConfigurations/Development__kanjai.xml
deleted
100644 → 0
| 1 | -<component name="ProjectRunConfigurationManager"> | |
| 2 | - <configuration default="false" name="Development: kanjai" type="RailsRunConfigurationType" factoryName="Rails"> | |
| 3 | - <predefined_log_file id="RUBY_RAILS_SERVER" enabled="true" /> | |
| 4 | - <module name="kanjai" /> | |
| 5 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="-e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift)" /> | |
| 6 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="WORK DIR" VALUE="$MODULE_DIR$" /> | |
| 7 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="SHOULD_USE_SDK" VALUE="false" /> | |
| 8 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="ALTERN_SDK_NAME" VALUE="" /> | |
| 9 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="myPassParentEnvs" VALUE="true" /> | |
| 10 | - <envs /> | |
| 11 | - <EXTENSION ID="BundlerRunConfigurationExtension" bundleExecEnabled="false" /> | |
| 12 | - <EXTENSION ID="JRubyRunConfigurationExtension" NailgunExecEnabled="false" /> | |
| 13 | - <EXTENSION ID="RubyCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" track_test_folders="true" runner="rcov"> | |
| 14 | - <COVERAGE_PATTERN ENABLED="true"> | |
| 15 | - <PATTERN REGEXPS="/.rvm/" INCLUDED="false" /> | |
| 16 | - </COVERAGE_PATTERN> | |
| 17 | - </EXTENSION> | |
| 18 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="SCRIPT_ARGS" VALUE="" /> | |
| 19 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="PORT" VALUE="3000" /> | |
| 20 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="IP" VALUE="0.0.0.0" /> | |
| 21 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="DUMMY_APP" VALUE="test/dummy" /> | |
| 22 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="RAILS_SERVER_TYPE" VALUE="Default" /> | |
| 23 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="ENVIRONMENT_TYPE" VALUE="development" /> | |
| 24 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="LAUNCH_JS" VALUE="false" /> | |
| 25 | - <method /> | |
| 26 | - </configuration> | |
| 27 | -</component> | |
| \ No newline at end of file |
.idea/runConfigurations/Production__kanjai.xml
deleted
100644 → 0
| 1 | -<component name="ProjectRunConfigurationManager"> | |
| 2 | - <configuration default="false" name="Production: kanjai" type="RailsRunConfigurationType" factoryName="Rails"> | |
| 3 | - <predefined_log_file id="RUBY_RAILS_SERVER" enabled="true" /> | |
| 4 | - <module name="kanjai" /> | |
| 5 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="-e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift)" /> | |
| 6 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="WORK DIR" VALUE="$MODULE_DIR$" /> | |
| 7 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="SHOULD_USE_SDK" VALUE="false" /> | |
| 8 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="ALTERN_SDK_NAME" VALUE="" /> | |
| 9 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="myPassParentEnvs" VALUE="true" /> | |
| 10 | - <envs /> | |
| 11 | - <EXTENSION ID="BundlerRunConfigurationExtension" bundleExecEnabled="false" /> | |
| 12 | - <EXTENSION ID="JRubyRunConfigurationExtension" NailgunExecEnabled="false" /> | |
| 13 | - <EXTENSION ID="RubyCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" track_test_folders="true" runner="rcov"> | |
| 14 | - <COVERAGE_PATTERN ENABLED="true"> | |
| 15 | - <PATTERN REGEXPS="/.rvm/" INCLUDED="false" /> | |
| 16 | - </COVERAGE_PATTERN> | |
| 17 | - </EXTENSION> | |
| 18 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="SCRIPT_ARGS" VALUE="" /> | |
| 19 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="PORT" VALUE="3000" /> | |
| 20 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="IP" VALUE="0.0.0.0" /> | |
| 21 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="DUMMY_APP" VALUE="test/dummy" /> | |
| 22 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="RAILS_SERVER_TYPE" VALUE="Default" /> | |
| 23 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="ENVIRONMENT_TYPE" VALUE="production" /> | |
| 24 | - <RAILS_SERVER_CONFIG_SETTINGS_ID NAME="LAUNCH_JS" VALUE="false" /> | |
| 25 | - <method /> | |
| 26 | - </configuration> | |
| 27 | -</component> | |
| \ No newline at end of file |
.idea/runConfigurations/spec__kanjai.xml
deleted
100644 → 0
| 1 | -<component name="ProjectRunConfigurationManager"> | |
| 2 | - <configuration default="false" name="spec: kanjai" type="RakeRunConfigurationType" factoryName="Rake"> | |
| 3 | - <module name="kanjai" /> | |
| 4 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="-e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift)" /> | |
| 5 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="WORK DIR" VALUE="$MODULE_DIR$" /> | |
| 6 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="SHOULD_USE_SDK" VALUE="false" /> | |
| 7 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="ALTERN_SDK_NAME" VALUE="" /> | |
| 8 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="myPassParentEnvs" VALUE="true" /> | |
| 9 | - <envs /> | |
| 10 | - <EXTENSION ID="BundlerRunConfigurationExtension" bundleExecEnabled="false" /> | |
| 11 | - <EXTENSION ID="JRubyRunConfigurationExtension" NailgunExecEnabled="false" /> | |
| 12 | - <EXTENSION ID="RubyCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" track_test_folders="true" runner="rcov"> | |
| 13 | - <COVERAGE_PATTERN ENABLED="true"> | |
| 14 | - <PATTERN REGEXPS="/.rvm/" INCLUDED="false" /> | |
| 15 | - </COVERAGE_PATTERN> | |
| 16 | - </EXTENSION> | |
| 17 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_NAME" VALUE="spec" /> | |
| 18 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_ARGS" VALUE="" /> | |
| 19 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_ATTACHED_TEST_FRAMEWORKS" VALUE=":rspec " /> | |
| 20 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_TRACE" VALUE="false" /> | |
| 21 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_DRYRUN" VALUE="false" /> | |
| 22 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_PREREQS" VALUE="false" /> | |
| 23 | - <method /> | |
| 24 | - </configuration> | |
| 25 | -</component> | |
| \ No newline at end of file |
.idea/runConfigurations/test__kanjai.xml
deleted
100644 → 0
| 1 | -<component name="ProjectRunConfigurationManager"> | |
| 2 | - <configuration default="false" name="test: kanjai" type="RakeRunConfigurationType" factoryName="Rake"> | |
| 3 | - <module name="kanjai" /> | |
| 4 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="-e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift)" /> | |
| 5 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="WORK DIR" VALUE="$MODULE_DIR$" /> | |
| 6 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="SHOULD_USE_SDK" VALUE="false" /> | |
| 7 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="ALTERN_SDK_NAME" VALUE="" /> | |
| 8 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="myPassParentEnvs" VALUE="true" /> | |
| 9 | - <envs> | |
| 10 | - <env name="RAILS_ENV" value="test" /> | |
| 11 | - </envs> | |
| 12 | - <EXTENSION ID="BundlerRunConfigurationExtension" bundleExecEnabled="false" /> | |
| 13 | - <EXTENSION ID="JRubyRunConfigurationExtension" NailgunExecEnabled="false" /> | |
| 14 | - <EXTENSION ID="RubyCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" track_test_folders="true" runner="rcov"> | |
| 15 | - <COVERAGE_PATTERN ENABLED="true"> | |
| 16 | - <PATTERN REGEXPS="/.rvm/" INCLUDED="false" /> | |
| 17 | - </COVERAGE_PATTERN> | |
| 18 | - </EXTENSION> | |
| 19 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_NAME" VALUE="test" /> | |
| 20 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_ARGS" VALUE="" /> | |
| 21 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_ATTACHED_TEST_FRAMEWORKS" VALUE=":test_unit " /> | |
| 22 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_TRACE" VALUE="false" /> | |
| 23 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_DRYRUN" VALUE="false" /> | |
| 24 | - <RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_PREREQS" VALUE="false" /> | |
| 25 | - <method /> | |
| 26 | - </configuration> | |
| 27 | -</component> | |
| \ No newline at end of file |
.idea/scopes/scope_settings.xml
deleted
100644 → 0
.idea/vcs.xml
deleted
100644 → 0
.idea/workspace.xml
deleted
100644 → 0
| 1 | -<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | -<project version="4"> | |
| 3 | - <component name="ChangeListManager"> | |
| 4 | - <list default="true" id="cbbcb0f9-d203-4967-aa4d-c08a939c7df0" name="Default" comment=""> | |
| 5 | - <change beforePath="$PROJECT_DIR$/.idea/kanjai.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/kanjai.iml" afterDir="false" /> | |
| 6 | - <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> | |
| 7 | - <change beforePath="$PROJECT_DIR$/Gemfile.lock" beforeDir="false" afterPath="$PROJECT_DIR$/Gemfile.lock" afterDir="false" /> | |
| 8 | - </list> | |
| 9 | - <ignored path="kanjai.iws" /> | |
| 10 | - <ignored path=".idea/workspace.xml" /> | |
| 11 | - <ignored path=".idea/dataSources.local.xml" /> | |
| 12 | - <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" /> | |
| 13 | - <option name="SHOW_DIALOG" value="false" /> | |
| 14 | - <option name="HIGHLIGHT_CONFLICTS" value="true" /> | |
| 15 | - <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> | |
| 16 | - <option name="LAST_RESOLUTION" value="IGNORE" /> | |
| 17 | - </component> | |
| 18 | - <component name="CreatePatchCommitExecutor"> | |
| 19 | - <option name="PATCH_PATH" value="" /> | |
| 20 | - </component> | |
| 21 | - <component name="FUSProjectUsageTrigger"> | |
| 22 | - <session id="1963050572"> | |
| 23 | - <usages-collector id="statistics.lifecycle.project"> | |
| 24 | - <counts> | |
| 25 | - <entry key="project.closed" value="1" /> | |
| 26 | - <entry key="project.open.time.8" value="1" /> | |
| 27 | - <entry key="project.open.time.9" value="1" /> | |
| 28 | - <entry key="project.opened" value="2" /> | |
| 29 | - </counts> | |
| 30 | - </usages-collector> | |
| 31 | - </session> | |
| 32 | - </component> | |
| 33 | - <component name="FavoritesManager"> | |
| 34 | - <favorites_list name="kanjai" /> | |
| 35 | - </component> | |
| 36 | - <component name="FileEditorManager"> | |
| 37 | - <leaf SIDE_TABS_SIZE_LIMIT_KEY="300"> | |
| 38 | - <file pinned="false" current-in-tab="false"> | |
| 39 | - <entry file="file://$PROJECT_DIR$/config/initializers/aws.rb"> | |
| 40 | - <provider selected="true" editor-type-id="text-editor"> | |
| 41 | - <state relative-caret-position="75"> | |
| 42 | - <caret line="5" column="57" selection-start-line="5" selection-start-column="41" selection-end-line="5" selection-end-column="57" /> | |
| 43 | - </state> | |
| 44 | - </provider> | |
| 45 | - </entry> | |
| 46 | - </file> | |
| 47 | - <file pinned="false" current-in-tab="false"> | |
| 48 | - <entry file="file://$PROJECT_DIR$/lib/kanjai/template_generator.rb"> | |
| 49 | - <provider selected="true" editor-type-id="text-editor"> | |
| 50 | - <state relative-caret-position="3390"> | |
| 51 | - <caret line="226" column="42" selection-start-line="226" selection-start-column="23" selection-end-line="226" selection-end-column="42" /> | |
| 52 | - </state> | |
| 53 | - </provider> | |
| 54 | - </entry> | |
| 55 | - </file> | |
| 56 | - <file pinned="false" current-in-tab="false"> | |
| 57 | - <entry file="file://$PROJECT_DIR$/app/controllers/kanjai/pages_controller.rb"> | |
| 58 | - <provider selected="true" editor-type-id="text-editor"> | |
| 59 | - <state relative-caret-position="465"> | |
| 60 | - <caret line="31" selection-start-line="31" selection-end-line="31" /> | |
| 61 | - </state> | |
| 62 | - </provider> | |
| 63 | - </entry> | |
| 64 | - </file> | |
| 65 | - <file pinned="false" current-in-tab="true"> | |
| 66 | - <entry file="file://$PROJECT_DIR$/lib/kanjai/version.rb"> | |
| 67 | - <provider selected="true" editor-type-id="text-editor"> | |
| 68 | - <state relative-caret-position="45"> | |
| 69 | - <caret line="3" selection-start-line="3" selection-end-line="3" /> | |
| 70 | - </state> | |
| 71 | - </provider> | |
| 72 | - </entry> | |
| 73 | - </file> | |
| 74 | - <file pinned="false" current-in-tab="false"> | |
| 75 | - <entry file="file://$PROJECT_DIR$/Gemfile.lock"> | |
| 76 | - <provider selected="true" editor-type-id="text-editor"> | |
| 77 | - <state relative-caret-position="795"> | |
| 78 | - <caret line="53" column="13" selection-start-line="53" selection-start-column="13" selection-end-line="53" selection-end-column="13" /> | |
| 79 | - </state> | |
| 80 | - </provider> | |
| 81 | - </entry> | |
| 82 | - </file> | |
| 83 | - <file pinned="false" current-in-tab="false"> | |
| 84 | - <entry file="file://$PROJECT_DIR$/config/initializers/devise.rb"> | |
| 85 | - <provider selected="true" editor-type-id="text-editor"> | |
| 86 | - <state relative-caret-position="90"> | |
| 87 | - <caret line="6" column="46" selection-start-line="6" selection-start-column="22" selection-end-line="6" selection-end-column="46" /> | |
| 88 | - </state> | |
| 89 | - </provider> | |
| 90 | - </entry> | |
| 91 | - </file> | |
| 92 | - <file pinned="false" current-in-tab="false"> | |
| 93 | - <entry file="file://$PROJECT_DIR$/config/initializers/admin.rb"> | |
| 94 | - <provider selected="true" editor-type-id="text-editor"> | |
| 95 | - <state relative-caret-position="45"> | |
| 96 | - <caret line="3" column="46" selection-start-line="3" selection-start-column="46" selection-end-line="3" selection-end-column="46" /> | |
| 97 | - </state> | |
| 98 | - </provider> | |
| 99 | - </entry> | |
| 100 | - </file> | |
| 101 | - <file pinned="false" current-in-tab="false"> | |
| 102 | - <entry file="file://$PROJECT_DIR$/lib/kanjai.rb"> | |
| 103 | - <provider selected="true" editor-type-id="text-editor" /> | |
| 104 | - </entry> | |
| 105 | - </file> | |
| 106 | - <file pinned="false" current-in-tab="false"> | |
| 107 | - <entry file="file://$PROJECT_DIR$/lib/kanjai/engine.rb"> | |
| 108 | - <provider selected="true" editor-type-id="text-editor" /> | |
| 109 | - </entry> | |
| 110 | - </file> | |
| 111 | - <file pinned="false" current-in-tab="false"> | |
| 112 | - <entry file="file://$PROJECT_DIR$/db/migrate/20160707115443_add_show_public_only_to_kanjai_pages.rb"> | |
| 113 | - <provider selected="true" editor-type-id="text-editor"> | |
| 114 | - <state relative-caret-position="30"> | |
| 115 | - <caret line="2" column="73" selection-start-line="2" selection-start-column="4" selection-end-line="2" selection-end-column="73" /> | |
| 116 | - </state> | |
| 117 | - </provider> | |
| 118 | - </entry> | |
| 119 | - </file> | |
| 120 | - </leaf> | |
| 121 | - </component> | |
| 122 | - <component name="FindInProjectRecents"> | |
| 123 | - <findStrings> | |
| 124 | - <find>check_p</find> | |
| 125 | - <find>check_permission</find> | |
| 126 | - <find>admin_email</find> | |
| 127 | - <find>INCLUDE_JS_FILE</find> | |
| 128 | - <find>files = $.makeArray(fileInput.prop('files'));</find> | |
| 129 | - <find>If the files property is not available, the browser does</find> | |
| 130 | - <find>If the files property is not available, the browser does not</find> | |
| 131 | - <find>if (cookieValue.length > 0) break</find> | |
| 132 | - <find>Extracts flash array stored in cookie and clears</find> | |
| 133 | - <find>UnobtrusiveFlash</find> | |
| 134 | - <find>pa</find> | |
| 135 | - <find>paper</find> | |
| 136 | - <find>S3_BUCKET</find> | |
| 137 | - <find>fil</find> | |
| 138 | - <find>fileuploa</find> | |
| 139 | - <find>fileupload</find> | |
| 140 | - <find>help-block</find> | |
| 141 | - <find>unzip_c</find> | |
| 142 | - <find>page_template</find> | |
| 143 | - <find>setTemplateContent</find> | |
| 144 | - <find>form</find> | |
| 145 | - <find>###FORM_ACTION###</find> | |
| 146 | - <find>form_subject</find> | |
| 147 | - <find>def get_marker_type</find> | |
| 148 | - <find>sqlite3</find> | |
| 149 | - <find>sqli</find> | |
| 150 | - <find>show_public_only</find> | |
| 151 | - <find>UserSession</find> | |
| 152 | - <find>User</find> | |
| 153 | - <find>KANJAI_DOMAIN</find> | |
| 154 | - </findStrings> | |
| 155 | - <dirStrings> | |
| 156 | - <dir>$PROJECT_DIR$/app/controllers</dir> | |
| 157 | - <dir>$PROJECT_DIR$/app/assets/javascripts</dir> | |
| 158 | - <dir>$PROJECT_DIR$</dir> | |
| 159 | - <dir>$PROJECT_DIR$/app</dir> | |
| 160 | - </dirStrings> | |
| 161 | - </component> | |
| 162 | - <component name="Git.Settings"> | |
| 163 | - <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" /> | |
| 164 | - </component> | |
| 165 | - <component name="IdeDocumentHistory"> | |
| 166 | - <option name="CHANGED_PATHS"> | |
| 167 | - <list> | |
| 168 | - <option value="$PROJECT_DIR$/app/assets/stylesheets/kanjai/fileinput.css" /> | |
| 169 | - <option value="$PROJECT_DIR$/app/assets/stylesheets/kanjai/frontend.css.scss" /> | |
| 170 | - <option value="$PROJECT_DIR$/app/assets/javascripts/kanjai/frontend.js" /> | |
| 171 | - <option value="$PROJECT_DIR$/app/assets/javascripts/kanjai/admin/html_generator.js" /> | |
| 172 | - <option value="$PROJECT_DIR$/app/assets/javascripts/kanjai/frontend/html_editor.js" /> | |
| 173 | - <option value="$PROJECT_DIR$/db/migrate/20160804133136_add_image_link_to_kanjai_images.rb" /> | |
| 174 | - <option value="$PROJECT_DIR$/app/views/kanjai/admin/pages/get_gallery.html.erb" /> | |
| 175 | - <option value="$PROJECT_DIR$/app/assets/stylesheets/kanjai/admin/admin.css.scss" /> | |
| 176 | - <option value="$PROJECT_DIR$/app/models/kanjai/image.rb" /> | |
| 177 | - <option value="$PROJECT_DIR$/app/models/kanjai/page.rb" /> | |
| 178 | - <option value="$PROJECT_DIR$/app/views/kanjai/admin/pages/_gallery_exist_images.html.erb" /> | |
| 179 | - <option value="$PROJECT_DIR$/app/views/kanjai/admin/pages/gallery.html.erb" /> | |
| 180 | - <option value="$PROJECT_DIR$/app/views/kanjai/admin/pages/update_gallery.js.erb" /> | |
| 181 | - <option value="$PROJECT_DIR$/app/views/kanjai/admin/pages/_preview.html.erb" /> | |
| 182 | - <option value="$PROJECT_DIR$/app/views/kanjai/admin/pages/delete_gallery_image.js.erb" /> | |
| 183 | - <option value="$PROJECT_DIR$/app/assets/stylesheets/kanjai/general_admin.css.scss" /> | |
| 184 | - <option value="$PROJECT_DIR$/app/helpers/kanjai/admin/pages_helper.rb" /> | |
| 185 | - <option value="$PROJECT_DIR$/lib/kanjai/content_function.rb" /> | |
| 186 | - <option value="$PROJECT_DIR$/app/views/kanjai/pages/show.pdf.erb" /> | |
| 187 | - <option value="$PROJECT_DIR$/app/assets/javascripts/kanjai/admin/admin.js" /> | |
| 188 | - <option value="$PROJECT_DIR$/lib/zip.rb" /> | |
| 189 | - <option value="$PROJECT_DIR$/app/views/layouts/kanjai/admin.html.erb" /> | |
| 190 | - <option value="$PROJECT_DIR$/app/views/kanjai/admin/admin_users/index.html.erb" /> | |
| 191 | - <option value="$PROJECT_DIR$/app/views/kanjai/admin/admin_users/new.html.erb" /> | |
| 192 | - <option value="$PROJECT_DIR$/app/views/kanjai/admin/admin_users/_form.html.erb" /> | |
| 193 | - <option value="$PROJECT_DIR$/app/controllers/kanjai/admin/admin_users_controller.rb" /> | |
| 194 | - <option value="$PROJECT_DIR$/config/locales/en.yml" /> | |
| 195 | - <option value="$PROJECT_DIR$/app/views/kanjai/admin/admin_users/edit.html.erb" /> | |
| 196 | - <option value="$PROJECT_DIR$/app/controllers/kanjai/admin_controller.rb" /> | |
| 197 | - <option value="$PROJECT_DIR$/app/views/kanjai/admin/pages/show_editor.html.erb" /> | |
| 198 | - <option value="$PROJECT_DIR$/db/migrate/20171214071607_add_form_data_to_page_content_marker.rb" /> | |
| 199 | - <option value="$PROJECT_DIR$/app/models/kanjai/page_content.rb" /> | |
| 200 | - <option value="$PROJECT_DIR$/config/routes.rb" /> | |
| 201 | - <option value="$PROJECT_DIR$/app/mailers/application_mailer.rb" /> | |
| 202 | - <option value="$PROJECT_DIR$/db/migrate/20171214092747_add_from_to_mai_to_page_content_marker.rb" /> | |
| 203 | - <option value="$PROJECT_DIR$/app/mailers/kanjai_mailer.rb" /> | |
| 204 | - <option value="$PROJECT_DIR$/app/views/kanjai_mailer/send_mail.html.erb" /> | |
| 205 | - <option value="$PROJECT_DIR$/db/migrate/20171214094525_add_answer_text_to_page_content_marker.rb" /> | |
| 206 | - <option value="$PROJECT_DIR$/app/controllers/kanjai/admin/pages_controller.rb" /> | |
| 207 | - <option value="$PROJECT_DIR$/app/controllers/kanjai/form_controller.rb" /> | |
| 208 | - <option value="$PROJECT_DIR$/kanjai.gemspec" /> | |
| 209 | - <option value="$PROJECT_DIR$/app/controllers/kanjai/site_controller.rb" /> | |
| 210 | - <option value="$PROJECT_DIR$/app/assets/javascripts/kanjai/admin/jquery.fileupload.js" /> | |
| 211 | - <option value="$PROJECT_DIR$/app/models/kanjai/page_template.rb" /> | |
| 212 | - <option value="$PROJECT_DIR$/app/views/kanjai/pages/show.html.erb" /> | |
| 213 | - <option value="$PROJECT_DIR$/lib/kanjai/template_generator.rb" /> | |
| 214 | - <option value="$PROJECT_DIR$/app/views/kanjai/admin/pages/content_types/_content.html.erb" /> | |
| 215 | - <option value="$PROJECT_DIR$/config/initializers/devise.rb" /> | |
| 216 | - <option value="$PROJECT_DIR$/app/controllers/kanjai/pages_controller.rb" /> | |
| 217 | - <option value="$PROJECT_DIR$/config/initializers/admin.rb" /> | |
| 218 | - <option value="$PROJECT_DIR$/lib/kanjai/version.rb" /> | |
| 219 | - </list> | |
| 220 | - </option> | |
| 221 | - </component> | |
| 222 | - <component name="JsBuildToolGruntFileManager" detection-done="true" sorting="DEFINITION_ORDER" /> | |
| 223 | - <component name="JsBuildToolPackageJson" detection-done="true" sorting="DEFINITION_ORDER" /> | |
| 224 | - <component name="JsGulpfileManager"> | |
| 225 | - <detection-done>true</detection-done> | |
| 226 | - <sorting>DEFINITION_ORDER</sorting> | |
| 227 | - </component> | |
| 228 | - <component name="ProjectFrameBounds" extendedState="6"> | |
| 229 | - <option name="y" value="23" /> | |
| 230 | - <option name="width" value="1280" /> | |
| 231 | - <option name="height" value="728" /> | |
| 232 | - </component> | |
| 233 | - <component name="ProjectLevelVcsManager" settingsEditedManually="true" /> | |
| 234 | - <component name="ProjectView"> | |
| 235 | - <navigator proportions="" version="1"> | |
| 236 | - <foldersAlwaysOnTop value="true" /> | |
| 237 | - </navigator> | |
| 238 | - <panes> | |
| 239 | - <pane id="ProjectPane"> | |
| 240 | - <subPane> | |
| 241 | - <expand> | |
| 242 | - <path> | |
| 243 | - <item name="kanjai" type="b2602c69:ProjectViewProjectNode" /> | |
| 244 | - <item name="kanjai" type="462c0819:PsiDirectoryNode" /> | |
| 245 | - </path> | |
| 246 | - <path> | |
| 247 | - <item name="kanjai" type="b2602c69:ProjectViewProjectNode" /> | |
| 248 | - <item name="kanjai" type="462c0819:PsiDirectoryNode" /> | |
| 249 | - <item name="config" type="462c0819:PsiDirectoryNode" /> | |
| 250 | - </path> | |
| 251 | - <path> | |
| 252 | - <item name="kanjai" type="b2602c69:ProjectViewProjectNode" /> | |
| 253 | - <item name="kanjai" type="462c0819:PsiDirectoryNode" /> | |
| 254 | - <item name="config" type="462c0819:PsiDirectoryNode" /> | |
| 255 | - <item name="initializers" type="462c0819:PsiDirectoryNode" /> | |
| 256 | - </path> | |
| 257 | - <path> | |
| 258 | - <item name="kanjai" type="b2602c69:ProjectViewProjectNode" /> | |
| 259 | - <item name="kanjai" type="462c0819:PsiDirectoryNode" /> | |
| 260 | - <item name="lib" type="462c0819:PsiDirectoryNode" /> | |
| 261 | - </path> | |
| 262 | - <path> | |
| 263 | - <item name="kanjai" type="b2602c69:ProjectViewProjectNode" /> | |
| 264 | - <item name="kanjai" type="462c0819:PsiDirectoryNode" /> | |
| 265 | - <item name="lib" type="462c0819:PsiDirectoryNode" /> | |
| 266 | - <item name="kanjai" type="462c0819:PsiDirectoryNode" /> | |
| 267 | - </path> | |
| 268 | - <path> | |
| 269 | - <item name="kanjai" type="b2602c69:ProjectViewProjectNode" /> | |
| 270 | - <item name="kanjai" type="462c0819:PsiDirectoryNode" /> | |
| 271 | - <item name="lib" type="462c0819:PsiDirectoryNode" /> | |
| 272 | - <item name="tasks" type="462c0819:PsiDirectoryNode" /> | |
| 273 | - </path> | |
| 274 | - </expand> | |
| 275 | - <select /> | |
| 276 | - </subPane> | |
| 277 | - </pane> | |
| 278 | - <pane id="Scope" /> | |
| 279 | - <pane id="RailsProjectView" /> | |
| 280 | - </panes> | |
| 281 | - </component> | |
| 282 | - <component name="PropertiesComponent"> | |
| 283 | - <property name="HbShouldOpenHtmlAsHb" value="" /> | |
| 284 | - <property name="WebServerToolWindowFactoryState" value="false" /> | |
| 285 | - <property name="last_opened_file_path" value="$PROJECT_DIR$" /> | |
| 286 | - <property name="recentsLimit" value="5" /> | |
| 287 | - </component> | |
| 288 | - <component name="RecentsManager"> | |
| 289 | - <key name="MoveFile.RECENT_KEYS"> | |
| 290 | - <recent name="$PROJECT_DIR$/app/assets/images/kanjai/fileinput" /> | |
| 291 | - <recent name="$PROJECT_DIR$/app/assets/stylesheets/kanjai" /> | |
| 292 | - <recent name="$PROJECT_DIR$/app/assets/javascripts/kanjai/lib" /> | |
| 293 | - </key> | |
| 294 | - <key name="CopyFile.RECENT_KEYS"> | |
| 295 | - <recent name="$PROJECT_DIR$/app/mailers" /> | |
| 296 | - <recent name="$PROJECT_DIR$/app/views/kanjai/admin/admin_users" /> | |
| 297 | - <recent name="$PROJECT_DIR$/config/initializers" /> | |
| 298 | - <recent name="$PROJECT_DIR$/bin" /> | |
| 299 | - <recent name="$PROJECT_DIR$/app/assets/stylesheets/kanjai/general" /> | |
| 300 | - </key> | |
| 301 | - </component> | |
| 302 | - <component name="RunDashboard"> | |
| 303 | - <option name="ruleStates"> | |
| 304 | - <list> | |
| 305 | - <RuleState> | |
| 306 | - <option name="name" value="ConfigurationTypeDashboardGroupingRule" /> | |
| 307 | - </RuleState> | |
| 308 | - <RuleState> | |
| 309 | - <option name="name" value="StatusDashboardGroupingRule" /> | |
| 310 | - </RuleState> | |
| 311 | - </list> | |
| 312 | - </option> | |
| 313 | - </component> | |
| 314 | - <component name="RunManager" selected="Rails.Development: kanjai"> | |
| 315 | - <configuration default="true" type="js.build_tools.gulp" factoryName="Gulp.js"> | |
| 316 | - <node-interpreter>project</node-interpreter> | |
| 317 | - <node-options /> | |
| 318 | - <gulpfile /> | |
| 319 | - <tasks /> | |
| 320 | - <arguments /> | |
| 321 | - <pass-parent-envs>true</pass-parent-envs> | |
| 322 | - <method v="2" /> | |
| 323 | - </configuration> | |
| 324 | - <list> | |
| 325 | - <item itemvalue="Rake.test: kanjai" /> | |
| 326 | - <item itemvalue="Rake.spec: kanjai" /> | |
| 327 | - <item itemvalue="Rails.Production: kanjai" /> | |
| 328 | - <item itemvalue="Rails.Development: kanjai" /> | |
| 329 | - </list> | |
| 330 | - </component> | |
| 331 | - <component name="SpringUtil" SPRING_PRE_LOADER_OPTION="true" /> | |
| 332 | - <component name="SvnConfiguration"> | |
| 333 | - <configuration /> | |
| 334 | - </component> | |
| 335 | - <component name="TaskManager"> | |
| 336 | - <task active="true" id="Default" summary="Default task"> | |
| 337 | - <changelist id="cbbcb0f9-d203-4967-aa4d-c08a939c7df0" name="Default" comment="" /> | |
| 338 | - <created>1461667396774</created> | |
| 339 | - <option name="number" value="Default" /> | |
| 340 | - <option name="presentableId" value="Default" /> | |
| 341 | - <updated>1461667396774</updated> | |
| 342 | - <workItem from="1494966983627" duration="731000" /> | |
| 343 | - <workItem from="1495090952619" duration="1573000" /> | |
| 344 | - <workItem from="1495108372095" duration="2000" /> | |
| 345 | - <workItem from="1498808617180" duration="1037000" /> | |
| 346 | - <workItem from="1498836423959" duration="4000" /> | |
| 347 | - <workItem from="1500931211896" duration="152000" /> | |
| 348 | - <workItem from="1500931637579" duration="304000" /> | |
| 349 | - <workItem from="1501482504677" duration="10000" /> | |
| 350 | - <workItem from="1513232887722" duration="10776000" /> | |
| 351 | - <workItem from="1513283335284" duration="121000" /> | |
| 352 | - <workItem from="1513543303254" duration="7193000" /> | |
| 353 | - <workItem from="1516654861781" duration="654000" /> | |
| 354 | - <workItem from="1519076359527" duration="5272000" /> | |
| 355 | - <workItem from="1519386347440" duration="1120000" /> | |
| 356 | - <workItem from="1519477125017" duration="2000" /> | |
| 357 | - <workItem from="1521110918867" duration="606000" /> | |
| 358 | - <workItem from="1521116413044" duration="527000" /> | |
| 359 | - <workItem from="1521124710073" duration="38000" /> | |
| 360 | - <workItem from="1522062575414" duration="786000" /> | |
| 361 | - <workItem from="1524563703669" duration="29000" /> | |
| 362 | - <workItem from="1524565240546" duration="602000" /> | |
| 363 | - <workItem from="1526849333726" duration="2848000" /> | |
| 364 | - <workItem from="1526898064400" duration="244000" /> | |
| 365 | - <workItem from="1526992788869" duration="3744000" /> | |
| 366 | - <workItem from="1527228957742" duration="663000" /> | |
| 367 | - <workItem from="1527239274712" duration="965000" /> | |
| 368 | - <workItem from="1527250151106" duration="1359000" /> | |
| 369 | - <workItem from="1528795289630" duration="58000" /> | |
| 370 | - <workItem from="1528797772730" duration="2306000" /> | |
| 371 | - <workItem from="1528983596909" duration="231000" /> | |
| 372 | - <workItem from="1528984727408" duration="942000" /> | |
| 373 | - <workItem from="1529067232509" duration="427000" /> | |
| 374 | - <workItem from="1529134009751" duration="477000" /> | |
| 375 | - <workItem from="1530563947793" duration="325000" /> | |
| 376 | - <workItem from="1532497382207" duration="775000" /> | |
| 377 | - <workItem from="1532528310773" duration="526000" /> | |
| 378 | - <workItem from="1532617523201" duration="881000" /> | |
| 379 | - <workItem from="1533023763618" duration="569000" /> | |
| 380 | - <workItem from="1533043884272" duration="812000" /> | |
| 381 | - <workItem from="1536316862776" duration="652000" /> | |
| 382 | - <workItem from="1536432181981" duration="68000" /> | |
| 383 | - </task> | |
| 384 | - <servers /> | |
| 385 | - </component> | |
| 386 | - <component name="TimeTrackingManager"> | |
| 387 | - <option name="totallyTimeSpent" value="50411000" /> | |
| 388 | - </component> | |
| 389 | - <component name="ToolWindowManager"> | |
| 390 | - <frame x="0" y="23" width="1280" height="728" extended-state="6" /> | |
| 391 | - <layout> | |
| 392 | - <window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.3861066" /> | |
| 393 | - <window_info id="Structure" order="1" side_tool="true" weight="0.25" /> | |
| 394 | - <window_info id="Favorites" order="2" side_tool="true" /> | |
| 395 | - <window_info anchor="bottom" id="Message" order="0" /> | |
| 396 | - <window_info anchor="bottom" id="Find" order="1" weight="0.32930514" /> | |
| 397 | - <window_info anchor="bottom" id="Run" order="2" /> | |
| 398 | - <window_info anchor="bottom" id="Debug" order="3" weight="0.4" /> | |
| 399 | - <window_info anchor="bottom" id="Cvs" order="4" weight="0.25" /> | |
| 400 | - <window_info anchor="bottom" id="Inspection" order="5" weight="0.4" /> | |
| 401 | - <window_info anchor="bottom" id="TODO" order="6" /> | |
| 402 | - <window_info anchor="bottom" id="Changes" order="7" /> | |
| 403 | - <window_info anchor="bottom" id="Terminal" order="8" /> | |
| 404 | - <window_info anchor="bottom" id="Version Control" order="9" /> | |
| 405 | - <window_info anchor="bottom" id="Event Log" order="10" side_tool="true" weight="0.32930514" /> | |
| 406 | - <window_info anchor="bottom" id="Application Servers" order="11" /> | |
| 407 | - <window_info anchor="bottom" id="Messages" order="12" weight="0.32930514" /> | |
| 408 | - <window_info anchor="bottom" id="Docker" order="13" show_stripe_button="false" /> | |
| 409 | - <window_info anchor="bottom" id="Database Changes" order="14" show_stripe_button="false" /> | |
| 410 | - <window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" /> | |
| 411 | - <window_info anchor="right" id="Ant Build" order="1" weight="0.25" /> | |
| 412 | - <window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" /> | |
| 413 | - <window_info anchor="right" id="Database" order="3" /> | |
| 414 | - </layout> | |
| 415 | - </component> | |
| 416 | - <component name="TypeScriptGeneratedFilesManager"> | |
| 417 | - <option name="version" value="1" /> | |
| 418 | - </component> | |
| 419 | - <component name="Vcs.Log.UiProperties"> | |
| 420 | - <option name="RECENTLY_FILTERED_USER_GROUPS"> | |
| 421 | - <collection /> | |
| 422 | - </option> | |
| 423 | - <option name="RECENTLY_FILTERED_BRANCH_GROUPS"> | |
| 424 | - <collection /> | |
| 425 | - </option> | |
| 426 | - </component> | |
| 427 | - <component name="VcsContentAnnotationSettings"> | |
| 428 | - <option name="myLimit" value="2678400000" /> | |
| 429 | - </component> | |
| 430 | - <component name="editorHistoryManager"> | |
| 431 | - <entry file="file://$PROJECT_DIR$/kanjai.gemspec"> | |
| 432 | - <provider selected="true" editor-type-id="text-editor"> | |
| 433 | - <state relative-caret-position="300"> | |
| 434 | - <caret line="20" column="41" selection-start-line="20" selection-start-column="41" selection-end-line="20" selection-end-column="41" /> | |
| 435 | - </state> | |
| 436 | - </provider> | |
| 437 | - </entry> | |
| 438 | - <entry file="file://$PROJECT_DIR$/app/models/kanjai/page_content.rb"> | |
| 439 | - <provider selected="true" editor-type-id="text-editor"> | |
| 440 | - <state relative-caret-position="2115"> | |
| 441 | - <caret line="141" column="119" selection-start-line="141" selection-start-column="119" selection-end-line="141" selection-end-column="119" /> | |
| 442 | - </state> | |
| 443 | - </provider> | |
| 444 | - </entry> | |
| 445 | - <entry file="file://$PROJECT_DIR$/app/views/kanjai/pages/show.html.erb"> | |
| 446 | - <provider selected="true" editor-type-id="text-editor"> | |
| 447 | - <state relative-caret-position="15"> | |
| 448 | - <caret line="1" column="27" selection-start-line="1" selection-start-column="27" selection-end-line="1" selection-end-column="27" /> | |
| 449 | - </state> | |
| 450 | - </provider> | |
| 451 | - </entry> | |
| 452 | - <entry file="file://$PROJECT_DIR$/config/routes.rb"> | |
| 453 | - <provider selected="true" editor-type-id="text-editor"> | |
| 454 | - <state relative-caret-position="855"> | |
| 455 | - <caret line="57" column="32" selection-start-line="57" selection-start-column="17" selection-end-line="57" selection-end-column="32" /> | |
| 456 | - </state> | |
| 457 | - </provider> | |
| 458 | - </entry> | |
| 459 | - <entry file="file://$PROJECT_DIR$/app/views/kanjai_mailer/send_mail.html.erb"> | |
| 460 | - <provider selected="true" editor-type-id="text-editor"> | |
| 461 | - <state relative-caret-position="45"> | |
| 462 | - <caret line="3" column="11" selection-start-line="3" selection-start-column="3" selection-end-line="3" selection-end-column="11" /> | |
| 463 | - </state> | |
| 464 | - </provider> | |
| 465 | - </entry> | |
| 466 | - <entry file="file://$PROJECT_DIR$/app/mailers/kanjai_mailer.rb"> | |
| 467 | - <provider selected="true" editor-type-id="text-editor"> | |
| 468 | - <state relative-caret-position="60"> | |
| 469 | - <caret line="4" column="5" selection-start-line="4" selection-start-column="5" selection-end-line="4" selection-end-column="5" /> | |
| 470 | - </state> | |
| 471 | - </provider> | |
| 472 | - </entry> | |
| 473 | - <entry file="file://$PROJECT_DIR$/app/controllers/kanjai/form_controller.rb"> | |
| 474 | - <provider selected="true" editor-type-id="text-editor"> | |
| 475 | - <state relative-caret-position="75"> | |
| 476 | - <caret line="5" column="44" selection-start-line="5" selection-start-column="32" selection-end-line="5" selection-end-column="44" /> | |
| 477 | - </state> | |
| 478 | - </provider> | |
| 479 | - </entry> | |
| 480 | - <entry file="file://$PROJECT_DIR$/app/models/kanjai/page_content_marker.rb"> | |
| 481 | - <provider selected="true" editor-type-id="text-editor"> | |
| 482 | - <state relative-caret-position="255"> | |
| 483 | - <caret line="17" column="65" selection-start-line="17" selection-start-column="53" selection-end-line="17" selection-end-column="65" /> | |
| 484 | - </state> | |
| 485 | - </provider> | |
| 486 | - </entry> | |
| 487 | - <entry file="file://$PROJECT_DIR$/app/views/kanjai/admin/pages/content_types/_content.html.erb"> | |
| 488 | - <provider selected="true" editor-type-id="text-editor"> | |
| 489 | - <state relative-caret-position="15"> | |
| 490 | - <caret line="1" column="121" selection-start-line="1" selection-start-column="121" selection-end-line="1" selection-end-column="121" /> | |
| 491 | - </state> | |
| 492 | - </provider> | |
| 493 | - </entry> | |
| 494 | - <entry file="file://$PROJECT_DIR$/app/controllers/kanjai/admin/page_templates_controller.rb"> | |
| 495 | - <provider selected="true" editor-type-id="text-editor"> | |
| 496 | - <state relative-caret-position="1500"> | |
| 497 | - <caret line="100" column="21" selection-start-line="100" selection-start-column="6" selection-end-line="100" selection-end-column="21" /> | |
| 498 | - </state> | |
| 499 | - </provider> | |
| 500 | - </entry> | |
| 501 | - <entry file="file://$PROJECT_DIR$/app/models/kanjai/page_template.rb"> | |
| 502 | - <provider selected="true" editor-type-id="text-editor"> | |
| 503 | - <state relative-caret-position="1815"> | |
| 504 | - <caret line="121" column="28" selection-start-line="121" selection-start-column="28" selection-end-line="121" selection-end-column="28" /> | |
| 505 | - </state> | |
| 506 | - </provider> | |
| 507 | - </entry> | |
| 508 | - <entry file="file://$PROJECT_DIR$/app/assets/javascripts/kanjai/admin/admin.js"> | |
| 509 | - <provider selected="true" editor-type-id="text-editor"> | |
| 510 | - <state relative-caret-position="2295"> | |
| 511 | - <caret line="153" column="51" selection-start-line="153" selection-start-column="27" selection-end-line="153" selection-end-column="51" /> | |
| 512 | - </state> | |
| 513 | - </provider> | |
| 514 | - </entry> | |
| 515 | - <entry file="file://$PROJECT_DIR$/.ruby-version"> | |
| 516 | - <provider selected="true" editor-type-id="text-editor"> | |
| 517 | - <state> | |
| 518 | - <caret column="5" selection-end-column="5" /> | |
| 519 | - </state> | |
| 520 | - </provider> | |
| 521 | - </entry> | |
| 522 | - <entry file="file://$PROJECT_DIR$/config/initializers/aws.rb"> | |
| 523 | - <provider selected="true" editor-type-id="text-editor"> | |
| 524 | - <state relative-caret-position="75"> | |
| 525 | - <caret line="5" column="57" selection-start-line="5" selection-start-column="41" selection-end-line="5" selection-end-column="57" /> | |
| 526 | - </state> | |
| 527 | - </provider> | |
| 528 | - </entry> | |
| 529 | - <entry file="file://$PROJECT_DIR$/lib/kanjai/template_generator.rb"> | |
| 530 | - <provider selected="true" editor-type-id="text-editor"> | |
| 531 | - <state relative-caret-position="3390"> | |
| 532 | - <caret line="226" column="42" selection-start-line="226" selection-start-column="23" selection-end-line="226" selection-end-column="42" /> | |
| 533 | - </state> | |
| 534 | - </provider> | |
| 535 | - </entry> | |
| 536 | - <entry file="file://$PROJECT_DIR$/app/controllers/kanjai/pages_controller.rb"> | |
| 537 | - <provider selected="true" editor-type-id="text-editor"> | |
| 538 | - <state relative-caret-position="465"> | |
| 539 | - <caret line="31" selection-start-line="31" selection-end-line="31" /> | |
| 540 | - </state> | |
| 541 | - </provider> | |
| 542 | - </entry> | |
| 543 | - <entry file="file://$PROJECT_DIR$/Gemfile.lock"> | |
| 544 | - <provider selected="true" editor-type-id="text-editor"> | |
| 545 | - <state relative-caret-position="795"> | |
| 546 | - <caret line="53" column="13" selection-start-line="53" selection-start-column="13" selection-end-line="53" selection-end-column="13" /> | |
| 547 | - </state> | |
| 548 | - </provider> | |
| 549 | - </entry> | |
| 550 | - <entry file="file://$PROJECT_DIR$/config/initializers/devise.rb"> | |
| 551 | - <provider selected="true" editor-type-id="text-editor"> | |
| 552 | - <state relative-caret-position="90"> | |
| 553 | - <caret line="6" column="46" selection-start-line="6" selection-start-column="22" selection-end-line="6" selection-end-column="46" /> | |
| 554 | - </state> | |
| 555 | - </provider> | |
| 556 | - </entry> | |
| 557 | - <entry file="file://$PROJECT_DIR$/config/initializers/admin.rb"> | |
| 558 | - <provider selected="true" editor-type-id="text-editor"> | |
| 559 | - <state relative-caret-position="45"> | |
| 560 | - <caret line="3" column="46" selection-start-line="3" selection-start-column="46" selection-end-line="3" selection-end-column="46" /> | |
| 561 | - </state> | |
| 562 | - </provider> | |
| 563 | - </entry> | |
| 564 | - <entry file="file://$PROJECT_DIR$/lib/kanjai.rb"> | |
| 565 | - <provider selected="true" editor-type-id="text-editor" /> | |
| 566 | - </entry> | |
| 567 | - <entry file="file://$PROJECT_DIR$/lib/kanjai/engine.rb"> | |
| 568 | - <provider selected="true" editor-type-id="text-editor" /> | |
| 569 | - </entry> | |
| 570 | - <entry file="file://$PROJECT_DIR$/db/migrate/20160707115443_add_show_public_only_to_kanjai_pages.rb"> | |
| 571 | - <provider selected="true" editor-type-id="text-editor"> | |
| 572 | - <state relative-caret-position="30"> | |
| 573 | - <caret line="2" column="73" selection-start-line="2" selection-start-column="4" selection-end-line="2" selection-end-column="73" /> | |
| 574 | - </state> | |
| 575 | - </provider> | |
| 576 | - </entry> | |
| 577 | - <entry file="file://$PROJECT_DIR$/lib/kanjai/version.rb"> | |
| 578 | - <provider selected="true" editor-type-id="text-editor"> | |
| 579 | - <state relative-caret-position="45"> | |
| 580 | - <caret line="3" selection-start-line="3" selection-end-line="3" /> | |
| 581 | - </state> | |
| 582 | - </provider> | |
| 583 | - </entry> | |
| 584 | - </component> | |
| 585 | -</project> | |
| \ No newline at end of file |
| ... | ... | @@ -2,6 +2,7 @@ PATH |
| 2 | 2 | remote: . |
| 3 | 3 | specs: |
| 4 | 4 | kanjai (0.0.140) |
| 5 | + acts-as-taggable-on (~> 6.5) | |
| 5 | 6 | acts_as_list |
| 6 | 7 | acts_as_tree |
| 7 | 8 | aws-sdk |
| ... | ... | @@ -55,8 +56,10 @@ GEM |
| 55 | 56 | i18n (>= 0.7, < 2) |
| 56 | 57 | minitest (~> 5.1) |
| 57 | 58 | tzinfo (~> 1.1) |
| 58 | - acts_as_list (0.9.19) | |
| 59 | - activerecord (>= 3.0) | |
| 59 | + acts-as-taggable-on (6.5.0) | |
| 60 | + activerecord (>= 5.0, < 6.1) | |
| 61 | + acts_as_list (1.0.1) | |
| 62 | + activerecord (>= 4.2) | |
| 60 | 63 | acts_as_tree (2.9.1) |
| 61 | 64 | activerecord (>= 3.0.0) |
| 62 | 65 | arel (9.0.0) |
| ... | ... | @@ -1019,16 +1022,16 @@ GEM |
| 1019 | 1022 | rb-fsevent (0.10.3) |
| 1020 | 1023 | rb-inotify (0.10.1) |
| 1021 | 1024 | ffi (~> 1.0) |
| 1022 | - responders (2.4.1) | |
| 1023 | - actionpack (>= 4.2.0, < 6.0) | |
| 1024 | - railties (>= 4.2.0, < 6.0) | |
| 1025 | + responders (3.0.0) | |
| 1026 | + actionpack (>= 5.0) | |
| 1027 | + railties (>= 5.0) | |
| 1025 | 1028 | sass (3.7.4) |
| 1026 | 1029 | sass-listen (~> 4.0.0) |
| 1027 | 1030 | sass-listen (4.0.0) |
| 1028 | 1031 | rb-fsevent (~> 0.9, >= 0.9.4) |
| 1029 | 1032 | rb-inotify (~> 0.9, >= 0.9.7) |
| 1030 | - sass-rails (5.0.7) | |
| 1031 | - railties (>= 4.0.0, < 6) | |
| 1033 | + sass-rails (5.1.0) | |
| 1034 | + railties (>= 5.2.0) | |
| 1032 | 1035 | sass (~> 3.1) |
| 1033 | 1036 | sprockets (>= 2.8, < 4.0) |
| 1034 | 1037 | sprockets-rails (>= 2.0, < 4.0) |
| ... | ... | @@ -1060,4 +1063,4 @@ DEPENDENCIES |
| 1060 | 1063 | kanjai! |
| 1061 | 1064 | |
| 1062 | 1065 | BUNDLED WITH |
| 1063 | - 2.0.1 | |
| 1066 | + 2.1.4 | ... | ... |
| ... | ... | @@ -14,8 +14,8 @@ RDoc::Task.new(:rdoc) do |rdoc| |
| 14 | 14 | rdoc.rdoc_files.include('lib/**/*.rb') |
| 15 | 15 | end |
| 16 | 16 | |
| 17 | -APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__) | |
| 18 | -load 'rails/tasks/engine.rake' | |
| 17 | +#APP_RAKEFILE = File.expand_path("../Rakefile", __FILE__) | |
| 18 | +#load 'rails/tasks/engine.rake' | |
| 19 | 19 | |
| 20 | 20 | |
| 21 | 21 | load 'rails/tasks/statistics.rake' | ... | ... |
| ... | ... | @@ -1389,40 +1389,31 @@ var add_fields = function(target, association, content){ |
| 1389 | 1389 | jQuery(target).append(content.replace(regexp, new_id)); |
| 1390 | 1390 | }; |
| 1391 | 1391 | |
| 1392 | - | |
| 1393 | - | |
| 1394 | - | |
| 1395 | -var initAjaxFileUpload = function(selector){ | |
| 1396 | - | |
| 1397 | - | |
| 1398 | - function send_ajax_form($form){ | |
| 1399 | - $('#progress-window').find('.modal-body').append('<div>Upload form data, please wait...</div>'); | |
| 1400 | - var url = $form.attr('action'); | |
| 1401 | - | |
| 1402 | - if($form.hasClass('simple_submit')){ | |
| 1392 | +function send_ajax_form($form){ | |
| 1393 | + $('#progress-window').find('.modal-body').append('<div>Upload form data, please wait...</div>'); | |
| 1394 | + var url = $form.attr('action'); | |
| 1395 | + | |
| 1396 | + if($form.hasClass('simple_submit')){ | |
| 1397 | + $('#progress-window').modal('hide'); | |
| 1398 | + $('#progress-window').remove(); | |
| 1399 | + $form.removeClass('ajax-file-upload-form'); | |
| 1400 | + //$form.unbind('submit', addFileForAjaxUpload); | |
| 1401 | + $form.unbind('submit'); | |
| 1402 | + $form.submit(); | |
| 1403 | + | |
| 1404 | + }else{ | |
| 1405 | + $.post(url, $form.serialize(), function(){ | |
| 1403 | 1406 | $('#progress-window').modal('hide'); |
| 1404 | 1407 | $('#progress-window').remove(); |
| 1405 | - $form.removeClass('ajax-file-upload-form'); | |
| 1406 | - //$form.unbind('submit', addFileForAjaxUpload); | |
| 1407 | - $form.unbind('submit', addFileForAjaxUpload); | |
| 1408 | - $form.submit(); | |
| 1409 | - | |
| 1410 | - }else{ | |
| 1411 | - $.post(url, $form.serialize(), function(){ | |
| 1412 | - $('#progress-window').modal('hide'); | |
| 1413 | - $('#progress-window').remove(); | |
| 1414 | - }); | |
| 1415 | - } | |
| 1408 | + $(window).trigger('images:update'); | |
| 1409 | + }); | |
| 1416 | 1410 | } |
| 1411 | +} | |
| 1417 | 1412 | |
| 1418 | 1413 | |
| 1419 | - | |
| 1420 | - var addFileForAjaxUpload = function(e){ | |
| 1421 | - var $form = $(this), | |
| 1422 | - count_files = 0, | |
| 1414 | +var addFileForAjaxUpload = function(selector, $form){ | |
| 1415 | + var count_files = 0, | |
| 1423 | 1416 | count_upload = 0; |
| 1424 | - e.preventDefault(); | |
| 1425 | - e.stopPropagation(); | |
| 1426 | 1417 | |
| 1427 | 1418 | selector.find(".ajax-file-upload-form input:file").each(function(){ |
| 1428 | 1419 | var $this = $(this), |
| ... | ... | @@ -1454,7 +1445,7 @@ var initAjaxFileUpload = function(selector){ |
| 1454 | 1445 | |
| 1455 | 1446 | |
| 1456 | 1447 | $this.fileupload('send', {files: fileToSend}) |
| 1457 | - .complete(function (result, textStatus, jqXHR) { | |
| 1448 | + .done(function (result, textStatus, jqXHR) { | |
| 1458 | 1449 | count_upload = count_upload + 1; |
| 1459 | 1450 | if(count_upload == count_files){ |
| 1460 | 1451 | send_ajax_form($form); |
| ... | ... | @@ -1472,7 +1463,11 @@ var initAjaxFileUpload = function(selector){ |
| 1472 | 1463 | |
| 1473 | 1464 | |
| 1474 | 1465 | |
| 1475 | - } | |
| 1466 | +} | |
| 1467 | + | |
| 1468 | + | |
| 1469 | +var initAjaxFileUpload = function(selector){ | |
| 1470 | + | |
| 1476 | 1471 | |
| 1477 | 1472 | var initFileInput = function(fileInputElem){ |
| 1478 | 1473 | var form = $(fileInputElem.parents('form:first')); |
| ... | ... | @@ -1499,7 +1494,6 @@ var initAjaxFileUpload = function(selector){ |
| 1499 | 1494 | }, |
| 1500 | 1495 | progressall: function (e, data) { |
| 1501 | 1496 | var progress = parseInt(data.loaded / data.total * 100, 10); |
| 1502 | - | |
| 1503 | 1497 | $('.' + class_name).find('.progress-bar').css('width', progress + '%'); |
| 1504 | 1498 | }, |
| 1505 | 1499 | start: function (e) { |
| ... | ... | @@ -1513,7 +1507,6 @@ var initAjaxFileUpload = function(selector){ |
| 1513 | 1507 | |
| 1514 | 1508 | $('.' + class_name).find('.progress-bar').addClass('progress-bar-success'); |
| 1515 | 1509 | |
| 1516 | - | |
| 1517 | 1510 | // extract key and generate URL from response |
| 1518 | 1511 | var key = $(data.jqXHR.responseXML).find("Key").text(); |
| 1519 | 1512 | var url = 'https://' + fileInputElem.data('host') + '/' + key; |
| ... | ... | @@ -1542,7 +1535,12 @@ var initAjaxFileUpload = function(selector){ |
| 1542 | 1535 | |
| 1543 | 1536 | |
| 1544 | 1537 | |
| 1545 | - selector.find('.ajax-file-upload-form').submit(addFileForAjaxUpload); | |
| 1538 | + selector.find('.ajax-file-upload-form').submit(function(e){ | |
| 1539 | + e.preventDefault(); | |
| 1540 | + e.stopPropagation(); | |
| 1541 | + | |
| 1542 | + addFileForAjaxUpload(selector, $(this)) | |
| 1543 | + }); | |
| 1546 | 1544 | |
| 1547 | 1545 | $(document).bind('drop dragover', function (e) { |
| 1548 | 1546 | e.preventDefault(); |
| ... | ... | @@ -1552,10 +1550,23 @@ var initAjaxFileUpload = function(selector){ |
| 1552 | 1550 | }; |
| 1553 | 1551 | |
| 1554 | 1552 | var clearAjaxFileUpload = function(selector){ |
| 1555 | - selector.find('.ajax-file-upload-form').unbind('submit', addFileForAjaxUpload); | |
| 1553 | + selector.find('.ajax-file-upload-form').unbind('submit'); | |
| 1556 | 1554 | }; |
| 1557 | 1555 | |
| 1558 | 1556 | |
| 1557 | +var tagnames = new Bloodhound({ | |
| 1558 | + datumTokenizer: Bloodhound.tokenizers.obj.whitespace('title'), | |
| 1559 | + queryTokenizer: Bloodhound.tokenizers.whitespace, | |
| 1560 | + prefetch: { | |
| 1561 | + url: '/admin/tags', | |
| 1562 | + filter: function(list) { | |
| 1563 | + return $.map(list, function(title) { | |
| 1564 | + return { title: title }; }); | |
| 1565 | + } | |
| 1566 | + } | |
| 1567 | +}); | |
| 1568 | +tagnames.initialize(); | |
| 1569 | + | |
| 1559 | 1570 | |
| 1560 | 1571 | jQuery(document).ready(function(){ |
| 1561 | 1572 | |
| ... | ... | @@ -1724,46 +1735,78 @@ jQuery(document).ready(function(){ |
| 1724 | 1735 | }else { |
| 1725 | 1736 | dropZone[0].ondrop = function (e) { |
| 1726 | 1737 | e.preventDefault(); |
| 1727 | - var file = e.dataTransfer.files[0], | |
| 1728 | - input_name = "gallery_image[" + file_index + "]", | |
| 1729 | - $fileInput = $('<div><input name="' + input_name + '" type="file" class="fileupload-field"></div>'); | |
| 1738 | + $.each(e.dataTransfer.files, function(){ | |
| 1739 | + var file = this, | |
| 1740 | + input_name = "gallery_image[" + file_index + "]", | |
| 1741 | + $fileInput = $('<div><input name="' + input_name + 'file" type="file" class="fileupload-field"></div>'); | |
| 1730 | 1742 | |
| 1731 | - file_index = file_index + 1; | |
| 1743 | + file_index = file_index + 1; | |
| 1732 | 1744 | |
| 1733 | - $fileInput.find('.fileupload-field').data('url', upload_url); | |
| 1734 | - $fileInput.find('.fileupload-field').data('form-data', upload_form_data); | |
| 1735 | - $fileInput.find('.fileupload-field').data('host', upload_host); | |
| 1745 | + $fileInput.find('.fileupload-field').data('url', upload_url); | |
| 1746 | + $fileInput.find('.fileupload-field').data('form-data', upload_form_data); | |
| 1747 | + $fileInput.find('.fileupload-field').data('host', upload_host); | |
| 1736 | 1748 | |
| 1737 | 1749 | |
| 1738 | - $fileInput.find('.fileupload-field').data('files', [{input_name: input_name, file: file}]); | |
| 1750 | + $fileInput.find('.fileupload-field').data('files', [{input_name: input_name + 'file', file: file}]); | |
| 1739 | 1751 | |
| 1740 | - var reader = new FileReader(); | |
| 1741 | - reader.onload = function (evt) { | |
| 1742 | - var options = { | |
| 1743 | - showUpload:false, | |
| 1744 | - dropZoneEnabled: false, | |
| 1745 | - initialPreview: ["<img src='"+ evt.target.result +"' class='file-preview-image' alt='' title=''>"] | |
| 1746 | - }; | |
| 1752 | + var reader = new FileReader(); | |
| 1753 | + reader.onload = function (evt) { | |
| 1754 | + var options = { | |
| 1755 | + showUpload:false, | |
| 1756 | + dropZoneEnabled: false, | |
| 1757 | + contentType: true, | |
| 1758 | + initialPreview: ["<img src='"+ evt.target.result +"' class='file-preview-image' alt='' title=''>"] | |
| 1759 | + }; | |
| 1747 | 1760 | |
| 1748 | - $fileInput.find('.fileupload-field').fileinput(options); | |
| 1761 | + $fileInput.find('.fileupload-field').fileinput(options); | |
| 1749 | 1762 | |
| 1750 | - $fileInput.find('.fileupload-field').on('fileclear', function(event) { | |
| 1751 | - $(this).closest('.file-input').remove(); | |
| 1752 | - }); | |
| 1763 | + $fileInput.find('.fileupload-field').on('fileclear', function(event) { | |
| 1764 | + if($(this).closest('.new-image-wrapper').length > 0){ | |
| 1765 | + $(this).closest('.new-image-wrapper').remove(); | |
| 1766 | + }else{ | |
| 1767 | + $(this).closest('.file-input').remove(); | |
| 1768 | + } | |
| 1769 | + }); | |
| 1753 | 1770 | |
| 1754 | - $fileInput.find('.fileupload-field').on('change', function(event) { | |
| 1771 | + $fileInput.find('.fileupload-field').on('change', function(event) { | |
| 1755 | 1772 | |
| 1756 | - }); | |
| 1773 | + }); | |
| 1774 | + if($('#gallery_form form').find('.add-new-field').length > 0){ | |
| 1775 | + var template = $('#gallery_form form').find('.add-new-field').data('template'); | |
| 1776 | + template = template.replace(/\{name\}/g, input_name); | |
| 1777 | + var $template = $(template); | |
| 1778 | + $template.find('.fileupload-preview').html($fileInput); | |
| 1779 | + $template.find('.file-type').val(file.type); | |
| 1780 | + | |
| 1781 | + $template.find('.remove').click(function(){ | |
| 1782 | + $(this).closest('.new-image-wrapper').find('.fileinput-remove').trigger('click'); | |
| 1783 | + return false; | |
| 1784 | + }); | |
| 1785 | + $('#gallery_form form #new_images').append($template); | |
| 1786 | + | |
| 1787 | + | |
| 1788 | + | |
| 1789 | + $template.find("input[data-role=tagsinput]").tagsinput({ | |
| 1790 | + typeaheadjs: { | |
| 1791 | + name: 'title', | |
| 1792 | + displayKey: 'title', | |
| 1793 | + valueKey: 'title', | |
| 1794 | + source: tagnames.ttAdapter() | |
| 1795 | + } | |
| 1796 | + }); | |
| 1797 | + }else{ | |
| 1798 | + $('#gallery_form form #new_images').append($fileInput); | |
| 1799 | + } | |
| 1757 | 1800 | |
| 1758 | - $('#gallery_form form #new_images').append($fileInput); | |
| 1801 | + $('#gallery_form form input:submit').removeClass('not-visible'); | |
| 1759 | 1802 | |
| 1760 | - $('#gallery_form form input:submit').removeClass('not-visible'); | |
| 1803 | + clearAjaxFileUpload($('#gallery_form')); | |
| 1804 | + initAjaxFileUpload($('#gallery_form')); | |
| 1761 | 1805 | |
| 1762 | - clearAjaxFileUpload($('#gallery_form')); | |
| 1763 | - initAjaxFileUpload($('#gallery_form')); | |
| 1806 | + }; | |
| 1807 | + reader.readAsDataURL(file); | |
| 1808 | + }); | |
| 1764 | 1809 | |
| 1765 | - }; | |
| 1766 | - reader.readAsDataURL(file); | |
| 1767 | 1810 | |
| 1768 | 1811 | |
| 1769 | 1812 | |
| ... | ... | @@ -1837,6 +1880,7 @@ jQuery(document).ready(function(){ |
| 1837 | 1880 | }); |
| 1838 | 1881 | }); |
| 1839 | 1882 | |
| 1883 | + | |
| 1840 | 1884 | $('.dropdown-toggle').dropdown(); |
| 1841 | 1885 | |
| 1842 | 1886 | }); | ... | ... |
| 1 | +/* | |
| 2 | + * bootstrap-filestyle | |
| 3 | + * doc: http://markusslima.github.io/bootstrap-filestyle/ | |
| 4 | + * github: https://github.com/markusslima/bootstrap-filestyle | |
| 5 | + * | |
| 6 | + * Copyright (c) 2017 Markus Vinicius da Silva Lima | |
| 7 | + * Version 2.1.0 | |
| 8 | + * Licensed under the MIT license. | |
| 9 | + */ | |
| 10 | +(function($) { | |
| 11 | + "use strict"; | |
| 12 | + | |
| 13 | + var nextId = 0; | |
| 14 | + | |
| 15 | + var Filestyle = function(element, options) { | |
| 16 | + this.options = options; | |
| 17 | + this.$elementFilestyle = []; | |
| 18 | + this.$element = $(element); | |
| 19 | + }; | |
| 20 | + | |
| 21 | + Filestyle.prototype = { | |
| 22 | + clear : function() { | |
| 23 | + this.$element.val(''); | |
| 24 | + this.$elementFilestyle.find(':text').val(''); | |
| 25 | + this.$elementFilestyle.find('.badge').remove(); | |
| 26 | + }, | |
| 27 | + | |
| 28 | + destroy : function() { | |
| 29 | + this.$element.removeAttr('style').removeData('filestyle'); | |
| 30 | + this.$elementFilestyle.remove(); | |
| 31 | + }, | |
| 32 | + | |
| 33 | + disabled : function(value) { | |
| 34 | + if (value === true || value === false) { | |
| 35 | + this.options.disabled = value; | |
| 36 | + this.$element.prop('disabled', this.options.disabled); | |
| 37 | + this.$elementFilestyle.find('label').prop('disabled', this.options.disabled); | |
| 38 | + | |
| 39 | + if (this.options.disabled) | |
| 40 | + this.$elementFilestyle.find('label').css('opacity', '0.65'); | |
| 41 | + else | |
| 42 | + this.$elementFilestyle.find('label').css('opacity', '1'); | |
| 43 | + } else { | |
| 44 | + return this.options.disabled; | |
| 45 | + } | |
| 46 | + }, | |
| 47 | + | |
| 48 | + dragdrop : function(value) { | |
| 49 | + if (value === true || value === false) { | |
| 50 | + this.options.dragdrop = value; | |
| 51 | + } else { | |
| 52 | + return this.options.dragdrop; | |
| 53 | + } | |
| 54 | + }, | |
| 55 | + | |
| 56 | + buttonBefore : function(value) { | |
| 57 | + if (value === true) { | |
| 58 | + if (!this.options.buttonBefore) { | |
| 59 | + this.options.buttonBefore = value; | |
| 60 | + if (this.options.input) { | |
| 61 | + this.$elementFilestyle.remove(); | |
| 62 | + this.constructor(); | |
| 63 | + this.pushNameFiles(); | |
| 64 | + } | |
| 65 | + } | |
| 66 | + } else if (value === false) { | |
| 67 | + if (this.options.buttonBefore) { | |
| 68 | + this.options.buttonBefore = value; | |
| 69 | + if (this.options.input) { | |
| 70 | + this.$elementFilestyle.remove(); | |
| 71 | + this.constructor(); | |
| 72 | + this.pushNameFiles(); | |
| 73 | + } | |
| 74 | + } | |
| 75 | + } else { | |
| 76 | + return this.options.buttonBefore; | |
| 77 | + } | |
| 78 | + }, | |
| 79 | + | |
| 80 | + input : function(value) { | |
| 81 | + if (value === true) { | |
| 82 | + if (!this.options.input) { | |
| 83 | + this.options.input = value; | |
| 84 | + | |
| 85 | + if (this.options.buttonBefore) { | |
| 86 | + this.$elementFilestyle.append(this.htmlInput()); | |
| 87 | + } else { | |
| 88 | + this.$elementFilestyle.prepend(this.htmlInput()); | |
| 89 | + } | |
| 90 | + | |
| 91 | + this.pushNameFiles(); | |
| 92 | + this.$elementFilestyle.find('.group-span-filestyle').addClass('input-group-btn'); | |
| 93 | + } | |
| 94 | + } else if (value === false) { | |
| 95 | + if (this.options.input) { | |
| 96 | + this.options.input = value; | |
| 97 | + this.$elementFilestyle.find(':text').remove(); | |
| 98 | + this.$elementFilestyle.find('.group-span-filestyle').removeClass('input-group-btn'); | |
| 99 | + } | |
| 100 | + } else { | |
| 101 | + return this.options.input; | |
| 102 | + } | |
| 103 | + }, | |
| 104 | + | |
| 105 | + size : function(value) { | |
| 106 | + if (value !== undefined) { | |
| 107 | + this.options.size = value; | |
| 108 | + var btn = this.$elementFilestyle.find('label'), input = this.$elementFilestyle.find('input'); | |
| 109 | + | |
| 110 | + btn.removeClass('btn-lg btn-sm'); | |
| 111 | + input.removeClass('form-control-lg form-control-sm'); | |
| 112 | + if (this.options.size != 'nr') { | |
| 113 | + btn.addClass('btn-' + this.options.size); | |
| 114 | + input.addClass('form-control-' + this.options.size); | |
| 115 | + } | |
| 116 | + } else { | |
| 117 | + return this.options.size; | |
| 118 | + } | |
| 119 | + }, | |
| 120 | + | |
| 121 | + placeholder : function(value) { | |
| 122 | + if (value !== undefined) { | |
| 123 | + this.options.placeholder = value; | |
| 124 | + this.$elementFilestyle.find('input').attr('placeholder', value); | |
| 125 | + } else { | |
| 126 | + return this.options.placeholder; | |
| 127 | + } | |
| 128 | + }, | |
| 129 | + | |
| 130 | + text : function(value) { | |
| 131 | + if (value !== undefined) { | |
| 132 | + this.options.text = value; | |
| 133 | + this.$elementFilestyle.find('label .text').html(this.options.text); | |
| 134 | + } else { | |
| 135 | + return this.options.text; | |
| 136 | + } | |
| 137 | + }, | |
| 138 | + | |
| 139 | + btnClass : function(value) { | |
| 140 | + if (value !== undefined) { | |
| 141 | + this.options.btnClass = value; | |
| 142 | + this.$elementFilestyle.find('label').attr({ | |
| 143 | + 'class' : 'btn ' + this.options.btnClass + ' btn-' + this.options.size | |
| 144 | + }); | |
| 145 | + } else { | |
| 146 | + return this.options.btnClass; | |
| 147 | + } | |
| 148 | + }, | |
| 149 | + | |
| 150 | + badge : function(value) { | |
| 151 | + if (value === true) { | |
| 152 | + this.options.badge = value; | |
| 153 | + var files = this.pushNameFiles(); | |
| 154 | + this.$elementFilestyle.find('label').append(' <span class="badge '+this.options.badgeName+'">' + files.length + '</span>'); | |
| 155 | + } else if (value === false) { | |
| 156 | + this.options.badge = value; | |
| 157 | + this.$elementFilestyle.find('.badge').remove(); | |
| 158 | + } else { | |
| 159 | + return this.options.badge; | |
| 160 | + } | |
| 161 | + }, | |
| 162 | + | |
| 163 | + badgeName : function(value) { | |
| 164 | + if (value !== undefined) { | |
| 165 | + this.options.badgeName = value; | |
| 166 | + this.$elementFilestyle.find('.badge').attr({ | |
| 167 | + 'class' : 'badge ' + this.options.badgeName | |
| 168 | + }); | |
| 169 | + } else { | |
| 170 | + return this.options.badgeName; | |
| 171 | + } | |
| 172 | + }, | |
| 173 | + | |
| 174 | + htmlIcon : function(value) { | |
| 175 | + if (value !== undefined) { | |
| 176 | + this.options.htmlIcon = value; | |
| 177 | + } | |
| 178 | + | |
| 179 | + return this.options.htmlIcon; | |
| 180 | + }, | |
| 181 | + | |
| 182 | + htmlInput : function() { | |
| 183 | + if (this.options.input) { | |
| 184 | + return '<input type="text" class="form-control ' + (this.options.size == 'nr' ? '' : 'form-control-' + this.options.size) + '" placeholder="'+ this.options.placeholder +'" disabled> '; | |
| 185 | + } else { | |
| 186 | + return ''; | |
| 187 | + } | |
| 188 | + }, | |
| 189 | + | |
| 190 | + // puts the name of the input files | |
| 191 | + // return files | |
| 192 | + pushNameFiles : function() { | |
| 193 | + var content = '', files = []; | |
| 194 | + if (this.$element[0].files === undefined) { | |
| 195 | + files[0] = { | |
| 196 | + 'name' : this.$element[0] && this.$element[0].value | |
| 197 | + }; | |
| 198 | + } else { | |
| 199 | + files = this.$element[0].files; | |
| 200 | + } | |
| 201 | + | |
| 202 | + for (var i = 0; i < files.length; i++) { | |
| 203 | + content += files[i].name.split("\\").pop() + ', '; | |
| 204 | + } | |
| 205 | + | |
| 206 | + if (content !== '') { | |
| 207 | + this.$elementFilestyle.find(':text').val(content.replace(/\, $/g, '')); | |
| 208 | + } else { | |
| 209 | + this.$elementFilestyle.find(':text').val(''); | |
| 210 | + } | |
| 211 | + | |
| 212 | + return files; | |
| 213 | + }, | |
| 214 | + | |
| 215 | + constructor : function() { | |
| 216 | + var _self = this, | |
| 217 | + html = '', | |
| 218 | + id = _self.$element.attr('id'), | |
| 219 | + files = [], | |
| 220 | + btn = '', | |
| 221 | + $label; | |
| 222 | + | |
| 223 | + if (id === '' || !id) { | |
| 224 | + id = 'filestyle-' + nextId; | |
| 225 | + _self.$element.attr({ | |
| 226 | + 'id' : id | |
| 227 | + }); | |
| 228 | + nextId++; | |
| 229 | + } | |
| 230 | + | |
| 231 | + btn = '<span class="group-span-filestyle ' + (_self.options.input ? 'input-group-btn' : '') + '">' + | |
| 232 | + '<label for="' + id + '" style="margin-bottom: 0;" class="btn ' + _self.options.btnClass + ' ' + | |
| 233 | + (_self.options.size == 'nr' ? '' : 'btn-' + _self.options.size) + '" ' + | |
| 234 | + (_self.options.disabled || _self.$element.attr('disabled') ? ' disabled="true"' : '') + '>' + | |
| 235 | + _self.htmlIcon() + '<span class="buttonText">' + _self.options.text + '</span>' + | |
| 236 | + '</label>' + | |
| 237 | + '</span>'; | |
| 238 | + | |
| 239 | + html = _self.options.buttonBefore ? btn + _self.htmlInput() : _self.htmlInput() + btn; | |
| 240 | + _self.$elementFilestyle = $('<div class="bootstrap-filestyle input-group"><div name="filedrag"></div>' + html + '</div>'); | |
| 241 | + _self.$elementFilestyle.find('.group-span-filestyle').attr('tabindex', "0").keypress(function(e) { | |
| 242 | + if (e.keyCode === 13 || e.charCode === 32) { | |
| 243 | + _self.$elementFilestyle.find('label').click(); | |
| 244 | + return false; | |
| 245 | + } | |
| 246 | + }); | |
| 247 | + | |
| 248 | + // hidding input file and add filestyle | |
| 249 | + _self.$element.css({ | |
| 250 | + 'position' : 'absolute', | |
| 251 | + 'clip' : 'rect(0px 0px 0px 0px)' // using 0px for work in IE8 | |
| 252 | + }).attr('tabindex', "-1").after(_self.$elementFilestyle); | |
| 253 | + | |
| 254 | + _self.$elementFilestyle.find(_self.options.buttonBefore ? 'label' : ':input').css({ | |
| 255 | + 'border-top-left-radius': '.25rem', | |
| 256 | + 'border-bottom-left-radius': '.25rem' | |
| 257 | + }); | |
| 258 | + | |
| 259 | + _self.$elementFilestyle.find('[name="filedrag"]').css({ | |
| 260 | + position: 'absolute', | |
| 261 | + width: '100%', | |
| 262 | + height: _self.$elementFilestyle.height()+'px', | |
| 263 | + 'z-index': -1 | |
| 264 | + }); | |
| 265 | + | |
| 266 | + if (_self.options.disabled || _self.$element.attr('disabled')) { | |
| 267 | + _self.$element.attr('disabled', 'true'); | |
| 268 | + if (_self.options.disabled) | |
| 269 | + _self.$elementFilestyle.find('label').css('opacity', '0.65'); | |
| 270 | + else | |
| 271 | + _self.$elementFilestyle.find('label').css('opacity', '1'); | |
| 272 | + } | |
| 273 | + | |
| 274 | + // Getting input file value | |
| 275 | + _self.$element.change(function () { | |
| 276 | + var files = _self.pushNameFiles(); | |
| 277 | + if (_self.options.badge) { | |
| 278 | + if (_self.$elementFilestyle.find('.badge').length == 0) { | |
| 279 | + _self.$elementFilestyle.find('label').append(' <span class="badge '+_self.options.badgeName+'">' + files.length + '</span>'); | |
| 280 | + } else if (files.length == 0) { | |
| 281 | + _self.$elementFilestyle.find('.badge').remove(); | |
| 282 | + } else { | |
| 283 | + _self.$elementFilestyle.find('.badge').html(files.length); | |
| 284 | + } | |
| 285 | + } else { | |
| 286 | + _self.$elementFilestyle.find('.badge').remove(); | |
| 287 | + } | |
| 288 | + | |
| 289 | + _self.options.onChange(files); | |
| 290 | + }); | |
| 291 | + | |
| 292 | + // Check if browser is Firefox | |
| 293 | + if (window.navigator.userAgent.search(/firefox/i) > -1) { | |
| 294 | + // Simulating choose file for firefox | |
| 295 | + _self.$elementFilestyle.find('label').click(function() { | |
| 296 | + _self.$element.click(); | |
| 297 | + return false; | |
| 298 | + }); | |
| 299 | + } | |
| 300 | + | |
| 301 | + /** DRAG AND DROP EVENTS **/ | |
| 302 | + $(document) | |
| 303 | + .on('dragover', function (e) { | |
| 304 | + e.preventDefault(); | |
| 305 | + e.stopPropagation(); | |
| 306 | + if (_self.options.dragdrop) { | |
| 307 | + $('[name="filedrag"]').css('z-index', '9'); | |
| 308 | + } | |
| 309 | + }) | |
| 310 | + .on('drop', function (e) { | |
| 311 | + e.preventDefault(); | |
| 312 | + e.stopPropagation(); | |
| 313 | + if (_self.options.dragdrop) { | |
| 314 | + $('[name="filedrag"]').css('z-index', '-1'); | |
| 315 | + } | |
| 316 | + }); | |
| 317 | + | |
| 318 | + _self.$elementFilestyle.find('[name="filedrag"]') | |
| 319 | + .on('dragover', | |
| 320 | + function (e) { | |
| 321 | + e.preventDefault(); | |
| 322 | + e.stopPropagation(); | |
| 323 | + } | |
| 324 | + ) | |
| 325 | + .on('dragenter', | |
| 326 | + function (e) { | |
| 327 | + e.preventDefault(); | |
| 328 | + e.stopPropagation(); | |
| 329 | + } | |
| 330 | + ) | |
| 331 | + .on('drop', | |
| 332 | + function (e) { | |
| 333 | + if (e.originalEvent.dataTransfer && !_self.options.disabled && _self.options.dragdrop) { | |
| 334 | + if (e.originalEvent.dataTransfer.files.length) { | |
| 335 | + e.preventDefault(); | |
| 336 | + e.stopPropagation(); | |
| 337 | + _self.$element[0].files = e.originalEvent.dataTransfer.files; | |
| 338 | + var files = _self.pushNameFiles(); | |
| 339 | + if (_self.options.badge) { | |
| 340 | + if (_self.$elementFilestyle.find('.badge').length == 0) { | |
| 341 | + _self.$elementFilestyle.find('label').append(' <span class="badge '+_self.options.badgeName+'">' + files.length + '</span>'); | |
| 342 | + } else if (files.length == 0) { | |
| 343 | + _self.$elementFilestyle.find('.badge').remove(); | |
| 344 | + } else { | |
| 345 | + _self.$elementFilestyle.find('.badge').html(files.length); | |
| 346 | + } | |
| 347 | + } else { | |
| 348 | + _self.$elementFilestyle.find('.badge').remove(); | |
| 349 | + } | |
| 350 | + | |
| 351 | + $('[name="filedrag"]').css('z-index', '-1'); | |
| 352 | + } | |
| 353 | + } | |
| 354 | + } | |
| 355 | + ); | |
| 356 | + } | |
| 357 | + }; | |
| 358 | + | |
| 359 | + var old = $.fn.filestyle; | |
| 360 | + | |
| 361 | + $.fn.filestyle = function(option, value) { | |
| 362 | + var get = '', element = this.each(function() { | |
| 363 | + if ($(this).attr('type') === 'file') { | |
| 364 | + var $this = $(this), data = $this.data('filestyle'), options = $.extend({}, $.fn.filestyle.defaults, option, typeof option === 'object' && option); | |
| 365 | + | |
| 366 | + if (!data) { | |
| 367 | + $this.data('filestyle', ( data = new Filestyle(this, options))); | |
| 368 | + data.constructor(); | |
| 369 | + } | |
| 370 | + | |
| 371 | + if ( typeof option === 'string') { | |
| 372 | + get = data[option](value); | |
| 373 | + } | |
| 374 | + } | |
| 375 | + }); | |
| 376 | + | |
| 377 | + if ( typeof get !== undefined) { | |
| 378 | + return get; | |
| 379 | + } else { | |
| 380 | + return element; | |
| 381 | + } | |
| 382 | + }; | |
| 383 | + | |
| 384 | + $.fn.filestyle.defaults = { | |
| 385 | + 'text' : 'Choose file', | |
| 386 | + 'htmlIcon' : '', | |
| 387 | + 'btnClass' : 'btn-secondary', | |
| 388 | + 'size' : 'nr', | |
| 389 | + 'input' : true, | |
| 390 | + 'badge' : false, | |
| 391 | + 'badgeName': 'badge-light', | |
| 392 | + 'buttonBefore' : false, | |
| 393 | + 'dragdrop' : true, | |
| 394 | + 'disabled' : false, | |
| 395 | + 'placeholder': '', | |
| 396 | + 'onChange': function () {} | |
| 397 | + }; | |
| 398 | + | |
| 399 | + $.fn.filestyle.noConflict = function() { | |
| 400 | + $.fn.filestyle = old; | |
| 401 | + return this; | |
| 402 | + }; | |
| 403 | + | |
| 404 | + $(function() { | |
| 405 | + $('.filestyle').each(function() { | |
| 406 | + var $this = $(this), options = { | |
| 407 | + 'input' : $this.attr('data-input') !== 'false', | |
| 408 | + 'htmlIcon' : $this.attr('data-icon'), | |
| 409 | + 'buttonBefore' : $this.attr('data-buttonBefore') === 'true', | |
| 410 | + 'disabled' : $this.attr('data-disabled') === 'true', | |
| 411 | + 'size' : $this.attr('data-size'), | |
| 412 | + 'text' : $this.attr('data-text'), | |
| 413 | + 'btnClass' : $this.attr('data-btnClass'), | |
| 414 | + 'badge' : $this.attr('data-badge') === 'true', | |
| 415 | + 'dragdrop' : $this.attr('data-dragdrop') !== 'false', | |
| 416 | + 'badgeName' : $this.attr('data-badgeName'), | |
| 417 | + 'placeholder': $this.attr('data-placeholder') | |
| 418 | + }; | |
| 419 | + | |
| 420 | + $this.filestyle(options); | |
| 421 | + }); | |
| 422 | + }); | |
| 423 | +})(window.jQuery); | |
| \ No newline at end of file | ... | ... |
| ... | ... | @@ -455,6 +455,7 @@ |
| 455 | 455 | options.headers['Content-Disposition'] = 'attachment; filename="' + |
| 456 | 456 | encodeURI(file.name) + '"'; |
| 457 | 457 | } |
| 458 | + | |
| 458 | 459 | if (!multipart) { |
| 459 | 460 | options.contentType = file.type || 'application/octet-stream'; |
| 460 | 461 | options.data = options.blob || file; | ... | ... |
| 1 | +jQuery(document).ready(function(){ | |
| 2 | + var loadImage = function($wrapper){ | |
| 3 | + var url = $wrapper.data('url'), | |
| 4 | + $loader = $wrapper.find('.loader-demo'), | |
| 5 | + $images = $wrapper.find('.exist-image-list'); | |
| 6 | + | |
| 7 | + $loader.removeClass('not-visible'); | |
| 8 | + $images.addClass('not-visible'); | |
| 9 | + | |
| 10 | + var mas = []; | |
| 11 | + $wrapper.find('.filter label.active').each(function(){ | |
| 12 | + mas.push($(this).data('value')); | |
| 13 | + }); | |
| 14 | + | |
| 15 | + jQuery.ajax({ | |
| 16 | + type: 'POST', | |
| 17 | + url: url, | |
| 18 | + data: ({tags: mas}), | |
| 19 | + dataType: 'html', | |
| 20 | + success: function(data){ | |
| 21 | + $images.html(data); | |
| 22 | + $loader.addClass('not-visible'); | |
| 23 | + $images.removeClass('not-visible'); | |
| 24 | + } | |
| 25 | + }); | |
| 26 | + }; | |
| 27 | + | |
| 28 | + if($('.image-list').length > 0){ | |
| 29 | + var $wrapper = $('.image-list'); | |
| 30 | + loadImage($wrapper); | |
| 31 | + $wrapper.find('.filter label').click(function(){ | |
| 32 | + var $this = $(this); | |
| 33 | + if($this.hasClass('active')){ | |
| 34 | + $this.removeClass('active'); | |
| 35 | + }else{ | |
| 36 | + $this.addClass('active'); | |
| 37 | + } | |
| 38 | + if($this.data('value') == 'all' && $this.hasClass('active')){ | |
| 39 | + $wrapper.find(".filter label.active").not($this).removeClass('active'); | |
| 40 | + }; | |
| 41 | + if($this.data('value') != 'all' && $this.hasClass('active')){ | |
| 42 | + $wrapper.find(".filter label.active[data-value=all]").removeClass('active'); | |
| 43 | + }; | |
| 44 | + loadImage($wrapper); | |
| 45 | + }); | |
| 46 | + } | |
| 47 | + | |
| 48 | + $(window).bind('images:update', function(){ | |
| 49 | + if($('.image-list').length > 0){ | |
| 50 | + loadImage($('.image-list')); | |
| 51 | + }; | |
| 52 | + }); | |
| 53 | +}); | |
| \ No newline at end of file | ... | ... |
| 1 | +(function ($) { | |
| 2 | + "use strict"; | |
| 3 | + | |
| 4 | + var defaultOptions = { | |
| 5 | + tagClass: function(item) { | |
| 6 | + return 'label label-info'; | |
| 7 | + }, | |
| 8 | + itemValue: function(item) { | |
| 9 | + return item ? item.toString() : item; | |
| 10 | + }, | |
| 11 | + itemText: function(item) { | |
| 12 | + return this.itemValue(item); | |
| 13 | + }, | |
| 14 | + itemTitle: function(item) { | |
| 15 | + return null; | |
| 16 | + }, | |
| 17 | + freeInput: true, | |
| 18 | + addOnBlur: true, | |
| 19 | + maxTags: undefined, | |
| 20 | + maxChars: undefined, | |
| 21 | + confirmKeys: [13, 44], | |
| 22 | + delimiter: ',', | |
| 23 | + delimiterRegex: null, | |
| 24 | + cancelConfirmKeysOnEmpty: true, | |
| 25 | + onTagExists: function(item, $tag) { | |
| 26 | + $tag.hide().fadeIn(); | |
| 27 | + }, | |
| 28 | + trimValue: false, | |
| 29 | + allowDuplicates: false | |
| 30 | + }; | |
| 31 | + | |
| 32 | + /** | |
| 33 | + * Constructor function | |
| 34 | + */ | |
| 35 | + function TagsInput(element, options) { | |
| 36 | + this.itemsArray = []; | |
| 37 | + | |
| 38 | + this.$element = $(element); | |
| 39 | + this.$element.hide(); | |
| 40 | + | |
| 41 | + this.isSelect = (element.tagName === 'SELECT'); | |
| 42 | + this.multiple = (this.isSelect && element.hasAttribute('multiple')); | |
| 43 | + this.objectItems = options && options.itemValue; | |
| 44 | + this.placeholderText = element.hasAttribute('placeholder') ? this.$element.attr('placeholder') : ''; | |
| 45 | + this.inputSize = Math.max(1, this.placeholderText.length); | |
| 46 | + | |
| 47 | + this.$container = $('<div class="bootstrap-tagsinput"></div>'); | |
| 48 | + this.$input = $('<input type="text" placeholder="' + this.placeholderText + '"/>').appendTo(this.$container); | |
| 49 | + | |
| 50 | + this.$element.before(this.$container); | |
| 51 | + | |
| 52 | + this.build(options); | |
| 53 | + } | |
| 54 | + | |
| 55 | + TagsInput.prototype = { | |
| 56 | + constructor: TagsInput, | |
| 57 | + | |
| 58 | + /** | |
| 59 | + * Adds the given item as a new tag. Pass true to dontPushVal to prevent | |
| 60 | + * updating the elements val() | |
| 61 | + */ | |
| 62 | + add: function(item, dontPushVal, options) { | |
| 63 | + var self = this; | |
| 64 | + | |
| 65 | + if (self.options.maxTags && self.itemsArray.length >= self.options.maxTags) | |
| 66 | + return; | |
| 67 | + | |
| 68 | + // Ignore falsey values, except false | |
| 69 | + if (item !== false && !item) | |
| 70 | + return; | |
| 71 | + | |
| 72 | + // Trim value | |
| 73 | + if (typeof item === "string" && self.options.trimValue) { | |
| 74 | + item = $.trim(item); | |
| 75 | + } | |
| 76 | + | |
| 77 | + // Throw an error when trying to add an object while the itemValue option was not set | |
| 78 | + if (typeof item === "object" && !self.objectItems) | |
| 79 | + throw("Can't add objects when itemValue option is not set"); | |
| 80 | + | |
| 81 | + // Ignore strings only containg whitespace | |
| 82 | + if (item.toString().match(/^\s*$/)) | |
| 83 | + return; | |
| 84 | + | |
| 85 | + // If SELECT but not multiple, remove current tag | |
| 86 | + if (self.isSelect && !self.multiple && self.itemsArray.length > 0) | |
| 87 | + self.remove(self.itemsArray[0]); | |
| 88 | + | |
| 89 | + if (typeof item === "string" && this.$element[0].tagName === 'INPUT') { | |
| 90 | + var delimiter = (self.options.delimiterRegex) ? self.options.delimiterRegex : self.options.delimiter; | |
| 91 | + var items = item.split(delimiter); | |
| 92 | + if (items.length > 1) { | |
| 93 | + for (var i = 0; i < items.length; i++) { | |
| 94 | + this.add(items[i], true); | |
| 95 | + } | |
| 96 | + | |
| 97 | + if (!dontPushVal) | |
| 98 | + self.pushVal(); | |
| 99 | + return; | |
| 100 | + } | |
| 101 | + } | |
| 102 | + | |
| 103 | + var itemValue = self.options.itemValue(item), | |
| 104 | + itemText = self.options.itemText(item), | |
| 105 | + tagClass = self.options.tagClass(item), | |
| 106 | + itemTitle = self.options.itemTitle(item); | |
| 107 | + | |
| 108 | + // Ignore items allready added | |
| 109 | + var existing = $.grep(self.itemsArray, function(item) { return self.options.itemValue(item) === itemValue; } )[0]; | |
| 110 | + if (existing && !self.options.allowDuplicates) { | |
| 111 | + // Invoke onTagExists | |
| 112 | + if (self.options.onTagExists) { | |
| 113 | + var $existingTag = $(".tag", self.$container).filter(function() { return $(this).data("item") === existing; }); | |
| 114 | + self.options.onTagExists(item, $existingTag); | |
| 115 | + } | |
| 116 | + return; | |
| 117 | + } | |
| 118 | + | |
| 119 | + // if length greater than limit | |
| 120 | + if (self.items().toString().length + item.length + 1 > self.options.maxInputLength) | |
| 121 | + return; | |
| 122 | + | |
| 123 | + // raise beforeItemAdd arg | |
| 124 | + var beforeItemAddEvent = $.Event('beforeItemAdd', { item: item, cancel: false, options: options}); | |
| 125 | + self.$element.trigger(beforeItemAddEvent); | |
| 126 | + if (beforeItemAddEvent.cancel) | |
| 127 | + return; | |
| 128 | + | |
| 129 | + // register item in internal array and map | |
| 130 | + self.itemsArray.push(item); | |
| 131 | + | |
| 132 | + // add a tag element | |
| 133 | + | |
| 134 | + var $tag = $('<span class="tag ' + htmlEncode(tagClass) + (itemTitle !== null ? ('" title="' + itemTitle) : '') + '">' + htmlEncode(itemText) + '<span data-role="remove"></span></span>'); | |
| 135 | + $tag.data('item', item); | |
| 136 | + self.findInputWrapper().before($tag); | |
| 137 | + $tag.after(' '); | |
| 138 | + | |
| 139 | + // add <option /> if item represents a value not present in one of the <select />'s options | |
| 140 | + if (self.isSelect && !$('option[value="' + encodeURIComponent(itemValue) + '"]',self.$element)[0]) { | |
| 141 | + var $option = $('<option selected>' + htmlEncode(itemText) + '</option>'); | |
| 142 | + $option.data('item', item); | |
| 143 | + $option.attr('value', itemValue); | |
| 144 | + self.$element.append($option); | |
| 145 | + } | |
| 146 | + | |
| 147 | + if (!dontPushVal) | |
| 148 | + self.pushVal(); | |
| 149 | + | |
| 150 | + // Add class when reached maxTags | |
| 151 | + if (self.options.maxTags === self.itemsArray.length || self.items().toString().length === self.options.maxInputLength) | |
| 152 | + self.$container.addClass('bootstrap-tagsinput-max'); | |
| 153 | + | |
| 154 | + self.$element.trigger($.Event('itemAdded', { item: item, options: options })); | |
| 155 | + }, | |
| 156 | + | |
| 157 | + /** | |
| 158 | + * Removes the given item. Pass true to dontPushVal to prevent updating the | |
| 159 | + * elements val() | |
| 160 | + */ | |
| 161 | + remove: function(item, dontPushVal, options) { | |
| 162 | + var self = this; | |
| 163 | + | |
| 164 | + if (self.objectItems) { | |
| 165 | + if (typeof item === "object") | |
| 166 | + item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) == self.options.itemValue(item); } ); | |
| 167 | + else | |
| 168 | + item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) == item; } ); | |
| 169 | + | |
| 170 | + item = item[item.length-1]; | |
| 171 | + } | |
| 172 | + | |
| 173 | + if (item) { | |
| 174 | + var beforeItemRemoveEvent = $.Event('beforeItemRemove', { item: item, cancel: false, options: options }); | |
| 175 | + self.$element.trigger(beforeItemRemoveEvent); | |
| 176 | + if (beforeItemRemoveEvent.cancel) | |
| 177 | + return; | |
| 178 | + | |
| 179 | + $('.tag', self.$container).filter(function() { return $(this).data('item') === item; }).remove(); | |
| 180 | + $('option', self.$element).filter(function() { return $(this).data('item') === item; }).remove(); | |
| 181 | + if($.inArray(item, self.itemsArray) !== -1) | |
| 182 | + self.itemsArray.splice($.inArray(item, self.itemsArray), 1); | |
| 183 | + } | |
| 184 | + | |
| 185 | + if (!dontPushVal) | |
| 186 | + self.pushVal(); | |
| 187 | + | |
| 188 | + // Remove class when reached maxTags | |
| 189 | + if (self.options.maxTags > self.itemsArray.length) | |
| 190 | + self.$container.removeClass('bootstrap-tagsinput-max'); | |
| 191 | + | |
| 192 | + self.$element.trigger($.Event('itemRemoved', { item: item, options: options })); | |
| 193 | + }, | |
| 194 | + | |
| 195 | + /** | |
| 196 | + * Removes all items | |
| 197 | + */ | |
| 198 | + removeAll: function() { | |
| 199 | + var self = this; | |
| 200 | + | |
| 201 | + $('.tag', self.$container).remove(); | |
| 202 | + $('option', self.$element).remove(); | |
| 203 | + | |
| 204 | + while(self.itemsArray.length > 0) | |
| 205 | + self.itemsArray.pop(); | |
| 206 | + | |
| 207 | + self.pushVal(); | |
| 208 | + }, | |
| 209 | + | |
| 210 | + /** | |
| 211 | + * Refreshes the tags so they match the text/value of their corresponding | |
| 212 | + * item. | |
| 213 | + */ | |
| 214 | + refresh: function() { | |
| 215 | + var self = this; | |
| 216 | + $('.tag', self.$container).each(function() { | |
| 217 | + var $tag = $(this), | |
| 218 | + item = $tag.data('item'), | |
| 219 | + itemValue = self.options.itemValue(item), | |
| 220 | + itemText = self.options.itemText(item), | |
| 221 | + tagClass = self.options.tagClass(item); | |
| 222 | + | |
| 223 | + // Update tag's class and inner text | |
| 224 | + $tag.attr('class', null); | |
| 225 | + $tag.addClass('tag ' + htmlEncode(tagClass)); | |
| 226 | + $tag.contents().filter(function() { | |
| 227 | + return this.nodeType == 3; | |
| 228 | + })[0].nodeValue = htmlEncode(itemText); | |
| 229 | + | |
| 230 | + if (self.isSelect) { | |
| 231 | + var option = $('option', self.$element).filter(function() { return $(this).data('item') === item; }); | |
| 232 | + option.attr('value', itemValue); | |
| 233 | + } | |
| 234 | + }); | |
| 235 | + }, | |
| 236 | + | |
| 237 | + /** | |
| 238 | + * Returns the items added as tags | |
| 239 | + */ | |
| 240 | + items: function() { | |
| 241 | + return this.itemsArray; | |
| 242 | + }, | |
| 243 | + | |
| 244 | + /** | |
| 245 | + * Assembly value by retrieving the value of each item, and set it on the | |
| 246 | + * element. | |
| 247 | + */ | |
| 248 | + pushVal: function() { | |
| 249 | + var self = this, | |
| 250 | + val = $.map(self.items(), function(item) { | |
| 251 | + return self.options.itemValue(item).toString(); | |
| 252 | + }); | |
| 253 | + | |
| 254 | + self.$element.val(val, true).trigger('change'); | |
| 255 | + }, | |
| 256 | + | |
| 257 | + /** | |
| 258 | + * Initializes the tags input behaviour on the element | |
| 259 | + */ | |
| 260 | + build: function(options) { | |
| 261 | + var self = this; | |
| 262 | + | |
| 263 | + self.options = $.extend({}, defaultOptions, options); | |
| 264 | + // When itemValue is set, freeInput should always be false | |
| 265 | + if (self.objectItems) | |
| 266 | + self.options.freeInput = false; | |
| 267 | + | |
| 268 | + makeOptionItemFunction(self.options, 'itemValue'); | |
| 269 | + makeOptionItemFunction(self.options, 'itemText'); | |
| 270 | + makeOptionFunction(self.options, 'tagClass'); | |
| 271 | + | |
| 272 | + // Typeahead Bootstrap version 2.3.2 | |
| 273 | + if (self.options.typeahead) { | |
| 274 | + var typeahead = self.options.typeahead || {}; | |
| 275 | + | |
| 276 | + makeOptionFunction(typeahead, 'source'); | |
| 277 | + | |
| 278 | + self.$input.typeahead($.extend({}, typeahead, { | |
| 279 | + source: function (query, process) { | |
| 280 | + function processItems(items) { | |
| 281 | + var texts = []; | |
| 282 | + | |
| 283 | + for (var i = 0; i < items.length; i++) { | |
| 284 | + var text = self.options.itemText(items[i]); | |
| 285 | + map[text] = items[i]; | |
| 286 | + texts.push(text); | |
| 287 | + } | |
| 288 | + process(texts); | |
| 289 | + } | |
| 290 | + | |
| 291 | + this.map = {}; | |
| 292 | + var map = this.map, | |
| 293 | + data = typeahead.source(query); | |
| 294 | + | |
| 295 | + if ($.isFunction(data.success)) { | |
| 296 | + // support for Angular callbacks | |
| 297 | + data.success(processItems); | |
| 298 | + } else if ($.isFunction(data.then)) { | |
| 299 | + // support for Angular promises | |
| 300 | + data.then(processItems); | |
| 301 | + } else { | |
| 302 | + // support for functions and jquery promises | |
| 303 | + $.when(data) | |
| 304 | + .then(processItems); | |
| 305 | + } | |
| 306 | + }, | |
| 307 | + updater: function (text) { | |
| 308 | + self.add(this.map[text]); | |
| 309 | + return this.map[text]; | |
| 310 | + }, | |
| 311 | + matcher: function (text) { | |
| 312 | + return (text.toLowerCase().indexOf(this.query.trim().toLowerCase()) !== -1); | |
| 313 | + }, | |
| 314 | + sorter: function (texts) { | |
| 315 | + return texts.sort(); | |
| 316 | + }, | |
| 317 | + highlighter: function (text) { | |
| 318 | + var regex = new RegExp( '(' + this.query + ')', 'gi' ); | |
| 319 | + return text.replace( regex, "<strong>$1</strong>" ); | |
| 320 | + } | |
| 321 | + })); | |
| 322 | + } | |
| 323 | + | |
| 324 | + // typeahead.js | |
| 325 | + if (self.options.typeaheadjs) { | |
| 326 | + var typeaheadConfig = null; | |
| 327 | + var typeaheadDatasets = {}; | |
| 328 | + | |
| 329 | + // Determine if main configurations were passed or simply a dataset | |
| 330 | + var typeaheadjs = self.options.typeaheadjs; | |
| 331 | + if ($.isArray(typeaheadjs)) { | |
| 332 | + typeaheadConfig = typeaheadjs[0]; | |
| 333 | + typeaheadDatasets = typeaheadjs[1]; | |
| 334 | + } else { | |
| 335 | + typeaheadDatasets = typeaheadjs; | |
| 336 | + } | |
| 337 | + | |
| 338 | + self.$input.typeahead(typeaheadConfig, typeaheadDatasets).on('typeahead:selected', $.proxy(function (obj, datum) { | |
| 339 | + if (typeaheadDatasets.valueKey) | |
| 340 | + self.add(datum[typeaheadDatasets.valueKey]); | |
| 341 | + else | |
| 342 | + self.add(datum); | |
| 343 | + self.$input.typeahead('val', ''); | |
| 344 | + }, self)); | |
| 345 | + } | |
| 346 | + | |
| 347 | + self.$container.on('click', $.proxy(function(event) { | |
| 348 | + if (! self.$element.attr('disabled')) { | |
| 349 | + self.$input.removeAttr('disabled'); | |
| 350 | + } | |
| 351 | + self.$input.focus(); | |
| 352 | + }, self)); | |
| 353 | + | |
| 354 | + if (self.options.addOnBlur && self.options.freeInput) { | |
| 355 | + self.$input.on('focusout', $.proxy(function(event) { | |
| 356 | + // HACK: only process on focusout when no typeahead opened, to | |
| 357 | + // avoid adding the typeahead text as tag | |
| 358 | + if ($('.typeahead, .twitter-typeahead', self.$container).length === 0) { | |
| 359 | + self.add(self.$input.val()); | |
| 360 | + self.$input.val(''); | |
| 361 | + } | |
| 362 | + }, self)); | |
| 363 | + } | |
| 364 | + | |
| 365 | + | |
| 366 | + self.$container.on('keydown', 'input', $.proxy(function(event) { | |
| 367 | + var $input = $(event.target), | |
| 368 | + $inputWrapper = self.findInputWrapper(); | |
| 369 | + | |
| 370 | + if (self.$element.attr('disabled')) { | |
| 371 | + self.$input.attr('disabled', 'disabled'); | |
| 372 | + return; | |
| 373 | + } | |
| 374 | + | |
| 375 | + switch (event.which) { | |
| 376 | + // BACKSPACE | |
| 377 | + case 8: | |
| 378 | + if (doGetCaretPosition($input[0]) === 0) { | |
| 379 | + var prev = $inputWrapper.prev(); | |
| 380 | + if (prev.length) { | |
| 381 | + self.remove(prev.data('item')); | |
| 382 | + } | |
| 383 | + } | |
| 384 | + break; | |
| 385 | + | |
| 386 | + // DELETE | |
| 387 | + case 46: | |
| 388 | + if (doGetCaretPosition($input[0]) === 0) { | |
| 389 | + var next = $inputWrapper.next(); | |
| 390 | + if (next.length) { | |
| 391 | + self.remove(next.data('item')); | |
| 392 | + } | |
| 393 | + } | |
| 394 | + break; | |
| 395 | + | |
| 396 | + // LEFT ARROW | |
| 397 | + case 37: | |
| 398 | + // Try to move the input before the previous tag | |
| 399 | + var $prevTag = $inputWrapper.prev(); | |
| 400 | + if ($input.val().length === 0 && $prevTag[0]) { | |
| 401 | + $prevTag.before($inputWrapper); | |
| 402 | + $input.focus(); | |
| 403 | + } | |
| 404 | + break; | |
| 405 | + // RIGHT ARROW | |
| 406 | + case 39: | |
| 407 | + // Try to move the input after the next tag | |
| 408 | + var $nextTag = $inputWrapper.next(); | |
| 409 | + if ($input.val().length === 0 && $nextTag[0]) { | |
| 410 | + $nextTag.after($inputWrapper); | |
| 411 | + $input.focus(); | |
| 412 | + } | |
| 413 | + break; | |
| 414 | + default: | |
| 415 | + // ignore | |
| 416 | + } | |
| 417 | + | |
| 418 | + // Reset internal input's size | |
| 419 | + var textLength = $input.val().length, | |
| 420 | + wordSpace = Math.ceil(textLength / 5), | |
| 421 | + size = textLength + wordSpace + 1; | |
| 422 | + $input.attr('size', Math.max(this.inputSize, $input.val().length)); | |
| 423 | + }, self)); | |
| 424 | + | |
| 425 | + self.$container.on('keypress', 'input', $.proxy(function(event) { | |
| 426 | + event.stopPropagation(); | |
| 427 | + var $input = $(event.target); | |
| 428 | + | |
| 429 | + if (self.$element.attr('disabled')) { | |
| 430 | + self.$input.attr('disabled', 'disabled'); | |
| 431 | + return; | |
| 432 | + } | |
| 433 | + var text = $input.val(), | |
| 434 | + maxLengthReached = self.options.maxChars && text.length >= self.options.maxChars; | |
| 435 | + if (self.options.freeInput && (keyCombinationInList(event, self.options.confirmKeys) || maxLengthReached)) { | |
| 436 | + // Only attempt to add a tag if there is data in the field | |
| 437 | + if (text.length !== 0) { | |
| 438 | + self.add(maxLengthReached ? text.substr(0, self.options.maxChars) : text); | |
| 439 | + $input.val(''); | |
| 440 | + } | |
| 441 | + | |
| 442 | + // If the field is empty, let the event triggered fire as usual | |
| 443 | + if (self.options.cancelConfirmKeysOnEmpty === false) { | |
| 444 | + event.preventDefault(); | |
| 445 | + } | |
| 446 | + } | |
| 447 | + | |
| 448 | + // Reset internal input's size | |
| 449 | + var textLength = $input.val().length, | |
| 450 | + wordSpace = Math.ceil(textLength / 5), | |
| 451 | + size = textLength + wordSpace + 1; | |
| 452 | + $input.attr('size', Math.max(this.inputSize, $input.val().length)); | |
| 453 | + if(keyCombinationInList(event, [13]) ){ | |
| 454 | + return false; | |
| 455 | + }else{ | |
| 456 | + return true; | |
| 457 | + } | |
| 458 | + | |
| 459 | + }, self)); | |
| 460 | + | |
| 461 | + // Remove icon clicked | |
| 462 | + self.$container.on('click', '[data-role=remove]', $.proxy(function(event) { | |
| 463 | + if (self.$element.attr('disabled')) { | |
| 464 | + return; | |
| 465 | + } | |
| 466 | + self.remove($(event.target).closest('.tag').data('item')); | |
| 467 | + }, self)); | |
| 468 | + | |
| 469 | + // Only add existing value as tags when using strings as tags | |
| 470 | + if (self.options.itemValue === defaultOptions.itemValue) { | |
| 471 | + if (self.$element[0].tagName === 'INPUT') { | |
| 472 | + self.add(self.$element.val()); | |
| 473 | + } else { | |
| 474 | + $('option', self.$element).each(function() { | |
| 475 | + self.add($(this).attr('value'), true); | |
| 476 | + }); | |
| 477 | + } | |
| 478 | + } | |
| 479 | + }, | |
| 480 | + | |
| 481 | + /** | |
| 482 | + * Removes all tagsinput behaviour and unregsiter all event handlers | |
| 483 | + */ | |
| 484 | + destroy: function() { | |
| 485 | + var self = this; | |
| 486 | + | |
| 487 | + // Unbind events | |
| 488 | + self.$container.off('keypress', 'input'); | |
| 489 | + self.$container.off('click', '[role=remove]'); | |
| 490 | + | |
| 491 | + self.$container.remove(); | |
| 492 | + self.$element.removeData('tagsinput'); | |
| 493 | + self.$element.show(); | |
| 494 | + }, | |
| 495 | + | |
| 496 | + /** | |
| 497 | + * Sets focus on the tagsinput | |
| 498 | + */ | |
| 499 | + focus: function() { | |
| 500 | + this.$input.focus(); | |
| 501 | + }, | |
| 502 | + | |
| 503 | + /** | |
| 504 | + * Returns the internal input element | |
| 505 | + */ | |
| 506 | + input: function() { | |
| 507 | + return this.$input; | |
| 508 | + }, | |
| 509 | + | |
| 510 | + /** | |
| 511 | + * Returns the element which is wrapped around the internal input. This | |
| 512 | + * is normally the $container, but typeahead.js moves the $input element. | |
| 513 | + */ | |
| 514 | + findInputWrapper: function() { | |
| 515 | + var elt = this.$input[0], | |
| 516 | + container = this.$container[0]; | |
| 517 | + while(elt && elt.parentNode !== container) | |
| 518 | + elt = elt.parentNode; | |
| 519 | + | |
| 520 | + return $(elt); | |
| 521 | + } | |
| 522 | + }; | |
| 523 | + | |
| 524 | + /** | |
| 525 | + * Register JQuery plugin | |
| 526 | + */ | |
| 527 | + $.fn.tagsinput = function(arg1, arg2, arg3) { | |
| 528 | + var results = []; | |
| 529 | + | |
| 530 | + this.each(function() { | |
| 531 | + var tagsinput = $(this).data('tagsinput'); | |
| 532 | + // Initialize a new tags input | |
| 533 | + if (!tagsinput) { | |
| 534 | + tagsinput = new TagsInput(this, arg1); | |
| 535 | + $(this).data('tagsinput', tagsinput); | |
| 536 | + results.push(tagsinput); | |
| 537 | + | |
| 538 | + if (this.tagName === 'SELECT') { | |
| 539 | + $('option', $(this)).attr('selected', 'selected'); | |
| 540 | + } | |
| 541 | + | |
| 542 | + // Init tags from $(this).val() | |
| 543 | + $(this).val($(this).val()); | |
| 544 | + } else if (!arg1 && !arg2) { | |
| 545 | + // tagsinput already exists | |
| 546 | + // no function, trying to init | |
| 547 | + results.push(tagsinput); | |
| 548 | + } else if(tagsinput[arg1] !== undefined) { | |
| 549 | + // Invoke function on existing tags input | |
| 550 | + if(tagsinput[arg1].length === 3 && arg3 !== undefined){ | |
| 551 | + var retVal = tagsinput[arg1](arg2, null, arg3); | |
| 552 | + }else{ | |
| 553 | + var retVal = tagsinput[arg1](arg2); | |
| 554 | + } | |
| 555 | + if (retVal !== undefined) | |
| 556 | + results.push(retVal); | |
| 557 | + } | |
| 558 | + }); | |
| 559 | + | |
| 560 | + if ( typeof arg1 == 'string') { | |
| 561 | + // Return the results from the invoked function calls | |
| 562 | + return results.length > 1 ? results : results[0]; | |
| 563 | + } else { | |
| 564 | + return results; | |
| 565 | + } | |
| 566 | + }; | |
| 567 | + | |
| 568 | + $.fn.tagsinput.Constructor = TagsInput; | |
| 569 | + | |
| 570 | + /** | |
| 571 | + * Most options support both a string or number as well as a function as | |
| 572 | + * option value. This function makes sure that the option with the given | |
| 573 | + * key in the given options is wrapped in a function | |
| 574 | + */ | |
| 575 | + function makeOptionItemFunction(options, key) { | |
| 576 | + if (typeof options[key] !== 'function') { | |
| 577 | + var propertyName = options[key]; | |
| 578 | + options[key] = function(item) { return item[propertyName]; }; | |
| 579 | + } | |
| 580 | + } | |
| 581 | + function makeOptionFunction(options, key) { | |
| 582 | + if (typeof options[key] !== 'function') { | |
| 583 | + var value = options[key]; | |
| 584 | + options[key] = function() { return value; }; | |
| 585 | + } | |
| 586 | + } | |
| 587 | + /** | |
| 588 | + * HtmlEncodes the given value | |
| 589 | + */ | |
| 590 | + var htmlEncodeContainer = $('<div />'); | |
| 591 | + function htmlEncode(value) { | |
| 592 | + if (value) { | |
| 593 | + return htmlEncodeContainer.text(value).html(); | |
| 594 | + } else { | |
| 595 | + return ''; | |
| 596 | + } | |
| 597 | + } | |
| 598 | + | |
| 599 | + /** | |
| 600 | + * Returns the position of the caret in the given input field | |
| 601 | + * http://flightschool.acylt.com/devnotes/caret-position-woes/ | |
| 602 | + */ | |
| 603 | + function doGetCaretPosition(oField) { | |
| 604 | + var iCaretPos = 0; | |
| 605 | + if (document.selection) { | |
| 606 | + oField.focus (); | |
| 607 | + var oSel = document.selection.createRange(); | |
| 608 | + oSel.moveStart ('character', -oField.value.length); | |
| 609 | + iCaretPos = oSel.text.length; | |
| 610 | + } else if (oField.selectionStart || oField.selectionStart == '0') { | |
| 611 | + iCaretPos = oField.selectionStart; | |
| 612 | + } | |
| 613 | + return (iCaretPos); | |
| 614 | + } | |
| 615 | + | |
| 616 | + /** | |
| 617 | + * Returns boolean indicates whether user has pressed an expected key combination. | |
| 618 | + * @param object keyPressEvent: JavaScript event object, refer | |
| 619 | + * http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html | |
| 620 | + * @param object lookupList: expected key combinations, as in: | |
| 621 | + * [13, {which: 188, shiftKey: true}] | |
| 622 | + */ | |
| 623 | + function keyCombinationInList(keyPressEvent, lookupList) { | |
| 624 | + var found = false; | |
| 625 | + $.each(lookupList, function (index, keyCombination) { | |
| 626 | + if (typeof (keyCombination) === 'number' && keyPressEvent.which === keyCombination) { | |
| 627 | + found = true; | |
| 628 | + return false; | |
| 629 | + } | |
| 630 | + | |
| 631 | + if (keyPressEvent.which === keyCombination.which) { | |
| 632 | + var alt = !keyCombination.hasOwnProperty('altKey') || keyPressEvent.altKey === keyCombination.altKey, | |
| 633 | + shift = !keyCombination.hasOwnProperty('shiftKey') || keyPressEvent.shiftKey === keyCombination.shiftKey, | |
| 634 | + ctrl = !keyCombination.hasOwnProperty('ctrlKey') || keyPressEvent.ctrlKey === keyCombination.ctrlKey; | |
| 635 | + if (alt && shift && ctrl) { | |
| 636 | + found = true; | |
| 637 | + return false; | |
| 638 | + } | |
| 639 | + } | |
| 640 | + }); | |
| 641 | + | |
| 642 | + return found; | |
| 643 | + } | |
| 644 | + | |
| 645 | + /** | |
| 646 | + * Initialize tagsinput behaviour on inputs and selects which have | |
| 647 | + * data-role=tagsinput | |
| 648 | + */ | |
| 649 | + | |
| 650 | + $(function() { | |
| 651 | + $("input[data-role=tagsinput], select[multiple][data-role=tagsinput]").tagsinput(); | |
| 652 | + }); | |
| 653 | +})(window.jQuery); | ... | ... |
| 1 | +/*! | |
| 2 | + * typeahead.js 0.11.1 | |
| 3 | + * https://github.com/twitter/typeahead.js | |
| 4 | + * Copyright 2013-2015 Twitter, Inc. and other contributors; Licensed MIT | |
| 5 | + */ | |
| 6 | + | |
| 7 | +(function(root, factory) { | |
| 8 | + if (typeof define === "function" && define.amd) { | |
| 9 | + define("bloodhound", [ "jquery" ], function(a0) { | |
| 10 | + return root["Bloodhound"] = factory(a0); | |
| 11 | + }); | |
| 12 | + } else if (typeof exports === "object") { | |
| 13 | + module.exports = factory(require("jquery")); | |
| 14 | + } else { | |
| 15 | + root["Bloodhound"] = factory(jQuery); | |
| 16 | + } | |
| 17 | +})(this, function($) { | |
| 18 | + var _ = function() { | |
| 19 | + "use strict"; | |
| 20 | + return { | |
| 21 | + isMsie: function() { | |
| 22 | + return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false; | |
| 23 | + }, | |
| 24 | + isBlankString: function(str) { | |
| 25 | + return !str || /^\s*$/.test(str); | |
| 26 | + }, | |
| 27 | + escapeRegExChars: function(str) { | |
| 28 | + return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); | |
| 29 | + }, | |
| 30 | + isString: function(obj) { | |
| 31 | + return typeof obj === "string"; | |
| 32 | + }, | |
| 33 | + isNumber: function(obj) { | |
| 34 | + return typeof obj === "number"; | |
| 35 | + }, | |
| 36 | + isArray: $.isArray, | |
| 37 | + isFunction: $.isFunction, | |
| 38 | + isObject: $.isPlainObject, | |
| 39 | + isUndefined: function(obj) { | |
| 40 | + return typeof obj === "undefined"; | |
| 41 | + }, | |
| 42 | + isElement: function(obj) { | |
| 43 | + return !!(obj && obj.nodeType === 1); | |
| 44 | + }, | |
| 45 | + isJQuery: function(obj) { | |
| 46 | + return obj instanceof $; | |
| 47 | + }, | |
| 48 | + toStr: function toStr(s) { | |
| 49 | + return _.isUndefined(s) || s === null ? "" : s + ""; | |
| 50 | + }, | |
| 51 | + bind: $.proxy, | |
| 52 | + each: function(collection, cb) { | |
| 53 | + $.each(collection, reverseArgs); | |
| 54 | + function reverseArgs(index, value) { | |
| 55 | + return cb(value, index); | |
| 56 | + } | |
| 57 | + }, | |
| 58 | + map: $.map, | |
| 59 | + filter: $.grep, | |
| 60 | + every: function(obj, test) { | |
| 61 | + var result = true; | |
| 62 | + if (!obj) { | |
| 63 | + return result; | |
| 64 | + } | |
| 65 | + $.each(obj, function(key, val) { | |
| 66 | + if (!(result = test.call(null, val, key, obj))) { | |
| 67 | + return false; | |
| 68 | + } | |
| 69 | + }); | |
| 70 | + return !!result; | |
| 71 | + }, | |
| 72 | + some: function(obj, test) { | |
| 73 | + var result = false; | |
| 74 | + if (!obj) { | |
| 75 | + return result; | |
| 76 | + } | |
| 77 | + $.each(obj, function(key, val) { | |
| 78 | + if (result = test.call(null, val, key, obj)) { | |
| 79 | + return false; | |
| 80 | + } | |
| 81 | + }); | |
| 82 | + return !!result; | |
| 83 | + }, | |
| 84 | + mixin: $.extend, | |
| 85 | + identity: function(x) { | |
| 86 | + return x; | |
| 87 | + }, | |
| 88 | + clone: function(obj) { | |
| 89 | + return $.extend(true, {}, obj); | |
| 90 | + }, | |
| 91 | + getIdGenerator: function() { | |
| 92 | + var counter = 0; | |
| 93 | + return function() { | |
| 94 | + return counter++; | |
| 95 | + }; | |
| 96 | + }, | |
| 97 | + templatify: function templatify(obj) { | |
| 98 | + return $.isFunction(obj) ? obj : template; | |
| 99 | + function template() { | |
| 100 | + return String(obj); | |
| 101 | + } | |
| 102 | + }, | |
| 103 | + defer: function(fn) { | |
| 104 | + setTimeout(fn, 0); | |
| 105 | + }, | |
| 106 | + debounce: function(func, wait, immediate) { | |
| 107 | + var timeout, result; | |
| 108 | + return function() { | |
| 109 | + var context = this, args = arguments, later, callNow; | |
| 110 | + later = function() { | |
| 111 | + timeout = null; | |
| 112 | + if (!immediate) { | |
| 113 | + result = func.apply(context, args); | |
| 114 | + } | |
| 115 | + }; | |
| 116 | + callNow = immediate && !timeout; | |
| 117 | + clearTimeout(timeout); | |
| 118 | + timeout = setTimeout(later, wait); | |
| 119 | + if (callNow) { | |
| 120 | + result = func.apply(context, args); | |
| 121 | + } | |
| 122 | + return result; | |
| 123 | + }; | |
| 124 | + }, | |
| 125 | + throttle: function(func, wait) { | |
| 126 | + var context, args, timeout, result, previous, later; | |
| 127 | + previous = 0; | |
| 128 | + later = function() { | |
| 129 | + previous = new Date(); | |
| 130 | + timeout = null; | |
| 131 | + result = func.apply(context, args); | |
| 132 | + }; | |
| 133 | + return function() { | |
| 134 | + var now = new Date(), remaining = wait - (now - previous); | |
| 135 | + context = this; | |
| 136 | + args = arguments; | |
| 137 | + if (remaining <= 0) { | |
| 138 | + clearTimeout(timeout); | |
| 139 | + timeout = null; | |
| 140 | + previous = now; | |
| 141 | + result = func.apply(context, args); | |
| 142 | + } else if (!timeout) { | |
| 143 | + timeout = setTimeout(later, remaining); | |
| 144 | + } | |
| 145 | + return result; | |
| 146 | + }; | |
| 147 | + }, | |
| 148 | + stringify: function(val) { | |
| 149 | + return _.isString(val) ? val : JSON.stringify(val); | |
| 150 | + }, | |
| 151 | + noop: function() {} | |
| 152 | + }; | |
| 153 | + }(); | |
| 154 | + var VERSION = "0.11.1"; | |
| 155 | + var tokenizers = function() { | |
| 156 | + "use strict"; | |
| 157 | + return { | |
| 158 | + nonword: nonword, | |
| 159 | + whitespace: whitespace, | |
| 160 | + obj: { | |
| 161 | + nonword: getObjTokenizer(nonword), | |
| 162 | + whitespace: getObjTokenizer(whitespace) | |
| 163 | + } | |
| 164 | + }; | |
| 165 | + function whitespace(str) { | |
| 166 | + str = _.toStr(str); | |
| 167 | + return str ? str.split(/\s+/) : []; | |
| 168 | + } | |
| 169 | + function nonword(str) { | |
| 170 | + str = _.toStr(str); | |
| 171 | + return str ? str.split(/\W+/) : []; | |
| 172 | + } | |
| 173 | + function getObjTokenizer(tokenizer) { | |
| 174 | + return function setKey(keys) { | |
| 175 | + keys = _.isArray(keys) ? keys : [].slice.call(arguments, 0); | |
| 176 | + return function tokenize(o) { | |
| 177 | + var tokens = []; | |
| 178 | + _.each(keys, function(k) { | |
| 179 | + tokens = tokens.concat(tokenizer(_.toStr(o[k]))); | |
| 180 | + }); | |
| 181 | + return tokens; | |
| 182 | + }; | |
| 183 | + }; | |
| 184 | + } | |
| 185 | + }(); | |
| 186 | + var LruCache = function() { | |
| 187 | + "use strict"; | |
| 188 | + function LruCache(maxSize) { | |
| 189 | + this.maxSize = _.isNumber(maxSize) ? maxSize : 100; | |
| 190 | + this.reset(); | |
| 191 | + if (this.maxSize <= 0) { | |
| 192 | + this.set = this.get = $.noop; | |
| 193 | + } | |
| 194 | + } | |
| 195 | + _.mixin(LruCache.prototype, { | |
| 196 | + set: function set(key, val) { | |
| 197 | + var tailItem = this.list.tail, node; | |
| 198 | + if (this.size >= this.maxSize) { | |
| 199 | + this.list.remove(tailItem); | |
| 200 | + delete this.hash[tailItem.key]; | |
| 201 | + this.size--; | |
| 202 | + } | |
| 203 | + if (node = this.hash[key]) { | |
| 204 | + node.val = val; | |
| 205 | + this.list.moveToFront(node); | |
| 206 | + } else { | |
| 207 | + node = new Node(key, val); | |
| 208 | + this.list.add(node); | |
| 209 | + this.hash[key] = node; | |
| 210 | + this.size++; | |
| 211 | + } | |
| 212 | + }, | |
| 213 | + get: function get(key) { | |
| 214 | + var node = this.hash[key]; | |
| 215 | + if (node) { | |
| 216 | + this.list.moveToFront(node); | |
| 217 | + return node.val; | |
| 218 | + } | |
| 219 | + }, | |
| 220 | + reset: function reset() { | |
| 221 | + this.size = 0; | |
| 222 | + this.hash = {}; | |
| 223 | + this.list = new List(); | |
| 224 | + } | |
| 225 | + }); | |
| 226 | + function List() { | |
| 227 | + this.head = this.tail = null; | |
| 228 | + } | |
| 229 | + _.mixin(List.prototype, { | |
| 230 | + add: function add(node) { | |
| 231 | + if (this.head) { | |
| 232 | + node.next = this.head; | |
| 233 | + this.head.prev = node; | |
| 234 | + } | |
| 235 | + this.head = node; | |
| 236 | + this.tail = this.tail || node; | |
| 237 | + }, | |
| 238 | + remove: function remove(node) { | |
| 239 | + node.prev ? node.prev.next = node.next : this.head = node.next; | |
| 240 | + node.next ? node.next.prev = node.prev : this.tail = node.prev; | |
| 241 | + }, | |
| 242 | + moveToFront: function(node) { | |
| 243 | + this.remove(node); | |
| 244 | + this.add(node); | |
| 245 | + } | |
| 246 | + }); | |
| 247 | + function Node(key, val) { | |
| 248 | + this.key = key; | |
| 249 | + this.val = val; | |
| 250 | + this.prev = this.next = null; | |
| 251 | + } | |
| 252 | + return LruCache; | |
| 253 | + }(); | |
| 254 | + var PersistentStorage = function() { | |
| 255 | + "use strict"; | |
| 256 | + var LOCAL_STORAGE; | |
| 257 | + try { | |
| 258 | + LOCAL_STORAGE = window.localStorage; | |
| 259 | + LOCAL_STORAGE.setItem("~~~", "!"); | |
| 260 | + LOCAL_STORAGE.removeItem("~~~"); | |
| 261 | + } catch (err) { | |
| 262 | + LOCAL_STORAGE = null; | |
| 263 | + } | |
| 264 | + function PersistentStorage(namespace, override) { | |
| 265 | + this.prefix = [ "__", namespace, "__" ].join(""); | |
| 266 | + this.ttlKey = "__ttl__"; | |
| 267 | + this.keyMatcher = new RegExp("^" + _.escapeRegExChars(this.prefix)); | |
| 268 | + this.ls = override || LOCAL_STORAGE; | |
| 269 | + !this.ls && this._noop(); | |
| 270 | + } | |
| 271 | + _.mixin(PersistentStorage.prototype, { | |
| 272 | + _prefix: function(key) { | |
| 273 | + return this.prefix + key; | |
| 274 | + }, | |
| 275 | + _ttlKey: function(key) { | |
| 276 | + return this._prefix(key) + this.ttlKey; | |
| 277 | + }, | |
| 278 | + _noop: function() { | |
| 279 | + this.get = this.set = this.remove = this.clear = this.isExpired = _.noop; | |
| 280 | + }, | |
| 281 | + _safeSet: function(key, val) { | |
| 282 | + try { | |
| 283 | + this.ls.setItem(key, val); | |
| 284 | + } catch (err) { | |
| 285 | + if (err.name === "QuotaExceededError") { | |
| 286 | + this.clear(); | |
| 287 | + this._noop(); | |
| 288 | + } | |
| 289 | + } | |
| 290 | + }, | |
| 291 | + get: function(key) { | |
| 292 | + if (this.isExpired(key)) { | |
| 293 | + this.remove(key); | |
| 294 | + } | |
| 295 | + return decode(this.ls.getItem(this._prefix(key))); | |
| 296 | + }, | |
| 297 | + set: function(key, val, ttl) { | |
| 298 | + if (_.isNumber(ttl)) { | |
| 299 | + this._safeSet(this._ttlKey(key), encode(now() + ttl)); | |
| 300 | + } else { | |
| 301 | + this.ls.removeItem(this._ttlKey(key)); | |
| 302 | + } | |
| 303 | + return this._safeSet(this._prefix(key), encode(val)); | |
| 304 | + }, | |
| 305 | + remove: function(key) { | |
| 306 | + this.ls.removeItem(this._ttlKey(key)); | |
| 307 | + this.ls.removeItem(this._prefix(key)); | |
| 308 | + return this; | |
| 309 | + }, | |
| 310 | + clear: function() { | |
| 311 | + var i, keys = gatherMatchingKeys(this.keyMatcher); | |
| 312 | + for (i = keys.length; i--; ) { | |
| 313 | + this.remove(keys[i]); | |
| 314 | + } | |
| 315 | + return this; | |
| 316 | + }, | |
| 317 | + isExpired: function(key) { | |
| 318 | + var ttl = decode(this.ls.getItem(this._ttlKey(key))); | |
| 319 | + return _.isNumber(ttl) && now() > ttl ? true : false; | |
| 320 | + } | |
| 321 | + }); | |
| 322 | + return PersistentStorage; | |
| 323 | + function now() { | |
| 324 | + return new Date().getTime(); | |
| 325 | + } | |
| 326 | + function encode(val) { | |
| 327 | + return JSON.stringify(_.isUndefined(val) ? null : val); | |
| 328 | + } | |
| 329 | + function decode(val) { | |
| 330 | + return $.parseJSON(val); | |
| 331 | + } | |
| 332 | + function gatherMatchingKeys(keyMatcher) { | |
| 333 | + var i, key, keys = [], len = LOCAL_STORAGE.length; | |
| 334 | + for (i = 0; i < len; i++) { | |
| 335 | + if ((key = LOCAL_STORAGE.key(i)).match(keyMatcher)) { | |
| 336 | + keys.push(key.replace(keyMatcher, "")); | |
| 337 | + } | |
| 338 | + } | |
| 339 | + return keys; | |
| 340 | + } | |
| 341 | + }(); | |
| 342 | + var Transport = function() { | |
| 343 | + "use strict"; | |
| 344 | + var pendingRequestsCount = 0, pendingRequests = {}, maxPendingRequests = 6, sharedCache = new LruCache(10); | |
| 345 | + function Transport(o) { | |
| 346 | + o = o || {}; | |
| 347 | + this.cancelled = false; | |
| 348 | + this.lastReq = null; | |
| 349 | + this._send = o.transport; | |
| 350 | + this._get = o.limiter ? o.limiter(this._get) : this._get; | |
| 351 | + this._cache = o.cache === false ? new LruCache(0) : sharedCache; | |
| 352 | + } | |
| 353 | + Transport.setMaxPendingRequests = function setMaxPendingRequests(num) { | |
| 354 | + maxPendingRequests = num; | |
| 355 | + }; | |
| 356 | + Transport.resetCache = function resetCache() { | |
| 357 | + sharedCache.reset(); | |
| 358 | + }; | |
| 359 | + _.mixin(Transport.prototype, { | |
| 360 | + _fingerprint: function fingerprint(o) { | |
| 361 | + o = o || {}; | |
| 362 | + return o.url + o.type + $.param(o.data || {}); | |
| 363 | + }, | |
| 364 | + _get: function(o, cb) { | |
| 365 | + var that = this, fingerprint, jqXhr; | |
| 366 | + fingerprint = this._fingerprint(o); | |
| 367 | + if (this.cancelled || fingerprint !== this.lastReq) { | |
| 368 | + return; | |
| 369 | + } | |
| 370 | + if (jqXhr = pendingRequests[fingerprint]) { | |
| 371 | + jqXhr.done(done).fail(fail); | |
| 372 | + } else if (pendingRequestsCount < maxPendingRequests) { | |
| 373 | + pendingRequestsCount++; | |
| 374 | + pendingRequests[fingerprint] = this._send(o).done(done).fail(fail).always(always); | |
| 375 | + } else { | |
| 376 | + this.onDeckRequestArgs = [].slice.call(arguments, 0); | |
| 377 | + } | |
| 378 | + function done(resp) { | |
| 379 | + cb(null, resp); | |
| 380 | + that._cache.set(fingerprint, resp); | |
| 381 | + } | |
| 382 | + function fail() { | |
| 383 | + cb(true); | |
| 384 | + } | |
| 385 | + function always() { | |
| 386 | + pendingRequestsCount--; | |
| 387 | + delete pendingRequests[fingerprint]; | |
| 388 | + if (that.onDeckRequestArgs) { | |
| 389 | + that._get.apply(that, that.onDeckRequestArgs); | |
| 390 | + that.onDeckRequestArgs = null; | |
| 391 | + } | |
| 392 | + } | |
| 393 | + }, | |
| 394 | + get: function(o, cb) { | |
| 395 | + var resp, fingerprint; | |
| 396 | + cb = cb || $.noop; | |
| 397 | + o = _.isString(o) ? { | |
| 398 | + url: o | |
| 399 | + } : o || {}; | |
| 400 | + fingerprint = this._fingerprint(o); | |
| 401 | + this.cancelled = false; | |
| 402 | + this.lastReq = fingerprint; | |
| 403 | + if (resp = this._cache.get(fingerprint)) { | |
| 404 | + cb(null, resp); | |
| 405 | + } else { | |
| 406 | + this._get(o, cb); | |
| 407 | + } | |
| 408 | + }, | |
| 409 | + cancel: function() { | |
| 410 | + this.cancelled = true; | |
| 411 | + } | |
| 412 | + }); | |
| 413 | + return Transport; | |
| 414 | + }(); | |
| 415 | + var SearchIndex = window.SearchIndex = function() { | |
| 416 | + "use strict"; | |
| 417 | + var CHILDREN = "c", IDS = "i"; | |
| 418 | + function SearchIndex(o) { | |
| 419 | + o = o || {}; | |
| 420 | + if (!o.datumTokenizer || !o.queryTokenizer) { | |
| 421 | + $.error("datumTokenizer and queryTokenizer are both required"); | |
| 422 | + } | |
| 423 | + this.identify = o.identify || _.stringify; | |
| 424 | + this.datumTokenizer = o.datumTokenizer; | |
| 425 | + this.queryTokenizer = o.queryTokenizer; | |
| 426 | + this.reset(); | |
| 427 | + } | |
| 428 | + _.mixin(SearchIndex.prototype, { | |
| 429 | + bootstrap: function bootstrap(o) { | |
| 430 | + this.datums = o.datums; | |
| 431 | + this.trie = o.trie; | |
| 432 | + }, | |
| 433 | + add: function(data) { | |
| 434 | + var that = this; | |
| 435 | + data = _.isArray(data) ? data : [ data ]; | |
| 436 | + _.each(data, function(datum) { | |
| 437 | + var id, tokens; | |
| 438 | + that.datums[id = that.identify(datum)] = datum; | |
| 439 | + tokens = normalizeTokens(that.datumTokenizer(datum)); | |
| 440 | + _.each(tokens, function(token) { | |
| 441 | + var node, chars, ch; | |
| 442 | + node = that.trie; | |
| 443 | + chars = token.split(""); | |
| 444 | + while (ch = chars.shift()) { | |
| 445 | + node = node[CHILDREN][ch] || (node[CHILDREN][ch] = newNode()); | |
| 446 | + node[IDS].push(id); | |
| 447 | + } | |
| 448 | + }); | |
| 449 | + }); | |
| 450 | + }, | |
| 451 | + get: function get(ids) { | |
| 452 | + var that = this; | |
| 453 | + return _.map(ids, function(id) { | |
| 454 | + return that.datums[id]; | |
| 455 | + }); | |
| 456 | + }, | |
| 457 | + search: function search(query) { | |
| 458 | + var that = this, tokens, matches; | |
| 459 | + tokens = normalizeTokens(this.queryTokenizer(query)); | |
| 460 | + _.each(tokens, function(token) { | |
| 461 | + var node, chars, ch, ids; | |
| 462 | + if (matches && matches.length === 0) { | |
| 463 | + return false; | |
| 464 | + } | |
| 465 | + node = that.trie; | |
| 466 | + chars = token.split(""); | |
| 467 | + while (node && (ch = chars.shift())) { | |
| 468 | + node = node[CHILDREN][ch]; | |
| 469 | + } | |
| 470 | + if (node && chars.length === 0) { | |
| 471 | + ids = node[IDS].slice(0); | |
| 472 | + matches = matches ? getIntersection(matches, ids) : ids; | |
| 473 | + } else { | |
| 474 | + matches = []; | |
| 475 | + return false; | |
| 476 | + } | |
| 477 | + }); | |
| 478 | + return matches ? _.map(unique(matches), function(id) { | |
| 479 | + return that.datums[id]; | |
| 480 | + }) : []; | |
| 481 | + }, | |
| 482 | + all: function all() { | |
| 483 | + var values = []; | |
| 484 | + for (var key in this.datums) { | |
| 485 | + values.push(this.datums[key]); | |
| 486 | + } | |
| 487 | + return values; | |
| 488 | + }, | |
| 489 | + reset: function reset() { | |
| 490 | + this.datums = {}; | |
| 491 | + this.trie = newNode(); | |
| 492 | + }, | |
| 493 | + serialize: function serialize() { | |
| 494 | + return { | |
| 495 | + datums: this.datums, | |
| 496 | + trie: this.trie | |
| 497 | + }; | |
| 498 | + } | |
| 499 | + }); | |
| 500 | + return SearchIndex; | |
| 501 | + function normalizeTokens(tokens) { | |
| 502 | + tokens = _.filter(tokens, function(token) { | |
| 503 | + return !!token; | |
| 504 | + }); | |
| 505 | + tokens = _.map(tokens, function(token) { | |
| 506 | + return token.toLowerCase(); | |
| 507 | + }); | |
| 508 | + return tokens; | |
| 509 | + } | |
| 510 | + function newNode() { | |
| 511 | + var node = {}; | |
| 512 | + node[IDS] = []; | |
| 513 | + node[CHILDREN] = {}; | |
| 514 | + return node; | |
| 515 | + } | |
| 516 | + function unique(array) { | |
| 517 | + var seen = {}, uniques = []; | |
| 518 | + for (var i = 0, len = array.length; i < len; i++) { | |
| 519 | + if (!seen[array[i]]) { | |
| 520 | + seen[array[i]] = true; | |
| 521 | + uniques.push(array[i]); | |
| 522 | + } | |
| 523 | + } | |
| 524 | + return uniques; | |
| 525 | + } | |
| 526 | + function getIntersection(arrayA, arrayB) { | |
| 527 | + var ai = 0, bi = 0, intersection = []; | |
| 528 | + arrayA = arrayA.sort(); | |
| 529 | + arrayB = arrayB.sort(); | |
| 530 | + var lenArrayA = arrayA.length, lenArrayB = arrayB.length; | |
| 531 | + while (ai < lenArrayA && bi < lenArrayB) { | |
| 532 | + if (arrayA[ai] < arrayB[bi]) { | |
| 533 | + ai++; | |
| 534 | + } else if (arrayA[ai] > arrayB[bi]) { | |
| 535 | + bi++; | |
| 536 | + } else { | |
| 537 | + intersection.push(arrayA[ai]); | |
| 538 | + ai++; | |
| 539 | + bi++; | |
| 540 | + } | |
| 541 | + } | |
| 542 | + return intersection; | |
| 543 | + } | |
| 544 | + }(); | |
| 545 | + var Prefetch = function() { | |
| 546 | + "use strict"; | |
| 547 | + var keys; | |
| 548 | + keys = { | |
| 549 | + data: "data", | |
| 550 | + protocol: "protocol", | |
| 551 | + thumbprint: "thumbprint" | |
| 552 | + }; | |
| 553 | + function Prefetch(o) { | |
| 554 | + this.url = o.url; | |
| 555 | + this.ttl = o.ttl; | |
| 556 | + this.cache = o.cache; | |
| 557 | + this.prepare = o.prepare; | |
| 558 | + this.transform = o.transform; | |
| 559 | + this.transport = o.transport; | |
| 560 | + this.thumbprint = o.thumbprint; | |
| 561 | + this.storage = new PersistentStorage(o.cacheKey); | |
| 562 | + } | |
| 563 | + _.mixin(Prefetch.prototype, { | |
| 564 | + _settings: function settings() { | |
| 565 | + return { | |
| 566 | + url: this.url, | |
| 567 | + type: "GET", | |
| 568 | + dataType: "json" | |
| 569 | + }; | |
| 570 | + }, | |
| 571 | + store: function store(data) { | |
| 572 | + if (!this.cache) { | |
| 573 | + return; | |
| 574 | + } | |
| 575 | + this.storage.set(keys.data, data, this.ttl); | |
| 576 | + this.storage.set(keys.protocol, location.protocol, this.ttl); | |
| 577 | + this.storage.set(keys.thumbprint, this.thumbprint, this.ttl); | |
| 578 | + }, | |
| 579 | + fromCache: function fromCache() { | |
| 580 | + var stored = {}, isExpired; | |
| 581 | + if (!this.cache) { | |
| 582 | + return null; | |
| 583 | + } | |
| 584 | + stored.data = this.storage.get(keys.data); | |
| 585 | + stored.protocol = this.storage.get(keys.protocol); | |
| 586 | + stored.thumbprint = this.storage.get(keys.thumbprint); | |
| 587 | + isExpired = stored.thumbprint !== this.thumbprint || stored.protocol !== location.protocol; | |
| 588 | + return stored.data && !isExpired ? stored.data : null; | |
| 589 | + }, | |
| 590 | + fromNetwork: function(cb) { | |
| 591 | + var that = this, settings; | |
| 592 | + if (!cb) { | |
| 593 | + return; | |
| 594 | + } | |
| 595 | + settings = this.prepare(this._settings()); | |
| 596 | + this.transport(settings).fail(onError).done(onResponse); | |
| 597 | + function onError() { | |
| 598 | + cb(true); | |
| 599 | + } | |
| 600 | + function onResponse(resp) { | |
| 601 | + cb(null, that.transform(resp)); | |
| 602 | + } | |
| 603 | + }, | |
| 604 | + clear: function clear() { | |
| 605 | + this.storage.clear(); | |
| 606 | + return this; | |
| 607 | + } | |
| 608 | + }); | |
| 609 | + return Prefetch; | |
| 610 | + }(); | |
| 611 | + var Remote = function() { | |
| 612 | + "use strict"; | |
| 613 | + function Remote(o) { | |
| 614 | + this.url = o.url; | |
| 615 | + this.prepare = o.prepare; | |
| 616 | + this.transform = o.transform; | |
| 617 | + this.transport = new Transport({ | |
| 618 | + cache: o.cache, | |
| 619 | + limiter: o.limiter, | |
| 620 | + transport: o.transport | |
| 621 | + }); | |
| 622 | + } | |
| 623 | + _.mixin(Remote.prototype, { | |
| 624 | + _settings: function settings() { | |
| 625 | + return { | |
| 626 | + url: this.url, | |
| 627 | + type: "GET", | |
| 628 | + dataType: "json" | |
| 629 | + }; | |
| 630 | + }, | |
| 631 | + get: function get(query, cb) { | |
| 632 | + var that = this, settings; | |
| 633 | + if (!cb) { | |
| 634 | + return; | |
| 635 | + } | |
| 636 | + query = query || ""; | |
| 637 | + settings = this.prepare(query, this._settings()); | |
| 638 | + return this.transport.get(settings, onResponse); | |
| 639 | + function onResponse(err, resp) { | |
| 640 | + err ? cb([]) : cb(that.transform(resp)); | |
| 641 | + } | |
| 642 | + }, | |
| 643 | + cancelLastRequest: function cancelLastRequest() { | |
| 644 | + this.transport.cancel(); | |
| 645 | + } | |
| 646 | + }); | |
| 647 | + return Remote; | |
| 648 | + }(); | |
| 649 | + var oParser = function() { | |
| 650 | + "use strict"; | |
| 651 | + return function parse(o) { | |
| 652 | + var defaults, sorter; | |
| 653 | + defaults = { | |
| 654 | + initialize: true, | |
| 655 | + identify: _.stringify, | |
| 656 | + datumTokenizer: null, | |
| 657 | + queryTokenizer: null, | |
| 658 | + sufficient: 5, | |
| 659 | + sorter: null, | |
| 660 | + local: [], | |
| 661 | + prefetch: null, | |
| 662 | + remote: null | |
| 663 | + }; | |
| 664 | + o = _.mixin(defaults, o || {}); | |
| 665 | + !o.datumTokenizer && $.error("datumTokenizer is required"); | |
| 666 | + !o.queryTokenizer && $.error("queryTokenizer is required"); | |
| 667 | + sorter = o.sorter; | |
| 668 | + o.sorter = sorter ? function(x) { | |
| 669 | + return x.sort(sorter); | |
| 670 | + } : _.identity; | |
| 671 | + o.local = _.isFunction(o.local) ? o.local() : o.local; | |
| 672 | + o.prefetch = parsePrefetch(o.prefetch); | |
| 673 | + o.remote = parseRemote(o.remote); | |
| 674 | + return o; | |
| 675 | + }; | |
| 676 | + function parsePrefetch(o) { | |
| 677 | + var defaults; | |
| 678 | + if (!o) { | |
| 679 | + return null; | |
| 680 | + } | |
| 681 | + defaults = { | |
| 682 | + url: null, | |
| 683 | + ttl: 24 * 60 * 60 * 1e3, | |
| 684 | + cache: true, | |
| 685 | + cacheKey: null, | |
| 686 | + thumbprint: "", | |
| 687 | + prepare: _.identity, | |
| 688 | + transform: _.identity, | |
| 689 | + transport: null | |
| 690 | + }; | |
| 691 | + o = _.isString(o) ? { | |
| 692 | + url: o | |
| 693 | + } : o; | |
| 694 | + o = _.mixin(defaults, o); | |
| 695 | + !o.url && $.error("prefetch requires url to be set"); | |
| 696 | + o.transform = o.filter || o.transform; | |
| 697 | + o.cacheKey = o.cacheKey || o.url; | |
| 698 | + o.thumbprint = VERSION + o.thumbprint; | |
| 699 | + o.transport = o.transport ? callbackToDeferred(o.transport) : $.ajax; | |
| 700 | + return o; | |
| 701 | + } | |
| 702 | + function parseRemote(o) { | |
| 703 | + var defaults; | |
| 704 | + if (!o) { | |
| 705 | + return; | |
| 706 | + } | |
| 707 | + defaults = { | |
| 708 | + url: null, | |
| 709 | + cache: true, | |
| 710 | + prepare: null, | |
| 711 | + replace: null, | |
| 712 | + wildcard: null, | |
| 713 | + limiter: null, | |
| 714 | + rateLimitBy: "debounce", | |
| 715 | + rateLimitWait: 300, | |
| 716 | + transform: _.identity, | |
| 717 | + transport: null | |
| 718 | + }; | |
| 719 | + o = _.isString(o) ? { | |
| 720 | + url: o | |
| 721 | + } : o; | |
| 722 | + o = _.mixin(defaults, o); | |
| 723 | + !o.url && $.error("remote requires url to be set"); | |
| 724 | + o.transform = o.filter || o.transform; | |
| 725 | + o.prepare = toRemotePrepare(o); | |
| 726 | + o.limiter = toLimiter(o); | |
| 727 | + o.transport = o.transport ? callbackToDeferred(o.transport) : $.ajax; | |
| 728 | + delete o.replace; | |
| 729 | + delete o.wildcard; | |
| 730 | + delete o.rateLimitBy; | |
| 731 | + delete o.rateLimitWait; | |
| 732 | + return o; | |
| 733 | + } | |
| 734 | + function toRemotePrepare(o) { | |
| 735 | + var prepare, replace, wildcard; | |
| 736 | + prepare = o.prepare; | |
| 737 | + replace = o.replace; | |
| 738 | + wildcard = o.wildcard; | |
| 739 | + if (prepare) { | |
| 740 | + return prepare; | |
| 741 | + } | |
| 742 | + if (replace) { | |
| 743 | + prepare = prepareByReplace; | |
| 744 | + } else if (o.wildcard) { | |
| 745 | + prepare = prepareByWildcard; | |
| 746 | + } else { | |
| 747 | + prepare = idenityPrepare; | |
| 748 | + } | |
| 749 | + return prepare; | |
| 750 | + function prepareByReplace(query, settings) { | |
| 751 | + settings.url = replace(settings.url, query); | |
| 752 | + return settings; | |
| 753 | + } | |
| 754 | + function prepareByWildcard(query, settings) { | |
| 755 | + settings.url = settings.url.replace(wildcard, encodeURIComponent(query)); | |
| 756 | + return settings; | |
| 757 | + } | |
| 758 | + function idenityPrepare(query, settings) { | |
| 759 | + return settings; | |
| 760 | + } | |
| 761 | + } | |
| 762 | + function toLimiter(o) { | |
| 763 | + var limiter, method, wait; | |
| 764 | + limiter = o.limiter; | |
| 765 | + method = o.rateLimitBy; | |
| 766 | + wait = o.rateLimitWait; | |
| 767 | + if (!limiter) { | |
| 768 | + limiter = /^throttle$/i.test(method) ? throttle(wait) : debounce(wait); | |
| 769 | + } | |
| 770 | + return limiter; | |
| 771 | + function debounce(wait) { | |
| 772 | + return function debounce(fn) { | |
| 773 | + return _.debounce(fn, wait); | |
| 774 | + }; | |
| 775 | + } | |
| 776 | + function throttle(wait) { | |
| 777 | + return function throttle(fn) { | |
| 778 | + return _.throttle(fn, wait); | |
| 779 | + }; | |
| 780 | + } | |
| 781 | + } | |
| 782 | + function callbackToDeferred(fn) { | |
| 783 | + return function wrapper(o) { | |
| 784 | + var deferred = $.Deferred(); | |
| 785 | + fn(o, onSuccess, onError); | |
| 786 | + return deferred; | |
| 787 | + function onSuccess(resp) { | |
| 788 | + _.defer(function() { | |
| 789 | + deferred.resolve(resp); | |
| 790 | + }); | |
| 791 | + } | |
| 792 | + function onError(err) { | |
| 793 | + _.defer(function() { | |
| 794 | + deferred.reject(err); | |
| 795 | + }); | |
| 796 | + } | |
| 797 | + }; | |
| 798 | + } | |
| 799 | + }(); | |
| 800 | + var Bloodhound = function() { | |
| 801 | + "use strict"; | |
| 802 | + var old; | |
| 803 | + old = window && window.Bloodhound; | |
| 804 | + function Bloodhound(o) { | |
| 805 | + o = oParser(o); | |
| 806 | + this.sorter = o.sorter; | |
| 807 | + this.identify = o.identify; | |
| 808 | + this.sufficient = o.sufficient; | |
| 809 | + this.local = o.local; | |
| 810 | + this.remote = o.remote ? new Remote(o.remote) : null; | |
| 811 | + this.prefetch = o.prefetch ? new Prefetch(o.prefetch) : null; | |
| 812 | + this.index = new SearchIndex({ | |
| 813 | + identify: this.identify, | |
| 814 | + datumTokenizer: o.datumTokenizer, | |
| 815 | + queryTokenizer: o.queryTokenizer | |
| 816 | + }); | |
| 817 | + o.initialize !== false && this.initialize(); | |
| 818 | + } | |
| 819 | + Bloodhound.noConflict = function noConflict() { | |
| 820 | + window && (window.Bloodhound = old); | |
| 821 | + return Bloodhound; | |
| 822 | + }; | |
| 823 | + Bloodhound.tokenizers = tokenizers; | |
| 824 | + _.mixin(Bloodhound.prototype, { | |
| 825 | + __ttAdapter: function ttAdapter() { | |
| 826 | + var that = this; | |
| 827 | + return this.remote ? withAsync : withoutAsync; | |
| 828 | + function withAsync(query, sync, async) { | |
| 829 | + return that.search(query, sync, async); | |
| 830 | + } | |
| 831 | + function withoutAsync(query, sync) { | |
| 832 | + return that.search(query, sync); | |
| 833 | + } | |
| 834 | + }, | |
| 835 | + _loadPrefetch: function loadPrefetch() { | |
| 836 | + var that = this, deferred, serialized; | |
| 837 | + deferred = $.Deferred(); | |
| 838 | + if (!this.prefetch) { | |
| 839 | + deferred.resolve(); | |
| 840 | + } else if (serialized = this.prefetch.fromCache()) { | |
| 841 | + this.index.bootstrap(serialized); | |
| 842 | + deferred.resolve(); | |
| 843 | + } else { | |
| 844 | + this.prefetch.fromNetwork(done); | |
| 845 | + } | |
| 846 | + return deferred.promise(); | |
| 847 | + function done(err, data) { | |
| 848 | + if (err) { | |
| 849 | + return deferred.reject(); | |
| 850 | + } | |
| 851 | + that.add(data); | |
| 852 | + that.prefetch.store(that.index.serialize()); | |
| 853 | + deferred.resolve(); | |
| 854 | + } | |
| 855 | + }, | |
| 856 | + _initialize: function initialize() { | |
| 857 | + var that = this, deferred; | |
| 858 | + this.clear(); | |
| 859 | + (this.initPromise = this._loadPrefetch()).done(addLocalToIndex); | |
| 860 | + return this.initPromise; | |
| 861 | + function addLocalToIndex() { | |
| 862 | + that.add(that.local); | |
| 863 | + } | |
| 864 | + }, | |
| 865 | + initialize: function initialize(force) { | |
| 866 | + return !this.initPromise || force ? this._initialize() : this.initPromise; | |
| 867 | + }, | |
| 868 | + add: function add(data) { | |
| 869 | + this.index.add(data); | |
| 870 | + return this; | |
| 871 | + }, | |
| 872 | + get: function get(ids) { | |
| 873 | + ids = _.isArray(ids) ? ids : [].slice.call(arguments); | |
| 874 | + return this.index.get(ids); | |
| 875 | + }, | |
| 876 | + search: function search(query, sync, async) { | |
| 877 | + var that = this, local; | |
| 878 | + local = this.sorter(this.index.search(query)); | |
| 879 | + sync(this.remote ? local.slice() : local); | |
| 880 | + if (this.remote && local.length < this.sufficient) { | |
| 881 | + this.remote.get(query, processRemote); | |
| 882 | + } else if (this.remote) { | |
| 883 | + this.remote.cancelLastRequest(); | |
| 884 | + } | |
| 885 | + return this; | |
| 886 | + function processRemote(remote) { | |
| 887 | + var nonDuplicates = []; | |
| 888 | + _.each(remote, function(r) { | |
| 889 | + !_.some(local, function(l) { | |
| 890 | + return that.identify(r) === that.identify(l); | |
| 891 | + }) && nonDuplicates.push(r); | |
| 892 | + }); | |
| 893 | + async && async(nonDuplicates); | |
| 894 | + } | |
| 895 | + }, | |
| 896 | + all: function all() { | |
| 897 | + return this.index.all(); | |
| 898 | + }, | |
| 899 | + clear: function clear() { | |
| 900 | + this.index.reset(); | |
| 901 | + return this; | |
| 902 | + }, | |
| 903 | + clearPrefetchCache: function clearPrefetchCache() { | |
| 904 | + this.prefetch && this.prefetch.clear(); | |
| 905 | + return this; | |
| 906 | + }, | |
| 907 | + clearRemoteCache: function clearRemoteCache() { | |
| 908 | + Transport.resetCache(); | |
| 909 | + return this; | |
| 910 | + }, | |
| 911 | + ttAdapter: function ttAdapter() { | |
| 912 | + return this.__ttAdapter(); | |
| 913 | + } | |
| 914 | + }); | |
| 915 | + return Bloodhound; | |
| 916 | + }(); | |
| 917 | + return Bloodhound; | |
| 918 | +}); | |
| 919 | + | |
| 920 | +(function(root, factory) { | |
| 921 | + if (typeof define === "function" && define.amd) { | |
| 922 | + define("typeahead.js", [ "jquery" ], function(a0) { | |
| 923 | + return factory(a0); | |
| 924 | + }); | |
| 925 | + } else if (typeof exports === "object") { | |
| 926 | + module.exports = factory(require("jquery")); | |
| 927 | + } else { | |
| 928 | + factory(jQuery); | |
| 929 | + } | |
| 930 | +})(this, function($) { | |
| 931 | + var _ = function() { | |
| 932 | + "use strict"; | |
| 933 | + return { | |
| 934 | + isMsie: function() { | |
| 935 | + return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false; | |
| 936 | + }, | |
| 937 | + isBlankString: function(str) { | |
| 938 | + return !str || /^\s*$/.test(str); | |
| 939 | + }, | |
| 940 | + escapeRegExChars: function(str) { | |
| 941 | + return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); | |
| 942 | + }, | |
| 943 | + isString: function(obj) { | |
| 944 | + return typeof obj === "string"; | |
| 945 | + }, | |
| 946 | + isNumber: function(obj) { | |
| 947 | + return typeof obj === "number"; | |
| 948 | + }, | |
| 949 | + isArray: $.isArray, | |
| 950 | + isFunction: $.isFunction, | |
| 951 | + isObject: $.isPlainObject, | |
| 952 | + isUndefined: function(obj) { | |
| 953 | + return typeof obj === "undefined"; | |
| 954 | + }, | |
| 955 | + isElement: function(obj) { | |
| 956 | + return !!(obj && obj.nodeType === 1); | |
| 957 | + }, | |
| 958 | + isJQuery: function(obj) { | |
| 959 | + return obj instanceof $; | |
| 960 | + }, | |
| 961 | + toStr: function toStr(s) { | |
| 962 | + return _.isUndefined(s) || s === null ? "" : s + ""; | |
| 963 | + }, | |
| 964 | + bind: $.proxy, | |
| 965 | + each: function(collection, cb) { | |
| 966 | + $.each(collection, reverseArgs); | |
| 967 | + function reverseArgs(index, value) { | |
| 968 | + return cb(value, index); | |
| 969 | + } | |
| 970 | + }, | |
| 971 | + map: $.map, | |
| 972 | + filter: $.grep, | |
| 973 | + every: function(obj, test) { | |
| 974 | + var result = true; | |
| 975 | + if (!obj) { | |
| 976 | + return result; | |
| 977 | + } | |
| 978 | + $.each(obj, function(key, val) { | |
| 979 | + if (!(result = test.call(null, val, key, obj))) { | |
| 980 | + return false; | |
| 981 | + } | |
| 982 | + }); | |
| 983 | + return !!result; | |
| 984 | + }, | |
| 985 | + some: function(obj, test) { | |
| 986 | + var result = false; | |
| 987 | + if (!obj) { | |
| 988 | + return result; | |
| 989 | + } | |
| 990 | + $.each(obj, function(key, val) { | |
| 991 | + if (result = test.call(null, val, key, obj)) { | |
| 992 | + return false; | |
| 993 | + } | |
| 994 | + }); | |
| 995 | + return !!result; | |
| 996 | + }, | |
| 997 | + mixin: $.extend, | |
| 998 | + identity: function(x) { | |
| 999 | + return x; | |
| 1000 | + }, | |
| 1001 | + clone: function(obj) { | |
| 1002 | + return $.extend(true, {}, obj); | |
| 1003 | + }, | |
| 1004 | + getIdGenerator: function() { | |
| 1005 | + var counter = 0; | |
| 1006 | + return function() { | |
| 1007 | + return counter++; | |
| 1008 | + }; | |
| 1009 | + }, | |
| 1010 | + templatify: function templatify(obj) { | |
| 1011 | + return $.isFunction(obj) ? obj : template; | |
| 1012 | + function template() { | |
| 1013 | + return String(obj); | |
| 1014 | + } | |
| 1015 | + }, | |
| 1016 | + defer: function(fn) { | |
| 1017 | + setTimeout(fn, 0); | |
| 1018 | + }, | |
| 1019 | + debounce: function(func, wait, immediate) { | |
| 1020 | + var timeout, result; | |
| 1021 | + return function() { | |
| 1022 | + var context = this, args = arguments, later, callNow; | |
| 1023 | + later = function() { | |
| 1024 | + timeout = null; | |
| 1025 | + if (!immediate) { | |
| 1026 | + result = func.apply(context, args); | |
| 1027 | + } | |
| 1028 | + }; | |
| 1029 | + callNow = immediate && !timeout; | |
| 1030 | + clearTimeout(timeout); | |
| 1031 | + timeout = setTimeout(later, wait); | |
| 1032 | + if (callNow) { | |
| 1033 | + result = func.apply(context, args); | |
| 1034 | + } | |
| 1035 | + return result; | |
| 1036 | + }; | |
| 1037 | + }, | |
| 1038 | + throttle: function(func, wait) { | |
| 1039 | + var context, args, timeout, result, previous, later; | |
| 1040 | + previous = 0; | |
| 1041 | + later = function() { | |
| 1042 | + previous = new Date(); | |
| 1043 | + timeout = null; | |
| 1044 | + result = func.apply(context, args); | |
| 1045 | + }; | |
| 1046 | + return function() { | |
| 1047 | + var now = new Date(), remaining = wait - (now - previous); | |
| 1048 | + context = this; | |
| 1049 | + args = arguments; | |
| 1050 | + if (remaining <= 0) { | |
| 1051 | + clearTimeout(timeout); | |
| 1052 | + timeout = null; | |
| 1053 | + previous = now; | |
| 1054 | + result = func.apply(context, args); | |
| 1055 | + } else if (!timeout) { | |
| 1056 | + timeout = setTimeout(later, remaining); | |
| 1057 | + } | |
| 1058 | + return result; | |
| 1059 | + }; | |
| 1060 | + }, | |
| 1061 | + stringify: function(val) { | |
| 1062 | + return _.isString(val) ? val : JSON.stringify(val); | |
| 1063 | + }, | |
| 1064 | + noop: function() {} | |
| 1065 | + }; | |
| 1066 | + }(); | |
| 1067 | + var WWW = function() { | |
| 1068 | + "use strict"; | |
| 1069 | + var defaultClassNames = { | |
| 1070 | + wrapper: "twitter-typeahead", | |
| 1071 | + input: "tt-input", | |
| 1072 | + hint: "tt-hint", | |
| 1073 | + menu: "tt-menu", | |
| 1074 | + dataset: "tt-dataset", | |
| 1075 | + suggestion: "tt-suggestion", | |
| 1076 | + selectable: "tt-selectable", | |
| 1077 | + empty: "tt-empty", | |
| 1078 | + open: "tt-open", | |
| 1079 | + cursor: "tt-cursor", | |
| 1080 | + highlight: "tt-highlight" | |
| 1081 | + }; | |
| 1082 | + return build; | |
| 1083 | + function build(o) { | |
| 1084 | + var www, classes; | |
| 1085 | + classes = _.mixin({}, defaultClassNames, o); | |
| 1086 | + www = { | |
| 1087 | + css: buildCss(), | |
| 1088 | + classes: classes, | |
| 1089 | + html: buildHtml(classes), | |
| 1090 | + selectors: buildSelectors(classes) | |
| 1091 | + }; | |
| 1092 | + return { | |
| 1093 | + css: www.css, | |
| 1094 | + html: www.html, | |
| 1095 | + classes: www.classes, | |
| 1096 | + selectors: www.selectors, | |
| 1097 | + mixin: function(o) { | |
| 1098 | + _.mixin(o, www); | |
| 1099 | + } | |
| 1100 | + }; | |
| 1101 | + } | |
| 1102 | + function buildHtml(c) { | |
| 1103 | + return { | |
| 1104 | + wrapper: '<span class="' + c.wrapper + '"></span>', | |
| 1105 | + menu: '<div class="' + c.menu + '"></div>' | |
| 1106 | + }; | |
| 1107 | + } | |
| 1108 | + function buildSelectors(classes) { | |
| 1109 | + var selectors = {}; | |
| 1110 | + _.each(classes, function(v, k) { | |
| 1111 | + selectors[k] = "." + v; | |
| 1112 | + }); | |
| 1113 | + return selectors; | |
| 1114 | + } | |
| 1115 | + function buildCss() { | |
| 1116 | + var css = { | |
| 1117 | + wrapper: { | |
| 1118 | + position: "relative", | |
| 1119 | + display: "inline-block" | |
| 1120 | + }, | |
| 1121 | + hint: { | |
| 1122 | + position: "absolute", | |
| 1123 | + top: "0", | |
| 1124 | + left: "0", | |
| 1125 | + borderColor: "transparent", | |
| 1126 | + boxShadow: "none", | |
| 1127 | + opacity: "1" | |
| 1128 | + }, | |
| 1129 | + input: { | |
| 1130 | + position: "relative", | |
| 1131 | + verticalAlign: "top", | |
| 1132 | + backgroundColor: "transparent" | |
| 1133 | + }, | |
| 1134 | + inputWithNoHint: { | |
| 1135 | + position: "relative", | |
| 1136 | + verticalAlign: "top" | |
| 1137 | + }, | |
| 1138 | + menu: { | |
| 1139 | + position: "absolute", | |
| 1140 | + top: "100%", | |
| 1141 | + left: "0", | |
| 1142 | + zIndex: "100", | |
| 1143 | + display: "none" | |
| 1144 | + }, | |
| 1145 | + ltr: { | |
| 1146 | + left: "0", | |
| 1147 | + right: "auto" | |
| 1148 | + }, | |
| 1149 | + rtl: { | |
| 1150 | + left: "auto", | |
| 1151 | + right: " 0" | |
| 1152 | + } | |
| 1153 | + }; | |
| 1154 | + if (_.isMsie()) { | |
| 1155 | + _.mixin(css.input, { | |
| 1156 | + backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)" | |
| 1157 | + }); | |
| 1158 | + } | |
| 1159 | + return css; | |
| 1160 | + } | |
| 1161 | + }(); | |
| 1162 | + var EventBus = function() { | |
| 1163 | + "use strict"; | |
| 1164 | + var namespace, deprecationMap; | |
| 1165 | + namespace = "typeahead:"; | |
| 1166 | + deprecationMap = { | |
| 1167 | + render: "rendered", | |
| 1168 | + cursorchange: "cursorchanged", | |
| 1169 | + select: "selected", | |
| 1170 | + autocomplete: "autocompleted" | |
| 1171 | + }; | |
| 1172 | + function EventBus(o) { | |
| 1173 | + if (!o || !o.el) { | |
| 1174 | + $.error("EventBus initialized without el"); | |
| 1175 | + } | |
| 1176 | + this.$el = $(o.el); | |
| 1177 | + } | |
| 1178 | + _.mixin(EventBus.prototype, { | |
| 1179 | + _trigger: function(type, args) { | |
| 1180 | + var $e; | |
| 1181 | + $e = $.Event(namespace + type); | |
| 1182 | + (args = args || []).unshift($e); | |
| 1183 | + this.$el.trigger.apply(this.$el, args); | |
| 1184 | + return $e; | |
| 1185 | + }, | |
| 1186 | + before: function(type) { | |
| 1187 | + var args, $e; | |
| 1188 | + args = [].slice.call(arguments, 1); | |
| 1189 | + $e = this._trigger("before" + type, args); | |
| 1190 | + return $e.isDefaultPrevented(); | |
| 1191 | + }, | |
| 1192 | + trigger: function(type) { | |
| 1193 | + var deprecatedType; | |
| 1194 | + this._trigger(type, [].slice.call(arguments, 1)); | |
| 1195 | + if (deprecatedType = deprecationMap[type]) { | |
| 1196 | + this._trigger(deprecatedType, [].slice.call(arguments, 1)); | |
| 1197 | + } | |
| 1198 | + } | |
| 1199 | + }); | |
| 1200 | + return EventBus; | |
| 1201 | + }(); | |
| 1202 | + var EventEmitter = function() { | |
| 1203 | + "use strict"; | |
| 1204 | + var splitter = /\s+/, nextTick = getNextTick(); | |
| 1205 | + return { | |
| 1206 | + onSync: onSync, | |
| 1207 | + onAsync: onAsync, | |
| 1208 | + off: off, | |
| 1209 | + trigger: trigger | |
| 1210 | + }; | |
| 1211 | + function on(method, types, cb, context) { | |
| 1212 | + var type; | |
| 1213 | + if (!cb) { | |
| 1214 | + return this; | |
| 1215 | + } | |
| 1216 | + types = types.split(splitter); | |
| 1217 | + cb = context ? bindContext(cb, context) : cb; | |
| 1218 | + this._callbacks = this._callbacks || {}; | |
| 1219 | + while (type = types.shift()) { | |
| 1220 | + this._callbacks[type] = this._callbacks[type] || { | |
| 1221 | + sync: [], | |
| 1222 | + async: [] | |
| 1223 | + }; | |
| 1224 | + this._callbacks[type][method].push(cb); | |
| 1225 | + } | |
| 1226 | + return this; | |
| 1227 | + } | |
| 1228 | + function onAsync(types, cb, context) { | |
| 1229 | + return on.call(this, "async", types, cb, context); | |
| 1230 | + } | |
| 1231 | + function onSync(types, cb, context) { | |
| 1232 | + return on.call(this, "sync", types, cb, context); | |
| 1233 | + } | |
| 1234 | + function off(types) { | |
| 1235 | + var type; | |
| 1236 | + if (!this._callbacks) { | |
| 1237 | + return this; | |
| 1238 | + } | |
| 1239 | + types = types.split(splitter); | |
| 1240 | + while (type = types.shift()) { | |
| 1241 | + delete this._callbacks[type]; | |
| 1242 | + } | |
| 1243 | + return this; | |
| 1244 | + } | |
| 1245 | + function trigger(types) { | |
| 1246 | + var type, callbacks, args, syncFlush, asyncFlush; | |
| 1247 | + if (!this._callbacks) { | |
| 1248 | + return this; | |
| 1249 | + } | |
| 1250 | + types = types.split(splitter); | |
| 1251 | + args = [].slice.call(arguments, 1); | |
| 1252 | + while ((type = types.shift()) && (callbacks = this._callbacks[type])) { | |
| 1253 | + syncFlush = getFlush(callbacks.sync, this, [ type ].concat(args)); | |
| 1254 | + asyncFlush = getFlush(callbacks.async, this, [ type ].concat(args)); | |
| 1255 | + syncFlush() && nextTick(asyncFlush); | |
| 1256 | + } | |
| 1257 | + return this; | |
| 1258 | + } | |
| 1259 | + function getFlush(callbacks, context, args) { | |
| 1260 | + return flush; | |
| 1261 | + function flush() { | |
| 1262 | + var cancelled; | |
| 1263 | + for (var i = 0, len = callbacks.length; !cancelled && i < len; i += 1) { | |
| 1264 | + cancelled = callbacks[i].apply(context, args) === false; | |
| 1265 | + } | |
| 1266 | + return !cancelled; | |
| 1267 | + } | |
| 1268 | + } | |
| 1269 | + function getNextTick() { | |
| 1270 | + var nextTickFn; | |
| 1271 | + if (window.setImmediate) { | |
| 1272 | + nextTickFn = function nextTickSetImmediate(fn) { | |
| 1273 | + setImmediate(function() { | |
| 1274 | + fn(); | |
| 1275 | + }); | |
| 1276 | + }; | |
| 1277 | + } else { | |
| 1278 | + nextTickFn = function nextTickSetTimeout(fn) { | |
| 1279 | + setTimeout(function() { | |
| 1280 | + fn(); | |
| 1281 | + }, 0); | |
| 1282 | + }; | |
| 1283 | + } | |
| 1284 | + return nextTickFn; | |
| 1285 | + } | |
| 1286 | + function bindContext(fn, context) { | |
| 1287 | + return fn.bind ? fn.bind(context) : function() { | |
| 1288 | + fn.apply(context, [].slice.call(arguments, 0)); | |
| 1289 | + }; | |
| 1290 | + } | |
| 1291 | + }(); | |
| 1292 | + var highlight = function(doc) { | |
| 1293 | + "use strict"; | |
| 1294 | + var defaults = { | |
| 1295 | + node: null, | |
| 1296 | + pattern: null, | |
| 1297 | + tagName: "strong", | |
| 1298 | + className: null, | |
| 1299 | + wordsOnly: false, | |
| 1300 | + caseSensitive: false | |
| 1301 | + }; | |
| 1302 | + return function hightlight(o) { | |
| 1303 | + var regex; | |
| 1304 | + o = _.mixin({}, defaults, o); | |
| 1305 | + if (!o.node || !o.pattern) { | |
| 1306 | + return; | |
| 1307 | + } | |
| 1308 | + o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ]; | |
| 1309 | + regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly); | |
| 1310 | + traverse(o.node, hightlightTextNode); | |
| 1311 | + function hightlightTextNode(textNode) { | |
| 1312 | + var match, patternNode, wrapperNode; | |
| 1313 | + if (match = regex.exec(textNode.data)) { | |
| 1314 | + wrapperNode = doc.createElement(o.tagName); | |
| 1315 | + o.className && (wrapperNode.className = o.className); | |
| 1316 | + patternNode = textNode.splitText(match.index); | |
| 1317 | + patternNode.splitText(match[0].length); | |
| 1318 | + wrapperNode.appendChild(patternNode.cloneNode(true)); | |
| 1319 | + textNode.parentNode.replaceChild(wrapperNode, patternNode); | |
| 1320 | + } | |
| 1321 | + return !!match; | |
| 1322 | + } | |
| 1323 | + function traverse(el, hightlightTextNode) { | |
| 1324 | + var childNode, TEXT_NODE_TYPE = 3; | |
| 1325 | + for (var i = 0; i < el.childNodes.length; i++) { | |
| 1326 | + childNode = el.childNodes[i]; | |
| 1327 | + if (childNode.nodeType === TEXT_NODE_TYPE) { | |
| 1328 | + i += hightlightTextNode(childNode) ? 1 : 0; | |
| 1329 | + } else { | |
| 1330 | + traverse(childNode, hightlightTextNode); | |
| 1331 | + } | |
| 1332 | + } | |
| 1333 | + } | |
| 1334 | + }; | |
| 1335 | + function getRegex(patterns, caseSensitive, wordsOnly) { | |
| 1336 | + var escapedPatterns = [], regexStr; | |
| 1337 | + for (var i = 0, len = patterns.length; i < len; i++) { | |
| 1338 | + escapedPatterns.push(_.escapeRegExChars(patterns[i])); | |
| 1339 | + } | |
| 1340 | + regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")"; | |
| 1341 | + return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i"); | |
| 1342 | + } | |
| 1343 | + }(window.document); | |
| 1344 | + var Input = function() { | |
| 1345 | + "use strict"; | |
| 1346 | + var specialKeyCodeMap; | |
| 1347 | + specialKeyCodeMap = { | |
| 1348 | + 9: "tab", | |
| 1349 | + 27: "esc", | |
| 1350 | + 37: "left", | |
| 1351 | + 39: "right", | |
| 1352 | + 13: "enter", | |
| 1353 | + 38: "up", | |
| 1354 | + 40: "down" | |
| 1355 | + }; | |
| 1356 | + function Input(o, www) { | |
| 1357 | + o = o || {}; | |
| 1358 | + if (!o.input) { | |
| 1359 | + $.error("input is missing"); | |
| 1360 | + } | |
| 1361 | + www.mixin(this); | |
| 1362 | + this.$hint = $(o.hint); | |
| 1363 | + this.$input = $(o.input); | |
| 1364 | + this.query = this.$input.val(); | |
| 1365 | + this.queryWhenFocused = this.hasFocus() ? this.query : null; | |
| 1366 | + this.$overflowHelper = buildOverflowHelper(this.$input); | |
| 1367 | + this._checkLanguageDirection(); | |
| 1368 | + if (this.$hint.length === 0) { | |
| 1369 | + this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop; | |
| 1370 | + } | |
| 1371 | + } | |
| 1372 | + Input.normalizeQuery = function(str) { | |
| 1373 | + return _.toStr(str).replace(/^\s*/g, "").replace(/\s{2,}/g, " "); | |
| 1374 | + }; | |
| 1375 | + _.mixin(Input.prototype, EventEmitter, { | |
| 1376 | + _onBlur: function onBlur() { | |
| 1377 | + this.resetInputValue(); | |
| 1378 | + this.trigger("blurred"); | |
| 1379 | + }, | |
| 1380 | + _onFocus: function onFocus() { | |
| 1381 | + this.queryWhenFocused = this.query; | |
| 1382 | + this.trigger("focused"); | |
| 1383 | + }, | |
| 1384 | + _onKeydown: function onKeydown($e) { | |
| 1385 | + var keyName = specialKeyCodeMap[$e.which || $e.keyCode]; | |
| 1386 | + this._managePreventDefault(keyName, $e); | |
| 1387 | + if (keyName && this._shouldTrigger(keyName, $e)) { | |
| 1388 | + this.trigger(keyName + "Keyed", $e); | |
| 1389 | + } | |
| 1390 | + }, | |
| 1391 | + _onInput: function onInput() { | |
| 1392 | + this._setQuery(this.getInputValue()); | |
| 1393 | + this.clearHintIfInvalid(); | |
| 1394 | + this._checkLanguageDirection(); | |
| 1395 | + }, | |
| 1396 | + _managePreventDefault: function managePreventDefault(keyName, $e) { | |
| 1397 | + var preventDefault; | |
| 1398 | + switch (keyName) { | |
| 1399 | + case "up": | |
| 1400 | + case "down": | |
| 1401 | + preventDefault = !withModifier($e); | |
| 1402 | + break; | |
| 1403 | + | |
| 1404 | + default: | |
| 1405 | + preventDefault = false; | |
| 1406 | + } | |
| 1407 | + preventDefault && $e.preventDefault(); | |
| 1408 | + }, | |
| 1409 | + _shouldTrigger: function shouldTrigger(keyName, $e) { | |
| 1410 | + var trigger; | |
| 1411 | + switch (keyName) { | |
| 1412 | + case "tab": | |
| 1413 | + trigger = !withModifier($e); | |
| 1414 | + break; | |
| 1415 | + | |
| 1416 | + default: | |
| 1417 | + trigger = true; | |
| 1418 | + } | |
| 1419 | + return trigger; | |
| 1420 | + }, | |
| 1421 | + _checkLanguageDirection: function checkLanguageDirection() { | |
| 1422 | + var dir = (this.$input.css("direction") || "ltr").toLowerCase(); | |
| 1423 | + if (this.dir !== dir) { | |
| 1424 | + this.dir = dir; | |
| 1425 | + this.$hint.attr("dir", dir); | |
| 1426 | + this.trigger("langDirChanged", dir); | |
| 1427 | + } | |
| 1428 | + }, | |
| 1429 | + _setQuery: function setQuery(val, silent) { | |
| 1430 | + var areEquivalent, hasDifferentWhitespace; | |
| 1431 | + areEquivalent = areQueriesEquivalent(val, this.query); | |
| 1432 | + hasDifferentWhitespace = areEquivalent ? this.query.length !== val.length : false; | |
| 1433 | + this.query = val; | |
| 1434 | + if (!silent && !areEquivalent) { | |
| 1435 | + this.trigger("queryChanged", this.query); | |
| 1436 | + } else if (!silent && hasDifferentWhitespace) { | |
| 1437 | + this.trigger("whitespaceChanged", this.query); | |
| 1438 | + } | |
| 1439 | + }, | |
| 1440 | + bind: function() { | |
| 1441 | + var that = this, onBlur, onFocus, onKeydown, onInput; | |
| 1442 | + onBlur = _.bind(this._onBlur, this); | |
| 1443 | + onFocus = _.bind(this._onFocus, this); | |
| 1444 | + onKeydown = _.bind(this._onKeydown, this); | |
| 1445 | + onInput = _.bind(this._onInput, this); | |
| 1446 | + this.$input.on("blur.tt", onBlur).on("focus.tt", onFocus).on("keydown.tt", onKeydown); | |
| 1447 | + if (!_.isMsie() || _.isMsie() > 9) { | |
| 1448 | + this.$input.on("input.tt", onInput); | |
| 1449 | + } else { | |
| 1450 | + this.$input.on("keydown.tt keypress.tt cut.tt paste.tt", function($e) { | |
| 1451 | + if (specialKeyCodeMap[$e.which || $e.keyCode]) { | |
| 1452 | + return; | |
| 1453 | + } | |
| 1454 | + _.defer(_.bind(that._onInput, that, $e)); | |
| 1455 | + }); | |
| 1456 | + } | |
| 1457 | + return this; | |
| 1458 | + }, | |
| 1459 | + focus: function focus() { | |
| 1460 | + this.$input.focus(); | |
| 1461 | + }, | |
| 1462 | + blur: function blur() { | |
| 1463 | + this.$input.blur(); | |
| 1464 | + }, | |
| 1465 | + getLangDir: function getLangDir() { | |
| 1466 | + return this.dir; | |
| 1467 | + }, | |
| 1468 | + getQuery: function getQuery() { | |
| 1469 | + return this.query || ""; | |
| 1470 | + }, | |
| 1471 | + setQuery: function setQuery(val, silent) { | |
| 1472 | + this.setInputValue(val); | |
| 1473 | + this._setQuery(val, silent); | |
| 1474 | + }, | |
| 1475 | + hasQueryChangedSinceLastFocus: function hasQueryChangedSinceLastFocus() { | |
| 1476 | + return this.query !== this.queryWhenFocused; | |
| 1477 | + }, | |
| 1478 | + getInputValue: function getInputValue() { | |
| 1479 | + return this.$input.val(); | |
| 1480 | + }, | |
| 1481 | + setInputValue: function setInputValue(value) { | |
| 1482 | + this.$input.val(value); | |
| 1483 | + this.clearHintIfInvalid(); | |
| 1484 | + this._checkLanguageDirection(); | |
| 1485 | + }, | |
| 1486 | + resetInputValue: function resetInputValue() { | |
| 1487 | + this.setInputValue(this.query); | |
| 1488 | + }, | |
| 1489 | + getHint: function getHint() { | |
| 1490 | + return this.$hint.val(); | |
| 1491 | + }, | |
| 1492 | + setHint: function setHint(value) { | |
| 1493 | + this.$hint.val(value); | |
| 1494 | + }, | |
| 1495 | + clearHint: function clearHint() { | |
| 1496 | + this.setHint(""); | |
| 1497 | + }, | |
| 1498 | + clearHintIfInvalid: function clearHintIfInvalid() { | |
| 1499 | + var val, hint, valIsPrefixOfHint, isValid; | |
| 1500 | + val = this.getInputValue(); | |
| 1501 | + hint = this.getHint(); | |
| 1502 | + valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0; | |
| 1503 | + isValid = val !== "" && valIsPrefixOfHint && !this.hasOverflow(); | |
| 1504 | + !isValid && this.clearHint(); | |
| 1505 | + }, | |
| 1506 | + hasFocus: function hasFocus() { | |
| 1507 | + return this.$input.is(":focus"); | |
| 1508 | + }, | |
| 1509 | + hasOverflow: function hasOverflow() { | |
| 1510 | + var constraint = this.$input.width() - 2; | |
| 1511 | + this.$overflowHelper.text(this.getInputValue()); | |
| 1512 | + return this.$overflowHelper.width() >= constraint; | |
| 1513 | + }, | |
| 1514 | + isCursorAtEnd: function() { | |
| 1515 | + var valueLength, selectionStart, range; | |
| 1516 | + valueLength = this.$input.val().length; | |
| 1517 | + selectionStart = this.$input[0].selectionStart; | |
| 1518 | + if (_.isNumber(selectionStart)) { | |
| 1519 | + return selectionStart === valueLength; | |
| 1520 | + } else if (document.selection) { | |
| 1521 | + range = document.selection.createRange(); | |
| 1522 | + range.moveStart("character", -valueLength); | |
| 1523 | + return valueLength === range.text.length; | |
| 1524 | + } | |
| 1525 | + return true; | |
| 1526 | + }, | |
| 1527 | + destroy: function destroy() { | |
| 1528 | + this.$hint.off(".tt"); | |
| 1529 | + this.$input.off(".tt"); | |
| 1530 | + this.$overflowHelper.remove(); | |
| 1531 | + this.$hint = this.$input = this.$overflowHelper = $("<div>"); | |
| 1532 | + } | |
| 1533 | + }); | |
| 1534 | + return Input; | |
| 1535 | + function buildOverflowHelper($input) { | |
| 1536 | + return $('<pre aria-hidden="true"></pre>').css({ | |
| 1537 | + position: "absolute", | |
| 1538 | + visibility: "hidden", | |
| 1539 | + whiteSpace: "pre", | |
| 1540 | + fontFamily: $input.css("font-family"), | |
| 1541 | + fontSize: $input.css("font-size"), | |
| 1542 | + fontStyle: $input.css("font-style"), | |
| 1543 | + fontVariant: $input.css("font-variant"), | |
| 1544 | + fontWeight: $input.css("font-weight"), | |
| 1545 | + wordSpacing: $input.css("word-spacing"), | |
| 1546 | + letterSpacing: $input.css("letter-spacing"), | |
| 1547 | + textIndent: $input.css("text-indent"), | |
| 1548 | + textRendering: $input.css("text-rendering"), | |
| 1549 | + textTransform: $input.css("text-transform") | |
| 1550 | + }).insertAfter($input); | |
| 1551 | + } | |
| 1552 | + function areQueriesEquivalent(a, b) { | |
| 1553 | + return Input.normalizeQuery(a) === Input.normalizeQuery(b); | |
| 1554 | + } | |
| 1555 | + function withModifier($e) { | |
| 1556 | + return $e.altKey || $e.ctrlKey || $e.metaKey || $e.shiftKey; | |
| 1557 | + } | |
| 1558 | + }(); | |
| 1559 | + var Dataset = function() { | |
| 1560 | + "use strict"; | |
| 1561 | + var keys, nameGenerator; | |
| 1562 | + keys = { | |
| 1563 | + val: "tt-selectable-display", | |
| 1564 | + obj: "tt-selectable-object" | |
| 1565 | + }; | |
| 1566 | + nameGenerator = _.getIdGenerator(); | |
| 1567 | + function Dataset(o, www) { | |
| 1568 | + o = o || {}; | |
| 1569 | + o.templates = o.templates || {}; | |
| 1570 | + o.templates.notFound = o.templates.notFound || o.templates.empty; | |
| 1571 | + if (!o.source) { | |
| 1572 | + $.error("missing source"); | |
| 1573 | + } | |
| 1574 | + if (!o.node) { | |
| 1575 | + $.error("missing node"); | |
| 1576 | + } | |
| 1577 | + if (o.name && !isValidName(o.name)) { | |
| 1578 | + $.error("invalid dataset name: " + o.name); | |
| 1579 | + } | |
| 1580 | + www.mixin(this); | |
| 1581 | + this.highlight = !!o.highlight; | |
| 1582 | + this.name = o.name || nameGenerator(); | |
| 1583 | + this.limit = o.limit || 5; | |
| 1584 | + this.displayFn = getDisplayFn(o.display || o.displayKey); | |
| 1585 | + this.templates = getTemplates(o.templates, this.displayFn); | |
| 1586 | + this.source = o.source.__ttAdapter ? o.source.__ttAdapter() : o.source; | |
| 1587 | + this.async = _.isUndefined(o.async) ? this.source.length > 2 : !!o.async; | |
| 1588 | + this._resetLastSuggestion(); | |
| 1589 | + this.$el = $(o.node).addClass(this.classes.dataset).addClass(this.classes.dataset + "-" + this.name); | |
| 1590 | + } | |
| 1591 | + Dataset.extractData = function extractData(el) { | |
| 1592 | + var $el = $(el); | |
| 1593 | + if ($el.data(keys.obj)) { | |
| 1594 | + return { | |
| 1595 | + val: $el.data(keys.val) || "", | |
| 1596 | + obj: $el.data(keys.obj) || null | |
| 1597 | + }; | |
| 1598 | + } | |
| 1599 | + return null; | |
| 1600 | + }; | |
| 1601 | + _.mixin(Dataset.prototype, EventEmitter, { | |
| 1602 | + _overwrite: function overwrite(query, suggestions) { | |
| 1603 | + suggestions = suggestions || []; | |
| 1604 | + if (suggestions.length) { | |
| 1605 | + this._renderSuggestions(query, suggestions); | |
| 1606 | + } else if (this.async && this.templates.pending) { | |
| 1607 | + this._renderPending(query); | |
| 1608 | + } else if (!this.async && this.templates.notFound) { | |
| 1609 | + this._renderNotFound(query); | |
| 1610 | + } else { | |
| 1611 | + this._empty(); | |
| 1612 | + } | |
| 1613 | + this.trigger("rendered", this.name, suggestions, false); | |
| 1614 | + }, | |
| 1615 | + _append: function append(query, suggestions) { | |
| 1616 | + suggestions = suggestions || []; | |
| 1617 | + if (suggestions.length && this.$lastSuggestion.length) { | |
| 1618 | + this._appendSuggestions(query, suggestions); | |
| 1619 | + } else if (suggestions.length) { | |
| 1620 | + this._renderSuggestions(query, suggestions); | |
| 1621 | + } else if (!this.$lastSuggestion.length && this.templates.notFound) { | |
| 1622 | + this._renderNotFound(query); | |
| 1623 | + } | |
| 1624 | + this.trigger("rendered", this.name, suggestions, true); | |
| 1625 | + }, | |
| 1626 | + _renderSuggestions: function renderSuggestions(query, suggestions) { | |
| 1627 | + var $fragment; | |
| 1628 | + $fragment = this._getSuggestionsFragment(query, suggestions); | |
| 1629 | + this.$lastSuggestion = $fragment.children().last(); | |
| 1630 | + this.$el.html($fragment).prepend(this._getHeader(query, suggestions)).append(this._getFooter(query, suggestions)); | |
| 1631 | + }, | |
| 1632 | + _appendSuggestions: function appendSuggestions(query, suggestions) { | |
| 1633 | + var $fragment, $lastSuggestion; | |
| 1634 | + $fragment = this._getSuggestionsFragment(query, suggestions); | |
| 1635 | + $lastSuggestion = $fragment.children().last(); | |
| 1636 | + this.$lastSuggestion.after($fragment); | |
| 1637 | + this.$lastSuggestion = $lastSuggestion; | |
| 1638 | + }, | |
| 1639 | + _renderPending: function renderPending(query) { | |
| 1640 | + var template = this.templates.pending; | |
| 1641 | + this._resetLastSuggestion(); | |
| 1642 | + template && this.$el.html(template({ | |
| 1643 | + query: query, | |
| 1644 | + dataset: this.name | |
| 1645 | + })); | |
| 1646 | + }, | |
| 1647 | + _renderNotFound: function renderNotFound(query) { | |
| 1648 | + var template = this.templates.notFound; | |
| 1649 | + this._resetLastSuggestion(); | |
| 1650 | + template && this.$el.html(template({ | |
| 1651 | + query: query, | |
| 1652 | + dataset: this.name | |
| 1653 | + })); | |
| 1654 | + }, | |
| 1655 | + _empty: function empty() { | |
| 1656 | + this.$el.empty(); | |
| 1657 | + this._resetLastSuggestion(); | |
| 1658 | + }, | |
| 1659 | + _getSuggestionsFragment: function getSuggestionsFragment(query, suggestions) { | |
| 1660 | + var that = this, fragment; | |
| 1661 | + fragment = document.createDocumentFragment(); | |
| 1662 | + _.each(suggestions, function getSuggestionNode(suggestion) { | |
| 1663 | + var $el, context; | |
| 1664 | + context = that._injectQuery(query, suggestion); | |
| 1665 | + $el = $(that.templates.suggestion(context)).data(keys.obj, suggestion).data(keys.val, that.displayFn(suggestion)).addClass(that.classes.suggestion + " " + that.classes.selectable); | |
| 1666 | + fragment.appendChild($el[0]); | |
| 1667 | + }); | |
| 1668 | + this.highlight && highlight({ | |
| 1669 | + className: this.classes.highlight, | |
| 1670 | + node: fragment, | |
| 1671 | + pattern: query | |
| 1672 | + }); | |
| 1673 | + return $(fragment); | |
| 1674 | + }, | |
| 1675 | + _getFooter: function getFooter(query, suggestions) { | |
| 1676 | + return this.templates.footer ? this.templates.footer({ | |
| 1677 | + query: query, | |
| 1678 | + suggestions: suggestions, | |
| 1679 | + dataset: this.name | |
| 1680 | + }) : null; | |
| 1681 | + }, | |
| 1682 | + _getHeader: function getHeader(query, suggestions) { | |
| 1683 | + return this.templates.header ? this.templates.header({ | |
| 1684 | + query: query, | |
| 1685 | + suggestions: suggestions, | |
| 1686 | + dataset: this.name | |
| 1687 | + }) : null; | |
| 1688 | + }, | |
| 1689 | + _resetLastSuggestion: function resetLastSuggestion() { | |
| 1690 | + this.$lastSuggestion = $(); | |
| 1691 | + }, | |
| 1692 | + _injectQuery: function injectQuery(query, obj) { | |
| 1693 | + return _.isObject(obj) ? _.mixin({ | |
| 1694 | + _query: query | |
| 1695 | + }, obj) : obj; | |
| 1696 | + }, | |
| 1697 | + update: function update(query) { | |
| 1698 | + var that = this, canceled = false, syncCalled = false, rendered = 0; | |
| 1699 | + this.cancel(); | |
| 1700 | + this.cancel = function cancel() { | |
| 1701 | + canceled = true; | |
| 1702 | + that.cancel = $.noop; | |
| 1703 | + that.async && that.trigger("asyncCanceled", query); | |
| 1704 | + }; | |
| 1705 | + this.source(query, sync, async); | |
| 1706 | + !syncCalled && sync([]); | |
| 1707 | + function sync(suggestions) { | |
| 1708 | + if (syncCalled) { | |
| 1709 | + return; | |
| 1710 | + } | |
| 1711 | + syncCalled = true; | |
| 1712 | + suggestions = (suggestions || []).slice(0, that.limit); | |
| 1713 | + rendered = suggestions.length; | |
| 1714 | + that._overwrite(query, suggestions); | |
| 1715 | + if (rendered < that.limit && that.async) { | |
| 1716 | + that.trigger("asyncRequested", query); | |
| 1717 | + } | |
| 1718 | + } | |
| 1719 | + function async(suggestions) { | |
| 1720 | + suggestions = suggestions || []; | |
| 1721 | + if (!canceled && rendered < that.limit) { | |
| 1722 | + that.cancel = $.noop; | |
| 1723 | + rendered += suggestions.length; | |
| 1724 | + that._append(query, suggestions.slice(0, that.limit - rendered)); | |
| 1725 | + that.async && that.trigger("asyncReceived", query); | |
| 1726 | + } | |
| 1727 | + } | |
| 1728 | + }, | |
| 1729 | + cancel: $.noop, | |
| 1730 | + clear: function clear() { | |
| 1731 | + this._empty(); | |
| 1732 | + this.cancel(); | |
| 1733 | + this.trigger("cleared"); | |
| 1734 | + }, | |
| 1735 | + isEmpty: function isEmpty() { | |
| 1736 | + return this.$el.is(":empty"); | |
| 1737 | + }, | |
| 1738 | + destroy: function destroy() { | |
| 1739 | + this.$el = $("<div>"); | |
| 1740 | + } | |
| 1741 | + }); | |
| 1742 | + return Dataset; | |
| 1743 | + function getDisplayFn(display) { | |
| 1744 | + display = display || _.stringify; | |
| 1745 | + return _.isFunction(display) ? display : displayFn; | |
| 1746 | + function displayFn(obj) { | |
| 1747 | + return obj[display]; | |
| 1748 | + } | |
| 1749 | + } | |
| 1750 | + function getTemplates(templates, displayFn) { | |
| 1751 | + return { | |
| 1752 | + notFound: templates.notFound && _.templatify(templates.notFound), | |
| 1753 | + pending: templates.pending && _.templatify(templates.pending), | |
| 1754 | + header: templates.header && _.templatify(templates.header), | |
| 1755 | + footer: templates.footer && _.templatify(templates.footer), | |
| 1756 | + suggestion: templates.suggestion || suggestionTemplate | |
| 1757 | + }; | |
| 1758 | + function suggestionTemplate(context) { | |
| 1759 | + return $("<div>").text(displayFn(context)); | |
| 1760 | + } | |
| 1761 | + } | |
| 1762 | + function isValidName(str) { | |
| 1763 | + return /^[_a-zA-Z0-9-]+$/.test(str); | |
| 1764 | + } | |
| 1765 | + }(); | |
| 1766 | + var Menu = function() { | |
| 1767 | + "use strict"; | |
| 1768 | + function Menu(o, www) { | |
| 1769 | + var that = this; | |
| 1770 | + o = o || {}; | |
| 1771 | + if (!o.node) { | |
| 1772 | + $.error("node is required"); | |
| 1773 | + } | |
| 1774 | + www.mixin(this); | |
| 1775 | + this.$node = $(o.node); | |
| 1776 | + this.query = null; | |
| 1777 | + this.datasets = _.map(o.datasets, initializeDataset); | |
| 1778 | + function initializeDataset(oDataset) { | |
| 1779 | + var node = that.$node.find(oDataset.node).first(); | |
| 1780 | + oDataset.node = node.length ? node : $("<div>").appendTo(that.$node); | |
| 1781 | + return new Dataset(oDataset, www); | |
| 1782 | + } | |
| 1783 | + } | |
| 1784 | + _.mixin(Menu.prototype, EventEmitter, { | |
| 1785 | + _onSelectableClick: function onSelectableClick($e) { | |
| 1786 | + this.trigger("selectableClicked", $($e.currentTarget)); | |
| 1787 | + }, | |
| 1788 | + _onRendered: function onRendered(type, dataset, suggestions, async) { | |
| 1789 | + this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty()); | |
| 1790 | + this.trigger("datasetRendered", dataset, suggestions, async); | |
| 1791 | + }, | |
| 1792 | + _onCleared: function onCleared() { | |
| 1793 | + this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty()); | |
| 1794 | + this.trigger("datasetCleared"); | |
| 1795 | + }, | |
| 1796 | + _propagate: function propagate() { | |
| 1797 | + this.trigger.apply(this, arguments); | |
| 1798 | + }, | |
| 1799 | + _allDatasetsEmpty: function allDatasetsEmpty() { | |
| 1800 | + return _.every(this.datasets, isDatasetEmpty); | |
| 1801 | + function isDatasetEmpty(dataset) { | |
| 1802 | + return dataset.isEmpty(); | |
| 1803 | + } | |
| 1804 | + }, | |
| 1805 | + _getSelectables: function getSelectables() { | |
| 1806 | + return this.$node.find(this.selectors.selectable); | |
| 1807 | + }, | |
| 1808 | + _removeCursor: function _removeCursor() { | |
| 1809 | + var $selectable = this.getActiveSelectable(); | |
| 1810 | + $selectable && $selectable.removeClass(this.classes.cursor); | |
| 1811 | + }, | |
| 1812 | + _ensureVisible: function ensureVisible($el) { | |
| 1813 | + var elTop, elBottom, nodeScrollTop, nodeHeight; | |
| 1814 | + elTop = $el.position().top; | |
| 1815 | + elBottom = elTop + $el.outerHeight(true); | |
| 1816 | + nodeScrollTop = this.$node.scrollTop(); | |
| 1817 | + nodeHeight = this.$node.height() + parseInt(this.$node.css("paddingTop"), 10) + parseInt(this.$node.css("paddingBottom"), 10); | |
| 1818 | + if (elTop < 0) { | |
| 1819 | + this.$node.scrollTop(nodeScrollTop + elTop); | |
| 1820 | + } else if (nodeHeight < elBottom) { | |
| 1821 | + this.$node.scrollTop(nodeScrollTop + (elBottom - nodeHeight)); | |
| 1822 | + } | |
| 1823 | + }, | |
| 1824 | + bind: function() { | |
| 1825 | + var that = this, onSelectableClick; | |
| 1826 | + onSelectableClick = _.bind(this._onSelectableClick, this); | |
| 1827 | + this.$node.on("click.tt", this.selectors.selectable, onSelectableClick); | |
| 1828 | + _.each(this.datasets, function(dataset) { | |
| 1829 | + dataset.onSync("asyncRequested", that._propagate, that).onSync("asyncCanceled", that._propagate, that).onSync("asyncReceived", that._propagate, that).onSync("rendered", that._onRendered, that).onSync("cleared", that._onCleared, that); | |
| 1830 | + }); | |
| 1831 | + return this; | |
| 1832 | + }, | |
| 1833 | + isOpen: function isOpen() { | |
| 1834 | + return this.$node.hasClass(this.classes.open); | |
| 1835 | + }, | |
| 1836 | + open: function open() { | |
| 1837 | + this.$node.addClass(this.classes.open); | |
| 1838 | + }, | |
| 1839 | + close: function close() { | |
| 1840 | + this.$node.removeClass(this.classes.open); | |
| 1841 | + this._removeCursor(); | |
| 1842 | + }, | |
| 1843 | + setLanguageDirection: function setLanguageDirection(dir) { | |
| 1844 | + this.$node.attr("dir", dir); | |
| 1845 | + }, | |
| 1846 | + selectableRelativeToCursor: function selectableRelativeToCursor(delta) { | |
| 1847 | + var $selectables, $oldCursor, oldIndex, newIndex; | |
| 1848 | + $oldCursor = this.getActiveSelectable(); | |
| 1849 | + $selectables = this._getSelectables(); | |
| 1850 | + oldIndex = $oldCursor ? $selectables.index($oldCursor) : -1; | |
| 1851 | + newIndex = oldIndex + delta; | |
| 1852 | + newIndex = (newIndex + 1) % ($selectables.length + 1) - 1; | |
| 1853 | + newIndex = newIndex < -1 ? $selectables.length - 1 : newIndex; | |
| 1854 | + return newIndex === -1 ? null : $selectables.eq(newIndex); | |
| 1855 | + }, | |
| 1856 | + setCursor: function setCursor($selectable) { | |
| 1857 | + this._removeCursor(); | |
| 1858 | + if ($selectable = $selectable && $selectable.first()) { | |
| 1859 | + $selectable.addClass(this.classes.cursor); | |
| 1860 | + this._ensureVisible($selectable); | |
| 1861 | + } | |
| 1862 | + }, | |
| 1863 | + getSelectableData: function getSelectableData($el) { | |
| 1864 | + return $el && $el.length ? Dataset.extractData($el) : null; | |
| 1865 | + }, | |
| 1866 | + getActiveSelectable: function getActiveSelectable() { | |
| 1867 | + var $selectable = this._getSelectables().filter(this.selectors.cursor).first(); | |
| 1868 | + return $selectable.length ? $selectable : null; | |
| 1869 | + }, | |
| 1870 | + getTopSelectable: function getTopSelectable() { | |
| 1871 | + var $selectable = this._getSelectables().first(); | |
| 1872 | + return $selectable.length ? $selectable : null; | |
| 1873 | + }, | |
| 1874 | + update: function update(query) { | |
| 1875 | + var isValidUpdate = query !== this.query; | |
| 1876 | + if (isValidUpdate) { | |
| 1877 | + this.query = query; | |
| 1878 | + _.each(this.datasets, updateDataset); | |
| 1879 | + } | |
| 1880 | + return isValidUpdate; | |
| 1881 | + function updateDataset(dataset) { | |
| 1882 | + dataset.update(query); | |
| 1883 | + } | |
| 1884 | + }, | |
| 1885 | + empty: function empty() { | |
| 1886 | + _.each(this.datasets, clearDataset); | |
| 1887 | + this.query = null; | |
| 1888 | + this.$node.addClass(this.classes.empty); | |
| 1889 | + function clearDataset(dataset) { | |
| 1890 | + dataset.clear(); | |
| 1891 | + } | |
| 1892 | + }, | |
| 1893 | + destroy: function destroy() { | |
| 1894 | + this.$node.off(".tt"); | |
| 1895 | + this.$node = $("<div>"); | |
| 1896 | + _.each(this.datasets, destroyDataset); | |
| 1897 | + function destroyDataset(dataset) { | |
| 1898 | + dataset.destroy(); | |
| 1899 | + } | |
| 1900 | + } | |
| 1901 | + }); | |
| 1902 | + return Menu; | |
| 1903 | + }(); | |
| 1904 | + var DefaultMenu = function() { | |
| 1905 | + "use strict"; | |
| 1906 | + var s = Menu.prototype; | |
| 1907 | + function DefaultMenu() { | |
| 1908 | + Menu.apply(this, [].slice.call(arguments, 0)); | |
| 1909 | + } | |
| 1910 | + _.mixin(DefaultMenu.prototype, Menu.prototype, { | |
| 1911 | + open: function open() { | |
| 1912 | + !this._allDatasetsEmpty() && this._show(); | |
| 1913 | + return s.open.apply(this, [].slice.call(arguments, 0)); | |
| 1914 | + }, | |
| 1915 | + close: function close() { | |
| 1916 | + this._hide(); | |
| 1917 | + return s.close.apply(this, [].slice.call(arguments, 0)); | |
| 1918 | + }, | |
| 1919 | + _onRendered: function onRendered() { | |
| 1920 | + if (this._allDatasetsEmpty()) { | |
| 1921 | + this._hide(); | |
| 1922 | + } else { | |
| 1923 | + this.isOpen() && this._show(); | |
| 1924 | + } | |
| 1925 | + return s._onRendered.apply(this, [].slice.call(arguments, 0)); | |
| 1926 | + }, | |
| 1927 | + _onCleared: function onCleared() { | |
| 1928 | + if (this._allDatasetsEmpty()) { | |
| 1929 | + this._hide(); | |
| 1930 | + } else { | |
| 1931 | + this.isOpen() && this._show(); | |
| 1932 | + } | |
| 1933 | + return s._onCleared.apply(this, [].slice.call(arguments, 0)); | |
| 1934 | + }, | |
| 1935 | + setLanguageDirection: function setLanguageDirection(dir) { | |
| 1936 | + this.$node.css(dir === "ltr" ? this.css.ltr : this.css.rtl); | |
| 1937 | + return s.setLanguageDirection.apply(this, [].slice.call(arguments, 0)); | |
| 1938 | + }, | |
| 1939 | + _hide: function hide() { | |
| 1940 | + this.$node.hide(); | |
| 1941 | + }, | |
| 1942 | + _show: function show() { | |
| 1943 | + this.$node.css("display", "block"); | |
| 1944 | + } | |
| 1945 | + }); | |
| 1946 | + return DefaultMenu; | |
| 1947 | + }(); | |
| 1948 | + var Typeahead = function() { | |
| 1949 | + "use strict"; | |
| 1950 | + function Typeahead(o, www) { | |
| 1951 | + var onFocused, onBlurred, onEnterKeyed, onTabKeyed, onEscKeyed, onUpKeyed, onDownKeyed, onLeftKeyed, onRightKeyed, onQueryChanged, onWhitespaceChanged; | |
| 1952 | + o = o || {}; | |
| 1953 | + if (!o.input) { | |
| 1954 | + $.error("missing input"); | |
| 1955 | + } | |
| 1956 | + if (!o.menu) { | |
| 1957 | + $.error("missing menu"); | |
| 1958 | + } | |
| 1959 | + if (!o.eventBus) { | |
| 1960 | + $.error("missing event bus"); | |
| 1961 | + } | |
| 1962 | + www.mixin(this); | |
| 1963 | + this.eventBus = o.eventBus; | |
| 1964 | + this.minLength = _.isNumber(o.minLength) ? o.minLength : 1; | |
| 1965 | + this.input = o.input; | |
| 1966 | + this.menu = o.menu; | |
| 1967 | + this.enabled = true; | |
| 1968 | + this.active = false; | |
| 1969 | + this.input.hasFocus() && this.activate(); | |
| 1970 | + this.dir = this.input.getLangDir(); | |
| 1971 | + this._hacks(); | |
| 1972 | + this.menu.bind().onSync("selectableClicked", this._onSelectableClicked, this).onSync("asyncRequested", this._onAsyncRequested, this).onSync("asyncCanceled", this._onAsyncCanceled, this).onSync("asyncReceived", this._onAsyncReceived, this).onSync("datasetRendered", this._onDatasetRendered, this).onSync("datasetCleared", this._onDatasetCleared, this); | |
| 1973 | + onFocused = c(this, "activate", "open", "_onFocused"); | |
| 1974 | + onBlurred = c(this, "deactivate", "_onBlurred"); | |
| 1975 | + onEnterKeyed = c(this, "isActive", "isOpen", "_onEnterKeyed"); | |
| 1976 | + onTabKeyed = c(this, "isActive", "isOpen", "_onTabKeyed"); | |
| 1977 | + onEscKeyed = c(this, "isActive", "_onEscKeyed"); | |
| 1978 | + onUpKeyed = c(this, "isActive", "open", "_onUpKeyed"); | |
| 1979 | + onDownKeyed = c(this, "isActive", "open", "_onDownKeyed"); | |
| 1980 | + onLeftKeyed = c(this, "isActive", "isOpen", "_onLeftKeyed"); | |
| 1981 | + onRightKeyed = c(this, "isActive", "isOpen", "_onRightKeyed"); | |
| 1982 | + onQueryChanged = c(this, "_openIfActive", "_onQueryChanged"); | |
| 1983 | + onWhitespaceChanged = c(this, "_openIfActive", "_onWhitespaceChanged"); | |
| 1984 | + this.input.bind().onSync("focused", onFocused, this).onSync("blurred", onBlurred, this).onSync("enterKeyed", onEnterKeyed, this).onSync("tabKeyed", onTabKeyed, this).onSync("escKeyed", onEscKeyed, this).onSync("upKeyed", onUpKeyed, this).onSync("downKeyed", onDownKeyed, this).onSync("leftKeyed", onLeftKeyed, this).onSync("rightKeyed", onRightKeyed, this).onSync("queryChanged", onQueryChanged, this).onSync("whitespaceChanged", onWhitespaceChanged, this).onSync("langDirChanged", this._onLangDirChanged, this); | |
| 1985 | + } | |
| 1986 | + _.mixin(Typeahead.prototype, { | |
| 1987 | + _hacks: function hacks() { | |
| 1988 | + var $input, $menu; | |
| 1989 | + $input = this.input.$input || $("<div>"); | |
| 1990 | + $menu = this.menu.$node || $("<div>"); | |
| 1991 | + $input.on("blur.tt", function($e) { | |
| 1992 | + var active, isActive, hasActive; | |
| 1993 | + active = document.activeElement; | |
| 1994 | + isActive = $menu.is(active); | |
| 1995 | + hasActive = $menu.has(active).length > 0; | |
| 1996 | + if (_.isMsie() && (isActive || hasActive)) { | |
| 1997 | + $e.preventDefault(); | |
| 1998 | + $e.stopImmediatePropagation(); | |
| 1999 | + _.defer(function() { | |
| 2000 | + $input.focus(); | |
| 2001 | + }); | |
| 2002 | + } | |
| 2003 | + }); | |
| 2004 | + $menu.on("mousedown.tt", function($e) { | |
| 2005 | + $e.preventDefault(); | |
| 2006 | + }); | |
| 2007 | + }, | |
| 2008 | + _onSelectableClicked: function onSelectableClicked(type, $el) { | |
| 2009 | + this.select($el); | |
| 2010 | + }, | |
| 2011 | + _onDatasetCleared: function onDatasetCleared() { | |
| 2012 | + this._updateHint(); | |
| 2013 | + }, | |
| 2014 | + _onDatasetRendered: function onDatasetRendered(type, dataset, suggestions, async) { | |
| 2015 | + this._updateHint(); | |
| 2016 | + this.eventBus.trigger("render", suggestions, async, dataset); | |
| 2017 | + }, | |
| 2018 | + _onAsyncRequested: function onAsyncRequested(type, dataset, query) { | |
| 2019 | + this.eventBus.trigger("asyncrequest", query, dataset); | |
| 2020 | + }, | |
| 2021 | + _onAsyncCanceled: function onAsyncCanceled(type, dataset, query) { | |
| 2022 | + this.eventBus.trigger("asynccancel", query, dataset); | |
| 2023 | + }, | |
| 2024 | + _onAsyncReceived: function onAsyncReceived(type, dataset, query) { | |
| 2025 | + this.eventBus.trigger("asyncreceive", query, dataset); | |
| 2026 | + }, | |
| 2027 | + _onFocused: function onFocused() { | |
| 2028 | + this._minLengthMet() && this.menu.update(this.input.getQuery()); | |
| 2029 | + }, | |
| 2030 | + _onBlurred: function onBlurred() { | |
| 2031 | + if (this.input.hasQueryChangedSinceLastFocus()) { | |
| 2032 | + this.eventBus.trigger("change", this.input.getQuery()); | |
| 2033 | + } | |
| 2034 | + }, | |
| 2035 | + _onEnterKeyed: function onEnterKeyed(type, $e) { | |
| 2036 | + var $selectable; | |
| 2037 | + if ($selectable = this.menu.getActiveSelectable()) { | |
| 2038 | + this.select($selectable) && $e.preventDefault(); | |
| 2039 | + } | |
| 2040 | + }, | |
| 2041 | + _onTabKeyed: function onTabKeyed(type, $e) { | |
| 2042 | + var $selectable; | |
| 2043 | + if ($selectable = this.menu.getActiveSelectable()) { | |
| 2044 | + this.select($selectable) && $e.preventDefault(); | |
| 2045 | + } else if ($selectable = this.menu.getTopSelectable()) { | |
| 2046 | + this.autocomplete($selectable) && $e.preventDefault(); | |
| 2047 | + } | |
| 2048 | + }, | |
| 2049 | + _onEscKeyed: function onEscKeyed() { | |
| 2050 | + this.close(); | |
| 2051 | + }, | |
| 2052 | + _onUpKeyed: function onUpKeyed() { | |
| 2053 | + this.moveCursor(-1); | |
| 2054 | + }, | |
| 2055 | + _onDownKeyed: function onDownKeyed() { | |
| 2056 | + this.moveCursor(+1); | |
| 2057 | + }, | |
| 2058 | + _onLeftKeyed: function onLeftKeyed() { | |
| 2059 | + if (this.dir === "rtl" && this.input.isCursorAtEnd()) { | |
| 2060 | + this.autocomplete(this.menu.getTopSelectable()); | |
| 2061 | + } | |
| 2062 | + }, | |
| 2063 | + _onRightKeyed: function onRightKeyed() { | |
| 2064 | + if (this.dir === "ltr" && this.input.isCursorAtEnd()) { | |
| 2065 | + this.autocomplete(this.menu.getTopSelectable()); | |
| 2066 | + } | |
| 2067 | + }, | |
| 2068 | + _onQueryChanged: function onQueryChanged(e, query) { | |
| 2069 | + this._minLengthMet(query) ? this.menu.update(query) : this.menu.empty(); | |
| 2070 | + }, | |
| 2071 | + _onWhitespaceChanged: function onWhitespaceChanged() { | |
| 2072 | + this._updateHint(); | |
| 2073 | + }, | |
| 2074 | + _onLangDirChanged: function onLangDirChanged(e, dir) { | |
| 2075 | + if (this.dir !== dir) { | |
| 2076 | + this.dir = dir; | |
| 2077 | + this.menu.setLanguageDirection(dir); | |
| 2078 | + } | |
| 2079 | + }, | |
| 2080 | + _openIfActive: function openIfActive() { | |
| 2081 | + this.isActive() && this.open(); | |
| 2082 | + }, | |
| 2083 | + _minLengthMet: function minLengthMet(query) { | |
| 2084 | + query = _.isString(query) ? query : this.input.getQuery() || ""; | |
| 2085 | + return query.length >= this.minLength; | |
| 2086 | + }, | |
| 2087 | + _updateHint: function updateHint() { | |
| 2088 | + var $selectable, data, val, query, escapedQuery, frontMatchRegEx, match; | |
| 2089 | + $selectable = this.menu.getTopSelectable(); | |
| 2090 | + data = this.menu.getSelectableData($selectable); | |
| 2091 | + val = this.input.getInputValue(); | |
| 2092 | + if (data && !_.isBlankString(val) && !this.input.hasOverflow()) { | |
| 2093 | + query = Input.normalizeQuery(val); | |
| 2094 | + escapedQuery = _.escapeRegExChars(query); | |
| 2095 | + frontMatchRegEx = new RegExp("^(?:" + escapedQuery + ")(.+$)", "i"); | |
| 2096 | + match = frontMatchRegEx.exec(data.val); | |
| 2097 | + match && this.input.setHint(val + match[1]); | |
| 2098 | + } else { | |
| 2099 | + this.input.clearHint(); | |
| 2100 | + } | |
| 2101 | + }, | |
| 2102 | + isEnabled: function isEnabled() { | |
| 2103 | + return this.enabled; | |
| 2104 | + }, | |
| 2105 | + enable: function enable() { | |
| 2106 | + this.enabled = true; | |
| 2107 | + }, | |
| 2108 | + disable: function disable() { | |
| 2109 | + this.enabled = false; | |
| 2110 | + }, | |
| 2111 | + isActive: function isActive() { | |
| 2112 | + return this.active; | |
| 2113 | + }, | |
| 2114 | + activate: function activate() { | |
| 2115 | + if (this.isActive()) { | |
| 2116 | + return true; | |
| 2117 | + } else if (!this.isEnabled() || this.eventBus.before("active")) { | |
| 2118 | + return false; | |
| 2119 | + } else { | |
| 2120 | + this.active = true; | |
| 2121 | + this.eventBus.trigger("active"); | |
| 2122 | + return true; | |
| 2123 | + } | |
| 2124 | + }, | |
| 2125 | + deactivate: function deactivate() { | |
| 2126 | + if (!this.isActive()) { | |
| 2127 | + return true; | |
| 2128 | + } else if (this.eventBus.before("idle")) { | |
| 2129 | + return false; | |
| 2130 | + } else { | |
| 2131 | + this.active = false; | |
| 2132 | + this.close(); | |
| 2133 | + this.eventBus.trigger("idle"); | |
| 2134 | + return true; | |
| 2135 | + } | |
| 2136 | + }, | |
| 2137 | + isOpen: function isOpen() { | |
| 2138 | + return this.menu.isOpen(); | |
| 2139 | + }, | |
| 2140 | + open: function open() { | |
| 2141 | + if (!this.isOpen() && !this.eventBus.before("open")) { | |
| 2142 | + this.menu.open(); | |
| 2143 | + this._updateHint(); | |
| 2144 | + this.eventBus.trigger("open"); | |
| 2145 | + } | |
| 2146 | + return this.isOpen(); | |
| 2147 | + }, | |
| 2148 | + close: function close() { | |
| 2149 | + if (this.isOpen() && !this.eventBus.before("close")) { | |
| 2150 | + this.menu.close(); | |
| 2151 | + this.input.clearHint(); | |
| 2152 | + this.input.resetInputValue(); | |
| 2153 | + this.eventBus.trigger("close"); | |
| 2154 | + } | |
| 2155 | + return !this.isOpen(); | |
| 2156 | + }, | |
| 2157 | + setVal: function setVal(val) { | |
| 2158 | + this.input.setQuery(_.toStr(val)); | |
| 2159 | + }, | |
| 2160 | + getVal: function getVal() { | |
| 2161 | + return this.input.getQuery(); | |
| 2162 | + }, | |
| 2163 | + select: function select($selectable) { | |
| 2164 | + var data = this.menu.getSelectableData($selectable); | |
| 2165 | + if (data && !this.eventBus.before("select", data.obj)) { | |
| 2166 | + this.input.setQuery(data.val, true); | |
| 2167 | + this.eventBus.trigger("select", data.obj); | |
| 2168 | + this.close(); | |
| 2169 | + return true; | |
| 2170 | + } | |
| 2171 | + return false; | |
| 2172 | + }, | |
| 2173 | + autocomplete: function autocomplete($selectable) { | |
| 2174 | + var query, data, isValid; | |
| 2175 | + query = this.input.getQuery(); | |
| 2176 | + data = this.menu.getSelectableData($selectable); | |
| 2177 | + isValid = data && query !== data.val; | |
| 2178 | + if (isValid && !this.eventBus.before("autocomplete", data.obj)) { | |
| 2179 | + this.input.setQuery(data.val); | |
| 2180 | + this.eventBus.trigger("autocomplete", data.obj); | |
| 2181 | + return true; | |
| 2182 | + } | |
| 2183 | + return false; | |
| 2184 | + }, | |
| 2185 | + moveCursor: function moveCursor(delta) { | |
| 2186 | + var query, $candidate, data, payload, cancelMove; | |
| 2187 | + query = this.input.getQuery(); | |
| 2188 | + $candidate = this.menu.selectableRelativeToCursor(delta); | |
| 2189 | + data = this.menu.getSelectableData($candidate); | |
| 2190 | + payload = data ? data.obj : null; | |
| 2191 | + cancelMove = this._minLengthMet() && this.menu.update(query); | |
| 2192 | + if (!cancelMove && !this.eventBus.before("cursorchange", payload)) { | |
| 2193 | + this.menu.setCursor($candidate); | |
| 2194 | + if (data) { | |
| 2195 | + this.input.setInputValue(data.val); | |
| 2196 | + } else { | |
| 2197 | + this.input.resetInputValue(); | |
| 2198 | + this._updateHint(); | |
| 2199 | + } | |
| 2200 | + this.eventBus.trigger("cursorchange", payload); | |
| 2201 | + return true; | |
| 2202 | + } | |
| 2203 | + return false; | |
| 2204 | + }, | |
| 2205 | + destroy: function destroy() { | |
| 2206 | + this.input.destroy(); | |
| 2207 | + this.menu.destroy(); | |
| 2208 | + } | |
| 2209 | + }); | |
| 2210 | + return Typeahead; | |
| 2211 | + function c(ctx) { | |
| 2212 | + var methods = [].slice.call(arguments, 1); | |
| 2213 | + return function() { | |
| 2214 | + var args = [].slice.call(arguments); | |
| 2215 | + _.each(methods, function(method) { | |
| 2216 | + return ctx[method].apply(ctx, args); | |
| 2217 | + }); | |
| 2218 | + }; | |
| 2219 | + } | |
| 2220 | + }(); | |
| 2221 | + (function() { | |
| 2222 | + "use strict"; | |
| 2223 | + var old, keys, methods; | |
| 2224 | + old = $.fn.typeahead; | |
| 2225 | + keys = { | |
| 2226 | + www: "tt-www", | |
| 2227 | + attrs: "tt-attrs", | |
| 2228 | + typeahead: "tt-typeahead" | |
| 2229 | + }; | |
| 2230 | + methods = { | |
| 2231 | + initialize: function initialize(o, datasets) { | |
| 2232 | + var www; | |
| 2233 | + datasets = _.isArray(datasets) ? datasets : [].slice.call(arguments, 1); | |
| 2234 | + o = o || {}; | |
| 2235 | + www = WWW(o.classNames); | |
| 2236 | + return this.each(attach); | |
| 2237 | + function attach() { | |
| 2238 | + var $input, $wrapper, $hint, $menu, defaultHint, defaultMenu, eventBus, input, menu, typeahead, MenuConstructor; | |
| 2239 | + _.each(datasets, function(d) { | |
| 2240 | + d.highlight = !!o.highlight; | |
| 2241 | + }); | |
| 2242 | + $input = $(this); | |
| 2243 | + $wrapper = $(www.html.wrapper); | |
| 2244 | + $hint = $elOrNull(o.hint); | |
| 2245 | + $menu = $elOrNull(o.menu); | |
| 2246 | + defaultHint = o.hint !== false && !$hint; | |
| 2247 | + defaultMenu = o.menu !== false && !$menu; | |
| 2248 | + defaultHint && ($hint = buildHintFromInput($input, www)); | |
| 2249 | + defaultMenu && ($menu = $(www.html.menu).css(www.css.menu)); | |
| 2250 | + $hint && $hint.val(""); | |
| 2251 | + $input = prepInput($input, www); | |
| 2252 | + if (defaultHint || defaultMenu) { | |
| 2253 | + $wrapper.css(www.css.wrapper); | |
| 2254 | + $input.css(defaultHint ? www.css.input : www.css.inputWithNoHint); | |
| 2255 | + $input.wrap($wrapper).parent().prepend(defaultHint ? $hint : null).append(defaultMenu ? $menu : null); | |
| 2256 | + } | |
| 2257 | + MenuConstructor = defaultMenu ? DefaultMenu : Menu; | |
| 2258 | + eventBus = new EventBus({ | |
| 2259 | + el: $input | |
| 2260 | + }); | |
| 2261 | + input = new Input({ | |
| 2262 | + hint: $hint, | |
| 2263 | + input: $input | |
| 2264 | + }, www); | |
| 2265 | + menu = new MenuConstructor({ | |
| 2266 | + node: $menu, | |
| 2267 | + datasets: datasets | |
| 2268 | + }, www); | |
| 2269 | + typeahead = new Typeahead({ | |
| 2270 | + input: input, | |
| 2271 | + menu: menu, | |
| 2272 | + eventBus: eventBus, | |
| 2273 | + minLength: o.minLength | |
| 2274 | + }, www); | |
| 2275 | + $input.data(keys.www, www); | |
| 2276 | + $input.data(keys.typeahead, typeahead); | |
| 2277 | + } | |
| 2278 | + }, | |
| 2279 | + isEnabled: function isEnabled() { | |
| 2280 | + var enabled; | |
| 2281 | + ttEach(this.first(), function(t) { | |
| 2282 | + enabled = t.isEnabled(); | |
| 2283 | + }); | |
| 2284 | + return enabled; | |
| 2285 | + }, | |
| 2286 | + enable: function enable() { | |
| 2287 | + ttEach(this, function(t) { | |
| 2288 | + t.enable(); | |
| 2289 | + }); | |
| 2290 | + return this; | |
| 2291 | + }, | |
| 2292 | + disable: function disable() { | |
| 2293 | + ttEach(this, function(t) { | |
| 2294 | + t.disable(); | |
| 2295 | + }); | |
| 2296 | + return this; | |
| 2297 | + }, | |
| 2298 | + isActive: function isActive() { | |
| 2299 | + var active; | |
| 2300 | + ttEach(this.first(), function(t) { | |
| 2301 | + active = t.isActive(); | |
| 2302 | + }); | |
| 2303 | + return active; | |
| 2304 | + }, | |
| 2305 | + activate: function activate() { | |
| 2306 | + ttEach(this, function(t) { | |
| 2307 | + t.activate(); | |
| 2308 | + }); | |
| 2309 | + return this; | |
| 2310 | + }, | |
| 2311 | + deactivate: function deactivate() { | |
| 2312 | + ttEach(this, function(t) { | |
| 2313 | + t.deactivate(); | |
| 2314 | + }); | |
| 2315 | + return this; | |
| 2316 | + }, | |
| 2317 | + isOpen: function isOpen() { | |
| 2318 | + var open; | |
| 2319 | + ttEach(this.first(), function(t) { | |
| 2320 | + open = t.isOpen(); | |
| 2321 | + }); | |
| 2322 | + return open; | |
| 2323 | + }, | |
| 2324 | + open: function open() { | |
| 2325 | + ttEach(this, function(t) { | |
| 2326 | + t.open(); | |
| 2327 | + }); | |
| 2328 | + return this; | |
| 2329 | + }, | |
| 2330 | + close: function close() { | |
| 2331 | + ttEach(this, function(t) { | |
| 2332 | + t.close(); | |
| 2333 | + }); | |
| 2334 | + return this; | |
| 2335 | + }, | |
| 2336 | + select: function select(el) { | |
| 2337 | + var success = false, $el = $(el); | |
| 2338 | + ttEach(this.first(), function(t) { | |
| 2339 | + success = t.select($el); | |
| 2340 | + }); | |
| 2341 | + return success; | |
| 2342 | + }, | |
| 2343 | + autocomplete: function autocomplete(el) { | |
| 2344 | + var success = false, $el = $(el); | |
| 2345 | + ttEach(this.first(), function(t) { | |
| 2346 | + success = t.autocomplete($el); | |
| 2347 | + }); | |
| 2348 | + return success; | |
| 2349 | + }, | |
| 2350 | + moveCursor: function moveCursoe(delta) { | |
| 2351 | + var success = false; | |
| 2352 | + ttEach(this.first(), function(t) { | |
| 2353 | + success = t.moveCursor(delta); | |
| 2354 | + }); | |
| 2355 | + return success; | |
| 2356 | + }, | |
| 2357 | + val: function val(newVal) { | |
| 2358 | + var query; | |
| 2359 | + if (!arguments.length) { | |
| 2360 | + ttEach(this.first(), function(t) { | |
| 2361 | + query = t.getVal(); | |
| 2362 | + }); | |
| 2363 | + return query; | |
| 2364 | + } else { | |
| 2365 | + ttEach(this, function(t) { | |
| 2366 | + t.setVal(newVal); | |
| 2367 | + }); | |
| 2368 | + return this; | |
| 2369 | + } | |
| 2370 | + }, | |
| 2371 | + destroy: function destroy() { | |
| 2372 | + ttEach(this, function(typeahead, $input) { | |
| 2373 | + revert($input); | |
| 2374 | + typeahead.destroy(); | |
| 2375 | + }); | |
| 2376 | + return this; | |
| 2377 | + } | |
| 2378 | + }; | |
| 2379 | + $.fn.typeahead = function(method) { | |
| 2380 | + if (methods[method]) { | |
| 2381 | + return methods[method].apply(this, [].slice.call(arguments, 1)); | |
| 2382 | + } else { | |
| 2383 | + return methods.initialize.apply(this, arguments); | |
| 2384 | + } | |
| 2385 | + }; | |
| 2386 | + $.fn.typeahead.noConflict = function noConflict() { | |
| 2387 | + $.fn.typeahead = old; | |
| 2388 | + return this; | |
| 2389 | + }; | |
| 2390 | + function ttEach($els, fn) { | |
| 2391 | + $els.each(function() { | |
| 2392 | + var $input = $(this), typeahead; | |
| 2393 | + (typeahead = $input.data(keys.typeahead)) && fn(typeahead, $input); | |
| 2394 | + }); | |
| 2395 | + } | |
| 2396 | + function buildHintFromInput($input, www) { | |
| 2397 | + return $input.clone().addClass(www.classes.hint).removeData().css(www.css.hint).css(getBackgroundStyles($input)).prop("readonly", true).removeAttr("id name placeholder required").attr({ | |
| 2398 | + autocomplete: "off", | |
| 2399 | + spellcheck: "false", | |
| 2400 | + tabindex: -1 | |
| 2401 | + }); | |
| 2402 | + } | |
| 2403 | + function prepInput($input, www) { | |
| 2404 | + $input.data(keys.attrs, { | |
| 2405 | + dir: $input.attr("dir"), | |
| 2406 | + autocomplete: $input.attr("autocomplete"), | |
| 2407 | + spellcheck: $input.attr("spellcheck"), | |
| 2408 | + style: $input.attr("style") | |
| 2409 | + }); | |
| 2410 | + $input.addClass(www.classes.input).attr({ | |
| 2411 | + autocomplete: "off", | |
| 2412 | + spellcheck: false | |
| 2413 | + }); | |
| 2414 | + try { | |
| 2415 | + !$input.attr("dir") && $input.attr("dir", "auto"); | |
| 2416 | + } catch (e) {} | |
| 2417 | + return $input; | |
| 2418 | + } | |
| 2419 | + function getBackgroundStyles($el) { | |
| 2420 | + return { | |
| 2421 | + backgroundAttachment: $el.css("background-attachment"), | |
| 2422 | + backgroundClip: $el.css("background-clip"), | |
| 2423 | + backgroundColor: $el.css("background-color"), | |
| 2424 | + backgroundImage: $el.css("background-image"), | |
| 2425 | + backgroundOrigin: $el.css("background-origin"), | |
| 2426 | + backgroundPosition: $el.css("background-position"), | |
| 2427 | + backgroundRepeat: $el.css("background-repeat"), | |
| 2428 | + backgroundSize: $el.css("background-size") | |
| 2429 | + }; | |
| 2430 | + } | |
| 2431 | + function revert($input) { | |
| 2432 | + var www, $wrapper; | |
| 2433 | + www = $input.data(keys.www); | |
| 2434 | + $wrapper = $input.parent().filter(www.selectors.wrapper); | |
| 2435 | + _.each($input.data(keys.attrs), function(val, key) { | |
| 2436 | + _.isUndefined(val) ? $input.removeAttr(key) : $input.attr(key, val); | |
| 2437 | + }); | |
| 2438 | + $input.removeData(keys.typeahead).removeData(keys.www).removeData(keys.attr).removeClass(www.classes.input); | |
| 2439 | + if ($wrapper.length) { | |
| 2440 | + $input.detach().insertAfter($wrapper); | |
| 2441 | + $wrapper.remove(); | |
| 2442 | + } | |
| 2443 | + } | |
| 2444 | + function $elOrNull(obj) { | |
| 2445 | + var isValid, $el; | |
| 2446 | + isValid = _.isJQuery(obj) || _.isElement(obj); | |
| 2447 | + $el = isValid ? $(obj).first() : []; | |
| 2448 | + return $el.length ? $el : null; | |
| 2449 | + } | |
| 2450 | + })(); | |
| 2451 | +}); | |
| \ No newline at end of file | ... | ... |
| ... | ... | @@ -2,6 +2,7 @@ |
| 2 | 2 | //= require kanjai/jquery-ui |
| 3 | 3 | //= require kanjai/admin/popper.js/popper.js |
| 4 | 4 | //= require kanjai/admin/bootstrap/bootstrap |
| 5 | +//= require kanjai/admin/tagsinput/typeahead | |
| 5 | 6 | //= require kanjai/rails |
| 6 | 7 | |
| 7 | 8 | |
| ... | ... | @@ -12,6 +13,8 @@ |
| 12 | 13 | //= require kanjai/lib/epiceditor |
| 13 | 14 | //= require kanjai/lib/fileinput |
| 14 | 15 | |
| 16 | +//= require kanjai/admin/jquery.fileupload | |
| 17 | + | |
| 15 | 18 | //= require kanjai/froala_editor/froala_editor.min |
| 16 | 19 | //= require kanjai/froala_editor/plugins/align.min |
| 17 | 20 | //= require kanjai/froala_editor/plugins/char_counter.min |
| ... | ... | @@ -37,4 +40,6 @@ |
| 37 | 40 | //= require kanjai/froala_editor/plugins/url.min |
| 38 | 41 | //= require kanjai/froala_editor/plugins/video.min |
| 39 | 42 | |
| 43 | + | |
| 44 | + | |
| 40 | 45 | //= require_tree ./admin/. | ... | ... |