diff js/dnd-library.js @ 31:767ebf925654

Added forcecontainer tinymce plugin, lots and lots and lots of refactorizing.
author David Eads <eads@chicagotech.org>
date Thu, 19 Mar 2009 15:58:36 -0500
parents 2d49adbd8992
children ee520ba7d98b
line wrap: on
line diff
--- a/js/dnd-library.js	Tue Mar 17 21:29:00 2009 -0500
+++ b/js/dnd-library.js	Thu Mar 19 15:58:36 2009 -0500
@@ -17,7 +17,7 @@
 (function($) {
   // Custom selectors
   $.extend($.expr[":"], {
-    'empty' : function(a, i, m) {
+    'dnd_empty' : function(a, i, m) {
       return !$(a).filter(function(i) {
         return !$(this).is('br');
       }).length && !$.trim(a.textContent || a.innerText||$(a).text() || "");
@@ -38,6 +38,7 @@
 
     // Set up some initial settings for BeautyTips
     var settings = Drupal.settings.dndEnabledLibraries[$editor.get(0).id] = $.extend({
+      'btSettings' : {
         'trigger': 'none',
         'width': 375,
         'spikeLength': 7,
@@ -46,6 +47,23 @@
         'strokeWidth': 1,
         'fill': '#ffd',
         'strokeStyle': '#555'
+      },
+      'libraryHoverIntentSettings' : {
+        'interval': 500,
+        'timeout' : 0,
+        'over': function() {
+          var $this = $(this);
+          this.btOn();
+          // Remove the preview once dragging of any image has commenced
+          $('img', $this).bind('drag', function(e) {
+            $this.btOff();
+          });
+          $('img', $this).bind('click', function(e) {
+            $this.btOff();
+          });
+        }, 
+        'out': function() { this.btOff(); }
+      }
     }, Drupal.settings.dndEnabledLibraries[$editor.get(0).id]);
 
     // Bind Drag and Drop plugin invocation to events emanating from Wysiwyg
@@ -56,7 +74,7 @@
     Drupal.settings.dndEditorRepresentations = {};
     Drupal.settings.dndLibraryPreviews = {};
 
-    // Populate
+    // Initialize the library
     $.getJSON(Drupal.settings.basePath + settings.url, function(data) {
       Drupal.behaviors.dndLibrary.renderLibrary.call($this.get(0), data, $editor);
     });
@@ -84,45 +102,44 @@
 
   // Add preview behavior to editor items (thanks, BeautyTips!)
   $('.editor-item', $this).each(function () {
-    $(this).bt(Drupal.settings.dndLibraryPreviews[this.id], settings.bt_settings);
-    var hover_opts = $.extend({
-      'interval': 500,
-      'timeout' : 0,
-      'over': function() {
-        var $this = $(this);
-        this.btOn();
-        // Remove the preview once dragging of any image has commenced
-        $('img', $this).bind('drag', function(e) {
-          $this.btOff();
-        });
-        $('img', $this).bind('click', function(e) {
-          $this.btOff();
-        });
-      }, 
-      'out': function() { this.btOff(); }
-    }, settings.libraryHoverIntentOpts);
-    $(this).hoverIntent(hover_opts);
+    $(this).bt(Drupal.settings.dndLibraryPreviews[this.id], settings.btSettings);
+    $(this).hoverIntent(settings.libraryHoverIntentSettings);
   });
 
   // Preload images in editor representations
   var cached = $.data($(editor), 'dnd_preload') || {};
-  /*for (editor_id in Drupal.settings.dndEditorRepresentations) {
+  for (editor_id in Drupal.settings.dndEditorRepresentations) {
     if (!cached[editor_id]) {
       $representation = $(Drupal.settings.dndEditorRepresentations[editor_id].body);
       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);
+          $(this).attr('src', this.src);
         });
       }
     }
   }
-  $.data($(editor), 'dnd_preload', cached);*/
+  $.data($(editor), 'dnd_preload', cached);
 
+  $('.pager a', $this).click(function() {
+    $.getJSON(this.href, function(data) {
+      Drupal.behaviors.dndLibrary.renderLibrary.call($this.get(0), data, $(editor));
+    });
+    return false;
+  });
+  $('.view-filters input[type=submit]', $this).click(function() {
+    $(this).ajaxSubmit({
+      'url' : Drupal.settings.basePath + settings.url,
+      'dataType' : 'json',
+      'success' : function(data) {
+        Drupal.behaviors.dndLibrary.renderLibrary.call($this.get(0), data, $(editor));
+      }
+    });
+    return false;
+  });
 }
 
-
 // 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]);
@@ -133,12 +150,7 @@
 }
 
 // Do garbage collection on detach
-Drupal.behaviors.dndLibrary.detach_library = function(e, data) {
-  for (t in $(document).data('dnd_timers')) {
-    clearInterval(t);
-  }
-  $(document).removeData('dnd_timers');
-}
+Drupal.behaviors.dndLibrary.detach_library = function(e, data) {}
 
 // Basic textareas
 Drupal.behaviors.dndLibrary.attach_none = function(data, settings) {
@@ -150,7 +162,7 @@
       // Update element count
       Drupal.behaviors.dndLibrary.countElements.call(target, representation_id);
 
-      var snippet = '<p class="dnd-dropped-wrapper">' + Drupal.settings.dndEditorRepresentations[representation_id].body + '</p>';
+      var snippet = '<p class="dnd-drop-wrapper">' + Drupal.settings.dndEditorRepresentations[representation_id].body + '</p>';
       $target.replaceSelection(snippet, true);
     }
   }, settings);
@@ -190,13 +202,24 @@
 
   settings = $.extend({
     targets: $('#'+ data.field +'-wrapper iframe'),
+    processTargets: function(targets) {
+      return targets.each(function() {
+        var target = this
+        // Decrement counter on delete
+        $(target).bind('dnd_delete', function(e, data) {
+          Drupal.behaviors.dndLibrary.countElements(target, $(data.node).attr('dnd_id'), true); 
+        });
+        $('head', $(this).contents()).append('<style type="text/css">img { display: none; } img.dnd-dropped {display: block; }</style>');
+        return this;
+      });
+    },
     processIframeDrop: function(drop, id_selector) {
       var representation_id = id_selector.call(this, drop);
       var representation = Drupal.settings.dndEditorRepresentations[representation_id].body;
       var target = this, $target = $(target), $drop = $(drop), block;
 
       // Update element count
-      //Drupal.behaviors.dndLibrary.countElements.call(target, representation_id);
+      Drupal.behaviors.dndLibrary.countElements(target, representation_id);
 
       // Search through block level parents
       $drop.parents().each(function() {
@@ -211,7 +234,7 @@
       $drop.remove();
 
       // Create an element to insert
-      var insert = dom.create('p', {'class' : 'dnd-dropped-wrapper', 'id' : 'dnd-inserted'}, representation);
+      var insert = dom.create('p', {'class' : 'dnd-drop-wrapper', 'id' : 'dnd-inserted'}, representation);
 
       // The no-parent case
       if ($(block).is('body')) {
@@ -223,17 +246,17 @@
         $block = $('#target-block', $target.contents());
 
         // @TODO is finding the parent broken in safari??
-        $block.after('<p class="dnd-dropped-wrapper" id="dnd-inserted">' + representation + '</p>');
+        $block.after('<p class="dnd-drop-wrapper" id="dnd-inserted">' + representation + '</p>');
 
         // The active target block should be empty
-        if ($('#target-block:empty', $target.contents()).length > 0) {
+        if ($('#target-block:dnd_empty', $target.contents()).length > 0) {
           $('#target-block', $target.contents()).remove();
         } else if (old_id) {
           block.id = old_id;
         } else {
           $block.removeAttr('id');
         }
-      }
+      } 
 
       var $inserted = $('#dnd-inserted', $target.contents());
       var inserted = $inserted.get(0);
@@ -243,12 +266,8 @@
 
       // If the previous element is also an editor representation, we need to
       // put a dummy paragraph between the elements to prevent editor errors.
-      if (previous && $(previous).hasClass('dnd-dropped-wrapper')) {
-        $inserted.before('<p><span id="__spacer">_</span></p>');
-        c = dom.get('__spacer');
-        s.select(c);
-        ed.execCommand('Delete', false, null);
-        dom.remove(c);
+      if (previous ) {
+        $inserted.before('<p></p>');
       }
 
       // Look ahead in the DOM
@@ -257,22 +276,28 @@
       // If the next item exists and isn't an editor representation, drop the
       // caret at the beginning of the element, otherwise make a new paragraph
       // to advance the caret to.
-      if (next && !$(next).hasClass('dnd-dropped-wrapper')) {
+      if (next && !$(next).hasClass('dnd-drop-wrapper')) {
         $(next).prepend('<span id="__caret">_</span>');
       }
-      else {
+      else if (!$(next).hasClass('dnd-drop-wrapper')) {
         var after = dom.create('p', {}, '<span id="__caret">_</span>');
         dom.insertAfter(after, 'dnd-inserted');
       }
-
-      // Clear the ID for the next drop
-      $inserted.removeAttr('id');
-
+ 
       // Force selection to reset the caret
       var c = dom.get('__caret');
-      s.select(c);
-      ed.execCommand('Delete', false, null);
-      dom.remove(c);
+      if (c) {
+        s.select(c);
+        ed.execCommand('Delete', false, null);
+        dom.remove(c);
+      }
+
+      // Unset id for next drop and add special dnd attribute for counting
+      // purposes
+      $inserted
+        .removeAttr('id')
+        .attr('dnd_id', representation_id);
+
     }
   }, settings);
 
@@ -281,18 +306,16 @@
 
 
 // Keep a counter of times a representation ID has been used
-Drupal.behaviors.dndLibrary.countElements = function(representation_id) {
-  // We need to track element usage betwen all editors, so we look for the
-  // parent form item
-  $target = $(this).parents('.form-item');
-  var counter = $target.data('representation_counter');      
+Drupal.behaviors.dndLibrary.countElements = function(target, representation_id, decrement) {
+  var counter = $(target).data('dnd_representation_counter');      
   if (!counter) {
     counter = {}
     counter[representation_id] = 1;
   } else if (counter && !counter[representation_id]) {
     counter[representation_id] = 1;
   } else {
-    counter[representation_id] = counter[representation_id] + 1;
+    counter[representation_id] = counter[representation_id] + ((decrement) ? -1 : 1);
   }
-  $target.data('representation_counter', counter);
+  $(target).data('dnd_representation_counter', counter);
+  return counter[representation_id];
 }