danielebarchiesi@0: /** danielebarchiesi@0: * @file danielebarchiesi@0: * JavaScript to activate "Insert" buttons on file and image fields. danielebarchiesi@0: */ danielebarchiesi@0: danielebarchiesi@0: (function ($) { danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Behavior to add "Insert" buttons. danielebarchiesi@0: */ danielebarchiesi@0: Drupal.behaviors.insert = {}; danielebarchiesi@0: Drupal.behaviors.insert.attach = function(context) { danielebarchiesi@0: if (typeof(insertTextarea) == 'undefined') { danielebarchiesi@0: insertTextarea = $('#edit-body textarea.text-full').get(0) || false; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // Keep track of the last active textarea (if not using WYSIWYG). danielebarchiesi@0: $('textarea:not([name$="[data][title]"]):not(.insert-processed)', context).addClass('insert-processed').focus(insertSetActive).blur(insertRemoveActive); danielebarchiesi@0: danielebarchiesi@0: // Add the click handler to the insert button. danielebarchiesi@0: $('.insert-button:not(.insert-processed)', context).addClass('insert-processed').click(insert); danielebarchiesi@0: danielebarchiesi@0: function insertSetActive() { danielebarchiesi@0: insertTextarea = this; danielebarchiesi@0: this.insertHasFocus = true; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: function insertRemoveActive() { danielebarchiesi@0: if (insertTextarea == this) { danielebarchiesi@0: var thisTextarea = this; danielebarchiesi@0: setTimeout(function() { danielebarchiesi@0: thisTextarea.insertHasFocus = false; danielebarchiesi@0: }, 1000); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: function insert() { danielebarchiesi@0: var widgetType = $(this).attr('rel'); danielebarchiesi@0: var settings = Drupal.settings.insert.widgets[widgetType]; danielebarchiesi@0: var wrapper = $(this).parents(settings.wrapper).filter(':first').get(0); danielebarchiesi@0: var style = $('.insert-style', wrapper).val(); danielebarchiesi@0: var content = $('input.insert-template[name$="[' + style + ']"]', wrapper).val(); danielebarchiesi@0: var filename = $('input.insert-filename', wrapper).val(); danielebarchiesi@0: var options = { danielebarchiesi@0: widgetType: widgetType, danielebarchiesi@0: filename: filename, danielebarchiesi@0: style: style, danielebarchiesi@0: fields: {} danielebarchiesi@0: }; danielebarchiesi@0: danielebarchiesi@0: // Update replacements. danielebarchiesi@0: for (var fieldName in settings.fields) { danielebarchiesi@0: var fieldValue = $(settings.fields[fieldName], wrapper).val(); danielebarchiesi@0: if (fieldValue) { danielebarchiesi@0: fieldValue = fieldValue danielebarchiesi@0: .replace(/&/g, '&') danielebarchiesi@0: .replace(/"/g, '"') danielebarchiesi@0: .replace(/'/g, ''') danielebarchiesi@0: .replace(//g, '>'); danielebarchiesi@0: } danielebarchiesi@0: options['fields'][fieldName] = fieldValue; danielebarchiesi@0: if (fieldValue) { danielebarchiesi@0: var fieldRegExp = new RegExp('__' + fieldName + '(_or_filename)?__', 'g'); danielebarchiesi@0: content = content.replace(fieldRegExp, fieldValue); danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: var fieldRegExp = new RegExp('__' + fieldName + '_or_filename__', 'g'); danielebarchiesi@0: content = content.replace(fieldRegExp, filename); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // File name replacement. danielebarchiesi@0: var fieldRegExp = new RegExp('__filename__', 'g'); danielebarchiesi@0: content = content.replace(fieldRegExp, filename); danielebarchiesi@0: danielebarchiesi@0: // Check for a maximum dimension and scale down the width if necessary. danielebarchiesi@0: // This is intended for use with Image Resize Filter. danielebarchiesi@0: var widthMatches = content.match(/width[ ]*=[ ]*"(\d*)"/i); danielebarchiesi@0: var heightMatches = content.match(/height[ ]*=[ ]*"(\d*)"/i); danielebarchiesi@0: if (settings.maxWidth && widthMatches && parseInt(widthMatches[1]) > settings.maxWidth) { danielebarchiesi@0: var insertRatio = settings.maxWidth / widthMatches[1]; danielebarchiesi@0: var width = settings.maxWidth; danielebarchiesi@0: content = content.replace(/width[ ]*=[ ]*"?(\d*)"?/i, 'width="' + width + '"'); danielebarchiesi@0: danielebarchiesi@0: if (heightMatches) { danielebarchiesi@0: var height = Math.round(heightMatches[1] * insertRatio); danielebarchiesi@0: content = content.replace(/height[ ]*=[ ]*"?(\d*)"?/i, 'height="' + height + '"'); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // Allow other modules to perform replacements. danielebarchiesi@0: options['content'] = content; danielebarchiesi@0: $.event.trigger('insertIntoActiveEditor', [options]); danielebarchiesi@0: content = options['content']; danielebarchiesi@0: danielebarchiesi@0: // Cleanup unused replacements. danielebarchiesi@0: content = content.replace(/"__([a-z0-9_]+)__"/g, '""'); danielebarchiesi@0: danielebarchiesi@0: // Cleanup empty attributes (other than alt). danielebarchiesi@0: content = content.replace(/([a-z]+)[ ]*=[ ]*""/g, function(match, tagName) { danielebarchiesi@0: return (tagName === 'alt') ? match : ''; danielebarchiesi@0: }); danielebarchiesi@0: danielebarchiesi@0: // Insert the text. danielebarchiesi@0: Drupal.insert.insertIntoActiveEditor(content); danielebarchiesi@0: } danielebarchiesi@0: }; danielebarchiesi@0: danielebarchiesi@0: // General Insert API functions. danielebarchiesi@0: Drupal.insert = { danielebarchiesi@0: /** danielebarchiesi@0: * Insert content into the current (or last active) editor on the page. This danielebarchiesi@0: * should work with most WYSIWYGs as well as plain textareas. danielebarchiesi@0: * danielebarchiesi@0: * @param content danielebarchiesi@0: */ danielebarchiesi@0: insertIntoActiveEditor: function(content) { danielebarchiesi@0: var editorElement; danielebarchiesi@0: danielebarchiesi@0: // Always work in normal text areas that currently have focus. danielebarchiesi@0: if (insertTextarea && insertTextarea.insertHasFocus) { danielebarchiesi@0: editorElement = insertTextarea; danielebarchiesi@0: Drupal.insert.insertAtCursor(insertTextarea, content); danielebarchiesi@0: } danielebarchiesi@0: // Direct tinyMCE support. danielebarchiesi@0: else if (typeof(tinyMCE) != 'undefined' && tinyMCE.activeEditor) { danielebarchiesi@0: editorElement = document.getElementById(tinyMCE.activeEditor.editorId); danielebarchiesi@0: Drupal.insert.activateTabPane(editorElement); danielebarchiesi@0: tinyMCE.activeEditor.execCommand('mceInsertContent', false, content); danielebarchiesi@0: } danielebarchiesi@0: // WYSIWYG support, should work in all editors if available. danielebarchiesi@0: else if (Drupal.wysiwyg && Drupal.wysiwyg.activeId) { danielebarchiesi@0: editorElement = document.getElementById(Drupal.wysiwyg.activeId); danielebarchiesi@0: Drupal.insert.activateTabPane(editorElement); danielebarchiesi@0: Drupal.wysiwyg.instances[Drupal.wysiwyg.activeId].insert(content) danielebarchiesi@0: } danielebarchiesi@0: // FCKeditor module support. danielebarchiesi@0: else if (typeof(FCKeditorAPI) != 'undefined' && typeof(fckActiveId) != 'undefined') { danielebarchiesi@0: editorElement = document.getElementById(fckActiveId); danielebarchiesi@0: Drupal.insert.activateTabPane(editorElement); danielebarchiesi@0: FCKeditorAPI.Instances[fckActiveId].InsertHtml(content); danielebarchiesi@0: } danielebarchiesi@0: // Direct FCKeditor support (only body field supported). danielebarchiesi@0: else if (typeof(FCKeditorAPI) != 'undefined') { danielebarchiesi@0: // Try inserting into the body. danielebarchiesi@0: if (FCKeditorAPI.Instances[insertTextarea.id]) { danielebarchiesi@0: editorElement = insertTextarea; danielebarchiesi@0: Drupal.insert.activateTabPane(editorElement); danielebarchiesi@0: FCKeditorAPI.Instances[insertTextarea.id].InsertHtml(content); danielebarchiesi@0: } danielebarchiesi@0: // Try inserting into the first instance we find (may occur with very danielebarchiesi@0: // old versions of FCKeditor). danielebarchiesi@0: else { danielebarchiesi@0: for (var n in FCKeditorAPI.Instances) { danielebarchiesi@0: editorElement = document.getElementById(n); danielebarchiesi@0: Drupal.insert.activateTabPane(editorElement); danielebarchiesi@0: FCKeditorAPI.Instances[n].InsertHtml(content); danielebarchiesi@0: break; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: // CKeditor module support. danielebarchiesi@0: else if (typeof(CKEDITOR) != 'undefined' && typeof(Drupal.ckeditorActiveId) != 'undefined') { danielebarchiesi@0: editorElement = document.getElementById(Drupal.ckeditorActiveId); danielebarchiesi@0: Drupal.insert.activateTabPane(editorElement); danielebarchiesi@0: CKEDITOR.instances[Drupal.ckeditorActiveId].insertHtml(content); danielebarchiesi@0: } danielebarchiesi@0: // Direct CKeditor support (only body field supported). danielebarchiesi@0: else if (typeof(CKEDITOR) != 'undefined' && CKEDITOR.instances[insertTextarea.id]) { danielebarchiesi@0: editorElement = insertTextarea; danielebarchiesi@0: Drupal.insert.activateTabPane(editorElement); danielebarchiesi@0: CKEDITOR.instances[insertTextarea.id].insertHtml(content); danielebarchiesi@0: } danielebarchiesi@0: else if (insertTextarea) { danielebarchiesi@0: editorElement = insertTextarea; danielebarchiesi@0: Drupal.insert.activateTabPane(editorElement); danielebarchiesi@0: Drupal.insert.insertAtCursor(insertTextarea, content); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: if (editorElement) { danielebarchiesi@0: Drupal.insert.contentWarning(editorElement, content); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: return false; danielebarchiesi@0: }, danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Check for vertical tabs and activate the pane containing the editor. danielebarchiesi@0: * danielebarchiesi@0: * @param editor danielebarchiesi@0: * The DOM object of the editor that will be checked. danielebarchiesi@0: */ danielebarchiesi@0: activateTabPane: function(editor) { danielebarchiesi@0: var $pane = $(editor).parents('.vertical-tabs-pane:first'); danielebarchiesi@0: var $panes = $pane.parent('.vertical-tabs-panes'); danielebarchiesi@0: var $tabs = $panes.parents('.vertical-tabs:first').find('ul.vertical-tabs-list:first li a'); danielebarchiesi@0: if ($pane.size() && $pane.is(':hidden') && $panes.size() && $tabs.size()) { danielebarchiesi@0: var index = $panes.children().index($pane); danielebarchiesi@0: $tabs.eq(index).click(); danielebarchiesi@0: } danielebarchiesi@0: }, danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Warn users when attempting to insert an image into an unsupported field. danielebarchiesi@0: * danielebarchiesi@0: * This function is only a 90% use-case, as it doesn't support when the filter danielebarchiesi@0: * tip are hidden, themed, or when only one format is available. However it danielebarchiesi@0: * should fail silently in these situations. danielebarchiesi@0: */ danielebarchiesi@0: contentWarning: function(editorElement, content) { danielebarchiesi@0: if (!content.match(//)) { danielebarchiesi@0: 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.")); danielebarchiesi@0: } danielebarchiesi@0: }); danielebarchiesi@0: }, danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Insert content into a textarea at the current cursor position. danielebarchiesi@0: * danielebarchiesi@0: * @param editor danielebarchiesi@0: * The DOM object of the textarea that will receive the text. danielebarchiesi@0: * @param content danielebarchiesi@0: * The string to be inserted. danielebarchiesi@0: */ danielebarchiesi@0: insertAtCursor: function(editor, content) { danielebarchiesi@0: // Record the current scroll position. danielebarchiesi@0: var scroll = editor.scrollTop; danielebarchiesi@0: danielebarchiesi@0: // IE support. danielebarchiesi@0: if (document.selection) { danielebarchiesi@0: editor.focus(); danielebarchiesi@0: sel = document.selection.createRange(); danielebarchiesi@0: sel.text = content; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // Mozilla/Firefox/Netscape 7+ support. danielebarchiesi@0: else if (editor.selectionStart || editor.selectionStart == '0') { danielebarchiesi@0: var startPos = editor.selectionStart; danielebarchiesi@0: var endPos = editor.selectionEnd; danielebarchiesi@0: editor.value = editor.value.substring(0, startPos) + content + editor.value.substring(endPos, editor.value.length); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // Fallback, just add to the end of the content. danielebarchiesi@0: else { danielebarchiesi@0: editor.value += content; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // Ensure the textarea does not unexpectedly scroll. danielebarchiesi@0: editor.scrollTop = scroll; danielebarchiesi@0: } danielebarchiesi@0: }; danielebarchiesi@0: danielebarchiesi@0: })(jQuery);