Merge pull request #1263 from dpvc/issue1250

Use less-aggressive CSS for ltr and inline-block, and do Edge check within the extension.
This commit is contained in:
Davide P. Cervone 2015-09-14 06:59:40 -04:00
commit 54854f88c1
15 changed files with 794 additions and 238 deletions

View File

@ -2569,6 +2569,8 @@ MathJax.Hub.Startup = {
}
if (SETTINGS.FastPreview && !MathJax.Extension["fast-preview"])
MathJax.Hub.config.extensions.push("fast-preview.js");
if (config.menuSettings.assistiveMML && !MathJax.Extension.AssistiveMML)
MathJax.Hub.config.extensions.push("AssistiveMML.js");
},MathJax.Hub.config],
["Post",this.signal,"End Cookie"]
);
@ -3090,12 +3092,13 @@ MathJax.Hub.Startup = {
isMac: (navigator.platform.substr(0,3) === "Mac"),
isPC: (navigator.platform.substr(0,3) === "Win"),
isMSIE: ("ActiveXObject" in window && "clipboardData" in window),
isMsEdge: (!!AGENT.match(/Edge\//)),
isEdge: ("MSGestureEvent" in window && "chrome" in window &&
window.chrome.loadTimes == null),
isFirefox: (!!AGENT.match(/Gecko\//) && !AGENT.match(/like Gecko/)),
isSafari: (!!AGENT.match(/ (Apple)?WebKit\//) && !AGENT.match(/ like iPhone /) &&
(!window.chrome || window.chrome.loadTimes == null)),
isChrome: (window.chrome != null && window.chrome.loadTimes != null),
isOpera: (window.opera != null && window.opera.version != null),
(!window.chrome || window.chrome.app == null)),
isChrome: ("chrome" in window && window.chrome.loadTimes != null),
isOpera: ("opera" in window && window.opera.version != null),
isKonqueror: ("konqueror" in window && navigator.vendor == "KDE"),
versionAtLeast: function (v) {
var bv = (this.version).split('.'); v = (new String(v)).split('.');
@ -3123,7 +3126,7 @@ MathJax.Hub.Startup = {
HUB.Browser = HUB.Insert(new String(browser),BROWSERS);
var VERSION = new RegExp(
".*(Version/| Trident/.*; rv:)((?:\\d+\\.)+\\d+)|" + // for Safari, Opera10, and IE11+
".*("+browser+")"+(browser == "MSIE" ? " " : "/")+"((?:\\d+\\.)*\\d+)|"+ // for one of the main browser
".*("+browser+")"+(browser == "MSIE" ? " " : "/")+"((?:\\d+\\.)*\\d+)|"+ // for one of the main browsers
"(?:^|\\(| )([a-z][-a-z0-9._: ]+|(?:Apple)?WebKit)/((?:\\d+\\.)+\\d+)"); // for unrecognized browser
var MATCH = VERSION.exec(xAGENT) || ["","","","unknown","0.0"];
HUB.Browser.name = (MATCH[1] != "" ? browser : (MATCH[3] || MATCH[5]));
@ -3177,8 +3180,15 @@ MathJax.Hub.Startup = {
AGENT.match(/ Fennec\//) != null ||
AGENT.match(/Mobile/) != null);
},
Chrome: function (browser) {
browser.noContextMenu = browser.isMobile = !!navigator.userAgent.match(/ Mobile[ \/]/);
},
Opera: function (browser) {browser.version = opera.version()},
Edge: function (browser) {
browser.isMobile = !!navigator.userAgent.match(/ Phone/);
},
MSIE: function (browser) {
browser.isMobile = !!navigator.userAgent.match(/ Phone/);
browser.isIE9 = !!(document.documentMode && (window.performance || window.msPerformance));
MathJax.HTML.setScriptBug = !browser.isIE9 || document.documentMode < 9;
MathJax.Hub.msieHTMLCollectionBug = (document.documentMode < 9);

View File

@ -0,0 +1,127 @@
/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/*************************************************************
*
* MathJax/extensions/AssistiveMML.js
*
* Implements an extension that inserts hidden MathML into the
* page for screen readers or other asistive technology.
*
* ---------------------------------------------------------------------
*
* Copyright (c) 2015 The MathJax Consortium
*
* 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 (AJAX,CALLBACK,HUB,HTML) {
var SETTINGS = HUB.config.menuSettings;
var AssistiveMML = MathJax.Extension["AssistiveMML"] = {
version: "2.6",
config: {
disabled: false,
styles: {
".MJX_Assistive_MathML": {
position:"absolute!important",
clip: (HUB.Browser.isMSIE && (document.documentMode||0) < 8 ?
"rect(1px 1px 1px 1px)" : "rect(1px, 1px, 1px, 1px)"),
padding: "1px 0 0 0!important",
border: "0!important",
height: "1px!important",
width: "1px!important",
overflow: "hidden!important",
display:"block!important"
}
}
},
Config: function () {
if (!this.config.disabled && SETTINGS.assistiveMML == null)
HUB.Config({menuSettings:{assistiveMML:true}});
AJAX.Styles(this.config.styles);
HUB.Register.MessageHook("End Math",function (msg) {AssistiveMML.EndMathHook(msg[1])});
},
//
// The hook for the End Math signal.
// This sets up a state object that lists the jax and index into the jax,
// and a dummy callback that is used to synchronizing with MathJax.
// It will be called when the jax are all processed, and that will
// let the MathJax queue continue (it will block until then).
//
EndMathHook: function (node) {
if (!SETTINGS.assistiveMML) return;
var state = {
jax: HUB.getAllJax(node), i: 0,
callback: MathJax.Callback({})
};
this.HandleMML(state);
return state.callback;
},
//
// For each jax in the state, look up the frame.
// If the jax doesn't use NativeMML and hasn't already been handled:
// Get the MathML for the jax, taking resets into account.
// Add a data-mathml attribute to the frame, and
// Create a span that is not visible on screen and put the MathML in it,
// and add it to the frame.
// When all the jax are processed, call the callback.
//
HandleMML: function (state) {
var m = state.jax.length, jax, mml, frame, span;
while (state.i < m) {
jax = state.jax[state.i];
frame = document.getElementById(jax.inputID+"-Frame");
if (jax.outputJax !== "NativeMML" && frame && !frame.getAttribute("data-mathml")) {
try {
mml = jax.root.toMathML("").replace(/\n */g,"").replace(/<!--.*?-->/g,"");
} catch (err) {
if (!err.restart) throw err; // an actual error
return MathJax.Callback.After(["HandleMML",this,state],err.restart);
}
frame.setAttribute("data-mathml",mml);
span = HTML.addElement(frame,"span",{
isMathJax: true, className: "MJX_Assistive_MathML"
});
span.innerHTML = mml;
frame.firstChild.setAttribute("aria-hidden","true");
span.setAttribute("aria-readonly","true");
}
state.i++;
}
state.callback();
}
};
HUB.Startup.signal.Post("AssistiveMML Ready");
})(MathJax.Ajax,MathJax.Callback,MathJax.Hub,MathJax.HTML);
//
// Make sure the toMathML extension is loaded before we signal
// the load complete for this extension. Then wait for the end
// of the user configuration before configuring this extension.
//
MathJax.Callback.Queue(
["Require",MathJax.Ajax,"[MathJax]/extensions/toMathML.js"],
["loadComplete",MathJax.Ajax,"[MathJax]/extensions/AssistiveMML.js"],
function () {
MathJax.Hub.Register.StartupHook("End Config",["Config",MathJax.Extension.AssistiveMML]);
}
);

