# HG changeset patch # User David Eads # Date 1236194971 21600 # Node ID 1a77f87927dd2875facbda41869e86e6eac7b5bd # Parent bb68dc3ad56fb35ca752708d680bd6cdddc21d8f Fixed :empty custom selector behavior in IE, a little refactoring, etc. diff -r bb68dc3ad56f -r 1a77f87927dd dnd.module --- a/dnd.module Tue Mar 03 16:57:39 2009 -0600 +++ b/dnd.module Wed Mar 04 13:29:31 2009 -0600 @@ -135,8 +135,18 @@ } } + // Generate an array of library previews to add + if (is_array($json['library_previews'])) { + foreach ($json['library_previews'] as $preview_id=>$preview_item) { + $library_previews[$preview_id] = filter_xss_admin($preview_item); + } + } + // Store editor representations in Drupal setting - drupal_add_js(array('dndEditorRepresentations' => $editor_representations,), 'setting'); + drupal_add_js(array( + 'dndEditorRepresentations' => $editor_representations, + 'dndLibraryPreviews' => $library_previews, + ), 'setting'); $variables['library_id'] = $settings['library_id']; $variables['header'] = filter_xss_admin($json['header']); diff -r bb68dc3ad56f -r 1a77f87927dd dnd_test/dnd-library-item.tpl.php --- a/dnd_test/dnd-library-item.tpl.php Tue Mar 03 16:57:39 2009 -0600 +++ b/dnd_test/dnd-library-item.tpl.php Wed Mar 04 13:29:31 2009 -0600 @@ -1,4 +1,4 @@ -
+
diff -r bb68dc3ad56f -r 1a77f87927dd dnd_test/dnd-library-preview.tpl.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dnd_test/dnd-library-preview.tpl.php Wed Mar 04 13:29:31 2009 -0600 @@ -0,0 +1,17 @@ +
+

+ +

+
+ +
+ +
+ +
+ +
+
+
+
+
diff -r bb68dc3ad56f -r 1a77f87927dd dnd_test/dnd_test.module --- a/dnd_test/dnd_test.module Tue Mar 03 16:57:39 2009 -0600 +++ b/dnd_test/dnd_test.module Wed Mar 04 13:29:31 2009 -0600 @@ -50,6 +50,10 @@ 'arguments' => array('i' => NULL), 'template' => 'dnd-library-item', ), + 'dnd_library_preview' => array( + 'arguments' => array('i' => NULL), + 'template' => 'dnd-library-preview', + ), ); } @@ -63,6 +67,7 @@ 'header' => '

'. t('Test library: Page @page', array('@page' => $page)) .'

