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

« back to all changes in this revision

Viewing changes to data/mathjax/unpacked/extensions/MathEvents.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/extensions/MathEvents.js
 
4
 *  
 
5
 *  Implements the event handlers needed by the output jax to perform
 
6
 *  menu, hover, and other events.
 
7
 *
 
8
 *  ---------------------------------------------------------------------
 
9
 *  
 
10
 *  Copyright (c) 2011-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 (HUB,HTML,AJAX,CALLBACK,OUTPUT,INPUT) {
 
26
  var VERSION = "2.1";
 
27
  
 
28
  var EXTENSION = MathJax.Extension;
 
29
  var ME = EXTENSION.MathEvents = {version: VERSION};
 
30
  
 
31
  var SETTINGS = HUB.config.menuSettings;
 
32
  
 
33
  var CONFIG = {
 
34
    hover: 500,              // time required to be considered a hover
 
35
    frame: {
 
36
      x: 3.5, y: 5,          // frame padding and
 
37
      bwidth: 1,             // frame border width (in pixels)
 
38
      bcolor: "#A6D",        // frame border color
 
39
      hwidth: "15px",        // haze width
 
40
      hcolor: "#83A"         // haze color
 
41
    },       
 
42
    button: {
 
43
      x: -4, y: -3,          // menu button offsets
 
44
      wx: -2,                // button offset for full-width equations
 
45
      src: AJAX.fileURL(OUTPUT.imageDir+"/MenuArrow-15.png")  // button image
 
46
    },
 
47
    fadeinInc: .2,           // increment for fade-in
 
48
    fadeoutInc: .05,         // increment for fade-out
 
49
    fadeDelay: 50,           // delay between fade-in or fade-out steps
 
50
    fadeoutStart: 400,       // delay before fade-out after mouseout
 
51
    fadeoutDelay: 15*1000,   // delay before automatic fade-out
 
52
 
 
53
    styles: {
 
54
      ".MathJax_Hover_Frame": {
 
55
        "border-radius": ".25em",                   // Opera 10.5 and IE9
 
56
        "-webkit-border-radius": ".25em",           // Safari and Chrome
 
57
        "-moz-border-radius": ".25em",              // Firefox
 
58
        "-khtml-border-radius": ".25em",            // Konqueror
 
59
 
 
60
        "box-shadow": "0px 0px 15px #83A",          // Opera 10.5 and IE9
 
61
        "-webkit-box-shadow": "0px 0px 15px #83A",  // Safari and Chrome
 
62
        "-moz-box-shadow": "0px 0px 15px #83A",     // Forefox
 
63
        "-khtml-box-shadow": "0px 0px 15px #83A",   // Konqueror
 
64
 
 
65
        border: "1px solid #A6D ! important",
 
66
        display: "inline-block", position:"absolute"
 
67
      },
 
68
 
 
69
      ".MathJax_Hover_Arrow": {
 
70
        position:"absolute",
 
71
        width:"15px", height:"11px",
 
72
        cursor:"pointer"
 
73
      }
 
74
    }
 
75
  };
 
76
 
 
77
  
 
78
  //
 
79
  //  Common event-handling code
 
80
  //
 
81
  var EVENT = ME.Event = {
 
82
    
 
83
    LEFTBUTTON: 0,           // the event.button value for left button
 
84
    RIGHTBUTTON: 2,          // the event.button value for right button
 
85
    MENUKEY: "altKey",       // the event value for alternate context menu
 
86
 
 
87
    Mousedown: function (event) {return EVENT.Handler(event,"Mousedown",this)},
 
88
    Mouseup:   function (event) {return EVENT.Handler(event,"Mouseup",this)},
 
89
    Mousemove: function (event) {return EVENT.Handler(event,"Mousemove",this)},
 
90
    Mouseover: function (event) {return EVENT.Handler(event,"Mouseover",this)},
 
91
    Mouseout:  function (event) {return EVENT.Handler(event,"Mouseout",this)},
 
92
    Click:     function (event) {return EVENT.Handler(event,"Click",this)},
 
93
    DblClick:  function (event) {return EVENT.Handler(event,"DblClick",this)},
 
94
    Menu:      function (event) {return EVENT.Handler(event,"ContextMenu",this)},
 
95
    
 
96
    //
 
97
    //  Call the output jax's event handler or the zoom handler
 
98
    //
 
99
    Handler: function (event,type,math) {
 
100
      if (AJAX.loadingMathMenu) {return EVENT.False(event)}
 
101
      var jax = OUTPUT[math.jaxID];
 
102
      if (!event) {event = window.event}
 
103
      event.isContextMenu = (type === "ContextMenu");
 
104
      if (jax[type]) {return jax[type](event,math)}
 
105
      if (EXTENSION.MathZoom) {return EXTENSION.MathZoom.HandleEvent(event,type,math)}
 
106
    },
 
107
    
 
108
    //
 
109
    //  Try to cancel the event in every way we can
 
110
    //
 
111
    False: function (event) {
 
112
      if (!event) {event = window.event}
 
113
      if (event) {
 
114
        if (event.preventDefault) {event.preventDefault()}
 
115
        if (event.stopPropagation) {event.stopPropagation()}
 
116
        event.cancelBubble = true;
 
117
        event.returnValue = false;
 
118
      }
 
119
      return false;
 
120
    },
 
121
 
 
122
    //
 
123
    //  Load the contextual menu code, if needed, and post the menu
 
124
    //
 
125
    ContextMenu: function (event,math,force) {
 
126
      //
 
127
      //  Check if we are showing menus
 
128
      //
 
129
      var JAX = OUTPUT[math.jaxID], jax = JAX.getJaxFromMath(math);
 
130
      var show = (JAX.config.showMathMenu != null ? JAX : HUB).config.showMathMenu;
 
131
      if (!show || (SETTINGS.context !== "MathJax" && !force)) return;
 
132
 
 
133
      //
 
134
      //  Remove selections, remove hover fades
 
135
      //
 
136
      if (ME.msieEventBug) {event = window.event || event}
 
137
      EVENT.ClearSelection(); HOVER.ClearHoverTimer();
 
138
      if (jax.hover) {
 
139
        if (jax.hover.remove) {clearTimeout(jax.hover.remove); delete jax.hover.remove}
 
140
        jax.hover.nofade = true;
 
141
      }
 
142
 
 
143
      //
 
144
      //  If the menu code is loaded, post the menu
 
145
      //  Otherwse lad the menu code and try again
 
146
      //
 
147
      var MENU = MathJax.Menu;
 
148
      if (MENU) {
 
149
        MENU.jax = jax;
 
150
        var source = MENU.menu.Find("Show Math As").menu;
 
151
        source.items[1].name = (INPUT[jax.inputJax].sourceMenuTitle||"Original Form");
 
152
        source.items[0].hidden = (jax.inputJax === "Error");  // hide MathML choice for error messages
 
153
        var MathPlayer = MENU.menu.Find("Math Settings","MathPlayer");
 
154
        MathPlayer.hidden = !(jax.outputJax === "NativeMML" && HUB.Browser.hasMathPlayer);
 
155
        return MENU.menu.Post(event);
 
156
      } else {
 
157
        if (!AJAX.loadingMathMenu) {
 
158
          AJAX.loadingMathMenu = true;
 
159
          var ev = {
 
160
            pageX:event.pageX, pageY:event.pageY,
 
161
            clientX:event.clientX, clientY:event.clientY
 
162
          };
 
163
          CALLBACK.Queue(
 
164
            AJAX.Require("[MathJax]/extensions/MathMenu.js"),
 
165
            function () {delete AJAX.loadingMathMenu; if (!MathJax.Menu) {MathJax.Menu = {}}},
 
166
            ["ContextMenu",this,ev,math,force]  // call this function again
 
167
          );
 
168
        }
 
169
        return EVENT.False(event);
 
170
      }
 
171
    },
 
172
    
 
173
    //
 
174
    //  Mousedown handler for alternate means of accessing menu
 
175
    //
 
176
    AltContextMenu: function (event,math) {
 
177
      var JAX = OUTPUT[math.jaxID];
 
178
      var show = (JAX.config.showMathMenu != null ? JAX : HUB).config.showMathMenu;
 
179
      if (show) {
 
180
        show = (JAX.config.showMathMenuMSIE != null ? JAX : HUB).config.showMathMenuMSIE;
 
181
        if (SETTINGS.context === "MathJax" && !SETTINGS.mpContext && show) {
 
182
          if (!ME.noContextMenuBug || event.button !== EVENT.RIGHTBUTTON) return;
 
183
        } else {
 
184
          if (!event[EVENT.MENUKEY] || event.button !== EVENT.LEFTBUTTON) return;
 
185
        }
 
186
        return JAX.ContextMenu(event,math,true);
 
187
      }
 
188
    },
 
189
    
 
190
    ClearSelection: function () {
 
191
      if (ME.safariContextMenuBug) {setTimeout("window.getSelection().empty()",0)}
 
192
      if (document.selection) {setTimeout("document.selection.empty()",0)}
 
193
    },
 
194
    
 
195
    getBBox: function (span) {
 
196
      span.appendChild(ME.topImg);
 
197
      var h = ME.topImg.offsetTop, d = span.offsetHeight-h, w = span.offsetWidth;
 
198
      span.removeChild(ME.topImg);
 
199
      return {w:w, h:h, d:d};
 
200
    }
 
201
    
 
202
  };
 
203
  
 
204
  //
 
205
  //  Handle hover "discoverability"
 
206
  //
 
207
  var HOVER = ME.Hover = {
 
208
    
 
209
    //
 
210
    //  Check if we are moving from a non-MathJax element to a MathJax one
 
211
    //  and either start fading in again (if it is fading out) or start the
 
212
    //  timer for the hover
 
213
    //
 
214
    Mouseover: function (event,math) {
 
215
      if (SETTINGS.discoverable || SETTINGS.zoom === "Hover") {
 
216
        var from = event.fromElement || event.relatedTarget,
 
217
            to   = event.toElement   || event.target;
 
218
        if (from && to && (from.isMathJax != to.isMathJax ||
 
219
                           HUB.getJaxFor(from) !== HUB.getJaxFor(to))) {
 
220
          var jax = this.getJaxFromMath(math);
 
221
          if (jax.hover) {HOVER.ReHover(jax)} else {HOVER.HoverTimer(jax,math)}
 
222
          return EVENT.False(event);
 
223
        }
 
224
      }
 
225
    },
 
226
    //
 
227
    //  Check if we are moving from a MathJax element to a non-MathJax one
 
228
    //  and either start fading out, or clear the timer if we haven't
 
229
    //  hovered yet
 
230
    //
 
231
    Mouseout: function (event,math) {
 
232
      if (SETTINGS.discoverable || SETTINGS.zoom === "Hover") {
 
233
        var from = event.fromElement || event.relatedTarget,
 
234
            to   = event.toElement   || event.target;
 
235
        if (from && to && (from.isMathJax != to.isMathJax ||
 
236
                           HUB.getJaxFor(from) !== HUB.getJaxFor(to))) {
 
237
          var jax = this.getJaxFromMath(math);
 
238
          if (jax.hover) {HOVER.UnHover(jax)} else {HOVER.ClearHoverTimer()}
 
239
          return EVENT.False(event);
 
240
        }
 
241
      }
 
242
    },
 
243
    //
 
244
    //  Restart hover timer if the mouse moves
 
245
    //
 
246
    Mousemove: function (event,math) {
 
247
      if (SETTINGS.discoverable || SETTINGS.zoom === "Hover") {
 
248
        var jax = this.getJaxFromMath(math); if (jax.hover) return;
 
249
        if (HOVER.lastX == event.clientX && HOVER.lastY == event.clientY) return;
 
250
        HOVER.lastX = event.clientX; HOVER.lastY = event.clientY;
 
251
        HOVER.HoverTimer(jax,math);
 
252
        return EVENT.False(event);
 
253
      }
 
254
    },
 
255
    
 
256
    //
 
257
    //  Clear the old timer and start a new one
 
258
    //
 
259
    HoverTimer: function (jax,math) {
 
260
      this.ClearHoverTimer();
 
261
      this.hoverTimer = setTimeout(CALLBACK(["Hover",this,jax,math]),CONFIG.hover);
 
262
    },
 
263
    ClearHoverTimer: function () {
 
264
      if (this.hoverTimer) {clearTimeout(this.hoverTimer); delete this.hoverTimer}
 
265
    },
 
266
    
 
267
    //
 
268
    //  Handle putting up the hover frame
 
269
    //
 
270
    Hover: function (jax,math) {
 
271
      //
 
272
      //  Check if Zoom handles the hover event
 
273
      //
 
274
      if (EXTENSION.MathZoom && EXTENSION.MathZoom.Hover({},math)) return;
 
275
      //
 
276
      //  Get the hover data
 
277
      //
 
278
      var JAX = OUTPUT[jax.outputJax],
 
279
          span = JAX.getHoverSpan(jax,math),
 
280
          bbox = JAX.getHoverBBox(jax,span,math),
 
281
          show = (JAX.config.showMathMenu != null ? JAX : HUB).config.showMathMenu;
 
282
      var dx = CONFIG.frame.x, dy = CONFIG.frame.y, dd = CONFIG.frame.bwidth;  // frame size
 
283
      if (ME.msieBorderWidthBug) {dd = 0}
 
284
      jax.hover = {opacity:0, id:jax.inputID+"-Hover"};
 
285
      //
 
286
      //  The frame and menu button
 
287
      //
 
288
      var frame = HTML.Element("span",{
 
289
         id:jax.hover.id, isMathJax: true,
 
290
         style:{display:"inline-block", width:0, height:0, position:"relative"}
 
291
        },[["span",{
 
292
          className:"MathJax_Hover_Frame", isMathJax: true,
 
293
          style:{
 
294
            display:"inline-block", position:"absolute",
 
295
            top:this.Px(-bbox.h-dy-dd-(bbox.y||0)), left:this.Px(-dx-dd+(bbox.x||0)),
 
296
            width:this.Px(bbox.w+2*dx), height:this.Px(bbox.h+bbox.d+2*dy),
 
297
            opacity:0, filter:"alpha(opacity=0)"
 
298
          }}
 
299
        ]]
 
300
      );
 
301
      var button = HTML.Element("span",{
 
302
         isMathJax: true, id:jax.hover.id+"Menu",
 
303
         style:{display:"inline-block", "z-index": 1, width:0, height:0, position:"relative"}
 
304
        },[["img",{
 
305
            className: "MathJax_Hover_Arrow", isMathJax: true, math: math,
 
306
            src: CONFIG.button.src, onclick: this.HoverMenu, jax:JAX.id,
 
307
            style: {
 
308
              left:this.Px(bbox.w+dx+dd+(bbox.x||0)+CONFIG.button.x),
 
309
              top:this.Px(-bbox.h-dy-dd-(bbox.y||0)-CONFIG.button.y),
 
310
              opacity:0, filter:"alpha(opacity=0)"
 
311
            }
 
312
          }]]
 
313
      );
 
314
      if (bbox.width) {
 
315
        frame.style.width = button.style.width = bbox.width;
 
316
        frame.style.marginRight = button.style.marginRight = "-"+bbox.width;
 
317
        frame.firstChild.style.width = bbox.width;
 
318
        button.firstChild.style.left = "";
 
319
        button.firstChild.style.right = this.Px(CONFIG.button.wx);
 
320
      }
 
321
      //
 
322
      //  Add the frame and button
 
323
      //
 
324
      span.parentNode.insertBefore(frame,span);
 
325
      if (show) {span.parentNode.insertBefore(button,span)}
 
326
      if (span.style) {span.style.position = "relative"} // so math is on top of hover frame
 
327
      //
 
328
      //  Start the hover fade-in
 
329
      //
 
330
      this.ReHover(jax);
 
331
    },
 
332
    //
 
333
    //  Restart the hover fade in and fade-out timers
 
334
    //
 
335
    ReHover: function (jax) {
 
336
      if (jax.hover.remove) {clearTimeout(jax.hover.remove)}
 
337
      jax.hover.remove = setTimeout(CALLBACK(["UnHover",this,jax]),CONFIG.fadeoutDelay);
 
338
      this.HoverFadeTimer(jax,CONFIG.fadeinInc);
 
339
    },
 
340
    //
 
341
    //  Start the fade-out
 
342
    //
 
343
    UnHover: function (jax) {
 
344
      if (!jax.hover.nofade) {this.HoverFadeTimer(jax,-CONFIG.fadeoutInc,CONFIG.fadeoutStart)}
 
345
    },
 
346
    //
 
347
    //  Handle the fade-in and fade-out
 
348
    //
 
349
    HoverFade: function (jax) {
 
350
      delete jax.hover.timer;
 
351
      jax.hover.opacity = Math.max(0,Math.min(1,jax.hover.opacity + jax.hover.inc));
 
352
      jax.hover.opacity = Math.floor(1000*jax.hover.opacity)/1000;
 
353
      var frame = document.getElementById(jax.hover.id),
 
354
          button = document.getElementById(jax.hover.id+"Menu");
 
355
      frame.firstChild.style.opacity = jax.hover.opacity;
 
356
      frame.firstChild.style.filter = "alpha(opacity="+Math.floor(100*jax.hover.opacity)+")";
 
357
      if (button) {
 
358
        button.firstChild.style.opacity = jax.hover.opacity;
 
359
        button.firstChild.style.filter = frame.style.filter;
 
360
      }
 
361
      if (jax.hover.opacity === 1) {return}
 
362
      if (jax.hover.opacity > 0) {this.HoverFadeTimer(jax,jax.hover.inc); return}
 
363
      frame.parentNode.removeChild(frame);
 
364
      if (button) {button.parentNode.removeChild(button)}
 
365
      if (jax.hover.remove) {clearTimeout(jax.hover.remove)}
 
366
      delete jax.hover;
 
367
    },
 
368
    //
 
369
    //  Set the fade to in or out (via inc) and start the timer, if needed
 
370
    //
 
371
    HoverFadeTimer: function (jax,inc,delay) {
 
372
      jax.hover.inc = inc;
 
373
      if (!jax.hover.timer) {
 
374
        jax.hover.timer = setTimeout(CALLBACK(["HoverFade",this,jax]),(delay||CONFIG.fadeDelay));
 
375
      }
 
376
    },
 
377
    
 
378
    //
 
379
    //  Handle a click on the menu button
 
380
    //
 
381
    HoverMenu: function (event) {
 
382
      if (!event) {event = window.event}
 
383
      return OUTPUT[this.jax].ContextMenu(event,this.math,true);
 
384
    },
 
385
    
 
386
    //
 
387
    //  Clear all hover timers
 
388
    //
 
389
    ClearHover: function (jax) {
 
390
      if (jax.hover.remove) {clearTimeout(jax.hover.remove)}
 
391
      if (jax.hover.timer)  {clearTimeout(jax.hover.timer)}
 
392
      HOVER.ClearHoverTimer();
 
393
      delete jax.hover;
 
394
    },
 
395
    
 
396
    //
 
397
    //  Make a measurement in pixels
 
398
    //
 
399
    Px: function (m) {
 
400
      if (Math.abs(m) < .006) {return "0px"}
 
401
      return m.toFixed(2).replace(/\.?0+$/,"") + "px";
 
402
    },
 
403
 
 
404
    //
 
405
    //  Preload images so they show up with the menu
 
406
    //
 
407
    getImages: function () {
 
408
      var menu = new Image();
 
409
      menu.src = CONFIG.button.src;
 
410
    }
 
411
 
 
412
  };
 
413
  
 
414
  //
 
415
  //  Handle touch events.  
 
416
  //
 
417
  //  Use double-tap-and-hold as a replacement for context menu event.
 
418
  //  Use double-tap as a replacement for double click.
 
419
  //
 
420
  var TOUCH = ME.Touch = {
 
421
 
 
422
    last: 0,          // time of last tap event
 
423
    delay: 500,       // delay time for double-click
 
424
    
 
425
    //
 
426
    //  Check if this is a double-tap, and if so, start the timer
 
427
    //  for the double-tap and hold (to trigger the contextual menu)
 
428
    //
 
429
    start: function (event) {
 
430
      var now = new Date().getTime();
 
431
      var dblTap = (now - TOUCH.last < TOUCH.delay && TOUCH.up);
 
432
      TOUCH.last = now; TOUCH.up = false;
 
433
      if (dblTap) {
 
434
        TOUCH.timeout = setTimeout(TOUCH.menu,TOUCH.delay,event,this);
 
435
        event.preventDefault();
 
436
      }
 
437
    },
 
438
          
 
439
    //
 
440
    //  Check if there is a timeout pending, i.e., we have a 
 
441
    //  double-tap and were waiting to see if it is held long
 
442
    //  enough for the menu.  Since we got the end before the
 
443
    //  timeout, it is a double-click, not a double-tap-and-hold.
 
444
    //  Prevent the default action and issue a double click.
 
445
    //
 
446
    end: function (event) {
 
447
      var now = new Date().getTime();
 
448
      TOUCH.up = (now - TOUCH.last < TOUCH.delay);
 
449
      if (TOUCH.timeout) {
 
450
        clearTimeout(TOUCH.timeout);
 
451
        delete TOUCH.timeout; TOUCH.last = 0; TOUCH.up = false;
 
452
        event.preventDefault();
 
453
        return EVENT.Handler((event.touches[0]||event.touch),"DblClick",this);
 
454
      }
 
455
    },
 
456
        
 
457
    //
 
458
    //  If the timeout passes without an end event, we issue
 
459
    //  the contextual menu event.
 
460
    //
 
461
    menu: function (event,math) {
 
462
      delete TOUCH.timeout; TOUCH.last = 0; TOUCH.up = false;
 
463
      return EVENT.Handler((event.touches[0]||event.touch),"ContextMenu",math);
 
464
    }
 
465
    
 
466
  };
 
467
  
 
468
  //
 
469
  //  Mobile screens are small, so use larger version of arrow
 
470
  //
 
471
  if (HUB.Browser.isMobile) {
 
472
    var arrow = CONFIG.styles[".MathJax_Hover_Arrow"];
 
473
    arrow.width = "25px"; arrow.height = "18px";
 
474
    CONFIG.button.x = -6;
 
475
  }
 
476
  
 
477
  //
 
478
  //  Set up browser-specific values
 
479
  //
 
480
  HUB.Browser.Select({
 
481
    MSIE: function (browser) {
 
482
      var mode = (document.documentMode || 0);
 
483
      var isIE8 = browser.versionAtLeast("8.0");
 
484
      ME.msieBorderWidthBug = (document.compatMode === "BackCompat");  // borders are inside offsetWidth/Height
 
485
      ME.msieEventBug = browser.isIE9;           // must get event from window even though event is passed
 
486
      ME.msieAlignBug = (!isIE8 || mode < 8);    // inline-block spans don't rest on baseline
 
487
      if (mode < 9) {EVENT.LEFTBUTTON = 1}       // IE < 9 has wrong event.button values
 
488
    },
 
489
    Safari: function (browser) {
 
490
      ME.safariContextMenuBug = true;  // selection can be started by contextmenu event
 
491
    },
 
492
    Opera: function (browser) {
 
493
      ME.operaPositionBug = true;      // position is wrong unless border is used
 
494
    },
 
495
    Konqueror: function (browser) {
 
496
      ME.noContextMenuBug = true;      // doesn't produce contextmenu event
 
497
    }
 
498
  });
 
499
  
 
500
  //
 
501
  //  Used in measuring zoom and hover positions
 
502
  //
 
503
  ME.topImg = (ME.msieAlignBug ?
 
504
    HTML.Element("img",{style:{width:0,height:0,position:"relative"},src:"about:blank"}) :
 
505
    HTML.Element("span",{style:{width:0,height:0,display:"inline-block"}})
 
506
  );
 
507
  if (ME.operaPositionBug) {ME.topImg.style.border="1px solid"}
 
508
 
 
509
  //
 
510
  //  Get configuration from user
 
511
  //
 
512
  ME.config = CONFIG = HUB.CombineConfig("MathEvents",CONFIG);
 
513
  var SETFRAME = function () {
 
514
    var haze = CONFIG.styles[".MathJax_Hover_Frame"];
 
515
    haze.border = CONFIG.frame.bwidth+"px solid "+CONFIG.frame.bcolor+" ! important";
 
516
    haze["box-shadow"] = haze["-webkit-box-shadow"] =
 
517
      haze["-moz-box-shadow"] = haze["-khtml-box-shadow"] =
 
518
        "0px 0px "+CONFIG.frame.hwidth+" "+CONFIG.frame.hcolor;
 
519
  };
 
520
  
 
521
  //
 
522
  //  Queue the events needed for startup
 
523
  //
 
524
  CALLBACK.Queue(
 
525
    HUB.Register.StartupHook("End Config",{}), // wait until config is complete
 
526
    [SETFRAME],
 
527
    ["getImages",HOVER],
 
528
    ["Styles",AJAX,CONFIG.styles],
 
529
    ["Post",HUB.Startup.signal,"MathEvents Ready"],
 
530
    ["loadComplete",AJAX,"[MathJax]/extensions/MathEvents.js"]
 
531
  );
 
532
  
 
533
})(MathJax.Hub,MathJax.HTML,MathJax.Ajax,MathJax.Callback,MathJax.OutputJax,MathJax.InputJax);