commit 42306c4b0ca9d357d4592b156af2e87d0132b777
parent 3a8a9f5df9bc0c65361aa73ca696f1c9ed8f6f7d
Author: Davide P. Cervone <dpvc@union.edu>
Date: Fri, 19 Aug 2011 18:31:43 -0400
Move event-handling code to a separate file, loaded by output jax (so if MathJax is loaded on a page with no math, it doesn't have to be loaded)
Diffstat:
6 files changed, 460 insertions(+), 433 deletions(-)
diff --git a/unpacked/MathJax.js b/unpacked/MathJax.js
@@ -30,7 +30,7 @@ if (!window.MathJax) {window.MathJax= {}}
if (!MathJax.Hub) { // skip if already loaded
MathJax.version = "1.1a";
-MathJax.fileversion = "1.1.11";
+MathJax.fileversion = "1.1.12";
/**********************************************************/
@@ -900,379 +900,104 @@ MathJax.fileversion = "1.1.11";
/**********************************************************/
-(function (BASENAME) {
- var BASE = window[BASENAME];
- if (!BASE) {BASE = window[BASENAME] = {}}
- var AJAX = BASE.Ajax, CALLBACK = BASE.Callback;
-
- BASE.HTML = {
-
- //
- // Create an HTML element with given attributes and content.
- // The def parameter is an (optional) object containing key:value pairs
- // of the attributes and their values, and contents is an (optional)
- // array of strings to be inserted as text, or arrays of the form
- // [type,def,contents] that describes an HTML element to be inserted
- // into the current element. Thus the contents can describe a complete
- // HTML snippet of arbitrary complexity. E.g.:
- //
- // MathJax.HTML.Element("span",{id:"mySpan",style{"font-style":"italic"}},[
- // "(See the ",["a",{href:"http://www.mathjax.org"},["MathJax home page"]],
- // " for more details.)"]);
- //
- Element: function (type,def,contents) {
- var obj = document.createElement(type);
- if (def) {
- if (def.style) {
- var style = def.style; def.style = {};
- for (var id in style) {if (style.hasOwnProperty(id))
- {def.style[id.replace(/-([a-z])/g,this.ucMatch)] = style[id]}}
- }
- BASE.Hub.Insert(obj,def);
- }
- if (contents) {
- for (var i = 0; i < contents.length; i++) {
- if (contents[i] instanceof Array) {
- obj.appendChild(this.Element(contents[i][0],contents[i][1],contents[i][2]));
- } else {
- obj.appendChild(document.createTextNode(contents[i]));
- }
- }
- }
- return obj;
- },
- ucMatch: function (match,c) {return c.toUpperCase()},
- addElement: function (span,type,def,contents) {return span.appendChild(this.Element(type,def,contents))},
- TextNode: function (text) {return document.createTextNode(text)},
- addText: function (span,text) {return span.appendChild(this.TextNode(text))},
-
- //
- // Set the text of a script
- //
- setScript: function (script,text) {
- if (this.setScriptBug) {script.text = text} else {
- while (script.firstChild) {script.removeChild(script.firstChild)}
- this.addText(script,text);
- }
- },
-
- //
- // Manage cookies
- //
- Cookie: {
- prefix: "mjx",
- expires: 365,
-
- //
- // Save an object as a named cookie
- //
- Set: function (name,def) {
- var keys = [];
- if (def) {
- for (var id in def) {if (def.hasOwnProperty(id)) {
- keys.push(id+":"+def[id].toString().replace(/&/g,"&&"));
- }}
- }
- var cookie = this.prefix+"."+name+"="+escape(keys.join('&;'));
- if (this.expires) {
- var time = new Date(); time.setDate(time.getDate() + this.expires);
- cookie += '; expires='+time.toGMTString();
- }
- document.cookie = cookie+"; path=/";
- },
-
- //
- // Get the contents of a named cookie and incorporate
- // it into the given object (or return a fresh one)
- //
- Get: function (name,obj) {
- if (!obj) {obj = {}}
- var pattern = new RegExp("(?:^|;\\s*)"+this.prefix+"\\."+name+"=([^;]*)(?:;|$)");
- var match = pattern.exec(document.cookie);
- if (match && match[1] !== "") {
- var keys = unescape(match[1]).split('&;');
- for (var i = 0, m = keys.length; i < m; i++) {
- match = keys[i].match(/([^:]+):(.*)/);
- var value = match[2].replace(/&&/g,'&');
- if (value === "true") {value = true} else if (value === "false") {value = false}
- else if (value.match(/^-?(\d+(\.\d+)?|\.\d+)$/)) {value = parseFloat(value)}
- obj[match[1]] = value;
- }
- }
- return obj;
- }
- }
-
- };
-
- //
- // Common event-handling code
+MathJax.HTML = {
//
- var EVENT = BASE.HTML.Event = {
-
- LEFTBUTTON: 0, // the event.button value for left button
- MENUKEY: "altKey", // the event value for alternate context menu
-
- styles: {
- ".MathJax_Hover_Frame": {
- "border-radius": ".25em", // Opera 10.5 and IE9
- "-webkit-border-radius": ".25em", // Safari and Chrome
- "-moz-border-radius": ".25em", // Firefox
- "-khtml-border-radius": ".25em", // Konqueror
-
- "box-shadow": "0px 0px 15px #83A", // Opera 10.5 and IE9
- "-webkit-box-shadow": "0px 0px 15px #83A", // Safari and Chrome
- "-moz-box-shadow": "0px 0px 15px #83A", // Forefox 3.5
- "-khtml-box-shadow": "0px 0px 15px #83A", // Konqueror
-
- border: ".1em solid #A6D ! important",
- display: "inline-block", position:"absolute"
- },
-
- ".MathJax_Hover_Arrow": {
- position:"absolute",
- top:"-5px", right:"-9px",
- width:"15px", height:"11px",
- cursor:"pointer"
- }
- },
-
- Mousedown: function (event) {return EVENT.Handler(event,"Mousedown",this)},
- Mouseup: function (event) {return EVENT.Handler(event,"Mouseup",this)},
- Mousemove: function (event) {return EVENT.Handler(event,"Mousemove",this)},
- Mouseover: function (event) {return EVENT.Handler(event,"Mouseover",this)},
- Mouseout: function (event) {return EVENT.Handler(event,"Mouseout",this)},
- Click: function (event) {return EVENT.Handler(event,"Click",this)},
- DblClick: function (event) {return EVENT.Handler(event,"DblClick",this)},
- Menu: function (event) {return EVENT.Handler(event,"ContextMenu",this)},
-
- //
- // Call the output jax's event handler
- //
- Handler: function (event,type,math) {
- if (AJAX.loadingMathMenu) {return False(event)}
- var jax = BASE.OutputJax[math.jaxID];
- if (!event) {event = window.event}
- event.isContextMenu = (type === "ContextMenu");
- return jax.HandleEvent(event,type,math);
- },
- //
- // For use in the output jax (this will be the output jax)
- //
- HandleEvent: function (event,type,math) {
- if (this[type]) {return this[type].call(this,event,math)}
- if (MathJax.Extension.MathZoom)
- {return MathJax.Extension.MathZoom.HandleEvent(event,type,math)}
- },
-
-
- //
- // Try to cancel the event in every way we can
- //
- False: function (event) {
- if (!event) {event = window.event}
- if (event) {
- if (event.preventDefault) {event.preventDefault()}
- if (event.stopPropagation) {event.stopPropagation()}
- event.cancelBubble = true;
- event.returnValue = false;
- }
- return false;
- },
-
- //
- // Load the contextual menu code, if needed, and post the menu
- //
- ContextMenu: function (event,jax) {
- if (jax.hover) {
- if (jax.hover.remove) {clearTimeout(jax.hover.remove); delete jax.hover.remove}
- jax.hover.nofade = true;
+ // Create an HTML element with given attributes and content.
+ // The def parameter is an (optional) object containing key:value pairs
+ // of the attributes and their values, and contents is an (optional)
+ // array of strings to be inserted as text, or arrays of the form
+ // [type,def,contents] that describes an HTML element to be inserted
+ // into the current element. Thus the contents can describe a complete
+ // HTML snippet of arbitrary complexity. E.g.:
+ //
+ // MathJax.HTML.Element("span",{id:"mySpan",style{"font-style":"italic"}},[
+ // "(See the ",["a",{href:"http://www.mathjax.org"},["MathJax home page"]],
+ // " for more details.)"]);
+ //
+ Element: function (type,def,contents) {
+ var obj = document.createElement(type);
+ if (def) {
+ if (def.style) {
+ var style = def.style; def.style = {};
+ for (var id in style) {if (style.hasOwnProperty(id))
+ {def.style[id.replace(/-([a-z])/g,this.ucMatch)] = style[id]}}
}
- var MENU = BASE.Menu;
- if (MENU) {
- MENU.jax = jax;
- MENU.menu.Find("Format").menu.items[1].name =
- (MENU.jax.inputJax.id === "MathML" ? "Original" : MENU.jax.inputJax.id);
- return MENU.menu.Post(event);
- } else {
- if (!AJAX.loadingMathMenu) {
- AJAX.loadingMathMenu = true;
- var ev = {
- pageX:event.pageX, pageY:event.pageY,
- clientX:event.clientX, clientY:event.clientY
- };
- CALLBACK.Queue(
- AJAX.Require("[MathJax]/extensions/MathMenu.js"),
- function () {delete AJAX.loadingMathMenu; if (!BASE.Menu) {BASE.Menu = {}}},
- ["ContextMenu",this,ev,jax] // call this function again
- );
+ MathJax.Hub.Insert(obj,def);
+ }
+ if (contents) {
+ for (var i = 0; i < contents.length; i++) {
+ if (contents[i] instanceof Array) {
+ obj.appendChild(this.Element(contents[i][0],contents[i][1],contents[i][2]));
+ } else {
+ obj.appendChild(document.createTextNode(contents[i]));
}
- return this.False(event);
}
}
- };
-
+ return obj;
+ },
+ ucMatch: function (match,c) {return c.toUpperCase()},
+ addElement: function (span,type,def,contents) {return span.appendChild(this.Element(type,def,contents))},
+ TextNode: function (text) {return document.createTextNode(text)},
+ addText: function (span,text) {return span.appendChild(this.TextNode(text))},
+
//
- // Handle hover "discoverability"
+ // Set the text of a script
//
- var HOVER = BASE.HTML.Hover = {
- Mouseover: function (event,math) {
- var from = event.fromElement || event.relatedTarget,
- to = event.toElement || event.target;
- if (from && to && from.isMathJax != to.isMathJax) {
- var jax = this.getJaxFromMath(math);
- if (jax.hover) {HOVER.ReHover(jax)} else {HOVER.HoverTimer(jax,math)}
- return EVENT.False(event);
- }
- },
- Mouseout: function (event,math) {
- var from = event.fromElement || event.relatedTarget,
- to = event.toElement || event.target;
- if (from && to && from.isMathJax != to.isMathJax) {
- var jax = this.getJaxFromMath(math);
- if (jax.hover) {HOVER.UnHover(jax)} else {HOVER.ClearHoverTimer()}
- return EVENT.False(event);
- }
- },
- Mousemove: function (event,math) {
- var jax = this.getJaxFromMath(math); if (jax.hover) return;
- if (HOVER.lastX == event.clientX && HOVER.lastY == event.clientY) return;
- HOVER.lastX = event.clientX; HOVER.lastY = event.clientY;
- HOVER.HoverTimer(jax,math);
- return EVENT.False(event);
- },
-
- HoverTimer: function (jax,math) {
- this.ClearHoverTimer();
- var delay = BASE.Hub.config.menuSettings.hover;
- this.hoverTimer = setTimeout(CALLBACK(["Hover",this,jax,math]),delay);
- },
- ClearHoverTimer: function () {
- if (this.hoverTimer) {clearTimeout(this.hoverTimer); delete this.hoverTimer}
- },
-
- Hover: function (jax,math) {
- // check for MathZoom hover
- var JAX = jax.outputJax, span = JAX.getHoverSpan(jax), bbox = JAX.getHoverBBox(jax,span);
- var dx = .25, dy = .33, dd = .1; // frame size
- jax.hover = {opacity:0};
- if (this.msieBorderWidthBug) {dd = 0}
- jax.hover.id = "MathJax-Hover-"+jax.inputID.replace(/.*-(\d+)$/,"$1");
- var frame = BASE.HTML.Element("span",{
- id:jax.hover.id, isMathJax: true,
- style:{display:"inline-block", "z-index":1, width:0, height:0, position:"relative"}
- },[["span",{
- className:"MathJax_Hover_Frame", isMathJax: true,
- style:{
- display:"inline-block", position:"absolute",
- top:this.Em(-bbox.h-dy-dd), left:this.Em(-dx-dd),
- width:this.Em(bbox.w+2*dx), height:this.Em(bbox.h+bbox.d+2*dy),
- opacity:0, filter:"alpha(opacity=0)"
- }},[[
- "img",{
- className: "MathJax_Hover_Arrow", isMathJax: true, math: math,
- src: BASE.Ajax.fileURL(MathJax.OutputJax.imageDir+"/MenuArrow-15.png"),
- onclick: this.HoverMenu, jax:JAX.id
- }
- ]]
- ]]
- );
- span.parentNode.insertBefore(frame,span); span.style.position = "relative";
- this.ReHover(jax,.2);
- },
- ReHover: function (jax) {
- if (jax.hover.remove) {clearTimeout(jax.hover.remove)}
- jax.hover.remove = setTimeout(MathJax.Callback(["UnHover",this,jax]),15*1000);
- this.HoverFadeTimer(jax,.2);
- },
- UnHover: function (jax) {
- if (!jax.hover.nofade) {this.HoverFadeTimer(jax,-.05,400)}
- },
- HoverFade: function (jax) {
- delete jax.hover.timer;
- jax.hover.opacity = Math.max(0,Math.min(1,jax.hover.opacity + jax.hover.inc));
- jax.hover.opacity = Math.floor(1000*jax.hover.opacity)/1000;
- var span = document.getElementById(jax.hover.id);
- span.firstChild.style.opacity = jax.hover.opacity;
- span.firstChild.style.filter = "alpha(opacity="+Math.floor(100*jax.hover.opacity)+")";
- if (jax.hover.opacity === 1) {return}
- if (jax.hover.opacity) {this.HoverFadeTimer(jax,jax.hover.inc); return}
- var frame = document.getElementById(jax.hover.id);
- frame.parentNode.removeChild(frame);
- if (jax.hover.remove) {clearTimeout(jax.hover.remove)}
- delete jax.hover;
- },
- HoverFadeTimer: function (jax,inc,delay) {
- jax.hover.inc = inc;
- if (!jax.hover.timer) {
- jax.hover.timer = setTimeout(MathJax.Callback(["HoverFade",this,jax]),(delay||50));
- }
- },
- HoverMenu: function (event) {
- if (!event) {event = window.event}
- BASE.OutputJax[this.jax].ContextMenu(event,this.math,true);
- },
-
- Em: function (m) {
- if (Math.abs(m) < .0006) {return "0em"}
- return m.toFixed(3).replace(/\.?0+$/,"") + "em";
+ setScript: function (script,text) {
+ if (this.setScriptBug) {script.text = text} else {
+ while (script.firstChild) {script.removeChild(script.firstChild)}
+ this.addText(script,text);
}
+ },
- };
-
- //
- // Handle touch events.
//
- // Use double-tap-and-hold as a replacement for context menu event.
- // Use double-tap as a replacement for double click.
+ // Manage cookies
//
- var TOUCH = BASE.HTML.Touch = {
-
- last: 0, // time of last tap event
- delay: 500, // delay time for double-click
+ Cookie: {
+ prefix: "mjx",
+ expires: 365,
//
- // Check if this is a double-tap, and if so, start the timer
- // for the double-tap and hold (to trigger the contextual menu)
+ // Save an object as a named cookie
//
- start: function (event) {
- var now = new Date().getTime();
- var dblTap = (now - TOUCH.last < TOUCH.delay);
- TOUCH.last = now;
- if (dblTap) {
- TOUCH.timeout = setTimeout(TOUCH.menu,TOUCH.delay,event,this);
- event.preventDefault();
+ Set: function (name,def) {
+ var keys = [];
+ if (def) {
+ for (var id in def) {if (def.hasOwnProperty(id)) {
+ keys.push(id+":"+def[id].toString().replace(/&/g,"&&"));
+ }}
}
- },
-
- //
- // Check if there is a timeout pending, i.e., we have a
- // double-tap and were waiting to see if it is held long
- // enough for the menu. Since we got the end before the
- // timeout, it is a double-click, not a double-tap-and-hold.
- // Prevent the default action and issue a double click.
- //
- end: function (event) {
- if (TOUCH.timeout) {
- clearTimeout(TOUCH.timeout);
- delete TOUCH.timeout; TOUCH.last = 0;
- event.preventDefault();
- return EVENT.Handler((event.touches[0]||event.touch),"DblClick",this);
+ var cookie = this.prefix+"."+name+"="+escape(keys.join('&;'));
+ if (this.expires) {
+ var time = new Date(); time.setDate(time.getDate() + this.expires);
+ cookie += '; expires='+time.toGMTString();
}
+ document.cookie = cookie+"; path=/";
},
-
- //
- // If the timeout passes without an end event, we issue
- // the contextual menu event.
+
//
- menu: function (event,math) {
- delete TOUCH.timeout; TOUCH.last = 0;
- return EVENT.Handler((event.touches[0]||event.touch),"ContextMenu",math);
+ // Get the contents of a named cookie and incorporate
+ // it into the given object (or return a fresh one)
+ //
+ Get: function (name,obj) {
+ if (!obj) {obj = {}}
+ var pattern = new RegExp("(?:^|;\\s*)"+this.prefix+"\\."+name+"=([^;]*)(?:;|$)");
+ var match = pattern.exec(document.cookie);
+ if (match && match[1] !== "") {
+ var keys = unescape(match[1]).split('&;');
+ for (var i = 0, m = keys.length; i < m; i++) {
+ match = keys[i].match(/([^:]+):(.*)/);
+ var value = match[2].replace(/&&/g,'&');
+ if (value === "true") {value = true} else if (value === "false") {value = false}
+ else if (value.match(/^-?(\d+(\.\d+)?|\.\d+)$/)) {value = parseFloat(value)}
+ obj[match[1]] = value;
+ }
+ }
+ return obj;
}
+ }
- };
-
-})("MathJax");
+};
/**********************************************************/
@@ -1781,7 +1506,6 @@ MathJax.Hub = {
}
};
MathJax.Hub.Insert(MathJax.Hub.config.styles,MathJax.Message.styles);
-MathJax.Hub.Insert(MathJax.Hub.config.styles,MathJax.HTML.Event.styles);
MathJax.Hub.Insert(MathJax.Hub.config.styles,{".MathJax_Error":MathJax.Hub.config.errorSettings.style});
//
@@ -2348,9 +2072,6 @@ MathJax.Hub.Startup = {
MSIE: function (browser) {
browser.isIE9 = !!(document.documentMode && (window.performance || window.msPerformance));
MathJax.HTML.setScriptBug = !browser.isIE9 || document.documentMode < 9;
- MathJax.HTML.Event.msieButtonBug = (document.documentMode||0) >= 9;
- if ((document.documentMode||0) < 9) {MathJax.HTML.Event.LEFTBUTTON = 1}
- MathJax.HTML.Event.msieBorderWidthBug = (document.compatMode === "BackCompat");
}
});
HUB.Browser.Select(MathJax.Message.browsers);
diff --git a/unpacked/extensions/MathMenu.js b/unpacked/extensions/MathMenu.js
@@ -134,11 +134,11 @@
}
});
- /*************************************************************/
- /*
- * Cancel event's default action (try everything we can)
- */
- var FALSE = MathJax.HTML.Event.False;
+ var FALSE, HOVER;
+ MathJax.Hub.Register.StartupHook("UIevents Ready",function () {
+ FALSE = MathJax.Extension.UIevents.Event.False;
+ HOVER = MathJax.Extension.UIevents.Hover;
+ });
/*************************************************************/
/*
@@ -167,8 +167,8 @@
delete MENU.skipUp;
}
var menu = HTML.addElement(div,"div",{
- onmouseup: MENU.Mouseup, ondblclick: this.False,
- ondragstart: this.False, onselectstart: this.False, oncontextmenu: this.False,
+ onmouseup: MENU.Mouseup, ondblclick: FALSE,
+ ondragstart: FALSE, onselectstart: FALSE, oncontextmenu: FALSE,
menuItem: this, className: "MathJax_Menu"
},title);
@@ -178,7 +178,7 @@
src: MathJax.Ajax.fileURL(MathJax.OutputJax.imageDir+"/CloseX-31.png"),
width: 31, height: 31, menu: parent,
style: {position:"absolute", top:"-15px", left:"-15px"},
- ontouchstart: MENU.Close, ontouchend: this.False, onmousedown: MENU.Close
+ ontouchstart: MENU.Close, ontouchend: FALSE, onmousedown: MENU.Close
});
}
this.posted = true;
@@ -215,7 +215,7 @@
menu.style.left = x+"px"; menu.style.top = y+"px";
if (document.selection && document.selection.empty) {document.selection.empty()}
- return this.False(event);
+ return FALSE(event);
},
/*
@@ -229,12 +229,10 @@
}
if (MENU.jax.hover) {
delete MENU.jax.hover.nofade;
- HTML.Hover.UnHover(MENU.jax);
+ HOVER.UnHover(MENU.jax);
}
},
- False: FALSE,
-
/*
* Find a named item in a menu (or submenu).
* A lsit of names means descend into submenus.
@@ -345,7 +343,7 @@
var def = {
onmouseover: MENU.Mouseover, onmouseout: MENU.Mouseout,
onmouseup: MENU.Mouseup, onmousedown: MENU.Mousedown,
- ondragstart: this.False, onselectstart: this.False, onselectend: this.False,
+ ondragstart: FALSE, onselectstart: FALSE, onselectend: FALSE,
ontouchstart: MENU.Touchstart, ontouchend: MENU.Touchend,
className: "MathJax_MenuItem", menuItem: this
};
@@ -399,8 +397,7 @@
Activate: function (menu) {this.Deactivate(menu); menu.className += " MathJax_MenuActive"},
Deactivate: function (menu) {menu.className = menu.className.replace(/ MathJax_MenuActive/,"")},
- With: function (def) {if (def) {HUB.Insert(this,def)}; return this},
- False: FALSE
+ With: function (def) {if (def) {HUB.Insert(this,def)}; return this}
});
/*************************************************************/
@@ -418,7 +415,7 @@
Label: function (def,menu) {return [this.name]},
Mouseup: function (event,menu) {
if (!this.disabled) {this.Remove(event,menu); this.action.call(this,event);}
- return this.False(event);
+ return FALSE(event);
}
});
@@ -467,7 +464,7 @@
}
}
}
- return this.False(event);
+ return FALSE(event);
}
});
@@ -502,7 +499,7 @@
if (this.action) {this.action.call(MENU)}
}
this.Remove(event,menu);
- return this.False(event);
+ return FALSE(event);
}
});
@@ -530,7 +527,7 @@
if (this.action) {this.action.call(MENU)}
}
this.Remove(event,menu);
- return this.False(event);
+ return FALSE(event);
}
});
@@ -866,7 +863,7 @@
if (MENU.isMobile) {
(function () {
- var settings = MathJax.Hub.config.menuSettings;
+ var settings = CONFIG.settings;
var trigger = MENU.menu.Find("Settings","Zoom Trigger").menu;
trigger.items[0].disabled = trigger.items[1].disabled = true;
if (settings.zoom === "Hover" || settings.zoom == "Click") {settings.zoom = "None"}
diff --git a/unpacked/extensions/MathZoom.js b/unpacked/extensions/MathZoom.js
@@ -23,7 +23,7 @@
*/
(function (HUB,HTML,AJAX,HTMLCSS,nMML) {
- var VERSION = "1.1";
+ var VERSION = "1.1.2";
var CONFIG = HUB.CombineConfig("MathZoom",{
delay: 400, // mouse must be still this long (milliseconds)
@@ -57,11 +57,11 @@
}
});
- /*************************************************************/
- /*
- * Cancel event's default action (try everything we can)
- */
- var FALSE = MathJax.HTML.Event.False;
+ var FALSE, HOVER;
+ MathJax.Hub.Register.StartupHook("UIevents Ready",function () {
+ FALSE = MathJax.Extension.UIevents.Event.False;
+ HOVER = MathJax.Extension.UIevents.Hover;
+ });
/*************************************************************/
@@ -95,40 +95,19 @@
},
//
- // Zoom on hover
+ // Zoom on hover (called by UI.Hover)
//
- Mouseover: function (event,math) {
- if (this.settings.zoom === "Hover") {
- ZOOM.oldMouseOver = math.onmouseover;
- math.onmouseover = null;
- math.onmousemove = this.Mousemove;
- math.onmouseout = this.Mouseout;
- return ZOOM.Timer(event,math);
- }
- },
- Mouseout: function (event) {
- this.onmouseover = ZOOM.oldMouseOver; delete ZOOM.oldMouseOver;
- this.onmousemove = this.onmouseout = null;
- ZOOM.ClearTimer();
- return FALSE(event);
- },
- Mousemove: function (event) {
- return ZOOM.Timer(event||window.event,this);
- },
- Timer: function (event,math) {
- this.ClearTimer();
- this.timer = setTimeout(MathJax.Callback(["Zoom",this,math,{}]),CONFIG.delay);
- return FALSE(event);
- },
- ClearTimer: function () {
- if (this.timer) {clearTimeout(this.timer); delete this.timer}
+ Hover: function (event,math) {
+ if (this.settings.zoom === "Hover") {this.Zoom(math,event); return true}
+ return false;
},
+
//
// Handle the actual zooming
//
Zoom: function (math,event) {
- this.ClearTimer(); this.Remove();
+ this.Remove();
//
// Find the jax and its type
@@ -141,6 +120,7 @@
var JAX = (HTMLCSS && jax.outputJax.isa(HTMLCSS.constructor) ? "HTMLCSS" :
(nMML && jax.outputJax.isa(nMML.constructor) ? "MathML" : null));
if (!JAX) return; // FIXME: report an error?
+ if (jax.hover) {HOVER.UnHover(jax)}
//
// Create the DOM elements for the zoom box
@@ -331,15 +311,18 @@
},
MSIEmouseover: function (event,math,span) {
if (this.settings.zoom !== "Hover") {return false}
- ZOOM.Timer(event,math); return true;
+ return !HOVER.Mouseover(event,math);
+// ZOOM.Timer(event,math); return true;
},
MSIEmouseout: function (event,math,span) {
if (this.settings.zoom !== "Hover") {return false}
- ZOOM.ClearTimer(); return true;
+ return !HOVER.Mouseout(event,math);
+// ZOOM.ClearTimer(); return true;
},
MSIEmousemove: function (event,math,span) {
if (this.settings.zoom !== "Hover") {return false}
- ZOOM.Timer(event,math); return true;
+ return !HOVER.Mousemove(event,math);
+// ZOOM.Timer(event,math); return true;
},
MSIEzoomKeys: function (event) {
if (this.settings.CTRL && !event.ctrlKey) return false;
diff --git a/unpacked/extensions/UIevents.js b/unpacked/extensions/UIevents.js
@@ -0,0 +1,331 @@
+/*************************************************************
+ *
+ * MathJax/extensions/UIevents.js
+ *
+ * Implements the event handlers needed by the output jax to perform
+ * menu, hover, and other events.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2011 Design Science, Inc.
+ *
+ * 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.
+ */
+
+(function (HUB,HTML,AJAX,CALLBACK,OUTPUT) {
+ var VERSION = "1.1";
+
+ var EXTENSION = MathJax.Extension;
+ var UI = EXTENSION.UIevents = {version: VERSION};
+
+ var SETTINGS = HUB.config.menuSettings;
+
+ var CONFIG = {
+ styles: {
+ ".MathJax_Hover_Frame": {
+ "border-radius": ".25em", // Opera 10.5 and IE9
+ "-webkit-border-radius": ".25em", // Safari and Chrome
+ "-moz-border-radius": ".25em", // Firefox
+ "-khtml-border-radius": ".25em", // Konqueror
+
+ "box-shadow": "0px 0px 15px #83A", // Opera 10.5 and IE9
+ "-webkit-box-shadow": "0px 0px 15px #83A", // Safari and Chrome
+ "-moz-box-shadow": "0px 0px 15px #83A", // Forefox 3.5
+ "-khtml-box-shadow": "0px 0px 15px #83A", // Konqueror
+
+ border: ".1em solid #A6D ! important",
+ display: "inline-block", position:"absolute"
+ },
+
+ ".MathJax_Hover_Arrow": {
+ position:"absolute",
+ top:"-5px", right:"-9px",
+ width:"15px", height:"11px",
+ cursor:"pointer"
+ }
+ }
+ };
+
+
+ //
+ // Common event-handling code
+ //
+ var EVENT = UI.Event = {
+
+ LEFTBUTTON: 0, // the event.button value for left button
+ MENUKEY: "altKey", // the event value for alternate context menu
+
+ Mousedown: function (event) {return EVENT.Handler(event,"Mousedown",this)},
+ Mouseup: function (event) {return EVENT.Handler(event,"Mouseup",this)},
+ Mousemove: function (event) {return EVENT.Handler(event,"Mousemove",this)},
+ Mouseover: function (event) {return EVENT.Handler(event,"Mouseover",this)},
+ Mouseout: function (event) {return EVENT.Handler(event,"Mouseout",this)},
+ Click: function (event) {return EVENT.Handler(event,"Click",this)},
+ DblClick: function (event) {return EVENT.Handler(event,"DblClick",this)},
+ Menu: function (event) {return EVENT.Handler(event,"ContextMenu",this)},
+
+ //
+ // Call the output jax's event handler
+ //
+ Handler: function (event,type,math) {
+ if (AJAX.loadingMathMenu) {return False(event)}
+ var jax = OUTPUT[math.jaxID];
+ if (!event) {event = window.event}
+ event.isContextMenu = (type === "ContextMenu");
+ return jax.HandleEvent(event,type,math);
+ },
+ //
+ // For use in the output jax (this will be the output jax)
+ //
+ HandleEvent: function (event,type,math) {
+ if (this[type]) {return this[type].call(this,event,math)}
+ if (EXTENSION.MathZoom) {return EXTENSION.MathZoom.HandleEvent(event,type,math)}
+ },
+
+
+ //
+ // Try to cancel the event in every way we can
+ //
+ False: function (event) {
+ if (!event) {event = window.event}
+ if (event) {
+ if (event.preventDefault) {event.preventDefault()}
+ if (event.stopPropagation) {event.stopPropagation()}
+ event.cancelBubble = true;
+ event.returnValue = false;
+ }
+ return false;
+ },
+
+ //
+ // Load the contextual menu code, if needed, and post the menu
+ //
+ ContextMenu: function (event,jax) {
+ if (jax.hover) {
+ if (jax.hover.remove) {clearTimeout(jax.hover.remove); delete jax.hover.remove}
+ jax.hover.nofade = true;
+ }
+ var MENU = MathJax.Menu;
+ if (MENU) {
+ MENU.jax = jax;
+ MENU.menu.Find("Format").menu.items[1].name =
+ (jax.inputJax.id === "MathML" ? "Original" : jax.inputJax.id);
+ return MENU.menu.Post(event);
+ } else {
+ if (!AJAX.loadingMathMenu) {
+ AJAX.loadingMathMenu = true;
+ var ev = {
+ pageX:event.pageX, pageY:event.pageY,
+ clientX:event.clientX, clientY:event.clientY
+ };
+ CALLBACK.Queue(
+ AJAX.Require("[MathJax]/extensions/MathMenu.js"),
+ function () {delete AJAX.loadingMathMenu; if (!MathJax.Menu) {MathJax.Menu = {}}},
+ ["ContextMenu",this,ev,jax] // call this function again
+ );
+ }
+ return this.False(event);
+ }
+ }
+ };
+
+ //
+ // Handle hover "discoverability"
+ //
+ var HOVER = UI.Hover = {
+ Mouseover: function (event,math) {
+ var from = event.fromElement || event.relatedTarget,
+ to = event.toElement || event.target;
+ if (from && to && from.isMathJax != to.isMathJax) {
+ var jax = this.getJaxFromMath(math);
+ if (jax.hover) {HOVER.ReHover(jax)} else {HOVER.HoverTimer(jax,math)}
+ return EVENT.False(event);
+ }
+ },
+ Mouseout: function (event,math) {
+ var from = event.fromElement || event.relatedTarget,
+ to = event.toElement || event.target;
+ if (from && to && from.isMathJax != to.isMathJax) {
+ var jax = this.getJaxFromMath(math);
+ if (jax.hover) {HOVER.UnHover(jax)} else {HOVER.ClearHoverTimer()}
+ return EVENT.False(event);
+ }
+ },
+ Mousemove: function (event,math) {
+ var jax = this.getJaxFromMath(math); if (jax.hover) return;
+ if (HOVER.lastX == event.clientX && HOVER.lastY == event.clientY) return;
+ HOVER.lastX = event.clientX; HOVER.lastY = event.clientY;
+ HOVER.HoverTimer(jax,math);
+ return EVENT.False(event);
+ },
+
+ HoverTimer: function (jax,math) {
+ this.ClearHoverTimer();
+ this.hoverTimer = setTimeout(CALLBACK(["Hover",this,jax,math]),SETTINGS.hover);
+ },
+ ClearHoverTimer: function () {
+ if (this.hoverTimer) {clearTimeout(this.hoverTimer); delete this.hoverTimer}
+ },
+
+ Hover: function (jax,math) {
+ if (EXTENSION.MathZoom && EXTENSION.MathZoom.Hover(event,math)) return;
+ var JAX = jax.outputJax, span = JAX.getHoverSpan(jax), bbox = JAX.getHoverBBox(jax,span);
+ var dx = .25, dy = .33, dd = .1; // frame size
+ jax.hover = {opacity:0};
+ if (this.msieBorderWidthBug) {dd = 0}
+ jax.hover.id = "MathJax-Hover-"+jax.inputID.replace(/.*-(\d+)$/,"$1");
+ var frame = HTML.Element("span",{
+ id:jax.hover.id, isMathJax: true,
+ style:{display:"inline-block", "z-index":1, width:0, height:0, position:"relative"}
+ },[["span",{
+ className:"MathJax_Hover_Frame", isMathJax: true,
+ style:{
+ display:"inline-block", position:"absolute",
+ top:this.Em(-bbox.h-dy-dd), left:this.Em(-dx-dd),
+ width:this.Em(bbox.w+2*dx), height:this.Em(bbox.h+bbox.d+2*dy),
+ opacity:0, filter:"alpha(opacity=0)"
+ }},[[
+ "img",{
+ className: "MathJax_Hover_Arrow", isMathJax: true, math: math,
+ src: AJAX.fileURL(OUTPUT.imageDir+"/MenuArrow-15.png"),
+ onclick: this.HoverMenu, jax:JAX.id
+ }
+ ]]
+ ]]
+ );
+ span.parentNode.insertBefore(frame,span); span.style.position = "relative";
+ this.ReHover(jax,.2);
+ },
+ ReHover: function (jax) {
+ if (jax.hover.remove) {clearTimeout(jax.hover.remove)}
+ jax.hover.remove = setTimeout(CALLBACK(["UnHover",this,jax]),15*1000);
+ this.HoverFadeTimer(jax,.2);
+ },
+ UnHover: function (jax) {
+ if (!jax.hover.nofade) {this.HoverFadeTimer(jax,-.05,400)}
+ },
+ HoverFade: function (jax) {
+ delete jax.hover.timer;
+ jax.hover.opacity = Math.max(0,Math.min(1,jax.hover.opacity + jax.hover.inc));
+ jax.hover.opacity = Math.floor(1000*jax.hover.opacity)/1000;
+ var span = document.getElementById(jax.hover.id);
+ span.firstChild.style.opacity = jax.hover.opacity;
+ span.firstChild.style.filter = "alpha(opacity="+Math.floor(100*jax.hover.opacity)+")";
+ if (jax.hover.opacity === 1) {return}
+ if (jax.hover.opacity) {this.HoverFadeTimer(jax,jax.hover.inc); return}
+ var frame = document.getElementById(jax.hover.id);
+ frame.parentNode.removeChild(frame);
+ if (jax.hover.remove) {clearTimeout(jax.hover.remove)}
+ delete jax.hover;
+ },
+ HoverFadeTimer: function (jax,inc,delay) {
+ jax.hover.inc = inc;
+ if (!jax.hover.timer) {
+ jax.hover.timer = setTimeout(CALLBACK(["HoverFade",this,jax]),(delay||50));
+ }
+ },
+ HoverMenu: function (event) {
+ if (!event) {event = window.event}
+ OUTPUT[this.jax].ContextMenu(event,this.math,true);
+ },
+
+ Em: function (m) {
+ if (Math.abs(m) < .0006) {return "0em"}
+ return m.toFixed(3).replace(/\.?0+$/,"") + "em";
+ },
+
+ //
+ // Preload images so they show up with the menu
+ //
+ getImages: function () {
+ var menu = new Image();
+ menu.src = AJAX.fileURL(OUTPUT.imageDir+"/MenuArrow-15.png");
+ }
+
+ };
+
+ //
+ // Handle touch events.
+ //
+ // Use double-tap-and-hold as a replacement for context menu event.
+ // Use double-tap as a replacement for double click.
+ //
+ var TOUCH = UI.Touch = {
+
+ last: 0, // time of last tap event
+ delay: 500, // delay time for double-click
+
+ //
+ // Check if this is a double-tap, and if so, start the timer
+ // for the double-tap and hold (to trigger the contextual menu)
+ //
+ start: function (event) {
+ var now = new Date().getTime();
+ var dblTap = (now - TOUCH.last < TOUCH.delay);
+ TOUCH.last = now;
+ if (dblTap) {
+ TOUCH.timeout = setTimeout(TOUCH.menu,TOUCH.delay,event,this);
+ event.preventDefault();
+ }
+ },
+
+ //
+ // Check if there is a timeout pending, i.e., we have a
+ // double-tap and were waiting to see if it is held long
+ // enough for the menu. Since we got the end before the
+ // timeout, it is a double-click, not a double-tap-and-hold.
+ // Prevent the default action and issue a double click.
+ //
+ end: function (event) {
+ if (TOUCH.timeout) {
+ clearTimeout(TOUCH.timeout);
+ delete TOUCH.timeout; TOUCH.last = 0;
+ event.preventDefault();
+ return EVENT.Handler((event.touches[0]||event.touch),"DblClick",this);
+ }
+ },
+
+ //
+ // If the timeout passes without an end event, we issue
+ // the contextual menu event.
+ //
+ menu: function (event,math) {
+ delete TOUCH.timeout; TOUCH.last = 0;
+ return EVENT.Handler((event.touches[0]||event.touch),"ContextMenu",math);
+ }
+
+ };
+
+ if (MathJax.Hub.Browser.isMobile) {
+ var arrow = CONFIG.styles[".MathJax_Hover_Arrow"];
+ arrow.width = "25px"; arrow.height = "18px";
+ arrow.top = "-11px"; arrow.right = "-15px";
+ }
+
+ HUB.Browser.Select({
+ MSIE: function (browser) {
+ if ((document.documentMode||0) < 9) {EVENT.LEFTBUTTON = 1}
+ EVENT.msieBorderWidthBug = (document.compatMode === "BackCompat");
+ }
+ });
+
+ CONFIG = HUB.CombineConfig("UIevents",CONFIG);
+
+ CALLBACK.Queue(
+ ["getImages",HOVER],
+ ["Styles",AJAX,CONFIG.styles],
+ ["Post",HUB.Startup.signal,"UIevents Ready"],
+ ["loadComplete",AJAX,"[MathJax]/extensions/UIevents.js"]
+ );
+
+})(MathJax.Hub,MathJax.HTML,MathJax.Ajax,MathJax.Callback,MathJax.OutputJax);
+\ No newline at end of file
diff --git a/unpacked/jax/output/HTML-CSS/config.js b/unpacked/jax/output/HTML-CSS/config.js
@@ -24,7 +24,7 @@
MathJax.OutputJax["HTML-CSS"] = MathJax.OutputJax({
id: "HTML-CSS",
- version: "1.1.9",
+ version: "1.1.10",
directory: MathJax.OutputJax.directory + "/HTML-CSS",
extensionDir: MathJax.OutputJax.extensionDir + "/HTML-CSS",
autoloadDir: MathJax.OutputJax.directory + "/HTML-CSS/autoload",
diff --git a/unpacked/jax/output/HTML-CSS/jax.js b/unpacked/jax/output/HTML-CSS/jax.js
@@ -182,10 +182,7 @@
}
});
- var EVENT = MathJax.HTML.Event;
- var TOUCH = MathJax.HTML.Touch;
- var HOVER = MathJax.HTML.Hover;
-
+ var EVENT, TOUCH, HOVER; // filled in later
HTMLCSS.Augment({
config: {
@@ -302,9 +299,19 @@
}
HUB.Startup.signal.Post("HTML-CSS Jax - no valid font");
}
+ this.require.push(MathJax.OutputJax.extensionDir+"/UIevents.js");
},
Startup: function () {
+ // Set up event handling
+ EVENT = MathJax.Extension.UIevents.Event;
+ TOUCH = MathJax.Extension.UIevents.Touch;
+ HOVER = MathJax.Extension.UIevents.Hover;
+ this.HandleEvent = EVENT.HandleEvent;
+ this.Mouseover = HOVER.Mouseover;
+ this.Mouseout = HOVER.Mouseout;
+ this.Mousemove = HOVER.Mousemove;
+
// Set up default fonts
var family = [], fonts = this.FONTDATA.VARIANT.normal.fonts;
if (!(fonts instanceof Array)) {fonts = [fonts]}
@@ -418,7 +425,6 @@
if (this.useProcessingFrame) frame.parentNode.replaceChild(div,frame);
},
- HandleEvent: EVENT.HandleEvent,
ContextMenu: function (event,math,force) {
if (this.config.showMathMenu && (this.settings.context === "MathJax" || force)) {
if (this.safariContextMenuBug) {setTimeout("window.getSelection().empty()",0)}
@@ -432,15 +438,11 @@
if (this.settings.context === "MathJax") {
if (!this.noContextMenuBug || event.button !== 2) return
} else {
- var BUTTON = (EVENT.msieButtonBug ? event.buttons & 1 : event.button);
- if (!event[EVENT.MENUKEY] || BUTTON !== EVENT.LEFTBUTTON) return
+ if (!event[EVENT.MENUKEY] || event.button !== EVENT.LEFTBUTTON) return
}
return this.ContextMenu(event,math,true);
}
},
- Mouseover: HOVER.Mouseover,
- Mouseout: HOVER.Mouseout,
- Mousemove: HOVER.Mousemove,
getJaxFromMath: function (math) {
if (math.parentNode.className === "MathJax_Display") {math = math.parentNode}
return HUB.getJaxFor(math.nextSibling);
@@ -2150,14 +2152,6 @@
HUB.Register.StartupHook("End Config",function () {
- /*
- * if (MathJax.Hub.Browser.isMobile) {
- * var arrow = HTMLCSS.config.styles[".MathJax_Hover_Arrow"];
- * arrow.width = "25px"; arrow.height = "18px";
- * arrow.top = "-11px"; arrow.right = "-15px";
- * }
- */
-
//
// Handle browser-specific setup
//