Mercurial > defr > drupal > scald > dnd
changeset 17:1a77f87927dd
Fixed :empty custom selector behavior in IE, a little refactoring, etc.
author | David Eads <eads@chicagotech.org> |
---|---|
date | Wed, 04 Mar 2009 13:29:31 -0600 |
parents | bb68dc3ad56f |
children | 0d557e6e73f7 |
files | dnd.module dnd_test/dnd-library-item.tpl.php dnd_test/dnd-library-preview.tpl.php dnd_test/dnd_test.module js/dnd-library.js js/dnd.js |
diffstat | 6 files changed, 137 insertions(+), 35 deletions(-) [+] |
line wrap: on
line diff
--- 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']);
--- 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 @@ -<div class="editor-item"> +<div class="editor-item" id="<?php print $id; ?>"> <div class="image"> <?php print $image; ?> </div>
--- /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 @@ +<div class="editor-preview" id="<?php print $id; ?>"> + <h2 class="title"> + <?php print $title; ?> + </h2> + <div class="image"> + <?php print $image; ?> + </div> + + <div class="description"> + <?php print $description; ?> + </div> + + <div class="meta"> + <div class="author"><?php print $author; ?></div> + <div class="date"><?php print $date; ?></div> + </div> +</div>
--- 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' => '<h3>'. t('Test library: Page @page', array('@page' => $page)) .'</h3>', 'library' => $test_library['library'], 'editor_representations' => $test_library['editor_representations'], + 'library_previews' => $test_library['library_previews'], 'footer' => '<div class="pager">'. l(t('1'), 'dnd-test/library') . ' '. l(t('2'), 'dnd-test/library', array('query' => array('page' => 2))) .'</div>', )); } @@ -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'] = '<img src="http://'. $_SERVER['HTTP_HOST'] . base_path() . drupal_get_path('module', 'dnd_test') .'/img/item-'. $variables['img_num'] .'-M.jpg" class="drop" />'; + + $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'] = '<img src="http://'. $_SERVER['HTTP_HOST'] . base_path() . drupal_get_path('module', 'dnd_test') .'/img/item-'. $img .'-thumb.jpg?dnd_id='. $i .'-M" class="drop" />'; $variables['title'] = t('Lorem Ipsum @count', array('@count' => $i)); $variables['date'] = 'Feb 18 2009';
--- 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 <br /> tags). + * often have non-breaking spaces and <br /> 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 = '<p class="dnd-dropped-wrapper">' + Drupal.settings.dndEditorRepresentations[representation_id] + '</p>'; $(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 {
--- 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); });