simple_form_markdown_editor 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +126 -0
  5. data/README.md +111 -0
  6. data/Rakefile +1 -0
  7. data/app/controllers/simple_form_markdown_editor/previews_controller.rb +21 -0
  8. data/config/routes.rb +7 -0
  9. data/lib/assets/javascripts/simple_form_markdown_editor/simple_form_markdown_editor_buttons.js.coffee +135 -0
  10. data/lib/assets/javascripts/simple_form_markdown_editor/simple_form_markdown_editor_help.js.coffee +100 -0
  11. data/lib/assets/javascripts/simple_form_markdown_editor/simple_form_markdown_editor_tabs.js.coffee +84 -0
  12. data/lib/assets/javascripts/simple_form_markdown_editor.js +3 -0
  13. data/lib/assets/stylesheets/simple_form_markdown_editor/simple_form_markdown_editor.css.scss +275 -0
  14. data/lib/assets/stylesheets/simple_form_markdown_editor.css +3 -0
  15. data/lib/config/locales/simple_form_markdown_editor.en.yml +96 -0
  16. data/lib/simple_form_markdown_editor/configuration.rb +26 -0
  17. data/lib/simple_form_markdown_editor/engine.rb +4 -0
  18. data/lib/simple_form_markdown_editor/renderer.rb +50 -0
  19. data/lib/simple_form_markdown_editor/simple_form_markdown_editor.rb +183 -0
  20. data/lib/simple_form_markdown_editor/version.rb +3 -0
  21. data/lib/simple_form_markdown_editor.rb +21 -0
  22. data/simple_form_markdown_editor.gemspec +30 -0
  23. data/test/dummy/.gitignore +13 -0
  24. data/test/dummy/Gemfile +25 -0
  25. data/test/dummy/Gemfile.lock +195 -0
  26. data/test/dummy/README.rdoc +28 -0
  27. data/test/dummy/Rakefile +6 -0
  28. data/test/dummy/app/assets/images/.keep +0 -0
  29. data/test/dummy/app/assets/javascripts/application.js +4 -0
  30. data/test/dummy/app/assets/javascripts/editor_tests.coffee +3 -0
  31. data/test/dummy/app/assets/stylesheets/application.css +5 -0
  32. data/test/dummy/app/assets/stylesheets/editor_tests.scss +32 -0
  33. data/test/dummy/app/controllers/application_controller.rb +5 -0
  34. data/test/dummy/app/controllers/concerns/.keep +0 -0
  35. data/test/dummy/app/controllers/editor_tests_controller.rb +5 -0
  36. data/test/dummy/app/helpers/application_helper.rb +2 -0
  37. data/test/dummy/app/helpers/editor_tests_helper.rb +2 -0
  38. data/test/dummy/app/mailers/.keep +0 -0
  39. data/test/dummy/app/models/.keep +0 -0
  40. data/test/dummy/app/models/concerns/.keep +0 -0
  41. data/test/dummy/app/models/editor_test.rb +4 -0
  42. data/test/dummy/app/views/editor_tests/new.html.slim +2 -0
  43. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  44. data/test/dummy/bin/bundle +3 -0
  45. data/test/dummy/bin/rails +8 -0
  46. data/test/dummy/bin/rake +8 -0
  47. data/test/dummy/bin/setup +29 -0
  48. data/test/dummy/bin/spring +15 -0
  49. data/test/dummy/config/application.rb +31 -0
  50. data/test/dummy/config/boot.rb +3 -0
  51. data/test/dummy/config/environment.rb +5 -0
  52. data/test/dummy/config/environments/development.rb +38 -0
  53. data/test/dummy/config/environments/production.rb +76 -0
  54. data/test/dummy/config/environments/test.rb +42 -0
  55. data/test/dummy/config/initializers/assets.rb +11 -0
  56. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  57. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  58. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  59. data/test/dummy/config/initializers/inflections.rb +16 -0
  60. data/test/dummy/config/initializers/mime_types.rb +4 -0
  61. data/test/dummy/config/initializers/session_store.rb +3 -0
  62. data/test/dummy/config/initializers/simple_form_markdown_editor.rb +5 -0
  63. data/test/dummy/config/initializers/wrap_parameters.rb +9 -0
  64. data/test/dummy/config/locales/en.yml +23 -0
  65. data/test/dummy/config/routes.rb +5 -0
  66. data/test/dummy/config/secrets.yml +22 -0
  67. data/test/dummy/config.ru +4 -0
  68. data/test/dummy/db/seeds.rb +7 -0
  69. data/test/dummy/lib/assets/.keep +0 -0
  70. data/test/dummy/lib/tasks/.keep +0 -0
  71. data/test/dummy/log/.keep +0 -0
  72. data/test/dummy/public/404.html +67 -0
  73. data/test/dummy/public/422.html +67 -0
  74. data/test/dummy/public/500.html +66 -0
  75. data/test/dummy/public/favicon.ico +0 -0
  76. data/test/dummy/public/robots.txt +5 -0
  77. data/test/dummy/test/controllers/.keep +0 -0
  78. data/test/dummy/test/controllers/editor_tests_controller_test.rb +7 -0
  79. data/test/dummy/test/fixtures/.keep +0 -0
  80. data/test/dummy/test/fixtures/editor_tests.yml +7 -0
  81. data/test/dummy/test/helpers/.keep +0 -0
  82. data/test/dummy/test/integration/.keep +0 -0
  83. data/test/dummy/test/mailers/.keep +0 -0
  84. data/test/dummy/test/models/.keep +0 -0
  85. data/test/dummy/test/models/editor_test_test.rb +7 -0
  86. data/test/dummy/test/test_helper.rb +7 -0
  87. data/test/dummy/vendor/assets/javascripts/.keep +0 -0
  88. data/test/dummy/vendor/assets/stylesheets/.keep +0 -0
  89. metadata +297 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c5c6a73ac5c7888296fde17f9ae33f400503c003
