十二月 1st, 2009

JAse开发点记

2 Comments, JAse, as、flex, by army8735.

JAse开源项目缓慢进展中,许多地方和许多算法不断地颠覆、重写,这也是预料当中的。目前来说总体架构是不会变的了:以一个swf文件为基础提供文本框和一些菜单栏的基本功能;语法分析插件以不同语法分发为各自的swf文件,用到的时候才去读取。

当然,所有的语法文件都是面向接口编程的(实现IParser接口即可,这个理念继承自jssc5),这也使得按需加载成为可能。废话不说,来看几张预览图。

开始的选择画面:

jase1

第一个被我“强奸”的是js(最熟么),其它的会陆续添上。我默认放了一段Mootools的代码:

jase2

拉一拉滚动条,性能还不错,就是有不少bug还没修正:

jase3

至于语法编辑器用到的破损、修复、高亮模型,我非常感谢http://www.cppblog.com/megax/archive/2008/07/09/55753.html这篇文章给予的提示,同时也感谢其作者和我互通邮件的帮助。不过Megax所采用的依然是分区正则法,并非DFA状态图分析。而C++的性能远非as3所能匹敌,所以JAse目前仅能做到千行级代码,上万行后就会感觉到卡。

as3的性能瓶颈其实并不是主因,主因是textfield的性能太弱。实际测试中只是在第一次装载大量文本(万行)会卡,在拖动分析的过程中却非常流畅。今天我装了CS4(以前一直用CS3),启用了GPU硬件加速来提高渲染textformat的速度,所以如果不计textfield的拖后腿的话,预计是能达到十万行的量的。如果分析状态的数据结构由数组换成Vector(类似Java的泛型ArrayList,基于性能考虑我决定JAse将基于Flash Player 10),那么百万行级也不是不可能。

所以在JAse基本完成后,如果自定义优化textfield的性能,则是重点。目前思路有点苗头,是否能实现就难说了。另外Text Layout Framework中并未包含什么高效的input组件,本来还想瞅瞅,结果失望而归。

十一月 25th, 2009

为TextField添加上tab缩进功能

5 Comments, JAse, as、flex, by army8735.

今天尝试为JAse的代码输入框添加tab缩进功能,华丽地失败了。仔细查阅下手册:

指定此对象是否遵循 Tab 键顺序。 如果该对象遵循 Tab 键顺序,值为 true;否则值为 false。 默认情况下,值为 false,但以下情况除外:

  • 对于 SimpleButton 对象,值为 true。
  • 对于具有 type = “input” 的 TextField 对象,值为 true。
  • 对于具有 buttonMode = true 的 Sprite 对象或 MovieClip 对象,值为 true。

原来如此,侦听TextField的按键事件,根本就判断不到是否是tab键,因为默认系统就屏蔽了。这样就无法改写默认响应方法,tab键变成了在按钮之间切换选择状态。

得儿,得罪不起你,去请你的上司吧。直接侦听stage的按键事件,改写其默认行为搞定。唯一有点不友好的地方是聚焦会先出现在按钮上,然后由改写的行为迅速回到输入框上并进行缩进。没办法,也只好这样了。

//全局侦听tag键,改变默认行为
addEventListener(Event.ADDED_TO_STAGE, function() {
	stage.addEventListener(KeyboardEvent.KEY_DOWN, function(event:KeyboardEvent):void {
		if (stage.focus == tf && event.keyCode == Keyboard.TAB) {
			saveInput();
			getSelection();
			//如果鼠标为选择区域,则先保存删除命令链
			if (left != right) {
				saveDelete();
			}
			//增加2个全角空格,增加输入命令链
			commandList.addCommand(new InputCommand(tf, tf.caretIndex, "\u3000\u3000"));
			tf.replaceSelectedText("\u3000\u3000");
			setIndex();
			focus();
		}
	});
	stage.addEventListener(KeyboardEvent.KEY_UP, function(event:KeyboardEvent):void {
		if (event.keyCode == Keyboard.TAB) {
			focus();
		}
	});
});

十一月 24th, 2009

说说最近在开发的JAse语法编辑器

No Comments, JAse, by army8735.

