redactor-paperclip 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2012 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ = RedactorPaperclip
2
+
3
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'RedactorPaperclip'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+ Bundler::GemHelper.install_tasks
27
+
28
+ require 'rake/testtask'
29
+
30
+ Rake::TestTask.new(:test) do |t|
31
+ t.libs << 'lib'
32
+ t.libs << 'test'
33
+ t.pattern = 'test/**/*_test.rb'
34
+ t.verbose = false
35
+ end
36
+
37
+
38
+ task :default => :test
@@ -0,0 +1,3405 @@
1
+ /*
2
+ Redactor v8.0.3
3
+ Updated: September 3, 2012
4
+
5
+ http://redactorjs.com/
6
+
7
+ Copyright (c) 2009-2012, Imperavi Inc.
8
+ License: http://redactorjs.com/license/
9
+
10
+ Usage: $('#content').redactor();
11
+ */
12
+
13
+ // selection mechanism
14
+ var _0xf6db=["(6(){11 49=24;11 14={50:6(8,10){5 10.58(8)\x2692},57:6(8,10){7(8.58!=12){5 8.58(10)\x2616}46{5 8.57(10)}},55:6(8,18,10,20){7(8===10){5 18\x3C=20}7(14.29(8)\x26\x2614.29(10)){5 14.50(8,10)}7(14.29(8)\x26\x26!14.29(10)){5!14.55(10,20,8,18)}7(!14.57(8,10)){5 14.50(8,10)}7(8.47.85\x3C=18){5 40}7(8.47[18]===10){5 0\x3C=20}5 14.50(8.47[18],10)},29:6(61){5(61!=12?61.93==3:40)},81:6(41){11 62=0;88(41=41.59){62++}5 62}};11 4=49.4=(6(){6 4(2){24.2=2}4.34.31=6(){5 4.31(24.2)};4.34.37=6(){5 4.37(24.2)};4.34.38=6(){5 4.38(24.2)};4.34.45=6(){5 4.45(24.2)};4.34.44=6(){5 4.44(24.2)};4.34.52=6(25,26,23,22){5 4.52(24.2,25,26,23,22)};4.34.51=6(){5 4.51(24.2)};5 4})();7(49.35){4.67=43;4.31=6(2){11 9;5(9=2.35())\x26\x26(9.63!=12)\x26\x26(9.36!=12)};4.37=6(2){11 9;7(!((9=2.35())\x26\x26(9.36!=12))){5 12}5[9.36,9.97]};4.38=6(2){11 9;7(!((9=2.35())\x26\x26(9.63!=12))){5 12}5[9.63,9.91]};4.45=6(2){11 8,10,18,20,27,28;7(!4.31(2)){5 12}27=4.37(2),8=27[0],18=27[1];28=4.38(2),10=28[0],20=28[1];7(14.55(8,18,10,20)){5[8,18]}5[10,20]};4.44=6(2){11 8,10,18,20,27,28;7(!4.31(2)){5 12}27=4.37(2),8=27[0],18=27[1];28=4.38(2),10=28[0],20=28[1];7(14.55(8,18,10,20)){5[10,20]}5[8,18]};4.52=6(2,25,26,23,22){11 9=2.35();7(!9){5}7(23==12){23=25}7(22==12){22=26}7(9.60\x26\x269.79){9.60(25,26);9.79(23,22)}46{54=2.15.56();54.106(25,26);54.107(23,22);71{9.73()}80(41){}9.98(54)}};4.51=6(2){71{11 9=2.35();7(!9){5}9.73()}80(41){}}}46 7(49.15.39){11 69=6(42,32,30){11 19,13,21,33,64;13=42.90(\x2789\x27);19=32.103();19.60(30);64=19.77();88(43){64.86(13,13.59);19.82(13);7(!(19.87((30?\x2766\x27:\x2783\x27),32)\x3E0\x26\x26(13.59!=12))){99}}7(19.87((30?\x2766\x27:\x2783\x27),32)===-1\x26\x2613.84){19.74((30?\x27100\x27:\x2778\x27),32);21=13.84;33=19.101.85}46{21=13.48;33=14.81(13)}13.48.72(13);5[21,33]};11 68=6(42,32,30,21,33){11 36,65,19,13,53;53=0;36=14.29(21)?21:21.47[33];65=14.29(21)?21.48:21;7(14.29(21)){53=33}13=42.90(\x2789\x27);65.86(13,36||12);19=42.76.75();19.82(13);13.48.72(13);32.74((30?\x2766\x27:\x2778\x27),19);5 32[30?\x27105\x27:\x27104\x27](\x27102\x27,53)};4.67=43;4.31=6(2){11 17;2.70();7(!2.15.39){5 40}17=2.15.39.56();5 17\x26\x2617.77().15===2.15};4.45=6(2){11 17;2.70();7(!4.31(2)){5 12}17=2.15.39.56();5 69(2.15,17,43)};4.44=6(2){11 17;2.70();7(!4.31(2)){5 12}17=2.15.39.56();5 69(2.15,17,40)};4.37=6(2){5 4.45(2)};4.38=6(2){5 4.44(2)};4.52=6(2,25,26,23,22){7(23==12){23=25}7(22==12){22=26}11 17=2.15.76.75();68(2.15,17,40,23,22);68(2.15,17,43,25,26);5 17.96()};4.51=6(2){5 2.15.39.95()}}46{4.67=40}}).94(24);","|","split","||win||Selection|return|function|if|n1|sel|n2|var|null|cursorNode|Dom|document||range|o1|cursor|o2|node|foco|focn|this|orgn|orgo|_ref|_ref2|isText|bStart|hasSelection|textRange|offset|prototype|getSelection|anchorNode|getOrigin|getFocus|selection|false|e|doc|true|getEnd|getStart|else|childNodes|parentNode|root|isPreceding|clearSelection|setSelection|textOffset|r|isCursorPreceding|createRange|contains|compareDocumentPosition|previousSibling|collapse|d|k|focusNode|parent|anchorParent|StartToStart|supported|moveBoundary|getBoundary|focus|try|removeChild|removeAllRanges|setEndPoint|createTextRange|body|parentElement|EndToEnd|extend|catch|getChildIndex|moveToElementText|StartToEnd|nextSibling|length|insertBefore|compareEndPoints|while|a|createElement|focusOffset|0x02|nodeType|call|empty|select|anchorOffset|addRange|break|EndToStart|text|character|duplicate|moveEnd|moveStart|setStart|setEnd","replace","","\x5Cw+","\x5Cb","g"];eval(function (p,a,c,k,e,d){e=function (c){return c;} ;if(!_0xf6db[5][_0xf6db[4]](/^/,String)){while(c--){d[c]=k[c]||c;} ;k=[function (e){return d[e];} ];e=function (){return _0xf6db[6];} ;c=1;} ;while(c--){if(k[c]){p=p[_0xf6db[4]]( new RegExp(_0xf6db[7]+e(c)+_0xf6db[7],_0xf6db[8]),k[c]);} ;} ;return p;} (_0xf6db[0],10,108,_0xf6db[3][_0xf6db[2]](_0xf6db[1]),0,{}));
15
+
16
+ if (typeof RELANG === 'undefined')
17
+ {
18
+ var RELANG = {};
19
+ }
20
+
21
+ var RLANG = {
22
+ html: 'HTML',
23
+ video: 'Insert Video...',
24
+ image: 'Insert Image...',
25
+ table: 'Table',
26
+ link: 'Link',
27
+ link_insert: 'Insert Link ...',
28
+ unlink: 'Unlink',
29
+ formatting: 'Formatting',
30
+ paragraph: 'Paragraph',
31
+ quote: 'Quote',
32
+ code: 'Code',
33
+ header1: 'Header 1',
34
+ header2: 'Header 2',
35
+ header3: 'Header 3',
36
+ header4: 'Header 4',
37
+ bold: 'Bold',
38
+ italic: 'Italic',
39
+ fontcolor: 'Font Color',
40
+ backcolor: 'Back Color',
41
+ unorderedlist: 'Unordered List',
42
+ orderedlist: 'Ordered List',
43
+ outdent: 'Outdent',
44
+ indent: 'Indent',
45
+ cancel: 'Cancel',
46
+ insert: 'Insert',
47
+ save: 'Save',
48
+ _delete: 'Delete',
49
+ insert_table: 'Insert Table...',
50
+ insert_row_above: 'Add Row Above',
51
+ insert_row_below: 'Add Row Below',
52
+ insert_column_left: 'Add Column Left',
53
+ insert_column_right: 'Add Column Right',
54
+ delete_column: 'Delete Column',
55
+ delete_row: 'Delete Row',
56
+ delete_table: 'Delete Table',
57
+ rows: 'Rows',
58
+ columns: 'Columns',
59
+ add_head: 'Add Head',
60
+ delete_head: 'Delete Head',
61
+ title: 'Title',
62
+ image_position: 'Position',
63
+ none: 'None',
64
+ left: 'Left',
65
+ right: 'Right',
66
+ image_web_link: 'Image Web Link',
67
+ text: 'Text',
68
+ mailto: 'Email',
69
+ web: 'URL',
70
+ video_html_code: 'Video Embed Code',
71
+ file: 'Insert File...',
72
+ upload: 'Upload',
73
+ download: 'Download',
74
+ choose: 'Choose',
75
+ or_choose: 'Or choose',
76
+ drop_file_here: 'Drop file here',
77
+ align_left: 'Align Left',
78
+ align_center: 'Align Center',
79
+ align_right: 'Align Right',
80
+ align_justify: 'Justify',
81
+ horizontalrule: 'Insert Horizontal Rule',
82
+ deleted: 'Deleted',
83
+ anchor: 'Anchor',
84
+ link_new_tab: 'Open link in new tab'
85
+ };
86
+
87
+ (function($){
88
+
89
+ // Plugin
90
+ jQuery.fn.redactor = function(option)
91
+ {
92
+ return this.each(function()
93
+ {
94
+ var $obj = $(this);
95
+
96
+ var data = $obj.data('redactor');
97
+ if (!data)
98
+ {
99
+ $obj.data('redactor', (data = new Redactor(this, option)));
100
+ }
101
+ });
102
+ };
103
+
104
+
105
+ // Initialization
106
+ var Redactor = function(element, options)
107
+ {
108
+ // Element
109
+ this.$el = $(element);
110
+
111
+ // Lang
112
+ if (typeof options !== 'undefined' && typeof options.lang !== 'undefined' && options.lang !== 'en' && typeof RELANG[options.lang] !== 'undefined')
113
+ {
114
+ RLANG = RELANG[options.lang];
115
+ }
116
+
117
+ // Options
118
+ this.opts = $.extend({
119
+
120
+ lang: 'en',
121
+ direction: 'ltr', // ltr or rtl
122
+
123
+ callback: false, // function
124
+ keyupCallback: false, // function
125
+ keydownCallback: false, // function
126
+ execCommandCallback: false, // function
127
+
128
+ cleanup: true,
129
+
130
+ focus: false,
131
+ tabindex: false,
132
+ autoresize: true,
133
+ minHeight: false,
134
+ fixed: false,
135
+ fixedTop: 0, // pixels
136
+ fixedBox: false,
137
+ source: true,
138
+ shortcuts: true,
139
+
140
+ mobile: true,
141
+ air: false,
142
+ wym: false,
143
+
144
+ paragraphy: true,
145
+ convertLinks: true,
146
+ convertDivs: true,
147
+ protocol: 'http://', // for links http or https
148
+
149
+ autosave: false, // false or url
150
+ autosaveCallback: false, // function
151
+ interval: 60, // seconds
152
+
153
+ imageGetJson: false, // url (ex. /folder/images.json ) or false
154
+
155
+ imageUpload: false, // url
156
+ imageUploadCallback: false, // function
157
+
158
+ fileUpload: false, // url
159
+ fileUploadCallback: false, // function
160
+
161
+ uploadCrossDomain: false,
162
+ uploadFields: false,
163
+
164
+ observeImages: true,
165
+ overlay: true, // modal overlay
166
+
167
+ allowedTags: ["code", "span", "div", "label", "a", "br", "p", "b", "i", "del", "strike", "u",
168
+ "img", "video", "audio", "iframe", "object", "embed", "param", "blockquote",
169
+ "mark", "cite", "small", "ul", "ol", "li", "hr", "dl", "dt", "dd", "sup", "sub",
170
+ "big", "pre", "code", "figure", "figcaption", "strong", "em", "table", "tr", "td",
171
+ "th", "tbody", "thead", "tfoot", "h1", "h2", "h3", "h4", "h5", "h6"],
172
+
173
+ buttonsCustom: {},
174
+ buttonsAdd: [],
175
+ buttons: ['html', '|', 'formatting', '|', 'bold', 'italic', 'deleted', '|', 'unorderedlist', 'orderedlist', 'outdent', 'indent', '|',
176
+ 'image', 'video', 'file', 'table', 'link', '|',
177
+ 'fontcolor', 'backcolor', '|', 'alignleft', 'aligncenter', 'alignright', 'justify', '|', 'horizontalrule'],
178
+
179
+ airButtons: ['formatting', '|', 'bold', 'italic', 'deleted', '|', 'unorderedlist', 'orderedlist', 'outdent', 'indent', '|', 'fontcolor', 'backcolor'],
180
+
181
+ colors: [
182
+ '#ffffff', '#000000', '#eeece1', '#1f497d', '#4f81bd', '#c0504d', '#9bbb59', '#8064a2', '#4bacc6', '#f79646', '#ffff00',
183
+ '#f2f2f2', '#7f7f7f', '#ddd9c3', '#c6d9f0', '#dbe5f1', '#f2dcdb', '#ebf1dd', '#e5e0ec', '#dbeef3', '#fdeada', '#fff2ca',
184
+ '#d8d8d8', '#595959', '#c4bd97', '#8db3e2', '#b8cce4', '#e5b9b7', '#d7e3bc', '#ccc1d9', '#b7dde8', '#fbd5b5', '#ffe694',
185
+ '#bfbfbf', '#3f3f3f', '#938953', '#548dd4', '#95b3d7', '#d99694', '#c3d69b', '#b2a2c7', '#b7dde8', '#fac08f', '#f2c314',
186
+ '#a5a5a5', '#262626', '#494429', '#17365d', '#366092', '#953734', '#76923c', '#5f497a', '#92cddc', '#e36c09', '#c09100',
187
+ '#7f7f7f', '#0c0c0c', '#1d1b10', '#0f243e', '#244061', '#632423', '#4f6128', '#3f3151', '#31859b', '#974806', '#7f6000'],
188
+
189
+ // private
190
+ allEmptyHtml: '<p><br /></p>',
191
+ mozillaEmptyHtml: '<p>&nbsp;</p>',
192
+ buffer: false,
193
+ visual: true,
194
+
195
+ // modal windows container
196
+ modal_file: String() +
197
+ '<form id="redactorUploadFileForm" method="post" action="" enctype="multipart/form-data">' +
198
+ '<label>Name (optional)</label>' +
199
+ '<input type="text" id="redactor_filename" class="redactor_input" />' +
200
+ '<div style="margin-top: 7px;">' +
201
+ '<input type="file" id="redactor_file" name="file" />' +
202
+ '</div>' +
203
+ '</form>',
204
+
205
+ modal_image_edit: String() +
206
+ '<label>' + RLANG.title + '</label>' +
207
+ '<input id="redactor_file_alt" class="redactor_input" />' +
208
+ '<label>' + RLANG.link + '</label>' +
209
+ '<input id="redactor_file_link" class="redactor_input" />' +
210
+ '<label>' + RLANG.image_position + '</label>' +
211
+ '<select id="redactor_form_image_align">' +
212
+ '<option value="none">' + RLANG.none + '</option>' +
213
+ '<option value="left">' + RLANG.left + '</option>' +
214
+ '<option value="right">' + RLANG.right + '</option>' +
215
+ '</select>' +
216
+ '<div id="redactor_modal_footer">' +
217
+ '<a href="javascript:void(null);" id="redactor_image_delete_btn" style="color: #000;">' + RLANG._delete + '</a>' +
218
+ '<span class="redactor_btns_box">' +
219
+ '<input type="button" name="save" id="redactorSaveBtn" value="' + RLANG.save + '" />' +
220
+ '<a href="javascript:void(null);" id="redactor_btn_modal_close">' + RLANG.cancel + '</a>' +
221
+ '</span>' +
222
+ '</div>',
223
+
224
+ modal_image: String() +
225
+ '<div id="redactor_tabs">' +
226
+ '<a href="javascript:void(null);" class="redactor_tabs_act">' + RLANG.upload + '</a>' +
227
+ '<a href="javascript:void(null);">' + RLANG.choose + '</a>' +
228
+ '<a href="javascript:void(null);">' + RLANG.link + '</a>' +
229
+ '</div>' +
230
+ '<form id="redactorInsertImageForm" method="post" action="" enctype="multipart/form-data">' +
231
+ '<div id="redactor_tab1" class="redactor_tab">' +
232
+ '<input type="file" id="redactor_file" name="file" />' +
233
+ '</div>' +
234
+ '<div id="redactor_tab2" class="redactor_tab" style="display: none;">' +
235
+ '<div id="redactor_image_box"></div>' +
236
+ '</div>' +
237
+ '</form>' +
238
+ '<div id="redactor_tab3" class="redactor_tab" style="display: none;">' +
239
+ '<label>' + RLANG.image_web_link + '</label>' +
240
+ '<input name="redactor_file_link" id="redactor_file_link" class="redactor_input" />' +
241
+ '</div>' +
242
+ '<div id="redactor_modal_footer">' +
243
+ '<span class="redactor_btns_box">' +
244
+ '<input type="button" name="upload" id="redactor_upload_btn" value="' + RLANG.insert + '" />' +
245
+ '<a href="javascript:void(null);" id="redactor_btn_modal_close">' + RLANG.cancel + '</a>' +
246
+ '</span>' +
247
+ '</div>',
248
+
249
+ modal_link: String() +
250
+ '<form id="redactorInsertLinkForm" method="post" action="">' +
251
+ '<div id="redactor_tabs">' +
252
+ '<a href="javascript:void(null);" class="redactor_tabs_act">URL</a>' +
253
+ '<a href="javascript:void(null);">Email</a>' +
254
+ '<a href="javascript:void(null);">' + RLANG.anchor + '</a>' +
255
+ '</div>' +
256
+ '<input type="hidden" id="redactor_tab_selected" value="1" />' +
257
+ '<div class="redactor_tab" id="redactor_tab1">' +
258
+ '<label>URL</label><input id="redactor_link_url" class="redactor_input" />' +
259
+ '<label>' + RLANG.text + '</label><input class="redactor_input redactor_link_text" id="redactor_link_url_text" />' +
260
+ '<label><input type="checkbox" id="redactor_link_blank"> ' + RLANG.link_new_tab +
261
+ '</div>' +
262
+ '<div class="redactor_tab" id="redactor_tab2" style="display: none;">' +
263
+ '<label>Email</label><input id="redactor_link_mailto" class="redactor_input" />' +
264
+ '<label>' + RLANG.text + '</label><input class="redactor_input redactor_link_text" id="redactor_link_mailto_text" />' +
265
+ '</div>' +
266
+ '<div class="redactor_tab" id="redactor_tab3" style="display: none;">' +
267
+ '<label>' + RLANG.anchor + '</label><input class="redactor_input" id="redactor_link_anchor" />' +
268
+ '<label>' + RLANG.text + '</label><input class="redactor_input redactor_link_text" id="redactor_link_anchor_text" />' +
269
+ '</div>' +
270
+ '</form>' +
271
+ '<div id="redactor_modal_footer">' +
272
+ '<span class="redactor_btns_box">' +
273
+ '<input type="button" id="redactor_insert_link_btn" value="' + RLANG.insert + '" />' +
274
+ '<a href="javascript:void(null);" id="redactor_btn_modal_close">' + RLANG.cancel + '</a>' +
275
+ '</span>' +
276
+ '</div>',
277
+
278
+ modal_table: String() +
279
+ '<label>' + RLANG.rows + '</label>' +
280
+ '<input size="5" value="2" id="redactor_table_rows" />' +
281
+ '<label>' + RLANG.columns + '</label>' +
282
+ '<input size="5" value="3" id="redactor_table_columns" />' +
283
+ '<div id="redactor_modal_footer">' +
284
+ '<span class="redactor_btns_box">' +
285
+ '<input type="button" name="upload" id="redactor_insert_table_btn" value="' + RLANG.insert + '" />' +
286
+ '<a href="javascript:void(null);" id="redactor_btn_modal_close">' + RLANG.cancel + '</a>' +
287
+ '</span>' +
288
+ '</div>',
289
+
290
+ modal_video: String() +
291
+ '<form id="redactorInsertVideoForm">' +
292
+ '<label>' + RLANG.video_html_code + '</label>' +
293
+ '<textarea id="redactor_insert_video_area" style="width: 99%; height: 160px;"></textarea>' +
294
+ '</form>' +
295
+ '<div id="redactor_modal_footer">' +
296
+ '<span class="redactor_btns_box">' +
297
+ '<input type="button" id="redactor_insert_video_btn" value="' + RLANG.insert + '" />' +
298
+ '<a href="javascript:void(null);" id="redactor_btn_modal_close">' + RLANG.cancel + '</a>' +
299
+ '</span>' +
300
+ '</div>',
301
+
302
+
303
+ toolbar: {
304
+ html:
305
+ {
306
+ title: RLANG.html,
307
+ func: 'toggle'
308
+ },
309
+ formatting:
310
+ {
311
+ title: RLANG.formatting,
312
+ func: 'show',
313
+ dropdown:
314
+ {
315
+ p:
316
+ {
317
+ title: RLANG.paragraph,
318
+ exec: 'formatblock'
319
+ },
320
+ blockquote:
321
+ {
322
+ title: RLANG.quote,
323
+ exec: 'formatblock',
324
+ className: 'redactor_format_blockquote'
325
+ },
326
+ pre:
327
+ {
328
+ title: RLANG.code,
329
+ exec: 'formatblock',
330
+ className: 'redactor_format_pre'
331
+ },
332
+ h1:
333
+ {
334
+ title: RLANG.header1,
335
+ exec: 'formatblock',
336
+ className: 'redactor_format_h1'
337
+ },
338
+ h2:
339
+ {
340
+ title: RLANG.header2,
341
+ exec: 'formatblock',
342
+ className: 'redactor_format_h2'
343
+ },
344
+ h3:
345
+ {
346
+ title: RLANG.header3,
347
+ exec: 'formatblock',
348
+ className: 'redactor_format_h3'
349
+ },
350
+ h4:
351
+ {
352
+ title: RLANG.header4,
353
+ exec: 'formatblock',
354
+ className: 'redactor_format_h4'
355
+ }
356
+ }
357
+ },
358
+ bold:
359
+ {
360
+ title: RLANG.bold,
361
+ exec: 'bold'
362
+ },
363
+ italic:
364
+ {
365
+ title: RLANG.italic,
366
+ exec: 'italic'
367
+ },
368
+ deleted:
369
+ {
370
+ title: RLANG.deleted,
371
+ exec: 'strikethrough'
372
+ },
373
+ unorderedlist:
374
+ {
375
+ title: '&bull; ' + RLANG.unorderedlist,
376
+ exec: 'insertunorderedlist'
377
+ },
378
+ orderedlist:
379
+ {
380
+ title: '1. ' + RLANG.orderedlist,
381
+ exec: 'insertorderedlist'
382
+ },
383
+ outdent:
384
+ {
385
+ title: '< ' + RLANG.outdent,
386
+ exec: 'outdent'
387
+ },
388
+ indent:
389
+ {
390
+ title: '> ' + RLANG.indent,
391
+ exec: 'indent'
392
+ },
393
+ image:
394
+ {
395
+ title: RLANG.image,
396
+ func: 'showImage'
397
+ },
398
+ video:
399
+ {
400
+ title: RLANG.video,
401
+ func: 'showVideo'
402
+ },
403
+ file:
404
+ {
405
+ title: RLANG.file,
406
+ func: 'showFile'
407
+ },
408
+ table:
409
+ {
410
+ title: RLANG.table,
411
+ func: 'show',
412
+ dropdown:
413
+ {
414
+ insert_table:
415
+ {
416
+ title: RLANG.insert_table,
417
+ func: 'showTable'
418
+ },
419
+ separator_drop1:
420
+ {
421
+ name: 'separator'
422
+ },
423
+ insert_row_above:
424
+ {
425
+ title: RLANG.insert_row_above,
426
+ func: 'insertRowAbove'
427
+ },
428
+ insert_row_below:
429
+ {
430
+ title: RLANG.insert_row_below,
431
+ func: 'insertRowBelow'
432
+ },
433
+ insert_column_left:
434
+ {
435
+ title: RLANG.insert_column_left,
436
+ func: 'insertColumnLeft'
437
+ },
438
+ insert_column_right:
439
+ {
440
+ title: RLANG.insert_column_right,
441
+ func: 'insertColumnRight'
442
+ },
443
+ separator_drop2:
444
+ {
445
+ name: 'separator'
446
+ },
447
+ add_head:
448
+ {
449
+ title: RLANG.add_head,
450
+ func: 'addHead'
451
+ },
452
+ delete_head:
453
+ {
454
+ title: RLANG.delete_head,
455
+ func: 'deleteHead'
456
+ },
457
+ separator_drop3:
458
+ {
459
+ name: 'separator'
460
+ },
461
+ delete_column:
462
+ {
463
+ title: RLANG.delete_column,
464
+ func: 'deleteColumn'
465
+ },
466
+ delete_row:
467
+ {
468
+ title: RLANG.delete_row,
469
+ func: 'deleteRow'
470
+ },
471
+ delete_table:
472
+ {
473
+ title: RLANG.delete_table,
474
+ func: 'deleteTable'
475
+ }
476
+ }
477
+ },
478
+ link:
479
+ {
480
+ title: RLANG.link,
481
+ func: 'show',
482
+ dropdown:
483
+ {
484
+ link:
485
+ {
486
+ title: RLANG.link_insert,
487
+ func: 'showLink'
488
+ },
489
+ unlink:
490
+ {
491
+ title: RLANG.unlink,
492
+ exec: 'unlink'
493
+ }
494
+ }
495
+ },
496
+ fontcolor:
497
+ {
498
+ title: RLANG.fontcolor,
499
+ func: 'show'
500
+ },
501
+ backcolor:
502
+ {
503
+ title: RLANG.backcolor,
504
+ func: 'show'
505
+ },
506
+ alignleft:
507
+ {
508
+ exec: 'JustifyLeft',
509
+ title: RLANG.align_left
510
+ },
511
+ aligncenter:
512
+ {
513
+ exec: 'JustifyCenter',
514
+ title: RLANG.align_center
515
+ },
516
+ alignright:
517
+ {
518
+ exec: 'JustifyRight',
519
+ title: RLANG.align_right
520
+ },
521
+ justify:
522
+ {
523
+ exec: 'justifyfull',
524
+ title: RLANG.align_justify
525
+ },
526
+ horizontalrule:
527
+ {
528
+ exec: 'inserthorizontalrule',
529
+ title: RLANG.horizontalrule
530
+ }
531
+ }
532
+
533
+
534
+ }, options, this.$el.data());
535
+
536
+ this.dropdowns = [];
537
+
538
+ // Init
539
+ this.init();
540
+ };
541
+
542
+ // Functionality
543
+ Redactor.prototype = {
544
+
545
+
546
+ // Initialization
547
+ init: function()
548
+ {
549
+ // set paperclip paths
550
+ if( this.opts.imageUpload == "paperclip" )
551
+ {
552
+ this.opts.imageUpload = "/redactorAssets/create"
553
+ this.opts.imageGetJson = "/redactorAssets"
554
+ }
555
+
556
+ // get dimensions
557
+ this.height = this.$el.css('height');
558
+ this.width = this.$el.css('width');
559
+
560
+ // mobile
561
+ if (this.opts.mobile === false && this.isMobile())
562
+ {
563
+ this.build(true);
564
+ return false;
565
+ }
566
+
567
+ if (this.opts.paragraphy === false)
568
+ {
569
+ this.opts.convertDivs = false;
570
+ }
571
+
572
+ // extend buttons
573
+ if (this.opts.air)
574
+ {
575
+ this.opts.buttons = this.opts.airButtons;
576
+ }
577
+ else if (this.opts.toolbar !== false)
578
+ {
579
+ if (this.opts.source === false)
580
+ {
581
+ var index = this.opts.buttons.indexOf('html');
582
+ var next = this.opts.buttons[index+1];
583
+ this.opts.buttons.splice(index, 1);
584
+ if (typeof next !== 'undefined' && next === '|')
585
+ {
586
+ this.opts.buttons.splice(index, 1);
587
+ }
588
+ }
589
+
590
+ $.extend(this.opts.toolbar, this.opts.buttonsCustom);
591
+ $.each(this.opts.buttonsAdd, $.proxy(function(i,s)
592
+ {
593
+ this.opts.buttons.push(s);
594
+
595
+ }, this));
596
+ }
597
+
598
+ // construct editor
599
+ this.build();
600
+
601
+ // air enable
602
+ this.enableAir();
603
+
604
+ // toolbar
605
+ this.buildToolbar();
606
+
607
+ // paste
608
+ var oldsafari = false;
609
+ if ($.browser.webkit && navigator.userAgent.indexOf('Chrome') === -1)
610
+ {
611
+ var arr = $.browser.version.split('.');
612
+ if (arr[0] < 536) oldsafari = true;
613
+ }
614
+
615
+ if (this.isMobile(true) === false && oldsafari === false)
616
+ {
617
+ this.$editor.bind('paste', $.proxy(function(e)
618
+ {
619
+ if (this.opts.cleanup === false)
620
+ {
621
+ return true;
622
+ }
623
+
624
+ this.setBuffer();
625
+
626
+ if (this.opts.autoresize === true)
627
+ {
628
+ this.saveScroll = document.body.scrollTop;
629
+ }
630
+ else
631
+ {
632
+ this.saveScroll = this.$editor.scrollTop();
633
+ }
634
+
635
+ var frag = this.extractContent();
636
+
637
+ setTimeout($.proxy(function()
638
+ {
639
+ var pastedFrag = this.extractContent();
640
+ this.$editor.append(frag);
641
+ this.restoreSelection();
642
+
643
+ var html = this.getFragmentHtml(pastedFrag);
644
+ this.pasteCleanUp(html);
645
+
646
+ }, this), 1);
647
+
648
+ }, this));
649
+ }
650
+
651
+ // key handlers
652
+ this.keyup();
653
+ this.keydown();
654
+
655
+ // autosave
656
+ if (this.opts.autosave !== false)
657
+ {
658
+ this.autoSave();
659
+ }
660
+
661
+ // observers
662
+ this.observeImages();
663
+ this.observeTables();
664
+
665
+ // FF fix
666
+ if ($.browser.mozilla)
667
+ {
668
+ document.execCommand('enableObjectResizing', false, false);
669
+ document.execCommand('enableInlineTableEditing', false, false);
670
+ }
671
+
672
+ // focus
673
+ if (this.opts.focus)
674
+ {
675
+ this.$editor.focus();
676
+ }
677
+
678
+ // fixed
679
+ if (this.opts.fixed)
680
+ {
681
+ this.observeScroll();
682
+ $(document).scroll($.proxy(this.observeScroll, this));
683
+ }
684
+
685
+ // callback
686
+ if (typeof this.opts.callback === 'function')
687
+ {
688
+ this.opts.callback(this);
689
+ }
690
+
691
+ },
692
+ shortcuts: function(e, cmd)
693
+ {
694
+ e.preventDefault();
695
+ this.execCommand(cmd, false);
696
+ },
697
+ keyup: function()
698
+ {
699
+ this.$editor.keyup($.proxy(function(e)
700
+ {
701
+ var key = e.keyCode || e.which;
702
+
703
+ // callback as you type
704
+ if (typeof this.opts.keyupCallback === 'function')
705
+ {
706
+ this.opts.keyupCallback(this, e);
707
+ }
708
+
709
+ // if empty
710
+ if (key === 8 || key === 46)
711
+ {
712
+ this.observeImages();
713
+ return this.formatEmpty(e);
714
+ }
715
+
716
+ // new line p
717
+ if (key === 13 && !e.shiftKey && !e.ctrlKey && !e.metaKey)
718
+ {
719
+ if ($.browser.webkit && this.opts.paragraphy)
720
+ {
721
+ this.formatNewLine(e);
722
+ }
723
+
724
+ // convert links
725
+ if (this.opts.convertLinks)
726
+ {
727
+ this.$editor.linkify();
728
+ }
729
+ }
730
+
731
+ this.syncCode();
732
+
733
+ }, this));
734
+ },
735
+ keydown: function()
736
+ {
737
+ this.$editor.keydown($.proxy(function(e)
738
+ {
739
+ var key = e.keyCode || e.which;
740
+ var parent = this.getParentNode();
741
+ var pre = false;
742
+ var ctrl = e.ctrlKey || e.metaKey;
743
+
744
+ if (parent && $(parent).get(0).tagName === 'PRE')
745
+ {
746
+ pre = true;
747
+ }
748
+
749
+ // callback keydown
750
+ if (typeof this.opts.keydownCallback === 'function')
751
+ {
752
+ this.opts.keydownCallback(this, e);
753
+ }
754
+
755
+ // breakline
756
+ if (this.opts.paragraphy === false && $.browser.webkit && key === 13 && !e.shiftKey && !e.ctrlKey && !e.metaKey)
757
+ {
758
+ e.preventDefault();
759
+ this.insertNodeAtCaret($('<span class="redactor-breakline"><br></span>').get(0));
760
+ setTimeout($.proxy(function()
761
+ {
762
+ this.$editor.find('span.redactor-breakline').replaceWith('<br>');
763
+ setTimeout($.proxy(function()
764
+ {
765
+ this.syncCode();
766
+ }, this), 10);
767
+
768
+ }, this), 10);
769
+ return false;
770
+ }
771
+
772
+ if (ctrl && this.opts.shortcuts)
773
+ {
774
+ if (key === 90)
775
+ {
776
+ if (this.opts.buffer !== false)
777
+ {
778
+ e.preventDefault();
779
+ this.getBuffer();
780
+ }
781
+ else if (e.shiftKey)
782
+ {
783
+ this.shortcuts(e, 'redo'); // Ctrl + Shift + z
784
+ }
785
+ else
786
+ {
787
+ this.shortcuts(e, 'undo'); // Ctrl + z
788
+ }
789
+ }
790
+ else if (key === 77)
791
+ {
792
+ this.shortcuts(e, 'removeFormat'); // Ctrl + m
793
+ }
794
+ else if (key === 66)
795
+ {
796
+ this.shortcuts(e, 'bold'); // Ctrl + b
797
+ }
798
+ else if (key === 73)
799
+ {
800
+ this.shortcuts(e, 'italic'); // Ctrl + i
801
+ }
802
+ else if (key === 74)
803
+ {
804
+ this.shortcuts(e, 'insertunorderedlist'); // Ctrl + j
805
+ }
806
+ else if (key === 75)
807
+ {
808
+ this.shortcuts(e, 'insertorderedlist'); // Ctrl + k
809
+ }
810
+ else if (key === 76)
811
+ {
812
+ this.shortcuts(e, 'superscript'); // Ctrl + l
813
+ }
814
+ else if (key === 72)
815
+ {
816
+ this.shortcuts(e, 'subscript'); // Ctrl + h
817
+ }
818
+ }
819
+
820
+ // clear undo buffer
821
+ if (!ctrl && key !== 90)
822
+ {
823
+ this.opts.buffer = false;
824
+ }
825
+
826
+ // enter
827
+ if (pre === true && key === 13)
828
+ {
829
+ e.preventDefault();
830
+ this.insertNodeAtCaret(document.createTextNode('\r\n'));
831
+ }
832
+
833
+ // tab
834
+ if (this.opts.shortcuts && !e.shiftKey && key === 9)
835
+ {
836
+ if (pre === false)
837
+ {
838
+ this.shortcuts(e, 'indent'); // Tab
839
+ }
840
+ else
841
+ {
842
+ e.preventDefault();
843
+ this.insertNodeAtCaret(document.createTextNode('\t'));
844
+ }
845
+ }
846
+ else if (this.opts.shortcuts && e.shiftKey && key === 9 )
847
+ {
848
+ this.shortcuts(e, 'outdent'); // Shift + tab
849
+ }
850
+
851
+ // safari shift key + enter
852
+ if ($.browser.webkit && navigator.userAgent.indexOf('Chrome') === -1)
853
+ {
854
+ return this.safariShiftKeyEnter(e, key);
855
+ }
856
+ }, this));
857
+ },
858
+ build: function(mobile)
859
+ {
860
+ if (mobile !== true)
861
+ {
862
+ // container
863
+ this.$box = $('<div class="redactor_box"></div>');
864
+
865
+ // air box
866
+ if (this.opts.air)
867
+ {
868
+ this.air = $('<div class="redactor_air" style="display: none;"></div>');
869
+ }
870
+
871
+ // editor
872
+ this.textareamode = true;
873
+ if (this.$el.get(0).tagName === 'TEXTAREA')
874
+ {
875
+ this.$editor = $('<div></div>');
876
+ }
877
+ else
878
+ {
879
+ this.textareamode = false;
880
+ this.$editor = this.$el;
881
+ this.$el = $('<textarea name="' + this.$editor.attr('id') + '"></textarea>').css('height', this.height);
882
+ }
883
+
884
+ this.$editor.addClass('redactor_editor').attr('contenteditable', true).attr('dir', this.opts.direction);
885
+
886
+ if (this.opts.tabindex !== false)
887
+ {
888
+ this.$editor.attr('tabindex', this.opts.tabindex);
889
+ }
890
+
891
+ if (this.opts.minHeight !== false)
892
+ {
893
+ this.$editor.css('min-height', this.opts.minHeight + 'px');
894
+ }
895
+
896
+ if (this.opts.wym === true)
897
+ {
898
+ this.$editor.addClass('redactor_editor_wym');
899
+ }
900
+
901
+ if (this.opts.autoresize === false)
902
+ {
903
+ this.$editor.css('height', this.height);
904
+ }
905
+
906
+ // hide textarea
907
+ this.$el.hide();
908
+
909
+ // append box and frame
910
+ var html = '';
911
+ if (this.textareamode)
912
+ {
913
+ // get html
914
+ html = this.$el.val();
915
+
916
+ this.$box.insertAfter(this.$el).append(this.$editor).append(this.$el);
917
+ }
918
+ else
919
+ {
920
+ // get html
921
+ html = this.$editor.html();
922
+
923
+ this.$box.insertAfter(this.$editor).append(this.$el).append(this.$editor);
924
+
925
+ }
926
+
927
+ // conver newlines to p
928
+ if (this.opts.paragraphy)
929
+ {
930
+ html = this.paragraphy(html);
931
+ }
932
+ else
933
+ {
934
+ html = html.replace(/<p>([\w\W]*?)<\/p>/gi, '$1<br><br>');
935
+ }
936
+
937
+ // enable
938
+ this.$editor.html(html);
939
+
940
+ if (this.textareamode === false)
941
+ {
942
+ this.syncCode();
943
+ }
944
+ }
945
+ else
946
+ {
947
+ if (this.$el.get(0).tagName !== 'TEXTAREA')
948
+ {
949
+ var html = this.$el.val();
950
+ var textarea = $('<textarea name="' + this.$editor.attr('id') + '"></textarea>').css('height', this.height).val(html);
951
+ this.$el.hide();
952
+ this.$el.after(textarea);
953
+ }
954
+ }
955
+
956
+ },
957
+ enableAir: function()
958
+ {
959
+ if (this.opts.air === false)
960
+ {
961
+ return false;
962
+ }
963
+
964
+ this.air.hide();
965
+
966
+ this.$editor.bind('textselect', $.proxy(function(e)
967
+ {
968
+ this.showAir(e);
969
+
970
+ }, this));
971
+
972
+ this.$editor.bind('textunselect', $.proxy(function()
973
+ {
974
+ this.air.hide();
975
+
976
+ }, this));
977
+
978
+ },
979
+ showAir: function(e)
980
+ {
981
+ $('.redactor_air').hide();
982
+
983
+ var width = this.air.innerWidth();
984
+ var left = e.clientX;
985
+
986
+ if ($(document).width() < (left + width))
987
+ {
988
+ left = left - width;
989
+ }
990
+
991
+ this.air.css({ left: left + 'px', top: (e.clientY + $(document).scrollTop() + 14) + 'px' }).show();
992
+ },
993
+ syncCode: function()
994
+ {
995
+ this.$el.val(this.$editor.html());
996
+ },
997
+
998
+ // API functions
999
+ setCode: function(html)
1000
+ {
1001
+ this.$editor.html(html).focus();
1002
+
1003
+ this.syncCode();
1004
+ },
1005
+ getCode: function()
1006
+ {
1007
+ if (this.opts.visual)
1008
+ {
1009
+ return this.$editor.html()
1010
+ }
1011
+ else
1012
+ {
1013
+ return this.$el.val();
1014
+ }
1015
+ },
1016
+ insertHtml: function(html)
1017
+ {
1018
+ this.$editor.focus();
1019
+ this.execCommand('inserthtml', html);
1020
+ this.observeImages();
1021
+ },
1022
+ destroy: function()
1023
+ {
1024
+ var html = this.getCode();
1025
+
1026
+ if (this.textareamode)
1027
+ {
1028
+ this.$box.after(this.$el);
1029
+ this.$box.remove();
1030
+ this.$el.height(this.height).val(html).show();
1031
+ }
1032
+ else
1033
+ {
1034
+ this.$box.after(this.$editor);
1035
+ this.$box.remove();
1036
+ this.$editor.removeClass('redactor_editor').removeClass('redactor_editor_wym').attr('contenteditable', false).html(html).show();
1037
+ }
1038
+
1039
+ $('.redactor_air').remove();
1040
+
1041
+ for (var i = 0; i < this.dropdowns.length; i++)
1042
+ {
1043
+ this.dropdowns[i].remove();
1044
+ delete(this.dropdowns[i]);
1045
+ }
1046
+
1047
+ },
1048
+ // end API functions
1049
+
1050
+ // OBSERVERS
1051
+ observeImages: function()
1052
+ {
1053
+ if (this.opts.observeImages === false)
1054
+ {
1055
+ return false;
1056
+ }
1057
+
1058
+ this.$editor.find('img').each($.proxy(function(i,s)
1059
+ {
1060
+ if ($.browser.msie)
1061
+ {
1062
+ $(s).attr('unselectable', 'on');
1063
+ }
1064
+
1065
+ this.resizeImage(s);
1066
+
1067
+ }, this));
1068
+
1069
+ },
1070
+ observeTables: function()
1071
+ {
1072
+ this.$editor.find('table').click($.proxy(this.tableObserver, this));
1073
+ },
1074
+ observeScroll: function()
1075
+ {
1076
+ var scrolltop = $(document).scrollTop();
1077
+ var boxtop = this.$box.offset().top;
1078
+ var left = 0;
1079
+
1080
+ if (scrolltop > boxtop)
1081
+ {
1082
+ var width = '100%';
1083
+ if (this.opts.fixedBox)
1084
+ {
1085
+ left = this.$editor.offset().left;
1086
+ width = this.$editor.innerWidth();
1087
+ }
1088
+
1089
+ this.fixed = true;
1090
+ this.$toolbar.css({ position: 'fixed', width: width, zIndex: 100, top: this.opts.fixedTop + 'px', left: left });
1091
+ }
1092
+ else
1093
+ {
1094
+ this.fixed = false;
1095
+ this.$toolbar.css({ position: 'relative', width: 'auto', zIndex: 1, top: 0, left: left });
1096
+ }
1097
+ },
1098
+
1099
+ // BUFFER
1100
+ setBuffer: function()
1101
+ {
1102
+ this.saveSelection();
1103
+ this.opts.buffer = this.$editor.html();
1104
+ },
1105
+ getBuffer: function()
1106
+ {
1107
+ if (this.opts.buffer === false)
1108
+ {
1109
+ return false;
1110
+ }
1111
+
1112
+ this.$editor.html(this.opts.buffer);
1113
+
1114
+ if (!$.browser.msie)
1115
+ {
1116
+ this.restoreSelection();
1117
+ }
1118
+
1119
+ this.opts.buffer = false;
1120
+ },
1121
+
1122
+ // EXECCOMMAND
1123
+ execCommand: function(cmd, param)
1124
+ {
1125
+ if (this.opts.visual == false)
1126
+ {
1127
+ this.$el.focus();
1128
+ return false;
1129
+ }
1130
+
1131
+ try
1132
+ {
1133
+ var parent;
1134
+
1135
+ if (cmd === 'inserthtml' && $.browser.msie)
1136
+ {
1137
+ /*** IE-Insertion-Fix by Fabio Poloni ***/
1138
+ if (!this.$editor.is(":focus"))
1139
+ {
1140
+ this.$editor.focus();
1141
+ }
1142
+
1143
+ document.selection.createRange().pasteHTML(param);
1144
+ }
1145
+ else if (cmd === 'formatblock' && $.browser.msie)
1146
+ {
1147
+ document.execCommand(cmd, false, '<' + param + '>');
1148
+ }
1149
+ else if (cmd === 'unlink')
1150
+ {
1151
+ parent = this.getParentNode();
1152
+ if ($(parent).get(0).tagName === 'A')
1153
+ {
1154
+ $(parent).replaceWith($(parent).text());
1155
+ }
1156
+ else
1157
+ {
1158
+ document.execCommand(cmd, false, param);
1159
+ }
1160
+ }
1161
+ else if (cmd === 'formatblock' && param === 'blockquote')
1162
+ {
1163
+ parent = this.getParentNode();
1164
+ if ($(parent).get(0).tagName === 'BLOCKQUOTE')
1165
+ {
1166
+ document.execCommand(cmd, false, 'p');
1167
+ }
1168
+ else if ($(parent).get(0).tagName === 'P')
1169
+ {
1170
+ var parent2 = $(parent).parent();
1171
+ if ($(parent2).get(0).tagName === 'BLOCKQUOTE')
1172
+ {
1173
+ var node = $('<p>' + $(parent).html() + '</p>');
1174
+ $(parent2).replaceWith(node);
1175
+ this.setFocusNode(node.get(0));
1176
+ }
1177
+ else
1178
+ {
1179
+ document.execCommand(cmd, false, param);
1180
+ }
1181
+ }
1182
+ else
1183
+ {
1184
+ document.execCommand(cmd, false, param);
1185
+ }
1186
+ }
1187
+ else if (cmd === 'formatblock' && param === 'pre')
1188
+ {
1189
+ parent = this.getParentNode();
1190
+ if ($(parent).get(0).tagName === 'PRE')
1191
+ {
1192
+ $(parent).replaceWith('<p>' + $(parent).text() + '</p>');
1193
+ }
1194
+ else
1195
+ {
1196
+ document.execCommand(cmd, false, param);
1197
+ }
1198
+ }
1199
+ else
1200
+ {
1201
+ document.execCommand(cmd, false, param);
1202
+ }
1203
+
1204
+ if (cmd === 'inserthorizontalrule')
1205
+ {
1206
+ this.$editor.find('hr').removeAttr('id');
1207
+ }
1208
+
1209
+ this.syncCode();
1210
+
1211
+ if (this.oldIE())
1212
+ {
1213
+ this.$editor.focus();
1214
+ }
1215
+
1216
+ if (typeof this.opts.execCommandCallback === 'function')
1217
+ {
1218
+ this.opts.execCommandCallback(this, cmd);
1219
+ }
1220
+
1221
+ if (this.opts.air)
1222
+ {
1223
+ this.air.hide();
1224
+ }
1225
+ }
1226
+ catch (e) { }
1227
+ },
1228
+
1229
+ // FORMAT NEW LINE
1230
+ formatNewLine: function(e)
1231
+ {
1232
+ var parent = this.getParentNode();
1233
+
1234
+ if (parent.nodeName === 'DIV' && parent.className === 'redactor_editor')
1235
+ {
1236
+ var element = $(this.getCurrentNode());
1237
+
1238
+ if (element.get(0).tagName === 'DIV' && (element.html() === '' || element.html() === '<br>'))
1239
+ {
1240
+ var newElement = $('<p>').append(element.clone().get(0).childNodes);
1241
+ element.replaceWith(newElement);
1242
+ newElement.html('<br />');
1243
+ this.setFocusNode(newElement.get(0));
1244
+ }
1245
+ }
1246
+ },
1247
+
1248
+ // SAFARI SHIFT KEY + ENTER
1249
+ safariShiftKeyEnter: function(e, key)
1250
+ {
1251
+ if (e.shiftKey && key === 13)
1252
+ {
1253
+ e.preventDefault();
1254
+ this.insertNodeAtCaret($('<span><br /></span>').get(0));
1255
+ this.syncCode();
1256
+ return false;
1257
+ }
1258
+ else
1259
+ {
1260
+ return true;
1261
+ }
1262
+ },
1263
+
1264
+ // FORMAT EMPTY
1265
+ formatEmpty: function(e)
1266
+ {
1267
+ var html = $.trim(this.$editor.html());
1268
+
1269
+ if ($.browser.mozilla)
1270
+ {
1271
+ html = html.replace(/<br>/i, '');
1272
+ }
1273
+
1274
+ if (html === '')
1275
+ {
1276
+ e.preventDefault();
1277
+
1278
+ var nodehtml = this.opts.allEmptyHtml;
1279
+ if ($.browser.mozilla)
1280
+ {
1281
+ nodehtml = this.opts.mozillaEmptyHtml;
1282
+ }
1283
+
1284
+ var node = $(nodehtml).get(0);
1285
+ this.$editor.html(node);
1286
+ this.setFocusNode(node);
1287
+
1288
+ this.syncCode();
1289
+ return false;
1290
+ }
1291
+ else
1292
+ {
1293
+ this.syncCode();
1294
+ }
1295
+ },
1296
+
1297
+ // PARAGRAPHY
1298
+ paragraphy: function (str)
1299
+ {
1300
+
1301
+
1302
+ str = $.trim(str);
1303
+ if (str === '')
1304
+ {
1305
+ if (!$.browser.mozilla)
1306
+ {
1307
+ return this.opts.allEmptyHtml;
1308
+ }
1309
+ else
1310
+ {
1311
+ return this.opts.mozillaEmptyHtml;
1312
+ }
1313
+ }
1314
+
1315
+ // convert div to p
1316
+ if (this.opts.convertDivs)
1317
+ {
1318
+
1319
+ str = str.replace(/<div(.*?)>([\w\W]*?)<\/div>/gi, '<p>$2</p>');
1320
+ }
1321
+
1322
+ // inner functions
1323
+ var X = function(x, a, b) { return x.replace(new RegExp(a, 'g'), b); };
1324
+ var R = function(a, b) { return X(str, a, b); };
1325
+
1326
+ // block elements
1327
+ var blocks = '(table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|style|script|object|input|param|p|h[1-6])';
1328
+
1329
+ //str = '<p>' + str;
1330
+ str += '\n';
1331
+
1332
+ R('<br />\\s*<br />', '\n\n');
1333
+ R('(<' + blocks + '[^>]*>)', '\n$1');
1334
+ R('(</' + blocks + '>)', '$1\n\n');
1335
+ R('\r\n|\r', '\n'); // newlines
1336
+ R('\n\n+', '\n\n'); // remove duplicates
1337
+ R('\n?((.|\n)+?)$', '<p>$1</p>\n'); // including one at the end
1338
+ R('<p>\\s*?</p>', ''); // remove empty p
1339
+ R('<p>(<div[^>]*>\\s*)', '$1<p>');
1340
+ R('<p>([^<]+)\\s*?(</(div|address|form)[^>]*>)', '<p>$1</p>$2');
1341
+ R('<p>\\s*(</?' + blocks + '[^>]*>)\\s*</p>', '$1');
1342
+ R('<p>(<li.+?)</p>', '$1');
1343
+ R('<p>\\s*(</?' + blocks + '[^>]*>)', '$1');
1344
+ R('(</?' + blocks + '[^>]*>)\\s*</p>', '$1');
1345
+ R('(</?' + blocks + '[^>]*>)\\s*<br />', '$1');
1346
+ R('<br />(\\s*</?(p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)', '$1');
1347
+
1348
+ // pre
1349
+ if (str.indexOf('<pre') != -1)
1350
+ {
1351
+ R('(<pre(.|\n)*?>)((.|\n)*?)</pre>', function(m0, m1, m2, m3)
1352
+ {
1353
+ return X(m1, '\\\\([\'\"\\\\])', '$1') + X(X(X(m3, '<p>', '\n'), '</p>|<br />', ''), '\\\\([\'\"\\\\])', '$1') + '</pre>';
1354
+ });
1355
+ }
1356
+
1357
+ return R('\n</p>$', '</p>');
1358
+ },
1359
+
1360
+ // REMOVE TAGS
1361
+ stripTags: function(html)
1362
+ {
1363
+ var allowed = this.opts.allowedTags;
1364
+ var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi;
1365
+ return html.replace(tags, function ($0, $1)
1366
+ {
1367
+ return $.inArray($1.toLowerCase(), allowed) > '-1' ? $0 : '';
1368
+ });
1369
+ },
1370
+
1371
+
1372
+ // PASTE CLEANUP
1373
+ pasteCleanUp: function(html)
1374
+ {
1375
+ // remove comments and php tags
1376
+ html = html.replace(/<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi, '');
1377
+
1378
+ // remove nbsp
1379
+ html = html.replace(/(&nbsp;){1,}/gi, '&nbsp;');
1380
+
1381
+ // remove google docs marker
1382
+ html = html.replace(/<b\sid="internal-source-marker(.*?)">([\w\W]*?)<\/b>/gi, "$2");
1383
+
1384
+ // strip tags
1385
+ html = this.stripTags(html);
1386
+
1387
+ // prevert
1388
+ html = html.replace(/<td><br><\/td>/gi, '[td]');
1389
+ html = html.replace(/<a(.*?)>([\w\W]*?)<\/a>/gi, '[a$1]$2[/a]');
1390
+ html = html.replace(/<iframe(.*?)>([\w\W]*?)<\/iframe>/gi, '[iframe$1]$2[/iframe]');
1391
+ html = html.replace(/<video(.*?)>([\w\W]*?)<\/video>/gi, '[video$1]$2[/video]');
1392
+ html = html.replace(/<audio(.*?)>([\w\W]*?)<\/audio>/gi, '[audio$1]$2[/audio]');
1393
+ html = html.replace(/<embed(.*?)>([\w\W]*?)<\/embed>/gi, '[embed$1]$2[/embed]');
1394
+ html = html.replace(/<object(.*?)>([\w\W]*?)<\/object>/gi, '[object$1]$2[/object]');
1395
+ html = html.replace(/<param(.*?)>/gi, '[param$1]');
1396
+ html = html.replace(/<img(.*?)>/gi, '[img$1]');
1397
+
1398
+ // remove attributes
1399
+ html = html.replace(/<(\w+)([\w\W]*?)>/gi, '<$1>');
1400
+
1401
+ // remove empty
1402
+ html = html.replace(/<[^\/>][^>]*>(\s*|\t*|\n*|&nbsp;|<br>)<\/[^>]+>/gi, '');
1403
+ html = html.replace(/<[^\/>][^>]*>(\s*|\t*|\n*|&nbsp;|<br>)<\/[^>]+>/gi, '');
1404
+
1405
+ // revert
1406
+ html = html.replace(/\[td\]/gi, '<td><br></td>');
1407
+ html = html.replace(/\[a(.*?)\]([\w\W]*?)\[\/a\]/gi, '<a$1>$2</a>');
1408
+ html = html.replace(/\[iframe(.*?)\]([\w\W]*?)\[\/iframe\]/gi, '<iframe$1>$2</iframe>');
1409
+ html = html.replace(/\[video(.*?)\]([\w\W]*?)\[\/video\]/gi, '<video$1>$2</video>');
1410
+ html = html.replace(/\[audio(.*?)\]([\w\W]*?)\[\/audio\]/gi, '<audio$1>$2</audio>');
1411
+ html = html.replace(/\[embed(.*?)\]([\w\W]*?)\[\/embed\]/gi, '<embed$1>$2</embed>');
1412
+ html = html.replace(/\[object(.*?)\]([\w\W]*?)\[\/object\]/gi, '<object$1>$2</object>');
1413
+ html = html.replace(/\[param(.*?)\]/gi, '<param$1>');
1414
+ html = html.replace(/\[img(.*?)\]/gi, '<img$1>');
1415
+
1416
+ // convert div to p
1417
+ if (this.opts.convertDivs)
1418
+ {
1419
+ html = html.replace(/<div(.*?)>([\w\W]*?)<\/div>/gi, '<p>$2</p>');
1420
+ }
1421
+
1422
+ if (this.opts.paragraphy === false)
1423
+ {
1424
+ html = html.replace(/<p>([\w\W]*?)<\/p>/gi, '$1<br>');
1425
+ }
1426
+
1427
+ // remove span
1428
+ html = html.replace(/<span>([\w\W]*?)<\/span>/gi, '$1');
1429
+
1430
+ html = html.replace(/\n{3,}/gi, '\n');
1431
+
1432
+ // remove dirty p
1433
+ html = html.replace(/<p><p>/g, '<p>');
1434
+ html = html.replace(/<\/p><\/p>/g, '</p>');
1435
+
1436
+ this.execCommand('inserthtml', html);
1437
+
1438
+ if (this.opts.autoresize === true)
1439
+ {
1440
+ $(document.body).scrollTop(this.saveScroll);
1441
+ }
1442
+ else
1443
+ {
1444
+ this.$editor.scrollTop(this.saveScroll);
1445
+ }
1446
+
1447
+ },
1448
+
1449
+
1450
+ // TEXTAREA CODE FORMATTING
1451
+ formattingRemove: function(html)
1452
+ {
1453
+ // save pre
1454
+ var prebuffer = [];
1455
+ var pre = html.match(/<pre(.*?)>([\w\W]*?)<\/pre>/gi);
1456
+ if (pre !== null)
1457
+ {
1458
+ $.each(pre, function(i,s)
1459
+ {
1460
+ html = html.replace(s, 'prebuffer_' + i);
1461
+ prebuffer.push(s);
1462
+ });
1463
+ }
1464
+
1465
+ html = html.replace(/\s{2,}/g, ' ');
1466
+ html = html.replace(/\n/g, ' ');
1467
+ html = html.replace(/[\t]*/g, '');
1468
+ html = html.replace(/\n\s*\n/g, "\n");
1469
+ html = html.replace(/^[\s\n]*/g, '');
1470
+ html = html.replace(/[\s\n]*$/g, '');
1471
+ html = html.replace(/>\s+</g, '><');
1472
+
1473
+ if (prebuffer)
1474
+ {
1475
+ $.each(prebuffer, function(i,s)
1476
+ {
1477
+ html = html.replace('prebuffer_' + i, s);
1478
+ });
1479
+
1480
+ prebuffer = [];
1481
+ }
1482
+
1483
+ return html;
1484
+ },
1485
+ formattingIndenting: function(html)
1486
+ {
1487
+ html = html.replace(/<li/g, "\t<li");
1488
+ html = html.replace(/<tr/g, "\t<tr");
1489
+ html = html.replace(/<td/g, "\t\t<td");
1490
+ html = html.replace(/<\/tr>/g, "\t</tr>");
1491
+
1492
+ return html;
1493
+ },
1494
+ formattingEmptyTags: function(html)
1495
+ {
1496
+ var etags = ["<pre></pre>","<blockquote>\\s*</blockquote>","<em>\\s*</em>","<ul></ul>","<ol></ol>","<li></li>","<table></table>","<tr></tr>","<span>\\s*<span>", "<span>&nbsp;<span>", "<b>\\s*</b>", "<b>&nbsp;</b>", "<p>\\s*</p>", "<p>&nbsp;</p>", "<p>\\s*<br>\\s*</p>", "<div>\\s*</div>", "<div>\\s*<br>\\s*</div>"];
1497
+ for (var i = 0; i < etags.length; ++i)
1498
+ {
1499
+ var bbb = etags[i];
1500
+ html = html.replace(new RegExp(bbb,'gi'), "");
1501
+ }
1502
+
1503
+ return html;
1504
+ },
1505
+ formattingAddBefore: function(html)
1506
+ {
1507
+ var lb = '\r\n';
1508
+ var btags = ["<p", "<form","</ul>", '</ol>', "<fieldset","<legend","<object","<embed","<select","<option","<input","<textarea","<pre","<blockquote","<ul","<ol","<li","<dl","<dt","<dd","<table", "<thead","<tbody","<caption","</caption>","<th","<tr","<td","<figure"];
1509
+ for (var i = 0; i < btags.length; ++i)
1510
+ {
1511
+ var eee = btags[i];
1512
+ html = html.replace(new RegExp(eee,'gi'),lb+eee);
1513
+ }
1514
+
1515
+ return html;
1516
+ },
1517
+ formattingAddAfter: function(html)
1518
+ {
1519
+ var lb = '\r\n';
1520
+ var atags = ['</p>', '</div>', '</h1>', '</h2>', '</h3>', '</h4>', '</h5>', '</h6>', '<br>', '<br />', '</dl>', '</dt>', '</dd>', '</form>', '</blockquote>', '</pre>', '</legend>', '</fieldset>', '</object>', '</embed>', '</textarea>', '</select>', '</option>', '</table>', '</thead>', '</tbody>', '</tr>', '</td>', '</th>', '</figure>'];
1521
+ for (var i = 0; i < atags.length; ++i)
1522
+ {
1523
+ var aaa = atags[i];
1524
+ html = html.replace(new RegExp(aaa,'gi'),aaa+lb);
1525
+ }
1526
+
1527
+ return html;
1528
+ },
1529
+ formatting: function(html)
1530
+ {
1531
+ html = this.formattingRemove(html);
1532
+
1533
+ // empty tags
1534
+ html = this.formattingEmptyTags(html);
1535
+
1536
+ // add formatting before
1537
+ html = this.formattingAddBefore(html);
1538
+
1539
+ // add formatting after
1540
+ html = this.formattingAddAfter(html);
1541
+
1542
+ // indenting
1543
+ html = this.formattingIndenting(html);
1544
+
1545
+ return html;
1546
+ },
1547
+
1548
+ // TOGGLE
1549
+ toggle: function()
1550
+ {
1551
+ var html;
1552
+
1553
+ if (this.opts.visual)
1554
+ {
1555
+ this.$editor.hide();
1556
+
1557
+ html = this.$editor.html();
1558
+ html = $.trim(this.formatting(html));
1559
+
1560
+ this.$el.height(this.$editor.innerHeight()).val(html).show().focus();
1561
+
1562
+ this.setBtnActive('html');
1563
+ this.opts.visual = false;
1564
+ }
1565
+ else
1566
+ {
1567
+ this.$el.hide();
1568
+
1569
+
1570
+ var html = this.stripTags(this.$el.val());
1571
+ this.$editor.html(html);
1572
+ this.$editor.show();
1573
+
1574
+ if (this.$editor.html() === '')
1575
+ {
1576
+ if (!$.browser.mozilla)
1577
+ {
1578
+ html = this.opts.allEmptyHtml;
1579
+ }
1580
+ else
1581
+ {
1582
+ html = this.opts.mozillaEmptyHtml;
1583
+ }
1584
+
1585
+ this.setCode(html);
1586
+ }
1587
+
1588
+ this.$editor.focus();
1589
+
1590
+ this.setBtnInactive('html');
1591
+ this.opts.visual = true;
1592
+
1593
+ this.observeImages();
1594
+ this.observeTables();
1595
+ }
1596
+ },
1597
+
1598
+ // AUTOSAVE
1599
+ autoSave: function()
1600
+ {
1601
+ setInterval($.proxy(function()
1602
+ {
1603
+ $.ajax({
1604
+ url: this.opts.autosave,
1605
+ type: 'post',
1606
+ data: this.$el.attr('name') + '=' + this.getCode(),
1607
+ success: $.proxy(function(data)
1608
+ {
1609
+ // callback
1610
+ if (typeof this.opts.autosaveCallback === 'function')
1611
+ {
1612
+ this.opts.autosaveCallback(data, this);
1613
+ }
1614
+
1615
+ }, this)
1616
+ });
1617
+
1618
+
1619
+ }, this), this.opts.interval*1000);
1620
+ },
1621
+
1622
+ // TOOLBAR
1623
+ buildToolbar: function()
1624
+ {
1625
+ if (this.opts.toolbar === false)
1626
+ {
1627
+ return false;
1628
+ }
1629
+
1630
+ this.$toolbar = $('<ul>').addClass('redactor_toolbar');
1631
+
1632
+ if (this.opts.air)
1633
+ {
1634
+ $(this.air).append(this.$toolbar);
1635
+ $('body').prepend(this.air);
1636
+ }
1637
+ else
1638
+ {
1639
+ this.$box.prepend(this.$toolbar);
1640
+ }
1641
+
1642
+ $.each(this.opts.buttons, $.proxy(function(i,key)
1643
+ {
1644
+
1645
+ if (key !== '|' && typeof this.opts.toolbar[key] !== 'undefined')
1646
+ {
1647
+ var s = this.opts.toolbar[key];
1648
+
1649
+ if (this.opts.fileUpload === false && key === 'file')
1650
+ {
1651
+ return true;
1652
+ }
1653
+
1654
+ var li = $('<li>');
1655
+ var a = this.buildButton(key, s);
1656
+
1657
+ // dropdown
1658
+ if (key === 'backcolor' || key === 'fontcolor' || typeof(s.dropdown) !== 'undefined')
1659
+ {
1660
+ var dropdown = $('<div class="redactor_dropdown" style="display: none;">');
1661
+
1662
+ if (key === 'backcolor' || key === 'fontcolor')
1663
+ {
1664
+ dropdown = this.buildColorPicker(dropdown, key);
1665
+ }
1666
+ else
1667
+ {
1668
+ dropdown = this.buildDropdown(dropdown, s.dropdown);
1669
+ }
1670
+
1671
+ this.dropdowns.push(dropdown.appendTo($(document.body)));
1672
+
1673
+ // observing dropdown
1674
+ this.hdlHideDropDown = $.proxy(function(e) { this.hideDropDown(e, dropdown, key); }, this);
1675
+ this.hdlShowDropDown = $.proxy(function(e) { this.showDropDown(e, dropdown, key); }, this);
1676
+
1677
+ a.click(this.hdlShowDropDown);
1678
+ }
1679
+
1680
+ this.$toolbar.append($(li).append(a));
1681
+ }
1682
+
1683
+
1684
+ if (key === '|')
1685
+ {
1686
+ this.$toolbar.append($('<li class="redactor_separator"></li>'));
1687
+ }
1688
+
1689
+ }, this));
1690
+
1691
+ $(document).click(this.hdlHideDropDown);
1692
+ this.$editor.click(this.hdlHideDropDown);
1693
+
1694
+ },
1695
+ buildButton: function(key, s)
1696
+ {
1697
+ var button = $('<a href="javascript:void(null);" title="' + s.title + '" class="redactor_btn_' + key + '"></a>');
1698
+
1699
+ if (typeof s.func === 'undefined')
1700
+ {
1701
+ button.click($.proxy(function() { this.execCommand(s.exec, key); }, this));
1702
+ }
1703
+ else if (s.func !== 'show')
1704
+ {
1705
+ button.click($.proxy(function(e) {
1706
+
1707
+ this[s.func](e);
1708
+
1709
+ }, this));
1710
+ }
1711
+
1712
+ if (typeof s.callback !== 'undefined')
1713
+ {
1714
+ button.click($.proxy(function(e) { s.callback(this, e, key); }, this));
1715
+ }
1716
+
1717
+ return button;
1718
+ },
1719
+ buildDropdown: function(dropdown, obj)
1720
+ {
1721
+ $.each(obj, $.proxy(
1722
+ function (x, d)
1723
+ {
1724
+ if (typeof(d.className) === 'undefined')
1725
+ {
1726
+ d.className = '';
1727
+ }
1728
+
1729
+ var drop_a;
1730
+ if (typeof d.name !== 'undefined' && d.name === 'separator')
1731
+ {
1732
+ drop_a = $('<a class="redactor_separator_drop">');
1733
+ }
1734
+ else
1735
+ {
1736
+ drop_a = $('<a href="javascript:void(null);" class="' + d.className + '">' + d.title + '</a>');
1737
+
1738
+ if (typeof(d.func) === 'undefined')
1739
+ {
1740
+ $(drop_a).click($.proxy(function() { this.execCommand(d.exec, x); }, this));
1741
+ }
1742
+ else
1743
+ {
1744
+ $(drop_a).click($.proxy(function(e) { this[d.func](e); }, this));
1745
+ }
1746
+ }
1747
+
1748
+ $(dropdown).append(drop_a);
1749
+
1750
+ }, this)
1751
+ );
1752
+
1753
+ return dropdown;
1754
+
1755
+ },
1756
+ buildColorPicker: function(dropdown, key)
1757
+ {
1758
+ var mode;
1759
+ if (key === 'backcolor')
1760
+ {
1761
+ if ($.browser.msie)
1762
+ {
1763
+ mode = 'BackColor';
1764
+ }
1765
+ else
1766
+ {
1767
+ mode = 'hilitecolor';
1768
+ }
1769
+ }
1770
+ else
1771
+ {
1772
+ mode = 'forecolor';
1773
+ }
1774
+
1775
+ $(dropdown).width(210);
1776
+
1777
+ var len = this.opts.colors.length;
1778
+ for (var i = 0; i < len; ++i)
1779
+ {
1780
+ var color = this.opts.colors[i];
1781
+
1782
+ var swatch = $('<a rel="' + color + '" href="javascript:void(null);" class="redactor_color_link"></a>').css({ 'backgroundColor': color });
1783
+ $(dropdown).append(swatch);
1784
+
1785
+ var _self = this;
1786
+ $(swatch).click(function()
1787
+ {
1788
+ _self.execCommand(mode, $(this).attr('rel'));
1789
+
1790
+ if (mode === 'forecolor')
1791
+ {
1792
+ _self.$editor.find('font').replaceWith(function() {
1793
+
1794
+ return $('<span style="color: ' + $(this).attr('color') + ';">' + $(this).html() + '</span>');
1795
+
1796
+ });
1797
+ }
1798
+
1799
+ if ($.browser.msie && mode === 'BackColor')
1800
+ {
1801
+ _self.$editor.find('font').replaceWith(function() {
1802
+
1803
+ return $('<span style="' + $(this).attr('style') + '">' + $(this).html() + '</span>');
1804
+
1805
+ });
1806
+ }
1807
+
1808
+ });
1809
+ }
1810
+
1811
+ var elnone = $('<a href="javascript:void(null);" class="redactor_color_none"></a>').html(RLANG.none);
1812
+
1813
+ if (key === 'backcolor')
1814
+ {
1815
+ elnone.click($.proxy(this.setBackgroundNone, this));
1816
+ }
1817
+ else
1818
+ {
1819
+ elnone.click($.proxy(this.setColorNone, this));
1820
+ }
1821
+
1822
+ $(dropdown).append(elnone);
1823
+
1824
+ return dropdown;
1825
+ },
1826
+ setBackgroundNone: function()
1827
+ {
1828
+ $(this.getParentNode()).css('background-color', 'transparent');
1829
+ this.syncCode();
1830
+ },
1831
+ setColorNone: function()
1832
+ {
1833
+ $(this.getParentNode()).attr('color', '').css('color', '');
1834
+ this.syncCode();
1835
+ },
1836
+
1837
+
1838
+ // DROPDOWNS
1839
+ showDropDown: function(e, dropdown, key)
1840
+ {
1841
+ if (this.getBtn(key).hasClass('dropact'))
1842
+ {
1843
+ this.hideAllDropDown();
1844
+ }
1845
+ else
1846
+ {
1847
+ this.hideAllDropDown();
1848
+
1849
+ this.setBtnActive(key);
1850
+ this.getBtn(key).addClass('dropact');
1851
+
1852
+ var left = this.getBtn(key).offset().left;
1853
+
1854
+ if (this.opts.air)
1855
+ {
1856
+ var air_top = this.air.offset().top;
1857
+
1858
+ $(dropdown).css({ position: 'absolute', left: left + 'px', top: air_top+30 + 'px' }).show();
1859
+ }
1860
+ else if (this.opts.fixed && this.fixed)
1861
+ {
1862
+ $(dropdown).css({ position: 'fixed', left: left + 'px', top: '30px' }).show();
1863
+ }
1864
+ else
1865
+ {
1866
+ var top = this.$toolbar.offset().top + 30;
1867
+ $(dropdown).css({ position: 'absolute', left: left + 'px', top: top + 'px' }).show();
1868
+ }
1869
+ }
1870
+
1871
+ },
1872
+ hideAllDropDown: function()
1873
+ {
1874
+ this.$toolbar.find('a.dropact').removeClass('act').removeClass('dropact');
1875
+ $('.redactor_dropdown').hide();
1876
+ },
1877
+ hideDropDown: function(e, dropdown, key)
1878
+ {
1879
+ if (!$(e.target).hasClass('dropact'))
1880
+ {
1881
+ $(dropdown).removeClass('act');
1882
+ this.showedDropDown = false;
1883
+ this.hideAllDropDown();
1884
+ }
1885
+ },
1886
+
1887
+ // SELECTION AND NODE MANIPULATION
1888
+ getSelection: function ()
1889
+ {
1890
+ if (typeof window.getSelection !== 'undefined')
1891
+ {
1892
+ return document.getSelection();
1893
+ }
1894
+ else if (typeof document.selection !== 'undefined')
1895
+ {
1896
+ return document.selection.createRange();
1897
+ }
1898
+ },
1899
+ getFragmentHtml: function (fragment)
1900
+ {
1901
+ var cloned = fragment.cloneNode(true);
1902
+ var div = document.createElement('div');
1903
+ div.appendChild(cloned);
1904
+ return div.innerHTML;
1905
+ },
1906
+ extractContent: function()
1907
+ {
1908
+ var node = this.$editor.get(0);
1909
+ var frag = document.createDocumentFragment(), child;
1910
+ while ((child = node.firstChild))
1911
+ {
1912
+ frag.appendChild(child);
1913
+ }
1914
+
1915
+ return frag;
1916
+ },
1917
+ saveSelection: function()
1918
+ {
1919
+ this.savedSel = null;
1920
+ this.savedSelObj = null;
1921
+
1922
+ if ($.browser.msie && parseInt($.browser.version, 10) < 9)
1923
+ {
1924
+ var node = this.$editor.get(0);
1925
+ this.savedSel = window.Selection.getOrigin(node);
1926
+ this.savedSelObj = window.Selection.getFocus(node);
1927
+ }
1928
+ else
1929
+ {
1930
+ this.savedSel = window.Selection.getOrigin(window);
1931
+ this.savedSelObj = window.Selection.getFocus(window);
1932
+ }
1933
+ },
1934
+ restoreSelection: function()
1935
+ {
1936
+ if (this.savedSel !== null && this.savedSelObj !== null && this.savedSel[0].tagName !== 'BODY')
1937
+ {
1938
+ if ($(this.savedSel[0]).closest('.redactor_editor').size() == 0)
1939
+ {
1940
+ this.$editor.focus();
1941
+ }
1942
+ else
1943
+ {
1944
+ window.Selection.setSelection(window, this.savedSel[0], this.savedSel[1], this.savedSelObj[0], this.savedSelObj[1]);
1945
+ }
1946
+ }
1947
+ else
1948
+ {
1949
+ this.$editor.focus();
1950
+ }
1951
+ },
1952
+ getParentNode: function()
1953
+ {
1954
+ if (typeof window.getSelection !== 'undefined')
1955
+ {
1956
+ var s = window.getSelection();
1957
+ if (s.rangeCount > 0)
1958
+ {
1959
+ return this.getSelection().getRangeAt(0).startContainer.parentNode;
1960
+ }
1961
+ else return false;
1962
+
1963
+ }
1964
+ else if (typeof document.selection !== 'undefined')
1965
+ {
1966
+ return this.getSelection().parentElement();
1967
+ }
1968
+ },
1969
+ getCurrentNode: function()
1970
+ {
1971
+ if (typeof window.getSelection !== 'undefined')
1972
+ {
1973
+ return this.getSelection().getRangeAt(0).startContainer;
1974
+ }
1975
+ else if (typeof document.selection !== 'undefined')
1976
+ {
1977
+ return this.getSelection();
1978
+ }
1979
+ },
1980
+ setFocusNode: function(node)
1981
+ {
1982
+ if (typeof node === 'undefined')
1983
+ {
1984
+ return false;
1985
+ }
1986
+
1987
+ try {
1988
+
1989
+ var range = document.createRange();
1990
+ var selection = this.getSelection();
1991
+
1992
+ if (selection !== null)
1993
+ {
1994
+ range.selectNodeContents(node);
1995
+ selection.addRange(range);
1996
+ selection.collapse(node, 0);
1997
+ }
1998
+
1999
+ this.$editor.focus();
2000
+
2001
+ } catch (e) { }
2002
+
2003
+ },
2004
+ insertNodeAtCaret: function (node)
2005
+ {
2006
+ if (window.getSelection)
2007
+ {
2008
+ var sel = this.getSelection();
2009
+ if (sel.rangeCount)
2010
+ {
2011
+ var range = sel.getRangeAt(0);
2012
+ range.collapse(false);
2013
+ range.insertNode(node);
2014
+ range = range.cloneRange();
2015
+ range.selectNodeContents(node);
2016
+ range.collapse(false);
2017
+ sel.removeAllRanges();
2018
+ sel.addRange(range);
2019
+ }
2020
+ }
2021
+ else if (document.selection)
2022
+ {
2023
+ var html = (node.nodeType === 1) ? node.outerHTML : node.data;
2024
+ var id = "marker_" + ("" + Math.random()).slice(2);
2025
+ html += '<span id="' + id + '"></span>';
2026
+ var textRange = this.getSelection();
2027
+ textRange.collapse(false);
2028
+ textRange.pasteHTML(html);
2029
+ var markerSpan = document.getElementById(id);
2030
+ textRange.moveToElementText(markerSpan);
2031
+ textRange.select();
2032
+ markerSpan.parentNode.removeChild(markerSpan);
2033
+ }
2034
+ },
2035
+ getSelectedHtml: function()
2036
+ {
2037
+ var html = '';
2038
+ if (window.getSelection)
2039
+ {
2040
+ var sel = window.getSelection();
2041
+ if (sel.rangeCount)
2042
+ {
2043
+ var container = document.createElement("div");
2044
+ for (var i = 0, len = sel.rangeCount; i < len; ++i)
2045
+ {
2046
+ container.appendChild(sel.getRangeAt(i).cloneContents());
2047
+ }
2048
+
2049
+ html = container.innerHTML;
2050
+
2051
+ }
2052
+ }
2053
+ else if (document.selection)
2054
+ {
2055
+ if (document.selection.type === "Text")
2056
+ {
2057
+ html = document.selection.createRange().htmlText;
2058
+ }
2059
+ }
2060
+
2061
+ return html;
2062
+ },
2063
+
2064
+ // BUTTONS MANIPULATIONS
2065
+ getBtn: function(key)
2066
+ {
2067
+ return $(this.$toolbar.find('a.redactor_btn_' + key));
2068
+ },
2069
+ setBtnActive: function(key)
2070
+ {
2071
+ this.getBtn(key).addClass('act');
2072
+ },
2073
+ setBtnInactive: function(key)
2074
+ {
2075
+ this.getBtn(key).removeClass('act');
2076
+ },
2077
+
2078
+ // RESIZE IMAGES
2079
+ resizeImage: function(resize)
2080
+ {
2081
+ var clicked = false;
2082
+ var clicker = false;
2083
+ var start_x;
2084
+ var start_y;
2085
+ var ratio = $(resize).width()/$(resize).height();
2086
+ var min_w = 10;
2087
+ var min_h = 10;
2088
+
2089
+ $(resize).hover(function() { clicked = false; });
2090
+
2091
+ $(resize).mousedown(function(e)
2092
+ {
2093
+ e.preventDefault();
2094
+
2095
+ ratio = $(resize).width()/$(resize).height();
2096
+
2097
+ clicked = true;
2098
+ clicker = true;
2099
+
2100
+ start_x = Math.round(e.pageX - $(resize).eq(0).offset().left);
2101
+ start_y = Math.round(e.pageY - $(resize).eq(0).offset().top);
2102
+ });
2103
+
2104
+ $(resize).mouseup($.proxy(function(e)
2105
+ {
2106
+ clicked = false;
2107
+ this.syncCode();
2108
+
2109
+ }, this));
2110
+
2111
+ $(resize).click($.proxy(function(e)
2112
+ {
2113
+ if (clicker)
2114
+ {
2115
+ this.imageEdit(e);
2116
+ }
2117
+
2118
+ }, this));
2119
+
2120
+ $(resize).mousemove(function(e)
2121
+ {
2122
+ if (clicked)
2123
+ {
2124
+ clicker = false;
2125
+
2126
+ var mouse_x = Math.round(e.pageX - $(this).eq(0).offset().left) - start_x;
2127
+ var mouse_y = Math.round(e.pageY - $(this).eq(0).offset().top) - start_y;
2128
+
2129
+ var div_h = $(resize).height();
2130
+
2131
+ var new_h = parseInt(div_h, 10) + mouse_y;
2132
+ var new_w = new_h*ratio;
2133
+
2134
+ if (new_w > min_w)
2135
+ {
2136
+ $(resize).width(new_w);
2137
+ }
2138
+
2139
+ if (new_h > min_h)
2140
+ {
2141
+ $(resize).height(new_h);
2142
+ }
2143
+
2144
+ start_x = Math.round(e.pageX - $(this).eq(0).offset().left);
2145
+ start_y = Math.round(e.pageY - $(this).eq(0).offset().top);
2146
+ }
2147
+ });
2148
+ },
2149
+
2150
+ // TABLE
2151
+ showTable: function()
2152
+ {
2153
+ this.saveSelection();
2154
+
2155
+ this.modalInit(RLANG.table, 'table', 300, $.proxy(function()
2156
+ {
2157
+ $('#redactor_insert_table_btn').click($.proxy(this.insertTable, this));
2158
+ }, this),
2159
+
2160
+ function()
2161
+ {
2162
+ $('#redactor_table_rows').focus();
2163
+ }
2164
+ );
2165
+ },
2166
+ insertTable: function()
2167
+ {
2168
+ var rows = $('#redactor_table_rows').val();
2169
+ var columns = $('#redactor_table_columns').val();
2170
+
2171
+ var table_box = $('<div></div>');
2172
+
2173
+ var tableid = Math.floor(Math.random() * 99999);
2174
+ var table = $('<table id="table' + tableid + '"><tbody></tbody></table>');
2175
+
2176
+ for (var i = 0; i < rows; i++)
2177
+ {
2178
+ var row = $('<tr></tr>');
2179
+ for (var z = 0; z < columns; z++)
2180
+ {
2181
+ var column = $('<td><br></td>');
2182
+ $(row).append(column);
2183
+ }
2184
+ $(table).append(row);
2185
+ }
2186
+
2187
+ $(table_box).append(table);
2188
+ var html = $(table_box).html() + '<p></p>';
2189
+
2190
+ this.restoreSelection();
2191
+ this.execCommand('inserthtml', html);
2192
+ this.modalClose();
2193
+ this.observeTables();
2194
+
2195
+ },
2196
+ tableObserver: function(e)
2197
+ {
2198
+ this.$table = $(e.target).closest('table');
2199
+
2200
+ this.$table_tr = this.$table.find('tr');
2201
+ this.$table_td = this.$table.find('td');
2202
+
2203
+ this.$table_td.removeClass('redactor-current-td');
2204
+
2205
+ this.$tbody = $(e.target).closest('tbody');
2206
+ this.$thead = $(this.$table).find('thead');
2207
+
2208
+ this.$current_td = $(e.target);
2209
+ this.$current_td.addClass('redactor-current-td');
2210
+
2211
+ this.$current_tr = $(e.target).closest('tr');
2212
+ },
2213
+ deleteTable: function()
2214
+ {
2215
+ $(this.$table).remove();
2216
+ this.$table = false;
2217
+ this.syncCode();
2218
+ },
2219
+ deleteRow: function()
2220
+ {
2221
+ $(this.$current_tr).remove();
2222
+ this.syncCode();
2223
+ },
2224
+ deleteColumn: function()
2225
+ {
2226
+ var index = $(this.$current_td).get(0).cellIndex;
2227
+
2228
+ $(this.$table).find('tr').each(function()
2229
+ {
2230
+ $(this).find('td').eq(index).remove();
2231
+ });
2232
+
2233
+ this.syncCode();
2234
+ },
2235
+ addHead: function()
2236
+ {
2237
+ if ($(this.$table).find('thead').size() !== 0)
2238
+ {
2239
+ this.deleteHead();
2240
+ }
2241
+ else
2242
+ {
2243
+ var tr = $(this.$table).find('tr').first().clone();
2244
+ tr.find('td').html('&nbsp;');
2245
+ this.$thead = $('<thead></thead>');
2246
+ this.$thead.append(tr);
2247
+ $(this.$table).prepend(this.$thead);
2248
+ this.syncCode();
2249
+ }
2250
+ },
2251
+ deleteHead: function()
2252
+ {
2253
+ $(this.$thead).remove();
2254
+ this.$thead = false;
2255
+ this.syncCode();
2256
+ },
2257
+ insertRowAbove: function()
2258
+ {
2259
+ this.insertRow('before');
2260
+ },
2261
+ insertRowBelow: function()
2262
+ {
2263
+ this.insertRow('after');
2264
+ },
2265
+ insertColumnLeft: function()
2266
+ {
2267
+ this.insertColumn('before');
2268
+ },
2269
+ insertColumnRight: function()
2270
+ {
2271
+ this.insertColumn('after');
2272
+ },
2273
+ insertRow: function(type)
2274
+ {
2275
+ var new_tr = $(this.$current_tr).clone();
2276
+ new_tr.find('td').html('&nbsp;');
2277
+ if (type === 'after')
2278
+ {
2279
+ $(this.$current_tr).after(new_tr);
2280
+ }
2281
+ else
2282
+ {
2283
+ $(this.$current_tr).before(new_tr);
2284
+ }
2285
+
2286
+ this.syncCode();
2287
+ },
2288
+ insertColumn: function(type)
2289
+ {
2290
+ var index = 0;
2291
+
2292
+ this.$current_td.addClass('redactor-current-td');
2293
+
2294
+ this.$current_tr.find('td').each(function(i,s)
2295
+ {
2296
+ if ($(s).hasClass('redactor-current-td'))
2297
+ {
2298
+ index = i;
2299
+ }
2300
+ });
2301
+
2302
+ this.$table_tr.each(function(i,s)
2303
+ {
2304
+ var current = $(s).find('td').eq(index);
2305
+
2306
+ var td = current.clone();
2307
+ td.html('&nbsp;');
2308
+
2309
+ if (type === 'after')
2310
+ {
2311
+ $(current).after(td);
2312
+ }
2313
+ else
2314
+ {
2315
+ $(current).before(td);
2316
+ }
2317
+
2318
+ });
2319
+
2320
+ this.syncCode();
2321
+ },
2322
+
2323
+ // INSERT VIDEO
2324
+ showVideo: function()
2325
+ {
2326
+ this.saveSelection();
2327
+ this.modalInit(RLANG.video, 'video', 600, $.proxy(function()
2328
+ {
2329
+ $('#redactor_insert_video_btn').click($.proxy(this.insertVideo, this));
2330
+ }, this),
2331
+
2332
+ function()
2333
+ {
2334
+ $('#redactor_insert_video_area').focus();
2335
+ }
2336
+ );
2337
+ },
2338
+ insertVideo: function()
2339
+ {
2340
+ var data = $('#redactor_insert_video_area').val();
2341
+ data = this.stripTags(data);
2342
+
2343
+ this.restoreSelection();
2344
+ this.execCommand('inserthtml', data);
2345
+ this.modalClose();
2346
+ },
2347
+
2348
+ // INSERT IMAGE
2349
+ imageEdit: function(e)
2350
+ {
2351
+ var $el = $(e.target);
2352
+ var parent = $el.parent();
2353
+
2354
+ var handler = $.proxy(function()
2355
+ {
2356
+ $('#redactor_file_alt').val($el.attr('alt'));
2357
+ $('#redactor_image_edit_src').attr('href', $el.attr('src'));
2358
+ $('#redactor_form_image_align').val($el.css('float'));
2359
+
2360
+ if ($(parent).get(0).tagName === 'A')
2361
+ {
2362
+ $('#redactor_file_link').val($(parent).attr('href'));
2363
+ }
2364
+
2365
+ $('#redactor_image_delete_btn').click($.proxy(function() { this.imageDelete($el); }, this));
2366
+ $('#redactorSaveBtn').click($.proxy(function() { this.imageSave($el); }, this));
2367
+
2368
+ }, this);
2369
+
2370
+ this.modalInit(RLANG.image, 'image_edit', 380, handler);
2371
+
2372
+ },
2373
+ imageDelete: function(el)
2374
+ {
2375
+ $(el).remove();
2376
+ this.modalClose();
2377
+ this.syncCode();
2378
+ },
2379
+ imageSave: function(el)
2380
+ {
2381
+ var parent = $(el).parent();
2382
+
2383
+ $(el).attr('alt', $('#redactor_file_alt').val());
2384
+
2385
+ var floating = $('#redactor_form_image_align').val();
2386
+
2387
+ if (floating === 'left')
2388
+ {
2389
+ $(el).css({ 'float': 'left', margin: '0 10px 10px 0' });
2390
+ }
2391
+ else if (floating === 'right')
2392
+ {
2393
+ $(el).css({ 'float': 'right', margin: '0 0 10px 10px' });
2394
+ }
2395
+ else
2396
+ {
2397
+ $(el).css({ 'float': 'none', margin: '0' });
2398
+ }
2399
+
2400
+ // as link
2401
+ var link = $.trim($('#redactor_file_link').val());
2402
+ if (link !== '')
2403
+ {
2404
+ if ($(parent).get(0).tagName !== 'A')
2405
+ {
2406
+ $(el).replaceWith('<a href="' + link + '">' + this.outerHTML(el) + '</a>');
2407
+ }
2408
+ else
2409
+ {
2410
+ $(parent).attr('href', link);
2411
+ }
2412
+ }
2413
+ else
2414
+ {
2415
+ if ($(parent).get(0).tagName === 'A')
2416
+ {
2417
+ $(parent).replaceWith(this.outerHTML(el));
2418
+ }
2419
+ }
2420
+
2421
+ this.modalClose();
2422
+ this.observeImages();
2423
+ this.syncCode();
2424
+
2425
+ },
2426
+ showImage: function()
2427
+ {
2428
+ this.saveSelection();
2429
+
2430
+ var handler = $.proxy(function()
2431
+ {
2432
+ // json
2433
+ if (this.opts.imageGetJson !== false)
2434
+ {
2435
+ $.getJSON(this.opts.imageGetJson, $.proxy(function(data) {
2436
+
2437
+ var folders = {};
2438
+ var z = 0;
2439
+
2440
+ // folders
2441
+ $.each(data, $.proxy(function(key, val)
2442
+ {
2443
+ if (typeof val.folder !== 'undefined')
2444
+ {
2445
+ z++;
2446
+ folders[val.folder] = z;
2447
+ }
2448
+
2449
+ }, this));
2450
+
2451
+ var folderclass = false;
2452
+ $.each(data, $.proxy(function(key, val)
2453
+ {
2454
+ // title
2455
+ var thumbtitle = '';
2456
+ if (typeof val.title !== 'undefined')
2457
+ {
2458
+ thumbtitle = val.title;
2459
+ }
2460
+
2461
+ var folderkey = 0;
2462
+ if (!$.isEmptyObject(folders) && typeof val.folder !== 'undefined')
2463
+ {
2464
+ folderkey = folders[val.folder];
2465
+ if (folderclass === false)
2466
+ {
2467
+ folderclass = '.redactorfolder' + folderkey;
2468
+ }
2469
+ }
2470
+
2471
+ var img = $('<img src="' + val.thumb + '" class="redactorfolder redactorfolder' + folderkey + '" rel="' + val.image + '" title="' + thumbtitle + '" />');
2472
+ $('#redactor_image_box').append(img);
2473
+ $(img).click($.proxy(this.imageSetThumb, this));
2474
+
2475
+
2476
+ }, this));
2477
+
2478
+ // folders
2479
+ if (!$.isEmptyObject(folders))
2480
+ {
2481
+ $('.redactorfolder').hide();
2482
+ $(folderclass).show();
2483
+
2484
+ var onchangeFunc = function(e)
2485
+ {
2486
+ $('.redactorfolder').hide();
2487
+ $('.redactorfolder' + $(e.target).val()).show();
2488
+ }
2489
+
2490
+ var select = $('<select id="redactor_image_box_select">');
2491
+ $.each(folders, function(k,v)
2492
+ {
2493
+ select.append($('<option value="' + v + '">' + k + '</option>'));
2494
+ });
2495
+
2496
+ $('#redactor_image_box').before(select);
2497
+ select.change(onchangeFunc);
2498
+ }
2499
+
2500
+ }, this));
2501
+ }
2502
+ else
2503
+ {
2504
+ $('#redactor_tabs a').eq(1).remove();
2505
+ }
2506
+
2507
+ if (this.opts.imageUpload !== false)
2508
+ {
2509
+
2510
+ // dragupload
2511
+ if (this.opts.uploadCrossDomain === false && this.isMobile() === false)
2512
+ {
2513
+
2514
+ if ($('#redactor_file').size() !== 0)
2515
+ {
2516
+ $('#redactor_file').dragupload(
2517
+ {
2518
+ url: this.opts.imageUpload,
2519
+ uploadFields: this.opts.uploadFields,
2520
+ success: $.proxy(this.imageUploadCallback, this)
2521
+ });
2522
+ }
2523
+ }
2524
+
2525
+ // ajax upload
2526
+ this.uploadInit('redactor_file', { auto: true, url: this.opts.imageUpload, success: $.proxy(this.imageUploadCallback, this) });
2527
+ }
2528
+ else
2529
+ {
2530
+ $('.redactor_tab').hide();
2531
+ if (this.opts.imageGetJson === false)
2532
+ {
2533
+ $('#redactor_tabs').remove();
2534
+ $('#redactor_tab3').show();
2535
+ }
2536
+ else
2537
+ {
2538
+ var tabs = $('#redactor_tabs a');
2539
+ tabs.eq(0).remove();
2540
+ tabs.eq(1).addClass('redactor_tabs_act');
2541
+ $('#redactor_tab2').show();
2542
+ }
2543
+ }
2544
+
2545
+ $('#redactor_upload_btn').click($.proxy(this.imageUploadCallbackLink, this));
2546
+
2547
+ }, this);
2548
+
2549
+ var endCallback = $.proxy(function()
2550
+ {
2551
+ if (this.opts.imageUpload === false && this.opts.imageGetJson === false)
2552
+ {
2553
+ $('#redactor_file_link').focus();
2554
+ }
2555
+ }, this);
2556
+
2557
+ this.modalInit(RLANG.image, 'image', 570, handler, endCallback, true);
2558
+
2559
+ },
2560
+ imageSetThumb: function(e)
2561
+ {
2562
+ this._imageSet('<img src="' + $(e.target).attr('rel') + '" alt="' + $(e.target).attr('title') + '" />', true);
2563
+ },
2564
+ imageUploadCallbackLink: function()
2565
+ {
2566
+ if ($('#redactor_file_link').val() !== '')
2567
+ {
2568
+ var data = '<img src="' + $('#redactor_file_link').val() + '" />';
2569
+ this._imageSet(data, true);
2570
+ }
2571
+ else
2572
+ {
2573
+ this.modalClose();
2574
+ }
2575
+ },
2576
+ imageUploadCallback: function(data)
2577
+ {
2578
+ this._imageSet(data);
2579
+ },
2580
+ _imageSet: function(json, link)
2581
+ {
2582
+ this.restoreSelection();
2583
+
2584
+ if (json !== false)
2585
+ {
2586
+ var html = '', data = '';
2587
+ if (link !== true)
2588
+ {
2589
+ data = $.parseJSON(json);
2590
+ html = '<p><img src="' + data.filelink + '" /></p>';
2591
+ }
2592
+ else
2593
+ {
2594
+ html = json;
2595
+ }
2596
+
2597
+ this.execCommand('inserthtml', html);
2598
+
2599
+ // upload image callback
2600
+ if (link !== true && typeof this.opts.imageUploadCallback === 'function')
2601
+ {
2602
+ this.opts.imageUploadCallback(this, data);
2603
+ }
2604
+ }
2605
+
2606
+ this.modalClose();
2607
+ this.observeImages();
2608
+ },
2609
+
2610
+ // INSERT LINK
2611
+ showLink: function()
2612
+ {
2613
+ this.saveSelection();
2614
+
2615
+ var handler = $.proxy(function()
2616
+ {
2617
+ this.insert_link_node = false;
2618
+ var sel = this.getSelection();
2619
+ var url = '', text = '', target = '';
2620
+
2621
+ if ($.browser.msie)
2622
+ {
2623
+ var parent = this.getParentNode();
2624
+ if (parent.nodeName === 'A')
2625
+ {
2626
+ this.insert_link_node = $(parent);
2627
+ text = this.insert_link_node.text();
2628
+ url = this.insert_link_node.attr('href');
2629
+ target = this.insert_link_node.attr('target');
2630
+ }
2631
+ else
2632
+ {
2633
+ if (this.oldIE())
2634
+ {
2635
+ text = sel.text;
2636
+ }
2637
+ else
2638
+ {
2639
+ text = sel.toString();
2640
+ }
2641
+ }
2642
+ }
2643
+ else
2644
+ {
2645
+ if (sel && sel.anchorNode && sel.anchorNode.parentNode.tagName === 'A')
2646
+ {
2647
+ url = sel.anchorNode.parentNode.href;
2648
+ text = sel.anchorNode.parentNode.text;
2649
+ target = sel.anchorNode.parentNode.target;
2650
+
2651
+ if (sel.toString() === '')
2652
+ {
2653
+ this.insert_link_node = sel.anchorNode.parentNode;
2654
+ }
2655
+ }
2656
+ else
2657
+ {
2658
+ text = sel.toString();
2659
+ }
2660
+ }
2661
+
2662
+ $('.redactor_link_text').val(text);
2663
+
2664
+ var turl = url.replace(self.location.href, '');
2665
+
2666
+ if (url.search('mailto:') === 0)
2667
+ {
2668
+ this.setModalTab(2);
2669
+
2670
+ $('#redactor_tab_selected').val(2);
2671
+ $('#redactor_link_mailto').val(url.replace('mailto:', ''));
2672
+ }
2673
+ else if (turl.search(/^#/gi) === 0)
2674
+ {
2675
+ this.setModalTab(3);
2676
+
2677
+ $('#redactor_tab_selected').val(3);
2678
+ $('#redactor_link_anchor').val(turl.replace(/^#/gi, ''));
2679
+ }
2680
+ else
2681
+ {
2682
+ $('#redactor_link_url').val(url);
2683
+ }
2684
+
2685
+ if (target === '_blank')
2686
+ {
2687
+ $('#redactor_link_blank').attr('checked', true);
2688
+ }
2689
+
2690
+ $('#redactor_insert_link_btn').click($.proxy(this.insertLink, this));
2691
+
2692
+
2693
+ }, this);
2694
+
2695
+ var endCallback = function(url)
2696
+ {
2697
+ $('#redactor_link_url').focus();
2698
+ };
2699
+
2700
+
2701
+ this.modalInit(RLANG.link, 'link', 460, handler, endCallback);
2702
+
2703
+ },
2704
+ insertLink: function()
2705
+ {
2706
+ var tab_selected = $('#redactor_tab_selected').val();
2707
+ var link = '', text = '', target = '';
2708
+
2709
+ if (tab_selected === '1') // url
2710
+ {
2711
+ link = $('#redactor_link_url').val();
2712
+ text = $('#redactor_link_url_text').val();
2713
+
2714
+ if ($('#redactor_link_blank').attr('checked'))
2715
+ {
2716
+ target = '_blank';
2717
+ }
2718
+
2719
+ // test http
2720
+ var re = new RegExp('^https?://', 'i');
2721
+ if (link.search(re) == -1)
2722
+ {
2723
+ link = this.opts.protocol + link;
2724
+ }
2725
+ }
2726
+ else if (tab_selected === '2') // mailto
2727
+ {
2728
+ link = 'mailto:' + $('#redactor_link_mailto').val();
2729
+ text = $('#redactor_link_mailto_text').val();
2730
+ }
2731
+ else if (tab_selected === '3') // anchor
2732
+ {
2733
+ link = '#' + $('#redactor_link_anchor').val();
2734
+ text = $('#redactor_link_anchor_text').val();
2735
+ }
2736
+
2737
+ this._insertLink('<a href="' + link + '" target="' + target + '">' + text + '</a>&nbsp;', $.trim(text), link, target);
2738
+
2739
+ },
2740
+ _insertLink: function(a, text, link, target)
2741
+ {
2742
+ this.$editor.focus();
2743
+ this.restoreSelection();
2744
+
2745
+ if (text !== '')
2746
+ {
2747
+ if (this.insert_link_node)
2748
+ {
2749
+ $(this.insert_link_node).text(text);
2750
+ $(this.insert_link_node).attr('href', link);
2751
+ if (target !== '')
2752
+ {
2753
+ $(this.insert_link_node).attr('target', target);
2754
+ }
2755
+ this.syncCode();
2756
+ }
2757
+ else
2758
+ {
2759
+ this.execCommand('inserthtml', a);
2760
+ }
2761
+ }
2762
+
2763
+ this.modalClose();
2764
+ },
2765
+
2766
+ // INSERT FILE
2767
+ showFile: function()
2768
+ {
2769
+ this.saveSelection();
2770
+
2771
+ var handler = $.proxy(function()
2772
+ {
2773
+ var sel = this.getSelection();
2774
+
2775
+ var text = '';
2776
+
2777
+ if (this.oldIE())
2778
+ {
2779
+ text = sel.text;
2780
+ }
2781
+ else
2782
+ {
2783
+ text = sel.toString();
2784
+ }
2785
+
2786
+ $('#redactor_filename').val(text);
2787
+
2788
+ // dragupload
2789
+ if (this.opts.uploadCrossDomain === false && this.isMobile() === false)
2790
+ {
2791
+ $('#redactor_file').dragupload(
2792
+ {
2793
+ url: this.opts.fileUpload,
2794
+ uploadFields: this.opts.uploadFields,
2795
+ success: $.proxy(function(data)
2796
+ {
2797
+ this.fileUploadCallback(data);
2798
+ }, this)
2799
+ });
2800
+ }
2801
+
2802
+ this.uploadInit('redactor_file', { auto: true, url: this.opts.fileUpload, success: $.proxy(function(data) {
2803
+
2804
+ this.fileUploadCallback(data);
2805
+
2806
+ }, this)});
2807
+
2808
+ }, this);
2809
+
2810
+ this.modalInit(RLANG.file, 'file', 500, handler);
2811
+ },
2812
+ fileUploadCallback: function(json)
2813
+ {
2814
+ this.restoreSelection();
2815
+
2816
+ if (json !== false)
2817
+ {
2818
+ var data = $.parseJSON(json);
2819
+ var text = $('#redactor_filename').val();
2820
+
2821
+ if (text === '')
2822
+ {
2823
+ text = data.filename;
2824
+ }
2825
+
2826
+ var link = '<a href="' + data.filelink + '">' + text + '</a>';
2827
+
2828
+ // chrome fix
2829
+ if ($.browser.webkit && !!window.chrome)
2830
+ {
2831
+ link = link + '&nbsp;';
2832
+ }
2833
+
2834
+ this.execCommand('inserthtml', link);
2835
+
2836
+ // file upload callback
2837
+ if (typeof this.opts.fileUploadCallback === 'function')
2838
+ {
2839
+ this.opts.fileUploadCallback(this, data);
2840
+ }
2841
+ }
2842
+
2843
+ this.modalClose();
2844
+ },
2845
+
2846
+
2847
+
2848
+ // MODAL
2849
+ modalInit: function(title, url, width, handler, endCallback)
2850
+ {
2851
+ // modal overlay
2852
+ if ($('#redactor_modal_overlay').size() === 0)
2853
+ {
2854
+ this.overlay = $('<div id="redactor_modal_overlay" style="display: none;"></div>');
2855
+ $('body').prepend(this.overlay);
2856
+ }
2857
+
2858
+ if (this.opts.overlay)
2859
+ {
2860
+ $('#redactor_modal_overlay').show();
2861
+ $('#redactor_modal_overlay').click($.proxy(this.modalClose, this));
2862
+ }
2863
+
2864
+ if ($('#redactor_modal').size() === 0)
2865
+ {
2866
+ this.modal = $('<div id="redactor_modal" style="display: none;"><div id="redactor_modal_close">&times;</div><div id="redactor_modal_header"></div><div id="redactor_modal_inner"></div></div>');
2867
+ $('body').append(this.modal);
2868
+ }
2869
+
2870
+ $('#redactor_modal_close').click($.proxy(this.modalClose, this));
2871
+
2872
+ this.hdlModalClose = $.proxy(function(e) { if ( e.keyCode === 27) { this.modalClose(); } }, this);
2873
+
2874
+ $(document).keyup(this.hdlModalClose);
2875
+ this.$editor.keyup(this.hdlModalClose);
2876
+
2877
+ $('#redactor_modal_inner').html(this.opts['modal_' + url]);
2878
+ $('#redactor_modal_header').html(title);
2879
+
2880
+ // tabs
2881
+ if ($('#redactor_tabs').size() !== 0)
2882
+ {
2883
+ var that = this;
2884
+ $('#redactor_tabs a').each(function(i,s)
2885
+ {
2886
+ i++;
2887
+ $(s).click(function()
2888
+ {
2889
+ $('#redactor_tabs a').removeClass('redactor_tabs_act');
2890
+ $(this).addClass('redactor_tabs_act');
2891
+ $('.redactor_tab').hide();
2892
+ $('#redactor_tab' + i).show();
2893
+ $('#redactor_tab_selected').val(i);
2894
+
2895
+ if (that.isMobile() === false)
2896
+ {
2897
+ var height = $('#redactor_modal').outerHeight();
2898
+ $('#redactor_modal').css('margin-top', '-' + (height+10)/2 + 'px');
2899
+ }
2900
+ });
2901
+ });
2902
+ }
2903
+
2904
+ $('#redactor_btn_modal_close').click($.proxy(this.modalClose, this));
2905
+
2906
+ // callback
2907
+ if (typeof(handler) === 'function')
2908
+ {
2909
+ handler();
2910
+ }
2911
+
2912
+ // setup
2913
+ var height = $('#redactor_modal').outerHeight();
2914
+
2915
+ if (this.isMobile() === false)
2916
+ {
2917
+ $('#redactor_modal').css({ position: 'fixed', top: '50%', left: '50%', width: width + 'px', height: 'auto', minHeight: 'auto', marginTop: '-' + (height+10)/2 + 'px', marginLeft: '-' + (width+60)/2 + 'px' }).fadeIn('fast');
2918
+
2919
+ this.modalSaveBodyOveflow = $(document.body).css('overflow');
2920
+ $(document.body).css('overflow', 'hidden');
2921
+ }
2922
+ else
2923
+ {
2924
+ $('#redactor_modal').css({ position: 'fixed', width: '100%', height: '100%', top: '0', left: '0', margin: '0', minHeight: '300px' }).show();
2925
+ }
2926
+
2927
+ // end callback
2928
+ if (typeof(endCallback) === 'function')
2929
+ {
2930
+ endCallback();
2931
+ }
2932
+
2933
+ },
2934
+ modalClose: function()
2935
+ {
2936
+
2937
+ $('#redactor_modal_close').unbind('click', this.modalClose);
2938
+ $('#redactor_modal').fadeOut('fast', $.proxy(function()
2939
+ {
2940
+ $('#redactor_modal_inner').html('');
2941
+
2942
+ if (this.opts.overlay)
2943
+ {
2944
+ $('#redactor_modal_overlay').hide();
2945
+ $('#redactor_modal_overlay').unbind('click', this.modalClose);
2946
+ }
2947
+
2948
+ $(document).unbind('keyup', this.hdlModalClose);
2949
+ this.$editor.unbind('keyup', this.hdlModalClose);
2950
+
2951
+ }, this));
2952
+
2953
+ if (this.isMobile() === false)
2954
+ {
2955
+ $(document.body).css('overflow', this.modalSaveBodyOveflow);
2956
+ }
2957
+
2958
+ },
2959
+ setModalTab: function(num)
2960
+ {
2961
+ $('.redactor_tab').hide();
2962
+ var tabs = $('#redactor_tabs a');
2963
+ tabs.removeClass('redactor_tabs_act');
2964
+ tabs.eq(num-1).addClass('redactor_tabs_act');
2965
+ $('#redactor_tab' + num).show();
2966
+ },
2967
+
2968
+ // UPLOAD
2969
+ uploadInit: function(element, options)
2970
+ {
2971
+ // Upload Options
2972
+ this.uploadOptions = {
2973
+ url: false,
2974
+ success: false,
2975
+ start: false,
2976
+ trigger: false,
2977
+ auto: false,
2978
+ input: false
2979
+ };
2980
+
2981
+ $.extend(this.uploadOptions, options);
2982
+
2983
+ // Test input or form
2984
+ if ($('#' + element).size() !== 0 && $('#' + element).get(0).tagName === 'INPUT')
2985
+ {
2986
+ this.uploadOptions.input = $('#' + element);
2987
+ this.element = $($('#' + element).get(0).form);
2988
+ }
2989
+ else
2990
+ {
2991
+ this.element = $('#' + element);
2992
+ }
2993
+
2994
+ this.element_action = this.element.attr('action');
2995
+
2996
+ // Auto or trigger
2997
+ if (this.uploadOptions.auto)
2998
+ {
2999
+ $(this.uploadOptions.input).change($.proxy(function()
3000
+ {
3001
+ this.element.submit(function(e) { return false; });
3002
+ this.uploadSubmit();
3003
+ }, this));
3004
+
3005
+ }
3006
+ else if (this.uploadOptions.trigger)
3007
+ {
3008
+ $('#' + this.uploadOptions.trigger).click($.proxy(this.uploadSubmit, this));
3009
+ }
3010
+ },
3011
+ uploadSubmit : function()
3012
+ {
3013
+ this.uploadForm(this.element, this.uploadFrame());
3014
+ },
3015
+ uploadFrame : function()
3016
+ {
3017
+ this.id = 'f' + Math.floor(Math.random() * 99999);
3018
+
3019
+ var d = document.createElement('div');
3020
+ var iframe = '<iframe style="display:none" id="'+this.id+'" name="'+this.id+'"></iframe>';
3021
+ d.innerHTML = iframe;
3022
+ document.body.appendChild(d);
3023
+
3024
+ // Start
3025
+ if (this.uploadOptions.start)
3026
+ {
3027
+ this.uploadOptions.start();
3028
+ }
3029
+
3030
+ $('#' + this.id).load($.proxy(this.uploadLoaded, this));
3031
+
3032
+ return this.id;
3033
+ },
3034
+ uploadForm : function(f, name)
3035
+ {
3036
+ if (this.uploadOptions.input)
3037
+ {
3038
+ var formId = 'redactorUploadForm' + this.id;
3039
+ var fileId = 'redactorUploadFile' + this.id;
3040
+ this.form = $('<form action="' + this.uploadOptions.url + '" method="POST" target="' + name + '" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
3041
+
3042
+ // append hidden fields
3043
+ if (this.opts.uploadFields !== false && typeof this.opts.uploadFields === 'object')
3044
+ {
3045
+ $.each(this.opts.uploadFields, $.proxy(function(k,v)
3046
+ {
3047
+ if (v.indexOf('#') === 0)
3048
+ {
3049
+ v = $(v).val();
3050
+ }
3051
+
3052
+ var hidden = $('<input type="hidden" name="' + k + '" value="' + v + '">');
3053
+ $(this.form).append(hidden);
3054
+
3055
+ }, this));
3056
+ }
3057
+
3058
+ var oldElement = this.uploadOptions.input;
3059
+ var newElement = $(oldElement).clone();
3060
+ $(oldElement).attr('id', fileId);
3061
+ $(oldElement).before(newElement);
3062
+ $(oldElement).appendTo(this.form);
3063
+ $(this.form).css('position', 'absolute');
3064
+ $(this.form).css('top', '-2000px');
3065
+ $(this.form).css('left', '-2000px');
3066
+ $(this.form).appendTo('body');
3067
+
3068
+ this.form.submit();
3069
+ }
3070
+ else
3071
+ {
3072
+ f.attr('target', name);
3073
+ f.attr('method', 'POST');
3074
+ f.attr('enctype', 'multipart/form-data');
3075
+ f.attr('action', this.uploadOptions.url);
3076
+
3077
+ this.element.submit();
3078
+ }
3079
+
3080
+ },
3081
+ uploadLoaded : function()
3082
+ {
3083
+ var i = $('#' + this.id);
3084
+ var d;
3085
+
3086
+ if (i.contentDocument)
3087
+ {
3088
+ d = i.contentDocument;
3089
+ }
3090
+ else if (i.contentWindow)
3091
+ {
3092
+ d = i.contentWindow.document;
3093
+ }
3094
+ else
3095
+ {
3096
+ d = window.frames[this.id].document;
3097
+ }
3098
+
3099
+ // Success
3100
+ if (this.uploadOptions.success)
3101
+ {
3102
+ if (typeof d !== 'undefined')
3103
+ {
3104
+ // Remove bizarre <pre> tag wrappers around our json data:
3105
+ var rawString = d.body.innerHTML;
3106
+ var jsonString = rawString.match(/\{.*\}/)[0];
3107
+ this.uploadOptions.success(jsonString);
3108
+ }
3109
+ else
3110
+ {
3111
+ alert('Upload failed!');
3112
+ this.uploadOptions.success(false);
3113
+ }
3114
+ }
3115
+
3116
+ this.element.attr('action', this.element_action);
3117
+ this.element.attr('target', '');
3118
+
3119
+ },
3120
+
3121
+ // UTILITY
3122
+ oldIE: function()
3123
+ {
3124
+ if ($.browser.msie && parseInt($.browser.version, 10) < 9)
3125
+ {
3126
+ return true;
3127
+ }
3128
+
3129
+ return false;
3130
+ },
3131
+ outerHTML: function(s)
3132
+ {
3133
+ return $("<p>").append($(s).eq(0).clone()).html();
3134
+ },
3135
+ normalize: function(str)
3136
+ {
3137
+ return parseInt(str.replace('px',''), 10);
3138
+ },
3139
+ isMobile: function(ipad)
3140
+ {
3141
+ if (ipad === true && /(iPhone|iPod|iPad|BlackBerry|Android)/.test(navigator.userAgent))
3142
+ {
3143
+ return true;
3144
+ }
3145
+ else if (/(iPhone|iPod|BlackBerry|Android)/.test(navigator.userAgent))
3146
+ {
3147
+ return true;
3148
+ }
3149
+ else
3150
+ {
3151
+ return false;
3152
+ }
3153
+ }
3154
+
3155
+ };
3156
+
3157
+
3158
+ // API
3159
+ $.fn.getEditor = function()
3160
+ {
3161
+ return this.data('redactor').$editor;
3162
+ };
3163
+
3164
+ $.fn.getCode = function()
3165
+ {
3166
+ return this.data('redactor').getCode();
3167
+ };
3168
+
3169
+ $.fn.getText = function()
3170
+ {
3171
+ return this.data('redactor').$editor.text();
3172
+ };
3173
+
3174
+ $.fn.getSelected = function()
3175
+ {
3176
+ return this.data('redactor').getSelectedHtml();
3177
+ };
3178
+
3179
+ $.fn.setCode = function(html)
3180
+ {
3181
+ this.data('redactor').setCode(html);
3182
+ };
3183
+
3184
+ $.fn.insertHtml = function(html)
3185
+ {
3186
+ this.data('redactor').insertHtml(html);
3187
+ };
3188
+
3189
+ $.fn.destroyEditor = function()
3190
+ {
3191
+ this.data('redactor').destroy();
3192
+ this.removeData('redactor');
3193
+ };
3194
+
3195
+ $.fn.setFocus = function()
3196
+ {
3197
+ this.data('redactor').$editor.focus();
3198
+ };
3199
+
3200
+ $.fn.execCommand = function(cmd, param)
3201
+ {
3202
+ this.data('redactor').execCommand(cmd, param);
3203
+ };
3204
+
3205
+ })(jQuery);
3206
+
3207
+ /*
3208
+ Plugin Drag and drop Upload v1.0.2
3209
+ http://imperavi.com/
3210
+ Copyright 2012, Imperavi Inc.
3211
+ */
3212
+ (function($){
3213
+
3214
+ "use strict";
3215
+
3216
+ // Initialization
3217
+ $.fn.dragupload = function(options)
3218
+ {
3219
+ return this.each(function() {
3220
+ var obj = new Construct(this, options);
3221
+ obj.init();
3222
+ });
3223
+ };
3224
+
3225
+ // Options and variables
3226
+ function Construct(el, options) {
3227
+
3228
+ this.opts = $.extend({
3229
+
3230
+ url: false,
3231
+ success: false,
3232
+ preview: false,
3233
+ uploadFields: false,
3234
+
3235
+ text: RLANG.drop_file_here,
3236
+ atext: RLANG.or_choose
3237
+
3238
+ }, options);
3239
+
3240
+ this.$el = $(el);
3241
+ }
3242
+
3243
+ // Functionality
3244
+ Construct.prototype = {
3245
+ init: function()
3246
+ {
3247
+ if (!$.browser.msie)
3248
+ {
3249
+ this.droparea = $('<div class="redactor_droparea"></div>');
3250
+ this.dropareabox = $('<div class="redactor_dropareabox">' + this.opts.text + '</div>');
3251
+ this.dropalternative = $('<div class="redactor_dropalternative">' + this.opts.atext + '</div>');
3252
+
3253
+ this.droparea.append(this.dropareabox);
3254
+
3255
+ this.$el.before(this.droparea);
3256
+ this.$el.before(this.dropalternative);
3257
+
3258
+ // drag over
3259
+ this.dropareabox.bind('dragover', $.proxy(function() { return this.ondrag(); }, this));
3260
+
3261
+ // drag leave
3262
+ this.dropareabox.bind('dragleave', $.proxy(function() { return this.ondragleave(); }, this));
3263
+
3264
+ var uploadProgress = $.proxy(function(e)
3265
+ {
3266
+ var percent = parseInt(e.loaded / e.total * 100, 10);
3267
+ this.dropareabox.text('Loading ' + percent + '%');
3268
+
3269
+ }, this);
3270
+
3271
+ var xhr = jQuery.ajaxSettings.xhr();
3272
+
3273
+ if (xhr.upload)
3274
+ {
3275
+ xhr.upload.addEventListener('progress', uploadProgress, false);
3276
+ }
3277
+
3278
+ var provider = function () { return xhr; };
3279
+
3280
+ // drop
3281
+ this.dropareabox.get(0).ondrop = $.proxy(function(event)
3282
+ {
3283
+ event.preventDefault();
3284
+
3285
+ this.dropareabox.removeClass('hover').addClass('drop');
3286
+
3287
+ var file = event.dataTransfer.files[0];
3288
+ var fd = new FormData();
3289
+
3290
+ // append hidden fields
3291
+ if (this.opts.uploadFields !== false && typeof this.opts.uploadFields === 'object')
3292
+ {
3293
+ $.each(this.opts.uploadFields, $.proxy(function(k,v)
3294
+ {
3295
+ if (v.indexOf('#') === 0)
3296
+ {
3297
+ v = $(v).val();
3298
+ }
3299
+
3300
+ fd.append(k, v);
3301
+
3302
+ }, this));
3303
+ }
3304
+
3305
+ // append file data
3306
+ fd.append('file', file);
3307
+
3308
+
3309
+ $.ajax({
3310
+ dataType: 'html',
3311
+ url: this.opts.url,
3312
+ data: fd,
3313
+ xhr: provider,
3314
+ cache: false,
3315
+ contentType: false,
3316
+ processData: false,
3317
+ type: 'POST',
3318
+ success: $.proxy(function(data)
3319
+ {
3320
+ if (this.opts.success !== false)
3321
+ {
3322
+ this.opts.success(data);
3323
+ }
3324
+
3325
+ if (this.opts.preview === true)
3326
+ {
3327
+ this.dropareabox.html(data);
3328
+ }
3329
+
3330
+ }, this)
3331
+ });
3332
+
3333
+
3334
+ }, this);
3335
+ }
3336
+ },
3337
+ ondrag: function()
3338
+ {
3339
+ this.dropareabox.addClass('hover');
3340
+ return false;
3341
+ },
3342
+ ondragleave: function()
3343
+ {
3344
+ this.dropareabox.removeClass('hover');
3345
+ return false;
3346
+ }
3347
+ };
3348
+
3349
+ })(jQuery);
3350
+
3351
+
3352
+ // Define: Linkify plugin from stackoverflow
3353
+ (function($){
3354
+
3355
+ "use strict";
3356
+
3357
+ var protocol = 'http://';
3358
+ var url1 = /(^|&lt;|\s)(www\..+?\..+?)(\s|&gt;|$)/g,
3359
+ url2 = /(^|&lt;|\s)(((https?|ftp):\/\/|mailto:).+?)(\s|&gt;|$)/g,
3360
+
3361
+ linkifyThis = function ()
3362
+ {
3363
+ var childNodes = this.childNodes,
3364
+ i = childNodes.length;
3365
+ while(i--)
3366
+ {
3367
+ var n = childNodes[i];
3368
+ if (n.nodeType === 3)
3369
+ {
3370
+ var html = n.nodeValue;
3371
+ if (html)
3372
+ {
3373
+ html = html.replace(/&/g, '&amp;')
3374
+ .replace(/</g, '&lt;')
3375
+ .replace(/>/g, '&gt;')
3376
+ .replace(url1, '$1<a href="' + protocol + '$2">$2</a>$3')
3377
+ .replace(url2, '$1<a href="$2">$2</a>$5');
3378
+
3379
+ $(n).after(html).remove();
3380
+ }
3381
+ }
3382
+ else if (n.nodeType === 1 && !/^(a|button|textarea)$/i.test(n.tagName))
3383
+ {
3384
+ linkifyThis.call(n);
3385
+ }
3386
+ }
3387
+ };
3388
+
3389
+ $.fn.linkify = function ()
3390
+ {
3391
+ this.each(linkifyThis);
3392
+ };
3393
+
3394
+ })(jQuery);
3395
+
3396
+
3397
+
3398
+
3399
+ /* jQuery plugin textselect
3400
+ * version: 0.9
3401
+ * author: Josef Moravec, josef.moravec@gmail.com
3402
+ * updated: Imperavi Inc.
3403
+ *
3404
+ */
3405
+ (function($){$.event.special.textselect={setup:function(data,namespaces){$(this).data("textselected",false);$(this).data("ttt",data);$(this).bind('mouseup',$.event.special.textselect.handler)},teardown:function(data){$(this).unbind('mouseup',$.event.special.textselect.handler)},handler:function(event){var data=$(this).data("ttt");var text=$.event.special.textselect.getSelectedText(data).toString();if(text!=''){$(this).data("textselected",true);event.type="textselect";event.text=text;$.event.handle.apply(this,arguments)}},getSelectedText:function(data){var text='';if(window.getSelection)text=window.getSelection();else if(document.getSelection) text=document.getSelection();else if(document.selection)text=document.selection.createRange().text;return text}};$.event.special.textunselect={setup:function(data,namespaces){$(this).data("rttt",data);$(this).data("textselected",false);$(this).bind('mouseup',$.event.special.textunselect.handler);$(this).bind('keyup',$.event.special.textunselect.handlerKey)},teardown:function(data){$(this).unbind('mouseup',$.event.special.textunselect.handler)},handler:function(event){if($(this).data("textselected")){var data=$(this).data("rttt");var text=$.event.special.textselect.getSelectedText(data).toString();if(text==''){$(this).data("textselected",false);event.type="textunselect";$.event.handle.apply(this,arguments)}}},handlerKey:function(event){if($(this).data("textselected")){var data=$(this).data("rttt");var text=$.event.special.textselect.getSelectedText(data).toString();if((event.keyCode=27)&&(text=='')){$(this).data("textselected",false);event.type="textunselect";$.event.handle.apply(this,arguments)}}}}})(jQuery);