Emditor 宏之菜单应用

        在常用的编辑器里面,我最常用的就是Emditor,它吸引我的就是它的宏,而且支持两种vbscript和javascript,我比较喜欢javascript的方式来使用它的宏

       由于在使用Emditor的过程中,时常为了提高工作效率,积累了不少Emditor的宏,放入工具栏太多宏,有时候都快找不出来了,经过一番研究,决定在它的宏菜单基础上面,按文件-功能类别,一个jsee文件对应一个工具集,工具集下面和有多个子菜单,这样不至于jsee太多而导致工具栏拥挤

如果你想把本文的内容用到Emditor,请先了解如下知识

  1. javascript基础知识
  2. Emditor 宏api,
  3. Emditor编辑器

 1.以前

一个jsee文件,仅仅包含一个宏,当点击工具栏上对应的jsee名称,则执行jsee中的宏

2.现在

一个jsee文件包含多个宏,这些宏通过菜单的形式提供给使用者使用

3.为了实现上述目标,献给jsee文件定一个规范

1)菜单管理器

2)菜单

3)工具

一个菜单对象对应一个工具

一个菜单有多个菜单项

每个菜单项对应工具中的一个方法

 一个jsee文件仅包含一个菜单管理,包含多个菜单,但是都是注册到菜单管理器统一管理

菜单管理器(不显示)

   菜单(显示)

              菜单项 (显示)

              菜单项 (显示)

              菜单项 (显示)

   菜单(显示)

              菜单项 (显示)

              菜单项 (显示)

   菜单(显示)

最终效果图(点击工具栏上的宏后)

  

Emditor中PopupMenu Object API

CreatePopupMenu : 创建弹出菜单,全局函数

AddPopup:添加子菜单

Add:添加菜单项

Track:显示菜单

第一步,实现如下几项

1)菜单基类

在具体的jsee里面,菜单只需要继承这个基类,加入菜单项,挂接点击菜单后的执行函数就行了

 2)菜单管理器(基类)

在具体的jsee里面,可以继承这个管理器,注册多个菜单,并在用户点击宏时候,显示

 下面我们开始实现着两个基类,用到了javascript的一些继承知识

 下面的Object代码不懂的可参看

http://www.cnblogs.com/5201314/archive/2009/05/22/1487213.html

感谢原作者

---------Object

 1 Object.extend = function(destination, source) {
 2   for (property in source) {
 3      destination[property] = source[property];
 4   }
 5   return destination;
 6 }
 7 
 8 Object.prototype.extend = function(object) {
 9   return Object.extend.apply(this, [this, object]);
10 }

--------------- GObject

 1 ////////////////////////////////////////////////////////////////
 2 //这个类就是Menu的基类,其实也是MenuManager的基类
 3 //后面可以看到为啥都用这个当基类
 4 ////////////////////////////////////////////////////////////////
 5 function GObject()
 6 {
 7 }
 8 
 9 GObject.prototype={
10        ShowAsSub:true,
11        Number:0,
12        Menu:null,
13        Name:"GObject",
14        DoCommand:function(n) {     },
15        AddM:function()    {     },
16        AddMenu:function(mmMenu)       {
17               if(this.ShowAsSub)
18                      this.Menu=CreatePopupMenu();
19               else
20                      this.Menu=mmMenu;
21               this.AddM();
22               if(this.ShowAsSub){
23                      mmMenu.AddPopup(this.Name,this.Menu);
24                      this.Menu=mmMenu;
25               }else
26                      this.Menu.Add( "", 0, eeMenuSeparator );
27        }
28 }

属性

参数名

默认值

ShowAsSub

True

是否显示为菜单子项目,后代需要自己设置 

Number

0

菜单项id映射用到数字初始值,每个jsee的菜单此数值都需要不一样,最好相隔100以上,防止菜单项彼此混淆

在菜单管理器中,已经设置,所以子类不需要设置

Menu

Null

菜单,后代添加菜单项需要用到

Name

GObject

名称,必须设置

方法

方法名

参数

DoCommand

n

点击菜单项后, 菜单子类用来执行对应命令,菜单子类必须实现

AddM

子类添加菜单项,菜单子类必须实现

AddMenu

菜单管理器注册菜单用到

注意:此类不需要直接使用,而是菜单和菜单管理器继承用到

 --------------- LibraryBase

这个类就是MenuManager,我们改名字

////////////////////////////////////////////////////////////
//version 0.2
///////////////////////////////////////////////////////////

function LibraryBase(){
}