最近时间比较少,年底之前公布JAse预览版的可能性看来不高了,那就拖到农历年底之前吧,XD~

主要想说的是JAse进展得益于JAte的经验非常多,若不是之前有过长时间的尝试经验(尽管JAte作为实验品失败了),JAse不可能一帆风顺地进行过来。曾经读到一篇文章——《趁年轻,赶紧去做该做的傻事》,里面德鲁克的话让我感受颇深:

“我绝对不会把从未犯错的人升到高层领导岗位上,因为没有犯过大错的人必然是平庸之辈。更糟糕的是,没有犯过错的人将不会学到如何及早找出错误,并且改正错误。在工作中,如果一个同事谈论他的成功,我只会谨慎的倾听,小心的吸取;但如果一个人介绍过去的失误,我一定会竖起耳朵,绝不放过,因为这样的人往往经验丰富,思考全面,在失误基础上的成功也是最迷人的成功。(所以,在简历中,我们是否应该写上自己曾经做过哪些傻事?)”

JAse就是如此,若没有jssc的5版开发经历、没有JAte的研究结果,它就不会出现在我的手中了。至于JAte,最主要的失败原因是对flash对文本支持的不了解,flash对文本的支持实在有限,而图文混排更是可怜。我想得等as4时代来临,flash对富文本的支持才会好些吧。不过我倒是和KindEditor的作者Roddy经常聊天,也一直在催他(现在又要催了!哈哈!)把KE可视化原理写出来!或许以后JAte会变成基于KE(LGPL)用as制作toolbar,iframe做content的样式。

附上缓慢进展的JAse预览图一张,可以看到ui方面受以前影响颇多:

jase

PS:JAte的图标取自于Open Office,JAse的图标取自于Flash Develop

十一月 18th, 2009

《Project Darkstar》中文文档

No Comments, 翻译, by army8735.

和我同住的某人开始把翻译好的《Project Darkstar》中文文档上传至Blog了,在这里宣传转一下。

地址:http://www.david0446.com/?p=6

十一月 16th, 2009

动态加载css和js资源

No Comments, 前端开发, by army8735.

近日,在秦歌的blog中看到动态加载的内容,主要是说YUI3.0在动态加载js的一点小bug。当时想了个问题:如何侦听动态加载的内容被成功加载了,翻阅一番后记录下来。

Omar AL Zabir曾在他的Ensure library库中写过类似的东西,用以动态加载css和js文件。加载js时,基本伪代码是这样:

var script = document.createElement("script");
script.onreadystatechange = function() {
	//
}
script.onload = function () {
	//
}
script.setAttribute("src", "xxx.js");
document.head.appendChild(script);

原理就是创建一个script标签,设置src属性后附加到head区域。ie中侦听onreadystatechange,其它的侦听onload。不过有些较古老的浏览器对这两种方法都不支持(Omar举例为Safari 2),解决的办法是通过xhr加载js文件资源,再eval()出来。目前来看,似乎已没必要花费经历去为了旧版本兼容了。

凑巧,前几日Mootools官网也发布了一个延迟独立加载js的库Depender,它被包括在More中(貌似1.2.4.1还有些性能问题,我希望最终它能够被包含在Core中)。看看其核心实现:

new Element('script', {
	src: scriptPath + (this.options.noCache ? '?noCache=' + new Date().getTime() : ''),
	events: {
		load: loaded,
		readystatechange: function(){
			if (['loaded', 'complete'].contains(this.readyState)) loaded();
		},
		error: error
	}
}).inject(this.options.target || document.head);

亦是一样。不过在我测试过程中,ie的readystate的值在加载完成后都是loaded(ie6、7、8),并没有出现complete的情况,不知道mt为何要多判别它。

另外关于css动态加载,似乎并没有可行的侦听的方法。虽然ie中侦听onreadystatechange的值为complete,但是firefox 3.5和chrome里却侦听不到onload事件。不过一般情况下,样式的加载都是异步的,同步的需求很少。除非考虑到某个地方必须等样式加载成功后才去执行显示,否则没必要使用同步。

我能想到的解决办法就是通过xhr读取css文件内容,然后插入到style标签中来实现同步读取,不知道可不可行。