maction.js (8793B)
1 /* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 4 /************************************************************* 5 * 6 * MathJax/jax/output/HTML-CSS/autoload/maction.js 7 * 8 * Implements the HTML-CSS output for <maction> elements. 9 * 10 * --------------------------------------------------------------------- 11 * 12 * Copyright (c) 2010-2015 The MathJax Consortium 13 * 14 * Licensed under the Apache License, Version 2.0 (the "License"); 15 * you may not use this file except in compliance with the License. 16 * You may obtain a copy of the License at 17 * 18 * http://www.apache.org/licenses/LICENSE-2.0 19 * 20 * Unless required by applicable law or agreed to in writing, software 21 * distributed under the License is distributed on an "AS IS" BASIS, 22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 23 * See the License for the specific language governing permissions and 24 * limitations under the License. 25 */ 26 27 MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () { 28 var VERSION = "2.6.0"; 29 var MML = MathJax.ElementJax.mml, 30 HTMLCSS = MathJax.OutputJax["HTML-CSS"]; 31 32 var currentTip, hover, clear; 33 34 // 35 // Add configuration for tooltips 36 // 37 var CONFIG = HTMLCSS.config.tooltip = MathJax.Hub.Insert({ 38 delayPost: 600, delayClear: 600, 39 offsetX: 10, offsetY: 5 40 },HTMLCSS.config.tooltip||{}); 41 42 43 MML.maction.Augment({ 44 HTMLtooltip: HTMLCSS.addElement(document.body,"div",{id:"MathJax_Tooltip"}), 45 46 toHTML: function (span,HW,D) { 47 var selected = this.selected(); 48 if (selected.type == "null") { 49 span = this.HTMLcreateSpan(span); 50 span.bbox = this.HTMLzeroBBox(); 51 return span; 52 } 53 span = this.HTMLcreateSpan(span); span.bbox = null; 54 span.scale = this.HTMLgetScale(); 55 var box = selected.toHTML(span); 56 if (D != null) {HTMLCSS.Remeasured(selected.HTMLstretchV(span,HW,D),span)} 57 else if (HW != null) { 58 HTMLCSS.Remeasured(selected.HTMLstretchH(span,HW),span) 59 } else {HTMLCSS.Measured(box,span)} 60 this.HTMLhandleHitBox(span); 61 this.HTMLhandleSpace(span); 62 this.HTMLhandleColor(span); 63 return span; 64 }, 65 HTMLhandleHitBox: function (span,postfix) { 66 var frame; 67 if (HTMLCSS.msieHitBoxBug) { 68 // margin-left doesn't work on inline-block elements in IE, so put it in a SPAN 69 var box = HTMLCSS.addElement(span,"span",{isMathJax:true}); 70 frame = HTMLCSS.createFrame(box,span.bbox.h,span.bbox.d,span.bbox.w,0,"none"); 71 span.insertBefore(box,span.firstChild); // move below the content 72 box.style.marginRight = HTMLCSS.Em(-span.bbox.w); 73 if (HTMLCSS.msieInlineBlockAlignBug) 74 {frame.style.verticalAlign = HTMLCSS.Em(HTMLCSS.getHD(span).d-span.bbox.d)} 75 } else { 76 frame = HTMLCSS.createFrame(span,span.bbox.h,span.bbox.d,span.bbox.w,0,"none"); 77 span.insertBefore(frame,span.firstChild); // move below the content 78 frame.style.marginRight = HTMLCSS.Em(-span.bbox.w); 79 } 80 frame.className = "MathJax_HitBox"; 81 frame.id = "MathJax-HitBox-" + this.spanID + (postfix||"") + HTMLCSS.idPostfix; 82 83 var type = this.Get("actiontype"); 84 if (this.HTMLaction[type]) {this.HTMLaction[type].call(this,span,frame,this.Get("selection"))} 85 }, 86 HTMLstretchH: MML.mbase.HTMLstretchH, 87 HTMLstretchV: MML.mbase.HTMLstretchV, 88 89 // 90 // Implementations for the various actions 91 // 92 HTMLaction: { 93 toggle: function (span,frame,selection) { 94 this.selection = selection; 95 span.onclick = MathJax.Callback(["HTMLclick",this]); 96 frame.style.cursor = span.childNodes[1].style.cursor = "pointer"; 97 }, 98 99 statusline: function (span,frame,selection) { 100 span.onmouseover = MathJax.Callback(["HTMLsetStatus",this]); 101 span.onmouseout = MathJax.Callback(["HTMLclearStatus",this]); 102 span.onmouseover.autoReset = span.onmouseout.autoReset = true; 103 frame.style.cursor = span.childNodes[1].style.cursor = "default"; 104 }, 105 106 tooltip: function(span,frame,selection) { 107 if (this.data[1] && this.data[1].isToken) { 108 span.title = span.alt = this.data[1].data.join(""); 109 } else { 110 span.onmouseover = MathJax.Callback(["HTMLtooltipOver",this]); 111 span.onmouseout = MathJax.Callback(["HTMLtooltipOut",this]); 112 span.onmouseover.autoReset = span.onmouseout.autoReset = true; 113 } 114 frame.style.cursor = span.childNodes[1].style.cursor = "default"; 115 } 116 }, 117 118 // 119 // Handle a click on the maction element 120 // (remove the original rendering and rerender) 121 // 122 HTMLclick: function (event) { 123 this.selection++; 124 if (this.selection > this.data.length) {this.selection = 1} 125 var math = this; while (math.type !== "math") {math = math.inherit} 126 var jax = MathJax.Hub.getJaxFor(math.inputID), hover = !!jax.hover; 127 jax.Update(); 128 if (hover) { 129 var span = document.getElementById(jax.inputID+"-Span"); 130 MathJax.Extension.MathEvents.Hover.Hover(jax,span); 131 } 132 return MathJax.Extension.MathEvents.Event.False(event); 133 }, 134 135 // 136 // Set/Clear the window status message 137 // 138 HTMLsetStatus: function (event) { 139 // FIXME: Do something better with non-token elements 140 this.messageID = MathJax.Message.Set 141 ((this.data[1] && this.data[1].isToken) ? 142 this.data[1].data.join("") : this.data[1].toString()); 143 }, 144 HTMLclearStatus: function (event) { 145 if (this.messageID) {MathJax.Message.Clear(this.messageID,0)} 146 delete this.messageID; 147 }, 148 149 // 150 // Handle tooltips 151 // 152 HTMLtooltipOver: function (event) { 153 if (!event) {event = window.event} 154 if (clear) {clearTimeout(clear); clear = null} 155 if (hover) {clearTimeout(hover)} 156 var x = event.pageX; var y = event.pageY; 157 if (x == null) { 158 x = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; 159 y = event.clientY + document.body.scrollTop + document.documentElement.scrollTop; 160 } 161 var callback = MathJax.Callback(["HTMLtooltipPost",this,x+CONFIG.offsetX,y+CONFIG.offsetY]) 162 hover = setTimeout(callback,CONFIG.delayPost); 163 }, 164 HTMLtooltipOut: function (event) { 165 if (hover) {clearTimeout(hover); hover = null} 166 if (clear) {clearTimeout(clear)} 167 var callback = MathJax.Callback(["HTMLtooltipClear",this,80]); 168 clear = setTimeout(callback,CONFIG.delayClear); 169 }, 170 HTMLtooltipPost: function (x,y) { 171 hover = null; if (clear) {clearTimeout(clear); clear = null} 172 var tip = this.HTMLtooltip; 173 tip.style.display = "block"; tip.style.opacity = ""; 174 tip.style.filter = HTMLCSS.config.styles["#MathJax_Tooltip"].filter; 175 if (this === currentTip) return; 176 tip.style.left = x+"px"; tip.style.top = y+"px"; 177 tip.innerHTML = '<span class="MathJax"><nobr></nobr></span>'; 178 // 179 // get em sizes (taken from HTMLCSS.preTranslate) 180 // 181 var emex = tip.insertBefore(HTMLCSS.EmExSpan.cloneNode(true),tip.firstChild); 182 var ex = emex.firstChild.offsetHeight/60, 183 em = emex.lastChild.firstChild.offsetHeight/60; 184 HTMLCSS.em = HTMLCSS.outerEm = MML.mbase.prototype.em = em; 185 var scale = Math.floor(Math.max(HTMLCSS.config.minScaleAdjust/100,(ex/HTMLCSS.TeX.x_height)/em) * HTMLCSS.config.scale); 186 tip.firstChild.style.fontSize = scale+"%"; 187 emex.parentNode.removeChild(emex); 188 189 var stack = HTMLCSS.createStack(tip.firstChild.firstChild); 190 var box = HTMLCSS.createBox(stack); 191 try {HTMLCSS.Measured(this.data[1].toHTML(box),box)} catch(err) { 192 if (!err.restart) {throw err} 193 tip.style.display = "none"; 194 MathJax.Callback.After(["HTMLtooltipPost",this,x,y],err.restart); 195 return; 196 } 197 HTMLCSS.placeBox(box,0,0); 198 HTMLCSS.createRule(tip.firstChild.firstChild,box.bbox.h,box.bbox.d,0); 199 currentTip = this; 200 }, 201 HTMLtooltipClear: function (n) { 202 var tip = this.HTMLtooltip; 203 if (n <= 0) { 204 tip.style.display = "none"; 205 tip.style.opacity = tip.style.filter = ""; 206 clear = null; 207 } else { 208 tip.style.opacity = n/100; 209 tip.style.filter = "alpha(opacity="+n+")"; 210 clear = setTimeout(MathJax.Callback(["HTMLtooltipClear",this,n-20]),50); 211 } 212 } 213 }); 214 215 // 216 // Do browser-specific setup 217 // 218 MathJax.Hub.Browser.Select({ 219 MSIE: function (browser) { 220 HTMLCSS.msieHitBoxBug = true; 221 } 222 }); 223 224 225 MathJax.Hub.Startup.signal.Post("HTML-CSS maction Ready"); 226 MathJax.Ajax.loadComplete(HTMLCSS.autoloadDir+"/maction.js"); 227 228 }); 229