add another section for important announcements.
[sgn.git] / js / JSAN.js
blobbe454af785a5a8b19d444ec77b79af909429ceac
1 /*
3 */
5 var JSAN = function () { JSAN.addRepository(arguments) }
7 JSAN.VERSION = 0.10;
9 /*
13 JSAN.globalScope   = self;
14 JSAN.includePath   = ['.', 'lib'];
15 JSAN.errorLevel    = "none";
16 JSAN.errorMessage  = "";
17 JSAN.loaded        = {};
23 JSAN.use = function () {
24     var classdef = JSAN.require(arguments[0]);
25     if (!classdef) return null;
27     var importList = JSAN._parseUseArgs.apply(JSAN, arguments).importList;
28     JSAN.exporter(classdef, importList);
30     return classdef;
37 JSAN.require = function (pkg) {
38     var path = JSAN._convertPackageToPath(pkg);
39     if (JSAN.loaded[path]) {
40         return JSAN.loaded[path];
41     }
43     try {
44         var classdef = eval(pkg);
45         if (typeof classdef != 'undefined') return classdef;
46     } catch (e) { /* nice try, eh? */ }
49     for (var i = 0; i < JSAN.includePath.length; i++) {
50         var js;
51         try{
52             var url = JSAN._convertPathToUrl(path, JSAN.includePath[i]);
53                 js  = JSAN._loadJSFromUrl(url);
54         } catch (e) {
55             if (i == JSAN.includePath.length - 1) throw e;
56         }
57         if (js != null) {
58             var classdef = JSAN._createScript(js, pkg);
59             JSAN.loaded[path] = classdef;
60             return classdef;
61         }
62     }
63     return false;
71 JSAN.exporter = function () {
72     JSAN._exportItems.apply(JSAN, arguments);
79 JSAN.addRepository = function () {
80     var temp = JSAN._flatten( arguments );
81     // Need to go in reverse to do something as simple as unshift( @foo, @_ );
82     for ( var i = temp.length - 1; i >= 0; i-- )
83         JSAN.includePath.unshift(temp[i]);
84     return JSAN;
87 JSAN._flatten = function( list1 ) {
88     var list2 = new Array();
89     for ( var i = 0; i < list1.length; i++ ) {
90         if ( typeof list1[i] == 'object' ) {
91             list2 = JSAN._flatten( list1[i], list2 );
92         }
93         else {
94             list2.push( list1[i] );
95         }
96     }
97     return list2;
100 JSAN._findMyPath = function () {
101     if (document) {
102         var scripts = document.getElementsByTagName('script');
103         for ( var i = 0; i < scripts.length; i++ ) {
104             var src = scripts[i].getAttribute('src');
105             if (src) {
106                 var inc = src.match(/^(.*?)\/?JSAN.js/);
107                 if (inc && inc[1]) {
108                     var repo = inc[1];
109                     for (var j = 0; j < JSAN.includePath.length; j++) {
110                         if (JSAN.includePath[j] == repo) {
111                             return;
112                         }
113                     }
114                     JSAN.addRepository(repo);
115                 }
116             }
117         }
118     }
120 JSAN._findMyPath();
122 JSAN._convertPathToUrl = function (path, repository) {
123     return repository.concat('/' + path);
125     
127 JSAN._convertPackageToPath = function (pkg) {
128     var path = pkg.replace(/\./g, '/');
129         path = path.concat('.js');
130     return path;
133 JSAN._parseUseArgs = function () {
134     var pkg        = arguments[0];
135     var importList = [];
137     for (var i = 1; i < arguments.length; i++)
138         importList.push(arguments[i]);
140     return {
141         pkg:        pkg,
142         importList: importList
143     }
146 JSAN._loadJSFromUrl = function (url) {
147     return new JSAN.Request().getText(url);
150 JSAN._findExportInList = function (list, request) {
151     if (list == null) return false;
152     for (var i = 0; i < list.length; i++)
153         if (list[i] == request)
154             return true;
155     return false;
158 JSAN._findExportInTag = function (tags, request) {
159     if (tags == null) return [];
160     for (var i in tags)
161         if (i == request)
162             return tags[i];
163     return [];
166 JSAN._exportItems = function (classdef, importList) {
167     var exportList  = new Array();
168     var EXPORT      = classdef.EXPORT;
169     var EXPORT_OK   = classdef.EXPORT_OK;
170     var EXPORT_TAGS = classdef.EXPORT_TAGS;
171     
172     if (importList.length > 0) {
173        importList = JSAN._flatten( importList );
175        for (var i = 0; i < importList.length; i++) {
176             var request = importList[i];
177             if (   JSAN._findExportInList(EXPORT,    request)
178                 || JSAN._findExportInList(EXPORT_OK, request)) {
179                 exportList.push(request);
180                 continue;
181             }
182             var list = JSAN._findExportInTag(EXPORT_TAGS, request);
183             for (var i = 0; i < list.length; i++) {
184                 exportList.push(list[i]);
185             }
186         }
187     } else {
188         exportList = EXPORT;
189     }
190     JSAN._exportList(classdef, exportList);
193 JSAN._exportList = function (classdef, exportList) {
194     if (typeof(exportList) != 'object') return null;
195     for (var i = 0; i < exportList.length; i++) {
196         var name = exportList[i];
198         if (JSAN.globalScope[name] == null)
199             JSAN.globalScope[name] = classdef[name];
200     }
203 JSAN._makeNamespace = function(js, pkg) {
204     var spaces = pkg.split('.');
205     var parent = JSAN.globalScope;
206     eval(js);
207     var classdef = eval(pkg);
208     for (var i = 0; i < spaces.length; i++) {
209         var name = spaces[i];
210         if (i == spaces.length - 1) {
211             if (typeof parent[name] == 'undefined') {
212                 parent[name] = classdef;
213                 if ( typeof classdef['prototype'] != 'undefined' ) {
214                     parent[name].prototype = classdef.prototype;
215                 }
216             }
217         } else {
218             if (parent[name] == undefined) {
219                 parent[name] = {};
220             }
221         }
223         parent = parent[name];
224     }
225     return classdef;
228 JSAN._handleError = function (msg, level) {
229     if (!level) level = JSAN.errorLevel;
230     JSAN.errorMessage = msg;
232     switch (level) {
233         case "none":
234             break;
235         case "warn":
236             alert(msg);
237             break;
238         case "die":
239         default:
240             throw new Error(msg);
241             break;
242     }
245 JSAN._createScript = function (js, pkg) {
246     try {
247         return JSAN._makeNamespace(js, pkg);
248     } catch (e) {
249         JSAN._handleError("Could not create namespace[" + pkg + "]: " + e);
250     }
251     return null;
255 JSAN.prototype = {
256     use: function () { JSAN.use.apply(JSAN, arguments) }
260 // Low-Level HTTP Request
261 JSAN.Request = function (jsan) {
262     if (JSAN.globalScope.XMLHttpRequest) {
263         this._req = new XMLHttpRequest();
264     } else {
265         this._req = new ActiveXObject("Microsoft.XMLHTTP");
266     }
269 JSAN.Request.prototype = {
270     _req:  null,
271     
272     getText: function (url) {
273         this._req.open("GET", url, false);
274         try {
275             this._req.send(null);
276             if (this._req.status == 200 || this._req.status == 0)
277                 return this._req.responseText;
278         } catch (e) {
279             JSAN._handleError("File not found: " + url);
280             return null;
281         };
283         JSAN._handleError("File not found: " + url);
284         return null;
285     }