Mercurial > hg > rr-repo
comparison sites/all/modules/insert/insert.js @ 0:ff03f76ab3fe
initial version
author | danieleb <danielebarchiesi@me.com> |
---|---|
date | Wed, 21 Aug 2013 18:51:11 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:ff03f76ab3fe |
---|---|
1 /** | |
2 * @file | |
3 * JavaScript to activate "Insert" buttons on file and image fields. | |
4 */ | |
5 | |
6 (function ($) { | |
7 | |
8 /** | |
9 * Behavior to add "Insert" buttons. | |
10 */ | |
11 Drupal.behaviors.insert = {}; | |
12 Drupal.behaviors.insert.attach = function(context) { | |
13 if (typeof(insertTextarea) == 'undefined') { | |
14 insertTextarea = $('#edit-body textarea.text-full').get(0) || false; | |
15 } | |
16 | |
17 // Keep track of the last active textarea (if not using WYSIWYG). | |
18 $('textarea:not([name$="[data][title]"]):not(.insert-processed)', context).addClass('insert-processed').focus(insertSetActive).blur(insertRemoveActive); | |
19 | |
20 // Add the click handler to the insert button. | |
21 $('.insert-button:not(.insert-processed)', context).addClass('insert-processed').click(insert); | |
22 | |
23 function insertSetActive() { | |
24 insertTextarea = this; | |
25 this.insertHasFocus = true; | |
26 } | |
27 | |
28 function insertRemoveActive() { | |
29 if (insertTextarea == this) { | |
30 var thisTextarea = this; | |
31 setTimeout(function() { | |
32 thisTextarea.insertHasFocus = false; | |
33 }, 1000); | |
34 } | |
35 } | |
36 | |
37 function insert() { | |
38 var widgetType = $(this).attr('rel'); | |
39 var settings = Drupal.settings.insert.widgets[widgetType]; | |
40 var wrapper = $(this).parents(settings.wrapper).filter(':first').get(0); | |
41 var style = $('.insert-style', wrapper).val(); | |
42 var content = $('input.insert-template[name$="[' + style + ']"]', wrapper).val(); | |
43 var filename = $('input.insert-filename', wrapper).val(); | |
44 var options = { | |
45 widgetType: widgetType, | |
46 filename: filename, | |
47 style: style, | |
48 fields: {} | |
49 }; | |
50 | |
51 // Update replacements. | |
52 for (var fieldName in settings.fields) { | |
53 var fieldValue = $(settings.fields[fieldName], wrapper).val(); | |
54 if (fieldValue) { | |
55 fieldValue = fieldValue | |
56 .replace(/&/g, '&') | |
57 .replace(/"/g, '"') | |
58 .replace(/'/g, ''') | |
59 .replace(/</g, '<') | |
60 .replace(/>/g, '>'); | |
61 } | |
62 options['fields'][fieldName] = fieldValue; | |
63 if (fieldValue) { | |
64 var fieldRegExp = new RegExp('__' + fieldName + '(_or_filename)?__', 'g'); | |
65 content = content.replace(fieldRegExp, fieldValue); | |
66 } | |
67 else { | |
68 var fieldRegExp = new RegExp('__' + fieldName + '_or_filename__', 'g'); | |
69 content = content.replace(fieldRegExp, filename); | |
70 } | |
71 } | |
72 | |
73 // File name replacement. | |
74 var fieldRegExp = new RegExp('__filename__', 'g'); | |
75 content = content.replace(fieldRegExp, filename); | |
76 | |
77 // Check for a maximum dimension and scale down the width if necessary. | |
78 // This is intended for use with Image Resize Filter. | |
79 var widthMatches = content.match(/width[ ]*=[ ]*"(\d*)"/i); | |
80 var heightMatches = content.match(/height[ ]*=[ ]*"(\d*)"/i); | |
81 if (settings.maxWidth && widthMatches && parseInt(widthMatches[1]) > settings.maxWidth) { | |
82 var insertRatio = settings.maxWidth / widthMatches[1]; | |
83 var width = settings.maxWidth; | |
84 content = content.replace(/width[ ]*=[ ]*"?(\d*)"?/i, 'width="' + width + '"'); | |
85 | |
86 if (heightMatches) { | |
87 var height = Math.round(heightMatches[1] * insertRatio); | |
88 content = content.replace(/height[ ]*=[ ]*"?(\d*)"?/i, 'height="' + height + '"'); | |
89 } | |
90 } | |
91 | |
92 // Allow other modules to perform replacements. | |
93 options['content'] = content; | |
94 $.event.trigger('insertIntoActiveEditor', [options]); | |
95 content = options['content']; | |
96 | |
97 // Cleanup unused replacements. | |
98 content = content.replace(/"__([a-z0-9_]+)__"/g, '""'); | |
99 | |
100 // Cleanup empty attributes (other than alt). | |
101 content = content.replace(/([a-z]+)[ ]*=[ ]*""/g, function(match, tagName) { | |
102 return (tagName === 'alt') ? match : ''; | |
103 }); | |
104 | |
105 // Insert the text. | |
106 Drupal.insert.insertIntoActiveEditor(content); | |
107 } | |
108 }; | |
109 | |
110 // General Insert API functions. | |
111 Drupal.insert = { | |
112 /** | |
113 * Insert content into the current (or last active) editor on the page. This | |
114 * should work with most WYSIWYGs as well as plain textareas. | |
115 * | |
116 * @param content | |
117 */ | |
118 insertIntoActiveEditor: function(content) { | |
119 var editorElement; | |
120 | |
121 // Always work in normal text areas that currently have focus. | |
122 if (insertTextarea && insertTextarea.insertHasFocus) { | |
123 editorElement = insertTextarea; | |
124 Drupal.insert.insertAtCursor(insertTextarea, content); | |
125 } | |
126 // Direct tinyMCE support. | |
127 else if (typeof(tinyMCE) != 'undefined' && tinyMCE.activeEditor) { | |
128 editorElement = document.getElementById(tinyMCE.activeEditor.editorId); | |
129 Drupal.insert.activateTabPane(editorElement); | |
130 tinyMCE.activeEditor.execCommand('mceInsertContent', false, content); | |
131 } | |
132 // WYSIWYG support, should work in all editors if available. | |
133 else if (Drupal.wysiwyg && Drupal.wysiwyg.activeId) { | |
134 editorElement = document.getElementById(Drupal.wysiwyg.activeId); | |
135 Drupal.insert.activateTabPane(editorElement); | |
136 Drupal.wysiwyg.instances[Drupal.wysiwyg.activeId].insert(content) | |
137 } | |
138 // FCKeditor module support. | |
139 else if (typeof(FCKeditorAPI) != 'undefined' && typeof(fckActiveId) != 'undefined') { | |
140 editorElement = document.getElementById(fckActiveId); | |
141 Drupal.insert.activateTabPane(editorElement); | |
142 FCKeditorAPI.Instances[fckActiveId].InsertHtml(content); | |
143 } | |
144 // Direct FCKeditor support (only body field supported). | |
145 else if (typeof(FCKeditorAPI) != 'undefined') { | |
146 // Try inserting into the body. | |
147 if (FCKeditorAPI.Instances[insertTextarea.id]) { | |
148 editorElement = insertTextarea; | |
149 Drupal.insert.activateTabPane(editorElement); | |
150 FCKeditorAPI.Instances[insertTextarea.id].InsertHtml(content); | |
151 } | |
152 // Try inserting into the first instance we find (may occur with very | |
153 // old versions of FCKeditor). | |
154 else { | |
155 for (var n in FCKeditorAPI.Instances) { | |
156 editorElement = document.getElementById(n); | |
157 Drupal.insert.activateTabPane(editorElement); | |
158 FCKeditorAPI.Instances[n].InsertHtml(content); | |
159 break; | |
160 } | |
161 } | |
162 } | |
163 // CKeditor module support. | |
164 else if (typeof(CKEDITOR) != 'undefined' && typeof(Drupal.ckeditorActiveId) != 'undefined') { | |
165 editorElement = document.getElementById(Drupal.ckeditorActiveId); | |
166 Drupal.insert.activateTabPane(editorElement); | |
167 CKEDITOR.instances[Drupal.ckeditorActiveId].insertHtml(content); | |
168 } | |
169 // Direct CKeditor support (only body field supported). | |
170 else if (typeof(CKEDITOR) != 'undefined' && CKEDITOR.instances[insertTextarea.id]) { | |
171 editorElement = insertTextarea; | |
172 Drupal.insert.activateTabPane(editorElement); | |
173 CKEDITOR.instances[insertTextarea.id].insertHtml(content); | |
174 } | |
175 else if (insertTextarea) { | |
176 editorElement = insertTextarea; | |
177 Drupal.insert.activateTabPane(editorElement); | |
178 Drupal.insert.insertAtCursor(insertTextarea, content); | |
179 } | |
180 | |
181 if (editorElement) { | |
182 Drupal.insert.contentWarning(editorElement, content); | |
183 } | |
184 | |
185 return false; | |
186 }, | |
187 | |
188 /** | |
189 * Check for vertical tabs and activate the pane containing the editor. | |
190 * | |
191 * @param editor | |
192 * The DOM object of the editor that will be checked. | |
193 */ | |
194 activateTabPane: function(editor) { | |
195 var $pane = $(editor).parents('.vertical-tabs-pane:first'); | |
196 var $panes = $pane.parent('.vertical-tabs-panes'); | |
197 var $tabs = $panes.parents('.vertical-tabs:first').find('ul.vertical-tabs-list:first li a'); | |
198 if ($pane.size() && $pane.is(':hidden') && $panes.size() && $tabs.size()) { | |
199 var index = $panes.children().index($pane); | |
200 $tabs.eq(index).click(); | |
201 } | |
202 }, | |
203 | |
204 /** | |
205 * Warn users when attempting to insert an image into an unsupported field. | |
206 * | |
207 * This function is only a 90% use-case, as it doesn't support when the filter | |
208 * tip are hidden, themed, or when only one format is available. However it | |
209 * should fail silently in these situations. | |
210 */ | |
211 contentWarning: function(editorElement, content) { | |
212 if (!content.match(/<img /)) return; | |
213 | |
214 var $wrapper = $(editorElement).parents('div.text-format-wrapper:first'); | |
215 if (!$wrapper.length) return; | |
216 | |
217 $wrapper.find('.filter-guidelines-item:visible li').each(function(index, element) { | |
218 var expression = new RegExp(Drupal.t('Allowed HTML tags')); | |
219 if (expression.exec(element.textContent) && !element.textContent.match(/<img>/)) { | |
220 alert(Drupal.t("The selected text format will not allow it to display images. The text format will need to be changed for this image to display properly when saved.")); | |
221 } | |
222 }); | |
223 }, | |
224 | |
225 /** | |
226 * Insert content into a textarea at the current cursor position. | |
227 * | |
228 * @param editor | |
229 * The DOM object of the textarea that will receive the text. | |
230 * @param content | |
231 * The string to be inserted. | |
232 */ | |
233 insertAtCursor: function(editor, content) { | |
234 // Record the current scroll position. | |
235 var scroll = editor.scrollTop; | |
236 | |
237 // IE support. | |
238 if (document.selection) { | |
239 editor.focus(); | |
240 sel = document.selection.createRange(); | |
241 sel.text = content; | |
242 } | |
243 | |
244 // Mozilla/Firefox/Netscape 7+ support. | |
245 else if (editor.selectionStart || editor.selectionStart == '0') { | |
246 var startPos = editor.selectionStart; | |
247 var endPos = editor.selectionEnd; | |
248 editor.value = editor.value.substring(0, startPos) + content + editor.value.substring(endPos, editor.value.length); | |
249 } | |
250 | |
251 // Fallback, just add to the end of the content. | |
252 else { | |
253 editor.value += content; | |
254 } | |
255 | |
256 // Ensure the textarea does not unexpectedly scroll. | |
257 editor.scrollTop = scroll; | |
258 } | |
259 }; | |
260 | |
261 })(jQuery); |