ESOE-IDE v0.3 技术说明书

ESOE-IDE v0.3 技术说明书

Author: Feng WeiGuo (冯卫国)

Email: forxm@21cn.com

Web: http://www.supertree.org

Tel: 86-0755-81030955

 

All Rights Reserved

2008-9

 

目录

 

ESOE-IDE v0.3 技术说明书... 1

1. 设计目标/特性... 3

2.类模型... 3

2.1 类模型和类声明... 3

2.1 类的名称空间管理... 6

3.绑定... 6

3.1 从HTML绑定js类... 6

3.2 从js类绑定DOM元素... 6

4.资源... 7

5.DOM元素寻址... 7

6.事件映射... 8

7.ESOE-IDE加载过程... 9

8. 类文件管理/打包输出/库文件... 9

9.ESOE-IDE对实现DOM类的建议... 10

9.1. 全局Z-index分配... 10

9.2. 事件映射方法... 10

9.3. 控件设计... 10

9.4. 窗体设计... 11

9.5. 对话框设计... 11

附录A. ESOE-IDE工具函数... 13

name convention. 13

$esoe.$preload. 13

$esoe.$declare. 13

$esoe.$new.. 13

$esoe.$derive. 14

$esoe.$import 14

$esoe.$bind. 14

$esoe.$find. 14

$esoe.$init 15

$esoe.$apply. 15

$esoe.$. 15

$esoe.$$. 16

$esoe.$notify. 16

附录B. 资源定义格式... 17

主资源格式... 17

附加资源格式... 17

附录C. 事件映射格式... 18

 

1. 设计目标/特性

  • 1. 由独立的js模块,和独立的html模块构造,减少传统Web设计时两者相互混合;
  • 2. 与传统IDE类似,Js和html之间的联系,应是代码(js)和资源(html)之间的关系;
  • 3. 伪编译:类库引用完整性检查/打包;
  • 4. 制作库文件(Library)功能;
  • 5. 事件à方法映射;
  • 6. 提供窗口框架/对话框/控件的功能;
  • 7. 提供类向导/映射向导等方便编辑;
  • 8. 输出的文件的js/html代码压缩;
  • 9. 类模型,基于早期版本的ESOE,提供类继承/名称空间等功能;
  • 10. 项目文件保存配置;
  • 11. 提供js/html语法着色编辑器;
  • 12. 自生系统:IDE自身使用js/html编码,使用IDE编译器制作生成;

 

2.类模型

ESOE-IDE v0.3是从早期版本ESOE v0.2演变而成,去除自动加载/共享/析构等功能,加入重要的类声明概念。

 

2.1 类模型和类声明

ESOE-IDE使用以下类模型:

  • 1.函数(Function)是类的构造函数,用于类实例的初始化;
  • 2.每个函数(Function)带有一个声明函数,用于构造类的原型(prototype);
  • 3.所有类在使用之前,必须声明,即调用声明函数。

 

以下给出实现以上类模型的实例,这些实例都可以兼容地应用到实际的编码中。

 

原始模型:

function MyClass(a,b)          //构造函数

{

       ...

}

MyClass._declare= function()              //声明函数

{

       MyClass2._declare();       //声明使用的外部类

      

       this.prototype={                   //构造原型

                     p1: 123,

                     f1: function(c,d)

                     {

                            var e= new MyClass2;     //使用外部类

                     }

              }

      

       this._declare=function(){}     //清除声明函数

}

 

....

MyClass._declare();              //声明一个类

var o= new MyClass(1,2);     //使用这个类

 

说明:

  • 1. 声明函数不带参数,避免引起闭包问题;
  • 2. 声明函数结束时清除声明函数,以允许多次声明;
  • 3. 使用一个类之前,必须先声明;
  • 4. 如果一个类使用了另一个外部类,在类的声明函数开始部分声明此外部类;
  • 5. ESOE-IDE中,类的声明函数的默认名称是"_declare";

 

使用类声明有以下好处:

  • 1. 使用大规模类库时,其中不被使用的类可以不用构造原型,加快系统加载,减少资源占用;
  • 2. 在类的声明函数开始部分声明外部类,如果此外部类未被加载,可以在应用启动时立即抛出异常,将运行时错误转为设计时错误,利于修改;

 

混合模型:

function MyClass(a,b)          //构造函数

{

}

MyClass._declare= function()       //声明函数

{

       ...

}

 

$esoe.$preload( "com.MyName.MyClass", MyClass, MyClass._declare );        //载入ESOE名称空间

...

var cls= $esoe.$declare("com.MyName.MyClass");          //声明一个类

