123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431 |
- /* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
- /* vim: set ts=2 et sw=2 tw=80: */
- /*************************************************************
- *
- * MathJax/jax/output/NativeMML/jax.js
- *
- * Implements the NativeMML OutputJax that displays mathematics
- * using a browser's native MathML capabilities (if any).
- *
- * ---------------------------------------------------------------------
- *
- * Copyright (c) 2010-2017 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 (nMML,HUB,AJAX,HTML) {
- var MML, isMSIE = HUB.Browser.isMSIE;
-
- var EVENT, TOUCH, HOVER, ZOOM; // filled in later
- HUB.Register.StartupHook("MathZoom Ready",function () {ZOOM = MathJax.Extension.MathZoom});
-
- var NOPADDING = function (side,obj) {
- var span = HTML.Element("span"); side = "padding"+side;
- if (obj) {
- span.style.cssText = (obj.getAttribute("style")||"");
- if (span.style.padding === "" && (span.style[side]||"") === "") {
- span.style[side] = "0px"; obj.setAttribute("style",span.style.cssText)
- }
- }
- };
-
- var CELLSPACING = function (obj,rowSpacing,columnSpacing) {
- //
- // Webkit default padding on mtd cells is simply
- //
- // mtd {padding: 0.5ex;}
- //
- // Gecko default padding on mtd cells is
- //
- // mtd {padding-right: 0.4em;
- // padding-left: 0.4em;
- // padding-bottom: 0.5ex;
- // padding-top: 0.5ex;}
- // mtr:first-child > mtd {padding-top: 0ex;}
- // mtr:last-child > mtd {padding-bottom: 0ex;}
- // mtd:first-child {padding-left: 0em;}
- // mtd:last-child {padding-right: 0em;}
- //
- // that is the columnspacing/rowspacing is split into two adjacent cells,
- // and the periphery of boundary cells is set to zero.
- //
- // Here, we will set the left/top padding of each cell to
- // rowSpacing/columnSpacing (or 0px for the leftmost/topmost cells) and
- // reset the right/bottom padding to zero.
- //
- if (obj) {
- var span = HTML.Element("span");
- span.style.cssText = (obj.getAttribute("style")||"");
- if (span.style.padding === "") {
- var padding = { paddingLeft: columnSpacing, paddingTop: rowSpacing,
- paddingRight: "0px", paddingBottom: "0px" };
- for (var side in padding) {if (padding.hasOwnProperty(side)) {
- if ((span.style[side]||"") === "") {span.style[side] = padding[side];}
- }}
- }
- obj.setAttribute("style",span.style.cssText);
- }
- };
-
- nMML.Augment({
- //
- // User can configure styles
- //
- config: {
- styles: {
- ".MathJax_MathML": {
- "font-style": "normal",
- "font-weight": "normal",
- "line-height": "normal",
- "font-size": "100%",
- "font-size-adjust":"none",
- "text-indent": 0,
- "text-align": "left",
- "text-transform": "none",
- "letter-spacing": "normal",
- "word-spacing": "normal",
- "word-wrap": "normal",
- "white-space": "nowrap",
- "float": "none",
- "direction": "ltr",
- "max-width": "none", "max-height": "none",
- "min-width": 0, "min-height": 0,
- border: 0, padding: 0, margin: 0
- },
-
- "span.MathJax_MathML": {
- display: "inline!important"
- },
-
- "div.MathJax_MathML": {
- display: "block!important"
- },
-
- ".MathJax_mmlExBox": {
- display:"block!important", overflow:"hidden",
- height:"1px", width:"60ex",
- "min-height": 0, "max-height":"none",
- padding:0, border: 0, margin: 0
- }
- }
- },
- handlesVariants: false, // true if native support for mathvariants
- settings: HUB.config.menuSettings,
- ex: 1, scale: 1, // filled in later
- adjustWidths: [], // array of elements to have their widths adjusted
-
- Config: function () {
- this.SUPER(arguments).Config.call(this);
- if (this.settings.scale) {this.config.scale = this.settings.scale}
- //
- // Insert styling to take account of displayAlign and displayIndent
- //
- if (HUB.config.displayAlign !== "center") {
- var align = HUB.config.displayAlign, indent = HUB.config.displayIndent;
- var def = {"text-align": align+"!important"}; def["margin-"+align] = indent+"!important";
- HUB.Insert(this.config.styles,{
- "div.MathJax_MathML": def,
- "div.MathJax_MathML math": {"text-align": align},
- "div.MathJax_MathContainer > span": {"text-align": align+"!important"}
- });
- }
- if (!this.require) {this.require = []}
- this.require.push(MathJax.OutputJax.extensionDir+"/MathEvents.js");
- },
- Startup: function () {
- // Set up event handling
- EVENT = MathJax.Extension.MathEvents.Event;
- TOUCH = MathJax.Extension.MathEvents.Touch;
- HOVER = MathJax.Extension.MathEvents.Hover;
- this.ContextMenu = EVENT.ContextMenu;
- this.Mousedown = EVENT.AltContextMenu;
- this.Mouseover = HOVER.Mouseover;
- this.Mouseout = HOVER.Mouseout;
- this.Mousemove = HOVER.Mousemove;
- if (!HUB.Browser.hasMathPlayer) {
- // Used in preTranslate to get scaling factors
- this.EmExSpan = HTML.Element("span",
- {style:{position:"absolute","font-size-adjust":"none"}},
- [
- ["div",{className:"MathJax_mmlExBox"}],
- ["span",{className:"MathJax_MathML"}]
- ]
- );
- MML.math(MML.mspace().With({width:"60ex"})).toNativeMML(this.EmExSpan.lastChild);
- }
- // Set up styles
- return AJAX.Styles(this.config.styles);
- },
- //
- // Set up MathPlayer for IE on the first time through.
- // Get the ex and em sizes.
- //
- InitializeMML: function () {
- this.initialized = true;
- if (HUB.Browser.hasMathPlayer) {
- try {
- //
- // Insert data needed to use MathPlayer for MathML output
- //
- if (!HUB.Browser.mpNamespace) {
- var mathplayer = document.createElement("object");
- mathplayer.id = "mathplayer"; mathplayer.classid = "clsid:32F66A20-7614-11D4-BD11-00104BD3F987";
- document.getElementsByTagName("head")[0].appendChild(mathplayer);
- document.namespaces.add("m","http://www.w3.org/1998/Math/MathML");
- HUB.Browser.mpNamespace = true;
- }
- if (!HUB.Browser.mpImported) {
- document.namespaces.m.doImport("#mathplayer");
- HUB.Browser.mpImported = true;
- }
- } catch (err) {
- //
- // If that fails, give an alert about security settings
- //
- if (!this.config.noMathPlayerWarning) {
- alert(MathJax.Localization._(["MathML", "MathPlayer"],
- "MathJax was not able to set up MathPlayer.\n\n"+
- "If MathPlayer is not installed, you need to install it first.\n"+
- "Otherwise, your security settings may be preventing ActiveX \n"+
- "controls from running. Use the Internet Options item under\n"+
- "the Tools menu and select the Security tab, then press the\n"+
- "Custom Level button. Check that the settings for\n"+
- "'Run ActiveX Controls', and 'Binary and script behaviors'\n"+
- "are enabled.\n\n"+
- "Currently you will see error messages rather than\n"+
- "typeset mathematics."));
- }
- }
- } else {
- //
- // Get the default sizes (need styles in place to do this)
- //
- document.body.appendChild(this.EmExSpan);
- this.defaultEx = this.EmExSpan.firstChild.offsetWidth/60;
- this.defaultMEx = this.EmExSpan.lastChild.offsetWidth/60;
- document.body.removeChild(this.EmExSpan);
- }
- },
-
- preTranslate: function (state) {
- var scripts = state.jax[this.id], i, m = scripts.length,
- script, prev, span, test, math, jax, ex, mex, scale;
- for (i = 0; i < m; i++) {
- script = scripts[i]; if (!script.parentNode) continue;
- if (!this.initialized) {this.InitializeMML()}
- //
- // Remove any existing output
- //
- prev = script.previousSibling;
- if (prev && prev.className === "MathJax_MathML") {prev.parentNode.removeChild(prev)}
- //
- // Add the MathJax span
- //
- jax = script.MathJax.elementJax; if (!jax) continue;
- math = jax.root; jax.NativeMML = {};
- var type = (math.Get("display") === "block" ? "div" : "span");
- span = HTML.Element(type,{
- className: "MathJax_MathML", id:jax.inputID+"-Frame"
- },[["span",{
- className:"MathJax_MathContainer", isMathJax: true, jaxID:this.id,
- style:{position:"relative", display:"inline-block", "white-space":"nowrap"}
- }, [["span",{isMathJax:true, style:{display:"inline-block"}}]] // for Firefox hover and zoom
- ]]);
- script.parentNode.insertBefore(span,script);
- //
- // Add the test span for determining scales
- //
- if (!isMSIE) {script.parentNode.insertBefore(this.EmExSpan.cloneNode(true),script)}
- }
- //
- // Determine the scaling factors for each script
- // (this only requires one reflow rather than a reflow for each equation)
- //
- for (i = 0; i < m; i++) {
- script = scripts[i]; if (!script.parentNode) continue;
- jax = script.MathJax.elementJax; if (!jax) continue;
- if (!isMSIE) {
- test = script.previousSibling;
- ex = test.firstChild.offsetWidth/60;
- mex = test.lastChild.offsetWidth/60;
- if (ex === 0 || ex === "NaN") {ex = this.defaultEx; mex = this.defaultMEx}
- scale = (this.config.matchFontHeight && mex > 1 ? ex/mex : 1);
- scale = Math.floor(Math.max(this.config.minScaleAdjust/100,scale) * this.config.scale);
- jax.NativeMML.ex = ex; jax.NativeMML.mex = mex;
- } else {scale = 100}
- jax.NativeMML.fontSize = scale+"%";
- jax.NativeMML.scale = scale/100;
- }
- //
- // Remove the test spans used for determining scales
- //
- if (!isMSIE) {
- for (i = 0; i < m; i++) {
- script = scripts[i];
- if (script.parentNode && script.MathJax.elementJax) {
- script.parentNode.removeChild(script.previousSibling);
- }
- }
- }
- },
- //
- // Add a SPAN to use as a container, and render the math into it
- //
- Translate: function (script) {
- if (!script.parentNode) return;
- //
- // Get the jax and the container and set the size
- //
- var jax = script.MathJax.elementJax, math = jax.root;
- var span = document.getElementById(jax.inputID+"-Frame"); if (!span) return;
- var container = span.firstChild, mspan = container.firstChild;
- this.ex = jax.NativeMML.ex || this.defaultEx;
- this.scale = jax.NativeMML.scale || 1;
- if (this.scale !== 1) {span.style.fontSize = jax.NativeMML.fontSize}
- //
- // Convert to MathML (if restarted, remove any partial math)
- //
- try {math.toNativeMML(mspan,jax)} catch (err) {
- if (err.restart) {while (mspan.firstChild) {mspan.removeChild(mspan.firstChild)}}
- throw err;
- }
- //
- // Add event handlers
- //
- if (isMSIE) {
- if (container.addEventListener) {
- for (var id in this.MSIE9events) {if (this.MSIE9events.hasOwnProperty(id)) {
- container.addEventListener(id,this.MSIE9event,true);
- }}
- } else {
- var config = (this.config.showMathMenuMSIE != null ? this : HUB).config;
- if (config.showMathMenuMSIE && !this.settings.mpContext && !this.settings.mpMouse)
- {this.MSIEoverlay(container)} else
- {container.style.position = ""; mspan.firstChild.onmousedown = this.MSIEaltMenu}
- }
- } else {
- container.oncontextmenu = EVENT.Menu;
- container.onmouseover = EVENT.Mouseover;
- container.onmouseout = EVENT.Mouseout;
- container.onmousedown = EVENT.Mousedown;
- container.onclick = EVENT.Click;
- container.ondblclick = EVENT.DblClick;
- // Added for keyboard accessible menu.
- container.onkeydown = EVENT.Keydown;
- container.tabIndex = HUB.getTabOrder(jax);
- if (HUB.Browser.noContextMenu) {
- container.ontouchstart = TOUCH.start;
- container.ontouchend = TOUCH.end;
- }
- }
- },
- postTranslate: function (state) {
- if (this.forceReflow) {
- //
- // Firefox messes up some mtable's when they are dynamically created
- // but gets them right on a reflow, so force reflow by toggling a stylesheet
- //
- var sheet = (document.styleSheets||[])[0]||{};
- sheet.disabled = true; sheet.disabled = false;
- }
- },
-
- //
- // Remove MathML preceeding the script
- //
- Remove: function (jax) {
- var span = jax.SourceElement(); if (!span) return;
- span = span.previousSibling; if (!span) return;
- if (span.className.match(/MathJax_MathML/)) {span.parentNode.removeChild(span)}
- },
- //
- // The namespace to use for MML
- //
- MMLnamespace: "http://www.w3.org/1998/Math/MathML",
- isFullWidth: function (node) {
- if (!node) return;
- var width = node.getAttribute("width") ||
- (String(node.getAttribute("style")).match(/(?:^| )width: *([^; ]*)/)||[])[1];
- if (width) return !!width.match(/%/);
- if (node.nodeName.match(/^(semantics|math|mstyle)$/)) {
- width = this.isFullWidth(node.firstChild);
- } else if (node.nodeName.toLowerCase() === "mrow") {
- for (var i = 0, m = node.childNodes.length; i < m && !width; i++)
- width = this.isFullWidth(node.childNodes[i]);
- }
- if (width) {
- var style = "width:100%; "+(node.getAttribute("style")||"");
- node.setAttribute("style",style.replace(/ +$/,""));
- }
- return width;
- },
-
- //
- // For MSIE, we must overlay the MathPlayer object to trap the events
- // (since they can't be cancelled when the events are on the <math> tag
- // itself). The events we DON'T want are transferred to the math element,
- // and the others are handled directly.
- //
- MSIEoverlay: function (span) {
- var math = span.firstChild;
- if (math.nodeName.toLowerCase() === "span") {math = math.firstChild}
- var bbox = this.getHoverBBox(null,math,{});
- HTML.addElement(span,"span",{
- style:{display:"inline-block", width:0, height:0, position:"relative"}
- },[["span",{isMathJax: true, className: "MathJax_MathPlayer_Overlay",
- style:{
- display:"inline-block", position:"absolute",
- left:HOVER.Px(-bbox.w), top:HOVER.Px(-bbox.h-(bbox.y||0)-1),
- width:HOVER.Px(bbox.w), height:HOVER.Px(bbox.h+bbox.d), cursor:"pointer",
- "background-color":"white", filter:"alpha(opacity=0)"
- }
- }]]);
- HUB.Insert(span,{
- msieMath: math,
- onmousedown: this.MSIEevent, oncontextmenu: this.MSIEevent, onclick: this.MSIEevent,
- onmouseup: this.MSIEevent, onmousemove: this.MSIEevent, ondblclick: this.MSIEevent,
- onmouseover: this.MSIEevent, onmouseout: this.MSIEevent
- });
- },
- MSIEevents: {
- mousedown:"Mousedown", contextmenu:"ContextMenu", click:"Click",
- mouseup:"Mouseup", mousemove:"Mousemove", dblclick: "DblClick",
- mouseover:"Mouseover", mouseout:"Mouseout"
- },
- MSIEevent: function () {
- var event = window.event;
- var type = nMML.MSIEevents[event.type];
- if (nMML[type] && nMML[type](event,this) === false) {return false}
- if (ZOOM && ZOOM.HandleEvent(event,type,this) === false) {return false}
- if (event.srcElement.className === "MathJax_MathPlayer_Overlay" && this.msieMath.fireEvent) {
- //
- // For now, ignore all other events. This will disable MathPlayer's zoom
- // feature, but also its <maction> support.
- //
- if (type === "ContextMenu" || type === "Mouseover" || type === "Mouseout")
- {this.msieMath.fireEvent("on"+event.type,event)}
- }
- return EVENT.False(event);
- },
- MSIEaltMenu: function () {
- var container = this.parentNode.parentNode;
- while (!container.jaxID) {container = container.parentNode}
- EVENT.AltContextMenu(window.event,container);
- },
- MSIE9events: {
- contextmenu:"Menu", click:"Click", dblclick: "DblClick",
- mouseup:"False", mouseover:"Mouseover", mouseout:"Mouseout"
- },
- MSIE9event: function (event) {
- if (event.type === "contextmenu" && nMML.settings.mpContext) {return true}
- if (event.type === "mouseup" && nMML.settings.mpMouse) {return true}
- if (event.type === "click" && nMML.settings.mpContext)
- {return EVENT.AltContextMenu(event,this)}
- var type = nMML.MSIE9events[event.type];
- return EVENT[type].call(this,event);
- },
- getJaxFromMath: function (math) {
- math = math.parentNode;
- do {math = math.nextSibling} while (math && math.nodeName.toLowerCase() !== "script");
- return HUB.getJaxFor(math);
- },
- getHoverSpan: function (jax,math) {return math.firstChild},
- getHoverBBox: function (jax,span,math) {return EVENT.getBBox(span.parentNode)},
- Zoom: function (jax,span,math,Mw,Mh) {
- jax.root.toNativeMML(span);
- if (this.msieIE8HeightBug) {span.style.position = "absolute"}
- if (nMML.widthBug) {span.style.width = span.parentNode.style.width = ""}
- if (span.parentNode.style.width.match(/%$/))
- {span.parentNode.style.minWidth = Math.ceil(3*Mh/4)+"px"} // for full-width tables
- var mW = math.offsetWidth || math.scrollWidth,
- mH = math.offsetHeight || math.scrollHeight;
- var zW = span.offsetWidth, zH = span.offsetHeight;
- if (nMML.widthBug || span.style.width.match(/%/)) {
- //
- // FF doesn't get width of <math> right, so get it from <mrow>
- //
- var W = span.firstChild.firstChild.scrollWidth;
- if (W > zW) {zW = W; span.parentNode.style.width = span.style.minWidth = zW + "px";}
- }
- if (this.msieIE8HeightBug) {span.style.position = ""}
- return {Y:-EVENT.getBBox(span.parentNode).h, mW:mW, mH:mH, zW:zW, zH:zH}
- },
- NAMEDSPACE: {
- negativeveryverythinmathspace: "-.0556em",
- negativeverythinmathspace: "-.1111em",
- negativethinmathspace: "-.1667em",
- negativemediummathspace: "-.2222em",
- negativethickmathspace: "-.2778em",
- negativeverythickmathspace: "-.3333em",
- negativeveryverythickmathspace: "-.3889em",
- veryverythinmathspace: ".0556em",
- verythinmathspace: ".1111em",
- thinmathspace: ".1667em",
- mediummathspace: ".2222em",
- thickmathspace: ".2778em",
- verythickmathspace: ".3333em",
- veryverythickmathspace: ".3889em"
- }
- });
- HUB.Register.StartupHook("mml Jax Ready",function () {
- MML = MathJax.ElementJax.mml;
- MML.mbase.Augment({
- //
- // Add a MathML tag of the correct type, and set its attributes
- // then populate it with its children and append it to the parent
- //
- toNativeMML: function (parent) {
- var tag = this.NativeMMLelement(this.type);
- this.NativeMMLattributes(tag);
- for (var i = 0, m = this.data.length; i < m; i++) {
- if (this.data[i]) {this.data[i].toNativeMML(tag)}
- else {tag.appendChild(this.NativeMMLelement("mrow"))}
- }
- parent.appendChild(tag);
- },
- //
- // Look for attributes that are different from the defaults
- // and set those in the tag's attribute list
- //
- NativeMMLattributes: function (tag) {
- var defaults = (this.type === "mstyle" ? MML.math.prototype.defaults : this.defaults);
- var names = (this.attrNames||MML.copyAttributeNames),
- skip = MML.skipAttributes, copy = MML.copyAttributes;
- if (!this.attrNames) {
- for (var id in defaults) {if (!skip[id] && !copy[id] && defaults.hasOwnProperty(id)) {
- if (this[id] != null && this[id] !== defaults[id]) {
- if (this.Get(id,null,1) !== this[id])
- tag.setAttribute(id,this.NativeMMLattribute(this[id]));
- }
- }}
- }
- for (var i = 0, m = names.length; i < m; i++) {
- if (copy[names[i]] === 1 && !defaults.hasOwnProperty(names[i])) continue;
- var value = (this.attr||{})[names[i]]; if (value == null) {value = this[names[i]]}
- if (value != null) {tag.setAttribute(names[i],this.NativeMMLattribute(value))}
- }
- this.NativeMMLclass(tag);
- },
- NativeMMLclass: function (tag) {
- var CLASS = []; if (this["class"]) {CLASS.push(this["class"])}
- if (this.isa(MML.TeXAtom)) {
- var TEXCLASS = ["ORD","OP","BIN","REL","OPEN","CLOSE","PUNCT","INNER","VCENTER"][this.texClass];
- if (TEXCLASS) {
- CLASS.push("MJX-TeXAtom-"+TEXCLASS)
- if (TEXCLASS === "OP" && !this.movablelimits) CLASS.push("MJX-fixedlimits");
- }
- }
- if (this.mathvariant && this.NativeMMLvariants[this.mathvariant])
- {CLASS.push("MJX"+this.mathvariant)}
- if (this.variantForm) {CLASS.push("MJX-variant")}
- if (CLASS.length) {tag.setAttribute("class",CLASS.join(" "))}
- },
- NativeMMLattribute: function (value) {
- value = String(value);
- if (nMML.NAMEDSPACE[value]) {value = nMML.NAMEDSPACE[value]} // MP doesn't do negative spaces
- else if (value.match(/^\s*(([-+])?(\d+(\.\d*)?|\.\d+))\s*mu\s*$/))
- {value = (RegExp.$2||"")+((1/18)*RegExp.$3).toFixed(3).replace(/\.?0+$/,"")+"em"} // FIXME: should take scriptlevel into account
- else if (this.NativeMMLvariants[value]) {value = this.NativeMMLvariants[value]}
- return value;
- },
- NativeMMLvariants: {
- "-tex-caligraphic": MML.VARIANT.SCRIPT,
- "-tex-caligraphic-bold": MML.VARIANT.BOLDSCRIPT,
- "-tex-oldstyle": MML.VARIANT.NORMAL,
- "-tex-oldstyle-bold": MML.VARIANT.BOLD,
- "-tex-mathit": MML.VARIANT.ITALIC
- },
- //
- // Create a MathML element
- //
- NativeMMLelement: function (type) {
- var math = ( HUB.Browser.mpNamespace ? document.createElement("m:"+type) :
- (document.createElementNS ? document.createElementNS(nMML.MMLnamespace,type) :
- document.createElement(type)));
- math.isMathJax = true;
- return math;
- }
- });
-
- MML.mrow.Augment({
- //
- // Make inferred rows not include an mrow tag
- //
- toNativeMML: function (parent) {
- var i, m;
- if (this.inferred && this.parent.inferRow) {
- for (i = 0, m = this.data.length; i < m; i++) {
- if (this.data[i]) {this.data[i].toNativeMML(parent)}
- else {parent.appendChild(this.NativeMMLelement("mrow"))}
- }
- } else if (nMML.stretchyMoBug && (this.open || this.close)) {
- //
- // This element contains opening and/or closing fences. Opera is not
- // able to stretch <mo> operators, so let's use an <mfenced> element
- // instead.
- //
- var mfenced = this.NativeMMLelement("mfenced");
- this.NativeMMLattributes(mfenced);
- i = 0, m = this.data.length;
- if (this.open) { mfenced.setAttribute("open", this.open); i++; }
- if (this.close) { mfenced.setAttribute("close", this.close); m--; }
- var tag = mfenced;
- if (m - i + 1 > 1) {
- //
- // If there are several children, put them in an <mrow>
- //
- tag = this.NativeMMLelement("mrow");
- parent.appendChild(mfenced);
- parent = mfenced;
- }
- for (; i < m; i++) {
- if (this.data[i]) {this.data[i].toNativeMML(tag)}
- else {tag.appendChild(this.NativeMMLelement("mrow"))}
- }
- parent.appendChild(tag);
- } else {
- this.SUPER(arguments).toNativeMML.call(this,parent);
- }
- }
- });
- MML.msubsup.Augment({
- //
- // Use proper version of msub, msup, or msubsup, depending on
- // which items are present
- //
- toNativeMML: function (parent) {
- var type = this.type;
- if (this.data[this.sup] == null) {type = "msub"}
- if (this.data[this.sub] == null) {type = "msup"}
- var tag = this.NativeMMLelement(type);
- this.NativeMMLattributes(tag);
- if (this.data[0]) {delete this.data[0].inferred}
- for (var i = 0, m = this.data.length; i < m; i++)
- {if (this.data[i]) {this.data[i].toNativeMML(tag)}}
- parent.appendChild(tag);
- }
- });
- MML.munderover.Augment({
- //
- // Use proper version of munder, mover, or munderover, depending on
- // which items are present. Handle movablelimits on TeXAtom base.
- //
- toNativeMML: function (parent) {
- var type = this.type;
- var base = this.data[this.base];
- if (base && base.isa(MML.TeXAtom) && base.movablelimits && !base.Get("displaystyle")) {
- type = "msubsup";
- if (this.data[this.under] == null) {type = "msup"}
- if (this.data[this.over] == null) {type = "msub"}
- } else {
- if (this.data[this.under] == null) {type = "mover"}
- if (this.data[this.over] == null) {type = "munder"}
- }
- var tag = this.NativeMMLelement(type);
- this.NativeMMLattributes(tag);
- if (this.data[0]) {delete this.data[0].inferred}
- for (var i = 0, m = this.data.length; i < m; i++)
- {if (this.data[i]) {this.data[i].toNativeMML(tag)}}
- parent.appendChild(tag);
- }
- });
- if (!isMSIE) {
- var SPLIT = HUB.SplitList;
- MML.mtable.Augment({
- toNativeMML: function (parent) {
- var i, m;
- if (nMML.tableSpacingBug) {
- //
- // Parse the rowspacing/columnspacing. For convenience, we convert
- // them to a left/top padding value that will be applied to each
- // cell. The leftmost/topmost cells will use "0px".
- //
- var values = this.getValues("rowspacing", "columnspacing");
- this.nMMLtopPadding = SPLIT("0px "+values.rowspacing);
- this.nMMLleftPadding = SPLIT("0px "+values.columnspacing);
- //
- // Transmit the top padding to each row.
- // If this.parent.nMML.topPadding does not contain enough value,
- // repeat the last one.
- //
- var tp = this.nMMLtopPadding, M = tp.length;
- for (i = 0, m = this.data.length; i < m; i++) {
- if (this.data[i])
- {this.data[i].nMMLtopPadding = tp[i < M ? i : M-1]}
- }
- }
- if (nMML.tableLabelBug) {
- //
- // Look for labeled rows so we know how to handle them
- //
- for (i = 0, m = this.data.length; i < m; i++) {
- if (this.data[i] && this.data[i].isa(MML.mlabeledtr)) {
- var align = HUB.config.displayAlign.charAt(0),
- side = this.Get("side").charAt(0);
- this.nMMLhasLabels = true;
- this.nMMLlaMatch = (align === side);
- this.nMMLforceWidth =
- (align === "c" || !!((this.width||"").match("%")));
- break;
- }
- }
- }
- //
- // Firefox < 13 doesn't handle width, so put it in styles instead
- //
- if (this.width && this.ffTableWidthBug) {
- var styles = (this.style||"").replace(/;\s*$/,"").split(";");
- if (styles[0] === "") {styles.shift()}
- styles.push("width:"+this.width);
- this.style = styles.join(";");
- }
- this.SUPER(arguments).toNativeMML.call(this,parent);
- //
- if (this.nMMLhasLabels) {
- var mtable = parent.firstChild;
- //
- // Add column attributes on the left when extra columns where inserted
- //
- if (this.nMMLforceWidth || side !== "r") {
- var n = (align !== "l" ? 1 : 0) + (side === "l" ? 1 : 0);
- if (n) {
- var attr = {columnalign:"left", columnwidth:"auto",
- columnspacing:"0px", columnlines:"none"};
- for (var id in attr) {if (attr.hasOwnProperty(id) && this[id]) {
- var cols = [attr[id],attr[id]].slice(2-n).join(" ")+" ";
- mtable.setAttribute(id,cols+mtable.getAttribute(id));
- }}
- }
- }
- //
- // Force the table width to 100% when needed
- //
- if (this.nMMLforceWidth || !this.nMMLlaMatch)
- {mtable.setAttribute("width","100%")}
- }
- }
- });
- MML.mtr.Augment({
- toNativeMML: function (parent) {
- this.SUPER(arguments).toNativeMML.call(this,parent);
- var mtr = parent.lastChild;
- if (nMML.tableSpacingBug) {
- //
- // Set the row/column spacing. If this.parent.nMMLleftPadding does
- // not contain enough value, repeat the last one.
- //
- var lp = this.parent.nMMLleftPadding, M = lp.length;
- for (var mtd = mtr.firstChild, i = 0; mtd; mtd = mtd.nextSibling, i++) {
- CELLSPACING(mtd,this.nMMLtopPadding,lp[i < M ? i : M-1]);
- }
- }
- if (nMML.tableLabelBug) {
- var forceWidth = this.parent.nMMLforceWidth,
- side = this.parent.Get("side").charAt(0),
- align = HUB.config.displayAlign.charAt(0);
- if (this.parent.nMMLhasLabels && mtr.firstChild) {
- //
- // If we add a label or padding column on the left of mlabeledtr,
- // mirror that here and remove padding from first table mtd
- // so the spacing is consistent with unlabeled equations
- //
- if (forceWidth || side !== "r") {
- NOPADDING("Left",mtr.firstChild);
- if (align !== "l") {
- mtr.insertBefore(this.NativeMMLelement("mtd"),mtr.firstChild)
- .setAttribute("style","padding:0");
- }
- if (side === "l") {
- mtr.insertBefore(this.NativeMMLelement("mtd"),mtr.firstChild)
- .setAttribute("style","padding:0");
- }
- }
- //
- // If columns were added on the right, remove mtd padding
- // so that spacing is consistent with unlabled equations
- //
- if (forceWidth || side !== "l") {NOPADDING("Right",mtr.lastChild)}
- }
- }
- }
- });
- MML.mlabeledtr.Augment({
- toNativeMML: function (parent) {
- var mtr = this.NativeMMLelement("mtr");
- this.NativeMMLattributes(mtr);
- //
- // Add row data
- //
- for (var i = 1, m = this.data.length; i < m; i++) {
- if (this.data[i]) {this.data[i].toNativeMML(mtr)}
- else {mtr.appendChild(this.NativeMMLelement("mtd"))}
- }
- if (nMML.tableSpacingBug) {
- //
- // Set the row/column spacing. If this.parent.nMMLleftPadding does
- // not contain enough value, repeat the last one.
- //
- var lp = this.parent.nMMLleftPadding, M = lp.length; i = 0;
- for (var mtd = mtr.firstChild; mtd; mtd = mtd.nextSibling, i++) {
- CELLSPACING(mtd,this.nMMLtopPadding,lp[i < M ? i : M-1]);
- }
- }
- if (nMML.tableLabelBug && this.data[0]) {
- var side = this.parent.Get("side").charAt(0),
- align = HUB.config.displayAlign.charAt(0),
- indent = HUB.config.displayIndent;
- //
- // Create label and either set the column width (if label is on the
- // same side as the alignment), or use mpadded to hide the label
- // width
- //
- this.data[0].toNativeMML(mtr);
- var label = mtr.lastChild, pad = label;
- if (side === align) {
- label.setAttribute("style","width:"+indent);
- label.setAttribute("columnalign",HUB.config.displayAlign);
- } else {
- pad = this.NativeMMLelement("mpadded");
- pad.setAttribute("style","width:0");
- pad.setAttribute("width","0px");
- pad.appendChild(label.firstChild);
- label.appendChild(pad);
- }
- NOPADDING("",label); mtr.removeChild(label);
- //
- // Get spacing to use for separation of label from main table
- //
- var width = 100, forceWidth = this.parent.nMMLforceWidth;
- if ((this.parent.width||"").match(/%/)) {
- width -= parseFloat(this.parent.width)
- };
- var w = width;
- //
- // Add spacing (and possibly label) at the left if needed
- //
- if (forceWidth || side !== "r") {
- NOPADDING("Left",mtr.firstChild);
- if (align !== "l") {
- if (align === "c") {w /= 2}; width -= w;
- mtr.insertBefore(this.NativeMMLelement("mtd"),mtr.firstChild)
- .setAttribute("style","padding:0;width:"+w+"%");
- }
- if (side === "l") {mtr.insertBefore(label,mtr.firstChild)}
- }
- //
- // Add spacing (and possibly label) at the right if needed
- //
- if (forceWidth || side !== "l") {
- NOPADDING("Right",mtr.lastChild);
- if (align !== "r") {
- mtr.appendChild(this.NativeMMLelement("mtd"))
- .setAttribute("style","padding:0;width:"+width+"%");
- }
- if (side === "r") {
- if (side !== align) {pad.setAttribute("lspace","-1width")}
- mtr.appendChild(label);
- }
- }
- }
- //
- // Add row to table
- //
- parent.appendChild(mtr);
- }
- });
-
- MML.mtd.Augment({
- toNativeMML: function (parent) {
- var tag = parent.appendChild(this.NativeMMLelement(this.type));
- this.NativeMMLattributes(tag);
- if (nMML.mtdWidthBug) {
- nMML.adjustWidths.push(tag);
- tag = tag.appendChild(this.NativeMMLelement("mrow"));
- }
- for (var i = 0, m = this.data.length; i < m; i++) {
- if (this.data[i]) {this.data[i].toNativeMML(tag)}
- else {tag.appendChild(this.NativeMMLelement("mrow"))}
- }
- }
- });
-
- MML.mspace.Augment({
- toNativeMML: function (parent) {
- this.SUPER(arguments).toNativeMML.call(this,parent);
- if (nMML.spaceWidthBug && this.width) {
- var mspace = parent.lastChild;
- var width = mspace.getAttribute("width");
- var style = (mspace.getAttribute("style") || "").replace(/;?\s*/,"; ");
- mspace.setAttribute("style",style+"width:"+width);
- }
- }
- });
-
- MML.mn.Augment({
- NativeMMLremapMinus: function (text) {return text.replace(/^-/,"\u2212")},
- toNativeMML: function (parent) {
- var tag = this.NativeMMLelement(this.type);
- this.NativeMMLattributes(tag);
- var remap = this.NativeMMLremapMinus;
- for (var i = 0, m = this.data.length; i < m; i++) {
- if (this.data[i]) {
- this.data[i].toNativeMML(tag,remap);
- remap = null;
- }
- }
- parent.appendChild(tag);
- }
- });
- var fontDir = AJAX.fileURL(MathJax.OutputJax.fontDir+"/HTML-CSS/TeX/otf");
- /*
- * Add fix for mathvariant issues
- */
- nMML.Augment({
- config: {
- styles: {
- '[class="MJX-tex-oldstyle"]': {"font-family":"MathJax_Caligraphic, MathJax_Caligraphic-WEB"},
- '[class="MJX-tex-oldstyle-bold"]': {"font-family":"MathJax_Caligraphic, MathJax_Caligraphic-WEB", "font-weight":"bold"},
- '[class="MJX-tex-caligraphic"]': {"font-family":"MathJax_Caligraphic, MathJax_Caligraphic-WEB"},
- '[class="MJX-tex-caligraphic-bold"]': {"font-family":"MathJax_Caligraphic, MathJax_Caligraphic-WEB", "font-weight":"bold"},
- '@font-face /*1*/': {
- "font-family": "MathJax_Caligraphic-WEB",
- "src": "url('"+fontDir+"/MathJax_Caligraphic-Regular.otf')"
- },
- '@font-face /*2*/': {
- "font-family": "MathJax_Caligraphic-WEB", "font-weight":"bold",
- "src": "url('"+fontDir+"/MathJax_Caligraphic-Bold.otf')"
- }
- }
- }
- });
- if (!this.handlesVariants) {
- nMML.Augment({
- config: {
- styles: {
- '[mathvariant="double-struck"]': {"font-family":"MathJax_AMS, MathJax_AMS-WEB"},
- '[mathvariant="script"]': {"font-family":"MathJax_Script, MathJax_Script-WEB"},
- '[mathvariant="fraktur"]': {"font-family":"MathJax_Fraktur, MathJax_Fraktur-WEB"},
- '[mathvariant="bold-script"]': {"font-family":"MathJax_Script, MathJax_Caligraphic-WEB", "font-weight":"bold"},
- '[mathvariant="bold-fraktur"]': {"font-family":"MathJax_Fraktur, MathJax_Fraktur-WEB", "font-weight":"bold"},
- '[mathvariant="monospace"]': {"font-family":"monospace"},
- '[mathvariant="sans-serif"]': {"font-family":"sans-serif"},
- '[mathvariant="bold-sans-serif"]': {"font-family":"sans-serif", "font-weight":"bold"},
- '[mathvariant="sans-serif-italic"]': {"font-family":"sans-serif", "font-style":"italic"},
- '[mathvariant="sans-serif-bold-italic"]': {"font-family":"sans-serif", "font-style":"italic", "font-weight":"bold"},
- '@font-face /*3*/': {
- "font-family": "MathJax_AMS-WEB",
- "src": "url('"+fontDir+"/MathJax_AMS-Regular.otf')"
- },
- '@font-face /*4*/': {
- "font-family": "MathJax_Script-WEB",
- "src": "url('"+fontDir+"/MathJax_Script-Regular.otf')"
- },
- '@font-face /*5*/': {
- "font-family": "MathJax_Fraktur-WEB",
- "src": "url('"+fontDir+"/MathJax_Fraktur-Regular.otf')"
- },
- '@font-face /*6*/': {
- "font-family": "MathJax_Fraktur-WEB", "font-weight":"bold",
- "src": "url('"+fontDir+"/MathJax_Fraktur-Bold.otf')"
- }
- }
- }
- });
- }
- }
-
- MML.math.Augment({
- toNativeMML: function (parent,jax) {
- var tag = this.NativeMMLelement(this.type), math = tag;
- var annotate = (jax ? MathJax.InputJax[jax.inputJax].annotationEncoding : null);
- var i, m;
- nMML.adjustWidths = [];
- //
- // Some browsers don't seem to add the xmlns attribute, so do it by hand.
- //
- tag.setAttribute("xmlns",nMML.MMLnamespace);
- this.NativeMMLattributes(tag);
- //
- // Use an extra <mrow> in FF so that we can get the correct width
- // (the math element doesn't always have an accurate one, see below)
- //
- if (nMML.widthBug) {tag = tag.appendChild(this.NativeMMLelement("mrow"))}
- //
- // Addannotation if the input jax provides an annotation encoding
- //
- if (annotate) {
- tag = tag.appendChild(this.NativeMMLelement("semantics"))
- tag.appendChild(this.NativeMMLelement("mrow"));
- var annotation = tag.appendChild(this.NativeMMLelement("annotation"));
- annotation.appendChild(document.createTextNode(jax.originalText));
- annotation.setAttribute("encoding",annotate);
- tag = tag.firstChild; // mrow
- }
- //
- // Add the children
- //
- for (i = 0, m = this.data.length; i < m; i++) {
- if (this.data[i]) {this.data[i].toNativeMML(tag)}
- else {tag.appendChild(this.NativeMMLelement("mrow"))}
- }
- //
- // Look for a top-level mtable and if it has labels
- // Make sure the containers have 100% width, when needed.
- // If the label is on the same side as alignment,
- // override the margin set by the stylesheet.
- //
- var mtable = ((this.data[0]||{data:[]}).data[0]||{});
- if (mtable.nMMLhasLabels) {
- if (mtable.nMMLforceWidth || !mtable.nMMLlaMatch) {
- tag.setAttribute("style","width:100%") // mrow node
- if (annotate) tag.parentNode.setAttribute("style","width:100%"); // semantics node
- };
- if (mtable.nMMLlaMatch) {
- if (parent.parentNode.parentNode.nodeName.toLowerCase() === "div") {
- parent.parentNode.parentNode.style
- .setProperty("margin-"+HUB.config.displayAlign,"0px","important");
- }
- }
- }
- //
- // Check if container must have width set to 100%
- //
- var fullWidth = nMML.isFullWidth(math);
- if (fullWidth) {parent.style.width = parent.parentNode.style.width = "100%"}
- //
- // Add the math to the page
- //
- parent.appendChild(math);
- //
- // Firefox can't seem to get the width of <math> elements right, so
- // use an <mrow> to get the actual width and set the style on the
- // parent element to match. Even if we set the <math> width properly,
- // it doesn't seem to propagate up to the <span> correctly.
- //
- if (nMML.widthBug &&!fullWidth) {
- //
- // Convert size to ex's so that it scales properly if the print media
- // has a different font size.
- //
- parent.style.width = (math.firstChild.scrollWidth/nMML.ex/nMML.scale).toFixed(3) + "ex";
- //
- // Save size for later when we check if Web fonts have arrived
- //
- if (jax) {jax.NativeMML.scrollWidth = math.firstChild.scrollWidth}
- }
- if (nMML.adjustWidths.length) {
- //
- // Firefox gets the widths of <mtd> elements wrong, so run
- // through them (now that the math is part of the page) and
- // fix them up. Use ex's so that they print properly (see above).
- //
- var mtd = [];
- for (i = 0, m = nMML.adjustWidths.length; i < m; i++) {
- tag = nMML.adjustWidths[i];
- var style = tag.getAttribute("style") || "";
- if (!style.match(/(^|;)\s*min-width:/)) {
- var width = tag.firstChild.scrollWidth;
- mtd.push(width);
- width = (width/nMML.ex).toFixed(3)+"ex";
- style = style.replace(/;?\s*$/,"; ");
- tag.setAttribute("style",style+"min-width:"+width);
- }
- }
- //
- // Save the lists so that we can check them later for web font downloads
- //
- if (!jax) {jax = HUB.getJaxFor(parent)}
- if (jax) {jax.NativeMML.mtds = mtd}
- math.MathJaxMtds = nMML.adjustWidths;
- nMML.adjustWidths = []; // clear it so we don't hold onto the DOM elements
- }
- }
- });
- MML.mfenced.Augment({
- toNativeMML: function (parent) {
- if (!nMML.mfencedBug) {
- this.SUPER(arguments).toNativeMML.call(this,parent);
- return;
- }
- //
- // Some browsers do not handle <mfenced> very well. The MathML spec
- // suggests this equivalent construction instead, so let's use it:
- // <mrow> open, child1, sep1, child2, ... sep(N-1), childN, close</mrow>
- // Opera is a bit special: it does not support stretchy <mo>, does not
- // parse mfenced@open/mfenced@close very well, does not support
- // mfenced@separators and only displays the first child of the <mfenced>
- // element... For this browser, we will use this construction:
- // <mfenced open="open" close="close">
- // <mrow>child1, sep1, child2, sep2, ..., sep(N-1), childN</mrow>
- // </mfenced>
- //
- var isOpera = HUB.Browser.isOpera;
- var i, m, operator;
- //
- // parse the open, close and separators attributes.
- //
- var values = this.getValues("open","close","separators");
- values.open = values.open.replace(/^\s+/,"").replace(/\s+$/,"");
- values.close = values.close.replace(/^\s+/,"").replace(/\s+$/,"");
- values.separators = values.separators.replace(/\s+/g,"").split("");
- if (values.separators.length == 0) {
- //
- // No separators specified, do not use separators at all.
- //
- values.separators = null;
- } else if (values.separators.length < this.data.length-1) {
- //
- // There are not enough separators, repeat the last one.
- //
- var s = values.separators[values.separators.length-1];
- for (i = this.data.length-1-values.separators.length; i > 0; i--)
- {values.separators.push(s)}
- }
- //
- // Create an <mrow> container and attach the attributes of the
- // <mfenced> element to it. Note: removeAttribute does not raise any
- // exception when the attributes is absent.
- //
- var tag = this.NativeMMLelement(isOpera ? this.type : "mrow");
- this.NativeMMLattributes(tag);
- tag.removeAttribute("separators");
- if (isOpera) {
- tag.setAttribute("open", values.open);
- tag.setAttribute("close", values.close);
- if (this.data.length > 1) {
- parent.appendChild(tag); parent = tag;
- tag = this.NativeMMLelement("mrow");
- }
- } else {
- tag.removeAttribute("open");
- tag.removeAttribute("close");
- }
- if (!isOpera) {
- //
- // Append the opening fence
- //
- operator = this.NativeMMLelement("mo");
- operator.setAttribute("fence", "true");
- operator.textContent = values.open;
- tag.appendChild(operator);
- }
- //
- // Append the content of the <mfenced>
- //
- for (i = 0, m = this.data.length; i < m; i++) {
- if (values.separators && i > 0) {
- operator = this.NativeMMLelement("mo");
- operator.setAttribute("separator", "true");
- operator.textContent = values.separators[i-1];
- tag.appendChild(operator);
- }
- if (this.data[i]) {this.data[i].toNativeMML(tag)}
- else {tag.appendChild(this.NativeMMLelement("mrow"))}
- }
- if (!isOpera) {
- //
- // Append the closing fence
- //
- operator = this.NativeMMLelement("mo");
- operator.setAttribute("fence", "true");
- operator.textContent = values.close;
- tag.appendChild(operator);
- }
- // finally, append the new element to the parent.
- parent.appendChild(tag);
- }
- });
- MML.TeXAtom.Augment({
- //
- // Convert TeXatom to an mrow
- //
- toNativeMML: function (parent) {
- // FIXME: Handle spacing using mpadded?
- var tag = this.NativeMMLelement("mrow");
- this.NativeMMLattributes(tag);
- this.data[0].toNativeMML(tag);
- parent.appendChild(tag);
- }
- });
- MML.chars.Augment({
- //
- // Add a text node
- //
- toNativeMML: function (parent,remap) {
- var text = this.toString();
- if (remap) text = remap(text);
- parent.appendChild(document.createTextNode(text));
- }
- });
- MML.entity.Augment({
- //
- // Add a text node
- //
- toNativeMML: function (parent) {
- parent.appendChild(document.createTextNode(this.toString()));
- }
- });
-
- MML.xml.Augment({
- //
- // Insert the XML verbatim
- //
- toNativeMML: function (parent) {
- for (var i = 0, m = this.data.length; i < m; i++)
- {parent.appendChild(this.data[i].cloneNode(true))}
- }
- });
- MML.mi.Augment({
- toNativeMML: function (parent) {
- this.SUPER(arguments).toNativeMML.call(this,parent);
- if (nMML.miItalicBug) {
- if (this.Get("mathvariant") === MML.VARIANT.NORMAL) {
- //
- // When not explicitly specified, mathvariant is set to "italic"
- // with single char mi and to "normal" with multiple char mi.
- // Some browsers always set the default to "italic", so let's
- // attach an explicit mathvariant="normal" attribute.
- //
- var mi = parent.lastChild;
- mi.setAttribute("mathvariant",MML.VARIANT.NORMAL);
- }
- }
- }
- });
- MML.mo.Augment({
- toNativeMML: function (parent) {
- this.SUPER(arguments).toNativeMML.call(this,parent);
- if (nMML.webkitMoSpacingBug) {
- //
- // WebKit does not support lspace/rspace values around operators
- // (neither explicit nor given by the operator dictionary) and uses
- // constant values instead. So let's modify the CSS properties here.
- //
- var lspace = 0, rspace = 0, p = this.parent;
- if (p && p.type === "mrow" && (p.inferred || !p.isEmbellished())) {
- //
- // Retrieve the values of lspace/rspace and convert named spaces.
- // Other values (except unitless) will be parsed by the CSS engine.
- //
- var values = this.getValues("lspace", "rspace");
- lspace = values.lspace, rspace = values.rspace;
- if (nMML.NAMEDSPACE[lspace]) {lspace = nMML.NAMEDSPACE[lspace]}
- if (nMML.NAMEDSPACE[rspace]) {rspace = nMML.NAMEDSPACE[rspace]}
- }
- //
- // Now update -webkit-margin-start and -webkit-margin-end.
- //
- var mo = parent.lastChild;
- var span = HTML.Element("span");
- span.style.cssText = (mo.getAttribute("style")||"");
- span.style.setProperty("-webkit-margin-start", lspace);
- span.style.setProperty("-webkit-margin-end", rspace);
- mo.setAttribute("style",span.style.cssText);
- }
- }
- });
- MML.mmultiscripts.Augment({
- toNativeMML: function (parent) {
- //
- // Some browsers do not implement the mmultiscripts element.
- // Try to emulate the support using basic script elements.
- //
- if (!nMML.mmultiscriptsBug || this.data.length === 0) {
- this.SUPER(arguments).toNativeMML.call(this,parent);
- return;
- }
- //
- // The children of the mmultiscripts will be wrapped in an mrow so that
- // attributes and properties set on the original mmultiscripts will
- // be reflected on this mrow element.
- //
- var tag = this.NativeMMLelement("mrow");
- this.NativeMMLattributes(tag);
- //
- // Create the base
- //
- if (this.data[0]) {this.data[0].toNativeMML(tag)}
- else {tag.appendChild(this.NativeMMLelement("mrow"))}
- var base = tag.removeChild(tag.lastChild);
- //
- // Process the postscript pairs
- //
- var m = this.data.length, i, msubsup;
- for (i = 1; i < m; i+=2) {
- if (this.data[i].type === "mprescripts") break;
- msubsup = this.NativeMMLelement("msubsup");
- msubsup.appendChild(base);
- //
- // append the subscript
- //
- if (this.data[i]) {this.data[i].toNativeMML(msubsup)}
- else {msubsup.appendChild(this.NativeMMLelement("mrow"))}
- //
- // append the supscript
- //
- if (i+1 < m && this.data[i+1]) {this.data[i+1].toNativeMML(msubsup)}
- else {msubsup.appendChild(this.NativeMMLelement("mrow"))}
- base = msubsup;
- }
- tag.appendChild(base);
- //
- // Process the prescript pairs
- //
- for (i++; i < m; i+=2) {
- msubsup = this.NativeMMLelement("msubsup");
- msubsup.appendChild(this.NativeMMLelement("mrow"));
- //
- // append the presubscript
- //
- if (this.data[i]) {this.data[i].toNativeMML(msubsup)}
- else {msubsup.appendChild(this.NativeMMLelement("mrow"))}
- //
- // append the presupscript
- //
- if (i+1 < m && this.data[i+1]) {this.data[i+1].toNativeMML(msubsup)}
- else {msubsup.appendChild(this.NativeMMLelement("mrow"))}
- tag.insertBefore(msubsup, base);
- }
- parent.appendChild(tag);
- }
- });
- HUB.Register.StartupHook("TeX mathchoice Ready",function () {
- MML.TeXmathchoice.Augment({
- //
- // Get the MathML for the selected choice
- //
- toNativeMML: function (parent) {this.Core().toNativeMML(parent)}
- });
- });
- //
- // Loading isn't complete until the element jax is modified,
- // but can't call loadComplete within the callback for "mml Jax Ready"
- // (it would call NativeMML's Require routine, asking for the mml jax again)
- // so wait until after the mml jax has finished processing.
- //
- setTimeout(MathJax.Callback(["loadComplete",nMML,"jax.js"]),0);
- });
-
- //
- // Determine browser characteristics
- //
- HUB.Browser.Select({
- MSIE: function (browser) {
- var mode = (document.documentMode || 0);
- nMML.msieIE8HeightBug = (mode === 8);
- },
- Opera: function (browser) {
- nMML.stretchyMoBug = true;
- nMML.tableLabelBug = true;
- nMML.mfencedBug = true;
- nMML.miBug = true;
- nMML.mmultiscriptsBug = true;
- },
- Firefox: function (browser) {
- var is29 = browser.versionAtLeast("29.0");
- nMML.ffTableWidthBug = !browser.versionAtLeast("13.0"); // <mtable width="xx"> not implemented
- nMML.forceReflow = !is29; // <mtable> with alignments set don't display properly without a reflow
- nMML.widthBug = !is29; // <math> elements don't always get the correct width
- nMML.mtdWidthBug = true; // <mtd> widths not properly determined
- nMML.handlesVariants = is29; // FF >=29 handles all math variants
- // In Firefox < 20, the intrinsic width of <mspace> is not computed
- // correctly and thus the element is displayed incorrectly in <mtable>.
- nMML.spaceWidthBug = !browser.versionAtLeast("20.0");
- // mtable@rowspacing/mtable@columnspacing not supported.
- nMML.tableSpacingBug = !browser.versionAtLeast("33.0");
- nMML.tableLabelBug = true; // mlabeledtr is not implemented.
- nMML.mfencedBug = true; // mfenced not displayed correctly
- },
- Chrome: function (browser) {
- nMML.tableSpacingBug = true;
- nMML.tableLabelBug = true;
- nMML.mfencedBug = true;
- },
- Safari: function (browser) {
- nMML.tableSpacingBug = true;
- nMML.tableLabelBug = true;
- nMML.mfencedBug = true;
- nMML.miItalicBug = true;
- nMML.webkitMoSpacingBug = true;
- nMML.spaceWidthBug = true;
- nMML.mmultiscriptsBug = true;
- }
- });
-
- HUB.Register.StartupHook("End Cookie",function () {
- if (HUB.config.menuSettings.zoom !== "None")
- {AJAX.Require("[MathJax]/extensions/MathZoom.js")}
- });
- })(MathJax.OutputJax.NativeMML, MathJax.Hub, MathJax.Ajax, MathJax.HTML);
|