LibraryBase.prototype=(new GObject()).extend({
       AddM:function()    {
              for(var i=0;i<this.keys.length;i++)
              {
                     var obj=this._(this.keys[i]).AddMenu(this.Menu);
              }
       },
       DoCommand:function(n){
              if (n<=0) return;
              for(var i=0;i<this.keys.length;i++)
              {
                     this._(this.keys[i]).DoCommand(n);
              }
       },
       Show:function()     {
              this.RegisterObject();
              this.Menu=CreatePopupMenu();
              this.AddM();
              //catch selected item
              var n=this.Menu.Track();
              //do action
              this.DoCommand(n);
       },

       RegisterObject:function(){       },

       dict:null,
       keys:new Array,
       RegisterObjects:function(objs){
              for(var i=0;i<objs.length;i++)
                     this.Register(objs[i]);
       },
       Register:function(obj)
       {
              if (!(obj instanceof GObject)) return;
              if(this.dict==null)
                     this.dict=new ActiveXObject("Scripting.Dictionary");
              if (!this.dict.Exists(obj.Name))
              {
                     obj.Number=this.dict.Count*100;
                     this.dict.Add(obj.Name,obj );
                     this.keys.push(obj.Name);
              }
       },
       _:function(strKey)
       {
              return this.dict.Exists(strKey)?(this.dict.Item(strKey)):new GObject();
       }
});

 

属性

参数名

默认值

keys

0

注册菜单的名称缓存

dict

Null

菜单注册后,存贮菜单

方法

方法名

参数

RegisterObject

后代以继承的方式,注册多个菜单,推荐使用

Register

obj

注册单个菜单

RegisterObjects

objs

注册多个菜单,

Show

显示菜单

_

strKey

返回strKey对应菜单,没有就创建一个假的

注意:此类可直接使用,推荐继承使用

 将上述三个类保存到一个Menu.jsee文件里面,

文件内容如下:

#title = "菜单基类"

#tooltip = "所有菜单和菜单管理器的基类,必须从它继承"

Object….. //将上述Object拷贝到此处

GObject….. //将上述GObject拷贝到此处

LibraryBase…. //将上述LibraryBase拷贝到此处

第二步,下面开始通过实例使用上述两个类

新建一个文件test.jsee

//////////---------------------test.jsee开始

#title = "测试"
#tooltip = "用来测试菜单基类"
#include "Menu.jsee"

//定义两个工具类,随便写
var Converter={
       Reserve:function(S)       {
              //return S.split("").reverse().join("");
              var tmp="";

              for(i=0;i<S.length;i++){
                     tmp=S.charAt(i)+tmp;
              }
              return tmp
       }
}

var Tool={
       Padding:function(S,C){
              while (S.length<C)        S="0"+S;
              return S;
       }
}

//定义一个menu, CommentMenu
function CommentMenu ()
{
}

CommentMenu.prototype=(new GObject()).extend({
       //注意设置为true,则显示为一级菜单项,不设置则为子菜单项
       ShowAsSub:false,
       //其实这里不用设置,看看管理器就知道它内部已经设置了
       Number:400,
       //必须设置,且本文件内部菜单类必须唯一
       Name:"Comment",

       AddM:function()    {
              //添加多个菜单项目,可以添加子项目,可以用数组定义,快速
              this.Menu.Add("倒序字符串",this.Number+1);
              this.Menu.Add( "", 0, eeMenuSeparator );
              this.Menu.Add("填充",this.Number+2);
       },

       DoCommand:function(n)       {
              switch(n-this.Number)
              {
                     case 1: alert(Converter. Reserve(‘1234567890’));
                    break;
                     case 2: alert(Tool. Padding(‘7’,8));
                    break;
              }
       }
});


//定义一个menu, DocMenu
function DocX()
{
 }

 

DocX.prototype=(new GObject()).extend({
       Number:200,
       Name:"Doc",
       MenuNames:["名称(没有扩展)","名称(有扩展)","当前目录","后缀名"],
       AddM:function()    {
              //使用数组方式增加菜单项
               for(var i=1;i<this.MenuNames.length+1;i++)
              this.Menu.Add(this.MenuNames[i],this.Number+i);
       },
       DoCommand:function(n)       {
              switch(n-this.Number)
              {
                  case 1:
                         //其它工具类的方法
                         break;
                  case 2:
                         其它工具类的方法
                         break;
              }
       }
});

 //注册上述两个菜单
/////////////////////////
function Library(){
}

//让Library继承于LibraryBase并注册需要在菜单上显示的对象

Library.prototype=(new LibraryBase()).extend({
       RegisterObject:function(){
              /*method 1
              //    this.Register(new ToolX);
              //    this.Register(new Comment);
              */
              //method 2
              this.RegisterObjects([new DocX,new CommentMenu]);
       }
});

///最后使用
var lib=new Library();
lib.Show();

//////////---------------------test.jsee结束

注意:

#title = "测试"

表示这个jsee在工具栏显示的名称

#tooltip = "用来测试菜单基类"

提示信息

#include "Menu.jsee"

//引用到Menu.jsee中的基类,必须加上此句,且这两个jsee的路径要正确

/////////上述菜单管理器中的DoCommand和菜单中DoCommand可以优化速度

原文地址:https://www.cnblogs.com/simfe/p/2551423.html