| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 | var _core = require("../core");var createElement = _core.createElement;var zrUtil = require("../../core/util");var Path = require("../../graphic/Path");var ZImage = require("../../graphic/Image");var ZText = require("../../graphic/Text");var _graphic = require("../graphic");var svgPath = _graphic.path;var svgImage = _graphic.image;var svgText = _graphic.text;/** * @file Manages elements that can be defined in <defs> in SVG, *       e.g., gradients, clip path, etc. * @author Zhang Wenli */var MARK_UNUSED = '0';var MARK_USED = '1';/** * Manages elements that can be defined in <defs> in SVG, * e.g., gradients, clip path, etc. * * @class * @param {number}          zrId      zrender instance id * @param {SVGElement}      svgRoot   root of SVG document * @param {string|string[]} tagNames  possible tag names * @param {string}          markLabel label name to make if the element *                                    is used */function Definable(zrId, svgRoot, tagNames, markLabel, domName) {  this._zrId = zrId;  this._svgRoot = svgRoot;  this._tagNames = typeof tagNames === 'string' ? [tagNames] : tagNames;  this._markLabel = markLabel;  this._domName = domName || '_dom';  this.nextId = 0;}Definable.prototype.createElement = createElement;/** * Get the <defs> tag for svgRoot; optionally creates one if not exists. * * @param {boolean} isForceCreating if need to create when not exists * @return {SVGDefsElement} SVG <defs> element, null if it doesn't * exist and isForceCreating is false */Definable.prototype.getDefs = function (isForceCreating) {  var svgRoot = this._svgRoot;  var defs = this._svgRoot.getElementsByTagName('defs');  if (defs.length === 0) {    // Not exist    if (isForceCreating) {      defs = svgRoot.insertBefore(this.createElement('defs'), // Create new tag      svgRoot.firstChild // Insert in the front of svg      );      if (!defs.contains) {        // IE doesn't support contains method        defs.contains = function (el) {          var children = defs.children;          if (!children) {            return false;          }          for (var i = children.length - 1; i >= 0; --i) {            if (children[i] === el) {              return true;            }          }          return false;        };      }      return defs;    } else {      return null;    }  } else {    return defs[0];  }};/** * Update DOM element if necessary. * * @param {Object|string} element style element. e.g., for gradient, *                                it may be '#ccc' or {type: 'linear', ...} * @param {Function|undefined} onUpdate update callback */Definable.prototype.update = function (element, onUpdate) {  if (!element) {    return;  }  var defs = this.getDefs(false);  if (element[this._domName] && defs.contains(element[this._domName])) {    // Update DOM    if (typeof onUpdate === 'function') {      onUpdate(element);    }  } else {    // No previous dom, create new    var dom = this.add(element);    if (dom) {      element[this._domName] = dom;    }  }};/** * Add gradient dom to defs * * @param {SVGElement} dom DOM to be added to <defs> */Definable.prototype.addDom = function (dom) {  var defs = this.getDefs(true);  defs.appendChild(dom);};/** * Remove DOM of a given element. * * @param {SVGElement} element element to remove dom */Definable.prototype.removeDom = function (element) {  var defs = this.getDefs(false);  if (defs && element[this._domName]) {    defs.removeChild(element[this._domName]);    element[this._domName] = null;  }};/** * Get DOMs of this element. * * @return {HTMLDomElement} doms of this defineable elements in <defs> */Definable.prototype.getDoms = function () {  var defs = this.getDefs(false);  if (!defs) {    // No dom when defs is not defined    return [];  }  var doms = [];  zrUtil.each(this._tagNames, function (tagName) {    var tags = defs.getElementsByTagName(tagName); // Note that tags is HTMLCollection, which is array-like    // rather than real array.    // So `doms.concat(tags)` add tags as one object.    doms = doms.concat([].slice.call(tags));  });  return doms;};/** * Mark DOMs to be unused before painting, and clear unused ones at the end * of the painting. */Definable.prototype.markAllUnused = function () {  var doms = this.getDoms();  var that = this;  zrUtil.each(doms, function (dom) {    dom[that._markLabel] = MARK_UNUSED;  });};/** * Mark a single DOM to be used. * * @param {SVGElement} dom DOM to mark */Definable.prototype.markUsed = function (dom) {  if (dom) {    dom[this._markLabel] = MARK_USED;  }};/** * Remove unused DOMs defined in <defs> */Definable.prototype.removeUnused = function () {  var defs = this.getDefs(false);  if (!defs) {    // Nothing to remove    return;  }  var doms = this.getDoms();  var that = this;  zrUtil.each(doms, function (dom) {    if (dom[that._markLabel] !== MARK_USED) {      // Remove gradient      defs.removeChild(dom);    }  });};/** * Get SVG proxy. * * @param {Displayable} displayable displayable element * @return {Path|Image|Text} svg proxy of given element */Definable.prototype.getSvgProxy = function (displayable) {  if (displayable instanceof Path) {    return svgPath;  } else if (displayable instanceof ZImage) {    return svgImage;  } else if (displayable instanceof ZText) {    return svgText;  } else {    return svgPath;  }};/** * Get text SVG element. * * @param {Displayable} displayable displayable element * @return {SVGElement} SVG element of text */Definable.prototype.getTextSvgElement = function (displayable) {  return displayable.__textSvgEl;};/** * Get SVG element. * * @param {Displayable} displayable displayable element * @return {SVGElement} SVG element */Definable.prototype.getSvgElement = function (displayable) {  return displayable.__svgEl;};var _default = Definable;module.exports = _default;
 |