var o= new cls(1,2);      //使用这个类

 

       说明:

  • 1. 使用$esoe.$preload()将类预载入ESOE名称空间,以利于管理;
  • 2. 预载入$esoe.$preload()不会调用类的声明函数;
  • 3. 使用$esoe.$declare ()声明类;
  • 4. $esoe.$declare ()自动清除声明函数;
  • 5. 混合模型可用于将已存在的代码快速改造为ESOE-IDE兼容的类;

 

IDE模型:

$esoe.$preload(

"com.MyName.MyClass",     //指定ESOE名称空间

function(a,b)          //构造函数

{

},

function()                     //声明函数

{

              ...

}

);

 

说明:

  • 1. 调用$esoe.$preload()时,直接使用匿名函数作为参数;
  • 2. ESOE-IDE编译器自动检查js代码中以下调用,以确保类引用完整性:
    $esoe.$preload
    $esoe.$declare
    $esoe.$import
    $esoe.$new
    $esoe.$derive
    $esoe.$bind
  • 3. ESOE-IDE编译器自动检查html代码中的jclass属性,以确保类引用完整性;

 

2.1 类的名称空间管理

与ESOE v0.2或其它具有名称空间管理框架类似,ESOE-IDE有自已的类名称空间。除了便于管理和避免名称冲突的作用外,ESOE-IDE的类名称空间具有以下特性:

  • 1. ESOE-IDE引擎在运行时不会利用类名进行自动加载工作;引用完整性在编译时被处理;
  • 2. ESOE-IDE编译器在确保类引用完整性时,按类名提示的路径信息查找对应的类文件;
  • 3. 类文件也可以不在对应类库的路径中,文件可以在任意路径位置,只要被加入项目文件中即可;例如可以在引用的类库文件中;

 

3.绑定

ESOE-IDE使用绑定的方法,将js类和html代码关联。

3.1 从HTML绑定js类

ESOE-IDE引擎将扫描HTML代码,如果DOM元素具有ESOE-IDE专有属性"jclass",则将该DOM元素与指示的js类绑定,生成一个DOM元素的"$jbind"属性,值为js类的一个实例。这种方式称为静态绑定。

 

例子:

<div jclass="MyClass" οnclick="this.$jbind.MyMethod()">abc</div>  <!--简单绑定-->

<div jclass="MyClass{a:1,b:2}"></div>  <!--带参数的绑定-->

3.2 从js类绑定DOM元素

    ESOE-IDE引擎提供$esoe.$bind函数,动态绑定DOM元素。

例子:

$esoe.$bind(

"MyClass",     //js类

ei,                  //Dom元素

{a:1,b:2}        //参数

);

 

4.资源

    ESOE-IDE系统以js代码为主要内容,HTML代码/CSS文件/其它文件作为js代码的附加项,称为附加资源。每一个js类可以带有一个默认的HTML代码,作为绑定DOM元素后设置为DOM元素的innerHTML值,此默认的HTML代码称为主资源。在ESOE-IDE系统中,HTML代码被分割为单独的小块代码而依附于js代码,被称为HTML片段,缩写为HTMI (HTML fragment item)。

例子:

//#ESOE_RES               //资源定义头部

this.$res=["",0,"<DIV>abc</DIV>" ];          //主资源

//#HTMI: htmi_MyHtmi2, MyHtmi2.htmi            //附加HTMI资源

//#CSS: css_MyCss, MyCss.css                        //附加CSS资源

//#FILE: file_MyPic_gif, MyPic.gif                     //附加FILE资源

//#END_ESOE_RES      //资源定义结束

 

       说明:

  • 1. 每个js类文件只可以有唯一的一段资源定义代码,以"//#ESOE_RES"起头,以"//#END_ESOE_RES"结束;
  • 2. 主资源定义在类构造函数的$res属性上;
  • 3. 附加资源以固定格式的注释语句定义,由ESOE-IDE编译器处理;
  • 4. 附加资源包括3种类型: htmi, css, file
  • 5. HTMI附加资源将被ESOE-IDE编译器编码到$esoe.$res数组中统一保存;

 

5.DOM元素寻址

传统Web程序主要依靠DOM元素的id属性,使用document.getElementById()寻找目标DOM元素。ESOE-IDE系统与传统方法不同,除某些特别场合外,ESOE-IDE主要使用name属性寻找目标元素,以利于js类对HTMI的封装和重用。

例子:

<div id=from>

       <div>

              <div name=name1></div>

              <div name=name2>

                     <div name=name3></div>

              </div>

       </div>

</dv>

