--- /dev/null
+<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>