6 | Part of the jsMath package for mathematics on the web.
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.
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.
17 | ---------------------------------------------------------------------
19 | Copyright 2006 by Davide P. Cervone
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
25 | http://www.apache.org/licenses/LICENSE-2.0
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.
33 <title>jsMath Global Frame</title>
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
44 /***************************************************************/
47 * This will be shared with the jsMath in the frameset
52 cache: {T: {}, D: {}, R: {}, B: {}},
53 ClearCache: function () {jsMath.Global.cache = {T: {}, D: {}, R: {}, B: {}}},
58 * Called by jsMath to attach to the Global data area.
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);
71 /***************************************************************/
74 * Initialize the global data and load the contents of the frame
77 if (this.inited) return;
78 this.controls = document.getElementById('jsMath_controls');
79 this.frame = document.getElementById('jsMath_frame');
80 this.window = this.FrameWindow();
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}
86 this.Global.frame = this.frame;
87 this.Global.Show = this.Show;
88 this.Global.GoLocal = this.GoLocal;
89 if (this.hide) {this.Hide()}
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)}
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}
110 * Called whenever the FRAME loads a new file.
111 * (Update the title, etc.)
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;
121 document.title = title;
122 jsMath.ShowURL(jsMath.window.location);
130 * Mark the page as offsite and can't be read
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;
139 jsMath.window = null;
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.
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) {}
154 Unload: function (event) {
155 if (jsMath.oldUnload) {jsMath.oldUnload(event)}
156 try {setTimeout('jsMath.StateChange(0)',1)} catch (err) {}
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);
172 MSIEcheckDocument: function () {
173 if (window.location.host == jsMath.window.location.host) {
174 jsMath.StateChange(0)
176 if (jsMath.oldLocation != jsMath.window.location) {
177 jsMath.ShowURL(jsMath.window.location);
178 document.title = jsMath.window.document.title;
180 setTimeout('jsMath.MSIEcheckDocument()',jsMath.msieDelay);
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.
189 localSetCookie: function (cookie,warn) {
190 if (cookie != "") {cookie = 'jsMath='+cookie}
191 if (cookie == jsMath.Global.cookie) return;
192 jsMath.Global.cookie = cookie;
194 localGetCookie: function () {return (jsMath.Global.cookie || "")},
197 * Set the URL in the controls window
199 ShowURL: function (URL) {
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;
208 SetURL: function () {this.frame.src = jsMath.url.value},
211 * Handle actions for the document frame
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 () {
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.");
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);
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.");
240 * Read the cookie data, set the hiddenGlobal and global fields
241 * and save the cookie again.
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
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;
261 cookies += '; path=/';
262 if (cookie.keep && cookie.keep != '0D') {
270 exp.setTime(exp.getTime() +
271 cookie.keep.substr(0,1) * ms[cookie.keep.substr(1,1)]);
272 cookies += '; expires=' + exp.toGMTString();
274 jsMath.window.document.cookie = 'jsMath='+cookies;
279 * Check if the control panel should be hidden
281 SetControls: function (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}
293 document.body.rows = rows;
297 * Remove the frame that holds the control panel
300 if (jsMath.Global.isHidden) return;
301 if (this.isMSIEmac) {
303 // MSIE/Mac can't remove the frame, so hide it (and the drag bar)
305 document.body.rows = "-6,*";
306 } else if (this.isOpera) {
308 // Opera can remove it, but it is unstable for that, but
309 // setting the size to -1 seems to remove it as well.
311 document.body.rows = "-1,*";
313 document.body.removeChild(this.controls);
314 document.body.rows = "*";
315 jsMath.window = jsMath.FrameWindow(1);
317 this.Global.isHidden = 1;
321 * Put back the control-panel frame
323 Show: function (bubble) {
324 if (!jsMath.Global.isHidden) {
325 if (bubble && jsMath.window) {jsMath.window.jsMath.Controls.Panel()}
328 if (!jsMath.isMSIEmac) {
329 document.body.insertBefore(jsMath.controls,jsMath.frame);
331 // Opera doesn't refresh the frames properly, so reload them
333 if (jsMath.isOpera) {
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
341 document.body.rows = jsMath.rows;
342 jsMath.window = jsMath.FrameWindow(1);
343 jsMath.Global.isHidden = 0;
350 var OK = confirm('Really empty the equation cache?');
351 if (OK) {jsMath.Global.ClearCache()}
355 * Find the largest common domain between the source file
356 * and the location of the jsMath files
358 Domain: function () {
360 // MSIE/Mac can't do domain changes, so don't bother trying
361 if (navigator.appName == 'Microsoft Internet Explorer' &&
362 !navigator.platform.match(/Mac/) && navigator.userProfile != null) return;
363 if (this.src == '') {
364 if (window == parent) return;
365 var oldDomain = document.domain;
368 try {if (parent.document.title != null) return} catch (err) {}
369 if (!document.domain.match(/\..*\./)) break;
370 document.domain = document.domain.replace(/^[^.]*\./,'');
373 document.domain = oldDomain;
375 if (!this.src.match(new RegExp('^[^:]+:\/\/([^/]+)(:[0-9]+)?\/'))) return;
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;
387 * Create the document content based on whether this is the initial
388 * call to this file, or the secondary one
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>');
399 document.writeln('<body><br/></body>');
409 jsMath.src = jsMath.GetURL();