...

e= document.getElementById(‘from');        //获取起始DOM元素

ei= $esoe.$find( "name1", e);                            //寻找DOM子元素

ei= $esoe.$find( "name2.name3", e);           //寻找多级DOM子元素

ei= $esoe.$find( "name3", e);                            //错误的寻址方式,无法找到元素

 

说明:

  • 1. 单个name寻址查找所有子孙节点的name属性,匹配第一个符合的节点;
  • 2. 单个name寻址不必是直接子节点;
  • 3. 匹配单个name属性的节点的所有祖先节点,到起始DOM元素为止,都不出现name属性;
  • 4. 多级name寻址使用"."联接;

 

6.事件映射

    与DOM元素绑定的js类,可以建立事件映射表,ESOE-IDE引擎自动将元素事件与js类方法进行关联。

例子:

//#ESOE_MAP              //事件映射定义头部

this.$map=[

       ["","click","OnClickMain" ],                 //映射主DOM元素事件

       ["name2.name3","click","OnClickName3" ]         //映射子DOM元素事件

       ];

//#END_ESOE_MAP     //事件映射定义结束

 

说明:

  • 1. 每个js类文件只可以有唯一的一段事件映射定义代码,以"//# ESOE_MAP"起头,以"//# END_ESOE_MAP"结束;
  • 2. 事件映射定义在类构造函数的$map属性上;
  • 3. 事件映射机制可以映射以静态绑定方法加载的直接位于HTMI中的DOM元素的事件,称为静态映射;
  • 4. 事件映射机制可以映射在构造函数中创建的DOM元素的事件,或在构造函数中以动态绑定方法加载的DOM元素的事件,称为动态映射;动态映射可能会降低系统的加载速度;

 

7.ESOE-IDE加载过程

如果Web应用为<body>指定了绑定的js类,那么ESOE-IDE引擎加载时实现以下过程:

  • 1. 在window.onload调用$esoe.$bind绑定<body>和指定的入口类;
  • 2. 通过分析HTML/HTMI的jclass属性,自顶(<body>)向底加载类的主资源(将主资源HTMI设置为innerHTML);
  • 3. 自底向顶(<body>)创建js类实例,将实例保存为关联DOM元素的$jbind属性;
  • 4. 创建js类实例的同时进行事件映射;

 

说明:

  • 1. 当创建一个绑定于DOM元素的js类实例时,在调用其构造函数之前,对应的DOM元素的所有子孙元素已完成了加载主资源的工作,并且所有子孙元素已完成绑定,具有相应的$jbind属性;
  • 2. 当创建一个绑定于DOM元素的js类实例时,在调用其构造函数之前,对应的DOM元素的所有祖先元素未完全加载主资源,并且没有绑定;

 

8. 类文件管理/打包输出/库文件

ESOE-IDE按以下方法对类文件进行管理和输出:

  • 1. 每个ESOE类的源代码应完整地放在单独的*.js文件中;
  • 2. js类用到的CSS文件以单独的*.css文件保存,并以附加CSS资源的方式记录在js类中;
  • 3. js类用到的外部文件,如图片等,以单独的文件保存,并以附加FILE资源的方式记录在js类中;
  • 4. 如果js类用到多个独立的HTMI资源,文件以单独的*.htmi文件保存,并以附加HTMI资源的方式记录在js类中;
  • 5. ESOE-IDE编译器对每个文件的打包方式包括:
    pack方式:将文件打包至输出文件,所有js文件打包到最终的htm或js输出文件,所有的css打包到最终的htm或css输出文件,所有的FILE资源拷贝到输出目录;
    pack_cp方式:(暂未实现)与pack方式类似,将js文件或css文件的顶部版权说明(第一个块注释)集合放置到最终的htm或js或css输出文件的顶部;
    link方式:将文件链接到输出文件,如js文件以"<script src=...>"的方式联接,css文件以"<link ...>" 的方式联接;
    default方式:见下;
  • 6. ESOE-IDE编译器支持2种编译模式:Debug模式和Release模式,可分别设置不同的输出目录;2种编译模式有以下区别:
    Debug模式:如果文件设置为default方式,则默认为link方式打包;
    Release模式:如果文件设置为default方式,则默认为pack方式打包;
  • 7. ESOE-IDE编译器支持2种输出模式:
    App输出:所有内容输出至主htm文件,此htm文件可作为一个独立的Web应用运行于浏览器;如果设置了输出lib.js文件,则所有pack方式js文件打包至lib.js文件,并在主htm文件链接;如果设置了输出lib.css文件,则所有pack方式css文件打包至lib.css文件,并在主htm文件链接;
    Lib输出:如果没有设置主htm文件,则仅输出lib.js文件和lib.css文件,与App输出类似,但没有htm作为Web应用入口,只可被其它项目引用;

 

9.ESOE-IDE对实现DOM类的建议

    本节提出一些设计方法和原则,这些方法是在ESOE-IDE建立自身的过程中总结出来并遵守的,建议用户使用。

9.1. 全局Z-index分配

       resizer: 100->110(dragging)

       popup menu: 105

       dragger: 110

       Window Manager: 1000 -> *

       _modal: 100000

 

9.2. 事件映射方法

MyMethod: function( evt, e )

{

       if(!e) e= this.FindMeFromEvent(evt);

       ...

}

说明:

  • 1. 加入第2参数e的作用是,使事件映射函数除了处理系统事件外,还可以被代码直接调用,例如 MyMethod( null, e ).
  • 2. FindMeFromEvent实现从事件对象查找主DOM元素,可以从org.supertree.dom.Base继承,或直接拷贝代码实现。

       FindMeFromEvent: function( evt )

       {

           return $esoe.$find(this,evt.srcElement?evt.srcElement:evt.target);

       }

 

9.3. 控件设计

  • 1. 控件可从org.supertree.dom.Base继承;
  • 2. 可以利用ESOE自定义事件$notify机制;

 

9.4. 窗体设计

  • 1. 窗体从org.supertree.dom.Window.Window继承;
  • 2. 窗体可以加载菜单/工具栏等;
  • 3. 窗体有可重载OnCommand()方法,用于处理菜单/工具栏命令;

 

9.5. 对话框设计

由于当前2种流行浏览器ie6/firefox对于实现对话框有诸多不一致和不必要的权限设置,ESOE-IDE自行实现异步式对话框,以解决一些设计上的不便。

  • 1. 将对话框划分为运行前和运行后2个方法进行处理;运行前方法用于打开对话框,运行后方法用于处理关闭对话框后的数据处理;
  • 2. 对话框从org.supertree.dom.Window.Dialog继承;
  • 3. 对话框是全局DOM对象,具有唯一的id属性;通常只建一次,后续调用将重新使用已建立的DOM对象;
  • 4. 对话框有可重载InitModal()方法,用于初始化对话框;
  • 5. 对话框不可重入,即不可在一个对话框打开时,打开另一个由相同js类创建的对话框;可重入对话框应另行设计;

 

由ESOE-IDE类向导生成的对话框可用以下代码打开:

$esoe.$import("MyDialog").prototype.DoGlobalModal(

       e,                   //主DOM元素对象

       "$jbind.OnMyMethod",         //回调函数名称引用字串

       p                   //参数

       );

 

对话框数据处理回调函数使用以下形式:

OnMyMethod: function(e,cmd,pOut)

{

       if(cmd=="ok")

       {

              ...

       }

}

 

说明:

  • 1. 回调函数的第1参数(e)为调用DoGlobalModal时传入的第1参数;
  • 2. 回调函数的第2参数(cmd)为对话框类向ExitModal传入的第2参数,通常为点击按钮的name属性;
  • 3. 回调函数的第2参数(pOut) 为对话框类向ExitModal传入的第3参数,为输出数据对象;数据名称通常与主资源DOM元素的name属性对应;

 

 

附录A. ESOE-IDE工具函数

name convention

       ns: name space, string type name list indicate object path.

       o: object

       obj: object, normally a function parameter.

       i: item

       oi: object item

       a: array

       ai: array item

       func: function, the constructor, class.

       cls: class

       e: dom element; or error in try/catch statement.

       ch: child

       res: resource

       h: head

       param: function parameter

       s: string

       l: length

       b: bool

$esoe.$preload

Pre-load into name space object, return class/package.

 

$esoe.$preload( ns, func [,funcDeclare] )

 

$esoe.$declare

Call declare function of the class, return the class.

 

$esoe.$declare( ns )

$esoe.$declare( func )

 

$esoe.$new

Create object, return the new object.

 

$esoe.$new( ns )

$esoe.$new( func )

 

$esoe.$derive

Prepare prototype from a base class, return the newly create prototype object. The new class should set its prototype to the return value, such as, func.prototype= $esoe.$derive("baseclass",...)

 

$esoe.$derive( ns [, oProto] )

$esoe.$derive( Array(ns1,ns2,...) [, oProto] )

 

ns: namespace string; or array of namespace string, for multiple deriving, where the 1st is the main base class.

oProto: new prototype object for new class

$esoe.$import

Import items into obj, if no object, just declare the items.

If want to import into the GLOBAL, use $import( ns, window )

 

$esoe.$import( ns [, obj ] )

$esoe.$import( func )

 

ns can be in below format:

1. if ns is like "name1.name2.*", where "*" appear only in the last name item, declare and import all the sub items to the obj, return the obj

2. if ns is like "name1.name2.cls1", declare and import 1 class to the obj, return the class

3. if ns is like "name1.name2.cls1|cls2[|cls3[...]]", where "|" appear only in the last name item, declare and import multiple classes to the obj, return the obj

4. if ns is a function, just call its _declare function and return the function

$esoe.$bind

Bind resource to dom object.

 

$esoe.$bind( ns, e [, param [,oMap] ] )

 

ns: class name

e: dom element

param: parameter to create the object

oMap: internal use

$esoe.$find

Find dom item, return the element; if not find, return null.

 

Format 1: $esoe.$find( dom_ns, e [, eFrom] )

search dom_ns under e, where e is not included in the search, from eFrom.

dom_ns: dom element name item list, separated by ".".

e: dom element

eFrom: sub item from which the search start; eFrom itself not included in the search. Default is e.

 

Format 2: $esoe.$find( o, e )

reverse search o from e to the ancestor, include e, for the $jbind===o

$esoe.$init

Call base class constructor.

 

Format 1: $esoe.$init: function( o, args )

args: constructor arguments, auto init all base class, with same parameters.

 

Format 2: $esoe.$init: function( o, args, base )

args: create new array as arguments.

base: base class constructor.

 

$esoe.$apply

Apply base class function, as Function.apply do..

 

$esoe.$apply ( path, o, args )

 

path: class-method path string, in bellow format,

              "FullThisClass:baseclass1[:baseclass2[:...]]:method"

o: this

args: parameters array

$esoe.$

Search 1 direct next item, default is child..

 

$esoe.$( s [,e] )

 

e: element to serch from

 

s format:

 

#xxx: element id, e is omitted

<xxx>: tag name

.xxx: class name

other: name attribute

 

prefix/axis (not support '#'):

:c: child/default

:a: ancestor

:n: next sibling

:p: previous sibling

:d: descendent

$esoe.$$

Like $esoe.$(), support filter.

 

$esoe.$$( s [,e] )

 

filter splitter: '|'

$esoe.$notify

Raise esoe notify event. ESOE support mapping self-defined notify event named "$notify". "$notify" can occur in dom or non-dom object, by calling $esoe.$notify(); and automatically be mapped by dom object, by mapping a "$notify" event.

 

$esoe.$notify ( o, cmd, p )

 

o: esoe class instance/object, in which the notify event occur, normally transfer a 'this'. It will contain a reserved var "$notify_index" used by esoe, don't touch it.

cmd: notify event string

p: param, will contain {oThis[,e,ei,data,...]},

       oThis: the callback oThis

       self-defined: e: the dom element, ei: the sub dom element,data:self-defined data

 

附录B. 资源定义格式

主资源格式

function.$res= [ sTag, type, sData ]

 

sTag: tag name for the class itself, only used by IDE, or dynamically create instance in javascript; usually not to be used, and a default "" equals "DIV".

 

type: type of the sData, 0- text, 1- res id, 2- replace text, 3- replace text res id

 

sData:     if type=0, it's res data text;

              if type=1, it's an res id;

              if type=2, it's res text, with which to replace the "$ESOE_INNERHTML" section in it's base class res;

              if type=3, it's an res id, with which to replace the "$ESOE_INNERHTML" section in it's base class res.

              all type 2 and 3 class res will be normalized to type 0 at runtime

附加资源格式

//#HTMI: unique_id, file_path

//#CSS: id, file_path

//#FILE: id, file_path

 

id: id for the resource

unique_id: for HTMI, its id must be unique in whole system; duplicated id may cause error.

file_path: external file path.

 

附录C. 事件映射格式

function.$map=  [ mi1, mi2, ... ];

 

mi: map item

mi= [ "dom_ns", "event_name", "method_name", "bDynamic" ];

 

dom_ns: dom element "name" attribute list, items are separated by ".". "" means the e itself; or directly a dom object.

 

event_name: event name without "on" prefix, such as "click"; or esoe self-defined notify event "$notify".

 

method_name: class method name, the event method is like: function(evt){...}.

 

bDynamic: dynamic mapping, optional, can be "1"( must be string); if fail to find static element, $esoe.$bind will using $esoe.$find() to search the dynamic element, which may slow down the binding process.

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值