~ubuntu-branches/ubuntu/utopic/yelp/utopic-proposed

« back to all changes in this revision

Viewing changes to data/mathjax/unpacked/jax/output/NativeMML/jax.js

  • Committer: Package Import Robot
  • Author(s): Matthew Fischer
  • Date: 2013-05-25 20:01:06 UTC
  • mfrom: (1.1.67) (131.1.1 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130525200106-4re1oimhqy8exd9b
Tags: 3.8.1-0ubuntu1
* New upstream release (LP: #1184244)
  - Added test token for classic mode (Matthias Clasen)
  - Updated translations
  - Stop checking for pangox and X11 (Emilio Pozuelo Monfort)
  - Add keywords to the desktop file (Matthias Clasen)
  - Fixed handling of xref links with anchors, #686095 (Tails developers)
  - Fixed various memory management bugs, #683100 (Carlos Garcia Campos)
  - Added local copy of MathJax for MathML display (Shaun McCance)
  - Added support for xdg help system in All Documents (Shaun McCance)
  - Fixed if:test="action:install" (Shaun McCance)
  - Switched to using 'itstool -j' for XSL domain (Shaun McCance)
* Refreshed patches, removed some patches that have been unused for some
  time.
  - debian/patches/00_no_am_gnu_gettext.patch - Removed, unused
  - debian/patches/02_man-utf8.patch - Removed, unused
  - debian/patches/04_man-utf8.patch - Removed, unused

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*************************************************************
 
2
 *
 
3
 *  MathJax/jax/output/NativeMML/jax.js
 
4
 *
 
5
 *  Implements the NativeMML OutputJax that displays mathematics
 
6
 *  using a browser's native MathML capabilities (if any).
 
7
 *  
 
8
 *  ---------------------------------------------------------------------
 
9
 *  
 
10
 *  Copyright (c) 2010-2012 Design Science, Inc.
 
11
 * 
 
12
 *  Licensed under the Apache License, Version 2.0 (the "License");
 
13
 *  you may not use this file except in compliance with the License.
 
14
 *  You may obtain a copy of the License at
 
15
 * 
 
16
 *      http://www.apache.org/licenses/LICENSE-2.0
 
17
 * 
 
18
 *  Unless required by applicable law or agreed to in writing, software
 
19
 *  distributed under the License is distributed on an "AS IS" BASIS,
 
20
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
21
 *  See the License for the specific language governing permissions and
 
22
 *  limitations under the License.
 
23
 */
 
24
 
 
25
(function (nMML,HUB,AJAX,HTML) {
 
26
  var MML, isMSIE = HUB.Browser.isMSIE;
 
27
  
 
28
  var EVENT, TOUCH, HOVER, ZOOM; // filled in later
 
29
 
 
30
  HUB.Register.StartupHook("MathZoom Ready",function () {ZOOM = MathJax.Extension.MathZoom});
 
31
  
 
32
  nMML.Augment({
 
33
    //
 
34
    //  User can configure styles
 
35
    //
 
36
    config: {
 
37
      styles: {
 
38
        ".MathJax_MathML": {
 
39
          "font-style":      "normal",
 
40
          "font-weight":     "normal",
 
41
          "line-height":     "normal",
 
42
          "font-size":       "100%",
 
43
          "font-size-adjust":"none",
 
44
          "text-indent":     0,
 
45
          "text-align":      "left",
 
46
          "text-transform":  "none",
 
47
          "letter-spacing":  "normal",
 
48
          "word-spacing":    "normal",
 
49
          "word-wrap":       "normal",
 
50
          "white-space":     "nowrap",
 
51
          "float":           "none",
 
52
          "direction":       "ltr",
 
53
          border: 0, padding: 0, margin: 0
 
54
        },
 
55
        
 
56
        "span.MathJax_MathML": {
 
57
          display: "inline"
 
58
        },
 
59
        
 
60
        "div.MathJax_MathML": {
 
61
          display: "block"
 
62
        },
 
63
        
 
64
        ".MathJax_mmlExBox": {
 
65
          display:"block", overflow:"hidden",
 
66
          height:"1px", width:"60ex",
 
67
          padding:0, border: 0, margin: 0
 
68
        }
 
69
      }
 
70
    },
 
71
    settings: HUB.config.menuSettings,
 
72
    
 
73
    Config: function () {
 
74
      this.SUPER(arguments).Config.call(this);
 
75
      if (this.settings.scale) {this.config.scale = this.settings.scale}
 
76
      //
 
77
      //  Insert styling to take account of displayAlign and displayIndent
 
78
      //
 
79
      if (HUB.config.displayAlign !== "center") {
 
80
        var align = HUB.config.displayAlign, indent = HUB.config.displayIndent;
 
81
        var def = {"text-align": align+"!important"}; def["margin-"+align] = indent+"!important";
 
82
        MathJax.Hub.Insert(this.config.styles,{
 
83
          "div.MathJax_MathML": def,
 
84
          "div.MathJax_MathML math": {"text-align": align},
 
85
          "div.MathJax_MathContainer > span": {"text-align": align+"!important"}
 
86
        });
 
87
      }
 
88
      if (!this.require) {this.require = []}
 
89
      this.require.push(MathJax.OutputJax.extensionDir+"/MathEvents.js");
 
90
    },
 
91
    Startup: function () {
 
92
      //  Set up event handling
 
93
      EVENT = MathJax.Extension.MathEvents.Event;
 
94
      TOUCH = MathJax.Extension.MathEvents.Touch;
 
95
      HOVER = MathJax.Extension.MathEvents.Hover;
 
96
      this.ContextMenu = EVENT.ContextMenu;
 
97
      this.Mousedown   = EVENT.AltContextMenu;
 
98
      this.Mouseover   = HOVER.Mouseover;
 
99
      this.Mouseout    = HOVER.Mouseout;
 
100
      this.Mousemove   = HOVER.Mousemove;
 
101
 
 
102
      if (!isMSIE) {
 
103
        // Used in preTranslate to get scaling factors
 
104
        this.EmExSpan = HTML.Element("span",
 
105
          {style:{position:"absolute","font-size-adjust":"none"}},
 
106
          [
 
107
            ["div",{className:"MathJax_mmlExBox"}],
 
108
            ["span",{className:"MathJax_MathML"}]
 
109
          ]
 
110
        );
 
111
        MML.math(MML.mspace().With({width:"60ex"})).toNativeMML(this.EmExSpan.lastChild);
 
112
      }
 
113
 
 
114
      //  Set up styles
 
115
      return AJAX.Styles(this.config.styles);
 
116
    },
 
117
    //
 
118
    //  Set up MathPlayer for IE on the first time through.
 
119
    //
 
120
    InitializeMML: function () {
 
121
      this.initialized = true;
 
122
      if (isMSIE) {
 
123
        try {
 
124
          //
 
125
          //  Insert data needed to use MathPlayer for MathML output
 
126
          //
 
127
          if (!HUB.Browser.mpNamespace) {
 
128
            var mathplayer = document.createElement("object");
 
129
            mathplayer.id = "mathplayer"; mathplayer.classid = "clsid:32F66A20-7614-11D4-BD11-00104BD3F987";
 
130
            document.getElementsByTagName("head")[0].appendChild(mathplayer);
 
131
            document.namespaces.add("m","http://www.w3.org/1998/Math/MathML");
 
132
            HUB.Browser.mpNamespace = true;
 
133
          }
 
134
          if (!HUB.Browser.mpImported) {
 
135
            document.namespaces.m.doImport("#mathplayer");
 
136
            HUB.Browser.mpImported = true;
 
137
          }
 
138
        } catch (err) {
 
139
          //
 
140
          //  If that fails, give an alert about security settings
 
141
          //
 
142
          alert("MathJax was not able to set up MathPlayer.\n\n"+
 
143
                "If MathPlayer is not installed, you need to install it first.\n"+
 
144
                "Otherwise, your security settings may be preventing ActiveX     \n"+
 
145
                "controls from running.  Use the Internet Options item under\n"+
 
146
                "the Tools menu and select the Security tab, then press the\n"+
 
147
                "Custom Level button. Check that the settings for\n"+
 
148
                "'Run ActiveX Controls', and 'Binary and script behaviors'\n"+
 
149
                "are enabled.\n\n"+
 
150
                "Currently you will see error messages rather than\n"+
 
151
                "typeset mathematics.");
 
152
        }
 
153
      } else {
 
154
        //
 
155
        //  Get the default sizes (need styles in place to do this)
 
156
        //
 
157
        document.body.appendChild(this.EmExSpan);
 
158
        this.defaultEx  = this.EmExSpan.firstChild.offsetWidth/60;
 
159
        this.defaultMEx = this.EmExSpan.lastChild.offsetWidth/60;
 
160
        document.body.removeChild(this.EmExSpan);
 
161
      }
 
162
    },
 
163
    
 
164
    preTranslate: function (state) {
 
165
      var scripts = state.jax[this.id], i, m = scripts.length,
 
166
          script, prev, span, test, math, jax, ex, mex, scale;
 
167
      for (i = 0; i < m; i++) {
 
168
        script = scripts[i]; if (!script.parentNode) continue;
 
169
        if (!this.initialized) {this.InitializeMML()}
 
170
        //
 
171
        //  Remove any existing output
 
172
        //
 
173
        prev = script.previousSibling;
 
174
        if (prev && prev.className === "MathJax_MathML") {prev.parentNode.removeChild(prev)}
 
175
        //
 
176
        //  Add the MathJax span
 
177
        //
 
178
        jax = script.MathJax.elementJax; if (!jax) continue;
 
179
        math = jax.root; jax.NativeMML = {};
 
180
        var type = (math.Get("display") === "block" ? "div" : "span");
 
181
        span = HTML.Element(type,{
 
182
          className: "MathJax_MathML", id:jax.inputID+"-Frame"
 
183
        },[["span",{
 
184
            className:"MathJax_MathContainer", isMathJax: true, jaxID:this.id,
 
185
            style:{position:"relative", display:"inline-block", "white-space":"nowrap"}
 
186
          }, [["span",{isMathJax:true, style:{display:"inline-block"}}]] // for Firefox hover and zoom
 
187
        ]]);
 
188
        script.parentNode.insertBefore(span,script);
 
189
        //
 
190
        //  Add the test span for determining scales
 
191
        //
 
192
        if (!isMSIE) {script.parentNode.insertBefore(this.EmExSpan.cloneNode(true),script)}
 
193
      }
 
194
      //
 
195
      //  Determine the scaling factors for each script
 
196
      //  (this only requires one reflow rather than a reflow for each equation)
 
197
      //
 
198
      for (i = 0; i < m; i++) {
 
199
        script = scripts[i]; if (!script.parentNode) continue;
 
200
        jax = script.MathJax.elementJax; if (!jax) continue;
 
201
        if (!isMSIE) {
 
202
          test = script.previousSibling; span = test.previousSibling;
 
203
          ex = test.firstChild.offsetWidth/60;
 
204
          mex = test.lastChild.offsetWidth/60;
 
205
          if (ex === 0 || ex === "NaN") {ex = this.defaultEx; mex = this.defaultMEx}
 
206
          scale = (mex > 1 ? ex/mex : 1) * this.config.scale;
 
207
          scale = Math.floor(Math.max(this.config.minScaleAdjust/100,scale));
 
208
        } else {scale = 100}
 
209
        jax.NativeMML.fontSize = scale+"%";
 
210
      }
 
211
      //
 
212
      //  Remove the test spans used for determining scales
 
213
      //
 
214
      if (!isMSIE) {
 
215
        for (i = 0; i < m; i++) {
 
216
          script = scripts[i]; if (!script.parentNode || !script.MathJax.elementJax) continue;
 
217
          test = scripts[i].previousSibling;
 
218
          test.parentNode.removeChild(test);
 
219
        }
 
220
      }
 
221
    },
 
222
 
 
223
    //
 
224
    //  Add a SPAN to use as a container, and render the math into it
 
225
    //  
 
226
    Translate: function (script) {
 
227
      if (!script.parentNode) return;
 
228
      //
 
229
      //  Get the jax and the container and set the size
 
230
      //
 
231
      var jax = script.MathJax.elementJax, math = jax.root;
 
232
      var span = document.getElementById(jax.inputID+"-Frame"),
 
233
          container = span.firstChild, mspan = container.firstChild;
 
234
      span.style.fontSize = jax.NativeMML.fontSize;
 
235
      //
 
236
      //  Convert to MathML (if restarted, remove any partial math)
 
237
      //
 
238
      try {math.toNativeMML(mspan)} catch (err) {
 
239
        if (err.restart) {while (mspan.firstChild) {mspan.removeChild(mspan.firstChild)}}
 
240
        throw err;
 
241
      }
 
242
      //
 
243
      //  Add event handlers
 
244
      //
 
245
      if (isMSIE) {
 
246
        if (container.addEventListener) {
 
247
          for (var id in this.MSIE9events) {if (this.MSIE9events.hasOwnProperty(id)) {
 
248
            container.addEventListener(id,this.MSIE9event,true);
 
249
          }}
 
250
        } else {
 
251
          var config = (this.config.showMathMenuMSIE != null ? this : HUB).config;
 
252
          if (config.showMathMenuMSIE && !this.settings.mpContext && !this.settings.mpMouse)
 
253
                {this.MSIEoverlay(container)} else
 
254
                {container.style.position = ""; mspan.firstChild.onmousedown = this.MSIEaltMenu}
 
255
        }
 
256
      } else {
 
257
        container.oncontextmenu = EVENT.Menu;
 
258
        container.onmouseover   = EVENT.Mouseover;
 
259
        container.onmouseout    = EVENT.Mouseout;
 
260
        container.onmousedown   = EVENT.Mousedown;
 
261
        container.onclick       = EVENT.Click;
 
262
        container.ondblclick    = EVENT.DblClick;
 
263
        if (HUB.Browser.noContextMenu) {
 
264
          container.ontouchstart = TOUCH.start;
 
265
          container.ontouchend   = TOUCH.end;
 
266
        }
 
267
      }
 
268
    },
 
269
 
 
270
    postTranslate: function (state) {
 
271
      if (this.forceReflow) {
 
272
        //  Firefox messes up some mtable's when they are dynamically created
 
273
        //  but gets them right on a reflow, so force reflow by toggling a stylesheet
 
274
        var sheet = (document.styleSheets||[])[0]||{};
 
275
        sheet.disabled = true; sheet.disabled = false;
 
276
      }
 
277
    },
 
278
    
 
279
    //
 
280
    //  Remove MathML preceeding the script
 
281
    //
 
282
    Remove: function (jax) {
 
283
      var span = jax.SourceElement(); if (!span) return;
 
284
      span = span.previousSibling; if (!span) return;
 
285
      if (span.className.match(/MathJax_MathML/)) {span.parentNode.removeChild(span)}
 
286
    },
 
287
    //
 
288
    //  The namespace to use for MML
 
289
    //
 
290
    MMLnamespace: "http://www.w3.org/1998/Math/MathML",
 
291
 
 
292
    //
 
293
    //  For MSIE, we must overlay the MathPlayer object to trap the events
 
294
    //  (since they can't be cancelled when the events are on the <math> tag
 
295
    //  itself).  The events we DON'T want are transferred to the math element,
 
296
    //  and the others are handled directly.
 
297
    //
 
298
    MSIEoverlay: function (span) {
 
299
      var math = span.firstChild;
 
300
      if (math.nodeName.toLowerCase() === "span") {math = math.firstChild}
 
301
      var bbox = this.getHoverBBox(null,math,{});
 
302
      HTML.addElement(span,"span",{
 
303
        style:{display:"inline-block", width:0, height:0, position:"relative"}
 
304
      },[["span",{isMathJax: true, className: "MathJax_MathPlayer_Overlay",
 
305
        style:{
 
306
          display:"inline-block", position:"absolute",
 
307
          left:HOVER.Px(-bbox.w), top:HOVER.Px(-bbox.h-(bbox.y||0)-1),
 
308
          width:HOVER.Px(bbox.w), height:HOVER.Px(bbox.h+bbox.d), cursor:"pointer",
 
309
          "background-color":"white", filter:"alpha(opacity=0)"
 
310
        }
 
311
      }]]);
 
312
      HUB.Insert(span,{
 
313
        msieMath: math,
 
314
        onmousedown: this.MSIEevent, oncontextmenu: this.MSIEevent, onclick: this.MSIEevent,
 
315
        onmouseup: this.MSIEevent, onmousemove: this.MSIEevent, ondblclick: this.MSIEevent,
 
316
        onmouseover: this.MSIEevent, onmouseout: this.MSIEevent
 
317
      });
 
318
    },
 
319
    MSIEevents: {
 
320
      mousedown:"Mousedown", contextmenu:"ContextMenu", click:"Click",
 
321
      mouseup:"Mouseup", mousemove:"Mousemove", dblclick: "DblClick",
 
322
      mouseover:"Mouseover", mouseout:"Mouseout"
 
323
    },
 
324
    MSIEevent: function () {
 
325
      var event = window.event;
 
326
      var type = nMML.MSIEevents[event.type];
 
327
      if (nMML[type] && nMML[type](event,this) === false) {return false}
 
328
      if (ZOOM && ZOOM.HandleEvent(event,type,this) === false) {return false}
 
329
      if (event.srcElement.className === "MathJax_MathPlayer_Overlay" && this.msieMath.fireEvent) {
 
330
        // for now, ignore all other events.  This will disable MathPlayer's zoom
 
331
        // feature, but also its <maction> support.
 
332
        if (type === "ContextMenu" || type === "Mouseover" || type === "Mouseout")
 
333
          {this.msieMath.fireEvent("on"+event.type,event)}
 
334
      }
 
335
      return EVENT.False(event);
 
336
    },
 
337
    MSIEaltMenu: function () {
 
338
      var container = this.parentNode.parentNode;
 
339
      while (!container.jaxID) {container = container.parentNode}
 
340
      EVENT.AltContextMenu(window.event,container);
 
341
    },
 
342
 
 
343
    MSIE9events: {
 
344
      contextmenu:"Menu", click:"Click", dblclick: "DblClick",
 
345
      mouseup:"False", mouseover:"Mouseover", mouseout:"Mouseout"
 
346
    },
 
347
    MSIE9event: function (event) {
 
348
      if (event.type === "contextmenu" && nMML.settings.mpContext) {return true}
 
349
      if (event.type === "mouseup" && nMML.settings.mpMouse) {return true}
 
350
      if (event.type === "click" && nMML.settings.mpContext)
 
351
        {return EVENT.AltContextMenu(event,this)}
 
352
      var type = nMML.MSIE9events[event.type];
 
353
      return EVENT[type].call(this,event);
 
354
    },
 
355
 
 
356
    getJaxFromMath: function (math) {
 
357
      math = math.parentNode;
 
358
      do {math = math.nextSibling} while (math && math.nodeName.toLowerCase() !== "script");
 
359
      return HUB.getJaxFor(math);
 
360
    },
 
361
    getHoverSpan: function (jax,math) {return math.firstChild},
 
362
    getHoverBBox: function (jax,span,math) {return EVENT.getBBox(span.parentNode)},
 
363
 
 
364
    Zoom: function (jax,span,math,Mw,Mh) {
 
365
      jax.root.toNativeMML(span);
 
366
      if (this.msieIE8HeightBug) {span.style.position = "absolute"}
 
367
      var mW = math.offsetWidth  || math.scrollWidth,
 
368
          mH = math.offsetHeight || math.scrollHeight;
 
369
      var zW = span.offsetWidth, zH = span.offsetHeight;
 
370
      if (this.msieIE8HeightBug) {span.style.position = ""}
 
371
      return {Y:-EVENT.getBBox(span.parentNode).h, mW:mW, mH:mH, zW:zW, zH:zH}
 
372
    },
 
373
 
 
374
    NAMEDSPACE: {
 
375
      negativeveryverythinmathspace:  "-.0556em",
 
376
      negativeverythinmathspace:      "-.1111em",
 
377
      negativethinmathspace:          "-.1667em",
 
378
      negativemediummathspace:        "-.2222em",
 
379
      negativethickmathspace:         "-.2778em",
 
380
      negativeverythickmathspace:     "-.3333em",
 
381
      negativeveryverythickmathspace: "-.3889em"
 
382
    }
 
383
  });
 
384
 
 
385
  HUB.Register.StartupHook("mml Jax Ready",function () {
 
386
 
 
387
    MML = MathJax.ElementJax.mml;
 
388
 
 
389
    MML.mbase.Augment({
 
390
      //
 
391
      //  Add a MathML tag of the correct type, and set its attributes
 
392
      //    then populate it with its children and append it to the parent
 
393
      //
 
394
      toNativeMML: function (parent) {
 
395
        var tag = this.NativeMMLelement(this.type);
 
396
        this.NativeMMLattributes(tag);
 
397
        for (var i = 0, m = this.data.length; i < m; i++) {
 
398
          if (this.data[i]) {this.data[i].toNativeMML(tag)}
 
399
            else {tag.appendChild(this.NativeMMLelement("mrow"))}
 
400
        }
 
401
        parent.appendChild(tag);
 
402
      },
 
403
      //
 
404
      //  Look for attributes that are different from the defaults
 
405
      //    and set those in the tag's attribute list
 
406
      //
 
407
      NativeMMLattributes: function (tag) {
 
408
        var defaults = this.defaults;
 
409
        var copy = (this.attrNames||MML.copyAttributeNames), skip = MML.skipAttributes;
 
410
        if (!this.attrNames) {
 
411
          if (this.type === "mstyle") {defaults = MML.math.prototype.defaults}
 
412
          for (var id in defaults) {if (!skip[id] && defaults.hasOwnProperty(id)) {
 
413
            if (this[id] != null) {tag.setAttribute(id,this.NativeMMLattribute(this[id]))}
 
414
          }}
 
415
        }
 
416
        for (var i = 0, m = copy.length; i < m; i++) {
 
417
          var value = (this.attr||{})[copy[i]]; if (value == null) {value = this[copy[i]]}
 
418
          if (value != null) {tag.setAttribute(copy[i],this.NativeMMLattribute(value))}
 
419
        }
 
420
        this.NativeMMLclass(tag);
 
421
      },
 
422
      NativeMMLclass: function (tag) {
 
423
        var CLASS = []; if (this["class"]) {CLASS.push(this["class"])}
 
424
        if (this.isa(MML.TeXAtom)) {
 
425
          var TEXCLASS = ["ORD","OP","BIN","REL","OPEN","CLOSE","PUNCT","INNER","VCENTER"][this.texClass];
 
426
          if (TEXCLASS) {CLASS.push("MJX-TeXAtom-"+TEXCLASS)}
 
427
        }
 
428
        if (this.mathvariant && this.NativeMMLvariants[this.mathvariant])
 
429
          {CLASS.push("MJX"+this.mathvariant)}
 
430
        if (this.arrow) {CLASS.push("MJX-arrow")}
 
431
        if (this.variantForm) {CLASS.push("MJX-variant")}
 
432
        if (CLASS.length) {tag.setAttribute("class",CLASS.join(" "))}
 
433
      },
 
434
      NativeMMLattribute: function (value) {
 
435
        value = String(value);
 
436
        if (nMML.NAMEDSPACE[value]) {value = nMML.NAMEDSPACE[value]} // MP doesn't do negative spaces
 
437
        else if (value.match(/^\s*(([-+])?(\d+(\.\d*)?|\.\d+))\s*mu\s*$/))
 
438
          {value = RegExp.$2+((1/18)*RegExp.$3).toFixed(3).replace(/\.?0+$/,"")+"em"} // FIXME:  should take scriptlevel into account
 
439
        else if (this.NativeMMLvariants[value]) {value = this.NativeMMLvariants[value]}
 
440
        return value;
 
441
      },
 
442
      NativeMMLvariants: {
 
443
        "-tex-caligraphic":      MML.VARIANT.SCRIPT,
 
444
        "-tex-caligraphic-bold": MML.VARIANT.BOLDSCRIPT,
 
445
        "-tex-oldstyle":         MML.VARIANT.NORMAL,
 
446
        "-tex-oldstyle-bold":    MML.VARIANT.BOLD,
 
447
        "-tex-mathit":           MML.VARIANT.ITALIC
 
448
      },
 
449
      //
 
450
      //  Create a MathML element
 
451
      //
 
452
      NativeMMLelement: function (type) {
 
453
        var math = (isMSIE ? document.createElement("m:"+type) :
 
454
                             document.createElementNS(nMML.MMLnamespace,type));
 
455
        math.isMathJax = true;
 
456
        return math;
 
457
      }
 
458
    });
 
459
    
 
460
    MML.mrow.Augment({
 
461
      //
 
462
      //  Make inferred rows not include an mrow tag
 
463
      //
 
464
      toNativeMML: function (parent) {
 
465
        if (this.inferred  && this.parent.inferRow) {
 
466
          for (var i = 0, m = this.data.length; i < m; i++) {
 
467
            if (this.data[i]) {this.data[i].toNativeMML(parent)}
 
468
              else {parent.appendChild(this.NativeMMLelement("mrow"))}
 
469
          }
 
470
        } else {
 
471
          this.SUPER(arguments).toNativeMML.call(this,parent);
 
472
        }
 
473
      }
 
474
    });
 
475
 
 
476
    MML.msubsup.Augment({
 
477
      //
 
478
      //  Use proper version of msub, msup, or msubsup, depending on
 
479
      //  which items are present
 
480
      //
 
481
      toNativeMML: function (parent) {
 
482
        var type = this.type;
 
483
        if (this.data[this.sup] == null) {type = "msub"}
 
484
        if (this.data[this.sub] == null) {type = "msup"}
 
485
        var tag = this.NativeMMLelement(type);
 
486
        this.NativeMMLattributes(tag);
 
487
        delete this.data[0].inferred;
 
488
        for (var i = 0, m = this.data.length; i < m; i++)
 
489
          {if (this.data[i]) {this.data[i].toNativeMML(tag)}}
 
490
        parent.appendChild(tag);
 
491
      }
 
492
    });
 
493
 
 
494
    MML.munderover.Augment({
 
495
      //
 
496
      //  Use proper version of munder, mover, or munderover, depending on
 
497
      //  which items are present
 
498
      //
 
499
      toNativeMML: function (parent) {
 
500
        var type = this.type;
 
501
        if (this.data[this.under] == null) {type = "mover"}
 
502
        if (this.data[this.over] == null)  {type = "munder"}
 
503
        var tag = this.NativeMMLelement(type);
 
504
        this.NativeMMLattributes(tag);
 
505
        delete this.data[0].inferred;
 
506
        for (var i = 0, m = this.data.length; i < m; i++)
 
507
          {if (this.data[i]) {this.data[i].toNativeMML(tag)}}
 
508
        parent.appendChild(tag);
 
509
      }
 
510
    });
 
511
 
 
512
    if (HUB.Browser.isFirefox) {
 
513
      if (!HUB.Browser.versionAtLeast("13.0")) {
 
514
        MML.mtable.Augment({
 
515
          toNativeMML: function (parent) {
 
516
            //
 
517
            //  Firefox < 13 doesn't handle width, so put it in styles instead
 
518
            //
 
519
            if (this.width) {
 
520
              var styles = (this.style||"").replace(/;\s*$/,"").split(";");
 
521
              if (styles[0] === "") {styles.shift()}
 
522
              styles.push("width:"+this.width);
 
523
              this.style = styles.join(";");
 
524
            }
 
525
            this.SUPER(arguments).toNativeMML.call(this,parent);
 
526
          }
 
527
        });
 
528
      }
 
529
      if (!HUB.Browser.versionAtLeast("9.0")) {
 
530
        MML.mlabeledtr.Augment({
 
531
          toNativeMML: function (parent) {
 
532
            //
 
533
            //  FF doesn't handle mlabeledtr, so remove the label
 
534
            //
 
535
            var tag = this.NativeMMLelement("mtr");
 
536
            this.NativeMMLattributes(tag);
 
537
            for (var i = 1, m = this.data.length; i < m; i++) {
 
538
              if (this.data[i]) {this.data[i].toNativeMML(tag)}
 
539
              else {tag.appendChild(this.NativeMMLelement("mrow"))}
 
540
            }
 
541
            parent.appendChild(tag);
 
542
          }
 
543
        });
 
544
      }
 
545
 
 
546
      var fontDir = MathJax.Ajax.fileURL(MathJax.OutputJax.fontDir+"/HTML-CSS/TeX/otf");
 
547
 
 
548
      /*
 
549
       *  Add fix for mathvariant issues in FF
 
550
       */
 
551
      nMML.Augment({
 
552
        config: {
 
553
          styles: {
 
554
            '[mathvariant="double-struck"]':          {"font-family":"MathJax_AMS, MathJax_AMS-WEB"},
 
555
            '[mathvariant="script"]':                 {"font-family":"MathJax_Script, MathJax_Script-WEB"},
 
556
            '[mathvariant="fraktur"]':                {"font-family":"MathJax_Fraktur, MathJax_Fraktur-WEB"},
 
557
            '[mathvariant="bold-script"]':            {"font-family":"MathJax_Script, MathJax_Caligraphic-WEB", "font-weight":"bold"},
 
558
            '[mathvariant="bold-fraktur"]':           {"font-family":"MathJax_Fraktur, MathJax_Fraktur-WEB", "font-weight":"bold"},
 
559
            '[mathvariant="monospace"]':              {"font-family":"monospace"},
 
560
            '[mathvariant="sans-serif"]':             {"font-family":"sans-serif"},
 
561
            '[mathvariant="bold-sans-serif"]':        {"font-family":"sans-serif", "font-weight":"bold"},
 
562
            '[mathvariant="sans-serif-italic"]':      {"font-family":"sans-serif", "font-style":"italic"},
 
563
            '[mathvariant="sans-serif-bold-italic"]': {"font-family":"sans-serif", "font-style":"italic", "font-weight":"bold"},
 
564
            '[class="MJX-tex-oldstyle"]':             {"font-family":"MathJax_Caligraphic, MathJax_Caligraphic-WEB"},
 
565
            '[class="MJX-tex-oldstyle-bold"]':        {"font-family":"MathJax_Caligraphic, MathJax_Caligraphic-WEB", "font-weight":"bold"},
 
566
            '[class="MJX-tex-caligraphic"]':          {"font-family":"MathJax_Caligraphic, MathJax_Caligraphic-WEB"},
 
567
            '[class="MJX-tex-caligraphic-bold"]':     {"font-family":"MathJax_Caligraphic, MathJax_Caligraphic-WEB", "font-weight":"bold"},
 
568
 
 
569
            '@font-face /*1*/': {
 
570
              "font-family": "MathJax_AMS-WEB",
 
571
              "src": "url('"+fontDir+"/MathJax_AMS-Regular.otf')"
 
572
            },
 
573
            '@font-face /*2*/': {
 
574
              "font-family": "MathJax_Script-WEB",
 
575
              "src": "url('"+fontDir+"/MathJax_Script-Regular.otf')"
 
576
            },
 
577
            '@font-face /*3*/': {
 
578
              "font-family": "MathJax_Fraktur-WEB",
 
579
              "src": "url('"+fontDir+"/MathJax_Fraktur-Regular.otf')"
 
580
            },
 
581
            '@font-face /*4*/': {
 
582
              "font-family": "MathJax_Caligraphic-WEB",
 
583
              "src": "url('"+fontDir+"/MathJax_Caligraphic-Regular.otf')"
 
584
            },
 
585
            '@font-face /*5*/': {
 
586
              "font-family": "MathJax_Fraktur-WEB", "font-weight":"bold",
 
587
              "src": "url('"+fontDir+"/MathJax_Fraktur-Bold.otf')"
 
588
            },
 
589
            '@font-face /*6*/': {
 
590
              "font-family": "MathJax_Caligraphic-WEB", "font-weight":"bold",
 
591
              "src": "url('"+fontDir+"/MathJax_Caligraphic-Bold.otf')"
 
592
            }
 
593
          }
 
594
        }
 
595
      });
 
596
    }
 
597
    
 
598
    MML.math.Augment({
 
599
      //
 
600
      //  Some browsers don't seem to add the xmlns attribute, so do it by hand.
 
601
      //
 
602
      toNativeMML: function (parent) {
 
603
        var tag = this.NativeMMLelement(this.type), math = tag;
 
604
        tag.setAttribute("xmlns",nMML.MMLnamespace);
 
605
        this.NativeMMLattributes(tag);
 
606
        if (nMML.widthBug) {tag = tag.appendChild(this.NativeMMLelement("mrow"))}
 
607
        for (var i = 0, m = this.data.length; i < m; i++) {
 
608
          if (this.data[i]) {this.data[i].toNativeMML(tag)}
 
609
            else {tag.appendChild(this.NativeMMLelement("mrow"))}
 
610
        }
 
611
        parent.appendChild(math);
 
612
        //
 
613
        //  Firefox can't seem to get the width of <math> elements right, so
 
614
        //  use an <mrow> to get the actual width and set the style on the 
 
615
        //  parent element to match.  Even if we set the <math> width properly,
 
616
        //  it doesn't seem to propagate up to the <span> correctly.
 
617
        //
 
618
        if (nMML.widthBug) {parent.style.width = math.firstChild.scrollWidth+"px"}
 
619
      }
 
620
    });
 
621
 
 
622
    MML.TeXAtom.Augment({
 
623
      //
 
624
      //  Convert TeXatom to an mrow
 
625
      //
 
626
      toNativeMML: function (parent) {
 
627
        // FIXME:  Handle spacing using mpadded?
 
628
        var tag = this.NativeMMLelement("mrow");
 
629
        this.NativeMMLattributes(tag);
 
630
        this.data[0].toNativeMML(tag);
 
631
        parent.appendChild(tag);
 
632
      }
 
633
    });
 
634
 
 
635
    MML.chars.Augment({
 
636
      //
 
637
      //  Add a text node
 
638
      //
 
639
      toNativeMML: function (parent) {
 
640
        parent.appendChild(document.createTextNode(this.toString()));
 
641
      }
 
642
    });
 
643
 
 
644
    MML.entity.Augment({
 
645
      //
 
646
      //  Add a text node
 
647
      //
 
648
      toNativeMML: function (parent) {
 
649
        parent.appendChild(document.createTextNode(this.toString()));
 
650
      }
 
651
    });
 
652
    
 
653
    MML.xml.Augment({
 
654
      //
 
655
      //  Insert the XML verbatim
 
656
      //
 
657
      toNativeMML: function (parent) {
 
658
        for (var i = 0, m = this.data.length; i < m; i++)
 
659
          {parent.appendChild(this.data[i].cloneNode(true))}
 
660
      }
 
661
    });
 
662
 
 
663
    HUB.Register.StartupHook("TeX mathchoice Ready",function () {
 
664
      MML.TeXmathchoice.Augment({
 
665
        //
 
666
        //  Get the MathML for the selected choice
 
667
        //
 
668
        toNativeMML: function (parent) {this.Core().toNativeMML(parent)}
 
669
      });
 
670
    });
 
671
 
 
672
    //
 
673
    //  Loading isn't complete until the element jax is modified,
 
674
    //  but can't call loadComplete within the callback for "mml Jax Ready"
 
675
    //  (it would call NativeMML's Require routine, asking for the mml jax again)
 
676
    //  so wait until after the mml jax has finished processing.
 
677
    //
 
678
    setTimeout(MathJax.Callback(["loadComplete",nMML,"jax.js"]),0);
 
679
  });
 
680
  
 
681
 
 
682
  //
 
683
  //  Determine browser characteristics
 
684
  //
 
685
  HUB.Browser.Select({
 
686
    MSIE: function (browser) {
 
687
      var mode = (document.documentMode || 0);
 
688
      nMML.msieIE8HeightBug = (mode === 8);
 
689
    },
 
690
    Opera: function (browser) {
 
691
      nMML.operaPositionBug = true;
 
692
    },
 
693
    Firefox: function (browser) {
 
694
      nMML.forceReflow = true;
 
695
      nMML.widthBug = true;
 
696
    }
 
697
  });
 
698
  
 
699
 
 
700
  HUB.Register.StartupHook("End Cookie",function () {
 
701
    if (HUB.config.menuSettings.zoom !== "None")
 
702
      {AJAX.Require("[MathJax]/extensions/MathZoom.js")}
 
703
  });
 
704
 
 
705
})(MathJax.OutputJax.NativeMML, MathJax.Hub, MathJax.Ajax, MathJax.HTML);