', 'library' => $test_library['library'], 'editor_representations' => $test_library['editor_representations'], + 'library_previews' => $test_library['library_previews'], 'footer' => '
'. l(t('1'), 'dnd-test/library') . ' '. l(t('2'), 'dnd-test/library', array('query' => array('page' => 2))) .'
', )); } @@ -76,13 +81,16 @@ $library = ''; $editor_representations = array(); + $library_previews = array(); for ($i=$start + 1; $i < $end + 1; $i++) { $library .= theme('dnd_library_item', $i); $editor_representations += dnd_editor_items($i); + $library_previews['dnd-test-'. $i] = theme('dnd_library_preview', $i); } return array( 'library' => $library, 'editor_representations' => $editor_representations, + 'library_previews' => $library_previews, ); } @@ -100,6 +108,19 @@ } /** + * Completely contrived library preview theme function + */ +function template_preprocess_dnd_library_preview(&$variables) { + template_preprocess_dnd_library_item($variables); + + $variables['id'] = 'dnd-preview-'. $variables['i']; + $variables['image'] = ''; + + $variables['description'] = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'; +} + + +/** * Completely contrived edit item theme function */ function template_preprocess_dnd_library_item(&$variables) { @@ -117,6 +138,8 @@ $img = 1; } + $variables['img_num'] = $img; + $variables['id'] = 'dnd-test-'. $i; $variables['image'] = ''; $variables['title'] = t('Lorem Ipsum @count', array('@count' => $i)); $variables['date'] = 'Feb 18 2009'; diff -r bb68dc3ad56f -r 1a77f87927dd js/dnd-library.js --- a/js/dnd-library.js Tue Mar 03 16:57:39 2009 -0600 +++ b/js/dnd-library.js Wed Mar 04 13:29:31 2009 -0600 @@ -11,16 +11,16 @@ * Extend jQuery a bit * * We add a selector to look for "empty" elements (empty elements in TinyMCE - * often have non-breaking spaces and
tags). + * often have non-breaking spaces and
tags). An exception is required + * to make this work in IE. */ (function($) { // Custom selectors $.extend($.expr[":"], { 'empty' : function(a, i, m) { - var text = $(a).html(); - text.replace(/\u00a0/g,''); // Remove   - $('br', $(text)).remove(); // Remove breaks - return !$.trim(text); + return !$(a).filter(function(i) { + return !$(this).is('br'); + }).length && !$.trim(a.textContent || a.innerText||$(a).text()||""); } }); }) (jQuery); @@ -30,35 +30,90 @@ var $this = $(this); // This is a bad hack to lop off '-dnd-library' from the id to get the editor name - var editor = this.id.slice(0, -12); + var $editor = $('#' + this.id.slice(0, -12)); + // Bind Drag and Drop plugin invocation to events emanating from Wysiwyg - $('#' + editor).bind('wysiwygAttach', Drupal.behaviors.dndLibrary.attach_library); - $('#' + editor).bind('wysiwygDetach', Drupal.behaviors.dndLibrary.detach_library); + $editor.bind('wysiwygAttach', Drupal.behaviors.dndLibrary.attach_library); + $editor.bind('wysiwygDetach', Drupal.behaviors.dndLibrary.detach_library); + + // Add basic hover behavior to editor items + $('.editor-item', context).hover(function() { + var $this = $(this); + var p = $('#edit-body-wrapper').position(); + var preview = $(Drupal.settings.dndLibraryPreviews[this.id]).css({ + 'position' : 'absolute', + 'top' : p.top + 150, + 'left' : p.left + $('#edit-body-wrapper').width() + 150, + 'display' : 'none', + 'width' : '300px', + 'background-color' : '#ddd', + 'border' : '3px solid #999', + 'padding' : '4px', + 'z-index' : 10 + }); + $('body').prepend(preview); + preview.fadeIn('slow'); + }, function() { + $('#' + this.id.replace(/test/,'preview')).fadeOut('fast', function() { $(this).remove(); }); + }); // Ajax pager - $('.pager a', $this).click(function(e, data) { + $('.pager a', $this).click(function() { $.getJSON(this.href, function(data) { - $('.header', $this).html(data.header); - $('.library', $this).html(data.library); - //$('.footer', $this).html(data.footer); - for (editor_id in data.editor_representations) { - Drupal.settings.dndEditorRepresentations[editor_id] = data.editor_representations[editor_id]; - } - var params = Drupal.wysiwyg.instances[editor]; - $('#' + editor).trigger('wysiwygDetach', params); - $('#' + editor).trigger('wysiwygAttach', params); + Drupal.behaviors.dndLibrary.refreshLibrary.call($this.get(0), data, $editor); }); + + // Reattach behaviors + Drupal.behaviors.dndLibrary(); + return false; }); + + // Preload images in editor representations + var cached = $.data($editor, 'dnd_preload') || {}; + for (editor_id in Drupal.settings.dndEditorRepresentations) { + if (!cached[editor_id]) { + $representation = $(Drupal.settings.dndEditorRepresentations[editor_id]); + if ($representation.is('img') && $representation.get(0).src) { + $representation.attr('src', $representation.get(0).src); + } else { + $('img', $representation).each(function() { + this.attr('src', this.src); + }); + } + } + } + $.data($editor, 'dnd_preload', cached); }); } +Drupal.behaviors.dndLibrary.refreshLibrary = function(data, editor) { + $this = $(this); + + $('.header', $this).html(data.header); + $('.library', $this).html(data.library); + $('.footer', $this).html(data.footer); + + var params = Drupal.wysiwyg.instances[editor.get(0).id]; + editor.trigger('wysiwygDetach', params); + editor.trigger('wysiwygAttach', params); + + for (editor_id in data.editor_representations) { + Drupal.settings.dndEditorRepresentations[editor_id] = data.editor_representations[editor_id]; + } + for (preview_id in data.library_previews) { + Drupal.settings.dndLibraryPreviews[preview_id] = data.library_previews[preview_id]; + } +} + + // Dynamically compose a callback based on the editor name Drupal.behaviors.dndLibrary.attach_library = function(e, data) { + var settings = $.extend({idSelector: Drupal.behaviors.dndLibrary.idSelector}, Drupal.settings.dndEnabledLibraries[data.field]); var editor_fn = 'attach_' + data.editor; if ($.isFunction(window.Drupal.behaviors.dndLibrary[editor_fn])) { - window.Drupal.behaviors.dndLibrary[editor_fn](data, Drupal.settings.dndEnabledLibraries[data.field]); + window.Drupal.behaviors.dndLibrary[editor_fn](data, settings); } } @@ -74,8 +129,8 @@ Drupal.behaviors.dndLibrary.attach_none = function(data, settings) { settings = $.extend({ targets: $('#'+ data.field), - procressTextAreaDrop: function(target, clicked, representation_id, e, data) { - var snippet = Drupal.settings.dndEditorRepresentations[representation_id]; + processTextAreaDrop: function(target, clicked, representation_id, e, data) { + var snippet = '

' + Drupal.settings.dndEditorRepresentations[representation_id] + '

'; $(target).replaceSelection(snippet, true); } }, settings); @@ -101,18 +156,19 @@ } } +Drupal.behaviors.dndLibrary.idSelector = function(element) { + if ($(element).is('img')) { + return $.url.setUrl(element.src).param('dnd_id'); + } + return false; +} + // Really attach TinyMCE Drupal.behaviors.dndLibrary._attach_tinymce = function(data, settings, tiny_instance) { var ed = tiny_instance, dom = ed.dom, s = ed.selection; settings = $.extend({ targets: $('#'+ data.field +'-wrapper iframe'), - idSelector: function(element) { - if ($(element).is('img')) { - return $.url.setUrl(element.src).param('dnd_id'); - } - return false; - }, interval: 100, processIframeDrop: function(target, dragged, dropped, representation_id) { var representation = Drupal.settings.dndEditorRepresentations[representation_id]; @@ -135,7 +191,6 @@ // The no-parent case if ($(block).is('body')) { - s.setNode(insert); } else { @@ -148,10 +203,7 @@ // The active target block should be empty if ($('#target-block:empty', $target.contents()).length > 0) { - var c = dom.get('target-block'); - s.select(dom.get('target-block')); - ed.execCommand('Delete', false, null); - dom.remove(c); + $('#target-block', $target.contents()).remove(); } else if (old_id) { block.id = old_id; } else { diff -r bb68dc3ad56f -r 1a77f87927dd js/dnd.js --- a/js/dnd.js Tue Mar 03 16:57:39 2009 -0600 +++ b/js/dnd.js Wed Mar 04 13:29:31 2009 -0600 @@ -135,7 +135,6 @@ // Indicate this element is draggy $element.css('cursor', 'move'); - // Watch the iframe for changes var t = setInterval(function() { $('img:not(.dnd-dropped)', $(target).contents()).each(function() { @@ -159,6 +158,7 @@ $(document).data('dnd_timers', data); } else if ($target.is('textarea')) { + $element.css('cursor', 'pointer'); $(element).click(function(e, data) { opt.processTextAreaDrop(target, element, representation_id, e, data); });