Annotation of loncom/html/adm/jsMath/plugins/autoload.js, revision 1.4
1.1 albertel 1: /*
2: * autoload.js
3: *
4: * Part of the jsMath package for mathematics on the web.
5: *
6: * This file is a plugin that checks if a page contains any math
7: * that must be processed by jsMath, and only loads jsMath.js
8: * when there is.
9: *
10: * You can control the items to look for via the variables
11: *
12: * jsMath.Autoload.findTeXstrings
13: * jsMath.Autoload.findLaTeXstrings
1.2 albertel 14: * jsMath.Autoload.findCustomStrings
15: * jsMath.Autoload.findCustomSettings
1.1 albertel 16: *
1.4 ! albertel 17: * which control whether to look for TeX strings that will be converted
! 18: * by jsMath.ConvertTeX(), or LaTeX strings that will be converted by
! 19: * jsMath.ConvertLaTeX(). By default, the first is true and the second
! 20: * and third are false. The findCustomStrings can be used to specify your
! 21: * own delimiters for in-line and display mathematics, e.g.
1.2 albertel 22: *
23: * jsMath.Autoload.findCustomStrings = [
24: * '[math],'[/math]', // start and end in-line math
25: * '[display]','[/display]' // start and end display math
26: * ];
27: *
28: * Finally, findCustomSettings can be set to an object reference whose
29: * name:value pairs control the individual search settings for tex2math.
30: * (See the plugins/tex2math.js file for more details).
1.1 albertel 31: *
32: * If any math strings are found, jsMath.js will be loaded automatically,
1.2 albertel 33: * but not loaded otherwise. If any of the last four are set and TeX math
1.1 albertel 34: * strings are found, then plugins/tex2ath.js will be loaded
35: * automatically. jsMath.Autoload.needsJsMath will be set to true or
1.2 albertel 36: * false depending on whether jsMath needed to be loaded.
1.1 albertel 37: *
38: * The value of jsMath.Autoload.element controls the element to be
39: * searched by the autoload plug-in. If unset, the complete document will
40: * be searched. If set to a string, the element with that name will be
41: * searched. If set to a DOM object, that object and its children will
42: * be searched.
43: *
44: * Finally, there are two additional parameters that control files to
45: * be loaded after jsMath.js, should it be needed. These are
46: *
47: * jsMath.Autoload.loadFonts
48: * jsMath.Autoload.loadFiles
49: *
50: * If jsMath.js is loaded, the fonts contained in the loadFonts array
51: * will be loaded, and the JavaScript files listed in the loadFiles array
52: * will be run. Relative URL's are loaded based from the URL containing
53: * jsMath.js.
54: *
1.2 albertel 55: * The autoload plugin can be loaded in the document HEAD or in the BODY.
56: * If it is loaded in the HEAD, you will need to call jsMath.Autoload.Check()
57: * at the end of the BODY (say in the window.onload handler) in order to
58: * get it to check the page for math that needs to be tagged, otherwise load
59: * the file at the bottom of the BODY and it will run the check automatically.
60: *
61: * You can call jsMath.Autoload.Run() after the check has been performed
62: * in order to call the appropriate tex2math routines for the given Autoload
63: * settings. You can call jsMath.Autoload.Run() even when jsMath isn't loaded.
64: *
1.1 albertel 65: * ---------------------------------------------------------------------
66: *
1.2 albertel 67: * Copyright 2004-2006 by Davide P. Cervone
68: *
69: * Licensed under the Apache License, Version 2.0 (the "License");
70: * you may not use this file except in compliance with the License.
71: * You may obtain a copy of the License at
72: *
73: * http://www.apache.org/licenses/LICENSE-2.0
74: *
75: * Unless required by applicable law or agreed to in writing, software
76: * distributed under the License is distributed on an "AS IS" BASIS,
77: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78: * See the License for the specific language governing permissions and
79: * limitations under the License.
1.1 albertel 80: */
81:
82: /*************************************************************************/
83:
84: /*
85: * Make sure jsMath.Autoload is available
86: */
1.3 albertel 87: if (!window.jsMath) {window.jsMath = {}}
1.1 albertel 88: if (jsMath.Autoload == null) {jsMath.Autoload = {}}
1.2 albertel 89: jsMath.Add = function (dst,src) {for (var id in src) {dst[id] = src[id]}},
90: jsMath.document = document; // tex2math needs this
91:
92: jsMath.Add(jsMath.Autoload,{
93:
94: Script: {
95:
1.4 ! albertel 96: request: null, // XMLHttpRequest object (if we can get it)
! 97: iframe: null, // the hidden iframe (if not)
1.2 albertel 98:
99: /*
1.4 ! albertel 100: * Get XMLHttpRequest object, if possible, and look up the URL root
! 101: * (MSIE can't use xmlReuest to load local files, so avoid that)
! 102: */
! 103: Init: function () {
! 104: if (!(document.URL && document.URL.match(/^file:\/\/.*\\/))) {
! 105: if (window.XMLHttpRequest) {try {this.request = new XMLHttpRequest} catch (err) {}}
! 106: if (!this.request && window.ActiveXObject) {
! 107: var xml = ["MSXML2.XMLHTTP.5.0","MSXML2.XMLHTTP.4.0","MSXML2.XMLHTTP.3.0",
! 108: "MSXML2.XMLHTTP","Microsoft.XMLHTTP"];
! 109: for (var i = 0; i < xml.length && !this.request; i++) {
! 110: try {this.request = new ActiveXObject(xml[i])} catch (err) {}
! 111: }
! 112: }
! 113: }
! 114: this.Root();
! 115: },
! 116:
! 117: /*
! 118: * Load an external JavaScript file
1.2 albertel 119: */
120: Load: function (url) {
1.4 ! albertel 121: if (this.request) {
! 122: setTimeout(function () {jsMath.Autoload.Script.xmlLoad(url)},1);
! 123: } else {
! 124: this.startLoad(url);
! 125: }
! 126: },
! 127:
! 128: /*
! 129: * Load an external JavaScript file via XMLHttpRequest
! 130: */
! 131: xmlLoad: function (url) {
! 132: try {
! 133: this.request.open("GET",jsMath.Autoload.root+url,false);
! 134: this.request.send(null);
! 135: } catch (err) {
! 136: throw "autoload: can't load the file '"+url+"'\n"
! 137: + "Message: "+err.message;
! 138: }
! 139: if (this.request.status && this.request.status >= 400) {
! 140: throw "autoload: can't load the file '"+url+"'\n"
! 141: + "Error status: "+this.request.status;
! 142: }
! 143: window.eval(this.request.responseText);
! 144: this.endLoad();
! 145: },
! 146:
! 147: /*
! 148: * Load an external JavaScript file via jsMath-autoload.html
! 149: */
! 150: startLoad: function (url) {
1.2 albertel 151: this.iframe = document.createElement('iframe');
152: this.iframe.style.visibility = 'hidden';
153: this.iframe.style.position = 'absolute';
154: this.iframe.style.width = '0px';
155: this.iframe.style.height = '0px';
156: if (document.body.firstChild) {
157: document.body.insertBefore(this.iframe,document.body.firstChild);
158: } else {
159: document.body.appendChild(this.iframe);
160: }
161: this.url = url; setTimeout('jsMath.Autoload.Script.setURL()',100);
162: },
163: endLoad: function () {setTimeout('jsMath.Autoload.Script.AfterLoad()',1)},
164:
165: /*
166: * Use location.replace() to avoid browsers placing the file in
167: * the history (and messing up the BACK button action). Not
168: * completely effective in Firefox 1.0.x. Safari won't handle
169: * replace() if the document is local (not sure if that's really
170: * the issue, but that's the only time I see it).
171: */
172: setURL: function () {
173: var url = jsMath.Autoload.root+"jsMath-autoload.html";
174: var doc = this.iframe.contentDocument;
175: if (!doc && this.iframe.contentWindow) {doc = this.iframe.contentWindow.document}
176: if (navigator.vendor == "Apple Computer, Inc." &&
177: document.location.protocol == 'file:') {doc = null}
178: if (doc) {doc.location.replace(url)} else {this.iframe.src = url}
179: },
180:
181: /*
182: * Queue items that need to be postponed until jsMath has run
183: */
184: queue: [],
185: Push: function (name,data) {this.queue[this.queue.length] = [name,data]},
186: RunStack: function () {
187: if (this.tex2math) {jsMath.Autoload.Check2(); return}
188: for (var i = 0; i < this.queue.length; i++) {
189: var name = this.queue[i][0];
190: var data = this.queue[i][1];
191: if (data.length == 1) {jsMath[name](data[0])}
192: else {jsMath[name](data[0],data[1],data[2],data[3])}
193: }
1.4 ! albertel 194: this.queue = [];
1.2 albertel 195: },
196:
197: AfterLoad: function () {jsMath.Autoload.Script.RunStack()},
198:
199: /*
200: * Look up the jsMath root directory, if it is not already supplied
201: */
202: Root: function () {
203: if (jsMath.Autoload.root) return;
204: var script = document.getElementsByTagName('script');
205: if (script) {
206: for (var i = 0; i < script.length; i++) {
207: var src = script[i].src;
1.4 ! albertel 208: if (src && src.match('(^|/|\\\\)plugins/autoload.js$')) {
1.2 albertel 209: jsMath.Autoload.root = src.replace(/plugins\/autoload.js$/,'');
210: break;
211: }
212: }
213: }
214: }
1.1 albertel 215:
1.2 albertel 216: },
217:
218: /**************************************************************/
219:
220: /*
221: * Load tex2math first (so we can call its search functions
222: * to look to see if anything needs to be turned into math)
223: * if it is needed, otherwise go on to the second check.
224: */
225: Check: function () {
226: if (this.checked) return; this.checked = 1;
1.4 ! albertel 227: if ((this.findTeXstrings || this.findLaTeXstrings ||
! 228: this.findCustomStrings || this.findCustomSettings) &&
! 229: (!jsMath.tex2math || !jsMath.tex2math.loaded)) {
1.2 albertel 230: this.Script.tex2math = 1;
231: this.Script.Load('plugins/tex2math.js');
232: } else {
233: if (!jsMath.tex2math) {jsMath.tex2math = {}}
234: this.Check2();
235: }
236: },
1.4 ! albertel 237: ReCheck: function () {
! 238: if (jsMath.loaded) return;
! 239: this.InitStubs();
! 240: this.checked = 0;
! 241: this.Script.queue = [];
! 242: this.Check();
! 243: },
1.1 albertel 244:
1.2 albertel 245: /*
246: * Once tex2math is loaded, use it to check for math that
247: * needs to be tagged for jsMath, and load jsMath if it is needed
248: */
249: Check2: function () {
1.4 ! albertel 250: this.Script.tex2math = 0; this.needsJsMath = 0;
! 251: if (this.checkElement == null) {this.checkElement = null}
! 252:
! 253: if (this.findTeXstrings) {jsMath.tex2math.ConvertTeX(this.checkElement)}
! 254: if (this.findLaTeXstrings) {jsMath.tex2math.ConvertLaTeX(this.checkElement)}
! 255: if (this.findCustomSettings) {jsMath.tex2math.Convert(this.checkElement,this.findCustomSettings)}
! 256: if (this.findCustomStrings) {
1.2 albertel 257: var s = this.findCustomStrings;
258: jsMath.tex2math.CustomSearch(s[0],s[1],s[2],s[3]);
259: jsMath.tex2math.ConvertCustom(this.checkElement);
260: }
1.1 albertel 261:
1.4 ! albertel 262: this.needsJsMath = this.areMathElements(this.checkElement);
1.2 albertel 263: if (this.needsJsMath) {
264: this.LoadJsMath();
265: } else {
266: jsMath.Process = function () {};
267: jsMath.ProcessBeforeShowing = function () {};
268: jsMath.ConvertTeX = function () {};
269: jsMath.ConvertTeX2 = function () {};
270: jsMath.ConvertLaTeX = function () {};
271: jsMath.ConvertCustom = function () {};
272: jsMath.CustomSearch = function () {};
273: jsMath.Macro = function () {};
1.4 ! albertel 274: jsMath.Synchronize = function (code,data) {
! 275: if (typeof(code) == 'string') {eval(code)} else {code(data)}
! 276: };
! 277: jsMath.Autoload.Script.RunStack(); // perform pending commands
! 278: jsMath.Autoload.setMessage();
1.1 albertel 279: }
1.2 albertel 280: },
1.1 albertel 281:
1.2 albertel 282: /*
283: * A callback used in the tex2math searches to signal that
284: * some math has been found.
285: */
286: tex2mathCallback: function () {
287: jsMath.Autoload.needsJsMath = 1;
288: return false;
289: },
290:
291: /*
1.4 ! albertel 292: * jsMath.Autoload.Run() is now longer needed
1.2 albertel 293: */
1.4 ! albertel 294: Run: function (data) {},
1.1 albertel 295:
1.2 albertel 296: /*
297: * Look to see if there are SPAN or DIV elements of class "math".
298: */
299: areMathElements: function (obj) {
300: if (!obj) {obj = document}
301: if (typeof(obj) == 'string') {obj = document.getElementById(obj)}
302: if (!obj.getElementsByTagName) {return false}
303: var math = obj.getElementsByTagName('div');
304: for (var k = 0; k < math.length; k++)
1.3 albertel 305: {if (math[k].className.match(/(^| )math( |$)/)) {return true}}
1.2 albertel 306: math = obj.getElementsByTagName('span');
307: for (var k = 0; k < math.length; k++)
1.3 albertel 308: {if (math[k].className.match(/(^| )math( |$)/)) {return true}}
1.2 albertel 309: return false;
310: },
311:
312: /*
313: * When math tags are found, load the jsMath.js file,
314: * and afterward, load any auxiliary files or fonts,
315: * and then do any pending commands.
316: */
317: LoadJsMath: function () {
1.4 ! albertel 318: if (this.loading) return;
! 319: if (jsMath.loaded) {this.afterLoad(); return}
1.2 albertel 320: if (this.root) {
1.4 ! albertel 321: this.loading = 1;
1.2 albertel 322: this.setMessage('Loading jsMath...');
323: this.Script.AfterLoad = this.afterLoad;
324: this.Script.Load('jsMath.js');
325: } else {
326: alert("Can't determine URL for jsMath.js");
327: }
328: },
329: afterLoad: function () {
1.4 ! albertel 330: jsMath.Autoload.loading = 0;
1.2 albertel 331: if (jsMath.tex2math.window) {jsMath.tex2math.window.jsMath = jsMath}
332: //
333: // Handle MSIE bug where jsMath.window both is and is not the actual window
334: //
335: if (jsMath.browser == 'MSIE') {window.onscroll = jsMath.window.onscroll};
336: var fonts = jsMath.Autoload.loadFonts;
337: if (fonts) {
338: if (typeof(fonts) != 'object') {fonts = [fonts]}
1.4 ! albertel 339: for (var i = 0; i < fonts.length; i++) {jsMath.Font.Load(fonts[i])}
1.2 albertel 340: }
341: var files = jsMath.Autoload.loadFiles;
342: if (files) {
343: if (typeof(files) != 'object') {files = [files]}
1.4 ! albertel 344: for (var i = 0; i < files.length; i++) {jsMath.Setup.Script(files[i])}
1.2 albertel 345: }
346: jsMath.Synchronize(function () {jsMath.Autoload.Script.RunStack()});
347: jsMath.Autoload.setMessage();
348: },
349:
350: /*
351: * Display a message in a small box at the bottom of the screen
352: */
353: setMessage: function (message) {
354: if (message) {
355: this.div = document.createElement('div');
356: if (!document.body.hasChildNodes) {document.body.appendChild(this.div)}
357: else {document.body.insertBefore(this.div,document.body.firstChild)}
358: var style = {
1.4 ! albertel 359: position:'fixed', bottom:'1px', left:'2px',
1.2 albertel 360: backgroundColor:'#E6E6E6', border:'solid 1px #959595',
361: margin:'0px', padding:'1px 8px', zIndex:102,
362: color:'black', fontSize:'75%', width:'auto'
363: };
364: for (var id in style) {this.div.style[id] = style[id]}
365: this.div.appendChild(jsMath.document.createTextNode(message));
1.4 ! albertel 366: } else if (this.div) {
1.2 albertel 367: this.div.firstChild.nodeValue = "";
368: this.div.style.visibility = 'hidden';
1.1 albertel 369: }
1.4 ! albertel 370: },
! 371:
! 372: /*
! 373: * Queue these so we can do them after jsMath has been loaded
! 374: */
! 375: stubs: {
! 376: Process: function (data) {jsMath.Autoload.Script.Push('Process',[data])},
! 377: ProcessBeforeShowing: function (data) {jsMath.Autoload.Script.Push('ProcessBeforeShowing',[data])},
! 378: ConvertTeX: function (data) {jsMath.Autoload.Script.Push('ConvertTeX',[data])},
! 379: ConvertTeX2: function (data) {jsMath.Autoload.Script.Push('ConvertTeX2',[data])},
! 380: ConvertLaTeX: function (data) {jsMath.Autoload.Script.Push('ConvertLaTeX',[data])},
! 381: ConvertCustom: function (data) {jsMath.Autoload.Script.Push('ConvertCustom',[data])},
! 382: CustomSearch: function (d1,d2,d3,d4) {jsMath.Autoload.Script.Push('CustomSearch',[d1,d2,d3,d4])},
! 383: Synchronize: function (data) {jsMath.Autoload.Script.Push('Synchronize',[data])},
! 384: Macro: function (cs,def,params) {jsMath.Autoload.Script.Push('Macro',[cs,def,params])}
! 385: },
! 386:
! 387: InitStubs: function () {jsMath.Add(jsMath,jsMath.Autoload.stubs)}
1.2 albertel 388:
389: });
1.1 albertel 390:
391: /*
1.2 albertel 392: * Initialize
1.1 albertel 393: */
394:
395: if (jsMath.Autoload.findTeXstrings == null) {jsMath.Autoload.findTeXstrings = 0}
396: if (jsMath.Autoload.findLaTeXstrings == null) {jsMath.Autoload.findLaTeXstrings = 0}
397:
1.4 ! albertel 398: jsMath.Autoload.Script.Init();
! 399: jsMath.Autoload.InitStubs();
1.2 albertel 400: if (document.body) {jsMath.Autoload.Check()}
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>