为 Web Page Editor 定制控件

Web Page Editor本身就自带了HTML和JSP的两大组控件,但是这些控件功能太简单了,你拖一个div控件出来,也就生成一个<div></div>,拖一个a控件出来,就生成一个<a></a>。有那拖的功夫,还不如自己拿键盘敲呢。比起Dreamweaver和Myeclipse的控件来说,差了不知道几个数量级。

想要定制控件,先得看看Palette(就是控件面版)上的每一项是怎么新建出来的。HTML和JSP控件最终都利用了以下代码在Palette中新建条目。

	private TagToolPaletteEntry internalCreateTagEntry(final TaglibPaletteDrawer category,
			final String id, final String tagName,
			final String label, String desc, final ImageDescriptor smallIcon,
			final ImageDescriptor largeIcon, final boolean expert) {
		final ITagDropSourceData data = new TagToolCreationAdapter(category
				.getURI(), tagName, category.getDefaultPrefix(), id);
		final TagToolPaletteEntry item = new TagToolPaletteEntry(data, label,
				desc, smallIcon, largeIcon);
		item.setId(id);
		item.setVisible(!expert);
		category.getChildren().add(item);
		item.setParent(category);
		return item;
	}

ITagDropSourceData是数据层的代表,一般被实例化为TagToolCreationAdapter,其中包含了组名,标签名,前缀名和ID号。
TagToolPaletteEntry是呈现层的代表,它规定了条目在Palette中的显示方式,包括了一个对ITagDropSourceData的引用,标签,简短介绍,图标。
ITagDropSourceData中包含的内容有限,如有必要,我们完全可以在里面附带任何我们想要的数据。
想要在Palette添加自己的条目,可以从PaletteItemManager::initTagRegistry()看起。
然而,当我们拖动一个Palette项到Editor中时,又是如何根据Palette项来决定生成什么样子的HTML语句呢?抛却前戏,我们直接来到语句生成的核心部分:

 public Element createTag(final CreationData creationData)
    {
        final ITagCreationAdvisor  advisor = selectCreationAdvisor(creationData);
        // adjust the creation position to accommodate required containers
        final IDOMPosition position =
            advisor.checkAndApplyNecessaryContainers(creationData.getModel(), creationData have a peek at these guys.getDomPosition());

        if (position == null) return null;//throw exception?

        creationData.setAdjustedPosition(position);

        // create the element
        final Element ele =  createElement(creationData);

        if (ele == null) return null;//throw exception?

        // apply tag customization
        advisor.applyCustomization(creationData.getModel(), ele);

        // ensure that any attributes required by the tag's definition
        // is initialized.
        // TODO: a drawback of this approach is that it leaves the tag in
        // a state where there are no error flags to tell the user something is
        // missing, but may initialize the tag with an (empty) invalid value
        // ensureRequiredAttrs(ele, creationData);
        addTagToContainer(position, ele);

        return ele;
    }

以上代码位于AbstractTagCreator::createTag(),其大致流程为:

  • 选择CreationAdvisor(后面会讲这个东西是干吗的),
  • 找出插入点
  • 创建Element(即GEF的MVC结构中M那一层的元素,一般是ElementImplForJSP)
  • 为新创建的Element执行自定义操作
  • 将Element插入到插入点中

createTag函数的入参为CreationData,它包含了插入点位置和一个TagDropSourceData。这个Data实际上就是最初我们创建Palette条目时的那个ITagDropSourceData。

CreationAdvisor是专门用来给Element进行自定义改造的。原始的代码中只是存在这个机制,但是其Advisor始终是个默认的,什么都不做。我们想要对元素进行附加操作,只需要写个自己的Advisor类(继承自DefaultTagCreationAdvisor),改写其中的applyCustomization函数,然后改写selectCreationAdvisor的机制,让它在特定的情况下(比如,针对特定的TagName或Prefix),选择我们这个改写的Advisor即可。
说到具体如何对元素级内容进行操作,这里可以给两个例子。

//给当前新建的Element添加子元素:
Element img = model.getDocument().createElement(“img”);
ele.appendChild(img)
//给当前的Element元素添加属性
ele.setAttribute("src","somewhere")

以上内容都是泛泛而谈,省略了不少内容,如能对人有所帮助,就幸甚了。

13 Responses

  1. 朋友,我最近也对wtp中的web page editor很感兴趣,看了你的文章很受启发,本人一直在困恼怎么在web page editor 中创建自己的控件,希望你能帮到我,谢谢。
    我的邮箱是xiexjbailx@yahoo.com.cn,联系不上您,看到我的消息请于我联系,谢谢!

  2. 朋友,我最近也在对wtp中的web page editor进行扩展,我属于入门级别的,一直在困恼怎么在web page editor 中创建自己的控件,看了你说的还是不太懂。
    希望我的邮箱是loveluqingsong@163.com,联系不上您,看到我的消息请于我联系,谢谢!

  3. Element img = model.getDocument().createElement(“img”);
    这个可以创建一个HTML节点,但是要是想创建一个空格: 这个样的特殊字符该怎么办呢?
    谢谢帮忙!

    1. Element div = model.getDocument().createElement(“div”);
      IDOMNode text = (IDOMNode) model.getDocument().createTextNode(“”);
      text.setSource(“1&nbsp&nbsp2″);
      div.appendChild(text);

      这样就OK了

      1. Element img = model.getDocument().createElement(“img”);//这个model是怎么来的啊
        我也在扩展控件,没有搞定呢,能给个例子吗?522750742@qq.com,谢谢

  4. 朋友您好:
    看了您的文档很有收获。
    我现在能够实现定制自己的控件,关于拖动控件生成HTML代码想进行比较大的改造,比如想生成一些注释代码之类。

    试过了你给的示例:

    //给当前新建的Element添加子元素:
    Element img = model.getDocument().createElement(“img”);
    ele.appendChild(img)
    //给当前的Element元素添加属性
    ele.setAttribute(“src”,”somewhere”)

    跟了下代码,发现没有什么大的突破。

    请问能指点一下吗?

    QQ:1278833522
    邮箱:1278833522@qq.com
    谢谢!!

  5. 朋友您好:
    不好意思,我重新阅读了几遍您的文档和回复,自己解决了,真是太惭愧了。

    不过,请问有没有关于web page editor 的相关文档可以推荐下没,如果没有类似您提供的这些文档恐怕花再多的精力也不一定能顺利搞出来。

    谢谢朋友!!

    1. 很高兴能对别人有所帮助,网上这方面的相关文档确实非常少(几乎没有)。我这里有一份sybase公司很久之前做的Page Designer Design Spec,可能还有点用,发你邮箱了

  6. 你好,刚开始接触wtp,想扩展web page editor的控件,看了你的文章还是不清楚怎么实现,请问能再指点下,将相关的资料或者代码发给我看看么?

发表评论

电子邮件地址不会被公开。 必填项已用*标注