From 88b51307b70324f17a91234553a6efab2f1e8c00 Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Thu, 1 Aug 2013 18:17:05 -0700 Subject: [PATCH 01/32] Update rails and README --- Gemfile | 27 ++++------ Gemfile.lock | 147 ++++++++++++++++++++++++++++++++------------------- README.md | 4 +- 3 files changed, 105 insertions(+), 73 deletions(-) diff --git a/Gemfile b/Gemfile index 6b62319..24dcf48 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'http://rubygems.org' -gem 'rails', '3.2.8' +gem 'rails', '3.2.14' gem 'will_paginate' gem 'haml-rails' @@ -17,21 +17,28 @@ gem 'symbolize' gem 'friendly_id', '~> 4.0.1' group :development do + gem 'better_errors' + gem 'binding_of_caller' + gem 'debugger' gem 'quiet_assets' gem 'bullet' gem 'pry-rails' + gem 'rails_best_practices' end group :assets do gem 'sass-rails', '~> 3.2.3' gem 'coffee-rails', '~> 3.2.1' gem 'uglifier', '>= 1.0.3' + gem 'therubyracer' gem 'compass-rails' gem 'fancybox-rails' end group :development, :test do - gem "rspec-rails", "~> 2.6" + gem 'rspec-rails' + gem 'single_test' + gem 'launchy' end group :test do @@ -39,6 +46,7 @@ group :test do gem 'factory_girl_rails' gem 'capybara-webkit' gem 'mocha', :require => false + gem 'simplecov' end platforms :ruby do @@ -50,18 +58,3 @@ platforms :ruby do gem 'mysql2' end end - -platforms :jruby do - gem 'activerecord-jdbc-adapter' - gem 'jruby-openssl' - gem 'trinidad' - gem 'ffi-ncurses' - - group :test, :development do - gem 'jdbc-sqlite3' - end - - group :production do - gem 'jdbc-mysql', :require => false - end -end diff --git a/Gemfile.lock b/Gemfile.lock index 6534b1d..c2b9ba8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,39 +1,45 @@ GEM remote: http://rubygems.org/ specs: - actionmailer (3.2.8) - actionpack (= 3.2.8) - mail (~> 2.4.4) - actionpack (3.2.8) - activemodel (= 3.2.8) - activesupport (= 3.2.8) + actionmailer (3.2.14) + actionpack (= 3.2.14) + mail (~> 2.5.4) + actionpack (3.2.14) + activemodel (= 3.2.14) + activesupport (= 3.2.14) builder (~> 3.0.0) erubis (~> 2.7.0) journey (~> 1.0.4) - rack (~> 1.4.0) + rack (~> 1.4.5) rack-cache (~> 1.2) rack-test (~> 0.6.1) - sprockets (~> 2.1.3) - activemodel (3.2.8) - activesupport (= 3.2.8) + sprockets (~> 2.2.1) + activemodel (3.2.14) + activesupport (= 3.2.14) builder (~> 3.0.0) - activerecord (3.2.8) - activemodel (= 3.2.8) - activesupport (= 3.2.8) + activerecord (3.2.14) + activemodel (= 3.2.14) + activesupport (= 3.2.14) arel (~> 3.0.2) tzinfo (~> 0.3.29) - activeresource (3.2.8) - activemodel (= 3.2.8) - activesupport (= 3.2.8) - activesupport (3.2.8) - i18n (~> 0.6) + activeresource (3.2.14) + activemodel (= 3.2.14) + activesupport (= 3.2.14) + activesupport (3.2.14) + i18n (~> 0.6, >= 0.6.4) multi_json (~> 1.0) acts-as-taggable-on (2.3.3) rails (~> 3.0) addressable (2.3.2) arel (3.0.2) + awesome_print (1.1.0) bcrypt-ruby (3.0.1) - builder (3.0.3) + better_errors (0.3.2) + coderay (>= 1.0.0) + erubis (>= 2.7.0) + binding_of_caller (0.7.1) + debug_inspector (>= 0.0.1) + builder (3.0.4) bullet (4.1.5) uniform_notifier (~> 1.0.0) capistrano (2.11.2) @@ -56,6 +62,8 @@ GEM ffi (~> 1.0, >= 1.0.6) chunky_png (1.2.5) cocaine (0.2.1) + code_analyzer (0.3.1) + sexp_processor coderay (1.0.7) coffee-rails (3.2.2) coffee-script (>= 2.2.0) @@ -64,6 +72,8 @@ GEM coffee-script-source execjs coffee-script-source (1.2.0) + colored (1.2) + columnize (0.3.6) compass (0.12.1) chunky_png (~> 1.2) fssm (>= 0.2.7) @@ -71,6 +81,13 @@ GEM compass-rails (1.0.1) compass (~> 0.12.0) database_cleaner (0.7.2) + debug_inspector (0.0.2) + debugger (1.6.0) + columnize (>= 0.3.1) + debugger-linecache (~> 1.2.0) + debugger-ruby_core_source (~> 1.2.1) + debugger-linecache (1.2.0) + debugger-ruby_core_source (1.2.2) devise (2.1.2) bcrypt-ruby (~> 3.0) orm_adapter (~> 0.1) @@ -97,25 +114,27 @@ GEM haml (~> 3.1) railties (>= 3.1, < 4.1) highline (1.6.11) - hike (1.2.1) - i18n (0.6.1) + hike (1.2.3) + i18n (0.6.4) journey (1.0.4) jquery-rails (2.0.2) railties (>= 3.2.0, < 5.0) thor (~> 0.14) - json (1.7.5) + json (1.8.0) + launchy (2.3.0) + addressable (~> 2.3) + libv8 (3.11.8.17) libwebsocket (0.1.5) addressable - mail (2.4.4) - i18n (>= 0.4.0) + mail (2.5.4) mime-types (~> 1.16) treetop (~> 1.4.8) metaclass (0.0.1) method_source (0.8) - mime-types (1.19) + mime-types (1.23) mocha (0.10.5) metaclass (~> 0.0.1) - multi_json (1.3.6) + multi_json (1.7.7) mysql2 (0.3.11) net-scp (1.0.4) net-ssh (>= 1.99.1) @@ -140,31 +159,40 @@ GEM pry quiet_assets (1.0.1) railties (~> 3.1) - rack (1.4.1) + rack (1.4.5) rack-cache (1.2) rack (>= 0.4) - rack-ssl (1.3.2) + rack-ssl (1.3.3) rack - rack-test (0.6.1) + rack-test (0.6.2) rack (>= 1.0) - rails (3.2.8) - actionmailer (= 3.2.8) - actionpack (= 3.2.8) - activerecord (= 3.2.8) - activeresource (= 3.2.8) - activesupport (= 3.2.8) + rails (3.2.14) + actionmailer (= 3.2.14) + actionpack (= 3.2.14) + activerecord (= 3.2.14) + activeresource (= 3.2.14) + activesupport (= 3.2.14) bundler (~> 1.0) - railties (= 3.2.8) - railties (3.2.8) - actionpack (= 3.2.8) - activesupport (= 3.2.8) + railties (= 3.2.14) + rails_best_practices (1.13.4) + activesupport + awesome_print + code_analyzer + colored + erubis + i18n + ruby-progressbar + railties (3.2.14) + actionpack (= 3.2.14) + activesupport (= 3.2.14) rack-ssl (~> 1.3.2) rake (>= 0.8.7) rdoc (~> 3.4) thor (>= 0.14.6, < 2.0) - rake (0.9.2.2) - rdoc (3.12) + rake (10.1.0) + rdoc (3.12.2) json (~> 1.4) + ref (1.0.4) rspec (2.9.0) rspec-core (~> 2.9.0) rspec-expectations (~> 2.9.0) @@ -178,6 +206,7 @@ GEM activesupport (>= 3.0) railties (>= 3.0) rspec (~> 2.9.0) + ruby-progressbar (1.0.2) rubyzip (0.9.9) sass (3.1.15) sass-rails (3.2.5) @@ -189,24 +218,33 @@ GEM libwebsocket (~> 0.1.3) multi_json (~> 1.0) rubyzip + sexp_processor (4.1.4) simple_form (2.0.2) actionpack (~> 3.0) activemodel (~> 3.0) + simplecov (0.7.1) + multi_json (~> 1.0) + simplecov-html (~> 0.7.1) + simplecov-html (0.7.1) single_test (0.4.4) slop (3.3.2) - sprockets (2.1.3) + sprockets (2.2.2) hike (~> 1.2) + multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) sqlite3 (1.3.5) symbolize (4.2.0) tabs_on_rails (2.1.1) - thor (0.16.0) - tilt (1.3.3) - treetop (1.4.10) + therubyracer (0.11.4) + libv8 (~> 3.11.8.12) + ref + thor (0.18.1) + tilt (1.4.1) + treetop (1.4.14) polyglot polyglot (>= 0.3.1) - tzinfo (0.3.33) + tzinfo (0.3.37) uglifier (1.2.3) execjs (>= 0.3.0) multi_json (>= 1.0.2) @@ -221,38 +259,39 @@ PLATFORMS ruby DEPENDENCIES - activerecord-jdbc-adapter acts-as-taggable-on + better_errors + binding_of_caller bullet capistrano capybara-webkit coffee-rails (~> 3.2.1) compass-rails database_cleaner + debugger devise factory_girl_rails fancybox-rails - ffi-ncurses friendly_id (~> 4.0.1) haml-rails - jdbc-mysql - jdbc-sqlite3 jquery-rails - jruby-openssl + launchy mime-types mocha mysql2 paperclip pry-rails quiet_assets - rails (= 3.2.8) - rspec-rails (~> 2.6) + rails (= 3.2.14) + rails_best_practices + rspec-rails sass-rails (~> 3.2.3) simple_form + simplecov single_test sqlite3 symbolize tabs_on_rails - trinidad + therubyracer uglifier (>= 1.0.3) will_paginate diff --git a/README.md b/README.md index 5570ee7..b9ff723 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Clover CMS [![Build Status](http://travis-ci.org/cloverinteractive/clovercms.png)](http://travis-ci.org/cloverinteractive/clovercms) +# Clover CMS [![Build Status](http://travis-ci.org/cloverinteractive/cms.png)](http://travis-ci.org/cloverinteractive/clovercms) -__A dead simple content management system for Rails 3.2.8__ +__A dead simple content management system for Rails 3.2.14__ CloveCMS provides the simpler barebones for creating a website, in v1.1 we embraced an even simpler approach by making it a single user app that means v1.1 does not support ACL nor multiple users, these features are present on v1.0, if you need ACL and multiple users checkout v1.0, From 82302136dfcd2c084ac79edf765d6fb9b2f5ac46 Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Wed, 19 Sep 2012 23:07:56 -0700 Subject: [PATCH 02/32] New improvements list --- Gemfile | 11 +- Gemfile.lock | 42 +- app/assets/javascripts/application.js | 3 +- app/assets/javascripts/global.js | 3 +- app/assets/stylesheets/main.scss | 1 + app/models/asset.rb | 3 + .../dashboard/pages/_page_editor.html.haml | 6 +- app/views/layouts/dashboard.html.haml | 3 +- .../layouts/dashboard/_navigation.html.haml | 9 +- vendor/assets/javascripts/markdown_editor.js | 4 + .../markdown_editor/Markdown.Converter.js | 1344 +++++++++++ .../markdown_editor/Markdown.Editor.js | 2110 +++++++++++++++++ .../markdown_editor/Markdown.Sanitizer.js | 111 + .../markdown_editor/load_editor.coffee | 5 + vendor/assets/javascripts/wymeditor.js | 21 - .../wymeditor/iframe/default/lbl-article.png | Bin 172 -> 0 bytes .../wymeditor/iframe/default/lbl-aside.png | Bin 168 -> 0 bytes .../iframe/default/lbl-blockquote.png | Bin 196 -> 0 bytes .../wymeditor/iframe/default/lbl-command.png | Bin 162 -> 0 bytes .../wymeditor/iframe/default/lbl-details.png | Bin 186 -> 0 bytes .../iframe/default/lbl-figcaption.png | Bin 180 -> 0 bytes .../wymeditor/iframe/default/lbl-figure.png | Bin 173 -> 0 bytes .../wymeditor/iframe/default/lbl-footer.png | Bin 168 -> 0 bytes .../wymeditor/iframe/default/lbl-h1.png | Bin 140 -> 0 bytes .../wymeditor/iframe/default/lbl-h2.png | Bin 146 -> 0 bytes .../wymeditor/iframe/default/lbl-h3.png | Bin 149 -> 0 bytes .../wymeditor/iframe/default/lbl-h4.png | Bin 141 -> 0 bytes .../wymeditor/iframe/default/lbl-h5.png | Bin 147 -> 0 bytes .../wymeditor/iframe/default/lbl-h6.png | Bin 145 -> 0 bytes .../wymeditor/iframe/default/lbl-header.png | Bin 181 -> 0 bytes .../wymeditor/iframe/default/lbl-hgroup.png | Bin 178 -> 0 bytes .../wymeditor/iframe/default/lbl-mark.png | Bin 163 -> 0 bytes .../wymeditor/iframe/default/lbl-meter.png | Bin 169 -> 0 bytes .../wymeditor/iframe/default/lbl-nav.png | Bin 163 -> 0 bytes .../wymeditor/iframe/default/lbl-p.png | Bin 129 -> 0 bytes .../wymeditor/iframe/default/lbl-pre.png | Bin 157 -> 0 bytes .../wymeditor/iframe/default/lbl-progress.png | Bin 191 -> 0 bytes .../wymeditor/iframe/default/lbl-rp.png | Bin 147 -> 0 bytes .../wymeditor/iframe/default/lbl-rt.png | Bin 145 -> 0 bytes .../wymeditor/iframe/default/lbl-ruby.png | Bin 171 -> 0 bytes .../wymeditor/iframe/default/lbl-section.png | Bin 169 -> 0 bytes .../wymeditor/iframe/default/lbl-summary.png | Bin 189 -> 0 bytes .../wymeditor/iframe/default/lbl-time.png | Bin 151 -> 0 bytes .../wymeditor/iframe/default/readme.md | 1 - .../wymeditor/iframe/default/wymiframe.css | 91 - .../wymeditor/iframe/default/wymiframe.html | 26 - .../wymeditor/jquery.wymeditor.min.js | 33 - .../assets/javascripts/wymeditor/lang/bg.js | 45 - .../assets/javascripts/wymeditor/lang/ca.js | 45 - .../assets/javascripts/wymeditor/lang/cs.js | 45 - .../assets/javascripts/wymeditor/lang/cy.js | 45 - .../assets/javascripts/wymeditor/lang/de.js | 45 - .../assets/javascripts/wymeditor/lang/en.js | 45 - .../assets/javascripts/wymeditor/lang/es.js | 45 - .../assets/javascripts/wymeditor/lang/fa.js | 46 - .../assets/javascripts/wymeditor/lang/fi.js | 44 - .../assets/javascripts/wymeditor/lang/fr.js | 45 - .../assets/javascripts/wymeditor/lang/gl.js | 45 - .../assets/javascripts/wymeditor/lang/he.js | 45 - .../assets/javascripts/wymeditor/lang/hr.js | 45 - .../assets/javascripts/wymeditor/lang/hu.js | 45 - .../assets/javascripts/wymeditor/lang/it.js | 45 - .../assets/javascripts/wymeditor/lang/ja.js | 44 - .../assets/javascripts/wymeditor/lang/lt.js | 45 - .../assets/javascripts/wymeditor/lang/nb.js | 45 - .../assets/javascripts/wymeditor/lang/nl.js | 45 - .../assets/javascripts/wymeditor/lang/nn.js | 45 - .../assets/javascripts/wymeditor/lang/pl.js | 45 - .../javascripts/wymeditor/lang/pt-br.js | 45 - .../assets/javascripts/wymeditor/lang/pt.js | 45 - .../assets/javascripts/wymeditor/lang/ru.js | 45 - .../assets/javascripts/wymeditor/lang/sv.js | 46 - .../assets/javascripts/wymeditor/lang/tr.js | 45 - .../javascripts/wymeditor/lang/zh_cn.js | 47 - .../plugins/embed/jquery.wymeditor.embed.js | 82 - .../plugins/fullscreen/icon_fullscreen.gif | Bin 509 -> 0 bytes .../fullscreen/jquery.wymeditor.fullscreen.js | 124 - .../hovertools/jquery.wymeditor.hovertools.js | 49 - .../plugins/list/jquery.wymeditor.list.js | 60 - .../plugins/rdfa/jquery.wymeditor.rdfa.js | 182 -- .../resizable/jquery.wymeditor.resizable.js | 77 - .../wymeditor/plugins/resizable/readme.txt | 124 - .../plugins/table/jquery.wymeditor.table.js | 676 ------ .../plugins/table/table_delete_column.png | Bin 744 -> 0 bytes .../plugins/table/table_delete_row.png | Bin 683 -> 0 bytes .../plugins/table/table_insert_column.png | Bin 720 -> 0 bytes .../plugins/table/table_insert_row.png | Bin 667 -> 0 bytes .../plugins/table/table_join_row.png | Bin 685 -> 0 bytes .../javascripts/wymeditor/plugins/tidy/README | 19 - .../plugins/tidy/jquery.wymeditor.tidy.js | 78 - .../wymeditor/plugins/tidy/tidy.php | 58 - .../wymeditor/plugins/tidy/wand.png | Bin 715 -> 0 bytes .../wymeditor/skins/compact/icons.png | Bin 3651 -> 0 bytes .../wymeditor/skins/compact/skin.css | 134 -- .../wymeditor/skins/compact/skin.js | 37 - .../wymeditor/skins/default/icons.png | Bin 3651 -> 0 bytes .../wymeditor/skins/default/skin.css | 133 -- .../wymeditor/skins/default/skin.js | 40 - .../skins/minimal/images/bg.header.gif | Bin 781 -> 0 bytes .../minimal/images/bg.selector.silver.gif | Bin 1621 -> 0 bytes .../skins/minimal/images/bg.wymeditor.png | Bin 498 -> 0 bytes .../skins/minimal/images/icons.silver.gif | Bin 15382 -> 0 bytes .../wymeditor/skins/minimal/skin.css | 131 - .../wymeditor/skins/minimal/skin.js | 30 - .../wymeditor/skins/silver/COPYING | 674 ------ .../javascripts/wymeditor/skins/silver/README | 27 - .../skins/silver/images/bg.header.gif | Bin 781 -> 0 bytes .../silver/images/bg.selector.silver.gif | Bin 1621 -> 0 bytes .../skins/silver/images/bg.wymeditor.png | Bin 498 -> 0 bytes .../skins/silver/images/icons.silver.gif | Bin 15382 -> 0 bytes .../wymeditor/skins/silver/skin.css | 297 --- .../wymeditor/skins/silver/skin.js | 61 - .../wymeditor/skins/twopanels/icons.png | Bin 3651 -> 0 bytes .../wymeditor/skins/twopanels/skin.css | 134 -- .../wymeditor/skins/twopanels/skin.js | 39 - .../wymeditor/skins/wymeditor_icon.png | Bin 1028 -> 0 bytes 116 files changed, 3628 insertions(+), 4682 deletions(-) create mode 100644 vendor/assets/javascripts/markdown_editor.js create mode 100644 vendor/assets/javascripts/markdown_editor/Markdown.Converter.js create mode 100644 vendor/assets/javascripts/markdown_editor/Markdown.Editor.js create mode 100644 vendor/assets/javascripts/markdown_editor/Markdown.Sanitizer.js create mode 100644 vendor/assets/javascripts/markdown_editor/load_editor.coffee delete mode 100644 vendor/assets/javascripts/wymeditor.js delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-article.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-aside.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-blockquote.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-command.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-details.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-figcaption.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-figure.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-footer.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-h1.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-h2.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-h3.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-h4.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-h5.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-h6.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-header.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-hgroup.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-mark.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-meter.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-nav.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-p.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-pre.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-progress.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-rp.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-rt.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-ruby.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-section.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-summary.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/lbl-time.png delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/readme.md delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/wymiframe.css delete mode 100644 vendor/assets/javascripts/wymeditor/iframe/default/wymiframe.html delete mode 100644 vendor/assets/javascripts/wymeditor/jquery.wymeditor.min.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/bg.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/ca.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/cs.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/cy.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/de.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/en.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/es.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/fa.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/fi.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/fr.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/gl.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/he.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/hr.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/hu.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/it.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/ja.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/lt.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/nb.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/nl.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/nn.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/pl.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/pt-br.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/pt.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/ru.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/sv.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/tr.js delete mode 100644 vendor/assets/javascripts/wymeditor/lang/zh_cn.js delete mode 100644 vendor/assets/javascripts/wymeditor/plugins/embed/jquery.wymeditor.embed.js delete mode 100644 vendor/assets/javascripts/wymeditor/plugins/fullscreen/icon_fullscreen.gif delete mode 100644 vendor/assets/javascripts/wymeditor/plugins/fullscreen/jquery.wymeditor.fullscreen.js delete mode 100644 vendor/assets/javascripts/wymeditor/plugins/hovertools/jquery.wymeditor.hovertools.js delete mode 100644 vendor/assets/javascripts/wymeditor/plugins/list/jquery.wymeditor.list.js delete mode 100644 vendor/assets/javascripts/wymeditor/plugins/rdfa/jquery.wymeditor.rdfa.js delete mode 100644 vendor/assets/javascripts/wymeditor/plugins/resizable/jquery.wymeditor.resizable.js delete mode 100644 vendor/assets/javascripts/wymeditor/plugins/resizable/readme.txt delete mode 100644 vendor/assets/javascripts/wymeditor/plugins/table/jquery.wymeditor.table.js delete mode 100644 vendor/assets/javascripts/wymeditor/plugins/table/table_delete_column.png delete mode 100644 vendor/assets/javascripts/wymeditor/plugins/table/table_delete_row.png delete mode 100644 vendor/assets/javascripts/wymeditor/plugins/table/table_insert_column.png delete mode 100644 vendor/assets/javascripts/wymeditor/plugins/table/table_insert_row.png delete mode 100644 vendor/assets/javascripts/wymeditor/plugins/table/table_join_row.png delete mode 100644 vendor/assets/javascripts/wymeditor/plugins/tidy/README delete mode 100644 vendor/assets/javascripts/wymeditor/plugins/tidy/jquery.wymeditor.tidy.js delete mode 100644 vendor/assets/javascripts/wymeditor/plugins/tidy/tidy.php delete mode 100644 vendor/assets/javascripts/wymeditor/plugins/tidy/wand.png delete mode 100644 vendor/assets/javascripts/wymeditor/skins/compact/icons.png delete mode 100644 vendor/assets/javascripts/wymeditor/skins/compact/skin.css delete mode 100644 vendor/assets/javascripts/wymeditor/skins/compact/skin.js delete mode 100644 vendor/assets/javascripts/wymeditor/skins/default/icons.png delete mode 100644 vendor/assets/javascripts/wymeditor/skins/default/skin.css delete mode 100644 vendor/assets/javascripts/wymeditor/skins/default/skin.js delete mode 100644 vendor/assets/javascripts/wymeditor/skins/minimal/images/bg.header.gif delete mode 100644 vendor/assets/javascripts/wymeditor/skins/minimal/images/bg.selector.silver.gif delete mode 100644 vendor/assets/javascripts/wymeditor/skins/minimal/images/bg.wymeditor.png delete mode 100644 vendor/assets/javascripts/wymeditor/skins/minimal/images/icons.silver.gif delete mode 100644 vendor/assets/javascripts/wymeditor/skins/minimal/skin.css delete mode 100644 vendor/assets/javascripts/wymeditor/skins/minimal/skin.js delete mode 100755 vendor/assets/javascripts/wymeditor/skins/silver/COPYING delete mode 100755 vendor/assets/javascripts/wymeditor/skins/silver/README delete mode 100644 vendor/assets/javascripts/wymeditor/skins/silver/images/bg.header.gif delete mode 100644 vendor/assets/javascripts/wymeditor/skins/silver/images/bg.selector.silver.gif delete mode 100644 vendor/assets/javascripts/wymeditor/skins/silver/images/bg.wymeditor.png delete mode 100644 vendor/assets/javascripts/wymeditor/skins/silver/images/icons.silver.gif delete mode 100644 vendor/assets/javascripts/wymeditor/skins/silver/skin.css delete mode 100644 vendor/assets/javascripts/wymeditor/skins/silver/skin.js delete mode 100644 vendor/assets/javascripts/wymeditor/skins/twopanels/icons.png delete mode 100644 vendor/assets/javascripts/wymeditor/skins/twopanels/skin.css delete mode 100644 vendor/assets/javascripts/wymeditor/skins/twopanels/skin.js delete mode 100644 vendor/assets/javascripts/wymeditor/skins/wymeditor_icon.png diff --git a/Gemfile b/Gemfile index 24dcf48..a5ebd58 100644 --- a/Gemfile +++ b/Gemfile @@ -2,15 +2,16 @@ source 'http://rubygems.org' gem 'rails', '3.2.14' -gem 'will_paginate' +gem 'bootstrap-will_paginate' gem 'haml-rails' gem 'devise' -gem 'paperclip' +gem 'devise_invitable' +gem 'carrierwave' +gem 'rmagick' gem 'acts-as-taggable-on' gem 'tabs_on_rails' gem 'jquery-rails' gem 'simple_form' -gem 'single_test' gem 'capistrano' gem 'mime-types', :require => 'mime/types' gem 'symbolize' @@ -32,6 +33,7 @@ group :assets do gem 'uglifier', '>= 1.0.3' gem 'therubyracer' gem 'compass-rails' + gem 'bootstrap-sass' gem 'fancybox-rails' end @@ -39,11 +41,12 @@ group :development, :test do gem 'rspec-rails' gem 'single_test' gem 'launchy' + gem 'evergreen', :group => [ :test, :development ], :require => 'evergreen/rails' end group :test do gem 'database_cleaner' - gem 'factory_girl_rails' + gem 'factory_girl_rails', '1.7.0' gem 'capybara-webkit' gem 'mocha', :require => false gem 'simplecov' diff --git a/Gemfile.lock b/Gemfile.lock index c2b9ba8..179470a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -39,6 +39,9 @@ GEM erubis (>= 2.7.0) binding_of_caller (0.7.1) debug_inspector (>= 0.0.1) + bootstrap-sass (2.1.0.0) + bootstrap-will_paginate (0.0.9) + will_paginate builder (3.0.4) bullet (4.1.5) uniform_notifier (~> 1.0.0) @@ -58,10 +61,12 @@ GEM capybara-webkit (0.12.1) capybara (>= 1.0.0, < 1.2) json + carrierwave (0.8.0) + activemodel (>= 3.2.0) + activesupport (>= 3.2.0) childprocess (0.3.5) ffi (~> 1.0, >= 1.0.6) chunky_png (1.2.5) - cocaine (0.2.1) code_analyzer (0.3.1) sexp_processor coderay (1.0.7) @@ -93,8 +98,18 @@ GEM orm_adapter (~> 0.1) railties (~> 3.1) warden (~> 1.2.1) + devise_invitable (1.1.8) + actionmailer (~> 3.0) + devise (>= 2.1.2) + railties (~> 3.0) diff-lcs (1.1.3) erubis (2.7.0) + evergreen (1.0.0) + capybara (~> 1.0) + coffee-script + json_pure + launchy + sinatra (~> 1.1) execjs (1.3.0) multi_json (~> 1.0) factory_girl (2.6.4) @@ -121,6 +136,7 @@ GEM railties (>= 3.2.0, < 5.0) thor (~> 0.14) json (1.8.0) + json_pure (1.8.0) launchy (2.3.0) addressable (~> 2.3) libv8 (3.11.8.17) @@ -145,11 +161,6 @@ GEM net-ssh (>= 1.99.1) nokogiri (1.5.5) orm_adapter (0.4.0) - paperclip (2.7.0) - activerecord (>= 2.3.0) - activesupport (>= 2.3.2) - cocaine (>= 0.0.2) - mime-types polyglot (0.3.3) pry (0.9.10) coderay (~> 1.0.5) @@ -162,6 +173,8 @@ GEM rack (1.4.5) rack-cache (1.2) rack (>= 0.4) + rack-protection (1.5.0) + rack rack-ssl (1.3.3) rack rack-test (0.6.2) @@ -193,6 +206,7 @@ GEM rdoc (3.12.2) json (~> 1.4) ref (1.0.4) + rmagick (2.13.2) rspec (2.9.0) rspec-core (~> 2.9.0) rspec-expectations (~> 2.9.0) @@ -226,6 +240,10 @@ GEM multi_json (~> 1.0) simplecov-html (~> 0.7.1) simplecov-html (0.7.1) + sinatra (1.3.6) + rack (~> 1.4) + rack-protection (~> 1.3) + tilt (~> 1.3, >= 1.3.3) single_test (0.4.4) slop (3.3.2) sprockets (2.2.2) @@ -251,7 +269,7 @@ GEM uniform_notifier (1.0.2) warden (1.2.1) rack (>= 1.0) - will_paginate (3.0.3) + will_paginate (3.0.4) xpath (0.1.4) nokogiri (~> 1.3) @@ -262,15 +280,20 @@ DEPENDENCIES acts-as-taggable-on better_errors binding_of_caller + bootstrap-sass + bootstrap-will_paginate bullet capistrano capybara-webkit + carrierwave coffee-rails (~> 3.2.1) compass-rails database_cleaner debugger devise - factory_girl_rails + devise_invitable + evergreen + factory_girl_rails (= 1.7.0) fancybox-rails friendly_id (~> 4.0.1) haml-rails @@ -279,11 +302,11 @@ DEPENDENCIES mime-types mocha mysql2 - paperclip pry-rails quiet_assets rails (= 3.2.14) rails_best_practices + rmagick rspec-rails sass-rails (~> 3.2.3) simple_form @@ -294,4 +317,3 @@ DEPENDENCIES tabs_on_rails therubyracer uglifier (>= 1.0.3) - will_paginate diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index e3b3f96..3897f2f 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -6,5 +6,6 @@ //= require fancybox //= require jquery.easing //= require loopedslider -//= require wymeditor +//= require bootstrap +//= require markdown_editor //= require_tree . diff --git a/app/assets/javascripts/global.js b/app/assets/javascripts/global.js index eb4083f..c6da081 100644 --- a/app/assets/javascripts/global.js +++ b/app/assets/javascripts/global.js @@ -1,8 +1,9 @@ +/* $(function() { $.fn.loopedSlider.defaults.addPagination = true; $('#slider').loopedSlider({ autoStart: 5000, containerClick: false }); }); - +*/ // Add images to editor function add_images() diff --git a/app/assets/stylesheets/main.scss b/app/assets/stylesheets/main.scss index e0404a9..83ffc5b 100644 --- a/app/assets/stylesheets/main.scss +++ b/app/assets/stylesheets/main.scss @@ -1,4 +1,5 @@ @import 'compass/reset'; +@import 'bootstrap'; #wrapper { .error, .warning, .info, .success { diff --git a/app/models/asset.rb b/app/models/asset.rb index d8ccc0a..02793e9 100644 --- a/app/models/asset.rb +++ b/app/models/asset.rb @@ -1,6 +1,8 @@ class Asset < ActiveRecord::Base belongs_to :attachable, :polymorphic => true + +=begin has_attached_file :asset, :styles => { :squared => "120x80#", :small => "120x80>", @@ -11,4 +13,5 @@ class Asset < ActiveRecord::Base validates_attachment_presence :asset validates_attachment_content_type :asset, :content_type => [ 'image/jpeg', 'image/png', 'image/gif' ] validates_attachment_size :asset, :less_than => 20.megabytes +=end end diff --git a/app/views/dashboard/pages/_page_editor.html.haml b/app/views/dashboard/pages/_page_editor.html.haml index 3719650..2f2c2a2 100644 --- a/app/views/dashboard/pages/_page_editor.html.haml +++ b/app/views/dashboard/pages/_page_editor.html.haml @@ -5,7 +5,10 @@ = t 'common.fields.name' %small= t 'common.descriptions.url.item_name', :item => t('activerecord.models.page').downcase = f.text_field :name - = f.text_area :content, :class => 'wymeditor' + + .wmd-panel + #wmd-button-bar + = f.text_area :content, :id => 'wmd-input', :class => 'wmd-input' %label{ :for => :page_section_id } = t 'activerecord.attributes.page.section' @@ -25,7 +28,6 @@ :javascript $(document).ready(function() { $('#tabs').tabs(); - $('.wymupdate').button({ icons: { primary: "ui-icon-circle-check" } }); $('.buttonset').buttonset(); $('.home_page').button({ icons: { primary: "ui-icon-home" } }); $('.contact_form').button({ icons: { primary: "ui-icon-mail-closed" } }); diff --git a/app/views/layouts/dashboard.html.haml b/app/views/layouts/dashboard.html.haml index 445c6b9..8e19ed0 100644 --- a/app/views/layouts/dashboard.html.haml +++ b/app/views/layouts/dashboard.html.haml @@ -2,12 +2,13 @@ = render 'layouts/dashboard/head', :selected_tab => selected_tab = render 'layouts/dashboard/navigation' = render 'layouts/dashboard/top' + !!! %html %head %title= content_for?(:title) ? yield(:title) : 'Dashboard' = javascript_include_tag :application - = stylesheet_link_tag 'dashboard' + = stylesheet_link_tag 'main', 'dashboard' = yield :head = csrf_meta_tag %body diff --git a/app/views/layouts/dashboard/_navigation.html.haml b/app/views/layouts/dashboard/_navigation.html.haml index 3d0c2bd..84376ff 100644 --- a/app/views/layouts/dashboard/_navigation.html.haml +++ b/app/views/layouts/dashboard/_navigation.html.haml @@ -1,13 +1,6 @@ - content_for :head do = stylesheet_link_tag 'jquery-ui' - = javascript_include_tag 'wymeditor/jquery.wymeditor.min', 'uploadify/uploadify.min', 'uploadify/swfobject' - :javascript - $(function() { - $("textarea.wymeditor").wymeditor({ - logoHtml: '', - skin: 'compact' - }); - }); + = javascript_include_tag 'uploadify/uploadify.min', 'uploadify/swfobject' - content_for :nav_wrap do %ul#nav diff --git a/vendor/assets/javascripts/markdown_editor.js b/vendor/assets/javascripts/markdown_editor.js new file mode 100644 index 0000000..f7b2ac5 --- /dev/null +++ b/vendor/assets/javascripts/markdown_editor.js @@ -0,0 +1,4 @@ +//= require markdown_editor/Markdown.Converter +//= require markdown_editor/Markdown.Sanitizer +//= require markdown_editor/Markdown.Editor +//= require markdown_editor/load_editor diff --git a/vendor/assets/javascripts/markdown_editor/Markdown.Converter.js b/vendor/assets/javascripts/markdown_editor/Markdown.Converter.js new file mode 100644 index 0000000..d1a6431 --- /dev/null +++ b/vendor/assets/javascripts/markdown_editor/Markdown.Converter.js @@ -0,0 +1,1344 @@ +var Markdown; + +if (typeof exports === "object" && typeof require === "function") // we're in a CommonJS (e.g. Node.js) module + Markdown = exports; +else + Markdown = {}; + +// The following text is included for historical reasons, but should +// be taken with a pinch of salt; it's not all true anymore. + +// +// Wherever possible, Showdown is a straight, line-by-line port +// of the Perl version of Markdown. +// +// This is not a normal parser design; it's basically just a +// series of string substitutions. It's hard to read and +// maintain this way, but keeping Showdown close to the original +// design makes it easier to port new features. +// +// More importantly, Showdown behaves like markdown.pl in most +// edge cases. So web applications can do client-side preview +// in Javascript, and then build identical HTML on the server. +// +// This port needs the new RegExp functionality of ECMA 262, +// 3rd Edition (i.e. Javascript 1.5). Most modern web browsers +// should do fine. Even with the new regular expression features, +// We do a lot of work to emulate Perl's regex functionality. +// The tricky changes in this file mostly have the "attacklab:" +// label. Major or self-explanatory changes don't. +// +// Smart diff tools like Araxis Merge will be able to match up +// this file with markdown.pl in a useful way. A little tweaking +// helps: in a copy of markdown.pl, replace "#" with "//" and +// replace "$text" with "text". Be sure to ignore whitespace +// and line endings. +// + + +// +// Usage: +// +// var text = "Markdown *rocks*."; +// +// var converter = new Markdown.Converter(); +// var html = converter.makeHtml(text); +// +// alert(html); +// +// Note: move the sample code to the bottom of this +// file before uncommenting it. +// + +(function () { + + function identity(x) { return x; } + function returnFalse(x) { return false; } + + function HookCollection() { } + + HookCollection.prototype = { + + chain: function (hookname, func) { + var original = this[hookname]; + if (!original) + throw new Error("unknown hook " + hookname); + + if (original === identity) + this[hookname] = func; + else + this[hookname] = function (x) { return func(original(x)); } + }, + set: function (hookname, func) { + if (!this[hookname]) + throw new Error("unknown hook " + hookname); + this[hookname] = func; + }, + addNoop: function (hookname) { + this[hookname] = identity; + }, + addFalse: function (hookname) { + this[hookname] = returnFalse; + } + }; + + Markdown.HookCollection = HookCollection; + + // g_urls and g_titles allow arbitrary user-entered strings as keys. This + // caused an exception (and hence stopped the rendering) when the user entered + // e.g. [push] or [__proto__]. Adding a prefix to the actual key prevents this + // (since no builtin property starts with "s_"). See + // http://meta.stackoverflow.com/questions/64655/strange-wmd-bug + // (granted, switching from Array() to Object() alone would have left only __proto__ + // to be a problem) + function SaveHash() { } + SaveHash.prototype = { + set: function (key, value) { + this["s_" + key] = value; + }, + get: function (key) { + return this["s_" + key]; + } + }; + + Markdown.Converter = function () { + var pluginHooks = this.hooks = new HookCollection(); + pluginHooks.addNoop("plainLinkText"); // given a URL that was encountered by itself (without markup), should return the link text that's to be given to this link + pluginHooks.addNoop("preConversion"); // called with the orignal text as given to makeHtml. The result of this plugin hook is the actual markdown source that will be cooked + pluginHooks.addNoop("postConversion"); // called with the final cooked HTML code. The result of this plugin hook is the actual output of makeHtml + + // + // Private state of the converter instance: + // + + // Global hashes, used by various utility routines + var g_urls; + var g_titles; + var g_html_blocks; + + // Used to track when we're inside an ordered or unordered list + // (see _ProcessListItems() for details): + var g_list_level; + + this.makeHtml = function (text) { + + // + // Main function. The order in which other subs are called here is + // essential. Link and image substitutions need to happen before + // _EscapeSpecialCharsWithinTagAttributes(), so that any *'s or _'s in the + // and tags get encoded. + // + + // This will only happen if makeHtml on the same converter instance is called from a plugin hook. + // Don't do that. + if (g_urls) + throw new Error("Recursive call to converter.makeHtml"); + + // Create the private state objects. + g_urls = new SaveHash(); + g_titles = new SaveHash(); + g_html_blocks = []; + g_list_level = 0; + + text = pluginHooks.preConversion(text); + + // attacklab: Replace ~ with ~T + // This lets us use tilde as an escape char to avoid md5 hashes + // The choice of character is arbitray; anything that isn't + // magic in Markdown will work. + text = text.replace(/~/g, "~T"); + + // attacklab: Replace $ with ~D + // RegExp interprets $ as a special character + // when it's in a replacement string + text = text.replace(/\$/g, "~D"); + + // Standardize line endings + text = text.replace(/\r\n/g, "\n"); // DOS to Unix + text = text.replace(/\r/g, "\n"); // Mac to Unix + + // Make sure text begins and ends with a couple of newlines: + text = "\n\n" + text + "\n\n"; + + // Convert all tabs to spaces. + text = _Detab(text); + + // Strip any lines consisting only of spaces and tabs. + // This makes subsequent regexen easier to write, because we can + // match consecutive blank lines with /\n+/ instead of something + // contorted like /[ \t]*\n+/ . + text = text.replace(/^[ \t]+$/mg, ""); + + // Turn block-level HTML blocks into hash entries + text = _HashHTMLBlocks(text); + + // Strip link definitions, store in hashes. + text = _StripLinkDefinitions(text); + + text = _RunBlockGamut(text); + + text = _UnescapeSpecialChars(text); + + // attacklab: Restore dollar signs + text = text.replace(/~D/g, "$$"); + + // attacklab: Restore tildes + text = text.replace(/~T/g, "~"); + + text = pluginHooks.postConversion(text); + + g_html_blocks = g_titles = g_urls = null; + + return text; + }; + + function _StripLinkDefinitions(text) { + // + // Strips link definitions from text, stores the URLs and titles in + // hash references. + // + + // Link defs are in the form: ^[id]: url "optional title" + + /* + text = text.replace(/ + ^[ ]{0,3}\[(.+)\]: // id = $1 attacklab: g_tab_width - 1 + [ \t]* + \n? // maybe *one* newline + [ \t]* + ? // url = $2 + (?=\s|$) // lookahead for whitespace instead of the lookbehind removed below + [ \t]* + \n? // maybe one newline + [ \t]* + ( // (potential) title = $3 + (\n*) // any lines skipped = $4 attacklab: lookbehind removed + [ \t]+ + ["(] + (.+?) // title = $5 + [")] + [ \t]* + )? // title is optional + (?:\n+|$) + /gm, function(){...}); + */ + + text = text.replace(/^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*?(?=\s|$)[ \t]*\n?[ \t]*((\n*)["(](.+?)[")][ \t]*)?(?:\n+)/gm, + function (wholeMatch, m1, m2, m3, m4, m5) { + m1 = m1.toLowerCase(); + g_urls.set(m1, _EncodeAmpsAndAngles(m2)); // Link IDs are case-insensitive + if (m4) { + // Oops, found blank lines, so it's not a title. + // Put back the parenthetical statement we stole. + return m3; + } else if (m5) { + g_titles.set(m1, m5.replace(/"/g, """)); + } + + // Completely remove the definition from the text + return ""; + } + ); + + return text; + } + + function _HashHTMLBlocks(text) { + + // Hashify HTML blocks: + // We only want to do this for block-level HTML tags, such as headers, + // lists, and tables. That's because we still want to wrap

s around + // "paragraphs" that are wrapped in non-block-level tags, such as anchors, + // phrase emphasis, and spans. The list of tags we're looking for is + // hard-coded: + var block_tags_a = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del" + var block_tags_b = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math" + + // First, look for nested blocks, e.g.: + //

+ //
+ // tags for inner block must be indented. + //
+ //
+ // + // The outermost tags must start at the left margin for this to match, and + // the inner nested divs must be indented. + // We need to do this before the next, more liberal match, because the next + // match will start at the first `
` and stop at the first `
`. + + // attacklab: This regex can be expensive when it fails. + + /* + text = text.replace(/ + ( // save in $1 + ^ // start of line (with /m) + <($block_tags_a) // start tag = $2 + \b // word break + // attacklab: hack around khtml/pcre bug... + [^\r]*?\n // any number of lines, minimally matching + // the matching end tag + [ \t]* // trailing spaces/tabs + (?=\n+) // followed by a newline + ) // attacklab: there are sentinel newlines at end of document + /gm,function(){...}}; + */ + text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b[^\r]*?\n<\/\2>[ \t]*(?=\n+))/gm, hashElement); + + // + // Now match more liberally, simply from `\n` to `\n` + // + + /* + text = text.replace(/ + ( // save in $1 + ^ // start of line (with /m) + <($block_tags_b) // start tag = $2 + \b // word break + // attacklab: hack around khtml/pcre bug... + [^\r]*? // any number of lines, minimally matching + .* // the matching end tag + [ \t]* // trailing spaces/tabs + (?=\n+) // followed by a newline + ) // attacklab: there are sentinel newlines at end of document + /gm,function(){...}}; + */ + text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math)\b[^\r]*?.*<\/\2>[ \t]*(?=\n+)\n)/gm, hashElement); + + // Special case just for
. It was easier to make a special case than + // to make the other regex more complicated. + + /* + text = text.replace(/ + \n // Starting after a blank line + [ ]{0,3} + ( // save in $1 + (<(hr) // start tag = $2 + \b // word break + ([^<>])*? + \/?>) // the matching end tag + [ \t]* + (?=\n{2,}) // followed by a blank line + ) + /g,hashElement); + */ + text = text.replace(/\n[ ]{0,3}((<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g, hashElement); + + // Special case for standalone HTML comments: + + /* + text = text.replace(/ + \n\n // Starting after a blank line + [ ]{0,3} // attacklab: g_tab_width - 1 + ( // save in $1 + -]|-[^>])(?:[^-]|-[^-])*)--) // see http://www.w3.org/TR/html-markup/syntax.html#comments and http://meta.stackoverflow.com/q/95256 + > + [ \t]* + (?=\n{2,}) // followed by a blank line + ) + /g,hashElement); + */ + text = text.replace(/\n\n[ ]{0,3}(-]|-[^>])(?:[^-]|-[^-])*)--)>[ \t]*(?=\n{2,}))/g, hashElement); + + // PHP and ASP-style processor instructions ( and <%...%>) + + /* + text = text.replace(/ + (?: + \n\n // Starting after a blank line + ) + ( // save in $1 + [ ]{0,3} // attacklab: g_tab_width - 1 + (?: + <([?%]) // $2 + [^\r]*? + \2> + ) + [ \t]* + (?=\n{2,}) // followed by a blank line + ) + /g,hashElement); + */ + text = text.replace(/(?:\n\n)([ ]{0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g, hashElement); + + return text; + } + + function hashElement(wholeMatch, m1) { + var blockText = m1; + + // Undo double lines + blockText = blockText.replace(/^\n+/, ""); + + // strip trailing blank lines + blockText = blockText.replace(/\n+$/g, ""); + + // Replace the element text with a marker ("~KxK" where x is its key) + blockText = "\n\n~K" + (g_html_blocks.push(blockText) - 1) + "K\n\n"; + + return blockText; + } + + function _RunBlockGamut(text, doNotUnhash) { + // + // These are all the transformations that form block-level + // tags like paragraphs, headers, and list items. + // + text = _DoHeaders(text); + + // Do Horizontal Rules: + var replacement = "
\n"; + text = text.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm, replacement); + text = text.replace(/^[ ]{0,2}([ ]?-[ ]?){3,}[ \t]*$/gm, replacement); + text = text.replace(/^[ ]{0,2}([ ]?_[ ]?){3,}[ \t]*$/gm, replacement); + + text = _DoLists(text); + text = _DoCodeBlocks(text); + text = _DoBlockQuotes(text); + + // We already ran _HashHTMLBlocks() before, in Markdown(), but that + // was to escape raw HTML in the original Markdown source. This time, + // we're escaping the markup we've just created, so that we don't wrap + //

tags around block-level tags. + text = _HashHTMLBlocks(text); + text = _FormParagraphs(text, doNotUnhash); + + return text; + } + + function _RunSpanGamut(text) { + // + // These are all the transformations that occur *within* block-level + // tags like paragraphs, headers, and list items. + // + + text = _DoCodeSpans(text); + text = _EscapeSpecialCharsWithinTagAttributes(text); + text = _EncodeBackslashEscapes(text); + + // Process anchor and image tags. Images must come first, + // because ![foo][f] looks like an anchor. + text = _DoImages(text); + text = _DoAnchors(text); + + // Make links out of things like `` + // Must come after _DoAnchors(), because you can use < and > + // delimiters in inline links like [this](). + text = _DoAutoLinks(text); + + text = text.replace(/~P/g, "://"); // put in place to prevent autolinking; reset now + + text = _EncodeAmpsAndAngles(text); + text = _DoItalicsAndBold(text); + + // Do hard breaks: + text = text.replace(/ +\n/g, "
\n"); + + return text; + } + + function _EscapeSpecialCharsWithinTagAttributes(text) { + // + // Within tags -- meaning between < and > -- encode [\ ` * _] so they + // don't conflict with their use in Markdown for code, italics and strong. + // + + // Build a regex to find HTML tags and comments. See Friedl's + // "Mastering Regular Expressions", 2nd Ed., pp. 200-201. + + // SE: changed the comment part of the regex + + var regex = /(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|-]|-[^>])(?:[^-]|-[^-])*)--)>)/gi; + + text = text.replace(regex, function (wholeMatch) { + var tag = wholeMatch.replace(/(.)<\/?code>(?=.)/g, "$1`"); + tag = escapeCharacters(tag, wholeMatch.charAt(1) == "!" ? "\\`*_/" : "\\`*_"); // also escape slashes in comments to prevent autolinking there -- http://meta.stackoverflow.com/questions/95987 + return tag; + }); + + return text; + } + + function _DoAnchors(text) { + // + // Turn Markdown link shortcuts into XHTML
tags. + // + // + // First, handle reference-style links: [link text] [id] + // + + /* + text = text.replace(/ + ( // wrap whole match in $1 + \[ + ( + (?: + \[[^\]]*\] // allow brackets nested one level + | + [^\[] // or anything else + )* + ) + \] + + [ ]? // one optional space + (?:\n[ ]*)? // one optional newline followed by spaces + + \[ + (.*?) // id = $3 + \] + ) + ()()()() // pad remaining backreferences + /g, writeAnchorTag); + */ + text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g, writeAnchorTag); + + // + // Next, inline-style links: [link text](url "optional title") + // + + /* + text = text.replace(/ + ( // wrap whole match in $1 + \[ + ( + (?: + \[[^\]]*\] // allow brackets nested one level + | + [^\[\]] // or anything else + )* + ) + \] + \( // literal paren + [ \t]* + () // no id, so leave $3 empty + ? + [ \t]* + ( // $5 + (['"]) // quote char = $6 + (.*?) // Title = $7 + \6 // matching quote + [ \t]* // ignore any spaces/tabs between closing quote and ) + )? // title is optional + \) + ) + /g, writeAnchorTag); + */ + + text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g, writeAnchorTag); + + // + // Last, handle reference-style shortcuts: [link text] + // These must come last in case you've also got [link test][1] + // or [link test](/foo) + // + + /* + text = text.replace(/ + ( // wrap whole match in $1 + \[ + ([^\[\]]+) // link text = $2; can't contain '[' or ']' + \] + ) + ()()()()() // pad rest of backreferences + /g, writeAnchorTag); + */ + text = text.replace(/(\[([^\[\]]+)\])()()()()()/g, writeAnchorTag); + + return text; + } + + function writeAnchorTag(wholeMatch, m1, m2, m3, m4, m5, m6, m7) { + if (m7 == undefined) m7 = ""; + var whole_match = m1; + var link_text = m2.replace(/:\/\//g, "~P"); // to prevent auto-linking withing the link. will be converted back after the auto-linker runs + var link_id = m3.toLowerCase(); + var url = m4; + var title = m7; + + if (url == "") { + if (link_id == "") { + // lower-case and turn embedded newlines into spaces + link_id = link_text.toLowerCase().replace(/ ?\n/g, " "); + } + url = "#" + link_id; + + if (g_urls.get(link_id) != undefined) { + url = g_urls.get(link_id); + if (g_titles.get(link_id) != undefined) { + title = g_titles.get(link_id); + } + } + else { + if (whole_match.search(/\(\s*\)$/m) > -1) { + // Special case for explicit empty url + url = ""; + } else { + return whole_match; + } + } + } + url = encodeProblemUrlChars(url); + url = escapeCharacters(url, "*_"); + var result = ""; + + return result; + } + + function _DoImages(text) { + // + // Turn Markdown image shortcuts into tags. + // + + // + // First, handle reference-style labeled images: ![alt text][id] + // + + /* + text = text.replace(/ + ( // wrap whole match in $1 + !\[ + (.*?) // alt text = $2 + \] + + [ ]? // one optional space + (?:\n[ ]*)? // one optional newline followed by spaces + + \[ + (.*?) // id = $3 + \] + ) + ()()()() // pad rest of backreferences + /g, writeImageTag); + */ + text = text.replace(/(!\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g, writeImageTag); + + // + // Next, handle inline images: ![alt text](url "optional title") + // Don't forget: encode * and _ + + /* + text = text.replace(/ + ( // wrap whole match in $1 + !\[ + (.*?) // alt text = $2 + \] + \s? // One optional whitespace character + \( // literal paren + [ \t]* + () // no id, so leave $3 empty + ? // src url = $4 + [ \t]* + ( // $5 + (['"]) // quote char = $6 + (.*?) // title = $7 + \6 // matching quote + [ \t]* + )? // title is optional + \) + ) + /g, writeImageTag); + */ + text = text.replace(/(!\[(.*?)\]\s?\([ \t]*()?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g, writeImageTag); + + return text; + } + + function attributeEncode(text) { + // unconditionally replace angle brackets here -- what ends up in an attribute (e.g. alt or title) + // never makes sense to have verbatim HTML in it (and the sanitizer would totally break it) + return text.replace(/>/g, ">").replace(/" + _RunSpanGamut(m1) + "\n\n"; } + ); + + text = text.replace(/^(.+)[ \t]*\n-+[ \t]*\n+/gm, + function (matchFound, m1) { return "

" + _RunSpanGamut(m1) + "

\n\n"; } + ); + + // atx-style headers: + // # Header 1 + // ## Header 2 + // ## Header 2 with closing hashes ## + // ... + // ###### Header 6 + // + + /* + text = text.replace(/ + ^(\#{1,6}) // $1 = string of #'s + [ \t]* + (.+?) // $2 = Header text + [ \t]* + \#* // optional closing #'s (not counted) + \n+ + /gm, function() {...}); + */ + + text = text.replace(/^(\#{1,6})[ \t]*(.+?)[ \t]*\#*\n+/gm, + function (wholeMatch, m1, m2) { + var h_level = m1.length; + return "" + _RunSpanGamut(m2) + "\n\n"; + } + ); + + return text; + } + + function _DoLists(text) { + // + // Form HTML ordered (numbered) and unordered (bulleted) lists. + // + + // attacklab: add sentinel to hack around khtml/safari bug: + // http://bugs.webkit.org/show_bug.cgi?id=11231 + text += "~0"; + + // Re-usable pattern to match any entirel ul or ol list: + + /* + var whole_list = / + ( // $1 = whole list + ( // $2 + [ ]{0,3} // attacklab: g_tab_width - 1 + ([*+-]|\d+[.]) // $3 = first list item marker + [ \t]+ + ) + [^\r]+? + ( // $4 + ~0 // sentinel for workaround; should be $ + | + \n{2,} + (?=\S) + (?! // Negative lookahead for another list item marker + [ \t]* + (?:[*+-]|\d+[.])[ \t]+ + ) + ) + ) + /g + */ + var whole_list = /^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm; + + if (g_list_level) { + text = text.replace(whole_list, function (wholeMatch, m1, m2) { + var list = m1; + var list_type = (m2.search(/[*+-]/g) > -1) ? "ul" : "ol"; + + var result = _ProcessListItems(list, list_type); + + // Trim any trailing whitespace, to put the closing `` + // up on the preceding line, to get it past the current stupid + // HTML block parser. This is a hack to work around the terrible + // hack that is the HTML block parser. + result = result.replace(/\s+$/, ""); + result = "<" + list_type + ">" + result + "\n"; + return result; + }); + } else { + whole_list = /(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/g; + text = text.replace(whole_list, function (wholeMatch, m1, m2, m3) { + var runup = m1; + var list = m2; + + var list_type = (m3.search(/[*+-]/g) > -1) ? "ul" : "ol"; + var result = _ProcessListItems(list, list_type); + result = runup + "<" + list_type + ">\n" + result + "\n"; + return result; + }); + } + + // attacklab: strip sentinel + text = text.replace(/~0/, ""); + + return text; + } + + var _listItemMarkers = { ol: "\\d+[.]", ul: "[*+-]" }; + + function _ProcessListItems(list_str, list_type) { + // + // Process the contents of a single ordered or unordered list, splitting it + // into individual list items. + // + // list_type is either "ul" or "ol". + + // The $g_list_level global keeps track of when we're inside a list. + // Each time we enter a list, we increment it; when we leave a list, + // we decrement. If it's zero, we're not in a list anymore. + // + // We do this because when we're not inside a list, we want to treat + // something like this: + // + // I recommend upgrading to version + // 8. Oops, now this line is treated + // as a sub-list. + // + // As a single paragraph, despite the fact that the second line starts + // with a digit-period-space sequence. + // + // Whereas when we're inside a list (or sub-list), that line will be + // treated as the start of a sub-list. What a kludge, huh? This is + // an aspect of Markdown's syntax that's hard to parse perfectly + // without resorting to mind-reading. Perhaps the solution is to + // change the syntax rules such that sub-lists must start with a + // starting cardinal number; e.g. "1." or "a.". + + g_list_level++; + + // trim trailing blank lines: + list_str = list_str.replace(/\n{2,}$/, "\n"); + + // attacklab: add sentinel to emulate \z + list_str += "~0"; + + // In the original attacklab showdown, list_type was not given to this function, and anything + // that matched /[*+-]|\d+[.]/ would just create the next
  • , causing this mismatch: + // + // Markdown rendered by WMD rendered by MarkdownSharp + // ------------------------------------------------------------------ + // 1. first 1. first 1. first + // 2. second 2. second 2. second + // - third 3. third * third + // + // We changed this to behave identical to MarkdownSharp. This is the constructed RegEx, + // with {MARKER} being one of \d+[.] or [*+-], depending on list_type: + + /* + list_str = list_str.replace(/ + (^[ \t]*) // leading whitespace = $1 + ({MARKER}) [ \t]+ // list marker = $2 + ([^\r]+? // list item text = $3 + (\n+) + ) + (?= + (~0 | \2 ({MARKER}) [ \t]+) + ) + /gm, function(){...}); + */ + + var marker = _listItemMarkers[list_type]; + var re = new RegExp("(^[ \\t]*)(" + marker + ")[ \\t]+([^\\r]+?(\\n+))(?=(~0|\\1(" + marker + ")[ \\t]+))", "gm"); + var last_item_had_a_double_newline = false; + list_str = list_str.replace(re, + function (wholeMatch, m1, m2, m3) { + var item = m3; + var leading_space = m1; + var ends_with_double_newline = /\n\n$/.test(item); + var contains_double_newline = ends_with_double_newline || item.search(/\n{2,}/) > -1; + + if (contains_double_newline || last_item_had_a_double_newline) { + item = _RunBlockGamut(_Outdent(item), /* doNotUnhash = */true); + } + else { + // Recursion for sub-lists: + item = _DoLists(_Outdent(item)); + item = item.replace(/\n$/, ""); // chomp(item) + item = _RunSpanGamut(item); + } + last_item_had_a_double_newline = ends_with_double_newline; + return "
  • " + item + "
  • \n"; + } + ); + + // attacklab: strip sentinel + list_str = list_str.replace(/~0/g, ""); + + g_list_level--; + return list_str; + } + + function _DoCodeBlocks(text) { + // + // Process Markdown `
    ` blocks.
    +            //  
    +
    +            /*
    +            text = text.replace(/
    +                (?:\n\n|^)
    +                (                               // $1 = the code block -- one or more lines, starting with a space/tab
    +                    (?:
    +                        (?:[ ]{4}|\t)           // Lines must start with a tab or a tab-width of spaces - attacklab: g_tab_width
    +                        .*\n+
    +                    )+
    +                )
    +                (\n*[ ]{0,3}[^ \t\n]|(?=~0))    // attacklab: g_tab_width
    +            /g ,function(){...});
    +            */
    +
    +            // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
    +            text += "~0";
    +
    +            text = text.replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g,
    +                function (wholeMatch, m1, m2) {
    +                    var codeblock = m1;
    +                    var nextChar = m2;
    +
    +                    codeblock = _EncodeCode(_Outdent(codeblock));
    +                    codeblock = _Detab(codeblock);
    +                    codeblock = codeblock.replace(/^\n+/g, ""); // trim leading newlines
    +                    codeblock = codeblock.replace(/\n+$/g, ""); // trim trailing whitespace
    +
    +                    codeblock = '
    ' + codeblock + '\n
    '; + + return "\n\n" + codeblock + "\n\n" + nextChar; + } + ); + + // attacklab: strip sentinel + text = text.replace(/~0/, ""); + + return text; + } + + function hashBlock(text) { + text = text.replace(/(^\n+|\n+$)/g, ""); + return "\n\n~K" + (g_html_blocks.push(text) - 1) + "K\n\n"; + } + + function _DoCodeSpans(text) { + // + // * Backtick quotes are used for spans. + // + // * You can use multiple backticks as the delimiters if you want to + // include literal backticks in the code span. So, this input: + // + // Just type ``foo `bar` baz`` at the prompt. + // + // Will translate to: + // + //

    Just type foo `bar` baz at the prompt.

    + // + // There's no arbitrary limit to the number of backticks you + // can use as delimters. If you need three consecutive backticks + // in your code, use four for delimiters, etc. + // + // * You can use spaces to get literal backticks at the edges: + // + // ... type `` `bar` `` ... + // + // Turns to: + // + // ... type `bar` ... + // + + /* + text = text.replace(/ + (^|[^\\]) // Character before opening ` can't be a backslash + (`+) // $2 = Opening run of ` + ( // $3 = The code block + [^\r]*? + [^`] // attacklab: work around lack of lookbehind + ) + \2 // Matching closer + (?!`) + /gm, function(){...}); + */ + + text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm, + function (wholeMatch, m1, m2, m3, m4) { + var c = m3; + c = c.replace(/^([ \t]*)/g, ""); // leading whitespace + c = c.replace(/[ \t]*$/g, ""); // trailing whitespace + c = _EncodeCode(c); + c = c.replace(/:\/\//g, "~P"); // to prevent auto-linking. Not necessary in code *blocks*, but in code spans. Will be converted back after the auto-linker runs. + return m1 + "" + c + ""; + } + ); + + return text; + } + + function _EncodeCode(text) { + // + // Encode/escape certain characters inside Markdown code runs. + // The point is that in code, these characters are literals, + // and lose their special Markdown meanings. + // + // Encode all ampersands; HTML entities are not + // entities within a Markdown code span. + text = text.replace(/&/g, "&"); + + // Do the angle bracket song and dance: + text = text.replace(//g, ">"); + + // Now, escape characters that are magic in Markdown: + text = escapeCharacters(text, "\*_{}[]\\", false); + + // jj the line above breaks this: + //--- + + //* Item + + // 1. Subitem + + // special char: * + //--- + + return text; + } + + function _DoItalicsAndBold(text) { + + // must go first: + text = text.replace(/([\W_]|^)(\*\*|__)(?=\S)([^\r]*?\S[\*_]*)\2([\W_]|$)/g, + "$1$3$4"); + + text = text.replace(/([\W_]|^)(\*|_)(?=\S)([^\r\*_]*?\S)\2([\W_]|$)/g, + "$1$3$4"); + + return text; + } + + function _DoBlockQuotes(text) { + + /* + text = text.replace(/ + ( // Wrap whole match in $1 + ( + ^[ \t]*>[ \t]? // '>' at the start of a line + .+\n // rest of the first line + (.+\n)* // subsequent consecutive lines + \n* // blanks + )+ + ) + /gm, function(){...}); + */ + + text = text.replace(/((^[ \t]*>[ \t]?.+\n(.+\n)*\n*)+)/gm, + function (wholeMatch, m1) { + var bq = m1; + + // attacklab: hack around Konqueror 3.5.4 bug: + // "----------bug".replace(/^-/g,"") == "bug" + + bq = bq.replace(/^[ \t]*>[ \t]?/gm, "~0"); // trim one level of quoting + + // attacklab: clean up hack + bq = bq.replace(/~0/g, ""); + + bq = bq.replace(/^[ \t]+$/gm, ""); // trim whitespace-only lines + bq = _RunBlockGamut(bq); // recurse + + bq = bq.replace(/(^|\n)/g, "$1 "); + // These leading spaces screw with
     content, so we need to fix that:
    +                    bq = bq.replace(
    +                            /(\s*
    [^\r]+?<\/pre>)/gm,
    +                        function (wholeMatch, m1) {
    +                            var pre = m1;
    +                            // attacklab: hack around Konqueror 3.5.4 bug:
    +                            pre = pre.replace(/^  /mg, "~0");
    +                            pre = pre.replace(/~0/g, "");
    +                            return pre;
    +                        });
    +
    +                    return hashBlock("
    \n" + bq + "\n
    "); + } + ); + return text; + } + + function _FormParagraphs(text, doNotUnhash) { + // + // Params: + // $text - string to process with html

    tags + // + + // Strip leading and trailing lines: + text = text.replace(/^\n+/g, ""); + text = text.replace(/\n+$/g, ""); + + var grafs = text.split(/\n{2,}/g); + var grafsOut = []; + + var markerRe = /~K(\d+)K/; + + // + // Wrap

    tags. + // + var end = grafs.length; + for (var i = 0; i < end; i++) { + var str = grafs[i]; + + // if this is an HTML marker, copy it + if (markerRe.test(str)) { + grafsOut.push(str); + } + else if (/\S/.test(str)) { + str = _RunSpanGamut(str); + str = str.replace(/^([ \t]*)/g, "

    "); + str += "

    " + grafsOut.push(str); + } + + } + // + // Unhashify HTML blocks + // + if (!doNotUnhash) { + end = grafsOut.length; + for (var i = 0; i < end; i++) { + var foundAny = true; + while (foundAny) { // we may need several runs, since the data may be nested + foundAny = false; + grafsOut[i] = grafsOut[i].replace(/~K(\d+)K/g, function (wholeMatch, id) { + foundAny = true; + return g_html_blocks[id]; + }); + } + } + } + return grafsOut.join("\n\n"); + } + + function _EncodeAmpsAndAngles(text) { + // Smart processing for ampersands and angle brackets that need to be encoded. + + // Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin: + // http://bumppo.net/projects/amputator/ + text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g, "&"); + + // Encode naked <'s + text = text.replace(/<(?![a-z\/?\$!])/gi, "<"); + + return text; + } + + function _EncodeBackslashEscapes(text) { + // + // Parameter: String. + // Returns: The string, with after processing the following backslash + // escape sequences. + // + + // attacklab: The polite way to do this is with the new + // escapeCharacters() function: + // + // text = escapeCharacters(text,"\\",true); + // text = escapeCharacters(text,"`*_{}[]()>#+-.!",true); + // + // ...but we're sidestepping its use of the (slow) RegExp constructor + // as an optimization for Firefox. This function gets called a LOT. + + text = text.replace(/\\(\\)/g, escapeCharacters_callback); + text = text.replace(/\\([`*_{}\[\]()>#+-.!])/g, escapeCharacters_callback); + return text; + } + + function _DoAutoLinks(text) { + + // note that at this point, all other URL in the text are already hyperlinked as
    + // *except* for the case + + // automatically add < and > around unadorned raw hyperlinks + // must be preceded by space/BOF and followed by non-word/EOF character + text = text.replace(/(^|\s)(https?|ftp)(:\/\/[-A-Z0-9+&@#\/%?=~_|\[\]\(\)!:,\.;]*[-A-Z0-9+&@#\/%=~_|\[\]])($|\W)/gi, "$1<$2$3>$4"); + + // autolink anything like + + var replacer = function (wholematch, m1) { return "" + pluginHooks.plainLinkText(m1) + ""; } + text = text.replace(/<((https?|ftp):[^'">\s]+)>/gi, replacer); + + // Email addresses: + /* + text = text.replace(/ + < + (?:mailto:)? + ( + [-.\w]+ + \@ + [-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+ + ) + > + /gi, _DoAutoLinks_callback()); + */ + + var email_replacer = function(wholematch, m1) { + var mailto = 'mailto:' + var link + var email + if (m1.substring(0, mailto.length) != mailto){ + link = mailto + m1; + email = m1; + } else { + link = m1; + email = m1.substring(mailto.length, m1.length); + } + return "" + pluginHooks.plainLinkText(email) + ""; + } + text = text.replace(/<((?:mailto:)?([-.\w]+\@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+))>/gi, email_replacer); + + return text; + } + + function _UnescapeSpecialChars(text) { + // + // Swap back in all the special characters we've hidden. + // + text = text.replace(/~E(\d+)E/g, + function (wholeMatch, m1) { + var charCodeToReplace = parseInt(m1); + return String.fromCharCode(charCodeToReplace); + } + ); + return text; + } + + function _Outdent(text) { + // + // Remove one level of line-leading tabs or spaces + // + + // attacklab: hack around Konqueror 3.5.4 bug: + // "----------bug".replace(/^-/g,"") == "bug" + + text = text.replace(/^(\t|[ ]{1,4})/gm, "~0"); // attacklab: g_tab_width + + // attacklab: clean up hack + text = text.replace(/~0/g, "") + + return text; + } + + function _Detab(text) { + if (!/\t/.test(text)) + return text; + + var spaces = [" ", " ", " ", " "], + skew = 0, + v; + + return text.replace(/[\n\t]/g, function (match, offset) { + if (match === "\n") { + skew = offset + 1; + return match; + } + v = (offset - skew) % 4; + skew = offset + 1; + return spaces[v]; + }); + } + + // + // attacklab: Utility functions + // + + var _problemUrlChars = /(?:["'*()[\]:]|~D)/g; + + // hex-encodes some unusual "problem" chars in URLs to avoid URL detection problems + function encodeProblemUrlChars(url) { + if (!url) + return ""; + + var len = url.length; + + return url.replace(_problemUrlChars, function (match, offset) { + if (match == "~D") // escape for dollar + return "%24"; + if (match == ":") { + if (offset == len - 1 || /[0-9\/]/.test(url.charAt(offset + 1))) + return ":"; + if (url.substring(0, 'mailto:'.length) === 'mailto:') + return ":"; + if (url.substring(0, 'magnet:'.length) === 'magnet:') + return ":"; + } + return "%" + match.charCodeAt(0).toString(16); + }); + } + + + function escapeCharacters(text, charsToEscape, afterBackslash) { + // First we have to escape the escape characters so that + // we can build a character class out of them + var regexString = "([" + charsToEscape.replace(/([\[\]\\])/g, "\\$1") + "])"; + + if (afterBackslash) { + regexString = "\\\\" + regexString; + } + + var regex = new RegExp(regexString, "g"); + text = text.replace(regex, escapeCharacters_callback); + + return text; + } + + + function escapeCharacters_callback(wholeMatch, m1) { + var charCodeToEscape = m1.charCodeAt(0); + return "~E" + charCodeToEscape + "E"; + } + + }; // end of the Markdown.Converter constructor + +})(); diff --git a/vendor/assets/javascripts/markdown_editor/Markdown.Editor.js b/vendor/assets/javascripts/markdown_editor/Markdown.Editor.js new file mode 100644 index 0000000..d229fcd --- /dev/null +++ b/vendor/assets/javascripts/markdown_editor/Markdown.Editor.js @@ -0,0 +1,2110 @@ +// needs Markdown.Converter.js at the moment + +(function () { + + var util = {}, + position = {}, + ui = {}, + doc = window.document, + re = window.RegExp, + nav = window.navigator, + SETTINGS = { lineLength: 72 }, + + // Used to work around some browser bugs where we can't use feature testing. + uaSniffed = { + isIE: /msie/.test(nav.userAgent.toLowerCase()), + isIE_5or6: /msie 6/.test(nav.userAgent.toLowerCase()) || /msie 5/.test(nav.userAgent.toLowerCase()), + isOpera: /opera/.test(nav.userAgent.toLowerCase()) + }; + + + // ------------------------------------------------------------------- + // YOUR CHANGES GO HERE + // + // I've tried to localize the things you are likely to change to + // this area. + // ------------------------------------------------------------------- + + // The text that appears on the upper part of the dialog box when + // entering links. + var linkDialogText = "

    http://example.com/ \"optional title\"

    "; + var imageDialogText = "

    http://example.com/images/diagram.jpg \"optional title\"

    "; + + // The default text that appears in the dialog input box when entering + // links. + var imageDefaultText = "http://"; + var linkDefaultText = "http://"; + + var defaultHelpHoverTitle = "Markdown Editing Help"; + + // ------------------------------------------------------------------- + // END OF YOUR CHANGES + // ------------------------------------------------------------------- + + // help, if given, should have a property "handler", the click handler for the help button, + // and can have an optional property "title" for the button's tooltip (defaults to "Markdown Editing Help"). + // If help isn't given, not help button is created. + // + // The constructed editor object has the methods: + // - getConverter() returns the markdown converter object that was passed to the constructor + // - run() actually starts the editor; should be called after all necessary plugins are registered. Calling this more than once is a no-op. + // - refreshPreview() forces the preview to be updated. This method is only available after run() was called. + Markdown.Editor = function (markdownConverter, idPostfix, help) { + + idPostfix = idPostfix || ""; + + var hooks = this.hooks = new Markdown.HookCollection(); + hooks.addNoop("onPreviewRefresh"); // called with no arguments after the preview has been refreshed + hooks.addNoop("postBlockquoteCreation"); // called with the user's selection *after* the blockquote was created; should return the actual to-be-inserted text + hooks.addFalse("insertImageDialog"); /* called with one parameter: a callback to be called with the URL of the image. If the application creates + * its own image insertion dialog, this hook should return true, and the callback should be called with the chosen + * image url (or null if the user cancelled). If this hook returns false, the default dialog will be used. + */ + + this.getConverter = function () { return markdownConverter; } + + var that = this, + panels; + + this.run = function () { + if (panels) + return; // already initialized + + panels = new PanelCollection(idPostfix); + var commandManager = new CommandManager(hooks); + var previewManager = new PreviewManager(markdownConverter, panels, function () { hooks.onPreviewRefresh(); }); + var undoManager, uiManager; + + if (!/\?noundo/.test(doc.location.href)) { + undoManager = new UndoManager(function () { + previewManager.refresh(); + if (uiManager) // not available on the first call + uiManager.setUndoRedoButtonStates(); + }, panels); + this.textOperation = function (f) { + undoManager.setCommandMode(); + f(); + that.refreshPreview(); + } + } + + uiManager = new UIManager(idPostfix, panels, undoManager, previewManager, commandManager, help); + uiManager.setUndoRedoButtonStates(); + + var forceRefresh = that.refreshPreview = function () { previewManager.refresh(true); }; + + forceRefresh(); + }; + + } + + // before: contains all the text in the input box BEFORE the selection. + // after: contains all the text in the input box AFTER the selection. + function Chunks() { } + + // startRegex: a regular expression to find the start tag + // endRegex: a regular expresssion to find the end tag + Chunks.prototype.findTags = function (startRegex, endRegex) { + + var chunkObj = this; + var regex; + + if (startRegex) { + + regex = util.extendRegExp(startRegex, "", "$"); + + this.before = this.before.replace(regex, + function (match) { + chunkObj.startTag = chunkObj.startTag + match; + return ""; + }); + + regex = util.extendRegExp(startRegex, "^", ""); + + this.selection = this.selection.replace(regex, + function (match) { + chunkObj.startTag = chunkObj.startTag + match; + return ""; + }); + } + + if (endRegex) { + + regex = util.extendRegExp(endRegex, "", "$"); + + this.selection = this.selection.replace(regex, + function (match) { + chunkObj.endTag = match + chunkObj.endTag; + return ""; + }); + + regex = util.extendRegExp(endRegex, "^", ""); + + this.after = this.after.replace(regex, + function (match) { + chunkObj.endTag = match + chunkObj.endTag; + return ""; + }); + } + }; + + // If remove is false, the whitespace is transferred + // to the before/after regions. + // + // If remove is true, the whitespace disappears. + Chunks.prototype.trimWhitespace = function (remove) { + var beforeReplacer, afterReplacer, that = this; + if (remove) { + beforeReplacer = afterReplacer = ""; + } else { + beforeReplacer = function (s) { that.before += s; return ""; } + afterReplacer = function (s) { that.after = s + that.after; return ""; } + } + + this.selection = this.selection.replace(/^(\s*)/, beforeReplacer).replace(/(\s*)$/, afterReplacer); + }; + + + Chunks.prototype.skipLines = function (nLinesBefore, nLinesAfter, findExtraNewlines) { + + if (nLinesBefore === undefined) { + nLinesBefore = 1; + } + + if (nLinesAfter === undefined) { + nLinesAfter = 1; + } + + nLinesBefore++; + nLinesAfter++; + + var regexText; + var replacementText; + + // chrome bug ... documented at: http://meta.stackoverflow.com/questions/63307/blockquote-glitch-in-editor-in-chrome-6-and-7/65985#65985 + if (navigator.userAgent.match(/Chrome/)) { + "X".match(/()./); + } + + this.selection = this.selection.replace(/(^\n*)/, ""); + + this.startTag = this.startTag + re.$1; + + this.selection = this.selection.replace(/(\n*$)/, ""); + this.endTag = this.endTag + re.$1; + this.startTag = this.startTag.replace(/(^\n*)/, ""); + this.before = this.before + re.$1; + this.endTag = this.endTag.replace(/(\n*$)/, ""); + this.after = this.after + re.$1; + + if (this.before) { + + regexText = replacementText = ""; + + while (nLinesBefore--) { + regexText += "\\n?"; + replacementText += "\n"; + } + + if (findExtraNewlines) { + regexText = "\\n*"; + } + this.before = this.before.replace(new re(regexText + "$", ""), replacementText); + } + + if (this.after) { + + regexText = replacementText = ""; + + while (nLinesAfter--) { + regexText += "\\n?"; + replacementText += "\n"; + } + if (findExtraNewlines) { + regexText = "\\n*"; + } + + this.after = this.after.replace(new re(regexText, ""), replacementText); + } + }; + + // end of Chunks + + // A collection of the important regions on the page. + // Cached so we don't have to keep traversing the DOM. + // Also holds ieCachedRange and ieCachedScrollTop, where necessary; working around + // this issue: + // Internet explorer has problems with CSS sprite buttons that use HTML + // lists. When you click on the background image "button", IE will + // select the non-existent link text and discard the selection in the + // textarea. The solution to this is to cache the textarea selection + // on the button's mousedown event and set a flag. In the part of the + // code where we need to grab the selection, we check for the flag + // and, if it's set, use the cached area instead of querying the + // textarea. + // + // This ONLY affects Internet Explorer (tested on versions 6, 7 + // and 8) and ONLY on button clicks. Keyboard shortcuts work + // normally since the focus never leaves the textarea. + function PanelCollection(postfix) { + this.buttonBar = doc.getElementById("wmd-button-bar" + postfix); + this.preview = doc.getElementById("wmd-preview" + postfix); + this.input = doc.getElementById("wmd-input" + postfix); + }; + + // Returns true if the DOM element is visible, false if it's hidden. + // Checks if display is anything other than none. + util.isVisible = function (elem) { + + if (window.getComputedStyle) { + // Most browsers + return window.getComputedStyle(elem, null).getPropertyValue("display") !== "none"; + } + else if (elem.currentStyle) { + // IE + return elem.currentStyle["display"] !== "none"; + } + }; + + + // Adds a listener callback to a DOM element which is fired on a specified + // event. + util.addEvent = function (elem, event, listener) { + if (elem.attachEvent) { + // IE only. The "on" is mandatory. + elem.attachEvent("on" + event, listener); + } + else { + // Other browsers. + elem.addEventListener(event, listener, false); + } + }; + + + // Removes a listener callback from a DOM element which is fired on a specified + // event. + util.removeEvent = function (elem, event, listener) { + if (elem.detachEvent) { + // IE only. The "on" is mandatory. + elem.detachEvent("on" + event, listener); + } + else { + // Other browsers. + elem.removeEventListener(event, listener, false); + } + }; + + // Converts \r\n and \r to \n. + util.fixEolChars = function (text) { + text = text.replace(/\r\n/g, "\n"); + text = text.replace(/\r/g, "\n"); + return text; + }; + + // Extends a regular expression. Returns a new RegExp + // using pre + regex + post as the expression. + // Used in a few functions where we have a base + // expression and we want to pre- or append some + // conditions to it (e.g. adding "$" to the end). + // The flags are unchanged. + // + // regex is a RegExp, pre and post are strings. + util.extendRegExp = function (regex, pre, post) { + + if (pre === null || pre === undefined) { + pre = ""; + } + if (post === null || post === undefined) { + post = ""; + } + + var pattern = regex.toString(); + var flags; + + // Replace the flags with empty space and store them. + pattern = pattern.replace(/\/([gim]*)$/, function (wholeMatch, flagsPart) { + flags = flagsPart; + return ""; + }); + + // Remove the slash delimiters on the regular expression. + pattern = pattern.replace(/(^\/|\/$)/g, ""); + pattern = pre + pattern + post; + + return new re(pattern, flags); + } + + // UNFINISHED + // The assignment in the while loop makes jslint cranky. + // I'll change it to a better loop later. + position.getTop = function (elem, isInner) { + var result = elem.offsetTop; + if (!isInner) { + while (elem = elem.offsetParent) { + result += elem.offsetTop; + } + } + return result; + }; + + position.getHeight = function (elem) { + return elem.offsetHeight || elem.scrollHeight; + }; + + position.getWidth = function (elem) { + return elem.offsetWidth || elem.scrollWidth; + }; + + position.getPageSize = function () { + + var scrollWidth, scrollHeight; + var innerWidth, innerHeight; + + // It's not very clear which blocks work with which browsers. + if (self.innerHeight && self.scrollMaxY) { + scrollWidth = doc.body.scrollWidth; + scrollHeight = self.innerHeight + self.scrollMaxY; + } + else if (doc.body.scrollHeight > doc.body.offsetHeight) { + scrollWidth = doc.body.scrollWidth; + scrollHeight = doc.body.scrollHeight; + } + else { + scrollWidth = doc.body.offsetWidth; + scrollHeight = doc.body.offsetHeight; + } + + if (self.innerHeight) { + // Non-IE browser + innerWidth = self.innerWidth; + innerHeight = self.innerHeight; + } + else if (doc.documentElement && doc.documentElement.clientHeight) { + // Some versions of IE (IE 6 w/ a DOCTYPE declaration) + innerWidth = doc.documentElement.clientWidth; + innerHeight = doc.documentElement.clientHeight; + } + else if (doc.body) { + // Other versions of IE + innerWidth = doc.body.clientWidth; + innerHeight = doc.body.clientHeight; + } + + var maxWidth = Math.max(scrollWidth, innerWidth); + var maxHeight = Math.max(scrollHeight, innerHeight); + return [maxWidth, maxHeight, innerWidth, innerHeight]; + }; + + // Handles pushing and popping TextareaStates for undo/redo commands. + // I should rename the stack variables to list. + function UndoManager(callback, panels) { + + var undoObj = this; + var undoStack = []; // A stack of undo states + var stackPtr = 0; // The index of the current state + var mode = "none"; + var lastState; // The last state + var timer; // The setTimeout handle for cancelling the timer + var inputStateObj; + + // Set the mode for later logic steps. + var setMode = function (newMode, noSave) { + if (mode != newMode) { + mode = newMode; + if (!noSave) { + saveState(); + } + } + + if (!uaSniffed.isIE || mode != "moving") { + timer = setTimeout(refreshState, 1); + } + else { + inputStateObj = null; + } + }; + + var refreshState = function (isInitialState) { + inputStateObj = new TextareaState(panels, isInitialState); + timer = undefined; + }; + + this.setCommandMode = function () { + mode = "command"; + saveState(); + timer = setTimeout(refreshState, 0); + }; + + this.canUndo = function () { + return stackPtr > 1; + }; + + this.canRedo = function () { + if (undoStack[stackPtr + 1]) { + return true; + } + return false; + }; + + // Removes the last state and restores it. + this.undo = function () { + + if (undoObj.canUndo()) { + if (lastState) { + // What about setting state -1 to null or checking for undefined? + lastState.restore(); + lastState = null; + } + else { + undoStack[stackPtr] = new TextareaState(panels); + undoStack[--stackPtr].restore(); + + if (callback) { + callback(); + } + } + } + + mode = "none"; + panels.input.focus(); + refreshState(); + }; + + // Redo an action. + this.redo = function () { + + if (undoObj.canRedo()) { + + undoStack[++stackPtr].restore(); + + if (callback) { + callback(); + } + } + + mode = "none"; + panels.input.focus(); + refreshState(); + }; + + // Push the input area state to the stack. + var saveState = function () { + var currState = inputStateObj || new TextareaState(panels); + + if (!currState) { + return false; + } + if (mode == "moving") { + if (!lastState) { + lastState = currState; + } + return; + } + if (lastState) { + if (undoStack[stackPtr - 1].text != lastState.text) { + undoStack[stackPtr++] = lastState; + } + lastState = null; + } + undoStack[stackPtr++] = currState; + undoStack[stackPtr + 1] = null; + if (callback) { + callback(); + } + }; + + var handleCtrlYZ = function (event) { + + var handled = false; + + if (event.ctrlKey || event.metaKey) { + + // IE and Opera do not support charCode. + var keyCode = event.charCode || event.keyCode; + var keyCodeChar = String.fromCharCode(keyCode); + + switch (keyCodeChar) { + + case "y": + undoObj.redo(); + handled = true; + break; + + case "z": + if (!event.shiftKey) { + undoObj.undo(); + } + else { + undoObj.redo(); + } + handled = true; + break; + } + } + + if (handled) { + if (event.preventDefault) { + event.preventDefault(); + } + if (window.event) { + window.event.returnValue = false; + } + return; + } + }; + + // Set the mode depending on what is going on in the input area. + var handleModeChange = function (event) { + + if (!event.ctrlKey && !event.metaKey) { + + var keyCode = event.keyCode; + + if ((keyCode >= 33 && keyCode <= 40) || (keyCode >= 63232 && keyCode <= 63235)) { + // 33 - 40: page up/dn and arrow keys + // 63232 - 63235: page up/dn and arrow keys on safari + setMode("moving"); + } + else if (keyCode == 8 || keyCode == 46 || keyCode == 127) { + // 8: backspace + // 46: delete + // 127: delete + setMode("deleting"); + } + else if (keyCode == 13) { + // 13: Enter + setMode("newlines"); + } + else if (keyCode == 27) { + // 27: escape + setMode("escape"); + } + else if ((keyCode < 16 || keyCode > 20) && keyCode != 91) { + // 16-20 are shift, etc. + // 91: left window key + // I think this might be a little messed up since there are + // a lot of nonprinting keys above 20. + setMode("typing"); + } + } + }; + + var setEventHandlers = function () { + util.addEvent(panels.input, "keypress", function (event) { + // keyCode 89: y + // keyCode 90: z + if ((event.ctrlKey || event.metaKey) && (event.keyCode == 89 || event.keyCode == 90)) { + event.preventDefault(); + } + }); + + var handlePaste = function () { + if (uaSniffed.isIE || (inputStateObj && inputStateObj.text != panels.input.value)) { + if (timer == undefined) { + mode = "paste"; + saveState(); + refreshState(); + } + } + }; + + util.addEvent(panels.input, "keydown", handleCtrlYZ); + util.addEvent(panels.input, "keydown", handleModeChange); + util.addEvent(panels.input, "mousedown", function () { + setMode("moving"); + }); + + panels.input.onpaste = handlePaste; + panels.input.ondrop = handlePaste; + }; + + var init = function () { + setEventHandlers(); + refreshState(true); + saveState(); + }; + + init(); + } + + // end of UndoManager + + // The input textarea state/contents. + // This is used to implement undo/redo by the undo manager. + function TextareaState(panels, isInitialState) { + + // Aliases + var stateObj = this; + var inputArea = panels.input; + this.init = function () { + if (!util.isVisible(inputArea)) { + return; + } + if (!isInitialState && doc.activeElement && doc.activeElement !== inputArea) { // this happens when tabbing out of the input box + return; + } + + this.setInputAreaSelectionStartEnd(); + this.scrollTop = inputArea.scrollTop; + if (!this.text && inputArea.selectionStart || inputArea.selectionStart === 0) { + this.text = inputArea.value; + } + + } + + // Sets the selected text in the input box after we've performed an + // operation. + this.setInputAreaSelection = function () { + + if (!util.isVisible(inputArea)) { + return; + } + + if (inputArea.selectionStart !== undefined && !uaSniffed.isOpera) { + + inputArea.focus(); + inputArea.selectionStart = stateObj.start; + inputArea.selectionEnd = stateObj.end; + inputArea.scrollTop = stateObj.scrollTop; + } + else if (doc.selection) { + + if (doc.activeElement && doc.activeElement !== inputArea) { + return; + } + + inputArea.focus(); + var range = inputArea.createTextRange(); + range.moveStart("character", -inputArea.value.length); + range.moveEnd("character", -inputArea.value.length); + range.moveEnd("character", stateObj.end); + range.moveStart("character", stateObj.start); + range.select(); + } + }; + + this.setInputAreaSelectionStartEnd = function () { + + if (!panels.ieCachedRange && (inputArea.selectionStart || inputArea.selectionStart === 0)) { + + stateObj.start = inputArea.selectionStart; + stateObj.end = inputArea.selectionEnd; + } + else if (doc.selection) { + + stateObj.text = util.fixEolChars(inputArea.value); + + // IE loses the selection in the textarea when buttons are + // clicked. On IE we cache the selection. Here, if something is cached, + // we take it. + var range = panels.ieCachedRange || doc.selection.createRange(); + + var fixedRange = util.fixEolChars(range.text); + var marker = "\x07"; + var markedRange = marker + fixedRange + marker; + range.text = markedRange; + var inputText = util.fixEolChars(inputArea.value); + + range.moveStart("character", -markedRange.length); + range.text = fixedRange; + + stateObj.start = inputText.indexOf(marker); + stateObj.end = inputText.lastIndexOf(marker) - marker.length; + + var len = stateObj.text.length - util.fixEolChars(inputArea.value).length; + + if (len) { + range.moveStart("character", -fixedRange.length); + while (len--) { + fixedRange += "\n"; + stateObj.end += 1; + } + range.text = fixedRange; + } + + if (panels.ieCachedRange) + stateObj.scrollTop = panels.ieCachedScrollTop; // this is set alongside with ieCachedRange + + panels.ieCachedRange = null; + + this.setInputAreaSelection(); + } + }; + + // Restore this state into the input area. + this.restore = function () { + + if (stateObj.text != undefined && stateObj.text != inputArea.value) { + inputArea.value = stateObj.text; + } + this.setInputAreaSelection(); + inputArea.scrollTop = stateObj.scrollTop; + }; + + // Gets a collection of HTML chunks from the inptut textarea. + this.getChunks = function () { + + var chunk = new Chunks(); + chunk.before = util.fixEolChars(stateObj.text.substring(0, stateObj.start)); + chunk.startTag = ""; + chunk.selection = util.fixEolChars(stateObj.text.substring(stateObj.start, stateObj.end)); + chunk.endTag = ""; + chunk.after = util.fixEolChars(stateObj.text.substring(stateObj.end)); + chunk.scrollTop = stateObj.scrollTop; + + return chunk; + }; + + // Sets the TextareaState properties given a chunk of markdown. + this.setChunks = function (chunk) { + + chunk.before = chunk.before + chunk.startTag; + chunk.after = chunk.endTag + chunk.after; + + this.start = chunk.before.length; + this.end = chunk.before.length + chunk.selection.length; + this.text = chunk.before + chunk.selection + chunk.after; + this.scrollTop = chunk.scrollTop; + }; + this.init(); + }; + + function PreviewManager(converter, panels, previewRefreshCallback) { + + var managerObj = this; + var timeout; + var elapsedTime; + var oldInputText; + var maxDelay = 3000; + var startType = "delayed"; // The other legal value is "manual" + + // Adds event listeners to elements + var setupEvents = function (inputElem, listener) { + + util.addEvent(inputElem, "input", listener); + inputElem.onpaste = listener; + inputElem.ondrop = listener; + + util.addEvent(inputElem, "keypress", listener); + util.addEvent(inputElem, "keydown", listener); + }; + + var getDocScrollTop = function () { + + var result = 0; + + if (window.innerHeight) { + result = window.pageYOffset; + } + else + if (doc.documentElement && doc.documentElement.scrollTop) { + result = doc.documentElement.scrollTop; + } + else + if (doc.body) { + result = doc.body.scrollTop; + } + + return result; + }; + + var makePreviewHtml = function () { + + // If there is no registered preview panel + // there is nothing to do. + if (!panels.preview) + return; + + + var text = panels.input.value; + if (text && text == oldInputText) { + return; // Input text hasn't changed. + } + else { + oldInputText = text; + } + + var prevTime = new Date().getTime(); + + text = converter.makeHtml(text); + + // Calculate the processing time of the HTML creation. + // It's used as the delay time in the event listener. + var currTime = new Date().getTime(); + elapsedTime = currTime - prevTime; + + pushPreviewHtml(text); + }; + + // setTimeout is already used. Used as an event listener. + var applyTimeout = function () { + + if (timeout) { + clearTimeout(timeout); + timeout = undefined; + } + + if (startType !== "manual") { + + var delay = 0; + + if (startType === "delayed") { + delay = elapsedTime; + } + + if (delay > maxDelay) { + delay = maxDelay; + } + timeout = setTimeout(makePreviewHtml, delay); + } + }; + + var getScaleFactor = function (panel) { + if (panel.scrollHeight <= panel.clientHeight) { + return 1; + } + return panel.scrollTop / (panel.scrollHeight - panel.clientHeight); + }; + + var setPanelScrollTops = function () { + if (panels.preview) { + panels.preview.scrollTop = (panels.preview.scrollHeight - panels.preview.clientHeight) * getScaleFactor(panels.preview); + } + }; + + this.refresh = function (requiresRefresh) { + + if (requiresRefresh) { + oldInputText = ""; + makePreviewHtml(); + } + else { + applyTimeout(); + } + }; + + this.processingTime = function () { + return elapsedTime; + }; + + var isFirstTimeFilled = true; + + // IE doesn't let you use innerHTML if the element is contained somewhere in a table + // (which is the case for inline editing) -- in that case, detach the element, set the + // value, and reattach. Yes, that *is* ridiculous. + var ieSafePreviewSet = function (text) { + var preview = panels.preview; + var parent = preview.parentNode; + var sibling = preview.nextSibling; + parent.removeChild(preview); + preview.innerHTML = text; + if (!sibling) + parent.appendChild(preview); + else + parent.insertBefore(preview, sibling); + } + + var nonSuckyBrowserPreviewSet = function (text) { + panels.preview.innerHTML = text; + } + + var previewSetter; + + var previewSet = function (text) { + if (previewSetter) + return previewSetter(text); + + try { + nonSuckyBrowserPreviewSet(text); + previewSetter = nonSuckyBrowserPreviewSet; + } catch (e) { + previewSetter = ieSafePreviewSet; + previewSetter(text); + } + }; + + var pushPreviewHtml = function (text) { + + var emptyTop = position.getTop(panels.input) - getDocScrollTop(); + + if (panels.preview) { + previewSet(text); + previewRefreshCallback(); + } + + setPanelScrollTops(); + + if (isFirstTimeFilled) { + isFirstTimeFilled = false; + return; + } + + var fullTop = position.getTop(panels.input) - getDocScrollTop(); + + if (uaSniffed.isIE) { + setTimeout(function () { + window.scrollBy(0, fullTop - emptyTop); + }, 0); + } + else { + window.scrollBy(0, fullTop - emptyTop); + } + }; + + var init = function () { + + setupEvents(panels.input, applyTimeout); + makePreviewHtml(); + + if (panels.preview) { + panels.preview.scrollTop = 0; + } + }; + + init(); + }; + + + // This simulates a modal dialog box and asks for the URL when you + // click the hyperlink or image buttons. + // + // text: The html for the input box. + // defaultInputText: The default value that appears in the input box. + // callback: The function which is executed when the prompt is dismissed, either via OK or Cancel. + // It receives a single argument; either the entered text (if OK was chosen) or null (if Cancel + // was chosen). + ui.prompt = function (title, text, defaultInputText, callback) { + + // These variables need to be declared at this level since they are used + // in multiple functions. + var dialog; // The dialog box. + var input; // The text box where you enter the hyperlink. + + + if (defaultInputText === undefined) { + defaultInputText = ""; + } + + // Used as a keydown event handler. Esc dismisses the prompt. + // Key code 27 is ESC. + var checkEscape = function (key) { + var code = (key.charCode || key.keyCode); + if (code === 27) { + close(true); + } + }; + + // Dismisses the hyperlink input box. + // isCancel is true if we don't care about the input text. + // isCancel is false if we are going to keep the text. + var close = function (isCancel) { + util.removeEvent(doc.body, "keydown", checkEscape); + var text = input.value; + + if (isCancel) { + text = null; + } + else { + // Fixes common pasting errors. + text = text.replace(/^http:\/\/(https?|ftp):\/\//, '$1://'); + if (!/^(?:https?|ftp):\/\//.test(text)) + text = 'http://' + text; + } + + $(dialog).modal('hide'); + + callback(text); + return false; + }; + + + + // Create the text input box form/window. + var createDialog = function () { + // + + // The main dialog box. + dialog = doc.createElement("div"); + dialog.className = "modal hide fade"; + dialog.style.display = "none"; + + // The header. + var header = doc.createElement("div"); + header.className = "modal-header"; + header.innerHTML = '×

    '+title+'

    '; + dialog.appendChild(header); + + // The body. + var body = doc.createElement("div"); + body.className = "modal-body"; + dialog.appendChild(body); + + // The footer. + var footer = doc.createElement("div"); + footer.className = "modal-footer"; + dialog.appendChild(footer); + + // The dialog text. + var question = doc.createElement("p"); + question.innerHTML = text; + question.style.padding = "5px"; + body.appendChild(question); + + // The web form container for the text box and buttons. + var form = doc.createElement("form"), + style = form.style; + form.onsubmit = function () { return close(false); }; + style.padding = "0"; + style.margin = "0"; + body.appendChild(form); + + // The input text box + input = doc.createElement("input"); + input.type = "text"; + input.value = defaultInputText; + style = input.style; + style.display = "block"; + style.width = "80%"; + style.marginLeft = style.marginRight = "auto"; + form.appendChild(input); + + // The ok button + var okButton = doc.createElement("button"); + okButton.className = "btn btn-primary"; + okButton.type = "button"; + okButton.onclick = function () { return close(false); }; + okButton.innerHTML = "OK"; + + // The cancel button + var cancelButton = doc.createElement("button"); + cancelButton.className = "btn btn-primary"; + cancelButton.type = "button"; + cancelButton.onclick = function () { return close(true); }; + cancelButton.innerHTML = "Cancel"; + + footer.appendChild(okButton); + footer.appendChild(cancelButton); + + util.addEvent(doc.body, "keydown", checkEscape); + + doc.body.appendChild(dialog); + + }; + + // Why is this in a zero-length timeout? + // Is it working around a browser bug? + setTimeout(function () { + + createDialog(); + + var defTextLen = defaultInputText.length; + if (input.selectionStart !== undefined) { + input.selectionStart = 0; + input.selectionEnd = defTextLen; + } + else if (input.createTextRange) { + var range = input.createTextRange(); + range.collapse(false); + range.moveStart("character", -defTextLen); + range.moveEnd("character", defTextLen); + range.select(); + } + + $(dialog).on('shown', function () { + input.focus(); + }) + + $(dialog).on('hidden', function () { + dialog.parentNode.removeChild(dialog); + }) + + $(dialog).modal() + + }, 0); + }; + + function UIManager(postfix, panels, undoManager, previewManager, commandManager, helpOptions) { + + var inputBox = panels.input, + buttons = {}; // buttons.undo, buttons.link, etc. The actual DOM elements. + + makeSpritedButtonRow(); + + var keyEvent = "keydown"; + if (uaSniffed.isOpera) { + keyEvent = "keypress"; + } + + util.addEvent(inputBox, keyEvent, function (key) { + + // Check to see if we have a button key and, if so execute the callback. + if ((key.ctrlKey || key.metaKey) && !key.altKey && !key.shiftKey) { + + var keyCode = key.charCode || key.keyCode; + var keyCodeStr = String.fromCharCode(keyCode).toLowerCase(); + + switch (keyCodeStr) { + case "b": + doClick(buttons.bold); + break; + case "i": + doClick(buttons.italic); + break; + case "l": + doClick(buttons.link); + break; + case "q": + doClick(buttons.quote); + break; + case "k": + doClick(buttons.code); + break; + case "g": + doClick(buttons.image); + break; + case "o": + doClick(buttons.olist); + break; + case "u": + doClick(buttons.ulist); + break; + case "h": + doClick(buttons.heading); + break; + case "r": + doClick(buttons.hr); + break; + case "y": + doClick(buttons.redo); + break; + case "z": + if (key.shiftKey) { + doClick(buttons.redo); + } + else { + doClick(buttons.undo); + } + break; + default: + return; + } + + + if (key.preventDefault) { + key.preventDefault(); + } + + if (window.event) { + window.event.returnValue = false; + } + } + }); + + // Auto-indent on shift-enter + util.addEvent(inputBox, "keyup", function (key) { + if (key.shiftKey && !key.ctrlKey && !key.metaKey) { + var keyCode = key.charCode || key.keyCode; + // Character 13 is Enter + if (keyCode === 13) { + var fakeButton = {}; + fakeButton.textOp = bindCommand("doAutoindent"); + doClick(fakeButton); + } + } + }); + + // special handler because IE clears the context of the textbox on ESC + if (uaSniffed.isIE) { + util.addEvent(inputBox, "keydown", function (key) { + var code = key.keyCode; + if (code === 27) { + return false; + } + }); + } + + + // Perform the button's action. + function doClick(button) { + + inputBox.focus(); + + if (button.textOp) { + + if (undoManager) { + undoManager.setCommandMode(); + } + + var state = new TextareaState(panels); + + if (!state) { + return; + } + + var chunks = state.getChunks(); + + // Some commands launch a "modal" prompt dialog. Javascript + // can't really make a modal dialog box and the WMD code + // will continue to execute while the dialog is displayed. + // This prevents the dialog pattern I'm used to and means + // I can't do something like this: + // + // var link = CreateLinkDialog(); + // makeMarkdownLink(link); + // + // Instead of this straightforward method of handling a + // dialog I have to pass any code which would execute + // after the dialog is dismissed (e.g. link creation) + // in a function parameter. + // + // Yes this is awkward and I think it sucks, but there's + // no real workaround. Only the image and link code + // create dialogs and require the function pointers. + var fixupInputArea = function () { + + inputBox.focus(); + + if (chunks) { + state.setChunks(chunks); + } + + state.restore(); + previewManager.refresh(); + }; + + var noCleanup = button.textOp(chunks, fixupInputArea); + + if (!noCleanup) { + fixupInputArea(); + } + + } + + if (button.execute) { + button.execute(undoManager); + } + }; + + function setupButton(button, isEnabled) { + + if (isEnabled) { + button.disabled = false; + + if (!button.isHelp) { + button.onclick = function () { + if (this.onmouseout) { + this.onmouseout(); + } + doClick(this); + return false; + } + } + } + else { + button.disabled = true; + } + } + + function bindCommand(method) { + if (typeof method === "string") + method = commandManager[method]; + return function () { method.apply(commandManager, arguments); } + } + + function makeSpritedButtonRow() { + + var buttonBar = panels.buttonBar; + var buttonRow = document.createElement("div"); + buttonRow.id = "wmd-button-row" + postfix; + buttonRow.className = 'btn-toolbar'; + buttonRow = buttonBar.appendChild(buttonRow); + + var makeButton = function (id, title, icon, textOp, group) { + var button = document.createElement("button"); + button.className = "btn"; + var buttonImage = document.createElement("i"); + buttonImage.className = icon; + button.id = id + postfix; + button.appendChild(buttonImage); + button.title = title; + $(button).tooltip({placement: 'bottom'}) + if (textOp) + button.textOp = textOp; + setupButton(button, true); + if (group) { + group.appendChild(button); + } else { + buttonRow.appendChild(button); + } + return button; + }; + var makeGroup = function (num) { + var group = document.createElement("div"); + group.className = "btn-group wmd-button-group" + num; + group.id = "wmd-button-group" + num + postfix; + buttonRow.appendChild(group); + return group + } + + group1 = makeGroup(1); + buttons.bold = makeButton("wmd-bold-button", "Bold - Ctrl+B", "icon-bold", bindCommand("doBold"), group1); + buttons.italic = makeButton("wmd-italic-button", "Italic - Ctrl+I", "icon-italic", bindCommand("doItalic"), group1); + + group2 = makeGroup(2); + buttons.link = makeButton("wmd-link-button", "Link - Ctrl+L", "icon-link", bindCommand(function (chunk, postProcessing) { + return this.doLinkOrImage(chunk, postProcessing, false); + }), group2); + buttons.quote = makeButton("wmd-quote-button", "Blockquote - Ctrl+Q", "icon-blockquote", bindCommand("doBlockquote"), group2); + buttons.code = makeButton("wmd-code-button", "Code Sample - Ctrl+K", "icon-code", bindCommand("doCode"), group2); + buttons.image = makeButton("wmd-image-button", "Image - Ctrl+G", "icon-picture", bindCommand(function (chunk, postProcessing) { + return this.doLinkOrImage(chunk, postProcessing, true); + }), group2); + + group3 = makeGroup(3); + buttons.olist = makeButton("wmd-olist-button", "Numbered List - Ctrl+O", "icon-list", bindCommand(function (chunk, postProcessing) { + this.doList(chunk, postProcessing, true); + }), group3); + buttons.ulist = makeButton("wmd-ulist-button", "Bulleted List - Ctrl+U", "icon-bullet-list", bindCommand(function (chunk, postProcessing) { + this.doList(chunk, postProcessing, false); + }), group3); + buttons.heading = makeButton("wmd-heading-button", "Heading - Ctrl+H", "icon-header", bindCommand("doHeading"), group3); + buttons.hr = makeButton("wmd-hr-button", "Horizontal Rule - Ctrl+R", "icon-hr-line", bindCommand("doHorizontalRule"), group3); + + group4 = makeGroup(4); + buttons.undo = makeButton("wmd-undo-button", "Undo - Ctrl+Z", "icon-undo", null, group4); + buttons.undo.execute = function (manager) { if (manager) manager.undo(); }; + + var redoTitle = /win/.test(nav.platform.toLowerCase()) ? + "Redo - Ctrl+Y" : + "Redo - Ctrl+Shift+Z"; // mac and other non-Windows platforms + + buttons.redo = makeButton("wmd-redo-button", redoTitle, "icon-share-alt", null, group4); + buttons.redo.execute = function (manager) { if (manager) manager.redo(); }; + + if (helpOptions) { + group5 = makeGroup(5); + group5.className = group5.className + " pull-right"; + var helpButton = document.createElement("button"); + var helpButtonImage = document.createElement("i"); + helpButtonImage.className = "icon-question-sign"; + helpButton.appendChild(helpButtonImage); + helpButton.className = "btn"; + helpButton.id = "wmd-help-button" + postfix; + helpButton.isHelp = true; + helpButton.title = helpOptions.title || defaultHelpHoverTitle; + $(helpButton).tooltip({placement: 'bottom'}) + helpButton.onclick = helpOptions.handler; + + setupButton(helpButton, true); + group5.appendChild(helpButton); + buttons.help = helpButton; + } + + setUndoRedoButtonStates(); + } + + function setUndoRedoButtonStates() { + if (undoManager) { + setupButton(buttons.undo, undoManager.canUndo()); + setupButton(buttons.redo, undoManager.canRedo()); + } + }; + + this.setUndoRedoButtonStates = setUndoRedoButtonStates; + + } + + function CommandManager(pluginHooks) { + this.hooks = pluginHooks; + } + + var commandProto = CommandManager.prototype; + + // The markdown symbols - 4 spaces = code, > = blockquote, etc. + commandProto.prefixes = "(?:\\s{4,}|\\s*>|\\s*-\\s+|\\s*\\d+\\.|=|\\+|-|_|\\*|#|\\s*\\[[^\n]]+\\]:)"; + + // Remove markdown symbols from the chunk selection. + commandProto.unwrap = function (chunk) { + var txt = new re("([^\\n])\\n(?!(\\n|" + this.prefixes + "))", "g"); + chunk.selection = chunk.selection.replace(txt, "$1 $2"); + }; + + commandProto.wrap = function (chunk, len) { + this.unwrap(chunk); + var regex = new re("(.{1," + len + "})( +|$\\n?)", "gm"), + that = this; + + chunk.selection = chunk.selection.replace(regex, function (line, marked) { + if (new re("^" + that.prefixes, "").test(line)) { + return line; + } + return marked + "\n"; + }); + + chunk.selection = chunk.selection.replace(/\s+$/, ""); + }; + + commandProto.doBold = function (chunk, postProcessing) { + return this.doBorI(chunk, postProcessing, 2, "strong text"); + }; + + commandProto.doItalic = function (chunk, postProcessing) { + return this.doBorI(chunk, postProcessing, 1, "emphasized text"); + }; + + // chunk: The selected region that will be enclosed with */** + // nStars: 1 for italics, 2 for bold + // insertText: If you just click the button without highlighting text, this gets inserted + commandProto.doBorI = function (chunk, postProcessing, nStars, insertText) { + + // Get rid of whitespace and fixup newlines. + chunk.trimWhitespace(); + chunk.selection = chunk.selection.replace(/\n{2,}/g, "\n"); + + // Look for stars before and after. Is the chunk already marked up? + // note that these regex matches cannot fail + var starsBefore = /(\**$)/.exec(chunk.before)[0]; + var starsAfter = /(^\**)/.exec(chunk.after)[0]; + + var prevStars = Math.min(starsBefore.length, starsAfter.length); + + // Remove stars if we have to since the button acts as a toggle. + if ((prevStars >= nStars) && (prevStars != 2 || nStars != 1)) { + chunk.before = chunk.before.replace(re("[*]{" + nStars + "}$", ""), ""); + chunk.after = chunk.after.replace(re("^[*]{" + nStars + "}", ""), ""); + } + else if (!chunk.selection && starsAfter) { + // It's not really clear why this code is necessary. It just moves + // some arbitrary stuff around. + chunk.after = chunk.after.replace(/^([*_]*)/, ""); + chunk.before = chunk.before.replace(/(\s?)$/, ""); + var whitespace = re.$1; + chunk.before = chunk.before + starsAfter + whitespace; + } + else { + + // In most cases, if you don't have any selected text and click the button + // you'll get a selected, marked up region with the default text inserted. + if (!chunk.selection && !starsAfter) { + chunk.selection = insertText; + } + + // Add the true markup. + var markup = nStars <= 1 ? "*" : "**"; // shouldn't the test be = ? + chunk.before = chunk.before + markup; + chunk.after = markup + chunk.after; + } + + return; + }; + + commandProto.stripLinkDefs = function (text, defsToAdd) { + + text = text.replace(/^[ ]{0,3}\[(\d+)\]:[ \t]*\n?[ \t]*?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|$)/gm, + function (totalMatch, id, link, newlines, title) { + defsToAdd[id] = totalMatch.replace(/\s*$/, ""); + if (newlines) { + // Strip the title and return that separately. + defsToAdd[id] = totalMatch.replace(/["(](.+?)[")]$/, ""); + return newlines + title; + } + return ""; + }); + + return text; + }; + + commandProto.addLinkDef = function (chunk, linkDef) { + + var refNumber = 0; // The current reference number + var defsToAdd = {}; // + // Start with a clean slate by removing all previous link definitions. + chunk.before = this.stripLinkDefs(chunk.before, defsToAdd); + chunk.selection = this.stripLinkDefs(chunk.selection, defsToAdd); + chunk.after = this.stripLinkDefs(chunk.after, defsToAdd); + + var defs = ""; + var regex = /(\[)((?:\[[^\]]*\]|[^\[\]])*)(\][ ]?(?:\n[ ]*)?\[)(\d+)(\])/g; + + var addDefNumber = function (def) { + refNumber++; + def = def.replace(/^[ ]{0,3}\[(\d+)\]:/, " [" + refNumber + "]:"); + defs += "\n" + def; + }; + + // note that + // a) the recursive call to getLink cannot go infinite, because by definition + // of regex, inner is always a proper substring of wholeMatch, and + // b) more than one level of nesting is neither supported by the regex + // nor making a lot of sense (the only use case for nesting is a linked image) + var getLink = function (wholeMatch, before, inner, afterInner, id, end) { + inner = inner.replace(regex, getLink); + if (defsToAdd[id]) { + addDefNumber(defsToAdd[id]); + return before + inner + afterInner + refNumber + end; + } + return wholeMatch; + }; + + chunk.before = chunk.before.replace(regex, getLink); + + if (linkDef) { + addDefNumber(linkDef); + } + else { + chunk.selection = chunk.selection.replace(regex, getLink); + } + + var refOut = refNumber; + + chunk.after = chunk.after.replace(regex, getLink); + + if (chunk.after) { + chunk.after = chunk.after.replace(/\n*$/, ""); + } + if (!chunk.after) { + chunk.selection = chunk.selection.replace(/\n*$/, ""); + } + + chunk.after += "\n\n" + defs; + + return refOut; + }; + + // takes the line as entered into the add link/as image dialog and makes + // sure the URL and the optinal title are "nice". + function properlyEncoded(linkdef) { + return linkdef.replace(/^\s*(.*?)(?:\s+"(.+)")?\s*$/, function (wholematch, link, title) { + link = link.replace(/\?.*$/, function (querypart) { + return querypart.replace(/\+/g, " "); // in the query string, a plus and a space are identical + }); + link = decodeURIComponent(link); // unencode first, to prevent double encoding + link = encodeURI(link).replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29'); + link = link.replace(/\?.*$/, function (querypart) { + return querypart.replace(/\+/g, "%2b"); // since we replaced plus with spaces in the query part, all pluses that now appear where originally encoded + }); + if (title) { + title = title.trim ? title.trim() : title.replace(/^\s*/, "").replace(/\s*$/, ""); + title = $.trim(title).replace(/"/g, "quot;").replace(/\(/g, "(").replace(/\)/g, ")").replace(//g, ">"); + } + return title ? link + ' "' + title + '"' : link; + }); + } + + commandProto.doLinkOrImage = function (chunk, postProcessing, isImage) { + + chunk.trimWhitespace(); + chunk.findTags(/\s*!?\[/, /\][ ]?(?:\n[ ]*)?(\[.*?\])?/); + var background; + + if (chunk.endTag.length > 1 && chunk.startTag.length > 0) { + + chunk.startTag = chunk.startTag.replace(/!?\[/, ""); + chunk.endTag = ""; + this.addLinkDef(chunk, null); + + } + else { + + // We're moving start and end tag back into the selection, since (as we're in the else block) we're not + // *removing* a link, but *adding* one, so whatever findTags() found is now back to being part of the + // link text. linkEnteredCallback takes care of escaping any brackets. + chunk.selection = chunk.startTag + chunk.selection + chunk.endTag; + chunk.startTag = chunk.endTag = ""; + + if (/\n\n/.test(chunk.selection)) { + this.addLinkDef(chunk, null); + return; + } + var that = this; + // The function to be executed when you enter a link and press OK or Cancel. + // Marks up the link and adds the ref. + var linkEnteredCallback = function (link) { + + if (link !== null) { + // ( $1 + // [^\\] anything that's not a backslash + // (?:\\\\)* an even number (this includes zero) of backslashes + // ) + // (?= followed by + // [[\]] an opening or closing bracket + // ) + // + // In other words, a non-escaped bracket. These have to be escaped now to make sure they + // don't count as the end of the link or similar. + // Note that the actual bracket has to be a lookahead, because (in case of to subsequent brackets), + // the bracket in one match may be the "not a backslash" character in the next match, so it + // should not be consumed by the first match. + // The "prepend a space and finally remove it" steps makes sure there is a "not a backslash" at the + // start of the string, so this also works if the selection begins with a bracket. We cannot solve + // this by anchoring with ^, because in the case that the selection starts with two brackets, this + // would mean a zero-width match at the start. Since zero-width matches advance the string position, + // the first bracket could then not act as the "not a backslash" for the second. + chunk.selection = (" " + chunk.selection).replace(/([^\\](?:\\\\)*)(?=[[\]])/g, "$1\\").substr(1); + + var linkDef = " [999]: " + properlyEncoded(link); + + var num = that.addLinkDef(chunk, linkDef); + chunk.startTag = isImage ? "![" : "["; + chunk.endTag = "][" + num + "]"; + + if (!chunk.selection) { + if (isImage) { + chunk.selection = "enter image description here"; + } + else { + chunk.selection = "enter link description here"; + } + } + } + postProcessing(); + }; + + + if (isImage) { + if (!this.hooks.insertImageDialog(linkEnteredCallback)) + ui.prompt('Insert Image', imageDialogText, imageDefaultText, linkEnteredCallback); + } + else { + ui.prompt('Insert Link', linkDialogText, linkDefaultText, linkEnteredCallback); + } + return true; + } + }; + + // When making a list, hitting shift-enter will put your cursor on the next line + // at the current indent level. + commandProto.doAutoindent = function (chunk, postProcessing) { + + var commandMgr = this, + fakeSelection = false; + + chunk.before = chunk.before.replace(/(\n|^)[ ]{0,3}([*+-]|\d+[.])[ \t]*\n$/, "\n\n"); + chunk.before = chunk.before.replace(/(\n|^)[ ]{0,3}>[ \t]*\n$/, "\n\n"); + chunk.before = chunk.before.replace(/(\n|^)[ \t]+\n$/, "\n\n"); + + // There's no selection, end the cursor wasn't at the end of the line: + // The user wants to split the current list item / code line / blockquote line + // (for the latter it doesn't really matter) in two. Temporarily select the + // (rest of the) line to achieve this. + if (!chunk.selection && !/^[ \t]*(?:\n|$)/.test(chunk.after)) { + chunk.after = chunk.after.replace(/^[^\n]*/, function (wholeMatch) { + chunk.selection = wholeMatch; + return ""; + }); + fakeSelection = true; + } + + if (/(\n|^)[ ]{0,3}([*+-]|\d+[.])[ \t]+.*\n$/.test(chunk.before)) { + if (commandMgr.doList) { + commandMgr.doList(chunk); + } + } + if (/(\n|^)[ ]{0,3}>[ \t]+.*\n$/.test(chunk.before)) { + if (commandMgr.doBlockquote) { + commandMgr.doBlockquote(chunk); + } + } + if (/(\n|^)(\t|[ ]{4,}).*\n$/.test(chunk.before)) { + if (commandMgr.doCode) { + commandMgr.doCode(chunk); + } + } + + if (fakeSelection) { + chunk.after = chunk.selection + chunk.after; + chunk.selection = ""; + } + }; + + commandProto.doBlockquote = function (chunk, postProcessing) { + + chunk.selection = chunk.selection.replace(/^(\n*)([^\r]+?)(\n*)$/, + function (totalMatch, newlinesBefore, text, newlinesAfter) { + chunk.before += newlinesBefore; + chunk.after = newlinesAfter + chunk.after; + return text; + }); + + chunk.before = chunk.before.replace(/(>[ \t]*)$/, + function (totalMatch, blankLine) { + chunk.selection = blankLine + chunk.selection; + return ""; + }); + + chunk.selection = chunk.selection.replace(/^(\s|>)+$/, ""); + chunk.selection = chunk.selection || "Blockquote"; + + // The original code uses a regular expression to find out how much of the + // text *directly before* the selection already was a blockquote: + + /* + if (chunk.before) { + chunk.before = chunk.before.replace(/\n?$/, "\n"); + } + chunk.before = chunk.before.replace(/(((\n|^)(\n[ \t]*)*>(.+\n)*.*)+(\n[ \t]*)*$)/, + function (totalMatch) { + chunk.startTag = totalMatch; + return ""; + }); + */ + + // This comes down to: + // Go backwards as many lines a possible, such that each line + // a) starts with ">", or + // b) is almost empty, except for whitespace, or + // c) is preceeded by an unbroken chain of non-empty lines + // leading up to a line that starts with ">" and at least one more character + // and in addition + // d) at least one line fulfills a) + // + // Since this is essentially a backwards-moving regex, it's susceptible to + // catstrophic backtracking and can cause the browser to hang; + // see e.g. http://meta.stackoverflow.com/questions/9807. + // + // Hence we replaced this by a simple state machine that just goes through the + // lines and checks for a), b), and c). + + var match = "", + leftOver = "", + line; + if (chunk.before) { + var lines = chunk.before.replace(/\n$/, "").split("\n"); + var inChain = false; + for (var i = 0; i < lines.length; i++) { + var good = false; + line = lines[i]; + inChain = inChain && line.length > 0; // c) any non-empty line continues the chain + if (/^>/.test(line)) { // a) + good = true; + if (!inChain && line.length > 1) // c) any line that starts with ">" and has at least one more character starts the chain + inChain = true; + } else if (/^[ \t]*$/.test(line)) { // b) + good = true; + } else { + good = inChain; // c) the line is not empty and does not start with ">", so it matches if and only if we're in the chain + } + if (good) { + match += line + "\n"; + } else { + leftOver += match + line; + match = "\n"; + } + } + if (!/(^|\n)>/.test(match)) { // d) + leftOver += match; + match = ""; + } + } + + chunk.startTag = match; + chunk.before = leftOver; + + // end of change + + if (chunk.after) { + chunk.after = chunk.after.replace(/^\n?/, "\n"); + } + + chunk.after = chunk.after.replace(/^(((\n|^)(\n[ \t]*)*>(.+\n)*.*)+(\n[ \t]*)*)/, + function (totalMatch) { + chunk.endTag = totalMatch; + return ""; + } + ); + + var replaceBlanksInTags = function (useBracket) { + + var replacement = useBracket ? "> " : ""; + + if (chunk.startTag) { + chunk.startTag = chunk.startTag.replace(/\n((>|\s)*)\n$/, + function (totalMatch, markdown) { + return "\n" + markdown.replace(/^[ ]{0,3}>?[ \t]*$/gm, replacement) + "\n"; + }); + } + if (chunk.endTag) { + chunk.endTag = chunk.endTag.replace(/^\n((>|\s)*)\n/, + function (totalMatch, markdown) { + return "\n" + markdown.replace(/^[ ]{0,3}>?[ \t]*$/gm, replacement) + "\n"; + }); + } + }; + + if (/^(?![ ]{0,3}>)/m.test(chunk.selection)) { + this.wrap(chunk, SETTINGS.lineLength - 2); + chunk.selection = chunk.selection.replace(/^/gm, "> "); + replaceBlanksInTags(true); + chunk.skipLines(); + } else { + chunk.selection = chunk.selection.replace(/^[ ]{0,3}> ?/gm, ""); + this.unwrap(chunk); + replaceBlanksInTags(false); + + if (!/^(\n|^)[ ]{0,3}>/.test(chunk.selection) && chunk.startTag) { + chunk.startTag = chunk.startTag.replace(/\n{0,2}$/, "\n\n"); + } + + if (!/(\n|^)[ ]{0,3}>.*$/.test(chunk.selection) && chunk.endTag) { + chunk.endTag = chunk.endTag.replace(/^\n{0,2}/, "\n\n"); + } + } + + chunk.selection = this.hooks.postBlockquoteCreation(chunk.selection); + + if (!/\n/.test(chunk.selection)) { + chunk.selection = chunk.selection.replace(/^(> *)/, + function (wholeMatch, blanks) { + chunk.startTag += blanks; + return ""; + }); + } + }; + + commandProto.doCode = function (chunk, postProcessing) { + + var hasTextBefore = /\S[ ]*$/.test(chunk.before); + var hasTextAfter = /^[ ]*\S/.test(chunk.after); + + // Use 'four space' markdown if the selection is on its own + // line or is multiline. + if ((!hasTextAfter && !hasTextBefore) || /\n/.test(chunk.selection)) { + + chunk.before = chunk.before.replace(/[ ]{4}$/, + function (totalMatch) { + chunk.selection = totalMatch + chunk.selection; + return ""; + }); + + var nLinesBack = 1; + var nLinesForward = 1; + + if (/(\n|^)(\t|[ ]{4,}).*\n$/.test(chunk.before)) { + nLinesBack = 0; + } + if (/^\n(\t|[ ]{4,})/.test(chunk.after)) { + nLinesForward = 0; + } + + chunk.skipLines(nLinesBack, nLinesForward); + + if (!chunk.selection) { + chunk.startTag = " "; + chunk.selection = "enter code here"; + } + else { + if (/^[ ]{0,3}\S/m.test(chunk.selection)) { + if (/\n/.test(chunk.selection)) + chunk.selection = chunk.selection.replace(/^/gm, " "); + else // if it's not multiline, do not select the four added spaces; this is more consistent with the doList behavior + chunk.before += " "; + } + else { + chunk.selection = chunk.selection.replace(/^[ ]{4}/gm, ""); + } + } + } + else { + // Use backticks (`) to delimit the code block. + + chunk.trimWhitespace(); + chunk.findTags(/`/, /`/); + + if (!chunk.startTag && !chunk.endTag) { + chunk.startTag = chunk.endTag = "`"; + if (!chunk.selection) { + chunk.selection = "enter code here"; + } + } + else if (chunk.endTag && !chunk.startTag) { + chunk.before += chunk.endTag; + chunk.endTag = ""; + } + else { + chunk.startTag = chunk.endTag = ""; + } + } + }; + + commandProto.doList = function (chunk, postProcessing, isNumberedList) { + + // These are identical except at the very beginning and end. + // Should probably use the regex extension function to make this clearer. + var previousItemsRegex = /(\n|^)(([ ]{0,3}([*+-]|\d+[.])[ \t]+.*)(\n.+|\n{2,}([*+-].*|\d+[.])[ \t]+.*|\n{2,}[ \t]+\S.*)*)\n*$/; + var nextItemsRegex = /^\n*(([ ]{0,3}([*+-]|\d+[.])[ \t]+.*)(\n.+|\n{2,}([*+-].*|\d+[.])[ \t]+.*|\n{2,}[ \t]+\S.*)*)\n*/; + + // The default bullet is a dash but others are possible. + // This has nothing to do with the particular HTML bullet, + // it's just a markdown bullet. + var bullet = "-"; + + // The number in a numbered list. + var num = 1; + + // Get the item prefix - e.g. " 1. " for a numbered list, " - " for a bulleted list. + var getItemPrefix = function () { + var prefix; + if (isNumberedList) { + prefix = " " + num + ". "; + num++; + } + else { + prefix = " " + bullet + " "; + } + return prefix; + }; + + // Fixes the prefixes of the other list items. + var getPrefixedItem = function (itemText) { + + // The numbering flag is unset when called by autoindent. + if (isNumberedList === undefined) { + isNumberedList = /^\s*\d/.test(itemText); + } + + // Renumber/bullet the list element. + itemText = itemText.replace(/^[ ]{0,3}([*+-]|\d+[.])\s/gm, + function (_) { + return getItemPrefix(); + }); + + return itemText; + }; + + chunk.findTags(/(\n|^)*[ ]{0,3}([*+-]|\d+[.])\s+/, null); + + if (chunk.before && !/\n$/.test(chunk.before) && !/^\n/.test(chunk.startTag)) { + chunk.before += chunk.startTag; + chunk.startTag = ""; + } + + if (chunk.startTag) { + + var hasDigits = /\d+[.]/.test(chunk.startTag); + chunk.startTag = ""; + chunk.selection = chunk.selection.replace(/\n[ ]{4}/g, "\n"); + this.unwrap(chunk); + chunk.skipLines(); + + if (hasDigits) { + // Have to renumber the bullet points if this is a numbered list. + chunk.after = chunk.after.replace(nextItemsRegex, getPrefixedItem); + } + if (isNumberedList == hasDigits) { + return; + } + } + + var nLinesUp = 1; + + chunk.before = chunk.before.replace(previousItemsRegex, + function (itemText) { + if (/^\s*([*+-])/.test(itemText)) { + bullet = re.$1; + } + nLinesUp = /[^\n]\n\n[^\n]/.test(itemText) ? 1 : 0; + return getPrefixedItem(itemText); + }); + + if (!chunk.selection) { + chunk.selection = "List item"; + } + + var prefix = getItemPrefix(); + + var nLinesDown = 1; + + chunk.after = chunk.after.replace(nextItemsRegex, + function (itemText) { + nLinesDown = /[^\n]\n\n[^\n]/.test(itemText) ? 1 : 0; + return getPrefixedItem(itemText); + }); + + chunk.trimWhitespace(true); + chunk.skipLines(nLinesUp, nLinesDown, true); + chunk.startTag = prefix; + var spaces = prefix.replace(/./g, " "); + this.wrap(chunk, SETTINGS.lineLength - spaces.length); + chunk.selection = chunk.selection.replace(/\n/g, "\n" + spaces); + + }; + + commandProto.doHeading = function (chunk, postProcessing) { + + // Remove leading/trailing whitespace and reduce internal spaces to single spaces. + chunk.selection = chunk.selection.replace(/\s+/g, " "); + chunk.selection = chunk.selection.replace(/(^\s+|\s+$)/g, ""); + + // If we clicked the button with no selected text, we just + // make a level 2 hash header around some default text. + if (!chunk.selection) { + chunk.startTag = "## "; + chunk.selection = "Heading"; + chunk.endTag = " ##"; + return; + } + + var headerLevel = 0; // The existing header level of the selected text. + + // Remove any existing hash heading markdown and save the header level. + chunk.findTags(/#+[ ]*/, /[ ]*#+/); + if (/#+/.test(chunk.startTag)) { + headerLevel = re.lastMatch.length; + } + chunk.startTag = chunk.endTag = ""; + + // Try to get the current header level by looking for - and = in the line + // below the selection. + chunk.findTags(null, /\s?(-+|=+)/); + if (/=+/.test(chunk.endTag)) { + headerLevel = 1; + } + if (/-+/.test(chunk.endTag)) { + headerLevel = 2; + } + + // Skip to the next line so we can create the header markdown. + chunk.startTag = chunk.endTag = ""; + chunk.skipLines(1, 1); + + // We make a level 2 header if there is no current header. + // If there is a header level, we substract one from the header level. + // If it's already a level 1 header, it's removed. + var headerLevelToCreate = headerLevel == 0 ? 2 : headerLevel - 1; + + if (headerLevelToCreate > 0) { + + // The button only creates level 1 and 2 underline headers. + // Why not have it iterate over hash header levels? Wouldn't that be easier and cleaner? + var headerChar = headerLevelToCreate >= 2 ? "-" : "="; + var len = chunk.selection.length; + if (len > SETTINGS.lineLength) { + len = SETTINGS.lineLength; + } + chunk.endTag = "\n"; + while (len--) { + chunk.endTag += headerChar; + } + } + }; + + commandProto.doHorizontalRule = function (chunk, postProcessing) { + chunk.startTag = "----------\n"; + chunk.selection = ""; + chunk.skipLines(2, 1, true); + } + + +})(); \ No newline at end of file diff --git a/vendor/assets/javascripts/markdown_editor/Markdown.Sanitizer.js b/vendor/assets/javascripts/markdown_editor/Markdown.Sanitizer.js new file mode 100644 index 0000000..be0445a --- /dev/null +++ b/vendor/assets/javascripts/markdown_editor/Markdown.Sanitizer.js @@ -0,0 +1,111 @@ +(function () { + var output, Converter; + if (typeof exports === "object" && typeof require === "function") { // we're in a CommonJS (e.g. Node.js) module + output = exports; + Converter = require("./Markdown.Converter").Converter; + } else { + output = window.Markdown; + Converter = output.Converter; + } + + output.getSanitizingConverter = function () { + var converter = new Converter(); + converter.hooks.chain("postConversion", sanitizeHtml); + converter.hooks.chain("postConversion", balanceTags); + return converter; + } + + function sanitizeHtml(html) { + return html.replace(/<[^>]*>?/gi, sanitizeTag); + } + + // (tags that can be opened/closed) | (tags that stand alone) + var basic_tag_whitelist = /^(<\/?(b|blockquote|code|del|dd|dl|dt|em|h1|h2|h3|i|kbd|li|ol|p|s|sup|sub|strong|strike|ul)>|<(br|hr)\s?\/?>)$/i; + // | + var a_white = /^(]+")?\s?>|<\/a>)$/i; + + // ]*")?(\stitle="[^"<>]*")?\s?\/?>)$/i; + + //
    |
    for twitter bootstrap + var pre_white = /^(|<\/pre>)$/i; + + function sanitizeTag(tag) { + if (tag.match(basic_tag_whitelist) || tag.match(a_white) || tag.match(img_white) || tag.match(pre_white)) + return tag; + else + return ""; + } + + /// + /// attempt to balance HTML tags in the html string + /// by removing any unmatched opening or closing tags + /// IMPORTANT: we *assume* HTML has *already* been + /// sanitized and is safe/sane before balancing! + /// + /// adapted from CODESNIPPET: A8591DBA-D1D3-11DE-947C-BA5556D89593 + /// + function balanceTags(html) { + + if (html == "") + return ""; + + var re = /<\/?\w+[^>]*(\s|$|>)/g; + // convert everything to lower case; this makes + // our case insensitive comparisons easier + var tags = html.toLowerCase().match(re); + + // no HTML tags present? nothing to do; exit now + var tagcount = (tags || []).length; + if (tagcount == 0) + return html; + + var tagname, tag; + var ignoredtags = "



  • "; + var match; + var tagpaired = []; + var tagremove = []; + var needsRemoval = false; + + // loop through matched tags in forward order + for (var ctag = 0; ctag < tagcount; ctag++) { + tagname = tags[ctag].replace(/<\/?(\w+).*/, "$1"); + // skip any already paired tags + // and skip tags in our ignore list; assume they're self-closed + if (tagpaired[ctag] || ignoredtags.search("<" + tagname + ">") > -1) + continue; + + tag = tags[ctag]; + match = -1; + + if (!/^<\//.test(tag)) { + // this is an opening tag + // search forwards (next tags), look for closing tags + for (var ntag = ctag + 1; ntag < tagcount; ntag++) { + if (!tagpaired[ntag] && tags[ntag] == "") { + match = ntag; + break; + } + } + } + + if (match == -1) + needsRemoval = tagremove[ctag] = true; // mark for removal + else + tagpaired[match] = true; // mark paired + } + + if (!needsRemoval) + return html; + + // delete all orphaned tags from the string + + var ctag = 0; + html = html.replace(re, function (match) { + var res = tagremove[ctag] ? "" : match; + ctag++; + return res; + }); + return html; + } +})(); diff --git a/vendor/assets/javascripts/markdown_editor/load_editor.coffee b/vendor/assets/javascripts/markdown_editor/load_editor.coffee new file mode 100644 index 0000000..f8a28b2 --- /dev/null +++ b/vendor/assets/javascripts/markdown_editor/load_editor.coffee @@ -0,0 +1,5 @@ +jQuery -> + if $("#wmd-input").length > 0 + converter = Markdown.getSanitizingConverter() + editor = new Markdown.Editor converter + editor.run() diff --git a/vendor/assets/javascripts/wymeditor.js b/vendor/assets/javascripts/wymeditor.js deleted file mode 100644 index 09ca5d1..0000000 --- a/vendor/assets/javascripts/wymeditor.js +++ /dev/null @@ -1,21 +0,0 @@ -// WYMEDITOR manifest -// -//= require_tree ./wymeditor -//= require_tree ./wymeditor/lang -//= require_tree ./wymeditor/iframe/default -//= require_tree ./wymeditor/plugins -//= require_tree ./wymeditor/plugins/embed -//= require_tree ./wymeditor/plugins/fullscreen -//= require_tree ./wymeditor/plugins/hovertools -//= require_tree ./wymeditor/plugins/list -//= require_tree ./wymeditor/plugins/rdfa -//= require_tree ./wymeditor/plugins/resizable -//= require_tree ./wymeditor/plugins/table -//= require_tree ./wymeditor/plugins/tidy -//= require_tree ./wymeditor/skins -//= require_tree ./wymeditor/skins/compact -//= require_tree ./wymeditor/skins/default -//= require_tree ./wymeditor/skins/minimal -//= require_tree ./wymeditor/skins/silver -//= require_tree ./wymeditor/skins/silver/images -//= require_tree ./wymeditor/skins/twopanels diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/lbl-article.png b/vendor/assets/javascripts/wymeditor/iframe/default/lbl-article.png deleted file mode 100644 index df229f1c34d03db5164c971d32b0eaab73fea82f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^szA)j!3HD`8L65ADajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MSh+xjv*DdlICoy_*>8BbAaQ>lMZ3!em;XMn-ww-E#sJN zp)4dnTa~Bch-63L`KHrbS&ppa4Y2Xa@%XEL_`68Eh~X@c!W;E6(}Yy{1QHk&Q$+qe TDxa|(XflJRtDnm{r-UW|p2avU diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/lbl-aside.png b/vendor/assets/javascripts/wymeditor/iframe/default/lbl-aside.png deleted file mode 100644 index 1bc09c6a582fa22dfcbdadc489f8a1435243f7e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 168 zcmeAS@N?(olHy`uVBq!ia0vp^l0eML!3HEZ{B>^z36!`-lmzFem6RtIr7}3Cou(KJCS#_=43KmtSIUV&e89JWaV PO=a+O^>bP0l+XkK%uhL$ diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/lbl-blockquote.png b/vendor/assets/javascripts/wymeditor/iframe/default/lbl-blockquote.png deleted file mode 100644 index 65ea20547f21a55b273ad1893d937db9bd95c792..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^%0SG@!3-pSd|K)Nq*&4&eH|GX)}JtE?Rp91OP07s zlmzFem6RtIr7}3C|6H_V+Po~-c6}fo2IEGZ*N}98+;%_~h&jF4j&8~AMvU*NpY*&-`(SOvy zP3TDBOy__(t&MgM>{VyIeCpxmC3B|9Sy|cCsliL}JcmF6!>dQ4KexsDECQOx;OXk; Jvd$@?2>=v_HSz!e diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/lbl-details.png b/vendor/assets/javascripts/wymeditor/iframe/default/lbl-details.png deleted file mode 100644 index fba6c638126d425354488019c1a79e7bcda50b82..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 186 zcmeAS@N?(olHy`uVBq!ia0vp^szA)j!3HD`8L65ADajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MKPW(jv*DdlICoy_*>5wa)4v$#iNNuPdbz@zhH2d=bq&( zalyp+(S{DjcGaFAI)|AhHd=Ct|L8wn$aCb!ESXxJB|jQm isRQ*%my{eD7#ZBlM1J2AZTG+mhmq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c6@_`aIEGZ*N}9Q?;%_~h&jF4j|0ia|eA*(W?kUebNyYAf zN8^urrbj&&t8s3iIC>q*U-KpPl5UHx3vIVCg!0Ky7BLI3~& diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/lbl-figure.png b/vendor/assets/javascripts/wymeditor/iframe/default/lbl-figure.png deleted file mode 100644 index 822ae04b62336fb955dc92966bfd86bd7c562a5b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^@<7bW!3HGvJ~lrBq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c75RI*IEGZ*N}98+;%_~h&jF4j|0ibDd@^w8sS-KRq|(VR zFzNX6fA)IC5f?-rY<^x32oDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MP8mRjv*DdlICoy_*>8BbAaPWiFmr>q?7{-IobXR3#7X| zGJa&pzWk?-1bP0l+XkK3WYa> diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/lbl-h1.png b/vendor/assets/javascripts/wymeditor/iframe/default/lbl-h1.png deleted file mode 100644 index 3e5adf0453c897ca24441c702a49992eb93946b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^96-#8U}fi7AzZCsS>Jiu62P978H@CC%AZ@wc9hjm?dXrQxHa39~SB9>cXGO-s17 l6CA^OeGToj4=^YkV5qNQ`}#fF^BYhngQu&X%Q~loCIH)_DJ}p2 diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/lbl-h2.png b/vendor/assets/javascripts/wymeditor/iframe/default/lbl-h2.png deleted file mode 100644 index 268375680d7916bf5921035c9eac85006be44f52..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^+(69A!3HEJFB1y`Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JicCCR978H@CC%AZ@wc9hjm?dXrQzd$;{}XjYFVdQ&MBb@03=Q=ng9R* diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/lbl-h3.png b/vendor/assets/javascripts/wymeditor/iframe/default/lbl-h3.png deleted file mode 100644 index 69647537731d62bd64b92d41aa3bfd57465a838e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^+(69A!3HEJFB1y`Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>Jip)J-978H@CC%AZ@wc9hjm?dXrQzd$;{}XjY8U}fi7AzZCsS>Jiu65Q978H@CC%AZ@wc9hjm?dXrQxIDk(m-63_2dm5}E&R n)J!|Fs6jAR+4CF&hXI4mHO|jbFS?EawK90R`njxgN@xNA48U}fi7AzZCsS>JicCFS978H@CC%AZ@wc9hjm?dXrQzd$;{}XjY=0UAXFvLH tA@cwDvKfNiOl~E;Kjt(hN;@<#GITR=ey>b_Ckixx!PC{xWt~$(699HPE;|4K diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/lbl-h6.png b/vendor/assets/javascripts/wymeditor/iframe/default/lbl-h6.png deleted file mode 100644 index 0aefe91e773dbd55e6ca05517f4d28d622613ba9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^+(69A!3HEJFB1y`Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>Jii|y7978H@CC%AZ@wc9hjm?dXrQzd$;{}XjY=0UAXFvLH qA@cwDvKfNyOd^F&=Nt?r6%H`8GjM)4W-x32oDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9Md6+z&xfvh$a%-CGWmS_L&n7;-El!rPb!`N e;T+q*$gu6b_@4*cvcChZVDNPHb6Mw<&;$Sr4@AfS diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/lbl-hgroup.png b/vendor/assets/javascripts/wymeditor/iframe/default/lbl-hgroup.png deleted file mode 100644 index 18b6db7dfb366a0894d7c581632bbb4305f34c36..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^%0SG@!3HGH>x32oDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MIoLpjv*DdlICoy_*>7$#^%Px((v)WaRO7((N3fJt&H{w zDo%gw1s@%m@qd0RNAC?C|FNWMdI814gqB?6-Fi= Zh7@1%?*+mu)Pd$Rc)I$ztaD0e0sti}Ij{f# diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/lbl-mark.png b/vendor/assets/javascripts/wymeditor/iframe/default/lbl-mark.png deleted file mode 100644 index 7918219da71e18d1c091b151debc2d401e43b5c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^;y}#G!3HGPnUosDSr z1<%~X^wgl##FWaylc_d9MXsJMjv*DdlICoy_*>8BbAaQ>lMZ90&cEqSlTsWew|tcJ z6lj;`nUtJ(fdAiQO}=eYCOqu1;7M^QQ`9R|V>`ug&w_!&fZ_fD{=X(F|6H_V+Po~-c6?uEQIEGZ*N}98+;%_~h&jF4jCc^2ClU>4(bR1S-Q~Aon za%FM%|MbKI{QravdLq95-}rM%BZs&UGsjO68LK0|rbM_41o8LTH83zUOk)!Kr*0(Z Q4m6g*)78&qol`;+0KSAb9smFU diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/lbl-nav.png b/vendor/assets/javascripts/wymeditor/iframe/default/lbl-nav.png deleted file mode 100644 index 6627d3fede186cb14057564f9c53e64ea229109a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^fDSr z1<%~X^wgl##FWaylc_d9MXsJMjv*DdlICoy_*>7$#^%Px((v)WaRQT@O686!HI-f- z3lqadnTHs3Dsm2_TW}>DdKBWM=NQJmZ3btzS`tIoX+|a<1`j*lUpzkbDL?}mJYD@< J);T3K0RXsNFLeL_ diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/lbl-p.png b/vendor/assets/javascripts/wymeditor/iframe/default/lbl-p.png deleted file mode 100644 index 0d7ac50ccafb3e2490183b0aa56ab8c580a95aa3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^tRT$61|)m))t&+=$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1G%APKcAr-fh=4`9@ThC^4fN81Z#3TO>v-}qhI(gto11kfI a1jFJBEZ^H#ZgB!CXYh3Ob6Mw<&;$UXy(oVG diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/lbl-pre.png b/vendor/assets/javascripts/wymeditor/iframe/default/lbl-pre.png deleted file mode 100644 index 5a7b9a1a7f4a7d93ae67d1661db1c936983e876c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 157 zcmeAS@N?(olHy`uVBq!ia0vp^;y}#G!3HGPnUosDSr z1<%~X^wgl##FWaylc_d9MfRR9jv*DdlICoy_*>8BbAaQ>kuGDWOrEbg8C((t87|j* z^v-phl~H4R)%5>FU&6vo4|{GjwZ14&QR;ZWpm2cU?LFS_GjpN?fkrWSy85}Sb4q9e E00LV!bN~PV diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/lbl-progress.png b/vendor/assets/javascripts/wymeditor/iframe/default/lbl-progress.png deleted file mode 100644 index c42cc4f46e4cc88a19ef1df6d3bbece113be7a71..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^`asOe!3HF+3T*uYq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c6(xGQIEGZ*N}98+;%_}$$N`R}7mp?uHM`AWJ$ul=-T09} zx`N}JMz2?eU7H_prq(?AaiCr)Suk?W#D={QXA>1KE&u;Y)?2f oHUFC|FzLyx!ya8X85r3Zewiu!Syiy%KhQD;Pgg&ebxsLQ0J_mg-T(jq diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/lbl-rp.png b/vendor/assets/javascripts/wymeditor/iframe/default/lbl-rp.png deleted file mode 100644 index 8fb414cf308bebf50eaf529bd630d2ed2cb8bc24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^+(69A!3HEJFB1y`Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JicCFS978H@CC%AZ@wc8W(PsIM0-!NA1BaKxVThe-A0hd=`uJYD@<);T3K0RR$(DwF^K diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/lbl-rt.png b/vendor/assets/javascripts/wymeditor/iframe/default/lbl-rt.png deleted file mode 100644 index 89b0cf9b70cf6c6b12bcaaf4417773b360dbc09e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^+(69A!3HEJFB1y`Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>Jii|y7978H@CC%AZ@wcAM=K#kMiAOpflMFt{`@XU7Ioq_1 rK|jICs8z6AH$wDrsWuM-iv)wT1^bWRQFlK9wKI6S`njxgN@xNA1news diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/lbl-ruby.png b/vendor/assets/javascripts/wymeditor/iframe/default/lbl-ruby.png deleted file mode 100644 index c81727768a42bf9a28fa76336e2f69e09593e107..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^;y}#G!3HGPnUosDSr z1<%~X^wgl##FWaylc_d9MZTUcjv*DdlICoy_*>5wa)4v$f8~u6f4+DnIpIj)mCXwz zJI)5M$+Ri1cHhq6vw4B0g4mzqiGp4H5gaV68}*K_YHxM8@mKxOQwv6i21bU7bA|s1 TUOxH@XfT7PtDnm{r-UW|Ts1q~ diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/lbl-section.png b/vendor/assets/javascripts/wymeditor/iframe/default/lbl-section.png deleted file mode 100644 index 0fc91553837af09536c77d0470c07ceea781a32b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^szA)j!3HD`8L65ADajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9Mc$q+jv*DdlICoy_*>8BbAaQ>6%ln$dG1Ln%zVB_x(*-t zC%p2#ybRH83zUEU6XxbNTz> Rr$A#FJYD@<);T3K0RR=+IfnoM diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/lbl-summary.png b/vendor/assets/javascripts/wymeditor/iframe/default/lbl-summary.png deleted file mode 100644 index f428236e8fb4467c9b726ea6ade8fc0b84dfc1a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^nn29T!3HF6@EzR^q$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c6~%kHIEGZ*N}98+;%_~h&jF4j{}-C@{BajLzI0yHBaLrH zik?czP7Q*+YHo8TdK9McH^`o8I&v^ga_fP5p`(FLQ&_v3{}~6!8$2?YFQ}`T$g0C4 lJy-w$ diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/lbl-time.png b/vendor/assets/javascripts/wymeditor/iframe/default/lbl-time.png deleted file mode 100644 index a8cec641b233021ecaea59be76ea77517366df57..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^!a&T*!3HFk-@on!q$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c6Bx(Ellirac{|$)B*;91cpy5xxZi8`(g#q5C%_IKbLh*2~7Y{&ox8< diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/readme.md b/vendor/assets/javascripts/wymeditor/iframe/default/readme.md deleted file mode 100644 index 57ca928..0000000 --- a/vendor/assets/javascripts/wymeditor/iframe/default/readme.md +++ /dev/null @@ -1 +0,0 @@ -Labels are made using the [Visitor font](http://www.dafont.com/visitor.font), 9.5px, no anti-aliasing. \ No newline at end of file diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/wymiframe.css b/vendor/assets/javascripts/wymeditor/iframe/default/wymiframe.css deleted file mode 100644 index d77860f..0000000 --- a/vendor/assets/javascripts/wymeditor/iframe/default/wymiframe.css +++ /dev/null @@ -1,91 +0,0 @@ -/* - * WYMeditor : what you see is What You Mean web-based editor - * Copyright (c) 2005 - 2009 Jean-Francois Hovinne, http://www.wymeditor.org/ - * Dual licensed under the MIT (MIT-license.txt) - * and GPL (GPL-license.txt) licenses. - * - * For further information visit: - * http://www.wymeditor.org/ - * - * File Name: - * wymeditor.css - * Main editor css file. - * See the documentation for more info. - * - * File Authors: - * Jean-Francois Hovinne (jf.hovinne a-t wymeditor dotorg) - * Daniel Reszka (d.reszka a-t wymeditor dotorg) -*/ - -/* VISUAL FEEDBACK */ - -/* basic */ - body { background: #e1e8f1;} - -/* make HTML blocs visible */ - p, - h1, - h2, - h3, - h4, - h5, - h6, - ul, - ol, - table, - blockquote, - pre { background: #FFFFFF no-repeat 2px 2px; - padding:8px 5px 5px; - margin:10px; } - td { background: #F0F4F8; } - th { background: #ffffcc; } - ul, - ol { border-left:20px solid #B9C4D0; padding:0px 5px; } - caption { background: #E4E4B0; padding: 5px; font-weight: bold; } - table { font-size: 12px; width: 500px; } - td { width: 25%; } - blockquote { margin-left: 30px; } - pre { background-color:transparent; border: 1px solid white; } - -/* Gecko min height fix */ - td { height: 1.6em; } - -/* labels */ - p { background-image: url(lbl-p.png); } - h1 { background-image: url(lbl-h1.png); } - h2 { background-image: url(lbl-h2.png); } - h3 { background-image: url(lbl-h3.png); } - h4 { background-image: url(lbl-h4.png); } - h5 { background-image: url(lbl-h5.png); } - h6 { background-image: url(lbl-h6.png); } - blockquote{ background-image: url(lbl-blockquote.png); } - pre { background-image: url(lbl-pre.png); } - -/* specific HTML elements */ - caption { text-align: left; } - img { margin-right: 5px; - border-style: solid; - border-color: gray; - border-width: 0; } - a img { border-width: 1px; border-color: blue; } - acronym { border: 1px solid gray; } - span { background-color: #eef; } - -/* visual feedback for non-valid nesting of elements*/ - h1 h1, h1 h2, h1 h3, h1 h4, h1 h5, h1 h6, h1 p, h1 pre, h1 address, - h2 h1, h2 h2, h2 h3, h2 h4, h2 h5, h2 h6, h2 p, h2 pre, h2 address, - h3 h1, h3 h2, h3 h3, h3 h4, h3 h5, h3 h6, h3 p, h3 pre, h3 address, - h4 h1, h4 h2, h4 h3, h4 h4, h4 h5, h4 h6, h4 p, h4 pre, h4 address, - h5 h1, h5 h2, h5 h3, h5 h4, h5 h5, h5 h6, h5 p, h5 pre, h5 address, - h6 h1, h6 h2, h6 h3, h6 h4, h6 h4, h6 h6, h6 p, h6 pre, h6 address, - p h1, p h2, p h3, p h4, p h5, p h6, p pre, p address, - pre h1, pre h2, pre h3, pre h4, pre h5, pre h6, pre p, pre pre, pre address, - address h1, address h2, address h3, address h4, address h5, address h6, - address p, address pre, address address - { background-color: #ff9999 !important; - border: 1px solid red !important; - font-size: 12px !important; - font-weight: normal; } - -/* Spacer BRs shouldn't add much whitespace */ -br { height: 5px; line-height: 5px; } \ No newline at end of file diff --git a/vendor/assets/javascripts/wymeditor/iframe/default/wymiframe.html b/vendor/assets/javascripts/wymeditor/iframe/default/wymiframe.html deleted file mode 100644 index 91a690c..0000000 --- a/vendor/assets/javascripts/wymeditor/iframe/default/wymiframe.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - -WYMeditor iframe - - - - - diff --git a/vendor/assets/javascripts/wymeditor/jquery.wymeditor.min.js b/vendor/assets/javascripts/wymeditor/jquery.wymeditor.min.js deleted file mode 100644 index 1748335..0000000 --- a/vendor/assets/javascripts/wymeditor/jquery.wymeditor.min.js +++ /dev/null @@ -1,33 +0,0 @@ -/*jslint evil: true, indent: 4 *//** - WYMeditor - ========= - - version 1.0.0a2 - - WYMeditor : what you see is What You Mean web-based editor - - Main JS file with core classes and functions. - - Copyright - --------- - - Copyright (c) 2005 - 2010 Jean-Francois Hovinne, http://www.wymeditor.org/ - Dual licensed under the MIT (MIT-license.txt) - and GPL (GPL-license.txt) licenses. - - Website - ------- - - For further information visit: - http://www.wymeditor.org/ - - - Authors - ------- - - See AUTHORS file -*/// Global WYMeditor namespace. -typeof WYMeditor=="undefined"&&(WYMeditor={}),function(){if(!window.console||!window.console.firebug){var a=["log","debug","info","warn","error","assert","dir","dirxml","group","groupEnd","time","timeEnd","count","trace","profile","profileEnd"],b=function(){},c;WYMeditor.console={};for(c=0;c"+"
    "+WYMeditor.TOOLS+"
    "+"
    "+"
    "+WYMeditor.CONTAINERS+WYMeditor.CLASSES+"
    "+"
    "+WYMeditor.HTML+WYMeditor.IFRAME+WYMeditor.STATUS+"
    "+"
    "+WYMeditor.LOGO+"
    "+"",logoHtml:String()+'WYMeditor',iframeHtml:String()+'
    '+'"+"
    ",editorStyles:[],toolsHtml:String()+'
    '+"

    {Tools}

    "+"
      "+WYMeditor.TOOLS_ITEMS+"
    "+"
    ",toolsItemHtml:String()+'
  • '+''+WYMeditor.TOOL_TITLE+""+"
  • ",toolsItems:[{name:"Bold",title:"Strong",css:"wym_tools_strong"},{name:"Italic",title:"Emphasis",css:"wym_tools_emphasis"},{name:"Superscript",title:"Superscript",css:"wym_tools_superscript"},{name:"Subscript",title:"Subscript",css:"wym_tools_subscript"},{name:"InsertOrderedList",title:"Ordered_List",css:"wym_tools_ordered_list"},{name:"InsertUnorderedList",title:"Unordered_List",css:"wym_tools_unordered_list"},{name:"Indent",title:"Indent",css:"wym_tools_indent"},{name:"Outdent",title:"Outdent",css:"wym_tools_outdent"},{name:"Undo",title:"Undo",css:"wym_tools_undo"},{name:"Redo",title:"Redo",css:"wym_tools_redo"},{name:"CreateLink",title:"Link",css:"wym_tools_link"},{name:"Unlink",title:"Unlink",css:"wym_tools_unlink"},{name:"InsertImage",title:"Image",css:"wym_tools_image"},{name:"InsertTable",title:"Table",css:"wym_tools_table"},{name:"Paste",title:"Paste_From_Word",css:"wym_tools_paste"},{name:"ToggleHtml",title:"HTML",css:"wym_tools_html"},{name:"Preview",title:"Preview",css:"wym_tools_preview"}],containersHtml:String()+'
    '+"

    {Containers}

    "+"
      "+WYMeditor.CONTAINERS_ITEMS+"
    "+"
    ",containersItemHtml:String()+'
  • '+''+WYMeditor.CONTAINER_TITLE+""+"
  • ",containersItems:[{name:"P",title:"Paragraph",css:"wym_containers_p"},{name:"H1",title:"Heading_1",css:"wym_containers_h1"},{name:"H2",title:"Heading_2",css:"wym_containers_h2"},{name:"H3",title:"Heading_3",css:"wym_containers_h3"},{name:"H4",title:"Heading_4",css:"wym_containers_h4"},{name:"H5",title:"Heading_5",css:"wym_containers_h5"},{name:"H6",title:"Heading_6",css:"wym_containers_h6"},{name:"PRE",title:"Preformatted",css:"wym_containers_pre"},{name:"BLOCKQUOTE",title:"Blockquote",css:"wym_containers_blockquote"},{name:"TH",title:"Table_Header",css:"wym_containers_th"}],classesHtml:String()+'
    '+"

    {Classes}

    "+"
      "+WYMeditor.CLASSES_ITEMS+"
    "+"
    ",classesItemHtml:String()+'
  • '+''+WYMeditor.CLASS_TITLE+""+"
  • ",classesItems:[],statusHtml:String()+'
    '+"

    {Status}

    "+"
    ",htmlHtml:String()+'
    '+"

    {Source_Code}

    "+''+"
    ",boxSelector:".wym_box",toolsSelector:".wym_tools",toolsListSelector:" ul",containersSelector:".wym_containers",classesSelector:".wym_classes",htmlSelector:".wym_html",iframeSelector:".wym_iframe iframe",iframeBodySelector:".wym_iframe",statusSelector:".wym_status",toolSelector:".wym_tools a",containerSelector:".wym_containers a",classSelector:".wym_classes a",htmlValSelector:".wym_html_val",hrefSelector:".wym_href",srcSelector:".wym_src",titleSelector:".wym_title",relSelector:".wym_rel",altSelector:".wym_alt",textSelector:".wym_text",rowsSelector:".wym_rows",colsSelector:".wym_cols",captionSelector:".wym_caption",summarySelector:".wym_summary",submitSelector:"form",cancelSelector:".wym_cancel",previewSelector:"",dialogTypeSelector:".wym_dialog_type",dialogLinkSelector:".wym_dialog_link",dialogImageSelector:".wym_dialog_image",dialogTableSelector:".wym_dialog_table",dialogPasteSelector:".wym_dialog_paste",dialogPreviewSelector:".wym_dialog_preview",updateSelector:".wymupdate",updateEvent:"click",dialogFeatures:"menubar=no,titlebar=no,toolbar=no,resizable=no,width=560,height=300,top=0,left=0",dialogFeaturesPreview:"menubar=no,titlebar=no,toolbar=no,resizable=no,scrollbars=yes,width=560,height=300,top=0,left=0",dialogHtml:String()+''+''+""+''+""+WYMeditor.DIALOG_TITLE+""+''+''+""+WYMeditor.DIALOG_BODY+"",dialogLinkHtml:String()+''+"
    "+"
    "+''+"{Link}"+'
    '+""+''+"
    "+'
    '+""+''+"
    "+'
    '+""+''+"
    "+'
    '+''+''+"
    "+"
    "+"
    "+"",dialogImageHtml:String()+''+"
    "+"
    "+''+"{Image}"+'
    '+""+''+"
    "+'
    '+""+''+"
    "+'
    '+""+''+"
    "+'
    '+''+''+"
    "+"
    "+"
    "+"",dialogTableHtml:String()+''+"
    "+"
    "+''+"{Table}"+'
    '+""+''+"
    "+'
    '+""+''+"
    "+'
    '+""+''+"
    "+'
    '+""+''+"
    "+'
    '+''+''+"
    "+"
    "+"
    "+"",dialogPasteHtml:String()+''+"
    "+''+"
    "+"{Paste_From_Word}"+'
    '+''+"
    "+'
    '+''+''+"
    "+"
    "+"
    "+"",dialogPreviewHtml:String()+'',dialogStyles:[],stringDelimiterLeft:"{",stringDelimiterRight:"}",preInit:null,preBind:null,postInit:null,preInitDialog:null,postInitDialog:null},a),this.each(function(){var b=new WYMeditor.editor(jQuery(this),a)})},jQuery.extend({wymeditors:function(a){return WYMeditor.INSTANCES[a]}}),WYMeditor.computeWymPath=function(){var a=jQuery(jQuery.grep(jQuery("script"),function(a){return a.src?a.src.match(/jquery\.wymeditor(\.pack|\.min|\.packed)?\.js(\?.*)?$/)||a.src.match(/\/core\.js(\?.*)?$/):null}));return a.length>0?a.attr("src"):(WYMeditor.console.warn("Error determining wymPath. No base WYMeditor file located."),WYMeditor.console.warn("Assuming wymPath to be the current URL"),WYMeditor.console.warn("Please pass a correct wymPath option"),"")},WYMeditor.computeBasePath=function(a){var b=a.lastIndexOf("/");return a.substr(0,b+1)},WYMeditor.computeJqueryPath=function(){return jQuery(jQuery.grep(jQuery("script"),function(a){return a.src&&a.src.match(/jquery(-(.*)){0,1}(\.pack|\.min|\.packed)?\.js(\?.*)?$/)})).attr("src")},WYMeditor.INIT_DIALOG=function(index){var wym=window.opener.WYMeditor.INSTANCES[index],doc=window.document,selected=wym.selected(),dialogType=jQuery(wym._options.dialogTypeSelector).val(),sStamp=wym.uniqueStamp(),styles,aCss,tableOnClick;dialogType===WYMeditor.DIALOG_LINK&&(selected&&selected.tagName&&selected.tagName.toLowerCase!==WYMeditor.A&&(selected=jQuery(selected).parentsOrSelf(WYMeditor.A)),!selected&&wym._selected_image&&(selected=jQuery(wym._selected_image).parentsOrSelf(WYMeditor.A))),jQuery.isFunction(wym._options.preInitDialog)&&wym._options.preInitDialog(wym,window),styles=doc.styleSheets[0],aCss=eval(wym._options.dialogStyles),wym.addCssRules(doc,aCss),selected&&(jQuery(wym._options.hrefSelector).val(jQuery(selected).attr(WYMeditor.HREF)),jQuery(wym._options.srcSelector).val(jQuery(selected).attr(WYMeditor.SRC)),jQuery(wym._options.titleSelector).val(jQuery(selected).attr(WYMeditor.TITLE)),jQuery(wym._options.relSelector).val(jQuery(selected).attr(WYMeditor.REL)),jQuery(wym._options.altSelector).val(jQuery(selected).attr(WYMeditor.ALT))),wym._selected_image&&(jQuery(wym._options.dialogImageSelector+" "+wym._options.srcSelector).val(jQuery(wym._selected_image).attr(WYMeditor.SRC)),jQuery(wym._options.dialogImageSelector+" "+wym._options.titleSelector).val(jQuery(wym._selected_image).attr(WYMeditor.TITLE)),jQuery(wym._options.dialogImageSelector+" "+wym._options.altSelector).val(jQuery(wym._selected_image).attr(WYMeditor.ALT))),jQuery(wym._options.dialogLinkSelector+" "+wym._options.submitSelector).submit(function(){var a=jQuery(wym._options.hrefSelector).val(),b;a.length>0&&(selected[0]&&selected[0].tagName.toLowerCase()===WYMeditor.A?b=selected:(wym._exec(WYMeditor.CREATE_LINK,sStamp),b=jQuery("a[href="+sStamp+"]",wym._doc.body)),b.attr(WYMeditor.HREF,a),b.attr(WYMeditor.TITLE,jQuery(wym._options.titleSelector).val()),b.attr(WYMeditor.REL,jQuery(wym._options.relSelector).val())),window.close()}),jQuery(wym._options.dialogImageSelector+" "+wym._options.submitSelector).submit(function(){var a=jQuery(wym._options.srcSelector).val(),b;a.length>0&&(wym._exec(WYMeditor.INSERT_IMAGE,sStamp),b=jQuery("img[src$="+sStamp+"]",wym._doc.body),b.attr(WYMeditor.SRC,a),b.attr(WYMeditor.TITLE,jQuery(wym._options.titleSelector).val()),b.attr(WYMeditor.ALT,jQuery(wym._options.altSelector).val())),window.close()}),tableOnClick=WYMeditor.MAKE_TABLE_ONCLICK(wym),jQuery(wym._options.dialogTableSelector+" "+wym._options.submitSelector).submit(tableOnClick),jQuery(wym._options.dialogPasteSelector+" "+wym._options.submitSelector).submit(function(){var a=jQuery(wym._options.textSelector).val();wym.paste(a),window.close()}),jQuery(wym._options.dialogPreviewSelector+" "+wym._options.previewSelector).html(wym.xhtml()),jQuery(wym._options.cancelSelector).mousedown(function(){window.close()}),jQuery.isFunction(wym._options.postInitDialog)&&wym._options.postInitDialog(wym,window)},WYMeditor.MAKE_TABLE_ONCLICK=function(a){var b=function(){var b=jQuery(a._options.rowsSelector).val(),c=jQuery(a._options.colsSelector).val(),d=jQuery(a._options.captionSelector).val(),e=jQuery(a._options.summarySelector).val(),f=a.insertTable(b,c,d,e);window.close()};return b},jQuery.fn.isPhantomNode=function(){return this[0].nodeType===3?!/[^\t\n\r ]/.test(this[0].data):!1},WYMeditor.isPhantomNode=function(a){return a.nodeType===3?!/[^\t\n\r ]/.test(a.data):!1},WYMeditor.isPhantomString=function(a){return!/[^\t\n\r ]/.test(a)},jQuery.fn.parentsOrSelf=function(a){var b=this;return b[0].nodeType===3&&(b=b.parents().slice(0,1)),b.filter(a).size()===1?b:b.parents(a).slice(0,1)},WYMeditor.Helper={replaceAll:function(a,b,c){var d=new RegExp(b,"g");return a.replace(d,c)},insertAt:function(a,b,c){return a.substr(0,c)+b+a.substring(c)},trim:function(a){return a.replace(/^(\s*)|(\s*)$/gm,"")},contains:function(a,b){var c;for(c=0;c["+a.childNodes.length+"]":a.nodeName:"[No node]"}function j(a){this._next=this.root=a}function k(a,b){this.node=a,this.offset=b}function l(a){this.code=this[a],this.codeName=a,this.message="DOMException: "+this.codeName}var m=a.util;m.areHostMethods(document,["createDocumentFragment","createElement","createTextNode"])||b.fail("document missing a Node creation method"),m.isHostMethod(document,"getElementsByTagName")||b.fail("document missing getElementsByTagName method");var n=document.createElement("div");m.areHostMethods(n,["insertBefore","appendChild","cloneNode"])||b.fail("Incomplete Element implementation"),n=document.createTextNode("test"),m.areHostMethods(n,["splitText","deleteData","insertData","appendData","cloneNode"])||b.fail("Incomplete Text Node implementation");var o=function(a,b){for(var c=a.length;c--;)if(a[c]===b)return!0;return!1};j.prototype={_current:null,hasNext:function(){return!!this._next},next:function(){var a=this._current=this._next,b;if(this._current)if(b=a.firstChild)this._next=b;else{for(b=null;a!==this.root&&!(b=a.nextSibling);)a=a.parentNode;this._next=b}return this._current},detach:function(){this._current=this._next=this.root=null}},k.prototype={equals:function(a){return this.node===a.node&this.offset==a.offset},inspect:function(){return"[DomPosition("+i(this.node)+":"+this.offset+")]"}},l.prototype={INDEX_SIZE_ERR:1,HIERARCHY_REQUEST_ERR:3,WRONG_DOCUMENT_ERR:4,NO_MODIFICATION_ALLOWED_ERR:7,NOT_FOUND_ERR:8,NOT_SUPPORTED_ERR:9,INVALID_STATE_ERR:11},l.prototype.toString=function(){return this.message},a.dom={arrayContains:o,getNodeIndex:c,getCommonAncestor:d,isAncestorOf:function(a,b,c){for(b=c?b:b.parentNode;b;){if(b===a)return!0;b=b.parentNode}return!1},getClosestAncestorIn:e,isCharacterDataNode:f,insertAfter:g,splitDataNode:function(a,b){var c;return a.nodeType==3?c=a.splitText(b):(c=a.cloneNode(),c.deleteData(0,b),a.deleteData(0,a.length-b),g(c,a)),c},getDocument:h,getWindow:function(a){a=h(a);if(typeof a.defaultView!="undefined")return a.defaultView;if(typeof a.parentWindow!="undefined")return a.parentWindow;throw Error("Cannot get a window object for node")},getIframeWindow:function(a){if(typeof a.contentWindow!="undefined")return a.contentWindow;if(typeof a.contentDocument!="undefined")return a.contentDocument.defaultView;throw Error("getIframeWindow: No Window object found for iframe element")},getIframeDocument:function(a){if(typeof a.contentDocument!="undefined")return a.contentDocument;if(typeof a.contentWindow!="undefined")return a.contentWindow.document;throw Error("getIframeWindow: No Document object found for iframe element")},getBody:function(a){return m.isHostObject(a,"body")?a.body:a.getElementsByTagName("body")[0]},comparePoints:function(a,b,f,g){var h;if(a==f)return b===g?0:b=b.childNodes.length?b.appendChild(a):b.insertBefore(a,b.childNodes[c]),d}function i(a){for(var b,d,e=c(a.range).createDocumentFragment();d=a.next();){b=a.isPartiallySelectedSubtree(),d=d.cloneNode(!b),b&&(b=a.getSubtreeIterator(),d.appendChild(i(b)),b.detach(!0));if(d.nodeType==10)throw new J("HIERARCHY_REQUEST_ERR");e.appendChild(d)}return e}function j(a,b,c){var d,e;for(c=c||{stop:!1};d=a.next();)if(a.isPartiallySelectedSubtree()){if(b(d)===!1){c.stop=!0;return}d=a.getSubtreeIterator(),j(d,b,c),d.detach(!0);if(c.stop)return}else for(d=H.createIterator(d);e=d.next();)if(b(e)===!1){c.stop=!0;return}}function k(a){for(var b;a.next();)a.isPartiallySelectedSubtree()?(b=a.getSubtreeIterator(),k(b),b.detach(!0)):a.remove()}function l(a){for(var b,d=c(a.range).createDocumentFragment(),e;b=a.next();){a.isPartiallySelectedSubtree()?(b=b.cloneNode(!1),e=a.getSubtreeIterator(),b.appendChild(l(e)),e.detach(!0)):a.remove();if(b.nodeType==10)throw new J("HIERARCHY_REQUEST_ERR");d.appendChild(b)}return d}function m(a,b,c){var d=!!b&&!!b.length,e,f=!!c;d&&(e=RegExp("^("+b.join("|")+")$"));var g=[];return j(new o(a,!1),function(a){(!d||e.test(a.nodeType))&&(!f||c(a))&&g.push(a)}),g}function n(a){return"["+(typeof a.getName=="undefined"?"Range":a.getName())+"("+H.inspectNode(a.startContainer)+":"+a.startOffset+", "+H.inspectNode(a.endContainer)+":"+a.endOffset+")]"}function o(a,b){this.range=a,this.clonePartiallySelectedTextNodes=b;if(!a.collapsed){this.sc=a.startContainer,this.so=a.startOffset,this.ec=a.endContainer,this.eo=a.endOffset;var c=a.commonAncestorContainer;this.sc===this.ec&&H.isCharacterDataNode(this.sc)?(this.isSingleCharacterDataNode=!0,this._first=this._last=this._next=this.sc):(this._first=this._next=this.sc===c&&!H.isCharacterDataNode(this.sc)?this.sc.childNodes[this.so]:H.getClosestAncestorIn(this.sc,c,!0),this._last=this.ec===c&&!H.isCharacterDataNode(this.ec)?this.ec.childNodes[this.eo-1]:H.getClosestAncestorIn(this.ec,c,!0))}}function p(a){this.code=this[a],this.codeName=a,this.message="RangeException: "+this.codeName}function q(a,b,c){this.nodes=m(a,b,c),this._next=this.nodes[0],this._position=0}function r(a){return function(b,c){for(var d,e=c?b:b.parentNode;e;){d=e.nodeType;if(H.arrayContains(a,d))return e;e=e.parentNode}return null}}function s(a){for(var b;b=a.parentNode;)a=b;return a}function t(a,b){if(Q(a,b))throw new p("INVALID_NODE_TYPE_ERR")}function u(a){if(!a.startContainer)throw new J("INVALID_STATE_ERR")}function v(a,b){if(!H.arrayContains(b,a.nodeType))throw new p("INVALID_NODE_TYPE_ERR")}function w(a,b){if(b<0||b>(H.isCharacterDataNode(a)?a.length:a.childNodes.length))throw new J("INDEX_SIZE_ERR")}function x(a,b){if(O(a,!0)!==O(b,!0))throw new J("WRONG_DOCUMENT_ERR")}function y(a){if(P(a,!0))throw new J("NO_MODIFICATION_ALLOWED_ERR")}function z(a,b){if(!a)throw new J(b)}function A(a){if(!O(a.startContainer,!0)||!O(a.endContainer,!0)||!(a.startOffset<=(H.isCharacterDataNode(a.startContainer)?a.startContainer.length:a.startContainer.childNodes.length))||!(a.endOffset<=(H.isCharacterDataNode(a.endContainer)?a.endContainer.length:a.endContainer.childNodes.length)))throw Error("Range error: Range is no longer valid after DOM mutation ("+a.inspect()+")")}function B(a){a.START_TO_START=S,a.START_TO_END=T,a.END_TO_END=U,a.END_TO_START=V,a.NODE_BEFORE=W,a.NODE_AFTER=X,a.NODE_BEFORE_AND_AFTER=Y,a.NODE_INSIDE=Z}function C(a){B(a),B(a.prototype)}function D(a,d,r){function B(a,b){return function(c){u(this),v(c,K),v(s(c),L),c=(a?e:f)(c),(b?D:E)(this,c.node,c.offset)}}function D(a,b,c){var e=a.endContainer,f=a.endOffset;if(b!==a.startContainer||c!==this.startOffset){if(s(b)!=s(e)||H.comparePoints(b,c,e,f)==1)e=b,f=c;d(a,b,c,e,f)}}function E(a,b,c){var e=a.startContainer,f=a.startOffset;if(b!==a.endContainer||c!==this.endOffset){if(s(b)!=s(e)||H.comparePoints(b,c,e,f)==-1)e=b,f=c;d(a,e,f,b,c)}}function F(a,b,c){(b!==a.startContainer||c!==this.startOffset||b!==a.endContainer||c!==this.endOffset)&&d(a,b,c,b,c)}function I(a){return function(){u(this),A(this);var b=this.startContainer,c=this.startOffset,e=this.commonAncestorContainer,g=new o(this,!0);return b!==e&&(b=H.getClosestAncestorIn(b,e,!0),c=f(b),b=c.node,c=c.offset),j(g,y),g.reset(),e=a(g),g.detach(),d(this,b,c,b,c),e}}a.prototype={attachListener:function(a,b){this._listeners[a].push(b)},setStart:function(a,b){u(this),t(a,!0),w(a,b),D(this,a,b)},setEnd:function(a,b){u(this),t(a,!0),w(a,b),E(this,a,b)},setStartBefore:B(!0,!0),setStartAfter:B(!1,!0),setEndBefore:B(!0,!1),setEndAfter:B(!1,!1),collapse:function(a){u(this),A(this),a?d(this,this.startContainer,this.startOffset,this.startContainer,this.startOffset):d(this,this.endContainer,this.endOffset,this.endContainer,this.endOffset)},selectNodeContents:function(a){u(this),t(a,!0),d(this,a,0,a,g(a))},selectNode:function(a){u(this),t(a,!1),v(a,K);var b=e(a);a=f(a),d(this,b.node,b.offset,a.node,a.offset)},compareBoundaryPoints:function(a,b){u(this),A(this),x(this.startContainer,b.startContainer);var c=a==V||a==S?"start":"end",d=a==T||a==S?"start":"end";return H.comparePoints(this[c+"Container"],this[c+"Offset"],b[d+"Container"],b[d+"Offset"])},insertNode:function(a){u(this),A(this),v(a,M),y(this.startContainer);if(H.isAncestorOf(a,this.startContainer,!0))throw new J("HIERARCHY_REQUEST_ERR");this.setStartBefore(h(a,this.startContainer,this.startOffset))},cloneContents:function(){u(this),A(this);var a,b;return this.collapsed?c(this).createDocumentFragment():this.startContainer===this.endContainer&&H.isCharacterDataNode(this.startContainer)?(a=this.startContainer.cloneNode(!0),a.data=a.data.slice(this.startOffset,this.endOffset),b=c(this).createDocumentFragment(),b.appendChild(a),b):(b=new o(this,!0),a=i(b),b.detach(),a)},extractContents:I(l),deleteContents:I(k),canSurroundContents:function(){u(this),A(this),y(this.startContainer),y(this.endContainer);var a=new o(this,!0),c=a._first&&b(a._first,this)||a._last&&b(a._last,this);return a.detach(),!c},surroundContents:function(a){v(a,N);if(!this.canSurroundContents())throw new p("BAD_BOUNDARYPOINTS_ERR");var b=this.extractContents();if(a.hasChildNodes())for(;a.lastChild;)a.removeChild(a.lastChild);h(a,this.startContainer,this.startOffset),a.appendChild(b),this.selectNode(a)},cloneRange:function(){u(this),A(this);for(var a=new G(c(this)),b=R.length,d;b--;)d=R[b],a[d]=this[d];return a},detach:function(){r(this)},toString:function(){u(this),A(this);var a=this.startContainer;if(a===this.endContainer&&H.isCharacterDataNode(a))return a.nodeType==3||a.nodeType==4?a.data.slice(this.startOffset,this.endOffset):"";var b=[];return a=new o(this,!0),j(a,function(a){(a.nodeType==3||a.nodeType==4)&& -b.push(a.data)}),a.detach(),b.join("")},compareNode:function(a){u(this),A(this);var b=a.parentNode,c=H.getNodeIndex(a);if(!b)throw new J("NOT_FOUND_ERR");return a=this.comparePoint(b,c),b=this.comparePoint(b,c+1),a<0?b>0?Y:W:b>0?X:Z},comparePoint:function(a,b){return u(this),A(this),z(a,"HIERARCHY_REQUEST_ERR"),x(a,this.startContainer),H.comparePoints(a,b,this.startContainer,this.startOffset)<0?-1:H.comparePoints(a,b,this.endContainer,this.endOffset)>0?1:0},createContextualFragment:function(a){u(this);var b=c(this),d=b.createElement("div");d.innerHTML=a;for(a=b.createDocumentFragment();b=d.firstChild;)a.appendChild(b);return a},intersectsNode:function(a,b){u(this),A(this),z(a,"NOT_FOUND_ERR");if(H.getDocument(a)!==c(this))return!1;var d=a.parentNode,e=H.getNodeIndex(a);z(d,"NOT_FOUND_ERR");var f=H.comparePoints(d,e,this.endContainer,this.endOffset);return d=H.comparePoints(d,e+1,this.startContainer,this.startOffset),b?f<=0&&d>=0:f<0&&d>0},isPointInRange:function(a,b){return u(this),A(this),z(a,"HIERARCHY_REQUEST_ERR"),x(a,this.startContainer),H.comparePoints(a,b,this.startContainer,this.startOffset)>=0&&H.comparePoints(a,b,this.endContainer,this.endOffset)<=0},intersectsRange:function(a){u(this),A(this);if(c(a)!=c(this))throw new J("WRONG_DOCUMENT_ERR");return H.comparePoints(this.startContainer,this.startOffset,a.endContainer,a.endOffset)<0&&H.comparePoints(this.endContainer,this.endOffset,a.startContainer,a.startOffset)>0},intersection:function(a){if(this.intersectsRange(a)){var b=H.comparePoints(this.startContainer,this.startOffset,a.startContainer,a.startOffset),c=H.comparePoints(this.endContainer,this.endOffset,a.endContainer,a.endOffset),d=this.cloneRange();return b==-1&&d.setStart(a.startContainer,a.startOffset),c==1&&d.setEnd(a.endContainer,a.endOffset),d}return null},containsNode:function(a,b){return b?this.intersectsNode(a,!1):this.compareNode(a)==Z},containsNodeContents:function(a){return this.comparePoint(a,0)>=0&&this.comparePoint(a,g(a))<=0},splitBoundaries:function(){A(this);var a=this.startContainer,b=this.startOffset,c=this.endContainer,e=this.endOffset,f=a===c;H.isCharacterDataNode(c)&&e>0&&e0&&b=H.getNodeIndex(a)&&e++,b=0),d(this,a,b,c,e)},normalizeBoundaries:function(){A(this);var a=this.startContainer,b=this.startOffset,c=this.endContainer,e=this.endOffset,f=function(a){var b=a.nextSibling;b&&b.nodeType==a.nodeType&&(c=a,e=a.length,a.appendData(b.data),b.parentNode.removeChild(b))},g=function(d){var f=d.previousSibling;if(f&&f.nodeType==d.nodeType){a=d;var g=d.length;b=f.length,d.insertData(0,f.data),f.parentNode.removeChild(f),a==c?(e+=b,c=a):c==d.parentNode&&(f=H.getNodeIndex(d),e==f?(c=d,e=g):e>f&&e--)}},h=!0;H.isCharacterDataNode(c)?c.length==e&&f(c):(e>0&&(h=c.childNodes[e-1])&&H.isCharacterDataNode(h)&&f(h),h=!this.collapsed),h?H.isCharacterDataNode(a)?b==0&&g(a):b0&&b.previousSibling);j=b.nextSibling;if(i==-1&&j&&e.isCharacterDataNode(j)){g.setEndPoint(c?"EndToStart":"EndToEnd",a);if(/[\r\n]/.test(j.data)){h=g.duplicate(),c=h.text.replace(/\r\n/g,"\r").length;for(c=h.moveStart("character",c);h.compareEndPoints("StartToEnd",h)==-1;)c++,h.moveStart("character",1)}else c=g.text.length;h=new f(j,c)}else j=(d||!c)&&b.previousSibling,h=(c=(d||c)&&b.nextSibling)&&e.isCharacterDataNode(c)?new f(c,0):j&&e.isCharacterDataNode(j)?new f(j,j.length):new f(h,e.getNodeIndex(b));return b.parentNode.removeChild(b),h}function c(a,b){var c,d,f=a.offset,g=e.getDocument(a.node),h=g.body.createTextRange(),i=e.isCharacterDataNode(a.node);return i?(c=a.node,d=c.parentNode):(c=a.node.childNodes,c=f12"),b.close();var c=p.getIframeWindow(a).getSelection(),d=b.documentElement.lastChild.firstChild;b=b.createRange(),b.setStart(d,1),b.collapse(!0),c.addRange(b),F=c.rangeCount==1,c.removeAllRanges();var e=b.cloneRange();b.setStart(d,0),e.setEnd(d,2),c.addRange(b),c.addRange(e),E=c.rangeCount==2,b.detach(),e.detach(),A.removeChild(a)}(),a.features.selectionSupportsMultipleRanges=E,a.features.collapsedNonEditableSelectionsSupported=F;var G=!1,H;A&&q.isHostMethod(A,"createControlRange")&&(H=A.createControlRange(),q.areHostProperties(H,["item","add"])&&(G=!0)),a.features.implementsControlRange=G,w=B?function(a){return a.anchorNode===a.focusNode&&a.anchorOffset===a.focusOffset}:function(a){return a.rangeCount?a.getRangeAt(a.rangeCount-1).collapsed:!1};var I;q.isHostMethod(x,"getRangeAt")?I=function(a,b){try{return a.getRangeAt(b)}catch(c){return null}}:B&&(I=function(b){var c=p.getDocument(b.anchorNode);return c=a.createRange(c),c.setStart(b.anchorNode,b.anchorOffset),c.setEnd(b.focusNode,b.focusOffset),c.collapsed!==this.isCollapsed&&(c.setStart(b.focusNode,b.focusOffset),c.setEnd(b.anchorNode,b.anchorOffset)),c}),a.getSelection=function(a){a=a||window;var b=a._rangySelection,c=v(a),e=y?d(a):null;return b?(b.nativeSelection=c,b.docSelection=e,b.refresh(a)):(b=new l(c,e,a),a._rangySelection=b),b},a.getIframeSelection=function(b){return a.getSelection(p.getIframeWindow(b))},H=l.prototype;if(B&&q.areHostMethods(x,["removeAllRanges","addRange"])){H.removeAllRanges=function(){this.nativeSelection.removeAllRanges(),f(this)};var J=function(b,c){var d=r.getRangeDocument(c);d=a.createRange(d),d.collapseToPoint(c.endContainer,c.endOffset),b.nativeSelection.addRange(g(d)),b.nativeSelection.extend(c.startContainer,c.startOffset),b.refresh()};H.addRange=D?function(b,c){if(G&&y&&this.docSelection.type=="Control")k(this,b);else if(c&&C)J(this,b);else{var d;E?d=this.rangeCount:(this.removeAllRanges(),d=0),this.nativeSelection.addRange(g(b)),this.rangeCount=this.nativeSelection.rangeCount,this.rangeCount==d+1?(a.config.checkSelectionRanges&&(d=I(this.nativeSelection,this.rangeCount-1))&&!r.rangesEqual(d,b)&&(b=new s(d)),this._ranges[this.rangeCount-1]=b,e(this,b,M(this.nativeSelection)),this.isCollapsed=w(this)):this.refresh()}}:function(a,b){b&&C?J(this,a):(this.nativeSelection.addRange(g(a)),this.refresh())},H.setRanges=function(a){if(G&&a.length>1)m(this,a);else{this.removeAllRanges();for(var b=0,c=a.length;b1?m(this,a):b&&this.addRange(a[0])};else return b.fail("No means of selecting a Range or TextRange was found"),!1;H.getRangeAt=function(a){if(a<0||a>=this.rangeCount)throw new t("INDEX_SIZE_ERR");return this._ranges[a]};var K;if(q.isHostMethod(x,"getRangeAt")&&typeof x.rangeCount=="number")K=function(b){if(G&&y&&b.docSelection.type=="Control")j(b);else{b._ranges.length=b.rangeCount=b.nativeSelection.rangeCount;if(b.rangeCount){for(var c=0,d=b.rangeCount;c0&&(h=f.item(0));for(i=0;i',e,f,g;c.length>0&&(e=$(c[0]),f=$(c[c.length-1]),e.is(a)&&e.before(d),f.is(a)&&f.after(d)),g=this._getBlockSepSelector(),b.find(g).before(d)},WYMeditor.editor.prototype._getBlockSepSelector=function(){if(typeof this._blockSpacersSel!="undefined")return this._blockSpacersSel;var a=[];return $.each(WYMeditor.BLOCKING_ELEMENTS,function(b,c){$.each(WYMeditor.BLOCKING_ELEMENTS,function(b,d){a.push(c+" + "+d)})}),$.each(WYMeditor.BLOCKING_ELEMENTS,function(b,c){$.each(WYMeditor.NON_BLOCKING_ELEMENTS,function(b,d){a.push(c+" + "+d),a.push(d+" + "+c)})}),this._blockSpacersSel=a.join(", "),this._blockSpacersSel},WYMeditor.editor.prototype.fixDoubleBr=function(){var a=$(this._doc).find("body.wym_iframe"),b;a.children("br + br").filter(":not(pre br)").remove(),a.find("p + br").next("p").prev("br").remove(),b=a.find("p + br").slice(-1),b.length>0&&b.next().length===0&&b.remove()},WYMeditor.editor.prototype.dialog=function(a,b,c){var d=b||this._wym._options.dialogFeatures,e=window.open("","dialog",d),f,g=WYMeditor.Helper,h,i;if(e){f="";switch(a){case WYMeditor.DIALOG_LINK:f=this._options.dialogLinkHtml;break;case WYMeditor.DIALOG_IMAGE:f=this._options.dialogImageHtml;break;case WYMeditor.DIALOG_TABLE:f=this._options.dialogTableHtml;break;case WYMeditor.DIALOG_PASTE:f=this._options.dialogPasteHtml;break;case WYMeditor.PREVIEW:f=this._options.dialogPreviewHtml;break;default:f=c}h=this._options.dialogHtml,h=g.replaceAll(h,WYMeditor.BASE_PATH,this._options.basePath),h=g.replaceAll(h,WYMeditor.DIRECTION,this._options.direction),h=g.replaceAll(h,WYMeditor.CSS_PATH,this._options.skinPath+WYMeditor.SKINS_DEFAULT_CSS),h=g.replaceAll(h,WYMeditor.WYM_PATH,this._options.wymPath),h=g.replaceAll(h,WYMeditor.JQUERY_PATH,this._options.jQueryPath),h=g.replaceAll(h,WYMeditor.DIALOG_TITLE,this.encloseString(a)),h=g.replaceAll(h,WYMeditor.DIALOG_BODY,f),h=g.replaceAll(h,WYMeditor.INDEX,this._index),h=this.replaceStrings(h),i=e.document,i.write(h),i.close()}},WYMeditor.editor.prototype.toggleHtml=function(){jQuery(this._box).find(this._options.htmlSelector).toggle()},WYMeditor.editor.prototype.uniqueStamp=function(){var a=new Date;return"wym-"+a.getTime()},WYMeditor.editor.prototype.paste=function(a){var b=this.selected(),c="",d,e,f,g;d=a.split(new RegExp(WYMeditor.NEWLINE+"{2,}","g"));for(f=0,g=d.length;f"+d[f].split(WYMeditor.NEWLINE).join("
    ")+"

    ";b&&b.tagName.toLowerCase()!==WYMeditor.BODY?(d=jQuery(c,this._doc).insertAfter(b),e=d[d.length-1]):(d=jQuery(c,this._doc).appendTo(this._doc.body),e=d[d.length-1]),jQuery(b).text()===""&&jQuery(b).remove(),jQuery("body > br",this._doc).remove(),this.setFocusToNode(e)},WYMeditor.editor.prototype.insert=function(a){var b=this._iframe.contentWindow.getSelection(),c,d;b.focusNode!==null?(c=b.getRangeAt(0),d=c.createContextualFragment(a),c.deleteContents(),c.insertNode(d)):this.paste(a)},WYMeditor.editor.prototype.wrap=function(a,b){this.insert(a+this._iframe.contentWindow.getSelection().toString()+b)},WYMeditor.editor.prototype.unwrap=function(){this.insert(this._iframe.contentWindow.getSelection().toString())},WYMeditor.editor.prototype.setFocusToNode=function(a,b){var c=this._doc.createRange(),d=this._iframe.contentWindow.getSelection();b=b?0:1,c.selectNodeContents(a),d.addRange(c),d.collapse(a,b),this._iframe.contentWindow.focus()},WYMeditor.editor.prototype.addCssRules=function(a,b){var c=a.styleSheets[0],d,e;if(c)for(d=0;d1||c.tagName.toLowerCase()===WYMeditor.OL||c.tagName.toLowerCase()===WYMeditor.UL||c.tagName.toLowerCase()===WYMeditor.LI)return!0}return!1},WYMeditor.editor.prototype._canOutdent=function(a,b){if(a&&a===b&&a.tagName.toLowerCase()===WYMeditor.LI){var c=a.parentNode.parentNode;if(a.parentNode.childNodes.length>1||c.tagName.toLowerCase()===WYMeditor.OL||c.tagName.toLowerCase()===WYMeditor.UL||c.tagName.toLowerCase()===WYMeditor.LI)if($(c).parent().is("ol,ul,li"))return!0}return!1},WYMeditor.editor.prototype.indent=function(){var a=this.selected(),b=rangy.getIframeSelection(this._iframe),c=b.getRangeAt(0).startContainer,d=b.getRangeAt(0).startOffset,e=b.anchorNode,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y;a=this.findUp(a,WYMeditor.BLOCKS),e=this.findUp(e,WYMeditor.BLOCKS);if(!this._canIndent(a,e))return;i=$(a),j=i.parent()[0].tagName.toLowerCase(),k=i.contents().not("ol,ul"),i.prev().length===0&&i.parent().not("ul,ol,li")?(l='
  • <'+j+">"+"
  • ",i.before(l),f=i.prev().find(j),i.children().unwrap(),f.append(i)):i.prev().contents().last().is(j)?(m=i.prev(),n=m.contents().last(),o=i.children(),o.unwrap(),n.append(i),o.detach(),m.append(o),o.first().is(j)&&(p=o.first().children(),p.unwrap(),p.detach(),n.append(p))):i.children("ol,ul").length===0?(g=i.prev().filter("li"),i.children().unwrap(),q="<"+j+">",g.append(q),g.children(j).last().append(i)):(r=i.contents().unwrap(),r.wrapAll('
  • '),r.filter("ol,ul").first().prepend(i)),i.prepend(k),s=i.parent().parent("li.spacer_li"),s.length===1&&(t=s.prev().filter("li").contents().last(),t.is(j)?(h=i.parent().contents(),s.detach(),t.append(h)):s.next("li").contents().first().is(j)?(u=s.next("li").children().first(),h=i.parent().contents(),s.detach(),u.prepend(h)):s.prev().is("li")&&(g=s.prev(),s.detach(),g.append(s.contents()))),i.next().is(".spacer_li")&&(v=i.next(".spacer_li"),w=v.contents(),w.detach(),i.append(w),v.remove()),x=this._iframe.contentWindow,b=rangy.getSelection(x),y=rangy.createRange(this._doc),y.setStart(c,d),y.setEnd(c,d),y.collapse(!1),b.setSingleRange(y)},WYMeditor.editor.prototype.outdent=function(){var a=this.selected(),b=rangy.getIframeSelection(this._iframe),c=b.getRangeAt(0).startContainer,d=b.getRangeAt(0).startOffset,e=b.anchorNode,f,g,h,i,j,k,l,m,n;a=this.findUp(a,WYMeditor.BLOCKS),e=this.findUp(e,WYMeditor.BLOCKS);if(!this._canOutdent(a,e))return;f=$(a),g=f.parent().parent("li"),h=f.parent()[0].tagName.toLowerCase(),i=f.nextAll("li"),f.detach(),g.after(f),j=f.children("ol,ul"),j.length>0&&j.each(function(a,b){var c=$(b),d;c.detach(),d="<"+h+">"+'
  • '+"",f.append(d),f.children(h).last().children("li").append(c)}),i.length>0&&(k=i,k.detach(),f.append("<"+h+">"),f.find(h).last().append(i),l=f.children(h+" + "+h),l.length>0&&l.each(function(a,b){var c=$(b),d=c.contents(),e=c.prev();d.detach(),c.remove(),e.append(d)})),g.find("ul:empty,ol:empty").remove(),g.is(".spacer_li")&&g.is(":empty")&&g.remove(),m=this._iframe.contentWindow,b=rangy.getSelection(m),n=rangy.createRange(this._doc),n.setStart(c,d),n.setEnd(c,d),n.collapse(!1),b.setSingleRange(n)},WYMeditor.editor.prototype.insertTable=function(a,b,c,d){if(a<=0||b<=0)return;var e=this._doc.createElement(WYMeditor.TABLE),f=null,g=null,h,i,j,k;h=e.createCaption(),h.innerHTML=c;for(i=0;i",WYMeditor.WymClassExplorer.prototype.initIframe=function(iframe){this._iframe=iframe,this._doc=iframe.contentWindow.document;var styles=this._doc.styleSheets[0],aCss=eval(this._options.editorStyles);this.addCssRules(this._doc,aCss),this._doc.title=this._wym._index,jQuery("html",this._doc).attr("dir",this._options.direction),jQuery(this._doc.body).html(this._wym._html);var wym=this;this._doc.body.onfocus=function(){wym._doc.designMode="on",wym._doc=iframe.contentWindow.document},this._doc.onbeforedeactivate=function(){wym.saveCaret()},$(this._doc).bind("keyup",wym.keyup);var ieVersion=parseInt($.browser.version,10);ieVersion>=8&&ieVersion<9&&$(this._doc).bind("keydown",function(){wym.fixBluescreenOfDeath()}),this._doc.onkeyup=function(){wym.saveCaret()},this._doc.onclick=function(){wym.saveCaret()},this._doc.body.onbeforepaste=function(){wym._iframe.contentWindow.event.returnValue=!1},this._doc.body.onpaste=function(){wym._iframe.contentWindow.event.returnValue=!1,wym.paste(window.clipboardData.getData("Text"))},this._initialized&&(jQuery.isFunction(this._options.preBind)&&this._options.preBind(this),this._wym.bindEvents(),jQuery.isFunction(this._options.postInit)&&this._options.postInit(this),this.listen()),this._initialized=!0,this._doc.designMode="on";try{this._doc=iframe.contentWindow.document}catch(e){}},function(a){WYMeditor.WymClassExplorer.prototype.loadSkin=function(){jQuery(this._box).find(this._options.containerSelector).attr("unselectable","on"),a.call(this)}}(WYMeditor.editor.prototype.loadSkin),WYMeditor.WymClassExplorer.prototype.fixBluescreenOfDeath=function(){var a=$(this._doc).find("p").eq(0).position();typeof a!="undefined"&&a.left<0&&($(this._box).append('
    '),$(this._box).find("#wym-bluescreen-bug-fix").remove())},WYMeditor.WymClassExplorer.prototype._exec=function(a,b){b?this._doc.execCommand(a,!1,b):this._doc.execCommand(a)},WYMeditor.WymClassExplorer.prototype.selected=function(){var a=this._iframe.contentWindow.document.caretPos;if(a&&a.parentElement)return a.parentElement()},WYMeditor.WymClassExplorer.prototype.saveCaret=function(){this._doc.caretPos=this._doc.selection.createRange()},WYMeditor.WymClassExplorer.prototype.addCssRule=function(a,b){var c=b.name.split(","),d;for(d=0;d0){var e=$(c[0]),f=$(c[c.length-1]);e.is(a)&&e.before(d),$.browser.version>="7.0"&&f.is(a)&&f.after(d)}var g=this._getBlockSepSelector();b.find(g).before(d)},WYMeditor.WymClassMozilla=function(a){this._wym=a,this._class="class"},WYMeditor.WymClassMozilla.CELL_PLACEHOLDER='
    ',WYMeditor.WymClassMozilla.NEEDS_CELL_FIX=$.browser.version>="1.9.1"&&$.browser.version<"2.0",WYMeditor.WymClassMozilla.prototype.initIframe=function(iframe){var wym=this;this._iframe=iframe,this._doc=iframe.contentDocument;var styles=this._doc.styleSheets[0],aCss=eval(this._options.editorStyles);this.addCssRules(this._doc,aCss),this._doc.title=this._wym._index,jQuery("html",this._doc).attr("dir",this._options.direction),this.html(this._wym._html),this.enableDesignMode(),jQuery.isFunction(this._options.preBind)&&this._options.preBind(this),this._wym.bindEvents(),jQuery(this._doc).bind("keydown",this.keydown),jQuery(this._doc).bind("keyup",this.keyup),jQuery(this._doc).bind("click",this.click),jQuery(this._doc).bind("focus",function(){wym.enableDesignMode.call(wym)}),jQuery.isFunction(this._options.postInit)&&this._options.postInit(this),this.listen()},WYMeditor.WymClassMozilla.prototype.html=function(a){if(typeof a!="string")return jQuery(this._doc.body).html();try{this._doc.designMode="off"}catch(b){}return a=a.replace(/]*)>/gi,""),a=a.replace(/<\/em>/gi,""),a=a.replace(/]*)>/gi,""),a=a.replace(/<\/strong>/gi,""),jQuery(this._doc.body).html(a),this._wym.fixBodyHtml(),this.enableDesignMode(),!1},WYMeditor.WymClassMozilla.prototype._exec=function(a,b){if(!this.selected())return!1;b?this._doc.execCommand(a,"",b):this._doc.execCommand(a,"",null);var c=this.selected();return c.tagName.toLowerCase()===WYMeditor.BODY&&this._exec(WYMeditor.FORMAT_BLOCK,WYMeditor.P),!0},WYMeditor.WymClassMozilla.prototype.addCssRule=function(a,b){a.insertRule(b.name+" {"+b.css+"}",a.cssRules.length)},WYMeditor.WymClassMozilla.prototype.keydown=function(a){var b=WYMeditor.INSTANCES[this.title];if(a.ctrlKey){if(a.keyCode===66)return b._exec(WYMeditor.BOLD),!1;if(a.keyCode===73)return b._exec(WYMeditor.ITALIC),!1}return!0},WYMeditor.WymClassMozilla.prototype.keyup=function(a){var b=WYMeditor.INSTANCES[this.title];b._selected_image=null;var c=null;if(a.keyCode!==WYMeditor.KEY.BACKSPACE&&a.keyCode!==WYMeditor.KEY.CTRL&&a.keyCode!==WYMeditor.KEY.DELETE&&a.keyCode!==WYMeditor.KEY.COMMAND&&a.keyCode!==WYMeditor.KEY.UP&&a.keyCode!==WYMeditor.KEY.DOWN&&a.keyCode!==WYMeditor.KEY.LEFT&&a.keyCode!==WYMeditor.KEY.RIGHT&&a.keyCode!==WYMeditor.KEY.ENTER&&!a.metaKey&&!a.ctrlKey){c=b.selected();var d=c.tagName.toLowerCase();if(d==="strong"||d==="b"||d==="em"||d==="i"||d==="sub"||d==="sup"||d==="a")d=c.parentNode.tagName.toLowerCase();d===WYMeditor.BODY&&(b._exec(WYMeditor.FORMAT_BLOCK,WYMeditor.P),b.fixBodyHtml())}(a.keyCode===WYMeditor.KEY.UP||a.keyCode===WYMeditor.KEY.DOWN||a.keyCode===WYMeditor.KEY.LEFT||a.keyCode===WYMeditor.KEY.RIGHT||a.keyCode===WYMeditor.KEY.BACKSPACE||a.keyCode===WYMeditor.KEY.ENTER)&&b.fixBodyHtml()},WYMeditor.WymClassMozilla.prototype.click=function(a){var b=WYMeditor.INSTANCES[this.title],c=b.selected();WYMeditor.WymClassMozilla.NEEDS_CELL_FIX===!0&&c&&c.tagName.toLowerCase()===WYMeditor.TR&&jQuery(WYMeditor.TD,b._doc.body).append(WYMeditor.WymClassMozilla.CELL_PLACEHOLDER);if(c&&c.tagName.toLowerCase()===WYMeditor.BODY){var d=b._iframe.contentWindow.getSelection();d.isCollapsed===!0&&b._exec(WYMeditor.FORMAT_BLOCK,WYMeditor.P)}},WYMeditor.WymClassMozilla.prototype.enableDesignMode=function(){if(this._doc.designMode==="off")try{this._doc.designMode="on",this._doc.execCommand("styleWithCSS","",!1),this._doc.execCommand("enableObjectResizing",!1,!1)}catch(a){}},WYMeditor.WymClassMozilla.prototype.openBlockTag=function(a,b){b=this.validator.getValidTagAttributes(a,b);if(a==="span"&&b.style){var c=this.getTagForStyle(b.style);c&&(a=c,this._tag_stack.pop(),this._tag_stack.push(a),b.style="")}this.output+=this.helper.tag(a,b,!0)},WYMeditor.WymClassMozilla.prototype.getTagForStyle=function(a){return/bold/.test(a)?"strong":/italic/.test(a)?"em":/sub/.test(a)?"sub":/super/.test(a)?"sup":!1},WYMeditor.WymClassMozilla.prototype.afterInsertTable=function(a){WYMeditor.WymClassMozilla.NEEDS_CELL_FIX===!0&&$(a).find("td").each(function(a,b){$(b).append(WYMeditor.WymClassMozilla.CELL_PLACEHOLDER)})},WYMeditor.WymClassOpera=function(a){this._wym=a,this._class="class"},WYMeditor.WymClassOpera.prototype.initIframe=function(iframe){this._iframe=iframe,this._doc=iframe.contentWindow.document;var styles=this._doc.styleSheets[0],aCss=eval(this._options.editorStyles);this.addCssRules(this._doc,aCss),this._doc.title=this._wym._index,jQuery("html",this._doc).attr("dir",this._options.direction),this._doc.designMode="on",this.html(this._wym._html),jQuery.isFunction(this._options.preBind)&&this._options.preBind(this),this._wym.bindEvents(),jQuery(this._doc).bind("keydown",this.keydown),jQuery(this._doc).bind("keyup",this.keyup),jQuery.isFunction(this._options.postInit)&&this._options.postInit(this),this.listen()},WYMeditor.WymClassOpera.prototype._exec=function(a,b){b?this._doc.execCommand(a,!1,b):this._doc.execCommand(a)},WYMeditor.WymClassOpera.prototype.selected=function(){var a=this._iframe.contentWindow.getSelection(),b=a.focusNode;return b?b.nodeName=="#text"?b.parentNode:b:null},WYMeditor.WymClassOpera.prototype.addCssRule=function(a,b){a.insertRule(b.name+" {"+b.css+"}",a.cssRules.length)},WYMeditor.WymClassOpera.prototype.keydown=function(a){var b=WYMeditor.INSTANCES[this.title],c=b._iframe.contentWindow.getSelection();startNode=c.getRangeAt(0).startContainer,!jQuery(startNode).parentsOrSelf(WYMeditor.MAIN_CONTAINERS.join(","))[0]&&!jQuery(startNode).parentsOrSelf("li")&&a.keyCode!=WYMeditor.KEY.ENTER&&a.keyCode!=WYMeditor.KEY.LEFT&&a.keyCode!=WYMeditor.KEY.UP&&a.keyCode!=WYMeditor.KEY.RIGHT&&a.keyCode!=WYMeditor.KEY.DOWN&&a.keyCode!=WYMeditor.KEY.BACKSPACE&&a.keyCode!=WYMeditor.KEY.DELETE&&b._exec(WYMeditor.FORMAT_BLOCK,WYMeditor.P)},WYMeditor.WymClassOpera.prototype.keyup=function(a){var b=WYMeditor.INSTANCES[this.title];b._selected_image=null},WYMeditor.WymClassSafari=function(a){this._wym=a,this._class="class"},WYMeditor.WymClassSafari.prototype.initIframe=function(iframe){this._iframe=iframe,this._doc=iframe.contentDocument;var styles=this._doc.styleSheets[0],aCss=eval(this._options.editorStyles);this.addCssRules(this._doc,aCss),this._doc.title=this._wym._index,jQuery("html",this._doc).attr("dir",this._options.direction),this._doc.designMode="on",this.html(this._wym._html),jQuery.isFunction(this._options.preBind)&&this._options.preBind(this),this._wym.bindEvents(),jQuery(this._doc).bind("keydown",this.keydown),jQuery(this._doc).bind("keyup",this.keyup),jQuery.isFunction(this._options.postInit)&&this._options.postInit(this),this.listen()},WYMeditor.WymClassSafari.prototype._exec=function(a,b){if(!this.selected())return!1;var c=this.selected();switch(a){case WYMeditor.INSERT_ORDEREDLIST:case WYMeditor.INSERT_UNORDEREDLIST:this._doc.execCommand(a,"",null);var d=this.findUp(c,WYMeditor.MAIN_CONTAINERS);d&&jQuery(d).replaceWith(jQuery(d).html());break;default:b?this._doc.execCommand(a,"",b):this._doc.execCommand(a,"",null)}return d=this.selected(),d&&d.tagName.toLowerCase()==WYMeditor.BODY&&this._exec(WYMeditor.FORMAT_BLOCK,WYMeditor.P),!0},WYMeditor.WymClassSafari.prototype.addCssRule=function(a,b){a.insertRule(b.name+" {"+b.css+"}",a.cssRules.length)},WYMeditor.WymClassSafari.prototype.keydown=function(a){var b=WYMeditor.INSTANCES[this.title];a.ctrlKey?(a.keyCode==WYMeditor.KEY.B&&(b._exec(WYMeditor.BOLD),a.preventDefault()),a.keyCode==WYMeditor.KEY.I&&(b._exec(WYMeditor.ITALIC),a.preventDefault())):a.shiftKey&&a.keyCode==WYMeditor.KEY.ENTER&&(b._exec("InsertLineBreak"),a.preventDefault())},WYMeditor.WymClassSafari.prototype.keyup=function(a){var b=WYMeditor.INSTANCES[this.title];b._selected_image=null;var c=null;$.browser.version<534.1&&a.keyCode==WYMeditor.KEY.ENTER&&a.shiftKey&&b._exec("InsertLineBreak");if(a.keyCode!=WYMeditor.KEY.BACKSPACE&&a.keyCode!=WYMeditor.KEY.CTRL&&a.keyCode!=WYMeditor.KEY.DELETE&&a.keyCode!=WYMeditor.KEY.COMMAND&&a.keyCode!=WYMeditor.KEY.UP&&a.keyCode!=WYMeditor.KEY.DOWN&&a.keyCode!=WYMeditor.KEY.LEFT&&a.keyCode!=WYMeditor.KEY.RIGHT&&a.keyCode!=WYMeditor.KEY.ENTER&&!a.metaKey&&!a.ctrlKey){c=b.selected();var d=c.tagName.toLowerCase();if(d=="strong"||d=="b"||d=="em"||d=="i"||d=="sub"||d=="sup"||d=="a"||d=="span")d=c.parentNode.tagName.toLowerCase();if(d==WYMeditor.BODY||d==WYMeditor.DIV)b._exec(WYMeditor.FORMAT_BLOCK,WYMeditor.P),b.fixBodyHtml()}(a.keyCode==WYMeditor.KEY.UP||a.keyCode==WYMeditor.KEY.DOWN||a.keyCode==WYMeditor.KEY.LEFT||a.keyCode==WYMeditor.KEY.RIGHT||a.keyCode==WYMeditor.KEY.BACKSPACE||a.keyCode==WYMeditor.KEY.ENTER)&&b.fixBodyHtml()},WYMeditor.WymClassSafari.prototype.openBlockTag=function(a,b){b=this.validator.getValidTagAttributes(a,b);if(a=="span"&&b.style){var c=this.getTagForStyle(b.style);c&&(a=c,this._tag_stack.pop(),this._tag_stack.push(a),b.style="",typeof b["class"]=="string"&&(b["class"]=b["class"].replace(/apple-style-span/gi,"")))}this.output+=this.helper.tag(a,b,!0)},WYMeditor.WymClassSafari.prototype.getTagForStyle=function(a){return/bold/.test(a)?"strong":/italic/.test(a)?"em":/sub/.test(a)?"sub":/super/.test(a)?"sup":!1},WYMeditor.XmlHelper=function(){return this._entitiesDiv=document.createElement("div"),this},WYMeditor.XmlHelper.prototype.tag=function(a,b,c){return b=b||!1,c=c||!1,"<"+a+(b?this.tagOptions(b):"")+(c?">":" />")},WYMeditor.XmlHelper.prototype.contentTag=function(a,b,c){return c=c||!1,"<"+a+(c?this.tagOptions(c):"")+">"+b+""},WYMeditor.XmlHelper.prototype.cdataSection=function(a){return""},WYMeditor.XmlHelper.prototype.escapeOnce=function(a){return this._fixDoubleEscape(this.escapeEntities(a))},WYMeditor.XmlHelper.prototype._fixDoubleEscape=function(a){return a.replace(/&([a-z]+|(#\d+));/ig,"&$1;")},WYMeditor.XmlHelper.prototype.tagOptions=function(a){var b=this;b._formated_options="";for(var c in a){var d="",e=a[c];typeof e!="function"&&e.length>0&&(parseInt(c,10)==c&&typeof e=="object"&&(c=e.shift(),e=e.pop()),c!==""&&e!==""&&(b._formated_options+=" "+c+'="'+b.escapeOnce(e)+'"'))}return b._formated_options},WYMeditor.XmlHelper.prototype.escapeEntities=function(a,b){this._entitiesDiv.innerHTML=a,this._entitiesDiv.textContent=a;var c=this._entitiesDiv.innerHTML;return typeof b=="undefined"&&(b!==!1&&(c=c.replace('"',""")),b===!0&&(c=c.replace('"',"'"))),c},WYMeditor.XmlHelper.prototype.parseAttributes=function(a){var b=[],c=a.split(/((=\s*")(")("))|((=\s*\')(\')(\'))|((=\s*[^>\s]*))/g);if(c.toString()!=a)for(var d in c){var e=c[d];if(typeof e!="function"&&e.length!==0){var f=new RegExp("(\\w+)\\s*"+e),g=a.match(f);if(g){var h=e.replace(/^[\s=]+/,""),i=h.charAt(0);i=i=='"'?'"':i=="'"?"'":"",i!==""&&(h=i=='"'?h.replace(/^"|"+$/g,""):h.replace(/^'|'+$/g,"")),a=a.replace(g[0],""),b.push([g[1],h])}}}return b},WYMeditor.XhtmlValidator={_attributes:{core:{except:["base","head","html","meta","param","script","style","title"],attributes:["class","id","style","title","accesskey","tabindex","/^data-.*/"]},language:{except:["base","br","hr","iframe","param","script"],attributes:{dir:["ltr","rtl"],0:"lang",1:"xml:lang"}},keyboard:{attributes:{accesskey:/^(\w){1}$/,tabindex:/^(\d)+$/}}},_events:{window:{only:["body"],attributes:["onload","onunload"]},form:{only:["form","input","textarea","select","a","label","button"],attributes:["onchange","onsubmit","onreset","onselect","onblur","onfocus"]},keyboard:{except:["base","bdo","br","frame","frameset","head","html","iframe","meta","param","script","style","title"],attributes:["onkeydown","onkeypress","onkeyup"]},mouse:{except:["base","bdo","br","head","html","meta","param","script","style","title"],attributes:["onclick","ondblclick","onmousedown","onmousemove","onmouseover","onmouseout","onmouseup"]}},_tags:{a:{attributes:{0:"charset",1:"coords",2:"href",3:"hreflang",4:"name",5:"rel",6:"rev",shape:/^(rect|rectangle|circ|circle|poly|polygon)$/,7:"type"}},0:"abbr",1:"acronym",2:"address",area:{attributes:{0:"alt",1:"coords",2:"href",nohref:/^(true|false)$/,shape:/^(rect|rectangle|circ|circle|poly|polygon)$/},required:["alt"]},3:"b",base:{attributes:["href"],required:["href"]},bdo:{attributes:{dir:/^(ltr|rtl)$/},required:["dir"]},4:"big",blockquote:{attributes:["cite"]},5:"body",6:"br",button:{attributes:{disabled:/^(disabled)$/,type:/^(button|reset|submit)$/,0:"value"},inside:"form"},7:"caption",8:"cite",9:"code",col:{attributes:{align:/^(right|left|center|justify)$/,0:"char",1:"charoff",span:/^(\d)+$/,valign:/^(top|middle|bottom|baseline)$/,2:"width"},inside:"colgroup"},colgroup:{attributes:{align:/^(right|left|center|justify)$/,0:"char",1:"charoff",span:/^(\d)+$/,valign:/^(top|middle|bottom|baseline)$/,2:"width"}},10:"dd",del:{attributes:{0:"cite",datetime:/^([0-9]){8}/}},11:"div",12:"dfn",13:"dl",14:"dt",15:"em",fieldset:{inside:"form"},form:{attributes:{0:"action",1:"accept",2:"accept-charset",3:"enctype",method:/^(get|post)$/},required:["action"]},head:{attributes:["profile"]},16:"h1",17:"h2",18:"h3",19:"h4",20:"h5",21:"h6",22:"hr",html:{attributes:["xmlns"]},23:"i",img:{attributes:["alt","src","height","ismap","longdesc","usemap","width"],required:["alt","src"]},input:{attributes:{0:"accept",1:"alt",checked:/^(checked)$/,disabled:/^(disabled)$/,maxlength:/^(\d)+$/,2:"name",readonly:/^(readonly)$/,size:/^(\d)+$/,3:"src",type:/^(button|checkbox|file|hidden|image|password|radio|reset|submit|text)$/,4:"value"},inside:"form"},ins:{attributes:{0:"cite",datetime:/^([0-9]){8}/}},24:"kbd",label:{attributes:["for"],inside:"form"},25:"legend",26:"li",link:{attributes:{0:"charset",1:"href",2:"hreflang",media:/^(all|braille|print|projection|screen|speech|,|;| )+$/i,rel:/^(alternate|appendix|bookmark|chapter|contents|copyright|glossary|help|home|index|next|prev|section|start|stylesheet|subsection| |shortcut|icon)+$/i,rev:/^(alternate|appendix|bookmark|chapter|contents|copyright|glossary|help|home|index|next|prev|section|start|stylesheet|subsection| |shortcut|icon)+$/i,3:"type"},inside:"head"},map:{attributes:["id","name"],required:["id"]},meta:{attributes:{0:"content","http-equiv":/^(content\-type|expires|refresh|set\-cookie)$/i,1:"name",2:"scheme"},required:["content"]},27:"noscript",object:{attributes:["archive","classid","codebase","codetype","data","declare","height","name","standby","type","usemap","width"]},28:"ol",optgroup:{attributes:{0:"label",disabled:/^(disabled)$/},required:["label"]},option:{attributes:{0:"label",disabled:/^(disabled)$/,selected:/^(selected)$/,1:"value"},inside:"select"},29:"p",param:{attributes:{0:"type",valuetype:/^(data|ref|object)$/,1:"valuetype",2:"value"},required:["name"]},30:"pre",q:{attributes:["cite"]},31:"samp",script:{attributes:{type:/^(text\/ecmascript|text\/javascript|text\/jscript|text\/vbscript|text\/vbs|text\/xml)$/,0:"charset",defer:/^(defer)$/,1:"src"},required:["type"]},select:{attributes:{disabled:/^(disabled)$/,multiple:/^(multiple)$/,0:"name",1:"size"},inside:"form"},32:"small",33:"span",34:"strong",style:{attributes:{0:"type",media:/^(screen|tty|tv|projection|handheld|print|braille|aural|all)$/},required:["type"]},35:"sub",36:"sup",table:{attributes:{0:"border",1:"cellpadding",2:"cellspacing",frame:/^(void|above|below|hsides|lhs|rhs|vsides|box|border)$/,rules:/^(none|groups|rows|cols|all)$/,3:"summary",4:"width"}},tbody:{attributes:{align:/^(right|left|center|justify)$/,0:"char",1:"charoff",valign:/^(top|middle|bottom|baseline)$/}},td:{attributes:{0:"abbr",align:/^(left|right|center|justify|char)$/,1:"axis",2:"char",3:"charoff",colspan:/^(\d)+$/,4:"headers",rowspan:/^(\d)+$/,scope:/^(col|colgroup|row|rowgroup)$/,valign:/^(top|middle|bottom|baseline)$/}},textarea:{attributes:["cols","rows","disabled","name","readonly"],required:["cols","rows"],inside:"form"},tfoot:{attributes:{align:/^(right|left|center|justify)$/,0:"char",1:"charoff",valign:/^(top|middle|bottom)$/,2:"baseline"}},th:{attributes:{0:"abbr",align:/^(left|right|center|justify|char)$/,1:"axis",2:"char",3:"charoff",colspan:/^(\d)+$/,4:"headers",rowspan:/^(\d)+$/,scope:/^(col|colgroup|row|rowgroup)$/,valign:/^(top|middle|bottom|baseline)$/}},thead:{attributes:{align:/^(right|left|center|justify)$/,0:"char",1:"charoff",valign:/^(top|middle|bottom|baseline)$/}},37:"title",tr:{attributes:{align:/^(right|left|center|justify|char)$/,0:"char",1:"charoff",valign:/^(top|middle|bottom|baseline)$/}},38:"tt",39:"ul",40:"var"},skiped_attributes:[],skiped_attribute_values:[],getValidTagAttributes:function(a,b){var c={},d=this.getPossibleTagAttributes(a);for(var e in b){var f=b[e];e=e.toLowerCase();var g=WYMeditor.Helper;!g.contains(this.skiped_attributes,e)&&!g.contains(this.skiped_attribute_values,f)&&(typeof f!="function"&&g.contains(d,e)?this.doesAttributeNeedsValidation(a,e)?this.validateAttribute(a,e,f)&&(c[e]=f):c[e]=f:jQuery.each(d,function(){this.match(/\/(.*)\//)&&(regex=new RegExp(this.match(/\/(.*)\//)[1]),regex.test(e)&&(c[e]=f))}))}return c},getUniqueAttributesAndEventsForTag:function(a){var b=[];if(this._tags[a]&&this._tags[a].attributes)for(var c in this._tags[a].attributes)b.push(parseInt(c,10)==c?this._tags[a].attributes[c]:c);return b},getDefaultAttributesAndEventsForTags:function(){var a=[];for(var b in this._events)a.push(this._events[b]);for(b in this._attributes)a.push(this._attributes[b]);return a},isValidTag:function(a){if(this._tags[a])return!0;for(var b in this._tags)if(this._tags[b]==a)return!0;return!1},getDefaultAttributesAndEventsForTag:function(a){var b=[];if(this.isValidTag(a)){var c=this.getDefaultAttributesAndEventsForTags();for(var d in c){var e=c[d];if(typeof e=="object"){var f=WYMeditor.Helper;if(e.except&&f.contains(e.except,a)||e.only&&!f.contains(e.only,a))continue;var g=e.attributes?e.attributes:e.events;for(var h in g)b.push(typeof g[h]!="string"?h:g[h])}}}return b},doesAttributeNeedsValidation:function(a,b){return this._tags[a]&&(this._tags[a].attributes&&this._tags[a].attributes[b]||this._tags[a].required&&WYMeditor.Helper.contains(this._tags[a].required,b))},validateAttribute:function(a,b,c){return this._tags[a]&&this._tags[a].attributes&&this._tags[a].attributes[b]&&c.length>0&&!c.match(this._tags[a].attributes[b])||this._tags[a]&&this._tags[a].required&&WYMeditor.Helper.contains(this._tags[a].required,b)&&c.length===0?!1:typeof this._tags[a]!="undefined"},getPossibleTagAttributes:function(a){return this._possible_tag_attributes||(this._possible_tag_attributes={}),this._possible_tag_attributes[a]||(this._possible_tag_attributes[a]=this.getUniqueAttributesAndEventsForTag(a).concat(this.getDefaultAttributesAndEventsForTag -(a))),this._possible_tag_attributes[a]}},WYMeditor.ParallelRegex=function(a){return this._case=a,this._patterns=[],this._labels=[],this._regex=null,this},WYMeditor.ParallelRegex.prototype.addPattern=function(a,b){b=b||!0;var c=this._patterns.length;this._patterns[c]=a,this._labels[c]=b,this._regex=null},WYMeditor.ParallelRegex.prototype.match=function(a){if(this._patterns.length===0)return[!1,""];var b=a.match(this._getCompoundedRegex());if(!b)return[!1,""];var c=b[0];for(var d=1;d","Comment")},WYMeditor.XhtmlLexer.prototype.addScriptTokens=function(a){this.addEntryPattern("","Script")},WYMeditor.XhtmlLexer.prototype.addCssTokens=function(a){this.addEntryPattern("","Css")},WYMeditor.XhtmlLexer.prototype.addTagTokens=function(a){this.addSpecialPattern("<\\s*[a-z0-9:-]+\\s*>",a,"OpeningTag"),this.addEntryPattern("<[a-z0-9:-]+[\\/ \\>]+",a,"OpeningTag"),this.addInTagDeclarationTokens("OpeningTag"),this.addSpecialPattern("",a,"ClosingTag")},WYMeditor.XhtmlLexer.prototype.addInTagDeclarationTokens=function(a){this.addSpecialPattern("\\s+",a,"Ignore"),this.addAttributeTokens(a),this.addExitPattern("/>",a),this.addExitPattern(">",a)},WYMeditor.XhtmlLexer.prototype.addAttributeTokens=function(a){this.addSpecialPattern("\\s*[a-z-_0-9]*:?[a-z-_0-9]+\\s*(?==)\\s*",a,"TagAttributes"),this.addEntryPattern('=\\s*"',a,"DoubleQuotedAttribute"),this.addPattern('\\\\"',"DoubleQuotedAttribute"),this.addExitPattern('"',"DoubleQuotedAttribute"),this.addEntryPattern("=\\s*'",a,"SingleQuotedAttribute"),this.addPattern("\\\\'","SingleQuotedAttribute"),this.addExitPattern("'","SingleQuotedAttribute"),this.addSpecialPattern("=\\s*[^>\\s]*",a,"UnquotedAttribute")},WYMeditor.XhtmlParser=function(a,b){return b=b||"Text",this._Lexer=new WYMeditor.XhtmlLexer(this),this._Listener=a,this._mode=b,this._matches=[],this._last_match="",this._current_match="",this},WYMeditor.XhtmlParser.prototype.parse=function(a){return this._Lexer.parse(this.beforeParsing(a)),this.afterParsing(this._Listener.getResult())},WYMeditor.XhtmlParser.prototype.beforeParsing=function(a){return(a.match(/class="MsoNormal"/)||a.match(/ns = "urn:schemas-microsoft-com/))&&this._Listener.avoidStylingTagsAndAttributes(),this._Listener.beforeParsing(a)},WYMeditor.XhtmlParser.prototype.afterParsing=function(a){return this._Listener._avoiding_tags_implicitly&&this._Listener.allowStylingTagsAndAttributes(),this._Listener.afterParsing(a)},WYMeditor.XhtmlParser.prototype.Ignore=function(a,b){return!0},WYMeditor.XhtmlParser.prototype.Text=function(a){return this._Listener.addContent(a),!0},WYMeditor.XhtmlParser.prototype.Comment=function(a,b){return this._addNonTagBlock(a,b,"addComment")},WYMeditor.XhtmlParser.prototype.Script=function(a,b){return this._addNonTagBlock(a,b,"addScript")},WYMeditor.XhtmlParser.prototype.Css=function(a,b){return this._addNonTagBlock(a,b,"addCss")},WYMeditor.XhtmlParser.prototype._addNonTagBlock=function(a,b,c){switch(b){case WYMeditor.LEXER_ENTER:this._non_tag=a;break;case WYMeditor.LEXER_UNMATCHED:this._non_tag+=a;break;case WYMeditor.LEXER_EXIT:switch(c){case"addComment":this._Listener.addComment(this._non_tag+a);break;case"addScript":this._Listener.addScript(this._non_tag+a);break;case"addCss":this._Listener.addCss(this._non_tag+a);break;default:}break;default:}return!0},WYMeditor.XhtmlParser.prototype.OpeningTag=function(a,b){switch(b){case WYMeditor.LEXER_ENTER:this._tag=this.normalizeTag(a),this._tag_attributes={};break;case WYMeditor.LEXER_SPECIAL:this._callOpenTagListener(this.normalizeTag(a));break;case WYMeditor.LEXER_EXIT:this._callOpenTagListener(this._tag,this._tag_attributes);break;default:}return!0},WYMeditor.XhtmlParser.prototype.ClosingTag=function(a,b){return this._callCloseTagListener(this.normalizeTag(a)),!0},WYMeditor.XhtmlParser.prototype._callOpenTagListener=function(a,b){b=b||{},this.autoCloseUnclosedBeforeNewOpening(a),this._Listener.isBlockTag(a)?(this._Listener._tag_stack.push(a),this._Listener.fixNestingBeforeOpeningBlockTag(a,b),this._Listener.openBlockTag(a,b),this._increaseOpenTagCounter(a)):this._Listener.isInlineTag(a)?this._Listener.inlineTag(a,b):(this._Listener.openUnknownTag(a,b),this._increaseOpenTagCounter(a)),this._Listener.last_tag=a,this._Listener.last_tag_opened=!0,this._Listener.last_tag_attributes=b},WYMeditor.XhtmlParser.prototype._callCloseTagListener=function(a){if(this._decreaseOpenTagCounter(a)){this.autoCloseUnclosedBeforeTagClosing(a);if(this._Listener.isBlockTag(a)){var b=this._Listener._tag_stack.pop();if(b===!1)return;b!=a&&(a=b),this._Listener.closeBlockTag(a)}else this._Listener.closeUnknownTag(a)}else this._Listener.closeUnopenedTag(a);this._Listener.last_tag=a,this._Listener.last_tag_opened=!1},WYMeditor.XhtmlParser.prototype._increaseOpenTagCounter=function(a){this._Listener._open_tags[a]=this._Listener._open_tags[a]||0,this._Listener._open_tags[a]++},WYMeditor.XhtmlParser.prototype._decreaseOpenTagCounter=function(a){return this._Listener._open_tags[a]?(this._Listener._open_tags[a]--,this._Listener._open_tags[a]===0&&(this._Listener._open_tags[a]=undefined),!0):!1},WYMeditor.XhtmlParser.prototype.autoCloseUnclosedBeforeNewOpening=function(a){this._autoCloseUnclosed(a,!1)},WYMeditor.XhtmlParser.prototype.autoCloseUnclosedBeforeTagClosing=function(a){this._autoCloseUnclosed(a,!0)},WYMeditor.XhtmlParser.prototype._autoCloseUnclosed=function(a,b){b=b||!1;if(this._Listener._open_tags)for(var c in this._Listener._open_tags){var d=this._Listener._open_tags[c];d>0&&this._Listener.shouldCloseTagAutomatically(c,a,b)&&this._callCloseTagListener(c,!0)}},WYMeditor.XhtmlParser.prototype.getTagReplacements=function(){return this._Listener.getTagReplacements()},WYMeditor.XhtmlParser.prototype.normalizeTag=function(a){a=a.replace(/^([\s<\/>]*)|([\s<\/>]*)$/gm,"").toLowerCase();var b=this._Listener.getTagReplacements();return b[a]?b[a]:a},WYMeditor.XhtmlParser.prototype.TagAttributes=function(a,b){return WYMeditor.LEXER_SPECIAL==b&&(this._current_attribute=a),!0},WYMeditor.XhtmlParser.prototype.DoubleQuotedAttribute=function(a,b){return WYMeditor.LEXER_UNMATCHED==b&&(this._tag_attributes[this._current_attribute]=a),!0},WYMeditor.XhtmlParser.prototype.SingleQuotedAttribute=function(a,b){return WYMeditor.LEXER_UNMATCHED==b&&(this._tag_attributes[this._current_attribute]=a),!0},WYMeditor.XhtmlParser.prototype.UnquotedAttribute=function(a,b){return this._tag_attributes[this._current_attribute]=a.replace(/^=/,""),!0},WYMeditor.XhtmlSaxListener=function(){return this.output="",this.helper=new WYMeditor.XmlHelper,this._open_tags={},this.validator=WYMeditor.XhtmlValidator,this._tag_stack=[],this.avoided_tags=[],this.entities={" ":" ","¡":"¡","¢":"¢","£":"£","¤":"¤","¥":"¥","¦":"¦","§":"§","¨":"¨","©":"©","ª":"ª","«":"«","¬":"¬","­":"­","®":"®","¯":"¯","°":"°","±":"±","²":"²","³":"³","´":"´","µ":"µ","¶":"¶","·":"·","¸":"¸","¹":"¹","º":"º","»":"»","¼":"¼","½":"½","¾":"¾","¿":"¿","À":"À","Á":"Á","Â":"Â","Ã":"Ã","Ä":"Ä","Å":"Å","Æ":"Æ","Ç":"Ç","È":"È","É":"É","Ê":"Ê","Ë":"Ë","Ì":"Ì","Í":"Í","Î":"Î","Ï":"Ï","Ð":"Ð","Ñ":"Ñ","Ò":"Ò","Ó":"Ó","Ô":"Ô","Õ":"Õ","Ö":"Ö","×":"×","Ø":"Ø","Ù":"Ù","Ú":"Ú","Û":"Û","Ü":"Ü","Ý":"Ý","Þ":"Þ","ß":"ß","à":"à","á":"á","â":"â","ã":"ã","ä":"ä","å":"å","æ":"æ","ç":"ç","è":"è","é":"é","ê":"ê","ë":"ë","ì":"ì","í":"í","î":"î","ï":"ï","ð":"ð","ñ":"ñ","ò":"ò","ó":"ó","ô":"ô","õ":"õ","ö":"ö","÷":"÷","ø":"ø","ù":"ù","ú":"ú","û":"û","ü":"ü","ý":"ý","þ":"þ","ÿ":"ÿ","Œ":"Œ","œ":"œ","Š":"Š","š":"š","Ÿ":"Ÿ","ƒ":"ƒ","ˆ":"ˆ","˜":"˜","Α":"Α","Β":"Β","Γ":"Γ","Δ":"Δ","Ε":"Ε","Ζ":"Ζ","Η":"Η","Θ":"Θ","Ι":"Ι","Κ":"Κ","Λ":"Λ","Μ":"Μ","Ν":"Ν","Ξ":"Ξ","Ο":"Ο","Π":"Π","Ρ":"Ρ","Σ":"Σ","Τ":"Τ","Υ":"Υ","Φ":"Φ","Χ":"Χ","Ψ":"Ψ","Ω":"Ω","α":"α","β":"β","γ":"γ","δ":"δ","ε":"ε","ζ":"ζ","η":"η","θ":"θ","ι":"ι","κ":"κ","λ":"λ","μ":"μ","ν":"ν","ξ":"ξ","ο":"ο","π":"π","ρ":"ρ","ς":"ς","σ":"σ","τ":"τ","υ":"υ","φ":"φ","χ":"χ","ψ":"ψ","ω":"ω","ϑ":"ϑ","ϒ":"ϒ","ϖ":"ϖ"," ":" "," ":" "," ":" ","‌":"‌","‍":"‍","‎":"‎","‏":"‏","–":"–","—":"—","‘":"‘","’":"’","‚":"‚","“":"“","”":"”","„":"„","†":"†","‡":"‡","•":"•","…":"…","‰":"‰","′":"′","″":"″","‹":"‹","›":"›","‾":"‾","⁄":"⁄","€":"€","ℑ":"ℑ","℘":"℘","ℜ":"ℜ","™":"™","ℵ":"ℵ","←":"←","↑":"↑","→":"→","↓":"↓","↔":"↔","↵":"↵","⇐":"⇐","⇑":"⇑","⇒":"⇒","⇓":"⇓","⇔":"⇔","∀":"∀","∂":"∂","∃":"∃","∅":"∅","∇":"∇","∈":"∈","∉":"∉","∋":"∋","∏":"∏","∑":"∑","−":"−","∗":"∗","√":"√","∝":"∝","∞":"∞","∠":"∠","∧":"∧","∨":"∨","∩":"∩","∪":"∪","∫":"∫","∴":"∴","∼":"∼","≅":"≅","≈":"≈","≠":"≠","≡":"≡","≤":"≤","≥":"≥","⊂":"⊂","⊃":"⊃","⊄":"⊄","⊆":"⊆","⊇":"⊇","⊕":"⊕","⊗":"⊗","⊥":"⊥","⋅":"⋅","⌈":"⌈","⌉":"⌉","⌊":"⌊","⌋":"⌋","⟨":"〈","⟩":"〉","◊":"◊","♠":"♠","♣":"♣","♥":"♥","♦":"♦"},this.block_tags=["a","abbr","acronym","address","area","b","base","bdo","big","blockquote","body","button","caption","cite","code","col","colgroup","dd","del","div","dfn","dl","dt","em","fieldset","form","head","h1","h2","h3","h4","h5","h6","html","i","ins","kbd","label","legend","li","map","noscript","object","ol","optgroup","option","p","param","pre","q","samp","script","select","small","span","strong","style","sub","sup","table","tbody","td","textarea","tfoot","th","thead","title","tr","tt","ul","var","extends"],this.inline_tags=["br","hr","img","input"],this},WYMeditor.XhtmlSaxListener.prototype.shouldCloseTagAutomatically=function(a,b,c){c=c||!1;if(a=="td"){if(c&&b=="tr"||!c&&b=="td")return!0}else if(a=="option")if(c&&b=="select"||!c&&b=="option")return!0;return!1},WYMeditor.XhtmlSaxListener.prototype.beforeParsing=function(a){return this.output="",a},WYMeditor.XhtmlSaxListener.prototype.afterParsing=function(a){return a=this.replaceNamedEntities(a),a=this.joinRepeatedEntities(a),a=this.removeEmptyTags(a),a=this.removeBrInPre(a),a},WYMeditor.XhtmlSaxListener.prototype.replaceNamedEntities=function(a){for(var b in this.entities)a=a.replace(new RegExp(b,"g"),this.entities[b]);return a},WYMeditor.XhtmlSaxListener.prototype.joinRepeatedEntities=function(a){var b="em|strong|sub|sup|acronym|pre|del|address";return a.replace(new RegExp("<\\1>",""),"").replace(new RegExp("(s*<("+b+")>s*){2}(.*)(s*s*){2}",""),"<$2>$3<$2>")},WYMeditor.XhtmlSaxListener.prototype.removeEmptyTags=function(a){return a.replace(new RegExp("<("+this.block_tags.join("|").replace(/\|td/,"").replace(/\|th/,"")+")>(
    | | |\\s)*","g"),"")},WYMeditor.XhtmlSaxListener.prototype.removeBrInPre=function(a){var b=a.match(new RegExp("]*>(.*?)
    ","gmi"));if(b)for(var c=0;c","g"),String.fromCharCode(13,10)));return a},WYMeditor.XhtmlSaxListener.prototype.getResult=function(){return this.output},WYMeditor.XhtmlSaxListener.prototype.getTagReplacements=function(){return{b:"strong",i:"em"}},WYMeditor.XhtmlSaxListener.prototype.addContent=function(a){this.last_tag&&this.last_tag=="li"&&(a=a.replace(/\n/,""),a=a.replace(/\r/,"")),this.output+=a},WYMeditor.XhtmlSaxListener.prototype.addComment=function(a){this.remove_comments&&(this.output+=a)},WYMeditor.XhtmlSaxListener.prototype.addScript=function(a){this.remove_scripts||(this.output+=a)},WYMeditor.XhtmlSaxListener.prototype.addCss=function(a){this.remove_embeded_styles||(this.output+=a)},WYMeditor.XhtmlSaxListener.prototype.openBlockTag=function(a,b){this.output+=this.helper.tag(a,this.validator.getValidTagAttributes(a,b),!0)},WYMeditor.XhtmlSaxListener.prototype.inlineTag=function(a,b){this.output+=this.helper.tag(a,this.validator.getValidTagAttributes(a,b))},WYMeditor.XhtmlSaxListener.prototype.openUnknownTag=function(a,b){},WYMeditor.XhtmlSaxListener.prototype.closeBlockTag=function(a){this.output=this.output.replace(/
    $/,"")+this._getClosingTagContent("before",a)+""+this._getClosingTagContent("after",a)},WYMeditor.XhtmlSaxListener.prototype.closeUnknownTag=function(a){},WYMeditor.XhtmlSaxListener.prototype.closeUnopenedTag=function(a){this.output+=""},WYMeditor.XhtmlSaxListener.prototype.avoidStylingTagsAndAttributes=function(){this.avoided_tags=["div","span"],this.validator.skiped_attributes=["style"],this.validator.skiped_attribute_values=["MsoNormal","main1"],this._avoiding_tags_implicitly=!0},WYMeditor.XhtmlSaxListener.prototype.allowStylingTagsAndAttributes=function(){this.avoided_tags=[],this.validator.skiped_attributes=[],this.validator.skiped_attribute_values=[],this._avoiding_tags_implicitly=!1},WYMeditor.XhtmlSaxListener.prototype.isBlockTag=function(a){return!WYMeditor.Helper.contains(this.avoided_tags,a)&&WYMeditor.Helper.contains(this.block_tags,a)},WYMeditor.XhtmlSaxListener.prototype.isInlineTag=function(a){return!WYMeditor.Helper.contains(this.avoided_tags,a)&&WYMeditor.Helper.contains(this.inline_tags,a)},WYMeditor.XhtmlSaxListener.prototype.insertContentAfterClosingTag=function(a,b){this._insertContentWhenClosingTag("after",a,b)},WYMeditor.XhtmlSaxListener.prototype.insertContentBeforeClosingTag=function(a,b){this._insertContentWhenClosingTag("before",a,b)},WYMeditor.XhtmlSaxListener.prototype.fixNestingBeforeOpeningBlockTag=function(a,b){if((a=="ul"||a=="ol")&&this.last_tag&&!this.last_tag_opened&&this.last_tag=="li")this.output=this.output.replace(/<\/li>\s*$/,""),this.insertContentAfterClosingTag(a,"");else if(a!="ul"&&a!="ol"||!this.last_tag||!this.last_tag_opened||this.last_tag!="ul"&&this.last_tag!="ol"){if(a=="li"&&!this.last_tag_opened&&this._tag_stack.length>=2){var c=this._tag_stack[this._tag_stack.length-2];c=="li"&&(this._open_tags.li--,this._open_tags.li===0&&(this._open_tags.li=undefined),this._tag_stack.pop(this._tag_stack.length-2),this.output+="")}}else this.output+=this.helper.tag("li",{},!0),this.insertContentAfterClosingTag(a,"")},WYMeditor.XhtmlSaxListener.prototype._insertContentWhenClosingTag=function(a,b,c){this["_insert_"+a+"_closing"]||(this["_insert_"+a+"_closing"]=[]),this["_insert_"+a+"_closing"][b]||(this["_insert_"+a+"_closing"][b]=[]),this["_insert_"+a+"_closing"][b].push(c)},WYMeditor.XhtmlSaxListener.prototype._getClosingTagContent=function(a,b){return this["_insert_"+a+"_closing"]&&this["_insert_"+a+"_closing"][b]&&this["_insert_"+a+"_closing"][b].length>0?this["_insert_"+a+"_closing"][b].pop():""},WYMeditor.WymCssLexer=function(a,b){return b=typeof b=="undefined"?!0:b,jQuery.extend(this,new WYMeditor.Lexer(a,b?"Ignore":"WymCss")),this.mapHandler("WymCss","Ignore"),b===!0&&(this.addEntryPattern("/\\*[<\\s]*WYMeditor[>\\s]*\\*/","Ignore","WymCss"),this.addExitPattern("/\\*[\\s]*\\*/","WymCss")),this.addSpecialPattern("[\\sa-z1-6]*\\.[a-z-_0-9]+","WymCss","WymCssStyleDeclaration"),this.addEntryPattern("/\\*","WymCss","WymCssComment"),this.addExitPattern("\\*/","WymCssComment"),this.addEntryPattern("{","WymCss","WymCssStyle"),this.addExitPattern("}","WymCssStyle"),this.addEntryPattern("/\\*","WymCssStyle","WymCssFeedbackStyle"),this.addExitPattern("\\*/","WymCssFeedbackStyle"),this},WYMeditor.WymCssParser=function(){return this._in_style=!1,this._has_title=!1,this.only_wym_blocks=!0,this.css_settings={classesItems:[],editorStyles:[],dialogStyles:[]},this},WYMeditor.WymCssParser.prototype.parse=function(a,b){b=typeof b=="undefined"?this.only_wym_blocks:b,this._Lexer=new WYMeditor.WymCssLexer(this,b),this._Lexer.parse(a)},WYMeditor.WymCssParser.prototype.Ignore=function(a,b){return!0},WYMeditor.WymCssParser.prototype.WymCssComment=function(a,b){return a.match(/end[a-z0-9\s]*wym[a-z0-9\s]*/mi)?!1:(b==WYMeditor.LEXER_UNMATCHED&&(this._in_style?this._current_item[this._current_element]&&(this._current_item[this._current_element].expressions?this._current_item[this._current_element].expressions.push(a):this._current_item[this._current_element].expressions=[a]):(this._has_title=!0,this._current_item={title:WYMeditor.Helper.trim(a)}),this._in_style=!0),!0)},WYMeditor.WymCssParser.prototype.WymCssStyle=function(a,b){return b==WYMeditor.LEXER_UNMATCHED?(a=WYMeditor.Helper.trim(a),a!==""&&(this._current_item[this._current_element].style=a)):b==WYMeditor.LEXER_EXIT&&(this._in_style=!1,this._has_title=!1,this.addStyleSetting(this._current_item)),!0},WYMeditor.WymCssParser.prototype.WymCssFeedbackStyle=function(a,b){return b==WYMeditor.LEXER_UNMATCHED&&(this._current_item[this._current_element].feedback_style=a.replace(/^([\s\/\*]*)|([\s\/\*]*)$/gm,"")),!0},WYMeditor.WymCssParser.prototype.WymCssStyleDeclaration=function(a){a=a.replace(/^([\s\.]*)|([\s\.*]*)$/gm,"");var b="";if(a.indexOf(".")>0){var c=a.split(".");this._current_element=c[1],b=c[0]}else this._current_element=a;return this._has_title||(this._current_item={title:(b?b.toUpperCase()+": ":"")+this._current_element},this._has_title=!0),this._current_item[this._current_element]||(this._current_item[this._current_element]={name:this._current_element}),b&&(this._current_item[this._current_element].tags?this._current_item[this._current_element].tags.push(b):this._current_item[this._current_element].tags=[b]),!0},WYMeditor.WymCssParser.prototype.addStyleSetting=function(a){for(var b in a){var c=a[b];typeof c=="object"&&b!="title"&&(this.css_settings.classesItems.push({name:WYMeditor.Helper.trim(c.name),title:a.title,expr:WYMeditor.Helper.trim((c.expressions||c.tags).join(", "))}),c.feedback_style&&this.css_settings.editorStyles.push({name:"."+WYMeditor.Helper.trim(c.name),css:c.feedback_style}),c.style&&this.css_settings.dialogStyles.push({name:"."+WYMeditor.Helper.trim(c.name),css:c.style}))}}; \ No newline at end of file diff --git a/vendor/assets/javascripts/wymeditor/lang/bg.js b/vendor/assets/javascripts/wymeditor/lang/bg.js deleted file mode 100644 index 35a8e2b..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/bg.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS.bg = { - Strong: 'Получер', - Emphasis: 'Курсив', - Superscript: 'Горен индекс', - Subscript: 'Долен индекс', - Ordered_List: 'Подреден списък', - Unordered_List: 'Неподреден списък', - Indent: 'Блок навътре', - Outdent: 'Блок навън', - Undo: 'Стъпка назад', - Redo: 'Стъпка напред', - Link: 'Създай хипервръзка', - Unlink: 'Премахни хипервръзката', - Image: 'Изображение', - Table: 'Таблица', - HTML: 'HTML', - Paragraph: 'Абзац', - Heading_1: 'Заглавие 1', - Heading_2: 'Заглавие 2', - Heading_3: 'Заглавие 3', - Heading_4: 'Заглавие 4', - Heading_5: 'Заглавие 5', - Heading_6: 'Заглавие 6', - Preformatted: 'Преформатиран', - Blockquote: 'Цитат', - Table_Header: 'Заглавие на таблицата', - URL: 'URL', - Title: 'Заглавие', - Alternative_Text: 'Алтернативен текст', - Caption: 'Етикет', - Summary: 'Общо', - Number_Of_Rows: 'Брой редове', - Number_Of_Cols: 'Брой колони', - Submit: 'Изпрати', - Cancel: 'Отмени', - Choose: 'Затвори', - Preview: 'Предварителен преглед', - Paste_From_Word: 'Вмъкни от MS WORD', - Tools: 'Инструменти', - Containers: 'Контейнери', - Classes: 'Класове', - Status: 'Статус', - Source_Code: 'Източник, код' -}; - diff --git a/vendor/assets/javascripts/wymeditor/lang/ca.js b/vendor/assets/javascripts/wymeditor/lang/ca.js deleted file mode 100644 index 595b8ce..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/ca.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS.ca = { - Strong: 'Ressaltar', - Emphasis: 'Emfatitzar', - Superscript: 'Superindex', - Subscript: 'Subindex', - Ordered_List: 'Llistat ordenat', - Unordered_List: 'Llistat sense ordenar', - Indent: 'Indentat', - Outdent: 'Sense indentar', - Undo: 'Desfer', - Redo: 'Refer', - Link: 'Enllaçar', - Unlink: 'Eliminar enllaç', - Image: 'Imatge', - Table: 'Taula', - HTML: 'HTML', - Paragraph: 'Paràgraf', - Heading_1: 'Capçalera 1', - Heading_2: 'Capçalera 2', - Heading_3: 'Capçalera 3', - Heading_4: 'Capçalera 4', - Heading_5: 'Capçalera 5', - Heading_6: 'Capçalera 6', - Preformatted: 'Pre-formatejat', - Blockquote: 'Cita', - Table_Header: 'Capçalera de la taula', - URL: 'URL', - Title: 'Títol', - Alternative_Text: 'Text alternatiu', - Caption: 'Llegenda', - Summary: 'Summary', - Number_Of_Rows: 'Nombre de files', - Number_Of_Cols: 'Nombre de columnes', - Submit: 'Enviar', - Cancel: 'Cancel·lar', - Choose: 'Triar', - Preview: 'Vista prèvia', - Paste_From_Word: 'Pegar des de Word', - Tools: 'Eines', - Containers: 'Contenidors', - Classes: 'Classes', - Status: 'Estat', - Source_Code: 'Codi font' -}; - diff --git a/vendor/assets/javascripts/wymeditor/lang/cs.js b/vendor/assets/javascripts/wymeditor/lang/cs.js deleted file mode 100644 index fdbbcc4..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/cs.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS.cs = { - Strong: 'Tučné', - Emphasis: 'Kurzíva', - Superscript: 'Horní index', - Subscript: 'Dolní index', - Ordered_List: 'Číslovaný seznam', - Unordered_List: 'Nečíslovaný seznam', - Indent: 'Zvětšit odsazení', - Outdent: 'Zmenšit odsazení', - Undo: 'Zpět', - Redo: 'Znovu', - Link: 'Vytvořit odkaz', - Unlink: 'Zrušit odkaz', - Image: 'Obrázek', - Table: 'Tabulka', - HTML: 'HTML', - Paragraph: 'Odstavec', - Heading_1: 'Nadpis 1. úrovně', - Heading_2: 'Nadpis 2. úrovně', - Heading_3: 'Nadpis 3. úrovně', - Heading_4: 'Nadpis 4. úrovně', - Heading_5: 'Nadpis 5. úrovně', - Heading_6: 'Nadpis 6. úrovně', - Preformatted: 'Předformátovaný text', - Blockquote: 'Citace', - Table_Header: 'Hlavičková buňka tabulky', - URL: 'Adresa', - Title: 'Text po najetí myší', - Alternative_Text: 'Text pro případ nezobrazení obrázku', - Caption: 'Titulek tabulky', - Summary: 'Shrnutí obsahu', - Number_Of_Rows: 'Počet řádek', - Number_Of_Cols: 'Počet sloupců', - Submit: 'Vytvořit', - Cancel: 'Zrušit', - Choose: 'Vybrat', - Preview: 'Náhled', - Paste_From_Word: 'Vložit z Wordu', - Tools: 'Nástroje', - Containers: 'Typy obsahu', - Classes: 'Třídy', - Status: 'Stav', - Source_Code: 'Zdrojový kód' -}; - diff --git a/vendor/assets/javascripts/wymeditor/lang/cy.js b/vendor/assets/javascripts/wymeditor/lang/cy.js deleted file mode 100644 index e812677..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/cy.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS.cy = { - Strong: 'Bras', - Emphasis: 'Italig', - Superscript: 'Uwchsgript', - Subscript: 'Is-sgript', - Ordered_List: 'Rhestr mewn Trefn', - Unordered_List: 'Pwyntiau Bwled', - Indent: 'Mewnoli', - Outdent: 'Alloli', - Undo: 'Dadwneud', - Redo: 'Ailwneud', - Link: 'Cysylltu', - Unlink: 'Datgysylltu', - Image: 'Delwedd', - Table: 'Tabl', - HTML: 'HTML', - Paragraph: 'Paragraff', - Heading_1: 'Pennawd 1', - Heading_2: 'Pennawd 2', - Heading_3: 'Pennawd 3', - Heading_4: 'Pennawd 4', - Heading_5: 'Pennawd 5', - Heading_6: 'Pennawd 6', - Preformatted: 'Rhagfformat', - Blockquote: 'Bloc Dyfyniad', - Table_Header: 'Pennyn Tabl', - URL: 'URL', - Title: 'Teitl', - Alternative_Text: 'Testun Amgen', - Caption: 'Pennawd', - Summary: 'Crynodeb', - Number_Of_Rows: 'Nifer y rhesi', - Number_Of_Cols: 'Nifer y colofnau', - Submit: 'Anfon', - Cancel: 'Diddymu', - Choose: 'Dewis', - Preview: 'Rhagolwg', - Paste_From_Word: 'Gludo o Word', - Tools: 'Offer', - Containers: 'Cynhwysyddion', - Classes: 'Dosbarthiadau', - Status: 'Statws', - Source_Code: 'Cod ffynhonnell' -}; - diff --git a/vendor/assets/javascripts/wymeditor/lang/de.js b/vendor/assets/javascripts/wymeditor/lang/de.js deleted file mode 100644 index d106829..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/de.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS.de = { - Strong: 'Fett', - Emphasis: 'Kursiv', - Superscript: 'Text hochstellen', - Subscript: 'Text tiefstellen', - Ordered_List: 'Geordnete Liste einfügen', - Unordered_List: 'Ungeordnete Liste einfügen', - Indent: 'Einzug erhöhen', - Outdent: 'Einzug vermindern', - Undo: 'Befehle rückgängig machen', - Redo: 'Befehle wiederherstellen', - Link: 'Hyperlink einfügen', - Unlink: 'Hyperlink entfernen', - Image: 'Bild einfügen', - Table: 'Tabelle einfügen', - HTML: 'HTML anzeigen/verstecken', - Paragraph: 'Absatz', - Heading_1: 'Überschrift 1', - Heading_2: 'Überschrift 2', - Heading_3: 'Überschrift 3', - Heading_4: 'Überschrift 4', - Heading_5: 'Überschrift 5', - Heading_6: 'Überschrift 6', - Preformatted: 'Vorformatiert', - Blockquote: 'Zitat', - Table_Header: 'Tabellenüberschrift', - URL: 'URL', - Title: 'Titel', - Alternative_Text: 'Alternativer Text', - Caption: 'Tabellenüberschrift', - Summary: 'Summary', - Number_Of_Rows: 'Anzahl Zeilen', - Number_Of_Cols: 'Anzahl Spalten', - Submit: 'Absenden', - Cancel: 'Abbrechen', - Choose: 'Auswählen', - Preview: 'Vorschau', - Paste_From_Word: 'Aus Word einfügen', - Tools: 'Werkzeuge', - Containers: 'Inhaltstyp', - Classes: 'Klassen', - Status: 'Status', - Source_Code: 'Quellcode' -}; - diff --git a/vendor/assets/javascripts/wymeditor/lang/en.js b/vendor/assets/javascripts/wymeditor/lang/en.js deleted file mode 100644 index df7ac51..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/en.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS.en = { - Strong: 'Strong', - Emphasis: 'Emphasis', - Superscript: 'Superscript', - Subscript: 'Subscript', - Ordered_List: 'Ordered List', - Unordered_List: 'Unordered List', - Indent: 'Indent', - Outdent: 'Outdent', - Undo: 'Undo', - Redo: 'Redo', - Link: 'Link', - Unlink: 'Unlink', - Image: 'Image', - Table: 'Table', - HTML: 'HTML', - Paragraph: 'Paragraph', - Heading_1: 'Heading 1', - Heading_2: 'Heading 2', - Heading_3: 'Heading 3', - Heading_4: 'Heading 4', - Heading_5: 'Heading 5', - Heading_6: 'Heading 6', - Preformatted: 'Preformatted', - Blockquote: 'Blockquote', - Table_Header: 'Table Header', - URL: 'URL', - Title: 'Title', - Relationship: 'Relationship', - Alternative_Text: 'Alternative text', - Caption: 'Caption', - Summary: 'Summary', - Number_Of_Rows: 'Number of rows', - Number_Of_Cols: 'Number of cols', - Submit: 'Submit', - Cancel: 'Cancel', - Choose: 'Choose', - Preview: 'Preview', - Paste_From_Word: 'Paste from Word', - Tools: 'Tools', - Containers: 'Containers', - Classes: 'Classes', - Status: 'Status', - Source_Code: 'Source code' -}; \ No newline at end of file diff --git a/vendor/assets/javascripts/wymeditor/lang/es.js b/vendor/assets/javascripts/wymeditor/lang/es.js deleted file mode 100644 index 4a89b00..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/es.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS.es = { - Strong: 'Resaltar', - Emphasis: 'Enfatizar', - Superscript: 'Superindice', - Subscript: 'Subindice', - Ordered_List: 'Lista ordenada', - Unordered_List: 'Lista sin ordenar', - Indent: 'Indentado', - Outdent: 'Sin indentar', - Undo: 'Deshacer', - Redo: 'Rehacer', - Link: 'Enlazar', - Unlink: 'Eliminar enlace', - Image: 'Imagen', - Table: 'Tabla', - HTML: 'HTML', - Paragraph: 'Párrafo', - Heading_1: 'Cabecera 1', - Heading_2: 'Cabecera 2', - Heading_3: 'Cabecera 3', - Heading_4: 'Cabecera 4', - Heading_5: 'Cabecera 5', - Heading_6: 'Cabecera 6', - Preformatted: 'Preformateado', - Blockquote: 'Cita', - Table_Header: 'Cabecera de la tabla', - URL: 'URL', - Title: 'Título', - Alternative_Text: 'Texto alternativo', - Caption: 'Leyenda', - Summary: 'Summary', - Number_Of_Rows: 'Número de filas', - Number_Of_Cols: 'Número de columnas', - Submit: 'Enviar', - Cancel: 'Cancelar', - Choose: 'Seleccionar', - Preview: 'Vista previa', - Paste_From_Word: 'Pegar desde Word', - Tools: 'Herramientas', - Containers: 'Contenedores', - Classes: 'Clases', - Status: 'Estado', - Source_Code: 'Código fuente' -}; - diff --git a/vendor/assets/javascripts/wymeditor/lang/fa.js b/vendor/assets/javascripts/wymeditor/lang/fa.js deleted file mode 100644 index c948f24..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/fa.js +++ /dev/null @@ -1,46 +0,0 @@ -//Translation To Persian: Ghassem Tofighi (http://ght.ir) -WYMeditor.STRINGS.fa = { - Strong: 'پررنگ',//Strong - Emphasis: 'ایتالیک',//Emphasis - Superscript: 'بالانويس‌ ',//Superscript - Subscript: 'زيرنويس‌',//Subscript - Ordered_List: 'لیست مرتب',//Ordered List - Unordered_List: 'لیست نامرتب',//Unordered List - Indent: 'افزودن دندانه',//Indent - Outdent: 'کاهش دندانه',//Outdent - Undo: 'واگردانی',//Undo - Redo: 'تکرار',//Redo - Link: 'ساختن پیوند',//Link - Unlink: 'برداشتن پیوند',//Unlink - Image: 'تصویر',//Image - Table: 'جدول',//Table - HTML: 'HTML',//HTML - Paragraph: 'پاراگراف',//Paragraph - Heading_1: 'سرتیتر ۱',//Heading 1 - Heading_2: 'سرتیتر ۲',//Heading 2 - Heading_3: 'سرتیتر ۳',//Heading 3 - Heading_4: 'سرتیتر ۴',//Heading 4 - Heading_5: 'سرتیتر ۵',//Heading 5 - Heading_6: 'سرتیتر ۶',//Heading 6 - Preformatted: 'قالب آماده',//Preformatted - Blockquote: 'نقل قول',//Blockquote - Table_Header: 'سرجدول',//Table Header - URL: 'آدرس اینترنتی',//URL - Title: 'عنوان',//Title - Alternative_Text: 'متن جایگزین',//Alternative text - Caption: 'عنوان',//Caption - Summary: 'Summary', - Number_Of_Rows: 'تعداد سطرها',//Number of rows - Number_Of_Cols: 'تعداد ستون‌ها',//Number of cols - Submit: 'فرستادن',//Submit - Cancel: 'لغو',//Cancel - Choose: 'انتخاب',//Choose - Preview: 'پیش‌نمایش',//Preview - Paste_From_Word: 'انتقال از ورد',//Paste from Word - Tools: 'ابزار',//Tools - Containers: '‌قالب‌ها',//Containers - Classes: 'کلاس‌ها',//Classes - Status: 'وضعیت',//Status - Source_Code: 'کد مبدأ'//Source code -}; - diff --git a/vendor/assets/javascripts/wymeditor/lang/fi.js b/vendor/assets/javascripts/wymeditor/lang/fi.js deleted file mode 100644 index 529fcec..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/fi.js +++ /dev/null @@ -1,44 +0,0 @@ -WYMeditor.STRINGS.fi = { - Strong: 'Lihavoitu', - Emphasis: 'Korostus', - Superscript: 'Yläindeksi', - Subscript: 'Alaindeksi', - Ordered_List: 'Numeroitu lista', - Unordered_List: 'Luettelomerkit', - Indent: 'Suurenna sisennystä', - Outdent: 'Pienennä sisennystä', - Undo: 'Kumoa', - Redo: 'Toista', - Link: 'Linkitä', - Unlink: 'Poista linkitys', - Image: 'Kuva', - Table: 'Taulukko', - HTML: 'HTML', - Paragraph: 'Kappale', - Heading_1: 'Otsikko 1', - Heading_2: 'Otsikko 2', - Heading_3: 'Otsikko 3', - Heading_4: 'Otsikko 4', - Heading_5: 'Otsikko 5', - Heading_6: 'Otsikko 6', - Preformatted: 'Esimuotoilu', - Blockquote: 'Sitaatti', - Table_Header: 'Taulukon otsikko', - URL: 'URL', - Title: 'Otsikko', - Alternative_Text: 'Vaihtoehtoinen teksti', - Caption: 'Kuvateksti', - Summary: 'Yhteenveto', - Number_Of_Rows: 'Rivien määrä', - Number_Of_Cols: 'Palstojen määrä', - Submit: 'Lähetä', - Cancel: 'Peruuta', - Choose: 'Valitse', - Preview: 'Esikatsele', - Paste_From_Word: 'Tuo Wordista', - Tools: 'Työkalut', - Containers: 'Muotoilut', - Classes: 'Luokat', - Status: 'Tila', - Source_Code: 'Lähdekoodi' -}; diff --git a/vendor/assets/javascripts/wymeditor/lang/fr.js b/vendor/assets/javascripts/wymeditor/lang/fr.js deleted file mode 100644 index 1b2ab75..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/fr.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS.fr = { - Strong: 'Mise en évidence', - Emphasis: 'Emphase', - Superscript: 'Exposant', - Subscript: 'Indice', - Ordered_List: 'Liste Ordonnée', - Unordered_List: 'Liste Non-Ordonnée', - Indent: 'Imbriqué', - Outdent: 'Non-imbriqué', - Undo: 'Annuler', - Redo: 'Rétablir', - Link: 'Lien', - Unlink: 'Supprimer le Lien', - Image: 'Image', - Table: 'Tableau', - HTML: 'HTML', - Paragraph: 'Paragraphe', - Heading_1: 'Titre 1', - Heading_2: 'Titre 2', - Heading_3: 'Titre 3', - Heading_4: 'Titre 4', - Heading_5: 'Titre 5', - Heading_6: 'Titre 6', - Preformatted: 'Pré-formatté', - Blockquote: 'Citation', - Table_Header: 'Cellule de titre', - URL: 'URL', - Title: 'Titre', - Alternative_Text: 'Texte alternatif', - Caption: 'Légende', - Summary: 'Résumé', - Number_Of_Rows: 'Nombre de lignes', - Number_Of_Cols: 'Nombre de colonnes', - Submit: 'Envoyer', - Cancel: 'Annuler', - Choose: 'Choisir', - Preview: 'Prévisualisation', - Paste_From_Word: 'Copier depuis Word', - Tools: 'Outils', - Containers: 'Type de texte', - Classes: 'Type de contenu', - Status: 'Infos', - Source_Code: 'Code source' -}; - diff --git a/vendor/assets/javascripts/wymeditor/lang/gl.js b/vendor/assets/javascripts/wymeditor/lang/gl.js deleted file mode 100644 index 58a0af4..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/gl.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS.gl = { - Strong: 'Moita énfase', - Emphasis: 'Énfase', - Superscript: 'Superíndice', - Subscript: 'Subíndice', - Ordered_List: 'Lista ordenada', - Unordered_List: 'Lista sen ordenar', - Indent: 'Aniñar', - Outdent: 'Desaniñar', - Undo: 'Desfacer', - Redo: 'Refacer', - Link: 'Ligazón', - Unlink: 'Desligar', - Image: 'Imaxe', - Table: 'Táboa', - HTML: 'HTML', - Paragraph: 'Parágrafo', - Heading_1: 'Título 1', - Heading_2: 'Título 2', - Heading_3: 'Título 3', - Heading_4: 'Título 4', - Heading_5: 'Título 5', - Heading_6: 'Título 6', - Preformatted: 'Preformatado', - Blockquote: 'Cita en parágrafo', - Table_Header: 'Cabeceira da táboa', - URL: 'URL', - Title: 'Título', - Alternative_Text: 'Texto alternativo', - Caption: 'Título', - Summary: 'Resumo', - Number_Of_Rows: 'Número de filas', - Number_Of_Cols: 'Número de columnas', - Submit: 'Enviar', - Cancel: 'Cancelar', - Choose: 'Escoller', - Preview: 'Previsualizar', - Paste_From_Word: 'Colar dende Word', - Tools: 'Ferramentas', - Containers: 'Contenedores', - Classes: 'Clases', - Status: 'Estado', - Source_Code: 'Código fonte' -}; - diff --git a/vendor/assets/javascripts/wymeditor/lang/he.js b/vendor/assets/javascripts/wymeditor/lang/he.js deleted file mode 100644 index 3d57c33..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/he.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS.he = { - Strong: 'חזק', - Emphasis: 'מובלט', - Superscript: 'כתב עילי', - Subscript: 'כתב תחתי', - Ordered_List: 'רשימה ממוספרת', - Unordered_List: 'רשימה לא ממוספרת', - Indent: 'הזחה פנימה', - Outdent: 'הזחה החוצה', - Undo: 'בטל פעולה', - Redo: 'בצע מחדש פעולה', - Link: 'קישור', - Unlink: 'בטל קישור', - Image: 'תמונה', - Table: 'טבלה', - HTML: 'קוד HTML', - Paragraph: 'פסקה', - Heading_1: 'כותרת 1 ; תג <h1>', - Heading_2: 'כותרת 2 ; תג <h2>', - Heading_3: 'כותרת 3 ; תג <h3>', - Heading_4: 'כותרת 4 ; תג <h4>', - Heading_5: 'כותרת 5 ; תג <h5>', - Heading_6: 'כותרת 6 ; תג <h6>', - Preformatted: 'משמר רווחים', - Blockquote: 'ציטוט', - Table_Header: 'כותרת טבלה', - URL: 'קישור (URL)', - Title: 'כותרת', - Alternative_Text: 'טקסט חלופי', - Caption: 'כותרת', - Summary: 'סיכום', - Number_Of_Rows: 'מספר שורות', - Number_Of_Cols: 'מספר טורים', - Submit: 'שלח', - Cancel: 'בטל', - Choose: 'בחר', - Preview: 'תצוגה מקדימה', - Paste_From_Word: 'העתק מ-Word', - Tools: 'כלים', - Containers: 'מיכלים', - Classes: 'מחלקות', - Status: 'מצב', - Source_Code: 'קוד מקור' -}; - diff --git a/vendor/assets/javascripts/wymeditor/lang/hr.js b/vendor/assets/javascripts/wymeditor/lang/hr.js deleted file mode 100644 index 22d6bda..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/hr.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS.hr = { - Strong: 'Podebljano', - Emphasis: 'Naglašeno', - Superscript: 'Iznad', - Subscript: 'Ispod', - Ordered_List: 'Pobrojana lista', - Unordered_List: 'Nepobrojana lista', - Indent: 'Uvuci', - Outdent: 'Izvuci', - Undo: 'Poništi promjenu', - Redo: 'Ponovno promjeni', - Link: 'Hiperveza', - Unlink: 'Ukloni hipervezu', - Image: 'Slika', - Table: 'Tablica', - HTML: 'HTML', - Paragraph: 'Paragraf', - Heading_1: 'Naslov 1', - Heading_2: 'Naslov 2', - Heading_3: 'Naslov 3', - Heading_4: 'Naslov 4', - Heading_5: 'Naslov 5', - Heading_6: 'Naslov 6', - Preformatted: 'Unaprijed formatirano', - Blockquote: 'Citat', - Table_Header: 'Zaglavlje tablice', - URL: 'URL', - Title: 'Naslov', - Alternative_Text: 'Alternativni tekst', - Caption: 'Zaglavlje', - Summary: 'Sažetak', - Number_Of_Rows: 'Broj redova', - Number_Of_Cols: 'Broj kolona', - Submit: 'Snimi', - Cancel: 'Odustani', - Choose: 'Izaberi', - Preview: 'Pregled', - Paste_From_Word: 'Zalijepi iz Word-a', - Tools: 'Alati', - Containers: 'Kontejneri', - Classes: 'Klase', - Status: 'Status', - Source_Code: 'Izvorni kod' -}; - diff --git a/vendor/assets/javascripts/wymeditor/lang/hu.js b/vendor/assets/javascripts/wymeditor/lang/hu.js deleted file mode 100644 index fcc3a4e..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/hu.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS.hu = { - Strong: 'Félkövér', - Emphasis: 'Kiemelt', - Superscript: 'Felső index', - Subscript: 'Alsó index', - Ordered_List: 'Rendezett lista', - Unordered_List: 'Rendezetlen lista', - Indent: 'Bekezdés', - Outdent: 'Bekezdés törlése', - Undo: 'Visszavon', - Redo: 'Visszaállít', - Link: 'Link', - Unlink: 'Link törlése', - Image: 'Kép', - Table: 'Tábla', - HTML: 'HTML', - Paragraph: 'Bekezdés', - Heading_1: 'Címsor 1', - Heading_2: 'Címsor 2', - Heading_3: 'Címsor 3', - Heading_4: 'Címsor 4', - Heading_5: 'Címsor 5', - Heading_6: 'Címsor 6', - Preformatted: 'Előformázott', - Blockquote: 'Idézet', - Table_Header: 'Tábla Fejléc', - URL: 'Webcím', - Title: 'Megnevezés', - Alternative_Text: 'Alternatív szöveg', - Caption: 'Fejléc', - Summary: 'Summary', - Number_Of_Rows: 'Sorok száma', - Number_Of_Cols: 'Oszlopok száma', - Submit: 'Elküld', - Cancel: 'Mégsem', - Choose: 'Választ', - Preview: 'Előnézet', - Paste_From_Word: 'Másolás Word-ból', - Tools: 'Eszközök', - Containers: 'Tartalmak', - Classes: 'Osztályok', - Status: 'Állapot', - Source_Code: 'Forráskód' -}; - diff --git a/vendor/assets/javascripts/wymeditor/lang/it.js b/vendor/assets/javascripts/wymeditor/lang/it.js deleted file mode 100644 index d296e0b..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/it.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS.it = { - Strong: 'Grassetto', - Emphasis: 'Corsetto', - Superscript: 'Apice', - Subscript: 'Pedice', - Ordered_List: 'Lista Ordinata', - Unordered_List: 'Lista Puntata', - Indent: 'Indenta', - Outdent: 'Caccia', - Undo: 'Indietro', - Redo: 'Avanti', - Link: 'Inserisci Link', - Unlink: 'Togli Link', - Image: 'Inserisci Immagine', - Table: 'Inserisci Tabella', - HTML: 'HTML', - Paragraph: 'Paragrafo', - Heading_1: 'Heading 1', - Heading_2: 'Heading 2', - Heading_3: 'Heading 3', - Heading_4: 'Heading 4', - Heading_5: 'Heading 5', - Heading_6: 'Heading 6', - Preformatted: 'Preformattato', - Blockquote: 'Blockquote', - Table_Header: 'Header Tabella', - URL: 'Indirizzo', - Title: 'Titolo', - Alternative_Text: 'Testo Alternativo', - Caption: 'Caption', - Summary: 'Summary', - Number_Of_Rows: 'Numero di Righe', - Number_Of_Cols: 'Numero di Colonne', - Submit: 'Invia', - Cancel: 'Cancella', - Choose: 'Scegli', - Preview: 'Anteprima', - Paste_From_Word: 'Incolla', - Tools: 'Tools', - Containers: 'Contenitori', - Classes: 'Classi', - Status: 'Stato', - Source_Code: 'Codice Sorgente' -}; - diff --git a/vendor/assets/javascripts/wymeditor/lang/ja.js b/vendor/assets/javascripts/wymeditor/lang/ja.js deleted file mode 100644 index b00ef84..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/ja.js +++ /dev/null @@ -1,44 +0,0 @@ -WYMeditor.STRINGS.ja = { - Strong: '強調', - Emphasis: '強調', - Superscript: '上付き', - Subscript: '下付き', - Ordered_List: '番号付きリスト', - Unordered_List: '番号無リスト', - Indent: 'インデントを増やす', - Outdent: 'インデントを減らす', - Undo: '元に戻す', - Redo: 'やり直す', - Link: 'リンク', - Unlink: 'リンク取消', - Image: '画像', - Table: 'テーブル', - HTML: 'HTML', - Paragraph: '段落', - Heading_1: '見出し 1', - Heading_2: '見出し 2', - Heading_3: '見出し 3', - Heading_4: '見出し 4', - Heading_5: '見出し 5', - Heading_6: '見出し 6', - Preformatted: '整形済みテキスト', - Blockquote: '引用文', - Table_Header: '表見出し', - URL: 'URL', - Title: 'タイトル', - Alternative_Text: '代替テキスト', - Caption: 'キャプション', - Summary: 'サマリー', - Number_Of_Rows: '行数', - Number_Of_Cols: '列数', - Submit: '送信', - Cancel: 'キャンセル', - Choose: '選択', - Preview: 'プレビュー', - Paste_From_Word: '貼り付け', - Tools: 'ツール', - Containers: 'コンテナ', - Classes: 'クラス', - Status: 'ステータス', - Source_Code: 'ソースコード' -}; diff --git a/vendor/assets/javascripts/wymeditor/lang/lt.js b/vendor/assets/javascripts/wymeditor/lang/lt.js deleted file mode 100644 index b442655..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/lt.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS.lt = { - Strong: 'Pusjuodis', - Emphasis: 'Kursyvas', - Superscript: 'Viršutinis indeksas', - Subscript: 'Apatinis indeksas', - Ordered_List: 'Numeruotas sąrašas', - Unordered_List: 'Suženklintas sąrašas', - Indent: 'Padidinti įtrauką', - Outdent: 'Sumažinti įtrauką', - Undo: 'Atšaukti', - Redo: 'Atstatyti', - Link: 'Nuoroda', - Unlink: 'Panaikinti nuorodą', - Image: 'Vaizdas', - Table: 'Lentelė', - HTML: 'HTML', - Paragraph: 'Paragrafas', - Heading_1: 'Antraštinis 1', - Heading_2: 'Antraštinis 2', - Heading_3: 'Antraštinis 3', - Heading_4: 'Antraštinis 4', - Heading_5: 'Antraštinis 5', - Heading_6: 'Antraštinis 6', - Preformatted: 'Formuotas', - Blockquote: 'Citata', - Table_Header: 'Lentelės antraštė', - URL: 'URL', - Title: 'Antraštinis tekstas', - Relationship: 'Sąryšis', - Alternative_Text: 'Alternatyvus tekstas', - Caption: 'Antraštė', - Summary: 'Santrauka', - Number_Of_Rows: 'Eilučių skaičius', - Number_Of_Cols: 'Stulpelių skaičius', - Submit: 'Išsaugoti', - Cancel: 'Nutraukti', - Choose: 'Rinktis', - Preview: 'Peržiūra', - Paste_From_Word: 'Įkelti iš MS Word', - Tools: 'Įrankiai', - Containers: 'Stiliai', - Classes: 'Klasės', - Status: 'Statusas', - Source_Code: 'Išeities tekstas' -}; \ No newline at end of file diff --git a/vendor/assets/javascripts/wymeditor/lang/nb.js b/vendor/assets/javascripts/wymeditor/lang/nb.js deleted file mode 100644 index 2ed2d95..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/nb.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS.nb = { - Strong: 'Fet', - Emphasis: 'Uthevet', - Superscript: 'Opphøyet', - Subscript: 'Nedsenket', - Ordered_List: 'Nummerert liste', - Unordered_List: 'Punktliste', - Indent: 'Rykk inn', - Outdent: 'Rykk ut', - Undo: 'Angre', - Redo: 'Gjenta', - Link: 'Lenke', - Unlink: 'Ta bort lenken', - Image: 'Bilde', - Table: 'Tabell', - HTML: 'HTML', - Paragraph: 'Avsnitt', - Heading_1: 'Overskrift 1', - Heading_2: 'Overskrift 2', - Heading_3: 'Overskrift 3', - Heading_4: 'Overskrift 4', - Heading_5: 'Overskrift 5', - Heading_6: 'Overskrift 6', - Preformatted: 'Preformatert', - Blockquote: 'Sitat', - Table_Header: 'Tabelloverskrift', - URL: 'URL', - Title: 'Tittel', - Alternative_Text: 'Alternativ tekst', - Caption: 'Overskrift', - Summary: 'Sammendrag', - Number_Of_Rows: 'Antall rader', - Number_Of_Cols: 'Antall kolonner', - Submit: 'Ok', - Cancel: 'Avbryt', - Choose: 'Velg', - Preview: 'Forhåndsvis', - Paste_From_Word: 'Lim inn fra Word', - Tools: 'Verktøy', - Containers: 'Formatering', - Classes: 'Klasser', - Status: 'Status', - Source_Code: 'Kildekode' -}; - diff --git a/vendor/assets/javascripts/wymeditor/lang/nl.js b/vendor/assets/javascripts/wymeditor/lang/nl.js deleted file mode 100644 index a7572f1..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/nl.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS.nl = { - Strong: 'Sterk benadrukken', - Emphasis: 'Benadrukken', - Superscript: 'Bovenschrift', - Subscript: 'Onderschrift', - Ordered_List: 'Geordende lijst', - Unordered_List: 'Ongeordende lijst', - Indent: 'Inspringen', - Outdent: 'Terugspringen', - Undo: 'Ongedaan maken', - Redo: 'Opnieuw uitvoeren', - Link: 'Linken', - Unlink: 'Ontlinken', - Image: 'Afbeelding', - Table: 'Tabel', - HTML: 'HTML', - Paragraph: 'Paragraaf', - Heading_1: 'Kop 1', - Heading_2: 'Kop 2', - Heading_3: 'Kop 3', - Heading_4: 'Kop 4', - Heading_5: 'Kop 5', - Heading_6: 'Kop 6', - Preformatted: 'Voorgeformatteerd', - Blockquote: 'Citaat', - Table_Header: 'Tabel-kop', - URL: 'URL', - Title: 'Titel', - Relationship: 'Relatie', - Alternative_Text: 'Alternatieve tekst', - Caption: 'Bijschrift', - Summary: 'Summary', - Number_Of_Rows: 'Aantal rijen', - Number_Of_Cols: 'Aantal kolommen', - Submit: 'Versturen', - Cancel: 'Annuleren', - Choose: 'Kiezen', - Preview: 'Voorbeeld bekijken', - Paste_From_Word: 'Plakken uit Word', - Tools: 'Hulpmiddelen', - Containers: 'Teksttypes', - Classes: 'Klassen', - Status: 'Status', - Source_Code: 'Broncode' -}; \ No newline at end of file diff --git a/vendor/assets/javascripts/wymeditor/lang/nn.js b/vendor/assets/javascripts/wymeditor/lang/nn.js deleted file mode 100644 index c7ea20c..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/nn.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS.nn = { - Strong: 'Feit', - Emphasis: 'Utheva', - Superscript: 'Opphøgd', - Subscript: 'Nedsenka', - Ordered_List: 'Nummerert liste', - Unordered_List: 'Punktliste', - Indent: 'Rykk inn', - Outdent: 'Rykk ut', - Undo: 'Angre', - Redo: 'Gjentaka', - Link: 'Lenkje', - Unlink: 'Ta bort lenkja', - Image: 'Bilete', - Table: 'Tabell', - HTML: 'HTML', - Paragraph: 'Avsnitt', - Heading_1: 'Overskrift 1', - Heading_2: 'Overskrift 2', - Heading_3: 'Overskrift 3', - Heading_4: 'Overskrift 4', - Heading_5: 'Overskrift 5', - Heading_6: 'Overskrift 6', - Preformatted: 'Preformatert', - Blockquote: 'Sitat', - Table_Header: 'Tabelloverskrift', - URL: 'URL', - Title: 'Tittel', - Alternative_Text: 'Alternativ tekst', - Caption: 'Overskrift', - Summary: 'Samandrag', - Number_Of_Rows: 'Tal på rader', - Number_Of_Cols: 'Tal på kolonnar', - Submit: 'Ok', - Cancel: 'Avbryt', - Choose: 'Vel', - Preview: 'Førehandsvis', - Paste_From_Word: 'Lim inn frå Word', - Tools: 'Verkty', - Containers: 'Formatering', - Classes: 'Klassar', - Status: 'Status', - Source_Code: 'Kjeldekode' -}; - diff --git a/vendor/assets/javascripts/wymeditor/lang/pl.js b/vendor/assets/javascripts/wymeditor/lang/pl.js deleted file mode 100644 index cf01891..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/pl.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS.pl = { - Strong: 'Nacisk', - Emphasis: 'Emfaza', - Superscript: 'Indeks górny', - Subscript: 'Indeks dolny', - Ordered_List: 'Lista numerowana', - Unordered_List: 'Lista wypunktowana', - Indent: 'Zwiększ wcięcie', - Outdent: 'Zmniejsz wcięcie', - Undo: 'Cofnij', - Redo: 'Ponów', - Link: 'Wstaw link', - Unlink: 'Usuń link', - Image: 'Obraz', - Table: 'Tabela', - HTML: 'Źródło HTML', - Paragraph: 'Akapit', - Heading_1: 'Nagłówek 1', - Heading_2: 'Nagłówek 2', - Heading_3: 'Nagłówek 3', - Heading_4: 'Nagłówek 4', - Heading_5: 'Nagłówek 5', - Heading_6: 'Nagłówek 6', - Preformatted: 'Preformatowany', - Blockquote: 'Cytat blokowy', - Table_Header: 'Nagłówek tabeli', - URL: 'URL', - Title: 'Tytuł', - Alternative_Text: 'Tekst alternatywny', - Caption: 'Tytuł tabeli', - Summary: 'Summary', - Number_Of_Rows: 'Liczba wierszy', - Number_Of_Cols: 'Liczba kolumn', - Submit: 'Wyślij', - Cancel: 'Anuluj', - Choose: 'Wybierz', - Preview: 'Podgląd', - Paste_From_Word: 'Wklej z Worda', - Tools: 'Narzędzia', - Containers: 'Format', - Classes: 'Styl', - Status: 'Status', - Source_Code: 'Kod źródłowy' -}; - diff --git a/vendor/assets/javascripts/wymeditor/lang/pt-br.js b/vendor/assets/javascripts/wymeditor/lang/pt-br.js deleted file mode 100644 index 2ec18fe..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/pt-br.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS['pt-br'] = { - Strong: 'Resaltar', - Emphasis: 'Enfatizar', - Superscript: 'Sobre escrito', - Subscript: 'Sub escrito ', - Ordered_List: 'Lista ordenada', - Unordered_List: 'Lista desordenada', - Indent: 'Indentado', - Outdent: 'Desidentar', - Undo: 'Desfazer', - Redo: 'Refazer', - Link: 'Link', - Unlink: 'Remover Link', - Image: 'Imagem', - Table: 'Tabela', - HTML: 'HTML', - Paragraph: 'Parágrafo', - Heading_1: 'Título 1', - Heading_2: 'Título 2', - Heading_3: 'Título 3', - Heading_4: 'Título 4', - Heading_5: 'Título 5', - Heading_6: 'Título 6', - Preformatted: 'Preformatado', - Blockquote: 'Citação', - Table_Header: 'Título de tabela', - URL: 'URL', - Title: 'Título', - Alternative_Text: 'Texto alternativo', - Caption: 'Legenda', - Summary: 'Summary', - Number_Of_Rows: 'Número de linhas', - Number_Of_Cols: 'Número de colunas', - Submit: 'Enviar', - Cancel: 'Cancelar', - Choose: 'Selecionar', - Preview: 'Previsualizar', - Paste_From_Word: 'Copiar do Word', - Tools: 'Ferramentas', - Containers: 'Conteneiners', - Classes: 'Classes', - Status: 'Estado', - Source_Code: 'Código fonte' -}; - diff --git a/vendor/assets/javascripts/wymeditor/lang/pt.js b/vendor/assets/javascripts/wymeditor/lang/pt.js deleted file mode 100644 index 7ea1d7c..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/pt.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS.pt = { - Strong: 'Negrito', - Emphasis: 'Itálico', - Superscript: 'Sobrescrito', - Subscript: 'Subsescrito', - Ordered_List: 'Lista Numerada', - Unordered_List: 'Lista Marcada', - Indent: 'Aumentar Indentaçã', - Outdent: 'Diminuir Indentaçã', - Undo: 'Desfazer', - Redo: 'Restaurar', - Link: 'Link', - Unlink: 'Tirar link', - Image: 'Imagem', - Table: 'Tabela', - HTML: 'HTML', - Paragraph: 'Parágrafo', - Heading_1: 'Título 1', - Heading_2: 'Título 2', - Heading_3: 'Título 3', - Heading_4: 'Título 4', - Heading_5: 'Título 5', - Heading_6: 'Título 6', - Preformatted: 'Pré-formatado', - Blockquote: 'Citação', - Table_Header: 'Cabeçalho Tabela', - URL: 'URL', - Title: 'Título', - Alternative_Text: 'Texto Alterativo', - Caption: 'Título Tabela', - Summary: 'Summary', - Number_Of_Rows: 'Número de Linhas', - Number_Of_Cols: 'Número de Colunas', - Submit: 'Enviar', - Cancel: 'Cancelar', - Choose: 'Escolha', - Preview: 'Prever', - Paste_From_Word: 'Colar do Word', - Tools: 'Ferramentas', - Containers: 'Containers', - Classes: 'Classes', - Status: 'Status', - Source_Code: 'Código Fonte' -}; - diff --git a/vendor/assets/javascripts/wymeditor/lang/ru.js b/vendor/assets/javascripts/wymeditor/lang/ru.js deleted file mode 100644 index 368a90c..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/ru.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS.ru = { - Strong: 'Жирный', - Emphasis: 'Наклонный', - Superscript: 'Надстрочный', - Subscript: 'Подстрочный', - Ordered_List: 'Нумерованый список', - Unordered_List: 'Ненумерованый список', - Indent: 'Увеличить отступ', - Outdent: 'Уменьшить отступ', - Undo: 'Отменить', - Redo: 'Повторить', - Link: 'Ссылка', - Unlink: 'Удалить ссылку', - Image: 'Изображение', - Table: 'Таблица', - HTML: 'Править HTML', - Paragraph: 'Параграф', - Heading_1: 'Заголовок 1', - Heading_2: 'Заголовок 2', - Heading_3: 'Заголовок 3', - Heading_4: 'Заголовок 4', - Heading_5: 'Заголовок 5', - Heading_6: 'Заголовок 6', - Preformatted: 'Preformatted', - Blockquote: 'Цитата', - Table_Header: 'Заголовок таблицы', - URL: 'URL', - Title: 'Заголовок', - Alternative_Text: 'Альтернативный текст', - Caption: 'Надпись', - Summary: 'Summary', - Number_Of_Rows: 'Кол-во строк', - Number_Of_Cols: 'Кол-во столбцов', - Submit: 'Отправить', - Cancel: 'Отмена', - Choose: 'Выбор', - Preview: 'Просмотр', - Paste_From_Word: 'Вставить из Word', - Tools: 'Инструменты', - Containers: 'Контейнеры', - Classes: 'Классы', - Status: 'Статус', - Source_Code: 'Исходный код' -}; - diff --git a/vendor/assets/javascripts/wymeditor/lang/sv.js b/vendor/assets/javascripts/wymeditor/lang/sv.js deleted file mode 100644 index 34081bc..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/sv.js +++ /dev/null @@ -1,46 +0,0 @@ -WYMeditor.STRINGS.sv = { - Strong: 'Viktigt', - Emphasis: 'Betoning', - Superscript: 'Upphöjt', - Subscript: 'Nedsänkt', - Ordered_List: 'Nummerlista', - Unordered_List: 'Punktlista', - Indent: 'Indrag', - Outdent: 'Utdrag', - Undo: 'Ångra', - Redo: 'Gör om', - Link: 'Länk', - Unlink: 'Ta bort länk', - Image: 'Bild', - Table: 'Tabell', - HTML: 'HTML', - Paragraph: 'Paragraf', - Heading_1: 'Rubrik 1', - Heading_2: 'Rubrik 2', - Heading_3: 'Rubrik 3', - Heading_4: 'Rubrik 4', - Heading_5: 'Rubrik 5', - Heading_6: 'Rubrik 6', - Preformatted: 'Förformaterad', - Blockquote: 'Blockcitat', - Table_Header: 'Tabellrubrik', - URL: 'URL', - Title: 'Titel', - Relationship: 'Relation', - Alternative_Text: 'Alternativ text', - Caption: 'Överskrift', - Summary: 'Summary', - Number_Of_Rows: 'Antal rader', - Number_Of_Cols: 'Antal kolumner', - Submit: 'Skicka', - Cancel: 'Avbryt', - Choose: 'Välj', - Preview: 'Förhandsgranska', - Paste_From_Word: 'Klistra in från Word', - Tools: 'Verktyg', - Containers: 'Formatering', - Classes: 'Klasser', - Status: 'Status', - Source_Code: 'Källkod' -}; - diff --git a/vendor/assets/javascripts/wymeditor/lang/tr.js b/vendor/assets/javascripts/wymeditor/lang/tr.js deleted file mode 100644 index f5e1aeb..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/tr.js +++ /dev/null @@ -1,45 +0,0 @@ -WYMeditor.STRINGS.tr = { - Strong: 'Kalın', - Emphasis: 'Vurgu', - Superscript: 'Superscript', - Subscript: 'Subscript', - Ordered_List: 'Sıralı List', - Unordered_List: 'Sırasız List', - Indent: 'İçerlek', - Outdent: 'Çıkıntılı', - Undo: 'Geri Al', - Redo: 'Yinele', - Link: 'Bağlantı', - Unlink: 'Bağlantıyı Kaldır', - Image: 'İmaj', - Table: 'Tablo', - HTML: 'HTML', - Paragraph: 'Parağraf', - Heading_1: 'Başlık 1', - Heading_2: 'Başlık 2', - Heading_3: 'Başlık 3', - Heading_4: 'Başlık 4', - Heading_5: 'Başlık 5', - Heading_6: 'Başlık 6', - Preformatted: 'Önceden Formatlı', - Blockquote: 'Alıntı', - Table_Header: 'Tablo Başlığı', - URL: 'URL', - Title: 'Başlık', - Alternative_Text: 'Alternatif Metin', - Caption: 'Etiket', - Summary: 'Summary', - Number_Of_Rows: 'Satır sayısı', - Number_Of_Cols: 'Sütun sayısı', - Submit: 'Gönder', - Cancel: 'İptal', - Choose: 'Seç', - Preview: 'Önizleme', - Paste_From_Word: 'Wordden yapıştır', - Tools: 'Araçlar', - Containers: 'Kapsayıcılar', - Classes: 'Sınıflar', - Status: 'Durum', - Source_Code: 'Kaynak Kodu' -}; - diff --git a/vendor/assets/javascripts/wymeditor/lang/zh_cn.js b/vendor/assets/javascripts/wymeditor/lang/zh_cn.js deleted file mode 100644 index 3e35678..0000000 --- a/vendor/assets/javascripts/wymeditor/lang/zh_cn.js +++ /dev/null @@ -1,47 +0,0 @@ -WYMeditor.STRINGS.zh_cn = { - Strong: '加粗', - Emphasis: '斜体', - Superscript: '上标', - Subscript: '下标', - Ordered_List: '有序列表', - Unordered_List: '无序列表', - Indent: '增加缩进', - Outdent: '减少缩进', - Undo: '撤消', - Redo: '重做', - Link: '链接', - Unlink: '取消链接', - Image: '图片', - Table: '表格', - HTML: 'HTML源代码', - Paragraph: '段落', - Heading_1: '标题 1', - Heading_2: '标题 2', - Heading_3: '标题 3', - Heading_4: '标题 4', - Heading_5: '标题 5', - Heading_6: '标题 6', - Preformatted: '原始文本', - Blockquote: '引语', - Table_Header: '表头', - URL: '地址', - Title: '提示文字', - Alternative_Text: '失效文字', - Caption: '标题', - Summary: 'Summary', - Number_Of_Rows: '行数', - Number_Of_Cols: '列数', - Submit: '提交', - Cancel: '放弃', - Choose: '选择', - Preview: '预览', - Paste_From_Word: '从Word粘贴纯文本', - Tools: '工具', - Containers: '容器', - Classes: '预定义样式', - Status: '状态', - Source_Code: '源代码', - Attachment: '附件', - NewParagraph: '新段落' -}; - diff --git a/vendor/assets/javascripts/wymeditor/plugins/embed/jquery.wymeditor.embed.js b/vendor/assets/javascripts/wymeditor/plugins/embed/jquery.wymeditor.embed.js deleted file mode 100644 index 79daa16..0000000 --- a/vendor/assets/javascripts/wymeditor/plugins/embed/jquery.wymeditor.embed.js +++ /dev/null @@ -1,82 +0,0 @@ -/** - * WYMeditor : what you see is What You Mean web-based editor - * Copyright (c) 2005 - 2009 Jean-Francois Hovinne, http://www.wymeditor.org/ - * Dual licensed under the MIT (MIT-license.txt) - * and GPL (GPL-license.txt) licenses. - * - * For further information visit: - * http://www.wymeditor.org/ - * - * File Name: - * jquery.wymeditor.embed.js - * Experimental embed plugin - * - * File Authors: - * Jonatan Lundin (jonatan.lundin a-t gmail dotcom) - * Roger Hu (roger.hu a-t gmail dotcom) - * Scott Nixon (citadelgrad a-t gmail dotcom) - */ - -(function () { - function removeItem(item, arr) { - for (var i = arr.length; i--;) { - if (arr[i] === item) { - arr.splice(i, 1); - } - } - return arr; - } - if (WYMeditor && WYMeditor.XhtmlValidator._tags.param.attributes) { - - WYMeditor.XhtmlValidator._tags.embed = { - "attributes":[ - "allowscriptaccess", - "allowfullscreen", - "height", - "src", - "type", - "width" - ] - }; - - WYMeditor.XhtmlValidator._tags.param.attributes = { - '0':'name', - '1':'type', - 'valuetype':/^(data|ref|object)$/, - '2':'valuetype', - '3':'value' - }; - - WYMeditor.XhtmlValidator._tags.iframe = { - "attributes":[ - "allowfullscreen", - "width", - "height", - "src", - "title", - "frameborder" - ] - }; - - // Override the XhtmlSaxListener to allow param, embed and iframe. - // - // We have to do an explicit override - // of the function instead of just changing the startup parameters - // because those are only used on creation, and changing them after - // the fact won't affect the existing XhtmlSaxListener - var XhtmlSaxListener = WYMeditor.XhtmlSaxListener; - WYMeditor.XhtmlSaxListener = function () { - var listener = XhtmlSaxListener.call(this); - // param, embed and iframe should be inline tags so that they can - // be nested inside other elements - removeItem('param', listener.block_tags); - listener.inline_tags.push('param'); - listener.inline_tags.push('embed'); - listener.inline_tags.push('iframe'); - - return listener; - }; - - WYMeditor.XhtmlSaxListener.prototype = XhtmlSaxListener.prototype; - } -})(); diff --git a/vendor/assets/javascripts/wymeditor/plugins/fullscreen/icon_fullscreen.gif b/vendor/assets/javascripts/wymeditor/plugins/fullscreen/icon_fullscreen.gif deleted file mode 100644 index d2a8b0ab985f290db50434fc07a76dfb6a803ee2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 509 zcmZ?wbhEHb6lD-$c*e~TpH$L3Yjg9=O?4Aj)=gNRQ`VW0-&oN;w{P{aijMgm^R_dL z0$PTE;!hSv1_o{h9groUIALIqYT#~aZfR|6@96C6?rG;_D)7C zHO-kff8qQEO{^^Jt5&aKXrIHzwQ2Kaw)IULw`|$gwqe)q?c6)}bM0x}cjV|nhBarI SI4)e|U|xFl+V%O34Aua#YeInl diff --git a/vendor/assets/javascripts/wymeditor/plugins/fullscreen/jquery.wymeditor.fullscreen.js b/vendor/assets/javascripts/wymeditor/plugins/fullscreen/jquery.wymeditor.fullscreen.js deleted file mode 100644 index 3f805e5..0000000 --- a/vendor/assets/javascripts/wymeditor/plugins/fullscreen/jquery.wymeditor.fullscreen.js +++ /dev/null @@ -1,124 +0,0 @@ -/* - * WYMeditor : what you see is What You Mean web-based editor - * Copyright (c) 2005 - 2009 Jean-Francois Hovinne, http://www.wymeditor.org/ - * Dual licensed under the MIT (MIT-license.txt) - * and GPL (GPL-license.txt) licenses. - * - * For further information visit: - * http://www.wymeditor.org/ - * - * File Name: - * jquery.wymeditor.fullscreen.js - * Fullscreen plugin for WYMeditor - * - * File Authors: - * Luis Santos (luis.santos a-t openquest dotpt) - * Jonatan Lundin (jonatan.lundin a-t gmail dotcom) - * Gerd Riesselmann (gerd a-t gyro-php dot org) : Fixed issue with new skin layout - */ - -//Extend WYMeditor -WYMeditor.editor.prototype.fullscreen = function() { - var wym = this, - $box = jQuery(this._box), - $iframe = jQuery(this._iframe), - $overlay = null, - $window = jQuery(window), - - editorMargin = 15; // Margin from window (without padding) - - - //construct the button's html - var html = '' + - "
  • " + - "" + - "Fullscreen" + - "" + - "
  • "; - //add the button to the tools box - $box.find(wym._options.toolsSelector + wym._options.toolsListSelector) - .append(html); - - function resize () { - // Calculate margins - var uiHeight = $box.outerHeight(true) - $iframe.outerHeight(true); - var editorPadding = $box.outerWidth() - $box.width(); - - // Calculate heights - var screenHeight = $window.height(); - var iframeHeight = (screenHeight - uiHeight - (editorMargin * 2)) + 'px'; - - // Calculate witdths - var screenWidth = $window.width(); - var boxWidth = (screenWidth - editorPadding - (editorMargin * 2)) + 'px'; - - $box.css('width', boxWidth); - $iframe.css('height', iframeHeight); - $overlay.css({ - 'height': screenHeight + 'px', - 'width': screenWidth + 'px' - }); - } - - //handle click event - $box.find('li.wym_tools_fullscreen a').click(function() { - if ($box.css('position') != 'fixed') { - // Store previous inline styles - $box.data('wym-inline-css', $box.attr('style')); - $iframe.data('wym-inline-css', $iframe.attr('style')); - - // Create overlay - $overlay = jQuery('
    ') - .appendTo('body').css({ - 'position': 'fixed', - 'background-color': 'rgb(0, 0, 0)', - 'opacity': '0.75', - 'z-index': '98', - 'top': '0px', - 'left': '0px' - }); - - // Possition the editor - $box.css({ - 'position': 'fixed', - 'z-index': '99', - 'top': editorMargin + 'px', - 'left': editorMargin + 'px' - }); - - // Bind event listeners - $window.bind('resize', resize); - $box.find('li.wym_tools_html a').bind('click', resize); - - // Force resize - resize(); - } else { - // Unbind event listeners - $window.unbind('resize', resize); - $box.find('li.wym_tools_html a').unbind('click', resize); - - // Remove inline styles - $box.css({ - 'position': 'static', - 'z-index': '', - 'width': '', - 'top': '', - 'left': '' - }); - $iframe.css('height', ''); - - // Remove overlay - $overlay.remove(); - $overlay = null; - - // Retore previous inline styles - $box.attr('style', $box.data('wym-inline-css')); - $iframe.attr('style', $iframe.data('wym-inline-css')); - } - - return false; - }); -}; diff --git a/vendor/assets/javascripts/wymeditor/plugins/hovertools/jquery.wymeditor.hovertools.js b/vendor/assets/javascripts/wymeditor/plugins/hovertools/jquery.wymeditor.hovertools.js deleted file mode 100644 index 1a9521d..0000000 --- a/vendor/assets/javascripts/wymeditor/plugins/hovertools/jquery.wymeditor.hovertools.js +++ /dev/null @@ -1,49 +0,0 @@ -/*jslint evil: true */ -/** - WYMeditor.hovertools - ==================== - - A hovertools plugin. -*/ - -WYMeditor.editor.prototype.hovertools = function() { - var wym = this; - - wym.status(' '); - - // Bind events on buttons - jQuery(this._box).find(this._options.toolSelector).hover( - function() { - wym.status(jQuery(this).html()); - }, - function() { - wym.status(' '); - } - ); - - // Classes: add/remove a style attr to matching elems - // while mouseover/mouseout - jQuery(this._box).find(this._options.classSelector).hover( - function() { - var aClasses = eval(wym._options.classesItems); - var sName = jQuery(this).attr(WYMeditor.NAME); - var oClass = WYMeditor.Helper.findByName(aClasses, sName); - - if (oClass){ - jqexpr = oClass.expr; - // Don't use jQuery.find() on the iframe body - // because of MSIE + jQuery + expando issue (#JQ1143) - if (!jQuery.browser.msie) { - jQuery(wym._doc).find(jqexpr).css('background-color','#cfc'); - } - } - }, - function() { - // Don't use jQuery.find() on the iframe body - // because of MSIE + jQuery + expando issue (#JQ1143) - if (!jQuery.browser.msie) { - jQuery(wym._doc).find('*').removeAttr('style'); - } - } - ); -}; diff --git a/vendor/assets/javascripts/wymeditor/plugins/list/jquery.wymeditor.list.js b/vendor/assets/javascripts/wymeditor/plugins/list/jquery.wymeditor.list.js deleted file mode 100644 index 1d75858..0000000 --- a/vendor/assets/javascripts/wymeditor/plugins/list/jquery.wymeditor.list.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (c) 2011 PolicyStat LLC. - * MIT licensed (MIT-license.txt) - * - * This plugin adds the ability to use tab and shift+tab to indent/outdent - * lists, mimicking a user's expected behavior when inside an editor. - * - * @author Wes Winham (winhamwr@gmail.com) - */ - -function ListPlugin(options, wym) { - this._options = jQuery.extend({}, options); - this._wym = wym; - - this.init(); -} - -ListPlugin.prototype.init = function() { - this._wym.listPlugin = this; - - this.bindEvents(); -}; - -ListPlugin.prototype.bindEvents = function() { - var listPlugin = this; - var wym = this._wym; - - // Bind a key listener so we can handle tabs - // With jQuery 1.3, live() can be used to simplify handler logic - $(wym._doc).bind('keydown', listPlugin.handleKeyDown); -}; - -/** - * Handle any tab presses when inside list items and indent/outdent. - */ -ListPlugin.prototype.handleKeyDown = function(evt) { - //'this' is the editor._doc - var wym = WYMeditor.INSTANCES[this.title]; - var listPlugin = wym.listPlugin; - - var container = wym.selected(); - var name = container.tagName.toLowerCase(); - // We only care about tabs when we're inside a list - if (name != "li") { - return null; - } - - // Handle tab presses - if (evt.keyCode == WYMeditor.KEY.TAB) { - if (evt.shiftKey) { - wym.exec(WYMeditor.OUTDENT); - return false; // Short-circuit normal tab behavior - } else { - wym.exec(WYMeditor.INDENT); - return false; - } - } - - return null; -}; diff --git a/vendor/assets/javascripts/wymeditor/plugins/rdfa/jquery.wymeditor.rdfa.js b/vendor/assets/javascripts/wymeditor/plugins/rdfa/jquery.wymeditor.rdfa.js deleted file mode 100644 index ecbacca..0000000 --- a/vendor/assets/javascripts/wymeditor/plugins/rdfa/jquery.wymeditor.rdfa.js +++ /dev/null @@ -1,182 +0,0 @@ -/* - * WYMeditor : what you see is What You Mean web-based editor - * Copyright (c) 2005 - 2011 Jean-Francois Hovinne, http://www.wymeditor.org/ - * Dual licensed under the MIT (MIT-license.txt) - * and GPL (GPL-license.txt) licenses. - * - * For further information visit: - * http://www.wymeditor.org/ - * - * File Name: - * jquery.wymeditor.rdfa.js - * RDFa plugin for WYMeditor - * - * File Authors: - * Jean-Francois Hovinne (@jfhovinne) - */ - -//Extend WYMeditor -WYMeditor.editor.prototype.rdfa = function(options) { - var rdfa = new WYMeditor.RDFa(options, this); - return(rdfa); -}; - -//RDFa constructor -WYMeditor.RDFa = function(options, wym) { - options = jQuery.extend({ - setStdNameSpaces: true, - extendXHTMLParser: true, - buttons: {} - }, options); - - this._options = options; - this._wym = wym; - this.init(); -}; - -//RDFa plugin init -WYMeditor.RDFa.prototype.init = function() { - if (this._options.setStdNameSpaces) { - this.setStdNameSpaces(); - } - if (this._options.extendXHTMLParser) { - this.extendXHTMLParser(); - } - this.setButtons(); -}; - -//Adding the namespaces to the document -WYMeditor.RDFa.prototype.setStdNameSpaces = function() { - this.addNameSpace('xmlns', 'http://www.w3.org/1999/xhtml'); - this.addNameSpace('version', 'XHTML+RDFa 1.0'); -}; - -WYMeditor.RDFa.prototype.addNameSpace = function(attr, value) { - jQuery('html', this._wym._doc) - .attr(attr, value); -}; - -WYMeditor.RDFa.prototype.extendXHTMLParser = function() { - this.extendAttributes(); - this.setStdVocabularies(); - this.extendLinkAttributes(); -}; - -WYMeditor.RDFa.prototype.extendAttributes = function() { - //Add the RDFa attributes - WYMeditor.XhtmlValidator._attributes.core.attributes.push( - 'rel', - 'rev', - 'content', - 'href', - 'src', - 'about', - 'property', - 'resource', - 'datatype', - 'typeof'); -}; - -WYMeditor.RDFa.prototype.setStdVocabularies = function() { - var _this = this; - //Add the 'standard' vocabularies - vocabularies = [ - 'xmlns:biblio', - 'xmlns:cc', - 'xmlns:dbp', - 'xmlns:dbr', - 'xmlns:dc', - 'xmlns:ex', - 'xmlns:foaf', - 'xmlns:rdf', - 'xmlns:rdfs', - 'xmlns:taxo', - 'xmlns:xhv', - 'xmlns:xsd' - ]; - jQuery.each(vocabularies, function(index, vocabulary) { - _this.addVocabulary(vocabulary); - }); -}; - -WYMeditor.RDFa.prototype.addVocabulary = function(vocabulary) { - WYMeditor.XhtmlValidator._attributes.core.attributes.push(vocabulary); -}; - -WYMeditor.RDFa.prototype.extendLinkAttributes = function() { - //Overwrite the attributes 'rel' and 'rev' - WYMeditor.XhtmlValidator._tags.a = { - "attributes": { - "0":"charset", - "1":"coords", - "2":"href", - "3":"hreflang", - "4":"name", - "5":"rel", - "6":"rev", - "shape":/^(rect|rectangle|circ|circle|poly|polygon)$/, - "7":"type" - } - }; -}; - -WYMeditor.RDFa.prototype.setButtons = function() { - var _this = this; - var list = jQuery(this._wym._box).find('div.wym_classes ul'); - jQuery.each(this._options.buttons, function(index, button) { - list - .append('
  • ') - .children(':last') - .append('
    ') - .children(':last') - .attr('href', '#') - .text(button.title) - .bind('click', - {instance: _this._wym, - button: button, - ns: button.ns, - attr: button.attr, - value: button.value}, - _this.clickButtonHandler); - }); -}; - -WYMeditor.RDFa.prototype.clickButtonHandler = function(evt) { - var wym = evt.data.instance, - selected = wym.selected(); - - //the attribute already exists, remove it - if (typeof(jQuery(selected).attr(evt.data.attr)) !== 'undefined' && - jQuery(selected).attr(evt.data.attr) != '') { - WYMeditor.console.log( - 'attribute already exists, remove it:', - evt.data.attr, - jQuery(selected).attr(evt.data.attr)); - jQuery(selected) - .removeAttr(evt.data.attr) - .removeClass(evt.data.ns) - .removeClass(evt.data.attr) - .removeClass(evt.data.value); - - //else, add it - } else { - WYMeditor.console.log('attribute does not exist, add it:', evt.data.attr, evt.data.value); - if (evt.data.value) { //value available - jQuery(selected) - .attr(evt.data.attr, evt.data.ns + ':' + evt.data.value) - .addClass(evt.data.ns) - .addClass(evt.data.attr) - .addClass(evt.data.value); - } else { //value not available - evt.data.value = prompt('Value', ''); - if (evt.data.value !== null) { - jQuery(selected) - .attr(evt.data.attr, evt.data.value) - .addClass(evt.data.ns) - .addClass(evt.data.attr) - .addClass(evt.data.value); - } - } - } - return false; -}; diff --git a/vendor/assets/javascripts/wymeditor/plugins/resizable/jquery.wymeditor.resizable.js b/vendor/assets/javascripts/wymeditor/plugins/resizable/jquery.wymeditor.resizable.js deleted file mode 100644 index cb6032d..0000000 --- a/vendor/assets/javascripts/wymeditor/plugins/resizable/jquery.wymeditor.resizable.js +++ /dev/null @@ -1,77 +0,0 @@ -/* - * WYMeditor : what you see is What You Mean web-based editor - * Copyright (c) 2005 - 2009 Jean-Francois Hovinne, http://www.wymeditor.org/ - * Dual licensed under the MIT (MIT-license.txt) - * and GPL (GPL-license.txt) licenses. - * - * For further information visit: - * http://www.wymeditor.org/ - * - * File Name: - * jquery.wymeditor.resizable.js - * resize plugin for WYMeditor - * - * File Authors: - * Peter Eschler (peschler _at_ gmail.com) - * Jean-Francois Hovinne - http://www.hovinne.com/ - * - * Version: - * 0.4 - * - * Changelog: - * - * 0.4 - * - Removed UI and UI.resizable scripts loading - see #167 (jfh). - * - * 0.3 - * - Added 'iframeOriginalSize' and removed 'ui.instance' calls (jfh). - * - * 0.2 - * - Added full support for all jQueryUI resizable plugin options. - * - Refactored and documented code. - * 0.1 - * - Initial release. - */ - -/** - * The resizable plugin makes the wymeditor box vertically resizable. - * It it based on the ui.resizable.js plugin of the jQuery UI library. - * - * The WYMeditor resizable plugin supports all parameters of the jQueryUI - * resizable plugin. The parameters are passed like this: - * - * wym.resizable({ handles: "s,e", - * maxHeight: 600 }); - * - * DEPENDENCIES: jQuery UI, jQuery UI resizable - * - * @param options options for the plugin - */ -WYMeditor.editor.prototype.resizable = function(options) { - - var wym = this; - var $iframe = jQuery(wym._box).find('iframe'); - var $iframe_div = jQuery(wym._box).find('.wym_iframe'); - var iframeOriginalSize = {}; - - // Define some default options - var default_options = { - resize: function() { - $iframe_div.height($iframe.height()); - }, - alsoResize: $iframe, - handles: "s,e,se", - minHeight: 250 - }; - - // Merge given options with default options. Given options override - // default ones. - var final_options = jQuery.extend(default_options, options); - - if (jQuery.isFunction(jQuery.fn.resizable)) { - jQuery(wym._box).resizable(final_options); - } else { - WYMeditor.console.error('Oops, jQuery UI.resizable unavailable.'); - } - -}; diff --git a/vendor/assets/javascripts/wymeditor/plugins/resizable/readme.txt b/vendor/assets/javascripts/wymeditor/plugins/resizable/readme.txt deleted file mode 100644 index 2a0444e..0000000 --- a/vendor/assets/javascripts/wymeditor/plugins/resizable/readme.txt +++ /dev/null @@ -1,124 +0,0 @@ - - -resizable plugin for WYMeditor -############################## - -The ``resizable`` plugin for WYMeditor_ enables vertical resizing of the -editor area. The plugin is based on the jQuery UI library. - -Requirements -============ -The following packages are required for using the WYMeditor ``resizable`` -plugin: - -* jQuery (tested with jQuery ``jquery-1.2.4a.js`` from ``jquery.ui`` package) -* WYMeditor SVN trunk (Revision: 482) -* jQuery-UI (tested with ``jquery.ui-1.5b2``) - -It should be possible to use this plugin with ``WYMeditor-0.4`` but I have not -tried. - -Download -======== -You can download the WYMeditor ``resizable`` plugin here: - -* wymeditor-resizable-plugin-0.2.tgz_ -* wymeditor-resizable-plugin-0.1.tgz_ - -See the Changelog_ for more infos about the releases. - -.. _wymeditor-resizable-plugin-0.2.tgz: http://pyjax.net/download/wymeditor-resizable-plugin-0.2.tgz -.. _wymeditor-resizable-plugin-0.1.tgz: http://pyjax.net/download/wymeditor-resizable-plugin-0.1.tgz - -Installation -============ -Just extract the downloaded archive into your WYMeditor's ``plugin`` -directory. - -Usage -===== -For general instructions on WYMeditor plugins please refer to the `WYMeditor -plugin page`_. - -To use the ``resizable`` plugin simply include the plugin's JavaScript file in -your code. You **do not** need to include the jQuery UI files - this is done -automatically by the plugin (see `Internals`_):: - - - -Make sure to adjust the ``src`` attribute to your needs, then initialize the -plugin in WYMeditor's ``postInit`` function:: - - wymeditor({postInit: function(wym) { - wym.hovertools(); // other plugins... - wym.resizable({handles: "s,e", - maxHeight: 600}); - } - }) - -The ``resizable`` plugin takes exactly one parameter, which is an object literal -containing the options of the plugin. The WYMeditor ``resizable`` plugin -supports all options of the jQuery UI ``resizable`` plugin. These are the -default values used by the plugin:: - - handles: "s,e,se", - minHeight: 250, - maxHeight: 600 - -See the `jQuery UI resizable plugin docs`_ for a list of all options. - -That's it! You are now able to resize the WYMeditor vertically, horizontally or -both, depending on your options. - -.. _jQuery UI resizable plugin docs: http://docs.jquery.com/UI/Resizables - -Internals -========= -The plugin takes care of loading the necessary jQuery UI files (``base`` and -``resizable``) from the same path the jQuery library was loaded. Here's how -it's done:: - - // Get the jQuery path from the editor, stripping away the jQuery file. - // see http://www.oreilly.com/catalog/regex/chapter/ch04.html - // The match result array contains the path and the filename. - var jQueryPath = wym.computeJqueryPath().match(/^(.*)\/(.*)$/)[1]; - - // Make an array of the external JavaScript files required by the plugin. - var jQueryPlugins = [jQueryPath + '/ui.base.js', - jQueryPath + '/ui.resizable.js']; - - // First get the jQuery UI base file - $.getScript(jQueryPlugins[0]); - - // Get the jQuery UI resizeable plugin and then init the wymeditor resizable - // plugin. It is import to do the initialisation after loading the - // necessary jQuery UI files has finished, otherwise the "resizable" method - // would not be available. - $.getScript(jQueryPlugins[1], function() { - jQuery(wym._box).resizable(final_options); - }); - -An alternative approach would be to use an AJAX queue when getting the script -files to ensure that all jQuery files are loaded before the initialisation code -of the plugin is executed. There is an `jQuery AJAX queue plugin`_ which does -that. - -.. _jQuery AJAX queue plugin: http://plugins.jquery.com/project/ajaxqueue - -Changelog -========= - -0.2 ---- -- Added full support for all jQuery UI resizable plugin options. -- Refactored and documented code. -- Now contains a packed version (775 bytes). - -0.1 ---- -- Initial release. - -.. _WYMeditor: http://www.wymeditor.org/ -.. _WYMeditor plugin page: http://trac.wymeditor.org/trac/wiki/0.4/Plugins diff --git a/vendor/assets/javascripts/wymeditor/plugins/table/jquery.wymeditor.table.js b/vendor/assets/javascripts/wymeditor/plugins/table/jquery.wymeditor.table.js deleted file mode 100644 index aacc528..0000000 --- a/vendor/assets/javascripts/wymeditor/plugins/table/jquery.wymeditor.table.js +++ /dev/null @@ -1,676 +0,0 @@ -/** - * Copyright (c) 2011 PolicyStat LLC. - * MIT licensed (MIT-license.txt) - * - * @author Wes Winham (winhamwr@gmail.com) - */ - -// Fugue icons by Yusuke Kamiyamane http://p.yusukekamiyamane.com/ -// and licensed under Creative Commons Attribution - -/** - * A Table editing plugin that gives the user ability to add and remove - * rows and columns as well as merge rows and columns. - * - * @param options A configuration object. - * @param wym The WYMeditor instance to which the TableEditor should attach. - * @class - */ -function TableEditor(options, wym) { - options = jQuery.extend({ - sMergeRowButtonHtml: '' + - '
  • ' + - '' + - 'Merge Table Row' + - '' + - '
  • ', - - sMergeRowButtonSelector: "li.wym_tools_merge_row a", - - sAddRowButtonHtml: '' + - "
  • " + - "" + - "Add Table Row" + - "" + - "
  • ", - sAddRowButtonSelector: "li.wym_tools_add_row a", - - sRemoveRowButtonHtml: '' + - "
  • " + - "" + - "Remove Table Row" + - "" + - "
  • ", - sRemoveRowButtonSelector: "li.wym_tools_remove_row a", - - sAddColumnButtonHtml: '' + - "
  • " + - "" + - "Add Table Column" + - "" + - "
  • ", - sAddColumnButtonSelector: "li.wym_tools_add_column a", - - sRemoveColumnButtonHtml: '' + - "
  • " + - "" + - "Remove Table Column" + - "" + - "
  • ", - sRemoveColumnButtonSelector: "li.wym_tools_remove_column a", - - enableCellTabbing: true - - }, options); - - this._options = options; - this._wym = wym; - - this.init(); -} - -/** - * Construct and return a table objects using the given options object. - * - * @param options The configuration object. - */ -WYMeditor.editor.prototype.table = function(options) { - var tableEditor = new TableEditor(options, this); - this.tableEditor = tableEditor; - - return tableEditor; -}; - -/** - * Initialize the TableEditor object by adding appropriate toolbar buttons and - * binding any required event listeners. - */ -TableEditor.prototype.init = function() { - var wym = this._wym; - var tableEditor = this; - - // Add the tool panel buttons - var tools = $(wym._box).find( - wym._options.toolsSelector + wym._options.toolsListSelector); - - tools.append(tableEditor._options.sMergeRowButtonHtml); - tools.append(tableEditor._options.sAddRowButtonHtml); - tools.append(tableEditor._options.sRemoveRowButtonHtml); - tools.append(tableEditor._options.sAddColumnButtonHtml); - tools.append(tableEditor._options.sRemoveColumnButtonHtml); - - tableEditor.bindEvents(); - rangy.init(); -}; - -/** - * Bind all required event listeners, including button listeners and support for - * tabbing through table cells if enableCellTabbing is true. - */ -TableEditor.prototype.bindEvents = function() { - var wym = this._wym; - var tableEditor = this; - - // Handle tool button click - $(wym._box).find(tableEditor._options.sMergeRowButtonSelector).click(function() { - var sel = rangy.getIframeSelection(wym._iframe); - tableEditor.mergeRow(sel); - return false; - }); - $(wym._box).find(tableEditor._options.sAddRowButtonSelector).click(function() { - return tableEditor.addRow(wym.selected()); - }); - $(wym._box).find(tableEditor._options.sRemoveRowButtonSelector).click(function() { - return tableEditor.removeRow(wym.selected()); - }); - $(wym._box).find(tableEditor._options.sAddColumnButtonSelector).click(function() { - return tableEditor.addColumn(wym.selected()); - }); - $(wym._box).find(tableEditor._options.sRemoveColumnButtonSelector).click(function() { - return tableEditor.removeColumn(wym.selected()); - }); - - // Handle tab clicks - if(tableEditor._options.enableCellTabbing) { - $(wym._doc).bind('keydown', tableEditor.keyDown); - } -}; - -/** - * Get the number of columns in a given tr element, accounting for colspan and - * rowspan. This function assumes that the table structure is valid, and will - * return incorrect results for uneven tables. - * - * @param tr The node whose number of columns we need to count. - * - * @returns {Number} The number of columns in the given tr, accounting for - * colspan and rowspan. - */ -TableEditor.prototype.getNumColumns = function(tr) { - var wym = this._wym; - var numColumns = 0; - - var table = wym.findUp(tr, 'table'); - var firstTr = $(table).find('tr:eq(0)'); - - // Count the tds and ths in the FIRST ROW of this table, accounting for - // colspan. We count the first td because it won't have any rowspan's before - // it to complicate things - $(firstTr).children('td,th').each(function(index, elmnt) { - numColumns += TableEditor.GET_COLSPAN_PROP(elmnt); - }); - - return numColumns; -}; - -/** - TableEditor.GET_COLSPAN_PROP - ============================ - - Get the integer value of the inferred colspan property on the given cell in - a cross-browser compatible way that's also compatible across jquery versions. - - jquery 1.6 changed the way .attr works, which affected certain browsers - differently with regard to colspan and rowspan for cells that didn't explcility - have that attribue set. -*/ -TableEditor.GET_COLSPAN_PROP = function(cell) { - var colspan = $(cell).attr('colspan'); - if (typeof(colspan) === 'undefined') { - colspan = 1; - } - return parseInt(colspan, 10); -}; - -/** - TableEditor.GET_ROWSPAN_PROP - ============================ - - Get the integer value of the inferred rowspan property on the given cell in - a cross-browser compatible way that's also compatible across jquery versions. - - See GET_COLSPAN_PROP for details -*/ -TableEditor.GET_ROWSPAN_PROP = function(cell) { - var rowspan = $(cell).attr('rowspan'); - if (typeof(rowspan) === 'undefined') { - rowspan = 1; - } - return parseInt(rowspan, 10); -}; -/** - * Get the X grid index of the given td or th table cell (0-indexed). This takes - * in to account all colspans and rowspans. - * - * @param cell The td or th node whose X index we're returning. - */ -TableEditor.prototype.getCellXIndex = function(cell) { - var tableEditor = this; - var parentTr = $(cell).parent('tr')[0]; - - var baseRowColumns = this.getNumColumns(parentTr); - - // Figure out how many explicit cells are missing which is how many rowspans - // we're affected by - var rowColCount = 0; - $(parentTr).children('td,th').each(function(index, elmnt) { - rowColCount += TableEditor.GET_COLSPAN_PROP(elmnt); - }); - - var missingCells = baseRowColumns - rowColCount; - var rowspanIndexes = []; - var checkTr = parentTr; - var rowOffset = 1; - - // If this cell is affected by a rowspan from farther up the table, - // we need to take in to account any possible colspan attributes on that - // cell. Store the real X index of the cells to the left of our cell to use - // in the colspan calculation. - while (missingCells > 0) { - checkTr = $(checkTr).prev('tr'); - rowOffset += 1; - var trChildren = $(checkTr).children('td,th'); - for (var i = 0; i < trChildren.length; i++) { - var elmnt = trChildren[i]; - if (TableEditor.GET_ROWSPAN_PROP(elmnt) >= rowOffset) { - // Actually affects our source row - missingCells -= 1; - var colspan = TableEditor.GET_COLSPAN_PROP(elmnt); - rowspanIndexes[tableEditor.getCellXIndex(elmnt)] = colspan; - } - } - } - - var indexCounter = 0; - var cellIndex = null; - // Taking in to account the real X indexes of all of the columns to the left - // of this cell, determine the real X index. - $(parentTr).children('td,th').each(function(index, elmnt) { - if (cellIndex !== null) { - // We've already iterated to the cell we're checking - return; - } - // Account for an inferred colspan created by a rowspan from above - while (typeof(rowspanIndexes[indexCounter]) != 'undefined') { - indexCounter += parseInt(rowspanIndexes[indexCounter], 10); - } - if (elmnt == cell) { - // We're at our cell, no need to keep moving to the right. - // Signal this by setting the cellIndex - cellIndex = indexCounter; - return; - } - // Account for an explicit colspan on this cell - indexCounter += TableEditor.GET_COLSPAN_PROP(elmnt); - }); - - if (cellIndex === null) { - // Somehow, we never found the cell when iterating over its row. - throw "Cell index not found"; - } - return cellIndex; -}; - -/** - * Get the number of columns represented by the given array of contiguous cell - * (td/th) nodes. - * Accounts for colspan and rowspan attributes. - * - * @param cells An array of td/th nodes whose total column span we're checking. - * - * @return {Number} The number of columns represented by the "cells" - */ -TableEditor.prototype.getTotalColumns = function(cells) { - var tableEditor = this; - - var rootTr = this.getCommonParentTr(cells); - if (rootTr === null) { - // Non-contiguous columns - throw "getTotalColumns only allowed for contiguous cells"; - } - - var baseRowColumns = this.getNumColumns(rootTr); - - // Count the number of simple columns, not accounting for rowspans - var colspanCount = 0; - $(cells).each(function(index, elmnt) { - colspanCount += TableEditor.GET_COLSPAN_PROP(elmnt); - }); - - // Determine if we're affected by rowspans. If the number of simple columns - // in the row equals the number of columns in the first row, we don't have - // any rowspans - var rowColCount = 0; - $(rootTr).children('td,th').each(function(index, elmnt) { - rowColCount += TableEditor.GET_COLSPAN_PROP(elmnt); - }); - - if (rowColCount == baseRowColumns) { - // Easy case. No rowspans to deal with - return colspanCount; - } else { - if (cells.length == 1) { - // Easy. Just the colspan - return TableEditor.GET_COLSPAN_PROP(cells[0]); - } else { - var lastCell = $(cells).eq(cells.length - 1)[0]; - var firstCell = $(cells).eq(0)[0]; - // On jQuery 1.4 upgrade, $(cells).eq(-1) - return 1 + tableEditor.getCellXIndex(lastCell) - - tableEditor.getCellXIndex(firstCell); - } - } -}; - -/** - * Merge the table cells in the given selection using a colspan. - * - * @param sel A rangy selection object across which to row merge. - * - * @return {Boolean} true if changes are made, false otherwise - */ -TableEditor.prototype.mergeRow = function(sel) { - var wym = this._wym; - var tableEditor = this; - - // Get all of the affected nodes in the range - var nodes = []; - var range = null; - for (var i = 0; i < sel.rangeCount; i++) { - range = sel.getRangeAt(i); - nodes = nodes.concat(range.getNodes(false)); - } - - // Just use the td and th nodes - var cells = $(nodes).filter('td,th'); - if (cells.length === 0) { - return false; - } - - // If the selection is across multiple tables, don't merge - var rootTr = tableEditor.getCommonParentTr(cells); - if (rootTr === null) { - return false; - } - - var mergeCell = cells[0]; - // If any of the cells have a rowspan, create the inferred cells - $(cells).each(function(i, elmnt) { - var $elmnt = $(elmnt); - var rowspanProp = TableEditor.GET_ROWSPAN_PROP(elmnt); - if (rowspanProp <= 1) { - // We don't care about cells without a rowspan - return; - } - - // This cell has an actual rowspan, we need to account for it - // Figure out the x index for this cell in the table grid - var prevCells = $elmnt.prevAll('td,th'); - var index = tableEditor.getCellXIndex(elmnt); - - // Create the previously-inferred cell in the appropriate index - // with one less rowspan - var newRowspan = rowspanProp - 1; - var newTd; - if (newRowspan == 1) { - newTd = '' + $elmnt.html() + ''; - } else { - newTd = '' + - '' + - $elmnt.html() + - ''; - } - if (index === 0) { - $elmnt.parent('tr') - .next('tr') - .prepend(newTd); - } else { - // TODO: account for colspan/rowspan with insertion - // Account for colspan/rowspan by walking from right to left looking - // for the cell closest to the desired index to APPEND to - var insertionIndex = index - 1; - var insertionCells = $elmnt.parent('tr').next('tr') - .find('td,th'); - var cellInserted = false; - for (i = insertionCells.length - 1; i >= 0; i--) { - var xIndex = tableEditor.getCellXIndex(insertionCells[i]); - if (xIndex <= insertionIndex) { - $(insertionCells[i]).append(newTd); - cellInserted = true; - break; - } - } - if (! cellInserted) { - // Bail out now before we clear HTML and break things - throw "Cell rowspan invalid"; - } - } - - // Clear the cell's html, since we just moved it down - $elmnt.html(''); - }); - - // Remove any rowspan from the mergecell now that we've shifted rowspans - // down - // ie fails when we try to remove a rowspan for some reason - try { - $(mergeCell).removeAttr('rowspan'); - } catch(err) { - $(mergeCell).attr('rowspan', 1); - } - - // Build the content of the new combined cell from all of the included cells - var newContent = ''; - $(cells).each(function(index, elmnt) { - newContent += $(elmnt).html(); - }); - - // Add a colspan to the farthest-left cell - var combinedColspan = this.getTotalColumns(cells); - if ($.browser.msie) { - // jQuery.attr doesn't work for colspan in ie - mergeCell.colSpan = combinedColspan; - } else { - $(mergeCell).attr('colspan', combinedColspan); - } - - // Delete the rest of the cells - $(cells).each(function(index, elmnt) { - if (index !== 0) { - $(elmnt).remove(); - } - }); - - // Change the content in our newly-merged cell - $(mergeCell).html(newContent); - - tableEditor.selectElement(mergeCell); - - return true; -}; - -/** - * Add a row to the given elmnt (representing a or a child of a ). - * - * @param The node which will have a row appended after its parent row. - */ -TableEditor.prototype.addRow = function(elmnt) { - var wym = this._wym; - var tr = wym.findUp(elmnt, 'tr'); - if (tr === null) { - return false; - } - - var numColumns = this.getNumColumns(tr); - - var td_html = ''; - for (i=0; i'+td_html+''); - - return false; -}; - -/** - * Remove the given table if it doesn't have any rows/columns. - * - * @param table The table to delete if it is empty. - */ -TableEditor.prototype.removeEmptyTable = function(table) { - var cells = $(table).find('td,th'); - if (cells.length === 0) { - $(table).remove(); - } -}; - -/** - * Remove the row for the given element (representing a or a child - * of a ). - * - * @param elmnt The node whose parent tr will be removed. - */ -TableEditor.prototype.removeRow = function(elmnt) { - var wym = this._wym; - var tr = wym.findUp(elmnt, 'tr'); - if (tr === null) { - return false; - } - var table = wym.findUp(elmnt, 'table'); - $(tr).remove(); - this.removeEmptyTable(table); - - return false; -}; - -/** - * Add a column to the given elmnt (representing a or a child of a ). - * - * @param elmnt The node which will have a column appended afterward. - */ -TableEditor.prototype.addColumn = function(elmnt) { - var wym = this._wym; - var td = wym.findUp(elmnt, ['td', 'th']); - if (td === null) { - return false; - } - var prevTds = $(td).prevAll(); - var tdIndex = prevTds.length; - - var newTd = ' '; - var newTh = ' '; - var tr = wym.findUp(td, 'tr'); - $(tr).siblings('tr').andSelf().each(function(index, element) { - var insertionElement = newTd; - if ($(element).find('th').length > 0) { - // The row has a TH, so insert a th - insertionElement = newTh; - } - - $(element).find('td,th').eq(tdIndex).after(insertionElement); - }); - - return false; -}; - -/** - * Remove the column to the right of the given elmnt (representing a or a - * child of a ). - */ -TableEditor.prototype.removeColumn = function(elmnt) { - var wym = this._wym; - var td = wym.findUp(elmnt, ['td', 'th']); - if (td === null) { - return false; - } - var table = wym.findUp(elmnt, 'table'); - var prevTds = $(td).prevAll(); - var tdIndex = prevTds.length; - - var tr = wym.findUp(td, 'tr'); - $(tr).siblings('tr').each(function(index, element) { - $(element).find('td,th').eq(tdIndex).remove(); - }); - $(td).remove(); - this.removeEmptyTable(table); - - return false; -}; - -/** - * keyDown event handler used for consistent tab key cell movement. - */ -TableEditor.prototype.keyDown = function(evt) { - //'this' is the doc - var wym = WYMeditor.INSTANCES[this.title]; - var tableEditor = wym.tableEditor; - - if (evt.keyCode == WYMeditor.KEY.TAB) { - return tableEditor.selectNextCell(wym.selected()); - } - - return null; -}; - -/** - * Move the focus to the next cell. - */ -TableEditor.prototype.selectNextCell = function(elmnt) { - var wym = this._wym; - var tableEditor = this; - - var cell = wym.findUp(elmnt, ['td', 'th']); - if (cell === null) { - return null; - } - - // Try moving to the next cell to the right - var nextCells = $(cell).next('td,th'); - if (nextCells.length > 0) { - tableEditor.selectElement(nextCells[0]); - return false; - } - - // There was no cell to the right, use the first cell in the next row - var tr = wym.findUp(cell, 'tr'); - var nextRows = $(tr).next('tr'); - if (nextRows.length !== 0) { - nextCells = $(nextRows).children('td,th'); - if (nextCells.length > 0) { - tableEditor.selectElement(nextCells[0]); - return false; - } - } - - // There is no next row. Do a normal tab - return null; -}; - -/** - * Select the given element using rangy selectors. - */ -TableEditor.prototype.selectElement = function(elmnt) { - var sel = rangy.getIframeSelection(this._wym._iframe); - - var range = rangy.createRange(this._wym._doc); - range.setStart(elmnt, 0); - range.setEnd(elmnt, 0); - range.collapse(false); - - try { - sel.setSingleRange(range); - } catch(err) { - // ie8 can raise an "unkown runtime error" trying to empty the range - } - // IE selection hack - if ($.browser.msie) { - this._wym.saveCaret(); - } -}; - -/** - * Get the common parent tr for the given table cell nodes. If the closest parent - * tr for each cell isn't the same, returns null. - */ -TableEditor.prototype.getCommonParentTr = function(cells) { - cells = $(cells).filter('td,th'); - if (cells.length === 0) { - return null; - } - var firstCell = cells[0]; - - var parentTrList = $(firstCell).parent('tr'); - if (parentTrList.length === 0) { - return null; - } - var rootTr = parentTrList[0]; - - // Ensure that all of the cells have the same parent tr - $(cells).each(function(index, elmnt) { - var parentTrList = $(elmnt).parent('tr'); - if (parentTrList.length === 0 || parentTrList[0] != rootTr) { - return null; - } - }); - - return rootTr; -}; diff --git a/vendor/assets/javascripts/wymeditor/plugins/table/table_delete_column.png b/vendor/assets/javascripts/wymeditor/plugins/table/table_delete_column.png deleted file mode 100644 index 9022d686f6b7cb7722159380fae4c7fc4e4b8f24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 744 zcmVP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igk( z6DTiO@l8hn00L-9L_t(Y$L*B8Pm@s;ho85lR)X;Znl?0~K};an$N)qf+*;jq!ovBDdhNXs|U^4@c=L(8izC3$gS;Vd`# z-E+?`&p9U-j^n7qsupey4c!2m|D#s+#pB1XEvvF*U3He$I{I>W_{m|b_YV%I#^j+vHCKS!(a0e}10nb@&zTHo8X6E0^zJSq!a_F7uay;-z;la~h?Bmkf$Uln7rk8Gi5VxNGXYMULZ>iYK6pZF4dhL@8AwP>O|Ymi3Jdm!McE_&ph{=JUZoAi(pE zt+EmXq5wGM88{+@BN4)p2mpaVfYp3H=*eJvbJK3??jEVuZ^z?rI&6DH$KyRKwmo%s zVBpc%Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igk( z6DbVijSX}F00JvXL_t(Y$L*EROH@%5$3OQukHJlZ4(e!_KNe~Tk%D2gQ=^hLk^g`T zYuBc=!mL`l30#HE+EuMmS3=1M3ep%7j!+CvAd@nVWt|Qi(KmgWSM^pjBP`hDvLm6r}h#17eYzhWi6_K*eZ-S^|t#yI{ zc%HFG0COp&EmTCe_E8a3gu!Y>ehNm)I#{h(y@vI?U<^FZJ7Pfj<>>=n-Kz1=6YJ~T z?dG}=x3~Rzv__+BW-`7VjYP1j+*w>)65wMH23CZY zr~M2~PV%Fpm(54R6+0*m++JCEqp%D-KOaDqy+VPNu`%u?5_~Qc81Cz<+^5~$z3<}j z05vF;j8!F@%h5kQ&05}&&E<&C&sUzZt*zxynL)53A1-V#br7O0cfi9$!q53>1!#&! zc|1D$vLl)NL^63Io^u8R$Exyvx0>cAm*1rljWsni)z)$&5+Rq*(_B}_&H8#;8XEYu zyNfN)!TqmYUFWChuvn}*ZqvDxG7yGu>9jw&0AEt66Sk;wSS(frYSW!;Htf1CZ#(iw zo-oi@G5@aXvXjk*0|D&s?WNm#dR||2**T7rHpZO4u8#|M>HTla)hGC$$sfDGQopJl R^Q!;=002ovPDHLkV1iIXGkyR7 diff --git a/vendor/assets/javascripts/wymeditor/plugins/table/table_insert_column.png b/vendor/assets/javascripts/wymeditor/plugins/table/table_insert_column.png deleted file mode 100644 index 49226ec5ec15dd0e11668b22c180d3151f5b5aac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 720 zcmV;>0x$iEP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igk( z6Db`2Ivo%I00K}+L_t(Y$L*BQPZL2HhM!$%N<#ul6B?l@1QH1nqZSXw8$mQCnrMh8 z{{ZiXD}kH-6&&>D$*329#28ORA`v~9h;5KmDw1tWOXkBpCD(h;0+<-I(5Vtr zr@G4F9|YI9C=te@os300dAqcPHZerRZtRGB1mi(iOe6?*bf82isv=5+L^{pd#zuL~ zAp~|k0;P480N`|gKRsPtC=s^w7D|LzcQ+SCM#=$NH%=fTwx8hB$_kzB?TF`5PzA*E zNT$>L%w(zr2L;p;cwY60_6UY!F?zyb#Pi7OJmPu8A`#9H5C0DEyyh=?kKps_D(#^V z;&~KRu}YB1<;riTNdntXa55UDHymcSRAO6ivs)_B7m09gXlOq{V|TFQx-EW!FR2u5 z!62KC0}mYllIb*?`FxdN$8}p83dlN6Fc1hZH?&o8f1gSf$01I0000Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igk( z6DcjPrOG-^`pjaBTnD)G)A=&!d#O4kV6{uli_t`RVUKVEBZHAR@`fD=YU8n|&#tzdelY zBQRP6C;_g%b_p@YxPDOlDt8K_welp;Jp!K*0TheVinWiz;_IVRH4uH~qg7vbH4cN$+ABZuCF)V}y^VOhC&lkdimT|P>cq?#v1bqecZeHnd zXEx%V+1%RV(#(t-Zxo9dN#Qt-w}S7NKXLM9>a!N%Mzjk}Au|zRr&e?Okx3-ju2$VR z5sjinMpN)}qAm4{<#}xk58huJd4dY@XQL_DZMAk7YZbHzyR8=IuUzm<{%)g$78#A8 zX<6wLc5GgY6q=UB=IV=)6lf8gZr8g+zFJs~zs=kPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igk( z6Dk5P7;~@y00J#ZL_t(Y$L*CdPg7A8$A7QTzDFXWVN!yzkI)h!21r<3TbOjy?_hK= zG0qT}oSd2b0=h9Fn}dUd2xv)D)6@h=Szd^(l$PFmjzddAWrQE*gA_XyI;6|2{=#yFt{#+Wk%vUA9*dp7}C&E=R%Bmnr7 z$?#xw6o8K#8;IV)7}Ghy-46kql?vr@iRn_7QmMqj!6C+EaGV&i*fl(F9nb5-^9ER2 z)XoX42mtqA4k9}NFOtImtmpHL4-GYFvRS4^MgVyDY#%Gq8G$h-Vw)w}e6vltTw?i; z1Yes3y;#)_4eE8rs`6u|pS0hP>;ya?Zk+mCp}<%?4#1aOj)~@dtZr>#wGUIT|J^08 z0mtUJox(ty=ABC-}a*i!?7jQz*1fy`IaRA*fZWU7-g1LEuKCQQjth zH5Ip`*%ysQ*$)CY)Zk~axaUt!zP`+`lS*YTbX)^HK<`E7Az^?raCr3>{J-KiBXd$k TjQQUG00000NkvXXu0mjfsNF6C diff --git a/vendor/assets/javascripts/wymeditor/plugins/tidy/README b/vendor/assets/javascripts/wymeditor/plugins/tidy/README deleted file mode 100644 index acc7ffd..0000000 --- a/vendor/assets/javascripts/wymeditor/plugins/tidy/README +++ /dev/null @@ -1,19 +0,0 @@ -WYMeditor : what you see is What You Mean web-based editor -Copyright (c) 2005 - 2009 Jean-Francois Hovinne, http://www.wymeditor.org/ -Dual licensed under the MIT (MIT-license.txt) -and GPL (GPL-license.txt) licenses. - -For further information visit: - http://www.wymeditor.org/ - -File Name: - README - HTML Tidy plugin for WYMeditor - -File Authors: - Jean-François Hovinne (jf.hovinne a-t wymeditor dotorg) - -Credits: - 'HTML Tidy' by Dave Ragget - http://tidy.sourceforge.net/ - Icon 'wand' by Mark James - http://famfamfam.com/ - -WYMeditor documentation is available online at http://www.wymeditor.org/ diff --git a/vendor/assets/javascripts/wymeditor/plugins/tidy/jquery.wymeditor.tidy.js b/vendor/assets/javascripts/wymeditor/plugins/tidy/jquery.wymeditor.tidy.js deleted file mode 100644 index 65c3eaf..0000000 --- a/vendor/assets/javascripts/wymeditor/plugins/tidy/jquery.wymeditor.tidy.js +++ /dev/null @@ -1,78 +0,0 @@ -/* - * WYMeditor : what you see is What You Mean web-based editor - * Copyright (c) 2005 - 2009 Jean-Francois Hovinne, http://www.wymeditor.org/ - * Dual licensed under the MIT (MIT-license.txt) - * and GPL (GPL-license.txt) licenses. - * - * For further information visit: - * http://www.wymeditor.org/ - * - * File Name: - * jquery.wymeditor.tidy.js - * HTML Tidy plugin for WYMeditor - * - * File Authors: - * Jean-Francois Hovinne (jf.hovinne a-t wymeditor dotorg) - */ - -//WymTidy constructor -function WymTidy(options, wym) { - var wand_url = wym._options.basePath + "plugins/tidy/wand.png"; - options = jQuery.extend({ - sUrl: wym._options.basePath + "plugins/tidy/tidy.php", - sButtonHtml: "" + - "
  • " + - "" + - "Clean up HTML" + - "" + - "
  • ", - - sButtonSelector: "li.wym_tools_tidy a" - - }, options); - - this._options = options; - this._wym = wym; -} - -//Extend WYMeditor -WYMeditor.editor.prototype.tidy = function(options) { - var tidy = new WymTidy(options, this); - return tidy; -}; - - -//WymTidy initialization -WymTidy.prototype.init = function() { - var tidy = this; - - jQuery(this._wym._box).find( - this._wym._options.toolsSelector + this._wym._options.toolsListSelector) - .append(this._options.sButtonHtml); - - //handle click event - jQuery(this._wym._box).find(this._options.sButtonSelector).click(function() { - tidy.cleanup(); - return(false); - }); -}; - -//WymTidy cleanup -WymTidy.prototype.cleanup = function() { - var wym = this._wym; - var html = "" + wym.xhtml() + ""; - - jQuery.post(this._options.sUrl, { html: html}, function(data) { - if (data.length > 0 && data != '0') { - if (data.indexOf(" tags, onclick, onblur, onload, onmouseover... attributes - if you *really* need this functionality. Or, even better, you could allow only the tags and - attributes that you explicitly allow (future versions of WYMeditor might provide this - functionality by default - please contribute). - - Be warned that providing authentication is NOT enough to guard you agains the attack. When - someone is authenticated in your page and visits www.badsite.com, the IFRAME has the proper - authentication so nothing has changed. - -*/ - -if (get_magic_quotes_gpc()) $html = stripslashes($_REQUEST['html']); -else $html = $_REQUEST['html']; - -if(strlen($html) > 0) { - - // Specify configuration - $config = array( - 'bare' => true, - 'clean' => true, - 'doctype' => 'strict', - 'drop-empty-paras' => true, - 'drop-font-tags' => true, - 'drop-proprietary-attributes' => true, - 'enclose-block-text' => true, - 'indent' => false, - 'join-classes' => true, - 'join-styles' => true, - 'logical-emphasis' => true, - 'output-xhtml' => true, - 'show-body-only' => true, - 'wrap' => 0); - - // Tidy - $tidy = new tidy; - $tidy->parseString($html, $config, 'utf8'); - $tidy->cleanRepair(); - - // Output - echo $tidy; -} else { - -echo ('0'); -} -?> diff --git a/vendor/assets/javascripts/wymeditor/plugins/tidy/wand.png b/vendor/assets/javascripts/wymeditor/plugins/tidy/wand.png deleted file mode 100644 index bb55eeab4f028a986023fb0b027b011340db5075..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 715 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 G67^roH{M+U diff --git a/vendor/assets/javascripts/wymeditor/skins/compact/skin.css b/vendor/assets/javascripts/wymeditor/skins/compact/skin.css deleted file mode 100644 index 4a6a0c6..0000000 --- a/vendor/assets/javascripts/wymeditor/skins/compact/skin.css +++ /dev/null @@ -1,134 +0,0 @@ -/* - * WYMeditor : what you see is What You Mean web-based editor - * Copyright (c) 2005 - 2009 Jean-Francois Hovinne, http://www.wymeditor.org/ - * Dual licensed under the MIT (MIT-license.txt) - * and GPL (GPL-license.txt) licenses. - * - * For further information visit: - * http://www.wymeditor.org/ - * - * File Name: - * screen.css - * main stylesheet for the WYMeditor skin - * See the documentation for more info. - * - * File Authors: - * Daniel Reszka (d.reszka a-t wymeditor dotorg) - * Jean-Francois Hovinne (jf.hovinne a-t wymeditor dotorg) -*/ - -/*TRYING TO RESET STYLES THAT MAY INTERFERE WITH WYMEDITOR*/ - .wym_skin_compact p, .wym_skin_compact h2, .wym_skin_compact h3, - .wym_skin_compact ul, .wym_skin_compact li { background: transparent url(); margin: 0; padding: 0; border-width:0; list-style: none; } - - -/*HIDDEN BY DEFAULT*/ - .wym_skin_compact .wym_area_left { display: none; } - .wym_skin_compact .wym_area_right { display: none; } - - -/*TYPO*/ - .wym_skin_compact { font-size: 10px; font-family: Verdana, Arial, sans-serif; } - .wym_skin_compact h2 { font-size: 110%; /* = 11px */} - .wym_skin_compact h3 { font-size: 100%; /* = 10px */} - .wym_skin_compact li { font-size: 100%; /* = 10px */} - - -/*WYM_BOX*/ - .wym_skin_compact { border: 1px solid gray; padding: 5px} - - /*auto-clear the wym_box*/ - .wym_skin_compact:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } - * html .wym_skin_compact { height: 1%;} - - -/*WYM_HTML*/ - .wym_skin_compact .wym_html { width: 98%;} - .wym_skin_compact .wym_html textarea { font-size: 120%; width: 100%; height: 200px; border: 1px solid gray; background: white; } - - -/*WYM_IFRAME*/ - .wym_skin_compact .wym_iframe { width: 98%;} - .wym_skin_compact .wym_iframe iframe { width: 100%; height: 200px; border: 1px solid gray; background: white } - - -/*AREAS*/ - .wym_skin_compact .wym_area_left { width: 100px; float: left;} - .wym_skin_compact .wym_area_right { width: 150px; float: right;} - .wym_skin_compact .wym_area_bottom { height: 1%; clear: both;} - * html .wym_skin_compact .wym_area_main { height: 1%;} - * html .wym_skin_compact .wym_area_top { height: 1%;} - *+html .wym_skin_compact .wym_area_top { height: 1%;} - -/*SECTIONS SYSTEM*/ - - /*common defaults for all sections*/ - .wym_skin_compact .wym_section { margin-bottom: 5px; } - .wym_skin_compact .wym_section h2, - .wym_skin_compact .wym_section h3 { padding: 1px 3px; margin: 0; } - .wym_skin_compact .wym_section a { padding: 0 3px; display: block; text-decoration: none; color: black; } - .wym_skin_compact .wym_section a:hover { background-color: yellow; } - /*hide section titles by default*/ - .wym_skin_compact .wym_section h2 { display: none; } - /*disable any margin-collapse*/ - .wym_skin_compact .wym_section { padding-top: 1px; padding-bottom: 1px; } - /*auto-clear sections*/ - .wym_skin_compact .wym_section ul:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } - * html .wym_skin_compact .wym_section ul { height: 1%;} - - /*option: add this class to a section to make it render as a panel*/ - .wym_skin_compact .wym_panel { } - .wym_skin_compact .wym_panel h2 { display: block; } - - /*option: add this class to a section to make it render as a dropdown menu*/ - .wym_skin_compact .wym_dropdown h2 { display: block; } - .wym_skin_compact .wym_dropdown ul { display: none; position: absolute; background: white; } - .wym_skin_compact .wym_dropdown:hover ul, - .wym_skin_compact .wym_dropdown.hover ul { display: block; } - - /*option: add this class to a section to make its elements render buttons (icons are only available for the wym_tools section for now)*/ - .wym_skin_compact .wym_buttons li { float:left;} - .wym_skin_compact .wym_buttons a { width: 20px; height: 20px; overflow: hidden; padding: 2px } - /*image replacements*/ - .wym_skin_compact .wym_buttons li a { background: url(icons.png) no-repeat; text-indent: -9999px;} - .wym_skin_compact .wym_buttons li.wym_tools_strong a { background-position: 0 -382px;} - .wym_skin_compact .wym_buttons li.wym_tools_emphasis a { background-position: 0 -22px;} - .wym_skin_compact .wym_buttons li.wym_tools_superscript a { background-position: 0 -430px;} - .wym_skin_compact .wym_buttons li.wym_tools_subscript a { background-position: 0 -454px;} - .wym_skin_compact .wym_buttons li.wym_tools_ordered_list a { background-position: 0 -48px;} - .wym_skin_compact .wym_buttons li.wym_tools_unordered_list a{ background-position: 0 -72px;} - .wym_skin_compact .wym_buttons li.wym_tools_indent a { background-position: 0 -574px;} - .wym_skin_compact .wym_buttons li.wym_tools_outdent a { background-position: 0 -598px;} - .wym_skin_compact .wym_buttons li.wym_tools_undo a { background-position: 0 -502px;} - .wym_skin_compact .wym_buttons li.wym_tools_redo a { background-position: 0 -526px;} - .wym_skin_compact .wym_buttons li.wym_tools_link a { background-position: 0 -96px;} - .wym_skin_compact .wym_buttons li.wym_tools_unlink a { background-position: 0 -168px;} - .wym_skin_compact .wym_buttons li.wym_tools_image a { background-position: 0 -121px;} - .wym_skin_compact .wym_buttons li.wym_tools_table a { background-position: 0 -144px;} - .wym_skin_compact .wym_buttons li.wym_tools_paste a { background-position: 0 -552px;} - .wym_skin_compact .wym_buttons li.wym_tools_html a { background-position: 0 -193px;} - .wym_skin_compact .wym_buttons li.wym_tools_preview a { background-position: 0 -408px;} - -/*DECORATION*/ - .wym_skin_compact .wym_section h2 { background: #f0f0f0; border: solid gray; border-width: 0 0 1px;} - .wym_skin_compact .wym_section h2 span { color: gray;} - .wym_skin_compact .wym_panel { padding: 0; border: solid gray; border-width: 1px; background: white;} - .wym_skin_compact .wym_panel ul { margin: 2px 0 5px; } - .wym_skin_compact .wym_dropdown { padding: 0; border: solid gray; border-width: 1px 1px 0 1px; } - .wym_skin_compact .wym_dropdown ul { border: solid gray; border-width: 0 1px 1px 1px; margin-left: -1px; padding: 5px 10px 5px 3px;} - -/*DIALOGS*/ - .wym_dialog div.row { margin-bottom: 5px;} - .wym_dialog div.row input { margin-right: 5px;} - .wym_dialog div.row label { float: left; width: 150px; display: block; text-align: right; margin-right: 10px; } - .wym_dialog div.row-indent { padding-left: 160px; } - /*autoclearing*/ - .wym_dialog div.row:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } - .wym_dialog div.row { display: inline-block; } - /* Hides from IE-mac \*/ - * html .wym_dialog div.row { height: 1%; } - .wym_dialog div.row { display: block; } - /* End hide from IE-mac */ - -/*WYMEDITOR_LINK*/ - a.wym_wymeditor_link { text-indent: -9999px; float: right; display: block; width: 50px; height: 15px; background: url(../wymeditor_icon.png); overflow: hidden; text-decoration: none; } diff --git a/vendor/assets/javascripts/wymeditor/skins/compact/skin.js b/vendor/assets/javascripts/wymeditor/skins/compact/skin.js deleted file mode 100644 index 2fa961b..0000000 --- a/vendor/assets/javascripts/wymeditor/skins/compact/skin.js +++ /dev/null @@ -1,37 +0,0 @@ -WYMeditor.SKINS.compact = { - - init: function(wym) { - - //move the containers panel to the top area - jQuery(wym._options.containersSelector + ', ' + - wym._options.classesSelector, wym._box) - .appendTo( jQuery("div.wym_area_top", wym._box) ) - .addClass("wym_dropdown") - .css({"margin-right": "10px", "width": "120px", "float": "left"}); - - //render following sections as buttons - jQuery(wym._options.toolsSelector, wym._box) - .addClass("wym_buttons") - .css({"margin-right": "10px", "float": "left"}); - - //make hover work under IE < 7 - jQuery(".wym_section", wym._box).hover(function(){ - jQuery(this).addClass("hover"); - },function(){ - jQuery(this).removeClass("hover"); - }); - - var postInit = wym._options.postInit; - wym._options.postInit = function(wym) { - - if (postInit) { - postInit.call(wym, wym); - } - var rule = { - name: 'body', - css: 'background-color: #f0f0f0;' - }; - wym.addCssRule( wym._doc.styleSheets[0], rule); - }; - } -}; diff --git a/vendor/assets/javascripts/wymeditor/skins/default/icons.png b/vendor/assets/javascripts/wymeditor/skins/default/icons.png deleted file mode 100644 index c6eb463f11754bd3ab5dedd05dd061a5039a0493..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3651 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 G67^roH{M+U diff --git a/vendor/assets/javascripts/wymeditor/skins/default/skin.css b/vendor/assets/javascripts/wymeditor/skins/default/skin.css deleted file mode 100644 index bbffd6e..0000000 --- a/vendor/assets/javascripts/wymeditor/skins/default/skin.css +++ /dev/null @@ -1,133 +0,0 @@ -/* - * WYMeditor : what you see is What You Mean web-based editor - * Copyright (c) 2005 - 2009 Jean-Francois Hovinne, http://www.wymeditor.org/ - * Dual licensed under the MIT (MIT-license.txt) - * and GPL (GPL-license.txt) licenses. - * - * For further information visit: - * http://www.wymeditor.org/ - * - * File Name: - * skin.css - * main stylesheet for the default WYMeditor skin - * See the documentation for more info. - * - * File Authors: - * Daniel Reszka (d.reszka a-t wymeditor dotorg) -*/ - -/*TRYING TO RESET STYLES THAT MAY INTERFERE WITH WYMEDITOR*/ - .wym_skin_default p, .wym_skin_default h2, .wym_skin_default h3, - .wym_skin_default ul, .wym_skin_default li { background: transparent url(); margin: 0; padding: 0; border-width:0; list-style: none; } - - -/*HIDDEN BY DEFAULT*/ - .wym_skin_default .wym_area_left { display: none; } - .wym_skin_default .wym_area_right { display: block; } - - -/*TYPO*/ - .wym_skin_default { font-size: 62.5%; font-family: Verdana, Arial, sans-serif; } - .wym_skin_default h2 { font-size: 110%; /* = 11px */} - .wym_skin_default h3 { font-size: 100%; /* = 10px */} - .wym_skin_default li { font-size: 100%; /* = 10px */} - - -/*WYM_BOX*/ - .wym_skin_default { border: 1px solid gray; background: #f2f2f2; padding: 5px} - - /*auto-clear the wym_box*/ - .wym_skin_default:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } - * html .wym_skin_default { height: 1%;} - - -/*WYM_HTML*/ - .wym_skin_default .wym_html { width: 98%;} - .wym_skin_default .wym_html textarea { width: 100%; height: 200px; border: 1px solid gray; background: white; } - - -/*WYM_IFRAME*/ - .wym_skin_default .wym_iframe { width: 98%;} - .wym_skin_default .wym_iframe iframe { width: 100%; height: 200px; border: 1px solid gray; background: white } - - -/*AREAS*/ - .wym_skin_default .wym_area_left { width: 150px; float: left;} - .wym_skin_default .wym_area_right { width: 150px; float: right;} - .wym_skin_default .wym_area_bottom { height: 1%; clear: both;} - * html .wym_skin_default .wym_area_main { height: 1%;} - * html .wym_skin_default .wym_area_top { height: 1%;} - *+html .wym_skin_default .wym_area_top { height: 1%;} - -/*SECTIONS SYSTEM*/ - - /*common defaults for all sections*/ - .wym_skin_default .wym_section { margin-bottom: 5px; } - .wym_skin_default .wym_section h2, - .wym_skin_default .wym_section h3 { padding: 1px 3px; margin: 0; } - .wym_skin_default .wym_section a { padding: 0 3px; display: block; text-decoration: none; color: black; } - .wym_skin_default .wym_section a:hover { background-color: yellow; } - /*hide section titles by default*/ - .wym_skin_default .wym_section h2 { display: none; } - /*disable any margin-collapse*/ - .wym_skin_default .wym_section { padding-top: 1px; padding-bottom: 1px; } - /*auto-clear sections*/ - .wym_skin_default .wym_section ul:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } - * html .wym_skin_default .wym_section ul { height: 1%;} - - /*option: add this class to a section to make it render as a panel*/ - .wym_skin_default .wym_panel { } - .wym_skin_default .wym_panel h2 { display: block; } - - /*option: add this class to a section to make it render as a dropdown menu*/ - .wym_skin_default .wym_dropdown h2 { display: block; } - .wym_skin_default .wym_dropdown ul { display: none; position: absolute; background: white; } - .wym_skin_default .wym_dropdown:hover ul, - .wym_skin_default .wym_dropdown.hover ul { display: block; } - - /*option: add this class to a section to make its elements render buttons (icons are only available for the wym_tools section for now)*/ - .wym_skin_default .wym_buttons li { float:left;} - .wym_skin_default .wym_buttons a { width: 20px; height: 20px; overflow: hidden; padding: 2px } - /*image replacements*/ - .wym_skin_default .wym_buttons li a { background: url(icons.png) no-repeat; text-indent: -9999px;} - .wym_skin_default .wym_buttons li.wym_tools_strong a { background-position: 0 -382px;} - .wym_skin_default .wym_buttons li.wym_tools_emphasis a { background-position: 0 -22px;} - .wym_skin_default .wym_buttons li.wym_tools_superscript a { background-position: 0 -430px;} - .wym_skin_default .wym_buttons li.wym_tools_subscript a { background-position: 0 -454px;} - .wym_skin_default .wym_buttons li.wym_tools_ordered_list a { background-position: 0 -48px;} - .wym_skin_default .wym_buttons li.wym_tools_unordered_list a{ background-position: 0 -72px;} - .wym_skin_default .wym_buttons li.wym_tools_indent a { background-position: 0 -574px;} - .wym_skin_default .wym_buttons li.wym_tools_outdent a { background-position: 0 -598px;} - .wym_skin_default .wym_buttons li.wym_tools_undo a { background-position: 0 -502px;} - .wym_skin_default .wym_buttons li.wym_tools_redo a { background-position: 0 -526px;} - .wym_skin_default .wym_buttons li.wym_tools_link a { background-position: 0 -96px;} - .wym_skin_default .wym_buttons li.wym_tools_unlink a { background-position: 0 -168px;} - .wym_skin_default .wym_buttons li.wym_tools_image a { background-position: 0 -121px;} - .wym_skin_default .wym_buttons li.wym_tools_table a { background-position: 0 -144px;} - .wym_skin_default .wym_buttons li.wym_tools_paste a { background-position: 0 -552px;} - .wym_skin_default .wym_buttons li.wym_tools_html a { background-position: 0 -193px;} - .wym_skin_default .wym_buttons li.wym_tools_preview a { background-position: 0 -408px;} - -/*DECORATION*/ - .wym_skin_default .wym_section h2 { background: #ddd; border: solid gray; border-width: 0 0 1px;} - .wym_skin_default .wym_section h2 span { color: gray;} - .wym_skin_default .wym_panel { padding: 0; border: solid gray; border-width: 1px; background: white;} - .wym_skin_default .wym_panel ul { margin: 2px 0 5px; } - .wym_skin_default .wym_dropdown { padding: 0; border: solid gray; border-width: 1px 1px 0 1px; } - .wym_skin_default .wym_dropdown ul { border: solid gray; border-width: 0 1px 1px 1px; margin-left: -1px; padding: 5px 10px 5px 3px;} - -/*DIALOGS*/ - .wym_dialog div.row { margin-bottom: 5px;} - .wym_dialog div.row input { margin-right: 5px;} - .wym_dialog div.row label { float: left; width: 120px; display: block; text-align: right; margin-right: 10px; } - .wym_dialog div.row-indent { padding-left: 160px; } - /*autoclearing*/ - .wym_dialog div.row:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } - .wym_dialog div.row { display: inline-block; } - /* Hides from IE-mac \*/ - * html .wym_dialog div.row { height: 1%; } - .wym_dialog div.row { display: block; } - /* End hide from IE-mac */ - -/*WYMEDITOR_LINK*/ - a.wym_wymeditor_link { text-indent: -9999px; float: right; display: block; width: 50px; height: 15px; background: url(../wymeditor_icon.png); overflow: hidden; text-decoration: none; } diff --git a/vendor/assets/javascripts/wymeditor/skins/default/skin.js b/vendor/assets/javascripts/wymeditor/skins/default/skin.js deleted file mode 100644 index 5f6d97e..0000000 --- a/vendor/assets/javascripts/wymeditor/skins/default/skin.js +++ /dev/null @@ -1,40 +0,0 @@ -WYMeditor.SKINS['default'] = { - - init: function(wym) { - - //render following sections as panels - jQuery(wym._box).find(wym._options.classesSelector) - .addClass("wym_panel"); - - //render following sections as buttons - jQuery(wym._box).find(wym._options.toolsSelector) - .addClass("wym_buttons"); - - //render following sections as dropdown menus - jQuery(wym._box).find(wym._options.containersSelector) - .addClass("wym_dropdown") - .find(WYMeditor.H2) - .append(" >"); - - // auto add some margin to the main area sides if left area - // or right area are not empty (if they contain sections) - jQuery(wym._box).find("div.wym_area_right ul") - .parents("div.wym_area_right").show() - .parents(wym._options.boxSelector) - .find("div.wym_area_main") - .css({"margin-right": "155px"}); - - jQuery(wym._box).find("div.wym_area_left ul") - .parents("div.wym_area_left").show() - .parents(wym._options.boxSelector) - .find("div.wym_area_main") - .css({"margin-left": "155px"}); - - //make hover work under IE < 7 - jQuery(wym._box).find(".wym_section").hover(function(){ - jQuery(this).addClass("hover"); - },function(){ - jQuery(this).removeClass("hover"); - }); - } -}; diff --git a/vendor/assets/javascripts/wymeditor/skins/minimal/images/bg.header.gif b/vendor/assets/javascripts/wymeditor/skins/minimal/images/bg.header.gif deleted file mode 100644 index b2d2907bde67290e74ebc1573d3f535ac19123a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 781 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 diff --git a/vendor/assets/javascripts/wymeditor/skins/minimal/images/icons.silver.gif b/vendor/assets/javascripts/wymeditor/skins/minimal/images/icons.silver.gif deleted file mode 100644 index 8c6a4fbfbe99081a58938c36300beca18b6c19a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15382 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 TJv>7BLrzzCsxmJM2^jt#VJT;& diff --git a/vendor/assets/javascripts/wymeditor/skins/minimal/skin.css b/vendor/assets/javascripts/wymeditor/skins/minimal/skin.css deleted file mode 100644 index cea8d84..0000000 --- a/vendor/assets/javascripts/wymeditor/skins/minimal/skin.css +++ /dev/null @@ -1,131 +0,0 @@ -/* - * WYMeditor : what you see is What You Mean web-based editor - * Copyright (c) 2005 - 2009 Jean-Francois Hovinne, http://www.wymeditor.org/ - * Dual licensed under the MIT (MIT-license.txt) - * and GPL (GPL-license.txt) licenses. - * - * For further information visit: - * http://www.wymeditor.org/ - * - * File Name: - * skin.css - * main stylesheet for the minimal WYMeditor skin - * See the documentation for more info. - * - * File Authors: - * Jean-Francois Hovinne - * Scott Lewis (see Silver skin) -*/ - -/* Set iframe */ -.wym_skin_minimal div.wym_iframe iframe { - width: 90%; - height: 200px; -} - -/* Hide h2 by default */ -.wym_skin_minimal h2 { - display: none; -} - -/* Show specific h2 */ -.wym_skin_minimal div.wym_tools h2, -.wym_skin_minimal div.wym_containers h2, -.wym_skin_minimal div.wym_classes h2 { - display: block; -} - -.wym_skin_minimal div.wym_section ul { - margin: 0; -} - -.wym_skin_minimal div.wym_section ul li { - float: left; - list-style-type: none; - margin-right: 5px; -} - -.wym_skin_minimal div.wym_area_top, -.wym_skin_minimal div.wym_area_right, -.wym_skin_minimal div.wym_containers, -.wym_skin_minimal div.wym_classes { - float: left; -} - -.wym_skin_minimal div.wym_area_main { - clear: both; -} - -.wym_skin_minimal div.wym_html { - width: 90%; -} - -.wym_skin_minimal textarea.wym_html_val { - width: 100%; - height: 100px; -} - -/* DROPDOWNS (see Silver skin) */ -.wym_skin_minimal div.wym_dropdown { - cursor: pointer; - margin: 0px 4px 10px 0px; - padding: 0px; - z-index: 1001; - display: block; -} - -.wym_skin_minimal div.wym_dropdown ul { - display: none; - width: 124px; - padding: 0px; - margin: 0px; - list-style-type: none; - list-style-image: none; - z-index: 1002; - position: absolute; - border-top: 1px solid #AAA; -} - -.wym_skin_minimal div.wym_dropdown ul li { - width: 146px; - height: 20px; - padding: 0px; - margin: 0px; - border: 1px solid #777; - border-top: none; - background: #EEE; - list-style-image: none; -} - -.wym_skin_minimal div.wym_dropdown h2 { - width: 138px; - height: 16px; - color: #000; - background-image: url(images/bg.selector.silver.gif); - background-position: 0px -18px; - background-repeat: no-repeat; - border: none; - font-family: "Trebuchet MS", Verdana, Arial, Helvetica, Sanserif; - font-size: 12px; - font-weight: bold; - padding: 2px 0px 0px 10px; - margin: 0px; -} - -.wym_skin_minimal div.wym_dropdown a { - text-decoration: none; - font-family: "Trebuchet MS", Verdana, Arial, Helvetica, Sanserif; - font-size: 12px; - padding: 5px 0px 0px 10px; - display: block; - width: 136px; - height: 15px; - color: #000; - text-align: left; - margin-left: 0px; -} - -.wym_skin_minimal div.wym_dropdown a:hover { - background: #BBB; - border-bottom: none; -} diff --git a/vendor/assets/javascripts/wymeditor/skins/minimal/skin.js b/vendor/assets/javascripts/wymeditor/skins/minimal/skin.js deleted file mode 100644 index d2536ce..0000000 --- a/vendor/assets/javascripts/wymeditor/skins/minimal/skin.js +++ /dev/null @@ -1,30 +0,0 @@ -jQuery.fn.selectify = function() { - return this.each(function() { - jQuery(this).hover( - function() { - jQuery("h2", this).css("background-position", "0px -18px"); - jQuery("ul", this).fadeIn("fast"); - }, - function() { - jQuery("h2", this).css("background-position", ""); - jQuery("ul", this).fadeOut("fast"); - } - ); - }); -}; - -WYMeditor.SKINS.minimal = { - //placeholder for the skin JS, if needed - - //init the skin - //wym is the WYMeditor.editor instance - init: function(wym) { - - //render following sections as dropdown menus - jQuery(wym._box).find(wym._options.toolsSelector + ', ' + wym._options.containersSelector + ', ' + wym._options.classesSelector) - .addClass("wym_dropdown") - .selectify(); - - - } -}; diff --git a/vendor/assets/javascripts/wymeditor/skins/silver/COPYING b/vendor/assets/javascripts/wymeditor/skins/silver/COPYING deleted file mode 100755 index 94a9ed0..0000000 --- a/vendor/assets/javascripts/wymeditor/skins/silver/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/vendor/assets/javascripts/wymeditor/skins/silver/README b/vendor/assets/javascripts/wymeditor/skins/silver/README deleted file mode 100755 index 130dc46..0000000 --- a/vendor/assets/javascripts/wymeditor/skins/silver/README +++ /dev/null @@ -1,27 +0,0 @@ -/** -* @version Alpha 0.1 2008-05-10 23:28:43 $ -* @package Silver skin for WYMeditor -* @copyright Copyright (C) 2008 Scott Edwin Lewis. All rights reserved. -* @license GNU/GPL, see COPYING -* Silver skin for WYMeditor is free software and is licensed under the -* GNU General Public License. See COPYING for copyright notices and details. -*/ - -Adds custom buttons and color palette to the WYMeditor XHTML Editor. - -INSTALLATION: - -1. Copy the entire /silver/ directory to /wymeditor/skins/ -2. Initialize the WYMeditor 'skin' option as below: - - - -That's it. You're done. diff --git a/vendor/assets/javascripts/wymeditor/skins/silver/images/bg.header.gif b/vendor/assets/javascripts/wymeditor/skins/silver/images/bg.header.gif deleted file mode 100644 index b2d2907bde67290e74ebc1573d3f535ac19123a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 781 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 diff --git a/vendor/assets/javascripts/wymeditor/skins/silver/images/icons.silver.gif b/vendor/assets/javascripts/wymeditor/skins/silver/images/icons.silver.gif deleted file mode 100644 index 8c6a4fbfbe99081a58938c36300beca18b6c19a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15382 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 TJv>7BLrzzCsxmJM2^jt#VJT;& diff --git a/vendor/assets/javascripts/wymeditor/skins/silver/skin.css b/vendor/assets/javascripts/wymeditor/skins/silver/skin.css deleted file mode 100644 index 8284d81..0000000 --- a/vendor/assets/javascripts/wymeditor/skins/silver/skin.css +++ /dev/null @@ -1,297 +0,0 @@ -/* - * WYMeditor : what you see is What You Mean web-based editor - * Copyright (c) 2005 - 2009 Jean-Francois Hovinne, http://www.wymeditor.org/ - * Dual licensed under the MIT (MIT-license.txt) - * and GPL (GPL-license.txt) licenses. - * - * For further information visit: - * http://www.wymeditor.org/ - * - * File Name: - * screen.css - * main stylesheet for the default WYMeditor skin - * See the documentation for more info. - * - * File Authors: - * Daniel Reszka (d.reszka a-t wymeditor dotorg) - * Scott Edwin Lewis -*/ - -/*TRYING TO RESET STYLES THAT MAY INTERFERE WITH WYMEDITOR*/ - .wym_skin_silver p, .wym_skin_silver h2, .wym_skin_silver h3, - .wym_skin_silver ul, .wym_skin_silver li { background: transparent url(); margin: 0; padding: 0; border-width:0; list-style: none; } - - -/*HIDDEN BY DEFAULT*/ - .wym_skin_silver .wym_area_left { display: none; } - .wym_skin_silver .wym_area_right { display: block; } - - -/*TYPO*/ - .wym_skin_silver { font-size: 62.5%; font-family: Verdana, Arial, sans-serif; } - .wym_skin_silver h2 { font-size: 110%; /* = 11px */} - .wym_skin_silver h3 { font-size: 100%; /* = 10px */} - .wym_skin_silver li { font-size: 100%; /* = 10px */} - - -/*WYM_BOX*/ - .wym_skin_silver { border: 1px solid gray; background: #f2f2f2; padding: 0px; margin: 0px;} - - /*auto-clear the wym_box*/ - .wym_skin_silver:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } - * html .wym_skin_silver { height: 1%;} - - -/*WYM_HTML*/ - .wym_skin_silver .wym_html { width: 98%;} - .wym_skin_silver .wym_html textarea { width: 100%; height: 200px; border: 1px solid gray; background: white; } - - -/*WYM_IFRAME*/ - .wym_skin_silver .wym_iframe { width: 98%;} - .wym_skin_silver .wym_iframe iframe { width: 100%; height: 200px; border: 1px solid gray; background: white } - - -/*AREAS*/ - .wym_skin_silver .wym_area_left { width: 150px; float: left;} - .wym_skin_silver .wym_area_right { width: 150px; float: right;} - .wym_skin_silver .wym_area_bottom { height: 1%; clear: both;} - * html .wym_skin_silver .wym_area_main { height: 1%;} - * html .wym_skin_silver .wym_area_top { height: 1%;} - *+html .wym_skin_silver .wym_area_top { height: 1%;} - -/*SECTIONS SYSTEM*/ - - /*common defaults for all sections*/ - .wym_skin_silver .wym_section { margin-bottom: 5px; } - .wym_skin_silver .wym_section h2, - .wym_skin_silver .wym_section h3 { padding: 1px 3px; margin: 0; cursor: pointer; } - .wym_skin_silver .wym_section a { padding: 5px 0px 0px 10px; display: block; text-decoration: none; color: black; } - .wym_skin_silver .wym_section a:hover { /*background-color: #DDD;*/} - /*hide section titles by default*/ - .wym_skin_silver .wym_section h2 { display: none; } - /*disable any margin-collapse*/ - .wym_skin_silver .wym_section { padding-top: 1px; padding-bottom: 1px; } - /*auto-clear sections*/ - .wym_skin_silver .wym_section ul:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; padding: 0px; } - * html .wym_skin_silver .wym_section ul { height: 1%;} - .wym_skin_silver .wym_section li {} - - /*option: add this class to a section to make it render as a panel*/ - .wym_skin_silver .wym_panel { } - .wym_skin_silver .wym_panel h2 { display: block; font-size: 11px; } - - /*option: add this class to a section to make it render as a dropdown menu*/ - .wym_skin_silver .wym_dropdown h2 { display: block; font-size: 11px;} - .wym_skin_silver .wym_dropdown ul { position: absolute; background: white; padding: 0px;} - .wym_skin_silver .wym_dropdown:hover ul, - .wym_skin_silver .wym_dropdown.hover ul { cursor: pointer;} - .wym_skin_silver .wym_dropdown ul li a {/*border-bottom: 1px solid #AAA;*/} - - /*option: add this class to a section to make its elements render buttons (icons are only available for the wym_tools section for now)*/ - .wym_skin_silver .wym_buttons li { float:left;} - .wym_skin_silver .wym_buttons a { width: 20px; height: 20px; overflow: hidden; padding: 2px; text-decoration: none !important; border: 1px solid #666; } - .wym_skin_silver .wym_buttons a:hover { text-decoration: none !important; border: 1px solid #000;} - /*image replacements*/ - .wym_skin_silver .wym_buttons li a { background: url(images/icons.silver.gif) no-repeat; text-indent: -9999px;} - .wym_skin_silver .wym_buttons li.wym_tools_strong a { background-position: 0 -384px;} - .wym_skin_silver .wym_buttons li.wym_tools_emphasis a { background-position: 0 -24px;} - .wym_skin_silver .wym_buttons li.wym_tools_superscript a { background-position: 0 -432px;} - .wym_skin_silver .wym_buttons li.wym_tools_subscript a { background-position: 0 -456px;} - .wym_skin_silver .wym_buttons li.wym_tools_ordered_list a { background-position: 0 -48px;} - .wym_skin_silver .wym_buttons li.wym_tools_unordered_list a{ background-position: 0 -72px;} - .wym_skin_silver .wym_buttons li.wym_tools_indent a { background-position: 0 -600px;} - .wym_skin_silver .wym_buttons li.wym_tools_outdent a { background-position: 0 -624px;} - .wym_skin_silver .wym_buttons li.wym_tools_undo a { background-position: 0 -504px;} - .wym_skin_silver .wym_buttons li.wym_tools_redo a { background-position: 0 -528px;} - .wym_skin_silver .wym_buttons li.wym_tools_link a { background-position: 0 -96px;} - .wym_skin_silver .wym_buttons li.wym_tools_unlink a { background-position: 0 -168px;} - .wym_skin_silver .wym_buttons li.wym_tools_image a { background-position: 0 -120px;} - .wym_skin_silver .wym_buttons li.wym_tools_table a { background-position: 0 -144px;} - .wym_skin_silver .wym_buttons li.wym_tools_paste a { background-position: 0 -552px;} - .wym_skin_silver .wym_buttons li.wym_tools_html a { background-position: 0 -192px;} - .wym_skin_silver .wym_buttons li.wym_tools_preview a { background-position: 0 -408px;} - .wym_skin_silver .wym_buttons li.wym_tools_gadget a { background-position: 0 -576px;} - - .wym_skin_silver .wym_buttons li.wym_tools_strong a:hover { background-position: -24px -384px;} - .wym_skin_silver .wym_buttons li.wym_tools_emphasis a:hover { background-position: -24px -24px;} - .wym_skin_silver .wym_buttons li.wym_tools_superscript a:hover { background-position: -24px -432px;} - .wym_skin_silver .wym_buttons li.wym_tools_subscript a:hover { background-position: -24px -456px;} - .wym_skin_silver .wym_buttons li.wym_tools_ordered_list a:hover { background-position: -24px -48px;} - .wym_skin_silver .wym_buttons li.wym_tools_unordered_list a:hover{ background-position: -24px -72px;} - .wym_skin_silver .wym_buttons li.wym_tools_indent a:hover { background-position: -24px -600px;} - .wym_skin_silver .wym_buttons li.wym_tools_outdent a:hover { background-position: -24px -624px;} - .wym_skin_silver .wym_buttons li.wym_tools_undo a:hover { background-position: -24px -504px;} - .wym_skin_silver .wym_buttons li.wym_tools_redo a:hover { background-position: -24px -528px;} - .wym_skin_silver .wym_buttons li.wym_tools_link a:hover { background-position: -24px -96px;} - .wym_skin_silver .wym_buttons li.wym_tools_unlink a:hover { background-position: -24px -168px;} - .wym_skin_silver .wym_buttons li.wym_tools_image a:hover { background-position: -24px -120px;} - .wym_skin_silver .wym_buttons li.wym_tools_table a:hover { background-position: -24px -144px;} - .wym_skin_silver .wym_buttons li.wym_tools_paste a:hover { background-position: -24px -552px;} - .wym_skin_silver .wym_buttons li.wym_tools_html a:hover { background-position: -24px -192px;} - .wym_skin_silver .wym_buttons li.wym_tools_preview a:hover { background-position: -24px -408px;} - .wym_skin_silver .wym_buttons li.wym_tools_gadget a:hover { background-position: -24px -576px;} - -/*DECORATION*/ - .wym_skin_silver .wym_section h2 { background: #ddd; border: none;} - .wym_skin_silver .wym_section h2 span { color: gray;} - .wym_skin_silver .wym_panel { padding: 0; border: solid gray; border-width: 0px;} - .wym_skin_silver .wym_panel ul { margin: 2px 0 5px; } - .wym_skin_silver .wym_dropdown { padding: 0; border: none; } - .wym_skin_silver .wym_dropdown ul { border: none; margin-left: -1px; padding: 0px;} - -/*DIALOGS*/ - .wym_dialog div.row { margin-bottom: 5px;} - .wym_dialog div.row input { margin-right: 5px;} - .wym_dialog div.row label { float: left; width: 150px; display: block; text-align: right; margin-right: 10px; } - .wym_dialog div.row-indent { padding-left: 160px; } - /*autoclearing*/ - .wym_dialog div.row:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } - .wym_dialog div.row { display: inline-block; } - /* Hides from IE-mac \*/ - * html .wym_dialog div.row { height: 1%; } - .wym_dialog div.row { display: block; } - /* End hide from IE-mac */ - -/*WYMEDITOR_LINK*/ - a.wym_wymeditor_link - { - text-indent: -9999px; - float: right; - display: block; - width: 50px; - height: 15px; - background: url(../wymeditor_icon.png); - background-position: 1px 1px; - background-repeat: no-repeat; - overflow: hidden; - text-decoration: none; - padding: 1px !important; - border: 1px solid #333 !important; - background-color: #FFF !important; - } - -.wym_box -{ - padding: 0px !important; - margin: 0px; -} -.wym_inner -{ - border-left: 1px solid #FFF; - border-top: 1px solid #FFF; - border-right: 1px solid #FFF; - border-bottom: 1px solid #FFF; - padding: 5px; - background-color: #B8C1C4; - height: auto; -} - -.clear {clear: both;} - -div.wym_dropdown -{ - cursor: pointer; - width: 138px !important; - margin: 0px 4px 10px 0px !important; - padding: 0px; - z-index: 1001; - display: block; - border: 1px solid red; -} - -div.wym_dropdown ul -{ - display: none; - width: 124px; - padding: 0px !important; - margin: 0px !important; - list-style-type: none; - list-style-image: none; - z-index: 1002; - position: absolute; - border-top: 1px solid #AAA; -} - -div.wym_dropdown ul li -{ - width: 146px; - height: 20px; - padding: 0px !important; - margin: 0px; - border: 1px solid #777; - border-top: none; - background: #DDD; - list-style-image: none; -} - -div.wym_dropdown h2 -{ - width: 138px; - height: 16px; - color: #000 !important; - background-image: url(images/bg.selector.silver.gif) !important; - background-position: 0px -18px; - background-repeat: no-repeat; - border: none; - font-family: "Trebuchet MS", Verdana, Arial, Helvetica, Sanserif; - font-size: 12px !important; - font-weight: bold !important; - padding: 2px 0px 0px 10px !important; - margin: 0px !important; -} - -.wym_skin_silver .wym_panel h2 -{ - width: 138px; - height: 16px; - color: #000 !important; - background-image: url(images/bg.header.gif) !important; - background-position: 0px 0px; - background-repeat: no-repeat; - border: none; - font-family: "Trebuchet MS", Verdana, Arial, Helvetica, Sanserif; - font-size: 12px !important; - font-weight: bold !important; - padding: 2px 0px 0px 10px !important; - margin: 0px !important; -} - -.wym_skin_silver .wym_panel ul -{ - margin-top: 0px !important; -} - -.wym_skin_silver .wym_panel ul li -{ - width: 146px; - height: 20px; - padding: 0px !important; - margin: 0px; - border: 1px solid #777; - border-top: none; - background: #DDD; - list-style-image: none; -} - -.wym_skin_silver .wym_panel a, -div.wym_dropdown a -{ - text-decoration: none; - font-family: "Trebuchet MS", Verdana, Arial, Helvetica, Sanserif; - font-size: 12px; - padding: 5px 0px 0px 10px !important; - display: block; - width: 136px; - height: 15px; - color: #000; - text-align: left !important; - margin-left: 0px !important; -} - -div.wym_dropdown a:hover, -.wym_skin_silver .wym_panel a:hover -{ - background: #BBB; - border-bottom: none !important; -} diff --git a/vendor/assets/javascripts/wymeditor/skins/silver/skin.js b/vendor/assets/javascripts/wymeditor/skins/silver/skin.js deleted file mode 100644 index 7d94094..0000000 --- a/vendor/assets/javascripts/wymeditor/skins/silver/skin.js +++ /dev/null @@ -1,61 +0,0 @@ -/* This file is part of the Silver skin for WYMeditor by Scott Edwin Lewis */ - -jQuery.fn.selectify = function() { - return this.each(function() { - jQuery(this).hover( - function() { - jQuery("h2", this).css("background-position", "0px -18px"); - jQuery("ul", this).fadeIn("fast"); - }, - function() { - jQuery("h2", this).css("background-position", ""); - jQuery("ul", this).fadeOut("fast"); - } - ); - }); -}; - -WYMeditor.SKINS.silver = { - - init: function(wym) { - - //add some elements to improve the rendering - jQuery(wym._box) - .append('
    ') - .wrapInner('
    '); - - //render following sections as panels - jQuery(wym._box).find(wym._options.classesSelector) - .addClass("wym_panel"); - - //render following sections as buttons - jQuery(wym._box).find(wym._options.toolsSelector) - .addClass("wym_buttons"); - - //render following sections as dropdown menus - jQuery(wym._box).find(wym._options.containersSelector) - .addClass("wym_dropdown") - .selectify(); - - // auto add some margin to the main area sides if left area - // or right area are not empty (if they contain sections) - jQuery(wym._box).find("div.wym_area_right ul") - .parents("div.wym_area_right").show() - .parents(wym._options.boxSelector) - .find("div.wym_area_main") - .css({"margin-right": "155px"}); - - jQuery(wym._box).find("div.wym_area_left ul") - .parents("div.wym_area_left").show() - .parents(wym._options.boxSelector) - .find("div.wym_area_main") - .css({"margin-left": "155px"}); - - //make hover work under IE < 7 - jQuery(wym._box).find(".wym_section").hover(function(){ - jQuery(this).addClass("hover"); - },function(){ - jQuery(this).removeClass("hover"); - }); - } -}; diff --git a/vendor/assets/javascripts/wymeditor/skins/twopanels/icons.png b/vendor/assets/javascripts/wymeditor/skins/twopanels/icons.png deleted file mode 100644 index c6eb463f11754bd3ab5dedd05dd061a5039a0493..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3651 zcmd^C`8V5(692}|t*fOTEiGLvrPfkZt+lt5SX)I@t7^L`UDO&|tyN1R5?d54QHtW) zmy4E+{_4kf}#Mx zmdV3@5IVTkW$1?*<0|2Pjm*-ofoN!4GGq5E9yix{$ zw;}+r=K%o8ng9Sj1c0q|0MIM|0P#RUwL3!qzz$g7vok)?uvjb%03Zv$x_})}C>)K( z+TCTPre-ji$B698r1X-(30i6itsT#Tc)>_ZtcF&csoCAV{X+}?Zl9Ee)JoRl7n!-W z>vC>m=QUp0zwPr!(p(~XVI{2e^3|#zhuAjS=Wm0T3}8mDe|e%B_@tsu>fN`!_L2P-{^igtlD!`iUb9irz41P~ z_Dv+5OC?xP*3vk9#yXy48_^3%B{@d*ImhB4K^SO!W#hmGuXc>6iW4~Mr(H~+!#kX3 zO0O?s7*$6qYaG%%CMOSbeG$5>iQPAEXW$e=K*-C2obUG{^IuNJA|vq>;7X1mt6hTp#(F%scp0{SmZ1Hp2XCoE@R;WnJ21 zVpVVx%6|rKFq?gE2mvPc)#20b52oE8NVfd$EJt5mK0ZD^Iyz!9nfv?uJ3BiJ27^YU zt*x!CtgI|9F3!)-&(6+HPfw4Hjp6Zl91hpp+uPaM+0oI_*4EbC+}zO6P+MDDRaI3{ zQBhJ-QdCs*@#Dw*{QR7p925$LKp-+QGTy&`pO}~!7Z(>D9SwuQLPA13Jw4Uc)upAS zPbUBRkIzd000Lfut!z)||FZ$MyWCPId#1qL$iOa$Ky`NZJv(vkcmPMe;PExO1Jc8r z;)@&8KU@3$LhqKLm#mZn#=l_YPML#!_nn7wITl9cSgeA#<;TkxEzTM%7#qVajIh=m z2@54kHL<7d+Fy^~O!4z=-fR8kvaycK(ak~S26_&fXkLSmFX#pBhBDm-SP@JXB?l#S zmXU-zXPxS1*ndGCcz-0MH0DsuCTC}F-*F5`gGx+NByaea0Cx8C2vGZJBejmAGar}C$&8$5gcPVOGwdLLj229UWl!kD?zti#W} z`)urcMkqM=!>J$>o8%O#_R6EqL+xMhOea*qVz;>J-@H|$V>v9F zg1Co$LSlq@%lR&E*rbTtn?j;LITMQ~(%I%XAb~%33)C7*8RujgZ_kCY8@zofl12Y3 z1(}z5UZPD)LBq9?e#Ao3Ik{i{J(^>@Y5QBL3D(A1qdHrUb&Ma#v(XNU*N)YOl5n8H zMJe6J5DjiMj82$#`3{e}-jdB}K7WazBVwf@@a)6Y5-puQ3L)2w5BBwmBmx~8f>?g_ zloq=nW@|Ea(TL|Z8@}c$)L+`AS{wEu;u`S#%qv;lV9ol~0Mh3BkiWFGBAze5dlq4m zU0C0^uj;3(wLeY8?Pl7W@NaNd50oUa3ib!|zNuG5ienVI9IF@hO$e1N*ofBd!GWu$ zOF~5G+H(8z#-sk;FW6}X+im)wF{}P5R@c?CPvGev4~#v`)!>RB+Q5SRZx7@6w)tF7 zE}0D|v9wW7E3C&O%suRv<6U(A;={C8N1ihOO!W8WxULeX-ulezM4oz;dCBb>p6rSb zdF~@R=|ZsY21!@yB~Dbd#eqkqI1-MAep6g^cXQKOCNXs`RZ@-O@y((Q%-8#^+0Bka z5I_0w)@bD35AD#4wbPj7XMb*nL4Oa)T&WeVf46O{ zQs%FM88KtiaRQHk49yD!*zSUWZsAK=(fTn-W8`+(;Z9{@(?<}nYADSG>S_?ia~b{! zH#C#K)SAiu z($+@)(5&>NuP)A_y%5C4PvMwS-W=2o?LgM+kBgoXVw4g>YY*hEY0$_ksFb8yY{&E5;e*Q1S8|5TumycLIZ)O(il*kDK19*+)0*41_D?VUdgCe#YhX7DU%77nbH-;rjNPg~ax}(TZkV7;k~#f6>^^qU-E8R&McDK* zvgt|d5M@;S57ojy^WPR+Ru$|omJYx!4rwG_u_=%aKL`)+RB+ePCfzoK+!eKseKGKk zFItSE{h2Lm|CY=P#*&$=vaoYZz)d?*Fj;H;q5f-0=Hod}YidwpjgwB15`}-)M8!=P z5SA`T%+ZC%Z@oButd$!=vxuctrp_m4D{C2@nNb%vI`e=m8LAso5q!VuV^Z}GQ8?J5 zUn3xsa)#Z{`92^MaPjt#jx@+#6|L6DcW_lkh!1c<#1M<@MoMnmWbb{WQ_0HG#pems z-8z1(0SL17pM#$0LV-&$;!-icaAS`P>o1b6G@o@6nLls8GSYWO3R;T4j&aO%k}+Adbsr z9>E1A|8pb|et7XJV_Nns%2ard+C0Br20BloFVwz}Xp@K?)eUOL`L%x`N*O`SFF9-i zOOkvp?7fCgn_hWdjD(qO#jzXb2CJ*G!D2dnY$JV-WQ?gRd6v5t_Y?EbHU6wc-*7=% zA1FlTH{kM`^YmXwk0pIG6s`g6@{_FN;&}S{&gbDP@Zpq8J99#`-P) z#gU!do-HTD>8?5Z@Gi2lr_Y^=76VF6`Sh!xI!~{09b2YQuCs9h=L^YElz{ANKYK}8 z@Fq3pTf9f}EMOf)7IJS+Q5Pqpl%l|wg#0Lj4y*bd3p6CHKE(7^A8gbR5+NE9%v zO3Shq(ou={cpbpgG+&AIi9QyATo#R>6z*Na_l3MYcplIvMjc%K~v@W!6)r>zGc zf`s+K=0%=S(z{H7^VU2D{7hd`?XjrMdL{r?< z>gDbE%eOvZzhaT>LSuy$ZoE!gyrvEji&u0!3w0;hxni<|1Y#Hj_%`eo_i0N2_8LY1 zltcf5eGMqMc}4oDsJ!3@4w_m9rf#rTfB@`m$DCymhbNn9j>%4fuIjOYLB&%=0U@;B z=5&1GRHX^0s|tBdDB1DNqwfljg@d-uesRhIoTNE6mKcD>H7W%;x}#5?H^AK3%BaE+ G67^roH{M+U diff --git a/vendor/assets/javascripts/wymeditor/skins/twopanels/skin.css b/vendor/assets/javascripts/wymeditor/skins/twopanels/skin.css deleted file mode 100644 index 7e6b8fd..0000000 --- a/vendor/assets/javascripts/wymeditor/skins/twopanels/skin.css +++ /dev/null @@ -1,134 +0,0 @@ -/* - * WYMeditor : what you see is What You Mean web-based editor - * Copyright (c) 2005 - 2009 Jean-Francois Hovinne, http://www.wymeditor.org/ - * Dual licensed under the MIT (MIT-license.txt) - * and GPL (GPL-license.txt) licenses. - * - * For further information visit: - * http://www.wymeditor.org/ - * - * File Name: - * screen.css - * main stylesheet for the WYMeditor skin - * See the documentation for more info. - * - * File Authors: - * Daniel Reszka (d.reszka a-t wymeditor dotorg) - * Jean-Francois Hovinne -*/ - -/*TRYING TO RESET STYLES THAT MAY INTERFERE WITH WYMEDITOR*/ - .wym_skin_twopanels p, .wym_skin_twopanels h2, .wym_skin_twopanels h3, - .wym_skin_twopanels ul, .wym_skin_twopanels li { background: transparent url(); margin: 0; padding: 0; border-width:0; list-style: none; } - - -/*HIDDEN BY DEFAULT*/ - .wym_skin_twopanels .wym_area_left { display: block; } - .wym_skin_twopanels .wym_area_right { display: block; } - - -/*TYPO*/ - .wym_skin_twopanels { font-size: 62.5%; font-family: Verdana, Arial, sans-serif; } - .wym_skin_twopanels h2 { font-size: 110%; /* = 11px */} - .wym_skin_twopanels h3 { font-size: 100%; /* = 10px */} - .wym_skin_twopanels li { font-size: 100%; /* = 10px */} - - -/*WYM_BOX*/ - .wym_skin_twopanels { border: 1px solid gray; background: #f2f2f2; padding: 5px} - - /*auto-clear the wym_box*/ - .wym_skin_twopanels:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } - * html .wym_skin_twopanels { height: 1%;} - - -/*WYM_HTML*/ - .wym_skin_twopanels .wym_html { width: 98%;} - .wym_skin_twopanels .wym_html textarea { width: 100%; height: 200px; border: 1px solid gray; background: white; } - - -/*WYM_IFRAME*/ - .wym_skin_twopanels .wym_iframe { width: 98%;} - .wym_skin_twopanels .wym_iframe iframe { width: 100%; height: 200px; border: 1px solid gray; background: white } - - -/*AREAS*/ - .wym_skin_twopanels .wym_area_left { width: 100px; float: left;} - .wym_skin_twopanels .wym_area_right { width: 150px; float: right;} - .wym_skin_twopanels .wym_area_bottom { height: 1%; clear: both;} - * html .wym_skin_twopanels .wym_area_main { height: 1%;} - * html .wym_skin_twopanels .wym_area_top { height: 1%;} - *+html .wym_skin_twopanels .wym_area_top { height: 1%;} - -/*SECTIONS SYSTEM*/ - - /*common defaults for all sections*/ - .wym_skin_twopanels .wym_section { margin-bottom: 5px; } - .wym_skin_twopanels .wym_section h2, - .wym_skin_twopanels .wym_section h3 { padding: 1px 3px; margin: 0; } - .wym_skin_twopanels .wym_section a { padding: 0 3px; display: block; text-decoration: none; color: black; } - .wym_skin_twopanels .wym_section a:hover { background-color: yellow; } - /*hide section titles by default*/ - .wym_skin_twopanels .wym_section h2 { display: none; } - /*disable any margin-collapse*/ - .wym_skin_twopanels .wym_section { padding-top: 1px; padding-bottom: 1px; } - /*auto-clear sections*/ - .wym_skin_twopanels .wym_section ul:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } - * html .wym_skin_twopanels .wym_section ul { height: 1%;} - - /*option: add this class to a section to make it render as a panel*/ - .wym_skin_twopanels .wym_panel { } - .wym_skin_twopanels .wym_panel h2 { display: block; } - - /*option: add this class to a section to make it render as a dropdown menu*/ - .wym_skin_twopanels .wym_dropdown h2 { display: block; } - .wym_skin_twopanels .wym_dropdown ul { display: none; position: absolute; background: white; } - .wym_skin_twopanels .wym_dropdown:hover ul, - .wym_skin_twopanels .wym_dropdown.hover ul { display: block; } - - /*option: add this class to a section to make its elements render buttons (icons are only available for the wym_tools section for now)*/ - .wym_skin_twopanels .wym_buttons li { float:left;} - .wym_skin_twopanels .wym_buttons a { width: 20px; height: 20px; overflow: hidden; padding: 2px } - /*image replacements*/ - .wym_skin_twopanels .wym_buttons li a { background: url(icons.png) no-repeat; text-indent: -9999px;} - .wym_skin_twopanels .wym_buttons li.wym_tools_strong a { background-position: 0 -382px;} - .wym_skin_twopanels .wym_buttons li.wym_tools_emphasis a { background-position: 0 -22px;} - .wym_skin_twopanels .wym_buttons li.wym_tools_superscript a { background-position: 0 -430px;} - .wym_skin_twopanels .wym_buttons li.wym_tools_subscript a { background-position: 0 -454px;} - .wym_skin_twopanels .wym_buttons li.wym_tools_ordered_list a { background-position: 0 -48px;} - .wym_skin_twopanels .wym_buttons li.wym_tools_unordered_list a{ background-position: 0 -72px;} - .wym_skin_twopanels .wym_buttons li.wym_tools_indent a { background-position: 0 -574px;} - .wym_skin_twopanels .wym_buttons li.wym_tools_outdent a { background-position: 0 -598px;} - .wym_skin_twopanels .wym_buttons li.wym_tools_undo a { background-position: 0 -502px;} - .wym_skin_twopanels .wym_buttons li.wym_tools_redo a { background-position: 0 -526px;} - .wym_skin_twopanels .wym_buttons li.wym_tools_link a { background-position: 0 -96px;} - .wym_skin_twopanels .wym_buttons li.wym_tools_unlink a { background-position: 0 -168px;} - .wym_skin_twopanels .wym_buttons li.wym_tools_image a { background-position: 0 -121px;} - .wym_skin_twopanels .wym_buttons li.wym_tools_table a { background-position: 0 -144px;} - .wym_skin_twopanels .wym_buttons li.wym_tools_paste a { background-position: 0 -552px;} - .wym_skin_twopanels .wym_buttons li.wym_tools_html a { background-position: 0 -193px;} - .wym_skin_twopanels .wym_buttons li.wym_tools_preview a { background-position: 0 -408px;} - -/*DECORATION*/ - .wym_skin_twopanels .wym_section h2 { background: #ddd; border: solid gray; border-width: 0 0 1px;} - .wym_skin_twopanels .wym_section h2 span { color: gray;} - .wym_skin_twopanels .wym_panel { padding: 0; border: solid gray; border-width: 1px; background: white;} - .wym_skin_twopanels .wym_panel ul { margin: 2px 0 5px; } - .wym_skin_twopanels .wym_dropdown { padding: 0; border: solid gray; border-width: 1px 1px 0 1px; } - .wym_skin_twopanels .wym_dropdown ul { border: solid gray; border-width: 0 1px 1px 1px; margin-left: -1px; padding: 5px 10px 5px 3px;} - -/*DIALOGS*/ - .wym_dialog div.row { margin-bottom: 5px;} - .wym_dialog div.row input { margin-right: 5px;} - .wym_dialog div.row label { float: left; width: 150px; display: block; text-align: right; margin-right: 10px; } - .wym_dialog div.row-indent { padding-left: 160px; } - /*autoclearing*/ - .wym_dialog div.row:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } - .wym_dialog div.row { display: inline-block; } - /* Hides from IE-mac \*/ - * html .wym_dialog div.row { height: 1%; } - .wym_dialog div.row { display: block; } - /* End hide from IE-mac */ - -/*WYMEDITOR_LINK*/ - a.wym_wymeditor_link { text-indent: -9999px; float: right; display: block; width: 50px; height: 15px; background: url(../wymeditor_icon.png); overflow: hidden; text-decoration: none; } diff --git a/vendor/assets/javascripts/wymeditor/skins/twopanels/skin.js b/vendor/assets/javascripts/wymeditor/skins/twopanels/skin.js deleted file mode 100644 index 79ccdf9..0000000 --- a/vendor/assets/javascripts/wymeditor/skins/twopanels/skin.js +++ /dev/null @@ -1,39 +0,0 @@ -WYMeditor.SKINS.twopanels = { - - init: function(wym) { - - //move the containers panel to the left area - jQuery(wym._box).find(wym._options.containersSelector) - .appendTo("div.wym_area_left"); - - //render following sections as panels - jQuery(wym._box).find(wym._options.classesSelector + ', ' + - wym._options.containersSelector) - .addClass("wym_panel"); - - //render following sections as buttons - jQuery(wym._box).find(wym._options.toolsSelector) - .addClass("wym_buttons"); - - // auto add some margin to the main area sides if left area - // or right area are not empty (if they contain sections) - jQuery(wym._box).find("div.wym_area_right ul") - .parents("div.wym_area_right").show() - .parents(wym._options.boxSelector) - .find("div.wym_area_main") - .css({"margin-right": "155px"}); - - jQuery(wym._box).find("div.wym_area_left ul") - .parents("div.wym_area_left").show() - .parents(wym._options.boxSelector) - .find("div.wym_area_main") - .css({"margin-left": "115px"}); - - //make hover work under IE < 7 - jQuery(wym._box).find(".wym_section").hover(function(){ - jQuery(this).addClass("hover"); - },function(){ - jQuery(this).removeClass("hover"); - }); - } -}; diff --git a/vendor/assets/javascripts/wymeditor/skins/wymeditor_icon.png b/vendor/assets/javascripts/wymeditor/skins/wymeditor_icon.png deleted file mode 100644 index d4fc155fd9f3340c9b6b062775ee5c478fe925ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1028 zcmV+f1pE7mP)&r_pQr5Y@4Udpp{A~|wY%Be;Qjsm*xKFp_xQ=o(Za^ezrx3@vbn;>%A%;R z?(gyK?(e@|L*4f?A)Y;3;(!j&XyT8P^yuq`$y{oUbrmM2I zyTQT4$+^A5mYk%Qou#qp7gW&(oNkrpe9GlbNEA zm7c-H%DutH$;;4-lAFcI&AgCMga7~n3Q0skRCwByiu-%nP#nfj5KK%L5fx!>QKD@& z=2BX%tPw%osuy}iw^=u~Y&H|g)_=W+XMLXj>hrwk`+dLfdBNY60S_w!R7lCY)U_8{ z2%OjI6W)@yqYjwx1tHaf1oNr4nRk?bTrs6ntSdDrB zc|fLSC||p!s(h59C_vM6VlVJ!Yp>;g*JCD3LC>izPEQI%56j&+I=1XApLH`~117&@ zdY%|f13?gq+lJRR%%686JHs#%1KDUX6`k`U++#2FpSO+Z2wqtHL4}!j(_GEjb z>l(UTUnB2h9W|O6t?e{N%{AIl1!~)~55Biy9UurYW+TB@pX%EEcp@v*MJ%~{|=yVM0pi-$c8ic2Tn~Tbi58=7Muv6lWNf-+u%ONrXX9cN= zjPjHR93=M>PFM%Zf^u1LUjE Date: Thu, 1 Aug 2013 18:46:54 -0700 Subject: [PATCH 03/32] Update sass coffeescript and uglifier --- Gemfile | 4 ++-- Gemfile.lock | 12 ++++++------ app/controllers/dashboard/pages_controller.rb | 2 +- app/controllers/dashboard/sections_controller.rb | 2 +- app/views/dashboard/pages/_page.html.haml | 4 ++-- app/views/dashboard/pages/index.haml | 3 ++- app/views/dashboard/sections/_section.html.haml | 4 ++-- app/views/dashboard/sections/index.haml | 4 +++- app/views/layouts/sessions.html.haml | 4 ++-- 9 files changed, 21 insertions(+), 18 deletions(-) diff --git a/Gemfile b/Gemfile index a5ebd58..dd4b02b 100644 --- a/Gemfile +++ b/Gemfile @@ -31,7 +31,7 @@ group :assets do gem 'sass-rails', '~> 3.2.3' gem 'coffee-rails', '~> 3.2.1' gem 'uglifier', '>= 1.0.3' - gem 'therubyracer' + gem 'therubyracer', platforms: :ruby gem 'compass-rails' gem 'bootstrap-sass' gem 'fancybox-rails' @@ -41,7 +41,7 @@ group :development, :test do gem 'rspec-rails' gem 'single_test' gem 'launchy' - gem 'evergreen', :group => [ :test, :development ], :require => 'evergreen/rails' + gem 'evergreen', :require => 'evergreen/rails' end group :test do diff --git a/Gemfile.lock b/Gemfile.lock index 179470a..89f6819 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -76,7 +76,7 @@ GEM coffee-script (2.2.0) coffee-script-source execjs - coffee-script-source (1.2.0) + coffee-script-source (1.6.3) colored (1.2) columnize (0.3.6) compass (0.12.1) @@ -110,7 +110,7 @@ GEM json_pure launchy sinatra (~> 1.1) - execjs (1.3.0) + execjs (1.4.0) multi_json (~> 1.0) factory_girl (2.6.4) activesupport (>= 2.3.9) @@ -222,8 +222,8 @@ GEM rspec (~> 2.9.0) ruby-progressbar (1.0.2) rubyzip (0.9.9) - sass (3.1.15) - sass-rails (3.2.5) + sass (3.2.10) + sass-rails (3.2.6) railties (~> 3.2.0) sass (>= 3.1.10) tilt (~> 1.3) @@ -263,9 +263,9 @@ GEM polyglot polyglot (>= 0.3.1) tzinfo (0.3.37) - uglifier (1.2.3) + uglifier (2.1.2) execjs (>= 0.3.0) - multi_json (>= 1.0.2) + multi_json (~> 1.0, >= 1.0.2) uniform_notifier (1.0.2) warden (1.2.1) rack (>= 1.0) diff --git a/app/controllers/dashboard/pages_controller.rb b/app/controllers/dashboard/pages_controller.rb index 8e788d6..15d6c68 100644 --- a/app/controllers/dashboard/pages_controller.rb +++ b/app/controllers/dashboard/pages_controller.rb @@ -6,7 +6,7 @@ class Dashboard::PagesController < ApplicationController # GET /pages def index - @pages = Page.page params[:page] + @pages = Page.includes( :section ).page params[:page] end # GET /pages/new diff --git a/app/controllers/dashboard/sections_controller.rb b/app/controllers/dashboard/sections_controller.rb index 3de13f9..4e4d20d 100644 --- a/app/controllers/dashboard/sections_controller.rb +++ b/app/controllers/dashboard/sections_controller.rb @@ -6,7 +6,7 @@ class Dashboard::SectionsController < ApplicationController # GET /sections def index - @sections = Section.page params[:page] + @sections = Section.includes( :main_section ).page params[:page] end # GET /sections/1 diff --git a/app/views/dashboard/pages/_page.html.haml b/app/views/dashboard/pages/_page.html.haml index ab6bcbd..2adcb50 100644 --- a/app/views/dashboard/pages/_page.html.haml +++ b/app/views/dashboard/pages/_page.html.haml @@ -4,5 +4,5 @@ %td= l page.created_at, :format => :short %td= l page.updated_at, :format => :short %td - = link_to t('links.edit'), edit_dashboard_page_path( page ), :class => 'icon edit' - = link_to t('links.destroy'), dashboard_page_path( page ), :confirm => t('common.messages.are_you_sure'), :method => :delete, :class => 'icon delete' \ No newline at end of file + = link_to t('links.edit'), edit_dashboard_page_path( page.id ), :class => 'icon edit' + = link_to t('links.destroy'), dashboard_page_path( page.id ), :confirm => t('common.messages.are_you_sure'), :method => :delete, :class => 'icon delete' diff --git a/app/views/dashboard/pages/index.haml b/app/views/dashboard/pages/index.haml index dffe86c..c3fc665 100644 --- a/app/views/dashboard/pages/index.haml +++ b/app/views/dashboard/pages/index.haml @@ -12,5 +12,6 @@ %th= t 'common.fields.updated_at' %th= t 'common.messages.options' %tbody - = render :partial => 'page', :collection => @pages + = render @pages + = will_paginate @pages diff --git a/app/views/dashboard/sections/_section.html.haml b/app/views/dashboard/sections/_section.html.haml index 0ac5067..6c3738a 100644 --- a/app/views/dashboard/sections/_section.html.haml +++ b/app/views/dashboard/sections/_section.html.haml @@ -4,6 +4,6 @@ %td= l section.created_at, :format => :short %td= l section.updated_at, :format => :short %td - = link_to t('links.edit'), edit_dashboard_section_path(section), :class => 'icon edit' - = link_to t('links.destroy'), dashboard_section_path(section), :confirm => t('common.messages.are_you_sure'), :method => :delete, :class => 'icon delete' + = link_to t('links.edit'), edit_dashboard_section_path( section.id ), :class => 'icon edit' + = link_to t('links.destroy'), dashboard_section_path( section.id ), :confirm => t('common.messages.are_you_sure'), :method => :delete, :class => 'icon delete' diff --git a/app/views/dashboard/sections/index.haml b/app/views/dashboard/sections/index.haml index bc270d6..9655d30 100644 --- a/app/views/dashboard/sections/index.haml +++ b/app/views/dashboard/sections/index.haml @@ -11,5 +11,7 @@ %th= t 'common.fields.created_at' %th= t 'common.fields.updated_at' %th= t 'common.messages.options' - %tbody= render :partial => 'section', :collection => @sections + %tbody + = render @sections + = will_paginate @sections diff --git a/app/views/layouts/sessions.html.haml b/app/views/layouts/sessions.html.haml index fa7264e..ec75616 100644 --- a/app/views/layouts/sessions.html.haml +++ b/app/views/layouts/sessions.html.haml @@ -2,10 +2,10 @@ = t "devise.#{ controller_name }.#{ action_name }.title" - content_for :head do - = stylesheet_link_tag 'sessions' + = stylesheet_link_tag :sessions - content_for :top do - %a{:href =>"/"} + = link_to root_path do %h1#logo CloverInteractive = render :file => 'layouts/application' From 22d6817abd44d7a7a9489671b47e6981ad8cb22e Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Thu, 1 Aug 2013 19:41:11 -0700 Subject: [PATCH 04/32] Update test suite and get model specs green --- .gitignore | 1 + Gemfile | 14 ++--------- Gemfile.lock | 40 +++++++++++++------------------- app/assets/stylesheets/main.scss | 1 - config/database.yml | 34 ++++++++++----------------- spec/factories.rb | 4 ++-- spec/models/page_spec.rb | 24 ++++++++----------- spec/models/section_spec.rb | 15 +++++------- spec/models/setting_spec.rb | 16 ++++++------- spec/models/user_spec.rb | 21 +++++++++-------- spec/spec_helper.rb | 29 +++++++++++++++++++++-- 11 files changed, 95 insertions(+), 104 deletions(-) diff --git a/.gitignore b/.gitignore index 7230c44..03e0085 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,5 @@ public/assets Thumbs.db .bundle bin/ +coverage/* config/vhost.conf diff --git a/Gemfile b/Gemfile index dd4b02b..5fbfbb9 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,7 @@ source 'http://rubygems.org' gem 'rails', '3.2.14' +gem 'pg' gem 'bootstrap-will_paginate' gem 'haml-rails' @@ -46,18 +47,7 @@ end group :test do gem 'database_cleaner' - gem 'factory_girl_rails', '1.7.0' + gem 'factory_girl_rails' gem 'capybara-webkit' - gem 'mocha', :require => false gem 'simplecov' end - -platforms :ruby do - group :test, :development do - gem 'sqlite3' - end - - group :production do - gem 'mysql2' - end -end diff --git a/Gemfile.lock b/Gemfile.lock index 89f6819..47d27b7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -102,7 +102,7 @@ GEM actionmailer (~> 3.0) devise (>= 2.1.2) railties (~> 3.0) - diff-lcs (1.1.3) + diff-lcs (1.2.4) erubis (2.7.0) evergreen (1.0.0) capybara (~> 1.0) @@ -112,10 +112,10 @@ GEM sinatra (~> 1.1) execjs (1.4.0) multi_json (~> 1.0) - factory_girl (2.6.4) - activesupport (>= 2.3.9) - factory_girl_rails (1.7.0) - factory_girl (~> 2.6.0) + factory_girl (4.2.0) + activesupport (>= 3.0.0) + factory_girl_rails (4.2.1) + factory_girl (~> 4.2.0) railties (>= 3.0.0) fancybox-rails (0.1.4) railties (>= 3.1.0) @@ -145,13 +145,9 @@ GEM mail (2.5.4) mime-types (~> 1.16) treetop (~> 1.4.8) - metaclass (0.0.1) method_source (0.8) mime-types (1.23) - mocha (0.10.5) - metaclass (~> 0.0.1) multi_json (1.7.7) - mysql2 (0.3.11) net-scp (1.0.4) net-ssh (>= 1.99.1) net-sftp (2.0.5) @@ -161,6 +157,7 @@ GEM net-ssh (>= 1.99.1) nokogiri (1.5.5) orm_adapter (0.4.0) + pg (0.14.1) polyglot (0.3.3) pry (0.9.10) coderay (~> 1.0.5) @@ -207,19 +204,17 @@ GEM json (~> 1.4) ref (1.0.4) rmagick (2.13.2) - rspec (2.9.0) - rspec-core (~> 2.9.0) - rspec-expectations (~> 2.9.0) - rspec-mocks (~> 2.9.0) - rspec-core (2.9.0) - rspec-expectations (2.9.0) - diff-lcs (~> 1.1.3) - rspec-mocks (2.9.0) - rspec-rails (2.9.0) + rspec-core (2.14.4) + rspec-expectations (2.14.0) + diff-lcs (>= 1.1.3, < 2.0) + rspec-mocks (2.14.2) + rspec-rails (2.14.0) actionpack (>= 3.0) activesupport (>= 3.0) railties (>= 3.0) - rspec (~> 2.9.0) + rspec-core (~> 2.14.0) + rspec-expectations (~> 2.14.0) + rspec-mocks (~> 2.14.0) ruby-progressbar (1.0.2) rubyzip (0.9.9) sass (3.2.10) @@ -251,7 +246,6 @@ GEM multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) - sqlite3 (1.3.5) symbolize (4.2.0) tabs_on_rails (2.1.1) therubyracer (0.11.4) @@ -293,15 +287,14 @@ DEPENDENCIES devise devise_invitable evergreen - factory_girl_rails (= 1.7.0) + factory_girl_rails fancybox-rails friendly_id (~> 4.0.1) haml-rails jquery-rails launchy mime-types - mocha - mysql2 + pg pry-rails quiet_assets rails (= 3.2.14) @@ -312,7 +305,6 @@ DEPENDENCIES simple_form simplecov single_test - sqlite3 symbolize tabs_on_rails therubyracer diff --git a/app/assets/stylesheets/main.scss b/app/assets/stylesheets/main.scss index 83ffc5b..e0404a9 100644 --- a/app/assets/stylesheets/main.scss +++ b/app/assets/stylesheets/main.scss @@ -1,5 +1,4 @@ @import 'compass/reset'; -@import 'bootstrap'; #wrapper { .error, .warning, .info, .success { diff --git a/config/database.yml b/config/database.yml index 7551340..352ff7d 100644 --- a/config/database.yml +++ b/config/database.yml @@ -1,25 +1,15 @@ -# SQLite version 3.x -# gem install sqlite3-ruby (not necessary on OS X Leopard) -development: - adapter: sqlite3 - database: db/development.sqlite3 +defaults: &defaults + adapter: postgresql + encoding: utf8 pool: 5 - timeout: 5000 + host: localhost + username: cms + min_messages: warning -# Warning: The database defined as "test" will be erased and -# re-generated from your development database when you run "rake". -# Do not set this db to the same as development or production. -test: &test - adapter: sqlite3 - database: db/test.sqlite3 - pool: 5 - timeout: 5000 +test: + <<: *defaults + database: cms_test -production: - adapter: sqlite3 - database: db/production.sqlite3 - pool: 5 - timeout: 5000 - -cucumber: - <<: *test \ No newline at end of file +development: + <<: *defaults + database: cms_development diff --git a/spec/factories.rb b/spec/factories.rb index 43e3050..50b57b5 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -9,7 +9,7 @@ factory :user do username 'user' - email { Factory.next :email } + email { generate :email } password 'password' password_confirmation 'password' end @@ -22,7 +22,7 @@ end factory :section do - name { Factory.next :name } + name { generate :name } end factory :setting do diff --git a/spec/models/page_spec.rb b/spec/models/page_spec.rb index 3b7930c..3fd7545 100644 --- a/spec/models/page_spec.rb +++ b/spec/models/page_spec.rb @@ -1,38 +1,34 @@ require 'spec_helper' describe Page do - before :each do - @page = Factory.create :page - end + let( :page ) { create :page } describe "name" do it "must be present" do - @page.name = nil - @page.should be_invalid + page.name = nil + page.should be_invalid end it "must be unique" do - page = Factory.build :page - page.should be_invalid + new_page = build :page, name: page.name + new_page.should be_invalid end end describe "slug" do it "must be autogenerated" do - @page.slug.should be_present + page.save! + page.slug.should be_present end end it "should belong to one section" do - page = Page.new :name => 'test_name', :content => 'Test content' + page = build :page, name: 'test_name', content: 'Test content', section: nil page.should be_invalid - - @page.section.should be_present end it "should accept keywords" do - @page.keyword_list = 'this, are, some, keywords' - @page.should be_valid - @page.save.should == true + page.keyword_list = 'this, are, some, keywords' + page.should be_valid end end diff --git a/spec/models/section_spec.rb b/spec/models/section_spec.rb index 82fa3de..8b31256 100644 --- a/spec/models/section_spec.rb +++ b/spec/models/section_spec.rb @@ -1,26 +1,23 @@ require 'spec_helper' describe Section do - before :each do - @section = Factory :section, :name => "test" - end + let( :section ) { create :section, name: 'test' } describe "name" do it "should be present" do - new_section = Section.new + new_section = build :section, name: nil new_section.should be_invalid end it "should be unique" do - section = Factory.build :section, :name => "test" - section.should be_invalid + section.should be_persisted - section.name = 'new_name' - section.should be_valid + new_section = build :section, name: section.name + new_section.should be_invalid end end it "should have an slug after created" do - @section.slug.should be_present + section.slug.should be_present end end diff --git a/spec/models/setting_spec.rb b/spec/models/setting_spec.rb index e275d8b..e0a9832 100644 --- a/spec/models/setting_spec.rb +++ b/spec/models/setting_spec.rb @@ -1,35 +1,35 @@ require 'spec_helper' describe Setting do - before :each do - @theme = Factory.create :setting, :name => 'theme', :value => 'clover', :destroyable => false - end + let( :theme ) { create :setting, name: 'theme', value: 'clover', destroyable: false } describe "name" do it "must be present" do - setting = Factory.build :setting, :name => '' + setting = build :setting, name: nil setting.should be_invalid end it "must be unique" do - setting = Factory.build :setting, :name => 'theme' + theme.should be_persisted + + setting = build :setting, name: 'theme' setting.should be_invalid end it "shold be properly formatted" do - setting = Factory.build :setting, :name => 'badly formatted name ' + setting = build :setting, name: 'badly formatted name ' setting.should be_invalid end end describe "value" do it "must be present" do - setting = Factory.build :setting, :value => '' + setting = build :setting, value: '' setting.should be_invalid end end it "should not delete non destroyable settings" do - @theme.delete.should be_false + theme.delete.should be_false end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 8454e71..b79ab09 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1,33 +1,34 @@ require 'spec_helper' describe User do - before :each do - @user = Factory.create :user - end + let( :user ) { create :user } describe "email" do it "must be unique" do - user = Factory.build :user, :email => @user.email - user.should be_invalid + user.should be_persisted + + new_user = build :user, email: user.email + new_user.should be_invalid end it "must have proper format" do - user = Factory.build :user + new_user = build :user + %w/invalid_email in@va@lid invalit@..@/.each do |invalid_email| - user.email = invalid_email - user.should be_invalid + new_user.email = invalid_email + new_user.should be_invalid end end end describe "username" do it "must be present" do - user = Factory.build :user, :username => '' + user = build :user, username: nil user.should be_invalid end it "must be properly formatted" do - user = Factory.build :user, :username => '' + user = build :user, username: nil %w/&*)@user tes!@@k ASc&#))/.each do |invalid_username| user.username = invalid_username diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 0d1b441..2683aa6 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,14 +1,39 @@ # This file is copied to spec/ when you run 'rails generate rspec:install' ENV["RAILS_ENV"] ||= 'test' + +require 'simplecov' +SimpleCov.start 'rails' + require File.expand_path("../../config/environment", __FILE__) require 'rspec/rails' -require 'mocha' +require 'rspec/autorun' +require 'capybara/rspec' + +Capybara.javascript_driver = :webkit # Requires supporting ruby files with custom matchers and macros, etc, # in spec/support/ and its subdirectories. Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} RSpec.configure do |config| - config.mock_with :mocha config.use_transactional_fixtures = true + + config.before( :suite ) do + DatabaseCleaner.strategy = :truncation + DatabaseCleaner.clean_with :truncation + end + + config.before( :each ) do + DatabaseCleaner.start + end + + config.after( :each ) do + DatabaseCleaner.clean + end + + config.infer_base_class_for_anonymous_controllers = false + config.order = "random" + + config.include FactoryGirl::Syntax::Methods + config.include Devise::TestHelpers, type: :controller end From db17bffee20f2c580b75861007494c39812d538b Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Thu, 1 Aug 2013 19:42:00 -0700 Subject: [PATCH 05/32] Remove evergreen since it's now unmaintained --- Gemfile | 1 - Gemfile.lock | 14 -------------- 2 files changed, 15 deletions(-) diff --git a/Gemfile b/Gemfile index 5fbfbb9..588913b 100644 --- a/Gemfile +++ b/Gemfile @@ -42,7 +42,6 @@ group :development, :test do gem 'rspec-rails' gem 'single_test' gem 'launchy' - gem 'evergreen', :require => 'evergreen/rails' end group :test do diff --git a/Gemfile.lock b/Gemfile.lock index 47d27b7..a83d561 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -104,12 +104,6 @@ GEM railties (~> 3.0) diff-lcs (1.2.4) erubis (2.7.0) - evergreen (1.0.0) - capybara (~> 1.0) - coffee-script - json_pure - launchy - sinatra (~> 1.1) execjs (1.4.0) multi_json (~> 1.0) factory_girl (4.2.0) @@ -136,7 +130,6 @@ GEM railties (>= 3.2.0, < 5.0) thor (~> 0.14) json (1.8.0) - json_pure (1.8.0) launchy (2.3.0) addressable (~> 2.3) libv8 (3.11.8.17) @@ -170,8 +163,6 @@ GEM rack (1.4.5) rack-cache (1.2) rack (>= 0.4) - rack-protection (1.5.0) - rack rack-ssl (1.3.3) rack rack-test (0.6.2) @@ -235,10 +226,6 @@ GEM multi_json (~> 1.0) simplecov-html (~> 0.7.1) simplecov-html (0.7.1) - sinatra (1.3.6) - rack (~> 1.4) - rack-protection (~> 1.3) - tilt (~> 1.3, >= 1.3.3) single_test (0.4.4) slop (3.3.2) sprockets (2.2.2) @@ -286,7 +273,6 @@ DEPENDENCIES debugger devise devise_invitable - evergreen factory_girl_rails fancybox-rails friendly_id (~> 4.0.1) From acd8a0fac62bdb0c29191a5397d21db124aa3c4f Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Thu, 1 Aug 2013 21:14:38 -0700 Subject: [PATCH 06/32] Get controller specs green --- .travis.yml | 3 +- Gemfile.lock | 12 ++--- app/controllers/application_controller.rb | 2 +- app/controllers/pages_controller.rb | 14 +----- .../dashboard/pages_controller_spec.rb | 43 ++++++++--------- .../dashboard/sections_controller_spec.rb | 41 +++++++--------- .../dashboard/settings_controller_spec.rb | 47 +++++++------------ .../dashboard/users_controller_spec.rb | 18 ++----- spec/controllers/pages_controller_spec.rb | 32 +++++++------ spec/support/devise.rb | 3 -- 10 files changed, 86 insertions(+), 129 deletions(-) delete mode 100644 spec/support/devise.rb diff --git a/.travis.yml b/.travis.yml index 6ea2f60..465d3a9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,8 @@ before_script: "RAILS_ENV=development bundle exec rake db:migrate db:test:prepare" script: "bundle exec rake spec" rvm: - - 1.8.7 + - 2.0.0 - 1.9.2 - - ree notifications: recipients: - enrique@cloverinteractive.com diff --git a/Gemfile.lock b/Gemfile.lock index a83d561..a65d4bf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -33,7 +33,7 @@ GEM addressable (2.3.2) arel (3.0.2) awesome_print (1.1.0) - bcrypt-ruby (3.0.1) + bcrypt-ruby (3.1.1) better_errors (0.3.2) coderay (>= 1.0.0) erubis (>= 2.7.0) @@ -93,11 +93,11 @@ GEM debugger-ruby_core_source (~> 1.2.1) debugger-linecache (1.2.0) debugger-ruby_core_source (1.2.2) - devise (2.1.2) + devise (3.0.0) bcrypt-ruby (~> 3.0) orm_adapter (~> 0.1) - railties (~> 3.1) - warden (~> 1.2.1) + railties (>= 3.2.6, < 5) + warden (~> 1.2.3) devise_invitable (1.1.8) actionmailer (~> 3.0) devise (>= 2.1.2) @@ -114,7 +114,7 @@ GEM fancybox-rails (0.1.4) railties (>= 3.1.0) ffi (1.1.5) - friendly_id (4.0.8) + friendly_id (4.0.9) fssm (0.2.8.1) haml (3.1.7) haml-rails (0.3.5) @@ -248,7 +248,7 @@ GEM execjs (>= 0.3.0) multi_json (~> 1.0, >= 1.0.2) uniform_notifier (1.0.2) - warden (1.2.1) + warden (1.2.3) rack (>= 1.0) will_paginate (3.0.4) xpath (0.1.4) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 6d00948..f8f27ae 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -55,6 +55,6 @@ def unauthorized_access end def page_not_found - render 'public/404.html', :formats => [ :html ], :status => :not_found, :layout => false + render 'public/404', :formats => [ :html ], :status => :not_found, :layout => false end end diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb index bb48ba9..e73fd50 100644 --- a/app/controllers/pages_controller.rb +++ b/app/controllers/pages_controller.rb @@ -4,8 +4,8 @@ class PagesController < ApplicationController # GET /:section/:page # GET /:section/:subsection/:page def show - @page = subsection.pages.published.find( params[:page] ) if subsection - @page ||= section.pages.published.find( params[:page] ) if section + @section = Section.find params[:section] + @page = @section.pages.published.find( params[:page] ) if @section raise Clover::PageNotFoundError if @page.blank? @@ -20,14 +20,4 @@ def home @section = @page.section render :show end - - private - def subsection - @subsection ||= Section.where( :slug => params[:subsection] ).first - end - - def section - @section = @subsection.try :main_section - @section ||= Section.find params[:section] - end end diff --git a/spec/controllers/dashboard/pages_controller_spec.rb b/spec/controllers/dashboard/pages_controller_spec.rb index 4385819..2fa449a 100644 --- a/spec/controllers/dashboard/pages_controller_spec.rb +++ b/spec/controllers/dashboard/pages_controller_spec.rb @@ -1,16 +1,14 @@ require 'spec_helper' describe Dashboard::PagesController do - before :each do - @user = Factory.create :user - @section = Factory.create :section - @page = Factory.create :page, :section => @section - end + let( :user ) { create :user } + let( :section ) { create :section } + let( :page ) { create :page, section: section } + + before { page.should be_persisted } describe "when user is logged in" do - before :each do - login_as @user - end + before { sign_in user } describe "GET index" do before :each do @@ -18,7 +16,7 @@ end it "should assign @pages" do - assigns( :pages ).should == [ @page ] + assigns( :pages ).should include( page ) end it "should be successful" do @@ -50,7 +48,7 @@ describe "GET edit" do before :each do - get :edit, :id => @page + get :edit, id: page end it "should assign @page" do @@ -67,10 +65,9 @@ end describe "POST create" do - before :each do - @page_attr = Factory.attributes_for :page, :name => 'new page', :section_id => @section.id - post :create, :page => @page_attr - end + let( :page_attr ) { attributes_for :page, name: 'new page', section_id: section.id } + + before { post :create, :page => page_attr } it "should redirect to index" do response.should redirect_to( dashboard_pages_path ) @@ -82,14 +79,14 @@ end it "should render new if anything goes wrong" do - post :create, :page => @page_attr.merge( :name => @page.name ) + post :create, :page => page_attr.merge( name: page.name ) response.should render_template( :new ) end end describe "PUT update" do before :each do - put :update, :id => @page, :page => { :name => 'batman' } + put :update, :id => page, page: { name: 'batman' } end it "should redirect to index" do @@ -97,7 +94,7 @@ end it "should update @page" do - assigns( :page ).should == @page.reload + assigns( :page ).should eql( page.reload ) end it "should assign @page" do @@ -107,11 +104,11 @@ describe "DELETE destroy" do before :each do - delete :destroy, :id => @page + delete :destroy, id: page end it "should destroy page" do - Page.count.should == 0 + Page.count.should eql( 0 ) end it "should redirect to index" do @@ -125,23 +122,23 @@ it "should redirect to login when using GET" do actions = %w/index new edit/ actions.each do |action| - get action, :id => @page + get action, id: page response.should redirect_to( new_user_session_path ) end end it "should redirect to login when using POST" do - post :create, :page => Factory.attributes_for( :page ) + post :create, page: attributes_for( :page ) response.should redirect_to( new_user_session_path ) end it "should redirect to login when using PUT" do - put :update, :id => @page, :page => { :name => '' } + put :update, id: page, page: { name: '' } response.should redirect_to( new_user_session_path ) end it "should redirect to login when using DELETE" do - delete :destroy, :id => @page + delete :destroy, id: page response.should redirect_to( new_user_session_path ) end end diff --git a/spec/controllers/dashboard/sections_controller_spec.rb b/spec/controllers/dashboard/sections_controller_spec.rb index 819d2f0..3c4285a 100644 --- a/spec/controllers/dashboard/sections_controller_spec.rb +++ b/spec/controllers/dashboard/sections_controller_spec.rb @@ -1,14 +1,13 @@ require 'spec_helper' describe Dashboard::SectionsController do - before :each do - @user = Factory.create :user - @section = Factory.create :section - end + let( :user ) { create :user } + let( :section ) { create :section } describe "when user is logged in" do before :each do - login_as @user + section.should be_persisted + sign_in user end describe "GET index" do @@ -21,7 +20,7 @@ end it "should assign @sections" do - assigns( :sections ).should == [ @section ] + assigns( :sections ).should include( section ) end it "should render index" do @@ -49,7 +48,7 @@ describe "GET edit" do before :each do - get :edit, :id => @section + get :edit, id: section end it "should be successfu" do @@ -67,11 +66,7 @@ describe "POST create" do before :each do - post :create, :section => Factory.attributes_for( :section ) - end - - it "should create new section" do - Section.count.should == 2 + expect { post :create, section: attributes_for( :section ) }.to change { Section.count }.by 1 end it "should assign @section" do @@ -83,14 +78,14 @@ end it "should render new should something go wrong" do - post :create, Factory.attributes_for( :section, :name => '' ) + post :create, attributes_for( :section, name: '' ) response.should render_template( :new ) end end describe "PUT update" do before :each do - put :update, :id => @section, :section => { :name => 'batman' } + put :update, id: section, section: { name: 'batman' } end it "should assign @section" do @@ -98,7 +93,7 @@ end it "should update @section" do - assigns( :section ).should == @section + assigns( :section ).should eql( section ) end it "should redirect to index" do @@ -106,18 +101,14 @@ end it "should render edit should something go wrong" do - put :update, :id => @section, :section => { :name => '' } + put :update, id: section, section: { name: nil } response.should render_template( :edit ) end end describe "DELETE destroy" do before :each do - delete :destroy, :id => @section - end - - it "should destroy section" do - Section.count.should == 0 + expect { delete :destroy, id: section }.to change { Section.count }.by -1 end it "should redirect to index" do @@ -131,23 +122,23 @@ it "should redirect to login when using GET" do actions = %w/index new edit/ actions.each do |action| - get action, :id => @section + get action, id: section response.should redirect_to( new_user_session_path ) end end it "should redirect to login when using POST" do - post :create, :setting => Factory.attributes_for( :section ) + post :create, setting: attributes_for( :section ) response.should redirect_to( new_user_session_path ) end it "should redirect to login when using PUT" do - put :update, :id => @section, :section => { :name => 'batman' } + put :update, id: section, section: { name: 'batman' } response.should redirect_to( new_user_session_path ) end it "should redirect to login when using DELETE" do - delete :destroy, :id => @section + delete :destroy, id: section response.should redirect_to( new_user_session_path ) end end diff --git a/spec/controllers/dashboard/settings_controller_spec.rb b/spec/controllers/dashboard/settings_controller_spec.rb index 62bf879..0a7933f 100644 --- a/spec/controllers/dashboard/settings_controller_spec.rb +++ b/spec/controllers/dashboard/settings_controller_spec.rb @@ -1,15 +1,11 @@ require 'spec_helper' describe Dashboard::SettingsController do - before :each do - @user = Factory.create :user - @setting = Factory.create :setting, :name => 'test_setting', :value => 'true' - end + let( :user ) { create :user } + let( :setting ) { create :setting, name: 'test_setting', value: 'true' } describe "when user is logged in" do - before :each do - login_as @user - end + before { sign_in user } describe "GET index" do before :each do @@ -21,7 +17,7 @@ end it "should assign @settings" do - assigns( :settings ).should == [ @setting ] + assigns( :settings ).should include( setting ) end it "should render index" do @@ -49,7 +45,7 @@ describe "GET edit" do before :each do - get :edit, :id => @setting + get :edit, id: setting end it "should be successful" do @@ -67,11 +63,7 @@ describe "POST create" do before :each do - post :create, :setting => Factory.attributes_for( :setting ) - end - - it "should create setting" do - Setting.count.should == 2 + expect { post :create, setting: attributes_for( :setting ) }.to change { Setting.count }.by 1 end it "should assign @setting" do @@ -83,18 +75,18 @@ end it "should render new should anything go wrong" do - post :create, :setting => Factory.attributes_for( :setting, :name => '' ) + post :create, setting: attributes_for( :setting, name: nil ) response.should render_template( :new ) end end describe "PUT update" do before :each do - put :update, :id => @setting, :setting => { :name => 'batman' } + put :update, id: setting, setting: { name: 'batman' } end it "should update setting" do - assigns( :setting ).should == @setting.reload + assigns( :setting ).should eql( setting.reload ) end it "should assign @setting" do @@ -106,18 +98,16 @@ end it "should render edit should anything go wrong" do - put :update, :id => @setting, :setting => { :name => '' } + put :update, id: setting, setting: { name: nil } response.should render_template( :edit ) end end describe "DELETE destroy" do - before :each do - delete :destroy, :id => @setting - end + before { delete :destroy, id: setting } it "should destroy setting" do - Setting.count.should == 0 + Setting.count.should eql( 0 ) end it "should redirect to index" do @@ -125,13 +115,10 @@ end it "should not destroy if setting is not destroyable" do - setting = Factory.create :setting setting.destroyable = false setting.save! - delete :destroy, :id => setting - Setting.count.should == 1 - Setting.first.should == setting + expect { delete :destroy, :id => setting }.to_not change { Setting.count } end end end @@ -141,23 +128,23 @@ it "should redirect to login when using GET" do actions = %w/index new edit/ actions.each do |action| - get action, :id => @setting + get action, id: setting response.should redirect_to( new_user_session_path ) end end it "should redirect to login when using POST" do - post :create, :setting => Factory.attributes_for( :setting ) + post :create, setting: attributes_for( :setting ) response.should redirect_to( new_user_session_path ) end it "should redirect to login when using PUT" do - put :update, :id => @setting, :setting => { :name => 'batman' } + put :update, id: setting, setting: { name: 'batman' } response.should redirect_to( new_user_session_path ) end it "should redirect to login when using DELETE" do - delete :destroy, :id => @setting + delete :destroy, id: setting response.should redirect_to( new_user_session_path ) end end diff --git a/spec/controllers/dashboard/users_controller_spec.rb b/spec/controllers/dashboard/users_controller_spec.rb index 022448d..61fed5d 100644 --- a/spec/controllers/dashboard/users_controller_spec.rb +++ b/spec/controllers/dashboard/users_controller_spec.rb @@ -1,14 +1,10 @@ require 'spec_helper' describe Dashboard::UsersController do - before :each do - @user = Factory.create :user - end + let( :user ) { create :user } describe "when user is logged in" do - before :each do - login_as @user - end + before { sign_in user } describe "GET index" do before :each do @@ -20,7 +16,7 @@ end it "should assign @users" do - assigns( :users ).should == [ @user ] + assigns( :users ).should include( user ) end it "should render index" do @@ -30,11 +26,7 @@ describe "DELETE destroy" do before :each do - delete :destroy, :id => @user - end - - it "should delete user" do - User.count.should == 0 + expect { delete :destroy, id: user }.to change { User.count }.by -1 end it "should redirect to index" do @@ -51,7 +43,7 @@ end it "should redirect to login when using DELETE" do - delete :destroy, :id => @user + delete :destroy, id: user response.should redirect_to( new_user_session_path ) end end diff --git a/spec/controllers/pages_controller_spec.rb b/spec/controllers/pages_controller_spec.rb index e870843..56a02b8 100644 --- a/spec/controllers/pages_controller_spec.rb +++ b/spec/controllers/pages_controller_spec.rb @@ -1,22 +1,26 @@ require 'spec_helper' describe PagesController do - before :each do - @page = Factory.create :page, :home_page => true - get :show, :page => @page.slug, :section => @page.section.slug - end + let( :page ) { create :page, home_page: true } - it "response should be sucessful" do - response.should be_success - end + context 'render page' do + before( :each ) do + page.should be_persisted + get :show, page: page.slug, section: page.section.slug + end - it "should render show" do - response.should render_template( :show ) - end + it "response should be sucessful" do + response.should be_success + end + + it "should render show" do + response.should render_template( :show ) + end - it "should render show for homepage" do - get :home - response.should be_success - response.should render_template( :show ) + it "should render show for homepage" do + get :home + response.should be_success + response.should render_template( :show ) + end end end diff --git a/spec/support/devise.rb b/spec/support/devise.rb deleted file mode 100644 index 3552bea..0000000 --- a/spec/support/devise.rb +++ /dev/null @@ -1,3 +0,0 @@ -RSpec.configure do |config| - config.include Devise::TestHelpers, :type => :controller -end From 527305d2007e81ef91ca4040e4536a4ad5766729 Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Sat, 3 Aug 2013 15:34:51 -0700 Subject: [PATCH 07/32] Too soon? Remove markdown editor from our assets --- app/assets/javascripts/application.js | 1 - vendor/assets/javascripts/markdown_editor.js | 4 - .../markdown_editor/Markdown.Converter.js | 1344 ----------- .../markdown_editor/Markdown.Editor.js | 2110 ----------------- .../markdown_editor/Markdown.Sanitizer.js | 111 - .../markdown_editor/load_editor.coffee | 5 - 6 files changed, 3575 deletions(-) delete mode 100644 vendor/assets/javascripts/markdown_editor.js delete mode 100644 vendor/assets/javascripts/markdown_editor/Markdown.Converter.js delete mode 100644 vendor/assets/javascripts/markdown_editor/Markdown.Editor.js delete mode 100644 vendor/assets/javascripts/markdown_editor/Markdown.Sanitizer.js delete mode 100644 vendor/assets/javascripts/markdown_editor/load_editor.coffee diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 3897f2f..f54aadb 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -7,5 +7,4 @@ //= require jquery.easing //= require loopedslider //= require bootstrap -//= require markdown_editor //= require_tree . diff --git a/vendor/assets/javascripts/markdown_editor.js b/vendor/assets/javascripts/markdown_editor.js deleted file mode 100644 index f7b2ac5..0000000 --- a/vendor/assets/javascripts/markdown_editor.js +++ /dev/null @@ -1,4 +0,0 @@ -//= require markdown_editor/Markdown.Converter -//= require markdown_editor/Markdown.Sanitizer -//= require markdown_editor/Markdown.Editor -//= require markdown_editor/load_editor diff --git a/vendor/assets/javascripts/markdown_editor/Markdown.Converter.js b/vendor/assets/javascripts/markdown_editor/Markdown.Converter.js deleted file mode 100644 index d1a6431..0000000 --- a/vendor/assets/javascripts/markdown_editor/Markdown.Converter.js +++ /dev/null @@ -1,1344 +0,0 @@ -var Markdown; - -if (typeof exports === "object" && typeof require === "function") // we're in a CommonJS (e.g. Node.js) module - Markdown = exports; -else - Markdown = {}; - -// The following text is included for historical reasons, but should -// be taken with a pinch of salt; it's not all true anymore. - -// -// Wherever possible, Showdown is a straight, line-by-line port -// of the Perl version of Markdown. -// -// This is not a normal parser design; it's basically just a -// series of string substitutions. It's hard to read and -// maintain this way, but keeping Showdown close to the original -// design makes it easier to port new features. -// -// More importantly, Showdown behaves like markdown.pl in most -// edge cases. So web applications can do client-side preview -// in Javascript, and then build identical HTML on the server. -// -// This port needs the new RegExp functionality of ECMA 262, -// 3rd Edition (i.e. Javascript 1.5). Most modern web browsers -// should do fine. Even with the new regular expression features, -// We do a lot of work to emulate Perl's regex functionality. -// The tricky changes in this file mostly have the "attacklab:" -// label. Major or self-explanatory changes don't. -// -// Smart diff tools like Araxis Merge will be able to match up -// this file with markdown.pl in a useful way. A little tweaking -// helps: in a copy of markdown.pl, replace "#" with "//" and -// replace "$text" with "text". Be sure to ignore whitespace -// and line endings. -// - - -// -// Usage: -// -// var text = "Markdown *rocks*."; -// -// var converter = new Markdown.Converter(); -// var html = converter.makeHtml(text); -// -// alert(html); -// -// Note: move the sample code to the bottom of this -// file before uncommenting it. -// - -(function () { - - function identity(x) { return x; } - function returnFalse(x) { return false; } - - function HookCollection() { } - - HookCollection.prototype = { - - chain: function (hookname, func) { - var original = this[hookname]; - if (!original) - throw new Error("unknown hook " + hookname); - - if (original === identity) - this[hookname] = func; - else - this[hookname] = function (x) { return func(original(x)); } - }, - set: function (hookname, func) { - if (!this[hookname]) - throw new Error("unknown hook " + hookname); - this[hookname] = func; - }, - addNoop: function (hookname) { - this[hookname] = identity; - }, - addFalse: function (hookname) { - this[hookname] = returnFalse; - } - }; - - Markdown.HookCollection = HookCollection; - - // g_urls and g_titles allow arbitrary user-entered strings as keys. This - // caused an exception (and hence stopped the rendering) when the user entered - // e.g. [push] or [__proto__]. Adding a prefix to the actual key prevents this - // (since no builtin property starts with "s_"). See - // http://meta.stackoverflow.com/questions/64655/strange-wmd-bug - // (granted, switching from Array() to Object() alone would have left only __proto__ - // to be a problem) - function SaveHash() { } - SaveHash.prototype = { - set: function (key, value) { - this["s_" + key] = value; - }, - get: function (key) { - return this["s_" + key]; - } - }; - - Markdown.Converter = function () { - var pluginHooks = this.hooks = new HookCollection(); - pluginHooks.addNoop("plainLinkText"); // given a URL that was encountered by itself (without markup), should return the link text that's to be given to this link - pluginHooks.addNoop("preConversion"); // called with the orignal text as given to makeHtml. The result of this plugin hook is the actual markdown source that will be cooked - pluginHooks.addNoop("postConversion"); // called with the final cooked HTML code. The result of this plugin hook is the actual output of makeHtml - - // - // Private state of the converter instance: - // - - // Global hashes, used by various utility routines - var g_urls; - var g_titles; - var g_html_blocks; - - // Used to track when we're inside an ordered or unordered list - // (see _ProcessListItems() for details): - var g_list_level; - - this.makeHtml = function (text) { - - // - // Main function. The order in which other subs are called here is - // essential. Link and image substitutions need to happen before - // _EscapeSpecialCharsWithinTagAttributes(), so that any *'s or _'s in the - // and tags get encoded. - // - - // This will only happen if makeHtml on the same converter instance is called from a plugin hook. - // Don't do that. - if (g_urls) - throw new Error("Recursive call to converter.makeHtml"); - - // Create the private state objects. - g_urls = new SaveHash(); - g_titles = new SaveHash(); - g_html_blocks = []; - g_list_level = 0; - - text = pluginHooks.preConversion(text); - - // attacklab: Replace ~ with ~T - // This lets us use tilde as an escape char to avoid md5 hashes - // The choice of character is arbitray; anything that isn't - // magic in Markdown will work. - text = text.replace(/~/g, "~T"); - - // attacklab: Replace $ with ~D - // RegExp interprets $ as a special character - // when it's in a replacement string - text = text.replace(/\$/g, "~D"); - - // Standardize line endings - text = text.replace(/\r\n/g, "\n"); // DOS to Unix - text = text.replace(/\r/g, "\n"); // Mac to Unix - - // Make sure text begins and ends with a couple of newlines: - text = "\n\n" + text + "\n\n"; - - // Convert all tabs to spaces. - text = _Detab(text); - - // Strip any lines consisting only of spaces and tabs. - // This makes subsequent regexen easier to write, because we can - // match consecutive blank lines with /\n+/ instead of something - // contorted like /[ \t]*\n+/ . - text = text.replace(/^[ \t]+$/mg, ""); - - // Turn block-level HTML blocks into hash entries - text = _HashHTMLBlocks(text); - - // Strip link definitions, store in hashes. - text = _StripLinkDefinitions(text); - - text = _RunBlockGamut(text); - - text = _UnescapeSpecialChars(text); - - // attacklab: Restore dollar signs - text = text.replace(/~D/g, "$$"); - - // attacklab: Restore tildes - text = text.replace(/~T/g, "~"); - - text = pluginHooks.postConversion(text); - - g_html_blocks = g_titles = g_urls = null; - - return text; - }; - - function _StripLinkDefinitions(text) { - // - // Strips link definitions from text, stores the URLs and titles in - // hash references. - // - - // Link defs are in the form: ^[id]: url "optional title" - - /* - text = text.replace(/ - ^[ ]{0,3}\[(.+)\]: // id = $1 attacklab: g_tab_width - 1 - [ \t]* - \n? // maybe *one* newline - [ \t]* - ? // url = $2 - (?=\s|$) // lookahead for whitespace instead of the lookbehind removed below - [ \t]* - \n? // maybe one newline - [ \t]* - ( // (potential) title = $3 - (\n*) // any lines skipped = $4 attacklab: lookbehind removed - [ \t]+ - ["(] - (.+?) // title = $5 - [")] - [ \t]* - )? // title is optional - (?:\n+|$) - /gm, function(){...}); - */ - - text = text.replace(/^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*?(?=\s|$)[ \t]*\n?[ \t]*((\n*)["(](.+?)[")][ \t]*)?(?:\n+)/gm, - function (wholeMatch, m1, m2, m3, m4, m5) { - m1 = m1.toLowerCase(); - g_urls.set(m1, _EncodeAmpsAndAngles(m2)); // Link IDs are case-insensitive - if (m4) { - // Oops, found blank lines, so it's not a title. - // Put back the parenthetical statement we stole. - return m3; - } else if (m5) { - g_titles.set(m1, m5.replace(/"/g, """)); - } - - // Completely remove the definition from the text - return ""; - } - ); - - return text; - } - - function _HashHTMLBlocks(text) { - - // Hashify HTML blocks: - // We only want to do this for block-level HTML tags, such as headers, - // lists, and tables. That's because we still want to wrap

    s around - // "paragraphs" that are wrapped in non-block-level tags, such as anchors, - // phrase emphasis, and spans. The list of tags we're looking for is - // hard-coded: - var block_tags_a = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del" - var block_tags_b = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math" - - // First, look for nested blocks, e.g.: - //

    - //
    - // tags for inner block must be indented. - //
    - //
    - // - // The outermost tags must start at the left margin for this to match, and - // the inner nested divs must be indented. - // We need to do this before the next, more liberal match, because the next - // match will start at the first `
    ` and stop at the first `
    `. - - // attacklab: This regex can be expensive when it fails. - - /* - text = text.replace(/ - ( // save in $1 - ^ // start of line (with /m) - <($block_tags_a) // start tag = $2 - \b // word break - // attacklab: hack around khtml/pcre bug... - [^\r]*?\n // any number of lines, minimally matching - // the matching end tag - [ \t]* // trailing spaces/tabs - (?=\n+) // followed by a newline - ) // attacklab: there are sentinel newlines at end of document - /gm,function(){...}}; - */ - text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b[^\r]*?\n<\/\2>[ \t]*(?=\n+))/gm, hashElement); - - // - // Now match more liberally, simply from `\n` to `\n` - // - - /* - text = text.replace(/ - ( // save in $1 - ^ // start of line (with /m) - <($block_tags_b) // start tag = $2 - \b // word break - // attacklab: hack around khtml/pcre bug... - [^\r]*? // any number of lines, minimally matching - .* // the matching end tag - [ \t]* // trailing spaces/tabs - (?=\n+) // followed by a newline - ) // attacklab: there are sentinel newlines at end of document - /gm,function(){...}}; - */ - text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math)\b[^\r]*?.*<\/\2>[ \t]*(?=\n+)\n)/gm, hashElement); - - // Special case just for
    . It was easier to make a special case than - // to make the other regex more complicated. - - /* - text = text.replace(/ - \n // Starting after a blank line - [ ]{0,3} - ( // save in $1 - (<(hr) // start tag = $2 - \b // word break - ([^<>])*? - \/?>) // the matching end tag - [ \t]* - (?=\n{2,}) // followed by a blank line - ) - /g,hashElement); - */ - text = text.replace(/\n[ ]{0,3}((<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g, hashElement); - - // Special case for standalone HTML comments: - - /* - text = text.replace(/ - \n\n // Starting after a blank line - [ ]{0,3} // attacklab: g_tab_width - 1 - ( // save in $1 - -]|-[^>])(?:[^-]|-[^-])*)--) // see http://www.w3.org/TR/html-markup/syntax.html#comments and http://meta.stackoverflow.com/q/95256 - > - [ \t]* - (?=\n{2,}) // followed by a blank line - ) - /g,hashElement); - */ - text = text.replace(/\n\n[ ]{0,3}(-]|-[^>])(?:[^-]|-[^-])*)--)>[ \t]*(?=\n{2,}))/g, hashElement); - - // PHP and ASP-style processor instructions ( and <%...%>) - - /* - text = text.replace(/ - (?: - \n\n // Starting after a blank line - ) - ( // save in $1 - [ ]{0,3} // attacklab: g_tab_width - 1 - (?: - <([?%]) // $2 - [^\r]*? - \2> - ) - [ \t]* - (?=\n{2,}) // followed by a blank line - ) - /g,hashElement); - */ - text = text.replace(/(?:\n\n)([ ]{0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g, hashElement); - - return text; - } - - function hashElement(wholeMatch, m1) { - var blockText = m1; - - // Undo double lines - blockText = blockText.replace(/^\n+/, ""); - - // strip trailing blank lines - blockText = blockText.replace(/\n+$/g, ""); - - // Replace the element text with a marker ("~KxK" where x is its key) - blockText = "\n\n~K" + (g_html_blocks.push(blockText) - 1) + "K\n\n"; - - return blockText; - } - - function _RunBlockGamut(text, doNotUnhash) { - // - // These are all the transformations that form block-level - // tags like paragraphs, headers, and list items. - // - text = _DoHeaders(text); - - // Do Horizontal Rules: - var replacement = "
    \n"; - text = text.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm, replacement); - text = text.replace(/^[ ]{0,2}([ ]?-[ ]?){3,}[ \t]*$/gm, replacement); - text = text.replace(/^[ ]{0,2}([ ]?_[ ]?){3,}[ \t]*$/gm, replacement); - - text = _DoLists(text); - text = _DoCodeBlocks(text); - text = _DoBlockQuotes(text); - - // We already ran _HashHTMLBlocks() before, in Markdown(), but that - // was to escape raw HTML in the original Markdown source. This time, - // we're escaping the markup we've just created, so that we don't wrap - //

    tags around block-level tags. - text = _HashHTMLBlocks(text); - text = _FormParagraphs(text, doNotUnhash); - - return text; - } - - function _RunSpanGamut(text) { - // - // These are all the transformations that occur *within* block-level - // tags like paragraphs, headers, and list items. - // - - text = _DoCodeSpans(text); - text = _EscapeSpecialCharsWithinTagAttributes(text); - text = _EncodeBackslashEscapes(text); - - // Process anchor and image tags. Images must come first, - // because ![foo][f] looks like an anchor. - text = _DoImages(text); - text = _DoAnchors(text); - - // Make links out of things like `` - // Must come after _DoAnchors(), because you can use < and > - // delimiters in inline links like [this](). - text = _DoAutoLinks(text); - - text = text.replace(/~P/g, "://"); // put in place to prevent autolinking; reset now - - text = _EncodeAmpsAndAngles(text); - text = _DoItalicsAndBold(text); - - // Do hard breaks: - text = text.replace(/ +\n/g, "
    \n"); - - return text; - } - - function _EscapeSpecialCharsWithinTagAttributes(text) { - // - // Within tags -- meaning between < and > -- encode [\ ` * _] so they - // don't conflict with their use in Markdown for code, italics and strong. - // - - // Build a regex to find HTML tags and comments. See Friedl's - // "Mastering Regular Expressions", 2nd Ed., pp. 200-201. - - // SE: changed the comment part of the regex - - var regex = /(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|-]|-[^>])(?:[^-]|-[^-])*)--)>)/gi; - - text = text.replace(regex, function (wholeMatch) { - var tag = wholeMatch.replace(/(.)<\/?code>(?=.)/g, "$1`"); - tag = escapeCharacters(tag, wholeMatch.charAt(1) == "!" ? "\\`*_/" : "\\`*_"); // also escape slashes in comments to prevent autolinking there -- http://meta.stackoverflow.com/questions/95987 - return tag; - }); - - return text; - } - - function _DoAnchors(text) { - // - // Turn Markdown link shortcuts into XHTML
    tags. - // - // - // First, handle reference-style links: [link text] [id] - // - - /* - text = text.replace(/ - ( // wrap whole match in $1 - \[ - ( - (?: - \[[^\]]*\] // allow brackets nested one level - | - [^\[] // or anything else - )* - ) - \] - - [ ]? // one optional space - (?:\n[ ]*)? // one optional newline followed by spaces - - \[ - (.*?) // id = $3 - \] - ) - ()()()() // pad remaining backreferences - /g, writeAnchorTag); - */ - text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g, writeAnchorTag); - - // - // Next, inline-style links: [link text](url "optional title") - // - - /* - text = text.replace(/ - ( // wrap whole match in $1 - \[ - ( - (?: - \[[^\]]*\] // allow brackets nested one level - | - [^\[\]] // or anything else - )* - ) - \] - \( // literal paren - [ \t]* - () // no id, so leave $3 empty - ? - [ \t]* - ( // $5 - (['"]) // quote char = $6 - (.*?) // Title = $7 - \6 // matching quote - [ \t]* // ignore any spaces/tabs between closing quote and ) - )? // title is optional - \) - ) - /g, writeAnchorTag); - */ - - text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g, writeAnchorTag); - - // - // Last, handle reference-style shortcuts: [link text] - // These must come last in case you've also got [link test][1] - // or [link test](/foo) - // - - /* - text = text.replace(/ - ( // wrap whole match in $1 - \[ - ([^\[\]]+) // link text = $2; can't contain '[' or ']' - \] - ) - ()()()()() // pad rest of backreferences - /g, writeAnchorTag); - */ - text = text.replace(/(\[([^\[\]]+)\])()()()()()/g, writeAnchorTag); - - return text; - } - - function writeAnchorTag(wholeMatch, m1, m2, m3, m4, m5, m6, m7) { - if (m7 == undefined) m7 = ""; - var whole_match = m1; - var link_text = m2.replace(/:\/\//g, "~P"); // to prevent auto-linking withing the link. will be converted back after the auto-linker runs - var link_id = m3.toLowerCase(); - var url = m4; - var title = m7; - - if (url == "") { - if (link_id == "") { - // lower-case and turn embedded newlines into spaces - link_id = link_text.toLowerCase().replace(/ ?\n/g, " "); - } - url = "#" + link_id; - - if (g_urls.get(link_id) != undefined) { - url = g_urls.get(link_id); - if (g_titles.get(link_id) != undefined) { - title = g_titles.get(link_id); - } - } - else { - if (whole_match.search(/\(\s*\)$/m) > -1) { - // Special case for explicit empty url - url = ""; - } else { - return whole_match; - } - } - } - url = encodeProblemUrlChars(url); - url = escapeCharacters(url, "*_"); - var result = ""; - - return result; - } - - function _DoImages(text) { - // - // Turn Markdown image shortcuts into tags. - // - - // - // First, handle reference-style labeled images: ![alt text][id] - // - - /* - text = text.replace(/ - ( // wrap whole match in $1 - !\[ - (.*?) // alt text = $2 - \] - - [ ]? // one optional space - (?:\n[ ]*)? // one optional newline followed by spaces - - \[ - (.*?) // id = $3 - \] - ) - ()()()() // pad rest of backreferences - /g, writeImageTag); - */ - text = text.replace(/(!\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g, writeImageTag); - - // - // Next, handle inline images: ![alt text](url "optional title") - // Don't forget: encode * and _ - - /* - text = text.replace(/ - ( // wrap whole match in $1 - !\[ - (.*?) // alt text = $2 - \] - \s? // One optional whitespace character - \( // literal paren - [ \t]* - () // no id, so leave $3 empty - ? // src url = $4 - [ \t]* - ( // $5 - (['"]) // quote char = $6 - (.*?) // title = $7 - \6 // matching quote - [ \t]* - )? // title is optional - \) - ) - /g, writeImageTag); - */ - text = text.replace(/(!\[(.*?)\]\s?\([ \t]*()?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g, writeImageTag); - - return text; - } - - function attributeEncode(text) { - // unconditionally replace angle brackets here -- what ends up in an attribute (e.g. alt or title) - // never makes sense to have verbatim HTML in it (and the sanitizer would totally break it) - return text.replace(/>/g, ">").replace(/" + _RunSpanGamut(m1) + "\n\n"; } - ); - - text = text.replace(/^(.+)[ \t]*\n-+[ \t]*\n+/gm, - function (matchFound, m1) { return "

    " + _RunSpanGamut(m1) + "

    \n\n"; } - ); - - // atx-style headers: - // # Header 1 - // ## Header 2 - // ## Header 2 with closing hashes ## - // ... - // ###### Header 6 - // - - /* - text = text.replace(/ - ^(\#{1,6}) // $1 = string of #'s - [ \t]* - (.+?) // $2 = Header text - [ \t]* - \#* // optional closing #'s (not counted) - \n+ - /gm, function() {...}); - */ - - text = text.replace(/^(\#{1,6})[ \t]*(.+?)[ \t]*\#*\n+/gm, - function (wholeMatch, m1, m2) { - var h_level = m1.length; - return "" + _RunSpanGamut(m2) + "\n\n"; - } - ); - - return text; - } - - function _DoLists(text) { - // - // Form HTML ordered (numbered) and unordered (bulleted) lists. - // - - // attacklab: add sentinel to hack around khtml/safari bug: - // http://bugs.webkit.org/show_bug.cgi?id=11231 - text += "~0"; - - // Re-usable pattern to match any entirel ul or ol list: - - /* - var whole_list = / - ( // $1 = whole list - ( // $2 - [ ]{0,3} // attacklab: g_tab_width - 1 - ([*+-]|\d+[.]) // $3 = first list item marker - [ \t]+ - ) - [^\r]+? - ( // $4 - ~0 // sentinel for workaround; should be $ - | - \n{2,} - (?=\S) - (?! // Negative lookahead for another list item marker - [ \t]* - (?:[*+-]|\d+[.])[ \t]+ - ) - ) - ) - /g - */ - var whole_list = /^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm; - - if (g_list_level) { - text = text.replace(whole_list, function (wholeMatch, m1, m2) { - var list = m1; - var list_type = (m2.search(/[*+-]/g) > -1) ? "ul" : "ol"; - - var result = _ProcessListItems(list, list_type); - - // Trim any trailing whitespace, to put the closing `` - // up on the preceding line, to get it past the current stupid - // HTML block parser. This is a hack to work around the terrible - // hack that is the HTML block parser. - result = result.replace(/\s+$/, ""); - result = "<" + list_type + ">" + result + "\n"; - return result; - }); - } else { - whole_list = /(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/g; - text = text.replace(whole_list, function (wholeMatch, m1, m2, m3) { - var runup = m1; - var list = m2; - - var list_type = (m3.search(/[*+-]/g) > -1) ? "ul" : "ol"; - var result = _ProcessListItems(list, list_type); - result = runup + "<" + list_type + ">\n" + result + "\n"; - return result; - }); - } - - // attacklab: strip sentinel - text = text.replace(/~0/, ""); - - return text; - } - - var _listItemMarkers = { ol: "\\d+[.]", ul: "[*+-]" }; - - function _ProcessListItems(list_str, list_type) { - // - // Process the contents of a single ordered or unordered list, splitting it - // into individual list items. - // - // list_type is either "ul" or "ol". - - // The $g_list_level global keeps track of when we're inside a list. - // Each time we enter a list, we increment it; when we leave a list, - // we decrement. If it's zero, we're not in a list anymore. - // - // We do this because when we're not inside a list, we want to treat - // something like this: - // - // I recommend upgrading to version - // 8. Oops, now this line is treated - // as a sub-list. - // - // As a single paragraph, despite the fact that the second line starts - // with a digit-period-space sequence. - // - // Whereas when we're inside a list (or sub-list), that line will be - // treated as the start of a sub-list. What a kludge, huh? This is - // an aspect of Markdown's syntax that's hard to parse perfectly - // without resorting to mind-reading. Perhaps the solution is to - // change the syntax rules such that sub-lists must start with a - // starting cardinal number; e.g. "1." or "a.". - - g_list_level++; - - // trim trailing blank lines: - list_str = list_str.replace(/\n{2,}$/, "\n"); - - // attacklab: add sentinel to emulate \z - list_str += "~0"; - - // In the original attacklab showdown, list_type was not given to this function, and anything - // that matched /[*+-]|\d+[.]/ would just create the next
  • , causing this mismatch: - // - // Markdown rendered by WMD rendered by MarkdownSharp - // ------------------------------------------------------------------ - // 1. first 1. first 1. first - // 2. second 2. second 2. second - // - third 3. third * third - // - // We changed this to behave identical to MarkdownSharp. This is the constructed RegEx, - // with {MARKER} being one of \d+[.] or [*+-], depending on list_type: - - /* - list_str = list_str.replace(/ - (^[ \t]*) // leading whitespace = $1 - ({MARKER}) [ \t]+ // list marker = $2 - ([^\r]+? // list item text = $3 - (\n+) - ) - (?= - (~0 | \2 ({MARKER}) [ \t]+) - ) - /gm, function(){...}); - */ - - var marker = _listItemMarkers[list_type]; - var re = new RegExp("(^[ \\t]*)(" + marker + ")[ \\t]+([^\\r]+?(\\n+))(?=(~0|\\1(" + marker + ")[ \\t]+))", "gm"); - var last_item_had_a_double_newline = false; - list_str = list_str.replace(re, - function (wholeMatch, m1, m2, m3) { - var item = m3; - var leading_space = m1; - var ends_with_double_newline = /\n\n$/.test(item); - var contains_double_newline = ends_with_double_newline || item.search(/\n{2,}/) > -1; - - if (contains_double_newline || last_item_had_a_double_newline) { - item = _RunBlockGamut(_Outdent(item), /* doNotUnhash = */true); - } - else { - // Recursion for sub-lists: - item = _DoLists(_Outdent(item)); - item = item.replace(/\n$/, ""); // chomp(item) - item = _RunSpanGamut(item); - } - last_item_had_a_double_newline = ends_with_double_newline; - return "
  • " + item + "
  • \n"; - } - ); - - // attacklab: strip sentinel - list_str = list_str.replace(/~0/g, ""); - - g_list_level--; - return list_str; - } - - function _DoCodeBlocks(text) { - // - // Process Markdown `
    ` blocks.
    -            //  
    -
    -            /*
    -            text = text.replace(/
    -                (?:\n\n|^)
    -                (                               // $1 = the code block -- one or more lines, starting with a space/tab
    -                    (?:
    -                        (?:[ ]{4}|\t)           // Lines must start with a tab or a tab-width of spaces - attacklab: g_tab_width
    -                        .*\n+
    -                    )+
    -                )
    -                (\n*[ ]{0,3}[^ \t\n]|(?=~0))    // attacklab: g_tab_width
    -            /g ,function(){...});
    -            */
    -
    -            // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
    -            text += "~0";
    -
    -            text = text.replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g,
    -                function (wholeMatch, m1, m2) {
    -                    var codeblock = m1;
    -                    var nextChar = m2;
    -
    -                    codeblock = _EncodeCode(_Outdent(codeblock));
    -                    codeblock = _Detab(codeblock);
    -                    codeblock = codeblock.replace(/^\n+/g, ""); // trim leading newlines
    -                    codeblock = codeblock.replace(/\n+$/g, ""); // trim trailing whitespace
    -
    -                    codeblock = '
    ' + codeblock + '\n
    '; - - return "\n\n" + codeblock + "\n\n" + nextChar; - } - ); - - // attacklab: strip sentinel - text = text.replace(/~0/, ""); - - return text; - } - - function hashBlock(text) { - text = text.replace(/(^\n+|\n+$)/g, ""); - return "\n\n~K" + (g_html_blocks.push(text) - 1) + "K\n\n"; - } - - function _DoCodeSpans(text) { - // - // * Backtick quotes are used for spans. - // - // * You can use multiple backticks as the delimiters if you want to - // include literal backticks in the code span. So, this input: - // - // Just type ``foo `bar` baz`` at the prompt. - // - // Will translate to: - // - //

    Just type foo `bar` baz at the prompt.

    - // - // There's no arbitrary limit to the number of backticks you - // can use as delimters. If you need three consecutive backticks - // in your code, use four for delimiters, etc. - // - // * You can use spaces to get literal backticks at the edges: - // - // ... type `` `bar` `` ... - // - // Turns to: - // - // ... type `bar` ... - // - - /* - text = text.replace(/ - (^|[^\\]) // Character before opening ` can't be a backslash - (`+) // $2 = Opening run of ` - ( // $3 = The code block - [^\r]*? - [^`] // attacklab: work around lack of lookbehind - ) - \2 // Matching closer - (?!`) - /gm, function(){...}); - */ - - text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm, - function (wholeMatch, m1, m2, m3, m4) { - var c = m3; - c = c.replace(/^([ \t]*)/g, ""); // leading whitespace - c = c.replace(/[ \t]*$/g, ""); // trailing whitespace - c = _EncodeCode(c); - c = c.replace(/:\/\//g, "~P"); // to prevent auto-linking. Not necessary in code *blocks*, but in code spans. Will be converted back after the auto-linker runs. - return m1 + "" + c + ""; - } - ); - - return text; - } - - function _EncodeCode(text) { - // - // Encode/escape certain characters inside Markdown code runs. - // The point is that in code, these characters are literals, - // and lose their special Markdown meanings. - // - // Encode all ampersands; HTML entities are not - // entities within a Markdown code span. - text = text.replace(/&/g, "&"); - - // Do the angle bracket song and dance: - text = text.replace(//g, ">"); - - // Now, escape characters that are magic in Markdown: - text = escapeCharacters(text, "\*_{}[]\\", false); - - // jj the line above breaks this: - //--- - - //* Item - - // 1. Subitem - - // special char: * - //--- - - return text; - } - - function _DoItalicsAndBold(text) { - - // must go first: - text = text.replace(/([\W_]|^)(\*\*|__)(?=\S)([^\r]*?\S[\*_]*)\2([\W_]|$)/g, - "$1$3$4"); - - text = text.replace(/([\W_]|^)(\*|_)(?=\S)([^\r\*_]*?\S)\2([\W_]|$)/g, - "$1$3$4"); - - return text; - } - - function _DoBlockQuotes(text) { - - /* - text = text.replace(/ - ( // Wrap whole match in $1 - ( - ^[ \t]*>[ \t]? // '>' at the start of a line - .+\n // rest of the first line - (.+\n)* // subsequent consecutive lines - \n* // blanks - )+ - ) - /gm, function(){...}); - */ - - text = text.replace(/((^[ \t]*>[ \t]?.+\n(.+\n)*\n*)+)/gm, - function (wholeMatch, m1) { - var bq = m1; - - // attacklab: hack around Konqueror 3.5.4 bug: - // "----------bug".replace(/^-/g,"") == "bug" - - bq = bq.replace(/^[ \t]*>[ \t]?/gm, "~0"); // trim one level of quoting - - // attacklab: clean up hack - bq = bq.replace(/~0/g, ""); - - bq = bq.replace(/^[ \t]+$/gm, ""); // trim whitespace-only lines - bq = _RunBlockGamut(bq); // recurse - - bq = bq.replace(/(^|\n)/g, "$1 "); - // These leading spaces screw with
     content, so we need to fix that:
    -                    bq = bq.replace(
    -                            /(\s*
    [^\r]+?<\/pre>)/gm,
    -                        function (wholeMatch, m1) {
    -                            var pre = m1;
    -                            // attacklab: hack around Konqueror 3.5.4 bug:
    -                            pre = pre.replace(/^  /mg, "~0");
    -                            pre = pre.replace(/~0/g, "");
    -                            return pre;
    -                        });
    -
    -                    return hashBlock("
    \n" + bq + "\n
    "); - } - ); - return text; - } - - function _FormParagraphs(text, doNotUnhash) { - // - // Params: - // $text - string to process with html

    tags - // - - // Strip leading and trailing lines: - text = text.replace(/^\n+/g, ""); - text = text.replace(/\n+$/g, ""); - - var grafs = text.split(/\n{2,}/g); - var grafsOut = []; - - var markerRe = /~K(\d+)K/; - - // - // Wrap

    tags. - // - var end = grafs.length; - for (var i = 0; i < end; i++) { - var str = grafs[i]; - - // if this is an HTML marker, copy it - if (markerRe.test(str)) { - grafsOut.push(str); - } - else if (/\S/.test(str)) { - str = _RunSpanGamut(str); - str = str.replace(/^([ \t]*)/g, "

    "); - str += "

    " - grafsOut.push(str); - } - - } - // - // Unhashify HTML blocks - // - if (!doNotUnhash) { - end = grafsOut.length; - for (var i = 0; i < end; i++) { - var foundAny = true; - while (foundAny) { // we may need several runs, since the data may be nested - foundAny = false; - grafsOut[i] = grafsOut[i].replace(/~K(\d+)K/g, function (wholeMatch, id) { - foundAny = true; - return g_html_blocks[id]; - }); - } - } - } - return grafsOut.join("\n\n"); - } - - function _EncodeAmpsAndAngles(text) { - // Smart processing for ampersands and angle brackets that need to be encoded. - - // Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin: - // http://bumppo.net/projects/amputator/ - text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g, "&"); - - // Encode naked <'s - text = text.replace(/<(?![a-z\/?\$!])/gi, "<"); - - return text; - } - - function _EncodeBackslashEscapes(text) { - // - // Parameter: String. - // Returns: The string, with after processing the following backslash - // escape sequences. - // - - // attacklab: The polite way to do this is with the new - // escapeCharacters() function: - // - // text = escapeCharacters(text,"\\",true); - // text = escapeCharacters(text,"`*_{}[]()>#+-.!",true); - // - // ...but we're sidestepping its use of the (slow) RegExp constructor - // as an optimization for Firefox. This function gets called a LOT. - - text = text.replace(/\\(\\)/g, escapeCharacters_callback); - text = text.replace(/\\([`*_{}\[\]()>#+-.!])/g, escapeCharacters_callback); - return text; - } - - function _DoAutoLinks(text) { - - // note that at this point, all other URL in the text are already hyperlinked as
    - // *except* for the case - - // automatically add < and > around unadorned raw hyperlinks - // must be preceded by space/BOF and followed by non-word/EOF character - text = text.replace(/(^|\s)(https?|ftp)(:\/\/[-A-Z0-9+&@#\/%?=~_|\[\]\(\)!:,\.;]*[-A-Z0-9+&@#\/%=~_|\[\]])($|\W)/gi, "$1<$2$3>$4"); - - // autolink anything like - - var replacer = function (wholematch, m1) { return "" + pluginHooks.plainLinkText(m1) + ""; } - text = text.replace(/<((https?|ftp):[^'">\s]+)>/gi, replacer); - - // Email addresses: - /* - text = text.replace(/ - < - (?:mailto:)? - ( - [-.\w]+ - \@ - [-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+ - ) - > - /gi, _DoAutoLinks_callback()); - */ - - var email_replacer = function(wholematch, m1) { - var mailto = 'mailto:' - var link - var email - if (m1.substring(0, mailto.length) != mailto){ - link = mailto + m1; - email = m1; - } else { - link = m1; - email = m1.substring(mailto.length, m1.length); - } - return "" + pluginHooks.plainLinkText(email) + ""; - } - text = text.replace(/<((?:mailto:)?([-.\w]+\@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+))>/gi, email_replacer); - - return text; - } - - function _UnescapeSpecialChars(text) { - // - // Swap back in all the special characters we've hidden. - // - text = text.replace(/~E(\d+)E/g, - function (wholeMatch, m1) { - var charCodeToReplace = parseInt(m1); - return String.fromCharCode(charCodeToReplace); - } - ); - return text; - } - - function _Outdent(text) { - // - // Remove one level of line-leading tabs or spaces - // - - // attacklab: hack around Konqueror 3.5.4 bug: - // "----------bug".replace(/^-/g,"") == "bug" - - text = text.replace(/^(\t|[ ]{1,4})/gm, "~0"); // attacklab: g_tab_width - - // attacklab: clean up hack - text = text.replace(/~0/g, "") - - return text; - } - - function _Detab(text) { - if (!/\t/.test(text)) - return text; - - var spaces = [" ", " ", " ", " "], - skew = 0, - v; - - return text.replace(/[\n\t]/g, function (match, offset) { - if (match === "\n") { - skew = offset + 1; - return match; - } - v = (offset - skew) % 4; - skew = offset + 1; - return spaces[v]; - }); - } - - // - // attacklab: Utility functions - // - - var _problemUrlChars = /(?:["'*()[\]:]|~D)/g; - - // hex-encodes some unusual "problem" chars in URLs to avoid URL detection problems - function encodeProblemUrlChars(url) { - if (!url) - return ""; - - var len = url.length; - - return url.replace(_problemUrlChars, function (match, offset) { - if (match == "~D") // escape for dollar - return "%24"; - if (match == ":") { - if (offset == len - 1 || /[0-9\/]/.test(url.charAt(offset + 1))) - return ":"; - if (url.substring(0, 'mailto:'.length) === 'mailto:') - return ":"; - if (url.substring(0, 'magnet:'.length) === 'magnet:') - return ":"; - } - return "%" + match.charCodeAt(0).toString(16); - }); - } - - - function escapeCharacters(text, charsToEscape, afterBackslash) { - // First we have to escape the escape characters so that - // we can build a character class out of them - var regexString = "([" + charsToEscape.replace(/([\[\]\\])/g, "\\$1") + "])"; - - if (afterBackslash) { - regexString = "\\\\" + regexString; - } - - var regex = new RegExp(regexString, "g"); - text = text.replace(regex, escapeCharacters_callback); - - return text; - } - - - function escapeCharacters_callback(wholeMatch, m1) { - var charCodeToEscape = m1.charCodeAt(0); - return "~E" + charCodeToEscape + "E"; - } - - }; // end of the Markdown.Converter constructor - -})(); diff --git a/vendor/assets/javascripts/markdown_editor/Markdown.Editor.js b/vendor/assets/javascripts/markdown_editor/Markdown.Editor.js deleted file mode 100644 index d229fcd..0000000 --- a/vendor/assets/javascripts/markdown_editor/Markdown.Editor.js +++ /dev/null @@ -1,2110 +0,0 @@ -// needs Markdown.Converter.js at the moment - -(function () { - - var util = {}, - position = {}, - ui = {}, - doc = window.document, - re = window.RegExp, - nav = window.navigator, - SETTINGS = { lineLength: 72 }, - - // Used to work around some browser bugs where we can't use feature testing. - uaSniffed = { - isIE: /msie/.test(nav.userAgent.toLowerCase()), - isIE_5or6: /msie 6/.test(nav.userAgent.toLowerCase()) || /msie 5/.test(nav.userAgent.toLowerCase()), - isOpera: /opera/.test(nav.userAgent.toLowerCase()) - }; - - - // ------------------------------------------------------------------- - // YOUR CHANGES GO HERE - // - // I've tried to localize the things you are likely to change to - // this area. - // ------------------------------------------------------------------- - - // The text that appears on the upper part of the dialog box when - // entering links. - var linkDialogText = "

    http://example.com/ \"optional title\"

    "; - var imageDialogText = "

    http://example.com/images/diagram.jpg \"optional title\"

    "; - - // The default text that appears in the dialog input box when entering - // links. - var imageDefaultText = "http://"; - var linkDefaultText = "http://"; - - var defaultHelpHoverTitle = "Markdown Editing Help"; - - // ------------------------------------------------------------------- - // END OF YOUR CHANGES - // ------------------------------------------------------------------- - - // help, if given, should have a property "handler", the click handler for the help button, - // and can have an optional property "title" for the button's tooltip (defaults to "Markdown Editing Help"). - // If help isn't given, not help button is created. - // - // The constructed editor object has the methods: - // - getConverter() returns the markdown converter object that was passed to the constructor - // - run() actually starts the editor; should be called after all necessary plugins are registered. Calling this more than once is a no-op. - // - refreshPreview() forces the preview to be updated. This method is only available after run() was called. - Markdown.Editor = function (markdownConverter, idPostfix, help) { - - idPostfix = idPostfix || ""; - - var hooks = this.hooks = new Markdown.HookCollection(); - hooks.addNoop("onPreviewRefresh"); // called with no arguments after the preview has been refreshed - hooks.addNoop("postBlockquoteCreation"); // called with the user's selection *after* the blockquote was created; should return the actual to-be-inserted text - hooks.addFalse("insertImageDialog"); /* called with one parameter: a callback to be called with the URL of the image. If the application creates - * its own image insertion dialog, this hook should return true, and the callback should be called with the chosen - * image url (or null if the user cancelled). If this hook returns false, the default dialog will be used. - */ - - this.getConverter = function () { return markdownConverter; } - - var that = this, - panels; - - this.run = function () { - if (panels) - return; // already initialized - - panels = new PanelCollection(idPostfix); - var commandManager = new CommandManager(hooks); - var previewManager = new PreviewManager(markdownConverter, panels, function () { hooks.onPreviewRefresh(); }); - var undoManager, uiManager; - - if (!/\?noundo/.test(doc.location.href)) { - undoManager = new UndoManager(function () { - previewManager.refresh(); - if (uiManager) // not available on the first call - uiManager.setUndoRedoButtonStates(); - }, panels); - this.textOperation = function (f) { - undoManager.setCommandMode(); - f(); - that.refreshPreview(); - } - } - - uiManager = new UIManager(idPostfix, panels, undoManager, previewManager, commandManager, help); - uiManager.setUndoRedoButtonStates(); - - var forceRefresh = that.refreshPreview = function () { previewManager.refresh(true); }; - - forceRefresh(); - }; - - } - - // before: contains all the text in the input box BEFORE the selection. - // after: contains all the text in the input box AFTER the selection. - function Chunks() { } - - // startRegex: a regular expression to find the start tag - // endRegex: a regular expresssion to find the end tag - Chunks.prototype.findTags = function (startRegex, endRegex) { - - var chunkObj = this; - var regex; - - if (startRegex) { - - regex = util.extendRegExp(startRegex, "", "$"); - - this.before = this.before.replace(regex, - function (match) { - chunkObj.startTag = chunkObj.startTag + match; - return ""; - }); - - regex = util.extendRegExp(startRegex, "^", ""); - - this.selection = this.selection.replace(regex, - function (match) { - chunkObj.startTag = chunkObj.startTag + match; - return ""; - }); - } - - if (endRegex) { - - regex = util.extendRegExp(endRegex, "", "$"); - - this.selection = this.selection.replace(regex, - function (match) { - chunkObj.endTag = match + chunkObj.endTag; - return ""; - }); - - regex = util.extendRegExp(endRegex, "^", ""); - - this.after = this.after.replace(regex, - function (match) { - chunkObj.endTag = match + chunkObj.endTag; - return ""; - }); - } - }; - - // If remove is false, the whitespace is transferred - // to the before/after regions. - // - // If remove is true, the whitespace disappears. - Chunks.prototype.trimWhitespace = function (remove) { - var beforeReplacer, afterReplacer, that = this; - if (remove) { - beforeReplacer = afterReplacer = ""; - } else { - beforeReplacer = function (s) { that.before += s; return ""; } - afterReplacer = function (s) { that.after = s + that.after; return ""; } - } - - this.selection = this.selection.replace(/^(\s*)/, beforeReplacer).replace(/(\s*)$/, afterReplacer); - }; - - - Chunks.prototype.skipLines = function (nLinesBefore, nLinesAfter, findExtraNewlines) { - - if (nLinesBefore === undefined) { - nLinesBefore = 1; - } - - if (nLinesAfter === undefined) { - nLinesAfter = 1; - } - - nLinesBefore++; - nLinesAfter++; - - var regexText; - var replacementText; - - // chrome bug ... documented at: http://meta.stackoverflow.com/questions/63307/blockquote-glitch-in-editor-in-chrome-6-and-7/65985#65985 - if (navigator.userAgent.match(/Chrome/)) { - "X".match(/()./); - } - - this.selection = this.selection.replace(/(^\n*)/, ""); - - this.startTag = this.startTag + re.$1; - - this.selection = this.selection.replace(/(\n*$)/, ""); - this.endTag = this.endTag + re.$1; - this.startTag = this.startTag.replace(/(^\n*)/, ""); - this.before = this.before + re.$1; - this.endTag = this.endTag.replace(/(\n*$)/, ""); - this.after = this.after + re.$1; - - if (this.before) { - - regexText = replacementText = ""; - - while (nLinesBefore--) { - regexText += "\\n?"; - replacementText += "\n"; - } - - if (findExtraNewlines) { - regexText = "\\n*"; - } - this.before = this.before.replace(new re(regexText + "$", ""), replacementText); - } - - if (this.after) { - - regexText = replacementText = ""; - - while (nLinesAfter--) { - regexText += "\\n?"; - replacementText += "\n"; - } - if (findExtraNewlines) { - regexText = "\\n*"; - } - - this.after = this.after.replace(new re(regexText, ""), replacementText); - } - }; - - // end of Chunks - - // A collection of the important regions on the page. - // Cached so we don't have to keep traversing the DOM. - // Also holds ieCachedRange and ieCachedScrollTop, where necessary; working around - // this issue: - // Internet explorer has problems with CSS sprite buttons that use HTML - // lists. When you click on the background image "button", IE will - // select the non-existent link text and discard the selection in the - // textarea. The solution to this is to cache the textarea selection - // on the button's mousedown event and set a flag. In the part of the - // code where we need to grab the selection, we check for the flag - // and, if it's set, use the cached area instead of querying the - // textarea. - // - // This ONLY affects Internet Explorer (tested on versions 6, 7 - // and 8) and ONLY on button clicks. Keyboard shortcuts work - // normally since the focus never leaves the textarea. - function PanelCollection(postfix) { - this.buttonBar = doc.getElementById("wmd-button-bar" + postfix); - this.preview = doc.getElementById("wmd-preview" + postfix); - this.input = doc.getElementById("wmd-input" + postfix); - }; - - // Returns true if the DOM element is visible, false if it's hidden. - // Checks if display is anything other than none. - util.isVisible = function (elem) { - - if (window.getComputedStyle) { - // Most browsers - return window.getComputedStyle(elem, null).getPropertyValue("display") !== "none"; - } - else if (elem.currentStyle) { - // IE - return elem.currentStyle["display"] !== "none"; - } - }; - - - // Adds a listener callback to a DOM element which is fired on a specified - // event. - util.addEvent = function (elem, event, listener) { - if (elem.attachEvent) { - // IE only. The "on" is mandatory. - elem.attachEvent("on" + event, listener); - } - else { - // Other browsers. - elem.addEventListener(event, listener, false); - } - }; - - - // Removes a listener callback from a DOM element which is fired on a specified - // event. - util.removeEvent = function (elem, event, listener) { - if (elem.detachEvent) { - // IE only. The "on" is mandatory. - elem.detachEvent("on" + event, listener); - } - else { - // Other browsers. - elem.removeEventListener(event, listener, false); - } - }; - - // Converts \r\n and \r to \n. - util.fixEolChars = function (text) { - text = text.replace(/\r\n/g, "\n"); - text = text.replace(/\r/g, "\n"); - return text; - }; - - // Extends a regular expression. Returns a new RegExp - // using pre + regex + post as the expression. - // Used in a few functions where we have a base - // expression and we want to pre- or append some - // conditions to it (e.g. adding "$" to the end). - // The flags are unchanged. - // - // regex is a RegExp, pre and post are strings. - util.extendRegExp = function (regex, pre, post) { - - if (pre === null || pre === undefined) { - pre = ""; - } - if (post === null || post === undefined) { - post = ""; - } - - var pattern = regex.toString(); - var flags; - - // Replace the flags with empty space and store them. - pattern = pattern.replace(/\/([gim]*)$/, function (wholeMatch, flagsPart) { - flags = flagsPart; - return ""; - }); - - // Remove the slash delimiters on the regular expression. - pattern = pattern.replace(/(^\/|\/$)/g, ""); - pattern = pre + pattern + post; - - return new re(pattern, flags); - } - - // UNFINISHED - // The assignment in the while loop makes jslint cranky. - // I'll change it to a better loop later. - position.getTop = function (elem, isInner) { - var result = elem.offsetTop; - if (!isInner) { - while (elem = elem.offsetParent) { - result += elem.offsetTop; - } - } - return result; - }; - - position.getHeight = function (elem) { - return elem.offsetHeight || elem.scrollHeight; - }; - - position.getWidth = function (elem) { - return elem.offsetWidth || elem.scrollWidth; - }; - - position.getPageSize = function () { - - var scrollWidth, scrollHeight; - var innerWidth, innerHeight; - - // It's not very clear which blocks work with which browsers. - if (self.innerHeight && self.scrollMaxY) { - scrollWidth = doc.body.scrollWidth; - scrollHeight = self.innerHeight + self.scrollMaxY; - } - else if (doc.body.scrollHeight > doc.body.offsetHeight) { - scrollWidth = doc.body.scrollWidth; - scrollHeight = doc.body.scrollHeight; - } - else { - scrollWidth = doc.body.offsetWidth; - scrollHeight = doc.body.offsetHeight; - } - - if (self.innerHeight) { - // Non-IE browser - innerWidth = self.innerWidth; - innerHeight = self.innerHeight; - } - else if (doc.documentElement && doc.documentElement.clientHeight) { - // Some versions of IE (IE 6 w/ a DOCTYPE declaration) - innerWidth = doc.documentElement.clientWidth; - innerHeight = doc.documentElement.clientHeight; - } - else if (doc.body) { - // Other versions of IE - innerWidth = doc.body.clientWidth; - innerHeight = doc.body.clientHeight; - } - - var maxWidth = Math.max(scrollWidth, innerWidth); - var maxHeight = Math.max(scrollHeight, innerHeight); - return [maxWidth, maxHeight, innerWidth, innerHeight]; - }; - - // Handles pushing and popping TextareaStates for undo/redo commands. - // I should rename the stack variables to list. - function UndoManager(callback, panels) { - - var undoObj = this; - var undoStack = []; // A stack of undo states - var stackPtr = 0; // The index of the current state - var mode = "none"; - var lastState; // The last state - var timer; // The setTimeout handle for cancelling the timer - var inputStateObj; - - // Set the mode for later logic steps. - var setMode = function (newMode, noSave) { - if (mode != newMode) { - mode = newMode; - if (!noSave) { - saveState(); - } - } - - if (!uaSniffed.isIE || mode != "moving") { - timer = setTimeout(refreshState, 1); - } - else { - inputStateObj = null; - } - }; - - var refreshState = function (isInitialState) { - inputStateObj = new TextareaState(panels, isInitialState); - timer = undefined; - }; - - this.setCommandMode = function () { - mode = "command"; - saveState(); - timer = setTimeout(refreshState, 0); - }; - - this.canUndo = function () { - return stackPtr > 1; - }; - - this.canRedo = function () { - if (undoStack[stackPtr + 1]) { - return true; - } - return false; - }; - - // Removes the last state and restores it. - this.undo = function () { - - if (undoObj.canUndo()) { - if (lastState) { - // What about setting state -1 to null or checking for undefined? - lastState.restore(); - lastState = null; - } - else { - undoStack[stackPtr] = new TextareaState(panels); - undoStack[--stackPtr].restore(); - - if (callback) { - callback(); - } - } - } - - mode = "none"; - panels.input.focus(); - refreshState(); - }; - - // Redo an action. - this.redo = function () { - - if (undoObj.canRedo()) { - - undoStack[++stackPtr].restore(); - - if (callback) { - callback(); - } - } - - mode = "none"; - panels.input.focus(); - refreshState(); - }; - - // Push the input area state to the stack. - var saveState = function () { - var currState = inputStateObj || new TextareaState(panels); - - if (!currState) { - return false; - } - if (mode == "moving") { - if (!lastState) { - lastState = currState; - } - return; - } - if (lastState) { - if (undoStack[stackPtr - 1].text != lastState.text) { - undoStack[stackPtr++] = lastState; - } - lastState = null; - } - undoStack[stackPtr++] = currState; - undoStack[stackPtr + 1] = null; - if (callback) { - callback(); - } - }; - - var handleCtrlYZ = function (event) { - - var handled = false; - - if (event.ctrlKey || event.metaKey) { - - // IE and Opera do not support charCode. - var keyCode = event.charCode || event.keyCode; - var keyCodeChar = String.fromCharCode(keyCode); - - switch (keyCodeChar) { - - case "y": - undoObj.redo(); - handled = true; - break; - - case "z": - if (!event.shiftKey) { - undoObj.undo(); - } - else { - undoObj.redo(); - } - handled = true; - break; - } - } - - if (handled) { - if (event.preventDefault) { - event.preventDefault(); - } - if (window.event) { - window.event.returnValue = false; - } - return; - } - }; - - // Set the mode depending on what is going on in the input area. - var handleModeChange = function (event) { - - if (!event.ctrlKey && !event.metaKey) { - - var keyCode = event.keyCode; - - if ((keyCode >= 33 && keyCode <= 40) || (keyCode >= 63232 && keyCode <= 63235)) { - // 33 - 40: page up/dn and arrow keys - // 63232 - 63235: page up/dn and arrow keys on safari - setMode("moving"); - } - else if (keyCode == 8 || keyCode == 46 || keyCode == 127) { - // 8: backspace - // 46: delete - // 127: delete - setMode("deleting"); - } - else if (keyCode == 13) { - // 13: Enter - setMode("newlines"); - } - else if (keyCode == 27) { - // 27: escape - setMode("escape"); - } - else if ((keyCode < 16 || keyCode > 20) && keyCode != 91) { - // 16-20 are shift, etc. - // 91: left window key - // I think this might be a little messed up since there are - // a lot of nonprinting keys above 20. - setMode("typing"); - } - } - }; - - var setEventHandlers = function () { - util.addEvent(panels.input, "keypress", function (event) { - // keyCode 89: y - // keyCode 90: z - if ((event.ctrlKey || event.metaKey) && (event.keyCode == 89 || event.keyCode == 90)) { - event.preventDefault(); - } - }); - - var handlePaste = function () { - if (uaSniffed.isIE || (inputStateObj && inputStateObj.text != panels.input.value)) { - if (timer == undefined) { - mode = "paste"; - saveState(); - refreshState(); - } - } - }; - - util.addEvent(panels.input, "keydown", handleCtrlYZ); - util.addEvent(panels.input, "keydown", handleModeChange); - util.addEvent(panels.input, "mousedown", function () { - setMode("moving"); - }); - - panels.input.onpaste = handlePaste; - panels.input.ondrop = handlePaste; - }; - - var init = function () { - setEventHandlers(); - refreshState(true); - saveState(); - }; - - init(); - } - - // end of UndoManager - - // The input textarea state/contents. - // This is used to implement undo/redo by the undo manager. - function TextareaState(panels, isInitialState) { - - // Aliases - var stateObj = this; - var inputArea = panels.input; - this.init = function () { - if (!util.isVisible(inputArea)) { - return; - } - if (!isInitialState && doc.activeElement && doc.activeElement !== inputArea) { // this happens when tabbing out of the input box - return; - } - - this.setInputAreaSelectionStartEnd(); - this.scrollTop = inputArea.scrollTop; - if (!this.text && inputArea.selectionStart || inputArea.selectionStart === 0) { - this.text = inputArea.value; - } - - } - - // Sets the selected text in the input box after we've performed an - // operation. - this.setInputAreaSelection = function () { - - if (!util.isVisible(inputArea)) { - return; - } - - if (inputArea.selectionStart !== undefined && !uaSniffed.isOpera) { - - inputArea.focus(); - inputArea.selectionStart = stateObj.start; - inputArea.selectionEnd = stateObj.end; - inputArea.scrollTop = stateObj.scrollTop; - } - else if (doc.selection) { - - if (doc.activeElement && doc.activeElement !== inputArea) { - return; - } - - inputArea.focus(); - var range = inputArea.createTextRange(); - range.moveStart("character", -inputArea.value.length); - range.moveEnd("character", -inputArea.value.length); - range.moveEnd("character", stateObj.end); - range.moveStart("character", stateObj.start); - range.select(); - } - }; - - this.setInputAreaSelectionStartEnd = function () { - - if (!panels.ieCachedRange && (inputArea.selectionStart || inputArea.selectionStart === 0)) { - - stateObj.start = inputArea.selectionStart; - stateObj.end = inputArea.selectionEnd; - } - else if (doc.selection) { - - stateObj.text = util.fixEolChars(inputArea.value); - - // IE loses the selection in the textarea when buttons are - // clicked. On IE we cache the selection. Here, if something is cached, - // we take it. - var range = panels.ieCachedRange || doc.selection.createRange(); - - var fixedRange = util.fixEolChars(range.text); - var marker = "\x07"; - var markedRange = marker + fixedRange + marker; - range.text = markedRange; - var inputText = util.fixEolChars(inputArea.value); - - range.moveStart("character", -markedRange.length); - range.text = fixedRange; - - stateObj.start = inputText.indexOf(marker); - stateObj.end = inputText.lastIndexOf(marker) - marker.length; - - var len = stateObj.text.length - util.fixEolChars(inputArea.value).length; - - if (len) { - range.moveStart("character", -fixedRange.length); - while (len--) { - fixedRange += "\n"; - stateObj.end += 1; - } - range.text = fixedRange; - } - - if (panels.ieCachedRange) - stateObj.scrollTop = panels.ieCachedScrollTop; // this is set alongside with ieCachedRange - - panels.ieCachedRange = null; - - this.setInputAreaSelection(); - } - }; - - // Restore this state into the input area. - this.restore = function () { - - if (stateObj.text != undefined && stateObj.text != inputArea.value) { - inputArea.value = stateObj.text; - } - this.setInputAreaSelection(); - inputArea.scrollTop = stateObj.scrollTop; - }; - - // Gets a collection of HTML chunks from the inptut textarea. - this.getChunks = function () { - - var chunk = new Chunks(); - chunk.before = util.fixEolChars(stateObj.text.substring(0, stateObj.start)); - chunk.startTag = ""; - chunk.selection = util.fixEolChars(stateObj.text.substring(stateObj.start, stateObj.end)); - chunk.endTag = ""; - chunk.after = util.fixEolChars(stateObj.text.substring(stateObj.end)); - chunk.scrollTop = stateObj.scrollTop; - - return chunk; - }; - - // Sets the TextareaState properties given a chunk of markdown. - this.setChunks = function (chunk) { - - chunk.before = chunk.before + chunk.startTag; - chunk.after = chunk.endTag + chunk.after; - - this.start = chunk.before.length; - this.end = chunk.before.length + chunk.selection.length; - this.text = chunk.before + chunk.selection + chunk.after; - this.scrollTop = chunk.scrollTop; - }; - this.init(); - }; - - function PreviewManager(converter, panels, previewRefreshCallback) { - - var managerObj = this; - var timeout; - var elapsedTime; - var oldInputText; - var maxDelay = 3000; - var startType = "delayed"; // The other legal value is "manual" - - // Adds event listeners to elements - var setupEvents = function (inputElem, listener) { - - util.addEvent(inputElem, "input", listener); - inputElem.onpaste = listener; - inputElem.ondrop = listener; - - util.addEvent(inputElem, "keypress", listener); - util.addEvent(inputElem, "keydown", listener); - }; - - var getDocScrollTop = function () { - - var result = 0; - - if (window.innerHeight) { - result = window.pageYOffset; - } - else - if (doc.documentElement && doc.documentElement.scrollTop) { - result = doc.documentElement.scrollTop; - } - else - if (doc.body) { - result = doc.body.scrollTop; - } - - return result; - }; - - var makePreviewHtml = function () { - - // If there is no registered preview panel - // there is nothing to do. - if (!panels.preview) - return; - - - var text = panels.input.value; - if (text && text == oldInputText) { - return; // Input text hasn't changed. - } - else { - oldInputText = text; - } - - var prevTime = new Date().getTime(); - - text = converter.makeHtml(text); - - // Calculate the processing time of the HTML creation. - // It's used as the delay time in the event listener. - var currTime = new Date().getTime(); - elapsedTime = currTime - prevTime; - - pushPreviewHtml(text); - }; - - // setTimeout is already used. Used as an event listener. - var applyTimeout = function () { - - if (timeout) { - clearTimeout(timeout); - timeout = undefined; - } - - if (startType !== "manual") { - - var delay = 0; - - if (startType === "delayed") { - delay = elapsedTime; - } - - if (delay > maxDelay) { - delay = maxDelay; - } - timeout = setTimeout(makePreviewHtml, delay); - } - }; - - var getScaleFactor = function (panel) { - if (panel.scrollHeight <= panel.clientHeight) { - return 1; - } - return panel.scrollTop / (panel.scrollHeight - panel.clientHeight); - }; - - var setPanelScrollTops = function () { - if (panels.preview) { - panels.preview.scrollTop = (panels.preview.scrollHeight - panels.preview.clientHeight) * getScaleFactor(panels.preview); - } - }; - - this.refresh = function (requiresRefresh) { - - if (requiresRefresh) { - oldInputText = ""; - makePreviewHtml(); - } - else { - applyTimeout(); - } - }; - - this.processingTime = function () { - return elapsedTime; - }; - - var isFirstTimeFilled = true; - - // IE doesn't let you use innerHTML if the element is contained somewhere in a table - // (which is the case for inline editing) -- in that case, detach the element, set the - // value, and reattach. Yes, that *is* ridiculous. - var ieSafePreviewSet = function (text) { - var preview = panels.preview; - var parent = preview.parentNode; - var sibling = preview.nextSibling; - parent.removeChild(preview); - preview.innerHTML = text; - if (!sibling) - parent.appendChild(preview); - else - parent.insertBefore(preview, sibling); - } - - var nonSuckyBrowserPreviewSet = function (text) { - panels.preview.innerHTML = text; - } - - var previewSetter; - - var previewSet = function (text) { - if (previewSetter) - return previewSetter(text); - - try { - nonSuckyBrowserPreviewSet(text); - previewSetter = nonSuckyBrowserPreviewSet; - } catch (e) { - previewSetter = ieSafePreviewSet; - previewSetter(text); - } - }; - - var pushPreviewHtml = function (text) { - - var emptyTop = position.getTop(panels.input) - getDocScrollTop(); - - if (panels.preview) { - previewSet(text); - previewRefreshCallback(); - } - - setPanelScrollTops(); - - if (isFirstTimeFilled) { - isFirstTimeFilled = false; - return; - } - - var fullTop = position.getTop(panels.input) - getDocScrollTop(); - - if (uaSniffed.isIE) { - setTimeout(function () { - window.scrollBy(0, fullTop - emptyTop); - }, 0); - } - else { - window.scrollBy(0, fullTop - emptyTop); - } - }; - - var init = function () { - - setupEvents(panels.input, applyTimeout); - makePreviewHtml(); - - if (panels.preview) { - panels.preview.scrollTop = 0; - } - }; - - init(); - }; - - - // This simulates a modal dialog box and asks for the URL when you - // click the hyperlink or image buttons. - // - // text: The html for the input box. - // defaultInputText: The default value that appears in the input box. - // callback: The function which is executed when the prompt is dismissed, either via OK or Cancel. - // It receives a single argument; either the entered text (if OK was chosen) or null (if Cancel - // was chosen). - ui.prompt = function (title, text, defaultInputText, callback) { - - // These variables need to be declared at this level since they are used - // in multiple functions. - var dialog; // The dialog box. - var input; // The text box where you enter the hyperlink. - - - if (defaultInputText === undefined) { - defaultInputText = ""; - } - - // Used as a keydown event handler. Esc dismisses the prompt. - // Key code 27 is ESC. - var checkEscape = function (key) { - var code = (key.charCode || key.keyCode); - if (code === 27) { - close(true); - } - }; - - // Dismisses the hyperlink input box. - // isCancel is true if we don't care about the input text. - // isCancel is false if we are going to keep the text. - var close = function (isCancel) { - util.removeEvent(doc.body, "keydown", checkEscape); - var text = input.value; - - if (isCancel) { - text = null; - } - else { - // Fixes common pasting errors. - text = text.replace(/^http:\/\/(https?|ftp):\/\//, '$1://'); - if (!/^(?:https?|ftp):\/\//.test(text)) - text = 'http://' + text; - } - - $(dialog).modal('hide'); - - callback(text); - return false; - }; - - - - // Create the text input box form/window. - var createDialog = function () { - // - - // The main dialog box. - dialog = doc.createElement("div"); - dialog.className = "modal hide fade"; - dialog.style.display = "none"; - - // The header. - var header = doc.createElement("div"); - header.className = "modal-header"; - header.innerHTML = '×

    '+title+'

    '; - dialog.appendChild(header); - - // The body. - var body = doc.createElement("div"); - body.className = "modal-body"; - dialog.appendChild(body); - - // The footer. - var footer = doc.createElement("div"); - footer.className = "modal-footer"; - dialog.appendChild(footer); - - // The dialog text. - var question = doc.createElement("p"); - question.innerHTML = text; - question.style.padding = "5px"; - body.appendChild(question); - - // The web form container for the text box and buttons. - var form = doc.createElement("form"), - style = form.style; - form.onsubmit = function () { return close(false); }; - style.padding = "0"; - style.margin = "0"; - body.appendChild(form); - - // The input text box - input = doc.createElement("input"); - input.type = "text"; - input.value = defaultInputText; - style = input.style; - style.display = "block"; - style.width = "80%"; - style.marginLeft = style.marginRight = "auto"; - form.appendChild(input); - - // The ok button - var okButton = doc.createElement("button"); - okButton.className = "btn btn-primary"; - okButton.type = "button"; - okButton.onclick = function () { return close(false); }; - okButton.innerHTML = "OK"; - - // The cancel button - var cancelButton = doc.createElement("button"); - cancelButton.className = "btn btn-primary"; - cancelButton.type = "button"; - cancelButton.onclick = function () { return close(true); }; - cancelButton.innerHTML = "Cancel"; - - footer.appendChild(okButton); - footer.appendChild(cancelButton); - - util.addEvent(doc.body, "keydown", checkEscape); - - doc.body.appendChild(dialog); - - }; - - // Why is this in a zero-length timeout? - // Is it working around a browser bug? - setTimeout(function () { - - createDialog(); - - var defTextLen = defaultInputText.length; - if (input.selectionStart !== undefined) { - input.selectionStart = 0; - input.selectionEnd = defTextLen; - } - else if (input.createTextRange) { - var range = input.createTextRange(); - range.collapse(false); - range.moveStart("character", -defTextLen); - range.moveEnd("character", defTextLen); - range.select(); - } - - $(dialog).on('shown', function () { - input.focus(); - }) - - $(dialog).on('hidden', function () { - dialog.parentNode.removeChild(dialog); - }) - - $(dialog).modal() - - }, 0); - }; - - function UIManager(postfix, panels, undoManager, previewManager, commandManager, helpOptions) { - - var inputBox = panels.input, - buttons = {}; // buttons.undo, buttons.link, etc. The actual DOM elements. - - makeSpritedButtonRow(); - - var keyEvent = "keydown"; - if (uaSniffed.isOpera) { - keyEvent = "keypress"; - } - - util.addEvent(inputBox, keyEvent, function (key) { - - // Check to see if we have a button key and, if so execute the callback. - if ((key.ctrlKey || key.metaKey) && !key.altKey && !key.shiftKey) { - - var keyCode = key.charCode || key.keyCode; - var keyCodeStr = String.fromCharCode(keyCode).toLowerCase(); - - switch (keyCodeStr) { - case "b": - doClick(buttons.bold); - break; - case "i": - doClick(buttons.italic); - break; - case "l": - doClick(buttons.link); - break; - case "q": - doClick(buttons.quote); - break; - case "k": - doClick(buttons.code); - break; - case "g": - doClick(buttons.image); - break; - case "o": - doClick(buttons.olist); - break; - case "u": - doClick(buttons.ulist); - break; - case "h": - doClick(buttons.heading); - break; - case "r": - doClick(buttons.hr); - break; - case "y": - doClick(buttons.redo); - break; - case "z": - if (key.shiftKey) { - doClick(buttons.redo); - } - else { - doClick(buttons.undo); - } - break; - default: - return; - } - - - if (key.preventDefault) { - key.preventDefault(); - } - - if (window.event) { - window.event.returnValue = false; - } - } - }); - - // Auto-indent on shift-enter - util.addEvent(inputBox, "keyup", function (key) { - if (key.shiftKey && !key.ctrlKey && !key.metaKey) { - var keyCode = key.charCode || key.keyCode; - // Character 13 is Enter - if (keyCode === 13) { - var fakeButton = {}; - fakeButton.textOp = bindCommand("doAutoindent"); - doClick(fakeButton); - } - } - }); - - // special handler because IE clears the context of the textbox on ESC - if (uaSniffed.isIE) { - util.addEvent(inputBox, "keydown", function (key) { - var code = key.keyCode; - if (code === 27) { - return false; - } - }); - } - - - // Perform the button's action. - function doClick(button) { - - inputBox.focus(); - - if (button.textOp) { - - if (undoManager) { - undoManager.setCommandMode(); - } - - var state = new TextareaState(panels); - - if (!state) { - return; - } - - var chunks = state.getChunks(); - - // Some commands launch a "modal" prompt dialog. Javascript - // can't really make a modal dialog box and the WMD code - // will continue to execute while the dialog is displayed. - // This prevents the dialog pattern I'm used to and means - // I can't do something like this: - // - // var link = CreateLinkDialog(); - // makeMarkdownLink(link); - // - // Instead of this straightforward method of handling a - // dialog I have to pass any code which would execute - // after the dialog is dismissed (e.g. link creation) - // in a function parameter. - // - // Yes this is awkward and I think it sucks, but there's - // no real workaround. Only the image and link code - // create dialogs and require the function pointers. - var fixupInputArea = function () { - - inputBox.focus(); - - if (chunks) { - state.setChunks(chunks); - } - - state.restore(); - previewManager.refresh(); - }; - - var noCleanup = button.textOp(chunks, fixupInputArea); - - if (!noCleanup) { - fixupInputArea(); - } - - } - - if (button.execute) { - button.execute(undoManager); - } - }; - - function setupButton(button, isEnabled) { - - if (isEnabled) { - button.disabled = false; - - if (!button.isHelp) { - button.onclick = function () { - if (this.onmouseout) { - this.onmouseout(); - } - doClick(this); - return false; - } - } - } - else { - button.disabled = true; - } - } - - function bindCommand(method) { - if (typeof method === "string") - method = commandManager[method]; - return function () { method.apply(commandManager, arguments); } - } - - function makeSpritedButtonRow() { - - var buttonBar = panels.buttonBar; - var buttonRow = document.createElement("div"); - buttonRow.id = "wmd-button-row" + postfix; - buttonRow.className = 'btn-toolbar'; - buttonRow = buttonBar.appendChild(buttonRow); - - var makeButton = function (id, title, icon, textOp, group) { - var button = document.createElement("button"); - button.className = "btn"; - var buttonImage = document.createElement("i"); - buttonImage.className = icon; - button.id = id + postfix; - button.appendChild(buttonImage); - button.title = title; - $(button).tooltip({placement: 'bottom'}) - if (textOp) - button.textOp = textOp; - setupButton(button, true); - if (group) { - group.appendChild(button); - } else { - buttonRow.appendChild(button); - } - return button; - }; - var makeGroup = function (num) { - var group = document.createElement("div"); - group.className = "btn-group wmd-button-group" + num; - group.id = "wmd-button-group" + num + postfix; - buttonRow.appendChild(group); - return group - } - - group1 = makeGroup(1); - buttons.bold = makeButton("wmd-bold-button", "Bold - Ctrl+B", "icon-bold", bindCommand("doBold"), group1); - buttons.italic = makeButton("wmd-italic-button", "Italic - Ctrl+I", "icon-italic", bindCommand("doItalic"), group1); - - group2 = makeGroup(2); - buttons.link = makeButton("wmd-link-button", "Link - Ctrl+L", "icon-link", bindCommand(function (chunk, postProcessing) { - return this.doLinkOrImage(chunk, postProcessing, false); - }), group2); - buttons.quote = makeButton("wmd-quote-button", "Blockquote - Ctrl+Q", "icon-blockquote", bindCommand("doBlockquote"), group2); - buttons.code = makeButton("wmd-code-button", "Code Sample - Ctrl+K", "icon-code", bindCommand("doCode"), group2); - buttons.image = makeButton("wmd-image-button", "Image - Ctrl+G", "icon-picture", bindCommand(function (chunk, postProcessing) { - return this.doLinkOrImage(chunk, postProcessing, true); - }), group2); - - group3 = makeGroup(3); - buttons.olist = makeButton("wmd-olist-button", "Numbered List - Ctrl+O", "icon-list", bindCommand(function (chunk, postProcessing) { - this.doList(chunk, postProcessing, true); - }), group3); - buttons.ulist = makeButton("wmd-ulist-button", "Bulleted List - Ctrl+U", "icon-bullet-list", bindCommand(function (chunk, postProcessing) { - this.doList(chunk, postProcessing, false); - }), group3); - buttons.heading = makeButton("wmd-heading-button", "Heading - Ctrl+H", "icon-header", bindCommand("doHeading"), group3); - buttons.hr = makeButton("wmd-hr-button", "Horizontal Rule - Ctrl+R", "icon-hr-line", bindCommand("doHorizontalRule"), group3); - - group4 = makeGroup(4); - buttons.undo = makeButton("wmd-undo-button", "Undo - Ctrl+Z", "icon-undo", null, group4); - buttons.undo.execute = function (manager) { if (manager) manager.undo(); }; - - var redoTitle = /win/.test(nav.platform.toLowerCase()) ? - "Redo - Ctrl+Y" : - "Redo - Ctrl+Shift+Z"; // mac and other non-Windows platforms - - buttons.redo = makeButton("wmd-redo-button", redoTitle, "icon-share-alt", null, group4); - buttons.redo.execute = function (manager) { if (manager) manager.redo(); }; - - if (helpOptions) { - group5 = makeGroup(5); - group5.className = group5.className + " pull-right"; - var helpButton = document.createElement("button"); - var helpButtonImage = document.createElement("i"); - helpButtonImage.className = "icon-question-sign"; - helpButton.appendChild(helpButtonImage); - helpButton.className = "btn"; - helpButton.id = "wmd-help-button" + postfix; - helpButton.isHelp = true; - helpButton.title = helpOptions.title || defaultHelpHoverTitle; - $(helpButton).tooltip({placement: 'bottom'}) - helpButton.onclick = helpOptions.handler; - - setupButton(helpButton, true); - group5.appendChild(helpButton); - buttons.help = helpButton; - } - - setUndoRedoButtonStates(); - } - - function setUndoRedoButtonStates() { - if (undoManager) { - setupButton(buttons.undo, undoManager.canUndo()); - setupButton(buttons.redo, undoManager.canRedo()); - } - }; - - this.setUndoRedoButtonStates = setUndoRedoButtonStates; - - } - - function CommandManager(pluginHooks) { - this.hooks = pluginHooks; - } - - var commandProto = CommandManager.prototype; - - // The markdown symbols - 4 spaces = code, > = blockquote, etc. - commandProto.prefixes = "(?:\\s{4,}|\\s*>|\\s*-\\s+|\\s*\\d+\\.|=|\\+|-|_|\\*|#|\\s*\\[[^\n]]+\\]:)"; - - // Remove markdown symbols from the chunk selection. - commandProto.unwrap = function (chunk) { - var txt = new re("([^\\n])\\n(?!(\\n|" + this.prefixes + "))", "g"); - chunk.selection = chunk.selection.replace(txt, "$1 $2"); - }; - - commandProto.wrap = function (chunk, len) { - this.unwrap(chunk); - var regex = new re("(.{1," + len + "})( +|$\\n?)", "gm"), - that = this; - - chunk.selection = chunk.selection.replace(regex, function (line, marked) { - if (new re("^" + that.prefixes, "").test(line)) { - return line; - } - return marked + "\n"; - }); - - chunk.selection = chunk.selection.replace(/\s+$/, ""); - }; - - commandProto.doBold = function (chunk, postProcessing) { - return this.doBorI(chunk, postProcessing, 2, "strong text"); - }; - - commandProto.doItalic = function (chunk, postProcessing) { - return this.doBorI(chunk, postProcessing, 1, "emphasized text"); - }; - - // chunk: The selected region that will be enclosed with */** - // nStars: 1 for italics, 2 for bold - // insertText: If you just click the button without highlighting text, this gets inserted - commandProto.doBorI = function (chunk, postProcessing, nStars, insertText) { - - // Get rid of whitespace and fixup newlines. - chunk.trimWhitespace(); - chunk.selection = chunk.selection.replace(/\n{2,}/g, "\n"); - - // Look for stars before and after. Is the chunk already marked up? - // note that these regex matches cannot fail - var starsBefore = /(\**$)/.exec(chunk.before)[0]; - var starsAfter = /(^\**)/.exec(chunk.after)[0]; - - var prevStars = Math.min(starsBefore.length, starsAfter.length); - - // Remove stars if we have to since the button acts as a toggle. - if ((prevStars >= nStars) && (prevStars != 2 || nStars != 1)) { - chunk.before = chunk.before.replace(re("[*]{" + nStars + "}$", ""), ""); - chunk.after = chunk.after.replace(re("^[*]{" + nStars + "}", ""), ""); - } - else if (!chunk.selection && starsAfter) { - // It's not really clear why this code is necessary. It just moves - // some arbitrary stuff around. - chunk.after = chunk.after.replace(/^([*_]*)/, ""); - chunk.before = chunk.before.replace(/(\s?)$/, ""); - var whitespace = re.$1; - chunk.before = chunk.before + starsAfter + whitespace; - } - else { - - // In most cases, if you don't have any selected text and click the button - // you'll get a selected, marked up region with the default text inserted. - if (!chunk.selection && !starsAfter) { - chunk.selection = insertText; - } - - // Add the true markup. - var markup = nStars <= 1 ? "*" : "**"; // shouldn't the test be = ? - chunk.before = chunk.before + markup; - chunk.after = markup + chunk.after; - } - - return; - }; - - commandProto.stripLinkDefs = function (text, defsToAdd) { - - text = text.replace(/^[ ]{0,3}\[(\d+)\]:[ \t]*\n?[ \t]*?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|$)/gm, - function (totalMatch, id, link, newlines, title) { - defsToAdd[id] = totalMatch.replace(/\s*$/, ""); - if (newlines) { - // Strip the title and return that separately. - defsToAdd[id] = totalMatch.replace(/["(](.+?)[")]$/, ""); - return newlines + title; - } - return ""; - }); - - return text; - }; - - commandProto.addLinkDef = function (chunk, linkDef) { - - var refNumber = 0; // The current reference number - var defsToAdd = {}; // - // Start with a clean slate by removing all previous link definitions. - chunk.before = this.stripLinkDefs(chunk.before, defsToAdd); - chunk.selection = this.stripLinkDefs(chunk.selection, defsToAdd); - chunk.after = this.stripLinkDefs(chunk.after, defsToAdd); - - var defs = ""; - var regex = /(\[)((?:\[[^\]]*\]|[^\[\]])*)(\][ ]?(?:\n[ ]*)?\[)(\d+)(\])/g; - - var addDefNumber = function (def) { - refNumber++; - def = def.replace(/^[ ]{0,3}\[(\d+)\]:/, " [" + refNumber + "]:"); - defs += "\n" + def; - }; - - // note that - // a) the recursive call to getLink cannot go infinite, because by definition - // of regex, inner is always a proper substring of wholeMatch, and - // b) more than one level of nesting is neither supported by the regex - // nor making a lot of sense (the only use case for nesting is a linked image) - var getLink = function (wholeMatch, before, inner, afterInner, id, end) { - inner = inner.replace(regex, getLink); - if (defsToAdd[id]) { - addDefNumber(defsToAdd[id]); - return before + inner + afterInner + refNumber + end; - } - return wholeMatch; - }; - - chunk.before = chunk.before.replace(regex, getLink); - - if (linkDef) { - addDefNumber(linkDef); - } - else { - chunk.selection = chunk.selection.replace(regex, getLink); - } - - var refOut = refNumber; - - chunk.after = chunk.after.replace(regex, getLink); - - if (chunk.after) { - chunk.after = chunk.after.replace(/\n*$/, ""); - } - if (!chunk.after) { - chunk.selection = chunk.selection.replace(/\n*$/, ""); - } - - chunk.after += "\n\n" + defs; - - return refOut; - }; - - // takes the line as entered into the add link/as image dialog and makes - // sure the URL and the optinal title are "nice". - function properlyEncoded(linkdef) { - return linkdef.replace(/^\s*(.*?)(?:\s+"(.+)")?\s*$/, function (wholematch, link, title) { - link = link.replace(/\?.*$/, function (querypart) { - return querypart.replace(/\+/g, " "); // in the query string, a plus and a space are identical - }); - link = decodeURIComponent(link); // unencode first, to prevent double encoding - link = encodeURI(link).replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29'); - link = link.replace(/\?.*$/, function (querypart) { - return querypart.replace(/\+/g, "%2b"); // since we replaced plus with spaces in the query part, all pluses that now appear where originally encoded - }); - if (title) { - title = title.trim ? title.trim() : title.replace(/^\s*/, "").replace(/\s*$/, ""); - title = $.trim(title).replace(/"/g, "quot;").replace(/\(/g, "(").replace(/\)/g, ")").replace(//g, ">"); - } - return title ? link + ' "' + title + '"' : link; - }); - } - - commandProto.doLinkOrImage = function (chunk, postProcessing, isImage) { - - chunk.trimWhitespace(); - chunk.findTags(/\s*!?\[/, /\][ ]?(?:\n[ ]*)?(\[.*?\])?/); - var background; - - if (chunk.endTag.length > 1 && chunk.startTag.length > 0) { - - chunk.startTag = chunk.startTag.replace(/!?\[/, ""); - chunk.endTag = ""; - this.addLinkDef(chunk, null); - - } - else { - - // We're moving start and end tag back into the selection, since (as we're in the else block) we're not - // *removing* a link, but *adding* one, so whatever findTags() found is now back to being part of the - // link text. linkEnteredCallback takes care of escaping any brackets. - chunk.selection = chunk.startTag + chunk.selection + chunk.endTag; - chunk.startTag = chunk.endTag = ""; - - if (/\n\n/.test(chunk.selection)) { - this.addLinkDef(chunk, null); - return; - } - var that = this; - // The function to be executed when you enter a link and press OK or Cancel. - // Marks up the link and adds the ref. - var linkEnteredCallback = function (link) { - - if (link !== null) { - // ( $1 - // [^\\] anything that's not a backslash - // (?:\\\\)* an even number (this includes zero) of backslashes - // ) - // (?= followed by - // [[\]] an opening or closing bracket - // ) - // - // In other words, a non-escaped bracket. These have to be escaped now to make sure they - // don't count as the end of the link or similar. - // Note that the actual bracket has to be a lookahead, because (in case of to subsequent brackets), - // the bracket in one match may be the "not a backslash" character in the next match, so it - // should not be consumed by the first match. - // The "prepend a space and finally remove it" steps makes sure there is a "not a backslash" at the - // start of the string, so this also works if the selection begins with a bracket. We cannot solve - // this by anchoring with ^, because in the case that the selection starts with two brackets, this - // would mean a zero-width match at the start. Since zero-width matches advance the string position, - // the first bracket could then not act as the "not a backslash" for the second. - chunk.selection = (" " + chunk.selection).replace(/([^\\](?:\\\\)*)(?=[[\]])/g, "$1\\").substr(1); - - var linkDef = " [999]: " + properlyEncoded(link); - - var num = that.addLinkDef(chunk, linkDef); - chunk.startTag = isImage ? "![" : "["; - chunk.endTag = "][" + num + "]"; - - if (!chunk.selection) { - if (isImage) { - chunk.selection = "enter image description here"; - } - else { - chunk.selection = "enter link description here"; - } - } - } - postProcessing(); - }; - - - if (isImage) { - if (!this.hooks.insertImageDialog(linkEnteredCallback)) - ui.prompt('Insert Image', imageDialogText, imageDefaultText, linkEnteredCallback); - } - else { - ui.prompt('Insert Link', linkDialogText, linkDefaultText, linkEnteredCallback); - } - return true; - } - }; - - // When making a list, hitting shift-enter will put your cursor on the next line - // at the current indent level. - commandProto.doAutoindent = function (chunk, postProcessing) { - - var commandMgr = this, - fakeSelection = false; - - chunk.before = chunk.before.replace(/(\n|^)[ ]{0,3}([*+-]|\d+[.])[ \t]*\n$/, "\n\n"); - chunk.before = chunk.before.replace(/(\n|^)[ ]{0,3}>[ \t]*\n$/, "\n\n"); - chunk.before = chunk.before.replace(/(\n|^)[ \t]+\n$/, "\n\n"); - - // There's no selection, end the cursor wasn't at the end of the line: - // The user wants to split the current list item / code line / blockquote line - // (for the latter it doesn't really matter) in two. Temporarily select the - // (rest of the) line to achieve this. - if (!chunk.selection && !/^[ \t]*(?:\n|$)/.test(chunk.after)) { - chunk.after = chunk.after.replace(/^[^\n]*/, function (wholeMatch) { - chunk.selection = wholeMatch; - return ""; - }); - fakeSelection = true; - } - - if (/(\n|^)[ ]{0,3}([*+-]|\d+[.])[ \t]+.*\n$/.test(chunk.before)) { - if (commandMgr.doList) { - commandMgr.doList(chunk); - } - } - if (/(\n|^)[ ]{0,3}>[ \t]+.*\n$/.test(chunk.before)) { - if (commandMgr.doBlockquote) { - commandMgr.doBlockquote(chunk); - } - } - if (/(\n|^)(\t|[ ]{4,}).*\n$/.test(chunk.before)) { - if (commandMgr.doCode) { - commandMgr.doCode(chunk); - } - } - - if (fakeSelection) { - chunk.after = chunk.selection + chunk.after; - chunk.selection = ""; - } - }; - - commandProto.doBlockquote = function (chunk, postProcessing) { - - chunk.selection = chunk.selection.replace(/^(\n*)([^\r]+?)(\n*)$/, - function (totalMatch, newlinesBefore, text, newlinesAfter) { - chunk.before += newlinesBefore; - chunk.after = newlinesAfter + chunk.after; - return text; - }); - - chunk.before = chunk.before.replace(/(>[ \t]*)$/, - function (totalMatch, blankLine) { - chunk.selection = blankLine + chunk.selection; - return ""; - }); - - chunk.selection = chunk.selection.replace(/^(\s|>)+$/, ""); - chunk.selection = chunk.selection || "Blockquote"; - - // The original code uses a regular expression to find out how much of the - // text *directly before* the selection already was a blockquote: - - /* - if (chunk.before) { - chunk.before = chunk.before.replace(/\n?$/, "\n"); - } - chunk.before = chunk.before.replace(/(((\n|^)(\n[ \t]*)*>(.+\n)*.*)+(\n[ \t]*)*$)/, - function (totalMatch) { - chunk.startTag = totalMatch; - return ""; - }); - */ - - // This comes down to: - // Go backwards as many lines a possible, such that each line - // a) starts with ">", or - // b) is almost empty, except for whitespace, or - // c) is preceeded by an unbroken chain of non-empty lines - // leading up to a line that starts with ">" and at least one more character - // and in addition - // d) at least one line fulfills a) - // - // Since this is essentially a backwards-moving regex, it's susceptible to - // catstrophic backtracking and can cause the browser to hang; - // see e.g. http://meta.stackoverflow.com/questions/9807. - // - // Hence we replaced this by a simple state machine that just goes through the - // lines and checks for a), b), and c). - - var match = "", - leftOver = "", - line; - if (chunk.before) { - var lines = chunk.before.replace(/\n$/, "").split("\n"); - var inChain = false; - for (var i = 0; i < lines.length; i++) { - var good = false; - line = lines[i]; - inChain = inChain && line.length > 0; // c) any non-empty line continues the chain - if (/^>/.test(line)) { // a) - good = true; - if (!inChain && line.length > 1) // c) any line that starts with ">" and has at least one more character starts the chain - inChain = true; - } else if (/^[ \t]*$/.test(line)) { // b) - good = true; - } else { - good = inChain; // c) the line is not empty and does not start with ">", so it matches if and only if we're in the chain - } - if (good) { - match += line + "\n"; - } else { - leftOver += match + line; - match = "\n"; - } - } - if (!/(^|\n)>/.test(match)) { // d) - leftOver += match; - match = ""; - } - } - - chunk.startTag = match; - chunk.before = leftOver; - - // end of change - - if (chunk.after) { - chunk.after = chunk.after.replace(/^\n?/, "\n"); - } - - chunk.after = chunk.after.replace(/^(((\n|^)(\n[ \t]*)*>(.+\n)*.*)+(\n[ \t]*)*)/, - function (totalMatch) { - chunk.endTag = totalMatch; - return ""; - } - ); - - var replaceBlanksInTags = function (useBracket) { - - var replacement = useBracket ? "> " : ""; - - if (chunk.startTag) { - chunk.startTag = chunk.startTag.replace(/\n((>|\s)*)\n$/, - function (totalMatch, markdown) { - return "\n" + markdown.replace(/^[ ]{0,3}>?[ \t]*$/gm, replacement) + "\n"; - }); - } - if (chunk.endTag) { - chunk.endTag = chunk.endTag.replace(/^\n((>|\s)*)\n/, - function (totalMatch, markdown) { - return "\n" + markdown.replace(/^[ ]{0,3}>?[ \t]*$/gm, replacement) + "\n"; - }); - } - }; - - if (/^(?![ ]{0,3}>)/m.test(chunk.selection)) { - this.wrap(chunk, SETTINGS.lineLength - 2); - chunk.selection = chunk.selection.replace(/^/gm, "> "); - replaceBlanksInTags(true); - chunk.skipLines(); - } else { - chunk.selection = chunk.selection.replace(/^[ ]{0,3}> ?/gm, ""); - this.unwrap(chunk); - replaceBlanksInTags(false); - - if (!/^(\n|^)[ ]{0,3}>/.test(chunk.selection) && chunk.startTag) { - chunk.startTag = chunk.startTag.replace(/\n{0,2}$/, "\n\n"); - } - - if (!/(\n|^)[ ]{0,3}>.*$/.test(chunk.selection) && chunk.endTag) { - chunk.endTag = chunk.endTag.replace(/^\n{0,2}/, "\n\n"); - } - } - - chunk.selection = this.hooks.postBlockquoteCreation(chunk.selection); - - if (!/\n/.test(chunk.selection)) { - chunk.selection = chunk.selection.replace(/^(> *)/, - function (wholeMatch, blanks) { - chunk.startTag += blanks; - return ""; - }); - } - }; - - commandProto.doCode = function (chunk, postProcessing) { - - var hasTextBefore = /\S[ ]*$/.test(chunk.before); - var hasTextAfter = /^[ ]*\S/.test(chunk.after); - - // Use 'four space' markdown if the selection is on its own - // line or is multiline. - if ((!hasTextAfter && !hasTextBefore) || /\n/.test(chunk.selection)) { - - chunk.before = chunk.before.replace(/[ ]{4}$/, - function (totalMatch) { - chunk.selection = totalMatch + chunk.selection; - return ""; - }); - - var nLinesBack = 1; - var nLinesForward = 1; - - if (/(\n|^)(\t|[ ]{4,}).*\n$/.test(chunk.before)) { - nLinesBack = 0; - } - if (/^\n(\t|[ ]{4,})/.test(chunk.after)) { - nLinesForward = 0; - } - - chunk.skipLines(nLinesBack, nLinesForward); - - if (!chunk.selection) { - chunk.startTag = " "; - chunk.selection = "enter code here"; - } - else { - if (/^[ ]{0,3}\S/m.test(chunk.selection)) { - if (/\n/.test(chunk.selection)) - chunk.selection = chunk.selection.replace(/^/gm, " "); - else // if it's not multiline, do not select the four added spaces; this is more consistent with the doList behavior - chunk.before += " "; - } - else { - chunk.selection = chunk.selection.replace(/^[ ]{4}/gm, ""); - } - } - } - else { - // Use backticks (`) to delimit the code block. - - chunk.trimWhitespace(); - chunk.findTags(/`/, /`/); - - if (!chunk.startTag && !chunk.endTag) { - chunk.startTag = chunk.endTag = "`"; - if (!chunk.selection) { - chunk.selection = "enter code here"; - } - } - else if (chunk.endTag && !chunk.startTag) { - chunk.before += chunk.endTag; - chunk.endTag = ""; - } - else { - chunk.startTag = chunk.endTag = ""; - } - } - }; - - commandProto.doList = function (chunk, postProcessing, isNumberedList) { - - // These are identical except at the very beginning and end. - // Should probably use the regex extension function to make this clearer. - var previousItemsRegex = /(\n|^)(([ ]{0,3}([*+-]|\d+[.])[ \t]+.*)(\n.+|\n{2,}([*+-].*|\d+[.])[ \t]+.*|\n{2,}[ \t]+\S.*)*)\n*$/; - var nextItemsRegex = /^\n*(([ ]{0,3}([*+-]|\d+[.])[ \t]+.*)(\n.+|\n{2,}([*+-].*|\d+[.])[ \t]+.*|\n{2,}[ \t]+\S.*)*)\n*/; - - // The default bullet is a dash but others are possible. - // This has nothing to do with the particular HTML bullet, - // it's just a markdown bullet. - var bullet = "-"; - - // The number in a numbered list. - var num = 1; - - // Get the item prefix - e.g. " 1. " for a numbered list, " - " for a bulleted list. - var getItemPrefix = function () { - var prefix; - if (isNumberedList) { - prefix = " " + num + ". "; - num++; - } - else { - prefix = " " + bullet + " "; - } - return prefix; - }; - - // Fixes the prefixes of the other list items. - var getPrefixedItem = function (itemText) { - - // The numbering flag is unset when called by autoindent. - if (isNumberedList === undefined) { - isNumberedList = /^\s*\d/.test(itemText); - } - - // Renumber/bullet the list element. - itemText = itemText.replace(/^[ ]{0,3}([*+-]|\d+[.])\s/gm, - function (_) { - return getItemPrefix(); - }); - - return itemText; - }; - - chunk.findTags(/(\n|^)*[ ]{0,3}([*+-]|\d+[.])\s+/, null); - - if (chunk.before && !/\n$/.test(chunk.before) && !/^\n/.test(chunk.startTag)) { - chunk.before += chunk.startTag; - chunk.startTag = ""; - } - - if (chunk.startTag) { - - var hasDigits = /\d+[.]/.test(chunk.startTag); - chunk.startTag = ""; - chunk.selection = chunk.selection.replace(/\n[ ]{4}/g, "\n"); - this.unwrap(chunk); - chunk.skipLines(); - - if (hasDigits) { - // Have to renumber the bullet points if this is a numbered list. - chunk.after = chunk.after.replace(nextItemsRegex, getPrefixedItem); - } - if (isNumberedList == hasDigits) { - return; - } - } - - var nLinesUp = 1; - - chunk.before = chunk.before.replace(previousItemsRegex, - function (itemText) { - if (/^\s*([*+-])/.test(itemText)) { - bullet = re.$1; - } - nLinesUp = /[^\n]\n\n[^\n]/.test(itemText) ? 1 : 0; - return getPrefixedItem(itemText); - }); - - if (!chunk.selection) { - chunk.selection = "List item"; - } - - var prefix = getItemPrefix(); - - var nLinesDown = 1; - - chunk.after = chunk.after.replace(nextItemsRegex, - function (itemText) { - nLinesDown = /[^\n]\n\n[^\n]/.test(itemText) ? 1 : 0; - return getPrefixedItem(itemText); - }); - - chunk.trimWhitespace(true); - chunk.skipLines(nLinesUp, nLinesDown, true); - chunk.startTag = prefix; - var spaces = prefix.replace(/./g, " "); - this.wrap(chunk, SETTINGS.lineLength - spaces.length); - chunk.selection = chunk.selection.replace(/\n/g, "\n" + spaces); - - }; - - commandProto.doHeading = function (chunk, postProcessing) { - - // Remove leading/trailing whitespace and reduce internal spaces to single spaces. - chunk.selection = chunk.selection.replace(/\s+/g, " "); - chunk.selection = chunk.selection.replace(/(^\s+|\s+$)/g, ""); - - // If we clicked the button with no selected text, we just - // make a level 2 hash header around some default text. - if (!chunk.selection) { - chunk.startTag = "## "; - chunk.selection = "Heading"; - chunk.endTag = " ##"; - return; - } - - var headerLevel = 0; // The existing header level of the selected text. - - // Remove any existing hash heading markdown and save the header level. - chunk.findTags(/#+[ ]*/, /[ ]*#+/); - if (/#+/.test(chunk.startTag)) { - headerLevel = re.lastMatch.length; - } - chunk.startTag = chunk.endTag = ""; - - // Try to get the current header level by looking for - and = in the line - // below the selection. - chunk.findTags(null, /\s?(-+|=+)/); - if (/=+/.test(chunk.endTag)) { - headerLevel = 1; - } - if (/-+/.test(chunk.endTag)) { - headerLevel = 2; - } - - // Skip to the next line so we can create the header markdown. - chunk.startTag = chunk.endTag = ""; - chunk.skipLines(1, 1); - - // We make a level 2 header if there is no current header. - // If there is a header level, we substract one from the header level. - // If it's already a level 1 header, it's removed. - var headerLevelToCreate = headerLevel == 0 ? 2 : headerLevel - 1; - - if (headerLevelToCreate > 0) { - - // The button only creates level 1 and 2 underline headers. - // Why not have it iterate over hash header levels? Wouldn't that be easier and cleaner? - var headerChar = headerLevelToCreate >= 2 ? "-" : "="; - var len = chunk.selection.length; - if (len > SETTINGS.lineLength) { - len = SETTINGS.lineLength; - } - chunk.endTag = "\n"; - while (len--) { - chunk.endTag += headerChar; - } - } - }; - - commandProto.doHorizontalRule = function (chunk, postProcessing) { - chunk.startTag = "----------\n"; - chunk.selection = ""; - chunk.skipLines(2, 1, true); - } - - -})(); \ No newline at end of file diff --git a/vendor/assets/javascripts/markdown_editor/Markdown.Sanitizer.js b/vendor/assets/javascripts/markdown_editor/Markdown.Sanitizer.js deleted file mode 100644 index be0445a..0000000 --- a/vendor/assets/javascripts/markdown_editor/Markdown.Sanitizer.js +++ /dev/null @@ -1,111 +0,0 @@ -(function () { - var output, Converter; - if (typeof exports === "object" && typeof require === "function") { // we're in a CommonJS (e.g. Node.js) module - output = exports; - Converter = require("./Markdown.Converter").Converter; - } else { - output = window.Markdown; - Converter = output.Converter; - } - - output.getSanitizingConverter = function () { - var converter = new Converter(); - converter.hooks.chain("postConversion", sanitizeHtml); - converter.hooks.chain("postConversion", balanceTags); - return converter; - } - - function sanitizeHtml(html) { - return html.replace(/<[^>]*>?/gi, sanitizeTag); - } - - // (tags that can be opened/closed) | (tags that stand alone) - var basic_tag_whitelist = /^(<\/?(b|blockquote|code|del|dd|dl|dt|em|h1|h2|h3|i|kbd|li|ol|p|s|sup|sub|strong|strike|ul)>|<(br|hr)\s?\/?>)$/i; - // | - var a_white = /^(]+")?\s?>|<\/a>)$/i; - - // ]*")?(\stitle="[^"<>]*")?\s?\/?>)$/i; - - //
    |
    for twitter bootstrap - var pre_white = /^(|<\/pre>)$/i; - - function sanitizeTag(tag) { - if (tag.match(basic_tag_whitelist) || tag.match(a_white) || tag.match(img_white) || tag.match(pre_white)) - return tag; - else - return ""; - } - - /// - /// attempt to balance HTML tags in the html string - /// by removing any unmatched opening or closing tags - /// IMPORTANT: we *assume* HTML has *already* been - /// sanitized and is safe/sane before balancing! - /// - /// adapted from CODESNIPPET: A8591DBA-D1D3-11DE-947C-BA5556D89593 - /// - function balanceTags(html) { - - if (html == "") - return ""; - - var re = /<\/?\w+[^>]*(\s|$|>)/g; - // convert everything to lower case; this makes - // our case insensitive comparisons easier - var tags = html.toLowerCase().match(re); - - // no HTML tags present? nothing to do; exit now - var tagcount = (tags || []).length; - if (tagcount == 0) - return html; - - var tagname, tag; - var ignoredtags = "



  • "; - var match; - var tagpaired = []; - var tagremove = []; - var needsRemoval = false; - - // loop through matched tags in forward order - for (var ctag = 0; ctag < tagcount; ctag++) { - tagname = tags[ctag].replace(/<\/?(\w+).*/, "$1"); - // skip any already paired tags - // and skip tags in our ignore list; assume they're self-closed - if (tagpaired[ctag] || ignoredtags.search("<" + tagname + ">") > -1) - continue; - - tag = tags[ctag]; - match = -1; - - if (!/^<\//.test(tag)) { - // this is an opening tag - // search forwards (next tags), look for closing tags - for (var ntag = ctag + 1; ntag < tagcount; ntag++) { - if (!tagpaired[ntag] && tags[ntag] == "") { - match = ntag; - break; - } - } - } - - if (match == -1) - needsRemoval = tagremove[ctag] = true; // mark for removal - else - tagpaired[match] = true; // mark paired - } - - if (!needsRemoval) - return html; - - // delete all orphaned tags from the string - - var ctag = 0; - html = html.replace(re, function (match) { - var res = tagremove[ctag] ? "" : match; - ctag++; - return res; - }); - return html; - } -})(); diff --git a/vendor/assets/javascripts/markdown_editor/load_editor.coffee b/vendor/assets/javascripts/markdown_editor/load_editor.coffee deleted file mode 100644 index f8a28b2..0000000 --- a/vendor/assets/javascripts/markdown_editor/load_editor.coffee +++ /dev/null @@ -1,5 +0,0 @@ -jQuery -> - if $("#wmd-input").length > 0 - converter = Markdown.getSanitizingConverter() - editor = new Markdown.Editor converter - editor.run() From 53edfdf46b6a6a81fdbd765860476891511222b9 Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Sat, 3 Aug 2013 15:53:59 -0700 Subject: [PATCH 08/32] Update the hash syntax --- .travis.yml | 2 +- app/controllers/application_controller.rb | 8 +- .../dashboard/assets_controller.rb | 8 +- app/controllers/dashboard/pages_controller.rb | 6 +- .../dashboard/sections_controller.rb | 6 +- .../dashboard/settings_controller.rb | 6 +- app/controllers/dashboard/users_controller.rb | 4 +- app/controllers/pages_controller.rb | 2 +- .../users/registrations_controller.rb | 4 +- app/helpers/application_helper.rb | 10 +-- app/models/asset.rb | 16 ++-- app/models/contact_form.rb | 4 +- app/models/page.rb | 14 ++-- app/models/section.rb | 8 +- app/models/setting.rb | 2 +- app/models/user.rb | 4 +- .../contact_forms/_contact_form.html.haml | 2 +- app/views/contact_forms/new.html.haml | 2 +- app/views/dashboard/pages/_page.html.haml | 10 +-- .../dashboard/pages/_page_editor.html.haml | 21 ++--- app/views/dashboard/pages/edit.haml | 14 ++-- app/views/dashboard/pages/index.haml | 4 +- app/views/dashboard/pages/new.haml | 8 +- .../sections/_page_section.html.haml | 8 +- .../dashboard/sections/_section.html.haml | 10 +-- app/views/dashboard/sections/edit.haml | 4 +- app/views/dashboard/sections/index.haml | 4 +- app/views/dashboard/sections/new.haml | 4 +- .../dashboard/settings/_setting.html.haml | 10 +-- .../settings/_setting_editor.html.haml | 2 +- app/views/dashboard/settings/edit.html.haml | 4 +- app/views/dashboard/settings/index.html.haml | 6 +- app/views/dashboard/settings/new.html.haml | 4 +- app/views/dashboard/users/_user.html.haml | 8 +- app/views/dashboard/users/index.html.haml | 4 +- app/views/devise/confirmations/new.html.haml | 4 +- .../confirmation_instructions.html.haml | 2 +- .../reset_password_instructions.html.haml | 2 +- .../mailer/unlock_instructions.html.haml | 2 +- app/views/devise/passwords/edit.html.haml | 4 +- app/views/devise/passwords/new.html.haml | 4 +- app/views/devise/registrations/edit.html.haml | 8 +- app/views/devise/registrations/new.html.haml | 12 +-- app/views/devise/sessions/new.html.haml | 4 +- app/views/devise/unlocks/new.html.haml | 4 +- app/views/layouts/application.html.haml | 2 +- .../layouts/application/_flashes.html.haml | 2 +- app/views/layouts/dashboard.html.haml | 4 +- .../layouts/dashboard/_flashes.html.haml | 2 +- app/views/layouts/dashboard/_top.html.haml | 2 +- .../layouts/dashboard/nav/_pages.html.haml | 6 +- .../layouts/dashboard/nav/_sections.html.haml | 6 +- .../layouts/dashboard/nav/_settings.html.haml | 6 +- .../layouts/dashboard/nav/_users.html.haml | 4 +- app/views/layouts/sessions.html.haml | 2 +- .../layouts/themes/clover/_banner.html.haml | 6 +- .../layouts/themes/clover/_bottom.html.haml | 8 +- .../layouts/themes/clover/_slides.html.haml | 6 +- .../layouts/themes/clover/theme.html.haml | 12 +-- .../layouts/themes/default/theme.html.haml | 2 +- .../themes/simple_blog/theme.html.haml | 10 +-- app/views/shared/_keywords.html.haml | 4 +- app/views/shared/_login_box.html.haml | 8 +- app/views/shared/_uploadify.html.haml | 2 +- config/application.rb | 2 +- config/capistrano_templates.rb | 4 +- config/deploy.rb | 4 +- config/environments/development.rb | 2 +- config/environments/production.rb | 2 +- config/environments/test.rb | 2 +- config/initializers/devise.rb | 12 +-- config/initializers/session_store.rb | 2 +- config/initializers/wrap_parameters.rb | 2 +- config/routes.rb | 24 +++--- db/migrate/20100805055902_create_sections.rb | 2 +- db/migrate/20100806061522_create_pages.rb | 6 +- .../20100814005921_devise_create_users.rb | 20 ++--- ...012145155_acts_as_taggable_on_migration.rb | 4 +- db/migrate/20110209072651_create_settings.rb | 6 +- .../20120918221141_add_slug_to_pages.rb | 2 +- .../20120918223422_add_slug_to_sections.rb | 2 +- db/schema.rb | 82 +++++++++---------- db/seeds.rb | 24 +++--- .../dashboard/pages_controller_spec.rb | 6 +- .../dashboard/settings_controller_spec.rb | 2 +- spec/support/controller_spec_helper.rb | 2 +- 86 files changed, 292 insertions(+), 295 deletions(-) diff --git a/.travis.yml b/.travis.yml index 465d3a9..79b7ebd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ before_script: "RAILS_ENV=development bundle exec rake db:migrate db:test:prepa script: "bundle exec rake spec" rvm: - 2.0.0 - - 1.9.2 + - 1.9.3 notifications: recipients: - enrique@cloverinteractive.com diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f8f27ae..fa7d5f2 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -2,9 +2,9 @@ class ApplicationController < ActionController::Base before_filter :set_locale, :authenticate_user! layout :guess_layout - rescue_from ActiveRecord::RecordNotFound, :with => :page_not_found - rescue_from Clover::PageNotFoundError, :with => :page_not_found - rescue_from Clover::UnauthorizedAccessError, :with => :unauthorized_access + rescue_from ActiveRecord::RecordNotFound, with: :page_not_found + rescue_from Clover::PageNotFoundError, with: :page_not_found + rescue_from Clover::UnauthorizedAccessError, with: :unauthorized_access protect_from_forgery @@ -55,6 +55,6 @@ def unauthorized_access end def page_not_found - render 'public/404', :formats => [ :html ], :status => :not_found, :layout => false + render 'public/404', formats: [ :html ], status: :not_found, layout: false end end diff --git a/app/controllers/dashboard/assets_controller.rb b/app/controllers/dashboard/assets_controller.rb index 3b0c65e..c00636d 100644 --- a/app/controllers/dashboard/assets_controller.rb +++ b/app/controllers/dashboard/assets_controller.rb @@ -2,14 +2,14 @@ class Dashboard::AssetsController < ApplicationController before_filter :fix_content_type def create - @asset = Asset.new :attachable_type => params[:attachable_type], :attachable_id => params[:attachable_id] + @asset = Asset.new attachable_type: params[:attachable_type], attachable_id: params[:attachable_id] @asset.asset = params[:Filedata] if @asset.save! - success = { :status => 'success', :thumbnail => @asset.asset.url(:small) }.to_json - render :json => success + success = { status: 'success', thumbnail: @asset.asset.url(:small) }.to_json + render json: success else - render :json => { :status => 'error' }.to_json + render json: { status: 'error' }.to_json end end diff --git a/app/controllers/dashboard/pages_controller.rb b/app/controllers/dashboard/pages_controller.rb index 15d6c68..d94e6cc 100644 --- a/app/controllers/dashboard/pages_controller.rb +++ b/app/controllers/dashboard/pages_controller.rb @@ -1,8 +1,8 @@ class Dashboard::PagesController < ApplicationController - before_filter :set_page, :only => [ :edit, :update, :destroy ] + before_filter :set_page, only: [ :edit, :update, :destroy ] - set_tab :list_pages, :only => :index - set_tab :new_page, :only => :new + set_tab :list_pages, only: :index + set_tab :new_page, only: :new # GET /pages def index diff --git a/app/controllers/dashboard/sections_controller.rb b/app/controllers/dashboard/sections_controller.rb index 4e4d20d..7504c5f 100644 --- a/app/controllers/dashboard/sections_controller.rb +++ b/app/controllers/dashboard/sections_controller.rb @@ -1,8 +1,8 @@ class Dashboard::SectionsController < ApplicationController - before_filter :set_section, :only => [ :edit, :update, :destroy ] + before_filter :set_section, only: [ :edit, :update, :destroy ] - set_tab :list_sections, :only => :index - set_tab :new_section, :only => :new + set_tab :list_sections, only: :index + set_tab :new_section, only: :new # GET /sections def index diff --git a/app/controllers/dashboard/settings_controller.rb b/app/controllers/dashboard/settings_controller.rb index 99ff9a3..838b51c 100644 --- a/app/controllers/dashboard/settings_controller.rb +++ b/app/controllers/dashboard/settings_controller.rb @@ -1,8 +1,8 @@ class Dashboard::SettingsController < ApplicationController - before_filter :set_setting, :only => [ :edit, :update, :destroy ] + before_filter :set_setting, only: [ :edit, :update, :destroy ] - set_tab :list_settings, :only => :index - set_tab :new_setting, :only => :new + set_tab :list_settings, only: :index + set_tab :new_setting, only: :new def index @settings = Setting.page params[:page] diff --git a/app/controllers/dashboard/users_controller.rb b/app/controllers/dashboard/users_controller.rb index 654ab03..016d790 100644 --- a/app/controllers/dashboard/users_controller.rb +++ b/app/controllers/dashboard/users_controller.rb @@ -1,5 +1,5 @@ class Dashboard::UsersController < ApplicationController - set_tab :list_users, :only => :index + set_tab :list_users, only: :index def index @users = User.order('username').page params[:page] @@ -10,7 +10,7 @@ def destroy if @user.delete flash[:success] = t('messages.deleted_successfully') - redirect_to :action => :index + redirect_to action: :index end end end diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb index e73fd50..ebdec89 100644 --- a/app/controllers/pages_controller.rb +++ b/app/controllers/pages_controller.rb @@ -10,7 +10,7 @@ def show raise Clover::PageNotFoundError if @page.blank? if @page.has_contact? - @contact_form = render_to_string :partial => 'contact_forms/contact_form', :object => ContactForm.new + @contact_form = render_to_string partial: 'contact_forms/contact_form', object: ContactForm.new end end diff --git a/app/controllers/users/registrations_controller.rb b/app/controllers/users/registrations_controller.rb index 7953108..f19b492 100644 --- a/app/controllers/users/registrations_controller.rb +++ b/app/controllers/users/registrations_controller.rb @@ -1,10 +1,10 @@ module Users class RegistrationsController < Devise::RegistrationsController - before_filter :deactivate_action, :only => [ :create, :new ] + before_filter :deactivate_action, only: [ :create, :new ] private def deactivate_action - render 'public/404', :formats => :html, :status => :not_found, :layout => false + render 'public/404', formats: :html, status: :not_found, layout: false end end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index cf5ea62..d67b55f 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -22,19 +22,19 @@ def new_child_fields_template(form_builder, association, options={}) options[:form_builder_local] ||= :f content_for :resource_templates do - content_tag(:div, :id => "#{options[:partial]}_fields_template", :style => "display: none") do - form_builder.fields_for(association, options[:object], :child_index => "new_#{association}") do |f| - render :partial => options[:partial], :locals => { options[:form_builder_local] => f } + content_tag(:div, id: "#{options[:partial]}_fields_template", style: "display: none") do + form_builder.fields_for(association, options[:object], child_index: "new_#{association}") do |f| + render partial: options[:partial], locals: { options[:form_builder_local] => f } end end end end def add_child_fields_link(name, association) - link_to name, "#", :class => 'add_child', :"data-association" => association + link_to name, "#", class: 'add_child', :"data-association" => association end def remove_child_fields_link(name, form_builder) - form_builder.hidden_field(:_destroy) + link_to(name, "#", :class => "remove_child") + form_builder.hidden_field(:_destroy) + link_to(name, "#", class: "remove_child") end end diff --git a/app/models/asset.rb b/app/models/asset.rb index 02793e9..2095e5d 100644 --- a/app/models/asset.rb +++ b/app/models/asset.rb @@ -1,17 +1,17 @@ class Asset < ActiveRecord::Base - belongs_to :attachable, :polymorphic => true + belongs_to :attachable, polymorphic: true =begin - has_attached_file :asset, :styles => { - :squared => "120x80#", - :small => "120x80>", - :medium => "180x120>", - :big => "300x225>" + has_attached_file :asset, styles: { + squared: "120x80#", + small: "120x80>", + medium: "180x120>", + big: "300x225>" } validates_attachment_presence :asset - validates_attachment_content_type :asset, :content_type => [ 'image/jpeg', 'image/png', 'image/gif' ] - validates_attachment_size :asset, :less_than => 20.megabytes + validates_attachment_content_type :asset, content_type: [ 'image/jpeg', 'image/png', 'image/gif' ] + validates_attachment_size :asset, less_than: 20.megabytes =end end diff --git a/app/models/contact_form.rb b/app/models/contact_form.rb index de3ca5a..91f8970 100644 --- a/app/models/contact_form.rb +++ b/app/models/contact_form.rb @@ -2,8 +2,8 @@ class ContactForm include ActiveModel::Validations validates_presence_of :recipient, :subject, :body - validates_format_of :recipient, :with => /\b[a-z0-9._%-]+@[a-z0-9.-]+\.[a-z]{2,4}\b/i - validates_length_of :body, :minimum => 10 + validates_format_of :recipient, with: /\b[a-z0-9._%-]+@[a-z0-9.-]+\.[a-z]{2,4}\b/i + validates_length_of :body, minimum: 10 attr_accessor :recipient, :subject, :body diff --git a/app/models/page.rb b/app/models/page.rb index d3fccec..43e2dae 100644 --- a/app/models/page.rb +++ b/app/models/page.rb @@ -3,29 +3,29 @@ class Page < ActiveRecord::Base acts_as_taggable_on :keywords - has_many :assets, :as => :attachable + has_many :assets, as: :attachable belongs_to :section before_save :check_home_page - validates :name, :content, :section, :presence => true - validates :name, :uniqueness => true + validates :name, :content, :section, presence: true + validates :name, uniqueness: true - friendly_id :name, :use => :slugged + friendly_id :name, use: :slugged attr_accessible :name, :content, :section, :home_page, :published, :section_id, :has_contact - scope :published, where(:published => true) + scope :published, where(published: true) def self.home_page - where( :home_page => true ).first + where( home_page: true ).first end private def check_home_page if home_page? Page.where("home_page = ?", true).each do |page| - page.update_attributes( :home_page => false ) if page != self + page.update_attributes( home_page: false ) if page != self end end end diff --git a/app/models/section.rb b/app/models/section.rb index 02fa036..d7f4b08 100644 --- a/app/models/section.rb +++ b/app/models/section.rb @@ -2,12 +2,12 @@ class Section < ActiveRecord::Base extend FriendlyId has_many :pages - has_many :subsections, :class_name => "Section", :foreign_key => :main_section_id - belongs_to :main_section, :class_name => "Section", :foreign_key => :main_section_id + has_many :subsections, class_name: "Section", foreign_key: :main_section_id + belongs_to :main_section, class_name: "Section", foreign_key: :main_section_id - validates :name, :presence => true, :uniqueness => true + validates :name, presence: true, uniqueness: true - friendly_id :name, :use => :slugged + friendly_id :name, use: :slugged attr_accessible :name, :main_section_id end diff --git a/app/models/setting.rb b/app/models/setting.rb index 4ab1973..78de542 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -2,7 +2,7 @@ class Setting < ActiveRecord::Base validates_presence_of :name, :value validates_uniqueness_of :name - validates_format_of :name, :with => /^[a-z0-9_]+$/ + validates_format_of :name, with: /^[a-z0-9_]+$/ attr_accessible :name, :value, :description attr_accessible :name, :value, :description, :destroyable diff --git a/app/models/user.rb b/app/models/user.rb index ed34d28..a131c3f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,7 +1,7 @@ class User < ActiveRecord::Base devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable, :lockable, :registerable - validates_format_of :username, :with => /^([a-z0-9\-_.]{2,31})$/i + validates_format_of :username, with: /^([a-z0-9\-_.]{2,31})$/i attr_accessor :login attr_accessible :email, :password, :password_confirmation, :remember_me, :avatar, :username, :login @@ -9,6 +9,6 @@ class User < ActiveRecord::Base protected def self.find_for_database_authentication(conditions) login = conditions.delete :login - where(conditions).where([ "username = :value OR email = :value", { :value => login } ]).first + where(conditions).where([ "username = :value OR email = :value", { value: login } ]).first end end diff --git a/app/views/contact_forms/_contact_form.html.haml b/app/views/contact_forms/_contact_form.html.haml index ebd71af..981ff32 100644 --- a/app/views/contact_forms/_contact_form.html.haml +++ b/app/views/contact_forms/_contact_form.html.haml @@ -1,5 +1,5 @@ %fieldset - = form_for contact_form, :as => :contact_form, :url => contact_form_path do |contact| + = form_for contact_form, as: :contact_form, url: contact_form_path do |contact| = contact.label :recipient = contact.text_field :recipient diff --git a/app/views/contact_forms/new.html.haml b/app/views/contact_forms/new.html.haml index 8d66559..8f7f199 100644 --- a/app/views/contact_forms/new.html.haml +++ b/app/views/contact_forms/new.html.haml @@ -1,5 +1,5 @@ %fieldset - = form_for @contact_form, :validate => true do |contact| + = form_for @contact_form, validate: true do |contact| = contact.label :recipient = contact.text_field :recipient diff --git a/app/views/dashboard/pages/_page.html.haml b/app/views/dashboard/pages/_page.html.haml index 2adcb50..2f18ccd 100644 --- a/app/views/dashboard/pages/_page.html.haml +++ b/app/views/dashboard/pages/_page.html.haml @@ -1,8 +1,8 @@ -%tr{ :class => cycle(:odd, :even) } +%tr{ class: cycle(:odd, :even) } %td= link_to page.name, edit_dashboard_page_path( page ) %td= page.section.name - %td= l page.created_at, :format => :short - %td= l page.updated_at, :format => :short + %td= l page.created_at, format: :short + %td= l page.updated_at, format: :short %td - = link_to t('links.edit'), edit_dashboard_page_path( page.id ), :class => 'icon edit' - = link_to t('links.destroy'), dashboard_page_path( page.id ), :confirm => t('common.messages.are_you_sure'), :method => :delete, :class => 'icon delete' + = link_to t('links.edit'), edit_dashboard_page_path( page.id ), class: 'icon edit' + = link_to t('links.destroy'), dashboard_page_path( page.id ), confirm: t('common.messages.are_you_sure'), method: :delete, class: 'icon delete' diff --git a/app/views/dashboard/pages/_page_editor.html.haml b/app/views/dashboard/pages/_page_editor.html.haml index 2f2c2a2..18b8966 100644 --- a/app/views/dashboard/pages/_page_editor.html.haml +++ b/app/views/dashboard/pages/_page_editor.html.haml @@ -1,27 +1,24 @@ -= form_for [:dashboard, page_editor ], :validate => true do |f| += form_for [:dashboard, page_editor ], validate: true do |f| #page_content - = f.hidden_field :keywords, :id => :final_keywords_list - %label{ :for => :page_name } + = f.hidden_field :keywords, id: :final_keywords_list + %label{ for: :page_name } = t 'common.fields.name' - %small= t 'common.descriptions.url.item_name', :item => t('activerecord.models.page').downcase + %small= t 'common.descriptions.url.item_name', item: t('activerecord.models.page').downcase = f.text_field :name + = f.text_area :content, id: 'wmd-input', class: 'wmd-input' - .wmd-panel - #wmd-button-bar - = f.text_area :content, :id => 'wmd-input', :class => 'wmd-input' - - %label{ :for => :page_section_id } + %label{ for: :page_section_id } = t 'activerecord.attributes.page.section' %small= t 'dashboard.page.descriptions.section' = f.select :section_id, all_sections_collection .buttonset = f.label :home_page - = f.check_box :home_page, :class => :home_page + = f.check_box :home_page, class: :home_page = f.label :has_contact - = f.check_box :has_contact, :class => :contact_form + = f.check_box :has_contact, class: :contact_form = f.label :published - = f.check_box :published, :class => :published + = f.check_box :published, class: :published %button.wymupdate= t 'common.forms.submit' diff --git a/app/views/dashboard/pages/edit.haml b/app/views/dashboard/pages/edit.haml index 97e61d6..d11b464 100644 --- a/app/views/dashboard/pages/edit.haml +++ b/app/views/dashboard/pages/edit.haml @@ -1,21 +1,21 @@ #tabs %ul - %li= link_to t('links.item_details', :item => t('activerecord.models.page')), '#tabs-1' - %li= link_to t('links.item_keywords', :item => t('activerecord.models.page')), '#tabs-2' - %li= link_to t('links.item_assets', :item => t('activerecord.models.page')), '#tabs-3' + %li= link_to t('links.item_details', item: t('activerecord.models.page')), '#tabs-1' + %li= link_to t('links.item_keywords', item: t('activerecord.models.page')), '#tabs-2' + %li= link_to t('links.item_assets', item: t('activerecord.models.page')), '#tabs-3' #tabs-1 - = render :partial => 'page_editor', :object => @page + = render partial: 'page_editor', object: @page #tabs-2 - = render 'shared/keywords', :resource_keywords => @page.keywords.map(&:name) + = render 'shared/keywords', resource_keywords: @page.keywords.map(&:name) .spacer #tabs-3 .splitcontentleft #images_list - @page.assets.each do |asset| = image_tag asset.asset.url(:small) - %file#uploadify{ :name => 'asset' } + %file#uploadify{ name: 'asset' } .splitcontentright - = render 'shared/uploadify', :object => @page + = render 'shared/uploadify', object: @page .spacer :javascript $(function() { diff --git a/app/views/dashboard/pages/index.haml b/app/views/dashboard/pages/index.haml index c3fc665..a7573a5 100644 --- a/app/views/dashboard/pages/index.haml +++ b/app/views/dashboard/pages/index.haml @@ -1,9 +1,9 @@ -%h2= t 'common.headers.item_list', :item => t('activerecord.models.page').pluralize +%h2= t 'common.headers.item_list', item: t('activerecord.models.page').pluralize %p.info %span.bold= t('messages.information') + ':' = t 'dashboard.page.instructions.index' -%table.tabular{ :cellpadding => 0, :cellspacing => 0} +%table.tabular{ cellpadding: 0, cellspacing: 0} %thead %tr %th= t 'common.fields.name' diff --git a/app/views/dashboard/pages/new.haml b/app/views/dashboard/pages/new.haml index a614893..978260e 100644 --- a/app/views/dashboard/pages/new.haml +++ b/app/views/dashboard/pages/new.haml @@ -1,9 +1,9 @@ #tabs %ul - %li= link_to t('links.item_details', :item => t('activerecord.models.page')), '#tabs-1' - %li= link_to t('links.item_keywords', :item => t('activerecord.models.page')), '#tabs-2' + %li= link_to t('links.item_details', item: t('activerecord.models.page')), '#tabs-1' + %li= link_to t('links.item_keywords', item: t('activerecord.models.page')), '#tabs-2' #tabs-1 - = render :partial => 'page_editor', :object => @page + = render partial: 'page_editor', object: @page #tabs-2 - = render :partial => 'shared/keywords', :locals => { :resource_keywords => @page.keywords.map(&:name) } + = render partial: 'shared/keywords', locals: { resource_keywords: @page.keywords.map(&:name) } .clear diff --git a/app/views/dashboard/sections/_page_section.html.haml b/app/views/dashboard/sections/_page_section.html.haml index 47bfd25..3a41fcb 100644 --- a/app/views/dashboard/sections/_page_section.html.haml +++ b/app/views/dashboard/sections/_page_section.html.haml @@ -1,15 +1,15 @@ -= form_for [ :dashboard, page_section ], :validate => true do |f| += form_for [ :dashboard, page_section ], validate: true do |f| .columns .half - %label{ :for => :section_name } + %label{ for: :section_name } = t 'activerecord.models.section' %small= t 'dashboard.sections.descriptions.name' = f.text_field :name - %label{ :for => :main_section_id } + %label{ for: :main_section_id } = t 'activerecord.attributes.section.main_section' %small= t 'dashboard.sections.descriptions.main_section' - = f.select :main_section_id, main_sections_collection(page_section.name), :include_blank => true + = f.select :main_section_id, main_sections_collection(page_section.name), include_blank: true %button#submit= t 'common.forms.submit' diff --git a/app/views/dashboard/sections/_section.html.haml b/app/views/dashboard/sections/_section.html.haml index 6c3738a..08544fe 100644 --- a/app/views/dashboard/sections/_section.html.haml +++ b/app/views/dashboard/sections/_section.html.haml @@ -1,9 +1,9 @@ -%tr{ :class => cycle(:odd, :even) } +%tr{ class: cycle(:odd, :even) } %td= section.name %td= section.main_section.name if section.main_section.present? - %td= l section.created_at, :format => :short - %td= l section.updated_at, :format => :short + %td= l section.created_at, format: :short + %td= l section.updated_at, format: :short %td - = link_to t('links.edit'), edit_dashboard_section_path( section.id ), :class => 'icon edit' - = link_to t('links.destroy'), dashboard_section_path( section.id ), :confirm => t('common.messages.are_you_sure'), :method => :delete, :class => 'icon delete' + = link_to t('links.edit'), edit_dashboard_section_path( section.id ), class: 'icon edit' + = link_to t('links.destroy'), dashboard_section_path( section.id ), confirm: t('common.messages.are_you_sure'), method: :delete, class: 'icon delete' diff --git a/app/views/dashboard/sections/edit.haml b/app/views/dashboard/sections/edit.haml index 767d9a9..2c4c872 100644 --- a/app/views/dashboard/sections/edit.haml +++ b/app/views/dashboard/sections/edit.haml @@ -1,2 +1,2 @@ -%h2= t 'links.edit_item', :item => t('activerecord.models.section') -= render :partial => 'page_section', :object => @section +%h2= t 'links.edit_item', item: t('activerecord.models.section') += render partial: 'page_section', object: @section diff --git a/app/views/dashboard/sections/index.haml b/app/views/dashboard/sections/index.haml index 9655d30..0cb1280 100644 --- a/app/views/dashboard/sections/index.haml +++ b/app/views/dashboard/sections/index.haml @@ -1,9 +1,9 @@ -%h2= t 'common.headers.item_list', :item => t('activerecord.models.section') +%h2= t 'common.headers.item_list', item: t('activerecord.models.section') %p.info %span.bold= t('messages.information') + ':' = t '.information' -%table.tabular{ :cellpading => 0, :cellspacing => 0 } +%table.tabular{ cellpading: 0, cellspacing: 0 } %thead %tr %th= t 'activerecord.attributes.section.name' diff --git a/app/views/dashboard/sections/new.haml b/app/views/dashboard/sections/new.haml index 415e0d5..4c43f06 100644 --- a/app/views/dashboard/sections/new.haml +++ b/app/views/dashboard/sections/new.haml @@ -1,2 +1,2 @@ -%h2= t 'links.new_item', :item => t("activerecord.models.section") -= render :partial => 'page_section', :object => @section +%h2= t 'links.new_item', item: t("activerecord.models.section") += render partial: 'page_section', object: @section diff --git a/app/views/dashboard/settings/_setting.html.haml b/app/views/dashboard/settings/_setting.html.haml index 01b6687..873467a 100644 --- a/app/views/dashboard/settings/_setting.html.haml +++ b/app/views/dashboard/settings/_setting.html.haml @@ -1,8 +1,8 @@ -%tr{ :class => cycle(:odd, :even) } +%tr{ class: cycle(:odd, :even) } %td= setting.name %td= setting.description - %td= l setting.created_at, :format => :short - %td= l setting.updated_at, :format => :short + %td= l setting.created_at, format: :short + %td= l setting.updated_at, format: :short %td - = link_to t('links.edit'), edit_dashboard_setting_path(setting), :class => 'icon edit' - = link_to t('links.destroy'), dashboard_setting_path(setting), :confirm => t('common.messages.are_you_sure'), :method => :delete, :class => 'icon delete' if setting.destroyable? + = link_to t('links.edit'), edit_dashboard_setting_path(setting), class: 'icon edit' + = link_to t('links.destroy'), dashboard_setting_path(setting), confirm: t('common.messages.are_you_sure'), method: :delete, class: 'icon delete' if setting.destroyable? diff --git a/app/views/dashboard/settings/_setting_editor.html.haml b/app/views/dashboard/settings/_setting_editor.html.haml index dc2661d..9d260c7 100644 --- a/app/views/dashboard/settings/_setting_editor.html.haml +++ b/app/views/dashboard/settings/_setting_editor.html.haml @@ -1,4 +1,4 @@ -= form_for [ :dashboard, setting_editor ], :validate => true do |f| += form_for [ :dashboard, setting_editor ], validate: true do |f| .columns .half = f.label :name diff --git a/app/views/dashboard/settings/edit.html.haml b/app/views/dashboard/settings/edit.html.haml index 5511557..e093aa6 100644 --- a/app/views/dashboard/settings/edit.html.haml +++ b/app/views/dashboard/settings/edit.html.haml @@ -1,2 +1,2 @@ -%h2= t 'links.edit_item', :item => t('activerecord.models.setting') -= render :partial => 'setting_editor', :object => @setting, :locals => { :themes => @themes } +%h2= t 'links.edit_item', item: t('activerecord.models.setting') += render partial: 'setting_editor', object: @setting, locals: { themes: @themes } diff --git a/app/views/dashboard/settings/index.html.haml b/app/views/dashboard/settings/index.html.haml index 569c852..9e637a7 100644 --- a/app/views/dashboard/settings/index.html.haml +++ b/app/views/dashboard/settings/index.html.haml @@ -1,10 +1,10 @@ -%h2= t 'common.headers.item_list', :item => t('activerecord.models.setting') +%h2= t 'common.headers.item_list', item: t('activerecord.models.setting') %p.info %span.bold= t('messages.information') + ':' = t '.instructions' -%table.tabular{ :cellpadding => 0, :cellspacing => 0 } +%table.tabular{ cellpadding: 0, cellspacing: 0 } %thead %tr %th= t 'common.fields.name' @@ -13,5 +13,5 @@ %th= t 'common.fields.updated_at' %th= t 'common.messages.options' %tbody - = render :partial => 'setting', :collection => @settings + = render partial: 'setting', collection: @settings = will_paginate @settings diff --git a/app/views/dashboard/settings/new.html.haml b/app/views/dashboard/settings/new.html.haml index 6c05d18..08b8374 100644 --- a/app/views/dashboard/settings/new.html.haml +++ b/app/views/dashboard/settings/new.html.haml @@ -1,2 +1,2 @@ -%h2= t 'links.new_item', :item => t('activerecord.models.setting') -= render :partial => 'setting_editor', :object => @setting, :locals => { :themes => @themes } +%h2= t 'links.new_item', item: t('activerecord.models.setting') += render partial: 'setting_editor', object: @setting, locals: { themes: @themes } diff --git a/app/views/dashboard/users/_user.html.haml b/app/views/dashboard/users/_user.html.haml index 68f32c8..36fcb6e 100644 --- a/app/views/dashboard/users/_user.html.haml +++ b/app/views/dashboard/users/_user.html.haml @@ -1,7 +1,7 @@ -%tr{ :class => cycle(:odd, :even) } +%tr{ class: cycle(:odd, :even) } %td= user.username %td= user.email - %td= l(user.confirmed_at, :format => :short) if user.confirmed_at - %td= l(user.last_sign_in_at, :format => :short) if user.last_sign_in_at + %td= l(user.confirmed_at, format: :short) if user.confirmed_at + %td= l(user.last_sign_in_at, format: :short) if user.last_sign_in_at %td - = link_to t('links.destroy'), dashboard_user_path(user), :method => :delete, :confirm => t('common.messages.are_you_sure'), :class => 'icon user_delete' + = link_to t('links.destroy'), dashboard_user_path(user), method: :delete, confirm: t('common.messages.are_you_sure'), class: 'icon user_delete' diff --git a/app/views/dashboard/users/index.html.haml b/app/views/dashboard/users/index.html.haml index 12baf29..b7c563d 100644 --- a/app/views/dashboard/users/index.html.haml +++ b/app/views/dashboard/users/index.html.haml @@ -1,4 +1,4 @@ -%h2= t 'common.headers.item_list', :item => t('activerecord.models.user') +%h2= t 'common.headers.item_list', item: t('activerecord.models.user') %p.info %span.bold= t('messages.information') + ':' = t '.tip' @@ -12,5 +12,5 @@ %th= t 'activerecord.attributes.user.last_sign_in_at' %th= t 'common.messages.options' %tbody - = render :partial => 'user', :collection => @users + = render partial: 'user', collection: @users = will_paginate @users diff --git a/app/views/devise/confirmations/new.html.haml b/app/views/devise/confirmations/new.html.haml index 87f8fef..fd7ca69 100644 --- a/app/views/devise/confirmations/new.html.haml +++ b/app/views/devise/confirmations/new.html.haml @@ -1,5 +1,5 @@ #login_form - = form_for resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post } do |f| + = form_for resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post } do |f| %fieldset = devise_error_messages! @@ -9,4 +9,4 @@ = f.submit t('devise.forms.resend_confirmation') .more_options - = render :partial => "devise/shared/links" + = render partial: "devise/shared/links" diff --git a/app/views/devise/mailer/confirmation_instructions.html.haml b/app/views/devise/mailer/confirmation_instructions.html.haml index 7840b9c..1b6bdb8 100644 --- a/app/views/devise/mailer/confirmation_instructions.html.haml +++ b/app/views/devise/mailer/confirmation_instructions.html.haml @@ -1,4 +1,4 @@ %p Welcome #{@resource.email}! %p You can confirm your account through the link below: -%p= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @resource.confirmation_token) +%p= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @resource.confirmation_token) diff --git a/app/views/devise/mailer/reset_password_instructions.html.haml b/app/views/devise/mailer/reset_password_instructions.html.haml index 4fc4743..1b8157b 100644 --- a/app/views/devise/mailer/reset_password_instructions.html.haml +++ b/app/views/devise/mailer/reset_password_instructions.html.haml @@ -1,6 +1,6 @@ %p Hello #{@resource.email}! %p Someone has requested a link to change your password, and you can do this through the link below. -%p= link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @resource.reset_password_token) +%p= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @resource.reset_password_token) %p If you didn't request this, please ignore this email. %p Your password won't change until you access the link above and create a new one. diff --git a/app/views/devise/mailer/unlock_instructions.html.haml b/app/views/devise/mailer/unlock_instructions.html.haml index 34b0e9e..543e209 100644 --- a/app/views/devise/mailer/unlock_instructions.html.haml +++ b/app/views/devise/mailer/unlock_instructions.html.haml @@ -2,4 +2,4 @@ Hello #{@resource.email}! %p Your account has been locked due to an excessive amount of unsuccessful sign in attempts. %p Click the link below to unlock your account: -%p= link_to 'Unlock my account', unlock_url(@resource, :unlock_token => @resource.unlock_token) +%p= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @resource.unlock_token) diff --git a/app/views/devise/passwords/edit.html.haml b/app/views/devise/passwords/edit.html.haml index 3b4e3e7..5cbdf8d 100644 --- a/app/views/devise/passwords/edit.html.haml +++ b/app/views/devise/passwords/edit.html.haml @@ -1,5 +1,5 @@ #login_form - = form_for resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put } do |f| + = form_for resource, as: resource_name, url: password_path(resource_name), html: { method: :put } do |f| %fieldset = devise_error_messages! = f.hidden_field :reset_password_token @@ -13,4 +13,4 @@ = f.submit t('devise.forms.change_password') .more_options - = render :partial => "devise/shared/links" + = render partial: "devise/shared/links" diff --git a/app/views/devise/passwords/new.html.haml b/app/views/devise/passwords/new.html.haml index 4f2a9ae..2f2ea5e 100644 --- a/app/views/devise/passwords/new.html.haml +++ b/app/views/devise/passwords/new.html.haml @@ -1,5 +1,5 @@ #login_form - = form_for resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post } do |f| + = form_for resource, as: resource_name, url: password_path(resource_name), html: { method: :post } do |f| %fieldset = devise_error_messages! @@ -8,4 +8,4 @@ = f.submit t('devise.forms.reset_password') .more_options - = render :partial => "devise/shared/links" + = render partial: "devise/shared/links" diff --git a/app/views/devise/registrations/edit.html.haml b/app/views/devise/registrations/edit.html.haml index cc28dce..5edf256 100644 --- a/app/views/devise/registrations/edit.html.haml +++ b/app/views/devise/registrations/edit.html.haml @@ -1,5 +1,5 @@ -%h2= t 'links.edit_item', :item => t('activerecord.models.user') -= form_for resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put } do |f| +%h2= t 'links.edit_item', item: t('activerecord.models.user') += form_for resource, as: resource_name, url: registration_path(resource_name), html: { method: :put } do |f| .columns .half = devise_error_messages! @@ -26,6 +26,6 @@ %h3= t 'common.headers.cancel_account' %p = t('common.messages.unhappy') - = link_to t('common.headers.cancel_account'), registration_path(resource_name), :confirm => t('common.messages.are_you_sure'), :method => :delete + = link_to t('common.headers.cancel_account'), registration_path(resource_name), confirm: t('common.messages.are_you_sure'), method: :delete - content_for :sub_nav do - = render :partial => 'layouts/dashboard/nav/users' + = render partial: 'layouts/dashboard/nav/users' diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml index e8194f7..9bf0c97 100644 --- a/app/views/devise/registrations/new.html.haml +++ b/app/views/devise/registrations/new.html.haml @@ -1,21 +1,21 @@ #login_form - = form_for resource, :as => resource_name, :url => registration_path(resource_name) do |f| + = form_for resource, as: resource_name, url: registration_path(resource_name) do |f| %fieldset = devise_error_messages! = f.label :email - = f.text_field :email, :class => :"input_text shadowed" + = f.text_field :email, class: :"input_text shadowed" = f.label :username - = f.text_field :username, :class => :"input_text shadowed" + = f.text_field :username, class: :"input_text shadowed" = f.label :password - = f.password_field :password, :class => :"input_password shadowed" + = f.password_field :password, class: :"input_password shadowed" = f.label :password_confirmation - = f.password_field :password_confirmation, :class => :"input_password shadowed" + = f.password_field :password_confirmation, class: :"input_password shadowed" = f.submit t('devise.forms.sign_up') .more_options - = render :partial => "devise/shared/links" + = render partial: "devise/shared/links" diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml index bf24239..7589c11 100644 --- a/app/views/devise/sessions/new.html.haml +++ b/app/views/devise/sessions/new.html.haml @@ -1,5 +1,5 @@ #login_form - = form_for resource, :as => resource_name, :url => session_path(resource_name) do |f| + = form_for resource, as: resource_name, url: session_path(resource_name) do |f| %fieldset = f.label :login = f.text_field :login @@ -13,4 +13,4 @@ = f.submit t('devise.forms.sign_in') .more_options - = render :partial => "devise/shared/links" + = render partial: "devise/shared/links" diff --git a/app/views/devise/unlocks/new.html.haml b/app/views/devise/unlocks/new.html.haml index 22b1033..b00f754 100644 --- a/app/views/devise/unlocks/new.html.haml +++ b/app/views/devise/unlocks/new.html.haml @@ -1,5 +1,5 @@ #login_form - = form_for(resource, :as => resource_name, :url => unlock_path(resource_name), :html => { :method => :post }) do |f| + = form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %fieldset = devise_error_messages! @@ -8,4 +8,4 @@ = f.submit "Resend unlock instructions" .more_options - = render :partial => "devise/shared/links" + = render partial: "devise/shared/links" diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 0192798..9b62715 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -14,7 +14,7 @@ #nav_wrap= yield :nav_wrap #content_wrap #content - = render :partial => 'layouts/application/flashes' + = render partial: 'layouts/application/flashes' - if content_for? :module .module %h2.title= yield :module_title diff --git a/app/views/layouts/application/_flashes.html.haml b/app/views/layouts/application/_flashes.html.haml index cb6a72f..a260f26 100644 --- a/app/views/layouts/application/_flashes.html.haml +++ b/app/views/layouts/application/_flashes.html.haml @@ -1,4 +1,4 @@ #flash - flash.each do |(status, message)| - css_class = (status == :alert) ? 'error' : status.to_s - = content_tag :div, flash[status], :class => css_class + = content_tag :div, flash[status], class: css_class diff --git a/app/views/layouts/dashboard.html.haml b/app/views/layouts/dashboard.html.haml index 8e19ed0..43bdcdc 100644 --- a/app/views/layouts/dashboard.html.haml +++ b/app/views/layouts/dashboard.html.haml @@ -1,5 +1,5 @@ - selected_tab = ( controller_name == 'registrations' ) ? 'users' : controller_name -= render 'layouts/dashboard/head', :selected_tab => selected_tab += render 'layouts/dashboard/head', selected_tab: selected_tab = render 'layouts/dashboard/navigation' = render 'layouts/dashboard/top' @@ -17,7 +17,7 @@ #nav_wrap= yield :nav_wrap #content_wrap #content - = render :partial => 'layouts/dashboard/flashes' + = render partial: 'layouts/dashboard/flashes' .module %h2.title= content_for?(:module_title) ? yield(:module_title) : t( "activerecord.models.#{ selected_tab.singularize }" ) .module_body= yield diff --git a/app/views/layouts/dashboard/_flashes.html.haml b/app/views/layouts/dashboard/_flashes.html.haml index fc8c769..40e2617 100644 --- a/app/views/layouts/dashboard/_flashes.html.haml +++ b/app/views/layouts/dashboard/_flashes.html.haml @@ -4,4 +4,4 @@ - when 'alert' then 'error' - when 'notice' then 'success' - else status.to_s - = content_tag :div, flash[status], :class => css_class + = content_tag :div, flash[status], class: css_class diff --git a/app/views/layouts/dashboard/_top.html.haml b/app/views/layouts/dashboard/_top.html.haml index 05c49dd..8f42cbc 100644 --- a/app/views/layouts/dashboard/_top.html.haml +++ b/app/views/layouts/dashboard/_top.html.haml @@ -1,5 +1,5 @@ = content_for :top do - = link_to '', root_path, :id => "logo" + = link_to '', root_path, id: "logo" #account_info - if defined?( current_user ) and defined?( edit_user_registration_path ) and defined?( destroy_user_registration_path ) = t 'common.messages.hi' diff --git a/app/views/layouts/dashboard/nav/_pages.html.haml b/app/views/layouts/dashboard/nav/_pages.html.haml index 333ee97..84c6f5c 100644 --- a/app/views/layouts/dashboard/nav/_pages.html.haml +++ b/app/views/layouts/dashboard/nav/_pages.html.haml @@ -1,3 +1,3 @@ -= tabs_tag :open_tabs => { :id => "sub_menu", :class => "sub_nav" } do |tab| - = tab.list_pages t('links.item_list', :item => t('activerecord.models.page')), dashboard_pages_path - = tab.new_page t('links.new_item', :item => t('activerecord.models.page')), new_dashboard_page_path += tabs_tag open_tabs: { id: "sub_menu", class: "sub_nav" } do |tab| + = tab.list_pages t('links.item_list', item: t('activerecord.models.page')), dashboard_pages_path + = tab.new_page t('links.new_item', item: t('activerecord.models.page')), new_dashboard_page_path diff --git a/app/views/layouts/dashboard/nav/_sections.html.haml b/app/views/layouts/dashboard/nav/_sections.html.haml index 9556f55..59014d4 100644 --- a/app/views/layouts/dashboard/nav/_sections.html.haml +++ b/app/views/layouts/dashboard/nav/_sections.html.haml @@ -1,3 +1,3 @@ -= tabs_tag :open_tabs => { :id => "sub_menu", :class => "sub_nav" } do |tab| - = tab.list_sections t('links.item_list', :item => t('activerecord.models.section')), dashboard_sections_path - = tab.new_section t('links.new_item', :item => t('activerecord.models.section')), new_dashboard_section_path += tabs_tag open_tabs: { id: "sub_menu", class: "sub_nav" } do |tab| + = tab.list_sections t('links.item_list', item: t('activerecord.models.section')), dashboard_sections_path + = tab.new_section t('links.new_item', item: t('activerecord.models.section')), new_dashboard_section_path diff --git a/app/views/layouts/dashboard/nav/_settings.html.haml b/app/views/layouts/dashboard/nav/_settings.html.haml index dfad712..5eb92b2 100644 --- a/app/views/layouts/dashboard/nav/_settings.html.haml +++ b/app/views/layouts/dashboard/nav/_settings.html.haml @@ -1,3 +1,3 @@ -= tabs_tag :open_tabs => { :id => "sub_menu", :class => "sub_nav" } do |tab| - = tab.list_settings t('links.item_list', :item => t('activerecord.models.setting')), dashboard_settings_path - = tab.new_setting t('links.new_item', :item => t('activerecord.models.setting')), new_dashboard_setting_path += tabs_tag open_tabs: { id: "sub_menu", class: "sub_nav" } do |tab| + = tab.list_settings t('links.item_list', item: t('activerecord.models.setting')), dashboard_settings_path + = tab.new_setting t('links.new_item', item: t('activerecord.models.setting')), new_dashboard_setting_path diff --git a/app/views/layouts/dashboard/nav/_users.html.haml b/app/views/layouts/dashboard/nav/_users.html.haml index d9d8cf0..fa95477 100644 --- a/app/views/layouts/dashboard/nav/_users.html.haml +++ b/app/views/layouts/dashboard/nav/_users.html.haml @@ -1,2 +1,2 @@ -= tabs_tag :open_tabs => { :id => "sub_menu", :class => "sub_nav" } do |tab| - = tab.list_users t('links.item_list', :item => t('activerecord.models.user')), dashboard_users_path += tabs_tag open_tabs: { id: "sub_menu", class: "sub_nav" } do |tab| + = tab.list_users t('links.item_list', item: t('activerecord.models.user')), dashboard_users_path diff --git a/app/views/layouts/sessions.html.haml b/app/views/layouts/sessions.html.haml index ec75616..aab7487 100644 --- a/app/views/layouts/sessions.html.haml +++ b/app/views/layouts/sessions.html.haml @@ -8,4 +8,4 @@ = link_to root_path do %h1#logo CloverInteractive -= render :file => 'layouts/application' += render file: 'layouts/application' diff --git a/app/views/layouts/themes/clover/_banner.html.haml b/app/views/layouts/themes/clover/_banner.html.haml index b3d531b..dfe759c 100644 --- a/app/views/layouts/themes/clover/_banner.html.haml +++ b/app/views/layouts/themes/clover/_banner.html.haml @@ -7,9 +7,9 @@ %h1 Impulsamos tu empresa a través de las ventajas que Internet te ofrece: reducir costos, potenciar tus productos y aumentar tu economía. %h3 Consigue aqui desde un consejo hasta una solución de telefonia #slider - #slider_left= link_to image_tag("themes/clover/scroll_left.gif", :alt => "Scroll left"), "#", :class => "previous" - = render :partial => 'layouts/themes/clover/slides' - #slider_right= link_to image_tag("themes/clover/scroll_right.gif", :alt => "Scroll right"), "#", :class => "next" + #slider_left= link_to image_tag("themes/clover/scroll_left.gif", alt: "Scroll left"), "#", class: "previous" + = render partial: 'layouts/themes/clover/slides' + #slider_right= link_to image_tag("themes/clover/scroll_right.gif", alt: "Scroll right"), "#", class: "next" - elsif page.present? %h1= section.name.titleize %h2= page.name.titleize diff --git a/app/views/layouts/themes/clover/_bottom.html.haml b/app/views/layouts/themes/clover/_bottom.html.haml index 697e8e9..1cc06d0 100644 --- a/app/views/layouts/themes/clover/_bottom.html.haml +++ b/app/views/layouts/themes/clover/_bottom.html.haml @@ -28,11 +28,11 @@ #newsletter_box.b360 %h2 Subscribete al newsletter - / - form_for EmailList.new, :url => "/email_lists/add_to_list", :html => { :id => "newsletter", :class => "forms_footer" } do |f| - / %label= f.text_field :email, :value => "Email", :class => "input_text" + / - form_for EmailList.new, url: "/email_lists/add_to_list", html: { id: "newsletter", class: "forms_footer" } do |f| + / %label= f.text_field :email, value: "Email", class: "input_text" / %label.right - / %a.button1{ :href => "javascript:void(null);" } - / %span{ :onclick => "$('#newsletter')[0].submit();" } Subscribir + / %a.button1{ href: "javascript:void(null);" } + / %span{ onclick: "$('#newsletter')[0].submit();" } Subscribir #footer2 diff --git a/app/views/layouts/themes/clover/_slides.html.haml b/app/views/layouts/themes/clover/_slides.html.haml index 3d32dc1..d0aeed0 100644 --- a/app/views/layouts/themes/clover/_slides.html.haml +++ b/app/views/layouts/themes/clover/_slides.html.haml @@ -3,19 +3,19 @@ .first_slide = image_tag "themes/clover/content/preview.jpg" .preview_intro - = link_to image_tag("themes/clover/view_project_btn.jpg"), "http://www.artificialonline.com", :target => "_blank", :class => "view_project" + = link_to image_tag("themes/clover/view_project_btn.jpg"), "http://www.artificialonline.com", target: "_blank", class: "view_project" %p Clover Interactive hospedaje web! %p Hospedaje y administración de sistemas .second_slide = image_tag "themes/clover/content/preview2.jpg" .preview_intro - = link_to image_tag("themes/clover/view_project_btn.jpg"), "http://www.aloboutique.com", :target => "_blank", :class => "view_project" + = link_to image_tag("themes/clover/view_project_btn.jpg"), "http://www.aloboutique.com", target: "_blank", class: "view_project" %p Clover Interactive desarrollo web! %p XHTML + CSS + Ruby, PHP + MySQL .third_slide = image_tag "themes/clover/content/preview3.jpg" .preview_intro - = link_to image_tag("themes/clover/view_project_btn.jpg"), "http://www.tjruby.org", :target => "_blank", :class => "view_project" + = link_to image_tag("themes/clover/view_project_btn.jpg"), "http://www.tjruby.org", target: "_blank", class: "view_project" %p Clover Interactive activo! %p Comprometidos con la comunidad. diff --git a/app/views/layouts/themes/clover/theme.html.haml b/app/views/layouts/themes/clover/theme.html.haml index c69ef44..fdfef1f 100644 --- a/app/views/layouts/themes/clover/theme.html.haml +++ b/app/views/layouts/themes/clover/theme.html.haml @@ -6,18 +6,18 @@ = stylesheet_link_tag :application, :clover = yield :head = csrf_meta_tag - %body{ :class => ( @page.present? && @page.home_page ? '' : 'section' ) } + %body{ class: ( @page.present? && @page.home_page ? '' : 'section' ) } #wrapper - = render :partial => 'layouts/themes/clover/top' - = render :partial => 'layouts/themes/clover/banner', :object => @page + = render partial: 'layouts/themes/clover/top' + = render partial: 'layouts/themes/clover/banner', object: @page #mid - if @page.present? && @page.home_page? #content= yield - = render :partial =>'layouts/themes/clover/sidebar', :object => @page, :locals => { :section => @section } + = render partial:'layouts/themes/clover/sidebar', object: @page, locals: { section: @section } - elsif @page.present? #imid - = render :partial => 'layouts/themes/clover/sidebar', :object => @page, :locals => { :section => @section } + = render partial: 'layouts/themes/clover/sidebar', object: @page, locals: { section: @section } #content= yield - = render :partial => 'layouts/themes/clover/bottom' + = render partial: 'layouts/themes/clover/bottom' diff --git a/app/views/layouts/themes/default/theme.html.haml b/app/views/layouts/themes/default/theme.html.haml index 839035e..1a0ca5c 100644 --- a/app/views/layouts/themes/default/theme.html.haml +++ b/app/views/layouts/themes/default/theme.html.haml @@ -6,7 +6,7 @@ %body #wrapper #page_top - = render :partial => 'layouts/themes/default/top' + = render partial: 'layouts/themes/default/top' #main #content= yield #sidebar= yield :sidebar diff --git a/app/views/layouts/themes/simple_blog/theme.html.haml b/app/views/layouts/themes/simple_blog/theme.html.haml index 04109d5..6059913 100644 --- a/app/views/layouts/themes/simple_blog/theme.html.haml +++ b/app/views/layouts/themes/simple_blog/theme.html.haml @@ -1,17 +1,17 @@ !!!5 %html %head - %meta{ :charset => 'utf-8' } + %meta{ charset: 'utf-8' } = yield :meta %title= content_for?(:title) ? yield(:title) : 'Simple Blog' = stylesheet_link_tag 'application', 'simple_blog' %body - = render :partial => 'layouts/themes/simple_blog/nav' + = render partial: 'layouts/themes/simple_blog/nav' #wrapper - = render :partial => 'layouts/application/flashes' + = render partial: 'layouts/application/flashes' #content_wrapper #content= yield - #sidebar= render :partial => 'layouts/themes/simple_blog/sidebar', :locals => { :section => @section } + #sidebar= render partial: 'layouts/themes/simple_blog/sidebar', locals: { section: @section } .clear - #footer= render :partial => 'layouts/themes/simple_blog/footer', :locals => { :section => @section } + #footer= render partial: 'layouts/themes/simple_blog/footer', locals: { section: @section } diff --git a/app/views/shared/_keywords.html.haml b/app/views/shared/_keywords.html.haml index 63832ae..6727f2e 100644 --- a/app/views/shared/_keywords.html.haml +++ b/app/views/shared/_keywords.html.haml @@ -3,9 +3,9 @@ %label = t 'common.fields.keywords' %small= t 'common.descriptions.keywords' - %input#keyword_input{ :type => :text, :style => 'width: 250px; display: inline' } + %input#keyword_input{ type: :text, style: 'width: 250px; display: inline' } %button#keyword_button= t 'common.forms.add' - %select{ :size => 5, :style => 'width: 350px; border: 1px solid gray;', :id => 'keywords' } + %select{ size: 5, style: 'width: 350px; border: 1px solid gray;', id: 'keywords' } - resource_keywords.each do |keyword| %option=keyword .half diff --git a/app/views/shared/_login_box.html.haml b/app/views/shared/_login_box.html.haml index a1a904e..ecfe482 100644 --- a/app/views/shared/_login_box.html.haml +++ b/app/views/shared/_login_box.html.haml @@ -1,12 +1,12 @@ %h1#logo= 'Clover Interactive' #login-form-container - = form_tag new_user_session_path, :id => 'login-form', :class => 'forms' do + = form_tag new_user_session_path, id: 'login-form', class: 'forms' do #form-body %fieldset = label_tag 'Email' - = text_field_tag 'user[email]', nil, :class => :input_text + = text_field_tag 'user[email]', nil, class: :input_text = label_tag 'Password' - = password_field_tag 'user[password]', nil, :class => :input_text + = password_field_tag 'user[password]', nil, class: :input_text %p - %input.input_button{ :type => :submit, :value => :login } + %input.input_button{ type: :submit, value: :login } %button.input_button Register \ No newline at end of file diff --git a/app/views/shared/_uploadify.html.haml b/app/views/shared/_uploadify.html.haml index f18c082..462da31 100644 --- a/app/views/shared/_uploadify.html.haml +++ b/app/views/shared/_uploadify.html.haml @@ -24,7 +24,7 @@ img.src = response.thumbnail; $("#images_list").append(img); $(img).click(function(){ - image_operations({ element: this, title: '#{t 'links.add_item', :item => t('common.fields.image')}', text: '#{t 'common.headers.add_image', :item => t('common.fields.image')}' }) + image_operations({ element: this, title: '#{t 'links.add_item', item: t('common.fields.image')}', text: '#{t 'common.headers.add_image', item: t('common.fields.image')}' }) }); } }, diff --git a/config/application.rb b/config/application.rb index 4a634fb..06b62f8 100644 --- a/config/application.rb +++ b/config/application.rb @@ -10,7 +10,7 @@ if defined?(Bundler) # If you precompile assets before deploying to production, use this line - Bundler.require(*Rails.groups(:assets => %w(development test))) + Bundler.require(*Rails.groups(assets: %w(development test))) # If you want your assets lazily compiled in production, use this line # Bundler.require(:default, :assets, Rails.env) end diff --git a/config/capistrano_templates.rb b/config/capistrano_templates.rb index 9765ec9..54e9294 100644 --- a/config/capistrano_templates.rb +++ b/config/capistrano_templates.rb @@ -21,7 +21,7 @@ capistrano-ext/multistaging to avoid multiple db:setup calls \ when running deploy:setup for all stages one by one. DESC - task :setup, :except => { :no_release => true } do + task :setup, except: { no_release: true } do default_template = <<-EOF base: &base @@ -61,7 +61,7 @@ desc <<-DESC [internal] Updates the symlink for database.yml file to the just deployed release. DESC - task :symlink, :except => { :no_release => true } do + task :symlink, except: { no_release: true } do run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml" end diff --git a/config/deploy.rb b/config/deploy.rb index 153f0ad..2f75da7 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -14,7 +14,7 @@ role :web, "#{subdomain}.#{domain}" role :app, "#{subdomain}.#{domain}" -role :db, "#{subdomain}.#{domain}", :primary => true +role :db, "#{subdomain}.#{domain}", primary: true set :deploy_to, "/home/#{user}/rails_apps/#{subdomain}.#{domain}/#{application}" @@ -23,7 +23,7 @@ namespace :deploy do task :start do ; end task :stop do ; end - task :restart, :roles => :app, :except => { :no_release => true } do + task :restart, roles: :app, except: { no_release: true } do run "touch #{File.join(current_path,'tmp','restart.txt')}" end diff --git a/config/environments/development.rb b/config/environments/development.rb index 416785b..897419e 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -18,7 +18,7 @@ # Print deprecation notices to the Rails logger config.active_support.deprecation = :log - config.action_mailer.default_url_options = { :host => 'localhost:3000' } + config.action_mailer.default_url_options = { host: 'localhost:3000' } # Only use best-standards-support built into browsers config.action_dispatch.best_standards_support = :builtin diff --git a/config/environments/production.rb b/config/environments/production.rb index 12f6679..53ff2c2 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -40,5 +40,5 @@ # Send deprecation notices to registered listeners config.active_support.deprecation = :notify - config.action_mailer.default_url_options = { :host => 'localhost:3000' } + config.action_mailer.default_url_options = { host: 'localhost:3000' } end diff --git a/config/environments/test.rb b/config/environments/test.rb index 5b27ebc..633b523 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -36,7 +36,7 @@ # Print deprecation notices to the stderr config.active_support.deprecation = :stderr - config.action_mailer.default_url_options = { :host => 'localhost:3000' } + config.action_mailer.default_url_options = { host: 'localhost:3000' } # Allow pass debug_assets=true as a query parameter to load pages with unpackaged assets config.assets.allow_debugging = true diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 6812fbc..d6bcc60 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -69,7 +69,7 @@ # :http_auth and :token_auth by adding those symbols to the array below. # Notice that if you are skipping storage for all authentication paths, you # may want to disable generating routes to Devise's sessions controller by - # passing :skip => :sessions to `devise_for` in your config/routes.rb + # passing skip: :sessions to `devise_for` in your config/routes.rb config.skip_session_storage = [:http_auth] # ==> Configuration for :database_authenticatable @@ -99,8 +99,8 @@ # The key to be used to check existing users when sending an invitation # and the regexp used to test it when validate_on_invite is not set. - # config.invite_key = {:email => /A[^@]+@[^@]+z/} - # config.invite_key = {:email => /A[^@]+@[^@]+z/, :username => nil} + # config.invite_key = {email: /A[^@]+@[^@]+z/} + # config.invite_key = {email: /A[^@]+@[^@]+z/, username: nil} # Flag that force a record to be valid before being actually invited # Default: false @@ -131,7 +131,7 @@ # config.extend_remember_period = false # Options to be passed to the created cookie. For instance, you can set - # :secure => true in order to force SSL only cookies. + # secure: true in order to force SSL only cookies. # config.rememberable_options = {} # ==> Configuration for :validatable @@ -227,7 +227,7 @@ # ==> OmniAuth # Add a new OmniAuth provider. Check the wiki for more information on setting # up on your models and hooks. - # config.omniauth :github, 'APP_ID', 'APP_SECRET', :scope => 'user,public_repo' + # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo' # ==> Warden configuration # If you want to use other strategies, that are not supported by Devise, or @@ -235,7 +235,7 @@ # # config.warden do |manager| # manager.intercept_401 = false - # manager.default_strategies(:scope => :user).unshift :some_external_strategy + # manager.default_strategies(scope: :user).unshift :some_external_strategy # end # ==> Mountable engine configurations diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb index 6dba04c..86a1001 100644 --- a/config/initializers/session_store.rb +++ b/config/initializers/session_store.rb @@ -1,6 +1,6 @@ # Be sure to restart your server when you modify this file. -Clover::Application.config.session_store :cookie_store, :key => '_clover_session' +Clover::Application.config.session_store :cookie_store, key: '_clover_session' # Use the database for sessions instead of the cookie-based default, # which shouldn't be used to store highly confidential information diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb index da4fb07..999df20 100644 --- a/config/initializers/wrap_parameters.rb +++ b/config/initializers/wrap_parameters.rb @@ -5,7 +5,7 @@ # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. ActiveSupport.on_load(:action_controller) do - wrap_parameters :format => [:json] + wrap_parameters format: [:json] end # Disable root element in JSON by default. diff --git a/config/routes.rb b/config/routes.rb index 20f16ae..9b48195 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,21 +1,21 @@ Clover::Application.routes.draw do - devise_for :users, :controllers => { :registrations => 'users/registrations' } + devise_for :users, controllers: { registrations: 'users/registrations' } - resource :contact_form, :only => [ :create ] + resource :contact_form, only: [ :create ] - match "/dashboard", :to => "dashboard/sections#index", :as => :dashboard, :via => :get - match "/dashboard/profile", :to => redirect("/users/edit"), :as => :user_root, :via => :get + match "/dashboard", to: "dashboard/sections#index", as: :dashboard, via: :get + match "/dashboard/profile", to: redirect("/users/edit"), as: :user_root, via: :get namespace :dashboard do - resources :users, :only => [ :index, :destroy ] - resources :assets, :only => [ :create, :destroy ] - resources :settings, :except => :show - resources :sections, :except => :show - resources :pages, :except => :show + resources :users, only: [ :index, :destroy ] + resources :assets, only: [ :create, :destroy ] + resources :settings, except: :show + resources :sections, except: :show + resources :pages, except: :show end - match ":section/:page", :to => "pages#show", :as => :section_page, :via => :get, :format => :html - match ":section/:subsection/:page", :to => "pages#show", :as => :subsection_page, :via => :get, :format => :html + match ":section/:page", to: "pages#show", as: :section_page, via: :get, format: :html + match ":section/:subsection/:page", to: "pages#show", as: :subsection_page, via: :get, format: :html - root :to => "pages#home", :via => :get + root to: "pages#home", via: :get end diff --git a/db/migrate/20100805055902_create_sections.rb b/db/migrate/20100805055902_create_sections.rb index c7d6f21..cfeb141 100644 --- a/db/migrate/20100805055902_create_sections.rb +++ b/db/migrate/20100805055902_create_sections.rb @@ -3,7 +3,7 @@ def self.up create_table :sections do |t| t.string :name t.integer :main_section_id - t.string :url_name, :unique => true + t.string :url_name, unique: true t.timestamps end diff --git a/db/migrate/20100806061522_create_pages.rb b/db/migrate/20100806061522_create_pages.rb index baf21f7..f63268d 100644 --- a/db/migrate/20100806061522_create_pages.rb +++ b/db/migrate/20100806061522_create_pages.rb @@ -5,9 +5,9 @@ def self.up t.string :url_name t.text :content t.integer :section_id - t.boolean :published, :default => false - t.boolean :home_page, :default => false - t.boolean :has_contact, :default => false + t.boolean :published, default: false + t.boolean :home_page, default: false + t.boolean :has_contact, default: false t.timestamps end diff --git a/db/migrate/20100814005921_devise_create_users.rb b/db/migrate/20100814005921_devise_create_users.rb index 5e5d3eb..8b0f52e 100644 --- a/db/migrate/20100814005921_devise_create_users.rb +++ b/db/migrate/20100814005921_devise_create_users.rb @@ -2,9 +2,9 @@ class DeviseCreateUsers < ActiveRecord::Migration def self.up create_table(:users) do |t| ## Database authenticatable - t.string :email, :null => false, :default => "" - t.string :username, :null => false, :default => '' - t.string :encrypted_password, :null => false, :default => "" + t.string :email, null: false, default: "" + t.string :username, null: false, default: '' + t.string :encrypted_password, null: false, default: "" ## Recoverable t.string :reset_password_token @@ -14,7 +14,7 @@ def self.up t.datetime :remember_created_at ## Trackable - t.integer :sign_in_count, :default => 0 + t.integer :sign_in_count, default: 0 t.datetime :current_sign_in_at t.datetime :last_sign_in_at t.string :current_sign_in_ip @@ -30,7 +30,7 @@ def self.up t.string :unconfirmed_email # Only if using reconfirmable ## Lockable - t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts + t.integer :failed_attempts, default: 0 # Only if lock strategy is :failed_attempts t.string :unlock_token # Only if unlock strategy is :email or :both t.datetime :locked_at @@ -43,11 +43,11 @@ def self.up t.timestamps end - add_index :users, :email, :unique => true - add_index :users, :username, :unique => true - add_index :users, :reset_password_token, :unique => true - add_index :users, :confirmation_token, :unique => true - add_index :users, :unlock_token, :unique => true + add_index :users, :email, unique: true + add_index :users, :username, unique: true + add_index :users, :reset_password_token, unique: true + add_index :users, :confirmation_token, unique: true + add_index :users, :unlock_token, unique: true end def self.down diff --git a/db/migrate/20101012145155_acts_as_taggable_on_migration.rb b/db/migrate/20101012145155_acts_as_taggable_on_migration.rb index e47c4a1..7d78c98 100644 --- a/db/migrate/20101012145155_acts_as_taggable_on_migration.rb +++ b/db/migrate/20101012145155_acts_as_taggable_on_migration.rb @@ -9,8 +9,8 @@ def self.up # You should make sure that the column created is # long enough to store the required class names. - t.references :taggable, :polymorphic => true - t.references :tagger, :polymorphic => true + t.references :taggable, polymorphic: true + t.references :tagger, polymorphic: true t.string :context diff --git a/db/migrate/20110209072651_create_settings.rb b/db/migrate/20110209072651_create_settings.rb index 583b527..f41b6b8 100644 --- a/db/migrate/20110209072651_create_settings.rb +++ b/db/migrate/20110209072651_create_settings.rb @@ -1,10 +1,10 @@ class CreateSettings < ActiveRecord::Migration def self.up create_table :settings do |t| - t.string :name, :null => false - t.text :value, :null => false + t.string :name, null: false + t.text :value, null: false t.string :description - t.boolean :destroyable, :default => true + t.boolean :destroyable, default: true t.timestamps end diff --git a/db/migrate/20120918221141_add_slug_to_pages.rb b/db/migrate/20120918221141_add_slug_to_pages.rb index 18bc4f8..35d70f9 100644 --- a/db/migrate/20120918221141_add_slug_to_pages.rb +++ b/db/migrate/20120918221141_add_slug_to_pages.rb @@ -1,6 +1,6 @@ class AddSlugToPages < ActiveRecord::Migration def change add_column :pages, :slug, :string - add_index :pages, :slug, :unique => true + add_index :pages, :slug, unique: true end end diff --git a/db/migrate/20120918223422_add_slug_to_sections.rb b/db/migrate/20120918223422_add_slug_to_sections.rb index 46407c6..733fc07 100644 --- a/db/migrate/20120918223422_add_slug_to_sections.rb +++ b/db/migrate/20120918223422_add_slug_to_sections.rb @@ -1,6 +1,6 @@ class AddSlugToSections < ActiveRecord::Migration def change add_column :sections, :slug, :string - add_index :sections, :slug, :unique => true + add_index :sections, :slug, unique: true end end diff --git a/db/schema.rb b/db/schema.rb index db70c88..9596aaa 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,9 +11,9 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120918223422) do +ActiveRecord::Schema.define(version: 20120918223422) do - create_table "assets", :force => true do |t| + create_table "assets", force: true do |t| t.string "description" t.string "asset_file_name" t.string "asset_content_type" @@ -22,45 +22,45 @@ t.string "attachable_type" end - add_index "assets", ["asset_content_type"], :name => "index_assets_on_asset_content_type" - add_index "assets", ["attachable_id", "attachable_type"], :name => "index_assets_on_attachable_id_and_attachable_type" + add_index "assets", ["asset_content_type"], name: "index_assets_on_asset_content_type" + add_index "assets", ["attachable_id", "attachable_type"], name: "index_assets_on_attachable_id_and_attachable_type" - create_table "pages", :force => true do |t| + create_table "pages", force: true do |t| t.string "name" t.text "content" t.integer "section_id" - t.boolean "published", :default => false - t.boolean "home_page", :default => false - t.boolean "has_contact", :default => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.boolean "published", default: false + t.boolean "home_page", default: false + t.boolean "has_contact", default: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "slug" end - add_index "pages", ["section_id"], :name => "index_pages_on_section_id" - add_index "pages", ["slug"], :name => "index_pages_on_slug", :unique => true + add_index "pages", ["section_id"], name: "index_pages_on_section_id" + add_index "pages", ["slug"], name: "index_pages_on_slug", unique: true - create_table "sections", :force => true do |t| + create_table "sections", force: true do |t| t.string "name" t.integer "main_section_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "slug" end - add_index "sections", ["main_section_id"], :name => "index_sections_on_main_section_id" - add_index "sections", ["slug"], :name => "index_sections_on_slug", :unique => true + add_index "sections", ["main_section_id"], name: "index_sections_on_main_section_id" + add_index "sections", ["slug"], name: "index_sections_on_slug", unique: true - create_table "settings", :force => true do |t| - t.string "name", :null => false - t.text "value", :null => false + create_table "settings", force: true do |t| + t.string "name", null: false + t.text "value", null: false t.string "description" - t.boolean "destroyable", :default => true - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.boolean "destroyable", default: true + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table "taggings", :force => true do |t| + create_table "taggings", force: true do |t| t.integer "tag_id" t.integer "taggable_id" t.string "taggable_type" @@ -70,22 +70,22 @@ t.datetime "created_at" end - add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" - add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context" - add_index "taggings", ["tagger_id", "tagger_type"], :name => "index_taggings_on_tagger_id_and_tagger_type" + add_index "taggings", ["tag_id"], name: "index_taggings_on_tag_id" + add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context" + add_index "taggings", ["tagger_id", "tagger_type"], name: "index_taggings_on_tagger_id_and_tagger_type" - create_table "tags", :force => true do |t| + create_table "tags", force: true do |t| t.string "name" end - create_table "users", :force => true do |t| - t.string "email", :default => "", :null => false - t.string "username", :default => "", :null => false - t.string "encrypted_password", :default => "", :null => false + create_table "users", force: true do |t| + t.string "email", default: "", null: false + t.string "username", default: "", null: false + t.string "encrypted_password", default: "", null: false t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" - t.integer "sign_in_count", :default => 0 + t.integer "sign_in_count", default: 0 t.datetime "current_sign_in_at" t.datetime "last_sign_in_at" t.string "current_sign_in_ip" @@ -94,17 +94,17 @@ t.datetime "confirmed_at" t.datetime "confirmation_sent_at" t.string "unconfirmed_email" - t.integer "failed_attempts", :default => 0 + t.integer "failed_attempts", default: 0 t.string "unlock_token" t.datetime "locked_at" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - add_index "users", ["confirmation_token"], :name => "index_users_on_confirmation_token", :unique => true - add_index "users", ["email"], :name => "index_users_on_email", :unique => true - add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true - add_index "users", ["unlock_token"], :name => "index_users_on_unlock_token", :unique => true - add_index "users", ["username"], :name => "index_users_on_username", :unique => true + add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true + add_index "users", ["email"], name: "index_users_on_email", unique: true + add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true + add_index "users", ["unlock_token"], name: "index_users_on_unlock_token", unique: true + add_index "users", ["username"], name: "index_users_on_username", unique: true end diff --git a/db/seeds.rb b/db/seeds.rb index 060d2b2..e6d4317 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -1,30 +1,30 @@ # We crate our default section and page to avoid CMS errors -section = Section.create!( :name => 'main' ) -page = section.pages.build( :name => 'main page', :content => 'this is my main page', :home_page => true, :published => true ).save! +section = Section.create!( name: 'main' ) +page = section.pages.build( name: 'main page', content: 'this is my main page', home_page: true, published: true ).save! # We create and activate a default user -user = User.create! :username => 'admin', :password => 'administrator', :email => "admin@example.com" +user = User.create! username: 'admin', password: 'administrator', email: "admin@example.com" user.save! # We create the default non-destroyable site settings default_settings = [ { - :name => 'theme', - :value => 'default', - :description => 'This is the theme of your site.' + name: 'theme', + value: 'default', + description: 'This is the theme of your site.' }, { - :name => 'site_name', - :value => 'CloverInteractive', - :description => 'This is your site name.' + name: 'site_name', + value: 'CloverInteractive', + description: 'This is your site name.' }, { - :name => 'footer', - :value => 'This site is powered by CloverInteractive', - :description => "This is your site's footer." + name: 'footer', + value: 'This site is powered by CloverInteractive', + description: "This is your site's footer." } ] diff --git a/spec/controllers/dashboard/pages_controller_spec.rb b/spec/controllers/dashboard/pages_controller_spec.rb index 2fa449a..5efafd6 100644 --- a/spec/controllers/dashboard/pages_controller_spec.rb +++ b/spec/controllers/dashboard/pages_controller_spec.rb @@ -67,7 +67,7 @@ describe "POST create" do let( :page_attr ) { attributes_for :page, name: 'new page', section_id: section.id } - before { post :create, :page => page_attr } + before { post :create, page: page_attr } it "should redirect to index" do response.should redirect_to( dashboard_pages_path ) @@ -79,14 +79,14 @@ end it "should render new if anything goes wrong" do - post :create, :page => page_attr.merge( name: page.name ) + post :create, page: page_attr.merge( name: page.name ) response.should render_template( :new ) end end describe "PUT update" do before :each do - put :update, :id => page, page: { name: 'batman' } + put :update, id: page, page: { name: 'batman' } end it "should redirect to index" do diff --git a/spec/controllers/dashboard/settings_controller_spec.rb b/spec/controllers/dashboard/settings_controller_spec.rb index 0a7933f..7094c7f 100644 --- a/spec/controllers/dashboard/settings_controller_spec.rb +++ b/spec/controllers/dashboard/settings_controller_spec.rb @@ -118,7 +118,7 @@ setting.destroyable = false setting.save! - expect { delete :destroy, :id => setting }.to_not change { Setting.count } + expect { delete :destroy, id: setting }.to_not change { Setting.count } end end end diff --git a/spec/support/controller_spec_helper.rb b/spec/support/controller_spec_helper.rb index dbaf678..5776d40 100644 --- a/spec/support/controller_spec_helper.rb +++ b/spec/support/controller_spec_helper.rb @@ -6,5 +6,5 @@ def login_as( user ) end RSpec.configure do |config| - config.include ControllerSpecHelpers, :type => :controller + config.include ControllerSpecHelpers, type: :controller end From b5e7e39011e41c8be5018814067c546e59118e46 Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Sat, 3 Aug 2013 16:37:33 -0700 Subject: [PATCH 09/32] Add config generate task --- config/_database.yml.erb | 15 +++++++++++++ config/_vhost.conf.erb | 47 ++++++++++++++++++++++++++++++++++++++++ lib/tasks/config.rake | 46 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 config/_database.yml.erb create mode 100644 config/_vhost.conf.erb create mode 100644 lib/tasks/config.rake diff --git a/config/_database.yml.erb b/config/_database.yml.erb new file mode 100644 index 0000000..3725b2a --- /dev/null +++ b/config/_database.yml.erb @@ -0,0 +1,15 @@ +defaults: &defaults + adapter: postgresql + encoding: utf8 + pool: 5 + host: localhost + username: cms + min_messages: warning + +test: + <<: *defaults + database: cms_test + +<%= Rails.env %>: + <<: *defaults + database: cms_<%= Rails.env %> diff --git a/config/_vhost.conf.erb b/config/_vhost.conf.erb new file mode 100644 index 0000000..f6ebcaa --- /dev/null +++ b/config/_vhost.conf.erb @@ -0,0 +1,47 @@ +<% +if _bare_host = @host.match( /^(?:www)\.(.*)/ ) + _bare_host = _bare_host[1] +end + +def ip_from_hostname hostname + require 'socket' + Socket.gethostbyname( hostname )[3].unpack( 'C4' ).join '.' +end + +if _bare_host.present? +%> +server { + listen 80; + server_name <%= _bare_host %>; + rewrite ^(.*) http://<%= @host %>$1 permanent; +} + +<% end %> +server { + listen 80; + server_name <%= @host %>; + + root <%= @public %>; + passenger_enabled on; + + access_log <%= @log %>/nginx.access.log; + error_log <%= @log %>/nginx.error.log warn; + + sendfile on; + location ~ ^/assets/ { + gzip_static on; + gzip_disable "MSIE [1-60]\."; + expires max; + add_header Cache-Control public; + add_header ETag ""; + } + + error_page 401 403 404 /404.html; + error_page 500 502 503 504 /50x.html; + + location = /50x.html { + root html; + } +} + +# vim: set ft=nginx: diff --git a/lib/tasks/config.rake b/lib/tasks/config.rake new file mode 100644 index 0000000..61db15f --- /dev/null +++ b/lib/tasks/config.rake @@ -0,0 +1,46 @@ +namespace :config do + desc "Generate application environtment files" + task :generate => [ :vhost, :database ] + + desc "Generate nginx vhost" + task :vhost do + erb_parse :vhost + end + + + desc "Generate database.yml" + task :database do + erb_parse :database, extension: '.yml' + end + + def erb_parse name, opts={} + require 'erb' + ext = opts[:extension] || '.conf' + + host = { + 'development' => 'www.cms.dev', + 'production' => 'www.cloverinteractive.com', + 'staging' => 'staging.cloverinteractive.com' + }[ Rails.env ] + + config_dir = Rails.root.join( 'config' ).to_s + + erb_env = Proc.new do + @host = host + @root = Rails.root + + @subdomain = host.split( '.' ).first + @public = "#{ @root.join 'public' }" + @log = "#{ @root.join 'log' }" + @dev_on = Rails.env.production? ? 'off' : 'on' + + binding + end.call + + response = ERB.new File.read( File.join( config_dir, "_#{ name }#{ ext }.erb" ) ) + + File.open File.join( config_dir, "#{ name }#{ ext }" ), 'w' do |f| + f.print response.result( erb_env ) + end + end +end From 870370b6e89fbf6923522036ed00565cd2515547 Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Sat, 3 Aug 2013 16:44:54 -0700 Subject: [PATCH 10/32] Remove fat --- .gitignore | 29 ++++------ config/capistrano_templates.rb | 74 -------------------------- config/cucumber.yml | 8 --- spec/support/controller_spec_helper.rb | 10 ---- 4 files changed, 9 insertions(+), 112 deletions(-) delete mode 100644 config/capistrano_templates.rb delete mode 100644 config/cucumber.yml delete mode 100644 spec/support/controller_spec_helper.rb diff --git a/.gitignore b/.gitignore index 03e0085..fcd76ad 100644 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,11 @@ -log/*.log -tmp/* -tmp/**/* -doc/api -doc/app -db/*.sqlite3 -.sass-cache/ -public/stylesheets/*.css -.rspec/ -*.swp -*~ -.DS_Store -public/images/system -public/system -public/.htaccess +/.bundle +/log/*.log +/tmp +config/vhost.conf +config/database.yml public/assets -*.bak -Thumbs.db -.bundle +public/system +.sass-cache +tags +coverage bin/ -coverage/* -config/vhost.conf diff --git a/config/capistrano_templates.rb b/config/capistrano_templates.rb deleted file mode 100644 index 54e9294..0000000 --- a/config/capistrano_templates.rb +++ /dev/null @@ -1,74 +0,0 @@ -unless Capistrano::Configuration.respond_to?(:instance) - abort "This extension requires Capistrano 2" -end - -Capistrano::Configuration.instance.load do - namespace :deploy do - namespace :db do - - desc <<-DESC - Creates the database.yml configuration file in shared path. - - By default, this task uses a template unless a template \ - called database.yml.erb is found either is :template_dir \ - or /config/deploy folders. The default template matches \ - the template for config/database.yml file shipped with Rails. - - When this recipe is loaded, db:setup is automatically configured \ - to be invoked after deploy:setup. You can skip this task setting \ - the variable :skip_db_setup to true. This is especially useful \ - if you are using this recipe in combination with \ - capistrano-ext/multistaging to avoid multiple db:setup calls \ - when running deploy:setup for all stages one by one. - DESC - task :setup, except: { no_release: true } do - - default_template = <<-EOF - base: &base - adapter: sqlite3 - timeout: 5000 - development: - database: #{shared_path}/db/development.sqlite3 - <<: *base - test: - database: #{shared_path}/db/test.sqlite3 - <<: *base - production: - database: #{shared_path}/db/production.sqlite3 - <<: *base - EOF - - database = fetch(:template_dir, "config/deploy") + '/database.yml.erb' - htaccess = fetch(:template_dir, "config/deploy") + '/htaccess.erb' - - database_template = File.file?(database) ? File.read(database) : default_template - database_config = ERB.new(database_template) - - if File.file?(htaccess) - htaccess_template = File.read(htaccess) - apache_config = ERB.new(htaccess_template) - end - - run "mkdir -p #{shared_path}/db" - run "mkdir -p #{shared_path}/config" - run "mkdir -p #{shared_path}/vendor" - run "mkdir -p #{shared_path}/public" - - put database_config.result(binding), "#{shared_path}/config/database.yml" - put apache_config.result(binding), "#{shared_path}/public/.htaccess" if !apache_config.nil? - end - - desc <<-DESC - [internal] Updates the symlink for database.yml file to the just deployed release. - DESC - task :symlink, except: { no_release: true } do - run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml" - end - - end - - after "deploy:setup", "deploy:db:setup" unless fetch(:skip_db_setup, false) - after "deploy:finalize_update", "deploy:db:symlink" - end -end - diff --git a/config/cucumber.yml b/config/cucumber.yml deleted file mode 100644 index 19b288d..0000000 --- a/config/cucumber.yml +++ /dev/null @@ -1,8 +0,0 @@ -<% -rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : "" -rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}" -std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags ~@wip" -%> -default: <%= std_opts %> features -wip: --tags @wip:3 --wip features -rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip diff --git a/spec/support/controller_spec_helper.rb b/spec/support/controller_spec_helper.rb deleted file mode 100644 index 5776d40..0000000 --- a/spec/support/controller_spec_helper.rb +++ /dev/null @@ -1,10 +0,0 @@ -module ControllerSpecHelpers - def login_as( user ) - @controller.class.any_instance.stubs( :current_user ).returns user - @controller.class.any_instance.stubs( :authenticate_user! ).returns true - end -end - -RSpec.configure do |config| - config.include ControllerSpecHelpers, type: :controller -end From 743e8315ebc0554986ec98486504aa5b33fcce18 Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Sat, 3 Aug 2013 17:10:42 -0700 Subject: [PATCH 11/32] Update travis recipe and set ruby-version --- .ruby-version | 1 + .travis.yml | 10 ++++++---- Gemfile.lock | 6 +++--- 3 files changed, 10 insertions(+), 7 deletions(-) create mode 100644 .ruby-version diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..cb50681 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +2.0.0-p247 diff --git a/.travis.yml b/.travis.yml index 79b7ebd..1ef9f20 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,13 @@ -before_script: "RAILS_ENV=development bundle exec rake db:migrate db:test:prepare" -script: "bundle exec rake spec" +before_script: + - RAILS_ENV=development bundle exec rake config:generate + - psql -c 'create database cms_test;' -U postgres + - 'sh -e /etc/init.d/xvfb start' +script: + - 'DISPLAY=:99.0 bundle exec rake spec' rvm: - 2.0.0 - 1.9.3 notifications: recipients: - enrique@cloverinteractive.com - - alejandro@cloverinteractive.com - adan@cloverinteractive.com - - alexperto@cloveritneractive.com diff --git a/Gemfile.lock b/Gemfile.lock index a65d4bf..bd48f03 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -87,12 +87,12 @@ GEM compass (~> 0.12.0) database_cleaner (0.7.2) debug_inspector (0.0.2) - debugger (1.6.0) + debugger (1.6.1) columnize (>= 0.3.1) debugger-linecache (~> 1.2.0) - debugger-ruby_core_source (~> 1.2.1) + debugger-ruby_core_source (~> 1.2.3) debugger-linecache (1.2.0) - debugger-ruby_core_source (1.2.2) + debugger-ruby_core_source (1.2.3) devise (3.0.0) bcrypt-ruby (~> 3.0) orm_adapter (~> 0.1) From 128f00018295b8125f3c2dd1d3e7fa2127cc090a Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Sat, 3 Aug 2013 17:30:25 -0700 Subject: [PATCH 12/32] Force test env on spec_helper --- spec/spec_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2683aa6..81760ce 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,5 @@ # This file is copied to spec/ when you run 'rails generate rspec:install' -ENV["RAILS_ENV"] ||= 'test' +ENV["RAILS_ENV"] = 'test' require 'simplecov' SimpleCov.start 'rails' From f0938ffd1e07bdbae37e06c67e3c5a726b955b50 Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Sat, 3 Aug 2013 17:41:43 -0700 Subject: [PATCH 13/32] Create postgres cms role in travis --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1ef9f20..e0cb193 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ before_script: - - RAILS_ENV=development bundle exec rake config:generate - - psql -c 'create database cms_test;' -U postgres + - sudo -u postgres createuser cms -d + - RAILS_ENV=development bundle exec rake config:generate db:create - 'sh -e /etc/init.d/xvfb start' script: - 'DISPLAY=:99.0 bundle exec rake spec' From 7eaca4cc609b9ccd5558e7e578e1fa826ad2a367 Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Sat, 3 Aug 2013 19:22:17 -0700 Subject: [PATCH 14/32] Update README links --- README.md | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index b9ff723..4f3a25a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Clover CMS [![Build Status](http://travis-ci.org/cloverinteractive/cms.png)](http://travis-ci.org/cloverinteractive/clovercms) +# Clover CMS [![Build Status](http://travis-ci.org/cloverinteractive/cms.png)](http://travis-ci.org/cloverinteractive/cms) __A dead simple content management system for Rails 3.2.14__ @@ -29,18 +29,8 @@ To install and run in development: We currently test with: -* ruby 1.9.2 -* ruby 1.8.7 -* ree - -### JRuby - -We take JRuby into consideration, and our Gemfile works nice with its platforms, but since we can only version one instance, we don't build against it. However you can use `clovercms` with JRuby by doing the following: - -0. `rm -f Gemfile.lock` -1. `jruby -S bundle install` - -## Contribute +* ruby 2.0.0 +* ruby 1.9.3 Feel free to submit a pull request and don't forget to add your name to the list below. From 61cd3a8216955dee0d547fea34702db23a65cc4f Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Sat, 3 Aug 2013 19:46:09 -0700 Subject: [PATCH 15/32] Generate secret_token from config:generate task --- .gitignore | 1 + .travis.yml | 2 +- config/_secret_token.rb.erb | 1 + config/initializers/secret_token.rb | 7 ------- lib/tasks/config.rake | 28 +++++++++++++++++++--------- 5 files changed, 22 insertions(+), 17 deletions(-) create mode 100644 config/_secret_token.rb.erb delete mode 100644 config/initializers/secret_token.rb diff --git a/.gitignore b/.gitignore index fcd76ad..b8d9d1e 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ public/system tags coverage bin/ +config/initializers/secret_token.rb diff --git a/.travis.yml b/.travis.yml index e0cb193..a7f9fc1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ before_script: - - sudo -u postgres createuser cms -d + - sudo -u postgres createuser cms -dSR - RAILS_ENV=development bundle exec rake config:generate db:create - 'sh -e /etc/init.d/xvfb start' script: diff --git a/config/_secret_token.rb.erb b/config/_secret_token.rb.erb new file mode 100644 index 0000000..da0392d --- /dev/null +++ b/config/_secret_token.rb.erb @@ -0,0 +1 @@ +Clover::Application.config.secret_token = '<%= @secret_token %>' diff --git a/config/initializers/secret_token.rb b/config/initializers/secret_token.rb deleted file mode 100644 index 2b560d3..0000000 --- a/config/initializers/secret_token.rb +++ /dev/null @@ -1,7 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Your secret key for verifying the integrity of signed cookies. -# If you change this key, all old signed cookies will become invalid! -# Make sure the secret is at least 30 characters and all random, -# no regular words or you'll be exposed to dictionary attacks. -Clover::Application.config.secret_token = 'eea93344927bd7860495a5c87132622ca87a41909fb0dddd3774b7f0d438386d1af9be3af199177c5987383fcbf31713c543bd659df8aeb54b7aa31aeed138b1' diff --git a/lib/tasks/config.rake b/lib/tasks/config.rake index 61db15f..8658fdf 100644 --- a/lib/tasks/config.rake +++ b/lib/tasks/config.rake @@ -1,6 +1,6 @@ namespace :config do - desc "Generate application environtment files" - task :generate => [ :vhost, :database ] + desc "Generate application environment files" + task :generate => [ :vhost, :database, :secret_token ] desc "Generate nginx vhost" task :vhost do @@ -13,8 +13,15 @@ namespace :config do erb_parse :database, extension: '.yml' end + desc "Generate secret_token.rb" + task :secret_token do + erb_parse :secret_token, extension: '.rb', output_dir: Rails.root.join( 'config', 'initializers' ).to_s + end + def erb_parse name, opts={} require 'erb' + require 'securerandom' + ext = opts[:extension] || '.conf' host = { @@ -24,22 +31,25 @@ namespace :config do }[ Rails.env ] config_dir = Rails.root.join( 'config' ).to_s - + output_dir = opts[:output_dir] || config_dir + erb_env = Proc.new do @host = host @root = Rails.root - @subdomain = host.split( '.' ).first - @public = "#{ @root.join 'public' }" - @log = "#{ @root.join 'log' }" - @dev_on = Rails.env.production? ? 'off' : 'on' + @subdomain = host.split( '.' ).first + @public = "#{ @root.join 'public' }" + @log = "#{ @root.join 'log' }" + @dev_on = Rails.env.production? ? 'off' : 'on' + + @secret_token = SecureRandom.hex 64 binding end.call response = ERB.new File.read( File.join( config_dir, "_#{ name }#{ ext }.erb" ) ) - - File.open File.join( config_dir, "#{ name }#{ ext }" ), 'w' do |f| + + File.open File.join( output_dir, "#{ name }#{ ext }" ), 'w' do |f| f.print response.result( erb_env ) end end From e3e9ec469e15b115d0c3976a8d171b5c22f99c50 Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Sat, 3 Aug 2013 19:53:02 -0700 Subject: [PATCH 16/32] Add migrate to the travis recipe --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a7f9fc1..b03b0a0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ before_script: - sudo -u postgres createuser cms -dSR - - RAILS_ENV=development bundle exec rake config:generate db:create + - RAILS_ENV=development bundle exec rake config:generate db:create db:migrate - 'sh -e /etc/init.d/xvfb start' script: - 'DISPLAY=:99.0 bundle exec rake spec' From af6c97af26941f05bced3ef6f188805e97bfe0ac Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Sat, 3 Aug 2013 20:04:15 -0700 Subject: [PATCH 17/32] Reset schema.rb --- db/schema.rb | 82 ++++++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 9596aaa..db70c88 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,9 +11,9 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(version: 20120918223422) do +ActiveRecord::Schema.define(:version => 20120918223422) do - create_table "assets", force: true do |t| + create_table "assets", :force => true do |t| t.string "description" t.string "asset_file_name" t.string "asset_content_type" @@ -22,45 +22,45 @@ t.string "attachable_type" end - add_index "assets", ["asset_content_type"], name: "index_assets_on_asset_content_type" - add_index "assets", ["attachable_id", "attachable_type"], name: "index_assets_on_attachable_id_and_attachable_type" + add_index "assets", ["asset_content_type"], :name => "index_assets_on_asset_content_type" + add_index "assets", ["attachable_id", "attachable_type"], :name => "index_assets_on_attachable_id_and_attachable_type" - create_table "pages", force: true do |t| + create_table "pages", :force => true do |t| t.string "name" t.text "content" t.integer "section_id" - t.boolean "published", default: false - t.boolean "home_page", default: false - t.boolean "has_contact", default: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.boolean "published", :default => false + t.boolean "home_page", :default => false + t.boolean "has_contact", :default => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.string "slug" end - add_index "pages", ["section_id"], name: "index_pages_on_section_id" - add_index "pages", ["slug"], name: "index_pages_on_slug", unique: true + add_index "pages", ["section_id"], :name => "index_pages_on_section_id" + add_index "pages", ["slug"], :name => "index_pages_on_slug", :unique => true - create_table "sections", force: true do |t| + create_table "sections", :force => true do |t| t.string "name" t.integer "main_section_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.string "slug" end - add_index "sections", ["main_section_id"], name: "index_sections_on_main_section_id" - add_index "sections", ["slug"], name: "index_sections_on_slug", unique: true + add_index "sections", ["main_section_id"], :name => "index_sections_on_main_section_id" + add_index "sections", ["slug"], :name => "index_sections_on_slug", :unique => true - create_table "settings", force: true do |t| - t.string "name", null: false - t.text "value", null: false + create_table "settings", :force => true do |t| + t.string "name", :null => false + t.text "value", :null => false t.string "description" - t.boolean "destroyable", default: true - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.boolean "destroyable", :default => true + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end - create_table "taggings", force: true do |t| + create_table "taggings", :force => true do |t| t.integer "tag_id" t.integer "taggable_id" t.string "taggable_type" @@ -70,22 +70,22 @@ t.datetime "created_at" end - add_index "taggings", ["tag_id"], name: "index_taggings_on_tag_id" - add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context" - add_index "taggings", ["tagger_id", "tagger_type"], name: "index_taggings_on_tagger_id_and_tagger_type" + add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" + add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context" + add_index "taggings", ["tagger_id", "tagger_type"], :name => "index_taggings_on_tagger_id_and_tagger_type" - create_table "tags", force: true do |t| + create_table "tags", :force => true do |t| t.string "name" end - create_table "users", force: true do |t| - t.string "email", default: "", null: false - t.string "username", default: "", null: false - t.string "encrypted_password", default: "", null: false + create_table "users", :force => true do |t| + t.string "email", :default => "", :null => false + t.string "username", :default => "", :null => false + t.string "encrypted_password", :default => "", :null => false t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" - t.integer "sign_in_count", default: 0 + t.integer "sign_in_count", :default => 0 t.datetime "current_sign_in_at" t.datetime "last_sign_in_at" t.string "current_sign_in_ip" @@ -94,17 +94,17 @@ t.datetime "confirmed_at" t.datetime "confirmation_sent_at" t.string "unconfirmed_email" - t.integer "failed_attempts", default: 0 + t.integer "failed_attempts", :default => 0 t.string "unlock_token" t.datetime "locked_at" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end - add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true - add_index "users", ["email"], name: "index_users_on_email", unique: true - add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true - add_index "users", ["unlock_token"], name: "index_users_on_unlock_token", unique: true - add_index "users", ["username"], name: "index_users_on_username", unique: true + add_index "users", ["confirmation_token"], :name => "index_users_on_confirmation_token", :unique => true + add_index "users", ["email"], :name => "index_users_on_email", :unique => true + add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true + add_index "users", ["unlock_token"], :name => "index_users_on_unlock_token", :unique => true + add_index "users", ["username"], :name => "index_users_on_username", :unique => true end From 810f821ba29cf132ea40f4ec562d466db8e7d3aa Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Sat, 14 Sep 2013 22:29:23 -0700 Subject: [PATCH 18/32] Add bootstrap_pagedown and remove keywords from pages --- .travis.yml | 2 +- Gemfile | 5 +- Gemfile.lock | 28 +++- app/assets/javascripts/application.js | 1 + app/assets/javascripts/global.js | 80 +--------- app/assets/stylesheets/dashboard.scss | 2 + app/controllers/dashboard/pages_controller.rb | 18 +-- app/exceptions/clover.rb | 2 + app/helpers/markdown_helper.rb | 6 + app/models/page.rb | 12 +- app/views/dashboard/pages/_form.html.haml | 17 +++ app/views/dashboard/pages/_page.html.haml | 4 +- .../dashboard/pages/_page_editor.html.haml | 35 ----- app/views/dashboard/pages/edit.haml | 19 +-- app/views/dashboard/pages/index.haml | 7 +- app/views/dashboard/pages/new.haml | 10 +- .../layouts/dashboard/_navigation.html.haml | 8 +- app/views/pages/show.haml | 5 +- app/views/shared/_keywords.html.haml | 15 -- config/application.rb | 18 ++- config/initializers/simple_form.rb | 138 ++++++++++++++++++ config/locales/simple_form.en.yml | 26 ++++ ...012145155_acts_as_taggable_on_migration.rb | 29 ---- db/schema.rb | 18 --- lib/extensions/pygments_renderer.rb | 9 ++ lib/templates/haml/scaffold/_form.html.haml | 10 ++ 26 files changed, 285 insertions(+), 239 deletions(-) create mode 100644 app/helpers/markdown_helper.rb create mode 100644 app/views/dashboard/pages/_form.html.haml delete mode 100644 app/views/dashboard/pages/_page_editor.html.haml delete mode 100644 app/views/shared/_keywords.html.haml create mode 100644 config/initializers/simple_form.rb create mode 100644 config/locales/simple_form.en.yml delete mode 100644 db/migrate/20101012145155_acts_as_taggable_on_migration.rb create mode 100644 lib/extensions/pygments_renderer.rb create mode 100644 lib/templates/haml/scaffold/_form.html.haml diff --git a/.travis.yml b/.travis.yml index b03b0a0..f1ee931 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ before_script: - sudo -u postgres createuser cms -dSR - - RAILS_ENV=development bundle exec rake config:generate db:create db:migrate + - RAILS_ENV=development bundle exec rake config:generate db:create:all db:migrate - 'sh -e /etc/init.d/xvfb start' script: - 'DISPLAY=:99.0 bundle exec rake spec' diff --git a/Gemfile b/Gemfile index 588913b..1226f18 100644 --- a/Gemfile +++ b/Gemfile @@ -9,7 +9,6 @@ gem 'devise' gem 'devise_invitable' gem 'carrierwave' gem 'rmagick' -gem 'acts-as-taggable-on' gem 'tabs_on_rails' gem 'jquery-rails' gem 'simple_form' @@ -17,6 +16,9 @@ gem 'capistrano' gem 'mime-types', :require => 'mime/types' gem 'symbolize' gem 'friendly_id', '~> 4.0.1' +gem 'redcarpet', '2.2.2' +gem 'pygments.rb', '0.4.2' +gem 'mail_form' group :development do gem 'better_errors' @@ -35,6 +37,7 @@ group :assets do gem 'therubyracer', platforms: :ruby gem 'compass-rails' gem 'bootstrap-sass' + gem 'bootstrap_pagedown' gem 'fancybox-rails' end diff --git a/Gemfile.lock b/Gemfile.lock index bd48f03..bee52fa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -28,8 +28,6 @@ GEM activesupport (3.2.14) i18n (~> 0.6, >= 0.6.4) multi_json (~> 1.0) - acts-as-taggable-on (2.3.3) - rails (~> 3.0) addressable (2.3.2) arel (3.0.2) awesome_print (1.1.0) @@ -39,9 +37,12 @@ GEM erubis (>= 2.7.0) binding_of_caller (0.7.1) debug_inspector (>= 0.0.1) - bootstrap-sass (2.1.0.0) + bootstrap-sass (2.3.2.2) + sass (~> 3.2) bootstrap-will_paginate (0.0.9) will_paginate + bootstrap_pagedown (1.0.1) + rails (>= 3.2) builder (3.0.4) bullet (4.1.5) uniform_notifier (~> 1.0.0) @@ -124,7 +125,7 @@ GEM railties (>= 3.1, < 4.1) highline (1.6.11) hike (1.2.3) - i18n (0.6.4) + i18n (0.6.5) journey (1.0.4) jquery-rails (2.0.2) railties (>= 3.2.0, < 5.0) @@ -138,9 +139,11 @@ GEM mail (2.5.4) mime-types (~> 1.16) treetop (~> 1.4.8) + mail_form (1.4.1) + actionmailer (~> 3.0) method_source (0.8) - mime-types (1.23) - multi_json (1.7.7) + mime-types (1.25) + multi_json (1.8.0) net-scp (1.0.4) net-ssh (>= 1.99.1) net-sftp (2.0.5) @@ -152,12 +155,16 @@ GEM orm_adapter (0.4.0) pg (0.14.1) polyglot (0.3.3) + posix-spawn (0.3.6) pry (0.9.10) coderay (~> 1.0.5) method_source (~> 0.8) slop (~> 3.3.1) pry-rails (0.1.6) pry + pygments.rb (0.4.2) + posix-spawn (~> 0.3.6) + yajl-ruby (~> 1.1.0) quiet_assets (1.0.1) railties (~> 3.1) rack (1.4.5) @@ -193,6 +200,7 @@ GEM rake (10.1.0) rdoc (3.12.2) json (~> 1.4) + redcarpet (2.2.2) ref (1.0.4) rmagick (2.13.2) rspec-core (2.14.4) @@ -240,7 +248,7 @@ GEM ref thor (0.18.1) tilt (1.4.1) - treetop (1.4.14) + treetop (1.4.15) polyglot polyglot (>= 0.3.1) tzinfo (0.3.37) @@ -253,16 +261,17 @@ GEM will_paginate (3.0.4) xpath (0.1.4) nokogiri (~> 1.3) + yajl-ruby (1.1.0) PLATFORMS ruby DEPENDENCIES - acts-as-taggable-on better_errors binding_of_caller bootstrap-sass bootstrap-will_paginate + bootstrap_pagedown bullet capistrano capybara-webkit @@ -279,12 +288,15 @@ DEPENDENCIES haml-rails jquery-rails launchy + mail_form mime-types pg pry-rails + pygments.rb (= 0.4.2) quiet_assets rails (= 3.2.14) rails_best_practices + redcarpet (= 2.2.2) rmagick rspec-rails sass-rails (~> 3.2.3) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index f54aadb..7ab2ce6 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -7,4 +7,5 @@ //= require jquery.easing //= require loopedslider //= require bootstrap +//= require bootstrap_pagedown //= require_tree . diff --git a/app/assets/javascripts/global.js b/app/assets/javascripts/global.js index c6da081..1510722 100644 --- a/app/assets/javascripts/global.js +++ b/app/assets/javascripts/global.js @@ -35,57 +35,6 @@ $("#documents a").each(function(){ }); } -// Keywords box functions - -function existing_keywords() -{ - $('#keywords option').each(function(){ - $(this).dblclick(function(){ - delete_confirmation_dialog({ - element: this, - title: 'Delete tag from tag list', - text: 'Are you sure you want to delete ' + this.value + ' from your tag list?', - onsuccess: 'keyword_list' - }); - }); - }); -} - -function add_keywords() -{ - $('#keyword_button').click(function(){ - $('#keyword_input').html(function() { - if (this.value != '') { - $.each(this.value.split(/\s?,\s?/), function(index, value) { - $('#keywords').append(''); - $("#keywords").children(":last").dblclick (function() { - delete_confirmation_dialog({ - element: this, - title: 'Delete tag from tag list', - text: 'Are you sure you want to delete ' + value + ' from your tag list?', - onsuccess: 'keyword_list' - }); - }); - }); - keyword_list(); - this.value = ''; - } - }); - }); -} - -function keyword_list() -{ - var keywords = ""; - $("#keywords option").each(function(){ - if ( keywords == "") - keywords = this.value; - else - keywords = keywords + ", " + this.value; - }); - $("#final_keywords_list").val(keywords); -} - // Dialog box functions function delete_confirmation_dialog( params ) { @@ -147,32 +96,7 @@ function image_operations( params ) { }); } -// nested models $(function() { - $('form a.add_child').click(function() { - var association = $(this).attr('data-association'); - var template = $('#' + association + '_fields_template').html(); - var regexp = new RegExp('new_' + association, 'g'); - var new_id = new Date().getTime(); - - $(this).parent().before(template.replace(regexp, new_id)); - return false; - }); - - $('form a.remove_child').live('click', function() { - var hidden_field = $(this).prev('input[type=hidden]')[0]; - if(hidden_field) { - hidden_field.value = '1'; - } - $(this).parents('.fields').hide(); - return false; - }); + $('#tabs').tabs(); + add_images(); }); - -// button methods -function submit_button() -{ - $('.submit').button( { icons: { primary: 'ui-icon-circle-check' } } ).click(function() { - $('.form').submit(); - }); -} diff --git a/app/assets/stylesheets/dashboard.scss b/app/assets/stylesheets/dashboard.scss index 15eefd2..e65b04f 100644 --- a/app/assets/stylesheets/dashboard.scss +++ b/app/assets/stylesheets/dashboard.scss @@ -1,5 +1,7 @@ @import "compass/reset"; @import "compass/css3/border-radius"; +@import "bootstrap"; +@import "bootstrap_pagedown"; html { height: 100%; diff --git a/app/controllers/dashboard/pages_controller.rb b/app/controllers/dashboard/pages_controller.rb index d94e6cc..de1441b 100644 --- a/app/controllers/dashboard/pages_controller.rb +++ b/app/controllers/dashboard/pages_controller.rb @@ -1,23 +1,19 @@ class Dashboard::PagesController < ApplicationController before_filter :set_page, only: [ :edit, :update, :destroy ] - set_tab :list_pages, only: :index - set_tab :new_page, only: :new + set_tab :list_pages, only: :index + set_tab :new_page, only: :new - # GET /pages def index @pages = Page.includes( :section ).page params[:page] end - # GET /pages/new def new @page = Page.new end - # POST /pages def create - @page = Page.new params[:page].except('keywords') - @page.keyword_list = params[:page][:keywords] if params[:page][:keywords].present? + @page = Page.new params[:page] if @page.save flash[:success] = t 'messages.created_successfully' @@ -27,19 +23,15 @@ def create end end - # PUT /pages/1 def update - @page.keyword_list = params[:page][:keywords] if params[:page][:keywords].present? - - if @page.update_attributes params[:page].except('keywords') + if @page.update_attributes params[:page] flash[:success] = t 'messages.updated_successfully' - redirect_to dashboard_pages_path + redirect_to edit_dashboard_page_path( @page ) else render :edit end end - # DELETE /pages/1 def destroy @page.destroy redirect_to dashboard_pages_path diff --git a/app/exceptions/clover.rb b/app/exceptions/clover.rb index c9fb8d2..b45e9ee 100644 --- a/app/exceptions/clover.rb +++ b/app/exceptions/clover.rb @@ -1,3 +1,5 @@ +require 'active_record/errors' + module Clover class UnauthorizedAccessError < SecurityError; end class PageNotFoundError < ActiveRecord::RecordNotFound; end diff --git a/app/helpers/markdown_helper.rb b/app/helpers/markdown_helper.rb new file mode 100644 index 0000000..c37fb93 --- /dev/null +++ b/app/helpers/markdown_helper.rb @@ -0,0 +1,6 @@ +module MarkdownHelper + def markdown text + renderer = PygmentsRenderer.new $render_options + Redcarpet::Markdown.new( renderer, $markdown_extensions ).render( text ).html_safe + end +end diff --git a/app/models/page.rb b/app/models/page.rb index 43e2dae..5c8470e 100644 --- a/app/models/page.rb +++ b/app/models/page.rb @@ -1,8 +1,6 @@ class Page < ActiveRecord::Base extend FriendlyId - acts_as_taggable_on :keywords - has_many :assets, as: :attachable belongs_to :section @@ -15,7 +13,7 @@ class Page < ActiveRecord::Base attr_accessible :name, :content, :section, :home_page, :published, :section_id, :has_contact - scope :published, where(published: true) + scope :published, -> { where published: true } def self.home_page where( home_page: true ).first @@ -23,10 +21,10 @@ def self.home_page private def check_home_page - if home_page? - Page.where("home_page = ?", true).each do |page| - page.update_attributes( home_page: false ) if page != self - end + return unless home_page? + + Page.where( home_page: true ).find_each do |page| + page.update_attributes( home_page: false ) if page != self end end end diff --git a/app/views/dashboard/pages/_form.html.haml b/app/views/dashboard/pages/_form.html.haml new file mode 100644 index 0000000..7867d8e --- /dev/null +++ b/app/views/dashboard/pages/_form.html.haml @@ -0,0 +1,17 @@ += simple_form_for [ :dashboard, page ] do |f| + #page_content + = f.input :name, placeholder: t('common.descriptions.url.item_name', item: Page.model_name.downcase ) + = f.pagedown_editor :content + + = f.label :section do + = t 'activerecord.attributes.page.section' + %small= t 'dashboard.page.descriptions.section' + + = f.select :section_id, all_sections_collection + + .buttonset + = f.input :home_page, input_html: { class: :home_page } + = f.input :has_contact, input_html: { class: :contact_form } + = f.input :published, input_html: { class: :published } + + = f.submit t( 'common.forms.submit' ) diff --git a/app/views/dashboard/pages/_page.html.haml b/app/views/dashboard/pages/_page.html.haml index 2f18ccd..e0cd65c 100644 --- a/app/views/dashboard/pages/_page.html.haml +++ b/app/views/dashboard/pages/_page.html.haml @@ -4,5 +4,5 @@ %td= l page.created_at, format: :short %td= l page.updated_at, format: :short %td - = link_to t('links.edit'), edit_dashboard_page_path( page.id ), class: 'icon edit' - = link_to t('links.destroy'), dashboard_page_path( page.id ), confirm: t('common.messages.are_you_sure'), method: :delete, class: 'icon delete' + = link_to t('links.edit'), edit_dashboard_page_path( page ), class: 'icon edit' + = link_to t('links.destroy'), dashboard_page_path( page ), class: 'icon delete', confirm: t('common.messages.are_you_sure'), data: { method: :delete } diff --git a/app/views/dashboard/pages/_page_editor.html.haml b/app/views/dashboard/pages/_page_editor.html.haml deleted file mode 100644 index 18b8966..0000000 --- a/app/views/dashboard/pages/_page_editor.html.haml +++ /dev/null @@ -1,35 +0,0 @@ -= form_for [:dashboard, page_editor ], validate: true do |f| - #page_content - = f.hidden_field :keywords, id: :final_keywords_list - %label{ for: :page_name } - = t 'common.fields.name' - %small= t 'common.descriptions.url.item_name', item: t('activerecord.models.page').downcase - = f.text_field :name - = f.text_area :content, id: 'wmd-input', class: 'wmd-input' - - %label{ for: :page_section_id } - = t 'activerecord.attributes.page.section' - %small= t 'dashboard.page.descriptions.section' - = f.select :section_id, all_sections_collection - - .buttonset - = f.label :home_page - = f.check_box :home_page, class: :home_page - = f.label :has_contact - = f.check_box :has_contact, class: :contact_form - = f.label :published - = f.check_box :published, class: :published - - %button.wymupdate= t 'common.forms.submit' - -:javascript - $(document).ready(function() { - $('#tabs').tabs(); - $('.buttonset').buttonset(); - $('.home_page').button({ icons: { primary: "ui-icon-home" } }); - $('.contact_form').button({ icons: { primary: "ui-icon-mail-closed" } }); - $('.published').button({ icons: { primary: "ui-icon-check" } }); - $('#keyword_button').button({ icons: { primary: "ui-icon-circle-plus" } }); - add_keywords(); - existing_keywords(); - }); diff --git a/app/views/dashboard/pages/edit.haml b/app/views/dashboard/pages/edit.haml index d11b464..4fd1e42 100644 --- a/app/views/dashboard/pages/edit.haml +++ b/app/views/dashboard/pages/edit.haml @@ -1,14 +1,11 @@ #tabs %ul - %li= link_to t('links.item_details', item: t('activerecord.models.page')), '#tabs-1' - %li= link_to t('links.item_keywords', item: t('activerecord.models.page')), '#tabs-2' - %li= link_to t('links.item_assets', item: t('activerecord.models.page')), '#tabs-3' - #tabs-1 - = render partial: 'page_editor', object: @page - #tabs-2 - = render 'shared/keywords', resource_keywords: @page.keywords.map(&:name) - .spacer - #tabs-3 + %li= link_to t('links.item_details', item: Page.model_name ), '#page-editor' + %li= link_to t('links.item_assets', item: Page.model_name ), '#assets' + + #page-editor= render 'form', page: @page + + #assets .splitcontentleft #images_list - @page.assets.each do |asset| @@ -17,7 +14,3 @@ .splitcontentright = render 'shared/uploadify', object: @page .spacer -:javascript - $(function() { - add_images(); - }) diff --git a/app/views/dashboard/pages/index.haml b/app/views/dashboard/pages/index.haml index a7573a5..d89a54d 100644 --- a/app/views/dashboard/pages/index.haml +++ b/app/views/dashboard/pages/index.haml @@ -1,13 +1,14 @@ -%h2= t 'common.headers.item_list', item: t('activerecord.models.page').pluralize +%h2= t 'common.headers.item_list', item: Page.model_name.pluralize + %p.info %span.bold= t('messages.information') + ':' = t 'dashboard.page.instructions.index' -%table.tabular{ cellpadding: 0, cellspacing: 0} +%table.tabular{ cellpadding: 0, cellspacing: 0 } %thead %tr %th= t 'common.fields.name' - %th= t 'activerecord.models.section' + %th= Section.model_name %th= t 'common.fields.created_at' %th= t 'common.fields.updated_at' %th= t 'common.messages.options' diff --git a/app/views/dashboard/pages/new.haml b/app/views/dashboard/pages/new.haml index 978260e..dd33032 100644 --- a/app/views/dashboard/pages/new.haml +++ b/app/views/dashboard/pages/new.haml @@ -1,9 +1,5 @@ #tabs %ul - %li= link_to t('links.item_details', item: t('activerecord.models.page')), '#tabs-1' - %li= link_to t('links.item_keywords', item: t('activerecord.models.page')), '#tabs-2' - #tabs-1 - = render partial: 'page_editor', object: @page - #tabs-2 - = render partial: 'shared/keywords', locals: { resource_keywords: @page.keywords.map(&:name) } - .clear + %li= link_to t('links.item_details', item: Page.model_name ), '#page-editor' + + #page-editor= render 'form', page: @page diff --git a/app/views/layouts/dashboard/_navigation.html.haml b/app/views/layouts/dashboard/_navigation.html.haml index 84376ff..955a4db 100644 --- a/app/views/layouts/dashboard/_navigation.html.haml +++ b/app/views/layouts/dashboard/_navigation.html.haml @@ -4,9 +4,9 @@ - content_for :nav_wrap do %ul#nav - %li#sections_menu_link= link_to t('activerecord.models.section'), dashboard_sections_path - %li#pages_menu_link= link_to t('activerecord.models.page'), dashboard_pages_path - %li#settings_menu_link= link_to t('activerecord.models.setting'), dashboard_settings_path - %li#users_menu_link= link_to t('activerecord.models.user'), dashboard_users_path + %li#sections_menu_link= link_to Section.model_name.pluralize, dashboard_sections_path + %li#pages_menu_link= link_to Page.model_name.pluralize, dashboard_pages_path + %li#settings_menu_link= link_to Setting.model_name.pluralize, dashboard_settings_path + %li#users_menu_link= link_to User.model_name.pluralize, dashboard_users_path = yield :nav = content_for?( :sub_nav ) ? yield( :sub_nav ) : render( "layouts/dashboard/nav/#{controller_name}" ) diff --git a/app/views/pages/show.haml b/app/views/pages/show.haml index ee8904f..4f658e4 100644 --- a/app/views/pages/show.haml +++ b/app/views/pages/show.haml @@ -1,11 +1,10 @@ %h1= @page.name.titleize -!= @page.content += markdown @page.content != @contact_form if @contact_form.present? = content_for :title do = "#{site[:site_name]} - #{@page.name.titleize}" + = content_for :footer do != "#{site[:footer]}" -= content_for :meta do - != meta "keywords", @page.keywords.join(',') if @page.keywords.present? diff --git a/app/views/shared/_keywords.html.haml b/app/views/shared/_keywords.html.haml deleted file mode 100644 index 6727f2e..0000000 --- a/app/views/shared/_keywords.html.haml +++ /dev/null @@ -1,15 +0,0 @@ -.columns - .half - %label - = t 'common.fields.keywords' - %small= t 'common.descriptions.keywords' - %input#keyword_input{ type: :text, style: 'width: 250px; display: inline' } - %button#keyword_button= t 'common.forms.add' - %select{ size: 5, style: 'width: 350px; border: 1px solid gray;', id: 'keywords' } - - resource_keywords.each do |keyword| - %option=keyword - .half - #tips_container.box - %h3= t 'common.headers.did_you_know' - %p= t 'common.tips.keywords.first' - %p= t 'common.tips.keywords.second' diff --git a/config/application.rb b/config/application.rb index 06b62f8..5db18a4 100644 --- a/config/application.rb +++ b/config/application.rb @@ -23,7 +23,7 @@ class Application < Rails::Application # -- all .rb files in that directory are automatically loaded. # Custom directories with classes and modules you want to be autoloadable. - config.autoload_paths += %W(#{config.root}/app/middleware #{config.root}/extras) + config.autoload_paths += %W(#{config.root}/app/middleware #{config.root}/extras #{config.root}/lib/extensions) # Only load the plugins named here, in the order given (default is alphabetical). # :all can be used as a placeholder for all plugins not explicitly named. @@ -50,10 +50,24 @@ class Application < Rails::Application config.assets.enabled = true config.assets.precompile += %w( clover.css tjruby.css dashboard.css simple_blog.css sessions.css jquery-ui.css ) - config.assets.precompile += %w( wymeditor/jquery.wymeditor.min.js uploadify/uploadify.min.js uploadify/swfobject.js ) + config.assets.precompile += %w( uploadify/uploadify.min.js uploadify/swfobject.js ) # Version of your assets, change this if you want to expire all your assets config.assets.version = '1.0' + + $markdown_extensions = { + autolink: true, + no_intra_emphasis: true, + fenced_code_blocks: true, + space_after_headers: true, + superscript: true, + } + + $render_options = { + filter_html: true, + hard_wrap: true, + with_toc_data: true, + } end end diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb new file mode 100644 index 0000000..59c7d25 --- /dev/null +++ b/config/initializers/simple_form.rb @@ -0,0 +1,138 @@ +# Use this setup block to configure all options available in SimpleForm. +SimpleForm.setup do |config| + # Wrappers are used by the form builder to generate a + # complete input. You can remove any component from the + # wrapper, change the order or even add your own to the + # stack. The options given below are used to wrap the + # whole input. + config.wrappers :default, :class => :input, + :hint_class => :field_with_hint, :error_class => :field_with_errors do |b| + ## Extensions enabled by default + # Any of these extensions can be disabled for a + # given input by passing: `f.input EXTENSION_NAME => false`. + # You can make any of these extensions optional by + # renaming `b.use` to `b.optional`. + + # Determines whether to use HTML5 (:email, :url, ...) + # and required attributes + b.use :html5 + + # Calculates placeholders automatically from I18n + # You can also pass a string as f.input :placeholder => "Placeholder" + b.use :placeholder + + ## Optional extensions + # They are disabled unless you pass `f.input EXTENSION_NAME => :lookup` + # to the input. If so, they will retrieve the values from the model + # if any exists. If you want to enable the lookup for any of those + # extensions by default, you can change `b.optional` to `b.use`. + + # Calculates maxlength from length validations for string inputs + b.optional :maxlength + + # Calculates pattern from format validations for string inputs + b.optional :pattern + + # Calculates min and max from length validations for numeric inputs + b.optional :min_max + + # Calculates readonly automatically from readonly attributes + b.optional :readonly + + ## Inputs + b.use :label_input + b.use :hint, :wrap_with => { :tag => :span, :class => :hint } + b.use :error, :wrap_with => { :tag => :span, :class => :error } + end + + # The default wrapper to be used by the FormBuilder. + config.default_wrapper = :default + + # Define the way to render check boxes / radio buttons with labels. + # Defaults to :nested for bootstrap config. + # :inline => input + label + # :nested => label > input + config.boolean_style = :nested + + # Default class for buttons + config.button_class = 'btn' + + # Method used to tidy up errors. Specify any Rails Array method. + # :first lists the first message for each field. + # Use :to_sentence to list all errors for each field. + # config.error_method = :first + + # Default tag used for error notification helper. + config.error_notification_tag = :div + + # CSS class to add for error notification helper. + config.error_notification_class = 'alert alert-error' + + # ID to add for error notification helper. + # config.error_notification_id = nil + + # Series of attempts to detect a default label method for collection. + # config.collection_label_methods = [ :to_label, :name, :title, :to_s ] + + # Series of attempts to detect a default value method for collection. + # config.collection_value_methods = [ :id, :to_s ] + + # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none. + # config.collection_wrapper_tag = nil + + # You can define the class to use on all collection wrappers. Defaulting to none. + # config.collection_wrapper_class = nil + + # You can wrap each item in a collection of radio/check boxes with a tag, + # defaulting to :span. Please note that when using :boolean_style = :nested, + # SimpleForm will force this option to be a label. + # config.item_wrapper_tag = :span + + # You can define a class to use in all item wrappers. Defaulting to none. + # config.item_wrapper_class = nil + + # How the label text should be generated altogether with the required text. + # config.label_text = lambda { |label, required| "#{required} #{label}" } + + # You can define the class to use on all labels. Default is nil. + config.label_class = 'control-label' + + # You can define the class to use on all forms. Default is simple_form. + # config.form_class = :simple_form + + # You can define which elements should obtain additional classes + # config.generate_additional_classes_for = [:wrapper, :label, :input] + + # Whether attributes are required by default (or not). Default is true. + # config.required_by_default = true + + # Tell browsers whether to use default HTML5 validations (novalidate option). + # Default is enabled. + config.browser_validations = false + + # Collection of methods to detect if a file type was given. + # config.file_methods = [ :mounted_as, :file?, :public_filename ] + + # Custom mappings for input types. This should be a hash containing a regexp + # to match as key, and the input type that will be used when the field name + # matches the regexp as value. + # config.input_mappings = { /count/ => :integer } + + # Default priority for time_zone inputs. + # config.time_zone_priority = nil + + # Default priority for country inputs. + # config.country_priority = nil + + # Default size for text inputs. + # config.default_input_size = 50 + + # When false, do not use translations for labels. + # config.translate_labels = true + + # Automatically discover new inputs in Rails' autoload path. + # config.inputs_discovery = true + + # Cache SimpleForm inputs discovery + # config.cache_discovery = !Rails.env.development? +end diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml new file mode 100644 index 0000000..0df11fe --- /dev/null +++ b/config/locales/simple_form.en.yml @@ -0,0 +1,26 @@ +en: + simple_form: + "yes": 'Yes' + "no": 'No' + required: + text: 'required' + mark: '*' + # You can uncomment the line below if you need to overwrite the whole required html. + # When using html, text and mark won't be used. + # html: '*' + error_notification: + default_message: "Please review the problems below:" + # Labels and hints examples + # labels: + # defaults: + # password: 'Password' + # user: + # new: + # email: 'E-mail to sign in.' + # edit: + # email: 'E-mail.' + # hints: + # defaults: + # username: 'User name to sign in.' + # password: 'No special characters, please.' + diff --git a/db/migrate/20101012145155_acts_as_taggable_on_migration.rb b/db/migrate/20101012145155_acts_as_taggable_on_migration.rb deleted file mode 100644 index 7d78c98..0000000 --- a/db/migrate/20101012145155_acts_as_taggable_on_migration.rb +++ /dev/null @@ -1,29 +0,0 @@ -class ActsAsTaggableOnMigration < ActiveRecord::Migration - def self.up - create_table :tags do |t| - t.string :name - end - - create_table :taggings do |t| - t.references :tag - - # You should make sure that the column created is - # long enough to store the required class names. - t.references :taggable, polymorphic: true - t.references :tagger, polymorphic: true - - t.string :context - - t.datetime :created_at - end - - add_index :taggings, :tag_id - add_index :taggings, [:taggable_id, :taggable_type, :context] - add_index :taggings, [:tagger_id, :tagger_type] - end - - def self.down - drop_table :taggings - drop_table :tags - end -end diff --git a/db/schema.rb b/db/schema.rb index db70c88..ed7f8df 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -60,24 +60,6 @@ t.datetime "updated_at", :null => false end - create_table "taggings", :force => true do |t| - t.integer "tag_id" - t.integer "taggable_id" - t.string "taggable_type" - t.integer "tagger_id" - t.string "tagger_type" - t.string "context" - t.datetime "created_at" - end - - add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" - add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context" - add_index "taggings", ["tagger_id", "tagger_type"], :name => "index_taggings_on_tagger_id_and_tagger_type" - - create_table "tags", :force => true do |t| - t.string "name" - end - create_table "users", :force => true do |t| t.string "email", :default => "", :null => false t.string "username", :default => "", :null => false diff --git a/lib/extensions/pygments_renderer.rb b/lib/extensions/pygments_renderer.rb new file mode 100644 index 0000000..683432b --- /dev/null +++ b/lib/extensions/pygments_renderer.rb @@ -0,0 +1,9 @@ +class PygmentsRenderer < Redcarpet::Render::HTML + def block_code( code, language ) + sha = Digest::SHA1.hexdigest( code ) + + Rails.cache.fetch [ 'code', language, sha ].join( '-' ) do + Pygments.highlight( code, lexer: language, options: { encoding: 'utf-8' } ) + end + end +end diff --git a/lib/templates/haml/scaffold/_form.html.haml b/lib/templates/haml/scaffold/_form.html.haml new file mode 100644 index 0000000..ac3aa7b --- /dev/null +++ b/lib/templates/haml/scaffold/_form.html.haml @@ -0,0 +1,10 @@ += simple_form_for(@<%= singular_table_name %>) do |f| + = f.error_notification + + .form-inputs + <%- attributes.each do |attribute| -%> + = f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> + <%- end -%> + + .form-actions + = f.button :submit From 0d885e3fdfdbbe12a4b92b27321bfd8ba51d6140 Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Sat, 14 Sep 2013 23:35:47 -0700 Subject: [PATCH 19/32] Add pip and pygments to travis config --- .travis.yml | 5 ++++- spec/controllers/dashboard/pages_controller_spec.rb | 4 ++-- spec/models/page_spec.rb | 5 ----- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index f1ee931..99ff3a6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,10 @@ before_script: + - sudo apt-get install python-pip + - sudo pip install pygments - sudo -u postgres createuser cms -dSR - - RAILS_ENV=development bundle exec rake config:generate db:create:all db:migrate + - RAILS_ENV=development bundle exec rake config:generate - 'sh -e /etc/init.d/xvfb start' + - bundle exec rake db:migrate db:test:prepare script: - 'DISPLAY=:99.0 bundle exec rake spec' rvm: diff --git a/spec/controllers/dashboard/pages_controller_spec.rb b/spec/controllers/dashboard/pages_controller_spec.rb index 5efafd6..84d8d92 100644 --- a/spec/controllers/dashboard/pages_controller_spec.rb +++ b/spec/controllers/dashboard/pages_controller_spec.rb @@ -75,7 +75,7 @@ it "should create page" do assigns( :page ).should be_kind_of( Page ) - Page.count.should == 2 + Page.count.should eql( 2 ) end it "should render new if anything goes wrong" do @@ -90,7 +90,7 @@ end it "should redirect to index" do - response.should redirect_to( dashboard_pages_path ) + response.should redirect_to( edit_dashboard_page_path( page.reload ) ) end it "should update @page" do diff --git a/spec/models/page_spec.rb b/spec/models/page_spec.rb index 3fd7545..9a0964d 100644 --- a/spec/models/page_spec.rb +++ b/spec/models/page_spec.rb @@ -26,9 +26,4 @@ page = build :page, name: 'test_name', content: 'Test content', section: nil page.should be_invalid end - - it "should accept keywords" do - page.keyword_list = 'this, are, some, keywords' - page.should be_valid - end end From 52a8a8f3f23db3818277b06f55728c095072f19d Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Sat, 14 Sep 2013 23:43:25 -0700 Subject: [PATCH 20/32] Instruct travis to create all databases before running the test suite --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 99ff3a6..2aaba94 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ before_script: - sudo apt-get install python-pip - sudo pip install pygments - sudo -u postgres createuser cms -dSR - - RAILS_ENV=development bundle exec rake config:generate + - RAILS_ENV=development bundle exec rake db:create:all config:generate - 'sh -e /etc/init.d/xvfb start' - bundle exec rake db:migrate db:test:prepare script: From 6b7626a3a97f2e0a8da6f906607b1023e4673de1 Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Sat, 14 Sep 2013 23:56:19 -0700 Subject: [PATCH 21/32] Update build image as per travis Markdown --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4f3a25a..31a1060 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Clover CMS [![Build Status](http://travis-ci.org/cloverinteractive/cms.png)](http://travis-ci.org/cloverinteractive/cms) +# Clover CMS [![Build Status](https://travis-ci.org/cloverinteractive/cms.png?branch=master)](https://travis-ci.org/cloverinteractive/cms) __A dead simple content management system for Rails 3.2.14__ From 56d69426fb834d4ec9fcb49f03832c3e660adf6d Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Sun, 15 Sep 2013 07:40:27 -0700 Subject: [PATCH 22/32] Fix the rails_best_practices notices that made sense --- Gemfile | 1 + Gemfile.lock | 16 +++++++--- app/helpers/application_helper.rb | 31 ------------------- app/models/page.rb | 4 ++- app/models/section.rb | 2 ++ app/models/setting.rb | 15 +++------ app/views/dashboard/pages/_page.html.haml | 2 +- ...page_section.html.haml => _form.html.haml} | 4 +-- .../dashboard/sections/_section.html.haml | 6 ++-- app/views/dashboard/sections/edit.haml | 4 +-- app/views/dashboard/sections/new.haml | 4 +-- ...tting_editor.html.haml => _form.html.haml} | 2 +- app/views/dashboard/settings/edit.html.haml | 4 +-- app/views/dashboard/settings/index.html.haml | 5 +-- app/views/dashboard/settings/new.html.haml | 4 +-- app/views/dashboard/users/_user.html.haml | 6 ++-- app/views/dashboard/users/index.html.haml | 5 +-- .../layouts/themes/default/theme.html.haml | 2 +- .../themes/simple_blog/_sidebar.html.haml | 4 +-- .../themes/simple_blog/theme.html.haml | 4 +-- 20 files changed, 50 insertions(+), 75 deletions(-) rename app/views/dashboard/sections/{_page_section.html.haml => _form.html.haml} (80%) rename app/views/dashboard/settings/{_setting_editor.html.haml => _form.html.haml} (89%) diff --git a/Gemfile b/Gemfile index 1226f18..cd10f42 100644 --- a/Gemfile +++ b/Gemfile @@ -39,6 +39,7 @@ group :assets do gem 'bootstrap-sass' gem 'bootstrap_pagedown' gem 'fancybox-rails' + gem 'turbo-sprockets-rails3' end group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index bee52fa..c768fa4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -68,7 +68,7 @@ GEM childprocess (0.3.5) ffi (~> 1.0, >= 1.0.6) chunky_png (1.2.5) - code_analyzer (0.3.1) + code_analyzer (0.4.2) sexp_processor coderay (1.0.7) coffee-rails (3.2.2) @@ -182,13 +182,14 @@ GEM activesupport (= 3.2.14) bundler (~> 1.0) railties (= 3.2.14) - rails_best_practices (1.13.4) + rails_best_practices (1.14.3) activesupport awesome_print - code_analyzer + code_analyzer (>= 0.4.2) colored erubis i18n + require_all ruby-progressbar railties (3.2.14) actionpack (= 3.2.14) @@ -202,6 +203,7 @@ GEM json (~> 1.4) redcarpet (2.2.2) ref (1.0.4) + require_all (1.3.0) rmagick (2.13.2) rspec-core (2.14.4) rspec-expectations (2.14.0) @@ -214,7 +216,7 @@ GEM rspec-core (~> 2.14.0) rspec-expectations (~> 2.14.0) rspec-mocks (~> 2.14.0) - ruby-progressbar (1.0.2) + ruby-progressbar (1.2.0) rubyzip (0.9.9) sass (3.2.10) sass-rails (3.2.6) @@ -226,7 +228,7 @@ GEM libwebsocket (~> 0.1.3) multi_json (~> 1.0) rubyzip - sexp_processor (4.1.4) + sexp_processor (4.3.0) simple_form (2.0.2) actionpack (~> 3.0) activemodel (~> 3.0) @@ -251,6 +253,9 @@ GEM treetop (1.4.15) polyglot polyglot (>= 0.3.1) + turbo-sprockets-rails3 (0.3.10) + railties (> 3.2.8, < 4.0.0) + sprockets (>= 2.0.0) tzinfo (0.3.37) uglifier (2.1.2) execjs (>= 0.3.0) @@ -306,4 +311,5 @@ DEPENDENCIES symbolize tabs_on_rails therubyracer + turbo-sprockets-rails3 uglifier (>= 1.0.3) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index d67b55f..828932a 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -6,35 +6,4 @@ def main_sections_collection section_name def all_sections_collection Section.all.map { |section| [ section.name, section.id ] } end - - def article_kinds - types = 'dashboard.articles.types' - [ %W(#{t("#{types}.post")} post), %W(#{t("#{types}.review")} review), %W(#{t("#{types}.news")} news) ] - end - - def meta(name, content) - %() - end - - def new_child_fields_template(form_builder, association, options={}) - options[:object] ||= form_builder.object.class.reflect_on_association(association).klass.new - options[:partial] ||= association.to_s.singularize - options[:form_builder_local] ||= :f - - content_for :resource_templates do - content_tag(:div, id: "#{options[:partial]}_fields_template", style: "display: none") do - form_builder.fields_for(association, options[:object], child_index: "new_#{association}") do |f| - render partial: options[:partial], locals: { options[:form_builder_local] => f } - end - end - end - end - - def add_child_fields_link(name, association) - link_to name, "#", class: 'add_child', :"data-association" => association - end - - def remove_child_fields_link(name, form_builder) - form_builder.hidden_field(:_destroy) + link_to(name, "#", class: "remove_child") - end end diff --git a/app/models/page.rb b/app/models/page.rb index 5c8470e..ae58225 100644 --- a/app/models/page.rb +++ b/app/models/page.rb @@ -15,6 +15,8 @@ class Page < ActiveRecord::Base scope :published, -> { where published: true } + delegate :name, to: :section, prefix: true + def self.home_page where( home_page: true ).first end @@ -24,7 +26,7 @@ def check_home_page return unless home_page? Page.where( home_page: true ).find_each do |page| - page.update_attributes( home_page: false ) if page != self + page.update_attributes!( home_page: false ) unless page === self end end end diff --git a/app/models/section.rb b/app/models/section.rb index d7f4b08..4474715 100644 --- a/app/models/section.rb +++ b/app/models/section.rb @@ -10,4 +10,6 @@ class Section < ActiveRecord::Base friendly_id :name, use: :slugged attr_accessible :name, :main_section_id + + delegate :name, to: :main_section, prefix: true, allow_nil: true end diff --git a/app/models/setting.rb b/app/models/setting.rb index 78de542..e2d022d 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -1,9 +1,8 @@ class Setting < ActiveRecord::Base - validates_presence_of :name, :value - validates_uniqueness_of :name + validates :name, :value, presence: true + validates :name, uniqueness: true validates_format_of :name, with: /^[a-z0-9_]+$/ - attr_accessible :name, :value, :description attr_accessible :name, :value, :description, :destroyable @@ -12,16 +11,10 @@ def delete false end - def delete! - return super if destroyable? - false - end - def self.get_site_settings - site = {} - Setting.select('name, value').each do |setting| + Setting.select('name, value').inject( {} ) do |site, setting| site[setting.name.to_sym] = setting.value + site end - site end end diff --git a/app/views/dashboard/pages/_page.html.haml b/app/views/dashboard/pages/_page.html.haml index e0cd65c..0400377 100644 --- a/app/views/dashboard/pages/_page.html.haml +++ b/app/views/dashboard/pages/_page.html.haml @@ -1,6 +1,6 @@ %tr{ class: cycle(:odd, :even) } %td= link_to page.name, edit_dashboard_page_path( page ) - %td= page.section.name + %td= page.section_name %td= l page.created_at, format: :short %td= l page.updated_at, format: :short %td diff --git a/app/views/dashboard/sections/_page_section.html.haml b/app/views/dashboard/sections/_form.html.haml similarity index 80% rename from app/views/dashboard/sections/_page_section.html.haml rename to app/views/dashboard/sections/_form.html.haml index 3a41fcb..74e4047 100644 --- a/app/views/dashboard/sections/_page_section.html.haml +++ b/app/views/dashboard/sections/_form.html.haml @@ -1,4 +1,4 @@ -= form_for [ :dashboard, page_section ], validate: true do |f| += form_for [ :dashboard, section ] do |f| .columns .half %label{ for: :section_name } @@ -9,7 +9,7 @@ %label{ for: :main_section_id } = t 'activerecord.attributes.section.main_section' %small= t 'dashboard.sections.descriptions.main_section' - = f.select :main_section_id, main_sections_collection(page_section.name), include_blank: true + = f.select :main_section_id, main_sections_collection( section.name ), include_blank: true %button#submit= t 'common.forms.submit' diff --git a/app/views/dashboard/sections/_section.html.haml b/app/views/dashboard/sections/_section.html.haml index 08544fe..f193350 100644 --- a/app/views/dashboard/sections/_section.html.haml +++ b/app/views/dashboard/sections/_section.html.haml @@ -1,9 +1,9 @@ %tr{ class: cycle(:odd, :even) } %td= section.name - %td= section.main_section.name if section.main_section.present? + %td= section.main_section_name %td= l section.created_at, format: :short %td= l section.updated_at, format: :short %td - = link_to t('links.edit'), edit_dashboard_section_path( section.id ), class: 'icon edit' - = link_to t('links.destroy'), dashboard_section_path( section.id ), confirm: t('common.messages.are_you_sure'), method: :delete, class: 'icon delete' + = link_to t('links.edit'), edit_dashboard_section_path( section.id ), class: 'icon edit' + = link_to t('links.destroy'), dashboard_section_path( section.id ), class: 'icon delete', confirm: t('common.messages.are_you_sure'), data: { method: :delete } diff --git a/app/views/dashboard/sections/edit.haml b/app/views/dashboard/sections/edit.haml index 2c4c872..55ebb65 100644 --- a/app/views/dashboard/sections/edit.haml +++ b/app/views/dashboard/sections/edit.haml @@ -1,2 +1,2 @@ -%h2= t 'links.edit_item', item: t('activerecord.models.section') -= render partial: 'page_section', object: @section +%h2= t 'links.edit_item', item: Section.model_name += render 'form', section: @section diff --git a/app/views/dashboard/sections/new.haml b/app/views/dashboard/sections/new.haml index 4c43f06..4ad8808 100644 --- a/app/views/dashboard/sections/new.haml +++ b/app/views/dashboard/sections/new.haml @@ -1,2 +1,2 @@ -%h2= t 'links.new_item', item: t("activerecord.models.section") -= render partial: 'page_section', object: @section +%h2= t 'links.new_item', item: Section.model_name += render 'form', section: @section diff --git a/app/views/dashboard/settings/_setting_editor.html.haml b/app/views/dashboard/settings/_form.html.haml similarity index 89% rename from app/views/dashboard/settings/_setting_editor.html.haml rename to app/views/dashboard/settings/_form.html.haml index 9d260c7..63382fe 100644 --- a/app/views/dashboard/settings/_setting_editor.html.haml +++ b/app/views/dashboard/settings/_form.html.haml @@ -1,4 +1,4 @@ -= form_for [ :dashboard, setting_editor ], validate: true do |f| += form_for [ :dashboard, setting ] do |f| .columns .half = f.label :name diff --git a/app/views/dashboard/settings/edit.html.haml b/app/views/dashboard/settings/edit.html.haml index e093aa6..070bb41 100644 --- a/app/views/dashboard/settings/edit.html.haml +++ b/app/views/dashboard/settings/edit.html.haml @@ -1,2 +1,2 @@ -%h2= t 'links.edit_item', item: t('activerecord.models.setting') -= render partial: 'setting_editor', object: @setting, locals: { themes: @themes } +%h2= t 'links.edit_item', item: Setting.model_name += render 'form', setting: @setting, themes: @themes diff --git a/app/views/dashboard/settings/index.html.haml b/app/views/dashboard/settings/index.html.haml index 9e637a7..b5336a2 100644 --- a/app/views/dashboard/settings/index.html.haml +++ b/app/views/dashboard/settings/index.html.haml @@ -1,4 +1,4 @@ -%h2= t 'common.headers.item_list', item: t('activerecord.models.setting') +%h2= t 'common.headers.item_list', item: Setting.model_name %p.info %span.bold= t('messages.information') + ':' @@ -13,5 +13,6 @@ %th= t 'common.fields.updated_at' %th= t 'common.messages.options' %tbody - = render partial: 'setting', collection: @settings + = render @settings + = will_paginate @settings diff --git a/app/views/dashboard/settings/new.html.haml b/app/views/dashboard/settings/new.html.haml index 08b8374..59fba95 100644 --- a/app/views/dashboard/settings/new.html.haml +++ b/app/views/dashboard/settings/new.html.haml @@ -1,2 +1,2 @@ -%h2= t 'links.new_item', item: t('activerecord.models.setting') -= render partial: 'setting_editor', object: @setting, locals: { themes: @themes } +%h2= t 'links.new_item', item: Setting.model_name += render 'form', setting: @setting, themes: @themes diff --git a/app/views/dashboard/users/_user.html.haml b/app/views/dashboard/users/_user.html.haml index 36fcb6e..3df0bd6 100644 --- a/app/views/dashboard/users/_user.html.haml +++ b/app/views/dashboard/users/_user.html.haml @@ -1,7 +1,7 @@ %tr{ class: cycle(:odd, :even) } %td= user.username %td= user.email - %td= l(user.confirmed_at, format: :short) if user.confirmed_at - %td= l(user.last_sign_in_at, format: :short) if user.last_sign_in_at + %td= l( user.confirmed_at, format: :short ) if user.confirmed_at + %td= l( user.last_sign_in_at, format: :short ) if user.last_sign_in_at %td - = link_to t('links.destroy'), dashboard_user_path(user), method: :delete, confirm: t('common.messages.are_you_sure'), class: 'icon user_delete' + = link_to t('links.destroy'), dashboard_user_path(user), class: 'icon delete', confirm: t('common.messages.are_you_sure'), data: { method: :delete } diff --git a/app/views/dashboard/users/index.html.haml b/app/views/dashboard/users/index.html.haml index b7c563d..395a486 100644 --- a/app/views/dashboard/users/index.html.haml +++ b/app/views/dashboard/users/index.html.haml @@ -1,4 +1,4 @@ -%h2= t 'common.headers.item_list', item: t('activerecord.models.user') +%h2= t 'common.headers.item_list', item: User.model_name %p.info %span.bold= t('messages.information') + ':' = t '.tip' @@ -12,5 +12,6 @@ %th= t 'activerecord.attributes.user.last_sign_in_at' %th= t 'common.messages.options' %tbody - = render partial: 'user', collection: @users + = render @users + = will_paginate @users diff --git a/app/views/layouts/themes/default/theme.html.haml b/app/views/layouts/themes/default/theme.html.haml index 1a0ca5c..0b1e1cc 100644 --- a/app/views/layouts/themes/default/theme.html.haml +++ b/app/views/layouts/themes/default/theme.html.haml @@ -1,4 +1,4 @@ -!!!5 +!!! %html %head %title= (content_for? :title) ? yield(:title) : 'CloverCMS - TJRuby theme' diff --git a/app/views/layouts/themes/simple_blog/_sidebar.html.haml b/app/views/layouts/themes/simple_blog/_sidebar.html.haml index 89a97ec..33da965 100644 --- a/app/views/layouts/themes/simple_blog/_sidebar.html.haml +++ b/app/views/layouts/themes/simple_blog/_sidebar.html.haml @@ -6,9 +6,9 @@ %ul - section.pages.published.each do |page| - if section.main_section - %li= link_to page.name.titleize, subsection_page_path(section.url_name, section.main_section.url_name, page.url_name) + %li= link_to page.name.titleize, subsection_page_path( section section.main_section, page ) - else - %li= link_to page.name.titleize, section_page_path(section.url_name, page.url_name) + %li= link_to page.name.titleize, section_page_path( section, page ) %h2 Follow us on %ul.icons diff --git a/app/views/layouts/themes/simple_blog/theme.html.haml b/app/views/layouts/themes/simple_blog/theme.html.haml index 6059913..787e82b 100644 --- a/app/views/layouts/themes/simple_blog/theme.html.haml +++ b/app/views/layouts/themes/simple_blog/theme.html.haml @@ -1,10 +1,10 @@ -!!!5 +!!! %html %head %meta{ charset: 'utf-8' } - = yield :meta %title= content_for?(:title) ? yield(:title) : 'Simple Blog' = stylesheet_link_tag 'application', 'simple_blog' + %body = render partial: 'layouts/themes/simple_blog/nav' #wrapper From efd6e29ce944fa69af9bd971f2257c42a59e3f6a Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Tue, 17 Sep 2013 16:56:09 -0700 Subject: [PATCH 23/32] Remove jquery-ui --- .../jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png | Bin 180 -> 0 bytes .../jquery-ui/ui-bg_flat_75_ffffff_40x100.png | Bin 178 -> 0 bytes .../jquery-ui/ui-bg_glass_55_fbf9ee_1x400.png | Bin 120 -> 0 bytes .../jquery-ui/ui-bg_glass_65_ffffff_1x400.png | Bin 105 -> 0 bytes .../jquery-ui/ui-bg_glass_75_dadada_1x400.png | Bin 111 -> 0 bytes .../jquery-ui/ui-bg_glass_75_e6e6e6_1x400.png | Bin 110 -> 0 bytes .../jquery-ui/ui-bg_glass_95_fef1ec_1x400.png | Bin 119 -> 0 bytes .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 101 -> 0 bytes .../jquery-ui/ui-icons_222222_256x240.png | Bin 4369 -> 0 bytes .../jquery-ui/ui-icons_2e83ff_256x240.png | Bin 4369 -> 0 bytes .../jquery-ui/ui-icons_454545_256x240.png | Bin 4369 -> 0 bytes .../jquery-ui/ui-icons_888888_256x240.png | Bin 4369 -> 0 bytes .../jquery-ui/ui-icons_cd0a0a_256x240.png | Bin 4369 -> 0 bytes app/assets/javascripts/application.js | 1 - app/assets/javascripts/global.js | 97 --- app/assets/stylesheets/jquery-ui.css | 565 ------------------ app/views/dashboard/sections/_form.html.haml | 6 - app/views/dashboard/settings/_form.html.haml | 5 - .../layouts/dashboard/_navigation.html.haml | 1 - config/application.rb | 4 +- 20 files changed, 2 insertions(+), 677 deletions(-) delete mode 100755 app/assets/images/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png delete mode 100755 app/assets/images/jquery-ui/ui-bg_flat_75_ffffff_40x100.png delete mode 100755 app/assets/images/jquery-ui/ui-bg_glass_55_fbf9ee_1x400.png delete mode 100755 app/assets/images/jquery-ui/ui-bg_glass_65_ffffff_1x400.png delete mode 100755 app/assets/images/jquery-ui/ui-bg_glass_75_dadada_1x400.png delete mode 100755 app/assets/images/jquery-ui/ui-bg_glass_75_e6e6e6_1x400.png delete mode 100755 app/assets/images/jquery-ui/ui-bg_glass_95_fef1ec_1x400.png delete mode 100755 app/assets/images/jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100.png delete mode 100755 app/assets/images/jquery-ui/ui-icons_222222_256x240.png delete mode 100755 app/assets/images/jquery-ui/ui-icons_2e83ff_256x240.png delete mode 100755 app/assets/images/jquery-ui/ui-icons_454545_256x240.png delete mode 100755 app/assets/images/jquery-ui/ui-icons_888888_256x240.png delete mode 100755 app/assets/images/jquery-ui/ui-icons_cd0a0a_256x240.png delete mode 100755 app/assets/stylesheets/jquery-ui.css diff --git a/app/assets/images/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png b/app/assets/images/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png deleted file mode 100755 index 5b5dab2ab7b1c50dea9cfe73dc5a269a92d2d4b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^8bF-F!3HG1q!d*FscKIb$B>N1x91EQ4=4yQ7#`R^ z$vje}bP0l+XkK DSH>_4 diff --git a/app/assets/images/jquery-ui/ui-bg_flat_75_ffffff_40x100.png b/app/assets/images/jquery-ui/ui-bg_flat_75_ffffff_40x100.png deleted file mode 100755 index ac8b229af950c29356abf64a6c4aa894575445f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^8bF-F!3HG1q!d*FsY*{5$B>N1x91EQ4=4yQYz+E8 zPo9&<{J;c_6SHRil>2s{Zw^OT)6@jj2u|u!(plXsM>LJD`vD!n;OXk;vd$@?2>^GI BH@yG= diff --git a/app/assets/images/jquery-ui/ui-bg_glass_55_fbf9ee_1x400.png b/app/assets/images/jquery-ui/ui-bg_glass_55_fbf9ee_1x400.png deleted file mode 100755 index ad3d6346e00f246102f72f2e026ed0491988b394..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 120 zcmeAS@N?(olHy`uVBq!ia0vp^j6gJjgAK^akKnour0hLi978O6-<~(*I$*%ybaDOn z{W;e!B}_MSUQoPXhYd^Y6RUoS1yepnPx`2Kz)7OXQG!!=-jY=F+d2OOy?#DnJ32>z UEim$g7SJdLPgg&ebxsLQ09~*s;{X5v diff --git a/app/assets/images/jquery-ui/ui-bg_glass_65_ffffff_1x400.png b/app/assets/images/jquery-ui/ui-bg_glass_65_ffffff_1x400.png deleted file mode 100755 index 42ccba269b6e91bef12ad0fa18be651b5ef0ee68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^j6gJjgAK^akKnouqzpV=978O6-=0?FV^9z|eBtf= z|7WztIJ;WT>{+tN>ySr~=F{k$>;_x^_y?afmf9pRKH0)6?eSP?3s5hEr>mdKI;Vst E0O;M1& diff --git a/app/assets/images/jquery-ui/ui-bg_glass_75_dadada_1x400.png b/app/assets/images/jquery-ui/ui-bg_glass_75_dadada_1x400.png deleted file mode 100755 index 5a46b47cb16631068aee9e0bd61269fc4e95e5cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 111 zcmeAS@N?(olHy`uVBq!ia0vp^j6gJjgAK^akKnouq|7{B978O6lPf+wIa#m9#>Unb zm^4K~wN3Zq+uP{vDV26o)#~38k_!`W=^oo1w6ixmPC4R1b Tyd6G3lNdZ*{an^LB{Ts5`idse diff --git a/app/assets/images/jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100.png b/app/assets/images/jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100.png deleted file mode 100755 index 7c9fa6c6edcfcdd3e5b77e6f547b719e6fc66e30..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 101 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 diff --git a/app/assets/images/jquery-ui/ui-icons_2e83ff_256x240.png b/app/assets/images/jquery-ui/ui-icons_2e83ff_256x240.png deleted file mode 100755 index 09d1cdc856c292c4ab6dd818c7543ac0828bd616..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4369 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 diff --git a/app/assets/images/jquery-ui/ui-icons_454545_256x240.png b/app/assets/images/jquery-ui/ui-icons_454545_256x240.png deleted file mode 100755 index 59bd45b907c4fd965697774ce8c5fc6b2fd9c105..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4369 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 oBo%DI*Kv;w;*%(i9W@f3_WCF#rGn diff --git a/app/assets/images/jquery-ui/ui-icons_cd0a0a_256x240.png b/app/assets/images/jquery-ui/ui-icons_cd0a0a_256x240.png deleted file mode 100755 index 2ab019b73ec11a485fa09378f3a0e155194f6a5d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4369 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

    '; - element += params.text + '

    '; - - $("#main").append(element); - - $(function() { - // a workaround for a flaw in the demo system (http://dev.jqueryui.com/ticket/4375), ignore! - $("#dialog").dialog("destroy"); - $("#dialog-confirm").dialog({ - resizable: false, - modal: true, - dialogClass: 'alert', - buttons: { - 'Delete': function() { - $(this).dialog('close'); - $(params.element).remove(); - eval(params.onsuccess + '()'); - $(this).remove(); - }, - Cancel: function() { - $(this).dialog('close'); - $(this).remove(); - } - } - }); - }); -} - -function image_operations( params ) { - element = '

    '; - element += params.text + '

    '; - $("#main").append(element); - - $(function() { - $("#dialog-pictures").dialog({ - resizable: false, - modal: true, - dialogClass: 'info', - buttons: { - 'Add picture to page': function() { - $(this).dialog('close'); - var img = document.createElement("img"); - var p = document.createElement(p) - p.innerHTML = ' '; - img.src = params.element.src.replace(/small/, 'medium' ); - $("body", $("iframe").contents()).append(img, p); - $("a[href=#tabs-1]").click(); - $(this).remove(); - }, - Cancel: function() { - $(this).dialog('close'); - $(this).remove(); - } - } - }); - }); -} - -$(function() { - $('#tabs').tabs(); - add_images(); -}); diff --git a/app/assets/stylesheets/jquery-ui.css b/app/assets/stylesheets/jquery-ui.css deleted file mode 100755 index 77d0ad2..0000000 --- a/app/assets/stylesheets/jquery-ui.css +++ /dev/null @@ -1,565 +0,0 @@ -/*! - * jQuery UI CSS Framework 1.8.19 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Theming/API - */ - -/* Layout helpers -----------------------------------*/ -.ui-helper-hidden { display: none; } -.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } -.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } -.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; } -.ui-helper-clearfix:after { clear: both; } -.ui-helper-clearfix { zoom: 1; } -.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } - - -/* Interaction Cues -----------------------------------*/ -.ui-state-disabled { cursor: default !important; } - - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } - - -/* Misc visuals -----------------------------------*/ - -/* Overlays */ -.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } - - -/*! - * jQuery UI CSS Framework 1.8.19 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Theming/API - * - * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px - */ - - -/* Component containers -----------------------------------*/ -.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; } -.ui-widget .ui-widget { font-size: 1em; } -.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; } -.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(/assets/jquery-ui/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; } -.ui-widget-content a { color: #222222; } -.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(/assets/jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; } -.ui-widget-header a { color: #222222; } - -/* Interaction states -----------------------------------*/ -.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(/assets/jquery-ui/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; } -.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; } -.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(/assets/jquery-ui/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } -.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; } -.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(/assets/jquery-ui/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } -.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; } -.ui-widget :active { outline: none; } - -/* Interaction Cues -----------------------------------*/ -.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(/assets/jquery-ui/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; } -.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } -.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(/assets/jquery-ui/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } -.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } -.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } -.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } -.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } -.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { width: 16px; height: 16px; background-image: url(/assets/jquery-ui/ui-icons_222222_256x240.png); } -.ui-widget-content .ui-icon {background-image: url(/assets/jquery-ui/ui-icons_222222_256x240.png); } -.ui-widget-header .ui-icon {background-image: url(/assets/jquery-ui/ui-icons_222222_256x240.png); } -.ui-state-default .ui-icon { background-image: url(/assets/jquery-ui/ui-icons_888888_256x240.png); } -.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(/assets/jquery-ui/ui-icons_454545_256x240.png); } -.ui-state-active .ui-icon {background-image: url(/assets/jquery-ui/ui-icons_454545_256x240.png); } -.ui-state-highlight .ui-icon {background-image: url(/assets/jquery-ui/ui-icons_2e83ff_256x240.png); } -.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(/assets/jquery-ui/ui-icons_cd0a0a_256x240.png); } - -/* positioning */ -.ui-icon-carat-1-n { background-position: 0 0; } -.ui-icon-carat-1-ne { background-position: -16px 0; } -.ui-icon-carat-1-e { background-position: -32px 0; } -.ui-icon-carat-1-se { background-position: -48px 0; } -.ui-icon-carat-1-s { background-position: -64px 0; } -.ui-icon-carat-1-sw { background-position: -80px 0; } -.ui-icon-carat-1-w { background-position: -96px 0; } -.ui-icon-carat-1-nw { background-position: -112px 0; } -.ui-icon-carat-2-n-s { background-position: -128px 0; } -.ui-icon-carat-2-e-w { background-position: -144px 0; } -.ui-icon-triangle-1-n { background-position: 0 -16px; } -.ui-icon-triangle-1-ne { background-position: -16px -16px; } -.ui-icon-triangle-1-e { background-position: -32px -16px; } -.ui-icon-triangle-1-se { background-position: -48px -16px; } -.ui-icon-triangle-1-s { background-position: -64px -16px; } -.ui-icon-triangle-1-sw { background-position: -80px -16px; } -.ui-icon-triangle-1-w { background-position: -96px -16px; } -.ui-icon-triangle-1-nw { background-position: -112px -16px; } -.ui-icon-triangle-2-n-s { background-position: -128px -16px; } -.ui-icon-triangle-2-e-w { background-position: -144px -16px; } -.ui-icon-arrow-1-n { background-position: 0 -32px; } -.ui-icon-arrow-1-ne { background-position: -16px -32px; } -.ui-icon-arrow-1-e { background-position: -32px -32px; } -.ui-icon-arrow-1-se { background-position: -48px -32px; } -.ui-icon-arrow-1-s { background-position: -64px -32px; } -.ui-icon-arrow-1-sw { background-position: -80px -32px; } -.ui-icon-arrow-1-w { background-position: -96px -32px; } -.ui-icon-arrow-1-nw { background-position: -112px -32px; } -.ui-icon-arrow-2-n-s { background-position: -128px -32px; } -.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } -.ui-icon-arrow-2-e-w { background-position: -160px -32px; } -.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } -.ui-icon-arrowstop-1-n { background-position: -192px -32px; } -.ui-icon-arrowstop-1-e { background-position: -208px -32px; } -.ui-icon-arrowstop-1-s { background-position: -224px -32px; } -.ui-icon-arrowstop-1-w { background-position: -240px -32px; } -.ui-icon-arrowthick-1-n { background-position: 0 -48px; } -.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } -.ui-icon-arrowthick-1-e { background-position: -32px -48px; } -.ui-icon-arrowthick-1-se { background-position: -48px -48px; } -.ui-icon-arrowthick-1-s { background-position: -64px -48px; } -.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } -.ui-icon-arrowthick-1-w { background-position: -96px -48px; } -.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } -.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } -.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } -.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } -.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } -.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } -.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } -.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } -.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } -.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } -.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } -.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } -.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } -.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } -.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } -.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } -.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } -.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } -.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } -.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } -.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } -.ui-icon-arrow-4 { background-position: 0 -80px; } -.ui-icon-arrow-4-diag { background-position: -16px -80px; } -.ui-icon-extlink { background-position: -32px -80px; } -.ui-icon-newwin { background-position: -48px -80px; } -.ui-icon-refresh { background-position: -64px -80px; } -.ui-icon-shuffle { background-position: -80px -80px; } -.ui-icon-transfer-e-w { background-position: -96px -80px; } -.ui-icon-transferthick-e-w { background-position: -112px -80px; } -.ui-icon-folder-collapsed { background-position: 0 -96px; } -.ui-icon-folder-open { background-position: -16px -96px; } -.ui-icon-document { background-position: -32px -96px; } -.ui-icon-document-b { background-position: -48px -96px; } -.ui-icon-note { background-position: -64px -96px; } -.ui-icon-mail-closed { background-position: -80px -96px; } -.ui-icon-mail-open { background-position: -96px -96px; } -.ui-icon-suitcase { background-position: -112px -96px; } -.ui-icon-comment { background-position: -128px -96px; } -.ui-icon-person { background-position: -144px -96px; } -.ui-icon-print { background-position: -160px -96px; } -.ui-icon-trash { background-position: -176px -96px; } -.ui-icon-locked { background-position: -192px -96px; } -.ui-icon-unlocked { background-position: -208px -96px; } -.ui-icon-bookmark { background-position: -224px -96px; } -.ui-icon-tag { background-position: -240px -96px; } -.ui-icon-home { background-position: 0 -112px; } -.ui-icon-flag { background-position: -16px -112px; } -.ui-icon-calendar { background-position: -32px -112px; } -.ui-icon-cart { background-position: -48px -112px; } -.ui-icon-pencil { background-position: -64px -112px; } -.ui-icon-clock { background-position: -80px -112px; } -.ui-icon-disk { background-position: -96px -112px; } -.ui-icon-calculator { background-position: -112px -112px; } -.ui-icon-zoomin { background-position: -128px -112px; } -.ui-icon-zoomout { background-position: -144px -112px; } -.ui-icon-search { background-position: -160px -112px; } -.ui-icon-wrench { background-position: -176px -112px; } -.ui-icon-gear { background-position: -192px -112px; } -.ui-icon-heart { background-position: -208px -112px; } -.ui-icon-star { background-position: -224px -112px; } -.ui-icon-link { background-position: -240px -112px; } -.ui-icon-cancel { background-position: 0 -128px; } -.ui-icon-plus { background-position: -16px -128px; } -.ui-icon-plusthick { background-position: -32px -128px; } -.ui-icon-minus { background-position: -48px -128px; } -.ui-icon-minusthick { background-position: -64px -128px; } -.ui-icon-close { background-position: -80px -128px; } -.ui-icon-closethick { background-position: -96px -128px; } -.ui-icon-key { background-position: -112px -128px; } -.ui-icon-lightbulb { background-position: -128px -128px; } -.ui-icon-scissors { background-position: -144px -128px; } -.ui-icon-clipboard { background-position: -160px -128px; } -.ui-icon-copy { background-position: -176px -128px; } -.ui-icon-contact { background-position: -192px -128px; } -.ui-icon-image { background-position: -208px -128px; } -.ui-icon-video { background-position: -224px -128px; } -.ui-icon-script { background-position: -240px -128px; } -.ui-icon-alert { background-position: 0 -144px; } -.ui-icon-info { background-position: -16px -144px; } -.ui-icon-notice { background-position: -32px -144px; } -.ui-icon-help { background-position: -48px -144px; } -.ui-icon-check { background-position: -64px -144px; } -.ui-icon-bullet { background-position: -80px -144px; } -.ui-icon-radio-off { background-position: -96px -144px; } -.ui-icon-radio-on { background-position: -112px -144px; } -.ui-icon-pin-w { background-position: -128px -144px; } -.ui-icon-pin-s { background-position: -144px -144px; } -.ui-icon-play { background-position: 0 -160px; } -.ui-icon-pause { background-position: -16px -160px; } -.ui-icon-seek-next { background-position: -32px -160px; } -.ui-icon-seek-prev { background-position: -48px -160px; } -.ui-icon-seek-end { background-position: -64px -160px; } -.ui-icon-seek-start { background-position: -80px -160px; } -/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ -.ui-icon-seek-first { background-position: -80px -160px; } -.ui-icon-stop { background-position: -96px -160px; } -.ui-icon-eject { background-position: -112px -160px; } -.ui-icon-volume-off { background-position: -128px -160px; } -.ui-icon-volume-on { background-position: -144px -160px; } -.ui-icon-power { background-position: 0 -176px; } -.ui-icon-signal-diag { background-position: -16px -176px; } -.ui-icon-signal { background-position: -32px -176px; } -.ui-icon-battery-0 { background-position: -48px -176px; } -.ui-icon-battery-1 { background-position: -64px -176px; } -.ui-icon-battery-2 { background-position: -80px -176px; } -.ui-icon-battery-3 { background-position: -96px -176px; } -.ui-icon-circle-plus { background-position: 0 -192px; } -.ui-icon-circle-minus { background-position: -16px -192px; } -.ui-icon-circle-close { background-position: -32px -192px; } -.ui-icon-circle-triangle-e { background-position: -48px -192px; } -.ui-icon-circle-triangle-s { background-position: -64px -192px; } -.ui-icon-circle-triangle-w { background-position: -80px -192px; } -.ui-icon-circle-triangle-n { background-position: -96px -192px; } -.ui-icon-circle-arrow-e { background-position: -112px -192px; } -.ui-icon-circle-arrow-s { background-position: -128px -192px; } -.ui-icon-circle-arrow-w { background-position: -144px -192px; } -.ui-icon-circle-arrow-n { background-position: -160px -192px; } -.ui-icon-circle-zoomin { background-position: -176px -192px; } -.ui-icon-circle-zoomout { background-position: -192px -192px; } -.ui-icon-circle-check { background-position: -208px -192px; } -.ui-icon-circlesmall-plus { background-position: 0 -208px; } -.ui-icon-circlesmall-minus { background-position: -16px -208px; } -.ui-icon-circlesmall-close { background-position: -32px -208px; } -.ui-icon-squaresmall-plus { background-position: -48px -208px; } -.ui-icon-squaresmall-minus { background-position: -64px -208px; } -.ui-icon-squaresmall-close { background-position: -80px -208px; } -.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } -.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } -.ui-icon-grip-solid-vertical { background-position: -32px -224px; } -.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } -.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } -.ui-icon-grip-diagonal-se { background-position: -80px -224px; } - - -/* Misc visuals -----------------------------------*/ - -/* Corner radius */ -.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; } -.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; } -.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } -.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } - -/* Overlays */ -.ui-widget-overlay { background: #aaaaaa url(/assets/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } -.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(/assets/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/*! - * jQuery UI Resizable 1.8.19 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Resizable#theming - */ -.ui-resizable { position: relative;} -.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; } -.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } -.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } -.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } -.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } -.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } -.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } -.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } -.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } -.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*! - * jQuery UI Selectable 1.8.19 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Selectable#theming - */ -.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } -/*! - * jQuery UI Accordion 1.8.19 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Accordion#theming - */ -/* IE/Win - Fix animation bug - #4615 */ -.ui-accordion { width: 100%; } -.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } -.ui-accordion .ui-accordion-li-fix { display: inline; } -.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } -.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } -.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } -.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } -.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } -.ui-accordion .ui-accordion-content-active { display: block; } -/*! - * jQuery UI Autocomplete 1.8.19 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Autocomplete#theming - */ -.ui-autocomplete { position: absolute; cursor: default; } - -/* workarounds */ -* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ - -/* - * jQuery UI Menu @VERSION - * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Menu#theming - */ -.ui-menu { - list-style:none; - padding: 2px; - margin: 0; - display:block; - float: left; -} -.ui-menu .ui-menu { - margin-top: -3px; -} -.ui-menu .ui-menu-item { - margin:0; - padding: 0; - zoom: 1; - float: left; - clear: left; - width: 100%; -} -.ui-menu .ui-menu-item a { - text-decoration:none; - display:block; - padding:.2em .4em; - line-height:1.5; - zoom:1; -} -.ui-menu .ui-menu-item a.ui-state-hover, -.ui-menu .ui-menu-item a.ui-state-active { - font-weight: normal; - margin: -1px; -} -/*! - * jQuery UI Button 1.8.19 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Button#theming - */ -.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ -.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ -button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ -.ui-button-icons-only { width: 3.4em; } -button.ui-button-icons-only { width: 3.7em; } - -/*button text element */ -.ui-button .ui-button-text { display: block; line-height: 1.4; } -.ui-button-text-only .ui-button-text { padding: .4em 1em; } -.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } -.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } -.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } -.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } -/* no icon support for input elements, provide padding by default */ -input.ui-button { padding: .4em 1em; } - -/*button icon element(s) */ -.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } -.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } -.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } -.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } -.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } - -/*button sets*/ -.ui-buttonset { margin-right: 7px; } -.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } - -/* workarounds */ -button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ -/*! - * jQuery UI Dialog 1.8.19 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Dialog#theming - */ -.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } -.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } -.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } -.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } -.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } -.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } -.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } -.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } -.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } -.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } -.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } -.ui-draggable .ui-dialog-titlebar { cursor: move; } -/*! - * jQuery UI Slider 1.8.19 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Slider#theming - */ -.ui-slider { position: relative; text-align: left; } -.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } -.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } - -.ui-slider-horizontal { height: .8em; } -.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } -.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } -.ui-slider-horizontal .ui-slider-range-min { left: 0; } -.ui-slider-horizontal .ui-slider-range-max { right: 0; } - -.ui-slider-vertical { width: .8em; height: 100px; } -.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } -.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } -.ui-slider-vertical .ui-slider-range-min { bottom: 0; } -.ui-slider-vertical .ui-slider-range-max { top: 0; }/*! - * jQuery UI Tabs 1.8.19 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Tabs#theming - */ -.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ -.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } -.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } -.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } -.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } -.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } -.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ -.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } -.ui-tabs .ui-tabs-hide { display: none !important; } -/*! - * jQuery UI Datepicker 1.8.19 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Datepicker#theming - */ -.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } -.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } -.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } -.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } -.ui-datepicker .ui-datepicker-prev { left:2px; } -.ui-datepicker .ui-datepicker-next { right:2px; } -.ui-datepicker .ui-datepicker-prev-hover { left:1px; } -.ui-datepicker .ui-datepicker-next-hover { right:1px; } -.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } -.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } -.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } -.ui-datepicker select.ui-datepicker-month-year {width: 100%;} -.ui-datepicker select.ui-datepicker-month, -.ui-datepicker select.ui-datepicker-year { width: 49%;} -.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } -.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } -.ui-datepicker td { border: 0; padding: 1px; } -.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } -.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } -.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } -.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } - -/* with multiple calendars */ -.ui-datepicker.ui-datepicker-multi { width:auto; } -.ui-datepicker-multi .ui-datepicker-group { float:left; } -.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } -.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } -.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } -.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } -.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } -.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } - -/* RTL support */ -.ui-datepicker-rtl { direction: rtl; } -.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } -.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } -.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } -.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } -.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } -.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } -.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } -.ui-datepicker-rtl .ui-datepicker-group { float:right; } -.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } -.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } - -/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ -.ui-datepicker-cover { - display: none; /*sorry for IE5*/ - display/**/: block; /*sorry for IE5*/ - position: absolute; /*must have*/ - z-index: -1; /*must have*/ - filter: mask(); /*must have*/ - top: -4px; /*must have*/ - left: -4px; /*must have*/ - width: 200px; /*must have*/ - height: 200px; /*must have*/ -}/*! - * jQuery UI Progressbar 1.8.19 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Progressbar#theming - */ -.ui-progressbar { height:2em; text-align: left; overflow: hidden; } -.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } diff --git a/app/views/dashboard/sections/_form.html.haml b/app/views/dashboard/sections/_form.html.haml index 74e4047..882f84b 100644 --- a/app/views/dashboard/sections/_form.html.haml +++ b/app/views/dashboard/sections/_form.html.haml @@ -17,9 +17,3 @@ #tips_content.box %h3= t 'common.headers.did_you_know' %p= t 'dashboard.sections.index.tip' - -:javascript - $(document).ready(function() { - $('#submit').button({ icons: { primary: 'ui-icon-circle-check' } }); - $('#sections_menu_link').addClass('active'); - }); diff --git a/app/views/dashboard/settings/_form.html.haml b/app/views/dashboard/settings/_form.html.haml index 63382fe..ea74a9f 100644 --- a/app/views/dashboard/settings/_form.html.haml +++ b/app/views/dashboard/settings/_form.html.haml @@ -19,8 +19,3 @@ #tips_content.box %h3= t 'common.headers.did_you_know' %p= t 'dashboard.settings.forms.tip' - -:javascript - $(function() { - $("#submit").button({ icons: { primary: 'ui-icon-circle-check' } }); - }); diff --git a/app/views/layouts/dashboard/_navigation.html.haml b/app/views/layouts/dashboard/_navigation.html.haml index 955a4db..2dd18ad 100644 --- a/app/views/layouts/dashboard/_navigation.html.haml +++ b/app/views/layouts/dashboard/_navigation.html.haml @@ -1,5 +1,4 @@ - content_for :head do - = stylesheet_link_tag 'jquery-ui' = javascript_include_tag 'uploadify/uploadify.min', 'uploadify/swfobject' - content_for :nav_wrap do diff --git a/config/application.rb b/config/application.rb index 5db18a4..09169b2 100644 --- a/config/application.rb +++ b/config/application.rb @@ -44,12 +44,12 @@ class Application < Rails::Application config.encoding = "utf-8" # Configure sensitive parameters which will be filtered from the log file. - config.filter_parameters += [:password] + config.filter_parameters += [:password, :password_confirmation] # Enable the asset pipeline config.assets.enabled = true - config.assets.precompile += %w( clover.css tjruby.css dashboard.css simple_blog.css sessions.css jquery-ui.css ) + config.assets.precompile += %w( clover.css tjruby.css dashboard.css simple_blog.css sessions.css ) config.assets.precompile += %w( uploadify/uploadify.min.js uploadify/swfobject.js ) # Version of your assets, change this if you want to expire all your assets From 00d52733e3d0e374402faa5e017559553bd7123b Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Wed, 18 Sep 2013 18:21:52 -0700 Subject: [PATCH 24/32] Put binstubs in version control --- .gitignore | 1 - bin/autospec | 16 ++++++++++++++++ bin/cap | 16 ++++++++++++++++ bin/capify | 16 ++++++++++++++++ bin/coderay | 16 ++++++++++++++++ bin/compass | 16 ++++++++++++++++ bin/erubis | 16 ++++++++++++++++ bin/haml | 16 ++++++++++++++++ bin/html2haml | 16 ++++++++++++++++ bin/htmldiff | 16 ++++++++++++++++ bin/launchy | 16 ++++++++++++++++ bin/ldiff | 16 ++++++++++++++++ bin/nokogiri | 16 ++++++++++++++++ bin/posix-spawn-benchmark | 16 ++++++++++++++++ bin/pry | 16 ++++++++++++++++ bin/rackup | 16 ++++++++++++++++ bin/rails | 16 ++++++++++++++++ bin/rails_best_practices | 16 ++++++++++++++++ bin/rake | 16 ++++++++++++++++ bin/rdebug | 16 ++++++++++++++++ bin/rdoc | 16 ++++++++++++++++ bin/redcarpet | 16 ++++++++++++++++ bin/ri | 16 ++++++++++++++++ bin/rspec | 16 ++++++++++++++++ bin/sass | 16 ++++++++++++++++ bin/sass-convert | 16 ++++++++++++++++ bin/scss | 16 ++++++++++++++++ bin/sprockets | 16 ++++++++++++++++ bin/thor | 16 ++++++++++++++++ bin/tilt | 16 ++++++++++++++++ bin/tt | 16 ++++++++++++++++ 31 files changed, 480 insertions(+), 1 deletion(-) create mode 100755 bin/autospec create mode 100755 bin/cap create mode 100755 bin/capify create mode 100755 bin/coderay create mode 100755 bin/compass create mode 100755 bin/erubis create mode 100755 bin/haml create mode 100755 bin/html2haml create mode 100755 bin/htmldiff create mode 100755 bin/launchy create mode 100755 bin/ldiff create mode 100755 bin/nokogiri create mode 100755 bin/posix-spawn-benchmark create mode 100755 bin/pry create mode 100755 bin/rackup create mode 100755 bin/rails create mode 100755 bin/rails_best_practices create mode 100755 bin/rake create mode 100755 bin/rdebug create mode 100755 bin/rdoc create mode 100755 bin/redcarpet create mode 100755 bin/ri create mode 100755 bin/rspec create mode 100755 bin/sass create mode 100755 bin/sass-convert create mode 100755 bin/scss create mode 100755 bin/sprockets create mode 100755 bin/thor create mode 100755 bin/tilt create mode 100755 bin/tt diff --git a/.gitignore b/.gitignore index b8d9d1e..ae8fd2b 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,4 @@ public/system .sass-cache tags coverage -bin/ config/initializers/secret_token.rb diff --git a/bin/autospec b/bin/autospec new file mode 100755 index 0000000..64dcb9c --- /dev/null +++ b/bin/autospec @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'autospec' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('rspec-core', 'autospec') diff --git a/bin/cap b/bin/cap new file mode 100755 index 0000000..30352d4 --- /dev/null +++ b/bin/cap @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'cap' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('capistrano', 'cap') diff --git a/bin/capify b/bin/capify new file mode 100755 index 0000000..0f486e8 --- /dev/null +++ b/bin/capify @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'capify' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('capistrano', 'capify') diff --git a/bin/coderay b/bin/coderay new file mode 100755 index 0000000..5be1c00 --- /dev/null +++ b/bin/coderay @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'coderay' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('coderay', 'coderay') diff --git a/bin/compass b/bin/compass new file mode 100755 index 0000000..e1ac749 --- /dev/null +++ b/bin/compass @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'compass' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('compass', 'compass') diff --git a/bin/erubis b/bin/erubis new file mode 100755 index 0000000..2c7348b --- /dev/null +++ b/bin/erubis @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'erubis' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('erubis', 'erubis') diff --git a/bin/haml b/bin/haml new file mode 100755 index 0000000..3c6d074 --- /dev/null +++ b/bin/haml @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'haml' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('haml', 'haml') diff --git a/bin/html2haml b/bin/html2haml new file mode 100755 index 0000000..a52215a --- /dev/null +++ b/bin/html2haml @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'html2haml' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('haml', 'html2haml') diff --git a/bin/htmldiff b/bin/htmldiff new file mode 100755 index 0000000..c70e238 --- /dev/null +++ b/bin/htmldiff @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'htmldiff' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('diff-lcs', 'htmldiff') diff --git a/bin/launchy b/bin/launchy new file mode 100755 index 0000000..92b254a --- /dev/null +++ b/bin/launchy @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'launchy' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('launchy', 'launchy') diff --git a/bin/ldiff b/bin/ldiff new file mode 100755 index 0000000..8e3524a --- /dev/null +++ b/bin/ldiff @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'ldiff' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('diff-lcs', 'ldiff') diff --git a/bin/nokogiri b/bin/nokogiri new file mode 100755 index 0000000..d55f84b --- /dev/null +++ b/bin/nokogiri @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'nokogiri' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('nokogiri', 'nokogiri') diff --git a/bin/posix-spawn-benchmark b/bin/posix-spawn-benchmark new file mode 100755 index 0000000..9e73bb8 --- /dev/null +++ b/bin/posix-spawn-benchmark @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'posix-spawn-benchmark' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('posix-spawn', 'posix-spawn-benchmark') diff --git a/bin/pry b/bin/pry new file mode 100755 index 0000000..54678a3 --- /dev/null +++ b/bin/pry @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'pry' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('pry', 'pry') diff --git a/bin/rackup b/bin/rackup new file mode 100755 index 0000000..8cc9953 --- /dev/null +++ b/bin/rackup @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'rackup' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('rack', 'rackup') diff --git a/bin/rails b/bin/rails new file mode 100755 index 0000000..657440d --- /dev/null +++ b/bin/rails @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'rails' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('railties', 'rails') diff --git a/bin/rails_best_practices b/bin/rails_best_practices new file mode 100755 index 0000000..30c973c --- /dev/null +++ b/bin/rails_best_practices @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'rails_best_practices' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('rails_best_practices', 'rails_best_practices') diff --git a/bin/rake b/bin/rake new file mode 100755 index 0000000..26c7a2d --- /dev/null +++ b/bin/rake @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'rake' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('rake', 'rake') diff --git a/bin/rdebug b/bin/rdebug new file mode 100755 index 0000000..c0c33af --- /dev/null +++ b/bin/rdebug @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'rdebug' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('debugger', 'rdebug') diff --git a/bin/rdoc b/bin/rdoc new file mode 100755 index 0000000..f57260f --- /dev/null +++ b/bin/rdoc @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'rdoc' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('rdoc', 'rdoc') diff --git a/bin/redcarpet b/bin/redcarpet new file mode 100755 index 0000000..37d58a8 --- /dev/null +++ b/bin/redcarpet @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'redcarpet' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('redcarpet', 'redcarpet') diff --git a/bin/ri b/bin/ri new file mode 100755 index 0000000..90f2517 --- /dev/null +++ b/bin/ri @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'ri' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('rdoc', 'ri') diff --git a/bin/rspec b/bin/rspec new file mode 100755 index 0000000..0c86b5c --- /dev/null +++ b/bin/rspec @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'rspec' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('rspec-core', 'rspec') diff --git a/bin/sass b/bin/sass new file mode 100755 index 0000000..d65bb10 --- /dev/null +++ b/bin/sass @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'sass' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('sass', 'sass') diff --git a/bin/sass-convert b/bin/sass-convert new file mode 100755 index 0000000..ddde743 --- /dev/null +++ b/bin/sass-convert @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'sass-convert' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('sass', 'sass-convert') diff --git a/bin/scss b/bin/scss new file mode 100755 index 0000000..9f5e435 --- /dev/null +++ b/bin/scss @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'scss' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('sass', 'scss') diff --git a/bin/sprockets b/bin/sprockets new file mode 100755 index 0000000..09a1ad1 --- /dev/null +++ b/bin/sprockets @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'sprockets' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('sprockets', 'sprockets') diff --git a/bin/thor b/bin/thor new file mode 100755 index 0000000..8421e00 --- /dev/null +++ b/bin/thor @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'thor' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('thor', 'thor') diff --git a/bin/tilt b/bin/tilt new file mode 100755 index 0000000..09fe73e --- /dev/null +++ b/bin/tilt @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'tilt' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('tilt', 'tilt') diff --git a/bin/tt b/bin/tt new file mode 100755 index 0000000..6e3920b --- /dev/null +++ b/bin/tt @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'tt' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('treetop', 'tt') From 5c28517e7510863464860fd316b8e3903dbbfe66 Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Thu, 19 Sep 2013 07:31:26 -0700 Subject: [PATCH 25/32] Remove assets for the time being and update bootstrap_pagedown --- Gemfile.lock | 2 +- app/models/asset.rb | 17 ----------------- app/models/page.rb | 1 - app/views/dashboard/pages/_form.html.haml | 1 + app/views/dashboard/pages/edit.haml | 17 +---------------- app/views/dashboard/pages/new.haml | 6 +----- db/migrate/20101110064447_create_assets.rb | 22 ---------------------- db/schema.rb | 12 ------------ 8 files changed, 4 insertions(+), 74 deletions(-) delete mode 100644 app/models/asset.rb delete mode 100644 db/migrate/20101110064447_create_assets.rb diff --git a/Gemfile.lock b/Gemfile.lock index c768fa4..cb00e6d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -41,7 +41,7 @@ GEM sass (~> 3.2) bootstrap-will_paginate (0.0.9) will_paginate - bootstrap_pagedown (1.0.1) + bootstrap_pagedown (1.0.2) rails (>= 3.2) builder (3.0.4) bullet (4.1.5) diff --git a/app/models/asset.rb b/app/models/asset.rb deleted file mode 100644 index 2095e5d..0000000 --- a/app/models/asset.rb +++ /dev/null @@ -1,17 +0,0 @@ -class Asset < ActiveRecord::Base - belongs_to :attachable, polymorphic: true - - -=begin - has_attached_file :asset, styles: { - squared: "120x80#", - small: "120x80>", - medium: "180x120>", - big: "300x225>" - } - - validates_attachment_presence :asset - validates_attachment_content_type :asset, content_type: [ 'image/jpeg', 'image/png', 'image/gif' ] - validates_attachment_size :asset, less_than: 20.megabytes -=end -end diff --git a/app/models/page.rb b/app/models/page.rb index ae58225..1cdb6bc 100644 --- a/app/models/page.rb +++ b/app/models/page.rb @@ -1,7 +1,6 @@ class Page < ActiveRecord::Base extend FriendlyId - has_many :assets, as: :attachable belongs_to :section before_save :check_home_page diff --git a/app/views/dashboard/pages/_form.html.haml b/app/views/dashboard/pages/_form.html.haml index 7867d8e..49229b7 100644 --- a/app/views/dashboard/pages/_form.html.haml +++ b/app/views/dashboard/pages/_form.html.haml @@ -1,6 +1,7 @@ = simple_form_for [ :dashboard, page ] do |f| #page_content = f.input :name, placeholder: t('common.descriptions.url.item_name', item: Page.model_name.downcase ) + = f.pagedown_editor :content = f.label :section do diff --git a/app/views/dashboard/pages/edit.haml b/app/views/dashboard/pages/edit.haml index 4fd1e42..e7640b3 100644 --- a/app/views/dashboard/pages/edit.haml +++ b/app/views/dashboard/pages/edit.haml @@ -1,16 +1 @@ -#tabs - %ul - %li= link_to t('links.item_details', item: Page.model_name ), '#page-editor' - %li= link_to t('links.item_assets', item: Page.model_name ), '#assets' - - #page-editor= render 'form', page: @page - - #assets - .splitcontentleft - #images_list - - @page.assets.each do |asset| - = image_tag asset.asset.url(:small) - %file#uploadify{ name: 'asset' } - .splitcontentright - = render 'shared/uploadify', object: @page - .spacer += render 'form', page: @page diff --git a/app/views/dashboard/pages/new.haml b/app/views/dashboard/pages/new.haml index dd33032..e7640b3 100644 --- a/app/views/dashboard/pages/new.haml +++ b/app/views/dashboard/pages/new.haml @@ -1,5 +1 @@ -#tabs - %ul - %li= link_to t('links.item_details', item: Page.model_name ), '#page-editor' - - #page-editor= render 'form', page: @page += render 'form', page: @page diff --git a/db/migrate/20101110064447_create_assets.rb b/db/migrate/20101110064447_create_assets.rb deleted file mode 100644 index f97d785..0000000 --- a/db/migrate/20101110064447_create_assets.rb +++ /dev/null @@ -1,22 +0,0 @@ -class CreateAssets < ActiveRecord::Migration - def self.up - create_table :assets do |t| - t.string :description - t.string :asset_file_name - t.string :asset_content_type - t.integer :asset_file_size - t.integer :attachable_id - t.string :attachable_type - end - - add_index :assets, :asset_content_type - add_index :assets, [ :attachable_id, :attachable_type ] - end - - def self.down - remove_index :assets, [ :attachable_id, :attachable_type ] - remove_index :assets, :asset_content_type - - drop_table :assets - end -end diff --git a/db/schema.rb b/db/schema.rb index ed7f8df..da3c21e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -13,18 +13,6 @@ ActiveRecord::Schema.define(:version => 20120918223422) do - create_table "assets", :force => true do |t| - t.string "description" - t.string "asset_file_name" - t.string "asset_content_type" - t.integer "asset_file_size" - t.integer "attachable_id" - t.string "attachable_type" - end - - add_index "assets", ["asset_content_type"], :name => "index_assets_on_asset_content_type" - add_index "assets", ["attachable_id", "attachable_type"], :name => "index_assets_on_attachable_id_and_attachable_type" - create_table "pages", :force => true do |t| t.string "name" t.text "content" From e835f15626cfbfc5ab4a5736c825b78a2bf00f4e Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Thu, 19 Sep 2013 07:54:46 -0700 Subject: [PATCH 26/32] Remove uploadify assets, carrierwave and rmagick --- Gemfile | 2 - Gemfile.lock | 6 -- app/assets/images/uploadify/cancel.png | Bin 2960 -> 0 bytes app/assets/stylesheets/application.css | 1 - app/assets/stylesheets/uploadify.css | 52 ------------------ .../flash_session_cookie_middleware.rb | 18 ------ app/models/user.rb | 6 +- .../layouts/dashboard/_navigation.html.haml | 3 - app/views/shared/_uploadify.html.haml | 34 ------------ config/application.rb | 3 +- config/initializers/session_store.rb | 6 -- public/swf/uploadify/uploadify.swf | Bin 22894 -> 0 bytes .../assets/javascripts/uploadify/swfobject.js | 4 -- .../javascripts/uploadify/uploadify.min.js | 26 --------- 14 files changed, 5 insertions(+), 156 deletions(-) delete mode 100755 app/assets/images/uploadify/cancel.png delete mode 100644 app/assets/stylesheets/uploadify.css delete mode 100644 app/middleware/flash_session_cookie_middleware.rb delete mode 100644 app/views/shared/_uploadify.html.haml delete mode 100755 public/swf/uploadify/uploadify.swf delete mode 100755 vendor/assets/javascripts/uploadify/swfobject.js delete mode 100755 vendor/assets/javascripts/uploadify/uploadify.min.js diff --git a/Gemfile b/Gemfile index cd10f42..9438000 100644 --- a/Gemfile +++ b/Gemfile @@ -7,8 +7,6 @@ gem 'bootstrap-will_paginate' gem 'haml-rails' gem 'devise' gem 'devise_invitable' -gem 'carrierwave' -gem 'rmagick' gem 'tabs_on_rails' gem 'jquery-rails' gem 'simple_form' diff --git a/Gemfile.lock b/Gemfile.lock index cb00e6d..e0ca0fd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -62,9 +62,6 @@ GEM capybara-webkit (0.12.1) capybara (>= 1.0.0, < 1.2) json - carrierwave (0.8.0) - activemodel (>= 3.2.0) - activesupport (>= 3.2.0) childprocess (0.3.5) ffi (~> 1.0, >= 1.0.6) chunky_png (1.2.5) @@ -204,7 +201,6 @@ GEM redcarpet (2.2.2) ref (1.0.4) require_all (1.3.0) - rmagick (2.13.2) rspec-core (2.14.4) rspec-expectations (2.14.0) diff-lcs (>= 1.1.3, < 2.0) @@ -280,7 +276,6 @@ DEPENDENCIES bullet capistrano capybara-webkit - carrierwave coffee-rails (~> 3.2.1) compass-rails database_cleaner @@ -302,7 +297,6 @@ DEPENDENCIES rails (= 3.2.14) rails_best_practices redcarpet (= 2.2.2) - rmagick rspec-rails sass-rails (~> 3.2.3) simple_form diff --git a/app/assets/images/uploadify/cancel.png b/app/assets/images/uploadify/cancel.png deleted file mode 100755 index 35682b010b0cd8758b2cedfd230aba50c4392996..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2960 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 diff --git a/vendor/assets/javascripts/uploadify/swfobject.js b/vendor/assets/javascripts/uploadify/swfobject.js deleted file mode 100755 index 8eafe9d..0000000 --- a/vendor/assets/javascripts/uploadify/swfobject.js +++ /dev/null @@ -1,4 +0,0 @@ -/* SWFObject v2.2 - is released under the MIT License -*/ -var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y0){for(var af=0;af0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad'}}aa.outerHTML='"+af+"";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab');swfobject.embedSWF(f.uploader,f.id+"Uploader",f.width,f.height,"9.0.24",f.expressInstall,g,{quality:"high",wmode:f.wmode,allowScriptAccess:f.scriptAccess},{},function(i){if(typeof(f.onSWFReady)=="function"&&i.success){f.onSWFReady()}});if(f.queueID==false){a("#"+a(this).attr("id")+"Uploader").after('
    ')}else{a("#"+f.queueID).addClass("uploadifyQueue")}}if(typeof(f.onOpen)=="function"){a(this).bind("uploadifyOpen",f.onOpen)}a(this).bind("uploadifySelect",{action:f.onSelect,queueID:f.queueID},function(k,i,j){if(k.data.action(k,i,j)!==false){var l=Math.round(j.size/1024*100)*0.01;var m="KB";if(l>1000){l=Math.round(l*0.001*100)*0.01;m="MB"}var n=l.toString().split(".");if(n.length>1){l=n[0]+"."+n[1].substr(0,2)}else{l=n[0]}if(j.name.length>20){fileName=j.name.substr(0,20)+"..."}else{fileName=j.name}queue="#"+a(this).attr("id")+"Queue";if(k.data.queueID){queue="#"+k.data.queueID}a(queue).append('
    ')}});a(this).bind("uploadifySelectOnce",{action:f.onSelectOnce},function(i,j){i.data.action(i,j);if(f.auto){if(f.checkScript){a(this).uploadifyUpload(null,false)}else{a(this).uploadifyUpload(null,true)}}});a(this).bind("uploadifyQueueFull",{action:f.onQueueFull},function(i,j){if(i.data.action(i,j)!==false){alert("The queue is full. The max size is "+j+".")}});a(this).bind("uploadifyCheckExist",{action:f.onCheck},function(n,m,l,k,p){var j=new Object();j=l;j.folder=(k.substr(0,1)=="/")?k:e+k;if(p){for(var i in l){var o=i}}a.post(m,j,function(s){for(var q in s){if(n.data.action(n,s,q)!==false){var r=confirm("Do you want to replace the file "+s[q]+"?");if(!r){document.getElementById(a(n.target).attr("id")+"Uploader").cancelFileUpload(q,true,true)}}}if(p){document.getElementById(a(n.target).attr("id")+"Uploader").startFileUpload(o,true)}else{document.getElementById(a(n.target).attr("id")+"Uploader").startFileUpload(null,true)}},"json")});a(this).bind("uploadifyCancel",{action:f.onCancel},function(n,j,m,o,i,l){if(n.data.action(n,j,m,o,l)!==false){if(i){var k=(l==true)?0:250;a("#"+a(this).attr("id")+j).fadeOut(k,function(){a(this).remove()})}}});a(this).bind("uploadifyClearQueue",{action:f.onClearQueue},function(k,j){var i=(f.queueID)?f.queueID:a(this).attr("id")+"Queue";if(j){a("#"+i).find(".uploadifyQueueItem").remove()}if(k.data.action(k,j)!==false){a("#"+i).find(".uploadifyQueueItem").each(function(){var l=a(".uploadifyQueueItem").index(this);a(this).delay(l*100).fadeOut(250,function(){a(this).remove()})})}});var c=[];a(this).bind("uploadifyError",{action:f.onError},function(m,i,l,k){if(m.data.action(m,i,l,k)!==false){var j=new Array(i,l,k);c.push(j);a("#"+a(this).attr("id")+i).find(".percentage").text(" - "+k.type+" Error");a("#"+a(this).attr("id")+i).find(".uploadifyProgress").hide();a("#"+a(this).attr("id")+i).addClass("uploadifyError")}});if(typeof(f.onUpload)=="function"){a(this).bind("uploadifyUpload",f.onUpload)}a(this).bind("uploadifyProgress",{action:f.onProgress,toDisplay:f.displayData},function(k,i,j,l){if(k.data.action(k,i,j,l)!==false){a("#"+a(this).attr("id")+i+"ProgressBar").animate({width:l.percentage+"%"},250,function(){if(l.percentage==100){a(this).closest(".uploadifyProgress").fadeOut(250,function(){a(this).remove()})}});if(k.data.toDisplay=="percentage"){displayData=" - "+l.percentage+"%"}if(k.data.toDisplay=="speed"){displayData=" - "+l.speed+"KB/s"}if(k.data.toDisplay==null){displayData=" "}a("#"+a(this).attr("id")+i).find(".percentage").text(displayData)}});a(this).bind("uploadifyComplete",{action:f.onComplete},function(l,i,k,j,m){if(l.data.action(l,i,k,unescape(j),m)!==false){a("#"+a(this).attr("id")+i).find(".percentage").text(" - Completed");if(f.removeCompleted){a("#"+a(l.target).attr("id")+i).fadeOut(250,function(){a(this).remove()})}a("#"+a(l.target).attr("id")+i).addClass("completed")}});if(typeof(f.onAllComplete)=="function"){a(this).bind("uploadifyAllComplete",{action:f.onAllComplete},function(i,j){if(i.data.action(i,j)!==false){c=[]}})}})},uploadifySettings:function(f,j,c){var g=false;a(this).each(function(){if(f=="scriptData"&&j!=null){if(c){var i=j}else{var i=a.extend(a(this).data("settings").scriptData,j)}var l="";for(var k in i){l+="&"+k+"="+i[k]}j=escape(l.substr(1))}g=document.getElementById(a(this).attr("id")+"Uploader").updateSettings(f,j)});if(j==null){if(f=="scriptData"){var b=unescape(g).split("&");var e=new Object();for(var d=0;d Date: Thu, 19 Sep 2013 20:05:22 -0700 Subject: [PATCH 27/32] Replace contactform ActiveModel class with mail_form and DRY out pages_controller --- app/controllers/contact_forms_controller.rb | 6 ++--- app/controllers/pages_controller.rb | 15 ++++++----- app/models/contact_form.rb | 26 ++++++++----------- .../contact_forms/_contact_form.html.haml | 14 ++++------ app/views/contact_forms/new.html.haml | 12 --------- app/views/pages/show.haml | 4 +-- 6 files changed, 29 insertions(+), 48 deletions(-) delete mode 100644 app/views/contact_forms/new.html.haml diff --git a/app/controllers/contact_forms_controller.rb b/app/controllers/contact_forms_controller.rb index d7b79a1..69a6a13 100644 --- a/app/controllers/contact_forms_controller.rb +++ b/app/controllers/contact_forms_controller.rb @@ -2,12 +2,12 @@ class ContactFormsController < ApplicationController def create @contact_form = ContactForm.new params[:contact_form] - if @contact_form.valid? + if @contact_form.deliver flash[:success] = t 'messages.email_sent' - redirect_to root_path else flash[:error] = t 'messages.failed_miserably' - redirect_to request.env["HTTP_REFERER"] end + + redirect_to :back end end diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb index ebdec89..a8969f1 100644 --- a/app/controllers/pages_controller.rb +++ b/app/controllers/pages_controller.rb @@ -1,23 +1,24 @@ class PagesController < ApplicationController - skip_before_filter :authenticate_user! + skip_before_filter :authenticate_user! + after_filter :raise_if_page_not_found! # GET /:section/:page # GET /:section/:subsection/:page def show @section = Section.find params[:section] @page = @section.pages.published.find( params[:page] ) if @section - - raise Clover::PageNotFoundError if @page.blank? - - if @page.has_contact? - @contact_form = render_to_string partial: 'contact_forms/contact_form', object: ContactForm.new - end end #GET / def home @page = Page.published.home_page @section = @page.section + render :show end + + private + def raise_if_page_not_found! + raise Clover::PageNotFoundError unless @page.present? + end end diff --git a/app/models/contact_form.rb b/app/models/contact_form.rb index 91f8970..4b24065 100644 --- a/app/models/contact_form.rb +++ b/app/models/contact_form.rb @@ -1,17 +1,13 @@ -class ContactForm - include ActiveModel::Validations - - validates_presence_of :recipient, :subject, :body - validates_format_of :recipient, with: /\b[a-z0-9._%-]+@[a-z0-9.-]+\.[a-z]{2,4}\b/i - validates_length_of :body, minimum: 10 - - attr_accessor :recipient, :subject, :body - - def initialize(attributes = {}) - @recipient = attributes[:recipient] - @body = attributes[:body] - @subject = attributes[:subject] - - yield(self) if block_given? +class ContactForm < MailForm::Base + attribute :name, validate: true + attribute :email, validate: /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\z/i + attribute :subject + attribute :message + + def headers + { + subject: subject, + from: %("#{ name }" <#{ email }>) + } end end diff --git a/app/views/contact_forms/_contact_form.html.haml b/app/views/contact_forms/_contact_form.html.haml index 981ff32..263108f 100644 --- a/app/views/contact_forms/_contact_form.html.haml +++ b/app/views/contact_forms/_contact_form.html.haml @@ -1,12 +1,8 @@ %fieldset - = form_for contact_form, as: :contact_form, url: contact_form_path do |contact| - = contact.label :recipient - = contact.text_field :recipient - - = contact.label :subject - = contact.text_field :subject - - = contact.label :body - = contact.text_area :body + = simple_form_for ContactForm.new, as: :contact_form, url: contact_form_path do |contact| + = contact.input :name + = contact.input :email + = contact.input :subject + = contact.input :message, as: :text = contact.submit :submit diff --git a/app/views/contact_forms/new.html.haml b/app/views/contact_forms/new.html.haml deleted file mode 100644 index 8f7f199..0000000 --- a/app/views/contact_forms/new.html.haml +++ /dev/null @@ -1,12 +0,0 @@ -%fieldset - = form_for @contact_form, validate: true do |contact| - = contact.label :recipient - = contact.text_field :recipient - - = contact.label :subject - = contact.text_field :subject - - = contact.label :body - = contact.text_area :body - - = contact.submit :submit diff --git a/app/views/pages/show.haml b/app/views/pages/show.haml index 4f658e4..5d63f08 100644 --- a/app/views/pages/show.haml +++ b/app/views/pages/show.haml @@ -1,10 +1,10 @@ %h1= @page.name.titleize = markdown @page.content -!= @contact_form if @contact_form.present? += render 'contact_forms/contact_form' if @page.has_contact? = content_for :title do - = "#{site[:site_name]} - #{@page.name.titleize}" + = "#{site[:site_name]} - #{ @page.name.titleize }" = content_for :footer do != "#{site[:footer]}" From f3924c42d0d46223be6ec9abf3ed701fa1f0488e Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Fri, 20 Sep 2013 00:40:26 -0700 Subject: [PATCH 28/32] DRY out controllers --- Gemfile.lock | 2 +- app/controllers/application_controller.rb | 28 ++++++--------- .../dashboard/assets_controller.rb | 23 ------------ app/controllers/dashboard/pages_controller.rb | 12 +++---- .../dashboard/sections_controller.rb | 12 +++---- .../dashboard/settings_controller.rb | 35 +++++-------------- app/controllers/dashboard/users_controller.rb | 6 ++-- app/models/setting.rb | 7 ++-- config/application.rb | 2 ++ .../dashboard/sections_controller_spec.rb | 33 +++++++++-------- spec/models/setting_spec.rb | 4 --- 11 files changed, 56 insertions(+), 108 deletions(-) delete mode 100644 app/controllers/dashboard/assets_controller.rb diff --git a/Gemfile.lock b/Gemfile.lock index e0ca0fd..0479736 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -200,7 +200,7 @@ GEM json (~> 1.4) redcarpet (2.2.2) ref (1.0.4) - require_all (1.3.0) + require_all (1.3.1) rspec-core (2.14.4) rspec-expectations (2.14.0) diff-lcs (>= 1.1.3, < 2.0) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index fa7d5f2..23d4348 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -21,37 +21,29 @@ def set_locale end def devise_layout - if controller_name == 'registrations' - set_tab :edit_user - return 'dashboard' - end - - 'sessions' + return 'sessions' unless controller_name === 'registrations' + set_tab :edit_user + return 'dashboard' end def website_layout - return "themes/#{ site[:theme] }/theme" if site[:theme].present? - 'themes/default/theme' + return "themes/#{ site[:theme] || 'default' }/theme" end def dashboard_controller? - params[:controller] =~ /^dashboard\/[a-z_]+$/ + controller_path =~ /^dashboard\/[a-z_]+$/ end def guess_layout - if dashboard_controller? - 'dashboard' - elsif devise_controller? - devise_layout - else - website_layout - end + return devise_layout if devise_controller? + return 'dashboard' if dashboard_controller? + + website_layout end protected def unauthorized_access - flash[:info] = t 'messages.unauthorized_access' - redirect_to new_user_session_path + redirect_to new_user_session_path, flash: { info: t('messages.unauthorized_access') } end def page_not_found diff --git a/app/controllers/dashboard/assets_controller.rb b/app/controllers/dashboard/assets_controller.rb deleted file mode 100644 index c00636d..0000000 --- a/app/controllers/dashboard/assets_controller.rb +++ /dev/null @@ -1,23 +0,0 @@ -class Dashboard::AssetsController < ApplicationController - before_filter :fix_content_type - - def create - @asset = Asset.new attachable_type: params[:attachable_type], attachable_id: params[:attachable_id] - @asset.asset = params[:Filedata] - - if @asset.save! - success = { status: 'success', thumbnail: @asset.asset.url(:small) }.to_json - render json: success - else - render json: { status: 'error' }.to_json - end - end - - def destroy - end - - private - def fix_content_type - params[:Filedata].content_type = MIME::Types.type_for(params[:Filedata].original_filename).to_s - end -end diff --git a/app/controllers/dashboard/pages_controller.rb b/app/controllers/dashboard/pages_controller.rb index de1441b..fa83b63 100644 --- a/app/controllers/dashboard/pages_controller.rb +++ b/app/controllers/dashboard/pages_controller.rb @@ -1,5 +1,5 @@ class Dashboard::PagesController < ApplicationController - before_filter :set_page, only: [ :edit, :update, :destroy ] + before_filter :find_page, only: [ :edit, :update, :destroy ] set_tab :list_pages, only: :index set_tab :new_page, only: :new @@ -16,8 +16,7 @@ def create @page = Page.new params[:page] if @page.save - flash[:success] = t 'messages.created_successfully' - redirect_to dashboard_pages_path + redirect_to dashboard_pages_path, flash: { success: t('messages.created_successfully') } else render :new end @@ -25,8 +24,7 @@ def create def update if @page.update_attributes params[:page] - flash[:success] = t 'messages.updated_successfully' - redirect_to edit_dashboard_page_path( @page ) + redirect_to edit_dashboard_page_path( @page ), flash: { success: t('messages.updated_successfully') } else render :edit end @@ -38,7 +36,7 @@ def destroy end private - def set_page - @page ||= Page.find params[:id] + def find_page + @page = Page.find params[:id] end end diff --git a/app/controllers/dashboard/sections_controller.rb b/app/controllers/dashboard/sections_controller.rb index 7504c5f..506d4f9 100644 --- a/app/controllers/dashboard/sections_controller.rb +++ b/app/controllers/dashboard/sections_controller.rb @@ -1,5 +1,5 @@ class Dashboard::SectionsController < ApplicationController - before_filter :set_section, only: [ :edit, :update, :destroy ] + before_filter :find_section, only: [ :edit, :update, :destroy ] set_tab :list_sections, only: :index set_tab :new_section, only: :new @@ -24,8 +24,7 @@ def create @section = Section.new params[:section] if @section.save - flash[:success] = t 'messages.created_successfully' - redirect_to dashboard_sections_path + redirect_to dashboard_sections_path, flash: { success: t('messages.created_successfully') } else render :new end @@ -34,8 +33,7 @@ def create # PUT /sections/1 def update if @section.update_attributes params[:section] - flash[:success] = t 'messages.updated_successfully' - redirect_to dashboard_sections_path + redirect_to dashboard_sections_path, flash: { success: t('messages.updated_successfully') } else render :edit end @@ -48,7 +46,7 @@ def destroy end private - def set_section - @section ||= Section.find params[:id] + def find_section + @section = Section.find params[:id] end end diff --git a/app/controllers/dashboard/settings_controller.rb b/app/controllers/dashboard/settings_controller.rb index 838b51c..9bc9020 100644 --- a/app/controllers/dashboard/settings_controller.rb +++ b/app/controllers/dashboard/settings_controller.rb @@ -1,5 +1,5 @@ class Dashboard::SettingsController < ApplicationController - before_filter :set_setting, only: [ :edit, :update, :destroy ] + before_filter :find_setting, only: [ :edit, :update, :destroy ] set_tab :list_settings, only: :index set_tab :new_setting, only: :new @@ -12,52 +12,35 @@ def new @setting = Setting.new end - def edit - @themes = get_themes if @setting.name == 'theme' - end - def create @setting = Setting.new params[:setting] if @setting.save - flash[:success] = t 'messages.created_successfully' - redirect_to dashboard_settings_path + redirect_to dashboard_settings_path, flash: { success: t('messages.created_successfully') } else render :new end end def update - params[:setting] = params[:setting].except(:name) if !@setting.destroyable? - if @setting.update_attributes params[:setting] - flash[:success] = t 'messages.updated_successfully' - redirect_to dashboard_settings_path + redirect_to dashboard_settings_path, flash: { success: t('messages.updated_successfully') } else render :edit end end def destroy - if @setting.delete - flash[:success] = t 'messages.deleted_successfully' - redirect_to dashboard_settings_path + if @setting.destroyable? and @setting.destroy + redirect_to dashboard_settings_path, flash: { success: t('messages.deleted_successfully') } else - flash[:error] = t 'messages.failed_miserably' - redirect_to dashboard_settings_path + redirect_to dashboard_settings_path, flash: { error: t('messages.failed_miserably') } end end private - def get_themes - themes_path = File.join Rails.root, 'app', 'views', 'layouts', 'themes' - - Dir.new(themes_path).select do |dir| - dir =~ /^[a-z0-9_-]+$/i && File.directory?( File.join themes_path, dir ) - end - end - - def set_setting - @setting ||= Setting.find params[:id] + def find_setting + @setting = Setting.find params[:id] + @themes = $themes end end diff --git a/app/controllers/dashboard/users_controller.rb b/app/controllers/dashboard/users_controller.rb index 016d790..4196a39 100644 --- a/app/controllers/dashboard/users_controller.rb +++ b/app/controllers/dashboard/users_controller.rb @@ -8,9 +8,7 @@ def index def destroy @user = User.find params[:id] - if @user.delete - flash[:success] = t('messages.deleted_successfully') - redirect_to action: :index - end + @user.destroy + redirect_to dashboard_users_path end end diff --git a/app/models/setting.rb b/app/models/setting.rb index e2d022d..370b91c 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -2,13 +2,12 @@ class Setting < ActiveRecord::Base validates :name, :value, presence: true validates :name, uniqueness: true - validates_format_of :name, with: /^[a-z0-9_]+$/ + validates_format_of :name, with: /\A[a-z0-9_]+\z/i attr_accessible :name, :value, :description, :destroyable - def delete - return super if destroyable? - false + def name=(value) + self[:name] = value if destroyable? end def self.get_site_settings diff --git a/config/application.rb b/config/application.rb index e2f8ead..a681569 100644 --- a/config/application.rb +++ b/config/application.rb @@ -67,6 +67,8 @@ class Application < Rails::Application hard_wrap: true, with_toc_data: true, } + + $themes = Dir[ Rails.root.join('app', 'views', 'layouts', 'themes', '**' ) ].map { |dir| File.basename dir } end end diff --git a/spec/controllers/dashboard/sections_controller_spec.rb b/spec/controllers/dashboard/sections_controller_spec.rb index 3c4285a..2d7a317 100644 --- a/spec/controllers/dashboard/sections_controller_spec.rb +++ b/spec/controllers/dashboard/sections_controller_spec.rb @@ -84,25 +84,30 @@ end describe "PUT update" do - before :each do - put :update, id: section, section: { name: 'batman' } - end + before { section.should be_persisted } - it "should assign @section" do - assigns( :section ).should be_kind_of( Section ) - end + context :update_successful do + before { put :update, id: section, section: { name: 'batman' } } - it "should update @section" do - assigns( :section ).should eql( section ) - end + it "should assign @section" do + assigns( :section ).should be_kind_of( Section ) + end - it "should redirect to index" do - response.should redirect_to( dashboard_sections_path ) + it "should update @section" do + assigns( :section ).should eql( section ) + end + + it "should redirect to index" do + response.should redirect_to( dashboard_sections_path ) + end end - it "should render edit should something go wrong" do - put :update, id: section, section: { name: nil } - response.should render_template( :edit ) + + context :update_fails do + it "should render edit should something go wrong" do + put :update, id: section, section: { name: '' } + response.should render_template( :edit ) + end end end diff --git a/spec/models/setting_spec.rb b/spec/models/setting_spec.rb index e0a9832..3ad87ce 100644 --- a/spec/models/setting_spec.rb +++ b/spec/models/setting_spec.rb @@ -28,8 +28,4 @@ setting.should be_invalid end end - - it "should not delete non destroyable settings" do - theme.delete.should be_false - end end From fbad092bb9420ba2f662d40bc212ed6182adae94 Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Fri, 20 Sep 2013 01:15:46 -0700 Subject: [PATCH 29/32] Fix spanish translation pluralization --- app/views/dashboard/pages/_form.html.haml | 2 +- app/views/dashboard/pages/index.haml | 4 ++-- app/views/dashboard/sections/_form.html.haml | 2 +- app/views/dashboard/sections/edit.haml | 2 +- app/views/dashboard/sections/index.haml | 2 +- app/views/dashboard/sections/new.haml | 2 +- app/views/dashboard/settings/edit.html.haml | 2 +- app/views/dashboard/settings/index.html.haml | 2 +- app/views/dashboard/settings/new.html.haml | 2 +- app/views/dashboard/users/index.html.haml | 2 +- app/views/devise/registrations/edit.html.haml | 2 +- app/views/layouts/dashboard.html.haml | 2 +- .../layouts/dashboard/_navigation.html.haml | 8 ++++---- .../layouts/dashboard/nav/_pages.html.haml | 4 ++-- .../layouts/dashboard/nav/_sections.html.haml | 4 ++-- .../layouts/dashboard/nav/_settings.html.haml | 4 ++-- .../layouts/dashboard/nav/_users.html.haml | 3 ++- config/locales/en.yml | 1 + config/locales/es.yml | 19 +++++++++++++------ 19 files changed, 39 insertions(+), 30 deletions(-) diff --git a/app/views/dashboard/pages/_form.html.haml b/app/views/dashboard/pages/_form.html.haml index 49229b7..22ec225 100644 --- a/app/views/dashboard/pages/_form.html.haml +++ b/app/views/dashboard/pages/_form.html.haml @@ -1,6 +1,6 @@ = simple_form_for [ :dashboard, page ] do |f| #page_content - = f.input :name, placeholder: t('common.descriptions.url.item_name', item: Page.model_name.downcase ) + = f.input :name, placeholder: t('common.descriptions.url.item_name', item: Page.model_name.human.downcase ) = f.pagedown_editor :content diff --git a/app/views/dashboard/pages/index.haml b/app/views/dashboard/pages/index.haml index d89a54d..9130674 100644 --- a/app/views/dashboard/pages/index.haml +++ b/app/views/dashboard/pages/index.haml @@ -1,4 +1,4 @@ -%h2= t 'common.headers.item_list', item: Page.model_name.pluralize +%h2= t 'common.headers.item_list', item: Page.model_name.human( count: 0 ) %p.info %span.bold= t('messages.information') + ':' @@ -8,7 +8,7 @@ %thead %tr %th= t 'common.fields.name' - %th= Section.model_name + %th= Section.model_name.human %th= t 'common.fields.created_at' %th= t 'common.fields.updated_at' %th= t 'common.messages.options' diff --git a/app/views/dashboard/sections/_form.html.haml b/app/views/dashboard/sections/_form.html.haml index 882f84b..6111c4f 100644 --- a/app/views/dashboard/sections/_form.html.haml +++ b/app/views/dashboard/sections/_form.html.haml @@ -2,7 +2,7 @@ .columns .half %label{ for: :section_name } - = t 'activerecord.models.section' + = Section.model_name.human %small= t 'dashboard.sections.descriptions.name' = f.text_field :name diff --git a/app/views/dashboard/sections/edit.haml b/app/views/dashboard/sections/edit.haml index 55ebb65..4885ab2 100644 --- a/app/views/dashboard/sections/edit.haml +++ b/app/views/dashboard/sections/edit.haml @@ -1,2 +1,2 @@ -%h2= t 'links.edit_item', item: Section.model_name +%h2= t 'links.edit_item', item: Section.model_name.human = render 'form', section: @section diff --git a/app/views/dashboard/sections/index.haml b/app/views/dashboard/sections/index.haml index 0cb1280..0df8abd 100644 --- a/app/views/dashboard/sections/index.haml +++ b/app/views/dashboard/sections/index.haml @@ -1,4 +1,4 @@ -%h2= t 'common.headers.item_list', item: t('activerecord.models.section') +%h2= t 'common.headers.item_list', item: Section.model_name.human( count: 0 ) %p.info %span.bold= t('messages.information') + ':' = t '.information' diff --git a/app/views/dashboard/sections/new.haml b/app/views/dashboard/sections/new.haml index 4ad8808..45ad999 100644 --- a/app/views/dashboard/sections/new.haml +++ b/app/views/dashboard/sections/new.haml @@ -1,2 +1,2 @@ -%h2= t 'links.new_item', item: Section.model_name +%h2= t 'links.new_item', item: Section.model_name.human = render 'form', section: @section diff --git a/app/views/dashboard/settings/edit.html.haml b/app/views/dashboard/settings/edit.html.haml index 070bb41..377625f 100644 --- a/app/views/dashboard/settings/edit.html.haml +++ b/app/views/dashboard/settings/edit.html.haml @@ -1,2 +1,2 @@ -%h2= t 'links.edit_item', item: Setting.model_name +%h2= t 'links.edit_item', item: Setting.model_name.human = render 'form', setting: @setting, themes: @themes diff --git a/app/views/dashboard/settings/index.html.haml b/app/views/dashboard/settings/index.html.haml index b5336a2..4779c9c 100644 --- a/app/views/dashboard/settings/index.html.haml +++ b/app/views/dashboard/settings/index.html.haml @@ -1,4 +1,4 @@ -%h2= t 'common.headers.item_list', item: Setting.model_name +%h2= t 'common.headers.item_list', item: Setting.model_name.human %p.info %span.bold= t('messages.information') + ':' diff --git a/app/views/dashboard/settings/new.html.haml b/app/views/dashboard/settings/new.html.haml index 59fba95..a5a1f62 100644 --- a/app/views/dashboard/settings/new.html.haml +++ b/app/views/dashboard/settings/new.html.haml @@ -1,2 +1,2 @@ -%h2= t 'links.new_item', item: Setting.model_name +%h2= t 'links.new_item', item: Setting.model_name.human = render 'form', setting: @setting, themes: @themes diff --git a/app/views/dashboard/users/index.html.haml b/app/views/dashboard/users/index.html.haml index 395a486..ea2ec3e 100644 --- a/app/views/dashboard/users/index.html.haml +++ b/app/views/dashboard/users/index.html.haml @@ -1,4 +1,4 @@ -%h2= t 'common.headers.item_list', item: User.model_name +%h2= t 'common.headers.item_list', item: User.model_name.human %p.info %span.bold= t('messages.information') + ':' = t '.tip' diff --git a/app/views/devise/registrations/edit.html.haml b/app/views/devise/registrations/edit.html.haml index 5edf256..72e3d71 100644 --- a/app/views/devise/registrations/edit.html.haml +++ b/app/views/devise/registrations/edit.html.haml @@ -1,4 +1,4 @@ -%h2= t 'links.edit_item', item: t('activerecord.models.user') +%h2= t 'links.edit_item', item: User.model_name.human = form_for resource, as: resource_name, url: registration_path(resource_name), html: { method: :put } do |f| .columns .half diff --git a/app/views/layouts/dashboard.html.haml b/app/views/layouts/dashboard.html.haml index 43bdcdc..f491cdd 100644 --- a/app/views/layouts/dashboard.html.haml +++ b/app/views/layouts/dashboard.html.haml @@ -19,7 +19,7 @@ #content = render partial: 'layouts/dashboard/flashes' .module - %h2.title= content_for?(:module_title) ? yield(:module_title) : t( "activerecord.models.#{ selected_tab.singularize }" ) + %h2.title= content_for?(:module_title) ? yield(:module_title) : selected_tab.singularize.classify.constantize.model_name.human .module_body= yield #footer_wrap #footer= content_for?(:footer) ? yield(:footer) : 'CloverInteractive' diff --git a/app/views/layouts/dashboard/_navigation.html.haml b/app/views/layouts/dashboard/_navigation.html.haml index 04da9c8..cf01c05 100644 --- a/app/views/layouts/dashboard/_navigation.html.haml +++ b/app/views/layouts/dashboard/_navigation.html.haml @@ -1,8 +1,8 @@ - content_for :nav_wrap do %ul#nav - %li#sections_menu_link= link_to Section.model_name.pluralize, dashboard_sections_path - %li#pages_menu_link= link_to Page.model_name.pluralize, dashboard_pages_path - %li#settings_menu_link= link_to Setting.model_name.pluralize, dashboard_settings_path - %li#users_menu_link= link_to User.model_name.pluralize, dashboard_users_path + %li#sections_menu_link= link_to Section.model_name.human(count: 0), dashboard_sections_path + %li#pages_menu_link= link_to Page.model_name.human(count: 0), dashboard_pages_path + %li#settings_menu_link= link_to Setting.model_name.human(count: 0), dashboard_settings_path + %li#users_menu_link= link_to User.model_name.human(count: 0), dashboard_users_path = yield :nav = content_for?( :sub_nav ) ? yield( :sub_nav ) : render( "layouts/dashboard/nav/#{controller_name}" ) diff --git a/app/views/layouts/dashboard/nav/_pages.html.haml b/app/views/layouts/dashboard/nav/_pages.html.haml index 84c6f5c..c7a3a19 100644 --- a/app/views/layouts/dashboard/nav/_pages.html.haml +++ b/app/views/layouts/dashboard/nav/_pages.html.haml @@ -1,3 +1,3 @@ = tabs_tag open_tabs: { id: "sub_menu", class: "sub_nav" } do |tab| - = tab.list_pages t('links.item_list', item: t('activerecord.models.page')), dashboard_pages_path - = tab.new_page t('links.new_item', item: t('activerecord.models.page')), new_dashboard_page_path + = tab.list_pages t('links.item_list', item: Page.model_name.human(count: 0)), dashboard_pages_path + = tab.new_page t('links.new_item', item: Page.model_name.human), new_dashboard_page_path diff --git a/app/views/layouts/dashboard/nav/_sections.html.haml b/app/views/layouts/dashboard/nav/_sections.html.haml index 59014d4..3133996 100644 --- a/app/views/layouts/dashboard/nav/_sections.html.haml +++ b/app/views/layouts/dashboard/nav/_sections.html.haml @@ -1,3 +1,3 @@ = tabs_tag open_tabs: { id: "sub_menu", class: "sub_nav" } do |tab| - = tab.list_sections t('links.item_list', item: t('activerecord.models.section')), dashboard_sections_path - = tab.new_section t('links.new_item', item: t('activerecord.models.section')), new_dashboard_section_path + = tab.list_sections t('links.item_list', item: Section.model_name.human( count: 0 )), dashboard_sections_path + = tab.new_section t('links.new_item', item: Section.model_name.human), new_dashboard_section_path diff --git a/app/views/layouts/dashboard/nav/_settings.html.haml b/app/views/layouts/dashboard/nav/_settings.html.haml index 5eb92b2..a42c227 100644 --- a/app/views/layouts/dashboard/nav/_settings.html.haml +++ b/app/views/layouts/dashboard/nav/_settings.html.haml @@ -1,3 +1,3 @@ = tabs_tag open_tabs: { id: "sub_menu", class: "sub_nav" } do |tab| - = tab.list_settings t('links.item_list', item: t('activerecord.models.setting')), dashboard_settings_path - = tab.new_setting t('links.new_item', item: t('activerecord.models.setting')), new_dashboard_setting_path + = tab.list_settings t('links.item_list', item: Setting.model_name.human( count: 0 )), dashboard_settings_path + = tab.new_setting t('links.new_item', item: Setting.model_name.human), new_dashboard_setting_path diff --git a/app/views/layouts/dashboard/nav/_users.html.haml b/app/views/layouts/dashboard/nav/_users.html.haml index fa95477..ec0c815 100644 --- a/app/views/layouts/dashboard/nav/_users.html.haml +++ b/app/views/layouts/dashboard/nav/_users.html.haml @@ -1,2 +1,3 @@ = tabs_tag open_tabs: { id: "sub_menu", class: "sub_nav" } do |tab| - = tab.list_users t('links.item_list', item: t('activerecord.models.user')), dashboard_users_path + = tab.list_users t('links.item_list', item: User.model_name.human(count: 0)), dashboard_users_path + = tab.edit_user t('links.item_edit', item: User.model_name.human), edit_user_registration_path diff --git a/config/locales/en.yml b/config/locales/en.yml index 96f6a58..4433436 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -77,6 +77,7 @@ en: item_details: '%{item} details' item_keywords: '%{item} keywords' item_assets: '%{item} Assets' + item_edit: '%{item} Edit' add_item: 'Add %{item}' logout: 'logout' diff --git a/config/locales/es.yml b/config/locales/es.yml index dccb078..95ad464 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -77,6 +77,7 @@ es: item_details: 'Detalles de %{item}' item_keywords: 'Palabras clave de %{item}' item_assets: 'Recursos de %{item}' + item_edit: 'Editar %{item}' add_item: 'Agregar %{item}' logout: 'salir' @@ -120,12 +121,18 @@ es: activerecord: models: - section: 'Sección' - page: 'Pagina' - article: 'Articulo' - user: 'Usuario' - role: 'Rol' - setting: 'Configuración' + section: + one: 'Sección' + other: 'Secciones' + page: + one: 'Página' + other: 'Páginas' + user: + one: 'Usuario' + other: 'Usuarios' + setting: + one: 'Configuración' + other: 'Configuraciones' attributes: section: name: 'Nombre' From 1874a52a3f6e34b99ab5c7c109fdbb3de9c56daa Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Fri, 20 Sep 2013 13:34:58 -0700 Subject: [PATCH 30/32] Refactor section helpers --- app/helpers/application_helper.rb | 7 ------- app/models/section.rb | 21 ++++++++++++++++++-- app/views/dashboard/pages/_form.html.haml | 2 +- app/views/dashboard/sections/_form.html.haml | 2 +- spec/models/section_spec.rb | 19 ++++++++++++++++++ 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 828932a..de6be79 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,9 +1,2 @@ module ApplicationHelper - def main_sections_collection section_name - Section.where("name != '#{section_name}'").map { |section| [ section.name, section.id ] } - end - - def all_sections_collection - Section.all.map { |section| [ section.name, section.id ] } - end end diff --git a/app/models/section.rb b/app/models/section.rb index 4474715..2f6a3dc 100644 --- a/app/models/section.rb +++ b/app/models/section.rb @@ -1,8 +1,9 @@ class Section < ActiveRecord::Base extend FriendlyId - has_many :pages - has_many :subsections, class_name: "Section", foreign_key: :main_section_id + has_many :pages, dependent: :destroy + + has_many :subsections, class_name: "Section", foreign_key: :main_section_id, dependent: :destroy belongs_to :main_section, class_name: "Section", foreign_key: :main_section_id validates :name, presence: true, uniqueness: true @@ -12,4 +13,20 @@ class Section < ActiveRecord::Base attr_accessible :name, :main_section_id delegate :name, to: :main_section, prefix: true, allow_nil: true + + def section_collection + return scoped_collection unless new_record? + + Section.section_collection + end + + def self.section_collection + Section.select( 'name, id' ).all.map { |section| [ section.name, section.id ] } + end + + private + def scoped_collection + Section.select( 'name, id' ).where( "id != ?", id ).where( main_section_id: nil ). + map { |section| [ section.name, section.id ] } + end end diff --git a/app/views/dashboard/pages/_form.html.haml b/app/views/dashboard/pages/_form.html.haml index 22ec225..88a5b1f 100644 --- a/app/views/dashboard/pages/_form.html.haml +++ b/app/views/dashboard/pages/_form.html.haml @@ -8,7 +8,7 @@ = t 'activerecord.attributes.page.section' %small= t 'dashboard.page.descriptions.section' - = f.select :section_id, all_sections_collection + = f.select :section_id, Section.section_collection .buttonset = f.input :home_page, input_html: { class: :home_page } diff --git a/app/views/dashboard/sections/_form.html.haml b/app/views/dashboard/sections/_form.html.haml index 6111c4f..5c69c06 100644 --- a/app/views/dashboard/sections/_form.html.haml +++ b/app/views/dashboard/sections/_form.html.haml @@ -9,7 +9,7 @@ %label{ for: :main_section_id } = t 'activerecord.attributes.section.main_section' %small= t 'dashboard.sections.descriptions.main_section' - = f.select :main_section_id, main_sections_collection( section.name ), include_blank: true + = f.select :main_section_id, section.section_collection, include_blank: true %button#submit= t 'common.forms.submit' diff --git a/spec/models/section_spec.rb b/spec/models/section_spec.rb index 8b31256..4d94fb5 100644 --- a/spec/models/section_spec.rb +++ b/spec/models/section_spec.rb @@ -20,4 +20,23 @@ it "should have an slug after created" do section.slug.should be_present end + + describe :section_collection do + before { section.should be_persisted } + + context :new_record do + it 'should show fetch all sections' do + new_section = build :section + new_section.section_collection.should include( [ section.name, section.id ] ) + new_section.section_collection.should eql( Section.section_collection ) + end + end + + context :exting_record do + it 'should not fetch self' do + section.section_collection.should_not include( [ section.name, section.id ] ) + section.section_collection.should eql( [] ) + end + end + end end From 1fe179dc1dc51f6bec57a302de65ccbcc9f0d5bc Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Fri, 20 Sep 2013 17:18:21 -0700 Subject: [PATCH 31/32] Improve subsection support --- app/controllers/pages_controller.rb | 7 +-- app/models/section.rb | 17 +++++++ spec/models/section_spec.rb | 77 ++++++++++++++++++++++++++++- 3 files changed, 97 insertions(+), 4 deletions(-) diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb index a8969f1..7a4a722 100644 --- a/app/controllers/pages_controller.rb +++ b/app/controllers/pages_controller.rb @@ -1,12 +1,11 @@ class PagesController < ApplicationController skip_before_filter :authenticate_user! - after_filter :raise_if_page_not_found! # GET /:section/:page # GET /:section/:subsection/:page def show - @section = Section.find params[:section] - @page = @section.pages.published.find( params[:page] ) if @section + @section, @subsection, @page = *Section.with_children( params ) + raise_if_page_not_found! end #GET / @@ -14,6 +13,8 @@ def home @page = Page.published.home_page @section = @page.section + raise_if_page_not_found! + render :show end diff --git a/app/models/section.rb b/app/models/section.rb index 2f6a3dc..49881ef 100644 --- a/app/models/section.rb +++ b/app/models/section.rb @@ -24,6 +24,23 @@ def self.section_collection Section.select( 'name, id' ).all.map { |section| [ section.name, section.id ] } end + def self.with_children( params ) + section = includes( :pages ).find_by_slug params[:section] + subsection = fetch_subsection( section, params[:subsection] ) if section and params[:subsection] + page = fetch_page ( subsection || section ), params[:page] + + [ section, subsection, page ] + end + + def self.fetch_subsection( section, slug ) + section.subsections.find_by_slug slug + end + + def self.fetch_page( section, slug ) + return if section.nil? + section.pages.published.find_by_slug slug + end + private def scoped_collection Section.select( 'name, id' ).where( "id != ?", id ).where( main_section_id: nil ). diff --git a/spec/models/section_spec.rb b/spec/models/section_spec.rb index 4d94fb5..8889668 100644 --- a/spec/models/section_spec.rb +++ b/spec/models/section_spec.rb @@ -1,7 +1,9 @@ require 'spec_helper' describe Section do - let( :section ) { create :section, name: 'test' } + let( :section ) { create :section, name: 'test' } + let( :subsection ) { create :section, main_section: section } + describe "name" do it "should be present" do @@ -39,4 +41,77 @@ end end end + + describe :with_children do + context :section_page do + let( :section_page ) { create :page, section: section } + + before( :each ) do + section.should be_persisted + section_page.should be_persisted + end + + it 'should fetch section and page' do + new_section, new_subsection, page = *Section.with_children( section: section.slug, page: section_page.slug ) + + new_section.should be_present + new_section.should be_kind_of( Section ) + + new_subsection.should be_blank + + page.should be_present + page.should be_kind_of( Page ) + end + + it 'should only fetch section if page name is wrong' do + new_section, new_subsection, page = *Section.with_children( section: section.slug, page: "#{ section_page.slug }-wrong" ) + + new_section.should be_present + new_subsection.should be_blank + page.should be_blank + end + + it 'should not fetch anything if section name is wrong' do + new_section, new_subsection, page = *Section.with_children( section: "#{ section.slug }-wrong", page: section_page.slug ) + + new_section.should be_blank + new_subsection.should be_blank + page.should be_blank + end + end + + context :subsection_page do + let( :section_page ) { create :page, section: subsection } + + before( :each ) do + section.should be_persisted + subsection.should be_persisted + section_page.should be_persisted + end + + it 'it should fetch section, subsection and page' do + new_section, new_subsection, page = *Section.with_children( section: section.slug, subsection: subsection.slug, page: section_page.slug ) + + new_section.should be_present + new_subsection.should be_present + page.should be_present + end + + it 'should not fetch anything if section name is wrong' do + new_section, new_subsection, page = *Section.with_children( section: "#{ section.slug }-wrong", subsection: subsection.slug, page: section_page.slug ) + + new_section.should be_blank + new_subsection.should be_blank + page.should be_blank + end + + it 'should not fetch page if subsection name is wrong' do + new_section, new_subsection, page = *Section.with_children( section: section.slug, subsection: "#{ subsection.slug }-wrong", page: section_page.slug ) + + new_section.should be_present + new_subsection.should be_blank + page.should be_blank + end + end + end end From 4838220b8bcce3b28044ace9a138f80d81b2e6e6 Mon Sep 17 00:00:00 2001 From: Enrique Vidal Date: Fri, 4 Oct 2013 19:42:45 -0700 Subject: [PATCH 32/32] Update bootstrap_pagedown to include pagedown-extra --- Gemfile.lock | 4 ++-- app/assets/javascripts/global.js | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 0479736..df6d422 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -41,7 +41,7 @@ GEM sass (~> 3.2) bootstrap-will_paginate (0.0.9) will_paginate - bootstrap_pagedown (1.0.2) + bootstrap_pagedown (1.1.0) rails (>= 3.2) builder (3.0.4) bullet (4.1.5) @@ -140,7 +140,7 @@ GEM actionmailer (~> 3.0) method_source (0.8) mime-types (1.25) - multi_json (1.8.0) + multi_json (1.8.1) net-scp (1.0.4) net-ssh (>= 1.99.1) net-sftp (2.0.5) diff --git a/app/assets/javascripts/global.js b/app/assets/javascripts/global.js index 0d2a0b4..72e49b5 100644 --- a/app/assets/javascripts/global.js +++ b/app/assets/javascripts/global.js @@ -1,5 +1,13 @@ $(function() { $.fn.loopedSlider.defaults.addPagination = true; $('#slider').loopedSlider({ autoStart: 5000, containerClick: false }); + + if ( $("#wmd-input").length > 0 ) { + var converter = Markdown.getSanitizingConverter(); + var editor = new Markdown.Editor( converter ); + + Markdown.Extra.init( converter ); + editor.run(); + } });
    '+fileName+" ("+l+m+')