You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					281 lines
				
				7.7 KiB
			
		
		
			
		
	
	
					281 lines
				
				7.7 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								* Licensed to the Apache Software Foundation (ASF) under one
							 | 
						||
| 
								 | 
							
								* or more contributor license agreements.  See the NOTICE file
							 | 
						||
| 
								 | 
							
								* distributed with this work for additional information
							 | 
						||
| 
								 | 
							
								* regarding copyright ownership.  The ASF licenses this file
							 | 
						||
| 
								 | 
							
								* to you under the Apache License, Version 2.0 (the
							 | 
						||
| 
								 | 
							
								* "License"); you may not use this file except in compliance
							 | 
						||
| 
								 | 
							
								* with the License.  You may obtain a copy of the License at
							 | 
						||
| 
								 | 
							
								*
							 | 
						||
| 
								 | 
							
								*   http://www.apache.org/licenses/LICENSE-2.0
							 | 
						||
| 
								 | 
							
								*
							 | 
						||
| 
								 | 
							
								* Unless required by applicable law or agreed to in writing,
							 | 
						||
| 
								 | 
							
								* software distributed under the License is distributed on an
							 | 
						||
| 
								 | 
							
								* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
							 | 
						||
| 
								 | 
							
								* KIND, either express or implied.  See the License for the
							 | 
						||
| 
								 | 
							
								* specific language governing permissions and limitations
							 | 
						||
| 
								 | 
							
								* under the License.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var _config = require("../config");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var __DEV__ = _config.__DEV__;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var zrUtil = require("zrender/lib/core/util");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								* Licensed to the Apache Software Foundation (ASF) under one
							 | 
						||
| 
								 | 
							
								* or more contributor license agreements.  See the NOTICE file
							 | 
						||
| 
								 | 
							
								* distributed with this work for additional information
							 | 
						||
| 
								 | 
							
								* regarding copyright ownership.  The ASF licenses this file
							 | 
						||
| 
								 | 
							
								* to you under the Apache License, Version 2.0 (the
							 | 
						||
| 
								 | 
							
								* "License"); you may not use this file except in compliance
							 | 
						||
| 
								 | 
							
								* with the License.  You may obtain a copy of the License at
							 | 
						||
| 
								 | 
							
								*
							 | 
						||
| 
								 | 
							
								*   http://www.apache.org/licenses/LICENSE-2.0
							 | 
						||
| 
								 | 
							
								*
							 | 
						||
| 
								 | 
							
								* Unless required by applicable law or agreed to in writing,
							 | 
						||
| 
								 | 
							
								* software distributed under the License is distributed on an
							 | 
						||
| 
								 | 
							
								* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
							 | 
						||
| 
								 | 
							
								* KIND, either express or implied.  See the License for the
							 | 
						||
| 
								 | 
							
								* specific language governing permissions and limitations
							 | 
						||
| 
								 | 
							
								* under the License.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								var TYPE_DELIMITER = '.';
							 | 
						||
| 
								 | 
							
								var IS_CONTAINER = '___EC__COMPONENT__CONTAINER___';
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Notice, parseClassType('') should returns {main: '', sub: ''}
							 | 
						||
