dragonbones-runtime
Version:
the tools to build dragonbones file for diffrent framework
301 lines (277 loc) • 8.55 kB
text/typescript
/**
* Created by yanjiaqi on 15/10/21.
*/
import file = require("../FileUtil");
import XMLTool = require("../xml/index");
/**
* @private
* EUI 命名空间
*/
export var NS_S:string = "http://ns.egret.com/eui";
/**
* @private
* Wing命名空间
*/
export var NS_W:string = "http://ns.egret.com/wing";
var coreClasses:string[] = ["Point","Matrix","Rectangle"];
var basicTypes:string[] = ["Object", "Array", "boolean", "string", "number"];
var MODULE_NAME = "eui.";
var hashCount = 0;
var properties: any = {};
//added by yanjiaqi 2015.10.21
var stylesMap = {};
class Component{
/**
* 构造函数
*/
public constructor(item?:any){
if(item){
this.id = item.$id;
this.className = item["$module"] +"."+ this.id;
if(item["$super"])
this.superClass = item.$super;
if(item["$default"])
this.defaultProp = item.$default;
}
}
/**
* 短名ID
*/
public id:string;
/**
* 完整类名
*/
public className:string;
/**
* 父级类名
*/
public superClass:string = "";
/**
* 默认属性
*/
public defaultProp:string = "";
}
//end by yanjiaqi
/**
* @private
*/
export class EXMLConfig {
//added by yanjiaqi 2015.10.21
static __instance :EXMLConfig = null;
/**
* 组件清单列表
*/
public componentDic:any = {};
public idMap:any = {};
/**
* 项目目录路径
*/
private _dirPath:string;
get dirPath():string{
return this._dirPath;
}
set dirPath(value:string){
if(this._dirPath !== value){
this._dirPath = value;
this.classNameToExmlFilePath = this.getClassToPathInfo(this.dirPath);
}
//this.parseModules();
}
private getClassToPathInfo(dirPath:string):any{
var exmls:string[] = file.search(dirPath, 'exml');
exmls.forEach(exml=>{
var str:string = file.read(exml);
var xml:egret.XML = XMLTool.parse(str);
var className:string = null;
if(xml["$class"]){
className = xml["$class"];
}else{
className = this.getClassNameById(xml.localName,xml.namespace);
}
exmls[className] = exml;
});
return exmls;
}
/**
* 目录下所有exml文件的地址与类全名的映射
*/
classNameToExmlFilePath:any;
constructor() {
var exmlPath:string = egret.root + "/tools/lib/eui/";
exmlPath = exmlPath.split("\\").join("/");
var str:string = file.read(exmlPath + "manifest.xml");
var manifest:any = XMLTool.parse(str);
this.parseManifest(manifest);
str = file.read(exmlPath + "properties.json");
properties = JSON.parse(str);
//this.findStyles(properties);
}
static getInstance():EXMLConfig{
if(EXMLConfig.__instance == null){
EXMLConfig.__instance = new EXMLConfig();
}
return EXMLConfig.__instance;
}
/**
* 解析框架清单文件
*/
public parseManifest(manifest:any):void {
var children:Array<any> = manifest.children;
var length:number = children.length;
for (var i:number = 0; i < length; i++) {
var item:any = children[i];
var component:Component = new Component(item);
this.componentDic[component.className] = component;
this.idMap[component.id] = component.className;
}
for (var className in this.componentDic) {
var component:Component = this.componentDic[className];
if (!component.defaultProp)
this.findProp(component);
}
}
/**
* 递归查找默认属性
*/
private findProp(component:Component):string {
if (component.defaultProp)
return component.defaultProp;
var superComp:Component = this.componentDic[component.superClass];
if (superComp) {
var prop:string = this.findProp(superComp);
if (prop) {
component.defaultProp = prop;
}
}
return component.defaultProp;
}
public getClassNameById(id:string, ns:string):string {
var name:string = "";
//基本类型直接返回
if (basicTypes.indexOf(id) != -1) {
return id;
}
//忽略wing的命名空间
if (ns == NS_W) {
}
//省略命名空间和命名空间是eui的去表中查
else if (!ns || ns == NS_S) {
name = this.idMap[id];
}
//自定义命名空间形如mrj.*要去掉*
else {
name = ns.substring(0, ns.length - 1) + id;
if (!this.classNameToExmlFilePath[name]) {
name = "";
}
}
return name;
}
//end by yanjiaqi
/**
* @private
* 根据ID获取对应的默认属性
* @param id 类的短名ID
* @param ns 命名空间
* @return 默认属性名
*/
//added by yanjiaqi
public getDefaultPropById(id:string, ns:string):string{
var className:string = this.getClassNameById(id,ns);
var component:Component = this.componentDic[className];
if(!component&&className){
component = this.findDefaultProp(className);
}
if(!component)
return "";
return component.defaultProp;
}
private findDefaultProp(className:string):Component{
//去properties配置文件中找
var classData:any = properties[className];
if(!classData){
var path:string = this.classNameToExmlFilePath[className];
//var ext:string = file.getExtension(path).toLowerCase();
var text:string = file.read(path);
//if(ext=="ts"){
// classData = this.getPropertiesFromTs(text,className,"");
//}
//else if(ext=="exml"){
classData = this.getPropertiesFromExml(text);
//}
if(classData){
properties[className] = classData;
}
else{
return null;
}
}
//向上递归寻找父类的默认属性
var superClass:string = classData["super"];
var component:Component = this.componentDic[superClass];
if(!component){
component = this.findDefaultProp(superClass);
}
return component;
}
/**
* 读取一个exml文件引用的类列表
*/
private getPropertiesFromExml(text:string):any{
var exml:any = XMLTool.parse(text);
if(!exml){
return null;
}
var superClass:string = this.getClassNameById(exml.localName,exml.namespace);
if(superClass){
var data:any = {};
data["super"] = superClass;
return data;
}
return null;
}
/**
* @private
* 获取指定属性的类型,返回基本数据类型:"boolean","string","number","any"。
* @param property 属性名
* @param className 要查询的完整类名
*/
public getPropertyType(prop:string,className:string):string{
if(className=="Object"){
return "any";
}
var type:string = this.findType(className,prop);
//if(!type){
// if(this.checkStyleProperty(prop,className)){
// return stylesMap[prop];
// }
//}
return type;
}
private findType(className:string,prop:string):string{
var classData:any = properties[className];
if(!classData){
var path:string = this.classNameToExmlFilePath[className];
//var ext:string = file.getExtension(path).toLowerCase();
var text:string = file.read(path);
//if(ext=="ts"){
// text = CodeUtil.removeComment(text,path);
// classData = this.getPropertiesFromTs(text,className,"");
//}
//else if(ext=="exml"){
classData = this.getPropertiesFromExml(text);
//}
if(classData){
properties[className] = classData;
}
else{
return "";
}
}
var type:string = classData[prop];
if(!type){
type = this.findType(classData["super"],prop);
}
return type;
}
}