/** * Debug Toolbar Javascript. * * Creates the DEBUGKIT namespace and provides methods for extending * and enhancing the Html toolbar. Includes library agnostic Event, Element, * Cookie and Request wrappers. * * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @package DebugKit.webroot.js * @since DebugKit 0.1 * @license http://www.opensource.org/licenses/mit-license.php MIT License */ var DEBUGKIT = function () { var undef; return { module: function (newmodule) { if (this[newmodule] === undef) { this[newmodule] = {}; return this[newmodule]; } return this[newmodule]; } }; }() ; DEBUGKIT.$ = jQuery.noConflict(true); DEBUGKIT.loader = function () { return { //list of methods to run on startup. _startup: [], //register a new method to be run on dom ready. register: function (method) { this._startup.push(method); }, init: function () { for (var i = 0, callback; callback = this._startup[i]; i++) { callback.init(); } } }; }(); DEBUGKIT.module('sqlLog'); DEBUGKIT.sqlLog = function () { var $ = DEBUGKIT.$; return { init : function () { var sqlPanel = $('#sqllog-tab'); var buttons = sqlPanel.find('input'); // Button handling code for explain links. // performs XHR request to get explain query. var handleButton = function (event) { event.preventDefault(); var form = $(this.form), data = form.serialize(), dbName = form.find('input[name*=ds]').val() || 'default'; var fetch = $.ajax({ url: this.form.action, data: data, type: 'POST', success : function (response) { $('#sql-log-explain-' + dbName).html(response); }, error : function () { alert('Could not fetch EXPLAIN for query.'); } }); }; buttons.filter('.sql-explain-link').on('click', handleButton); } }; }(); DEBUGKIT.loader.register(DEBUGKIT.sqlLog); // // NOTE DEBUGKIT.Util.Element is Deprecated. // //Util module and Element utility class. DEBUGKIT.module('Util'); DEBUGKIT.Util.Element = { //test if an element is a name node. nodeName: function (element, name) { return element.nodeName && element.nodeName.toLowerCase() == name.toLowerCase(); }, //return a boolean if the element has the classname hasClass: function (element, className) { if (!element.className) { return false; } return element.className.indexOf(className) > -1; }, addClass: function (element, className) { if (!element.className) { element.className = className; return; } element.className = element.className.replace(/^(.*)$/, '$1 ' + className); }, removeClass: function (element, className) { if (DEBUGKIT.Util.isArray(element)) { DEBUGKIT.Util.Collection.apply(element, function (element) { DEBUGKIT.Util.Element.removeClass(element, className); }); } if (!element.className) { return false; } element.className = element.className.replace(new RegExp(' ?(' + className +') ?'), ''); }, swapClass: function (element, removeClass, addClass) { if (!element.className) { return false; } element.className = element.className.replace(removeClass, addClass); }, show: function (element) { element.style.display = 'block'; }, hide: function (element) { element.style.display = 'none'; }, //go between hide() and show() depending on element.style.display toggle: function (element) { if (element.style.display == 'none') { this.show(element); return; } this.hide(element); }, _walk: function (element, walk) { var sibling = element[walk]; while (true) { if (sibling.nodeType == 1) { break; } sibling = sibling[walk]; } return sibling; }, getNext: function (element) { return this._walk(element, 'nextSibling'); }, getPrevious: function (element) { return this._walk(element, 'previousSibling'); }, //get or set an element's height, omit value to get, add value (integer) to set. height: function (element, value) { //get value if (value === undefined) { return parseInt(this.getStyle(element, 'height'), 10); } element.style.height = value + 'px'; }, //gets the style in css format for property getStyle: function (element, property) { if (element.currentStyle) { property = property.replace(/-[a-z]/g, function (match) { return match.charAt(1).toUpperCase(); }); return element.currentStyle[property]; } if (window.getComputedStyle) { return document.defaultView.getComputedStyle(element, null).getPropertyValue(property); } } }; // // NOTE DEBUGKIT.Util.Collection is Deprecated. // DEBUGKIT.Util.Collection = { /* Apply the passed function to each item in the collection. The current element in the collection will be `this` in the callback The callback is also passed the element and the index as arguments. Optionally you can supply a binding parameter to change `this` in the callback. */ apply: function (collection, callback, binding) { var name, thisVar, i = 0, len = collection.length; if (len === undefined) { for (name in collection) { thisVar = (binding === undefined) ? collection[name] : binding; callback.apply(thisVar, [collection[name], name]); } } else { for (; i < len; i++) { thisVar = (binding === undefined) ? collection[i] : binding; callback.apply(thisVar, [collection[i], i]); } } } }; // // NOTE DEBUGKIT.Util.Event is Deprecated. // //Event binding DEBUGKIT.Util.Event = function () { var _listeners = {}, _eventId = 0; var preventDefault = function () { this.returnValue = false; }; var stopPropagation = function () { this.cancelBubble = true; }; // Fixes IE's broken event object, adds in common methods + properties. var fixEvent = function (event) { if (!event.preventDefault) { event.preventDefault = preventDefault; } if (!event.stopPropagation) { event.stopPropagation = stopPropagation; } if (!event.target) { event.target = event.srcElement || document; } if (event.pageX === null && event.clientX !== null) { var doc = document.body; event.pageX = event.clientX + (doc.scrollLeft || 0) - (doc.clientLeft || 0); event.pageY = event.clientY + (doc.scrollTop || 0) - (doc.clientTop || 0); } return event; }; return { // bind an event listener of type to element, handler is your method. addEvent: function(element, type, handler, capture) { capture = (capture === undefined) ? false : capture; var callback = function (event) { event = fixEvent(event || window.event); handler.apply(element, [event]); }; if (element.addEventListener) { element.addEventListener(type, callback, capture); } else if (element.attachEvent) { type = 'on' + type; element.attachEvent(type, callback); } else { type = 'on' + type; element[type] = callback; } _listeners[++_eventId] = {element: element, type: type, handler: callback}; }, // destroy an event listener. requires the exact same function as was used for attaching // the event. removeEvent: function (element, type, handler) { if (element.removeEventListener) { element.removeEventListener(type, handler, false); } else if (element.detachEvent) { type = 'on' + type; element.detachEvent(type, handler); } else { type = 'on' + type; element[type] = null; } }, // bind an event to the DOMContentLoaded or other similar event. domready: function(callback) { if (document.addEventListener) { return document.addEventListener("DOMContentLoaded", callback, false); } if (document.all && !window.opera) { //Define a "blank" external JavaScript tag document.write('