# HG changeset patch # User David Eads # Date 1234906496 21600 # Node ID 5a44c430b7ac10a56d24024d78d5300c04c76a88 # Parent cee0530857556eeb4df411680fe7285516c29fdb Added dnd_test module, tons and tons of fixes and changes. diff -r cee053085755 -r 5a44c430b7ac dnd-library.tpl.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dnd-library.tpl.php Tue Feb 17 15:34:56 2009 -0600 @@ -0,0 +1,11 @@ +
+
+ +
+
+ +
+ +
diff -r cee053085755 -r 5a44c430b7ac dnd.admin.inc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dnd.admin.inc Tue Feb 17 15:34:56 2009 -0600 @@ -0,0 +1,5 @@ + array( 'textarea' => array('type' => 'varchar', 'not null' => TRUE), 'source' => array('type' => 'varchar', 'length' => 128, 'not null' => TRUE), + 'settings' => array('type' => 'text', 'default' => ''), ), 'primary key' => array('textarea'), ); diff -r cee053085755 -r 5a44c430b7ac dnd.module --- a/dnd.module Mon Feb 16 01:39:54 2009 -0600 +++ b/dnd.module Tue Feb 17 15:34:56 2009 -0600 @@ -1,5 +1,8 @@ array('arguments' => array('element' => NULL, 'settings' => NULL), 'template' => 'dnd-library'), + ); +} + + +/** + * Implementation of hook_elements(). + * + * Overload textareas. + */ +function dnd_elements() { + $type = array(); + $type['textarea'] = array( + '#input' => TRUE, + '#cols' => 60, + '#rows' => 5, + '#resizable' => TRUE, + '#dnd-enabled' => FALSE, + '#dnd-settings' => NULL, + '#process' => array('form_expand_ahah', 'dnd_process_textarea'), + ); + return $type; +} + +/** + * Settings array: + * What should it take, if anything? Probably a source... + * maybe editor specific configuration shit? + * + * - source for library json/ajax shit + * - target selector + * - item selector + * + * perhaps like so: + * + * global => + * droppable targets + * library source for textarea + * + * tinymce/othereditor => + * target selector logic + * configuration options + * callback should be smart about attachment and detachment + */ +function dnd_process_textarea($element, $form_state) { + if ($element['#dnd-enabled']) { + + drupal_add_js(drupal_get_path('module', 'dnd') .'/dnd/dnd.js'); + drupal_add_js(drupal_get_path('module', 'dnd') .'/js/dnd-library.js', 'footer'); + + $settings = array(); + + // We take a string or an + if (is_string($element['#dnd-settings'])) { + // @TODO load settings + } + else if (is_object($element['#dnd-settings'])) { + $settings = (array) $element['#dnd-settings']; + } + else if (is_array($element['#dnd-settings'])) { + $settings = $element['#dnd-settings']; + } + + // Set some important defaults + $settings = array('library_id' => $element['#id'] . DND_ID_SUFFIX) + $settings; + + // Add enabled libraries to settings for tracking + drupal_add_js(array( + 'dndEnabledLibraries' => array($element['#id'] => $settings), + ), 'setting'); + + $element['#prefix'] = theme('dnd_library', $element, $settings); + } + return $element; +} + +function template_preprocess_dnd_library(&$variables) { + global $base_url; + list($element, $settings) = array($variables['element'], $variables['settings']); + + // Get library via a backdoor HTTP request. This is plenty fast for this + // application and keeps things nice and consistent. + if (!($url = parse_url($settings['url']))) { + return t('This library is not available'); + } + + // Handle both relative and absolute urls + if (!isset($url['scheme'])) { + $settings['url'] = $base_url .'/'. $settings['url']; + } + + $request = drupal_http_request($settings['url']); + + // We must remove some Drupal escaping + $json = json_decode(str_replace(array('\x3c', '\x3e', '\x26'), array("<", ">", "&"), $request->data), TRUE); + + foreach ($json['library'] as $id=>$item) { + $editor_representations[$id] = filter_xss_admin($item['editor']); + $library_representations[$id] = filter_xss_admin($item['library']); + } + + $variables['library_id'] = $settings['library_id']; + $variables['header'] = filter_xss_admin($json['header']); + $variables['items'] = $library_representations; + $variables['footer'] = filter_xss_admin($json['footer']); + + // Store editor representations in Drupal setting + drupal_add_js(array( + 'dndEditorRepresentations' => $editor_representations, + ), 'setting'); +} diff -r cee053085755 -r 5a44c430b7ac dnd_test/dnd_test.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dnd_test/dnd_test.css Tue Feb 17 15:34:56 2009 -0600 @@ -0,0 +1,25 @@ +.body-field-wrapper { + float: left; + width: 100%; +} + +#edit-body-dnd-library { + float: left; + width: 15%; + text-align: center; +} +#edit-body-dnd-library img { + display: block; + margin: 2px auto; +} +#edit-body-dnd-library .library a { + color: #000; + display: block; + padding: 4px; + margin-bottom: 6px; + text-decoration: none; +} +#edit-body-wrapper { + float: left; + width: 85%; +} diff -r cee053085755 -r 5a44c430b7ac dnd_test/dnd_test.info --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dnd_test/dnd_test.info Tue Feb 17 15:34:56 2009 -0600 @@ -0,0 +1,7 @@ +; $Id$ +name = DnD Library Tests +package = User interface +description = Defines some menu callbacks and form alterations which test the drag and drop plugin. +dependencies[] = dnd +core = 6.x + diff -r cee053085755 -r 5a44c430b7ac dnd_test/dnd_test.module --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dnd_test/dnd_test.module Tue Feb 17 15:34:56 2009 -0600 @@ -0,0 +1,46 @@ + 'Drag and drop test library', + 'page callback' => 'dnd_test_library', + 'access arguments' => array('access dnd test library'), + ); + return $items; +} + +function dnd_test_perm() { + return array('access dnd test library'); +} + +function dnd_test_form_alter(&$form, &$form_state) { + if ($form['#id'] == 'node-form' && $form['type']['#value'] == 'page') { + drupal_add_css(drupal_get_path('module', 'dnd_test') .'/dnd_test.css'); + $form['body_field']['body']['#dnd-enabled'] = TRUE; + $form['body_field']['body']['#dnd-settings'] = array( + 'drop_selector' => '#edit-body-dnd-library .drop', + 'url' => 'dnd-test/library', + ); + $form['body_field']['body']['#rows'] = 28; + } +} + +function dnd_test_library() { + + $var = array( + 'header' => '

Test library

', + 'footer' => '
'. l(1, 'dnd-test/library') . ' '. l(2, 'dnd-test/library', array('query' => array('page' => 2))) .'
', + ); + $modifier = ($_GET['page'] == 2) ? 'page-2' : 'page-1'; + for ($i=1; $i < 6; $i++) { + $library = '
'. theme('image', drupal_get_path('module', 'dnd_test') .'/img/'. $modifier .'-small.jpg') .'Image '. $i .'
'; + $editor = theme('image', drupal_get_path('module', 'dnd_test') .'/img/'. $modifier .'-large.jpg'); + $var['library']['image-'. $i .'-'. $modifier] = array( + 'library' => $library, + 'editor' => $editor, + ); + } + drupal_json($var); + exit(); +} diff -r cee053085755 -r 5a44c430b7ac dnd_test/img-backup/page-1-large.jpg Binary file dnd_test/img-backup/page-1-large.jpg has changed diff -r cee053085755 -r 5a44c430b7ac dnd_test/img-backup/page-1-small.jpg Binary file dnd_test/img-backup/page-1-small.jpg has changed diff -r cee053085755 -r 5a44c430b7ac dnd_test/img-backup/page-2-large.jpg Binary file dnd_test/img-backup/page-2-large.jpg has changed diff -r cee053085755 -r 5a44c430b7ac dnd_test/img-backup/page-2-small.jpg Binary file dnd_test/img-backup/page-2-small.jpg has changed diff -r cee053085755 -r 5a44c430b7ac dnd_test/img/page-1-large.jpg Binary file dnd_test/img/page-1-large.jpg has changed diff -r cee053085755 -r 5a44c430b7ac dnd_test/img/page-1-small.jpg Binary file dnd_test/img/page-1-small.jpg has changed diff -r cee053085755 -r 5a44c430b7ac dnd_test/img/page-2-large.jpg Binary file dnd_test/img/page-2-large.jpg has changed diff -r cee053085755 -r 5a44c430b7ac dnd_test/img/page-2-small.jpg Binary file dnd_test/img/page-2-small.jpg has changed diff -r cee053085755 -r 5a44c430b7ac js/dnd-library.js --- a/js/dnd-library.js Mon Feb 16 01:39:54 2009 -0600 +++ b/js/dnd-library.js Tue Feb 17 15:34:56 2009 -0600 @@ -0,0 +1,64 @@ +Drupal.behaviors.dndLibrary = function(context) { + var libraries = Drupal.settings.dndEnabledLibraries; + + // Loop over libraries keyed by the textarea they are associated with + for (var textarea_id in libraries) { + + var library = $('#' + textarea_id + '-dnd-library'); + + // Ajax pager: This seems like it is bad to be here + $('.pager a', library).click(function(e, data) { + $.getJSON(this.href, function(data) { + $('.library', library).html(''); + for (item in data.library) { + $('.library', library).append(data.library[item].library); + Drupal.settings.dndEditorRepresentations[item] = data.library[item].editor; + Drupal.behaviors.dndLibrary(context); // Durn event reattachment + } + }); + return false; + }); + + // Bind Drag and Drop plugin invocation to wywsiwygAttach event + $('#' + textarea_id).bind('wysiwygAttach', function(e, data) { + var settings = { + renderRepresentation: function(target, drop, representation_id) { + console.log(representation_id); + return Drupal.settings.dndEditorRepresentations[representation_id]; + } + } + settings = $.extend(settings, libraries[textarea_id]); + + // Get editor attachment function + var editor_fn = 'attach_' + data.editor; + if ($.isFunction(window.Drupal.behaviors.dndLibrary[editor_fn])) { + window.Drupal.behaviors.dndLibrary[editor_fn](data, settings); + } + }); + + // @TODO track and clear intervals to save memory at the cost of + // more processing? + $('#' + textarea_id).bind('wysiwygDetach', function(e, data) { + console.log('detach'); + }); + } +} + +Drupal.behaviors.dndLibrary.attach_tinymce = function(data, settings) { + var tiny = tinyMCE.getInstanceById(data.field); + $('#'+ data.field +'-wrapper iframe').load(function() { + settings = $.extend({ + targets: $('#'+ data.field +'-wrapper iframe'), + insertAfter: '

_

', + postprocessDrop: function() { + // Get our special span, select it, delete it, and hope the caret + // resets correctly. + tiny.selection.select(tiny.dom.get('__caret')); + tiny.execCommand('Delete', false, null); + tiny.dom.remove('__caret'); + } + }, settings); + + $(settings.drop_selector).dnd(settings); + }); +}