[Jifty-commit] r1684 - in jifty/trunk/plugins/ProfileBehaviour: .
doc lib lib/Jifty lib/Jifty/Plugin
lib/Jifty/Plugin/ProfileBehaviour/Action
lib/Jifty/Plugin/ProfileBehaviour/Model share share/po
share/web share/web/static share/web/static/css
share/web/static/js share/web/templates t
jifty-commit at lists.jifty.org
jifty-commit at lists.jifty.org
Thu Jul 27 17:23:24 EDT 2006
Author: nelhage
Date: Thu Jul 27 17:23:23 2006
New Revision: 1684
Added:
jifty/trunk/plugins/ProfileBehaviour/
jifty/trunk/plugins/ProfileBehaviour/Makefile.PL
jifty/trunk/plugins/ProfileBehaviour/doc/
jifty/trunk/plugins/ProfileBehaviour/lib/
jifty/trunk/plugins/ProfileBehaviour/lib/Jifty/
jifty/trunk/plugins/ProfileBehaviour/lib/Jifty/Plugin/
jifty/trunk/plugins/ProfileBehaviour/lib/Jifty/Plugin/ProfileBehaviour/
jifty/trunk/plugins/ProfileBehaviour/lib/Jifty/Plugin/ProfileBehaviour.pm
jifty/trunk/plugins/ProfileBehaviour/lib/Jifty/Plugin/ProfileBehaviour/Action/
jifty/trunk/plugins/ProfileBehaviour/lib/Jifty/Plugin/ProfileBehaviour/Dispatcher.pm
jifty/trunk/plugins/ProfileBehaviour/lib/Jifty/Plugin/ProfileBehaviour/Model/
jifty/trunk/plugins/ProfileBehaviour/share/
jifty/trunk/plugins/ProfileBehaviour/share/po/
jifty/trunk/plugins/ProfileBehaviour/share/web/
jifty/trunk/plugins/ProfileBehaviour/share/web/static/
jifty/trunk/plugins/ProfileBehaviour/share/web/static/css/
jifty/trunk/plugins/ProfileBehaviour/share/web/static/css/behaviour-profile.css
jifty/trunk/plugins/ProfileBehaviour/share/web/static/js/
jifty/trunk/plugins/ProfileBehaviour/share/web/static/js/behaviour.js
jifty/trunk/plugins/ProfileBehaviour/share/web/templates/
jifty/trunk/plugins/ProfileBehaviour/t/
Log:
Adding a ProfileBehaviour plugin to aid profiling Javascript
Behaviours (see app_behaviour.js in the Jifty source for some more
information)
Added: jifty/trunk/plugins/ProfileBehaviour/Makefile.PL
==============================================================================
--- (empty file)
+++ jifty/trunk/plugins/ProfileBehaviour/Makefile.PL Thu Jul 27 17:23:23 2006
@@ -0,0 +1,8 @@
+use inc::Module::Install;
+name('Jifty-Plugin-ProfileBehaviour');
+version('0.01');
+requires('Jifty' => '0.60722');
+
+install_share;
+
+WriteAll;
Added: jifty/trunk/plugins/ProfileBehaviour/lib/Jifty/Plugin/ProfileBehaviour.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/plugins/ProfileBehaviour/lib/Jifty/Plugin/ProfileBehaviour.pm Thu Jul 27 17:23:23 2006
@@ -0,0 +1,10 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::ProfileBehaviour;
+use base qw/Jifty::Plugin/;
+
+# Your plugin goes here. If takes any configuration or arguments, you
+# probably want to override L<Jifty::Plugin/init>.
+
+1;
Added: jifty/trunk/plugins/ProfileBehaviour/lib/Jifty/Plugin/ProfileBehaviour/Dispatcher.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/plugins/ProfileBehaviour/lib/Jifty/Plugin/ProfileBehaviour/Dispatcher.pm Thu Jul 27 17:23:23 2006
@@ -0,0 +1,9 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::ProfileBehaviour::Dispatcher;
+use Jifty::Dispatcher -base;
+
+# Put any plugin-specific dispatcher rules here.
+
+1;
Added: jifty/trunk/plugins/ProfileBehaviour/share/web/static/css/behaviour-profile.css
==============================================================================
--- (empty file)
+++ jifty/trunk/plugins/ProfileBehaviour/share/web/static/css/behaviour-profile.css Thu Jul 27 17:23:23 2006
@@ -0,0 +1,67 @@
+#behaviour-profile-data {
+ width: 90%;
+ height: 90%;
+ position: absolute;
+ left: 5%;
+ top: 5%;
+ background-color: white;
+ border: 2px solid black;
+ overflow: scroll;
+}
+
+#behaviour-profile-data div.title {
+ font-size: 200%;
+ border-bottom: 2px solid black;
+}
+
+#behaviour-profile-data .section .title {
+ font-size: 150%;
+}
+
+#behaviour-profile-data .title .close {
+ font-size: 80%;
+ text-align: right;
+ text-decoration:none;
+ position: absolute:
+ right: 10px;
+ top: 10px;
+}
+
+#behaviour-profile-data .code code {
+ position: absolute;
+ background-color: lightgrey;
+ border: 1px solid black;
+ z-index: 100;
+ white-space: pre;
+ text-align: left;
+}
+
+#behaviour-profile-data table td.time {
+ text-align:center;
+}
+
+#behaviour-profile-data table td.selector {
+ text-align:right;
+}
+
+#behaviour-profile-data table tr,
+#behaviour-profile-data table td,
+#behaviour-profile-data table th {
+ text-align:center;
+ padding: 0px 5px;
+}
+
+#behaviour-profile-data table .time {
+ border-left: 1px solid black;
+}
+
+#behaviour-profile-data table .total {
+ border-right: 1px solid black;
+}
+
+
+#show-behaviour-profile {
+ position: absolute;
+ left: 0;
+ bottom: 0;
+}
Added: jifty/trunk/plugins/ProfileBehaviour/share/web/static/js/behaviour.js
==============================================================================
--- (empty file)
+++ jifty/trunk/plugins/ProfileBehaviour/share/web/static/js/behaviour.js Thu Jul 27 17:23:23 2006
@@ -0,0 +1,225 @@
+/*
+ Modified to fix some bugs, use a different css query engine, and to
+ to use JSAN classes.
+
+ Based on Behaviour v1.1 by Ben Nolan, June 2005, which was based
+ largely on the work of Simon Willison.
+
+ Usage:
+
+ var myrules = {
+ 'b.someclass' : function(element){
+ element.onclick = function(){
+ alert(this.innerHTML);
+ }
+ },
+ '#someid u' : function(element){
+ element.onmouseover = function(){
+ this.innerHTML = "BLAH!";
+ }
+ }
+ };
+
+ Behaviour.register(myrules);
+
+ // Call Behaviour.apply() to re-apply the rules (if you
+ // update the dom, etc).
+
+
+ This Behaviour has been modified to keep track of timing
+ information and render it to an on-screen display for profiling
+ purposes
+*/
+
+JSAN.use("DOM.Events");
+JSAN.use("Upgrade.Array.push");
+
+var Behaviour = {
+ profileData: {
+ calls: [],
+ applyTime: 0,
+ searchTime: 0,
+ numCalls: 0
+ },
+ list: new Array(),
+
+ register: function(sheet) {
+ Behaviour.list.push(sheet);
+ },
+
+ apply: function() {
+ var root = arguments[0];
+ if(root) root = $(root);
+ var _applyStart = new Date();
+ var profile = {
+ searchTimes: {},
+ applyTimes: {},
+ funcs: {},
+ searchTime: 0,
+ applyTime: 0,
+ caller: Behaviour.apply.caller
+ };
+
+ for (var h = 0; sheet = Behaviour.list[h]; h++) {
+ for (var selector in sheet) {
+ var start = new Date();
+ var elements = cssQuery(selector, root);
+ var searchDone = new Date();
+ profile.searchTimes[selector] = searchDone - start;
+ profile.searchTime += profile.searchTimes[selector];
+
+ if ( !elements ) continue;
+
+ for (var i = 0; element = elements[i]; i++) {
+ sheet[selector](element);
+ }
+ profile.applyTimes[selector] = new Date() - searchDone;
+ profile.applyTime += profile.applyTimes[selector];
+ profile.funcs[selector] = sheet[selector];
+ }
+ }
+
+ Behaviour.profileData.calls.push(profile);
+ Behaviour.profileData.numCalls++;
+ Behaviour.profileData.searchTime += profile.searchTime;
+ Behaviour.profileData.applyTime += profile.applyTime;
+ },
+
+ showProfile: function() {
+ var pane = this.createElement('div');
+ pane.id = 'behaviour-profile-data';
+
+ var title = this.createElement('div');
+ title.appendChild(document.createTextNode('Behaviour profiling information'));
+ title.className = 'title';
+ var close = this.createElement('a', 'close', '[close]');
+ close.href = '#';
+ close.onclick = function() { Element.remove($('behaviour-profile-data')); }
+
+ pane.appendChild(close);
+ pane.appendChild(title);
+
+ pane.appendChild(Behaviour._callData());
+
+ document.getElementsByTagName('body')[0].appendChild(pane);
+
+ },
+
+ _callData: function() {
+ list = this.createElement('ul', 'section');
+
+ for( var i = 0; i < Behaviour.profileData.calls.length; i++ ) {
+ var call = Behaviour.profileData.calls[i];
+ var item = this.createElement('li', 'call');
+ var text = call.caller.length == 0 ? ' (Page load)' : ' (AJAX)';
+ var title = this.createElement('div', 'title', 'Call ' + i + text);
+ item.appendChild(title);
+
+ var table = this.createElement('table');
+ var head = this.createElement('tr');
+ head.appendChild(this.createElement('th', 'selector', 'Selector'));
+ head.appendChild(this.createElement('th', 'time search', 'cssQuery time'));
+ head.appendChild(this.createElement('th', 'time apply', 'Function time'));
+ head.appendChild(this.createElement('th', 'time total', 'Total time'));
+ head.appendChild(this.createElement('th'));
+ table.appendChild(head);
+
+ var searchTimes = $H(call.searchTimes).keys().sort(function(a,b) {
+ var timeA = call.searchTimes[a] + call.applyTimes[a];
+ var timeB = call.searchTimes[b] + call.applyTimes[b];
+
+ if(timeA < timeB) {
+ return 1;
+ } else if(timeA > timeB) {
+ return -1;
+ } else {
+ return 0;
+ }
+ });
+
+ for(var j = 0; j < searchTimes.length; j++) {
+ var k = searchTimes[j];
+ var tr = this.createElement('tr');
+ tr.appendChild(this.createElement('td', 'selector', k));
+ tr.appendChild(this.createElement('td', 'time search', call.searchTimes[k]));
+ tr.appendChild(this.createElement('td', 'time apply', call.applyTimes[k]));
+ tr.appendChild(this.createElement('td', 'time total', call.searchTimes[k] + call.applyTimes[k]));
+
+ var code = this.createElement('td', 'code');
+ var a = this.createElement('a', null, '[code]');
+ a.href = '#';
+ var src = this.createElement('code', null, call.funcs[k]);
+ var id = 'code-' + i + '-' + j;
+ src.id = id;
+ src.style.display = 'none';
+ // Kludge to make the onclick function close over id properly
+ (function (id) {
+ a.onclick = function() { Element.toggle($(id)); return false; }
+ })(id);
+
+ var div = this.createElement('div');
+ div.appendChild(src);
+ code.appendChild(div);
+ code.appendChild(a);
+ tr.appendChild(code);
+ table.appendChild(tr);
+ }
+
+ item.appendChild(table);
+
+ item.appendChild(this.createElement('div','totals',
+ 'Total: '
+ + call.searchTime + ' search, '
+ + call.applyTime + ' apply, '
+ + (call.searchTime + call.applyTime) + ' total'));
+
+
+ list.appendChild(item);
+ }
+
+ return list;
+ },
+
+
+ // Convenience method for the above
+ createElement: function (elt, className, text) {
+ elt = elt ? elt : 'div';
+ var d = document.createElement(elt);
+ if(className) d.className = className;
+ if(text) d.appendChild(document.createTextNode(text));
+ return d;
+ },
+
+ onLoad: function () {
+ // Make sure we only run once
+ if(Behaviour.loaded) return;
+ Behaviour.loaded = true;
+ Behaviour.apply();
+
+ // Add the profiling CSS to the document
+ var head = document.getElementsByTagName('head')[0];
+ var link = document.createElement('link');
+ link.rel = 'stylesheet';
+ link.type = 'text/css';
+ link.href = '/css/behaviour-profile.css';
+ head.appendChild(link);
+
+ var open = this.createElement('a', null, '[Behaviour profile]');
+ open.id = 'show-behaviour-profile';
+ open.href ='#';
+ open.onclick = function() { Behaviour.toggleProfile() }
+ document.getElementsByTagName('body')[0].appendChild(open);
+ },
+
+ toggleProfile: function () {
+ var e = $('behaviour-profile-data');
+ if(e) {
+ Element.remove(e);
+ } else {
+ this.showProfile();
+ }
+ }
+}
+
+
+DOM.Events.addListener( window, "load", function() { Behaviour.onLoad() } );
More information about the Jifty-commit
mailing list