├── .gitignore
├── LICENSE
├── README.md
├── about.html
├── application.xml
├── bg2css.html
├── css
└── sample.css
├── default.png
├── divlist.html
├── help.html
├── help
├── 001.png
├── 003.gif
├── 004.gif
├── 005.gif
├── 02.png
└── r.png
├── icons
├── AIRApp_128.png
├── AIRApp_16.png
├── AIRApp_32.png
├── AIRApp_48.png
└── b.gif
└── lib
├── air
├── AIRAliases.js
├── applicationupdater_ui.swf
└── library.swf
├── js
├── AIRLocalizer.js
├── AIRMenuBuilder.js
├── divlist.js
└── main.js
└── menus
├── menu.js
└── menu2.js
/.gitignore:
--------------------------------------------------------------------------------
1 | bg2css.air
2 | bg2css_reverse_finally.icns
3 | bg2css.sublime-workspace
4 | bg2css.sublime-project
5 | .vscode
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 GhostZhang
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # bg2css
2 |
3 | CSS Sprites 样式生成工具
4 |
5 | ## 使用说明
6 |
7 | 1. 运行软件
8 | 2. 将要处理的图片拖入界面或 \command+o\
9 | 3. 双击图片上的任意位置,会得到一个蓝色的区域,区域可移动位置,按住右下角可改变区域的大小
10 |
11 | ## 安装说明
12 |
13 | 1. 先安装[Adobe Air](https://airsdk.harman.com/runtime)运行环境
14 | 2. 下载安装最新版的[bg2css.air](https://github.com/ghostzhang/bg2css/releases)
15 |
16 | ## 版本信息
17 |
18 | bg2css v3.2.3 2020-12-22
19 |
20 | - (fix)帮助文档地址迁移到 github
21 | - (fix)版本更新改为手动
22 | - (fix)样式问题
23 | - (add)默认界面
24 | - (add)更新快捷键说明文档
25 |
26 | bg2css v3.2.2 2019-2-17
27 |
28 | - (fix)更新证书,请重新安装
29 |
30 | bg2css v3.2.1 2010-2-8
31 |
32 | - (add)复制当前大小
33 | - (add)复制提示优化
34 | - (add)从样式表导入
35 | - (add)多语言支持
36 |
37 | bg2css v3.2 2010-2-3
38 |
39 | - (fix)拖动全选
40 | - (fix)使用快捷键修改位置和大小时无边界判定
41 | - (add)修改层配色
42 | - (add)优化改变位置的快捷键
43 | - (add)优化改变大小的快捷键
44 | - (add)优化图片缩放的快捷键
45 | - (add)更新当前图片
46 |
47 | bg2css v3.1.2 2009-11-30
48 |
49 | - (add)“复制当前位置”
50 | - (fix)“操作区”位置挡到滚动条
51 | - (fix)复制坐标时没有“-”号
52 |
53 | bg2css v3.1.1 2009-8-1
54 |
55 | - (add)‘选中层时显示“当前层信息”’为默认选中
56 | - (fix)当前层激活状态不正确
57 |
58 | bg2css v3.1 2009-8-1
59 |
60 | - (fix)样式输出格式不统一
61 | - (fix)当图片太小是层大小判定错误
62 | - (fix)读取有边距的记录时层位置出错
63 |
64 | bg2css v3.0 2009-6-16
65 |
66 | - (add)单独定义层的输出设置
67 | - (add)当前信息层显示设置
68 | - (add)更新所有层信息窗
69 | - (fix)新建层时不激活
70 | - (fix)读取设置后图片不能缩放
71 | - (fix)操作界面布局
72 |
73 | bg2css v2.3 2009-6-2
74 |
75 | - (add)图片缩放增加快捷键
76 | - (add)新的程序图标
77 | - (fix)当前信息层会被层挡住
78 |
79 | bg2css v2.2 2009-5-27
80 |
81 | - (add)优化操作界面,操作区扩展到整个窗口
82 | - (add)程序菜单
83 | - (add)右键菜单
84 | - (fix)数字输入框内容不容易选中
85 |
86 | bg2css v2.1 2009-5-20
87 |
88 | - (add)窗口改变时保持当前层在窗口中
89 | - (fix)移动当前层信息框时当前层变灰
90 | - (fix)放大后载入新图层没有初始化
91 |
92 | bg2css v2.0 2009-5-12
93 |
94 | - (add)优化操作界面
95 | - (add)放大时定位到当前层位置
96 | - (add)图片放大不消锯齿
97 | - (add)图片放大 6 倍(用于原图过小的情况,大图片慎用)
98 | - (fix)图片放大后添加层再缩小信息出错
99 |
100 | bg2css v1.9.5 2009-5-2
101 |
102 | - (fix)保存时文件不能替换
103 |
104 | bg2css v1.9.4 2009-5-2
105 |
106 | - (add)自定义保存路径
107 | - (add)单独复制宽、高、X 坐标、Y 坐标
108 | - (add)复制当前样式时类名可选择
109 | - (fix)修改默认层大小
110 | - (fix)拖入文件时检查类型
111 | - (fix)"关于"里的链接在浏览器窗口打开
112 |
113 | bg2css v1.9.3 2009-4-14
114 |
115 | - (add)文件保存时覆盖提示
116 | - (fix)修改图片拖动响应区域
117 |
118 | bg2css v1.9.2 2009-4-13
119 |
120 | - (add)图片背景色可改
121 | - (add)快捷键删除层
122 | - (add)拖动更改图片
123 |
124 | bg2css v1.9.1 2009-4-12
125 |
126 | - (fix)支持中文路径
127 |
128 | bg2css v1.9.0 2009-4-12
129 |
130 | - (add)复制当前层
131 | - (fix)读取设置后再保存出错
132 | - (fix)修改了部分界面
133 |
134 | bg2css v1.8.2 2009-4-10
135 |
136 | - (add)公共样式部分可编辑
137 | - (fix)修改了部分界面
138 | 保存的设置文件增加一个项,请在之前保存的 xml 里的“imginfo”节点下手动增加一个“gbstyle”节点,值为“”.
139 |
140 | bg2css v1.8.1 2009-4-9
141 |
142 | - (add)一定范围的负边界
143 | - (add)复制选中层的样式
144 | - (fix)输出 0 时的显示
145 | 保存的设置文件增加一个项,请在之前保存的 xml 里的“imginfo”节点下手动增加一个“margin”节点,值为“0”.
146 |
147 | bg2css v1.8.0 2009-4-7
148 |
149 | - (add)复制样式
150 | - (add)层列表,以方便管理
151 |
152 | bg2css v1.7.0 2009-4-1
153 |
154 | - (add)保存层位置信息
155 |
156 | bg2css v1.6.0 2009-3-27
157 |
158 | - (add)边界验证
159 | - (fix)修改类名后放大失效
160 |
161 | bg2css v1.5.1 2009-3-26
162 |
163 | - (add)图片放大培数可改
164 |
165 | bg2css v1.5.0 2009-3-25
166 |
167 | - (add)图片放大预览
168 | - (fix)空值无验证
169 |
170 | bg2css v1.4.1 2009-3-21
171 |
172 | - (add)支持快捷键
173 | - (add)在线更新
174 | - (fix)添加层时有 bug:双负数
175 | - (fix)窗口滚动影响微调
176 | - (fix)值为 0 时输出为"-0px"
177 |
178 | bg2css v1.3 2009-3-20
179 |
180 | - (add)输出样式时可选是否输出宽高
181 | - (fix)生成样式时最后一个类删除后生成有问题
182 | - (fix)样式路径自定义
183 |
184 | bg2css v1.2 2009-3-19
185 |
186 | - (add)双击添加层
187 | - (add)层位置和大小微调
188 |
189 | bg2css v1.0 2009-3-17
190 |
191 | - (add)添加、删除层
192 | - (add)拖动层、修改层大小
193 | - (add)显示层相关信息
194 | - (add)生成样式
195 | - (add)当前层样式
196 |
197 | bg2css v1.1 2009-3-18
198 |
199 | - (add)修改类名
200 | - (add)修改层位置、大小
201 | - (add)重置层
202 | - (add)保存成样式文件
203 |
--------------------------------------------------------------------------------
/about.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 关于 CSS Sprites 样式生成工具
7 |
14 |
15 |
20 |
21 |
22 |
23 | CSS Sprites 样式生成工具
24 | 简介
25 | 程序名称:CSS Sprites 样式生成工具(bg2css)
26 | 主要功能:方便使用CSS Sprites时对图片生成样式
27 | © 2009 by GhostZhang
28 | 官方地址:https://www.cssforest.org/2019/02/17/CSS-Sprites-样式生成工具.html
30 |
31 | 帮助文档:https://github.com/ghostzhang/bg2css/wiki/bg2css-help
33 |
34 | 版本信息
35 |
36 | bg2css v3.2.3 2020-12-22
37 | (fix)帮助文档地址迁移到 github
38 | (fix)版本更新改为手动
39 | (fix)样式问题
40 | (add)默认界面
41 | (add)更新快捷键说明文档
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/application.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
15 |
16 |
17 | com.adobe.example.bg2css
18 |
19 |
20 | bg2css
21 |
22 |
23 | CSS Sprites 样式生成工具 v3.2.3
24 |
25 |
26 | 3.2.3
27 |
28 |
29 | CSS Sprites 样式生成工具
30 |
31 |
32 | GhostZhang
33 |
34 |
35 |
36 |
37 | bg2css.html
38 |
39 |
40 | CSS Sprites 样式生成工具 v3.2.3
41 |
42 |
43 | standard
44 |
45 |
46 | false
47 |
48 |
49 | true
50 |
51 |
52 | true
53 |
54 |
55 | true
56 |
57 |
58 | true
59 |
60 |
61 | 800
62 |
63 |
64 | 600
65 |
66 |
67 | 200
68 |
69 |
70 | 50
71 |
72 |
73 | 785 500
74 |
75 |
76 | 1280 1024
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
87 |
88 | icons/AIRApp_16.png
89 | icons/AIRApp_32.png
90 | icons/AIRApp_48.png
91 | icons/AIRApp_128.png
92 |
93 |
94 |
97 |
98 |
99 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
122 |
123 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/bg2css.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | CSS Sprites 样式生成工具 v3.2.3
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |

18 |
19 |
20 |
21 |
23 |
图片缩放:
24 |
25 |
26 |
27 |
28 | | 更换背景色:
29 |
30 |
31 |
32 | |
33 | 边界留白:
34 |
36 | px
37 |
38 |
39 |
40 |
41 |
42 |
114 |
115 |
116 |
143 |
144 |
145 |
151 |
152 | 45
153 |
154 |
155 |
--------------------------------------------------------------------------------
/css/sample.css:
--------------------------------------------------------------------------------
1 | @charset "utf-8";
2 |
3 | body{overflow:hidden;padding:6px;font-family:Arial,Helvetica,Tahoma,sans-serif;font-size:14px }
4 | li{margin-bottom:14px }
5 | input{font-size:12px;margin-top:10px;font-weight:bold;}
6 | fieldset{clear:both;margin-top:10px;padding-top:10px;border-left-style:none;border-right-style:none;border-bottom-style:none;border-top:2px solid #9eb1aa;}
7 | .hint{color:#FF0000;text-indent:15px;}
8 | #div_image_view{position:relative;height:99.5%;padding:0;overflow:auto;border:1px solid #000000;background-color:#555555;font-size:0;line-height:0;}
9 | #image_view{height:474px;}
10 | .div-drag{width:100%;height:100%;cursor:move;}
11 | .div-resize{width:8px;height:8px;background-color:#BF7F26;position:absolute;bottom:0;right:0;cursor:se-resize;}
12 | .div-dnr,.div-dnr-now{position:absolute;background-color:#BF7F26;opacity:0.6;}
13 | .div-dnr-now{background-color:#3399FF;}
14 | .div-dnr:hover{background-color:#1D5790;}
15 | #input_bg_path{width:15em;}
16 | .nonce-div-info,.save-css,.pre-css,.op-div-info{position:absolute;z-index:20000;padding:10px;border:1px solid #15A4B1;background-color:#FFFFFF;}
17 | .nonce-div-info button{width:auto;height:auto;}
18 | .list-button-op{margin-top:10px;padding-top:10px;}
19 | .list-button-op button{float:left;width:4em;height:3em;margin-right:10px;}
20 | .save-css legend,.pre-css legend{padding:2px;background-color:#FFFFFF;border:1px solid #15A4B1;}
21 | .save-css{top:50%;left:50%;width:80%;min-height:220px;margin:-45% 0 0 -40%;}
22 | .pre-css{top:50%;left:50%;width:80%;height:73%;margin:-45% 0 0 -40%;}
23 | #div_view_css{width:591px;height:80%;overflow:auto;padding:10px 3%;word-break:normal;word-wrap:break-word;}
24 | #input_bg_path,#textarea_gb_class{width:100%;}
25 | #textarea_gb_class{border-color:#C0C0C0;}
26 | #input_div_margin{width:3em;}
27 | #input_div_width,#input_div_height,#input_div_left,#input_div_top{width:5em;}
28 | #input_copy_pyl{width:3em;}
29 | #button_copy_top{position:absolute;top:0;left:30px;}
30 | #button_copy_bottom{position:absolute;bottom:0;left:30px;}
31 | #button_copy_left{position:absolute;top:30px;left:0;}
32 | #button_copy_right{position:absolute;top:30px;left:60px;}
33 | #input_div_name{width:113px;}
34 | #hint_txt{display:none;position:absolute;z-index:99999;top:50%;left:50%;width:260px;min-height:2em;margin-left:-130px;margin-top:-20px;padding:4px;border:2px solid #04b338;background-color:#FFFFFF;}
35 |
--------------------------------------------------------------------------------
/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ghostzhang/bg2css/c465e9d86aac9cd36891128a9c70342c287631e6/default.png
--------------------------------------------------------------------------------
/divlist.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 层信息
8 |
36 |
37 |
38 |
39 |
40 | 层信息表
41 |
42 |
43 |
44 |
45 | 层名
46 | |
47 |
48 | 宽度
49 | |
50 |
51 | 高度
52 | |
53 |
54 | 水平位置
55 | |
56 |
57 | 垂直位置
58 | |
59 |
60 | 输出宽
61 | |
62 |
63 | 输出高
64 | |
65 |
66 | 操作
67 | |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/help.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 | CSS Sprites 样式生成工具 快捷键
13 |
38 |
39 |
40 |
41 | CSS Sprites 样式生成工具 快捷键
42 |
43 |
44 | 菜单快捷键列表
45 |
46 |
47 |
48 | 名称 |
49 | 快捷键(win) |
50 | 快捷键(mac) |
51 | 说明 |
52 |
53 |
54 |
55 |
56 | 打开图片
57 | |
58 | Ctrl + O
59 | |
60 | command + O
61 | |
62 | 打开要操作的图片。
63 | |
64 |
65 |
66 | 更新图片
67 | |
68 | F5
69 | |
70 | 无
71 | |
72 | 更新当前图片文件。
73 | |
74 |
75 |
76 | 读取定义文件
77 | |
78 | Ctrl + Shift + O
79 | |
80 | command + Shift + O
81 | |
82 | 打开之前保存的定义文件。
83 | |
84 |
85 |
86 | 保存当前定义
87 | |
88 | Ctrl + S
89 | |
90 | command + S
91 | |
92 | 保存当前的定义到文件。
93 | |
94 |
95 |
96 | 当前层信息
97 | |
98 | Ctrl + N
99 | |
100 | command + N
101 | |
102 | 显示|隐藏当前层的信息面板。
103 | |
104 |
105 |
106 | 所有层信息
107 | |
108 | Ctrl + Shift + N
109 | |
110 | 无
111 | |
112 | 打当前层的信息窗口。
113 | |
114 |
115 |
116 | 显示区定义
117 | |
118 | Ctrl + M
119 | |
120 | 无
121 | |
122 | 显示|隐藏显示区的定义面板。
123 | |
124 |
125 |
126 | 生成样式
127 | |
128 | Ctrl + P
129 | |
130 | command + P
131 | |
132 | 显示|隐藏生成样式的定义面板。
133 | |
134 |
135 |
136 | 样式预览
137 | |
138 | Ctrl + Shift + P
139 | |
140 | command + Shift + P
141 | |
142 | 显示|隐藏样式预览面板。
143 | |
144 |
145 |
146 |
147 |
148 |
149 | 图片操作快捷键列表
150 |
151 |
152 |
153 | 名称 |
154 | 快捷键(win) |
155 | 快捷键(mac) |
156 | 说明 |
157 |
158 |
159 |
160 |
161 | 图片缩放
162 | |
163 | Ctrl + 0
164 | |
165 | cntrol + command + 0
166 | |
167 | 图片100%显示。
168 | |
169 |
170 |
171 | Ctrl + 2
172 | |
173 | cntrol + command + 2
174 | |
175 | 图片200%显示。
176 | |
177 |
178 |
179 | Ctrl + 4
180 | |
181 | cntrol + command + 4
182 | |
183 | 图片400%显示。
184 | |
185 |
186 |
187 | Ctrl + 6
188 | |
189 | cntrol + command + 6
190 | |
191 | 图片600%显示。
192 | |
193 |
194 |
195 |
196 |
197 |
198 |
199 | 当前层操作快捷键列表
200 |
201 |
202 |
203 | 名称 |
204 | 快捷键(win) |
205 | 快捷键(mac) |
206 | 说明 |
207 |
208 |
209 |
210 |
211 | 删除
212 | |
213 | Delete
214 | |
215 | fn + delete
216 | |
217 | 删除当前层
218 | |
219 |
220 |
221 | 移动当前层
222 | |
223 | Ctrl + 向上方向键
224 | |
225 | cntrol + command + 向上方向键
226 | |
227 | 向上移动当前层的位置
228 | |
229 |
230 |
231 | Ctrl + 向下方向键
232 | |
233 | cntrol + command + 向下方向键
234 | |
235 | 向下移动当前层的位置
236 | |
237 |
238 |
239 | Ctrl + 向左方向键
240 | |
241 | cntrol + command + 向左方向键
242 | |
243 | 向左移动当前层的位置
244 | |
245 |
246 |
247 | Ctrl + 向右方向键
248 | |
249 | cntrol + command + 向右方向键
250 | |
251 | 向右移动当前层的位置
252 | |
253 |
254 |
255 | 修改当前层
256 | |
257 | Ctrl + Shift + 向上方向键
258 | |
259 | cntrol + command + Shift + 向上方向键
260 | |
261 | 减少当前层的高度
262 | |
263 |
264 |
265 | Ctrl + Shift + 向下方向键
266 | |
267 | cntrol + command + Shift + 向下方向键
268 | |
269 | 增加当前层的高度
270 | |
271 |
272 |
273 | Ctrl + Shift + 向左方向键
274 | |
275 | cntrol + command + Shift + 向左方向键
276 | |
277 | 减少当前层的宽度
278 | |
279 |
280 |
281 | Ctrl + Shift + 向右方向键
282 | |
283 | cntrol + command + Shift + 向右方向键
284 | |
285 | 增加当前层的宽度
286 | |
287 |
288 |
289 |
290 |
291 | 帮助文档:https://github.com/ghostzhang/bg2css/wiki/bg2css-help
293 |
294 |
295 |
296 |
--------------------------------------------------------------------------------
/help/001.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ghostzhang/bg2css/c465e9d86aac9cd36891128a9c70342c287631e6/help/001.png
--------------------------------------------------------------------------------
/help/003.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ghostzhang/bg2css/c465e9d86aac9cd36891128a9c70342c287631e6/help/003.gif
--------------------------------------------------------------------------------
/help/004.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ghostzhang/bg2css/c465e9d86aac9cd36891128a9c70342c287631e6/help/004.gif
--------------------------------------------------------------------------------
/help/005.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ghostzhang/bg2css/c465e9d86aac9cd36891128a9c70342c287631e6/help/005.gif
--------------------------------------------------------------------------------
/help/02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ghostzhang/bg2css/c465e9d86aac9cd36891128a9c70342c287631e6/help/02.png
--------------------------------------------------------------------------------
/help/r.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ghostzhang/bg2css/c465e9d86aac9cd36891128a9c70342c287631e6/help/r.png
--------------------------------------------------------------------------------
/icons/AIRApp_128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ghostzhang/bg2css/c465e9d86aac9cd36891128a9c70342c287631e6/icons/AIRApp_128.png
--------------------------------------------------------------------------------
/icons/AIRApp_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ghostzhang/bg2css/c465e9d86aac9cd36891128a9c70342c287631e6/icons/AIRApp_16.png
--------------------------------------------------------------------------------
/icons/AIRApp_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ghostzhang/bg2css/c465e9d86aac9cd36891128a9c70342c287631e6/icons/AIRApp_32.png
--------------------------------------------------------------------------------
/icons/AIRApp_48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ghostzhang/bg2css/c465e9d86aac9cd36891128a9c70342c287631e6/icons/AIRApp_48.png
--------------------------------------------------------------------------------
/icons/b.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ghostzhang/bg2css/c465e9d86aac9cd36891128a9c70342c287631e6/icons/b.gif
--------------------------------------------------------------------------------
/lib/air/AIRAliases.js:
--------------------------------------------------------------------------------
1 | /* AIRAliases.js - Revision: 1.5 */
2 |
3 | /*
4 | ADOBE SYSTEMS INCORPORATED
5 | Copyright 2007-2008 Adobe Systems Incorporated. All Rights Reserved.
6 |
7 | NOTICE: Adobe permits you to modify and distribute this file only in accordance with
8 | the terms of Adobe AIR SDK license agreement. You may have received this file from a
9 | source other than Adobe. Nonetheless, you may modify or
10 | distribute this file only in accordance with such agreement.
11 | */
12 |
13 |
14 | var air;
15 | if (window.runtime)
16 | {
17 | if (!air) air = {};
18 | // functions
19 | air.trace = window.runtime.trace;
20 | air.navigateToURL = window.runtime.flash.net.navigateToURL;
21 | air.sendToURL = window.runtime.flash.net.sendToURL;
22 |
23 |
24 | // file
25 | air.File = window.runtime.flash.filesystem.File;
26 | air.FileStream = window.runtime.flash.filesystem.FileStream;
27 | air.FileMode = window.runtime.flash.filesystem.FileMode;
28 |
29 | // events
30 | air.ActivityEvent = window.runtime.flash.events.ActivityEvent;
31 | air.AsyncErrorEvent = window.runtime.flash.events.AsyncErrorEvent;
32 | air.BrowserInvokeEvent = window.runtime.flash.events.BrowserInvokeEvent;
33 | air.DataEvent = window.runtime.flash.events.DataEvent;
34 | air.DRMAuthenticateEvent = window.runtime.flash.events.DRMAuthenticateEvent;
35 | air.DRMStatusEvent = window.runtime.flash.events.DRMStatusEvent;
36 | air.ErrorEvent = window.runtime.flash.events.ErrorEvent;
37 | air.Event = window.runtime.flash.events.Event;
38 | air.EventDispatcher = window.runtime.flash.events.EventDispatcher;
39 | air.FileListEvent = window.runtime.flash.events.FileListEvent;
40 | air.HTTPStatusEvent = window.runtime.flash.events.HTTPStatusEvent;
41 | air.IOErrorEvent = window.runtime.flash.events.IOErrorEvent;
42 | air.InvokeEvent = window.runtime.flash.events.InvokeEvent;
43 | air.NetStatusEvent = window.runtime.flash.events.NetStatusEvent;
44 | air.OutputProgressEvent = window.runtime.flash.events.OutputProgressEvent;
45 | air.ProgressEvent = window.runtime.flash.events.ProgressEvent;
46 | air.SecurityErrorEvent = window.runtime.flash.events.SecurityErrorEvent;
47 | air.StatusEvent = window.runtime.flash.events.StatusEvent;
48 | air.TimerEvent = window.runtime.flash.events.TimerEvent;
49 | air.SampleDataEvent = window.runtime.flash.events.SampleDataEvent;
50 |
51 | // native window
52 | air.NativeWindow = window.runtime.flash.display.NativeWindow;
53 | air.NativeWindowDisplayState = window.runtime.flash.display.NativeWindowDisplayState;
54 | air.NativeWindowInitOptions = window.runtime.flash.display.NativeWindowInitOptions;
55 | air.NativeWindowSystemChrome = window.runtime.flash.display.NativeWindowSystemChrome;
56 | air.NativeWindowResize = window.runtime.flash.display.NativeWindowResize;
57 | air.NativeWindowType = window.runtime.flash.display.NativeWindowType;
58 |
59 | air.NativeWindowBoundsEvent = window.runtime.flash.events.NativeWindowBoundsEvent;
60 | air.NativeWindowDisplayStateEvent = window.runtime.flash.events.NativeWindowDisplayStateEvent;
61 |
62 | // geom
63 | air.Point = window.runtime.flash.geom.Point;
64 | air.Rectangle = window.runtime.flash.geom.Rectangle;
65 | air.Matrix = window.runtime.flash.geom.Matrix;
66 |
67 | // 3D
68 | air.Matrix3D = window.runtime.flash.geom.Matrix3D;
69 | air.Vector3D = window.runtime.flash.geom.Vector3D;
70 | air.Orientation3D = window.runtime.flash.geom.Orientation3D;
71 | air.Utils3D = window.runtime.flash.geom.Utils3D;
72 |
73 | // Shader
74 | air.Shader = window.runtime.flash.display.Shader;
75 | air.ShaderFilter = window.runtime.flash.filters.ShaderFilter;
76 | air.ShaderPrecision = window.runtime.flash.display.ShaderPrecision;
77 |
78 | // net
79 | air.FileFilter = window.runtime.flash.net.FileFilter;
80 |
81 | air.LocalConnection = window.runtime.flash.net.LocalConnection;
82 | air.NetConnection = window.runtime.flash.net.NetConnection;
83 |
84 | air.URLLoader = window.runtime.flash.net.URLLoader;
85 | air.URLLoaderDataFormat = window.runtime.flash.net.URLLoaderDataFormat;
86 | air.URLRequest = window.runtime.flash.net.URLRequest;
87 | air.URLRequestDefaults = window.runtime.flash.net.URLRequestDefaults;
88 | air.URLRequestHeader = window.runtime.flash.net.URLRequestHeader;
89 | air.URLRequestMethod = window.runtime.flash.net.URLRequestMethod;
90 | air.URLStream = window.runtime.flash.net.URLStream;
91 | air.URLVariables = window.runtime.flash.net.URLVariables;
92 | air.Socket = window.runtime.flash.net.Socket;
93 | air.XMLSocket = window.runtime.flash.net.XMLSocket;
94 |
95 | air.Responder = window.runtime.flash.net.Responder;
96 | air.ObjectEncoding = window.runtime.flash.net.ObjectEncoding;
97 |
98 | air.NetStream = window.runtime.flash.net.NetStream;
99 | air.NetStreamInfo = window.runtime.flash.net.NetStreamInfo;
100 | air.NetStreamPlayOptions = window.runtime.flash.net.NetStreamPlayOptions;
101 | air.NetStreamPlayTransitions = window.runtime.flash.net.NetStreamPlayTransitions;
102 | air.SharedObject = window.runtime.flash.net.SharedObject;
103 | air.SharedObjectFlushStatus = window.runtime.flash.net.SharedObjectFlushStatus;
104 |
105 | // system
106 | air.Capabilities = window.runtime.flash.system.Capabilities;
107 | air.System = window.runtime.flash.system.System;
108 | air.Security = window.runtime.flash.system.Security;
109 | air.Updater = window.runtime.flash.desktop.Updater;
110 |
111 | // desktop
112 | air.Clipboard = window.runtime.flash.desktop.Clipboard;
113 | air.ClipboardFormats = window.runtime.flash.desktop.ClipboardFormats;
114 | air.ClipboardTransferMode = window.runtime.flash.desktop.ClipboardTransferMode;
115 |
116 | air.NativeDragManager = window.runtime.flash.desktop.NativeDragManager;
117 | air.NativeDragOptions = window.runtime.flash.desktop.NativeDragOptions;
118 | air.NativeDragActions = window.runtime.flash.desktop.NativeDragActions;
119 |
120 | air.Icon = window.runtime.flash.desktop.Icon;
121 | air.DockIcon = window.runtime.flash.desktop.DockIcon;
122 | air.InteractiveIcon = window.runtime.flash.desktop.InteractiveIcon;
123 | air.NotificationType = window.runtime.flash.desktop.NotificationType;
124 | air.SystemTrayIcon = window.runtime.flash.desktop.SystemTrayIcon;
125 |
126 | air.NativeApplication = window.runtime.flash.desktop.NativeApplication;
127 |
128 | // display
129 | air.NativeMenu = window.runtime.flash.display.NativeMenu;
130 | air.NativeMenuItem = window.runtime.flash.display.NativeMenuItem;
131 | air.Screen = window.runtime.flash.display.Screen;
132 |
133 | air.Loader = window.runtime.flash.display.Loader;
134 | air.Bitmap = window.runtime.flash.display.Bitmap;
135 | air.BitmapData = window.runtime.flash.display.BitmapData;
136 |
137 | // ui
138 | air.Keyboard = window.runtime.flash.ui.Keyboard;
139 | air.KeyLocation = window.runtime.flash.ui.KeyLocation;
140 | air.Mouse = window.runtime.flash.ui.Mouse;
141 |
142 |
143 | //security
144 | air.ReferencesValidationSetting = window.runtime.flash.security.ReferencesValidationSetting;
145 | air.RevocationCheckSettings = window.runtime.flash.security.RevocationCheckSettings;
146 | air.SignatureStatus = window.runtime.flash.security.SignatureStatus;
147 | air.SignerTrustSettings = window.runtime.flash.security.SignerTrustSettings;
148 | air.XMLSignatureValidator = window.runtime.flash.security.XMLSignatureValidator;
149 |
150 |
151 | // utils
152 | air.ByteArray = window.runtime.flash.utils.ByteArray;
153 | air.CompressionAlgorithm = window.runtime.flash.utils.CompressionAlgorithm;
154 | air.Endian = window.runtime.flash.utils.Endian;
155 | air.Timer = window.runtime.flash.utils.Timer;
156 |
157 | air.HTMLLoader = window.runtime.flash.html.HTMLLoader;
158 | air.HTMLPDFCapability = window.runtime.flash.html.HTMLPDFCapability;
159 |
160 | // media
161 | air.ID3Info = window.runtime.flash.media.ID3Info;
162 | air.Sound = window.runtime.flash.media.Sound;
163 | air.SoundChannel = window.runtime.flash.media.SoundChannel;
164 | air.SoundLoaderContext = window.runtime.flash.media.SoundLoaderContext;
165 | air.SoundMixer = window.runtime.flash.media.SoundMixer;
166 | air.SoundTransform = window.runtime.flash.media.SoundTransform;
167 | air.Microphone = window.runtime.flash.media.Microphone;
168 | air.Video = window.runtime.flash.media.Video;
169 | air.Camera = window.runtime.flash.media.Camera;
170 | air.SoundCodec = window.runtime.flash.media.SoundCodec;
171 |
172 | // data
173 | air.EncryptedLocalStore = window.runtime.flash.data.EncryptedLocalStore;
174 | air.SQLCollationType = window.runtime.flash.data.SQLCollationType;
175 | air.SQLColumnNameStyle = window.runtime.flash.data.SQLColumnNameStyle;
176 | air.SQLColumnSchema = window.runtime.flash.data.SQLColumnSchema;
177 | air.SQLConnection = window.runtime.flash.data.SQLConnection;
178 | air.SQLError = window.runtime.flash.errors.SQLError;
179 | air.SQLErrorEvent = window.runtime.flash.events.SQLErrorEvent;
180 | air.SQLErrorOperation = window.runtime.flash.errors.SQLErrorOperation;
181 | air.SQLEvent = window.runtime.flash.events.SQLEvent;
182 | air.SQLIndexSchema = window.runtime.flash.data.SQLIndexSchema;
183 | air.SQLMode = window.runtime.flash.data.SQLMode;
184 | air.SQLResult = window.runtime.flash.data.SQLResult;
185 | air.SQLSchema = window.runtime.flash.data.SQLSchema;
186 | air.SQLSchemaResult = window.runtime.flash.data.SQLSchemaResult;
187 | air.SQLStatement = window.runtime.flash.data.SQLStatement;
188 | air.SQLTableSchema = window.runtime.flash.data.SQLTableSchema;
189 | air.SQLTransactionLockType = window.runtime.flash.data.SQLTransactionLockType;
190 | air.SQLTriggerSchema = window.runtime.flash.data.SQLTriggerSchema;
191 | air.SQLUpdateEvent = window.runtime.flash.events.SQLUpdateEvent;
192 | air.SQLViewSchema = window.runtime.flash.data.SQLViewSchema;
193 |
194 | // service monitoring framework
195 | air.__defineGetter__("ServiceMonitor", function() { return window.runtime.air.net.ServiceMonitor; })
196 | air.__defineGetter__("SocketMonitor", function() { return window.runtime.air.net.SocketMonitor; })
197 | air.__defineGetter__("URLMonitor", function() { return window.runtime.air.net.URLMonitor; })
198 |
199 | // update framework
200 | air.__defineGetter__("ApplicationUpdater", function() { return window.runtime.air.update.ApplicationUpdater; });
201 | air.__defineGetter__("ApplicationUpdaterUI", function() { return window.runtime.air.update.ApplicationUpdaterUI; });
202 | air.__defineGetter__("UpdateEvent", function() { return window.runtime.air.update.events.UpdateEvent; });
203 | air.__defineGetter__("StatusUpdateEvent", function() { return window.runtime.air.update.events.StatusUpdateEvent; });
204 | air.__defineGetter__("StatusUpdateErrorEvent", function() { return window.runtime.air.update.events.StatusUpdateErrorEvent; });
205 | air.__defineGetter__("DownloadErrorEvent", function() { return window.runtime.air.update.events.DownloadErrorEvent; });
206 | air.__defineGetter__("StatusFileUpdateEvent", function() { return window.runtime.air.update.events.StatusFileUpdateEvent; });
207 | air.__defineGetter__("StatusFileUpdateErrorEvent", function() { return window.runtime.air.update.events.StatusFileUpdateErrorEvent; });
208 | }
--------------------------------------------------------------------------------
/lib/air/applicationupdater_ui.swf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ghostzhang/bg2css/c465e9d86aac9cd36891128a9c70342c287631e6/lib/air/applicationupdater_ui.swf
--------------------------------------------------------------------------------
/lib/air/library.swf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ghostzhang/bg2css/c465e9d86aac9cd36891128a9c70342c287631e6/lib/air/library.swf
--------------------------------------------------------------------------------
/lib/js/AIRLocalizer.js:
--------------------------------------------------------------------------------
1 | /* AIRLocalizer.js - Revision: 1.5 */
2 |
3 | /*
4 | ADOBE SYSTEMS INCORPORATED
5 | Copyright 2007-2008 Adobe Systems Incorporated. All Rights Reserved.
6 |
7 | NOTICE: Adobe permits you to modify and distribute this file only in accordance with
8 | the terms of Adobe AIR SDK license agreement. You may have received this file from a
9 | source other than Adobe. Nonetheless, you may modify or
10 | distribute this file only in accordance with such agreement.
11 | */
12 |
13 |
14 | // Using the function method to obfuscate inner globals to the main script, so that the
15 | // "window" remains untouched.
16 | (function(){
17 | /**
18 | * This is automatically replaced while building
19 | * @version "1.5"
20 | * @private
21 | */
22 | var version = "1.5";
23 |
24 |
25 | /**
26 | * Just to make sure we have the right shortcuts included
27 | * @namespace window.air
28 | * @private
29 | */
30 | var air = {
31 | File : window.runtime.flash.filesystem.File,
32 | FileStream : window.runtime.flash.filesystem.FileStream,
33 | FileMode : window.runtime.flash.filesystem.FileMode,
34 | Capabilities : window.runtime.flash.system.Capabilities
35 | };
36 |
37 | /**
38 | * Utility functions
39 | * @namespace util
40 | * @private
41 | */
42 | var util = {
43 | /**
44 | * Returns the content of a file
45 | * @param file air.File File that should be read
46 | * @return string
47 | */
48 | stringFromFile : function stringFromFile(file){
49 | var fileStream = new air.FileStream();
50 | fileStream.open(file, air.FileMode.READ);
51 | var result = fileStream.readUTFBytes(file.size);
52 | fileStream.close();
53 | return result;
54 | }
55 | };
56 |
57 | /**
58 | * Used for sorting the locales array
59 | * @private
60 | */
61 |
62 | function LocaleId(){
63 | this.lang = '';
64 | this.script = '';
65 | this.region = '';
66 | this.extended_langs = [];
67 | this.variants = [];
68 | this.extensions = {};
69 | this.privates = [];
70 | this.privateLangs = false;
71 | };
72 |
73 |
74 | LocaleId.prototype = {
75 | transformToParent: function(){
76 | if(this.privates.length>0){
77 | this.privates.splice(this.privates.length-1, 1);
78 | return true;
79 | }
80 |
81 | var lastExtensionName = null;
82 | for(var i in this.extensions){
83 | if(this.extensions.hasOwnProperty(i)){
84 | lastExtensionName = i;
85 | }
86 | }
87 | if(lastExtensionName){
88 | var lastExtension = this.extensions[lastExtensionName];
89 | if(lastExtension.length==1){
90 | delete this.extensions[ lastExtensionName ];
91 | return true;
92 | }
93 | lastExtension.splice(lastExtension.length-1, 1);
94 | return true;
95 | }
96 |
97 | if(this.variants.length>0){
98 | this.variants.splice(this.variants.length-1, 1);
99 | return true;
100 | }
101 |
102 | if(this.script!=''){
103 | //check if we can surpress the script
104 | if(LocaleId.getScriptByLang(this.lang)!=''){
105 | this.script='';
106 | return true;
107 | }else if(this.region==''){
108 | //maybe the default region can surpress the script
109 | var region = LocaleId.getDefaultRegionForLangAndScript(this.lang, this.script);
110 | if(region!=''){
111 | this.region = region;
112 | this.script = '';
113 | return true;
114 | }
115 | }
116 | }
117 |
118 | if(this.region!=''){
119 | if(!(this.script=='' && LocaleId.getScriptByLang(this.lang) == '')){
120 | this.region='';
121 | return true;
122 | }
123 | }
124 |
125 |
126 | if(this.extended_langs.length>0){
127 | this.extended_langs.splice(this.extended_langs.length-1, 1);
128 | return true;
129 | }
130 |
131 | return false;
132 | },
133 |
134 | isSiblingOf: function(other){
135 | if(this.lang==other.lang&&this.script==other.script){
136 | return true;
137 | }
138 | return false;
139 | },
140 |
141 | equals: function(locale){
142 | return this.toString() == locale.toString();
143 | },
144 | toString: function(){
145 | var stack = [ this.lang ];
146 | Array.prototype.push.apply(stack, this.extended_langs);
147 | if(this.script!='') stack.push(this.script);
148 | if(this.region!='') stack.push(this.region);
149 | Array.prototype.push.apply(stack, this.variants);
150 | for(var i in this.extensions){
151 | if(this.extensions.hasOwnProperty(i)){
152 | stack.push(i);
153 | Array.prototype.push.apply(stack, this.extensions[i]);
154 | }
155 | }
156 | if(this.privates.length>0){
157 | stack.push('x');
158 | Array.prototype.push.apply(stack, this.privates);
159 | }
160 | return stack.join('_');
161 | },
162 | canonicalize: function(){
163 | for(var i in this.extensions){
164 | if(this.extensions.hasOwnProperty(i)){
165 | //also clear zero length extensions
166 | if(this.extensions[i].length==0) delete this.extensions[i];
167 | else this.extensions[i] = this.extensions[i].sort();
168 | }
169 | }
170 | this.extended_langs = this.extended_langs.sort();
171 | this.variants = this.variants.sort();
172 | this.privates = this.privates.sort();
173 | if(this.script == ''){
174 | this.script = LocaleId.getScriptByLang(this.lang);
175 | }
176 | //still no script, check the region
177 | if(this.script == '' && this.region!=''){
178 | this.script = LocaleId.getScriptByLangAndRegion(this.lang, this.region);
179 | }
180 |
181 | if(this.region=='' && this.script!=''){
182 | this.region = LocaleId.getDefaultRegionForLangAndScript(this.lang, this.script);
183 | }
184 | }
185 | }
186 |
187 | LocaleId.registry = {
188 | "scripts": ["cyrl", "latn", "ethi", "arab", "beng", "cyrl", "thaa", "tibt", "grek", "gujr", "hebr", "deva", "armn", "jpan", "geor", "khmr", "knda", "kore", "laoo", "mlym", "mymr", "orya", "guru", "sinh", "taml", "telu", "thai", "nkoo", "blis", "hans", "hant", "mong", "syrc"],
189 | "scriptById": {"cyrl": 5, "latn": 1, "ethi": 2, "arab": 3, "beng": 4, "thaa": 6, "tibt": 7, "grek": 8, "gujr": 9, "hebr": 10, "deva": 11, "armn": 12, "jpan": 13, "geor": 14, "khmr": 15, "knda": 16, "kore": 17, "laoo": 18, "mlym": 19, "mymr": 20, "orya": 21, "guru": 22, "sinh": 23, "taml": 24, "telu": 25, "thai": 26, "nkoo": 27, "blis": 28, "hans": 29, "hant": 30, "mong": 31, "syrc": 32} ,
190 | "defaultRegionByLangAndScript": {"bg": {5: "bg"}, "ca": {1: "es"}, "zh": {30: "tw", 29: "cn"}, "cs": {1: "cz"}, "da": {1: "dk"}, "de": {1: "de"}, "el": {8: "gr"}, "en": {1: "us"}, "es": {1: "es"}, "fi": {1: "fi"}, "fr": {1: "fr"}, "he": {10: "il"}, "hu": {1: "hu"}, "is": {1: "is"}, "it": {1: "it"}, "ja": {13: "jp"}, "ko": {17: "kr"}, "nl": {1: "nl"}, "nb": {1: "no"}, "pl": {1: "pl"}, "pt": {1: "br"}, "ro": {1: "ro"}, "ru": {5: "ru"}, "hr": {1: "hr"}, "sk": {1: "sk"}, "sq": {1: "al"}, "sv": {1: "se"}, "th": {26: "th"}, "tr": {1: "tr"}, "ur": {3: "pk"}, "id": {1: "id"}, "uk": {5: "ua"}, "be": {5: "by"}, "sl": {1: "si"}, "et": {1: "ee"}, "lv": {1: "lv"}, "lt": {1: "lt"}, "fa": {3: "ir"}, "vi": {1: "vn"}, "hy": {12: "am"}, "az": {1: "az", 5: "az"}, "eu": {1: "es"}, "mk": {5: "mk"}, "af": {1: "za"}, "ka": {14: "ge"}, "fo": {1: "fo"}, "hi": {11: "in"}, "ms": {1: "my"}, "kk": {5: "kz"}, "ky": {5: "kg"}, "sw": {1: "ke"}, "uz": {1: "uz", 5: "uz"}, "tt": {5: "ru"}, "pa": {22: "in"}, "gu": {9: "in"}, "ta": {24: "in"}, "te": {25: "in"}, "kn": {16: "in"}, "mr": {11: "in"}, "sa": {11: "in"}, "mn": {5: "mn"}, "gl": {1: "es"}, "kok": {11: "in"}, "syr": {32: "sy"}, "dv": {6: "mv"}, "nn": {1: "no"}, "sr": {1: "cs", 5: "cs"}, "cy": {1: "gb"}, "mi": {1: "nz"}, "mt": {1: "mt"}, "quz": {1: "bo"}, "tn": {1: "za"}, "xh": {1: "za"}, "zu": {1: "za"}, "nso": {1: "za"}, "se": {1: "no"}, "smj": {1: "no"}, "sma": {1: "no"}, "sms": {1: "fi"}, "smn": {1: "fi"}, "bs": {1: "ba"}},
191 | "scriptIdByLang": {"ab": 0, "af": 1, "am": 2, "ar": 3, "as": 4, "ay": 1, "be": 5, "bg": 5, "bn": 4, "bs": 1, "ca": 1, "ch": 1, "cs": 1, "cy": 1, "da": 1, "de": 1, "dv": 6, "dz": 7, "el": 8, "en": 1, "eo": 1, "es": 1, "et": 1, "eu": 1, "fa": 3, "fi": 1, "fj": 1, "fo": 1, "fr": 1, "frr": 1, "fy": 1, "ga": 1, "gl": 1, "gn": 1, "gu": 9, "gv": 1, "he": 10, "hi": 11, "hr": 1, "ht": 1, "hu": 1, "hy": 12, "id": 1, "in": 1, "is": 1, "it": 1, "iw": 10, "ja": 13, "ka": 14, "kk": 5, "kl": 1, "km": 15, "kn": 16, "ko": 17, "la": 1, "lb": 1, "ln": 1, "lo": 18, "lt": 1, "lv": 1, "mg": 1, "mh": 1, "mk": 5, "ml": 19, "mo": 1, "mr": 11, "ms": 1, "mt": 1, "my": 20, "na": 1, "nb": 1, "nd": 1, "ne": 11, "nl": 1, "nn": 1, "no": 1, "nr": 1, "ny": 1, "om": 1, "or": 21, "pa": 22, "pl": 1, "ps": 3, "pt": 1, "qu": 1, "rn": 1, "ro": 1, "ru": 5, "rw": 1, "sg": 1, "si": 23, "sk": 1, "sl": 1, "sm": 1, "so": 1, "sq": 1, "ss": 1, "st": 1, "sv": 1, "sw": 1, "ta": 24, "te": 25, "th": 26, "ti": 2, "tl": 1, "tn": 1, "to": 1, "tr": 1, "ts": 1, "uk": 5, "ur": 3, "ve": 1, "vi": 1, "wo": 1, "xh": 1, "yi": 10, "zu": 1, "cpe": 1, "dsb": 1, "frs": 1, "gsw": 1, "hsb": 1, "kok": 11, "mai": 11, "men": 1, "nds": 1, "niu": 1, "nqo": 27, "nso": 1, "son": 1, "tem": 1, "tkl": 1, "tmh": 1, "tpi": 1, "tvl": 1, "zbl": 28},
192 | "scriptIdByLangAndRegion": {"zh": {"cn": 29, "sg": 29, "tw": 30, "hk": 30, "mo": 30}, "mn": {"cn": 31, "sg": 5}, "pa": {"pk": 3, "in": 22}, "ha": {"gh": 1, "ne": 1}}};
193 |
194 |
195 | LocaleId.getScriptByLangAndRegion = function(lang, region){
196 | var langRegions = LocaleId.registry.scriptIdByLangAndRegion[ lang ];
197 | if(typeof langRegions=='undefined') return '';
198 | var scriptId = langRegions[region];
199 | if(typeof scriptId!='undefined'){
200 | return LocaleId.registry.scripts[scriptId].toLowerCase();
201 | }
202 | return '';
203 | }
204 |
205 | LocaleId.getScriptByLang = function(lang){
206 | var scriptId = LocaleId.registry.scriptIdByLang[ lang ];
207 | if(typeof scriptId!='undefined'){
208 | return LocaleId.registry.scripts[scriptId].toLowerCase();
209 | }
210 | return '';
211 | }
212 |
213 | LocaleId.getDefaultRegionForLangAndScript = function(lang, script){
214 | var lang = LocaleId.registry.defaultRegionByLangAndScript[ lang ];
215 | var scriptId = LocaleId.registry.scriptById[ script ];
216 | if(typeof lang!='undefined' && typeof scriptId !='undefined' ){
217 | return lang[scriptId] || "";
218 | }
219 | return '';
220 | }
221 |
222 |
223 | LocaleId.fromString = function(str){
224 | //states
225 | {
226 | var PrimaryLanguage = 0,
227 | ExtendedLanguages = 1,
228 | Script = 2,
229 | Region = 3,
230 | Variants = 5,
231 | Extensions = 6,
232 | Privates = 7;
233 | }
234 | var localeId = new LocaleId();
235 |
236 | var state = PrimaryLanguage;
237 | var subtags = str.replace(/-/g, '_').split('_');
238 |
239 | var last_extension;
240 |
241 | for(var i=0, l=subtags.length; i='a' && firstChar<='z' && subtag_length>=5 )
278 | ||
279 | ( firstChar>='0' && firstChar<='9' && subtag_length>=4 )
280 | )
281 | ){
282 | //variant
283 | localeId.variants.push(subtag);
284 | state = Variants;
285 | }else if ( state < Privates && subtag_length==1 ){ //singleton
286 | if(subtag == 'x'){
287 | state = Privates;
288 | last_extension = localeId.privates;
289 | } else {
290 | state = Extensions;
291 | last_extension = localeId.extensions[subtag] || [];
292 | localeId.extensions[subtag] = last_extension;
293 | }
294 | }else if(state >= Extensions){
295 | last_extension.push(subtag);
296 | }
297 | }
298 | }
299 | localeId.canonicalize();
300 | return localeId;
301 | }
302 |
303 | var LocaleSorter = {
304 | /**
305 | * Promote only that locales from preferenceLocales that have parents in locales
306 | * @private
307 | * @param locales String[] List of locales to be sorted.
308 | * @param preferenceLocales String[] List of locales in the preference order
309 | * @param addAll Adds all the locales at the end, even though no locale is in the preferences list. Default is true
310 | * @return String[]
311 | */
312 | sortLocalesUsingPreferences: function(_locales, _preferenceLocales, ultimateFallbackLocale, addAll){
313 | var result = [];
314 | var haveLocale = {};
315 |
316 | function prepare(list){
317 | var resultList = [];
318 | for(var i=0,l=list.length;i=0;i--){
527 | var attr = node.attributes[i];
528 | if(attr.name.toLowerCase()==attributeInnerPrefix){
529 | setInner = true;
530 | innerValue = attr.value;
531 | }else if(this.isLocalAttribute(attr)){
532 | params.push([this.getLocalAttribute(attr), attr.value]);
533 | }
534 | }
535 | if(setInner){
536 | var value = this.getHtmlString(innerValue);
537 | try{
538 | node.innerHTML = value||innerValue;
539 | }catch(e){
540 | node.textContent = value||innerValue;
541 | }
542 | }
543 | for(var i=params.length-1;i>=0;i--){
544 | var param = params[i];
545 | var value = this.getHtmlString(param[1]);
546 | node.setAttribute(param[0], value||param[1]);
547 | }
548 | },
549 |
550 | /**
551 | * Replaces each node under 'node'
552 | * @param node DOMElement
553 | * @public
554 | */
555 | run: function (node){
556 | this.attributePrefix = this.parent.attributePrefix.toLowerCase();
557 | this.attributePrefixLength = this.attributePrefix.length;
558 | var treeWalker = document.createTreeWalker(
559 | node||document,
560 | NodeFilter.SHOW_ELEMENT,
561 | { acceptNode: function(node) { return NodeFilter.FILTER_ACCEPT; } },
562 | false
563 | );
564 | while(treeWalker.nextNode()) this.walkNode(treeWalker.currentNode);
565 | },
566 |
567 | /**
568 | * Separates the bundleName and resourceName and returns the string from locale chain
569 | * @param resourceName String Default bundle is "default"
570 | * @return String
571 | */
572 | getHtmlString: function(resourceName){
573 | var bundleName;
574 | var i = resourceName.indexOf('.');
575 | if(i!=-1){ bundleName = resourceName.substr(0, i); resourceName=resourceName.substr(i+1); }
576 | else bundleName = "default"
577 | return this.parent.getStringFromChain(bundleName, resourceName);
578 | }
579 | };
580 |
581 |
582 |
583 | /**
584 | * Creates a new object used in Localizer to store loaded bundles, locale chain and bundles path
585 | * @private
586 | * @constructor
587 | * @v
588 | */
589 | function LocalizerPrivate(parent){
590 | this.parent = parent;
591 |
592 | // dom walker needed to update nodes
593 | this.domWalker = new DOMWalker(this);
594 |
595 |
596 | // Locale chain is the internal order that the framework uses to search for locales
597 | this.localeChain = [];
598 |
599 | // When the developer sets the locale chain we should disable the automatic detection
600 | this.autoLocaleChain = true;
601 |
602 | // Loaded locales should be sorted for later use
603 | this.localeCache = {};
604 |
605 | // Default bundle path used to solve the locales directories
606 | this.bundlePath = new air.File('app:/locale/');
607 |
608 | // Store the system capabilities for later use
609 | this.userPreference = air.Capabilities.languages || [air.Capabilities.language];
610 |
611 | // Event listeners
612 | this.eventListeners = {};
613 |
614 | this.attributePrefix = 'local_';
615 |
616 | }
617 | LocalizerPrivate.prototype = {
618 |
619 | /**
620 | * Creates a new locale object that caches bundles and files
621 | * registers the locale for later use
622 | * @private
623 | * @param locale The localeName to be created
624 | * @return LocaleHash
625 | */
626 | createLocaleCache: function(locale){
627 | var obj = {
628 | name : locale,
629 | bundles: {},
630 | files: {}
631 | };
632 | this.localeCache[locale] = obj;
633 | return obj;
634 | },
635 |
636 | /**
637 | * Returns the locale cache object. In case it is not already loaded it is created.
638 | * @private
639 | * @param locale String The localeName to be returned
640 | * @return LocaleHash
641 | */
642 | getLocaleCache: function(locale){
643 | return this.localeCache[locale] || this.createLocaleCache(locale);
644 | },
645 |
646 |
647 | /**
648 | * Removes all the cached locales that are not in the locale chain
649 | * @private
650 | */
651 | cleanupCache: function (){
652 | var isInChain = {};
653 | for(var i in this.localeChain) isInChain[ this.localeChain[i] ] = true;
654 |
655 | for(var locale in this.localeCache ) {
656 | if( ! isInChain[locale] ){
657 | this.localeCache [ locale ] = null;
658 | delete this.localeCache [locale];
659 | }
660 | }
661 | },
662 |
663 | /**
664 | * Removes all the cached locales
665 | * @private
666 | */
667 | clearCache: function (){
668 | for(var locale in this.localeCache ) {
669 | this.localeCache [ locale ] = null;
670 | delete this.localeCache [locale];
671 | }
672 | },
673 | /**
674 | * Creates the bundle object. Also caches it for later use
675 | * @private
676 | * @param locale String The locale name where it should search the bundle
677 | * @param bundlename String The bundle name for the returned bundle
678 | * @return ResourceBundle
679 | */
680 | createBundle: function(locale, bundleName){
681 | var localeCache = this.getLocaleCache(locale);
682 | var file = this.bundlePath.resolvePath(locale).resolvePath(bundleName+".properties");
683 | var resourceBundle = new ResourceBundle(file);
684 | localeCache.bundles[bundleName] = resourceBundle;
685 | if(!resourceBundle.found){
686 | setTimeout(function(obj){
687 | obj.dispatchEvent(new LocalizerEvent(Localizer.BUNDLE_NOT_FOUND, {
688 | bundleName: bundleName,
689 | locale: locale
690 | }));
691 | }, 0, this);
692 | }
693 | return resourceBundle;
694 | },
695 |
696 | /**
697 | * Loads a bundle and returns it.
698 | * @private
699 | * @param locale String The locale name where it should search the bundle
700 | * @param bundleName String The bundle name to be loaded
701 | * @param useCache Bool Setting this to false will force the function to reread the bundle. Default is true
702 | * @return ResourceBundle
703 | */
704 | loadBundle: function(locale, bundleName, useCache){
705 | var localeCache = this.getLocaleCache(locale);
706 | useCache=(typeof useCache=='undefined')?true:useCache;
707 | return (useCache&&localeCache.bundles[bundleName]) || this.createBundle(locale, bundleName);
708 | },
709 |
710 | /**
711 | * Loads a bundle and returns its keys and values as an object.
712 | * @private
713 | * @param locale String The locale name where it should search the bundle
714 | * @param bundleName String The bundle name to be loaded
715 | * @return Object Returns null if the bundle is not found.
716 | */
717 | getResourceBundle: function(locale, bundleName){
718 | var bundle = this.loadBundle(locale, bundleName);
719 | if(bundle==null)
720 | return null;
721 | //make a copy of the bundle
722 | var result = {};
723 | for (var key in bundle.keys){
724 | result [ key ] = bundle.keys [key];
725 | }
726 | return result;
727 | },
728 |
729 | /**
730 | * Creates a new ResourceFile based on the fileName
731 | * @private
732 | * @param locale String The locale name where it should search the file
733 | * @param fileName String Filename that should be loaded
734 | * @return ResourceFile
735 | */
736 | createFile: function(locale, fileName){
737 | var localeCache = this.getLocaleCache(locale);
738 | var file = this.bundlePath.resolvePath(locale).resolvePath(fileName);
739 | var resourceFile = new ResourceFile(file);
740 | localeCache.files[fileName] = resourceFile;
741 | if(!resourceFile.found){
742 | setTimeout(function(obj){
743 | obj.dispatchEvent(new LocalizerEvent(Localizer.FILE_NOT_FOUND, {
744 | fileName: fileName,
745 | locale: locale
746 | }));
747 | }, 0, this);
748 | }
749 | return resourceFile;
750 | },
751 |
752 | /**
753 | * Loads a file and returns it.
754 | * @private
755 | * @param locale String The locale name where it should search the file
756 | * @param bundleName String The file name to be loaded
757 | * @param useCache Bool Setting this to false will force the function to reread the file. Default is true
758 | * @return ResourceFile
759 | */
760 | loadFile: function(locale, fileName, useCache){
761 | var localeCache = this.getLocaleCache(locale);
762 | useCache=(typeof useCache=='undefined')?true:useCache;
763 | return (useCache&&localeCache.files[fileName]) || this.createFile(locale, fileName);
764 | },
765 |
766 | /**
767 | * Automatically discovers the available locales using the listing directory of the bundle path,
768 | * returns an array of locales
769 | * @private
770 | * @return StringArray
771 | */
772 | discoverAndReturnAvailableLocales: function (){
773 | var folder = this.bundlePath;
774 | // check if the file exists and is a directory
775 | if(!(folder.exists&&folder.isDirectory)){
776 | // just die sillently, because a higher level should take care of that
777 | return [];
778 | }
779 |
780 | var localeChain = []
781 | var localeFolders = folder.getDirectoryListing();
782 | for(var i=0, l=localeFolders.length; i0 ){
871 | var oldChain = this.localeChain;
872 | this.localeChain = this.cloneChain(chain);
873 |
874 | // switch off auto locale chain detection
875 | this.autoLocaleChain = false;
876 |
877 | // send some events
878 | this.diffChainsAndFireEvent(this.localeChain, oldChain);
879 | }
880 | },
881 |
882 | /**
883 | * Returns the current locale chain
884 | * @return String[]
885 | */
886 | getLocaleChain: function(){
887 | return this.cloneChain(this.localeChain);
888 | },
889 |
890 | /**
891 | * Returns the source string, but replaces the "{i}" string with args[i]
892 | * @param source String
893 | * @param args String[]
894 | * @return String
895 | */
896 | template: function(source, args){
897 | var parser = /{([^}]*)}/g;
898 | var a = source.split(parser);
899 | var result = [];
900 | var d=0;
901 | for(var i=0,l=a.length;i=0;i--){
935 | var evh = handlers[i];
936 | if(evh.eventName==eventName&&evh.handler==handler){
937 | handlers.splice(i, 1);
938 | }
939 | }
940 | },
941 |
942 | dispatchEvent: function(ev){
943 | var handlers = this.eventListeners[ev.name];
944 | if(!handlers) return;
945 | for(var i=handlers.length-1;i>=0;i--){
946 | handlers[i].handler.call(this.parent, ev);
947 | }
948 | },
949 |
950 |
951 | /**
952 | * Loads the bundle and returns the resource value
953 | * @public
954 | * @param bundleName String
955 | * @param resourceName String
956 | * @param locale String
957 | * @return String
958 | */
959 | getString: function(bundleName, resourceName, locale){
960 | var bundle = this.loadBundle(locale, bundleName);
961 | var result = bundle.get(resourceName);
962 | if(result==null){
963 | setTimeout(function(obj){
964 | obj.dispatchEvent(new LocalizerEvent(Localizer.RESOURCE_NOT_FOUND, {
965 | bundleName: bundleName,
966 | resourceName: resourceName,
967 | locale: locale
968 | }));
969 | }, 0, this);
970 | }
971 | return result;
972 | },
973 |
974 | /**
975 | * loads the file and returns the contents
976 | * @public
977 | * @param fileName String
978 | * @param locale String
979 | * @return String
980 | */
981 | getFile: function(fileName, locale){
982 | var file = this.loadFile(locale, fileName);
983 | return file.getContent();
984 | },
985 |
986 | /**
987 | * Uses the locale chain to get the first defined value
988 | * @public
989 | * @param bundleName String
990 | * @param resourcename String
991 | * @return String
992 | */
993 | getStringFromChain: function(bundleName, resourceName){
994 | var result;
995 | var chain = this.localeChain;
996 | if(chain){
997 | for(var i=0, l=chain.length; i
1103 | // becomes
1104 | // Click here to login
1105 |
1106 | update: function update(/* DOMElement, optional */ parentNode /* = document */){
1107 | this._private.update(parentNode);
1108 | },
1109 |
1110 | // * If “locale” argument is provided it is used to return the value of the localization resource
1111 | // called “resourceName” located in the bundle called “bundleName” only for the locale “locale”.
1112 | // Otherwise, the locale chain returned by “getLocaleChain” is used to lookup the first locale
1113 | // that that provides the “resourceName”. For example if the locale chain is [fr_CA, fr] and a
1114 | // particular resource is not found in “fr_CA”, the framework will also search that resource in the “fr”.
1115 | //
1116 | // * It will automatically load the bundles if needed.
1117 | //
1118 | // * Returns null if the resource is not found and fires one of the following events:
1119 | // * RESOURCE_NOT_FOUND when the bundle does not contain the specified “resourceName”;
1120 | // * BUNDLE_NOT_FOUND when the bundle file is not found.
1121 | //
1122 | // * If “templateArgs” is provided the function will use it to replace bracketed numbers in the resource
1123 | // with the correspondent values from the “templateArgs” array (only where applicable, meaning
1124 | // that if templateArgs[n] is not defined, “{n}” will not be changed):
1125 | // * “{0}”, “{1}”, .... “{n}” will be replaced with templateArgs[0], templateArgs[1] ... templateArgs[n].
1126 | // * in order to skip replacement for one number, just set that “templateArgs” item to undefined or null;
1127 |
1128 | getString: function getString(/* String */ bundleName, /*String */ resourceName, /* optional String[] */ templateArgs, /* optional, String */ locale ) /*: String*/{
1129 | var result = null;
1130 | if(locale){
1131 | result = this._private.getString(bundleName, resourceName, locale);
1132 | }else{
1133 | result = this._private.getStringFromChain(bundleName, resourceName);
1134 | }
1135 | if(templateArgs&&result!=null){
1136 | result = this._private.template(result, templateArgs);
1137 | }
1138 | return result;
1139 | },
1140 |
1141 | //
1142 | // * Returns the keys found in a bundle
1143 | //
1144 | // @param locale String The locale name where it should search the bundle
1145 | // @param bundleName String The bundle name to be loaded
1146 | //
1147 | // * Returns null if the bundle is not found.
1148 | //
1149 | getResourceBundle: function(locale, bundleName){
1150 | return this._private.getResourceBundle(locale, bundleName);
1151 | },
1152 |
1153 | // * If “locale” argument is provided, it returns the contents of the file
1154 | // “{bundlesDirectory}/{locale}/{resourceFileName}”. Otherwise, the locale
1155 | // chain returned by “getLocaleChain” is used to lookup the first locale that
1156 | // that provides the “resourceFileName” file. For example if the locale chain is
1157 | // [fr_FR, fr] the file will be searched using that order: first will search
1158 | // “{bundlesDirectory}/fr_FR/{resourceFileName}” and only if it is not found the
1159 | // framework will continue to search for “{bundlesDirectory}/fr/{resourceFileName}”.
1160 | //
1161 | // * {bundlesPath} is the current bundle path set using “setBundlesDirectory”;
1162 | //
1163 | // * Returns null if the resource file is not found and fires:
1164 | // * FILE_NOT_FOUND event;
1165 | //
1166 | // * If “templateArgs” is provided the function will use it to replace bracketed numbers in the
1167 | // resource file with the correspondent values from the “templateArgs” array (only where applicable,
1168 | // meaning that if templateArgs[n] is not defined, “{n}” will not be changed):
1169 | // * “{0}”, “{1}”, .... “{n}” will be replaced with templateArgs[0], templateArgs[1] ... templateArgs[n].
1170 | // * in order to skip replacement for one number, just set that “templateArgs” item to undefined;
1171 |
1172 | getFile: function getFile(/* String */ resourceFileName, /* optional String[] */ templateArgs, /* String */ locale ) /*: String*/ {
1173 | var result = null;
1174 | if(locale){
1175 | result = this._private.getFile(resourceFileName, locale);
1176 | }else{
1177 | result = this._private.getFileFromChain(resourceFileName);
1178 | }
1179 | if(templateArgs&&result!=null){
1180 | result = this._private.template(result, templateArgs);
1181 | }
1182 | return result;
1183 | },
1184 |
1185 | // * Sets the locale chain and updates the current locale used by all other functions.
1186 | //
1187 | // * Note: When “chain” argument is missing, is not an array or has zero length the function fails
1188 | // and throws “air.Localizer.IllegalArgumentsError” exception
1189 | //
1190 | // * Fires LOCALE_CHANGE event, the developer should update the DOM using update function. This event
1191 | // is fired synchronous whenever the locale chain has changed.
1192 | setLocaleChain: function setLocaleChain(/* optional, String[] */ chain){
1193 | if(!(chain&&chain.hasOwnProperty&&chain.hasOwnProperty('length')&&chain.length>0)){
1194 | throw new Localizer.IllegalArgumentsError("Locale chain should be an array.");
1195 | }
1196 | this._private.setLocaleChain(chain);
1197 | },
1198 |
1199 | // * Returns the locale chain set by the previous call to “setLocaleChain”.
1200 | //
1201 | // * NOTE: If “setLocaleChain” hasn’t been called the function returns the automatically
1202 | // detected locale chain computed when the Localizer is instantiated (see also the property called “localizer”);
1203 |
1204 | getLocaleChain: function getLocaleChain()/* :String[] */ {
1205 | return this._private.getLocaleChain();
1206 | },
1207 |
1208 | // * Sets the prefix for local attributes used in the “update” function.
1209 | //
1210 | // * Default prefix is “local_”.
1211 |
1212 | setLocalAttributePrefix: function setLocalAttributePrefix(value){
1213 | this._private.attributePrefix = value+'';
1214 | },
1215 |
1216 | // typical add/remove Event Dispatcher
1217 |
1218 | addEventListener: function addEventListener(/* String */ eventName, /* callback function */ callback){
1219 | this._private.addEventListener(eventName, callback);
1220 | },
1221 | removeEventListener: function removeEventListener(/* String */ eventName, /* callback function */ callback){
1222 | this._private.removeEventListener(eventName, callback);
1223 | }
1224 |
1225 | };
1226 |
1227 |
1228 | // Define the getter function. This will temporararly set canCreateLocalizer to true
1229 | // and create a new Localizer. It writes the newly created localizer to the localizerInstance variable;
1230 |
1231 | var localizerInstance = null;
1232 | Localizer.__defineGetter__("localizer", function(){
1233 | if(!localizerInstance){
1234 | canCreateLocalizer = true;
1235 | localizerInstance = new Localizer();
1236 | canCreateLocalizer = false;
1237 | }
1238 | return localizerInstance;
1239 | });
1240 |
1241 |
1242 | // EVENTS
1243 |
1244 | // Fired by “setLocaleChain” when the current locale is changed (synchronous)
1245 | // Event object strcuture is : { localeChain /* : String [] */ }
1246 | Localizer.LOCALE_CHANGE = "change";
1247 |
1248 | // Fired by “getString” and “update” functions when a resource is not found in the specified bundle (fired asynchronous)
1249 | // Event object structure is : { resourceName /* : String */, bundleName /* : String */ }
1250 | Localizer.RESOURCE_NOT_FOUND = "resourceNotFound";
1251 |
1252 | // Fired by “getFile” when a resource file is not found (fired asynchronous)
1253 | // Event object structure is : { resourceFileName /* : String */ }
1254 | Localizer.FILE_NOT_FOUND = "fileNotFound";
1255 |
1256 | // Fired by “getString” and “update” functions when a bundle file is not found (fired asynchronous)
1257 | // Event object structure is : { bundleName /* : String */ }
1258 | Localizer.BUNDLE_NOT_FOUND = "bundleNotFound";
1259 |
1260 | // Version number
1261 | Localizer.version = version;
1262 |
1263 | (function(){
1264 |
1265 | // ERROR
1266 | function BundlePathNotFoundError(path){
1267 | this.name = 'air.Localizer.BundlePathNotFoundError';
1268 | this.message = "Bundle directory not found "+path;
1269 | }
1270 | BundlePathNotFoundError.prototype = new Error;
1271 | Localizer.BundlePathNotFoundError = BundlePathNotFoundError;
1272 |
1273 |
1274 | function IllegalArgumentsError(msg){
1275 | this.name = 'air.Localizer.IllegalArgumentsError';
1276 | this.message = msg;
1277 | }
1278 | IllegalArgumentsError.prototype = new Error;
1279 | Localizer.IllegalArgumentsError = IllegalArgumentsError;
1280 |
1281 | }());
1282 |
1283 | Localizer.LocaleId = LocaleId;
1284 |
1285 | Localizer.ultimateFallbackLocale = 'en';
1286 |
1287 |
1288 | // * This function is for internal use only.
1289 | //
1290 | // * Sort a languages array using the order given by the system capabilities languages array.
1291 | //
1292 | // * Setting removeUnsupported to true removes system unsupported languages. When removeUnsupported is false it makes the system unsupported languages be the last ones preserving order from original array.
1293 | //
1294 | // * Default value for removeUnsupported is true.
1295 | //
1296 | // *NOTE: It uses the same approach that the ADOBE AIR application Installer uses:
1297 | // * it tries to find the perfect match for locale name;
1298 | // * otherwise it fallbacks to finding locales with same parents (eg. “en_US” will fallback to “en” )
1299 | // * user preference will be promoted;
1300 | //
1301 | // * (system supported means they are in the Capabilities.languages array from the runtime)
1302 | //
1303 | // * eg: If Capabilities.languages = [ “fr_CA”, “en_UK”, “ja” ] and the “languages” argument
1304 | // is [ “en”, “fr_FR”, “zn_ZN” ] the returning array will be [ “fr_FR”, “en” ]
1305 | //
1306 | // * eg2: When the “languages” argument is [ fr, fr_CA, fr_FR, ro, en, en_US ]:
1307 | // * and the Capabilities.languages = [ fr_CA ] the result will be [ fr_CA, fr, fr_FR ]
1308 | // * and the Capabilities.languages = [ fr_CA, en ] the result will be [ fr_CA, fr, fr_FR, en, en_US ]
1309 |
1310 | Localizer.sortLanguagesByPreference = function sortLanguagesByPreference( /* String[] */ appLocales, /* String[] */ systemPreferences, /* String, optional */ ultimateFallbackLocale /* = null*/, /*Boolean, optional */ keepAllLocales /* = true */) /* : String[] */{
1311 | if(!( appLocales && appLocales.hasOwnProperty('length') && systemPreferences&&systemPreferences.hasOwnProperty('length') )){
1312 | throw new Localizer.IllegalArgumentsError("Expected at least two arguments: appLocales and systemPreferences.");
1313 | }
1314 | return LocaleSorter.sortLocalesUsingPreferences( appLocales, systemPreferences, ultimateFallbackLocale, keepAllLocales)
1315 | };
1316 |
1317 |
1318 |
1319 | if(!window.air){
1320 | window.air = {};
1321 | }
1322 |
1323 | window.air.Localizer = Localizer;
1324 |
1325 | }());
--------------------------------------------------------------------------------
/lib/js/AIRMenuBuilder.js:
--------------------------------------------------------------------------------
1 | /* AIRMenuBuilder.js - Revision: 1.5 */
2 |
3 | /*
4 | ADOBE SYSTEMS INCORPORATED
5 | Copyright 2007-2008 Adobe Systems Incorporated. All Rights Reserved.
6 |
7 | NOTICE: Adobe permits you to modify and distribute this file only in accordance with
8 | the terms of Adobe AIR SDK license agreement. You may have received this file from a
9 | source other than Adobe. Nonetheless, you may modify or
10 | distribute this file only in accordance with such agreement.
11 | */
12 |
13 | (function AIRMenuBuilder () {
14 |
15 | function constructor ( ) {
16 | window ['air'] = window ['air'] || {};
17 | window.air['ui'] = window.air['ui'] || {};
18 | window.air.ui['Menu'] = new Menu();
19 | registry = new FieldsRegistry();
20 | currentOS = runtime.flash.system.Capabilities.os;
21 | }
22 |
23 | var currentOS = null;
24 | var registry = null;
25 |
26 | var File = runtime.flash.filesystem.File;
27 | var FileStream = runtime.flash.filesystem.FileStream;
28 | var FileMode = runtime.flash.filesystem.FileMode;
29 | var NativeMenu = runtime.flash.display.NativeMenu;
30 | var NativeMenuItem = runtime.flash.display.NativeMenuItem;
31 | var SELECT = runtime.flash.events.Event.SELECT;
32 | var KEYBOARD = runtime.flash.ui.Keyboard;
33 | var COMPLETE = runtime.flash.events.Event.COMPLETE;
34 | var IO_ERROR = runtime.flash.events.IOErrorEvent.IO_ERROR;
35 | var NativeApplication = runtime.flash.desktop.NativeApplication;
36 | var NativeWindow = runtime.flash.display.NativeWindow;
37 | var Loader = runtime.flash.display.Loader;
38 | var URLRequest = runtime.flash.net.URLRequest;
39 | var BitmapData = runtime.flash.display.BitmapData;
40 |
41 | /**
42 | * CLASS FieldsRegistry
43 | * @class
44 | * @private
45 | */
46 | function FieldsRegistry () {
47 |
48 | this.proof = function (name, value) {
49 | if (!validateName(name)) { return null };
50 | switch (name) {
51 | case FieldsRegistry.ENABLED:
52 | case FieldsRegistry.ALT_KEY:
53 | case FieldsRegistry.SHIFT_KEY:
54 | case FieldsRegistry.CMD_KEY:
55 | case FieldsRegistry.CTRL_KEY:
56 | case FieldsRegistry.TOGGLED:
57 | case FieldsRegistry.DEFAULT_KEY:
58 | return (typeof value == 'boolean')?
59 | value: (typeof value == 'string')?
60 | (value.toLowerCase() == 'false')? false :
61 | true : getDefault (name);
62 | case FieldsRegistry.KEY_EQUIVALENT:
63 | var d;
64 | return (typeof value == 'string')?
65 | (value.length == 1)? value :
66 | getDefault (name) : getDefault (name);
67 | case FieldsRegistry.LABEL:
68 | return (typeof value == 'string')?
69 | (value.length != 0)? value:
70 | getDefault (name) : getDefault (name);
71 | case FieldsRegistry.MNEMONIC_INDEX:
72 | var n;
73 | return (typeof value == 'number')?
74 | value: (typeof value == 'string')?
75 | (!isNaN ( n = parseInt(value) ))? n :
76 | getDefault (name) : getDefault (name);
77 | case FieldsRegistry.TYPE:
78 | return (typeof value == 'string') ?
79 | (validateType(value))? value :
80 | getDefault (name) : getDefault (name);
81 | case FieldsRegistry.ON_SELECT:
82 | var f;
83 | return (typeof value == 'function')?
84 | value : (typeof value == 'string')?
85 | (typeof (f = window[value]) == 'function')?
86 | f : getDefault (name) : getDefault (name);
87 | }
88 | }
89 |
90 | this.iterateFields = function (callback, scope) {
91 | var f, n, fr = FieldsRegistry;
92 | for (f in fr) {
93 | n = fr [f] !== fr.prototype? fr [f] : null;
94 | if (n && !validateType(n)) {
95 | callback.call ( scope || window, n )
96 | };
97 | }
98 | }
99 |
100 | var validateType = function (type) {
101 | return type == FieldsRegistry.REGULAR ||
102 | type == FieldsRegistry.SEPARATOR ||
103 | type == FieldsRegistry.CHECK;
104 | }
105 |
106 | var validateName = function (fieldName) {
107 | for (var f in FieldsRegistry) {
108 | if (FieldsRegistry[f] == fieldName) { return true };
109 | }
110 | return false;
111 | }
112 |
113 |
114 | var getDefault = function (fieldName) {
115 | switch (fieldName) {
116 | case FieldsRegistry.ALT_KEY:
117 | case FieldsRegistry.SHIFT_KEY:
118 | case FieldsRegistry.TOGGLED:
119 | return false;
120 | case FieldsRegistry.ENABLED:
121 | case FieldsRegistry.DEFAULT_KEY:
122 | return true;
123 | case FieldsRegistry.KEY_EQUIVALENT:
124 | case FieldsRegistry.ON_SELECT:
125 | return null;
126 | case FieldsRegistry.LABEL:
127 | return ' ';
128 | case FieldsRegistry.MNEMONIC_INDEX:
129 | return -1;
130 | case FieldsRegistry.TYPE:
131 | return FieldsRegistry.REGULAR;
132 | case FieldsRegistry.CMD_KEY:
133 | case FieldsRegistry.CTRL_KEY:
134 | default:
135 | return null;
136 | }
137 | }
138 |
139 | }
140 | FieldsRegistry.ALT_KEY = 'altKey';
141 | FieldsRegistry.CMD_KEY = 'cmdKey';
142 | FieldsRegistry.CTRL_KEY = 'ctrlKey';
143 | FieldsRegistry.ENABLED = 'enabled';
144 | FieldsRegistry.KEY_EQUIVALENT = 'keyEquivalent';
145 | FieldsRegistry.LABEL = 'label';
146 | FieldsRegistry.MNEMONIC_INDEX = 'mnemonicIndex';
147 | FieldsRegistry.SHIFT_KEY = 'shiftKey';
148 | FieldsRegistry.TOGGLED = 'toggled';
149 | FieldsRegistry.TYPE = 'type';
150 | FieldsRegistry.ON_SELECT = 'onSelect';
151 | FieldsRegistry.DEFAULT_KEY = 'defaultKeyEquivalentModifiers';
152 | FieldsRegistry.SEPARATOR = 'separator';
153 | FieldsRegistry.CHECK = 'check';
154 | FieldsRegistry.REGULAR = 'regular';
155 |
156 | /**
157 | * CLASS Menu
158 | * Description
159 | * Loads a user menu defined as XML or JSON, and sets it as one of the
160 | * supported menu types.
161 | * @class
162 | * @author ciacob
163 | */
164 | function Menu() {
165 |
166 | var buildMenu = function (source, type) {
167 | var b = new Builder();
168 | b.loadData (source, type);
169 | return b.build();
170 | }
171 |
172 | var attachMenu = function (menu, type, target, icons) {
173 | var s = new Shell();
174 | s.link(menu, type, target, icons);
175 | }
176 |
177 | /**
178 | * Load a menu defined in XML format.
179 | * @param source
180 | * An object containing XML menu(s) to be loaded for various OS-es.
181 | * @return
182 | * A NativeMenu object built from the given XML source.
183 | */
184 | this.createFromXML = function ( source ) {
185 | return buildMenu ( source, Builder.XML );
186 | }
187 |
188 | /**
189 | * Same as air.ui.Menu.fromXML, except it handles JSON data.
190 | */
191 | this.createFromJSON = function ( source ) {
192 | return buildMenu ( source, Builder.JSON );
193 | }
194 |
195 | /**
196 | * - on Windows: sets the given nativeMenu object as the NativeWindow's
197 | * menu;
198 | * - on Mac: inserts the items of the given nativeMenu object between
199 | * the 'Edit' and 'Window' default menus;
200 | * @param nativeMenu
201 | * A NativeMenu returned by one of the air.ui.Menu.from...
202 | * functions.
203 | * @param overwrite
204 | * A boolean that will change the behavior on Mac. If true, the
205 | * default menus will be replaced entirely by the given nativeMenu
206 | */
207 | this.setAsMenu = function ( nativeMenu, overwrite ) {
208 | if (!arguments.length) {
209 | throw (new Error(
210 | "No argument given for the 'setAsMenu()' method."
211 | ));
212 | }
213 | var style = overwrite? Shell.MENU | Shell.OVERWRITE : Shell.MENU;
214 | attachMenu (nativeMenu, style);
215 | }
216 |
217 | /**
218 | * Displays the given menu as a contextual menu when the user right
219 | * clicks a certain DOM element.
220 | * @param nativeMenu
221 | * A NativeMenu returned by one of the air.ui.Menu.from...
222 | * functions.
223 | * @param domElement
224 | * The DOM Element to link with the given nativeMenu. The
225 | * contextual menu will only show when the user right clicks over
226 | * domElement. This attribute is optional. If missing, the context
227 | * menu will display on every right-click over the application.
228 | */
229 | this.setAsContextMenu = function ( nativeMenu, domElement ) {
230 | if (!arguments.length) {
231 | throw (new Error(
232 | "No argument given for the 'setAsContextMenu()' method."
233 | ));
234 | }
235 | if (arguments.length < 2) { domElement = Shell.UNSPECIFIED };
236 | attachMenu (nativeMenu, Shell.CONTEXT, domElement);
237 | }
238 |
239 | /**
240 | * Sets the given nativeMenu as the
241 | * ''NativeApplication.nativeApplication.icon.menu'' property.
242 | * @param nativeMenu
243 | * A NativeMenu returned by one of the air.ui.Menu.from...
244 | * functions.
245 | * @param icons
246 | * An array holding icon file paths or bitmap data objects.
247 | * If specified, these will be used as the application's
248 | * tray/dock icons.
249 | * @throws
250 | * If no bitmap data was set for the ''icon'' object and no default
251 | * icons are specified in the application descriptor.
252 | */
253 | this.setAsIconMenu = function ( nativeMenu, icons ) {
254 | if (!arguments.length) {
255 | throw (new Error(
256 | "No argument given for the 'setAsIconMenu()' method."
257 | ));
258 | }
259 | attachMenu (nativeMenu, Shell.ICON, null, icons);
260 | }
261 |
262 | }
263 |
264 | /**
265 | * CLASS DataSource
266 | * @public
267 | * @abstract
268 | */
269 | function DataSource() {
270 | var _this = this;
271 |
272 | var legalExtensions = ['xml', 'js'];
273 |
274 | var rSeed = null;
275 |
276 | var DATA_OBJECT = 1;
277 | var INLINE_STRING = 2;
278 | var FILE_PATH = 3;
279 | var FILE_OBJECT = 4;
280 | var ILLEGAL_TYPE = 5;
281 |
282 | function getFileContent (file) {
283 | var ret = '';
284 | var fileStream = new FileStream();
285 | fileStream.open(file, FileMode.READ);
286 | try {
287 | ret = fileStream.readUTFBytes(file.size);
288 | } catch(e) {
289 | throw(
290 | new Error(["Error\n", "ID: ", e.errorID, "\n", "Message: ",
291 | e.message, "\n"].join(''))
292 | );
293 | }
294 | fileStream.close();
295 | return ret;
296 | }
297 |
298 | function checkExtension (url, whiteList) {
299 | var match = url.match(/\.([^\.]*)$/);
300 | var extension = match? match[1] : null;
301 | for(var i=0; i 0);
467 | if (isError) {
468 | var errText = doc.getElementsByTagName(err)[0].innerText;
469 | var msg = errText.split(':');
470 | msg.length -= 1;
471 | msg = msg.join(':\n');
472 | throw (new Error ([
473 | 'Could not parse data: malformed XML file.', msg
474 | ].join('\n')));
475 | }
476 | that.document = doc;
477 | }
478 | }
479 |
480 | that.getRoot = function() {
481 | return that.document.documentElement;
482 | }
483 |
484 | that.getChildren = function (node) {
485 | var ret = [];
486 | if(node) {
487 | if(node.hasChildNodes && node.hasChildNodes()){
488 | var children = node.childNodes;
489 | for(var i=0; i 0) {
693 | var prev = iterable[i-1];
694 | prev['nextSibling'] = child;
695 | }
696 | }
697 | }
698 | }
699 | return ret;
700 | }
701 |
702 | that.getNextSibling = function (node) {
703 | if (node) {
704 | if(node !== that.getRoot()) {
705 | if (node['nextSibling']) { return node['nextSibling'] };
706 | }
707 | }
708 | return null;
709 | }
710 |
711 | that.getParent = function (node) {
712 | if (node) {
713 | if(node !== that.getRoot()) {
714 | if (node['parent']) { return node['parent'] };
715 | }
716 | }
717 | return null;
718 | }
719 |
720 | that.hasChildren = function (node) {
721 | if (node) {
722 | var iterable = (node === that.getRoot())? node:
723 | (node ['items'])? node ['items']: null;
724 | if (iterable) {
725 | return iterable.length && iterable.length > 0;
726 | }
727 | return false;
728 | }
729 | return false;
730 | }
731 |
732 | that.addChildAt = function (node, newChild, index) {
733 | if (node && newChild) {
734 | var children = that.getChildren (node) || (function() {
735 | node['items'] = [];
736 | return node['items'];
737 | })();
738 | index = Math.min(Math.max(0, index), children.length);
739 | children.splice (index, 0, newChild);
740 | if (index > 0) {
741 | children [index-1]['nextSibling'] = children [index]
742 | };
743 | if (index < children.length-1) {
744 | children[index]['nextSibling'] = children [index]+1
745 | };
746 | node['items'] = children;
747 | }
748 | }
749 |
750 | that.removeChildAt = function (node, index) {
751 | if (node) {
752 | var children = that.getChildren (node) || (function() {
753 | node['items'] = [];
754 | return node['items'];
755 | })();
756 | index = Math.min(Math.max(0, index), children.length);
757 | var removed = children [index];
758 | children.splice (index, 1);
759 | if(index > 0 && index < children.length) {
760 | children [index-1]['nextSibling'] = children [index];
761 | }
762 | node['items'] = children;
763 | return removed;
764 | }
765 | return null;
766 | }
767 |
768 | that.createNode = function (properties) {
769 | var node = {};
770 | for (var p in properties) {
771 | that.setProperty (node, p, properties[p])
772 | };
773 | if (that.getProperty (node, 'id') == null) {
774 | that.setProperty (node, 'id', that.generateUID());
775 | }
776 | return node;
777 | }
778 |
779 | that.getProperty = function (node, propName) {
780 | if (node) { return registry.proof(propName, node[propName]) };
781 | return null;
782 | }
783 |
784 | that.setProperty = function (node, propName, propValue) {
785 | if (node) {
786 | node[propName] = registry.proof(propName, propValue);
787 | }
788 | }
789 |
790 | this.$JSONDataSource.apply (this, arguments);
791 | }
792 |
793 | /**
794 | * CLASS Builder
795 | * @private
796 | * @class
797 | */
798 | function Builder() {
799 |
800 | var ds, root = null;
801 |
802 | function createDataSource (source, type) {
803 | var ret = null;
804 | if (type == Builder.XML) { ret = new XMLDataSource ( source ) };
805 | if (type == Builder.JSON) { ret = new JSONDataSource( source )};
806 | return ret;
807 | }
808 |
809 | function buildMenu() {
810 | var w = new Walker(ds, buildItem);
811 | w.walk ();
812 | }
813 |
814 | function buildItem (item) {
815 |
816 | // Get & parse info about the item to be built:
817 | var summary = ds.getSummary (item);
818 | var isFirstLevel = (!ds.getParent(item));
819 | var isItemDisabled = (!summary[FieldsRegistry.ENABLED]);
820 | var hasChildren = ds.hasChildren(item);
821 | var isItemSeparator = (summary [FieldsRegistry.TYPE] ==
822 | FieldsRegistry.SEPARATOR);
823 | var isItemAToggle = (summary [FieldsRegistry.TYPE] ==
824 | FieldsRegistry.CHECK);
825 |
826 | // Build the NativeMenuItem to represent this item:
827 | var ret = parseLabelForMnemonic (summary [FieldsRegistry.LABEL]);
828 | var nmi = new NativeMenuItem ( ret[0], isItemSeparator );
829 |
830 |
831 | // Attach features for this item:
832 | var parsedMnemonicIndex = ret[1];
833 | if (parsedMnemonicIndex >= 0) {
834 | summary [FieldsRegistry.MNEMONIC_INDEX] = parsedMnemonicIndex;
835 | };
836 | var mnemonicIndex = summary [FieldsRegistry.MNEMONIC_INDEX];
837 | if (mnemonicIndex != -1) { nmi.mnemonicIndex = mnemonicIndex };
838 | if (isItemAToggle) {
839 | var toggler = function (event) {
840 | var val = !ds.getProperty (item,
841 | FieldsRegistry.TOGGLED);
842 | ds.setProperty (item, FieldsRegistry.TOGGLED, val);
843 | nmi.checked = val;
844 | }
845 | nmi.addEventListener (SELECT, toggler);
846 | nmi.checked = summary [FieldsRegistry.TOGGLED];
847 | }
848 | if (summary [FieldsRegistry.ON_SELECT]) {
849 | var f = function (event) {
850 | var target = event.target;
851 | summary [FieldsRegistry.ON_SELECT].call (
852 | window, event, summary
853 | );
854 | }
855 | nmi.addEventListener (SELECT, f);
856 | }
857 | attachKeyEquivalentHandler (nmi, summary);
858 | if ( isItemDisabled ) { nmi.enabled = false };
859 |
860 | // Attach our item within the menu structure:
861 | item['_widget_'] = nmi;
862 | if (hasChildren) { nmi.submenu = new NativeMenu() };
863 | var data = nmi.data || (nmi.data = {});
864 | data['item'] = item;
865 | var parMnu = null;
866 | var parItem = ds.getParent(item);
867 | if (parItem) {
868 | var parWidget = parItem['_widget_'];
869 | parMnu = parWidget.submenu;
870 | if (!parMnu) { return };
871 | } else {
872 | parMnu = root || ( root = new NativeMenu() );
873 | }
874 | parMnu.addItem(nmi);
875 | }
876 |
877 | function qReplace (tStr, searchStr , replaceStr) {
878 | var index;
879 | while ((index = tStr.indexOf (searchStr)) >= 0) {
880 | var arr = tStr.split('');
881 | arr.splice (index, searchStr.length,
882 | replaceStr);
883 | tStr = arr.join('');
884 | }
885 | return tStr;
886 | }
887 |
888 | function parseLabelForMnemonic (label) {
889 | var l = label;
890 | if (l) {
891 | l = qReplace(l, '__', '[UNDERSCORE]');
892 | l = qReplace(l, '_', '[MNEMONIC]');
893 | l = qReplace(l, '[UNDERSCORE]', '_');
894 | var mi = l.indexOf ('[MNEMONIC]');
895 | l = qReplace(l, '[MNEMONIC]', '');
896 | if (mi >= 0) { return [l, mi] };
897 | }
898 | return [l, -1];
899 | }
900 |
901 | function attachKeyEquivalentHandler (nativeItem, summary) {
902 | if (summary[FieldsRegistry.DEFAULT_KEY]) {
903 | // Linux implementation needs this check:
904 | var def = nativeItem.keyEquivalentModifiers &&
905 | nativeItem.keyEquivalentModifiers[0]?
906 | nativeItem.keyEquivalentModifiers[0] : null;
907 | if (def && typeof def != "undefined") {
908 | if (summary[FieldsRegistry.CTRL_KEY] === false) {
909 | if (def == KEYBOARD.CONTROL) { def = null };
910 | }
911 | if (summary[FieldsRegistry.CMD_KEY] === false) {
912 | if (def == KEYBOARD.COMMAND) { def = null };
913 | }
914 | }
915 | }
916 | var key;
917 | if (key = summary[FieldsRegistry.KEY_EQUIVALENT]) {
918 | var mods = [];
919 | if (def) { mods.push(def) };
920 | if (summary[FieldsRegistry.CTRL_KEY]) {
921 | mods.push (KEYBOARD.CONTROL);
922 | }
923 | if (summary[FieldsRegistry.CMD_KEY]) {
924 | mods.push (KEYBOARD.COMMAND);
925 | }
926 | if (summary[FieldsRegistry.ALT_KEY]) {
927 | mods.push (KEYBOARD.ALTERNATE);
928 | }
929 | key = (summary[FieldsRegistry.SHIFT_KEY])?
930 | key.toUpperCase() : key.toLowerCase();
931 | nativeItem.keyEquivalent = key;
932 | nativeItem.keyEquivalentModifiers = mods;
933 | }
934 | }
935 |
936 | this.loadData = function (source, type) {
937 | if (source) { ds = createDataSource (source, type) }
938 | else { throw new Error([
939 | "Cannot create menu. ",
940 | "Provided data source is null"
941 | ].join('')) }
942 | }
943 |
944 | this.build = function() {
945 | if(ds) {buildMenu()};
946 | return root;
947 | }
948 | }
949 | Builder.XML = 0x10;
950 | Builder.JSON = 0x20;
951 |
952 | /**
953 | * CLASS NIConnector
954 | * @private
955 | * @class
956 | */
957 | function NIConnector () {
958 |
959 | var that = this;
960 |
961 | var LAST = 0x1;
962 | var BEFORE_LAST = 0x2;
963 |
964 | var ni;
965 | var nativeMenu;
966 | var overwrite;
967 | var allSet;
968 | var isMac;
969 |
970 | function $NIConnector (oNi, oNewNativeMenu, bOverwriteExisting) {
971 | if (oNi && oNewNativeMenu) {
972 | allSet = true;
973 | ni = oNi;
974 | nativeMenu = oNewNativeMenu;
975 | overwrite = bOverwriteExisting;
976 | isMac = currentOS.indexOf('Mac') >= 0;
977 | if (typeof NIConnector.defaultMenu == "undefined") {
978 | var app = NativeApplication.nativeApplication;
979 | NIConnector.defaultMenu = app.menu;
980 | }
981 | }
982 | }
983 |
984 |
985 | function isDefaultApplicationMenu () {
986 | var app = NativeApplication.nativeApplication;
987 | return (app.menu == NIConnector.defaultMenu);
988 | }
989 |
990 | function purge () {
991 | while (ni.menu.numItems) { ni.menu.removeItemAt (0) }
992 | }
993 |
994 | function add ( style ) {
995 | if (!ni.menu) {
996 | replace();
997 | return;
998 | }
999 | var addFunction = (style == LAST)?
1000 | ni.menu.addItem : function (item) {
1001 | ni.menu.addItemAt (item, ni.menu.numItems-1);
1002 | }
1003 | var item;
1004 | while (nativeMenu.numItems && (item = nativeMenu.removeItemAt(0))) {
1005 | if(isMac && !item.submenu) { continue };
1006 | addFunction.call (that, item);
1007 | }
1008 | }
1009 |
1010 | function replace () {
1011 | ni.menu = nativeMenu;
1012 | }
1013 |
1014 | this.doConnect = function () {
1015 | if (allSet) {
1016 | if (overwrite) {
1017 | if (isMac) {
1018 | purge ();
1019 | add (LAST);
1020 | }
1021 | else { replace() };
1022 | }
1023 | else {
1024 | if (isMac) {
1025 | if (isDefaultApplicationMenu()) { add (BEFORE_LAST) }
1026 | else { add (LAST) };
1027 | } else { add (LAST) };
1028 | }
1029 | }
1030 | }
1031 |
1032 | $NIConnector.apply (this, arguments);
1033 | }
1034 | NIConnector.defaultMenu;
1035 |
1036 |
1037 | /**
1038 | * CLASS Shell
1039 | * @private
1040 | * @class
1041 | */
1042 | function Shell() {
1043 |
1044 | function $Shell(){}
1045 |
1046 | var that = this;
1047 |
1048 | var CONTEXT_MENU = 'contextmenu';
1049 | var app = NativeApplication.nativeApplication;
1050 |
1051 | var uidSeed = 0;
1052 | var DEFAULT_ID = "DEFAULT_ID";
1053 |
1054 | var isMac = currentOS.indexOf('Mac') >= 0;
1055 |
1056 | var isBitmapData = function(obj) {
1057 | return obj &&
1058 | obj.constructor &&
1059 | obj.constructor === (new BitmapData (1, 1));
1060 | }
1061 |
1062 | var resolveDomEl = function (obj) {
1063 | var ret = null;
1064 | if (obj) {
1065 | if (typeof obj == 'object' && obj.nodeType == 1) { ret = obj };
1066 | if (typeof obj == 'string') {
1067 | var el;
1068 | if (el = document.getElementById(obj)) { ret = el };
1069 | }
1070 | }
1071 | return ret;
1072 | }
1073 |
1074 | var checkUserIcon = function (obj) {
1075 | var icon = app.icon;
1076 | return icon.bitmaps.length > 0;
1077 | }
1078 |
1079 | var getIcons = function (userIcons) {
1080 | var ret = [];
1081 | var entries = [];
1082 | if (userIcons && userIcons.length) {
1083 | entries = userIcons;
1084 | } else {
1085 | var p = new DOMParser();
1086 | var descr = String(app.applicationDescriptor);
1087 | var descrDoc = p.parseFromString(descr, "text/xml");
1088 | var appEl = descrDoc.getElementsByTagName('application')[0];
1089 | var iconEl = appEl.getElementsByTagName('icon')[0];
1090 | if (iconEl) {
1091 | var iconEntries = iconEl.getElementsByTagName('*');
1092 | for (var i=0; i 0;
1188 | if (!haveDefaultIcons) {
1189 | if (!isMac) {
1190 | throw (new Error([
1191 | "Cannot set the icon menu.",
1192 | "On operating systems that do not provide a default",
1193 | "tray icon, you must specify one before calling",
1194 | "setAsIconMenu().",
1195 | "Alternativelly, you can specify default icons in the",
1196 | "application's XML descriptor."
1197 | ].join('\n')));
1198 | }
1199 | }
1200 | var doAttach = function(bitmaps){
1201 | setBitmaps (bitmaps);
1202 | app.icon.menu = menu;
1203 | }
1204 | if (defaultIcons) {
1205 | loadDefaultBitmaps(defaultIcons, doAttach);
1206 | }
1207 | }
1208 | }
1209 |
1210 | this.link = function (oMenu, style, target, icons) {
1211 | if (Shell.MENU & style) {
1212 | var bOverwrite = style & Shell.OVERWRITE;
1213 | return linkMenu(oMenu, bOverwrite);
1214 | }
1215 | if (Shell.CONTEXT & style) {return linkContextMenu(oMenu, target)};
1216 | if (Shell.ICON & style) { return linkIconMenu(oMenu, icons) };
1217 | }
1218 |
1219 | $Shell.apply (this, arguments);
1220 | }
1221 | Shell.UNSPECIFIED = -1;
1222 | Shell.MENU = 1;
1223 | Shell.CONTEXT = 2;
1224 | Shell.ICON = 4;
1225 | Shell.OVERWRITE = 8;
1226 |
1227 | Shell.resolve = function (pathOrFile) {
1228 | var file = null;
1229 | try {
1230 | file = File(pathOrFile);
1231 | } catch(e) {
1232 | file = File.applicationDirectory.resolvePath (pathOrFile);
1233 | if (!file.exists) {
1234 | try {
1235 | file = new File (pathOrFile);
1236 | } catch(e) {
1237 | // must be a path, both 'relative' AND 'non-existing'.
1238 | }
1239 | }
1240 | }
1241 | return file;
1242 | }
1243 |
1244 | /**
1245 | * CLASS Walker
1246 | * @class
1247 | * @private
1248 | */
1249 | function Walker() {
1250 | var t, c, currentItem, allSet, item;
1251 |
1252 | function $Walker (target, callback) {
1253 | if (target && target instanceof DataSource) {
1254 | t = target;
1255 | }
1256 | if (callback && typeof callback == "function") {
1257 | c = callback;
1258 | }
1259 | if (t && c) { allSet = true };
1260 | }
1261 |
1262 | function getNearestAncestorSibling(node) {
1263 | while (node) {
1264 | node = t.getParent(node);
1265 | if(node) {
1266 | var s = t.getNextSibling(node);
1267 | if (s) { return s };
1268 | }
1269 | }
1270 | return null;
1271 | }
1272 |
1273 | function getFirstChildOfRoot() {
1274 | return t.getChildren(t.getRoot())[0] || null;
1275 | }
1276 |
1277 | function doTraverse() {
1278 | if (allSet) {
1279 | while (item = getNext()) { c.call (window, item) };
1280 |
1281 | } else {
1282 | throw (new Error([
1283 | 'Cannot traverse data tree.',
1284 | 'Please check the arguments you provided to the Walker class.',
1285 | ].join('\n')));
1286 | }
1287 | }
1288 |
1289 | function getNext() {
1290 | if (currentItem === null) { return null };
1291 |
1292 | if (typeof currentItem == 'undefined') {
1293 | currentItem = getFirstChildOfRoot();
1294 | }
1295 |
1296 | if (t.hasChildren(currentItem)) {
1297 | var parentNode = currentItem;
1298 | currentItem = t.getChildren(currentItem)[0];
1299 | return parentNode;
1300 | }
1301 |
1302 | if(t.getNextSibling(currentItem)) {
1303 | var current = currentItem;
1304 | currentItem = t.getNextSibling(currentItem);
1305 | return current;
1306 | }
1307 |
1308 | var ci = currentItem;
1309 | currentItem = getNearestAncestorSibling(currentItem);
1310 | return ci;
1311 | }
1312 |
1313 | this.walk = function (callback) {
1314 | doTraverse();
1315 | if (typeof callback == "function") { callback.call (this) };
1316 | }
1317 |
1318 | $Walker.apply (this, arguments);
1319 | }
1320 |
1321 | constructor.apply (this, arguments);
1322 | })();
--------------------------------------------------------------------------------
/lib/js/divlist.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author ghostzhang
3 | */
4 | function $(e){
5 | return document.getElementById("" + e + "");
6 | }
7 |
8 | function delDiv(divinfo){
9 | var id = divinfo.parentNode.parentNode.id;
10 | window.opener.div_list_del(id);
11 | $(id).style.display = "none";
12 | }
13 |
14 | function div_info(divinfo){
15 | var id = divinfo.parentNode.parentNode.id;
16 | window.opener.reset_div_class();
17 | window.opener.div_info(id, 0, 0, 0, 0);
18 | $(id).className = "div-dnr-now";
19 | var temp_div = $("input_div_id").value;
20 | if (temp_div) {
21 | temp_div = $(temp_div);
22 | temp_div.className = "div-dnr";
23 | }
24 | $("input_div_id").value = id;
25 | window.opener.image_x(1);
26 | }
27 |
28 | function resetDive(){
29 | window.opener.resetDive();
30 | }
31 |
32 | function delAll(){
33 | window.opener.delAll();
34 | $("div_list").style.display = "none";
35 | }
36 |
37 | function addAtt(div_list){
38 | for (var n = 0; n < div_list.length; n++) {
39 | if (div_list[n]) {
40 | var ch = document.createElement('input');
41 | var bt = document.createElement('input');
42 |
43 | ch.type = "radio";
44 | ch.name = "radio_ch";
45 | ch.onclick = function(){
46 | div_info(this);
47 | }
48 | bt.type = "button";
49 | bt.value = "X";
50 | bt.onclick = function(){
51 | delDiv(this)
52 | }
53 |
54 | $("choose_" + div_list[n][0] + "").appendChild(ch);
55 | $("del_" + div_list[n][0] + "").appendChild(bt);
56 | }
57 | }
58 | }
59 |
60 | function onload(){
61 | var temp_div_list = window.opener.div_list();
62 | var temp = "";
63 |
64 | for (var n = 0; n < temp_div_list.length; n++) {
65 | if (temp_div_list[n]) {
66 | temp += "";
67 | temp += "" + temp_div_list[n][1] + " | ";
68 | temp += "" + temp_div_list[n][2] + "px | ";
69 | temp += "" + temp_div_list[n][3] + "px | ";
70 | temp += "" + temp_div_list[n][4] + "px | ";
71 | temp += "" + temp_div_list[n][5] + "px | ";
72 |
73 | if (temp_div_list[n][6]){
74 | temp +='' + temp_div_list[n][6] + " | ";
75 | }else{
76 | temp +='' + temp_div_list[n][6] + " | ";
77 | }
78 |
79 | if (temp_div_list[n][7]){
80 | temp +='' + temp_div_list[n][7] + " | ";
81 | }else{
82 | temp +='' + temp_div_list[n][7] + " | ";
83 | }
84 | temp += ' | ';
85 | temp += ' | ';
86 | temp += "
";
87 | }
88 | }
89 | $("div_list").innerHTML = temp;
90 | addAtt(temp_div_list);
91 | $('bt_reset').addEventListener('click', resetDive);
92 | $('bt_delall').addEventListener('click', delAll);
93 | }
94 |
--------------------------------------------------------------------------------
/lib/js/main.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @author ghost
3 | */
4 | var Browser_Name = navigator.appName;
5 | var x = 25, y = 25, x1 = 0, y1 = 0, xx = 0, yy = 0, xx1 = 0, yy1 = 0;
6 | var moveable = false;
7 | var index = 10000;
8 | var resizeable = false;
9 | var objId = "";
10 | var objParentId = "";
11 | var num = 1;
12 | var default_width = "30";
13 | var default_height = "30";
14 |
15 | var file = null;
16 | var file_path = null;
17 | var image = null;
18 | var image_path = new Array();
19 | var image_url = "";
20 | var image_width = null;
21 | var image_height = null;
22 | var file_xml = null;
23 | var file_path_xml = null;
24 | var div_margin = 0;
25 | var read_end = true;
26 |
27 | var array_style = new Array();
28 | var array_div = new Array();
29 | var num_array_style = 0;
30 | var del_array_div = new Array();
31 |
32 | var menu_array = new Array();
33 | var show_new = true;
34 | var show_nonce = true;
35 |
36 | function $(e) {
37 | return document.getElementById("" + e + "");
38 | }
39 |
40 | function openInBrowser(url) {
41 | air.navigateToURL(new air.URLRequest(url));
42 | }
43 |
44 | // 选择图片
45 | function doBrowseImg() {
46 | var filters = new runtime.Array(new air.FileFilter('Images(*.jpg;*.gif;*.png)', '*.jpg;*.gif;*.png;*.jpeg'));
47 |
48 | file.browseForOpen('Select an Image', filters);
49 | }
50 |
51 | function doSelectImg(e) {
52 | image_url = file.url;
53 | image.load(new air.URLRequest(image_url));
54 |
55 | file_path = file.nativePath;
56 | }
57 |
58 | function doOver(e) {
59 | e.preventDefault();
60 | }
61 |
62 | function doDrop(e) {
63 | var files = e.dataTransfer.getData('application/x-vnd.adobe.air.file-list');
64 |
65 | if (checkFileType(files[0])) {
66 | image_url = files[0].url;
67 | image.load(new air.URLRequest(image_url));
68 | file_path = files[0].nativePath;
69 | }
70 | else {
71 | return false;
72 | }
73 | doComplete(event);
74 | }
75 |
76 | function checkFileType(file) {
77 | var temp_file = file.name.split(".");
78 | var temp_type = "jpg,gif,png,jpeg,JPG,GIF,PNG,JPEG";
79 | if (temp_type.search(temp_file[1]) >= 0) {
80 | return true;
81 | }
82 | else {
83 | return false;
84 | }
85 | }
86 |
87 | // 选择xml
88 | function doBrowseXml() {
89 | var filters = new runtime.Array(new air.FileFilter('XML(*.xml)', '*.xml'));
90 |
91 | file_xml.browseForOpen('Select an XML', filters);
92 | }
93 |
94 | function doSelectXml(e) {
95 | file_path_xml = file_xml.nativePath;
96 | doCompleteXml();
97 | }
98 |
99 | function doComplete(event, imginfo) {
100 | var div = null;
101 | image_path.length = 0;
102 | $("div_view_css").innerText = "";
103 | image_x(1);
104 |
105 | div = $("image_view");
106 | if (arguments.length == 2) {
107 | image_width = div.style.width = imginfo[1] + "px";
108 | image_height = div.style.height = imginfo[2] + "px";
109 | image_path[0] = div.src = "file:///" + imginfo[0];
110 | $("input_bg_path").value = file_path = imginfo[0];
111 | }
112 | else {
113 | image_width = div.style.width = image.width + "px";
114 | image_height = div.style.height = image.height + "px";
115 | image_path[0] = div.src = "file:///" + file_path;
116 | $("input_bg_path").value = file_path;
117 | $("textarea_gb_class").value = "";
118 | }
119 |
120 | div.style.backgroundRepeat = "no-repeat";
121 | div.style.backgroundImage = "url(icon/b.gif)";
122 | div.style.backgroundColor = "#000000";
123 |
124 | $("bt_x1").disabled = "";
125 | $("bt_x2").disabled = "";
126 | $("bt_x4").disabled = "";
127 |
128 | var temp_img_width = parseInt(image_width.replace("px", ""));
129 | var temp_img_height = parseInt(image_height.replace("px", ""));
130 | if (temp_img_width < 150 && temp_img_height < 150) {
131 | $("bt_x6").disabled = "";
132 | }
133 | else {
134 | $("bt_x6").disabled = "true";
135 | }
136 | if (temp_img_width > 0 && temp_img_width < default_width) {
137 | default_width = temp_img_width;
138 | }
139 | if (temp_img_height > 0 && temp_img_height < default_height) {
140 | default_height = temp_img_height;
141 | }
142 | $("bt_color_1").disabled = "";
143 | $("bt_color_2").disabled = "";
144 | $("bt_color_3").disabled = "";
145 | $("checkbox_show_width").disabled = "";
146 | $("checkbox_show_height").disabled = "";
147 | }
148 |
149 | //修改层信息
150 | function doEdit() {
151 | var temp = $("input_div_id").value;
152 | if (temp) {
153 | $("button_div_edit").disabled = "";
154 | $("button_copy_left").disabled = "true";
155 | $("button_copy_top").disabled = "trun";
156 | $("button_copy_right").disabled = "true";
157 | $("button_copy_bottom").disabled = "true";
158 | $("input_copy_pyl").disabled = "true";
159 | $("button_div_copy_width").disabled = "true";
160 | $("button_div_copy_height").disabled = "true";
161 | $("button_div_copy_left").disabled = "true";
162 | $("button_div_copy_top").disabled = "true";
163 | $("checkbox_copy_div_class").disabled = "true";
164 | $("checkbox_copy_div_width").disabled = "true";
165 | $("checkbox_copy_div_height").disabled = "true";
166 | $("checkbox_show_div_width").disabled = "true";
167 | $("checkbox_show_div_height").disabled = "true";
168 | $("button_div_copy").disabled = "true";
169 | }
170 | }
171 |
172 | //修改层信息
173 | function editDiv() {
174 | var temp = $("input_div_id").value;
175 |
176 | if (temp != "") {
177 | checkinput(temp);
178 | update_info(temp);
179 | $("button_div_edit").disabled = "true";
180 | $("button_copy_left").disabled = "";
181 | $("button_copy_top").disabled = "";
182 | $("button_copy_right").disabled = "";
183 | $("button_copy_bottom").disabled = "";
184 | $("input_copy_pyl").disabled = "";
185 | $("button_div_copy_width").disabled = "";
186 | $("button_div_copy_height").disabled = "";
187 | $("button_div_copy_left").disabled = "";
188 | $("button_div_copy_top").disabled = "";
189 | $("checkbox_copy_div_class").disabled = "";
190 | $("checkbox_copy_div_width").disabled = "";
191 | $("checkbox_copy_div_height").disabled = "";
192 | $("checkbox_show_div_width").disabled = "";
193 | $("checkbox_show_div_height").disabled = "";
194 | $("button_div_copy").disabled = "";
195 | }
196 | }
197 |
198 | //删除层
199 | function delDiv(event, divid) {
200 | var temp = "";
201 | if (arguments.length == 2) {
202 | temp = divid;
203 | }
204 | else {
205 | temp = $("input_div_id").value;
206 | }
207 | var temp_div_num = get_array_num(temp);
208 | if (temp_div_num >= 0) {
209 | $(temp).parentNode.removeChild($(temp));
210 |
211 | $("input_div_id").value = "";
212 | $("input_div_name").value = "";
213 | $("input_div_width").value = "";
214 | $("input_div_height").value = "";
215 | $("input_div_left").value = "";
216 | $("input_div_top").value = "";
217 |
218 | array_div[temp_div_num] = "";
219 | array_style[temp_div_num] = "";
220 | $("button_div_edit").disabled = "true";
221 | $("button_div_del").disabled = "true";
222 | $("button_copy_left").disabled = "true";
223 | $("button_copy_top").disabled = "true";
224 | $("button_copy_right").disabled = "true";
225 | $("button_copy_bottom").disabled = "true";
226 | $("input_copy_pyl").disabled = "true";
227 | $("checkbox_copy_div_class").disabled = "true";
228 | $("checkbox_copy_div_width").disabled = "true";
229 | $("checkbox_copy_div_height").disabled = "true";
230 | $("checkbox_show_div_width").disabled = "true";
231 | $("checkbox_show_div_height").disabled = "true";
232 | $("button_div_copy").disabled = "true";
233 | }
234 | }
235 |
236 | //重置层
237 | function resetDive() {
238 | var temp = $("input_div_id").value;
239 | var temp_style = array_style;
240 | var temp_image_view = $("image_view");
241 |
242 | for (var n = 0; n < array_div.length; n++) {
243 | if (array_div[n] != "") {
244 | temp_style[n][2] = default_width;
245 | temp_style[n][3] = default_height;
246 | temp_style[n][4] = "10";
247 | temp_style[n][5] = "10";
248 |
249 | $(array_div[n]).style.width = temp_style[n][2] * num + "px";
250 | $(array_div[n]).style.height = temp_style[n][3] * num + "px";
251 | $(array_div[n]).style.left = temp_style[n][4] * num + "px";
252 | $(array_div[n]).style.top = temp_style[n][5] * num + "px";
253 | }
254 | }
255 | if (temp) {
256 | $("input_div_width").value = default_width;
257 | $("input_div_height").value = default_height;
258 | $("input_div_left").value = "10";
259 | $("input_div_top").value = "10";
260 | }
261 | }
262 |
263 | //增加层
264 | function addDiv(divinfo, addDiv) {
265 | var temp_background = $("image_view").style.backgroundImage;
266 | if (temp_background != "") {
267 | var rn = Math.round(Math.random() * 10000);
268 | var div = document.createElement('div');
269 | var div_drag = document.createElement('div');
270 | var div_resize = document.createElement('div');
271 | var temp_image_view = $("image_view");
272 | var e = addDiv ? addDiv : window.event;
273 | var temp_array = new Array();
274 |
275 | //正常
276 | if (arguments.length == 2) {
277 | div.id = divinfo[0];
278 | div.title = divinfo[1];
279 | div.className = "div-dnr";
280 | div.style.width = divinfo[2] + "px";
281 | div.style.height = divinfo[3] + "px";
282 | div.style.left = parseInt(divinfo[4]) + "px";
283 | div.style.top = parseInt(divinfo[5]) + "px";
284 | if (divinfo.length > 6) {
285 | temp_array[6] = divinfo[6];
286 | temp_array[7] = divinfo[7];
287 | }
288 | else {
289 | temp_array[6] = true;
290 | temp_array[7] = true;
291 | }
292 | }
293 | else {
294 | div.id = "div_" + rn;
295 | div.title = "div_" + rn;
296 | div.className = "div-dnr";
297 | div.style.width = default_width * num + "px";
298 | div.style.height = default_height * num + "px";
299 | div.style.left = e.offsetX - parseInt(default_width * num / 2) + parseInt(div_margin * num) + "px";
300 | div.style.top = e.offsetY - parseInt(default_height * num / 2) + parseInt(div_margin * num) + "px";
301 | temp_array[6] = true;
302 | temp_array[7] = true;
303 | }
304 |
305 | div_drag.id = "drag_" + rn;
306 | div_drag.className = "div-drag";
307 | div_drag.onmousedown = function () {
308 | startDrag(this, event)
309 | };
310 | div_drag.onmousemove = function () {
311 | drag(event)
312 | };
313 | div_drag.onmouseup = function () {
314 | stopDrag(event)
315 | };
316 |
317 | div_resize.id = "resize_" + rn;
318 | div_resize.className = "div-resize";
319 | div_resize.onmousedown = function () {
320 | startResize(this, event)
321 | };
322 | div_resize.onmousemove = function () {
323 | Resizing(event)
324 | };
325 | div_resize.onmouseup = function () {
326 | stopResize(event)
327 | };
328 |
329 | div.appendChild(div_drag);
330 | div.appendChild(div_resize);
331 | $("div_image_view").appendChild(div);
332 |
333 | checkxy(div.id);
334 |
335 | var temp = $(div.id);
336 | var temp_id = div.id;
337 | temp_array[0] = "" + temp_id + "";
338 | temp_array[1] = "" + temp.title + "";
339 | temp_array[2] = "" + parseInt(temp.style.width.replace("px", "") / num) + "";
340 | temp_array[3] = "" + parseInt(temp.style.height.replace("px", "") / num) + "";
341 | temp_array[4] = "" + parseInt(temp.style.left.replace("px", "") / num) + "";
342 | temp_array[5] = "" + parseInt(temp.style.top.replace("px", "") / num) + "";
343 |
344 | array_div[num_array_style] = temp_array[0];
345 | array_style[num_array_style++] = temp_array;
346 |
347 | $("bt_view_css").disabled = "";
348 | if (arguments.length == 1) {
349 | $("input_div_id").value = temp_id;
350 | reset_div_className();
351 | div_info(temp_id, 0, 0, 0, 0);
352 | $(temp_id).style.zIndex = ++index;
353 | if (show_new) {
354 | showNonceDiv("true");
355 | }
356 | }
357 | }
358 | }
359 |
360 | //设置当前层信息显示方式
361 | function setShowDiv() {
362 | var temp = arguments[0].target.data.item.name;
363 | var op = arguments[0].target.data.item.toggled;
364 |
365 | switch (temp) {
366 | case "show_new":
367 | if (!op) {
368 | show_new = false;
369 | }
370 | else {
371 | show_new = true;
372 | }
373 | break;
374 | case "show_nonce":
375 | if (!op) {
376 | show_nonce = false;
377 | }
378 | else {
379 | show_nonce = true;
380 | }
381 | break;
382 | }
383 | }
384 |
385 | //重置层的类名
386 | function reset_div_className() {
387 | var temp_lenght = array_style.length;
388 | for (var n = 0; n < temp_lenght; n++) {
389 | if ($(array_style[n][1])) {
390 | $(array_style[n][1]).className = "div-dnr";
391 | }
392 | }
393 | }
394 |
395 | //取得层位置
396 | function get_array_num(e) {
397 | var temp_lenght = array_div.length;
398 | for (var n = 0; n < temp_lenght; n++) {
399 | if (array_div[n] == e) {
400 | return n;
401 | }
402 | }
403 | }
404 |
405 | //修改留白
406 | function doEditDivMargin() {
407 | var temp = $("image_view").style.width;
408 | if (temp != 0) {
409 | $("button_div_margin_edit").disabled = "";
410 | }
411 | }
412 |
413 | //修改留白
414 | function editDivMargin() {
415 | var temp_margin = $("input_div_margin").value;
416 | if (temp_margin != div_margin) {
417 | div_margin = temp_margin;
418 | }
419 | else
420 | if (temp_margin == "") {
421 | div_margin = 0;
422 | $("input_div_margin").value = 0;
423 | }
424 | $("div_image").style.padding = div_margin * num;
425 | updataDivMagin();
426 | $("button_div_margin_edit").disabled = "true";
427 | }
428 |
429 | //检查输入
430 | function checkinput(e) {
431 | var temp = $("" + e + "");
432 | var temp_num = get_array_num(e);
433 | var temp_array = new Array();
434 |
435 | temp_array[1] = $("input_div_name").value;
436 | temp_array[2] = $("input_div_width").value;
437 | temp_array[3] = $("input_div_height").value;
438 | temp_array[4] = $("input_div_left").value;
439 | temp_array[5] = $("input_div_top").value;
440 |
441 | if (temp_array[1] == "") {
442 | $("input_div_name").value = array_style[temp_num][1];
443 | }
444 | if (temp_array[2] == "") {
445 | $("input_div_width").value = array_style[temp_num][2];
446 | }
447 | if (temp_array[3] == "") {
448 | $("input_div_height").value = array_style[temp_num][3];
449 | }
450 | if (temp_array[4] == "") {
451 | $("input_div_left").value = array_style[temp_num][4];
452 | }
453 | if (temp_array[5] == "") {
454 | $("input_div_top").value = array_style[temp_num][5];
455 | }
456 | }
457 |
458 | //检查坐标
459 | function checkxy(e) {
460 | var temp = $("" + e + "");
461 | var temp_div_width = parseInt(temp.style.width);
462 | var temp_div_height = parseInt(temp.style.height);
463 | var temp_div_left = parseInt(temp.style.left);
464 | var temp_div_top = parseInt(temp.style.top);
465 |
466 | if (temp.id.substr(0, 4) == "div_") {
467 | var temp_div_right = parseInt($("image_view").style.width) - temp_div_width + parseInt(div_margin * 2 * num);
468 | var temp_div_bottom = parseInt($("image_view").style.height) - temp_div_height + parseInt(div_margin * 2 * num);
469 | }
470 | else {
471 | var temp_div_right = parseInt($("div_image_view").offsetWidth) - parseInt(temp_div_width);
472 | var temp_div_bottom = parseInt($("div_image_view").offsetHeight) - parseInt(temp_div_height + 22);
473 | }
474 |
475 | if (read_end && temp_div_left < 0) {
476 | temp.style.left = 0;
477 | }
478 |
479 | if (temp_div_left > temp_div_right) {
480 | temp.style.left = Math.round(temp_div_right);
481 | }
482 |
483 | if (read_end && temp_div_top < 0) {
484 | temp.style.top = 0;
485 | }
486 |
487 | if (temp_div_top > temp_div_bottom) {
488 | temp.style.top = Math.round(temp_div_bottom);
489 | }
490 | }
491 |
492 | //检查大小
493 | function checkwh(e) {
494 | var temp = $("" + e + "");
495 | var temp_div_width = parseInt(temp.style.width);
496 | var temp_div_height = parseInt(temp.style.height);
497 | var temp_div_left = parseInt(temp.style.left);
498 | var temp_div_top = parseInt(temp.style.top);
499 | var temp_div_right = temp_div_left + temp_div_width;
500 | var temp_div_bottom = temp_div_top + temp_div_height;
501 | var temp_div_width = parseInt($("image_view").style.width) + parseInt(div_margin * 2 * num);
502 | var temp_div_height = parseInt($("image_view").style.height) + parseInt(div_margin * 2 * num);
503 | var temp_width = temp_div_width - temp_div_left;
504 | var temp_height = temp_div_height - temp_div_top;
505 |
506 | if (temp_div_right > temp_div_width) {
507 | temp.style.width = temp_width;
508 | }
509 | if (temp_div_bottom > temp_div_height) {
510 | temp.style.height = temp_height;
511 | }
512 | }
513 |
514 | //更新层信息
515 | function update_info(e) {
516 | var temp = $("" + e + "");
517 | if (temp.id.substr(0, 4) == "div_") {
518 | var temp_num = get_array_num(e);
519 | var temp_array = new Array();
520 |
521 | temp_array[0] = "" + e + "";
522 | temp_array[1] = $("input_div_name").value;
523 | temp_array[2] = $("input_div_width").value;
524 | temp_array[3] = $("input_div_height").value;
525 | temp_array[4] = $("input_div_left").value;
526 | temp_array[5] = $("input_div_top").value;
527 | temp_array[6] = $("checkbox_show_div_width").checked;
528 | temp_array[7] = $("checkbox_show_div_height").checked;
529 | array_style[temp_num] = temp_array;
530 |
531 | temp.title = temp_array[1];
532 | temp.style.width = Math.round(temp_array[2]) * num + "px";
533 | temp.style.height = Math.round(temp_array[3]) * num + "px";
534 | temp.style.left = Math.round(temp_array[4]) * num + div_margin * num + "px";
535 | temp.style.top = Math.round(temp_array[5]) * num + div_margin * num + "px";
536 | }
537 | }
538 |
539 | function checkNum(e) {
540 | if (e > 0) {
541 | return "-" + e + "px";
542 | }
543 | else
544 | if (e < 0) {
545 | e = e - e * 2;
546 | return e + "px";
547 | }
548 | else {
549 | return e;
550 | }
551 | }
552 |
553 | function checkType(fullpath) {
554 | var temp_path = fullpath.split("/");
555 | var temp_file = temp_path[temp_path.length - 1].split(".");
556 | if (temp_file[1]) {
557 | var type = temp_file[1];
558 |
559 | if (type != "xml") {
560 | temp_file[1] = "xml";
561 | var temp = temp_file.join(".");
562 | temp_path[temp_path.length - 1] = temp;
563 | temp = temp_path.join("/");
564 | return temp;
565 | }
566 | else {
567 | return fullpath;
568 | }
569 | }
570 | else {
571 | var temp = fullpath + ".xml";
572 | return temp;
573 | }
574 | }
575 |
576 | function div_info(e, t1, t2, t3, t4) {
577 | var temp = $("" + e + "");
578 | if (temp.id.substr(0, 4) == "div_") {
579 | $("input_div_id").value = temp.id;
580 | $("input_div_name").value = temp.title;
581 |
582 | if (num > 1) {
583 | $("input_div_width").value = Math.round(parseInt(temp.style.width) / num) + parseInt(t1);
584 | $("input_div_height").value = Math.round(parseInt(temp.style.height) / num) + parseInt(t2);
585 | $("input_div_left").value = Math.round(parseInt(temp.style.left) / num) - div_margin + parseInt(t3);
586 | $("input_div_top").value = Math.round(parseInt(temp.style.top) / num) - div_margin + parseInt(t4);
587 | }
588 | else {
589 | $("input_div_width").value = parseInt(temp.style.width) + parseInt(t1);
590 | $("input_div_height").value = parseInt(temp.style.height) + parseInt(t2);
591 | $("input_div_left").value = parseInt(temp.style.left) - div_margin + parseInt(t3);
592 | $("input_div_top").value = parseInt(temp.style.top) - div_margin + parseInt(t4);
593 | }
594 | $("checkbox_show_div_width").checked = show_divwh("width");
595 | $("checkbox_show_div_height").checked = show_divwh("height");
596 |
597 | temp.className = "div-dnr-now";
598 | $("button_div_edit").disabled = "true";
599 | $("button_div_del").disabled = "";
600 | $("button_copy_left").disabled = "";
601 | $("button_copy_top").disabled = "";
602 | $("button_copy_right").disabled = "";
603 | $("button_copy_bottom").disabled = "";
604 | $("input_copy_pyl").disabled = "";
605 | $("button_div_copy_width").disabled = "";
606 | $("button_div_copy_height").disabled = "";
607 | $("button_div_copy_left").disabled = "";
608 | $("button_div_copy_top").disabled = "";
609 | $("checkbox_copy_div_class").disabled = "";
610 | $("checkbox_copy_div_width").disabled = "";
611 | $("checkbox_copy_div_height").disabled = "";
612 | $("checkbox_show_div_width").disabled = "";
613 | $("checkbox_show_div_height").disabled = "";
614 | $("button_div_copy").disabled = "";
615 | }
616 | }
617 |
618 | //输出样式
619 | function view_css() {
620 | var temp = "";
621 | var temp_css = "";
622 | var temp_background = $("image_view").style.backgroundImage;
623 | var temp_background_value = $("input_bg_path").value;
624 | var temp_gbstyle = $("textarea_gb_class").value;
625 | var div = $("div_view_css");
626 | var temp_lenght = array_div.length;
627 | var checkbox_show_width = $("checkbox_show_width").checked;
628 | var checkbox_show_height = $("checkbox_show_height").checked;
629 | var radio_show_allwh = $("radio_show_allwh").checked;
630 |
631 | if (temp_background_value == "") {
632 | temp_background_value = "background:url(" + temp_background + ") no-repeat 0 0;";
633 | }
634 | else {
635 | temp_background_value = "background:url(" + temp_background_value + ") no-repeat 0 0;";
636 | }
637 |
638 | for (var n = 0; n < temp_lenght; n++) {
639 | if (array_div[n] != "") {
640 | temp += "." + array_style[n][1] + ",";
641 | }
642 | }
643 | if (temp != "") {
644 | temp = temp.replace(/,$/g, "");
645 | if (temp_gbstyle != "") {
646 | temp += "{\n" + temp_background_value + "\n" + temp_gbstyle + "\n}\n";
647 | }
648 | else {
649 | temp += "{" + temp_background_value + "}\n";
650 | }
651 | temp_css = temp;
652 | for (var n = 0; n < array_div.length; n++) {
653 | if (radio_show_allwh) {
654 | if (array_div[n] != "") {
655 | temp = "." + array_style[n][1] + "{";
656 |
657 | if (checkbox_show_width) {
658 | temp += "width:" + array_style[n][2] + "px;";
659 | }
660 | if (checkbox_show_height) {
661 | temp += "height:" + array_style[n][3] + "px;";
662 | }
663 |
664 | temp += "background-position:" + checkNum(array_style[n][4]);
665 | temp += " " + checkNum(array_style[n][5]);
666 | temp += ";}\n";
667 | temp_css = temp_css + temp;
668 | }
669 | }
670 | else {
671 | if (array_div[n] != "") {
672 | temp = "." + array_style[n][1] + "{";
673 |
674 | if (array_style[n][6]) {
675 | temp += "width:" + array_style[n][2] + "px;";
676 | }
677 | if (array_style[n][7]) {
678 | temp += "height:" + array_style[n][3] + "px;";
679 | }
680 |
681 | temp += "background-position:" + checkNum(array_style[n][4]);
682 | temp += " " + checkNum(array_style[n][5]);
683 | temp += ";}\n";
684 | temp_css = temp_css + temp;
685 | }
686 | }
687 | }
688 | div.innerText = temp_css;
689 | $("bt_copy_css").disabled = "";
690 | }
691 | else {
692 | div.innerText = "";
693 | $("bt_copy_css").disabled = "true";
694 | }
695 | showhide("pre_css_div");
696 | }
697 |
698 | //显示当前层宽高是否输出
699 | function show_divwh(op) {
700 | var temp = $("input_div_id").value;
701 |
702 | if (temp) {
703 | var n = get_array_num(temp);
704 | if (op == "width") {
705 | return array_style[n][6];
706 | }
707 | if (op == "height") {
708 | return array_style[n][7];
709 | }
710 | }
711 | }
712 |
713 | //设置当前层宽高是否输出
714 | function set_divwh() {
715 | var temp = $("input_div_id").value;
716 | var nonce = $(this.id).checked;
717 |
718 | if (temp) {
719 | var n = get_array_num(temp);
720 | switch (this.id) {
721 | case "checkbox_show_div_width":
722 | if (nonce) {
723 | array_style[n][6] = true;
724 | }
725 | else {
726 | array_style[n][6] = false;
727 | }
728 | break;
729 | case "checkbox_show_div_height":
730 | if (nonce) {
731 | array_style[n][7] = true;
732 | }
733 | else {
734 | array_style[n][7] = false;
735 | }
736 | break;
737 | }
738 | }
739 | }
740 |
741 | function doSave() {
742 | var docsDir = air.File.documentsDirectory;
743 | try {
744 | docsDir.browseForSave("Save As");
745 | docsDir.addEventListener(air.Event.SELECT, doSaveSet);
746 | }
747 | catch (error) {
748 | air.trace("Failed:", error.message)
749 | }
750 | }
751 |
752 | function doSaveSet(event) {
753 | view_css();
754 | var newFile = event.target;
755 | newFile.url = "" + checkType(event.target.url) + "";
756 |
757 | var stream = new air.FileStream();
758 | stream.open(newFile, air.FileMode.WRITE);
759 |
760 | var temp_gbstyle = $("textarea_gb_class").value;
761 | var cr = air.File.lineEnding;
762 | temp_gbstyle.replace("\n", cr);
763 | image_width.replace("px", "");
764 | image_height.replace("px", "");
765 | var note = '' + cr +
766 | '' +
767 | cr +
768 | '3' +
769 | cr +
770 | '' +
771 | cr +
772 | '' +
773 | file_path +
774 | '' +
775 | cr +
776 | '' +
777 | image_width +
778 | '' +
779 | cr +
780 | '' +
781 | image_height +
782 | '' +
783 | cr +
784 | '' +
785 | div_margin +
786 | '' +
787 | cr +
788 | '' +
789 | temp_gbstyle +
790 | '' +
791 | cr +
792 | '';
793 |
794 | var temp_style = array_style;
795 |
796 | for (var n = 0; n < array_div.length; n++) {
797 | if (array_div[n] != "") {
798 | note += ' ' + cr + '' + array_style[n][0] + '' + cr + '' + array_style[n][1] + '' + cr + '' + array_style[n][2] + '' + cr + '' + array_style[n][3] + '' + cr + '' + array_style[n][4] + '' + cr + '' + array_style[n][5] + '' + cr + '' + array_style[n][6] + '' + cr + '' + array_style[n][7] + '' + cr + '';
799 | }
800 | }
801 |
802 | note += cr + '';
803 |
804 | stream.writeUTFBytes(note);
805 | stream.close();
806 |
807 | }
808 |
809 | //开始拖动
810 | function startDrag(obj, evt) {
811 | e = evt ? evt : window.event;
812 | if (true) {
813 | window.captureEvents(Event.MOUSEMOVE | Event.MOUSEUP);
814 |
815 | var win = obj.parentNode;//取得父窗体
816 | objId = obj.id;
817 | objParentId = win.id;
818 |
819 | if (objParentId.substr(0, 4) == "div_") {
820 | var temp_id = $("input_div_id").value;
821 | if (temp_id) {
822 | $(temp_id).className = "div-dnr";
823 | }
824 |
825 | div_info(objParentId, 0, 0, 0, 0);
826 | win.style.zIndex = ++index;//设置父窗体的Z轴值
827 | }
828 |
829 | x = parseInt(e.clientX);//取得当前鼠标的X坐标
830 | y = parseInt(e.clientY);//取得当前鼠标的Y坐标
831 | x1 = parseInt(win.style.left);//将父窗体的距浏览器左边界的距离转换为NUMBER
832 | y1 = parseInt(win.style.top);//将父窗体的距浏览器上边界的距离转换为NUMBER
833 | moveable = true;
834 | if (show_nonce) {
835 | showNonceDiv("true");
836 | }
837 | }
838 | }
839 |
840 | function drag(evt) {
841 | e = evt ? evt : window.event;
842 | if (moveable) {
843 | var win = $("" + objParentId + "");
844 | win.style.left = parseInt(x1 + e.clientX - x);
845 | win.style.top = parseInt(y1 + e.clientY - y);
846 | checkxy(objParentId);
847 | div_info(objParentId, 0, 0, 0, 0);
848 | }
849 | }
850 |
851 | //停止拖动
852 | function stopDrag(event) {
853 | var obj = $("" + objId + "");
854 | if (moveable) {
855 | e.preventDefault();
856 | document.addEventListener("mouseup", stopDrag, true);
857 | document.addEventListener("mousemove", drag, true);
858 |
859 | update_info(objParentId);
860 |
861 | moveable = false;
862 | objId = "";
863 | objParentId = "";
864 | }
865 | }
866 |
867 | //开始缩放
868 | function startResize(obj, evt) {
869 | var e = evt;
870 |
871 | e.preventDefault();
872 | document.addEventListener("mouseup", stopResize, true);
873 | document.addEventListener("mousemove", Resizing, true);
874 |
875 | var win = obj.parentNode;
876 | objId = obj.id;
877 | objParentId = win.id;
878 | win.style.zIndex = ++index;
879 | x = parseInt(e.screenX);
880 | y = parseInt(e.screenY);
881 | x1 = parseInt(win.style.width);
882 | y1 = parseInt(win.style.height);
883 | resizeable = true;
884 | }
885 |
886 | function Resizing(evt) {
887 | var e = evt ? evt : window.event;
888 |
889 | if (resizeable) {
890 | var win = $("" + objParentId + "");
891 | win.style.width = parseInt(x1 + e.screenX - x) + "px";
892 | win.style.height = parseInt(y1 + e.screenY - y) + "px";
893 | checkwh(objParentId);
894 | div_info(objParentId, 0, 0, 0, 0);
895 | }
896 | }
897 |
898 | //停止缩放
899 | function stopResize(evt) {
900 | var obj = $("" + objId + "");
901 | if (resizeable) {
902 | document.removeEventListener("mouseup", stopResize, true);
903 | document.removeEventListener("mousemove", Resizing, true);
904 |
905 | update_info(objParentId);
906 | resizeable = false;
907 | objId = "";
908 | objParentId = "";
909 | }
910 | }
911 |
912 | //更改图片底色
913 | function image_color(n) {
914 | var img = $("image_view");
915 | img.style.backgroundColor = "#" + n;
916 | }
917 |
918 | //图片缩放
919 | function image_x(n) {
920 | var img_div = $("div_image_view");
921 | var img = $("image_view");
922 |
923 | if (n != "" && n > 0) {
924 | num = parseInt(n);
925 |
926 | if (num > 1) {
927 | if (image_path[num]) {
928 | img.src = image_path[num];
929 | }
930 | else {
931 | if (image.width * num < 8192 && image.height * num < 8192) {
932 | var bmp = new air.BitmapData(image.width * num, image.height * num, true, 0x00000000);
933 | var temp = air.File.createTempFile();
934 | var desktop = null;
935 | var matrix = new air.Matrix();
936 | var stream = new air.FileStream();
937 | var div = null;
938 | var elem = null;
939 |
940 | matrix.scale(num, num);
941 | bmp.draw(image.content, matrix);
942 |
943 | png = runtime.com.adobe.images.PNGEncoder.encode(bmp);
944 |
945 | stream.open(temp, air.FileMode.WRITE);
946 | stream.writeBytes(png, 0, 0);
947 | stream.close();
948 | image_path[num] = img.src = temp.url;
949 | }
950 | else {
951 | img.src = image_path[0];
952 | }
953 | }
954 | }
955 | else {
956 | img.src = image_path[0];
957 | }
958 | img.style.width = parseInt(image_width) * num + "px";
959 | img.style.height = parseInt(image_height) * num + "px";
960 |
961 |
962 |
963 | $("div_image").style.padding = div_margin * num;
964 |
965 | var temp = 0;
966 | var temp_lenght = array_div.length;
967 |
968 | for (var n = 0; n < temp_lenght; n++) {
969 | if (array_div[n] != "") {
970 | temp++;
971 | }
972 | }
973 | if (temp > 0) {
974 | for (var n = 0; n < temp_lenght; n++) {
975 | if (array_div[n] != "") {
976 | $(array_style[n][0]).style.width = array_style[n][2] * num + "px";
977 | $(array_style[n][0]).style.height = array_style[n][3] * num + "px";
978 | $(array_style[n][0]).style.left = parseInt(array_style[n][4]) * num + div_margin * num + "px";
979 | $(array_style[n][0]).style.top = parseInt(array_style[n][5]) * num + div_margin * num + "px";
980 | }
981 | }
982 | resetDivXY();
983 | }
984 |
985 | }
986 | else {
987 | num = 1;
988 | }
989 | }
990 |
991 | //当前层在窗口内显示
992 | function resetDivXY() {
993 | var img_div = $("div_image_view");
994 | var nonce_div = $("input_div_id").value;
995 | if (nonce_div != "") {
996 | nonce_div = $("" + nonce_div + "");
997 | if (nonce_div.offsetLeft > img_div.clientWidth) {
998 | img_div.scrollLeft = parseInt(nonce_div.offsetLeft) - parseInt(img_div.clientWidth / 2) + parseInt(nonce_div.clientWidth / 2);
999 | }
1000 | else {
1001 | img_div.scrollLeft = parseInt(nonce_div.offsetLeft) - parseInt(img_div.clientWidth / 2) + parseInt(nonce_div.clientWidth / 2);
1002 | }
1003 | if (nonce_div.offsetTop > img_div.clientHeight) {
1004 | img_div.scrollTop = parseInt(nonce_div.offsetTop) - parseInt(img_div.clientHeight / 2) + parseInt(nonce_div.clientHeight / 2);
1005 | }
1006 | else {
1007 | img_div.scrollTop = parseInt(nonce_div.offsetTop) - parseInt(img_div.clientHeight / 2) + parseInt(nonce_div.clientHeight / 2);
1008 | }
1009 | }
1010 | }
1011 |
1012 | function updataDivMagin() {
1013 | var temp_margin = $("input_div_margin").value;
1014 | var temp = 0;
1015 | var temp_lenght = array_div.length;
1016 |
1017 | for (var n = 0; n < temp_lenght; n++) {
1018 | if (array_div[n] != "") {
1019 | temp++;
1020 | }
1021 | }
1022 | if (temp > 0) {
1023 | for (var n = 0; n < array_div.length; n++) {
1024 | if (array_div[n] != "") {
1025 | $(array_style[n][0]).style.left = parseInt(array_style[n][4]) * num + div_margin * num + "px";
1026 | $(array_style[n][0]).style.top = parseInt(array_style[n][5]) * num + div_margin * num + "px";
1027 | checkxy(array_style[n][0]);
1028 | }
1029 | }
1030 | }
1031 | }
1032 |
1033 | //显示隐藏层
1034 | function showhide(e, op) {
1035 | var temp_div = $("" + e + "");
1036 | if (temp_div) {
1037 | var display = "blcok";
1038 | if (op != "true") {
1039 | display = temp_div.style.display;
1040 | }
1041 | switch (display) {
1042 | case "block":
1043 | temp_div.style.display = "none";
1044 | break;
1045 | default:
1046 | temp_div.style.display = "block";
1047 | break;
1048 | }
1049 | }
1050 | }
1051 |
1052 | //显示隐藏当前层
1053 | function showNonceDiv(op) {
1054 | checkxy('nonce_div');
1055 | showhide('nonce_div', op);
1056 | }
1057 |
1058 | //显示隐藏生成样式层
1059 | function showSaveDiv() {
1060 | showhide('save_css_div');
1061 | }
1062 |
1063 | //显示隐藏操作层
1064 | function showOpDiv() {
1065 | showhide('op_div');
1066 | }
1067 |
1068 | //打开窗口
1069 | function menuOpenWin() {
1070 | var op = arguments[0].target.data.item.name;
1071 |
1072 | switch (op) {
1073 | case "allDiv":
1074 | doWindow('divlist.html', 'width=600,height=600,top=100,scrollbars=yes');
1075 | break;
1076 | case "about":
1077 | doWindow('about.html', 'width=460,height=360,scrollbars=yes');
1078 | break;
1079 | case "help":
1080 | doWindow('help.html', 'width=700,height=600,top=100,scrollbars=yes');
1081 | break;
1082 | default:
1083 | break;
1084 | }
1085 | }
1086 |
1087 | //初始化页面
1088 | function doLoad() {
1089 | //菜单
1090 | var menu = air.ui.Menu.createFromJSON("lib/menus/menu.js");
1091 | air.ui.Menu.setAsMenu(menu);
1092 | var menu1 = air.ui.Menu.createFromJSON("lib/menus/menu2.js");
1093 | air.ui.Menu.setAsContextMenu(menu1, "div_image_view");
1094 |
1095 | $('button_div_del').addEventListener('click', delDiv);
1096 | $('button_div_edit').addEventListener('click', editDiv);
1097 | $('button_div_margin_edit').addEventListener('click', editDivMargin);
1098 | $('input_div_margin').addEventListener('focus', doEditDivMargin);
1099 |
1100 | $('bt_copy_css').addEventListener('click', doCopyCss);
1101 | $('button_div_copy_width').addEventListener('click', doCopyDivCss);
1102 | $('button_div_copy_height').addEventListener('click', doCopyDivCss);
1103 | $('button_div_copy_left').addEventListener('click', doCopyDivCss);
1104 | $('button_div_copy_top').addEventListener('click', doCopyDivCss);
1105 | $('button_div_copy').addEventListener('click', doCopyDivCss);
1106 | $('button_div_copy_wh').addEventListener('click', doCopyDivCss);
1107 | $('button_div_copy_xy').addEventListener('click', doCopyDivCss);
1108 | $('button_copy_left').addEventListener('click', doCopyDiv);
1109 | $('button_copy_top').addEventListener('click', doCopyDiv);
1110 | $('button_copy_right').addEventListener('click', doCopyDiv);
1111 | $('button_copy_bottom').addEventListener('click', doCopyDiv);
1112 |
1113 | $('checkbox_copy_div_class').checked = "";
1114 | $('checkbox_copy_div_width').checked = "";
1115 | $('checkbox_copy_div_height').checked = "";
1116 | $('checkbox_show_div_width').addEventListener('click', set_divwh);
1117 | $('checkbox_show_div_height').addEventListener('click', set_divwh);
1118 |
1119 | image = new air.Loader();
1120 | image.contentLoaderInfo.addEventListener(air.Event.COMPLETE, doComplete);
1121 |
1122 | file = air.File.applicationDirectory;
1123 | file.addEventListener(air.Event.SELECT, doSelectImg);
1124 |
1125 | file_xml = air.File.applicationDirectory;
1126 | file_xml.addEventListener(air.Event.SELECT, doSelectXml);
1127 |
1128 | $('bt_view_css').addEventListener('click', view_css);
1129 |
1130 | $('input_div_name').addEventListener('focus', doEdit);
1131 | $('input_div_width').addEventListener('focus', doEdit);
1132 | $('input_div_height').addEventListener('focus', doEdit);
1133 | $('input_div_left').addEventListener('focus', doEdit);
1134 | $('input_div_top').addEventListener('focus', doEdit);
1135 |
1136 | $('image_view').addEventListener('dblclick', addDiv);
1137 | }
1138 |
1139 | //快捷键
1140 | function keyDown(e) {
1141 | var e = event ? event : window.event.getEvent();
1142 | var key = runtime.flash.ui.Keyboard;
1143 | var temp_img = $("image_view").src;
1144 | var temp_div = $("input_div_id").value;
1145 | var key_ctrl = e.ctrlKey;
1146 | var key_alt = e.altKey;
1147 | var key_shift = e.shiftKey;
1148 |
1149 | if (temp_img != "") {
1150 | if (key_ctrl) {
1151 | switch (event.keyCode) {
1152 | case key.NUMBER_0:
1153 | case key.NUMPAD_1:
1154 | image_x(1);
1155 | break;
1156 | case key.NUMBER_2:
1157 | case key.NUMPAD_2:
1158 | image_x(2);
1159 | break;
1160 | case key.NUMBER_4:
1161 | case key.NUMPAD_4:
1162 | image_x(4);
1163 | break;
1164 | case key.NUMBER_6:
1165 | case key.NUMPAD_6:
1166 | image_x(6);
1167 | break;
1168 | }
1169 | }
1170 | }
1171 | if (event.keyCode == 116) {
1172 | refreshPic();
1173 | }
1174 | if (temp_div != "") {
1175 | //alert("ASCII代码是:"+event.keyCode);
1176 | if (event.keyCode == key.DELETE || event.keyCode == 15 && event.keyCode == 8) {
1177 | delDiv(event, temp_div);
1178 | }
1179 | if (key_shift && key_ctrl) {
1180 | switch (event.keyCode) {
1181 | case 38:
1182 | div_info(temp_div, 0, -1, 0, 0);
1183 | update_info(temp_div);
1184 | checkwh(temp_div);
1185 | break;
1186 | case 40:
1187 | div_info(temp_div, 0, 1, 0, 0);
1188 | update_info(temp_div);
1189 | checkwh(temp_div);
1190 | break;
1191 | case 37:
1192 | div_info(temp_div, -1, 0, 0, 0);
1193 | update_info(temp_div);
1194 | checkwh(temp_div);
1195 | break;
1196 | case 39:
1197 | div_info(temp_div, 1, 0, 0, 0);
1198 | update_info(temp_div);
1199 | checkwh(temp_div);
1200 | break;
1201 | }
1202 | }
1203 | else
1204 | if (!key_shift && key_ctrl) {
1205 | switch (event.keyCode) {
1206 | case 38:
1207 | div_info(temp_div, 0, 0, 0, -1);
1208 | update_info(temp_div);
1209 | checkxy(temp_div);
1210 | break;
1211 | case 40:
1212 | div_info(temp_div, 0, 0, 0, 1);
1213 | update_info(temp_div);
1214 | checkxy(temp_div);
1215 | break;
1216 | case 37:
1217 | div_info(temp_div, 0, 0, -1, 0);
1218 | update_info(temp_div);
1219 | checkxy(temp_div);
1220 | break;
1221 | case 39:
1222 | div_info(temp_div, 0, 0, 1, 0);
1223 | update_info(temp_div);
1224 | checkxy(temp_div);
1225 | break;
1226 | }
1227 | }
1228 | }
1229 | }
1230 |
1231 | /*
1232 | * 打开新窗口
1233 | */
1234 | function doWindow(page, info) {
1235 | /*
1236 | var init = new air.NativeWindowInitOptions();
1237 | var bounds = null;
1238 | var win = null;
1239 | var page = air.File.applicationDirectory.resolvePath( page );
1240 | bounds = new air.Rectangle( ( air.Capabilities.screenResolutionX - 325 ) / 2, ( air.Capabilities.screenResolutionY - 145 ) / 2, 325, 145 );
1241 | init.minimizable = false;
1242 | init.maximizable = false;
1243 | init.resizable = false;
1244 |
1245 | win = air.HTMLLoader.createRootWindow( true, init, false, bounds );
1246 | win.load( new air.URLRequest( page.url ) );
1247 | */
1248 | var login = window.open(page, null, info);
1249 | }
1250 |
1251 | function doCopyDiv() {
1252 | var id = this.id;
1253 | var rn = Math.round(Math.random() * 10000);
1254 | var temp = $("input_div_id").value;
1255 | var n = get_array_num(temp);
1256 | var temp_id = temp_name = "div_" + rn;
1257 | var temp_width = parseInt(array_style[n][2]) * num;
1258 | var temp_height = parseInt(array_style[n][3]) * num;
1259 | var temp_left = parseInt(array_style[n][4]) * num + div_margin * num;
1260 | var temp_top = parseInt(array_style[n][5]) * num + div_margin * num;
1261 | var temp_array = new Array();
1262 | var pyl = $("input_copy_pyl").value;
1263 |
1264 | if (pyl == "") {
1265 | pyl = default_width * num;
1266 | }
1267 | else {
1268 | pyl = pyl * num;
1269 | }
1270 | switch (id) {
1271 | case "button_copy_left":
1272 | temp_left = temp_left - pyl;
1273 | break;
1274 | case "button_copy_top":
1275 | temp_top = temp_top - pyl;
1276 | break;
1277 | case "button_copy_right":
1278 | temp_left = temp_left + pyl;
1279 | break;
1280 | case "button_copy_bottom":
1281 | temp_top = temp_top + pyl;
1282 | break;
1283 | }
1284 |
1285 | temp_array = [temp_id, temp_name, temp_width, temp_height, temp_left, temp_top];
1286 | addDiv(temp_array, addDiv);
1287 | $(temp).className = "div-dnr";
1288 | div_info(temp_id, 0, 0, 0, 0);
1289 | update_info(temp_id);
1290 | }
1291 |
1292 | //复制当前层样式
1293 | function doCopyDivCss(event) {
1294 | var temp_id = this.id;
1295 | var temp = $("input_div_id").value;
1296 | var n = get_array_num(temp);
1297 | var checkbox_show_class = $("checkbox_copy_div_class").checked;
1298 | var checkbox_show_width = $("checkbox_copy_div_width").checked;
1299 | var checkbox_show_height = $("checkbox_copy_div_height").checked;
1300 | var copy = "";
1301 |
1302 | if (temp != "") {
1303 | checkinput(temp);
1304 | switch (temp_id) {
1305 | case "button_div_copy_width":
1306 | copy = "width:" + array_style[n][2] + "px;";
1307 | break;
1308 | case "button_div_copy_height":
1309 | copy = "height:" + array_style[n][3] + "px;";
1310 | break;
1311 | case "button_div_copy_left":
1312 | copy = (0 - array_style[n][4]) + "px";
1313 | break;
1314 | case "button_div_copy_top":
1315 | copy = (0 - array_style[n][5]) + "px";
1316 | break;
1317 | case "button_div_copy":
1318 | if (checkbox_show_class) {
1319 | copy = "." + array_style[n][1] + "{";
1320 | }
1321 | if (checkbox_show_width) {
1322 | copy += "width:" + array_style[n][2] + "px;";
1323 | }
1324 | if (checkbox_show_height) {
1325 | copy += "height:" + array_style[n][3] + "px;";
1326 | }
1327 | copy += "background-position:" + checkNum(array_style[n][4]) + " " + checkNum(array_style[n][5]) + ";";
1328 | if (checkbox_show_class) {
1329 | copy += "}\n";
1330 | }
1331 | break;
1332 | case "button_div_copy_wh":
1333 | copy += "width:" + array_style[n][2] + "px;height:" + array_style[n][3] + "px;";
1334 | break;
1335 | case "button_div_copy_xy":
1336 | copy += checkNum(array_style[n][4]) + " " + checkNum(array_style[n][5]);
1337 | break;
1338 | }
1339 | }
1340 |
1341 | air.Clipboard.generalClipboard.clear();
1342 | air.Clipboard.generalClipboard.setData(air.ClipboardFormats.TEXT_FORMAT, copy);
1343 | doTimer("样式 " + copy + " 已复制到剪贴板!");
1344 | }
1345 |
1346 | //复制所有样式
1347 | function doCopyCss(v) {
1348 | var copy = $("div_view_css").innerText;
1349 | air.Clipboard.generalClipboard.clear();
1350 | air.Clipboard.generalClipboard.setData(air.ClipboardFormats.TEXT_FORMAT, copy);
1351 | doTimer("样式复制成功!");
1352 | }
1353 |
1354 | //刷新图片
1355 | function refreshPic() {
1356 | if ($("image_view").src != "") {
1357 | image.load(new air.URLRequest(image_url));
1358 | file_path = image_url.replace("file:///", "");
1359 | doComplete(event);
1360 | }
1361 | }
1362 |
1363 | function doTimer(txt) {
1364 | $("hint_txt").style.display = "block";
1365 | $("hint_txt").innerText = txt;
1366 | setTimeout(function () { $("hint_txt").style.display = "none" }, 1500);
1367 | }
1368 |
1369 | //读取设置
1370 | function doCompleteXml() {
1371 | xml = new XMLHttpRequest();
1372 |
1373 | xml.onreadystatechange = function () {
1374 | read_end = false;
1375 | var version = null;
1376 | var imginfo = null;
1377 | var divinfo = null;
1378 | var temp_path = null;
1379 | var temp_id = null;
1380 | var temp_name = null;
1381 | var temp_width = null;
1382 | var temp_height = null;
1383 | var temp_left = null;
1384 | var temp_top = null;
1385 | var temp_set_width = null;
1386 | var temp_set_height = null;
1387 | var temp_array = new Array();
1388 | var temp_array_div = new Array();
1389 | image_path.length = 0;
1390 |
1391 | if (xml.readyState == 4) {
1392 | imginfo = xml.responseXML.documentElement.getElementsByTagName('imginfo');
1393 | divinfo = xml.responseXML.documentElement.getElementsByTagName('divinfo');
1394 | version = xml.responseXML.documentElement.getElementsByTagName('version');
1395 |
1396 | image_path[0] = temp_path = imginfo[0].getElementsByTagName('path')[0].textContent;
1397 | temp_width = imginfo[0].getElementsByTagName('width')[0].textContent;
1398 | temp_height = imginfo[0].getElementsByTagName('height')[0].textContent;
1399 | $("input_div_margin").value = div_margin = imginfo[0].getElementsByTagName('margin')[0].textContent;
1400 | $("textarea_gb_class").value = imginfo[0].getElementsByTagName('gbstyle')[0].textContent;
1401 |
1402 | temp_array_div = [temp_path, temp_width, temp_height]
1403 | doComplete(event, temp_array_div);
1404 | if (version == "3") {
1405 | for (var c = 0; c < divinfo.length; c++) {
1406 | temp_id = divinfo[c].getElementsByTagName('id')[0].textContent;
1407 | temp_name = divinfo[c].getElementsByTagName('name')[0].textContent;
1408 | temp_width = divinfo[c].getElementsByTagName('width')[0].textContent;
1409 | temp_height = divinfo[c].getElementsByTagName('height')[0].textContent;
1410 | temp_left = divinfo[c].getElementsByTagName('left')[0].textContent;
1411 | temp_top = divinfo[c].getElementsByTagName('top')[0].textContent;
1412 | temp_set_width = divinfo[c].getElementsByTagName('setWidth')[0].textContent;
1413 | temp_set_height = divinfo[c].getElementsByTagName('setHeight')[0].textContent;
1414 |
1415 | temp_array[c] = [temp_id, temp_name, temp_width, temp_height, temp_left, temp_top, temp_set_width, temp_set_height];
1416 | }
1417 | }
1418 | else {
1419 | for (var c = 0; c < divinfo.length; c++) {
1420 | temp_id = divinfo[c].getElementsByTagName('id')[0].textContent;
1421 | temp_name = divinfo[c].getElementsByTagName('name')[0].textContent;
1422 | temp_width = divinfo[c].getElementsByTagName('width')[0].textContent;
1423 | temp_height = divinfo[c].getElementsByTagName('height')[0].textContent;
1424 | temp_left = divinfo[c].getElementsByTagName('left')[0].textContent;
1425 | temp_top = divinfo[c].getElementsByTagName('top')[0].textContent;
1426 |
1427 | temp_array[c] = [temp_id, temp_name, temp_width, temp_height, temp_left, temp_top];
1428 | }
1429 | }
1430 | $("div_view_css").innerText = "";
1431 | temp_path = "file:///" + temp_path;
1432 | image.load(new air.URLRequest(temp_path));
1433 | setDiv(temp_array);
1434 | }
1435 | read_end = true;
1436 | }
1437 | xml.open('GET', file_xml.url, true);
1438 | xml.send(null);
1439 | }
1440 |
1441 | function setDiv(e) {
1442 | for (var c = 0; c < array_div.length; c++) {
1443 | if (array_div[c] != "") {
1444 | delDiv(event, array_div[c]);
1445 | }
1446 | }
1447 |
1448 | array_div.length = 0;
1449 | array_style.length = 0;
1450 | num_array_style = 0;
1451 | image_x(1);
1452 |
1453 | for (var c = 0; c < e.length; c++) {
1454 | array_div[c] = e[c][0];
1455 | addDiv(e[c], addDiv);
1456 | }
1457 | updataDivMagin();
1458 | }
1459 |
1460 | function delAll() {
1461 | for (var c = 0; c < array_div.length; c++) {
1462 | if (array_div[c] != "") {
1463 | delDiv(event, array_div[c]);
1464 | }
1465 | }
1466 |
1467 | array_div.length = 0;
1468 | array_style.length = 0;
1469 | num_array_style = 0;
1470 | }
1471 |
1472 | /*
1473 | 用于其它页面调用
1474 | */
1475 | function div_list() {
1476 | var temp = new Array();
1477 | var temp_lenght = array_div.length;
1478 | for (var n = 0; n < temp_lenght; n++) {
1479 | if (array_div[n] != "") {
1480 | temp[n] = array_style[n];
1481 | }
1482 | }
1483 |
1484 | return temp;
1485 | }
1486 |
1487 | function div_list_del(e) {
1488 | delDiv(event, e);
1489 | }
1490 |
1491 | function reset_div_class() {
1492 | var temp_div = $("input_div_id").value;
1493 | if (temp_div) {
1494 | temp_div = $(temp_div);
1495 | temp_div.className = "div-dnr";
1496 | }
1497 | }
1498 |
1499 | function checkUpdates() {
1500 | openInBrowser("https://github.com/ghostzhang/bg2css/releases")
1501 | }
--------------------------------------------------------------------------------
/lib/menus/menu.js:
--------------------------------------------------------------------------------
1 | [{
2 | label: "文件",
3 | items: [{
4 | label: "选择图片",
5 | keyEquivalent: "O",
6 | onSelect: doBrowseImg
7 | }, {
8 | label: "读取定义文件",
9 | keyEquivalent: "O",
10 | shiftKey: true,
11 | onSelect: doBrowseXml
12 | }, {
13 | type: "separator"
14 | }, {
15 | label: "保存当前定义",
16 | keyEquivalent: "S",
17 | onSelect: doSave
18 | }]
19 | }, {
20 | label: "图层",
21 | items: [{
22 | label: "显示|隐藏“当前层信息”",
23 | keyEquivalent: "N",
24 | onSelect: showNonceDiv
25 | }, {
26 | label: "显示|隐藏“所有层信息”",
27 | keyEquivalent: "N",
28 | shiftKey: true,
29 | name: "allDiv",
30 | onSelect: menuOpenWin
31 | }]
32 | }, {
33 | label: "操作",
34 | items: [{
35 | label: "刷新图片",
36 | toggled: "true",
37 | onSelect: refreshPic
38 | }, {
39 | type: "separator"
40 | },{
41 | label: "新建层时显示“当前层信息”",
42 | type: "check",
43 | name: "show_new",
44 | toggled: "true",
45 | onSelect: setShowDiv
46 | }, {
47 | label: "选中层时显示“当前层信息”",
48 | type: "check",
49 | name: "show_nonce",
50 | toggled: "true",
51 | onSelect: setShowDiv
52 | }, {
53 | type: "separator"
54 | }, {
55 | label: "显示|隐藏“区定义”",
56 | keyEquivalent: "M",
57 | onSelect: showOpDiv
58 | }, {
59 | type: "separator"
60 | }, {
61 | label: "生成样式",
62 | keyEquivalent: "P",
63 | onSelect: showSaveDiv
64 | }, {
65 | label: "样式预览",
66 | shiftKey: true,
67 | keyEquivalent: "P",
68 | onSelect: view_css
69 | }]
70 | }, {
71 | label: "帮助",
72 | items: [{
73 | label: "关于...",
74 | name: "about",
75 | onSelect: menuOpenWin
76 | }, {
77 | label: "快捷键...",
78 | name: "help",
79 | onSelect: menuOpenWin
80 | }, {
81 | type: "separator"
82 | }, {
83 | label: "检查更新...",
84 | onSelect: checkUpdates
85 | }]
86 | }]
87 |
--------------------------------------------------------------------------------
/lib/menus/menu2.js:
--------------------------------------------------------------------------------
1 | [{
2 | label: "显示|隐藏“当前层信息”",
3 | toggled: "false",
4 | keyEquivalent: "N",
5 | onSelect: showNonceDiv
6 | }, {
7 | label: "显示|隐藏“所有层信息",
8 | keyEquivalent: "N",
9 | shiftKey: true,
10 | name: "allDiv",
11 | onSelect: menuOpenWin
12 | }, {
13 | type: "separator"
14 | }, {
15 | label: "显示|隐藏“区定义”",
16 | keyEquivalent: "M",
17 | onSelect: showOpDiv
18 | }, {
19 | label: "生成样式",
20 | keyEquivalent: "P",
21 | onSelect: showSaveDiv
22 | }]
23 |
--------------------------------------------------------------------------------