4
+ data.tar.gz: 9e5e6861ebc55abb6f60d3d4557fe8b5b4259b63
5
+ SHA512:
6
+ metadata.gz: c0cba84a45c4023bc1e08287e1edabe4da75fd5c000d7c8793c0a89d7455ae9f2377bd9a51c844558f4bf877fbb6067e4838790424a99ef5c28884996a831c27
7
+ data.tar.gz: b237ae007a6f238bd28453532a2cf2544629fab7472e718b26e895248a1f440ccf0a808249d305f9dc712bb981f8e823b8f8105b0bc10948a69134bcb1d11796
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ test/dummy/Gemfile.lock
2
+ pkg
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in simple_form_localized_input.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,126 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ simple_form_markdown_editor (0.0.1)
5
+ autoprefixer-rails
6
+ rails (>= 4.2)
7
+ redcarpet
8
+ responders (~> 2.0)
9
+ simple_form (>= 3.0.2)
10
+
11
+ GEM
12
+ remote: https://rubygems.org/
13
+ specs:
14
+ actionmailer (4.2.0)
15
+ actionpack (= 4.2.0)
16
+ actionview (= 4.2.0)
17
+ activejob (= 4.2.0)
18
+ mail (~> 2.5, >= 2.5.4)
19
+ rails-dom-testing (~> 1.0, >= 1.0.5)
20
+ actionpack (4.2.0)
21
+ actionview (= 4.2.0)
22
+ activesupport (= 4.2.0)
23
+ rack (~> 1.6.0)
24
+ rack-test (~> 0.6.2)
25
+ rails-dom-testing (~> 1.0, >= 1.0.5)
26
+ rails-html-sanitizer (~> 1.0, >= 1.0.1)
27
+ actionview (4.2.0)
28
+ activesupport (= 4.2.0)
29
+ builder (~> 3.1)
30
+ erubis (~> 2.7.0)
31
+ rails-dom-testing (~> 1.0, >= 1.0.5)
32
+ rails-html-sanitizer (~> 1.0, >= 1.0.1)
33
+ activejob (4.2.0)
34
+ activesupport (= 4.2.0)
35
+ globalid (>= 0.3.0)
36
+ activemodel (4.2.0)
37
+ activesupport (= 4.2.0)
38
+ builder (~> 3.1)
39
+ activerecord (4.2.0)
40
+ activemodel (= 4.2.0)
41
+ activesupport (= 4.2.0)
42
+ arel (~> 6.0)
43
+ activesupport (4.2.0)
44
+ i18n (~> 0.7)
45
+ json (~> 1.7, >= 1.7.7)
46
+ minitest (~> 5.1)
47
+ thread_safe (~> 0.3, >= 0.3.4)
48
+ tzinfo (~> 1.1)
49
+ arel (6.0.0)
50
+ autoprefixer-rails (5.1.7.1)
51
+ execjs
52
+ json
53
+ builder (3.2.2)
54
+ erubis (2.7.0)
55
+ execjs (2.4.0)
56
+ globalid (0.3.3)
57
+ activesupport (>= 4.1.0)
58
+ hike (1.2.3)
59
+ i18n (0.7.0)
60
+ json (1.8.2)
61
+ loofah (2.0.1)
62
+ nokogiri (>= 1.5.9)
63
+ mail (2.6.3)
64
+ mime-types (>= 1.16, < 3)
65
+ mime-types (2.4.3)
66
+ mini_portile (0.6.2)
67
+ minitest (5.5.1)
68
+ multi_json (1.11.0)
69
+ nokogiri (1.6.6.2)
70
+ mini_portile (~> 0.6.0)
71
+ rack (1.6.0)
72
+ rack-test (0.6.3)
73
+ rack (>= 1.0)
74
+ rails (4.2.0)
75
+ actionmailer (= 4.2.0)
76
+ actionpack (= 4.2.0)
77
+ actionview (= 4.2.0)
78
+ activejob (= 4.2.0)
79
+ activemodel (= 4.2.0)
80
+ activerecord (= 4.2.0)
81
+ activesupport (= 4.2.0)
82
+ bundler (>= 1.3.0, < 2.0)
83
+ railties (= 4.2.0)
84
+ sprockets-rails
85
+ rails-deprecated_sanitizer (1.0.3)
86
+ activesupport (>= 4.2.0.alpha)
87
+ rails-dom-testing (1.0.6)
88
+ activesupport (>= 4.2.0.beta, < 5.0)
89
+ nokogiri (~> 1.6.0)
90
+ rails-deprecated_sanitizer (>= 1.0.1)
91
+ rails-html-sanitizer (1.0.2)
92
+ loofah (~> 2.0)
93
+ railties (4.2.0)
94
+ actionpack (= 4.2.0)
95
+ activesupport (= 4.2.0)
96
+ rake (>= 0.8.7)
97
+ thor (>= 0.18.1, < 2.0)
98
+ rake (10.4.2)
99
+ redcarpet (3.2.2)
100
+ responders (2.1.0)
101
+ railties (>= 4.2.0, < 5)
102
+ simple_form (3.1.0)
103
+ actionpack (~> 4.0)
104
+ activemodel (~> 4.0)
105
+ sprockets (2.12.3)
106
+ hike (~> 1.2)
107
+ multi_json (~> 1.0)
108
+ rack (~> 1.0)
109
+ tilt (~> 1.1, != 1.3.0)
110
+ sprockets-rails (2.2.4)
111
+ actionpack (>= 3.0)
112
+ activesupport (>= 3.0)
113
+ sprockets (>= 2.8, < 4.0)
114
+ thor (0.19.1)
115
+ thread_safe (0.3.5)
116
+ tilt (1.4.1)
117
+ tzinfo (1.2.2)
118
+ thread_safe (~> 0.1)
119
+
120
+ PLATFORMS
121
+ ruby
122
+
123
+ DEPENDENCIES
124
+ bundler (~> 1.6)
125
+ rake
126
+ simple_form_markdown_editor!
data/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # SimpleForm Markdown Editor
2
+
3
+ A simple [Markdown](http://daringfireball.net/projects/markdown/) editor inspired by [gollum_editor](https://github.com/samknight/gollum_editor), the editor used for Github's wiki pages.
4
+
5
+ [Markdown](http://daringfireball.net/projects/markdown/) rendering is handled by [Redcarpet](https://github.com/vmg/redcarpet).
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'simple_form_markdown_editor'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install simple_form_markdown_editor
20
+
21
+ ## Usage
22
+
23
+ Require the javascripts in `application.js`:
24
+
25
+ //= require simple_form_markdown_editor
26
+
27
+ And require the stylesheets in `application.css`:
28
+
29
+ *= require simple_form_markdown_editor
30
+
31
+ Finally mount the engine in your routes:
32
+
33
+ mount SimpleFormMarkdownEditor::Engine => "/"
34
+
35
+ Use in forms:
36
+
37
+ = form.input :markdown, as: :markdown_editor
38
+
39
+ ## Configuration
40
+
41
+ Configuration is possible app-wide (using an initializer) and per input.
42
+
43
+ Refer to [redcarpet](https://github.com/vmg/redcarpet) for a list of available [extensions](https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use) and [render](https://github.com/vmg/redcarpet#darling-i-packed-you-a-couple-renderers-for-lunch) options.
44
+
45
+ ### Global
46
+
47
+ ```ruby
48
+ # config/initializers/simple_form_markdown_editor.rb
49
+
50
+ SimpleFormMarkdownEditor::MarkdownEditor.configure do |c|
51
+ c.buttons = [ %w(h1 h2 h3), %w(strong em), %w(a img) ]
52
+ c.help = { enabled: true, visible: false }
53
+ c.extensions = {
54
+ footnotes: true,
55
+ smartypants: true,
56
+ lax_spacing: true,
57
+ escape_html: false
58
+ }
59
+ c.render_options = {
60
+ :no_images,
61
+ :no_links
62
+ }
63
+ end
64
+ ```
65
+
66
+ ### Input
67
+
68
+ ```ruby
69
+ = f.input :markdown, as: :markdown_editor, help: { enabled: true, visible: false }, buttons: [ %w(h1 h2), %w(a img) ]
70
+ ```
71
+
72
+ ## Internationalization
73
+
74
+ All strings (buttons, help etc.) are defined in a `I18n` `YAML` file along with buttons and tabs. This can easily be overridden and extended to other languages:
75
+
76
+ ```YAML
77
+ # simple_form_markdown_editor.en.yml
78
+
79
+ en:
80
+ simple_form_markdown_editor:
81
+ tabs:
82
+ edit: Write
83
+ preview: Sneak peek
84
+ buttons:
85
+ h1: Header 1
86
+ h2: Header 2
87
+ h3: Header 3
88
+ a: Link
89
+ img: Image
90
+ help:
91
+ block_elements:
92
+ title: Blocks
93
+ elements:
94
+ headers:
95
+ title: # Headers
96
+ text: A very good explanation
97
+ ```
98
+
99
+
100
+ ## Testing
101
+
102
+ The gem includes a rails app for easy testing, simply `cd test/dummy`, `bundle install` and `bundle exec bin/rails s`, then direct your browser to `127.0.0.1:3000` to see the editor in action.
103
+
104
+ ## Todo
105
+
106
+ * How to make it possible to plug in other render engines?
107
+ * How to implement "custom Markdown" (basic gsub)?
108
+ * Highlighting trailing spaces (for linebreaks)?
109
+ * Implement keyboard shortcuts
110
+ * Implement Ctrl+z
111
+ * Implement install task (create YML and config)?
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,21 @@
1
+ require 'responders'
2
+
3
+ module SimpleFormMarkdownEditor
4
+ class PreviewsController < ActionController::Base
5
+
6
+ respond_to :html
7
+
8
+ def preview
9
+ respond_to do |format|
10
+ format.html { render text: SimpleFormMarkdownEditor::Renderer.call(preview_params) }
11
+ end
12
+ end
13
+
14
+ private # =============================================================
15
+
16
+ def preview_params
17
+ params.require(:text)
18
+ end
19
+
20
+ end
21
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,7 @@
1
+ # NOTE: Is this the best way to do it? Users will have to mount the engine. Alternative?
2
+
3
+ SimpleFormMarkdownEditor::Engine.routes.draw do
4
+ scope module: :simple_form_markdown_editor do
5
+ post "/preview" => "previews#preview", as: :preview
6
+ end
7
+ end
@@ -0,0 +1,135 @@
1
+ # https://github.com/jquery-boilerplate/jquery-boilerplate/
2
+ do ($ = jQuery, window, document) ->
3
+
4
+ pluginName = 'simple_form_markdown_editor_buttons'
5
+ defaults =
6
+ debug: false
7
+ definitions:
8
+ 'strong': '**%{str}**'
9
+ 'em': '*%{str}*'
10
+ 'code': '`%{str}`'
11
+ 'hr': '%{str}***'
12
+ 'ul': '* %{str}'
13
+ 'ol': '1. %{str}'
14
+ 'blockquote': '> %{str}'
15
+ 'h1': '# %{str}'
16
+ 'h2': '## %{str}'
17
+ 'h3': '### %{str}'
18
+ 'h4': '#### %{str}'
19
+ 'h5': '##### %{str}'
20
+ 'h6': '###### %{str}'
21
+ 'a': '[%{str}](|)'
22
+ 'img': '![%{str}](|)'
23
+
24
+ # ---------------------------------------------------------------------
25
+
26
+ class Plugin
27
+ constructor: (@element, options) ->
28
+ @settings = $.extend {}, defaults, options
29
+
30
+ @$element = $(@element)
31
+
32
+ @_defaults = defaults
33
+ @_name = pluginName
34
+
35
+ @init()
36
+
37
+ init: ->
38
+ console.log 'init' if @settings.debug
39
+
40
+ @get_help_button().addClass('active') if @help_is_visible()
41
+
42
+ @get_help_button().on 'click', (e) =>
43
+ $(e.currentTarget).toggleClass('active')
44
+ @toggle_help_visibility()
45
+
46
+ @get_command_buttons().on 'click', (e) =>
47
+ $btn = $(e.currentTarget)
48
+ cmd = $btn.attr('value')
49
+ @execute_command(cmd)
50
+
51
+ # ---------------------------------------------------------------------
52
+
53
+ get_textarea: -> @get_editor_div().children('textarea')
54
+ get_editor_div: -> @$element.children('div.editor')
55
+ get_header_div: -> @$element.children('div.header:first')
56
+ get_help_div: -> @$element.children('div.help')
57
+ get_button_groups_ul: -> @get_header_div().find('ul.button_groups')
58
+ get_button_group_lis: -> @get_button_groups_ul().children('li.button_group')
59
+ get_buttons_uls: -> @get_button_group_lis().children('ul.buttons')
60
+ get_button_lis: -> @get_buttons_uls().children('li.button')
61
+ get_buttons: -> @get_button_lis().children('button')
62
+ get_command_buttons: -> @get_buttons().not(@get_help_button())
63
+ get_help_button: -> @get_buttons().filter('.help')
64
+
65
+ help_is_visible: -> @get_help_div().attr('data-visible') == 'true'
66
+
67
+ execute_command: (cmd) ->
68
+ $textarea = @get_textarea()
69
+ selection = @get_selection($textarea)
70
+ definition = @settings.definitions[cmd]
71
+ replacement = definition.replace('%{str}', selection.text)
72
+ caret_pos = replacement.indexOf('|')
73
+ start = selection.start
74
+ end = selection.start + replacement.length
75
+ if caret_pos > -1
76
+ replacement = replacement.replace(/\|/g, '')
77
+ start = selection.start + caret_pos
78
+ end = selection.start + caret_pos
79
+ @replace_selection($textarea, replacement)
80
+ @set_selection($textarea, start, end)
81
+
82
+ get_selection: ($e) ->
83
+ {
84
+ start: $e[0].selectionStart
85
+ end: $e[0].selectionEnd
86
+ length: $e[0].selectionEnd - $e[0].selectionStart
87
+ text: $e.val().substring($e[0].selectionStart, $e[0].selectionEnd)
88
+ }
89
+
90
+ set_selection: ($e, start, end) ->
91
+ $e.focus()
92
+ $e[0].selectionStart = start
93
+ $e[0].selectionEnd = end
94
+
95
+ replace_selection: ($e, string) ->
96
+ start = $e[0].selectionStart
97
+ end = $e[0].selectionEnd
98
+ val = $e.val()
99
+ $e.val(val.substring(0, start) + string + val.substring(end, val.length))
100
+
101
+ toggle_help_visibility: ->
102
+ @get_help_div().attr('data-visible', String(!@help_is_visible()))
103
+
104
+ # ---------------------------------------------------------------------
105
+
106
+ # A really lightweight plugin wrapper around the constructor,
107
+ # preventing against multiple instantiations and allowing any
108
+ # public function (ie. a function whose name doesn't start
109
+ # with an underscore) to be called via the jQuery plugin,
110
+ # e.g. $(element).defaultPluginName('functionName', arg1, arg2)
111
+
112
+ $.fn[pluginName] = (options) ->
113
+ args = arguments
114
+ if options is `undefined` or typeof options is "object"
115
+ @each ->
116
+ $.data this, "plugin_" + pluginName, new Plugin(this, options) unless $.data(this, "plugin_" + pluginName)
117
+
118
+ else if typeof options is "string" and options[0] isnt "_" and options isnt "init"
119
+ returns = undefined
120
+ @each ->
121
+ instance = $.data(this, "plugin_" + pluginName)
122
+ returns = instance[options].apply(instance, Array::slice.call(args, 1)) if instance instanceof Plugin and typeof instance[options] is "function"
123
+ $.data this, "plugin_" + pluginName, null if options is "destroy"
124
+
125
+ (if returns isnt `undefined` then returns else this)
126
+
127
+ # =====================================================================
128
+
129
+ $ ->
130
+
131
+ $('div.simple_form_markdown_editor').simple_form_markdown_editor_buttons()
132
+
133
+ # make sure the plugin is correctly rebound to new elements
134
+ $('body').on 'dom_update', (e) ->
135
+ $('div.simple_form_markdown_editor').simple_form_markdown_editor_buttons()
@@ -0,0 +1,100 @@
1
+ # https://github.com/jquery-boilerplate/jquery-boilerplate/
2
+ do ($ = jQuery, window, document) ->
3
+
4
+ pluginName = 'simple_form_markdown_editor_help'
5
+ defaults =
6
+ debug: false
7
+
8
+ # ---------------------------------------------------------------------
9
+
10
+ class Plugin
11
+ constructor: (@element, options) ->
12
+ @settings = $.extend {}, defaults, options
13
+
14
+ @$element = $(@element)
15
+
16
+ @_defaults = defaults
17
+ @_name = pluginName
18
+
19
+ @init()
20
+
21
+ init: ->
22
+ console.log 'init' if @settings.debug
23
+
24
+ @set_section_li @get_section_lis().first()
25
+
26
+ @get_section_lis().on 'click', (e) =>
27
+ $li = $(e.currentTarget)
28
+ @set_section_li($li)
29
+
30
+ @get_sub_section_lis().on 'click', (e) =>
31
+ $li = $(e.currentTarget)
32
+ @set_sub_section_li($li)
33
+
34
+ # ---------------------------------------------------------------------
35
+
36
+ get_help_div: -> @$element.find('div.help')
37
+
38
+ get_sections_ul: -> @get_help_div().find('ul.sections')
39
+ get_section_lis: -> @get_sections_ul().children('li')
40
+ get_sub_section_ul: (section) -> @get_sub_sections_uls().filter(".#{section}")
41
+ get_sub_sections_uls: -> @get_help_div().find('ul.sub_sections')
42
+ get_sub_section_lis: -> @get_sub_sections_uls().children('li.sub_section')
43
+
44
+ get_help_text_divs: -> @get_help_div().find('div.help_text')
45
+
46
+ set_section_li: ($li) ->
47
+ $li.siblings('li').removeClass('active')
48
+ $li.addClass('active')
49
+ section = $li.data('toggle')
50
+ $sub_section_ul = @get_sub_section_ul(section)
51
+ @set_sub_section_ul($sub_section_ul)
52
+
53
+ set_sub_section_ul: ($ul) ->
54
+ $ul.siblings('ul').removeClass('active')
55
+ $ul.addClass('active')
56
+ $li = $ul.children('li:first')
57
+ @set_sub_section_li($li)
58
+
59
+ set_sub_section_li: ($li) ->
60
+ $li.siblings('li').removeClass('active')
61
+ $li.addClass('active')
62
+ $help_text_div = @get_help_text_divs().filter(".#{$li.data('toggle')}")
63
+ @set_help_text_div($help_text_div)
64
+
65
+ set_help_text_div: ($div) ->
66
+ $div.siblings('div').removeClass('active')
67
+ $div.addClass('active')
68
+
69
+ # ---------------------------------------------------------------------
70
+
71
+ # A really lightweight plugin wrapper around the constructor,
72
+ # preventing against multiple instantiations and allowing any
73
+ # public function (ie. a function whose name doesn't start
74
+ # with an underscore) to be called via the jQuery plugin,
75
+ # e.g. $(element).defaultPluginName('functionName', arg1, arg2)
76
+
77
+ $.fn[pluginName] = (options) ->
78
+ args = arguments
79
+ if options is `undefined` or typeof options is "object"
80
+ @each ->
81
+ $.data this, "plugin_" + pluginName, new Plugin(this, options) unless $.data(this, "plugin_" + pluginName)
82
+
83
+ else if typeof options is "string" and options[0] isnt "_" and options isnt "init"
84
+ returns = undefined
85
+ @each ->
86
+ instance = $.data(this, "plugin_" + pluginName)
87
+ returns = instance[options].apply(instance, Array::slice.call(args, 1)) if instance instanceof Plugin and typeof instance[options] is "function"
88
+ $.data this, "plugin_" + pluginName, null if options is "destroy"
89
+
90
+ (if returns isnt `undefined` then returns else this)
91
+
92
+ # =====================================================================
93
+
94
+ $ ->
95
+
96
+ $('div.simple_form_markdown_editor').simple_form_markdown_editor_help()
97
+
98
+ # make sure the plugin is correctly rebound to new elements
99
+ $('body').on 'dom_update', (e) ->
100
+ $('div.simple_form_markdown_editor').simple_form_markdown_editor_help()
@@ -0,0 +1,84 @@
1
+ # https://github.com/jquery-boilerplate/jquery-boilerplate/
2
+ do ($ = jQuery, window, document) ->
3
+
4
+ pluginName = 'simple_form_markdown_editor_tabs'
5
+ defaults =
6
+ debug: false
7
+
8
+ # ---------------------------------------------------------------------
9
+
10
+ class Plugin
11
+ constructor: (@element, options) ->
12
+ @settings = $.extend {}, defaults, options
13
+
14
+ @$element = $(@element)
15
+
16
+ @_defaults = defaults
17
+ @_name = pluginName
18
+
19
+ @init()
20
+
21
+ init: ->
22
+ console.log 'init' if @settings.debug
23
+
24
+ @get_edit_tab().addClass('active')
25
+
26
+ @get_tab_lis().on 'click', (e) =>
27
+ @get_tab_lis().removeClass('active')
28
+ $(e.currentTarget).addClass('active')
29
+ @$element.attr('data-show', $(e.currentTarget).data('command'))
30
+
31
+ @get_preview_tab().on 'click', (e) =>
32
+ $.ajax(
33
+ context: @element
34
+ type: 'POST'
35
+ url: @$element.attr('data-preview-url')
36
+ data: text: @get_textarea().val()
37
+ success: (html) =>
38
+ @get_preview_div().html(html) or "<p>#{@get_nothing_to_preview_text()}</p>"
39
+ )
40
+
41
+ # ---------------------------------------------------------------------
42
+
43
+ get_textarea: -> @get_editor_div().find('textarea')
44
+ get_preview_div: -> @$element.find('div.preview')
45
+ get_editor_div: -> @$element.find('div.editor')
46
+ get_header: -> @$element.find('div.header:first')
47
+ get_tabs_ul: -> @get_header().find('ul.tabs')
48
+ get_tab_lis: -> @get_tabs_ul().children('li')
49
+ get_preview_tab: -> @get_tab_lis().filter('.preview')
50
+ get_edit_tab: -> @get_tab_lis().filter('.edit')
51
+ get_nothing_to_preview_text: -> @get_preview_div().data('nothing-to-preview-text') or "Nothing to preview."
52
+
53
+ # ---------------------------------------------------------------------
54
+
55
+ # A really lightweight plugin wrapper around the constructor,
56
+ # preventing against multiple instantiations and allowing any
57
+ # public function (ie. a function whose name doesn't start
58
+ # with an underscore) to be called via the jQuery plugin,
59
+ # e.g. $(element).defaultPluginName('functionName', arg1, arg2)
60
+
61
+ $.fn[pluginName] = (options) ->
62
+ args = arguments
63
+ if options is `undefined` or typeof options is "object"
64
+ @each ->
65
+ $.data this, "plugin_" + pluginName, new Plugin(this, options) unless $.data(this, "plugin_" + pluginName)
66
+
67
+ else if typeof options is "string" and options[0] isnt "_" and options isnt "init"
68
+ returns = undefined
69
+ @each ->
70
+ instance = $.data(this, "plugin_" + pluginName)
71
+ returns = instance[options].apply(instance, Array::slice.call(args, 1)) if instance instanceof Plugin and typeof instance[options] is "function"
72
+ $.data this, "plugin_" + pluginName, null if options is "destroy"
73
+
74
+ (if returns isnt `undefined` then returns else this)
75
+
76
+ # =====================================================================
77
+
78
+ $ ->
79
+
80
+ $('div.simple_form_markdown_editor').simple_form_markdown_editor_tabs()
81
+
82
+ # make sure the plugin is correctly rebound to new elements
83
+ $('body').on 'dom_update', (e) ->
84
+ $('div.simple_form_markdown_editor').simple_form_markdown_editor_tabs()
@@ -0,0 +1,3 @@
1
+ //= require simple_form_markdown_editor/simple_form_markdown_editor_tabs
2
+ //= require simple_form_markdown_editor/simple_form_markdown_editor_buttons
3
+ //= require simple_form_markdown_editor/simple_form_markdown_editor_help