@standardnotes/bold-editor 1.6.3

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.
Files changed (57) hide show
  1. package/.babelrc +11 -0
  2. package/.eslintignore +3 -0
  3. package/.eslintrc +29 -0
  4. package/CHANGELOG.md +82 -0
  5. package/LICENSE +661 -0
  6. package/README.md +98 -0
  7. package/app/App.js +18 -0
  8. package/app/components/Editor.js +415 -0
  9. package/app/main.js +8 -0
  10. package/app/stylesheets/main.scss +272 -0
  11. package/dist/dist.css +1 -0
  12. package/dist/dist.min.js +2 -0
  13. package/dist/dist.min.js.LICENSE.txt +42 -0
  14. package/dist/filesafe-js/EncryptionWorker.js +2 -0
  15. package/dist/filesafe-js/EncryptionWorker.js.LICENSE.txt +5 -0
  16. package/dist/index.html +1 -0
  17. package/dist/vendor.css +6 -0
  18. package/dist/vendor.js +1 -0
  19. package/editor.index.ejs +14 -0
  20. package/editor_bar.png +0 -0
  21. package/ext.json.sample +9 -0
  22. package/package.json +54 -0
  23. package/redactor/plugins/alignment/alignment.js +55 -0
  24. package/redactor/plugins/alignment/alignment.min.js +1 -0
  25. package/redactor/plugins/counter/counter.js +76 -0
  26. package/redactor/plugins/counter/counter.min.js +1 -0
  27. package/redactor/plugins/filesafe/filesafe.js +70 -0
  28. package/redactor/plugins/filesafe/filesafe.min.js +70 -0
  29. package/redactor/plugins/fontcolor/fontcolor.js +184 -0
  30. package/redactor/plugins/fontcolor/fontcolor.min.js +1 -0
  31. package/redactor/plugins/fontfamily/fontfamily.js +59 -0
  32. package/redactor/plugins/fontfamily/fontfamily.min.js +1 -0
  33. package/redactor/plugins/fontsize/fontsize.js +58 -0
  34. package/redactor/plugins/fontsize/fontsize.min.js +1 -0
  35. package/redactor/plugins/imagemanager/imagemanager.js +82 -0
  36. package/redactor/plugins/imagemanager/imagemanager.min.js +1 -0
  37. package/redactor/plugins/inlinestyle/inlinestyle.css +34 -0
  38. package/redactor/plugins/inlinestyle/inlinestyle.js +62 -0
  39. package/redactor/plugins/inlinestyle/inlinestyle.min.css +1 -0
  40. package/redactor/plugins/inlinestyle/inlinestyle.min.js +1 -0
  41. package/redactor/plugins/specialchars/specialchars.js +78 -0
  42. package/redactor/plugins/specialchars/specialchars.min.js +1 -0
  43. package/redactor/plugins/table/table.js +477 -0
  44. package/redactor/plugins/table/table.min.js +1 -0
  45. package/redactor/plugins/textdirection/textdirection.js +44 -0
  46. package/redactor/plugins/textdirection/textdirection.min.js +1 -0
  47. package/redactor/plugins/textexpander/textexpander.js +64 -0
  48. package/redactor/plugins/textexpander/textexpander.min.js +1 -0
  49. package/redactor/plugins/variable/variable.css +23 -0
  50. package/redactor/plugins/variable/variable.js +222 -0
  51. package/redactor/plugins/variable/variable.min.css +1 -0
  52. package/redactor/plugins/variable/variable.min.js +1 -0
  53. package/redactor/src/redactor.min.css +1 -0
  54. package/redactor/src/redactor.min.js +1 -0
  55. package/webpack.config.js +82 -0
  56. package/webpack.dev.js +20 -0
  57. package/webpack.prod.js +11 -0
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <base target="_blank">
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
7
+ <link href="vendor.css" rel="stylesheet">
8
+ <script type="text/javascript" src="vendor.js"></script>
9
+ <script type="text/javascript" src="filesafe-js/EncryptionWorker.js"></script>
10
+ <title><%= htmlWebpackPlugin.options.title %></title>
11
+ </head>
12
+
13
+ <body></body>
14
+ </html>
package/editor_bar.png ADDED
Binary file
@@ -0,0 +1,9 @@
1
+ {
2
+ "identifier": "org.standardnotes.bold-editor-dev",
3
+ "name": "Bold Editor - Dev",
4
+ "content_type": "SN|Component",
5
+ "area": "editor-editor",
6
+ "version": "1.0.0",
7
+ "description": "Text formatting and Filesafe integration!",
8
+ "url": "http://localhost:8001/"
9
+ }
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@standardnotes/bold-editor",
3
+ "publishConfig": {
4
+ "access": "public"
5
+ },
6
+ "version": "1.6.3",
7
+ "main": "dist/dist.js",
8
+ "author": "Standard Notes Retired",
9
+ "sn": {
10
+ "name": "Bold Editor",
11
+ "content_type": "SN|Component",
12
+ "area": "editor-editor",
13
+ "spellcheckControl": true,
14
+ "note_type": "rich-text",
15
+ "main": "dist/index.html",
16
+ "file_type": "html"
17
+ },
18
+ "scripts": {
19
+ "lint": "eslint app/ --ext .js",
20
+ "lint:fix": "eslint app/ --ext .js --fix",
21
+ "build": "webpack --config webpack.prod.js",
22
+ "start": "webpack serve --config webpack.dev.js --progress --hot",
23
+ "test": "echo \"Error: no test specified\" && exit 0"
24
+ },
25
+ "devDependencies": {
26
+ "@babel/core": "^7.13.14",
27
+ "@babel/eslint-parser": "^7.13.14",
28
+ "@babel/preset-env": "^7.13.12",
29
+ "@babel/preset-react": "^7.13.13",
30
+ "@standardnotes/editor-kit": "2.2.3",
31
+ "babel-loader": "^8.2.2",
32
+ "copy-webpack-plugin": "*",
33
+ "css-loader": "^5.2.0",
34
+ "dompurify": "^2.2.9",
35
+ "eslint": "*",
36
+ "eslint-plugin-react": "*",
37
+ "filesafe-embed": "1.0.13",
38
+ "filesafe-js": "1.0.5",
39
+ "html-webpack-plugin": "^5.3.1",
40
+ "mini-css-extract-plugin": "^1.4.0",
41
+ "node-sass": "*",
42
+ "react": "17.x",
43
+ "react-dom": "17.x",
44
+ "sass-loader": "^11.0.1",
45
+ "sn-stylekit": "3.0.1",
46
+ "style-loader": "~2.0.0",
47
+ "terser-webpack-plugin": "^5.1.1",
48
+ "webpack": "*",
49
+ "webpack-cli": "*",
50
+ "webpack-dev-server": "*",
51
+ "webpack-merge": "^5.7.3",
52
+ "webpack-merge-and-include-globally": "^2.3.4"
53
+ }
54
+ }
@@ -0,0 +1,55 @@
1
+ (function($R)
2
+ {
3
+ $R.add('plugin', 'alignment', {
4
+ translations: {
5
+ en: {
6
+ "align": "Align",
7
+ "align-left": "Align Left",
8
+ "align-center": "Align Center",
9
+ "align-right": "Align Right",
10
+ "align-justify": "Align Justify"
11
+ }
12
+ },
13
+ init: function(app)
14
+ {
15
+ this.app = app;
16
+ this.opts = app.opts;
17
+ this.lang = app.lang;
18
+ this.block = app.block;
19
+ this.toolbar = app.toolbar;
20
+ },
21
+ // public
22
+ start: function()
23
+ {
24
+ var dropdown = {};
25
+
26
+ dropdown.left = { title: this.lang.get('align-left'), api: 'plugin.alignment.set', args: 'left' };
27
+ dropdown.center = { title: this.lang.get('align-center'), api: 'plugin.alignment.set', args: 'center' };
28
+ dropdown.right = { title: this.lang.get('align-right'), api: 'plugin.alignment.set', args: 'right' };
29
+ dropdown.justify = { title: this.lang.get('align-justify'), api: 'plugin.alignment.set', args: 'justify' };
30
+
31
+ var $button = this.toolbar.addButton('alignment', { title: this.lang.get('align') });
32
+ $button.setIcon('<i class="re-icon-alignment"></i>');
33
+ $button.setDropdown(dropdown);
34
+ },
35
+ set: function(type)
36
+ {
37
+ if (type === 'left' && this.opts.direction === 'ltr')
38
+ {
39
+ return this._remove();
40
+ }
41
+
42
+ var args = {
43
+ style: { 'text-align': type }
44
+ };
45
+
46
+ this.block.toggle(args);
47
+ },
48
+
49
+ // private
50
+ _remove: function()
51
+ {
52
+ this.block.remove({ style: 'text-align' });
53
+ }
54
+ });
55
+ })(Redactor);
@@ -0,0 +1 @@
1
+ Redactor.add("plugin","alignment",{translations:{en:{align:"Align","align-left":"Align Left","align-center":"Align Center","align-right":"Align Right","align-justify":"Align Justify"}},init:function(t){this.app=t,this.opts=t.opts,this.lang=t.lang,this.block=t.block,this.toolbar=t.toolbar},start:function(){var t={};t.left={title:this.lang.get("align-left"),api:"plugin.alignment.set",args:"left"},t.center={title:this.lang.get("align-center"),api:"plugin.alignment.set",args:"center"},t.right={title:this.lang.get("align-right"),api:"plugin.alignment.set",args:"right"},t.justify={title:this.lang.get("align-justify"),api:"plugin.alignment.set",args:"justify"};var i=this.toolbar.addButton("alignment",{title:this.lang.get("align")});i.setIcon('<i class="re-icon-alignment"></i>'),i.setDropdown(t)},set:function(t){if("left"===t&&"ltr"===this.opts.direction)return this._remove();var i={style:{"text-align":t}};this.block.toggle(i)},_remove:function(){this.block.remove({style:"text-align"})}});
@@ -0,0 +1,76 @@
1
+ (function($R)
2
+ {
3
+ $R.add('plugin', 'counter', {
4
+ translations: {
5
+ en: {
6
+ "words": "words",
7
+ "chars": "chars"
8
+ }
9
+ },
10
+ init: function(app)
11
+ {
12
+ this.app = app;
13
+ this.lang = app.lang;
14
+ this.utils = app.utils;
15
+ this.editor = app.editor;
16
+ this.statusbar = app.statusbar;
17
+ },
18
+ // public
19
+ start: function()
20
+ {
21
+ var $editor = this.editor.getElement();
22
+ $editor.on('keyup.redactor-plugin-counter paste.redactor-plugin-counter', this.count.bind(this));
23
+ this.count();
24
+ },
25
+ stop: function()
26
+ {
27
+ var $editor = this.editor.getElement();
28
+ $editor.off('.redactor-plugin-counter');
29
+
30
+ this.statusbar.remove('words');
31
+ this.statusbar.remove('chars');
32
+ },
33
+ count: function()
34
+ {
35
+ var words = 0, characters = 0, spaces = 0;
36
+ var $editor = this.editor.getElement();
37
+ var html = $editor.html();
38
+
39
+ html = this._clean(html)
40
+ if (html !== '')
41
+ {
42
+ var arrWords = html.split(/\s+/);
43
+ var arrSpaces = html.match(/\s/g);
44
+
45
+ words = (arrWords) ? arrWords.length : 0;
46
+ spaces = (arrSpaces) ? arrSpaces.length : 0;
47
+
48
+ characters = html.length;
49
+ }
50
+
51
+ var data = { words: words, characters: characters, spaces: spaces };
52
+
53
+ // callback
54
+ this.app.broadcast('counter', data);
55
+
56
+ // statusbar
57
+ this.statusbar.add('words', this.lang.get('words') + ': ' + data.words);
58
+ this.statusbar.add('chars', this.lang.get('chars') + ': ' + data.characters);
59
+ },
60
+
61
+ // private
62
+ _clean: function(html)
63
+ {
64
+ html = html.replace(/<\/(.*?)>/gi, ' ');
65
+ html = html.replace(/<(.*?)>/gi, '');
66
+ html = html.replace(/\t/gi, '');
67
+ html = html.replace(/\n/gi, ' ');
68
+ html = html.replace(/\r/gi, ' ');
69
+ html = html.replace(/&nbsp;/g, '1');
70
+ html = html.trim();
71
+ html = this.utils.removeInvisibleChars(html);
72
+
73
+ return html;
74
+ }
75
+ });
76
+ })(Redactor);
@@ -0,0 +1 @@
1
+ Redactor.add("plugin","counter",{translations:{en:{words:"words",chars:"chars"}},init:function(t){this.app=t,this.lang=t.lang,this.utils=t.utils,this.editor=t.editor,this.statusbar=t.statusbar},start:function(){this.editor.getElement().on("keyup.redactor-plugin-counter paste.redactor-plugin-counter",this.count.bind(this)),this.count()},stop:function(){this.editor.getElement().off(".redactor-plugin-counter"),this.statusbar.remove("words"),this.statusbar.remove("chars")},count:function(){var t=0,s=0,r=0,e=this.editor.getElement().html();if(""!==(e=this._clean(e))){var a=e.split(/\s+/),i=e.match(/\s/g);t=a?a.length:0,r=i?i.length:0,s=e.length}var n={words:t,characters:s,spaces:r};this.app.broadcast("counter",n),this.statusbar.add("words",this.lang.get("words")+": "+n.words),this.statusbar.add("chars",this.lang.get("chars")+": "+n.characters)},_clean:function(t){return t=(t=(t=(t=(t=(t=(t=t.replace(/<\/(.*?)>/gi," ")).replace(/<(.*?)>/gi,"")).replace(/\t/gi,"")).replace(/\n/gi," ")).replace(/\r/gi," ")).replace(/&nbsp;/g,"1")).trim(),t=this.utils.removeInvisibleChars(t)}});
@@ -0,0 +1,70 @@
1
+ (function($R)
2
+ {
3
+ $R.add('plugin', 'filesafe', {
4
+ modals: {
5
+ 'filesafe':
6
+ '<div id="filesafe-react-client"> \
7
+ </div>'
8
+ },
9
+ translations: {
10
+ en: {
11
+ "filesafe": "FileSafe",
12
+ "filesafe-label": "Please, type some text"
13
+ }
14
+ },
15
+ init: function(app)
16
+ {
17
+ // define app
18
+ this.app = app;
19
+ this.filesafe = window.filesafe_params;
20
+ this.lang = app.lang;
21
+ this.toolbar = app.toolbar;
22
+ this.insertion = app.insertion;
23
+ },
24
+
25
+ // messages
26
+ onmodal: {
27
+ filesafe: {
28
+ opened: function($modal, $form)
29
+ {
30
+ const mountPoint = document.getElementById('filesafe-react-client');
31
+ this.filesafe.embed.FilesafeEmbed.renderInElement(mountPoint, this.filesafe.client);
32
+ },
33
+ closed: function()
34
+ {
35
+ const mountPoint = document.getElementById('filesafe-react-client');
36
+ this.filesafe.embed.FilesafeEmbed.unload(mountPoint);
37
+ }
38
+ }
39
+ },
40
+
41
+ // public
42
+ start: function()
43
+ {
44
+ // create the button data
45
+ var buttonData = {
46
+ title: 'FileSafe',
47
+ api: 'plugin.filesafe.open'
48
+ };
49
+
50
+ // create the button
51
+ var $button = this.toolbar.addButton('filesafe', buttonData);
52
+ $button.setIcon('<i class="re-icon-clips"></i>');
53
+ },
54
+ open: function()
55
+ {
56
+ var options = {
57
+ title: this.lang.get('filesafe'),
58
+ width: '600px',
59
+ height: '500px',
60
+ name: 'filesafe',
61
+ commands: {
62
+ // cancel: { title: "Done" }
63
+ }
64
+ };
65
+
66
+ this.app.api('module.modal.build', options);
67
+ },
68
+
69
+ });
70
+ })(Redactor);
@@ -0,0 +1,70 @@
1
+ (function($R)
2
+ {
3
+ $R.add('plugin', 'filesafe', {
4
+ modals: {
5
+ 'filesafe':
6
+ '<div id="filesafe-react-client"> \
7
+ </div>'
8
+ },
9
+ translations: {
10
+ en: {
11
+ "filesafe": "FileSafe",
12
+ "filesafe-label": "Please, type some text"
13
+ }
14
+ },
15
+ init: function(app)
16
+ {
17
+ // define app
18
+ this.app = app;
19
+ this.filesafe = window.filesafe_params;
20
+ this.lang = app.lang;
21
+ this.toolbar = app.toolbar;
22
+ this.insertion = app.insertion;
23
+ },
24
+
25
+ // messages
26
+ onmodal: {
27
+ filesafe: {
28
+ opened: function($modal, $form)
29
+ {
30
+ const mountPoint = document.getElementById('filesafe-react-client');
31
+ this.filesafe.embed.FilesafeEmbed.renderInElement(mountPoint, this.filesafe.client);
32
+ },
33
+ closed: function()
34
+ {
35
+ const mountPoint = document.getElementById('filesafe-react-client');
36
+ this.filesafe.embed.FilesafeEmbed.unload(mountPoint);
37
+ }
38
+ }
39
+ },
40
+
41
+ // public
42
+ start: function()
43
+ {
44
+ // create the button data
45
+ var buttonData = {
46
+ title: 'FileSafe',
47
+ api: 'plugin.filesafe.open'
48
+ };
49
+
50
+ // create the button
51
+ var $button = this.toolbar.addButton('filesafe', buttonData);
52
+ $button.setIcon('<i class="re-icon-clips"></i>');
53
+ },
54
+ open: function()
55
+ {
56
+ var options = {
57
+ title: this.lang.get('filesafe'),
58
+ width: '600px',
59
+ height: '500px',
60
+ name: 'filesafe',
61
+ commands: {
62
+ // cancel: { title: "Done" }
63
+ }
64
+ };
65
+
66
+ this.app.api('module.modal.build', options);
67
+ },
68
+
69
+ });
70
+ })(Redactor);
@@ -0,0 +1,184 @@
1
+ (function($R)
2
+ {
3
+ $R.add('plugin', 'fontcolor', {
4
+ translations: {
5
+ en: {
6
+ "fontcolor": "Text Color",
7
+ "text": "Text",
8
+ "highlight": "Highlight"
9
+ }
10
+ },
11
+ init: function(app)
12
+ {
13
+ this.app = app;
14
+ this.opts = app.opts;
15
+ this.lang = app.lang;
16
+ this.inline = app.inline;
17
+ this.toolbar = app.toolbar;
18
+ this.selection = app.selection;
19
+
20
+ // local
21
+ this.colors = (this.opts.fontcolors) ? this.opts.fontcolors : [
22
+ '#ffffff', '#000000', '#eeece1', '#1f497d', '#4f81bd', '#c0504d', '#9bbb59', '#8064a2', '#4bacc6', '#f79646', '#ffff00',
23
+ '#f2f2f2', '#7f7f7f', '#ddd9c3', '#c6d9f0', '#dbe5f1', '#f2dcdb', '#ebf1dd', '#e5e0ec', '#dbeef3', '#fdeada', '#fff2ca',
24
+ '#d8d8d8', '#595959', '#c4bd97', '#8db3e2', '#b8cce4', '#e5b9b7', '#d7e3bc', '#ccc1d9', '#b7dde8', '#fbd5b5', '#ffe694',
25
+ '#bfbfbf', '#3f3f3f', '#938953', '#548dd4', '#95b3d7', '#d99694', '#c3d69b', '#b2a2c7', '#b7dde8', '#fac08f', '#f2c314',
26
+ '#a5a5a5', '#262626', '#494429', '#17365d', '#366092', '#953734', '#76923c', '#5f497a', '#92cddc', '#e36c09', '#c09100',
27
+ '#7f7f7f', '#0c0c0c', '#1d1b10', '#0f243e', '#244061', '#632423', '#4f6128', '#3f3151', '#31859b', '#974806', '#7f6000'
28
+ ];
29
+ },
30
+ // messages
31
+ onfontcolor: {
32
+ set: function(rule, value)
33
+ {
34
+ this._set(rule, value);
35
+ },
36
+ remove: function(rule)
37
+ {
38
+ this._remove(rule);
39
+ }
40
+ },
41
+
42
+ // public
43
+ start: function()
44
+ {
45
+ var btnObj = {
46
+ title: this.lang.get('fontcolor')
47
+ };
48
+
49
+ var $dropdown = this._buildDropdown();
50
+
51
+ this.$button = this.toolbar.addButton('fontcolor', btnObj);
52
+ this.$button.setIcon('<i class="re-icon-fontcolor"></i>');
53
+ this.$button.setDropdown($dropdown);
54
+ },
55
+
56
+ // private
57
+ _buildDropdown: function()
58
+ {
59
+ var $dropdown = $R.dom('<div class="redactor-dropdown-cells">');
60
+
61
+ this.$selector = this._buildSelector();
62
+
63
+ this.$selectorText = this._buildSelectorItem('text', this.lang.get('text'));
64
+ this.$selectorText.addClass('active');
65
+
66
+ this.$selectorBack = this._buildSelectorItem('back', this.lang.get('highlight'));
67
+
68
+ this.$selector.append(this.$selectorText);
69
+ this.$selector.append(this.$selectorBack);
70
+
71
+ this.$pickerText = this._buildPicker('textcolor');
72
+ this.$pickerBack = this._buildPicker('backcolor');
73
+
74
+ $dropdown.append(this.$selector);
75
+ $dropdown.append(this.$pickerText);
76
+ $dropdown.append(this.$pickerBack);
77
+
78
+ this._buildSelectorEvents();
79
+
80
+ $dropdown.width(242);
81
+
82
+ return $dropdown;
83
+ },
84
+ _buildSelector: function()
85
+ {
86
+ var $selector = $R.dom('<div>');
87
+ $selector.addClass('redactor-dropdown-selector');
88
+
89
+ return $selector;
90
+ },
91
+ _buildSelectorItem: function(name, title)
92
+ {
93
+ var $item = $R.dom('<span>');
94
+ $item.attr('rel', name).html(title);
95
+ $item.addClass('redactor-dropdown-not-close');
96
+
97
+ return $item;
98
+ },
99
+ _buildSelectorEvents: function()
100
+ {
101
+ this.$selectorText.on('mousedown', function(e)
102
+ {
103
+ e.preventDefault();
104
+
105
+ this.$selector.find('span').removeClass('active');
106
+ this.$pickerBack.hide();
107
+ this.$pickerText.show();
108
+ this.$selectorText.addClass('active');
109
+
110
+ }.bind(this));
111
+
112
+ this.$selectorBack.on('mousedown', function(e)
113
+ {
114
+ e.preventDefault();
115
+
116
+ this.$selector.find('span').removeClass('active');
117
+ this.$pickerText.hide();
118
+ this.$pickerBack.show();
119
+ this.$selectorBack.addClass('active');
120
+
121
+ }.bind(this));
122
+ },
123
+ _buildPicker: function(name)
124
+ {
125
+ var $box = $R.dom('<div class="re-dropdown-box-' + name + '">');
126
+ var rule = (name == 'backcolor') ? 'background-color' : 'color';
127
+ var len = this.colors.length;
128
+ var self = this;
129
+ var func = function(e)
130
+ {
131
+ e.preventDefault();
132
+
133
+ var $el = $R.dom(e.target);
134
+ self._set($el.data('rule'), $el.attr('rel'));
135
+ };
136
+
137
+ for (var z = 0; z < len; z++)
138
+ {
139
+ var color = this.colors[z];
140
+
141
+ var $swatch = $R.dom('<span>');
142
+ $swatch.attr({ 'rel': color, 'data-rule': rule });
143
+ $swatch.css({ 'background-color': color, 'font-size': 0, 'border': '2px solid #fff', 'width': '22px', 'height': '22px' });
144
+ $swatch.on('mousedown', func);
145
+
146
+ $box.append($swatch);
147
+ }
148
+
149
+ var $el = $R.dom('<a>');
150
+ $el.attr({ 'href': '#' });
151
+ $el.css({ 'display': 'block', 'clear': 'both', 'padding': '8px 5px', 'font-size': '12px', 'line-height': 1 });
152
+ $el.html(this.lang.get('none'));
153
+
154
+ $el.on('click', function(e)
155
+ {
156
+ e.preventDefault();
157
+ self._remove(rule);
158
+ });
159
+
160
+ $box.append($el);
161
+
162
+ if (name == 'backcolor') $box.hide();
163
+
164
+ return $box;
165
+ },
166
+ _set: function(rule, value)
167
+ {
168
+ var style = {};
169
+ style[rule] = value;
170
+
171
+ var args = {
172
+ tag: 'span',
173
+ style: style,
174
+ type: 'toggle'
175
+ };
176
+
177
+ this.inline.format(args);
178
+ },
179
+ _remove: function(rule)
180
+ {
181
+ this.inline.remove({ style: rule });
182
+ }
183
+ });
184
+ })(Redactor);
@@ -0,0 +1 @@
1
+ !function(a){a.add("plugin","fontcolor",{translations:{en:{fontcolor:"Text Color",text:"Text",highlight:"Highlight"}},init:function(t){this.app=t,this.opts=t.opts,this.lang=t.lang,this.inline=t.inline,this.toolbar=t.toolbar,this.selection=t.selection,this.colors=this.opts.fontcolors?this.opts.fontcolors:["#ffffff","#000000","#eeece1","#1f497d","#4f81bd","#c0504d","#9bbb59","#8064a2","#4bacc6","#f79646","#ffff00","#f2f2f2","#7f7f7f","#ddd9c3","#c6d9f0","#dbe5f1","#f2dcdb","#ebf1dd","#e5e0ec","#dbeef3","#fdeada","#fff2ca","#d8d8d8","#595959","#c4bd97","#8db3e2","#b8cce4","#e5b9b7","#d7e3bc","#ccc1d9","#b7dde8","#fbd5b5","#ffe694","#bfbfbf","#3f3f3f","#938953","#548dd4","#95b3d7","#d99694","#c3d69b","#b2a2c7","#b7dde8","#fac08f","#f2c314","#a5a5a5","#262626","#494429","#17365d","#366092","#953734","#76923c","#5f497a","#92cddc","#e36c09","#c09100","#7f7f7f","#0c0c0c","#1d1b10","#0f243e","#244061","#632423","#4f6128","#3f3151","#31859b","#974806","#7f6000"]},onfontcolor:{set:function(t,e){this._set(t,e)},remove:function(t){this._remove(t)}},start:function(){var t={title:this.lang.get("fontcolor")},e=this._buildDropdown();this.$button=this.toolbar.addButton("fontcolor",t),this.$button.setIcon('<i class="re-icon-fontcolor"></i>'),this.$button.setDropdown(e)},_buildDropdown:function(){var t=a.dom('<div class="redactor-dropdown-cells">');return this.$selector=this._buildSelector(),this.$selectorText=this._buildSelectorItem("text",this.lang.get("text")),this.$selectorText.addClass("active"),this.$selectorBack=this._buildSelectorItem("back",this.lang.get("highlight")),this.$selector.append(this.$selectorText),this.$selector.append(this.$selectorBack),this.$pickerText=this._buildPicker("textcolor"),this.$pickerBack=this._buildPicker("backcolor"),t.append(this.$selector),t.append(this.$pickerText),t.append(this.$pickerBack),this._buildSelectorEvents(),t.width(242),t},_buildSelector:function(){var t=a.dom("<div>");return t.addClass("redactor-dropdown-selector"),t},_buildSelectorItem:function(t,e){var o=a.dom("<span>");return o.attr("rel",t).html(e),o.addClass("redactor-dropdown-not-close"),o},_buildSelectorEvents:function(){this.$selectorText.on("mousedown",function(t){t.preventDefault(),this.$selector.find("span").removeClass("active"),this.$pickerBack.hide(),this.$pickerText.show(),this.$selectorText.addClass("active")}.bind(this)),this.$selectorBack.on("mousedown",function(t){t.preventDefault(),this.$selector.find("span").removeClass("active"),this.$pickerText.hide(),this.$pickerBack.show(),this.$selectorBack.addClass("active")}.bind(this))},_buildPicker:function(t){function e(t){t.preventDefault();var e=a.dom(t.target);c._set(e.data("rule"),e.attr("rel"))}for(var o=a.dom('<div class="re-dropdown-box-'+t+'">'),i="backcolor"==t?"background-color":"color",s=this.colors.length,c=this,r=0;r<s;r++){var n=this.colors[r],d=a.dom("<span>");d.attr({rel:n,"data-rule":i}),d.css({"background-color":n,"font-size":0,border:"2px solid #fff",width:"22px",height:"22px"}),d.on("mousedown",e),o.append(d)}var l=a.dom("<a>");return l.attr({href:"#"}),l.css({display:"block",clear:"both",padding:"8px 5px","font-size":"12px","line-height":1}),l.html(this.lang.get("none")),l.on("click",function(t){t.preventDefault(),c._remove(i)}),o.append(l),"backcolor"==t&&o.hide(),o},_set:function(t,e){var o={};o[t]=e;var i={tag:"span",style:o,type:"toggle"};this.inline.format(i)},_remove:function(t){this.inline.remove({style:t})}})}(Redactor);
@@ -0,0 +1,59 @@
1
+ (function($R)
2
+ {
3
+ $R.add('plugin', 'fontfamily', {
4
+ translations: {
5
+ en: {
6
+ "fontfamily": "Font",
7
+ "remove-font-family": "Remove Font Family"
8
+ }
9
+ },
10
+ init: function(app)
11
+ {
12
+ this.app = app;
13
+ this.opts = app.opts;
14
+ this.lang = app.lang;
15
+ this.inline = app.inline;
16
+ this.toolbar = app.toolbar;
17
+
18
+ // local
19
+ this.fonts = (this.opts.fontfamily) ? this.opts.fontfamily : ['Arial', 'Helvetica', 'Georgia', 'Times New Roman', 'Monospace'];
20
+ },
21
+ // public
22
+ start: function()
23
+ {
24
+ var dropdown = {};
25
+ for (var i = 0; i < this.fonts.length; i++)
26
+ {
27
+ var font = this.fonts[i];
28
+ dropdown[i] = {
29
+ title: font.replace(/'/g, ''),
30
+ api: 'plugin.fontfamily.set',
31
+ args: font
32
+ };
33
+ }
34
+
35
+ dropdown.remove = {
36
+ title: this.lang.get('remove-font-family'),
37
+ api: 'plugin.fontfamily.remove'
38
+ };
39
+
40
+ var $button = this.toolbar.addButton('fontfamily', { title: this.lang.get('fontfamily') });
41
+ $button.setIcon('<i class="re-icon-fontfamily"></i>');
42
+ $button.setDropdown(dropdown);
43
+ },
44
+ set: function(value)
45
+ {
46
+ var args = {
47
+ tag: 'span',
48
+ style: { 'font-family': value },
49
+ type: 'toggle'
50
+ };
51
+
52
+ this.inline.format(args);
53
+ },
54
+ remove: function()
55
+ {
56
+ this.inline.remove({ style: 'font-family' });
57
+ }
58
+ });
59
+ })(Redactor);
@@ -0,0 +1 @@
1
+ Redactor.add("plugin","fontfamily",{translations:{en:{fontfamily:"Font","remove-font-family":"Remove Font Family"}},init:function(t){this.app=t,this.opts=t.opts,this.lang=t.lang,this.inline=t.inline,this.toolbar=t.toolbar,this.fonts=this.opts.fontfamily?this.opts.fontfamily:["Arial","Helvetica","Georgia","Times New Roman","Monospace"]},start:function(){for(var t={},i=0;i<this.fonts.length;i++){var n=this.fonts[i];t[i]={title:n.replace(/'/g,""),api:"plugin.fontfamily.set",args:n}}t.remove={title:this.lang.get("remove-font-family"),api:"plugin.fontfamily.remove"};var o=this.toolbar.addButton("fontfamily",{title:this.lang.get("fontfamily")});o.setIcon('<i class="re-icon-fontfamily"></i>'),o.setDropdown(t)},set:function(t){var i={tag:"span",style:{"font-family":t},type:"toggle"};this.inline.format(i)},remove:function(){this.inline.remove({style:"font-family"})}});