View File

@ -29,6 +29,12 @@
var STIXURL = "http://www.stixfonts.org/";
var MENU = MathJax.Menu;
var FALSE, KEY;
HUB.Register.StartupHook("MathEvents Ready",function () {
FALSE = MathJax.Extension.MathEvents.Event.False;
KEY = MathJax.Extension.MathEvents.Event.KEY;
});
var CONFIG = HUB.CombineConfig("HelpDialog",{
@ -101,10 +107,10 @@
HELP.Post = function () {
this.div = MENU.Background(this);
var help = HTML.addElement(this.div,"div",{
id: "MathJax_Help"
id: "MathJax_Help", tabIndex: 0, onkeydown: HELP.Keydown
},LOCALE._("HelpDialog",[
["b",{style:{fontSize:"120%"}},[["Help","MathJax Help"]]],
["div",{id: "MathJax_HelpContent"},[
["div",{id: "MathJax_HelpContent", tabIndex: 0},[
["p",{},[["MathJax",
"*MathJax* is a JavaScript library that allows page authors to include " +
"mathematics within their web pages. As a reader, you don't need to do " +
@ -148,10 +154,13 @@
]
]],
["a",{href:"http://www.mathjax.org/"},["www.mathjax.org"]],
["span",{id: "MathJax_HelpClose", onclick: HELP.Remove},
["span",{id: "MathJax_HelpClose", onclick: HELP.Remove,
onkeydown: HELP.Keydown, tabIndex: 0,
"aria-label": "Close", "aria-describedby": "Close window"},
[["span",{},["\u00D7"]]]
]
]));
help.focus();
LOCALE.setCSS(help);
var doc = (document.documentElement||{});
var H = window.innerHeight || doc.clientHeight || doc.scrollHeight || 0;
@ -167,6 +176,15 @@
HELP.Remove = function (event) {
if (HELP.div) {document.body.removeChild(HELP.div); delete HELP.div}
};
HELP.Keydown = function(event) {
if (event.keyCode === KEY.ESCAPE ||
(this.id === "MathJax_HelpClose" &&
(event.keyCode === KEY.SPACE || event.keyCode === KEY.RETURN))) {
HELP.Remove(event);
MENU.CurrentNode().focus();
FALSE(event);
}
},
MathJax.Callback.Queue(
HUB.Register.StartupHook("End Config",{}), // wait until config is complete

View File

@ -109,6 +109,20 @@
RIGHTBUTTON: 2, // the event.button value for right button
MENUKEY: "altKey", // the event value for alternate context menu
/*************************************************************/
/*
* Enum element for key codes.
*/
KEY: {
RETURN: 13,
ESCAPE: 27,
SPACE: 32,
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40
},
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)},
@ -143,6 +157,15 @@
return false;
},
//
// Keydown event handler. Should only fire on Space key.
//
Keydown: function (event, math) {
if (event.keyCode === EVENT.KEY.SPACE) {
EVENT.ContextMenu(event, this);
};
},
//
// Load the contextual menu code, if needed, and post the menu
//
@ -178,7 +201,7 @@
load = LOCALE.loadDomain("MathMenu");
if (!load) {
MENU.jax = jax;
var source = MENU.menu.Find("Show Math As").menu;
var source = MENU.menu.Find("Show Math As").submenu;
source.items[0].name = jax.sourceMenuTitle;
source.items[0].format = (jax.sourceMenuFormat||"MathML");
source.items[1].name = INPUT[jax.inputJax].sourceMenuTitle;
@ -189,7 +212,7 @@
// items accordingly.
//
var annotations = source.items[2]; annotations.disabled = true;
var annotationItems = annotations.menu.items;
var annotationItems = annotations.submenu.items;
annotationList = MathJax.Hub.Config.semanticsAnnotations;
for (var i = 0, m = annotationItems.length; i < m; i++) {
var name = annotationItems[i].name[1]

View File

@ -80,7 +80,7 @@ MathJax.Hub.Register.StartupHook("MathML Jax Ready",function () {
*/
var BROWSER = MathJax.Hub.Browser;
var exslt = '';
if (BROWSER.isMsEdge || BROWSER.isMSIE) {
if (BROWSER.isEdge || BROWSER.isMSIE) {
exslt = 'urn:schemas-microsoft-com:xslt'
} else {
exslt = 'http://exslt.org/common';
@ -767,7 +767,16 @@ MathJax.Hub.Register.StartupHook("MathML Jax Ready",function () {
}
// Tweak CSS to avoid some browsers rearranging HTML output
MathJax.Ajax.Styles(".MathJax span { direction: ltr !important; display: inline-block !important;}");
MathJax.Ajax.Styles({
".MathJax .mi, .MathJax .mo, .MathJax .mn, .MathJax .mtext": {
direction: "ltr",
display: "inline-block"
},
".MathJax .ms, .MathJax .mspace, .MathJax .mglyph": {
direction: "ltr",
display: "inline-block"
}
});
MathJax.Hub.Startup.signal.Post("MathML mml3.js Ready");
});

View File

@ -29,7 +29,7 @@
(function (HUB,HTML,AJAX,CALLBACK,OUTPUT) {
var VERSION = "2.5.0";
var SIGNAL = MathJax.Callback.Signal("menu") // signal for menu events
var SIGNAL = MathJax.Callback.Signal("menu"); // signal for menu events
MathJax.Extension.MathMenu = {
version: VERSION,
@ -194,21 +194,66 @@
".MathJax_MenuClose:hover span": {
"background-color":"#CCC!important"
}
}
});
var FALSE, HOVER;
var FALSE, HOVER, KEY;
HUB.Register.StartupHook("MathEvents Ready",function () {
FALSE = MathJax.Extension.MathEvents.Event.False;
HOVER = MathJax.Extension.MathEvents.Hover;
KEY = MathJax.Extension.MathEvents.Event.KEY;
});
/*************************************************************/
/*
* Abstract class of all keyboard navigatable objects.
*/
var NAV = MathJax.Object.Subclass({
/*
* Moving in the list of items.
*/
Keydown: function(event, menu) {
switch (event.keyCode) {
case KEY.ESCAPE:
this.Remove(event, menu);
break;
case KEY.RIGHT:
this.Right(event, menu);
break;
case KEY.LEFT:
this.Left(event, menu);
break;
case KEY.UP:
this.Up(event, menu);
break;
case KEY.DOWN:
this.Down(event, menu);
break;
case KEY.RETURN:
case KEY.SPACE:
this.Space(event, menu);
break;
default:
return;
break;
}
return FALSE(event);
},
Escape: function(event, menu) { },
Right: function(event, menu) { },
Left: function(event, menu) { },
Up: function(event, menu) { },
Down: function(event, menu) { },
Space: function(event, menu) { }
}, {});
/*************************************************************/
/*
* The main menu class
*/
var MENU = MathJax.Menu = MathJax.Object.Subclass({
var MENU = MathJax.Menu = NAV.Subclass({
version: VERSION,
items: [],
posted: false,
@ -234,7 +279,8 @@
var menu = HTML.Element("div",{
onmouseup: MENU.Mouseup, ondblclick: FALSE,
ondragstart: FALSE, onselectstart: FALSE, oncontextmenu: FALSE,
menuItem: this, className: "MathJax_Menu"
menuItem: this, className: "MathJax_Menu", onkeydown: MENU.Keydown,
role: "navigation"
});
if (!forceLTR) {MathJax.Localization.setCSS(menu)}
@ -248,18 +294,27 @@
div.appendChild(menu);
this.posted = true;
menu.style.width = (menu.offsetWidth+2) + "px";
if (event) {
var x = event.pageX, y = event.pageY;
if (!x && !y) {
}
if (!x && !y && event && event.clientX && event.clientY) {
x = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
y = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
if (!parent) {
var node = MENU.CurrentNode() || event.target;
if (!x && !y && node) {
var offsetX = window.pageXOffset || document.documentElement.scrollLeft;
var offsetY = window.pageYOffset || document.documentElement.scrollTop;
var rect = node.getBoundingClientRect();
x = (rect.right + rect.left) / 2 + offsetX;
y = (rect.bottom + rect.top) / 2 + offsetY;
}
if (x + menu.offsetWidth > document.body.offsetWidth - this.margin)
{x = document.body.offsetWidth - menu.offsetWidth - this.margin}
if (MENU.isMobile) {x = Math.max(5,x-Math.floor(menu.offsetWidth/2)); y -= 20}
MENU.skipUp = event.isContextMenu;
if (event) {MENU.skipUp = event.isContextMenu;}
} else {
var side = "left", mw = parent.offsetWidth;
x = (MENU.isMobile ? 30 : mw - 2); y = 0;
@ -282,8 +337,17 @@
}
menu.style.left = x+"px"; menu.style.top = y+"px";
if (document.selection && document.selection.empty) {document.selection.empty()}
// Focusing while keeping the scroll position.
var oldX = window.pageXOffset || document.documentElement.scrollLeft;
var oldY = window.pageYOffset || document.documentElement.scrollTop;
MENU.Focus(menu);
if (event.type === "keydown") {
MENU.skipMouseoverFromKey = true;
setTimeout(function() {delete MENU.skipMouseoverFromKey;}, CONFIG.delay);
}
window.scrollTo(oldX, oldY);
return FALSE(event);
},
@ -301,6 +365,7 @@
delete MENU.jax.hover.nofade;
HOVER.UnHover(MENU.jax);
}
MENU.Unfocus(menu);
return FALSE(event);
},
@ -314,8 +379,8 @@
for (var i = 0, m = this.items.length; i < m; i++) {
if (this.items[i].name[n] === name) {
if (names.length) {
if (!this.items[i].menu) {return null}
return this.items[i].menu.FindN(n,names[0],names.slice(1));
if (!this.items[i].submenu) {return null}
return this.items[i].submenu.FindN(n,names[0],names.slice(1));
}
return this.items[i];
}
@ -332,25 +397,49 @@
for (var i = 0, m = this.items.length; i < m; i++)
{if (this.items[i].name[n] === name) {return i}}
return null;
}
},
Right: function(event, menu) {
MENU.Right(event, menu);
},
Left: function(event, menu) {
MENU.Left(event, menu);
},
Up: function(event, menu) {
var node = menu.lastChild;
node.menuItem.Activate(event, node);
},
Down: function(event, menu) {
var node = menu.firstChild;
node.menuItem.Activate(event, node);
},
Space: function(event, menu) {
this.Remove(event, menu);
}
},{
config: CONFIG,
div: null, // the DOM elements for the menu and submenus
Close: function (event)
{return MENU.Event(event,this.menu||this.parentNode,(this.menu?"Touchend":"Remove"))},
Remove: function (event) {return MENU.Event(event,this,"Remove")},
Mouseover: function (event) {return MENU.Event(event,this,"Mouseover")},
Mouseout: function (event) {return MENU.Event(event,this,"Mouseout")},
Mousedown: function (event) {return MENU.Event(event,this,"Mousedown")},
Mouseup: function (event) {return MENU.Event(event,this,"Mouseup")},
Keydown: function (event) {return MENU.Event(event,this,"Keydown")},
/*
* Events for mobile devices.
*/
Touchstart: function (event) {return MENU.Event(event,this,"Touchstart")},
Touchend: function (event) {return MENU.Event(event,this,"Touchend")},
Close: function (event) {
return MENU.Event(event,this.menu||this.parentNode,(this.menu?"Touchend":"Remove"));
},
Event: function (event,menu,type,force) {
if (MENU.skipMouseover && type === "Mouseover" && !force) {return FALSE(event)}
if (MENU.skipMouseoverFromKey && type === "Mouseover") {
delete MENU.skipMouseoverFromKey;
return FALSE(event);
}
if (MENU.skipUp) {
if (type.match(/Mouseup|Touchend/)) {delete MENU.skipUp; return FALSE(event)}
if (type === "Touchstart" ||
@ -361,7 +450,6 @@
if (item && item[type]) {return item[type](event,menu)}
return null;
},
/*
* Style for the background DIV
*/
@ -371,7 +459,8 @@
},
Background: function (menu) {
var div = HTML.addElement(document.body,"div",{style:this.BGSTYLE, id:"MathJax_MenuFrame"},
var div = HTML.addElement(document.body,"div",
{style:this.BGSTYLE, id:"MathJax_MenuFrame"},
[["div",{style: this.BGSTYLE, menuItem: menu, onmousedown: this.Remove}]]);
var bg = div.firstChild;
if (MENU.msieBackgroundBug) {
@ -401,31 +490,108 @@
}
},
/*************************************************************/
/*
* Keyboard navigation of menu.
*/
posted: false, // Is a menu open?
active: null, // The focused in HTML node in the menu.
GetNode: function(jax) {
var node = document.getElementById(jax.inputID + "-Frame");
return node.isMathJax ? node : node.firstChild;
},
CurrentNode: function() {
return MENU.GetNode(MENU.jax);
},
AllNodes: function() {
var jaxs = MathJax.Hub.getAllJax();
var nodes = [];
for (var i = 0, jax; jax = jaxs[i]; i++) {
nodes.push(MENU.GetNode(jax));
}
return nodes;
},
ActiveNode: function() {
return MENU.active;
},
FocusNode: function(node) {
MENU.active = node;
node.focus();
},
//
// Focus is a global affair, since we only ever want a single focused item.
//
Focus: function(menu) {
!MENU.posted ? MENU.Activate(menu) : MENU.ActiveNode().tabIndex = -1;
menu.tabIndex = 0;
MENU.FocusNode(menu);
},
Activate: function(event, menu) {
var jaxs = MENU.AllNodes();
for (var j = 0, jax; jax = jaxs[j]; j++) {
jax.tabIndex = -1;
}
MENU.posted = true;
},
Unfocus: function() {
MENU.ActiveNode().tabIndex = -1;
var jaxs = MENU.AllNodes();
for (var j = 0, jax; jax = jaxs[j]; j++) {
jax.tabIndex = 0;
}
MENU.FocusNode(MENU.CurrentNode());
MENU.posted = false;
},
MoveHorizontal: function(event, menu, move) {
if (!event.shiftKey) return;
var jaxs = MENU.AllNodes();
var len = jaxs.length;
if (len === 0) return;
var next = jaxs[MENU.Mod(move(MENU.IndexOf(jaxs, MENU.CurrentNode())), len)];
if (next === MENU.CurrentNode()) return;
MENU.menu.Remove(event, menu);
MENU.jax = MathJax.Hub.getJaxFor(next);
MENU.FocusNode(next);
MENU.menu.Post(null);
},
Right: function(event, menu) {
MENU.MoveHorizontal(event, menu, function(x) {return x + 1;});
},
Left: function(event, menu) {
MENU.MoveHorizontal(event, menu, function(x) {return x - 1;});
},
//TODO: Move to utility class.
// Computes a mod n.
Mod: function(a, n) {
return ((a % n) + n) % n;
},
IndexOf: (Array.prototype.indexOf ?
function (A, item, start) {return A.indexOf(item, start);} :
function (A, item, start) {
for (var i = (start || 0), j = A.length; i < j; i++) {
if (item === A[i]) return i;
}
return -1;
}),
saveCookie: function () {HTML.Cookie.Set("menu",this.cookie)},
getCookie: function () {this.cookie = HTML.Cookie.Get("menu")}
});
MathJax.Menu.NAV = NAV;
/*************************************************************/
/*
* Abstract class of menu items.
*/
var ITEM = MENU.ITEM = MathJax.Object.Subclass({
name: "", // the menu item's label as [id,label] pair
node: null,
var ITEM = MENU.ITEM = NAV.Subclass({
/*
* Accessor method for node.
*/
GetNode: function() {
return this.node;
},
/*
* Registers the HTML node of the menu item.
*/
SetNode: function(node) {
this.node = node;
},
name: "", // The menu item's label as [id,label] pair.
node: null, // The HTML node of the item.
menu: null, // The parent menu containing that item. HTML node.
Attributes: function(def) {
return HUB.Insert(
@ -435,39 +601,50 @@
className: "MathJax_MenuItem", menuItem: this},
def);
},
Create: function (menu) {
if (!this.hidden) {
var def = this.Attributes();
var label = this.Label(def,menu);
var node = HTML.addElement(menu, "div", def, label);
this.SetNode(node);
}
},
Name: function () {return _(this.name[0],this.name[1])},
Mouseover: function (event,menu) {
if (!this.disabled) {this.Activate(menu)}
if (!this.menu || !this.menu.posted) {
if (menu.parentNode === MENU.ActiveNode().parentNode) {
this.Deactivate(MENU.ActiveNode());
}
this.Activate(event, menu);
},
Mouseout: function (event,menu) {
this.Deactivate(menu);
},
Mouseup: function (event,menu) {return this.Remove(event,menu)},
DeactivateSubmenus: function(menu) {
var menus = document.getElementById("MathJax_MenuFrame").childNodes,
items = menu.parentNode.childNodes;
items = ITEM.GetMenuNode(menu).childNodes;
for (var i = 0, m = items.length; i < m; i++) {
var item = items[i].menuItem;
if (item && item.menu && item.menu.posted) {item.Deactivate(items[i])}
// Deactivates submenu items.
if (item && item.submenu && item.submenu.posted &&
item !== menu.menuItem) {
item.Deactivate(items[i]);
}
m = menus.length-1;
while (m >= 0 && menu.parentNode.menuItem !== menus[m].menuItem) {
}
this.RemoveSubmenus(menu, menus);
},
RemoveSubmenus: function(menu, menus) {
menus = menus || document.getElementById("MathJax_MenuFrame").childNodes;
var m = menus.length-1;
while (m >= 0 && ITEM.GetMenuNode(menu).menuItem !== menus[m].menuItem) {
menus[m].menuItem.posted = false;
menus[m].parentNode.removeChild(menus[m]);
m--;
}
if (this.Timer && !MENU.isMobile) {this.Timer(event,menu)}
}
},
Mouseout: function (event,menu) {
if (!this.menu || !this.menu.posted) {this.Deactivate(menu)}
if (this.timer) {clearTimeout(this.timer); delete this.timer}
},
Mouseup: function (event,menu) {return this.Remove(event,menu)},
Touchstart: function (event,menu) {return this.TouchEvent(event,menu,"Mousedown")},
Touchend: function (event,menu) {return this.TouchEvent(event,menu,"Mouseup")},
@ -487,13 +664,14 @@
return menu.Remove(event,menu);
},
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},
isRTL: function () {return MENU.isRTL},
rtlClass: function () {return (this.isRTL() ? " RTL" : "")}
}, {
GetMenuNode: function(item) {
return item.parentNode;
}
});
/*************************************************************/
@ -504,17 +682,87 @@
role: "menuitem", // Aria role.
Attributes: function() {
var def = this.SUPER(arguments).Attributes.call(
this,
Attributes: function(def) {
def = HUB.Insert(
{onmouseover: MENU.Mouseover, onmouseout: MENU.Mouseout,
onmousedown: MENU.Mousedown, role: this.role,
'aria-disabled': !!this.disabled});
onkeydown: MENU.Keydown,
"aria-disabled": !!this.disabled},
def);
def = this.SUPER(arguments).Attributes.call(this, def);
if (this.disabled) {
def.className += " MathJax_MenuDisabled";
}
return def;
},
MoveVertical: function(event, item, move) {
var menuNode = ITEM.GetMenuNode(item);
var items = [];
for (var i = 0, allItems = menuNode.menuItem.items, it;
it = allItems[i]; i++) {
if (!it.hidden) {
items.push(it);
}
}
var index = MENU.IndexOf(items, this);
if (index === -1) return;
var len = items.length;
var children = menuNode.childNodes;
do {
index = MENU.Mod(move(index), len);
} while (items[index].hidden || !children[index].role);
this.Deactivate(item);
items[index].Activate(event, children[index]);
},
Up: function(event, item) {
this.MoveVertical(event, item, function(x) { return x - 1; });
},
Down: function(event, item) {
this.MoveVertical(event, item, function(x) { return x + 1; });
},
Right: function(event, item) {
this.MoveHorizontal(event, item, MENU.Right, !this.isRTL());
},
Left: function(event, item) {
this.MoveHorizontal(event, item, MENU.Left, this.isRTL());
},
MoveHorizontal: function(event, item, move, rtl) {
var menuNode = ITEM.GetMenuNode(item);
if (menuNode.menuItem === MENU.menu && event.shiftKey) {
move(event, item);
}
if (rtl) return;
if (menuNode.menuItem !== MENU.menu) {
this.Deactivate(item);
}
var parentNodes = menuNode.previousSibling.childNodes;
var length = parentNodes.length;
while (length--) {
var parent = parentNodes[length];
if (parent.menuItem.submenu &&
parent.menuItem.submenu === menuNode.menuItem) {
MENU.Focus(parent);
break;
}
}
this.RemoveSubmenus(item);
},
Space: function (event, menu) {
this.Mouseup(event, menu);
},
Activate: function (event, menu) {
this.Deactivate(menu);
if (!this.disabled) {
menu.className += " MathJax_MenuActive";
}
this.DeactivateSubmenus(menu);
MENU.Focus(menu);
},
Deactivate: function (menu) {
menu.className = menu.className.replace(/ MathJax_MenuActive/,"");
}
});
/*************************************************************/
@ -546,7 +794,7 @@
* A menu item that posts a submenu
*/
MENU.ITEM.SUBMENU = MENU.ENTRY.Subclass({
menu: null, // the submenu
submenu: null, // the submenu
marker: "\u25BA", // the submenu arrow
markerRTL: "\u25C4", // the submenu arrow for RTL
@ -554,43 +802,83 @@
if (!(name instanceof Array)) {name = [name,name]} // make [id,label] pair
this.name = name; var i = 1;
if (!(def instanceof MENU.ITEM)) {this.With(def), i++}
this.menu = MENU.apply(MENU,[].slice.call(arguments,i));
this.submenu = MENU.apply(MENU,[].slice.call(arguments,i));
},
Label: function (def,menu) {
this.menu.posted = false;
this.submenu.posted = false;
return [this.Name()+" ",["span",{
className:"MathJax_MenuArrow" + this.rtlClass()
},[this.isRTL() ? this.markerRTL : this.marker]]];
},
Timer: function (event,menu) {
if (this.timer) {clearTimeout(this.timer)}
event = {clientX: event.clientX, clientY: event.clientY}; // MSIE can't pass the event below
this.ClearTimer();
event = {type: event.type,
clientX: event.clientX, clientY: event.clientY}; // MSIE can't pass the event below
this.timer = setTimeout(CALLBACK(["Mouseup",this,event,menu]),CONFIG.delay);
},
ClearTimer: function() {
if (this.timer) {
clearTimeout(this.timer);
}
},
Touchend: function (event,menu) {
var forceout = this.menu.posted;
var forceout = this.submenu.posted;
var result = this.SUPER(arguments).Touchend.apply(this,arguments);
if (forceout) {this.Deactivate(menu); delete ITEM.lastItem; delete ITEM.lastMenu}
return result;
},
Mouseout: function(event, menu) {
if (!this.submenu.posted) {
this.Deactivate(menu);
}
this.ClearTimer();
},
Mouseover: function(event, menu) {
this.Activate(event, menu);
},
Mouseup: function (event,menu) {
if (!this.disabled) {
if (!this.menu.posted) {
if (this.timer) {clearTimeout(this.timer); delete this.timer}
this.menu.Post(event,menu,this.ltr);
if (!this.submenu.posted) {
this.ClearTimer();
this.submenu.Post(event, menu, this.ltr);
MENU.Focus(menu);
} else {
var menus = document.getElementById("MathJax_MenuFrame").childNodes,
m = menus.length-1;
while (m >= 0) {
var child = menus[m];
child.menuItem.posted = false;
child.parentNode.removeChild(child);
if (child.menuItem === this.menu) {break};
m--;
}
this.DeactivateSubmenus(menu);
}
}
return FALSE(event);
},
Activate: function (event, menu) {
if (!this.disabled) {
this.Deactivate(menu);
menu.className += " MathJax_MenuActive";
}
if (!this.submenu.posted) {
this.DeactivateSubmenus(menu);
if (!MENU.isMobile) {
this.Timer(event,menu);
}
}
MENU.Focus(menu);
},
MoveVertical: function(event, item, move) {
this.ClearTimer();
this.SUPER(arguments).MoveVertical.apply(this, arguments);
},
MoveHorizontal: function(event, menu, move, rtl) {
if (!rtl) {
this.SUPER(arguments).MoveHorizontal.apply(this, arguments);
return;
}
if (this.disabled) return;
if (!this.submenu.posted) {
this.Activate(event, menu);
return;
}
var submenuNodes = ITEM.GetMenuNode(menu).nextSibling.childNodes;
if (submenuNodes.length > 0) {
this.submenu.items[0].Activate(event, submenuNodes[0]);
}
}
});
@ -667,7 +955,9 @@
/*
* A menu item that is a label
*/
MENU.ITEM.LABEL = MENU.ITEM.Subclass({
MENU.ITEM.LABEL = MENU.ENTRY.Subclass({
role: "menuitem", // Aria role.
Init: function (name,def) {
if (!(name instanceof Array)) {name = [name,name]} // make [id,label] pair
this.name = name; this.With(def);
@ -675,7 +965,12 @@
Label: function (def,menu) {
def.className += " MathJax_MenuLabel";
return [this.Name()];
}
},
Activate: function(event, menu) {
this.Deactivate(menu);
MENU.Focus(menu);
},
Mouseup: function (event,menu) { }
});
/*************************************************************/
@ -697,13 +992,8 @@
*/
MENU.About = function () {
var HTMLCSS = OUTPUT["HTML-CSS"] || {};
var font =
(HTMLCSS.imgFonts ? "image" :
(HTMLCSS.fontInUse ?
(HTMLCSS.webFonts ? "web" : "local")+" "+HTMLCSS.fontInUse :
(OUTPUT.SVG ? "web SVG" : "generic")) ) + " fonts";
var format = (!HTMLCSS.webFonts || HTMLCSS.imgFonts ? null :
HTMLCSS.allowWebFonts.replace(/otf/,"woff or otf") + " fonts");
var font = MENU.About.GetFont();
var format = MENU.About.GetFormat();
var jax = ["MathJax.js v"+MathJax.fileversion,["br"]];
jax.push(["div",{style:{"border-top":"groove 2px",margin:".25em 0"}}]);
MENU.About.GetJax(jax,MathJax.InputJax,["InputJax","%1 Input Jax v%2"]);
@ -717,7 +1007,7 @@
]]);
MENU.About.div = MENU.Background(MENU.About);
var about = HTML.addElement(MENU.About.div,"div",{
id: "MathJax_About"
id: "MathJax_About", tabIndex: 0, onkeydown: MENU.About.Keydown
},[
["b",{style:{fontSize:"120%"}},["MathJax"]]," v"+MathJax.version,["br"],
_(font.replace(/ /g,""),"using "+font),["br"],["br"],
@ -725,11 +1015,15 @@
display:"inline-block", "text-align":"left", "font-size":"80%",
"max-height":"20em", overflow:"auto",
"background-color":"#E4E4E4", padding:".4em .6em", border:"1px inset"
}},jax],["br"],["br"],
}, tabIndex: 0},jax],["br"],["br"],
["a",{href:"http://www.mathjax.org/"},["www.mathjax.org"]],
["span",{className:"MathJax_MenuClose",id:"MathJax_AboutClose",onclick:MENU.About.Remove},
["span",{className:"MathJax_MenuClose",id:"MathJax_AboutClose",
onclick:MENU.About.Remove,
onkeydown: MENU.About.Keydown, tabIndex: 0,
"aria-label": "Close", "aria-describedby": "Close window"},
[["span",{},"\u00D7"]]]
]);
about.focus();
MathJax.Localization.setCSS(about);
var doc = (document.documentElement||{});
var H = window.innerHeight || doc.clientHeight || doc.scrollHeight || 0;
@ -745,6 +1039,15 @@
MENU.About.Remove = function (event) {
if (MENU.About.div) {document.body.removeChild(MENU.About.div); delete MENU.About.div}
};
MENU.About.Keydown = function(event) {
if (event.keyCode === KEY.ESCAPE ||
(this.id === "MathJax_AboutClose" &&
(event.keyCode === KEY.SPACE || event.keyCode === KEY.RETURN))) {
MENU.About.Remove(event);
MENU.CurrentNode().focus();
FALSE(event);
}
},
MENU.About.GetJax = function (jax,JAX,type,noTypeCheck) {
var info = [];
for (var id in JAX) {if (JAX.hasOwnProperty(id) && JAX[id]) {
@ -755,6 +1058,20 @@
for (var i = 0, m = info.length; i < m; i++) {jax.push(info[i],["br"])}
return jax;
};
MENU.About.GetFont = function () {
var jax = MathJax.Hub.outputJax["jax/mml"][0] || {};
var font = {
SVG: "web SVG",
CommonHTML: "web TeX",
"HTML-CSS": (jax.imgFonts ? "image" : (jax.webFonts ? "web" : "local")+" "+jax.fontInUse)
}[jax.id] || "generic";
return font + " fonts";
};
MENU.About.GetFormat = function () {
var jax = MathJax.Hub.outputJax["jax/mml"][0] || {};
if (jax.id !== "HTML-CSS"|| !jax.webFonts || jax.imgFonts) return;
return jax.allowWebFonts.replace(/otf/,"woff or otf") + " fonts";
};
/*
@ -835,7 +1152,7 @@
var table = w.document.body.firstChild;
setTimeout(function () {
var H = (w.outerHeight-w.innerHeight)||30, W = (w.outerWidth-w.innerWidth)||30, x, y;
W = Math.max(100,Math.min(Math.floor(.5*screen.width),table.offsetWidth+W+25));
W = Math.max(140,Math.min(Math.floor(.5*screen.width),table.offsetWidth+W+25));
H = Math.max(40,Math.min(Math.floor(.5*screen.height),table.offsetHeight+H+25));
if (MENU.prototype.msieHeightBug) {H += 35}; // for title bar in XP
w.resizeTo(W,H);
@ -896,6 +1213,7 @@
if (BROWSER.isChrome && BROWSER.version.substr(0,3) !== "24.") {message = MESSAGE.MML.WebKit}
else if (BROWSER.isSafari && !BROWSER.versionAtLeast("5.0")) {message = MESSAGE.MML.WebKit}
else if (BROWSER.isMSIE) {if (!BROWSER.hasMathPlayer) {message = MESSAGE.MML.MSIE}}
else if (BROWSER.isEdge) {message = MESSAGE.MML.WebKit}
else {message = MESSAGE.MML[BROWSER]}
warned = "warnedMML";
}
@ -1059,7 +1377,7 @@
//
MENU.CreateLocaleMenu = function () {
if (!MENU.menu) return;
var menu = MENU.menu.Find("Language").menu, items = menu.items;
var menu = MENU.menu.Find("Language").submenu, items = menu.items;
//
// Get the names of the languages and sort them
//
@ -1085,7 +1403,7 @@
//
MENU.CreateAnnotationMenu = function () {
if (!MENU.menu) return;
var menu = MENU.menu.Find("Show Math As","Annotation").menu;
var menu = MENU.menu.Find("Show Math As","Annotation").submenu;
var annotations = CONFIG.semanticsAnnotations;
for (var a in annotations) {
if (annotations.hasOwnProperty(a)) {
@ -1154,7 +1472,8 @@
ITEM.RADIO("MathML", "renderer", {action: MENU.Renderer, value:"NativeMML"}),
ITEM.RADIO("SVG", "renderer", {action: MENU.Renderer}),
ITEM.RULE(),
ITEM.CHECKBOX("Fast Preview", "FastPreview")
ITEM.CHECKBOX("Fast Preview", "FastPreview"),
ITEM.CHECKBOX("Assistive MathML", "assistiveMML", {hidden:!CONFIG.showAssistiveMML})
),
ITEM.SUBMENU("MathPlayer", {hidden:!HUB.Browser.isMSIE || !CONFIG.showMathPlayer,
disabled:!HUB.Browser.hasMathPlayer},
@ -1201,7 +1520,7 @@
if (MENU.isMobile) {
(function () {
var settings = CONFIG.settings;
var trigger = MENU.menu.Find("Math Settings","Zoom Trigger").menu;
var trigger = MENU.menu.Find("Math Settings","Zoom Trigger").submenu;
trigger.items[0].disabled = trigger.items[1].disabled = true;
if (settings.zoom === "Hover" || settings.zoom == "Click") {settings.zoom = "None"}
trigger.items = trigger.items.slice(0,4);
@ -1241,6 +1560,10 @@
MENU.cookie.showLocale = CONFIG.showLocale = show; MENU.saveCookie();
MENU.menu.Find("Language").hidden = !show;
};
MENU.showAssistiveMML = function (show) {
MENU.cookie.showAssistiveMML = CONFIG.showAssistiveMML = show; MENU.saveCookie();
MENU.menu.Find("Math Settings","Math Renderer","Assistive MathML").hidden = !show;
};
MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
if (!MathJax.OutputJax["HTML-CSS"].config.imageFont)

View File

@ -134,14 +134,14 @@ MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
aligned: ['AlignedAMSArray',null,null,null,'rlrlrlrlrlrl',COLS([0,2,0,2,0,2,0,2,0,2,0]),".5em",'D'],
gathered: ['AlignedAMSArray',null,null,null,'c',null,".5em",'D'],
subarray: ['Array',null,null,null,null,COLS([0,0,0,0]),"0.1em",'S',1],
subarray: ['Array',null,null,null,null,COLS([0]),"0.1em",'S',1],
smallmatrix: ['Array',null,null,null,'c',COLS([1/3]),".2em",'S',1],
'equation': ['EquationBegin','Equation',true],
'equation*': ['EquationBegin','EquationStar',false],
eqnarray: ['AMSarray',null,true,true, 'rcl',MML.LENGTH.THICKMATHSPACE,".5em"],
'eqnarray*': ['AMSarray',null,false,true,'rcl',MML.LENGTH.THICKMATHSPACE,".5em"]
eqnarray: ['AMSarray',null,true,true, 'rcl',COLS([0]),".5em"],
'eqnarray*': ['AMSarray',null,false,true,'rcl',COLS([0]),".5em"]
},
delimiter: {

View File

@ -99,8 +99,8 @@ MathJax.Extension.mml2jax = {
}
for (var i = 0, m = math.length; i < m; i++) {
var parent = math[i].parentNode;
if (parent && parent.className !== preview && !math[i].prefix === !namespace)
{array.push(math[i])}
if (parent && parent.className !== preview &&
!parent.isMathJax && !math[i].prefix === !namespace) array.push(math[i]);
}
},

View File

@ -45,7 +45,7 @@ MathJax.Hub.Register.StartupHook("CommonHTML Jax Ready",function () {
//
var base, bbox;
if (stretch) {
base = node.getElementsByTagName("mjx-base")[0];
base = CHTML.getNode(node,"mjx-base");
} else {
this.CHTMLaddChild(node,0,{type:"mjx-base", noBBox:true, forceChild:true});
base = node.firstChild;
@ -137,10 +137,10 @@ MathJax.Hub.Register.StartupHook("CommonHTML Jax Ready",function () {
//
CHTMLgetScripts: function (BOX,BBOX,stretch,node) {
if (stretch) {
BOX.sub = node.getElementsByTagName("mjx-sub")[0];
BOX.sup = node.getElementsByTagName("mjx-sup")[0];
BOX.presub = node.getElementsByTagName("mjx-presub")[0];
BOX.presup = node.getElementsByTagName("mjx-presup")[0];
BOX.sub = CHTML.getNode(node,"mjx-sub");
BOX.sup = CHTML.getNode(node,"mjx-sup");
BOX.presub = CHTML.getNode(node,"mjx-presub");
BOX.presup = CHTML.getNode(node,"mjx-presup");
BBOX.sub = this.CHTMLbbox.sub;
BBOX.sup = this.CHTMLbbox.sup;
BBOX.presub = this.CHTMLbbox.presub;
@ -182,7 +182,7 @@ MathJax.Hub.Register.StartupHook("CommonHTML Jax Ready",function () {
BBOX = state.BBOX[type] = CHTML.BBOX.empty();
if (state.w) {
BOX.style.paddingLeft = CHTML.Em(state.w);
BBOX.w = BBOX.r = state.w;
BBOX.w = BBOX.r = state.w; BBOX.x = state.w;
}
}
data.toCommonHTML(BOX);
@ -198,7 +198,7 @@ MathJax.Hub.Register.StartupHook("CommonHTML Jax Ready",function () {
// right-justify the scripts, otherwise, left-justify them.
//
CHTMLpadScript: function (type,w,bbox,state) {
if (!bbox) bbox = {w:0, fake:1};
if (!bbox) bbox = {w:0, fake:1, rscale:1};
var BBOX = state.BBOX[type], dx = 0, dw = 0;
if (BBOX) {
if (bbox.rscale*bbox.w < w) {
@ -252,7 +252,7 @@ MathJax.Hub.Register.StartupHook("CommonHTML Jax Ready",function () {
CHTMLplaceSubSup: function (sub,sbox,sup,Sbox,x,delta,u,v,s) {
sub.style.paddingRight = CHTML.Em(s); sbox.w += s;
sup.style.paddingBottom = CHTML.Em(u+v-Sbox.d-sbox.h);
sup.style.paddingLeft = CHTML.Em(delta);
sup.style.paddingLeft = CHTML.Em(delta+(Sbox.x||0));
sup.style.paddingRight = CHTML.Em(s); Sbox.w += s;
sup.parentNode.style.verticalAlign = CHTML.Em(-v);
this.CHTML.combine(sbox,x,-v);
@ -272,7 +272,7 @@ MathJax.Hub.Register.StartupHook("CommonHTML Jax Ready",function () {
CHTMLplacePresubPresup: function (presub,pbox,presup,Pbox,delta,u,v,s) {
presub.style.paddingLeft = CHTML.Em(s);
presup.style.paddingBottom = CHTML.Em(u+v-Pbox.d-pbox.h);
presup.style.paddingLeft = CHTML.Em(delta+s);
presup.style.paddingLeft = CHTML.Em(delta+s+(Pbox.x||0));
presup.style.paddingRight = CHTML.Em(-delta);
presup.parentNode.style.verticalAlign = CHTML.Em(-v);
this.CHTML.combine(pbox,s,-v);

View File

@ -505,9 +505,9 @@ MathJax.Hub.Register.StartupHook("CommonHTML Jax Ready",function () {
//
if (end.length === 0) {
var NODE = this.CHTMLnodeElement(),
stack = NODE.getElementsByTagName("mjx-stack")[0],
sup = NODE.getElementsByTagName("mjx-sup")[0],
sub = NODE.getElementsByTagName("mjx-sub")[0];
stack = CHTML.getNode(NODE,"mjx-stack"),
sup = CHTML.getNode(NODE,"mjx-sup"),
sub = CHTML.getNode(NODE,"mjx-sub");
if (stack) node.appendChild(stack);
else if (sup) node.appendChild(sup);
else if (sub) node.appendChild(sub);
@ -569,9 +569,9 @@ MathJax.Hub.Register.StartupHook("CommonHTML Jax Ready",function () {
//
if (start.length < 1) {
NODE = this.CHTMLnodeElement();
var prestack = NODE.getElementsByTagName("mjx-prestack")[0],
presup = NODE.getElementsByTagName("mjx-presup")[0],
presub = NODE.getElementsByTagName("mjx-presub")[0];
var prestack = CHTML.getNode(NODE,"mjx-prestack"),
presup = CHTML.getNode(NODE,"mjx-presup"),
presub = CHTML.getNode(NODE,"mjx-presub");
if (prestack) node.appendChild(prestack);
else if (presup) node.appendChild(presup);
else if (presub) node.appendChild(presub);
@ -598,9 +598,9 @@ MathJax.Hub.Register.StartupHook("CommonHTML Jax Ready",function () {
//
if (end.length === 0) {
NODE = this.CHTMLnodeElement();
var stack = NODE.getElementsByTagName("mjx-stack")[0],
sup = NODE.getElementsByTagName("mjx-sup")[0],
sub = NODE.getElementsByTagName("mjx-sub")[0];
var stack = CHTML.getNode(NODE,"mjx-stack"),
sup = CHTML.getNode(NODE,"mjx-sup"),
sub = CHTML.getNode(NODE,"mjx-sub");
if (stack) node.appendChild(stack);
else if (sup) node.appendChild(sup);
else if (sub) node.appendChild(sub);

View File

@ -324,8 +324,9 @@
if (type.substr(0,4) === "mjx-") {
if (!def) def = {};
if (def.className) def.className = type+" "+def.className; else def.className = type;
type = "span";
}
return this.HTMLElement("span",def,content);
return this.HTMLElement(type,def,content);
},
addElement: function (node,type,def,content) {
return node.appendChild(this.Element(type,def,content));
@ -334,6 +335,22 @@
ucMatch: HTML.ucMatch,
setScript: HTML.setScript,
//
// This replaces node.getElementsByTagName(type)[0]
// and should be replaced by that if we go back to using
// custom tags
//
getNode: (document.getElementsByClassName ?
function (node,type) {return node.getElementsByClassName(type)[0]} :
function (node,type) {
var nodes = node.getElementsByTagName("span");
var name = RegExp("\\b"+type+"\\b");
for (var i = 0, m = nodes.length; i < m; i++) {
if (name.test(nodes[i].className)) return nodes[i];
}
}
),
/********************************************/
@ -360,7 +377,7 @@
// Remove any existing output
//
prev = script.previousSibling;
if (prev && prev.nodeName.toLowerCase() === "mjx-chtml")
if (prev && prev.className && String(prev.className).substr(0,9) === "mjx-chtml")
prev.parentNode.removeChild(prev);
//
// Add the node for the math and mark it as being processed
@ -371,7 +388,9 @@
id:jax.inputID+"-Frame", isMathJax:true, jaxID:this.id,
oncontextmenu:EVENT.Menu, onmousedown: EVENT.Mousedown,
onmouseover:EVENT.Mouseover, onmouseout:EVENT.Mouseout, onmousemove:EVENT.Mousemove,
onclick:EVENT.Click, ondblclick:EVENT.DblClick
onclick:EVENT.Click, ondblclick:EVENT.DblClick,
// Added for keyboard accessible menu.
onkeydown: EVENT.Keydown, tabIndex: "0"
});
if (jax.CHTML.display) {
//
@ -1325,7 +1344,7 @@
if (child) {
var type = options.childNodes;
if (type) {
if (type instanceof Array) type = type[i];
if (type instanceof Array) type = type[i]||"span";
node = CHTML.addElement(node,type);
}
cnode = child.toCommonHTML(node,options.childOptions);
@ -1664,6 +1683,9 @@
MML.math.Augment({
toCommonHTML: function (node) {
node = this.CHTMLdefaultNode(node);
var alttext = this.Get("alttext");
if (alttext && !node.getAttribute("aria-label")) node.setAttribute("aria-label",alttext);
if (!node.getAttribute("role")) node.setAttribute("role","math");
if (this.CHTML.pwidth) {
node.parentNode.style.width = this.CHTML.pwidth;
node.parentNode.style.minWidth = this.CHTML.mwidth;
@ -2029,9 +2051,9 @@
//
var base, under, over, nodes = [];
if (stretch) {
base = node.getElementsByTagName("mjx-op")[0];
under = node.getElementsByTagName("mjx-under")[0];
over = node.getElementsByTagName("mjx-over")[0];
base = CHTML.getNode(node,"mjx-op");
under = CHTML.getNode(node,"mjx-under");
over = CHTML.getNode(node,"mjx-over");
nodes[0] = base; nodes[1] = under||over; nodes[2] = over;
} else {
var types = ["mjx-op","mjx-under","mjx-over"];
@ -2229,9 +2251,9 @@
//
var base, sub, sup;
if (stretch) {
base = node.getElementsByTagName("mjx-base")[0];
sub = node.getElementsByTagName("mjx-sub")[0];
sup = node.getElementsByTagName("mjx-sup")[0];
base = CHTML.getNode(node,"mjx-base");
sub = CHTML.getNode(node,"mjx-sub");
sup = CHTML.getNode(node,"mjx-sup");
} else {
var types = ["mjx-base","mjx-sub","mjx-sup"];
if (this.sup === 1) types[1] = types[2];

View File

@ -345,6 +345,22 @@
filter: "none", opacity:1, background:"transparent" // for IE
},
// Focus elements for keyboard tabbing.
".MathJax:focus": (
(MathJax.Hub.Browser.isSafari || MathJax.Hub.Browser.isChrome) ? {
display:"inline-block",
outline:"none",
margin:"-3px",
padding:"3px",
"-webkit-box-shadow": "0px 0px 5px #345, inset 0px 0px 5px #345",
"box-shadow": "0px 0px 5px #345, inset 0px 0px 5px #345"
} : {
display:"inline-block",
outline:"none",
border:"1px dotted",
margin:"-1px"
}),
//
// Used for testing web fonts against the default font used while
// web fonts are loading
@ -569,8 +585,11 @@
span = div = this.Element("span",{
className:"MathJax", id:jax.inputID+"-Frame", isMathJax:true, jaxID:this.id,
oncontextmenu:EVENT.Menu, onmousedown: EVENT.Mousedown,
onmouseover:EVENT.Mouseover, onmouseout:EVENT.Mouseout, onmousemove:EVENT.Mousemove,
onclick:EVENT.Click, ondblclick:EVENT.DblClick
onmouseover:EVENT.Mouseover, onmouseout:EVENT.Mouseout,
onmousemove:EVENT.Mousemove, onclick:EVENT.Click,
ondblclick:EVENT.DblClick,
// Added for keyboard accessible menu.
onkeydown: EVENT.Keydown, tabIndex: "0"
});
if (HUB.Browser.noContextMenu) {
span.ontouchstart = TOUCH.start;
@ -2868,7 +2887,6 @@
var alttext = this.Get("alttext");
if (alttext && !span.getAttribute("aria-label")) span.setAttribute("aria-label",alttext);
if (!span.getAttribute("role")) span.setAttribute("role","math");
// span.setAttribute("tabindex",0); // causes focus outline, so disable for now
stack = HTMLCSS.createStack(span); box = HTMLCSS.createBox(stack);
// Move font-size from outer span to stack to avoid line separation
// problem in strict HTML mode

View File

@ -326,6 +326,9 @@
container.onmousedown = EVENT.Mousedown;
container.onclick = EVENT.Click;
container.ondblclick = EVENT.DblClick;
// Added for keyboard accessible menu.
container.onkeydown = EVENT.Keydown;
container.tabIndex = "0";
if (HUB.Browser.noContextMenu) {
container.ontouchstart = TOUCH.start;
container.ontouchend = TOUCH.end;

View File

@ -197,7 +197,9 @@
className:"MathJax_PHTML", id:jax.inputID+"-Frame", isMathJax:true, jaxID:this.id,
oncontextmenu:EVENT.Menu, onmousedown: EVENT.Mousedown,
onmouseover:EVENT.Mouseover, onmouseout:EVENT.Mouseout, onmousemove:EVENT.Mousemove,
onclick:EVENT.Click, ondblclick:EVENT.DblClick
onclick:EVENT.Click, ondblclick:EVENT.DblClick,
// Added for keyboard accessible menu.
onkeydown: EVENT.Keydown, tabIndex: "0"
});
if (HUB.Browser.noContextMenu) {
span.ontouchstart = TOUCH.start;

View File

@ -220,7 +220,9 @@
className:"MathJax_SVG", id:jax.inputID+"-Frame", isMathJax:true, jaxID:this.id,
oncontextmenu:EVENT.Menu, onmousedown: EVENT.Mousedown,
onmouseover:EVENT.Mouseover, onmouseout:EVENT.Mouseout, onmousemove:EVENT.Mousemove,
onclick:EVENT.Click, ondblclick:EVENT.DblClick
onclick:EVENT.Click, ondblclick:EVENT.DblClick,
// Added for keyboard accessible menu.
onkeydown: EVENT.Keydown, tabIndex: "0"
});
if (HUB.Browser.noContextMenu) {
span.ontouchstart = TOUCH.start;
@ -2098,9 +2100,8 @@
// Add it to the MathJax span
//
var alttext = this.Get("alttext");
if (alttext && !svg.element.getAttribute("aria-label")) span.setAttribute("aria-label",alttext);
if (!svg.element.getAttribute("role")) span.setAttribute("role","math");
// span.setAttribute("tabindex",0); // causes focus outline, so disable for now
if (alttext && !svg.element.getAttribute("aria-label")) svg.element.setAttribute("aria-label",alttext);
if (!svg.element.getAttribute("role")) svg.element.setAttribute("role","img");
span.appendChild(svg.element);
svg.element = null;
//