| 
								 | 
							
								 * @public
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function parseClassType(componentType) {
							 | 
						||
| 
								 | 
							
								  var ret = {
							 | 
						||
| 
								 | 
							
								    main: '',
							 | 
						||
| 
								 | 
							
								    sub: ''
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (componentType) {
							 | 
						||
| 
								 | 
							
								    componentType = componentType.split(TYPE_DELIMITER);
							 | 
						||
| 
								 | 
							
								    ret.main = componentType[0] || '';
							 | 
						||
| 
								 | 
							
								    ret.sub = componentType[1] || '';
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return ret;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @public
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function checkClassType(componentType) {
							 | 
						||
| 
								 | 
							
								  zrUtil.assert(/^[a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)?$/.test(componentType), 'componentType "' + componentType + '" illegal');
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @public
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function enableClassExtend(RootClass, mandatoryMethods) {
							 | 
						||
| 
								 | 
							
								  RootClass.$constructor = RootClass;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  RootClass.extend = function (proto) {
							 | 
						||
| 
								 | 
							
								    var superClass = this;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var ExtendedClass = function () {
							 | 
						||
| 
								 | 
							
								      if (!proto.$constructor) {
							 | 
						||
| 
								 | 
							
								        superClass.apply(this, arguments);
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        proto.$constructor.apply(this, arguments);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    zrUtil.extend(ExtendedClass.prototype, proto);
							 | 
						||
| 
								 | 
							
								    ExtendedClass.extend = this.extend;
							 | 
						||
| 
								 | 
							
								    ExtendedClass.superCall = superCall;
							 | 
						||
| 
								 | 
							
								    ExtendedClass.superApply = superApply;
							 | 
						||
| 
								 | 
							
								    zrUtil.inherits(ExtendedClass, this);
							 | 
						||
| 
								 | 
							
								    ExtendedClass.superClass = superClass;
							 | 
						||
| 
								 | 
							
								    return ExtendedClass;
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var classBase = 0;
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Can not use instanceof, consider different scope by
							 | 
						||
| 
								 | 
							
								 * cross domain or es module import in ec extensions.
							 | 
						||
| 
								 | 
							
								 * Mount a method "isInstance()" to Clz.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function enableClassCheck(Clz) {
							 | 
						||
| 
								 | 
							
								  var classAttr = ['__\0is_clz', classBase++, Math.random().toFixed(3)].join('_');
							 | 
						||
| 
								 | 
							
								  Clz.prototype[classAttr] = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  Clz.isInstance = function (obj) {
							 | 
						||
| 
								 | 
							
								    return !!(obj && obj[classAttr]);
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								} // superCall should have class info, which can not be fetch from 'this'.
							 | 
						||
| 
								 | 
							
								// Consider this case:
							 | 
						||
| 
								 | 
							
								// class A has method f,
							 | 
						||
| 
								 | 
							
								// class B inherits class A, overrides method f, f call superApply('f'),
							 | 
						||
| 
								 | 
							
								// class C inherits class B, do not overrides method f,
							 | 
						||
| 
								 | 
							
								// then when method of class C is called, dead loop occured.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function superCall(context, methodName) {
							 | 
						||
| 
								 | 
							
								  var args = zrUtil.slice(arguments, 2);
							 | 
						||
| 
								 | 
							
								  return this.superClass.prototype[methodName].apply(context, args);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function superApply(context, methodName, args) {
							 | 
						||
| 
								 | 
							
								  return this.superClass.prototype[methodName].apply(context, args);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @param {Object} entity
							 | 
						||
| 
								 | 
							
								 * @param {Object} options
							 | 
						||
| 
								 | 
							
								 * @param {boolean} [options.registerWhenExtend]
							 | 
						||
| 
								 | 
							
								 * @public
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function enableClassManagement(entity, options) {
							 | 
						||
| 
								 | 
							
								  options = options || {};
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * Component model classes
							 | 
						||
| 
								 | 
							
								   * key: componentType,
							 | 
						||
| 
								 | 
							
								   * value:
							 | 
						||
| 
								 | 
							
								   *     componentClass, when componentType is 'xxx'
							 | 
						||
| 
								 | 
							
								   *     or Object.<subKey, componentClass>, when componentType is 'xxx.yy'
							 | 
						||
| 
								 | 
							
								   * @type {Object}
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var storage = {};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  entity.registerClass = function (Clazz, componentType) {
							 | 
						||
| 
								 | 
							
								    if (componentType) {
							 | 
						||
| 
								 | 
							
								      checkClassType(componentType);
							 | 
						||
| 
								 | 
							
								      componentType = parseClassType(componentType);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (!componentType.sub) {
							 | 
						||
| 
								 | 
							
								        storage[componentType.main] = Clazz;
							 | 
						||
| 
								 | 
							
								      } else if (componentType.sub !== IS_CONTAINER) {
							 | 
						||
| 
								 | 
							
								        var container = makeContainer(componentType);
							 | 
						||
| 
								 | 
							
								        container[componentType.sub] = Clazz;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return Clazz;
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  entity.getClass = function (componentMainType, subType, throwWhenNotFound) {
							 | 
						||
| 
								 | 
							
								    var Clazz = storage[componentMainType];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (Clazz && Clazz[IS_CONTAINER]) {
							 | 
						||
| 
								 | 
							
								      Clazz = subType ? Clazz[subType] : null;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (throwWhenNotFound && !Clazz) {
							 | 
						||
| 
								 | 
							
								      throw new Error(!subType ? componentMainType + '.' + 'type should be specified.' : 'Component ' + componentMainType + '.' + (subType || '') + ' not exists. Load it first.');
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return Clazz;
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  entity.getClassesByMainType = function (componentType) {
							 | 
						||
| 
								 | 
							
								    componentType = parseClassType(componentType);
							 | 
						||
| 
								 | 
							
								    var result = [];
							 | 
						||
| 
								 | 
							
								    var obj = storage[componentType.main];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (obj && obj[IS_CONTAINER]) {
							 | 
						||
| 
								 | 
							
								      zrUtil.each(obj, function (o, type) {
							 | 
						||
| 
								 | 
							
								        type !== IS_CONTAINER && result.push(o);
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      result.push(obj);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return result;
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  entity.hasClass = function (componentType) {
							 | 
						||
| 
								 | 
							
								    // Just consider componentType.main.
							 | 
						||
| 
								 | 
							
								    componentType = parseClassType(componentType);
							 | 
						||
| 
								 | 
							
								    return !!storage[componentType.main];
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * @return {Array.<string>} Like ['aa', 'bb'], but can not be ['aa.xx']
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  entity.getAllClassMainTypes = function () {
							 | 
						||
| 
								 | 
							
								    var types = [];
							 | 
						||
| 
								 | 
							
								    zrUtil.each(storage, function (obj, type) {
							 | 
						||
| 
								 | 
							
								      types.push(type);
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    return types;
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * If a main type is container and has sub types
							 | 
						||
| 
								 | 
							
								   * @param  {string}  mainType
							 | 
						||
| 
								 | 
							
								   * @return {boolean}
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  entity.hasSubTypes = function (componentType) {
							 | 
						||
| 
								 | 
							
								    componentType = parseClassType(componentType);
							 | 
						||
| 
								 | 
							
								    var obj = storage[componentType.main];
							 | 
						||
| 
								 | 
							
								    return obj && obj[IS_CONTAINER];
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  entity.parseClassType = parseClassType;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function makeContainer(componentType) {
							 | 
						||
| 
								 | 
							
								    var container = storage[componentType.main];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!container || !container[IS_CONTAINER]) {
							 | 
						||
| 
								 | 
							
								      container = storage[componentType.main] = {};
							 | 
						||
| 
								 | 
							
								      container[IS_CONTAINER] = true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return container;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (options.registerWhenExtend) {
							 | 
						||
| 
								 | 
							
								    var originalExtend = entity.extend;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (originalExtend) {
							 | 
						||
| 
								 | 
							
								      entity.extend = function (proto) {
							 | 
						||
| 
								 | 
							
								        var ExtendedClass = originalExtend.call(this, proto);
							 | 
						||
| 
								 | 
							
								        return entity.registerClass(ExtendedClass, proto.type);
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return entity;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @param {string|Array.<string>} properties
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function setReadOnly(obj, properties) {// FIXME It seems broken in IE8 simulation of IE11
							 | 
						||
| 
								 | 
							
								  // if (!zrUtil.isArray(properties)) {
							 | 
						||
| 
								 | 
							
								  //     properties = properties != null ? [properties] : [];
							 | 
						||
| 
								 | 
							
								  // }
							 | 
						||
| 
								 | 
							
								  // zrUtil.each(properties, function (prop) {
							 | 
						||
| 
								 | 
							
								  //     var value = obj[prop];
							 | 
						||
| 
								 | 
							
								  //     Object.defineProperty
							 | 
						||
| 
								 | 
							
								  //         && Object.defineProperty(obj, prop, {
							 | 
						||
| 
								 | 
							
								  //             value: value, writable: false
							 | 
						||
| 
								 | 
							
								  //         });
							 | 
						||
| 
								 | 
							
								  //     zrUtil.isArray(obj[prop])
							 | 
						||
| 
								 | 
							
								  //         && Object.freeze
							 | 
						||
| 
								 | 
							
								  //         && Object.freeze(obj[prop]);
							 | 
						||
| 
								 | 
							
								  // });
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								exports.parseClassType = parseClassType;
							 | 
						||
| 
								 | 
							
								exports.enableClassExtend = enableClassExtend;
							 | 
						||
| 
								 | 
							
								exports.enableClassCheck = enableClassCheck;
							 | 
						||
| 
								 | 
							
								exports.enableClassManagement = enableClassManagement;
							 | 
						||
| 
								 | 
							
								exports.setReadOnly = setReadOnly;
							 |