added jsMath files
[lambda.git] / jsMath / jsMath-global.html
diff --git a/jsMath/jsMath-global.html b/jsMath/jsMath-global.html
new file mode 100644 (file)
index 0000000..1732662
--- /dev/null
@@ -0,0 +1,414 @@
+<html>
+<head>
+<!--
+ | jsMath-global.html
+ |
+ | Part of the jsMath package for mathematics on the web.
+ | 
+ | This file is used to store persistent data across multiple
+ | documents, for example, the cookie data when files are loaded
+ | locally, or cached typset math data.
+ |
+ | The file opens a frameset with one frame containing the
+ | actual document to view, and stores the global data in the
+ | outer document.  That way, when the frame changes documents
+ | the global data is still available.
+ | 
+ | ---------------------------------------------------------------------
+ | 
+ | Copyright 2006 by Davide P. Cervone
+ |
+ | Licensed under the Apache License, Version 2.0 (the "License");
+ | you may not use this file except in compliance with the License.
+ | You may obtain a copy of the License at
+ |
+ |     http://www.apache.org/licenses/LICENSE-2.0
+ |
+ | Unless required by applicable law or agreed to in writing, software
+ | distributed under the License is distributed on an "AS IS" BASIS,
+ | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ | See the License for the specific language governing permissions and
+ | limitations under the License.
+-->
+<title>jsMath Global Frame</title>
+<style></style>
+
+<script>
+var jsMath = {
+  isGlobal:  1,  // to pervent FRAME from inheriting this jsMath
+  isOpera:   (window.opera != null && window.Packages != null),
+  isSafari:  (window.clientInformation && document.implementation.createCSSStyleSheet != null),
+  isMSIEmac: (screen.updateInterval != null && !window.SyntaxError && !window.print),
+  msieDelay: 1000,  // MSIE/mac delay time for checking for offsite pages
+
+  /***************************************************************/
+
+  /*
+   *  This will be shared with the jsMath in the frameset
+   */
+  Global: {
+    isHidden: 0,
+    cookie: '',
+    cache: {T: {}, D: {}, R: {}, B: {}},
+    ClearCache: function () {jsMath.Global.cache = {T: {}, D: {}, R: {}, B: {}}},
+    Init: function () {}
+  },
+
+  /*
+   *  Called by jsMath to attach to the Global data area.
+   */
+  Register: function (w) {
+    w.jsMath.Global = jsMath.Global;
+    w.jsMath.Controls.localSetCookie = jsMath.localSetCookie;
+    w.jsMath.Controls.localGetCookie = jsMath.localGetCookie;
+    if (window.location.protocol != 'mk:') {
+      document.title = w.document.title;
+      this.ShowURL(w.location);
+      jsMath.SetUnload();
+    }
+  },
+
+  /***************************************************************/
+
+  /*
+   *  Initialize the global data and load the contents of the frame
+   */
+  Init: function () {
+    if (this.inited) return;
+    this.controls = document.getElementById('jsMath_controls');
+    this.frame    = document.getElementById('jsMath_frame');
+    this.window   = this.FrameWindow();
+    var URL;
+    if (!this.isOpera) {try {URL = this.window.document.URL} catch (err) {}}
+    if (!URL || URL == "about:blank" || URL.match(/jsMath-global.html$/))
+      {this.frame.src = this.src}
+
+    this.Global.frame = this.frame;
+    this.Global.Show = this.Show;
+    this.Global.GoLocal = this.GoLocal;
+    if (this.hide) {this.Hide()}
+    this.inited = 1;
+  },
+
+  GetURL: function () {
+    var src = unescape(document.location.search.substr(1));
+    if (src == '') {src = unescape(document.location.hash.substr(1))}
+    src = src.replace(/\?(.*)/,'');
+    if (RegExp.$1) {this.Global.cookie = unescape(RegExp.$1)}
+    return src;
+  },
+
+  FrameWindow: function (force) {
+    if (this.window && !force) {return this.window}
+    if (this.frame.contentWindow) {return this.frame.contentWindow}
+    if (document.frames && document.frames.jsMath_frame) 
+      {return document.frames.jsMath_frame}
+    return null;
+  },
+
+  /*
+   *  Called whenever the FRAME loads a new file.
+   *  (Update the title, etc.)
+   */
+  Loaded: function () {
+    if (!jsMath.inited) {jsMath.Init()}
+    if (!jsMath.window) {jsMath.window = jsMath.FrameWindow()}
+    if (!jsMath.window || window.location.protocol == 'mk:') return;
+    var URL; try {URL = jsMath.frame.src} catch (err) {}
+    var title; try {title = jsMath.window.document.title} catch (err) {}
+    if (URL != null && URL == jsMath.URL) return;
+    if (title != null) {
+      document.title = title;
+      jsMath.ShowURL(jsMath.window.location);
+      jsMath.SetUnload();
+    } else {
+      jsMath.Offsite();
+    }
+  },
+
+  /*
+   *  Mark the page as offsite and can't be read
+   */
+  Offsite: function () {
+    document.title = "jsMath Global: Offsite document -- can't read title";
+    jsMath.ShowURL("(Offsite document -- cant' read URL)");
+    if (jsMath.print && !jsMath.Global.isHidden) {
+      jsMath.print.disabled  = true;
+      jsMath.reload.disabled = true;
+    }
+    jsMath.window = null;
+  },
+
+  //
+  //  Safari doesn't fire onload for offsite URL's, so use in unload
+  //  handler to look for these and mark them.
+  //  MSIE/mac doesn't fire onload events at all, so use unload
+  //  handler to simulate them.
+  //
+  SetUnload: function () {
+    if (jsMath.isMSIEmac || jsMath.isSafari) {
+      try {jsMath.oldUnload = jsMath.window.unload} catch (err) {}
+      try {jsMath.window.onunload = jsMath.Unload} catch (err) {}
+    }
+  },
+  Unload: function (event) {
+    if (jsMath.oldUnload) {jsMath.oldUnload(event)}
+    try {setTimeout('jsMath.StateChange(0)',1)} catch (err) {}
+  },
+  StateChange: function (i) {
+    jsMath.ShowURL(jsMath.window.location);
+    var state = 'unknown'; try {state = jsMath.window.document.readyState} catch (err) {};
+    if (state == 'unknown' || i++ == 20) {jsMath.Offsite(); return}
+    if (state != 'complete') {setTimeout('jsMath.StateChange('+i+')',50*i); return}
+    document.title = jsMath.window.document.title;
+    jsMath.ShowURL(jsMath.window.location);
+    if (window.location.host == jsMath.window.location.host) 
+      {jsMath.SetUnload(); return}
+    if (jsMath.isMSIEmac) {
+      jsMath.oldLocation = jsMath.window.location;
+      setTimeout('jsMath.MSIEcheckDocument()',jsMath.msieDelay);
+    }
+  },
+  MSIEcheckDocument: function () {
+    if (window.location.host == jsMath.window.location.host) {
+      jsMath.StateChange(0)
+    } else {
+      if (jsMath.oldLocation != jsMath.window.location) {
+        jsMath.ShowURL(jsMath.window.location);
+        document.title = jsMath.window.document.title;
+      }
+      setTimeout('jsMath.MSIEcheckDocument()',jsMath.msieDelay);
+    }
+  },
+
+  /*
+   *  Replacements for standard localSetCookie/localGetCookie that
+   *  use the global cache for storing the cookie data rather than
+   *  the document.location's search field.
+   */
+  localSetCookie: function (cookie,warn) {
+    if (cookie != "") {cookie = 'jsMath='+cookie}
+    if (cookie == jsMath.Global.cookie) return;
+    jsMath.Global.cookie = cookie;
+  },
+  localGetCookie: function () {return (jsMath.Global.cookie || "")},
+
+  /*
+   *  Set the URL in the controls window
+   */
+  ShowURL: function (URL) {
+    try {
+      jsMath.URL = URL; if (jsMath.url) {jsMath.url.value = URL}
+      if (jsMath.print && !jsMath.Global.isHidden) {
+        jsMath.print.disabled  = !window.print;
+        jsMath.reload.disabled = false;
+      }
+    } catch (err) {}
+  },
+  SetURL: function () {this.frame.src = jsMath.url.value},
+
+  /*
+   *  Handle actions for the document frame
+   */
+  Print: function () {if (this.window) {this.window.document.body.focus(); this.window.print()}},
+  Reload: function () {if (this.window) {this.window.location.reload()}},
+  GoLocal: function () {
+    if (jsMath.window) {
+      jsMath.UpdateCookie();
+      if (jsMath.isMSIEmac) {
+        alert("MSIE/Mac has a bug that causes it not to go local properly.  "
+            + "After you press OK below, your browser will appear to hang.  "
+            + "When this happens, press Command-. to cancel the action.  "
+            + "The window should clear and the page location will appear "
+            + "in the address area at the top of the screen.  Press the "
+            + "REFRESH button to load the page correctly.");
+      }
+      jsMath.location = jsMath.window.location;
+      if (jsMath.window.location.protocol == 'file:' && jsMath.Global.cookie)
+        {jsMath.location += '?' + escape(jsMath.Global.cookie)}
+      setTimeout('window.location = jsMath.location',1);
+      return;
+    }
+    alert("You are viewing a web page from a site other than the "
+        + "one where you loaded jsMath-Global, so jsMath can't read "
+        + "its URL to load it locally.\n\n"
+        + "Check to see if your browser has a contextual menu item to "
+        + "open the active frame in a separate window.");
+  },
+
+  /*
+   *  Read the cookie data, set the hiddenGlobal and global fields
+   *  and save the cookie again.
+   */
+  UpdateCookie: function () {
+    var cookie = []; var cookies = jsMath.window.document.cookie;
+    if (window.location.protocol == 'file:') {cookies = jsMath.Global.cookie}
+    if (cookies.match(/jsMath=([^;]+)/)) {
+      var data = RegExp.$1.split(/,/);
+      for (var i = 0; i < data.length; i++) {
+        var x = data[i].match(/(.*):(.*)/);
+        if (x[2].match(/^\d+$/)) {x[2] = 1*x[2]} // convert from string
+        cookie[x[1]] = x[2];
+      }
+    }
+    cookie.hiddenGlobal = jsMath.Global.isHidden;
+    cookie.global = "never"; cookies = [];
+    for (var id in cookie) {cookies[cookies.length] = id + ':' + cookie[id]}
+    cookies = cookies.join(',');
+    if (window.location.protocol == 'file:') {
+      jsMath.Global.cookie = 'jsMath='+cookies;
+    } else {
+      cookies += '; path=/';
+      if (cookie.keep && cookie.keep != '0D') {
+        var ms = {
+          D: 1000*60*60*24,
+          W: 1000*60*60*24*7,
+          M: 1000*60*60*24*30,
+          Y: 1000*60*60*24*365
+        };
+        var exp = new Date;
+        exp.setTime(exp.getTime() +
+            cookie.keep.substr(0,1) * ms[cookie.keep.substr(1,1)]);
+        cookies += '; expires=' + exp.toGMTString();
+      }
+      jsMath.window.document.cookie = 'jsMath='+cookies;
+    }
+  },
+
+  /*
+   *  Check if the control panel should be hidden
+   */
+  SetControls: function (rows) {
+    if (!jsMath.rows) {
+      jsMath.rows = rows;
+      var cookie = document.cookie;
+      if (String(window.location.protocol).match(/^(file|mk):$/))
+        {cookie = jsMath.Global.cookie}
+      if (cookie.match(/jsMath=([^;]+)/)) {cookie = RegExp.$1}
+      if (!cookie.match("hiddenGlobal:0")) {
+        if (this.inited) {setTimeout('jsMath.Hide()',1)} else {jsMath.hide = 1}
+        return;
+      }
+    }
+    document.body.rows = rows;
+  },
+
+  /*
+   *  Remove the frame that holds the control panel
+   */ 
+  Hide: function () {
+    if (jsMath.Global.isHidden) return;
+    if (this.isMSIEmac) {
+      //
+      //  MSIE/Mac can't remove the frame, so hide it (and the drag bar)
+      //
+      document.body.rows = "-6,*";
+    } else if (this.isOpera) {
+      //
+      //  Opera can remove it, but it is unstable for that, but
+      //  setting the size to -1 seems to remove it as well.
+      //
+      document.body.rows = "-1,*";
+    } else {
+      document.body.removeChild(this.controls);
+      document.body.rows = "*";
+      jsMath.window = jsMath.FrameWindow(1);
+    }
+    this.Global.isHidden = 1;
+  },
+
+  /*
+   *  Put back the control-panel frame
+   */
+  Show: function (bubble) {
+    if (!jsMath.Global.isHidden) {
+      if (bubble && jsMath.window) {jsMath.window.jsMath.Controls.Panel()}
+      return;
+    }
+    if (!jsMath.isMSIEmac) {
+      document.body.insertBefore(jsMath.controls,jsMath.frame);
+      //
+      //  Opera doesn't refresh the frames properly, so reload them
+      //
+      if (jsMath.isOpera) {
+        setTimeout(
+          'jsMath.controls.src = "about:blank";\n' +
+          'jsMath.controls.src = jsMath.root+"jsMath-global-controls.html"+jsMath.domain;\n' +
+          'jsMath.frame.src = jsMath.window.location;',1
+        );
+      }
+    }
+    document.body.rows = jsMath.rows;
+    jsMath.window = jsMath.FrameWindow(1);
+    jsMath.Global.isHidden = 0;
+  },
+
+  /*
+   *  Empty the cache
+   */
+  Empty: function () {
+    var OK = confirm('Really empty the equation cache?');
+    if (OK) {jsMath.Global.ClearCache()}
+  },
+
+  /*
+   *  Find the largest common domain between the source file
+   *  and the location of the jsMath files
+   */
+  Domain: function () {
+    this.domain = '';
+    // MSIE/Mac can't do domain changes, so don't bother trying
+    if (navigator.appName == 'Microsoft Internet Explorer' &&
+        !navigator.platform.match(/Mac/) && navigator.userProfile != null) return;
+    if (this.src == '') {
+      if (window == parent) return;
+      var oldDomain = document.domain;
+      try {
+        while (true) {
+          try {if (parent.document.title != null) return} catch (err) {}
+         if (!document.domain.match(/\..*\./)) break;
+          document.domain = document.domain.replace(/^[^.]*\./,'');
+        }
+      } catch (err) {}
+      document.domain = oldDomain;
+    } else {
+      if (!this.src.match(new RegExp('^[^:]+:\/\/([^/]+)(:[0-9]+)?\/'))) return;
+      if (document.domain == RegExp.$1) return;
+      var src = RegExp.$1.split(/\./);
+      var loc = String(window.location.host).split(/\./);
+      var si, li; si = src.length-2; li = loc.length-2
+      while (si >= 0 && li >= 0 && src[si] == loc[li]) {li--; si--}
+      document.domain = src.slice(si+1).join('.');
+      this.domain = '?'+document.domain;
+    }
+  },
+
+  /*
+   *  Create the document content based on whether this is the initial
+   *  call to this file, or the secondary one
+   */
+  Content: function () {
+    if (this.src != '') {
+      this.root = (!this.isOpera) ? '' : 
+        String(window.location).replace(/\/jsMath-global.html\??.*/,'/');
+      document.writeln('<frameset rows="0,*" onload="jsMath.Init()">');
+      document.writeln('<frame src="'+this.root+'jsMath-global-controls.html'+this.domain+'" frameborder="0" scrolling="no" id="jsMath_controls" />');
+      document.writeln('<frame src="'+this.root+'jsMath-global.html" frameborder="0" onload="jsMath.Loaded()" id="jsMath_frame" />');
+      document.writeln('</frameset>');
+    } else {
+      document.writeln('<body><br/></body>');
+    }
+  }
+
+};
+
+</script>
+</head>
+
+<script>
+jsMath.src = jsMath.GetURL();
+jsMath.Domain();
+jsMath.Content();
+</script>
+
+</html>