[Jifty-commit] jifty branch, master, updated. 86d839a03bc1bc7ecd69d94a7e12006d37904623

Jifty commits jifty-commit at lists.jifty.org
Fri Jan 15 16:23:33 EST 2010


The branch, master has been updated
       via  86d839a03bc1bc7ecd69d94a7e12006d37904623 (commit)
       via  4c4b07b3b305f909e17f6caa15ffee405f6b7f70 (commit)
       via  1d32bfc0dc54c090395e83b5041af9dc0bb84ecb (commit)
       via  72cb1ffe8110ff103022c40c76a0c5a093bc17f6 (commit)
       via  034ea91d49db3a079f4d7791266e64141bd7c71b (commit)
       via  5a47db20ccff2ad4b279474b703785ad6424ed70 (commit)
       via  8ba7bc45b37f8705a190763542c245ca024461e0 (commit)
       via  bae815253fbc4c1483c142fc637a74d335bcb461 (commit)
       via  dc85afcf2506ece9da59f3c1f779bc3b849fd731 (commit)
       via  3848dc8afe00668eee35bfe847a8e97db07db851 (commit)
       via  9a27a8054b78650039537c481768f2e6749be2a5 (commit)
       via  58b98c38c5211dea6fb86fc8d592bf5902ba476f (commit)
       via  925eee7d47f5909be58086fa2a5b983bc449b57c (commit)
       via  85f8259b61709c13c8c4d388b06d0802571c4265 (commit)
       via  f8a357f5814c172a7646155ff7ff8ca96cae99a1 (commit)
      from  9e072ae08af1d44a2697e42e9aabdc2308c491b1 (commit)

Summary of changes:
 doc/js-refactor                                    |   37 ++
 lib/Jifty/Manual/UsingCSSandJS.pod                 |   12 +-
 lib/Jifty/Plugin/CompressedCSSandJS.pm             |   41 ++-
 lib/Jifty/View/Static/Handler.pm                   |    4 -
 lib/Jifty/Web.pm                                   |    7 -
 lib/Jifty/Web/Form/Field.pm                        |    4 +-
 share/web/static/js/bps_util.js                    |  105 ------
 share/web/static/js/context_menu.js                |   10 +-
 share/web/static/js/css_browser_selector.js        |    8 +-
 share/web/static/js/formatDate.js                  |  356 --------------------
 share/web/static/js/halo.js                        |    2 +
 share/web/static/js/jifty.js                       |    6 +-
 share/web/static/js/jifty_subs.js                  |    2 +-
 share/web/static/js/jifty_utils.js                 |   57 +++-
 share/web/static/js/jsan/DOM/Events.js             |  262 --------------
 share/web/static/js/jsan/JSAN.js                   |  303 -----------------
 share/web/static/js/jsan/Push.js                   |   76 -----
 share/web/static/js/jsan/Upgrade.js                |  121 -------
 share/web/static/js/jsan/Upgrade/Array/push.js     |   14 -
 share/web/static/js/jsan/Upgrade/Function/apply.js |   19 -
 share/web/static/js/key_bindings.js                |   16 +-
 share/web/static/js/setup_jsan.js                  |   13 -
 share/web/templates/helpers/calendar.html          |    6 +-
 23 files changed, 150 insertions(+), 1331 deletions(-)
 create mode 100644 doc/js-refactor
 delete mode 100644 share/web/static/js/bps_util.js
 delete mode 100644 share/web/static/js/formatDate.js
 mode change 100755 => 100644 share/web/static/js/iautocompleter.js
 mode change 100755 => 100644 share/web/static/js/iutil.js
 mode change 100755 => 100644 share/web/static/js/jquery.jgrowl.js
 mode change 100755 => 100644 share/web/static/js/jquery.timepickr.js
 delete mode 100644 share/web/static/js/jsan/DOM/Events.js
 delete mode 100644 share/web/static/js/jsan/JSAN.js
 delete mode 100644 share/web/static/js/jsan/Push.js
 delete mode 100644 share/web/static/js/jsan/Upgrade.js
 delete mode 100644 share/web/static/js/jsan/Upgrade/Array/push.js
 delete mode 100644 share/web/static/js/jsan/Upgrade/Function/apply.js
 delete mode 100644 share/web/static/js/setup_jsan.js

- Log -----------------------------------------------------------------
commit f8a357f5814c172a7646155ff7ff8ca96cae99a1
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Thu Jan 14 18:11:09 2010 -0500

    Kill bps_utils.js and move into Jifty.Utils

