maction.js (7182B)
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/SVG/autoload/maction.js 7 * 8 * Implements the SVG output for <maction> elements. 9 * 10 * --------------------------------------------------------------------- 11 * 12 * Copyright (c) 2011-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("SVG Jax Ready",function () { 28 var VERSION = "2.6.0"; 29 var MML = MathJax.ElementJax.mml, 30 SVG = MathJax.OutputJax["SVG"]; 31 32 var currentTip, hover, clear; 33 34 // 35 // Add configuration for tooltips 36 // 37 var CONFIG = SVG.config.tooltip = MathJax.Hub.Insert({ 38 delayPost: 600, delayClear: 600, 39 offsetX: 10, offsetY: 5 40 },SVG.config.tooltip||{}); 41 42 43 MML.maction.Augment({ 44 SVGtooltip: MathJax.HTML.addElement(document.body,"div",{id:"MathJax_SVG_Tooltip"}), 45 46 toSVG: function (HW,D) { 47 this.SVGgetStyles(); 48 var svg = this.SVG(); 49 var selected = this.selected(); 50 if (selected.type == "null") {this.SVGsaveData(svg);return svg;} 51 svg.Add(this.SVGdataStretched(this.Get("selection")-1,HW,D)); 52 svg.removeable = false; 53 this.SVGhandleHitBox(svg); 54 this.SVGhandleSpace(svg); 55 this.SVGhandleColor(svg); 56 this.SVGsaveData(svg); 57 return svg; 58 }, 59 SVGhandleHitBox: function (svg) { 60 var frame = SVG.Element("rect", 61 {width:svg.w, height:svg.h+svg.d, y:-svg.d, fill:"none", "pointer-events":"all"}); 62 svg.element.insertBefore(frame,svg.element.firstChild); 63 var type = this.Get("actiontype"); 64 if (this.SVGaction[type]) 65 {this.SVGaction[type].call(this,svg,svg.element,this.Get("selection"))} 66 }, 67 SVGstretchH: MML.mbase.prototype.SVGstretchH, 68 SVGstretchV: MML.mbase.prototype.SVGstretchV, 69 70 // 71 // Implementations for the various actions 72 // 73 SVGaction: { 74 toggle: function (svg,frame,selection) { 75 this.selection = selection; 76 SVG.Element(frame,{cursor:"pointer"}); 77 frame.onclick = MathJax.Callback(["SVGclick",this]); 78 }, 79 80 statusline: function (svg,frame,selection) { 81 frame.onmouseover = MathJax.Callback(["SVGsetStatus",this]), 82 frame.onmouseout = MathJax.Callback(["SVGclearStatus",this]); 83 frame.onmouseover.autoReset = frame.onmouseout.autoReset = true; 84 }, 85 86 tooltip: function(svg,frame,selection) { 87 frame.onmouseover = MathJax.Callback(["SVGtooltipOver",this]), 88 frame.onmouseout = MathJax.Callback(["SVGtooltipOut",this]); 89 frame.onmouseover.autoReset = frame.onmouseout.autoReset = true; 90 } 91 }, 92 93 // 94 // Handle a click on the maction element 95 // (remove the original rendering and rerender) 96 // 97 SVGclick: function (event) { 98 this.selection++; 99 if (this.selection > this.data.length) {this.selection = 1} 100 var math = this; while (math.type !== "math") {math = math.inherit} 101 var jax = MathJax.Hub.getJaxFor(math.inputID); //, hover = !!jax.hover; 102 jax.Update(); 103 /* 104 * if (hover) { 105 * var span = document.getElementById(jax.inputID+"-Span"); 106 * MathJax.Extension.MathEvents.Hover.Hover(jax,span); 107 * } 108 */ 109 return MathJax.Extension.MathEvents.Event.False(event); 110 }, 111 112 // 113 // Set/Clear the window status message 114 // 115 SVGsetStatus: function (event) { 116 // FIXME: Do something better with non-token elements 117 this.messageID = MathJax.Message.Set 118 ((this.data[1] && this.data[1].isToken) ? 119 this.data[1].data.join("") : this.data[1].toString()); 120 }, 121 SVGclearStatus: function (event) { 122 if (this.messageID) {MathJax.Message.Clear(this.messageID,0)} 123 delete this.messageID; 124 }, 125 126 // 127 // Handle tooltips 128 // 129 SVGtooltipOver: function (event) { 130 if (!event) {event = window.event} 131 if (clear) {clearTimeout(clear); clear = null} 132 if (hover) {clearTimeout(hover)} 133 var x = event.pageX; var y = event.pageY; 134 if (x == null) { 135 x = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; 136 y = event.clientY + document.body.scrollTop + document.documentElement.scrollTop; 137 } 138 var callback = MathJax.Callback(["SVGtooltipPost",this,x+CONFIG.offsetX,y+CONFIG.offsetY]) 139 hover = setTimeout(callback,CONFIG.delayPost); 140 }, 141 SVGtooltipOut: function (event) { 142 if (hover) {clearTimeout(hover); hover = null} 143 if (clear) {clearTimeout(clear)} 144 var callback = MathJax.Callback(["SVGtooltipClear",this,80]); 145 clear = setTimeout(callback,CONFIG.delayClear); 146 }, 147 SVGtooltipPost: function (x,y) { 148 hover = null; if (clear) {clearTimeout(clear); clear = null} 149 150 // 151 // Get the tip div and show it at the right location, then clear its contents 152 // 153 var tip = this.SVGtooltip; 154 tip.style.display = "block"; tip.style.opacity = ""; 155 if (this === currentTip) return; 156 tip.style.left = x+"px"; tip.style.top = y+"px"; 157 tip.innerHTML = ''; var span = MathJax.HTML.addElement(tip,"span"); 158 159 // 160 // Get the sizes from the jax (FIXME: should calculate again?) 161 // 162 var math = this; while (math.type !== "math") {math = math.inherit} 163 var jax = MathJax.Hub.getJaxFor(math.inputID); 164 this.em = MML.mbase.prototype.em = jax.SVG.em; this.ex = jax.SVG.ex; 165 this.linebreakWidth = jax.SVG.lineWidth; this.cwidth = jax.SVG.cwidth; 166 167 // 168 // Make a new math element and temporarily move the tooltip to it 169 // Display the math containing the tip, but check for errors 170 // Then put the tip back into the maction element 171 // 172 var mml = this.data[1]; 173 math = MML.math(mml); 174 try {math.toSVG(span,tip)} catch(err) { 175 this.SetData(1,mml); tip.style.display = "none"; 176 if (!err.restart) {throw err} 177 MathJax.Callback.After(["SVGtooltipPost",this,x,y],err.restart); 178 return; 179 } 180 this.SetData(1,mml); 181 182 currentTip = this; 183 }, 184 SVGtooltipClear: function (n) { 185 var tip = this.SVGtooltip; 186 if (n <= 0) { 187 tip.style.display = "none"; 188 tip.style.opacity = ""; 189 clear = null; 190 } else { 191 tip.style.opacity = n/100; 192 clear = setTimeout(MathJax.Callback(["SVGtooltipClear",this,n-20]),50); 193 } 194 } 195 }); 196 197 MathJax.Hub.Startup.signal.Post("SVG maction Ready"); 198 MathJax.Ajax.loadComplete(SVG.autoloadDir+"/maction.js"); 199 200 }); 201