devel_themer.js 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. (function ($) {
  2. $(document).ready(function () {
  3. lastObj = false;
  4. strs = Drupal.settings.thmrStrings;
  5. $('body').addClass("thmr_call").attr("id", "thmr_" + Drupal.settings.page_id);
  6. var themerEnabled = 0;
  7. var themerToggle = function () {
  8. themerEnabled = 1 - themerEnabled;
  9. $('#themer-toggle :checkbox').attr('checked', themerEnabled ? 'checked' : '');
  10. $('#themer-popup').css('display', themerEnabled ? 'block' : 'none');
  11. if (themerEnabled) {
  12. document.onclick = themerEvent;
  13. if (lastObj != false) {
  14. $(lastObj).css('outline', '3px solid #999');
  15. }
  16. $('[data-thmr]').hover(
  17. function () {
  18. if (this.parentNode.nodeName != 'BODY' && $(this).attr('thmr_curr') != 1) {
  19. $(this).css('outline', 'red solid 1px');
  20. }
  21. },
  22. function () {
  23. if ($(this).attr('thmr_curr') != 1) {
  24. $(this).css('outline', 'none');
  25. }
  26. }
  27. );
  28. }
  29. else {
  30. document.onclick = null;
  31. if (lastObj != false) {
  32. $(lastObj).css('outline', 'none');
  33. }
  34. $('[data-thmr]').unbind('mouseenter mouseleave');
  35. }
  36. };
  37. $(Drupal.settings.thmr_popup)
  38. .appendTo($('body'));
  39. $('<div id="themer-toggle"><input type="checkbox" />'+ strs.themer_info +'</div>')
  40. .appendTo($('body'))
  41. .click(themerToggle);
  42. $('#themer-popup').resizable();
  43. $('#themer-popup')
  44. .draggable({
  45. opacity: .6,
  46. handle: $('#themer-popup .topper')
  47. })
  48. .prepend(strs.toggle_throbber)
  49. ;
  50. // close box
  51. $('#themer-popup .topper .close').click(function() {
  52. themerToggle();
  53. });
  54. });
  55. /**
  56. * Known issue: IE does NOT support outline css property.
  57. * Solution: use another browser
  58. */
  59. function themerHilight(obj) {
  60. // hilight the current object (and un-highlight the last)
  61. if (lastObj != false) {
  62. $(lastObj).css('outline', 'none').attr('thmr_curr', 0);
  63. }
  64. $(obj).css('outline', '#999 solid 3px').attr('thmr_curr', 1);
  65. lastObj = obj;
  66. }
  67. function themerDoIt(obj) {
  68. if (thmrInPop(obj)) {
  69. return true;
  70. }
  71. // start throbber
  72. //$('#themer-popup img.throbber').show();
  73. var objs = thmrFindParents(obj);
  74. if (objs.length) {
  75. themerHilight(objs[0]);
  76. thmrRebuildPopup(objs);
  77. }
  78. return false;
  79. }
  80. function thmrInPop(obj) {
  81. //is the element in either the popup box or the toggle div?
  82. if (obj.id == "themer-popup" || obj.id == "themer-toggle") return true;
  83. if (obj.parentNode) {
  84. while (obj = obj.parentNode) {
  85. if (obj.id=="themer-popup" || obj.id == "themer-toggle") return true;
  86. }
  87. }
  88. return false;
  89. }
  90. function themerEvent(e) {
  91. if (!e) {
  92. var e = window.event;
  93. };
  94. if (e.target) var tg = e.target;
  95. else if (e.srcElement) var tg = e.srcElement;
  96. return themerDoIt(tg);
  97. }
  98. /**
  99. * Find all parents with @data-thmr"
  100. */
  101. function thmrFindParents(obj) {
  102. var parents = new Array();
  103. if ($(obj).attr('data-thmr') != undefined) {
  104. parents[parents.length] = obj;
  105. }
  106. if (obj && obj.parentNode) {
  107. while ((obj = obj.parentNode) && (obj.nodeType != 9)) {
  108. if ($(obj).attr('data-thmr') != undefined) {
  109. parents[parents.length] = obj;
  110. }
  111. }
  112. }
  113. return parents;
  114. }
  115. /**
  116. * Check to see if object is a block element
  117. */
  118. function thmrIsBlock(obj) {
  119. if (obj.style.display == 'block') {
  120. return true;
  121. }
  122. else if (obj.style.display == 'inline' || obj.style.display == 'none') {
  123. return false;
  124. }
  125. if (obj.tagName != undefined) {
  126. var i = blocks.length;
  127. if (i > 0) {
  128. do {
  129. if (blocks[i] === obj.tagName) {
  130. return true;
  131. }
  132. } while (i--);
  133. }
  134. }
  135. return false;
  136. }
  137. function thmrRefreshCollapse() {
  138. $('#themer-popup .devel-obj-output dt').each(function() {
  139. $(this).toggle(function() {
  140. $(this).parent().children('dd').show();
  141. }, function() {
  142. $(this).parent().children('dd').hide();
  143. });
  144. });
  145. }
  146. /**
  147. * Rebuild the popup
  148. *
  149. * @param objs
  150. * The array of the current object and its parents. Current object is first element of the array
  151. */
  152. function thmrRebuildPopup(objs) {
  153. // rebuild the popup box
  154. var id = objs[0].getAttribute('data-thmr').split(' ').reverse()[0];
  155. // vars is the settings array element for this theme item
  156. var vars = Drupal.settings[id];
  157. // strs is the translatable strings
  158. var strs = Drupal.settings.thmrStrings;
  159. var type = vars.type;
  160. var key = vars.used;
  161. // clear out the initial "click on any element" starter text
  162. $('#themer-popup div.starter').empty();
  163. if (type == 'func') {
  164. // populate the function name
  165. $('#themer-popup dd.key').empty().prepend('<a href="'+ strs.api_site +'api/search/'+ strs.drupal_version +'/'+ key +'" title="'+ strs.drupal_api_docs +'">'+ key +'()</a>');
  166. $('#themer-popup dt.key-type').empty().prepend(strs.function_called);
  167. }
  168. else {
  169. // populate the template name
  170. $('#themer-popup dd.key').empty().prepend(key);
  171. $('#themer-popup dt.key-type').empty().prepend(strs.template_called);
  172. }
  173. // parents
  174. var parents = '';
  175. var parents = strs.parents +' <span class="parents">';
  176. var isFirst = true;
  177. for (i = 0; i < objs.length; i++) {
  178. thmr_ids = objs[i].getAttribute('data-thmr').split(' ').reverse();
  179. for (j = (i==0?1:0); j < thmr_ids.length; j++) {
  180. var thmrid = thmr_ids[j];
  181. var pvars = Drupal.settings[thmrid];
  182. parents += (isFirst) ? '' : '&lt; ';
  183. // populate the parents
  184. // each parent is wrapped with a span containing a 'trig' attribute with the id of the element it represents
  185. parents += '<span class="parent" trig="'+ objs[i].getAttribute('data-thmr') +'">'+ pvars.name +'</span> ';
  186. isFirst = false;
  187. }
  188. }
  189. parents += '</span>';
  190. // stick the parents spans in the #parents div
  191. $('#themer-popup #parents').empty().prepend(parents);
  192. $('#themer-popup span.parent')
  193. .click(function() {
  194. var thmr_id = $(this).attr('trig');
  195. var thmr_obj = $('[data-thmr = "' + thmr_id + '"]')[0];
  196. themerDoIt(thmr_obj);
  197. })
  198. .hover(
  199. function() {
  200. // make them highlight their element on mouseover
  201. $('#'+ $(this).attr('trig')).trigger('mouseover');
  202. },
  203. function() {
  204. // and unhilight on mouseout
  205. $('#'+ $(this).attr('trig')).trigger('mouseout');
  206. }
  207. );
  208. if (vars == undefined) {
  209. // if there's no item in the settings array for this element
  210. $('#themer-popup dd.candidates').empty();
  211. $('#themer-popup dd.preprocessors').empty();
  212. $('#themer-popup div.attributes').empty();
  213. $('#themer-popup div.used').empty();
  214. $('#themer-popup div.duration').empty();
  215. }
  216. else {
  217. $('#themer-popup div.duration').empty().prepend('<span class="dt">' + strs.duration + '</span>' + vars.duration + ' ms');
  218. $('#themer-popup dd.candidates').empty().prepend(vars.candidates.join('<span class="delimiter"> < </span>'));
  219. $('#themer-popup dd.preprocessors').empty().prepend(vars.preprocessors.join('<span class="delimiter"> + </span>'));
  220. $('#themer-popup dt.preprocessors-type').empty().prepend(strs.preprocessors);
  221. $('#themer-popup dd.processors').empty().prepend(vars.processors.join('<span class="delimiter"> + </span>'));
  222. $('#themer-popup dt.processors-type').empty().prepend(strs.processors);
  223. var uri = Drupal.settings.devel_themer_uri + '/' + id;
  224. if (type == 'func') {
  225. // populate the candidates
  226. $('#themer-popup dt.candidates-type').empty().prepend(strs.candidate_functions);
  227. }
  228. else {
  229. $('#themer-popup dt.candidates-type').empty().prepend(strs.candidate_files);
  230. }
  231. // Use drupal ajax to do what we need
  232. vars_div_array = $('div.themer-variables');
  233. vars_div = vars_div_array[0];
  234. // Programatically using the drupal ajax things is tricky, so cheat.
  235. dummy_link = $('<a href="'+uri+'" class="use-ajax">Loading Vars</a>');
  236. $(vars_div).append(dummy_link);
  237. Drupal.attachBehaviors(vars_div);
  238. dummy_link.click();
  239. thmrRefreshCollapse();
  240. }
  241. // stop throbber
  242. //$('#themer-popup img.throbber').hide();
  243. }
  244. })(jQuery);