diff --git a/doc/js-refactor b/doc/js-refactor
new file mode 100644
index 0000000..09dabbf
--- /dev/null
+++ b/doc/js-refactor
@@ -0,0 +1,5 @@
+bps_util.js
+    focusElementById removed
+    custom onload hook code removed
+    buttonToLink, updateParentField, createCalendarLink, createDateTimeLink moved to Jifty.Utils
+    
diff --git a/share/web/static/js/bps_util.js b/share/web/static/js/bps_util.js
deleted file mode 100644
index 012e92b..0000000
--- a/share/web/static/js/bps_util.js
+++ /dev/null
@@ -1,105 +0,0 @@
-// XXX TODO This library should likely be refactored to use behaviour
-
-function focusElementById(id) {
-    var e = document.getElementById(id);
-    if (e) e.focus();
-}
-
-function updateParentField(field, value) {
-    if (window.opener) {
-        window.opener.document.getElementById(field).value = value;
-        window.close();
-    }
-}
-
-function createCalendarLink(id) {
-    return Jifty.Calendar.registerDateWidget( id );
-}
-
-function createDateTimeLink(id) {
-    return Jifty.DateTime.registerDateTimeWidget( id );
-}
-
-JSAN.use("DOM.Events");
-
-function buttonToLink(e) {
-    var link = document.createElement("a");
-    link.setAttribute("href","#");
-    link.setAttribute("name",e.getAttribute("name"));
-
-    var form = Jifty.Form.Element.getForm(e);
-    var onclick = e.getAttribute("onclick");
-
-    /* Simple buttons that don't use any JS need us to create an onclick
-       for them that makes sure the original button's name gets passed
-       and the form submitted normally (without any Ajax-ness)
-    */
-    if ( !onclick ) {
-        DOM.Events.addListener( link, "click", function(ev) {
-            var a = ev.target;
-            var hidden = document.createElement("input");
-            hidden.setAttribute("type", "hidden");
-            hidden.setAttribute("name", a.getAttribute("name"));
-            a["virtualform"].appendChild( hidden );
-            if ( a["virtualform"].onsubmit )
-                a["virtualform"].onsubmit();
-            a["virtualform"].submit();
-        });
-    }
-    link.setAttribute("onclick", onclick);
-    link.setAttribute("title", e.getAttribute("title"));
-
-    link.className = e.className;
-    link["virtualform"] = form;
-    link.appendChild(document.createTextNode(e.getAttribute("value")));
-
-    e.parentNode.insertBefore(link, e.nextSibling);
-    e.parentNode.removeChild(e);
-    return link;
-}
-
-// onload handlers
-
-var onLoadStack     = new Array();
-var onLoadLastStack = new Array();
-var onLoadExecuted  = 0;
-
-function onLoadHook(commandStr) {
-    if(typeof(commandStr) == "string") {
-        onLoadStack[onLoadStack.length] = commandStr;
-        return true;
-    }
-    return false;
-}
-
-// some things *really* need to be done after everything else
-function onLoadLastHook(commandStr) {
-    if(typeof(commandStr) == "string"){
-        onLoadLastStack[onLoadLastStack.length] = commandStr;
-        return true;
-    }
-    return false;
-}
-
-function doOnLoadHooks() {
-    if(onLoadExecuted) return;
-    for (var x=0; x < onLoadStack.length; x++) { 
-        eval(onLoadStack[x]);
-    }
-    for (var x=0; x < onLoadLastStack.length; x++) { 
-        eval(onLoadLastStack[x]); 
-    }
-    onLoadExecuted = 1;
-}
-
-
-if (typeof window.onload != 'function') {
-    window.onload = doOnLoadHooks;
-} else {
-    var oldonload = window.onload;
-    
-    window.onload = function() {
-        oldonload();
-        doOnLoadHooks();
-    }
-}
diff --git a/share/web/static/js/jifty.js b/share/web/static/js/jifty.js
index b00a139..037ac9a 100644
--- a/share/web/static/js/jifty.js
+++ b/share/web/static/js/jifty.js
@@ -724,7 +724,7 @@ Behaviour.register({
     },
     'input.date': function(e) {
         if ( !jQuery(e).hasClass('has_calendar_link') ) {
-            createCalendarLink(e);
+            Jifty.Utils.createCalendarLink(e);
             jQuery(e).addClass('has_calendar_link');
         }
     },
@@ -733,7 +733,7 @@ Behaviour.register({
     },
     'input.datetime': function(e) {
         if ( !jQuery(e).hasClass('has_datetime_link') ) {
-            createDateTimeLink(e);
+            Jifty.Utils.createDateTimeLink(e);
 
             var button = document.createElement('input');
             button.setAttribute('type',  'button');
@@ -757,7 +757,7 @@ Behaviour.register({
         }
     },
     'input.button_as_link': function(e) {
-        buttonToLink(e);
+        Jifty.Utils.buttonToLink(e);
     },
     "input.date, input.text": function(e) {
         /* XXX TODO: Figure out how to make our enter handler detect
diff --git a/share/web/static/js/jifty_utils.js b/share/web/static/js/jifty_utils.js
index da8c04b..802301c 100644
--- a/share/web/static/js/jifty_utils.js
+++ b/share/web/static/js/jifty_utils.js
@@ -1,7 +1,60 @@
 
 if (typeof Jifty == "undefined") Jifty = { };
 
-Jifty.Utils = {
+Jifty.Utils = {};
+
+jQuery.extend(Jifty.Utils, {
+    buttonToLink: function(e) {
+        var link = document.createElement("a");
+        link.setAttribute("href","#");
+        link.setAttribute("name",e.getAttribute("name"));
+
+        var form = Jifty.Form.Element.getForm(e);
+        var onclick = e.getAttribute("onclick");
+
+        /* Simple buttons that don't use any JS need us to create an onclick
+           for them that makes sure the original button's name gets passed
+           and the form submitted normally (without any Ajax-ness)
+        */
+        if ( !onclick ) {
+            jQuery( link ).click(function(ev) {
+                var a = ev.target;
+                var hidden = document.createElement("input");
+                hidden.setAttribute("type", "hidden");
+                hidden.setAttribute("name", a.getAttribute("name"));
+                a["virtualform"].appendChild( hidden );
+                if ( a["virtualform"].onsubmit )
+                    a["virtualform"].onsubmit();
+                a["virtualform"].submit();
+            });
+        }
+        link.setAttribute("onclick", onclick);
+        link.setAttribute("title", e.getAttribute("title"));
+
+        link.className = e.className;
+        link["virtualform"] = form;
+        link.appendChild(document.createTextNode(e.getAttribute("value")));
+
+        e.parentNode.insertBefore(link, e.nextSibling);
+        e.parentNode.removeChild(e);
+        return link;
+    },
+
+    updateParentField: function(field, value) {
+        if (window.opener) {
+            window.opener.document.getElementById(field).value = value;
+            window.close();
+        }
+    },
+
+    createCalendarLink: function(id) {
+        return Jifty.Calendar.registerDateWidget( id );
+    },
+
+    createDateTimeLink: function(id) {
+        return Jifty.DateTime.registerDateTimeWidget( id );
+    },
+
     /* From http://blog.firetree.net/2005/07/04/javascript-find-position/ */
     findPosX: function(obj)
     {
@@ -142,7 +195,7 @@ Jifty.Utils = {
     stripScripts: function(str) {
         return str.replace(/<script(.|\s)*?\/script>/g, "");
     }
-};
+});
 
 /* This sets Jifty.Utils.isMSIE to true in IE */
 /* @cc_on
diff --git a/share/web/templates/helpers/calendar.html b/share/web/templates/helpers/calendar.html
index fbfe41a..dd8e8df 100644
--- a/share/web/templates/helpers/calendar.html
+++ b/share/web/templates/helpers/calendar.html
@@ -21,7 +21,7 @@
       <td>
 %         if ($day) {
 %             my $datestr = sprintf('%04d-%02d-%02d', $DisplayedYear, $DisplayedMonth, $day);
-        <a href="#" onclick="updateParentField('<% $field %>','<% $datestr %>'); return false;"><% $day %></a>
+        <a href="#" onclick="Jifty.Utils.updateParentField('<% $field %>','<% $datestr %>'); return false;"><% $day %></a>
 %         } else {
         &nbsp;
 %         }
@@ -32,13 +32,13 @@
   </table>
   <span class="calendar today">
 %             my $datestr = sprintf('%04d-%02d-%02d', $today[5]+1900,$today[4]+1, $today[3]);
-        <a href="#" onclick="updateParentField('<% $field %>','<% $datestr %>'); return false;">Today</a>
+        <a href="#" onclick="Jifty.Utils.updateParentField('<% $field %>','<% $datestr %>'); return false;">Today</a>
   
   </span>
   <span class="calendar tomorrow">
 % my @tomorrow = localtime(time()+86400);
 % $datestr = sprintf('%04d-%02d-%02d', $tomorrow[5]+1900,$tomorrow[4]+1, $tomorrow[3]);
-        <a href="#" onclick="updateParentField('<% $field %>','<% $datestr %>'); return false;">Tomorrow</a>
+        <a href="#" onclick="Jifty.Utils.updateParentField('<% $field %>','<% $datestr %>'); return false;">Tomorrow</a>
   </span>
 </div>
 </div>

commit 85f8259b61709c13c8c4d388b06d0802571c4265
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Thu Jan 14 18:14:59 2010 -0500

    Remove bps_util.js from JS list too

diff --git a/lib/Jifty/Web.pm b/lib/Jifty/Web.pm
index 561ba8b..5c25a8d 100644
--- a/lib/Jifty/Web.pm
+++ b/lib/Jifty/Web.pm
@@ -58,7 +58,6 @@ __PACKAGE__->javascript_libs([qw(
     combobox.js
     key_bindings.js
     context_menu.js
-    bps_util.js
     yui/yahoo.js
     yui/dom.js
     yui/event.js

commit 925eee7d47f5909be58086fa2a5b983bc449b57c
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Thu Jan 14 18:34:28 2010 -0500

    Remove JSAN usage and cleanup namespace

diff --git a/doc/js-refactor b/doc/js-refactor
index 09dabbf..4e45d66 100644
--- a/doc/js-refactor
+++ b/doc/js-refactor
@@ -2,4 +2,6 @@ bps_util.js
     focusElementById removed
     custom onload hook code removed
     buttonToLink, updateParentField, createCalendarLink, createDateTimeLink moved to Jifty.Utils
+
+removing JSAN usage wherever I can
     
diff --git a/share/web/static/js/context_menu.js b/share/web/static/js/context_menu.js
index 175134a..c191868 100644
--- a/share/web/static/js/context_menu.js
+++ b/share/web/static/js/context_menu.js
@@ -1,8 +1,6 @@
-JSAN.use("DOM.Events");
-
 if (typeof Jifty == "undefined") Jifty = { };
 
-function prepExpandButton(e) {
+function jifty_context_menu_prepExpandButton(e) {
     e.onmousedown = function() { this.onfocus = this.blur };
     e.onmouseup   = function() { this.onfocus = window.clientInformation ? null : window.undefined };
     e = null;	// Don't leak in IE
@@ -10,8 +8,8 @@ function prepExpandButton(e) {
 
 Jifty.ContextMenu = {
     behaviourRules: {
-        "ul.menu li.toplevel span.expand a": prepExpandButton,
-        "ul.context_menu li.toplevel span.expand a": prepExpandButton
+        "ul.menu li.toplevel span.expand a": jifty_context_menu_prepExpandButton,
+        "ul.context_menu li.toplevel span.expand a": jifty_context_menu_prepExpandButton
     },
 
     currently_open:  "",
@@ -106,6 +104,6 @@ Jifty.ContextMenu = {
     }
 };
 
-DOM.Events.addListener( document, "click", Jifty.ContextMenu.hideOpenMenu );
+jQuery(document).click( Jifty.ContextMenu.hideOpenMenu );
 Behaviour.register( Jifty.ContextMenu.behaviourRules );
 

commit 58b98c38c5211dea6fb86fc8d592bf5902ba476f
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Thu Jan 14 18:55:01 2010 -0500

    Add note for the future about CSS browser selection

diff --git a/share/web/static/js/css_browser_selector.js b/share/web/static/js/css_browser_selector.js
index 52cde04..a32899e 100644
--- a/share/web/static/js/css_browser_selector.js
+++ b/share/web/static/js/css_browser_selector.js
@@ -1,3 +1,9 @@
+/*
+ * XXX TODO JS
+ * This should be migrated to either Jifty's browser detection or jQuery's, but
+ * changing the class values has the potential to break existing CSS.
+ */
+
 // CSS Browser Selector   v0.4
 // Documentation:         http://rafael.adm.br/css_browser_selector
 // License:               http://creativecommons.org/licenses/by/2.5/
@@ -12,4 +18,4 @@ function css_browser_selector() {
 	else if(ua.indexOf('konqueror') != -1) h.className='konqueror';
 	else if(ua.indexOf('applewebkit/') != - 1) h.className='safari';
 }
-css_browser_selector();
\ No newline at end of file
+css_browser_selector();

commit 9a27a8054b78650039537c481768f2e6749be2a5
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Thu Jan 14 18:55:14 2010 -0500

    formatDate hasn't been used by calendar.js in 3yrs

diff --git a/doc/js-refactor b/doc/js-refactor
index 4e45d66..d455fa1 100644
--- a/doc/js-refactor
+++ b/doc/js-refactor
@@ -4,4 +4,13 @@ bps_util.js
     buttonToLink, updateParentField, createCalendarLink, createDateTimeLink moved to Jifty.Utils
 
 removing JSAN usage wherever I can
+
+
+
+What's left?
+
+grep 'XXX TODO JS'
+use DatePicker from jQuery UI instead of YUI
+    removes YUI calendar
+    most (all?) of our calendar handler JS
     
diff --git a/share/web/static/js/formatDate.js b/share/web/static/js/formatDate.js
deleted file mode 100644
index 58d443a..0000000
--- a/share/web/static/js/formatDate.js
+++ /dev/null
@@ -1,356 +0,0 @@
-// formatDate :
-// a PHP date like function, for formatting date strings
-// authored by Svend Tofte <www.svendtofte.com>
-// the code is in the public domain
-//
-// see http://www.svendtofte.com/code/date_format/
-// and http://www.php.net/date
-//
-// thanks to 
-//  - Daniel Berlin <mail at daniel-berlin.de>,
-//    major overhaul and improvements
-//  - Matt Bannon,
-//    correcting some stupid bugs in my days-in-the-months list!
-//
-// input : format string
-// time : epoch time (seconds, and optional)
-//
-// if time is not passed, formatting is based on 
-// the current "this" date object's set time.
-//
-// supported switches are
-// a, A, B, c, d, D, F, g, G, h, H, i, I (uppercase i), j, l (lowecase L), 
-// L, m, M, n, N, O, P, r, s, S, t, U, w, W, y, Y, z, Z
-// 
-// unsupported (as compared to date in PHP 5.1.3)
-// T, e, o
-
-Date.prototype.formatDate = function (input,time) {
-    
-    var daysLong =    ["Sunday", "Monday", "Tuesday", "Wednesday", 
-                       "Thursday", "Friday", "Saturday"];
-    var daysShort =   ["Sun", "Mon", "Tue", "Wed", 
-                       "Thu", "Fri", "Sat"];
-    var monthsShort = ["Jan", "Feb", "Mar", "Apr",
-                       "May", "Jun", "Jul", "Aug", "Sep",
-                       "Oct", "Nov", "Dec"];
-    var monthsLong =  ["January", "February", "March", "April",
-                       "May", "June", "July", "August", "September",
-                       "October", "November", "December"];
-
-    var switches = { // switches object
-        
-        a : function () {
-            // Lowercase Ante meridiem and Post meridiem
-            return date.getHours() > 11? "pm" : "am";
-        },
-        
-        A : function () {
-            // Uppercase Ante meridiem and Post meridiem
-            return (this.a().toUpperCase ());
-        },
-    
-        B : function (){
-            // Swatch internet time. code simply grabbed from ppk,
-            // since I was feeling lazy:
-            // http://www.xs4all.nl/~ppk/js/beat.html
-            var off = (date.getTimezoneOffset() + 60)*60;
-            var theSeconds = (date.getHours() * 3600) + 
-                             (date.getMinutes() * 60) + 
-                              date.getSeconds() + off;
-            var beat = Math.floor(theSeconds/86.4);
-            if (beat > 1000) beat -= 1000;
-            if (beat < 0) beat += 1000;
-            if ((String(beat)).length == 1) beat = "00"+beat;
-            if ((String(beat)).length == 2) beat = "0"+beat;
-            return beat;
-        },
-        
-        c : function () {
-            // ISO 8601 date (e.g.: "2004-02-12T15:19:21+00:00"), as per
-            // http://www.cl.cam.ac.uk/~mgk25/iso-time.html
-            return (this.Y() + "-" + this.m() + "-" + this.d() + "T" + 
-                    this.h() + ":" + this.i() + ":" + this.s() + this.P());
-        },
-        
-        d : function () {
-            // Day of the month, 2 digits with leading zeros
-            var j = String(this.j());
-            return (j.length == 1 ? "0"+j : j);
-        },
-        
-        D : function () {
-            // A textual representation of a day, three letters
-            return daysShort[date.getDay()];
-        },
-        
-        F : function () {
-            // A full textual representation of a month
-            return monthsLong[date.getMonth()];
-        },
-        
-        g : function () {
-            // 12-hour format of an hour without leading zeros
-            return date.getHours() > 12? date.getHours()-12 : date.getHours();
-        },
-        
-        G : function () {
-            // 24-hour format of an hour without leading zeros
-            return date.getHours();
-        },
-        
-        h : function () {
-            // 12-hour format of an hour with leading zeros
-            var g = String(this.g());
-            return (g.length == 1 ? "0"+g : g);
-        },
-        
-        H : function () {
-            // 24-hour format of an hour with leading zeros
-            var G = String(this.G());
-            return (G.length == 1 ? "0"+G : G);
-        },
-        
-        i : function () {
-            // Minutes with leading zeros
-            var min = String (date.getMinutes ());
-            return (min.length == 1 ? "0" + min : min);
-        },
-        
-        I : function () {
-            // Whether or not the date is in daylight saving time (DST)
-            // note that this has no bearing in actual DST mechanics,
-            // and is just a pure guess. buyer beware.
-            var noDST = new Date ("January 1 " + this.Y() + " 00:00:00");
-            return (noDST.getTimezoneOffset () == 
-                    date.getTimezoneOffset () ? 0 : 1);
-        },
-        
-        j : function () {
-            // Day of the month without leading zeros
-            return date.getDate();
-        },
-        
-        l : function () {
-            // A full textual representation of the day of the week
-            return daysLong[date.getDay()];
-        },
-        
-        L : function () {
-            // leap year or not. 1 if leap year, 0 if not.
-            // the logic should match iso's 8601 standard.
-            // http://www.uic.edu/depts/accc/software/isodates/leapyear.html
-            var Y = this.Y();
-            if (         
-                (Y % 4 == 0 && Y % 100 != 0) ||
-                (Y % 4 == 0 && Y % 100 == 0 && Y % 400 == 0)
-                ) {
-                return 1;
-            } else {
-                return 0;
-            }
-        },
-        
-        m : function () {
-            // Numeric representation of a month, with leading zeros
-            var n = String(this.n());
-            return (n.length == 1 ? "0"+n : n);
-        },
-        
-        M : function () {
-            // A short textual representation of a month, three letters
-            return monthsShort[date.getMonth()];
-        },
-        
-        n : function () {
-            // Numeric representation of a month, without leading zeros
-            return date.getMonth()+1;
-        },
-        
-        N : function () {
-            // ISO-8601 numeric representation of the day of the week
-            var w = this.w();
-            return (w == 0 ? 7 : w);
-        },
-        
-        O : function () {
-            // Difference to Greenwich time (GMT) in hours
-            var os = Math.abs(date.getTimezoneOffset());
-            var h = String(Math.floor(os/60));
-            var m = String(os%60);
-            h.length == 1? h = "0"+h:1;
-            m.length == 1? m = "0"+m:1;
-            return date.getTimezoneOffset() < 0 ? "+"+h+m : "-"+h+m;
-        },
-        
-        P : function () {
-            // Difference to GMT, with colon between hours and minutes
-            var O = this.O();
-            return (O.substr(0, 3) + ":" + O.substr(3, 2));
-        },      
-        
-        r : function () {
-            // RFC 822 formatted date
-            var r; // result
-            //  Thu         ,     21               Dec              2000
-            r = this.D() + ", " + this.d() + " " + this.M() + " " + this.Y() +
-            //    16          :    01          :    07               0200
-            " " + this.H() + ":" + this.i() + ":" + this.s() + " " + this.O();
-            return r;
-        },
-
-        s : function () {
-            // Seconds, with leading zeros
-            var sec = String (date.getSeconds ());
-            return (sec.length == 1 ? "0" + sec : sec);
-        },        
-        
-        S : function () {
-            // English ordinal suffix for the day of the month, 2 characters
-            switch (date.getDate ()) {
-                case  1: return ("st"); 
-                case  2: return ("nd"); 
-                case  3: return ("rd");
-                case 21: return ("st"); 
-                case 22: return ("nd"); 
-                case 23: return ("rd");
-                case 31: return ("st");
-                default: return ("th");
-            }
-        },
-        
-        t : function () {
-            // thanks to Matt Bannon for some much needed code-fixes here!
-            var daysinmonths = [null,31,28,31,30,31,30,31,31,30,31,30,31];
-            if (this.L()==1 && this.n()==2) return 29; // ~leap day
-            return daysinmonths[this.n()];
-        },
-        
-        U : function () {
-            // Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
-            return Math.round(date.getTime()/1000);
-        },
-
-        w : function () {
-            // Numeric representation of the day of the week
-            return date.getDay();
-        },
-        
-        W : function () {
-            // Weeknumber, as per ISO specification:
-            // http://www.cl.cam.ac.uk/~mgk25/iso-time.html
-        
-            var DoW = this.N ();
-            var DoY = this.z ();
-
-            // If the day is 3 days before New Year's Eve and is Thursday or earlier,
-            // it's week 1 of next year.
-            var daysToNY = 364 + this.L () - DoY;
-            if (daysToNY <= 2 && DoW <= (3 - daysToNY)) {
-                return 1;
-            }
-
-            // If the day is within 3 days after New Year's Eve and is Friday or later,
-            // it belongs to the old year.
-            if (DoY <= 2 && DoW >= 5) {
-                return new Date (this.Y () - 1, 11, 31).formatDate ("W");
-            }
-            
-            var nyDoW = new Date (this.Y (), 0, 1).getDay ();
-            nyDoW = nyDoW != 0 ? nyDoW - 1 : 6;
-
-            if (nyDoW <= 3) { // First day of the year is a Thursday or earlier
-                return (1 + Math.floor ((DoY + nyDoW) / 7));
-            } else {  // First day of the year is a Friday or later
-                return (1 + Math.floor ((DoY - (7 - nyDoW)) / 7));
-            }
-        },
-        
-        y : function () {
-            // A two-digit representation of a year
-            var y = String(this.Y());
-            return y.substring(y.length-2,y.length);
-        },        
-        
-        Y : function () {
-            // A full numeric representation of a year, 4 digits
-    
-            // we first check, if getFullYear is supported. if it
-            // is, we just use that. ppks code is nice, but wont
-            // work with dates outside 1900-2038, or something like that
-            if (date.getFullYear) {
-                var newDate = new Date("January 1 2001 00:00:00 +0000");
-                var x = newDate .getFullYear();
-                if (x == 2001) {              
-                    // i trust the method now
-                    return date.getFullYear();
-                }
-            }
-            // else, do this:
-            // codes thanks to ppk:
-            // http://www.xs4all.nl/~ppk/js/introdate.html
-            var x = date.getYear();
-            var y = x % 100;
-            y += (y < 38) ? 2000 : 1900;
-            return y;
-        },
-
-        
-        z : function () {
-            // The day of the year, zero indexed! 0 through 366
-            var t = new Date("January 1 " + this.Y() + " 00:00:00");
-            var diff = date.getTime() - t.getTime();
-            return Math.floor(diff/1000/60/60/24);
-        },
-
-        Z : function () {
-            // Timezone offset in seconds
-            return (date.getTimezoneOffset () * -60);
-        }        
-    
-    }
-
-    function getSwitch(str) {
-        if (switches[str] != undefined) {
-            return switches[str]();
-        } else {
-            return str;
-        }
-    }
-
-    var date;
-    if (time) {
-        var date = new Date (time);
-    } else {
-        var date = this;
-    }
-
-    var formatString = input.split("");
-    var i = 0;
-    while (i < formatString.length) {
-        if (formatString[i] == "\\") {
-            // this is our way of allowing users to escape stuff
-            formatString.splice(i,1);
-        } else {
-            formatString[i] = getSwitch(formatString[i]);
-        }
-        i++;
-    }
-    
-    return formatString.join("");
-}
-
-
-// Some (not all) predefined format strings from PHP 5.1.1, which 
-// offer standard date representations.
-// See: http://www.php.net/manual/en/ref.datetime.php#datetime.constants
-//
-
-// Atom      "2005-08-15T15:52:01+00:00"
-Date.DATE_ATOM    = "Y-m-d\\TH:i:sP";
-// ISO-8601  "2005-08-15T15:52:01+0000"
-Date.DATE_ISO8601 = "Y-m-d\\TH:i:sO";
-// RFC 2822  "Mon, 15 Aug 2005 15:52:01 +0000"
-Date.DATE_RFC2822 = "D, d M Y H:i:s O";
-// W3C       "2005-08-15T15:52:01+00:00"
-Date.DATE_W3C     = "Y-m-d\\TH:i:sP";

commit 3848dc8afe00668eee35bfe847a8e97db07db851
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Thu Jan 14 18:56:49 2010 -0500

    Add a note about future work

diff --git a/share/web/static/js/halo.js b/share/web/static/js/halo.js
index 611fe9d..7b2fec7 100644
--- a/share/web/static/js/halo.js
+++ b/share/web/static/js/halo.js
@@ -1,3 +1,5 @@
+/* XXX TODO JS: move into Jifty.Halos rather than global */
+
 var halo_shown = null;
 var halos_drawn = null;
 

commit dc85afcf2506ece9da59f3c1f779bc3b849fd731
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Thu Jan 14 19:03:43 2010 -0500

    chmod a-x *.js

diff --git a/share/web/static/js/iautocompleter.js b/share/web/static/js/iautocompleter.js
old mode 100755
new mode 100644
diff --git a/share/web/static/js/iutil.js b/share/web/static/js/iutil.js
old mode 100755
new mode 100644
diff --git a/share/web/static/js/jquery.jgrowl.js b/share/web/static/js/jquery.jgrowl.js
old mode 100755
new mode 100644
diff --git a/share/web/static/js/jquery.timepickr.js b/share/web/static/js/jquery.timepickr.js
old mode 100755
new mode 100644

commit bae815253fbc4c1483c142fc637a74d335bcb461
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Thu Jan 14 19:06:59 2010 -0500

    Doc updates

diff --git a/doc/js-refactor b/doc/js-refactor
index d455fa1..956a74c 100644
--- a/doc/js-refactor
+++ b/doc/js-refactor
@@ -5,12 +5,21 @@ bps_util.js
 
 removing JSAN usage wherever I can
 
+formatDate not used in the last 3 years
 
 
-What's left?
+
+=== What's left?
 
 grep 'XXX TODO JS'
 use DatePicker from jQuery UI instead of YUI
     removes YUI calendar
     most (all?) of our calendar handler JS
-    
+
+update libraries
+    jQuery
+    iAutocompleter (and iUtil)
+
+jQuery 1.4
+    http://jquery14.com/day-01/jquery-14#backwards
+    we can replace css_browser_selector and our own browser stuff with jQuery.browser now

commit 8ba7bc45b37f8705a190763542c245ca024461e0
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Thu Jan 14 19:28:35 2010 -0500

    Update js refactor docs

diff --git a/doc/js-refactor b/doc/js-refactor
index 956a74c..080e7b8 100644
--- a/doc/js-refactor
+++ b/doc/js-refactor
@@ -12,10 +12,14 @@ formatDate not used in the last 3 years
 === What's left?
 
 grep 'XXX TODO JS'
+
 use DatePicker from jQuery UI instead of YUI
     removes YUI calendar
     most (all?) of our calendar handler JS
 
+Jifty.Utils has a bunch of methods probably redundant with those in jQuery, but
+we need to check compat with what uses them
+
 update libraries
     jQuery
     iAutocompleter (and iUtil)

commit 5a47db20ccff2ad4b279474b703785ad6424ed70
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Thu Jan 14 19:41:37 2010 -0500

    Remove JSAN usage from key bindings JS

diff --git a/share/web/static/js/key_bindings.js b/share/web/static/js/key_bindings.js
index 0c62c53..7f5e199 100644
--- a/share/web/static/js/key_bindings.js
+++ b/share/web/static/js/key_bindings.js
@@ -1,27 +1,23 @@
-// Copyright 2004-2006, Best Practical Solutions, LLC
+// Copyright 2004-2010, Best Practical Solutions, LLC
 // This Library is licensed to you under the same terms as Perl 5.x
 
-JSAN.use("DOM.Events");
-
 if ( typeof Jifty == "undefined" ) Jifty = {};
 
 Jifty.KeyBindings = {
     bindings: new Array(),
-    listener: null,
+    listener: false,
 
     activate: function() {
         if ( Jifty.KeyBindings.listener )
             return;
         
-        Jifty.KeyBindings.listener = DOM.Events.addListener(
-                                        document,
-                                        "keydown",
-                                        Jifty.KeyBindings.doClick
-                                     );
+        jQuery(document).keydown( Jifty.KeyBindings.doClick );
+        Jifty.KeyBindings.listener = true;
     },
 
     deactivate: function() {
-        DOM.Events.removeListener(Jifty.KeyBindings.listener);
+        jQuery(document).unbind( "keydown", Jifty.KeyBindings.doClick );
+        Jifty.KeyBindings.listener = false;
     },
 
     reset: function() {

commit 034ea91d49db3a079f4d7791266e64141bd7c71b
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Thu Jan 14 20:15:52 2010 -0500

    Remove JSAN core and now-unused libs

diff --git a/doc/js-refactor b/doc/js-refactor
index 080e7b8..fd1e23e 100644
--- a/doc/js-refactor
+++ b/doc/js-refactor
@@ -4,11 +4,11 @@ bps_util.js
     buttonToLink, updateParentField, createCalendarLink, createDateTimeLink moved to Jifty.Utils
 
 removing JSAN usage wherever I can
+removing JSAN core and now-unused libraries
 
 formatDate not used in the last 3 years
 
 
-
 === What's left?
 
 grep 'XXX TODO JS'
@@ -27,3 +27,11 @@ update libraries
 jQuery 1.4
     http://jquery14.com/day-01/jquery-14#backwards
     we can replace css_browser_selector and our own browser stuff with jQuery.browser now
+
+
+=== Unused (but still useful??)
+
+DUBIOUS - rico.js - not even the full library, just corner rounding, and
+                    hacked ones at that
+
+UNCLEAR - jsTrace.js
diff --git a/lib/Jifty/View/Static/Handler.pm b/lib/Jifty/View/Static/Handler.pm
index 8023737..a590de1 100644
--- a/lib/Jifty/View/Static/Handler.pm
+++ b/lib/Jifty/View/Static/Handler.pm
@@ -184,10 +184,6 @@ sub mime_type {
 
     # The key is the file extension, the value is the MIME type to send.
     my %type_override = (
-        # MIME::Types returns application/javascript for .js, but Opera
-        # chokes on ajax-fetched JS that has a type other than the one below
-        # JSAN.js fetches JS via Ajax when it loads JSAN modules
-        'js'   => 'application/x-javascript',
         'json' => 'application/json; charset=UTF-8',
         'htc'  => 'text/x-component',
     );
diff --git a/lib/Jifty/Web.pm b/lib/Jifty/Web.pm
index 5c25a8d..bcbed54 100644
--- a/lib/Jifty/Web.pm
+++ b/lib/Jifty/Web.pm
@@ -32,11 +32,6 @@ __PACKAGE__->css_files([qw( main.css )]);
 __PACKAGE__->external_javascript_libs([]);
 
 __PACKAGE__->javascript_libs([qw(
-    jsan/JSAN.js
-    jsan/Push.js
-    setup_jsan.js
-    jsan/Upgrade/Array/push.js
-    jsan/DOM/Events.js
     json.js
     jquery-1.2.6.js
     iutil.js
diff --git a/share/web/static/js/jifty_subs.js b/share/web/static/js/jifty_subs.js
index 1e06fce..ca92657 100644
--- a/share/web/static/js/jifty_subs.js
+++ b/share/web/static/js/jifty_subs.js
@@ -37,7 +37,7 @@ if (typeof Jifty == "undefined") Jifty = { };
 
     
     /* This function constructs a new Jifty.Subs object and sets
-    up a callback with HTTP.Push to run our onPushHandler each time
+    up a callback with jQuery.ajax to run our onPushHandler each time
     a new element is added to the hidden iframe's body.
 
     We could instead say "sets up our transport. every time the
diff --git a/share/web/static/js/jsan/DOM/Events.js b/share/web/static/js/jsan/DOM/Events.js
deleted file mode 100644
index a0324eb..0000000
--- a/share/web/static/js/jsan/DOM/Events.js
+++ /dev/null
@@ -1,262 +0,0 @@
-/**
-
-=head1 NAME
-
-DOM.Events - Event registration abstraction layer
-
-=head1 SYNOPSIS
-
-  JSAN.use("DOM.Events");
-
-  function handleClick(e) {
-      e.currentTarget.style.backgroundColor = "#68b";
-  }
-
-  DOM.Events.addListener(window, "load", function () {
-      alert("The page is loaded.");
-  });
-
-  DOM.Events.addListener(window, "load", function () {
-      // this listener won't interfere with the first one
-      var divs = document.getElementsByTagName("div");
-      for(var i=0; i<divs.length; i++) {
-          DOM.Events.addListener(divs[i], "click", handleClick);
-      }
-  });
-
-=head1 DESCRIPTION
-
-This library lets you use a single interface to listen for and handle all DOM events
-to reduce browser-specific code branching.  It also helps in dealing with Internet
-Explorer's memory leak problem by automatically unsetting all event listeners when
-the page is unloaded (for IE only).
-
-=cut
-
-*/
-
-(function () {
-	if(typeof DOM == "undefined") DOM = {};
-	DOM.Events = {};
-	
-    DOM.Events.VERSION = "0.02";
-	DOM.Events.EXPORT = [];
-	DOM.Events.EXPORT_OK = ["addListener", "removeListener"];
-	DOM.Events.EXPORT_TAGS = {
-		":common": DOM.Events.EXPORT,
-		":all": [].concat(DOM.Events.EXPORT, DOM.Events.EXPORT_OK)
-	};
-	
-	// list of event listeners set by addListener
-	// offset 0 is null to prevent 0 from being used as a listener identifier
-	var listenerList = [null];
-	
-/**
-
-=head2 Functions
-
-All functions are kept inside the namespace C<DOM.Events> and aren't exported
-automatically.
-
-=head3 addListener( S<I<HTMLElement> element,> S<I<string> eventType,>
-S<I<Function> handler> S<[, I<boolean> makeCompatible = true] )>
-
-Registers an event listener/handler on an element.  The C<eventType> string should
-I<not> be prefixed with "on" (e.g. "mouseover" not "onmouseover"). If C<makeCompatible>
-is C<true> (the default), the handler is put inside a wrapper that lets you handle the
-events using parts of the DOM Level 2 Events model, even in Internet Explorer (and
-behave-alikes). Specifically:
-
-=over
-
-=item *
-
-The event object is passed as the first argument to the event handler, so you don't
-have to access it through C<window.event>.
-
-=item *
-
-The event object has the properties C<target>, C<currentTarget>, and C<relatedTarget>
-and the methods C<preventDefault()> and C<stopPropagation()> that behave as described
-in the DOM Level 2 Events specification (for the most part).
-
-=item *
-
-If possible, the event object for mouse events will have the properties C<pageX> and
-C<pageY> that contain the mouse's position relative to the document at the time the
-event occurred.
-
-=item *
-
-If you attempt to set a duplicate event handler on an element, the duplicate will
-still be added (this is different from the DOM2 Events model, where duplicates are
-discarded).
-
-=back
-
-If C<makeCompatible> is C<false>, the arguments are simply passed to the browser's
-native event registering facilities, which means you'll have to deal with event
-incompatibilities yourself. However, if you don't need to access the event information,
-doing it this way can be slightly faster and it gives you the option of unsetting the
-handler with a different syntax (see below).
-
-The return value is a positive integer identifier for the listener that can be used to
-unregister it later on in your script.
-
-=cut
-
-*/
-    
-	DOM.Events.addListener = function(elt, ev, func, makeCompatible) {
-		var usedFunc = func;
-        var id = listenerList.length;
-		if(makeCompatible == true || makeCompatible == undefined) {
-			usedFunc = makeCompatibilityWrapper(elt, ev, func);
-		}
-		if(elt.addEventListener) {
-			elt.addEventListener(ev, usedFunc, false);
-			listenerList[id] = [elt, ev, usedFunc];
-			return id;
-		}
-		else if(elt.attachEvent) {
-			elt.attachEvent("on" + ev, usedFunc);
-			listenerList[id] = [elt, ev, usedFunc];
-			return id;
-		}
-		else return false;
-	};
-	
-/**
-
-=head3 removeListener( S<I<integer> identifier> )
-
-Unregisters the event listener associated with the given identifier so that it will
-no longer be called when the event fires.
-
-  var listener = DOM.Events.addListener(myElement, "mousedown", myHandler);
-  // later on ...
-  DOM.Events.removeListener(listener);
-
-=head3 removeListener( S<I<HTMLElement> element,> S<I<string> eventType,> S<I<Function> handler )>
-
-This alternative syntax can be also be used to unset an event listener, but it can only
-be used if C<makeCompatible> was C<false> when it was set.
-
-=cut
-
-*/
-
-	DOM.Events.removeListener = function() {
-		var elt, ev, func;
-		if(arguments.length == 1 && listenerList[arguments[0]]) {
-			elt  = listenerList[arguments[0]][0];
-			ev   = listenerList[arguments[0]][1];
-			func = listenerList[arguments[0]][2];
-			delete listenerList[arguments[0]];
-		}
-		else if(arguments.length == 3) {
-			elt  = arguments[0];
-			ev   = arguments[1];
-			func = arguments[2];
-		}
-		else return;
-		
-		if(elt.removeEventListener) {
-			elt.removeEventListener(ev, func, false);
-		}
-		else if(elt.detachEvent) {
-			elt.detachEvent("on" + ev, func);
-		}
-	};
-	
-    var rval;
-    
-    function makeCompatibilityWrapper(elt, ev, func) {
-        return function (e) {
-            rval = true;
-            if(e == undefined && window.event != undefined)
-                e = window.event;
-            if(e.target == undefined && e.srcElement != undefined)
-                e.target = e.srcElement;
-            if(e.currentTarget == undefined)
-                e.currentTarget = elt;
-            if(e.relatedTarget == undefined) {
-                if(ev == "mouseover" && e.fromElement != undefined)
-                    e.relatedTarget = e.fromElement;
-                else if(ev == "mouseout" && e.toElement != undefined)
-                    e.relatedTarget = e.toElement;
-            }
-            if(e.pageX == undefined) {
-                if(document.body.scrollTop != undefined) {
-                    e.pageX = e.clientX + document.body.scrollLeft;
-                    e.pageY = e.clientY + document.body.scrollTop;
-                }
-                if(document.documentElement != undefined
-                && document.documentElement.scrollTop != undefined) {
-                    if(document.documentElement.scrollTop > 0
-                    || document.documentElement.scrollLeft > 0) {
-                        e.pageX = e.clientX + document.documentElement.scrollLeft;
-                        e.pageY = e.clientY + document.documentElement.scrollTop;
-                    }
-                }
-            }
-            if(e.stopPropagation == undefined)
-                e.stopPropagation = IEStopPropagation;
-            if(e.preventDefault == undefined)
-                e.preventDefault = IEPreventDefault;
-            if(e.cancelable == undefined) e.cancelable = true;
-            func(e);
-            return rval;
-        };
-    }
-    
-    function IEStopPropagation() {
-        if(window.event) window.event.cancelBubble = true;
-    }
-    
-    function IEPreventDefault() {
-        rval = false;
-    }
-
-	function cleanUpIE () {
-		for(var i=0; i<listenerList.length; i++) {
-			var listener = listenerList[i];
-			if(listener) {
-				var elt = listener[0];
-                var ev = listener[1];
-                var func = listener[2];
-				elt.detachEvent("on" + ev, func);
-			}
-		}
-        listenerList = null;
-	}
-
-	if(!window.addEventListener && window.attachEvent) {
-		window.attachEvent("onunload", cleanUpIE);
-	}
-
-})();
-
-/**
-
-=head1 SEE ALSO
-
-DOM Level 2 Events Specification,
-L<http://www.w3.org/TR/DOM-Level-2-Events/>
-
-Understanding and Solving Internet Explorer Leak Patterns,
-L<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol/dnwebgen/ie_leak_patterns.asp>
-
-=head1 AUTHOR
-
-Justin Constantino, <F<goflyapig at gmail.com>>.
-
-=head1 COPYRIGHT
-
-  Copyright (c) 2005 Justin Constantino.  All rights reserved.
-  This module is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public Licence.
-
-=cut
-
-*/
\ No newline at end of file
diff --git a/share/web/static/js/jsan/JSAN.js b/share/web/static/js/jsan/JSAN.js
deleted file mode 100644
index 4b6c0bd..0000000
--- a/share/web/static/js/jsan/JSAN.js
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * This is not a stock JSAN.js.  To increase browser compatibility,
- * s/'/"/g has been applied to the file and the range of valid response
- * codes for JSAN.Request has been expanded (lifted from Prototype, in
- * fact).
- */
-
-/*
-
-*/
-
-var JSAN = function () { JSAN.addRepository(arguments) };
-
-JSAN.VERSION = "0.10-jifty2";
-
-/*
-
-*/
-
-JSAN.globalScope   = self;
-JSAN.includePath   = [".", "lib"];
-JSAN.errorLevel    = "none";
-JSAN.errorMessage  = "";
-JSAN.loaded        = {};
-
-/*
-
-*/
-
-JSAN.use = function () {
-    var classdef = JSAN.require(arguments[0]);
-    if (!classdef) return null;
-
-    var importList = JSAN._parseUseArgs.apply(JSAN, arguments).importList;
-    JSAN.exporter(classdef, importList);
-
-    return classdef;
-}
-
-/*
-
-*/
-
-JSAN.require = function (pkg) {
-    var path = JSAN._convertPackageToPath(pkg);
-    if (JSAN.loaded[path]) {
-        return JSAN.loaded[path];
-    }
-
-    try {
-        var classdef = eval(pkg);
-        if (typeof classdef != "undefined") return classdef;
-    } catch (e) { /* nice try, eh? */ }
-
-
-    for (var i = 0; i < JSAN.includePath.length; i++) {
-        var js;
-        try{
-            var url = JSAN._convertPathToUrl(path, JSAN.includePath[i]);
-                js  = JSAN._loadJSFromUrl(url);
-        } catch (e) {
-            if (i == JSAN.includePath.length - 1) throw e;
-        }
-        if (js != null) {
-            var classdef = JSAN._createScript(js, pkg);
-            JSAN.loaded[path] = classdef;
-            return classdef;
-        }
-    }
-    return false;
-
-}
-
-/*
-
-*/
-
-JSAN.exporter = function () {
-    JSAN._exportItems.apply(JSAN, arguments);
-}
-
-/*
-
-*/
-
-JSAN.addRepository = function () {
-    var temp = JSAN._flatten( arguments );
-    // Need to go in reverse to do something as simple as unshift( @foo, @_ );
-    for ( var i = temp.length - 1; i >= 0; i-- )
-        JSAN.includePath.unshift(temp[i]);
-    return JSAN;
-}
-
-JSAN._flatten = function( list1 ) {
-    var list2 = new Array();
-    for ( var i = 0; i < list1.length; i++ ) {
-        if ( typeof list1[i] == "object" ) {
-            list2 = JSAN._flatten( list1[i], list2 );
-        }
-        else {
-            list2.push( list1[i] );
-        }
-    }
-    return list2;
-};
-
-JSAN._findMyPath = function () {
-    if (document) {
-        var scripts = document.getElementsByTagName("script");
-        for ( var i = 0; i < scripts.length; i++ ) {
-            var src = scripts[i].getAttribute("src");
-            if (src) {
-                var inc = src.match(/^(.*?)\/?JSAN.js/);
-                if (inc && inc[1]) {
-                    var repo = inc[1];
-                    for (var j = 0; j < JSAN.includePath.length; j++) {
-                        if (JSAN.includePath[j] == repo) {
-                            return;
-                        }
-                    }
-                    JSAN.addRepository(repo);
-                }
-            }
-        }
-    }
-}
-JSAN._findMyPath();
-
-JSAN._convertPathToUrl = function (path, repository) {
-    return repository.concat("/" + path);
-};
-    
-
-JSAN._convertPackageToPath = function (pkg) {
-    var path = pkg.replace(/\./g, "/");
-        path = path.concat(".js");
-    return path;
-}
-
-JSAN._parseUseArgs = function () {
-    var pkg        = arguments[0];
-    var importList = [];
-
-    for (var i = 1; i < arguments.length; i++)
-        importList.push(arguments[i]);
-
-    return {
-        pkg:        pkg,
-        importList: importList
-    }
-}
-
-JSAN._loadJSFromUrl = function (url) {
-    return new JSAN.Request().getText(url);
-}
-
-JSAN._findExportInList = function (list, request) {
-    if (list == null) return false;
-    for (var i = 0; i < list.length; i++)
-        if (list[i] == request)
-            return true;
-    return false;
-}
-
-JSAN._findExportInTag = function (tags, request) {
-    if (tags == null) return [];
-    for (var i in tags)
-        if (i == request)
-            return tags[i];
-    return [];
-}
-
-JSAN._exportItems = function (classdef, importList) {
-    var exportList  = new Array();
-    var EXPORT      = classdef.EXPORT;
-    var EXPORT_OK   = classdef.EXPORT_OK;
-    var EXPORT_TAGS = classdef.EXPORT_TAGS;
-    
-    if (importList.length > 0) {
-       importList = JSAN._flatten( importList );
-
-       for (var i = 0; i < importList.length; i++) {
-            var request = importList[i];
-            if (   JSAN._findExportInList(EXPORT,    request)
-                || JSAN._findExportInList(EXPORT_OK, request)) {
-                exportList.push(request);
-                continue;
-            }
-            var list = JSAN._findExportInTag(EXPORT_TAGS, request);
-            for (var i = 0; i < list.length; i++) {
-                exportList.push(list[i]);
-            }
-        }
-    } else {
-        exportList = EXPORT;
-    }
-    JSAN._exportList(classdef, exportList);
-}
-
-JSAN._exportList = function (classdef, exportList) {
-    if (typeof(exportList) != "object") return null;
-    for (var i = 0; i < exportList.length; i++) {
-        var name = exportList[i];
-
-        if (JSAN.globalScope[name] == null)
-            JSAN.globalScope[name] = classdef[name];
-    }
-}
-
-JSAN._makeNamespace = function(js, pkg) {
-    var spaces = pkg.split(".");
-    var parent = JSAN.globalScope;
-    eval(js);
-    var classdef = eval(pkg);
-    for (var i = 0; i < spaces.length; i++) {
-        var name = spaces[i];
-        if (i == spaces.length - 1) {
-            if (typeof parent[name] == "undefined") {
-                parent[name] = classdef;
-                if ( typeof classdef["prototype"] != "undefined" ) {
-                    parent[name].prototype = classdef.prototype;
-                }
-            }
-        } else {
-            if (parent[name] == undefined) {
-                parent[name] = {};
-            }
-        }
-
-        parent = parent[name];
-    }
-    return classdef;
-}
-
-JSAN._handleError = function (msg, level) {
-    if (!level) level = JSAN.errorLevel;
-    JSAN.errorMessage = msg;
-
-    switch (level) {
-        case "none":
-            break;
-        case "warn":
-            alert(msg);
-            break;
-        case "die":
-        default:
-            throw new Error(msg);
-            break;
-    }
-}
-
-JSAN._createScript = function (js, pkg) {
-    try {
-        return JSAN._makeNamespace(js, pkg);
-    } catch (e) {
-        JSAN._handleError("Could not create namespace[" + pkg + "]: " + e);
-    }
-    return null;
-}
-
-
-JSAN.prototype = {
-    use: function () { JSAN.use.apply(JSAN, arguments) }
-};
-
-
-// Low-Level HTTP Request
-JSAN.Request = function (jsan) {
-    if (JSAN.globalScope.XMLHttpRequest) {
-        this._req = new XMLHttpRequest();
-    } else {
-        this._req = new ActiveXObject("Microsoft.XMLHTTP");
-    }
-}
-
-JSAN.Request.prototype = {
-    _req:  null,
-    
-    getText: function (url) {
-        this._req.open("GET", url, false);
-        try {
-            this._req.send(null);
-            if ( this.responseIsSuccess() )
-                return this._req.responseText;
-        } catch (e) {
-            JSAN._handleError("File not found: " + url);
-            return null;
-        };
-
-        JSAN._handleError("File not found: " + url);
-        return null;
-    },
-
-    responseIsSuccess: function() {
-        return this._req.status == undefined
-            || this._req.status == 0
-            || (this._req.status >= 200 && this._req.status < 300);
-    }
-};
-
-/*
-
-*/
diff --git a/share/web/static/js/jsan/Push.js b/share/web/static/js/jsan/Push.js
deleted file mode 100644
index 6bfdc59..0000000
--- a/share/web/static/js/jsan/Push.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-
-*/
-
-if (typeof(HTTP) == "undefined") { HTTP = {}; }
-
-HTTP.Push = {};
-HTTP.Push.VERSION = '0.04';
-
-/*
-
-*/
-
-HTTP.Push = function(args) {
-  if (args == undefined) { throw "Push must be passed an argument hash!"; }
-  if (args.uri == undefined) { throw "Must specify push URI!"; }
-  if (args.onPush == undefined) { throw "Must specify onPush handler!"; }
-  if (args.interval == undefined) { args.interval = 100; }
-
-
-  var body = document.getElementsByTagName("body")[0];
-  var iframe = document.createElement("iframe");
-  iframe.style.border = "0px";
-  iframe.style.height = "0px";
-  iframe.style.width = "0px";
-  iframe.src = args.uri;
-
-  var interval = undefined;
-
-/*
-
-*/
-
-  this.start = function() {
-    body.appendChild(iframe);
-    interval = setInterval(function() { flushIframe(); }, args.interval);
-  }
-
-
-// TODO: make the stop function work in IE
-//   this.stop = function() {
-//     body.removeChild(iframe);
-//     clearInterval(interval);
-//   }
-
-
-  function flushIframe() {
-    var doc;
-    if (iframe.contentDocument) {          // For NS6
-      doc = iframe.contentDocument;
-    } else if (iframe.contentWindow) {     // For IE5.5 and IE6
-      doc = iframe.contentWindow.document;
-    } else if (iframe.document) {          // For IE5
-      doc = iframe.document;
-    } else {
-      return;
-    }
-  
-    var body = doc.body;
-  
-    while (body && body.hasChildNodes()) {
-      var node = body.firstChild;
-      try {
-         args.onPush(node);
-      }
-      catch (e) { };
-      body.removeChild(node);
-    }
-  }
-
-  return this;
-}
-
-/*
-
-*/
diff --git a/share/web/static/js/jsan/Upgrade.js b/share/web/static/js/jsan/Upgrade.js
deleted file mode 100644
index 7474555..0000000
--- a/share/web/static/js/jsan/Upgrade.js
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
-Keep package scanners happy
-Upgrade.VERSION = 0.04;
-*/
-
-/*
-
-=head1 NAME
-
-Upgrade - Upgrade older JavaScript implementations to support newer features
-
-=head1 SYNOPSIS
-
-  // Upgrade Array.push if the client does not have it
-  JSAN.use("Upgrade.Array.push");
-
-=head1 DESCRIPTION
-
-Many many different JavaScript toolkits start with something like the following:
-
-  // Provides Array.push for implementations that don't have it
-  if ( ! Array.prototype.push ) {
-      Array.prototype.push = function () {
-          var l = this.length;
-          for ( var i = 0; i < arguments.length; i++ ) {
-              this[l+i] = arguments[i];
-          }
-          return this.length;
-      }
-  }
-
-These provide implementations of expected or required functions/classes
-for older JavaScript implementations that do not provide them natively,
-in effect "upgrading" the client at run-time.
-
-In fact, due to its flexibility JavaScript is a language ideally suited
-to this sort of behaviour.
-
-C<Upgrade> is a JSAN package that provides standard implementations for
-many of these standard functions. If your code relies on a particular
-function that you later find to be not as common as you might have
-initially thought, you can simply add a dependency on that function within
-the C<Upgrade> namespace, and if an implementation exists the standard code
-to implement it will be added it the current environment (when it doesn't
-already have it).
-
-Rather than one huge file that provides a "compatibility layer" and upgrades
-verything all at once, C<Upgrade> is broken down into a large number of
-maller .js files, each implementing one function or class.
-
-Generally these functions are ones defined in the ECMA standard, and those
-that aren't, such as C<HTMLHttpRequest> are not provided by Upgrade (as much
-as we would like to) :)
-
-=head1 USING UPGRADE
-
-The C<Upgrade> namespace acts as a parallel root to the global namespace.
-For any function you want to upgrade, you can then simply prepend
-C<"Upgrade"> to it.
-
-For example, to do the very common upgrade for the C<Array.push> function,
-you simply add C<JSAN.use("Upgrade.Array.push") to your module (or manually
-load the C<Upgrade/Array/push.js> file).
-
-One advantage of using these standard implementations rather than your own
-is that when a number of modules with C<Upgrade> depedencies are merged
-together by C<JSAN::Concat> or another package merger it results in only
-a single copy of the upgrading code at the appropriate place in the code.
-
-=head1 UPGRADABLE FUNCTIONS
-
-While implementations are provided seperately, rather than document them
-this way we will instead defined all functions available in the C<Upgrade>
-package here.
-
-=head2 Upgrade.Array.push
-
-This provides the same standard implementation of the instance method
-C<Array.push> (located at Array.prototype.push) as used by all of the
-major frameworks.
-
-=head2 Upgrade.Function.apply
-
-This provides a version of the instance method C<Function.apply>
-(located at C<Function.prototype.apply>) adapted from an implementation
-found in the L<Prototype> framework, which was itself adapted from an
-implementation found on L<http://www.youngpup.net/>.
-
-=head1 METHODS
-
-The C<Upgrade> module itself does not at this time provide any
-functionality, and only acts as a source of documentation.
-
-Likewise, nothing is ever actually created at or beneath the C<Upgrade>
-namespace, but serves as an address mechanism for determining which
-.js files to load. Each of these files only inserts functions into the
-core tree and do not create any additional useless namespace variables.
-
-=head1 SUPPORT
-
-Until the JSAN RT gains package-specific queues, bugs or new functions
-to add to Upgrade should be reported to the jsan-authors mailing list.
-
-For B<non-support> issues or questions, contact the author.
-
-=head1 AUTHOR
-
-Adam Kennedy <jsan at ali.as>, L<http://ali.as/>
-
-=head1 COPYRIGHT
-
-Copyright (c) 2005 Adam Kennedy. All rights reserved.
-This program is free software; you can redistribute it and/or modify
-it under the the terms of the Perl dual GPL/Artistic license.
-
-The full text of the license can be found in the
-LICENSE file included with this package
-
-=cut
-
-*/
diff --git a/share/web/static/js/jsan/Upgrade/Array/push.js b/share/web/static/js/jsan/Upgrade/Array/push.js
deleted file mode 100644
index bd93c6f..0000000
--- a/share/web/static/js/jsan/Upgrade/Array/push.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
-Upgrade.Array.push.VERSION = 0.04;
-*/
-
-// Provides Array.push for implementations that don't have it
-if ( ! Array.prototype.push ) {
-	Array.prototype.push = function () {
-		var l = this.length;
-		for ( var i = 0; i < arguments.length; i++ ) {
-			this[l+i] = arguments[i];
-		}
-		return this.length;
-	}
-}
diff --git a/share/web/static/js/jsan/Upgrade/Function/apply.js b/share/web/static/js/jsan/Upgrade/Function/apply.js
deleted file mode 100644
index 8d41590..0000000
--- a/share/web/static/js/jsan/Upgrade/Function/apply.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-Upgrade.Function.Apply.VERSION = 0.04;
-*/
-// Adapted from a Prototype adaptation of code
-// originally from http://www.youngpup.net/
-if ( ! Function.prototype.apply ) {
-	Function.prototype.apply = function(o, p) {
-		var pstr = new Array();
-		if ( ! o ) o = window;
-		if ( ! p ) p = new Array();
-		for ( var i = 0; i < p.length; i++ ) {
-			pstr[i] = 'p[' + i + ']';
-		}
-    		o.__apply__ = this;
-		var rv = eval('o.__apply__(' + pstr[i].join(', ') + ')' );
-		o.__apply__ = null;
-		return rv;
-	}
-}
diff --git a/share/web/static/js/setup_jsan.js b/share/web/static/js/setup_jsan.js
deleted file mode 100644
index 08c0aa0..0000000
--- a/share/web/static/js/setup_jsan.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Setup JSAN for Jifty defaults */
-JSAN.includePath = [ "/static/js/jsan" ];
-JSAN.errorLevel  = "none";
-
-/*
- * Stub out JSAN.use to avoid Ajax loading of JSAN libs if they've
- * already been loaded by a <script> tag
- */
-JSAN._use = JSAN.use;
-JSAN.use  = function() {
-    if ( !arguments[0] ) JSAN._use(arguments);
-};
-

commit 72cb1ffe8110ff103022c40c76a0c5a093bc17f6
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Thu Jan 14 21:48:00 2010 -0500

    Support generating CSS/JS at start rather than the first request

diff --git a/lib/Jifty/Plugin/CompressedCSSandJS.pm b/lib/Jifty/Plugin/CompressedCSSandJS.pm
index aafcb69..1a8d190 100644
--- a/lib/Jifty/Plugin/CompressedCSSandJS.pm
+++ b/lib/Jifty/Plugin/CompressedCSSandJS.pm
@@ -24,6 +24,7 @@ Jifty::Plugin::CompressedCSSandJS - Compression of CSS and javascript files
         gzip: 1
         skipped_js:
             - complex.js
+        generate_early: 1
 
 
 =head1 DESCRIPTION
@@ -45,9 +46,14 @@ indicates it supports that feature.
 
 skipped_js is a list of js that you don't want to compress for some reason.
 
+generate_early tells the plugin to compress the CSS and JS at process start
+rather than on the first request.  This can save time, especially if your
+JS minifier is slow, for the poor sucker who makes the first request.  Enabled
+by default.
+
 =cut
 
-__PACKAGE__->mk_accessors(qw(css js jsmin cdn gzip_enabled skipped_js));
+__PACKAGE__->mk_accessors(qw(css js jsmin cdn gzip_enabled skipped_js generate_early));
 
 =head2 init
 
@@ -67,18 +73,27 @@ sub init {
     $self->js( $opt{js} );
     $self->jsmin( $opt{jsmin} );
     $self->cdn( $opt{cdn} || '');
+    $self->generate_early( exists $opt{generate_early} ? $opt{generate_early} : 1 );
+
+    if ( $self->js_enabled ) {
+        Jifty::Web->add_trigger(
+            name      => 'include_javascript',
+            callback  => sub { $self->_include_javascript(@_) },
+            abortable => 1,
+        );
+        Jifty->add_trigger( post_init => sub { $self->_generate_javascript })
+            if $self->generate_early;
+    }
 
-    Jifty::Web->add_trigger(
-        name      => 'include_javascript',
-        callback  => sub { $self->_include_javascript(@_) },
-        abortable => 1,
-    ) if $self->js_enabled;
-
-    Jifty::Web->add_trigger(
-        name => 'include_css',
-        callback => sub { $self->_include_css(@_) },
-        abortable => 1,
-    ) if $self->css_enabled;
+    if ( $self->css_enabled ) {
+        Jifty::Web->add_trigger(
+            name => 'include_css',
+            callback => sub { $self->_include_css(@_) },
+            abortable => 1,
+        );
+        Jifty->add_trigger( post_init => sub { $self->generate_css })
+            if $self->generate_early;
+    }
 }
 
 =head2 js_enabled

commit 1d32bfc0dc54c090395e83b5041af9dc0bb84ecb
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Fri Jan 15 14:35:30 2010 -0500

    Remove all traces of formatDate.js

diff --git a/lib/Jifty/Web.pm b/lib/Jifty/Web.pm
index bcbed54..b7ce9b5 100644
--- a/lib/Jifty/Web.pm
+++ b/lib/Jifty/Web.pm
@@ -41,7 +41,6 @@ __PACKAGE__->javascript_libs([qw(
     jquery.jgrowl.js
     facebox.js
     behaviour.js
-    formatDate.js
     jifty.js
     jifty_utils.js
     jifty_subs.js

commit 4c4b07b3b305f909e17f6caa15ffee405f6b7f70
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Fri Jan 15 14:36:49 2010 -0500

    Update using JS doc

diff --git a/lib/Jifty/Manual/UsingCSSandJS.pod b/lib/Jifty/Manual/UsingCSSandJS.pod
index a4f0860..c9b24e1 100644
--- a/lib/Jifty/Manual/UsingCSSandJS.pod
+++ b/lib/Jifty/Manual/UsingCSSandJS.pod
@@ -130,23 +130,15 @@ libraries, like
 
 jQuery is a fast, concise, JavaScript Library that simplifies how you traverse HTML documents, handle events, perform animations, and add Ajax interactions to your web pages.
 
-=item C<Rico> L<http://openrico.org>
-
-Rico also provides graphical effects.
-
-=item C<Json> L<http://json.org>
+=item C<JSON> L<http://json.org>
 
 Hereby, major support for encoding and decoding data into the JSON
 data format (similar to C<YAML>) is provided.
 
-=item C<behaviour.js> L<http://bennolan.com/behaviour/>
+=item C<behaviour.js>
 
 With C<behaviour.js>, intelligent JavaScript handlers can be defined.
 
-=item C<cssQuery.js> L<http://dean.edwards.name/>
-
-This library adds support for querying the DOM using CSS selectors.
-
 =back
 
 =head2 Assembly of JS definitions

commit 86d839a03bc1bc7ecd69d94a7e12006d37904623
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Fri Jan 15 14:42:10 2010 -0500

    Move to jQuery event handling from JSAN

diff --git a/lib/Jifty/Web/Form/Field.pm b/lib/Jifty/Web/Form/Field.pm
index 5583a6e..8b9ac8a 100644
--- a/lib/Jifty/Web/Form/Field.pm
+++ b/lib/Jifty/Web/Form/Field.pm
@@ -722,8 +722,8 @@ sub focus_javascript {
     my $self = shift;
     return undef;
     if($self->focus) {
-        return qq!document.getElementById("@{[$self->element_id]}").focus()!;
-        return qq!DOM.Events.addListener( window, "load", function(){document.getElementById("@{[$self->element_id]}").focus()})!;
+        return qq!document.getElementById("@{[$self->element_id]}").focus();!;
+        return qq!jQuery(document).ready(function(){jQuery("#@{[$self->element_id]}").focus()});!;
     }
 }
 

-----------------------------------------------------------------------


More information about the Jifty-commit mailing list