simple_form_markdown_editor_bootstrap 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +27 -0
- data/lib/assets/images/wmd-buttons.png +0 -0
- data/lib/assets/javascripts/Markdown.Converter.js +1332 -0
- data/lib/assets/javascripts/Markdown.Editor.js +2192 -0
- data/lib/assets/javascripts/Markdown.Sanitizer.js +108 -0
- data/lib/assets/javascripts/markdown.js.coffee +18 -0
- data/lib/assets/stylesheets/markdown.css +79 -0
- data/lib/simple_form_markdown_editor_bootstrap/engine.rb +6 -0
- data/lib/simple_form_markdown_editor_bootstrap/markdown_input.rb +13 -0
- data/lib/simple_form_markdown_editor_bootstrap/version.rb +3 -0
- data/lib/simple_form_markdown_editor_bootstrap.rb +9 -0
- data/lib/tasks/simple_form_markdown_editor_tasks.rake +4 -0
- metadata +187 -0
@@ -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,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,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
|
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: []
|