simple_form_markdown_editor_bootstrap 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,108 @@
1
+ (function () {
2
+ var output, Converter;
3
+ if (typeof exports === "object" && typeof require === "function") { // we're in a CommonJS (e.g. Node.js) module
4
+ output = exports;
5
+ Converter = require("./Markdown.Converter").Converter;
6
+ } else {
7
+ output = window.Markdown;
8
+ Converter = output.Converter;
9
+ }
10
+
11
+ output.getSanitizingConverter = function () {
12
+ var converter = new Converter();
13
+ converter.hooks.chain("postConversion", sanitizeHtml);
14
+ converter.hooks.chain("postConversion", balanceTags);
15
+ return converter;
16
+ }
17
+
18
+ function sanitizeHtml(html) {
19
+ return html.replace(/<[^>]*>?/gi, sanitizeTag);
20
+ }
21
+
22
+ // (tags that can be opened/closed) | (tags that stand alone)
23
+ var basic_tag_whitelist = /^(<\/?(b|blockquote|code|del|dd|dl|dt|em|h1|h2|h3|i|kbd|li|ol|p|pre|s|sup|sub|strong|strike|ul)>|<(br|hr)\s?\/?>)$/i;
24
+ // <a href="url..." optional title>|</a>
25
+ var a_white = /^(<a\shref="((https?|ftp):\/\/|\/)[-A-Za-z0-9+&@#\/%?=~_|!:,.;\(\)]+"(\stitle="[^"<>]+")?\s?>|<\/a>)$/i;
26
+
27
+ // <img src="url..." optional width optional height optional alt optional title
28
+ var img_white = /^(<img\ssrc="(https?:\/\/|\/)[-A-Za-z0-9+&@#\/%?=~_|!:,.;\(\)]+"(\swidth="\d{1,3}")?(\sheight="\d{1,3}")?(\salt="[^"<>]*")?(\stitle="[^"<>]*")?\s?\/?>)$/i;
29
+
30
+ function sanitizeTag(tag) {
31
+ if (tag.match(basic_tag_whitelist) || tag.match(a_white) || tag.match(img_white))
32
+ return tag;
33
+ else
34
+ return "";
35
+ }
36
+
37
+ /// <summary>
38
+ /// attempt to balance HTML tags in the html string
39
+ /// by removing any unmatched opening or closing tags
40
+ /// IMPORTANT: we *assume* HTML has *already* been
41
+ /// sanitized and is safe/sane before balancing!
42
+ ///
43
+ /// adapted from CODESNIPPET: A8591DBA-D1D3-11DE-947C-BA5556D89593
44
+ /// </summary>
45
+ function balanceTags(html) {
46
+
47
+ if (html == "")
48
+ return "";
49
+
50
+ var re = /<\/?\w+[^>]*(\s|$|>)/g;
51
+ // convert everything to lower case; this makes
52
+ // our case insensitive comparisons easier
53
+ var tags = html.toLowerCase().match(re);
54
+
55
+ // no HTML tags present? nothing to do; exit now
56
+ var tagcount = (tags || []).length;
57
+ if (tagcount == 0)
58
+ return html;
59
+
60
+ var tagname, tag;
61
+ var ignoredtags = "<p><img><br><li><hr>";
62
+ var match;
63
+ var tagpaired = [];
64
+ var tagremove = [];
65
+ var needsRemoval = false;
66
+
67
+ // loop through matched tags in forward order
68
+ for (var ctag = 0; ctag < tagcount; ctag++) {
69
+ tagname = tags[ctag].replace(/<\/?(\w+).*/, "$1");
70
+ // skip any already paired tags
71
+ // and skip tags in our ignore list; assume they're self-closed
72
+ if (tagpaired[ctag] || ignoredtags.search("<" + tagname + ">") > -1)
73
+ continue;
74
+
75
+ tag = tags[ctag];
76
+ match = -1;
77
+
78
+ if (!/^<\//.test(tag)) {
79
+ // this is an opening tag
80
+ // search forwards (next tags), look for closing tags
81
+ for (var ntag = ctag + 1; ntag < tagcount; ntag++) {
82
+ if (!tagpaired[ntag] && tags[ntag] == "</" + tagname + ">") {
83
+ match = ntag;
84
+ break;
85
+ }
86
+ }
87
+ }
88
+
89
+ if (match == -1)
90
+ needsRemoval = tagremove[ctag] = true; // mark for removal
91
+ else
92
+ tagpaired[match] = true; // mark paired
93
+ }
94
+
95
+ if (!needsRemoval)
96
+ return html;
97
+
98
+ // delete all orphaned tags from the string
99
+
100
+ var ctag = 0;
101
+ html = html.replace(re, function (match) {
102
+ var res = tagremove[ctag] ? "" : match;
103
+ ctag++;
104
+ return res;
105
+ });
106
+ return html;
107
+ }
108
+ })();
@@ -0,0 +1,18 @@
1
+ #= require_tree .
2
+
3
+ @initMarkdown = (suffix = '') ->
4
+ identifier = if suffix
5
+ '#wmd-input' + suffix
6
+ else
7
+ 'textarea.markdown'
8
+
9
+ if isExisiting && isNotInitialized
10
+ converter = Markdown.getSanitizingConverter()
11
+ editor = new Markdown.Editor(converter, suffix)
12
+ editor.run()
13
+
14
+ isNotInitialized = () ->
15
+ $(identifier).parent().find('#wmd-bold-button').length == 0
16
+
17
+ isExisiting = () ->
18
+ $(identifier).length != 0
@@ -0,0 +1,79 @@
1
+ .wmd-panel {
2
+ width: 100%;
3
+ }
4
+ .wmd-input {
5
+ -moz-box-sizing: border-box;
6
+ height: 300px;
7
+ width: 100%;
8
+ }
9
+ .wmd-preview {
10
+ -moz-box-sizing: border-box;
11
+ background-color: #F5F5F5;
12
+ border: 1px solid rgba(0, 0, 0, 0.05);
13
+ border-radius: 4px 4px 4px 4px;
14
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05) inset;
15
+ margin-bottom: 20px;
16
+ min-height: 20px;
17
+ padding: 19px;
18
+ width: 100%;
19
+ }
20
+ .wmd-preview blockquote {
21
+ border-color: rgba(0, 0, 0, 0.15);
22
+ }
23
+ .wmd-panel .btn-toolbar {
24
+ margin-bottom: 0;
25
+ padding: 0;
26
+ width: 100%;
27
+ }
28
+ .icon-link, .icon-blockquote, .icon-code, .icon-bullet-list, .icon-list, .icon-header, .icon-hr-line, .icon-undo {
29
+ width: 14px;
30
+ height: 14px;
31
+ display: inline-block;
32
+ vertical-align: middle;
33
+ background-image: url("/assets/wmd-buttons.png");
34
+ }
35
+ .icon-link {
36
+ background-position: 0 0;
37
+ }
38
+ .icon-blockquote {
39
+ background-position: -24px 0;
40
+ }
41
+ .icon-code {
42
+ background-position: -48px 0;
43
+ }
44
+ .icon-bullet-list {
45
+ background-position: -72px 0;
46
+ }
47
+ .icon-list {
48
+ background-position: -96px 0;
49
+ }
50
+ .icon-header {
51
+ background-position: -120px 0;
52
+ }
53
+ .icon-hr-line {
54
+ background-position: -144px 0;
55
+ }
56
+ .icon-undo {
57
+ background-position: -168px 0;
58
+ }
59
+ .wmd-prompt-background {
60
+ background-color: Black;
61
+ }
62
+ .wmd-prompt-dialog {
63
+ background-color: #F5F5F5;
64
+ border: 1px solid #999999;
65
+ }
66
+ .wmd-prompt-dialog > div {
67
+ font-family: arial,helvetica,sans-serif;
68
+ font-size: 0.8em;
69
+ }
70
+ .wmd-prompt-dialog > form > input[type="text"] {
71
+ border: 1px solid #999999;
72
+ color: black;
73
+ }
74
+ .wmd-prompt-dialog > form > input[type="button"] {
75
+ border: 1px solid #888888;
76
+ font-family: trebuchet MS,helvetica,sans-serif;
77
+ font-size: 0.8em;
78
+ font-weight: bold;
79
+ }
@@ -0,0 +1,6 @@
1
+ module SimepleFormMarkdownEditorBootstrap
2
+ module Rails
3
+ class Engine < ::Rails::Engine
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,13 @@
1
+ class MarkdownInput < SimpleForm::Inputs::Base
2
+ def input
3
+ suffix = input_options[:suffix]
4
+ id = "wmd-input#{suffix}"
5
+ input_html_options.merge!({id: id})
6
+
7
+ template.content_tag(:div, class: 'wmd-panel') do
8
+ template.content_tag(:div, '', id: "wmd-button-bar#{suffix}") +
9
+ @builder.text_area(attribute_name, input_html_options)
10
+ end +
11
+ template.content_tag(:div, '', id: id, class: 'wmd-preview')
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module SimepleFormMarkdownEditorBootstrap
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,9 @@
1
+ require 'less-rails'
2
+ require 'coffee-rails'
3
+ require 'twitter-bootstrap-rails'
4
+ require 'simple_form'
5
+ require 'simple_form_markdown_editor_bootstrap/engine'
6
+ require 'simple_form_markdown_editor_bootstrap/markdown_input'
7
+
8
+ module SimepleFormMarkdownEditorBootstrap
9
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :simple_form_markdown_editor do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,187 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple_form_markdown_editor_bootstrap
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Guirec Corbel
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-12 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 3.2.12
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 3.2.12
30
+ - !ruby/object:Gem::Dependency
31
+ name: simple_form
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 2.0.4
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 2.0.4
46
+ - !ruby/object:Gem::Dependency
47
+ name: coffee-rails
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 3.2.2
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 3.2.2
62
+ - !ruby/object:Gem::Dependency
63
+ name: twitter-bootstrap-rails
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - '='
68
+ - !ruby/object:Gem::Version
69
+ version: 2.1.9
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - '='
76
+ - !ruby/object:Gem::Version
77
+ version: 2.1.9
78
+ - !ruby/object:Gem::Dependency
79
+ name: less-rails
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - '='
84
+ - !ruby/object:Gem::Version
85
+ version: 2.2.6
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - '='
92
+ - !ruby/object:Gem::Version
93
+ version: 2.2.6
94
+ - !ruby/object:Gem::Dependency
95
+ name: therubyracer
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - '='
100
+ - !ruby/object:Gem::Version
101
+ version: 0.11.4
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - '='
108
+ - !ruby/object:Gem::Version
109
+ version: 0.11.4
110
+ - !ruby/object:Gem::Dependency
111
+ name: sqlite3
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: rspec-rails
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ description:
143
+ email:
144
+ - guirec.corbel@gmail.com
145
+ executables: []
146
+ extensions: []
147
+ extra_rdoc_files: []
148
+ files:
149
+ - lib/tasks/simple_form_markdown_editor_tasks.rake
150
+ - lib/simple_form_markdown_editor_bootstrap.rb
151
+ - lib/assets/images/wmd-buttons.png
152
+ - lib/assets/stylesheets/markdown.css
153
+ - lib/assets/javascripts/markdown.js.coffee
154
+ - lib/assets/javascripts/Markdown.Editor.js
155
+ - lib/assets/javascripts/Markdown.Converter.js
156
+ - lib/assets/javascripts/Markdown.Sanitizer.js
157
+ - lib/simple_form_markdown_editor_bootstrap/markdown_input.rb
158
+ - lib/simple_form_markdown_editor_bootstrap/version.rb
159
+ - lib/simple_form_markdown_editor_bootstrap/engine.rb
160
+ - MIT-LICENSE
161
+ - Rakefile
162
+ - README.rdoc
163
+ homepage: https://github.com/GCorbel/simple_form_markdown_editor_bootstrap
164
+ licenses: []
165
+ post_install_message:
166
+ rdoc_options: []
167
+ require_paths:
168
+ - lib
169
+ required_ruby_version: !ruby/object:Gem::Requirement
170
+ none: false
171
+ requirements:
172
+ - - ! '>='
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ required_rubygems_version: !ruby/object:Gem::Requirement
176
+ none: false
177
+ requirements:
178
+ - - ! '>='
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ requirements: []
182
+ rubyforge_project:
183
+ rubygems_version: 1.8.23
184
+ signing_key:
185
+ specification_version: 3
186
+ summary: This is an markdown editor for simple_form
187
+ test_files: []