Annotation of loncom/html/adm/jsMath/jsMath-global.html, revision 1.2

1.1       albertel    1: <html>
                      2: <head>
                      3: <!--
                      4:  | jsMath-global.html
                      5:  |
                      6:  | Part of the jsMath package for mathematics on the web.
                      7:  | 
                      8:  | This file is used to store persistent data across multiple
                      9:  | documents, for example, the cookie data when files are loaded
                     10:  | locally, or cached typset math data.
                     11:  |
                     12:  | The file opens a frameset with one frame containing the
                     13:  | actual document to view, and stores the global data in the
                     14:  | outer document.  That way, when the frame changes documents
                     15:  | the global data is still available.
                     16:  | 
                     17:  | ---------------------------------------------------------------------
                     18:  | 
                     19:  | Copyright 2006 by Davide P. Cervone
                     20:  |
                     21:  | Licensed under the Apache License, Version 2.0 (the "License");
                     22:  | you may not use this file except in compliance with the License.
                     23:  | You may obtain a copy of the License at
                     24:  |
                     25:  |     http://www.apache.org/licenses/LICENSE-2.0
                     26:  |
                     27:  | Unless required by applicable law or agreed to in writing, software
                     28:  | distributed under the License is distributed on an "AS IS" BASIS,
                     29:  | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                     30:  | See the License for the specific language governing permissions and
                     31:  | limitations under the License.
                     32: -->
                     33: <title>jsMath Global Frame</title>
                     34: <style></style>
                     35: 
                     36: <script>
                     37: var jsMath = {
                     38:   isGlobal:  1,  // to pervent FRAME from inheriting this jsMath
                     39:   isOpera:   (window.opera != null && window.Packages != null),
                     40:   isSafari:  (window.clientInformation && document.implementation.createCSSStyleSheet != null),
                     41:   isMSIEmac: (screen.updateInterval != null && !window.SyntaxError && !window.print),
                     42:   msieDelay: 1000,  // MSIE/mac delay time for checking for offsite pages
                     43: 
                     44:   /***************************************************************/
                     45: 
                     46:   /*
                     47:    *  This will be shared with the jsMath in the frameset
                     48:    */
                     49:   Global: {
                     50:     isHidden: 0,
                     51:     cookie: '',
                     52:     cache: {T: {}, D: {}, R: {}, B: {}},
                     53:     ClearCache: function () {jsMath.Global.cache = {T: {}, D: {}, R: {}, B: {}}},
                     54:     Init: function () {}
                     55:   },
                     56: 
                     57:   /*
                     58:    *  Called by jsMath to attach to the Global data area.
                     59:    */
                     60:   Register: function (w) {
                     61:     w.jsMath.Global = jsMath.Global;
                     62:     w.jsMath.Controls.localSetCookie = jsMath.localSetCookie;
                     63:     w.jsMath.Controls.localGetCookie = jsMath.localGetCookie;
                     64:     if (window.location.protocol != 'mk:') {
                     65:       document.title = w.document.title;
                     66:       this.ShowURL(w.location);
                     67:       jsMath.SetUnload();
                     68:     }
                     69:   },
                     70: 
                     71:   /***************************************************************/
                     72: 
                     73:   /*
                     74:    *  Initialize the global data and load the contents of the frame
                     75:    */
                     76:   Init: function () {
                     77:     if (this.inited) return;
                     78:     this.controls = document.getElementById('jsMath_controls');
                     79:     this.frame    = document.getElementById('jsMath_frame');
                     80:     this.window   = this.FrameWindow();
                     81:     var URL;
                     82:     if (!this.isOpera) {try {URL = this.window.document.URL} catch (err) {}}
                     83:     if (!URL || URL == "about:blank" || URL.match(/jsMath-global.html$/))
                     84:       {this.frame.src = this.src}
                     85: 
                     86:     this.Global.frame = this.frame;
                     87:     this.Global.Show = this.Show;
                     88:     this.Global.GoLocal = this.GoLocal;
                     89:     if (this.hide) {this.Hide()}
                     90:     this.inited = 1;
                     91:   },
                     92: 
                     93:   GetURL: function () {
                     94:     var src = unescape(document.location.search.substr(1));
                     95:     if (src == '') {src = unescape(document.location.hash.substr(1))}
                     96:     src = src.replace(/\?(.*)/,'');
                     97:     if (RegExp.$1) {this.Global.cookie = unescape(RegExp.$1)}
                     98:     return src;
                     99:   },
                    100: 
                    101:   FrameWindow: function (force) {
                    102:     if (this.window && !force) {return this.window}
                    103:     if (this.frame.contentWindow) {return this.frame.contentWindow}
                    104:     if (document.frames && document.frames.jsMath_frame) 
                    105:       {return document.frames.jsMath_frame}
                    106:     return null;
                    107:   },
                    108: 
                    109:   /*
                    110:    *  Called whenever the FRAME loads a new file.
                    111:    *  (Update the title, etc.)
                    112:    */
                    113:   Loaded: function () {
                    114:     if (!jsMath.inited) {jsMath.Init()}
                    115:     if (!jsMath.window) {jsMath.window = jsMath.FrameWindow()}
                    116:     if (!jsMath.window || window.location.protocol == 'mk:') return;
                    117:     var URL; try {URL = jsMath.frame.src} catch (err) {}
                    118:     var title; try {title = jsMath.window.document.title} catch (err) {}
                    119:     if (URL != null && URL == jsMath.URL) return;
                    120:     if (title != null) {
                    121:       document.title = title;
                    122:       jsMath.ShowURL(jsMath.window.location);
                    123:       jsMath.SetUnload();
                    124:     } else {
                    125:       jsMath.Offsite();
                    126:     }
                    127:   },
                    128: 
                    129:   /*
                    130:    *  Mark the page as offsite and can't be read
                    131:    */
                    132:   Offsite: function () {
                    133:     document.title = "jsMath Global: Offsite document -- can't read title";
                    134:     jsMath.ShowURL("(Offsite document -- cant' read URL)");
                    135:     if (jsMath.print && !jsMath.Global.isHidden) {
                    136:       jsMath.print.disabled  = true;
                    137:       jsMath.reload.disabled = true;
                    138:     }
                    139:     jsMath.window = null;
                    140:   },
                    141: 
                    142:   //
                    143:   //  Safari doesn't fire onload for offsite URL's, so use in unload
                    144:   //  handler to look for these and mark them.
                    145:   //  MSIE/mac doesn't fire onload events at all, so use unload
                    146:   //  handler to simulate them.
                    147:   //
                    148:   SetUnload: function () {
                    149:     if (jsMath.isMSIEmac || jsMath.isSafari) {
                    150:       try {jsMath.oldUnload = jsMath.window.unload} catch (err) {}
                    151:       try {jsMath.window.onunload = jsMath.Unload} catch (err) {}
                    152:     }
                    153:   },
                    154:   Unload: function (event) {
                    155:     if (jsMath.oldUnload) {jsMath.oldUnload(event)}
                    156:     try {setTimeout('jsMath.StateChange(0)',1)} catch (err) {}
                    157:   },
                    158:   StateChange: function (i) {
                    159:     jsMath.ShowURL(jsMath.window.location);
                    160:     var state = 'unknown'; try {state = jsMath.window.document.readyState} catch (err) {};
                    161:     if (state == 'unknown' || i++ == 20) {jsMath.Offsite(); return}
                    162:     if (state != 'complete') {setTimeout('jsMath.StateChange('+i+')',50*i); return}
                    163:     document.title = jsMath.window.document.title;
                    164:     jsMath.ShowURL(jsMath.window.location);
                    165:     if (window.location.host == jsMath.window.location.host) 
                    166:       {jsMath.SetUnload(); return}
                    167:     if (jsMath.isMSIEmac) {
                    168:       jsMath.oldLocation = jsMath.window.location;
                    169:       setTimeout('jsMath.MSIEcheckDocument()',jsMath.msieDelay);
                    170:     }
                    171:   },
                    172:   MSIEcheckDocument: function () {
                    173:     if (window.location.host == jsMath.window.location.host) {
                    174:       jsMath.StateChange(0)
                    175:     } else {
                    176:       if (jsMath.oldLocation != jsMath.window.location) {
                    177:         jsMath.ShowURL(jsMath.window.location);
                    178:         document.title = jsMath.window.document.title;
                    179:       }
                    180:       setTimeout('jsMath.MSIEcheckDocument()',jsMath.msieDelay);
                    181:     }
                    182:   },
                    183: 
                    184:   /*
                    185:    *  Replacements for standard localSetCookie/localGetCookie that
                    186:    *  use the global cache for storing the cookie data rather than
                    187:    *  the document.location's search field.
                    188:    */
                    189:   localSetCookie: function (cookie,warn) {
                    190:     if (cookie != "") {cookie = 'jsMath='+cookie}
                    191:     if (cookie == jsMath.Global.cookie) return;
                    192:     jsMath.Global.cookie = cookie;
                    193:   },
                    194:   localGetCookie: function () {return (jsMath.Global.cookie || "")},
                    195: 
                    196:   /*
                    197:    *  Set the URL in the controls window
                    198:    */
                    199:   ShowURL: function (URL) {
                    200:     try {
                    201:       jsMath.URL = URL; if (jsMath.url) {jsMath.url.value = URL}
                    202:       if (jsMath.print && !jsMath.Global.isHidden) {
                    203:         jsMath.print.disabled  = !window.print;
                    204:         jsMath.reload.disabled = false;
                    205:       }
                    206:     } catch (err) {}
                    207:   },
                    208:   SetURL: function () {this.frame.src = jsMath.url.value},
                    209: 
                    210:   /*
                    211:    *  Handle actions for the document frame
                    212:    */
                    213:   Print: function () {if (this.window) {this.window.document.body.focus(); this.window.print()}},
                    214:   Reload: function () {if (this.window) {this.window.location.reload()}},
                    215:   GoLocal: function () {
                    216:     if (jsMath.window) {
                    217:       jsMath.UpdateCookie();
                    218:       if (jsMath.isMSIEmac) {
                    219:         alert("MSIE/Mac has a bug that causes it not to go local properly.  "
                    220:             + "After you press OK below, your browser will appear to hang.  "
                    221:             + "When this happens, press Command-. to cancel the action.  "
                    222:             + "The window should clear and the page location will appear "
                    223:             + "in the address area at the top of the screen.  Press the "
                    224:             + "REFRESH button to load the page correctly.");
                    225:       }
                    226:       jsMath.location = jsMath.window.location;
                    227:       if (jsMath.window.location.protocol == 'file:' && jsMath.Global.cookie)
                    228:         {jsMath.location += '?' + escape(jsMath.Global.cookie)}
                    229:       setTimeout('window.location = jsMath.location',1);
                    230:       return;
                    231:     }
                    232:     alert("You are viewing a web page from a site other than the "
                    233:         + "one where you loaded jsMath-Global, so jsMath can't read "
                    234:         + "its URL to load it locally.\n\n"
                    235:         + "Check to see if your browser has a contextual menu item to "
                    236:         + "open the active frame in a separate window.");
                    237:   },
                    238: 
                    239:   /*
                    240:    *  Read the cookie data, set the hiddenGlobal and global fields
                    241:    *  and save the cookie again.
                    242:    */
                    243:   UpdateCookie: function () {
                    244:     var cookie = []; var cookies = jsMath.window.document.cookie;
                    245:     if (window.location.protocol == 'file:') {cookies = jsMath.Global.cookie}
                    246:     if (cookies.match(/jsMath=([^;]+)/)) {
                    247:       var data = RegExp.$1.split(/,/);
                    248:       for (var i = 0; i < data.length; i++) {
                    249:         var x = data[i].match(/(.*):(.*)/);
                    250:         if (x[2].match(/^\d+$/)) {x[2] = 1*x[2]} // convert from string
                    251:         cookie[x[1]] = x[2];
                    252:       }
                    253:     }
                    254:     cookie.hiddenGlobal = jsMath.Global.isHidden;
                    255:     cookie.global = "never"; cookies = [];
                    256:     for (var id in cookie) {cookies[cookies.length] = id + ':' + cookie[id]}
                    257:     cookies = cookies.join(',');
                    258:     if (window.location.protocol == 'file:') {
                    259:       jsMath.Global.cookie = 'jsMath='+cookies;
                    260:     } else {
                    261:       cookies += '; path=/';
                    262:       if (cookie.keep && cookie.keep != '0D') {
                    263:         var ms = {
                    264:           D: 1000*60*60*24,
                    265:           W: 1000*60*60*24*7,
                    266:           M: 1000*60*60*24*30,
                    267:           Y: 1000*60*60*24*365
                    268:         };
                    269:         var exp = new Date;
                    270:         exp.setTime(exp.getTime() +
                    271:             cookie.keep.substr(0,1) * ms[cookie.keep.substr(1,1)]);
                    272:         cookies += '; expires=' + exp.toGMTString();
                    273:       }
                    274:       jsMath.window.document.cookie = 'jsMath='+cookies;
                    275:     }
                    276:   },
                    277: 
                    278:   /*
                    279:    *  Check if the control panel should be hidden
                    280:    */
                    281:   SetControls: function (rows) {
                    282:     if (!jsMath.rows) {
                    283:       jsMath.rows = rows;
                    284:       var cookie = document.cookie;
                    285:       if (String(window.location.protocol).match(/^(file|mk):$/))
                    286:         {cookie = jsMath.Global.cookie}
                    287:       if (cookie.match(/jsMath=([^;]+)/)) {cookie = RegExp.$1}
                    288:       if (!cookie.match("hiddenGlobal:0")) {
                    289:         if (this.inited) {setTimeout('jsMath.Hide()',1)} else {jsMath.hide = 1}
                    290:         return;
                    291:       }
                    292:     }
                    293:     document.body.rows = rows;
                    294:   },
                    295: 
                    296:   /*
                    297:    *  Remove the frame that holds the control panel
                    298:    */ 
                    299:   Hide: function () {
                    300:     if (jsMath.Global.isHidden) return;
                    301:     if (this.isMSIEmac) {
                    302:       //
                    303:       //  MSIE/Mac can't remove the frame, so hide it (and the drag bar)
                    304:       //
                    305:       document.body.rows = "-6,*";
                    306:     } else if (this.isOpera) {
                    307:       //
                    308:       //  Opera can remove it, but it is unstable for that, but
                    309:       //  setting the size to -1 seems to remove it as well.
                    310:       //
                    311:       document.body.rows = "-1,*";
                    312:     } else {
                    313:       document.body.removeChild(this.controls);
                    314:       document.body.rows = "*";
                    315:       jsMath.window = jsMath.FrameWindow(1);
                    316:     }
                    317:     this.Global.isHidden = 1;
                    318:   },
                    319: 
                    320:   /*
                    321:    *  Put back the control-panel frame
                    322:    */
                    323:   Show: function (bubble) {
                    324:     if (!jsMath.Global.isHidden) {
                    325:       if (bubble && jsMath.window) {jsMath.window.jsMath.Controls.Panel()}
                    326:       return;
                    327:     }
                    328:     if (!jsMath.isMSIEmac) {
                    329:       document.body.insertBefore(jsMath.controls,jsMath.frame);
                    330:       //
                    331:       //  Opera doesn't refresh the frames properly, so reload them
                    332:       //
                    333:       if (jsMath.isOpera) {
                    334:         setTimeout(
                    335:           'jsMath.controls.src = "about:blank";\n' +
                    336:           'jsMath.controls.src = jsMath.root+"jsMath-global-controls.html"+jsMath.domain;\n' +
                    337:           'jsMath.frame.src = jsMath.window.location;',1
                    338:         );
                    339:       }
                    340:     }
                    341:     document.body.rows = jsMath.rows;
                    342:     jsMath.window = jsMath.FrameWindow(1);
                    343:     jsMath.Global.isHidden = 0;
                    344:   },
                    345: 
                    346:   /*
                    347:    *  Empty the cache
                    348:    */
                    349:   Empty: function () {
                    350:     var OK = confirm('Really empty the equation cache?');
                    351:     if (OK) {jsMath.Global.ClearCache()}
                    352:   },
                    353: 
                    354:   /*
                    355:    *  Find the largest common domain between the source file
                    356:    *  and the location of the jsMath files
                    357:    */
                    358:   Domain: function () {
                    359:     this.domain = '';
                    360:     // MSIE/Mac can't do domain changes, so don't bother trying
                    361:     if (navigator.appName == 'Microsoft Internet Explorer' &&
1.2     ! albertel  362:         !navigator.platform.match(/Mac/) && navigator.userProfile != null) return;
1.1       albertel  363:     if (this.src == '') {
                    364:       if (window == parent) return;
                    365:       var oldDomain = document.domain;
                    366:       try {
                    367:         while (true) {
                    368:           try {if (parent.document.title != null) return} catch (err) {}
                    369: 	  if (!document.domain.match(/\..*\./)) break;
                    370:           document.domain = document.domain.replace(/^[^.]*\./,'');
                    371:         }
                    372:       } catch (err) {}
                    373:       document.domain = oldDomain;
                    374:     } else {
1.2     ! albertel  375:       if (!this.src.match(new RegExp('^[^:]+:\/\/([^/]+)(:[0-9]+)?\/'))) return;
1.1       albertel  376:       if (document.domain == RegExp.$1) return;
                    377:       var src = RegExp.$1.split(/\./);
                    378:       var loc = String(window.location.host).split(/\./);
                    379:       var si, li; si = src.length-2; li = loc.length-2
                    380:       while (si >= 0 && li >= 0 && src[si] == loc[li]) {li--; si--}
                    381:       document.domain = src.slice(si+1).join('.');
                    382:       this.domain = '?'+document.domain;
                    383:     }
                    384:   },
                    385: 
                    386:   /*
                    387:    *  Create the document content based on whether this is the initial
                    388:    *  call to this file, or the secondary one
                    389:    */
                    390:   Content: function () {
                    391:     if (this.src != '') {
                    392:       this.root = (!this.isOpera) ? '' : 
                    393:         String(window.location).replace(/\/jsMath-global.html\??.*/,'/');
                    394:       document.writeln('<frameset rows="0,*" onload="jsMath.Init()">');
                    395:       document.writeln('<frame src="'+this.root+'jsMath-global-controls.html'+this.domain+'" frameborder="0" scrolling="no" id="jsMath_controls" />');
                    396:       document.writeln('<frame src="'+this.root+'jsMath-global.html" frameborder="0" onload="jsMath.Loaded()" id="jsMath_frame" />');
                    397:       document.writeln('</frameset>');
                    398:     } else {
                    399:       document.writeln('<body><br/></body>');
                    400:     }
                    401:   }
                    402: 
                    403: };
                    404: 
                    405: </script>
                    406: </head>
                    407: 
                    408: <script>
                    409: jsMath.src = jsMath.GetURL();
                    410: jsMath.Domain();
                    411: jsMath.Content();
                    412: </script>
                    413: 
                    414: </html>

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>