Source file src/cmd/vendor/github.com/google/pprof/third_party/svgpan/svgpan.go

     1  // SVG pan and zoom library.
     2  // See copyright notice in string constant below.
     3  
     4  package svgpan
     5  
     6  // https://github.com/aleofreddi/svgpan
     7  
     8  // JSSource returns the svgpan.js file
     9  const JSSource = `
    10  /**
    11   *  SVGPan library 1.2.2
    12   * ======================
    13   *
    14   * Given an unique existing element with id "viewport" (or when missing, the
    15   * first g-element), including the library into any SVG adds the following
    16   * capabilities:
    17   *
    18   *  - Mouse panning
    19   *  - Mouse zooming (using the wheel)
    20   *  - Object dragging
    21   *
    22   * You can configure the behaviour of the pan/zoom/drag with the variables
    23   * listed in the CONFIGURATION section of this file.
    24   *
    25   * Known issues:
    26   *
    27   *  - Zooming (while panning) on Safari has still some issues
    28   *
    29   * Releases:
    30   *
    31   * 1.2.2, Tue Aug 30 17:21:56 CEST 2011, Andrea Leofreddi
    32   *	- Fixed viewBox on root tag (#7)
    33   *	- Improved zoom speed (#2)
    34   *
    35   * 1.2.1, Mon Jul  4 00:33:18 CEST 2011, Andrea Leofreddi
    36   *	- Fixed a regression with mouse wheel (now working on Firefox 5)
    37   *	- Working with viewBox attribute (#4)
    38   *	- Added "use strict;" and fixed resulting warnings (#5)
    39   *	- Added configuration variables, dragging is disabled by default (#3)
    40   *
    41   * 1.2, Sat Mar 20 08:42:50 GMT 2010, Zeng Xiaohui
    42   *	Fixed a bug with browser mouse handler interaction
    43   *
    44   * 1.1, Wed Feb  3 17:39:33 GMT 2010, Zeng Xiaohui
    45   *	Updated the zoom code to support the mouse wheel on Safari/Chrome
    46   *
    47   * 1.0, Andrea Leofreddi
    48   *	First release
    49   *
    50   * This code is licensed under the following BSD license:
    51   *
    52   * Copyright 2009-2017 Andrea Leofreddi <a.leofreddi@vleo.net>. All rights reserved.
    53   *
    54   * Redistribution and use in source and binary forms, with or without modification, are
    55   * permitted provided that the following conditions are met:
    56   *
    57   *    1. Redistributions of source code must retain the above copyright
    58   *       notice, this list of conditions and the following disclaimer.
    59   *    2. Redistributions in binary form must reproduce the above copyright
    60   *       notice, this list of conditions and the following disclaimer in the
    61   *       documentation and/or other materials provided with the distribution.
    62   *    3. Neither the name of the copyright holder nor the names of its
    63   *       contributors may be used to endorse or promote products derived from
    64   *       this software without specific prior written permission.
    65   *
    66   * THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND ANY EXPRESS
    67   * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
    68   * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS OR
    69   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    70   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    71   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
    72   * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    73   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
    74   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    75   *
    76   * The views and conclusions contained in the software and documentation are those of the
    77   * authors and should not be interpreted as representing official policies, either expressed
    78   * or implied, of Andrea Leofreddi.
    79   */
    80  
    81  "use strict";
    82  
    83  /// CONFIGURATION
    84  /// ====>
    85  
    86  var enablePan = 1; // 1 or 0: enable or disable panning (default enabled)
    87  var enableZoom = 1; // 1 or 0: enable or disable zooming (default enabled)
    88  var enableDrag = 0; // 1 or 0: enable or disable dragging (default disabled)
    89  var zoomScale = 0.2; // Zoom sensitivity
    90  
    91  /// <====
    92  /// END OF CONFIGURATION
    93  
    94  var root = document.documentElement;
    95  
    96  var state = 'none', svgRoot = null, stateTarget, stateOrigin, stateTf;
    97  
    98  setupHandlers(root);
    99  
   100  /**
   101   * Register handlers
   102   */
   103  function setupHandlers(root){
   104  	setAttributes(root, {
   105  		"onmouseup" : "handleMouseUp(evt)",
   106  		"onmousedown" : "handleMouseDown(evt)",
   107  		"onmousemove" : "handleMouseMove(evt)",
   108  		//"onmouseout" : "handleMouseUp(evt)", // Decomment this to stop the pan functionality when dragging out of the SVG element
   109  	});
   110  
   111  	if(navigator.userAgent.toLowerCase().indexOf('webkit') >= 0)
   112  		window.addEventListener('mousewheel', handleMouseWheel, false); // Chrome/Safari
   113  	else
   114  		window.addEventListener('DOMMouseScroll', handleMouseWheel, false); // Others
   115  }
   116  
   117  /**
   118   * Retrieves the root element for SVG manipulation. The element is then cached into the svgRoot global variable.
   119   */
   120  function getRoot(root) {
   121  	if(svgRoot == null) {
   122  		var r = root.getElementById("viewport") ? root.getElementById("viewport") : root.documentElement, t = r;
   123  
   124  		while(t != root) {
   125  			if(t.getAttribute("viewBox")) {
   126  				setCTM(r, t.getCTM());
   127  
   128  				t.removeAttribute("viewBox");
   129  			}
   130  
   131  			t = t.parentNode;
   132  		}
   133  
   134  		svgRoot = r;
   135  	}
   136  
   137  	return svgRoot;
   138  }
   139  
   140  /**
   141   * Instance an SVGPoint object with given event coordinates.
   142   */
   143  function getEventPoint(evt) {
   144  	var p = root.createSVGPoint();
   145  
   146  	p.x = evt.clientX;
   147  	p.y = evt.clientY;
   148  
   149  	return p;
   150  }
   151  
   152  /**
   153   * Sets the current transform matrix of an element.
   154   */
   155  function setCTM(element, matrix) {
   156  	var s = "matrix(" + matrix.a + "," + matrix.b + "," + matrix.c + "," + matrix.d + "," + matrix.e + "," + matrix.f + ")";
   157  
   158  	element.setAttribute("transform", s);
   159  }
   160  
   161  /**
   162   * Dumps a matrix to a string (useful for debug).
   163   */
   164  function dumpMatrix(matrix) {
   165  	var s = "[ " + matrix.a + ", " + matrix.c + ", " + matrix.e + "\n  " + matrix.b + ", " + matrix.d + ", " + matrix.f + "\n  0, 0, 1 ]";
   166  
   167  	return s;
   168  }
   169  
   170  /**
   171   * Sets attributes of an element.
   172   */
   173  function setAttributes(element, attributes){
   174  	for (var i in attributes)
   175  		element.setAttributeNS(null, i, attributes[i]);
   176  }
   177  
   178  /**
   179   * Handle mouse wheel event.
   180   */
   181  function handleMouseWheel(evt) {
   182  	if(!enableZoom)
   183  		return;
   184  
   185  	if(evt.preventDefault)
   186  		evt.preventDefault();
   187  
   188  	evt.returnValue = false;
   189  
   190  	var svgDoc = evt.target.ownerDocument;
   191  
   192  	var delta;
   193  
   194  	if(evt.wheelDelta)
   195  		delta = evt.wheelDelta / 360; // Chrome/Safari
   196  	else
   197  		delta = evt.detail / -9; // Mozilla
   198  
   199  	var z = Math.pow(1 + zoomScale, delta);
   200  
   201  	var g = getRoot(svgDoc);
   202  
   203  	var p = getEventPoint(evt);
   204  
   205  	p = p.matrixTransform(g.getCTM().inverse());
   206  
   207  	// Compute new scale matrix in current mouse position
   208  	var k = root.createSVGMatrix().translate(p.x, p.y).scale(z).translate(-p.x, -p.y);
   209  
   210          setCTM(g, g.getCTM().multiply(k));
   211  
   212  	if(typeof(stateTf) == "undefined")
   213  		stateTf = g.getCTM().inverse();
   214  
   215  	stateTf = stateTf.multiply(k.inverse());
   216  }
   217  
   218  /**
   219   * Handle mouse move event.
   220   */
   221  function handleMouseMove(evt) {
   222  	if(evt.preventDefault)
   223  		evt.preventDefault();
   224  
   225  	evt.returnValue = false;
   226  
   227  	var svgDoc = evt.target.ownerDocument;
   228  
   229  	var g = getRoot(svgDoc);
   230  
   231  	if(state == 'pan' && enablePan) {
   232  		// Pan mode
   233  		var p = getEventPoint(evt).matrixTransform(stateTf);
   234  
   235  		setCTM(g, stateTf.inverse().translate(p.x - stateOrigin.x, p.y - stateOrigin.y));
   236  	} else if(state == 'drag' && enableDrag) {
   237  		// Drag mode
   238  		var p = getEventPoint(evt).matrixTransform(g.getCTM().inverse());
   239  
   240  		setCTM(stateTarget, root.createSVGMatrix().translate(p.x - stateOrigin.x, p.y - stateOrigin.y).multiply(g.getCTM().inverse()).multiply(stateTarget.getCTM()));
   241  
   242  		stateOrigin = p;
   243  	}
   244  }
   245  
   246  /**
   247   * Handle click event.
   248   */
   249  function handleMouseDown(evt) {
   250  	if(evt.preventDefault)
   251  		evt.preventDefault();
   252  
   253  	evt.returnValue = false;
   254  
   255  	var svgDoc = evt.target.ownerDocument;
   256  
   257  	var g = getRoot(svgDoc);
   258  
   259  	if(
   260  		evt.target.tagName == "svg"
   261  		|| !enableDrag // Pan anyway when drag is disabled and the user clicked on an element
   262  	) {
   263  		// Pan mode
   264  		state = 'pan';
   265  
   266  		stateTf = g.getCTM().inverse();
   267  
   268  		stateOrigin = getEventPoint(evt).matrixTransform(stateTf);
   269  	} else {
   270  		// Drag mode
   271  		state = 'drag';
   272  
   273  		stateTarget = evt.target;
   274  
   275  		stateTf = g.getCTM().inverse();
   276  
   277  		stateOrigin = getEventPoint(evt).matrixTransform(stateTf);
   278  	}
   279  }
   280  
   281  /**
   282   * Handle mouse button release event.
   283   */
   284  function handleMouseUp(evt) {
   285  	if(evt.preventDefault)
   286  		evt.preventDefault();
   287  
   288  	evt.returnValue = false;
   289  
   290  	var svgDoc = evt.target.ownerDocument;
   291  
   292  	if(state == 'pan' || state == 'drag') {
   293  		// Quit pan mode
   294  		state = '';
   295  	}
   296  }
   297  `
   298  

View as plain text