"
7 | ],
8 | "description": "a markdown plugin for Simditor",
9 | "main": "lib/js",
10 | "keywords": [
11 | "simditor",
12 | "markdown"
13 | ],
14 | "license": "MIT",
15 | "ignore": [
16 | "**/.*",
17 | "node_modules",
18 | "bower_components",
19 | "test",
20 | "tests"
21 | ],
22 | "dependencies": {
23 | "jquery": "~2.1.0",
24 | "simditor": "~2.1.5",
25 | "marked": "~0.3.2"
26 | },
27 | "devDependencies": {
28 | "requirejs": "~2.1.15"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/index-require.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
42 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
27 |
--------------------------------------------------------------------------------
/lib/simditor-marked.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | var __hasProp = {}.hasOwnProperty,
3 | __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
4 |
5 | (function(factory) {
6 | if ((typeof define === 'function') && define.amd) {
7 | return define(['simditor', 'marked'], factory);
8 | } else {
9 | return factory(window.Simditor, window.marked);
10 | }
11 | })(function(Simditor, _marked) {
12 | var MarkedButton;
13 | MarkedButton = (function(_super) {
14 | __extends(MarkedButton, _super);
15 |
16 | function MarkedButton() {
17 | MarkedButton.__super__.constructor.apply(this, arguments);
18 | this.marked = _marked;
19 | if (!_marked) {
20 | throw new Error('cannot find the plugin marked');
21 | }
22 | }
23 |
24 | MarkedButton.prototype._init = function() {
25 | if (this.editor.util.os.mac) {
26 | this.title = this.title + ' ( Cmd + m )';
27 | } else {
28 | this.title = this.title + ' ( Ctrl + m )';
29 | this.shortcut = 'ctrl+m';
30 | }
31 | MarkedButton.__super__._init.apply(this, arguments);
32 | return this.setIcon("maxcdn");
33 | };
34 |
35 | MarkedButton.prototype.name = 'marked';
36 |
37 | MarkedButton.prototype.title = 'marked';
38 |
39 | MarkedButton.prototype.icon = 'maxcdn';
40 |
41 | MarkedButton.prototype.shortcut = 'cmd+m';
42 |
43 | MarkedButton.prototype.setIcon = function(icon) {
44 | return this.el.find("span").removeClass().addClass("fa fa-" + icon);
45 | };
46 |
47 | MarkedButton.prototype.decodeHTML = function(str) {
48 | var div;
49 | div = document.createElement('div');
50 | div.innerHTML = str;
51 | return div.innerText || div.textContent;
52 | };
53 |
54 | MarkedButton.prototype.encodeHTML = function(str) {
55 | var div;
56 | div = document.createElement('div');
57 | div.appendChild(document.createTextNode(str));
58 | return div.innerHTML;
59 | };
60 |
61 | MarkedButton.prototype.decodeCodes = function(content) {
62 | var code, codes, div, text, _i, _len;
63 | div = document.createElement('div');
64 | div.innerHTML = content;
65 | codes = div.querySelectorAll('code');
66 | for (_i = 0, _len = codes.length; _i < _len; _i++) {
67 | code = codes[_i];
68 | text = this.decodeHTML(code.innerText || div.textContent);
69 | if (code.innerText) {
70 | code.innerText = text;
71 | }
72 | if (code.textContent) {
73 | code.textContent = text;
74 | }
75 | }
76 | return div.innerHTML;
77 | };
78 |
79 | MarkedButton.prototype.replaceSelection = function(html, selectInserted) {
80 | var child, div, firstInsertedNode, fragment, lastInsertedNode, range, sel;
81 | if (selectInserted == null) {
82 | selectInserted = true;
83 | }
84 | sel = window.getSelection();
85 | if (!(sel.getRangeAt && sel.rangeCount)) {
86 | return;
87 | }
88 | range = window.getSelection().getRangeAt(0);
89 | range.deleteContents();
90 | if (range.createContextualFragment) {
91 | fragment = range.createContextualFragment(html);
92 | } else {
93 | div = document.createElement("div");
94 | div.innerHTML = html;
95 | fragment = document.createDocumentFragment();
96 | while ((child = div.firstChild)) {
97 | fragment.appendChild(child);
98 | }
99 | }
100 | firstInsertedNode = fragment.firstChild;
101 | lastInsertedNode = fragment.lastChild;
102 | range.insertNode(fragment);
103 | if (!selectInserted) {
104 | return;
105 | }
106 | if (firstInsertedNode) {
107 | range.setStartBefore(firstInsertedNode);
108 | range.setEndAfter(lastInsertedNode);
109 | }
110 | sel.removeAllRanges();
111 | return sel.addRange(range);
112 | };
113 |
114 | MarkedButton.prototype.doReplaceSelction = function(sel) {
115 | var value;
116 | value = this.marked(this.encodeHTML(sel));
117 | value = this.decodeCodes(value);
118 | return this.replaceSelection(value);
119 | };
120 |
121 | MarkedButton.prototype.doReplaceAll = function() {
122 | var value;
123 | value = this.editor.getValue();
124 | value = value.replace(//g, '').replace(/<\/p>/g, '\n');
125 | value = this.marked(value);
126 | value = this.decodeCodes(value);
127 | return this.editor.setValue(value);
128 | };
129 |
130 | MarkedButton.prototype.command = function() {
131 | var sel;
132 | sel = window.getSelection().toString();
133 | if (sel.length === 0) {
134 | this.doReplaceAll();
135 | } else {
136 | this.doReplaceSelction(sel);
137 | }
138 | return this.editor.selection.setRangeAtEndOf('p');
139 | };
140 |
141 | return MarkedButton;
142 |
143 | })(Simditor.Button);
144 | return Simditor.Toolbar.addButton(MarkedButton);
145 | });
146 |
147 | }).call(this);
148 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "simditor-marked",
3 | "version": "0.0.6",
4 | "homepage": "https://github.com/huyinghuan/simditor-marked",
5 | "keywords": [
6 | "simditor",
7 | "markdown"
8 | ],
9 | "license": "MIT",
10 | "devDependencies": {
11 | "grunt": "^0.4.5",
12 | "grunt-contrib-coffee": "^0.11.1"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/simditor-marked.coffee:
--------------------------------------------------------------------------------
1 | ((factory)->
2 | if (typeof define is 'function') and define.amd
3 | define ['simditor', 'marked'], factory
4 | else
5 | factory window.Simditor, window.marked
6 | )((Simditor, _marked)->
7 | class MarkedButton extends Simditor.Button
8 | constructor: ->
9 | super
10 | @marked = _marked
11 | throw new Error('cannot find the plugin marked') if not _marked
12 |
13 | _init: ->
14 | if @editor.util.os.mac
15 | @title = @title + ' ( Cmd + m )'
16 | else
17 | @title = @title + ' ( Ctrl + m )'
18 | @shortcut = 'ctrl+m'
19 | super
20 | @setIcon("maxcdn")
21 |
22 | name: 'marked'
23 | title: 'marked'
24 | icon: 'maxcdn'
25 | shortcut: 'cmd+m'
26 |
27 | setIcon: (icon)->
28 | @el.find("span").removeClass().addClass("fa fa-#{icon}")
29 | #反转义字符串
30 | decodeHTML: (str)->
31 | div = document.createElement('div')
32 | div.innerHTML = str
33 | div.innerText or div.textContent
34 |
35 | #转义字符串
36 | encodeHTML: (str)->
37 | div = document.createElement('div')
38 | div.appendChild document.createTextNode str
39 | div.innerHTML
40 |
41 | #反转义所有code标签里面的字符
42 | decodeCodes: (content)->
43 | div = document.createElement 'div'
44 | div.innerHTML = content
45 | codes = div.querySelectorAll 'code'
46 | for code in codes
47 | text = @decodeHTML(code.innerText or div.textContent)
48 | code.innerText = text if code.innerText
49 | code.textContent = text if code.textContent
50 |
51 | return div.innerHTML
52 |
53 |
54 | ## 替换选中文字
55 | ## 代码来自 http://stackoverflow.com/questions/5393922/javascript-replace-selection-all-browsers
56 | ## 删除了一部分关于ie8的兼容代码,并改写成了coffee
57 | replaceSelection: (html, selectInserted = true)->
58 | sel = window.getSelection()
59 | # Test that the Selection object contains at least one Range
60 | return if not (sel.getRangeAt && sel.rangeCount)
61 | range = window.getSelection().getRangeAt(0)
62 | range.deleteContents()
63 | if range.createContextualFragment
64 | fragment = range.createContextualFragment html
65 | else
66 | div = document.createElement "div"
67 | div.innerHTML = html
68 | fragment = document.createDocumentFragment()
69 | fragment.appendChild child while (child = div.firstChild)
70 |
71 | firstInsertedNode = fragment.firstChild
72 | lastInsertedNode = fragment.lastChild
73 | range.insertNode fragment
74 |
75 | return if not selectInserted
76 | if firstInsertedNode
77 | range.setStartBefore firstInsertedNode
78 | range.setEndAfter lastInsertedNode
79 | sel.removeAllRanges()
80 | sel.addRange range
81 |
82 | doReplaceSelction: (sel)->
83 | value = @marked @encodeHTML sel
84 | value = @decodeCodes value
85 | @replaceSelection value
86 |
87 | doReplaceAll: ()->
88 | value = @editor.getValue()
89 | value = value.replace(/
/g, '').replace(/<\/p>/g, '\n')
90 | value = @marked value
91 | value = @decodeCodes value
92 | @editor.setValue value
93 |
94 | command: ()->
95 | sel = window.getSelection().toString()
96 | if sel.length is 0 then @doReplaceAll() else @doReplaceSelction(sel)
97 | @editor.selection.setRangeAtEndOf('p')
98 |
99 | Simditor.Toolbar.addButton(MarkedButton)
100 | )
--------------------------------------------------------------------------------