From be1a433c279dd7f4373ef1af4769e693178274d2 Mon Sep 17 00:00:00 2001 From: Earl Miles <merlin@logrus.com> Date: Tue, 14 Apr 2009 05:24:20 +0000 Subject: [PATCH] More robust AJAX stuff that will eliminate some ugly errors plus prevent double clicks on ajax links. --- css/ctools.css | 10 +++ css/modal.css | 2 +- ctools.module | 7 ++ images/no-icon.png | Bin 0 -> 574 bytes images/status-active.gif | Bin 0 -> 2196 bytes includes/content.inc | 7 +- js/ajax-responder.js | 112 +++++++++++++++--------- js/modal.js | 60 +++++++++---- plugins/content_types/block/block.inc | 8 +- plugins/content_types/custom/custom.inc | 3 + 10 files changed, 146 insertions(+), 63 deletions(-) create mode 100644 images/no-icon.png create mode 100644 images/status-active.gif diff --git a/css/ctools.css b/css/ctools.css index 5cf9c5b4..4a2d875d 100644 --- a/css/ctools.css +++ b/css/ctools.css @@ -10,3 +10,13 @@ border: 1px solid #F0C020; padding: 1em; } + +a.ctools-ajaxing { + padding-right: 18px !important; + background: url(../images/status-active.gif) right center no-repeat; +} + +input.ctools-ajaxing { + padding-right: 18px; + background: url(../images/status-active.gif) right center no-repeat; +} diff --git a/css/modal.css b/css/modal.css index 40a75258..61cabacb 100644 --- a/css/modal.css +++ b/css/modal.css @@ -28,7 +28,7 @@ div.ctools-modal-content .modal-header a { } div.ctools-modal-content .modal-content { - padding: 0 1em; + padding: 1em 1em 0 1em; overflow: auto; width: 575px; height: 400px; diff --git a/ctools.module b/ctools.module index fa41de94..cc5b13d1 100644 --- a/ctools.module +++ b/ctools.module @@ -43,6 +43,13 @@ function ctools_add_js($file) { drupal_add_js(drupal_get_path('module', 'ctools') . "/js/$file.js"); } +/** + * Implement hook_init to keep our global CSS at the ready. + */ +function ctools_init() { + ctools_add_css('ctools'); +} + /** * Provide a hook passthrough to included files. * diff --git a/images/no-icon.png b/images/no-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..fa78ec179a83428e5b8e247890278cdf91a8cb3e GIT binary patch literal 574 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl;=8&~`zjDUQ}64!{5 z;QX|b^2DN42FH~Aq*MjZ+{E<Mpwz^a%EFVWHb6za0X`wFr45!Je(pYfWm-(COIf{R zd6V9oHxIsid0$fJW$SEo`f5jcz0Kr#;igtPWlb7C|6e?HweQFOEB9`%zH@8cwJS?s zew%dq@~pQ%Hop2cr@TdB$^y5t8qc@iSAF=g_1DjDXU|Og@&9sJgYlcUPo^&LIdf&= zlzD;P!IqytKQF6u{q*bLf@QgT_BMU}ed7QB|3DYT#AfRNDgBZlzhIyU34kGLsl|7o z)<2#ujv*Ddk}e1fiA|h-osCIX;lgER4h1$v5k@}S28JYoYgZYWeFZLDeaZk772MFU ztgVerS>S{rGmAj8jfaD?v!i2UYjjvlpQJ*A1Jfmibqf^i?VA_L7&|Z+X1sot(Xnwu z!w#NRT}4?8j7Jun<r7IrN_zP0*+WK71{Q$;hu~&USJ&1?_t4Opp|QLQ4F)U>OdXEg zItmI4IG$*KURlh<BH+>B>e|rlEqG%3qu@s@KxgP$`nu(@>FI?n*t0}KS|4Q7%GJhQ zr!}-TZTjTdv1#K+psr@Qb}IpmMn>t`v&?`hUc4+UFfd-t$f&NazkZvXLjxnjnNaC9 Um!If;0EPpDr>mdKI;Vst09}j(6951J literal 0 HcmV?d00001 diff --git a/images/status-active.gif b/images/status-active.gif new file mode 100644 index 0000000000000000000000000000000000000000..207e95c3fa8cc31a89af150ad74059b1667922b6 GIT binary patch literal 2196 zcmeH{Urbw79LLW&_xASmFQt@HSs}NhO2-Jh1BM+kb4v^B62vmdY!-sIxUi{Y-eKaZ zd%2gEe>0H6h_VE=!^E(JL`)>X2jVS^Zcfvn5<-k2WvFCNG`ghG7rZ6$WnPVsKJ5GO zJ8$RvJD>CY{Z5~0cApFxfB|GdPWa6w{k0|AwWK|oJQ2I!Je@i}^Zo0eZod2F_QJwK zJhi*9v9}~^YcH8hrc$Ymjg76Xt@{st+t|%+?PYgm$u+ybCo8+3&1pZopVPthPs$Sl z|6c-*eO+r)N4wV(XsWJa2q<^z_?=Wy@>!YdIyWW&Uj-18tONF|3Mu0pM+@E|b#0}^ z!~zi%9q%)3&a(p~G`B1c3*4%%lzk?{ByJ6=pegKss;|dO;n%+FeCW7{V%4V@w<Prd z%F>$Z{GnR7Ggdfd96mCSRsm(IU3X`eH-@mY!nv5{mPH7adf{@tFd+{D#Z*P7E4Cu( zNI<&yxF8`-(K~6DmV_bgDJSM6QPSy-`a53zHsK*ro@??84uYGYiss#G335cQ(q<T@ z`^CZLH_nsuwU=5Zb#0}cHj|R+xtu8<;s!)Qci1v(k~|`1?F+irB10NPwE`0tSF2U^ z+6<im-Ww1Hd@dR`k+{&xVS1-gZ9in)bj2<%i#281b&mh}&cO2{Mm<)t3jM`e#IVEf z3J{GD(1#g123De0)!E_UoF_nTk~awv(p3<=z%wHIKJ2D|V0J_Zci!BO;e4ksj*7ZE zaK0c;0L<IMq65W=XG<*=46Wqa{SQ<*PK@eny6#~a=BV}<y_imT#W8h0o^#RS&~=>^ z%wp~p0g$crQ*_&{2!a61R3ETvWG(*SZ8O_GR^u5Yc|OD{*}kN}6<BQdLfgxbC<mBp z`xxY*JbDh(Gfkp~t@6?H=&rUxgG>zL0fe!xt};GOz%hKaYMskC&qRw=<`U&U>^cAo zLBAqcYczaZ@J3LHlNVx%1c};=4Y#YG7RXW%xDepEe!!I1`hwd%{Td?N=QPn}&`2C( ze3|@EBBE1Mq|)<VKA;NO$Fur4RVf(Xkt2F^h74Rup!Z4$EV<S^2>`TYFdd2uA0l<j zqjX|tdH7`B<TqbkNyC`KP_3Mw;D1Ak8-n?)FKRdQpW|_Gnk3527MlcAF<|fQ^>e6o z6d!7|&nD=vC$NZI_5Tu^++t8<dUiOR&jN!6nB45IfQagiRPYGn6e3kR=hRI}WUuS% zv~r?WB#l9B4Q_she1I~Z`-#aQFKH~e+~Duv6k~HRBMLhp$CW6nwuC+1fUr>Y=|vzw z1Q9I-fe?vcx1AJNZgm0}!<m5NlSXxc^D;?G-sDI66TkFogokU>B}H#d-&TI?-^oT* zRA10W&q#7unMxBUvZJU0H>48~K*CV@D7`H;MzIa8(QDnFN!<(7r69X=cc1~zTKw(l Pm4SkyKc+`yv*-Q<rDLic literal 0 HcmV?d00001 diff --git a/includes/content.inc b/includes/content.inc index a7a2a857..be810d71 100644 --- a/includes/content.inc +++ b/includes/content.inc @@ -75,6 +75,9 @@ function ctools_content_defaults($info, &$plugin) { if (isset($plugin['required contexts'])) { $type['required contexts'] = $plugin['required contexts']; } + if (isset($plugin['top level'])) { + $type['top level'] = $plugin['top level']; + } $plugin['content types'] = array($plugin['name'] => $type); } // Otherwise, auto discover the function based upon pattern naming. @@ -503,7 +506,7 @@ function _ctools_content_create_add_form_info(&$form_info, $info, $plugin, $subt * @param $default_types * A default allowed/denied status for content that isn't known about */ -function ctools_get_available_content_types($contexts = NULL, $has_content = FALSE, $allowed_types = NULL, $default_types = NULL) { +function ctools_content_get_available_types($contexts = NULL, $has_content = FALSE, $allowed_types = NULL, $default_types = NULL) { $plugins = ctools_get_content_types(); $available = array(); @@ -546,7 +549,7 @@ function ctools_get_available_content_types($contexts = NULL, $has_content = FAL * availability. * */ -function ctools_get_all_content_types() { +function ctools_content_get_all_types() { $plugins = ctools_get_content_types(); $available = array(); diff --git a/js/ajax-responder.js b/js/ajax-responder.js index 4a09865b..a1db193e 100644 --- a/js/ajax-responder.js +++ b/js/ajax-responder.js @@ -29,31 +29,14 @@ Drupal.CTools.AJAX.respond = function(data) { * specified by the href of the link. */ Drupal.CTools.AJAX.clickAJAXLink = function() { - var url = $(this).attr('href'); - url.replace('/nojs/', '/ajax/'); - $.ajax({ - type: "POST", - url: url, - data: '', - global: true, - success: Drupal.CTools.AJAX.respond, - error: function() { - alert("An error occurred while attempting to process " + url); - }, - dataType: 'json' - }); - return false; -}; + if ($(this).hasClass('ctools-ajaxing')) { + return false; + } -/** - * Generic replacement click handler to open the modal with the destination - * specified by the href of the link. - */ -Drupal.CTools.AJAX.clickAJAXButton = function() { - // @todo -- if no url we should take the form action and submit the - // form. - var url = Drupal.CTools.AJAX.findURL(this); - if (url) { + var url = $(this).attr('href'); + var object = $(this); + $(this).addClass('ctools-ajaxing'); + try { url.replace('/nojs/', '/ajax/'); $.ajax({ type: "POST", @@ -64,25 +47,76 @@ Drupal.CTools.AJAX.clickAJAXButton = function() { error: function() { alert("An error occurred while attempting to process " + url); }, - dataType: 'json' - }); - } - else { - var form = $(this).parents('form'); - url = $(form).attr('action'); - url.replace('/nojs/', '/ajax/'); - $(form).ajaxSubmit({ - type: "POST", - url: url, - data: '', - global: true, - success: Drupal.CTools.AJAX.respond, - error: function() { - alert("An error occurred while attempting to process " + url); + complete: function() { + object.removeClass('ctools-ajaxing'); }, dataType: 'json' }); } + catch (err) { + alert("An error occurred while attempting to process " + url); + $(this).removeClass('ctools-ajaxing'); + return false; + } + + return false; +}; + +/** + * Generic replacement click handler to open the modal with the destination + * specified by the href of the link. + */ +Drupal.CTools.AJAX.clickAJAXButton = function() { + if ($(this).hasClass('ctools-ajaxing')) { + return false; + } + + var url = Drupal.CTools.AJAX.findURL(this); + $(this).addClass('ctools-ajaxing'); + var object = $(this); + try { + if (url) { + url.replace('/nojs/', '/ajax/'); + $.ajax({ + type: "POST", + url: url, + data: '', + global: true, + success: Drupal.CTools.AJAX.respond, + error: function() { + alert("An error occurred while attempting to process " + url); + }, + complete: function() { + object.removeClass('ctools-ajaxing'); + }, + dataType: 'json' + }); + } + else { + var form = $(this).parents('form'); + url = $(form).attr('action'); + url.replace('/nojs/', '/ajax/'); + $(form).ajaxSubmit({ + type: "POST", + url: url, + data: '', + global: true, + success: Drupal.CTools.AJAX.respond, + error: function() { + alert("An error occurred while attempting to process " + url); + }, + complete: function() { + object.removeClass('ctools-ajaxing'); + }, + dataType: 'json' + }); + } + } + catch (err) { + alert("An error occurred while attempting to process " + url); + $(this).removeClass('ctools-ajaxing'); + return false; + } return false; }; diff --git a/js/modal.js b/js/modal.js index 5f7179e1..195156e4 100644 --- a/js/modal.js +++ b/js/modal.js @@ -27,7 +27,7 @@ Drupal.CTools.Modal.show = function() { }); $('div.ctools-modal-content .modal-content', context).css({ 'width': ($(window).width() * .8 - 25) + 'px', - 'height': ($(window).height() * .8 - 22) + 'px' + 'height': ($(window).height() * .8 - 35) + 'px' }); } @@ -97,7 +97,12 @@ Drupal.theme.prototype.CToolsModalThrobber = function () { Drupal.CTools.Modal.clickAjaxLink = function() { // show the empty dialog right away. Drupal.CTools.Modal.show(); - return Drupal.CTools.AJAX.clickAJAXLink.apply(this); + Drupal.CTools.AJAX.clickAJAXLink.apply(this); + if (!$(this).hasClass('ctools-ajaxing')) { + Drupal.CTools.Modal.dismiss(); + } + + return false; }; /** @@ -105,27 +110,52 @@ Drupal.CTools.Modal.clickAjaxLink = function() { * specified by the href of the link. */ Drupal.CTools.Modal.clickAjaxButton = function() { + if ($(this).hasClass('ctools-ajaxing')) { + return false; + } + Drupal.CTools.Modal.show(); - return Drupal.CTools.AJAX.clickAJAXButton.apply(this); + Drupal.CTools.AJAX.clickAJAXButton.apply(this); + if (!$(this).hasClass('ctools-ajaxing')) { + Drupal.CTools.Modal.dismiss(); + } + + return false; }; /** * Submit responder to do an AJAX submit on all modal forms. */ Drupal.CTools.Modal.submitAjaxForm = function() { + if ($(this).hasClass('ctools-ajaxing')) { + return false; + } + url = $(this).attr('action'); - url.replace('/nojs/', '/ajax/'); - $(this).ajaxSubmit({ - type: "POST", - url: url, - data: '', - global: true, - success: Drupal.CTools.AJAX.respond, - error: function() { - alert("An error occurred while attempting to process " + url); - }, - dataType: 'json' - }); + $(this).addClass('ctools-ajaxing'); + var object = $(this); + try { + url.replace('/nojs/', '/ajax/'); + $(this).ajaxSubmit({ + type: "POST", + url: url, + data: '', + global: true, + success: Drupal.CTools.AJAX.respond, + error: function() { + alert("An error occurred while attempting to process " + url); + }, + complete: function() { + object.removeClass('ctools-ajaxing'); + }, + dataType: 'json' + }); + } + catch (err) { + alert("An error occurred while attempting to process " + url); + $(this).removeClass('ctools-ajaxing'); + return false; + } return false; } diff --git a/plugins/content_types/block/block.inc b/plugins/content_types/block/block.inc index be244625..595fe957 100644 --- a/plugins/content_types/block/block.inc +++ b/plugins/content_types/block/block.inc @@ -276,17 +276,13 @@ function forum_ctools_block_info($module, $delta, &$info) { function profile_ctools_block_info($module, $delta, &$info) { // Hide the author information block which isn't as rich as what we can // do with context. - return NULL; - $info['icon'] = 'icon_core_authorinformation.png'; - $info['category'] = t('Core blocks'); + $info = NULL; } function book_ctools_block_info($module, $delta, &$info) { // Hide the book navigation block which isn't as rich as what we can // do with context. - return NULL; - $info['icon'] = 'icon_core_booknavigation.png'; - $info['category'] = t('Core blocks'); + $info = NULL; } function blog_ctools_block_info($module, $delta, &$info) { diff --git a/plugins/content_types/custom/custom.inc b/plugins/content_types/custom/custom.inc index 26eb6baf..6fe17eed 100644 --- a/plugins/content_types/custom/custom.inc +++ b/plugins/content_types/custom/custom.inc @@ -20,6 +20,9 @@ function ctools_custom_ctools_content_types() { 'title' => t('New custom content'), 'icon' => 'icon_block_custom.png', 'description' => t('Create a completely custom piece of HTML content.'), + // Make this a top level category so it appears higher in UIs that support + // that. + 'top level' => TRUE, 'category' => t('Custom'), 'defaults' => array('title' => '', 'body' => '', 'format' => FILTER_FORMAT_DEFAULT), // render callback is automatically deduced: -- GitLab