concrete 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +32 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +87 -0
- data/concrete/basic_inline_editor.js +73 -0
- data/concrete/clipboard.js +72 -0
- data/concrete/concrete.js +58 -0
- data/concrete/constraint_checker.js +297 -0
- data/concrete/editor.js +964 -0
- data/concrete/element_extension.js +68 -0
- data/concrete/external_identifier_provider.js +112 -0
- data/concrete/helper.js +63 -0
- data/concrete/identifier_provider.js +168 -0
- data/concrete/inline_editor.js +55 -0
- data/concrete/metamodel_provider.js +171 -0
- data/concrete/model_interface.js +429 -0
- data/concrete/scroller.js +106 -0
- data/concrete/selector.js +302 -0
- data/concrete/template_provider.js +141 -0
- data/concrete/ui/abstract_dialog.js +80 -0
- data/concrete/ui/concrete_ui.js +28 -0
- data/concrete/ui/create_module_dialog.js +55 -0
- data/concrete/ui/images/close.png +0 -0
- data/concrete/ui/images/document-new.png +0 -0
- data/concrete/ui/images/document-save.png +0 -0
- data/concrete/ui/images/edit-find-replace.png +0 -0
- data/concrete/ui/images/emblem-symbolic-link.png +0 -0
- data/concrete/ui/images/help-browser.png +0 -0
- data/concrete/ui/images/minus_11px.png +0 -0
- data/concrete/ui/images/plus_11px.png +0 -0
- data/concrete/ui/images/preferences-system.png +0 -0
- data/concrete/ui/images/process-stop.png +0 -0
- data/concrete/ui/images/system-search.png +0 -0
- data/concrete/ui/layout_manager.js +54 -0
- data/concrete/ui/module_browser.js +88 -0
- data/concrete/ui/module_editor.js +217 -0
- data/concrete/ui/open_element_dialog.js +90 -0
- data/concrete/ui/preferences_dialog.js +75 -0
- data/concrete/ui/proceed_dialog.js +52 -0
- data/concrete/ui/search_replace_dialog.js +323 -0
- data/concrete/ui/style.css +296 -0
- data/concrete/ui/toolbar.js +74 -0
- data/concrete/ui/workbench.js +165 -0
- data/doc/concrete_developers_guide.html +1054 -0
- data/doc/concrete_developers_guide.txt +502 -0
- data/doc/concrete_users_guide.html +694 -0
- data/doc/concrete_users_guide.txt +223 -0
- data/example/formula_editor/example_data/example1.json +11 -0
- data/example/formula_editor/formula_editor.html +83 -0
- data/example/formula_editor/sqrt_horz.png +0 -0
- data/example/formula_editor/sqrt_vert.png +0 -0
- data/example/formula_editor/style.css +31 -0
- data/example/metamodel_editor/edit.rb +54 -0
- data/example/metamodel_editor/example_data/formula_metamodel.json +18 -0
- data/example/metamodel_editor/example_data/meta_metamodel.json +22 -0
- data/example/metamodel_editor/example_data/statemachine_metamodel.json +32 -0
- data/example/metamodel_editor/metamodel_editor.html +120 -0
- data/example/metamodel_editor/metamodel_editor2.html +135 -0
- data/example/metamodel_editor/metamodel_editor3.html +151 -0
- data/example/metamodel_editor/style.css +8 -0
- data/example/metamodel_editor/style2.css +19 -0
- data/example/metamodel_editor/style3.css +35 -0
- data/example/minimal_editor/minimal_editor.html +43 -0
- data/example/statemachine_editor/example_data/example1.json +11 -0
- data/example/statemachine_editor/state_background.png +0 -0
- data/example/statemachine_editor/statemachine_editor0.html +55 -0
- data/example/statemachine_editor/statemachine_editor1.html +62 -0
- data/example/statemachine_editor/statemachine_editor2.html +103 -0
- data/example/statemachine_editor/style0.css +8 -0
- data/example/statemachine_editor/style1.css +32 -0
- data/example/statemachine_editor/style2.css +43 -0
- data/example/themes/cobalt.css +176 -0
- data/example/themes/dialog-error.png +0 -0
- data/example/themes/dialog-information.png +0 -0
- data/example/themes/dialog-warning.png +0 -0
- data/example/themes/dots_12px.png +0 -0
- data/example/themes/fold_button_dots_when_hidden.css +18 -0
- data/example/themes/fold_button_plus_minus.css +21 -0
- data/example/themes/fold_button_plus_when_hidden.css +18 -0
- data/example/themes/light_blue.css +177 -0
- data/example/themes/minus_11px.png +0 -0
- data/example/themes/minus_13px.png +0 -0
- data/example/themes/minus_9px.png +0 -0
- data/example/themes/plus_11px.png +0 -0
- data/example/themes/plus_13px.png +0 -0
- data/example/themes/plus_9px.png +0 -0
- data/example/themes/white.css +177 -0
- data/lib/concrete/concrete_syntax_provider.rb +63 -0
- data/lib/concrete/config.rb +36 -0
- data/lib/concrete/file_cache_map.rb +88 -0
- data/lib/concrete/index_builder.rb +108 -0
- data/lib/concrete/metamodel/concrete_mmm.rb +45 -0
- data/lib/concrete/metamodel/ecore_to_concrete.rb +80 -0
- data/lib/concrete/server.rb +92 -0
- data/lib/concrete/util/logger.rb +24 -0
- data/lib/concrete/util/string_writer.rb +17 -0
- data/lib/concrete/working_set.rb +41 -0
- data/rakefile +33 -0
- data/redist/prototype.js +4320 -0
- data/redist/scriptaculous/builder.js +136 -0
- data/redist/scriptaculous/controls.js +991 -0
- data/redist/scriptaculous/dragdrop.js +975 -0
- data/redist/scriptaculous/effects.js +1130 -0
- data/redist/scriptaculous/scriptaculous.js +60 -0
- data/redist/scriptaculous/slider.js +275 -0
- data/redist/scriptaculous/sound.js +55 -0
- data/redist/scriptaculous/unittest.js +568 -0
- data/test/concrete_test.rb +5 -0
- data/test/file_cache_map_test.rb +90 -0
- data/test/file_cache_map_test/testdir/fileA +1 -0
- data/test/index_builder_test.rb +68 -0
- data/test/index_builder_test/ecore_index.js +85 -0
- data/test/index_builder_test/ecore_index_expected.js +85 -0
- data/test/integration/external_elements_test.html +114 -0
- data/test/metamodel_test.rb +40 -0
- data/test/metamodel_test/concrete_mmm_expected.js +19 -0
- data/test/metamodel_test/concrete_mmm_generated.js +19 -0
- data/test/metamodel_test/concrete_mmm_regenerated.js +19 -0
- data/test/unit/external_identifier_provider_test.html +138 -0
- data/test/unit/identifier_provider_test.html +269 -0
- data/test/unit/metamodel_provider_test.html +318 -0
- data/test/unit/model_interface_test.html +257 -0
- data/test/unit/template_provider_test.html +171 -0
- data/test/unit/test.css +90 -0
- data/test/working_set_test.rb +54 -0
- data/test/working_set_test/file1.txt +0 -0
- data/test/working_set_test/file2 +0 -0
- data/test/working_set_test/subdir/file3.xml +0 -0
- metadata +201 -0
@@ -0,0 +1,1054 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
4
|
+
<head>
|
5
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
6
|
+
<meta name="generator" content="AsciiDoc 8.4.5" />
|
7
|
+
<title>Concrete Developers Guide</title>
|
8
|
+
<style type="text/css">
|
9
|
+
/* Debug borders */
|
10
|
+
p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
|
11
|
+
/*
|
12
|
+
border: 1px solid red;
|
13
|
+
*/
|
14
|
+
}
|
15
|
+
|
16
|
+
body {
|
17
|
+
margin: 1em 5% 1em 5%;
|
18
|
+
}
|
19
|
+
|
20
|
+
a {
|
21
|
+
color: blue;
|
22
|
+
text-decoration: underline;
|
23
|
+
}
|
24
|
+
a:visited {
|
25
|
+
color: fuchsia;
|
26
|
+
}
|
27
|
+
|
28
|
+
em {
|
29
|
+
font-style: italic;
|
30
|
+
color: navy;
|
31
|
+
}
|
32
|
+
|
33
|
+
strong {
|
34
|
+
font-weight: bold;
|
35
|
+
color: #083194;
|
36
|
+
}
|
37
|
+
|
38
|
+
tt {
|
39
|
+
color: navy;
|
40
|
+
}
|
41
|
+
|
42
|
+
h1, h2, h3, h4, h5, h6 {
|
43
|
+
color: #527bbd;
|
44
|
+
font-family: sans-serif;
|
45
|
+
margin-top: 1.2em;
|
46
|
+
margin-bottom: 0.5em;
|
47
|
+
line-height: 1.3;
|
48
|
+
}
|
49
|
+
|
50
|
+
h1, h2, h3 {
|
51
|
+
border-bottom: 2px solid silver;
|
52
|
+
}
|
53
|
+
h2 {
|
54
|
+
padding-top: 0.5em;
|
55
|
+
}
|
56
|
+
h3 {
|
57
|
+
float: left;
|
58
|
+
}
|
59
|
+
h3 + * {
|
60
|
+
clear: left;
|
61
|
+
}
|
62
|
+
|
63
|
+
div.sectionbody {
|
64
|
+
font-family: serif;
|
65
|
+
margin-left: 0;
|
66
|
+
}
|
67
|
+
|
68
|
+
hr {
|
69
|
+
border: 1px solid silver;
|
70
|
+
}
|
71
|
+
|
72
|
+
p {
|
73
|
+
margin-top: 0.5em;
|
74
|
+
margin-bottom: 0.5em;
|
75
|
+
}
|
76
|
+
|
77
|
+
ul, ol, li > p {
|
78
|
+
margin-top: 0;
|
79
|
+
}
|
80
|
+
|
81
|
+
pre {
|
82
|
+
padding: 0;
|
83
|
+
margin: 0;
|
84
|
+
}
|
85
|
+
|
86
|
+
span#author {
|
87
|
+
color: #527bbd;
|
88
|
+
font-family: sans-serif;
|
89
|
+
font-weight: bold;
|
90
|
+
font-size: 1.1em;
|
91
|
+
}
|
92
|
+
span#email {
|
93
|
+
}
|
94
|
+
span#revnumber, span#revdate, span#revremark {
|
95
|
+
font-family: sans-serif;
|
96
|
+
}
|
97
|
+
|
98
|
+
div#footer {
|
99
|
+
font-family: sans-serif;
|
100
|
+
font-size: small;
|
101
|
+
border-top: 2px solid silver;
|
102
|
+
padding-top: 0.5em;
|
103
|
+
margin-top: 4.0em;
|
104
|
+
}
|
105
|
+
div#footer-text {
|
106
|
+
float: left;
|
107
|
+
padding-bottom: 0.5em;
|
108
|
+
}
|
109
|
+
div#footer-badges {
|
110
|
+
float: right;
|
111
|
+
padding-bottom: 0.5em;
|
112
|
+
}
|
113
|
+
|
114
|
+
div#preamble {
|
115
|
+
margin-top: 1.5em;
|
116
|
+
margin-bottom: 1.5em;
|
117
|
+
}
|
118
|
+
div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
|
119
|
+
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
|
120
|
+
div.admonitionblock {
|
121
|
+
margin-top: 1.5em;
|
122
|
+
margin-bottom: 1.5em;
|
123
|
+
}
|
124
|
+
div.admonitionblock {
|
125
|
+
margin-top: 2.5em;
|
126
|
+
margin-bottom: 2.5em;
|
127
|
+
}
|
128
|
+
|
129
|
+
div.content { /* Block element content. */
|
130
|
+
padding: 0;
|
131
|
+
}
|
132
|
+
|
133
|
+
/* Block element titles. */
|
134
|
+
div.title, caption.title {
|
135
|
+
color: #527bbd;
|
136
|
+
font-family: sans-serif;
|
137
|
+
font-weight: bold;
|
138
|
+
text-align: left;
|
139
|
+
margin-top: 1.0em;
|
140
|
+
margin-bottom: 0.5em;
|
141
|
+
}
|
142
|
+
div.title + * {
|
143
|
+
margin-top: 0;
|
144
|
+
}
|
145
|
+
|
146
|
+
td div.title:first-child {
|
147
|
+
margin-top: 0.0em;
|
148
|
+
}
|
149
|
+
div.content div.title:first-child {
|
150
|
+
margin-top: 0.0em;
|
151
|
+
}
|
152
|
+
div.content + div.title {
|
153
|
+
margin-top: 0.0em;
|
154
|
+
}
|
155
|
+
|
156
|
+
div.sidebarblock > div.content {
|
157
|
+
background: #ffffee;
|
158
|
+
border: 1px solid silver;
|
159
|
+
padding: 0.5em;
|
160
|
+
}
|
161
|
+
|
162
|
+
div.listingblock > div.content {
|
163
|
+
border: 1px solid silver;
|
164
|
+
background: #f4f4f4;
|
165
|
+
padding: 0.5em;
|
166
|
+
}
|
167
|
+
|
168
|
+
div.quoteblock {
|
169
|
+
padding-left: 2.0em;
|
170
|
+
margin-right: 10%;
|
171
|
+
}
|
172
|
+
div.quoteblock > div.attribution {
|
173
|
+
padding-top: 0.5em;
|
174
|
+
text-align: right;
|
175
|
+
}
|
176
|
+
|
177
|
+
div.verseblock {
|
178
|
+
padding-left: 2.0em;
|
179
|
+
margin-right: 10%;
|
180
|
+
}
|
181
|
+
div.verseblock > div.content {
|
182
|
+
white-space: pre;
|
183
|
+
}
|
184
|
+
div.verseblock > div.attribution {
|
185
|
+
padding-top: 0.75em;
|
186
|
+
text-align: left;
|
187
|
+
}
|
188
|
+
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
|
189
|
+
div.verseblock + div.attribution {
|
190
|
+
text-align: left;
|
191
|
+
}
|
192
|
+
|
193
|
+
div.admonitionblock .icon {
|
194
|
+
vertical-align: top;
|
195
|
+
font-size: 1.1em;
|
196
|
+
font-weight: bold;
|
197
|
+
text-decoration: underline;
|
198
|
+
color: #527bbd;
|
199
|
+
padding-right: 0.5em;
|
200
|
+
}
|
201
|
+
div.admonitionblock td.content {
|
202
|
+
padding-left: 0.5em;
|
203
|
+
border-left: 2px solid silver;
|
204
|
+
}
|
205
|
+
|
206
|
+
div.exampleblock > div.content {
|
207
|
+
border-left: 2px solid silver;
|
208
|
+
padding: 0.5em;
|
209
|
+
}
|
210
|
+
|
211
|
+
div.imageblock div.content { padding-left: 0; }
|
212
|
+
span.image img { border-style: none; }
|
213
|
+
a.image:visited { color: white; }
|
214
|
+
|
215
|
+
dl {
|
216
|
+
margin-top: 0.8em;
|
217
|
+
margin-bottom: 0.8em;
|
218
|
+
}
|
219
|
+
dt {
|
220
|
+
margin-top: 0.5em;
|
221
|
+
margin-bottom: 0;
|
222
|
+
font-style: normal;
|
223
|
+
color: navy;
|
224
|
+
}
|
225
|
+
dd > *:first-child {
|
226
|
+
margin-top: 0.1em;
|
227
|
+
}
|
228
|
+
|
229
|
+
ul, ol {
|
230
|
+
list-style-position: outside;
|
231
|
+
}
|
232
|
+
ol.arabic {
|
233
|
+
list-style-type: decimal;
|
234
|
+
}
|
235
|
+
ol.loweralpha {
|
236
|
+
list-style-type: lower-alpha;
|
237
|
+
}
|
238
|
+
ol.upperalpha {
|
239
|
+
list-style-type: upper-alpha;
|
240
|
+
}
|
241
|
+
ol.lowerroman {
|
242
|
+
list-style-type: lower-roman;
|
243
|
+
}
|
244
|
+
ol.upperroman {
|
245
|
+
list-style-type: upper-roman;
|
246
|
+
}
|
247
|
+
|
248
|
+
div.compact ul, div.compact ol,
|
249
|
+
div.compact p, div.compact p,
|
250
|
+
div.compact div, div.compact div {
|
251
|
+
margin-top: 0.1em;
|
252
|
+
margin-bottom: 0.1em;
|
253
|
+
}
|
254
|
+
|
255
|
+
div.tableblock > table {
|
256
|
+
border: 3px solid #527bbd;
|
257
|
+
}
|
258
|
+
thead {
|
259
|
+
font-family: sans-serif;
|
260
|
+
font-weight: bold;
|
261
|
+
}
|
262
|
+
tfoot {
|
263
|
+
font-weight: bold;
|
264
|
+
}
|
265
|
+
td > div.verse {
|
266
|
+
white-space: pre;
|
267
|
+
}
|
268
|
+
p.table {
|
269
|
+
margin-top: 0;
|
270
|
+
}
|
271
|
+
/* Because the table frame attribute is overriden by CSS in most browsers. */
|
272
|
+
div.tableblock > table[frame="void"] {
|
273
|
+
border-style: none;
|
274
|
+
}
|
275
|
+
div.tableblock > table[frame="hsides"] {
|
276
|
+
border-left-style: none;
|
277
|
+
border-right-style: none;
|
278
|
+
}
|
279
|
+
div.tableblock > table[frame="vsides"] {
|
280
|
+
border-top-style: none;
|
281
|
+
border-bottom-style: none;
|
282
|
+
}
|
283
|
+
|
284
|
+
|
285
|
+
div.hdlist {
|
286
|
+
margin-top: 0.8em;
|
287
|
+
margin-bottom: 0.8em;
|
288
|
+
}
|
289
|
+
div.hdlist tr {
|
290
|
+
padding-bottom: 15px;
|
291
|
+
}
|
292
|
+
dt.hdlist1.strong, td.hdlist1.strong {
|
293
|
+
font-weight: bold;
|
294
|
+
}
|
295
|
+
td.hdlist1 {
|
296
|
+
vertical-align: top;
|
297
|
+
font-style: normal;
|
298
|
+
padding-right: 0.8em;
|
299
|
+
color: navy;
|
300
|
+
}
|
301
|
+
td.hdlist2 {
|
302
|
+
vertical-align: top;
|
303
|
+
}
|
304
|
+
div.hdlist.compact tr {
|
305
|
+
margin: 0;
|
306
|
+
padding-bottom: 0;
|
307
|
+
}
|
308
|
+
|
309
|
+
.comment {
|
310
|
+
background: yellow;
|
311
|
+
}
|
312
|
+
|
313
|
+
@media print {
|
314
|
+
div#footer-badges { display: none; }
|
315
|
+
}
|
316
|
+
|
317
|
+
div#toctitle {
|
318
|
+
color: #527bbd;
|
319
|
+
font-family: sans-serif;
|
320
|
+
font-size: 1.1em;
|
321
|
+
font-weight: bold;
|
322
|
+
margin-top: 1.0em;
|
323
|
+
margin-bottom: 0.1em;
|
324
|
+
}
|
325
|
+
|
326
|
+
div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
|
327
|
+
margin-top: 0;
|
328
|
+
margin-bottom: 0;
|
329
|
+
}
|
330
|
+
div.toclevel2 {
|
331
|
+
margin-left: 2em;
|
332
|
+
font-size: 0.9em;
|
333
|
+
}
|
334
|
+
div.toclevel3 {
|
335
|
+
margin-left: 4em;
|
336
|
+
font-size: 0.9em;
|
337
|
+
}
|
338
|
+
div.toclevel4 {
|
339
|
+
margin-left: 6em;
|
340
|
+
font-size: 0.9em;
|
341
|
+
}
|
342
|
+
/* Workarounds for IE6's broken and incomplete CSS2. */
|
343
|
+
|
344
|
+
div.sidebar-content {
|
345
|
+
background: #ffffee;
|
346
|
+
border: 1px solid silver;
|
347
|
+
padding: 0.5em;
|
348
|
+
}
|
349
|
+
div.sidebar-title, div.image-title {
|
350
|
+
color: #527bbd;
|
351
|
+
font-family: sans-serif;
|
352
|
+
font-weight: bold;
|
353
|
+
margin-top: 0.0em;
|
354
|
+
margin-bottom: 0.5em;
|
355
|
+
}
|
356
|
+
|
357
|
+
div.listingblock div.content {
|
358
|
+
border: 1px solid silver;
|
359
|
+
background: #f4f4f4;
|
360
|
+
padding: 0.5em;
|
361
|
+
}
|
362
|
+
|
363
|
+
div.quoteblock-attribution {
|
364
|
+
padding-top: 0.5em;
|
365
|
+
text-align: right;
|
366
|
+
}
|
367
|
+
|
368
|
+
div.verseblock-content {
|
369
|
+
white-space: pre;
|
370
|
+
}
|
371
|
+
div.verseblock-attribution {
|
372
|
+
padding-top: 0.75em;
|
373
|
+
text-align: left;
|
374
|
+
}
|
375
|
+
|
376
|
+
div.exampleblock-content {
|
377
|
+
border-left: 2px solid silver;
|
378
|
+
padding-left: 0.5em;
|
379
|
+
}
|
380
|
+
|
381
|
+
/* IE6 sets dynamically generated links as visited. */
|
382
|
+
div#toc a:visited { color: blue; }
|
383
|
+
</style>
|
384
|
+
</head>
|
385
|
+
<body>
|
386
|
+
<div id="header">
|
387
|
+
<h1>Concrete Developers Guide</h1>
|
388
|
+
</div>
|
389
|
+
<div id="preamble">
|
390
|
+
<div class="sectionbody">
|
391
|
+
<div class="paragraph"><p>This document describes the <em>Concrete</em> model editor from a DSL developer’s point of view. If you are interested in using the editor for a given DSL, refer to the users guide.</p></div>
|
392
|
+
</div>
|
393
|
+
</div>
|
394
|
+
<h2 id="_metamodels">Metamodels</h2>
|
395
|
+
<div class="sectionbody">
|
396
|
+
<div class="paragraph"><p><em>Concrete</em> uses metamodels to define the abstract syntax of a DSL. A metamodel specifies the possible abstract content of models by means of <em>metamodel classes</em>. Each metamodel class defines the <em>features</em> the instance model elements can have. Features are <em>attributes</em>, <em>references</em> and <em>containments</em>. Attributes hold primitive values, references reference other model elements and containments contain other elements as part of the element itself. Each feature has a name and a type.</p></div>
|
397
|
+
<div class="paragraph"><p>In case of an attribute, the type must be one of the predefined primitive datatypes (currently String, Bool, Integer and Float) or a custom defined enum datatype. Enum datatypes consist of a set of string literals.</p></div>
|
398
|
+
<div class="paragraph"><p>In case of a reference, the type must be a metamodel class. Only instances of that metamodel class can be valid targets of the reference.</p></div>
|
399
|
+
<div class="paragraph"><p>In case of a containment, the type must be a metamodel class as well. Only instances of that metamodel class can be nested in the containment.</p></div>
|
400
|
+
<div class="paragraph"><p>Optionally, an upper and lower limit may be specified for each feature. For example, an upper limit of "1" means that only one attribute/reference value or contained element is allowed. A lower limit of "2" means that at least 2 values or contained elements are required.</p></div>
|
401
|
+
<div class="paragraph"><p>Some of the constraines defined by the metamodel are enforced by the editor, i.e. only valid changes can be done. For the other constraints, errors are annotated at the model.</p></div>
|
402
|
+
</div>
|
403
|
+
<h2 id="_models">Models</h2>
|
404
|
+
<div class="sectionbody">
|
405
|
+
<div class="paragraph"><p>Models are represented by DOM nodes with special (CSS) classes. Elements, attributes, references and containments are represented by DOM nodes with classes <tt>ct_element</tt>, <tt>ct_attribute</tt>, <tt>ct_reference</tt> and <tt>ct_containment</tt> respectively. Attribute, reference and containment nodes are child nodes of element nodes. However, they do not have to be direct children, there can be other nodes around them.</p></div>
|
406
|
+
<div class="paragraph"><p>Within each attribute, reference or containment node, there has to be a <em>slot</em> node marked by class <tt>ct_slot</tt>. Again, slots don’t have to be direct children and may have other nodes around them. The slot is the place where attribute values, reference values or child elements are inserted.</p></div>
|
407
|
+
<div class="paragraph"><p>Attribute and reference values are DOM nodes marked with class <tt>ct_value</tt>. These nodes contain plain text which represents the actual attribute value or the identifier of the referenced element. Note that the visible value of an attribute or reference may be different from the actual value in the model. As an example, long references by qualified names may be shortened to only the last path element. The internal model value is stored in a Javascript property "value" of the value node. Between the slot and the contained values or elements, there must not be any other nodes.</p></div>
|
408
|
+
<div class="paragraph"><p>Note, that other custom CSS classes may be added to all the nodes as long as no predefined, reserved class is used (see CSS Class Reference).</p></div>
|
409
|
+
<div class="paragraph"><p>For each element, the corresponding metamodel class is indicated by an additional CSS class. The CSS class name consists of the prefix <tt>ctc_</tt> followed by the name of the metamodel class. For example, an instance of the metamodel class "State" is annotated with CSS class <tt>ctc_State</tt>.</p></div>
|
410
|
+
<div class="paragraph"><p>In order to indentify the features within each model element, they are annotated with CSS classes indicating the feature name. The CSS class name consists of the prefix <tt>ctn_</tt> followed by the name of the feature. For example an instance of the feature "name" would be annotated with CSS class <tt>ctn_name</tt>.</p></div>
|
411
|
+
<div class="paragraph"><p>Here is an example:</p></div>
|
412
|
+
<div class="listingblock">
|
413
|
+
<div class="content">
|
414
|
+
<pre><tt><div class="ct_element ctc_Class1">
|
415
|
+
<p>Here comes an attribute:</p>
|
416
|
+
<span class="ct_attribuet ctn_feature1">
|
417
|
+
<p>Inside the attribute</p>
|
418
|
+
<span class="ct_slot">
|
419
|
+
<span class="ct_value">Value 1</span>
|
420
|
+
<span class="ct_value">Value 2</span>
|
421
|
+
<span class="ct_value">Value 3</span>
|
422
|
+
</span>
|
423
|
+
<p>After the slot</p>
|
424
|
+
</span>
|
425
|
+
<p>Here comes a reference:</p>
|
426
|
+
<span class="ct_reference ctn_feature2">
|
427
|
+
<p>Inside the reference</p>
|
428
|
+
<span class="ct_slot">
|
429
|
+
<span class="ct_value">/ref/to/elementA</span>
|
430
|
+
<span class="ct_value">/ref/to/elementB</span>
|
431
|
+
<span class="ct_value">/ref/to/elementC</span>
|
432
|
+
</span>
|
433
|
+
<p>After the slot</p>
|
434
|
+
</span>
|
435
|
+
<p>Here comes a containment:</p>
|
436
|
+
<div class="ct_containment ctn_feature3">
|
437
|
+
<p>Inside the containment</p>
|
438
|
+
<div class="ct_slot">
|
439
|
+
<div class="ct_element ctc_Class2">
|
440
|
+
<p>Here go the element's attributes, references and containments</p>
|
441
|
+
</div>
|
442
|
+
<div class="ct_element">
|
443
|
+
<p>Another element</p>
|
444
|
+
</div>
|
445
|
+
</div>
|
446
|
+
<p>After the slot</p>
|
447
|
+
</div>
|
448
|
+
<p>End of element</p>
|
449
|
+
</div></tt></pre>
|
450
|
+
</div></div>
|
451
|
+
<div class="paragraph"><p>In this example, <tt>div</tt> nodes are used for elements and <tt>span</tt> nodes are used for attributes and references. Note however, that this is not mandatory. In fact, any valid HTML tag can be used.</p></div>
|
452
|
+
</div>
|
453
|
+
<h2 id="_dom_templates">DOM Templates</h2>
|
454
|
+
<div class="sectionbody">
|
455
|
+
<div class="paragraph"><p>The concrete syntax of a <em>Concrete</em> DSL is specified using CSS. However, since CSS has it’s limits and CSS based layouts often need special DOM nodes, also DOM nodes are part of the concrete syntax. In order to facilitate this, DOM templates can be specified for each metamodel class. Together with CSS, these templates define the graphical representation of instance elements of that class.</p></div>
|
456
|
+
<div class="paragraph"><p>DOM Templates are very similar to the model itself. The only difference is that all slots are empty and thus template definitions are not nested. In fact, a model is created by applying and nesting DOM templates.</p></div>
|
457
|
+
<div class="paragraph"><p>Here is an example:</p></div>
|
458
|
+
<div class="listingblock">
|
459
|
+
<div class="content">
|
460
|
+
<pre><tt><div class="ct_element ctc_Class1">
|
461
|
+
<p>Here comes an attribute:</p>
|
462
|
+
<span class="ct_attribuet ctn_feature1">
|
463
|
+
<p>Inside the attribute</p>
|
464
|
+
<span class="ct_slot">
|
465
|
+
</span>
|
466
|
+
<p>After the slot</p>
|
467
|
+
</span>
|
468
|
+
<p>Here comes a reference:</p>
|
469
|
+
<span class="ct_reference ctn_feature2">
|
470
|
+
<p>Inside the reference</p>
|
471
|
+
<span class="ct_slot">
|
472
|
+
</span>
|
473
|
+
<p>After the slot</p>
|
474
|
+
</span>
|
475
|
+
<p>Here comes a containment:</p>
|
476
|
+
<div class="ct_containment ctn_feature3">
|
477
|
+
<p>Inside the containment</p>
|
478
|
+
<div class="ct_slot">
|
479
|
+
</div>
|
480
|
+
<p>After the slot</p>
|
481
|
+
</div>
|
482
|
+
<p>End of element</p>
|
483
|
+
</div></tt></pre>
|
484
|
+
</div></div>
|
485
|
+
<div class="paragraph"><p>This template describes the DOM representation used for elements which are instances of metamodel class "Class1". The example model shown in section "Models" could have been created by this template.</p></div>
|
486
|
+
<div class="paragraph"><p>CSS definitions can use the mandatory CSS classes as well as any additional custom CSS class.</p></div>
|
487
|
+
</div>
|
488
|
+
<h2 id="_json_model_exchange_format">JSON Model Exchange Format</h2>
|
489
|
+
<div class="sectionbody">
|
490
|
+
<div class="paragraph"><p>As described above, models are represented by DOM nodes at runtime. However, neither DOM nodes nor the corresponding HTML code are well suited to exchange the model data. One reason is that the DOM representation also contains part of the concrete syntax which should not be part of the pure model.</p></div>
|
491
|
+
<div class="paragraph"><p>Instead of HTML, models are exchanged using the well known JSON format. JSON is basically the textual representation of objects/hashes/maps, arrays and primitive values in Javascript syntax. Today, JSON libraries are available for many major programming languages.</p></div>
|
492
|
+
<div class="paragraph"><p><em>Concrete</em> models are represented in JSON using the following conventions:</p></div>
|
493
|
+
<div class="ulist"><ul>
|
494
|
+
<li>
|
495
|
+
<p>
|
496
|
+
A model is an array holding the top-level model elements.
|
497
|
+
</p>
|
498
|
+
</li>
|
499
|
+
<li>
|
500
|
+
<p>
|
501
|
+
Model elements are hashes, the metamodel class name is stored in a hash property named "_class".
|
502
|
+
</p>
|
503
|
+
</li>
|
504
|
+
<li>
|
505
|
+
<p>
|
506
|
+
Feature values and contained elements are stored in properties named like the feature.
|
507
|
+
</p>
|
508
|
+
</li>
|
509
|
+
<li>
|
510
|
+
<p>
|
511
|
+
If a feature contains multiple values/elements, they are grouped in an array. Otherwise the value/element is assigned directly to the property.
|
512
|
+
</p>
|
513
|
+
</li>
|
514
|
+
<li>
|
515
|
+
<p>
|
516
|
+
Attribute values are converted to text using Javascript’s default conversion mechanism.
|
517
|
+
</p>
|
518
|
+
</li>
|
519
|
+
<li>
|
520
|
+
<p>
|
521
|
+
Reference values are strings holding the identifier of the referenced element.
|
522
|
+
</p>
|
523
|
+
</li>
|
524
|
+
</ul></div>
|
525
|
+
<div class="paragraph"><p>Here is an example:</p></div>
|
526
|
+
<div class="listingblock">
|
527
|
+
<div class="content">
|
528
|
+
<pre><tt>[{"_class": "Statemachine", "name": "AC", "states": [
|
529
|
+
{"_class": "SimpleState", "name": "Off", "transitions":
|
530
|
+
{"_class": "Transition", "target": "/AC/On"}},
|
531
|
+
{"_class": "CompositeState", "name": "On", "subStates": [
|
532
|
+
{"_class": "SimpleState", "name": "Heating", "transitions":
|
533
|
+
{"_class": "Transition", "target": "/AC/On/Cooling"}},
|
534
|
+
{"_class": "SimpleState", "name": "Cooling", "transitions":
|
535
|
+
{"_class": "Transition", "target": "/AC/On/Heating"}}], "transitions":
|
536
|
+
{"_class": "Transition", "target": "/AC/Off"}}]}]</tt></pre>
|
537
|
+
</div></div>
|
538
|
+
</div>
|
539
|
+
<h2 id="_embedding_concrete">Embedding Concrete</h2>
|
540
|
+
<div class="sectionbody">
|
541
|
+
<h3 id="_depencencies">Depencencies</h3><div style="clear:left"></div>
|
542
|
+
<div class="paragraph"><p><em>Concrete</em> depends on <em>Prototype</em> and <em>Scriptaculous</em>. So you need to make sure, that these libraries are included before <em>Concrete</em> itself:</p></div>
|
543
|
+
<div class="listingblock">
|
544
|
+
<div class="content">
|
545
|
+
<pre><tt><script src="../../redist/prototype.js" type="text/javascript"></script>
|
546
|
+
<script src="../../redist/scriptaculous/scriptaculous.js" type="text/javascript"></script>
|
547
|
+
<script src="../../concrete/concrete.js" type="text/javascript"></script></tt></pre>
|
548
|
+
</div></div>
|
549
|
+
<div class="paragraph"><p>Note that for the current version of <em>Concrete</em>, a slightly patched version of Scriptaculous is required which comes in the release package.</p></div>
|
550
|
+
<h3 id="_style_sheets">Style Sheets</h3><div style="clear:left"></div>
|
551
|
+
<div class="paragraph"><p>In order to make the editor look right, you need to define styles for the CSS classes mentioned above (alse see the CSS Class Reference). You can start with one of the "theme" CSS files from the examples folder. Then for DSL specific styles, you can add another stylesheet overwriting some of the definitions in the "theme" stylesheet. Of course, another option is to create one single new stylesheet.</p></div>
|
552
|
+
<div class="listingblock">
|
553
|
+
<div class="content">
|
554
|
+
<pre><tt><link rel="stylesheet" href="../../example/themes/cobalt.css" type="text/css" />
|
555
|
+
<link rel="stylesheet" href="../../editor/specific/style.css" type="text/css" /></tt></pre>
|
556
|
+
</div></div>
|
557
|
+
<h3 id="_template_provider">Template Provider</h3><div style="clear:left"></div>
|
558
|
+
<div class="paragraph"><p><em>Concrete</em> needs a place where the DOM templates can be located. This is the place where custom DOM templates are specified, as well as the place where the default DOM templates are prepared automatically in case there are no custom templates. There is no special CSS class required, just an ID to reference the node. Normally, this template container should be made invisible.</p></div>
|
559
|
+
<div class="listingblock">
|
560
|
+
<div class="content">
|
561
|
+
<pre><tt><div id="templates1" style="display: none">
|
562
|
+
</div></tt></pre>
|
563
|
+
</div></div>
|
564
|
+
<div class="paragraph"><p>Then, an instance of <tt>TemplateProvider</tt> needs to be created. The constructor gets the template container DOM node and may take additional options. For example, by setting <tt>identifierAttribute</tt> to "name", all attributes named "name" will be marked as identifier attributes when the default templates are created. This can be used to highlight these attributes differently.</p></div>
|
565
|
+
<div class="listingblock">
|
566
|
+
<div class="content">
|
567
|
+
<pre><tt>var tp = new Concrete.TemplateProvider($("templates1"), {identifierAttribute: "name"});</tt></pre>
|
568
|
+
</div></div>
|
569
|
+
<h3 id="_metamodel_provider">Metamodel Provider</h3><div style="clear:left"></div>
|
570
|
+
<div class="paragraph"><p><em>Concret</em> knows about the metamodel by asking an instance of <tt>MetamodelProvider</tt>. The constructor takes the metamodel which is a model by itself, following the conventions described for the <em>Concrete</em> JSON format. It can be convenient to put the metamodel as text in JSON format into the HTML code. In this case, the text content of the containing node has to be evaluated as JSON before the metamodel provider can use it.</p></div>
|
571
|
+
<div class="paragraph"><p>Here is a simple example metamodel:</p></div>
|
572
|
+
<div class="listingblock">
|
573
|
+
<div class="content">
|
574
|
+
<pre><tt><div id="metamodel1" style="display: none">
|
575
|
+
[
|
576
|
+
{"_class": "Datatype", "name": "String"},
|
577
|
+
{"_class": "Class", "A": "Feature", "features": [
|
578
|
+
{"_class": "Feature", "name": "feat1", "kind": "attribute", "type": "String"},
|
579
|
+
{"_class": "Feature", "name": "feat2", "kind": "attribute", "type": "String"},
|
580
|
+
]}
|
581
|
+
]
|
582
|
+
</div></tt></pre>
|
583
|
+
</div></div>
|
584
|
+
<div class="paragraph"><p>Here is how this metamodel can be fed into a new instance of <tt>MetamodelProvider</tt>.</p></div>
|
585
|
+
<div class="listingblock">
|
586
|
+
<div class="content">
|
587
|
+
<pre><tt>var mp = new Concrete.MetamodelProvider($("metamodel1").textContent.evalJSON());</tt></pre>
|
588
|
+
</div></div>
|
589
|
+
<h3 id="_identifier_provider">Identifier Provider</h3><div style="clear:left"></div>
|
590
|
+
<div class="paragraph"><p>In <em>Concrete</em>, identifiers are used to define reference targets. In order to create identifiers, the editor needs an identifier provider. Currently, the <tt>QualifiedNameBasedIdentifierProvider</tt> is included with <em>Concrete</em>, but other providers implementing custom identifier calculation strategies could be used instead. The <tt>QualifiedNameBasedIdentifierProvider</tt> needs to know the name of the attribute holding the local (non-qualified) name.</p></div>
|
591
|
+
<div class="paragraph"><p>In the following example, all attributes named "name" are used for qualified name calculation.</p></div>
|
592
|
+
<div class="listingblock">
|
593
|
+
<div class="content">
|
594
|
+
<pre><tt>var ip = new Concrete.QualifiedNameBasedIdentifierProvider({nameAttribute: "name"});</tt></pre>
|
595
|
+
</div></div>
|
596
|
+
<h3 id="_clipboard">Clipboard</h3><div style="clear:left"></div>
|
597
|
+
<div class="paragraph"><p>By default, the editor uses a clipboard it creates internally. However, to let several editors share a clipboard, an instance of <tt>Clipboard</tt> can be explicitly passed into each editor. This is also useful for making the clipboard content visible or editable. When a clipboard is created, a DOM node can be passed into the constructor which acts as the container of the clipboard data. If a HTML <tt>Textarea</tt> node is used, the clipboard content will be visible and editable within this textarea. If another type of node is passed in, its text content will hold the clipboard data and make it visible. If no DOM node is given, the data will be held as plain text internally.</p></div>
|
598
|
+
<div class="paragraph"><p>Here is an example:</p></div>
|
599
|
+
<div class="listingblock">
|
600
|
+
<div class="content">
|
601
|
+
<pre><tt><textarea id="clipboard1" style="background-color: white; color: black; border: 1px solid grey" cols="80" rows="10" wrap="off">
|
602
|
+
</textarea></tt></pre>
|
603
|
+
</div></div>
|
604
|
+
<div class="paragraph"><p>This textarea can be passed into a new instance of <tt>Clipboard</tt>.</p></div>
|
605
|
+
<div class="listingblock">
|
606
|
+
<div class="content">
|
607
|
+
<pre><tt>var cb = new Concrete.Clipboard($("clipboard1"));</tt></pre>
|
608
|
+
</div></div>
|
609
|
+
<h3 id="_conrete_editor">Conrete Editor</h3><div style="clear:left"></div>
|
610
|
+
<div class="paragraph"><p>The editor itself is some kind of widget which lives in a DOM node with CSS class <tt>ct_editor</tt>.</p></div>
|
611
|
+
<div class="listingblock">
|
612
|
+
<div class="content">
|
613
|
+
<pre><tt><div class="ct_editor" id="editor1">
|
614
|
+
</div></tt></pre>
|
615
|
+
</div></div>
|
616
|
+
<div class="paragraph"><p>With all the objects created before, the editor can be instantiated. The constructor takes the DOM node the editor should live in, the template provider, the metamodel provider, the identifier provider and additional options. One of the options is an externally created clipboard as described above. Another option defines the metamodel classes which can be instantiated on root level. If not specified, all metamodel classes can be instantiated on root level.</p></div>
|
617
|
+
<div class="paragraph"><p>Here is an example:</p></div>
|
618
|
+
<div class="listingblock">
|
619
|
+
<div class="content">
|
620
|
+
<pre><tt>var ed = new Concrete.Editor($("editor1"), tp, mp, ip, {clipboard: cb,
|
621
|
+
rootClasses: mp.metaclasses.select(function(c) { return ["Class", "Datatype", "Enum"].include(c.name)})});</tt></pre>
|
622
|
+
</div></div>
|
623
|
+
<div class="paragraph"><p>Once the editor has been created it has to be connected to the browser window events. Currently the <tt>click</tt>, <tt>keydown</tt> and <tt>mousemove</tt> events are supported.</p></div>
|
624
|
+
<div class="listingblock">
|
625
|
+
<div class="content">
|
626
|
+
<pre><tt>Event.observe(window, 'click', function(event) {
|
627
|
+
ed.handleEvent(event);
|
628
|
+
});
|
629
|
+
Event.observe(window, 'keydown', function(event) {
|
630
|
+
ed.handleEvent(event);
|
631
|
+
});
|
632
|
+
Event.observe(window, 'mousemove', function(event) {
|
633
|
+
ed.handleEvent(event);
|
634
|
+
});</tt></pre>
|
635
|
+
</div></div>
|
636
|
+
<h3 id="_loading_and_storing_data">Loading and Storing Data</h3><div style="clear:left"></div>
|
637
|
+
<div class="paragraph"><p>A newly created editor is empty and the user can start building a model from scratch. However in most cases, some prebuilt model should be loaded and the final result should be stored. For this purpose, the <em>Concrete</em> editor provides the methods <tt>getModel</tt> and <tt>setModel</tt>. In both cases the model is a JSON string following the JSON conventions as described above.</p></div>
|
638
|
+
<div class="paragraph"><p>One possible way to use this API is to get the data from a server via AJAX and also store it back in the same way. Another option for loading is to embed the model in an HTML element in JSON text format and load it from there.</p></div>
|
639
|
+
<div class="listingblock">
|
640
|
+
<div class="content">
|
641
|
+
<pre><tt><div id="model1" style="display: none">
|
642
|
+
<!-- json model here -->
|
643
|
+
</div></tt></pre>
|
644
|
+
</div></div>
|
645
|
+
<div class="paragraph"><p>Code for loading the model…</p></div>
|
646
|
+
<div class="listingblock">
|
647
|
+
<div class="content">
|
648
|
+
<pre><tt>// load model only if present and valid JSON
|
649
|
+
var modelData = $("model1").textContent;
|
650
|
+
if (modelData.isJSON()) {
|
651
|
+
ed.setModel(modelData);
|
652
|
+
}</tt></pre>
|
653
|
+
</div></div>
|
654
|
+
<div class="paragraph"><p>…and for storing it via AJAX using the Prototype library.</p></div>
|
655
|
+
<div class="listingblock">
|
656
|
+
<div class="content">
|
657
|
+
<pre><tt>new Ajax.Request("/save", { method: 'post', postBody: ed.getModel() });</tt></pre>
|
658
|
+
</div></div>
|
659
|
+
</div>
|
660
|
+
<h2 id="_the_workbench">The Workbench</h2>
|
661
|
+
<div class="sectionbody">
|
662
|
+
<div class="paragraph"><p>The "workbench" is an environment for editing larger models which are made up from <em>modules</em>. It is actually an assembly of two <em>Concrete</em> editor widgets. Thus it is both, an example of how the editor widget can be used in a larger scope and a base for more sophisticated editors. Just like the simple editor widget itself, the workbench is metamodel independant.</p></div>
|
663
|
+
<div class="paragraph"><p>The workbench features:</p></div>
|
664
|
+
<div class="ulist"><ul>
|
665
|
+
<li>
|
666
|
+
<p>
|
667
|
+
a module index view (read only)
|
668
|
+
</p>
|
669
|
+
</li>
|
670
|
+
<li>
|
671
|
+
<p>
|
672
|
+
a module editor
|
673
|
+
</p>
|
674
|
+
</li>
|
675
|
+
<li>
|
676
|
+
<p>
|
677
|
+
an inter module index supporting inter module references
|
678
|
+
</p>
|
679
|
+
</li>
|
680
|
+
<li>
|
681
|
+
<p>
|
682
|
+
a dialog to jump to elements based on the index
|
683
|
+
</p>
|
684
|
+
</li>
|
685
|
+
<li>
|
686
|
+
<p>
|
687
|
+
search/replace functionality
|
688
|
+
</p>
|
689
|
+
</li>
|
690
|
+
<li>
|
691
|
+
<p>
|
692
|
+
support for switchable layouts via a preferences dialog
|
693
|
+
</p>
|
694
|
+
</li>
|
695
|
+
<li>
|
696
|
+
<p>
|
697
|
+
a Ruby based server backend for reading/writing to the filesystem
|
698
|
+
</p>
|
699
|
+
</li>
|
700
|
+
</ul></div>
|
701
|
+
<div class="paragraph"><p>In order to use the Ruby backend, you need to have the Ruby runtime installed. Once Ruby is installed <em>Concrete</em> can be installed as a Ruby <em>gem</em>. See the Readme file for details.</p></div>
|
702
|
+
<h3 id="_modules_and_index">Modules and Index</h3><div style="clear:left"></div>
|
703
|
+
<div class="paragraph"><p>The workbench is used to edit models devided into modules. It is based on the assumption that modules can be loaded and stored independantly.</p></div>
|
704
|
+
<div class="paragraph"><p>An index is used to implement inter-module search and link functionality. The overall index is composed of the the indices of the individual modules. In case a module is modified, only this module’s index needs to be regenerated.</p></div>
|
705
|
+
<div class="paragraph"><p>The index is a stripped down version of the original model. From the point of view of the <em>Concrete</em> editor widget, the index is just a model as any other model. Thus it needs to be an instance of a metamodel, the <em>index metamodel</em>. The index metamodel can be derived from the original metamodel: It contains a metaclass for each metaclass in the original metamodel. However the only features of an index metaclass are the name ("name") and the child elements ("elements"). The <em>Concrete::IndexBuilder</em> can be used to both create the index metamodel from the original metamodel and the index model from the original model.</p></div>
|
706
|
+
<div class="paragraph"><p>The module index view of the workbench is actually a <em>Concret</em> editor widget which shows the index model. With the index structure as described above, class information, element names and the containment structure are available in the index. Using class information, class specific layouts (e.g. class specific icons) can be applied to the index view.</p></div>
|
707
|
+
<h3 id="_data_provider_and_working_set">Data Provider and Working Set</h3><div style="clear:left"></div>
|
708
|
+
<div class="paragraph"><p>The workbench functionality is generic, you need to provide a metamodel as well as an instantiator and serializer for your models. This is done by passing a <em>data provider</em> to the generic server. The data provider is a Ruby object implementing the following methods:</p></div>
|
709
|
+
<div class="tableblock">
|
710
|
+
<table rules="none"
|
711
|
+
width="100%"
|
712
|
+
frame="hsides"
|
713
|
+
cellspacing="0" cellpadding="4">
|
714
|
+
<caption class="title">Methods to be implemented by a Data Provider</caption>
|
715
|
+
<col width="50%" />
|
716
|
+
<col width="50%" />
|
717
|
+
<tbody>
|
718
|
+
<tr>
|
719
|
+
<td align="left" valign="top"><p class="table">metamodelAsJson</p></td>
|
720
|
+
<td align="left" valign="top"><p class="table">returns the metamodel as a JSON string following the conventions described above</p></td>
|
721
|
+
</tr>
|
722
|
+
<tr>
|
723
|
+
<td align="left" valign="top"><p class="table">indexMetamodelAsJson</p></td>
|
724
|
+
<td align="left" valign="top"><p class="table">returns the index metamodel as a JSON string</p></td>
|
725
|
+
</tr>
|
726
|
+
<tr>
|
727
|
+
<td align="left" valign="top"><p class="table">getJsonModel(fileIdent)</p></td>
|
728
|
+
<td align="left" valign="top"><p class="table">reads the model part contained in module <em>fileIdent</em> from the filesystem or a database and returns a JSON string</p></td>
|
729
|
+
</tr>
|
730
|
+
<tr>
|
731
|
+
<td align="left" valign="top"><p class="table">setJsonModel(fileIdent, data)</p></td>
|
732
|
+
<td align="left" valign="top"><p class="table">takes a JSON string representing the model in module <em>fileIdent</em> and writes it to the filesystem or a database</p></td>
|
733
|
+
</tr>
|
734
|
+
<tr>
|
735
|
+
<td align="left" valign="top"><p class="table">createModule(fileIdent)</p></td>
|
736
|
+
<td align="left" valign="top"><p class="table">creates a new empty module for the given identifier</p></td>
|
737
|
+
</tr>
|
738
|
+
<tr>
|
739
|
+
<td align="left" valign="top"><p class="table">getAllJsonIndex</p></td>
|
740
|
+
<td align="left" valign="top"><p class="table">returns a JSON string representing the overall model index (i.e. the composition of all module indices)</p></td>
|
741
|
+
</tr>
|
742
|
+
</tbody>
|
743
|
+
</table>
|
744
|
+
</div>
|
745
|
+
<div class="paragraph"><p>The server also needs to know which modules exist. Therefor you should provide an instance of <em>Concrete::WorkingSet</em> which is basically a set of module identifiers.</p></div>
|
746
|
+
<h3 id="_concrete_syntaxes">Concrete Syntaxes</h3><div style="clear:left"></div>
|
747
|
+
<div class="paragraph"><p>The workbench server supports selecting a concrete syntax from a set of available syntaxes. A concrete syntax consists of a stylesheet part and a HTML template part. Use an instance of <em>Concrete::ConcreteSyntaxProvider</em> to tell the server about the available syntaxes. The syntax provider takes a set of directories which contain concrete syntax information represented by directories and files following a naming convention:</p></div>
|
748
|
+
<div class="listingblock">
|
749
|
+
<div class="content">
|
750
|
+
<pre><tt><syntax root dir 1>
|
751
|
+
<syntax 1>
|
752
|
+
style.css
|
753
|
+
templates.html
|
754
|
+
<syntax 2>
|
755
|
+
style.css
|
756
|
+
templates.html</tt></pre>
|
757
|
+
</div></div>
|
758
|
+
<div class="paragraph"><p>There can be several syntax root directories (e.g. one which is deployed with your editor and one in the user’s home directory). The display name of a specific syntax is derived from the syntax directory within a root directory. The syntax directory should contain a file "templates.html" in case the syntax contains a HTML part. It should also contain a CSS file "style.css" and it may contain more resources (e.g. images) referenced from that stylesheet.</p></div>
|
759
|
+
<div class="paragraph"><p>The server will make the files in the directory of the selected syntax available via the path prefix "/syntax". It will also insert the contents of the file "template.html" in the main HTML file by replacing the placeholder comment "html templates". See below for an example.</p></div>
|
760
|
+
<h3 id="_setting_up_the_server">Setting up the Server</h3><div style="clear:left"></div>
|
761
|
+
<div class="paragraph"><p>With a working set, data provider and syntax provider in place the server can be instantiated. As an additional argument, it needs the location of its HTML root directory. The root directory should contain a file named "editor.html" which is the main HTML file as described in the next section.</p></div>
|
762
|
+
<div class="paragraph"><p>The following example code sets up an instance of <em>Concrete::Server</em>. It reads the module names as file names from the command line and uses the RGen builtin ECore meta-metamodel as metamodel (in fact this is taken form the "mmedit" metamodel editor project). It uses the <em>Concrete::IndexBuilder</em> to derive the index metamodel and the index model and it uses a <em>Concrete::Config</em> to store the preferences in the user’s home directory.</p></div>
|
763
|
+
<div class="listingblock">
|
764
|
+
<div class="content">
|
765
|
+
<pre><tt>logger = Concrete::Util::Logger.new
|
766
|
+
|
767
|
+
workingSet = Concrete::WorkingSet.new(".")
|
768
|
+
ARGV.each{|a| workingSet.addFile(a)}
|
769
|
+
|
770
|
+
mm = RGen::ECore
|
771
|
+
indexBuilder = Concrete::IndexBuilder.new(mm)
|
772
|
+
indexBuilder.indexMetamodel
|
773
|
+
|
774
|
+
dataProvider = MMEdit::DataProvider.new(workingSet, mm, indexBuilder, logger)
|
775
|
+
config = Concrete::Config.new(File.expand_path("~/.mmedit_config"))
|
776
|
+
syntaxProvider = Concrete::ConcreteSyntaxProvider.new([File.dirname(__FILE__)+"/../syntax"], logger, config)
|
777
|
+
Concrete::Server.new(workingSet, dataProvider, syntaxProvider, File.dirname(__FILE__)+"/../html").start</tt></pre>
|
778
|
+
</div></div>
|
779
|
+
<h3 id="_setting_up_the_javascript_part">Setting up the Javascript Part</h3><div style="clear:left"></div>
|
780
|
+
<div class="paragraph"><p>The server expects a file named "editor.html" in its HTML root directory. This is the place to setup the Javascript part of the workbench.</p></div>
|
781
|
+
<div class="paragraph"><p>To be able to use the workbench functionality, you need to include the "concrete_ui" package as well as the workbench specific styles.</p></div>
|
782
|
+
<div class="paragraph"><p>Note that the server will automatically redirect requests with prefix "/concrete" to the directory containing the <em>Concrete</em> Javascript code. It will redirect requests to "/html" to the HTML root directory and it will redirect requests to "/syntax" to the selected syntax directory. Requests to "metamodel.js" and "index_metamodel.js" will be served with the data returned from the data provider methodes "metamodelAsJson" and "indexMetamodelAsJson".</p></div>
|
783
|
+
<div class="paragraph"><p>Here is an example from the "mmedit" project.</p></div>
|
784
|
+
<div class="listingblock">
|
785
|
+
<div class="content">
|
786
|
+
<pre><tt><link rel="stylesheet" href="/concrete/example/themes/white.css" type="text/css" />
|
787
|
+
<link rel="stylesheet" href="/concrete/concrete/ui/style.css" type="text/css" />
|
788
|
+
<link rel="stylesheet" href="/html/style.css" type="text/css" />
|
789
|
+
<link rel="stylesheet" href="/syntax/style.css" type="text/css" />
|
790
|
+
<script src="/concrete/redist/prototype.js" type="text/javascript"></script>
|
791
|
+
<script src="/concrete/redist/scriptaculous/scriptaculous.js" type="text/javascript"></script>
|
792
|
+
<script src="/concrete/concrete/concrete.js" type="text/javascript"></script>
|
793
|
+
<script src="/concrete/concrete/ui/concrete_ui.js" type="text/javascript"></script>
|
794
|
+
<script src="metamodel.js" type="text/javascript"></script>
|
795
|
+
<script src="index_metamodel.js" type="text/javascript"></script></tt></pre>
|
796
|
+
</div></div>
|
797
|
+
<div class="paragraph"><p>The "editor.html" file should also contain the placeholder which is to be replaced with the HTML templates from the syntax directory. Therefor it should contain a template container element including the placeholder:</p></div>
|
798
|
+
<div class="listingblock">
|
799
|
+
<div class="content">
|
800
|
+
<pre><tt><div id="editor_templates" style='display: none'>
|
801
|
+
<!-- html templates -->
|
802
|
+
</div></tt></pre>
|
803
|
+
</div></div>
|
804
|
+
<div class="paragraph"><p>The workbench is created by means of a setup method which takes the metamodel and index metamodel as arguments. Note that in this example, the requests to "metamodel.js" and "index_metamodel.js" do not only return the JSON text but they return a Javascript assignment of this text to the variables "Metamodel" and "IndexMetamodel". In addition to the metamodels, the setup method takes options which are passed to the index view editor widget and the model editor widget.</p></div>
|
805
|
+
<div class="listingblock">
|
806
|
+
<div class="content">
|
807
|
+
<pre><tt>Concrete.UI.Workbench.setup(Metamodel, IndexMetamodel, {
|
808
|
+
|
809
|
+
moduleEditorOptions: {
|
810
|
+
rootClasses: ["EPackage"],
|
811
|
+
templateProvider: new Concrete.TemplateProvider($("editor_templates"), {
|
812
|
+
identifierAttribute: "name"
|
813
|
+
}),
|
814
|
+
shortReferences: true
|
815
|
+
}
|
816
|
+
});</tt></pre>
|
817
|
+
</div></div>
|
818
|
+
<h3 id="_going_beyond_the_workbench">Going beyond the Workbench</h3><div style="clear:left"></div>
|
819
|
+
<div class="paragraph"><p>The "workbench" should cover a number of editing usecases without change. In case you need different functionality, just use it as an example and starting point to create your own <em>Concrete</em> based editor.</p></div>
|
820
|
+
</div>
|
821
|
+
<h2 id="_css_class_reference">CSS Class Reference</h2>
|
822
|
+
<div class="sectionbody">
|
823
|
+
<div class="tableblock">
|
824
|
+
<table rules="none"
|
825
|
+
width="100%"
|
826
|
+
frame="hsides"
|
827
|
+
cellspacing="0" cellpadding="4">
|
828
|
+
<caption class="title">Model and Template Related CSS Classes</caption>
|
829
|
+
<col width="50%" />
|
830
|
+
<col width="50%" />
|
831
|
+
<tbody>
|
832
|
+
<tr>
|
833
|
+
<td align="left" valign="top"><p class="table">ct_element</p></td>
|
834
|
+
<td align="left" valign="top"><p class="table">model element</p></td>
|
835
|
+
</tr>
|
836
|
+
<tr>
|
837
|
+
<td align="left" valign="top"><p class="table">ct_attribute</p></td>
|
838
|
+
<td align="left" valign="top"><p class="table">model element attribute</p></td>
|
839
|
+
</tr>
|
840
|
+
<tr>
|
841
|
+
<td align="left" valign="top"><p class="table">ct_reference</p></td>
|
842
|
+
<td align="left" valign="top"><p class="table">model element reference to other model element</p></td>
|
843
|
+
</tr>
|
844
|
+
<tr>
|
845
|
+
<td align="left" valign="top"><p class="table">ct_containment</p></td>
|
846
|
+
<td align="left" valign="top"><p class="table">model element containment of other element</p></td>
|
847
|
+
</tr>
|
848
|
+
<tr>
|
849
|
+
<td align="left" valign="top"><p class="table">ct_slot</p></td>
|
850
|
+
<td align="left" valign="top"><p class="table">slot inside an attribute, reference or containment</p></td>
|
851
|
+
</tr>
|
852
|
+
<tr>
|
853
|
+
<td align="left" valign="top"><p class="table">ct_value</p></td>
|
854
|
+
<td align="left" valign="top"><p class="table">attribute or reference value</p></td>
|
855
|
+
</tr>
|
856
|
+
<tr>
|
857
|
+
<td align="left" valign="top"><p class="table">ctc_<…></p></td>
|
858
|
+
<td align="left" valign="top"><p class="table">class indicating an element’s metamodel class</p></td>
|
859
|
+
</tr>
|
860
|
+
<tr>
|
861
|
+
<td align="left" valign="top"><p class="table">ctn_<…></p></td>
|
862
|
+
<td align="left" valign="top"><p class="table">class indicating a feature’s name</p></td>
|
863
|
+
</tr>
|
864
|
+
<tr>
|
865
|
+
<td align="left" valign="top"><p class="table">ct_handle</p></td>
|
866
|
+
<td align="left" valign="top"><p class="table">marks a DOM node which is used as an element’s handle, this node will change into an editor when the element’s class is to be changed</p></td>
|
867
|
+
</tr>
|
868
|
+
<tr>
|
869
|
+
<td align="left" valign="top"><p class="table">ct_auto_hide</p></td>
|
870
|
+
<td align="left" valign="top"><p class="table">marks a feature as "auto hide", it will be hidden if it is empty</p></td>
|
871
|
+
</tr>
|
872
|
+
<tr>
|
873
|
+
<td align="left" valign="top"><p class="table">ct_always_hide</p></td>
|
874
|
+
<td align="left" valign="top"><p class="table">marks a feature as "always hide", it will be hidden when the selection leaves the current element</p></td>
|
875
|
+
</tr>
|
876
|
+
<tr>
|
877
|
+
<td align="left" valign="top"><p class="table">ct_root</p></td>
|
878
|
+
<td align="left" valign="top"><p class="table">internal. marks the model root node</p></td>
|
879
|
+
</tr>
|
880
|
+
</tbody>
|
881
|
+
</table>
|
882
|
+
</div>
|
883
|
+
<div class="tableblock">
|
884
|
+
<table rules="none"
|
885
|
+
width="100%"
|
886
|
+
frame="hsides"
|
887
|
+
cellspacing="0" cellpadding="4">
|
888
|
+
<caption class="title">Editor Related CSS Classes</caption>
|
889
|
+
<col width="50%" />
|
890
|
+
<col width="50%" />
|
891
|
+
<tbody>
|
892
|
+
<tr>
|
893
|
+
<td align="left" valign="top"><p class="table">ct_editor</p></td>
|
894
|
+
<td align="left" valign="top"><p class="table">the editor itself</p></td>
|
895
|
+
</tr>
|
896
|
+
<tr>
|
897
|
+
<td align="left" valign="top"><p class="table">ct_inline_editor</p></td>
|
898
|
+
<td align="left" valign="top"><p class="table">inline editor for editing text inside the editor</p></td>
|
899
|
+
</tr>
|
900
|
+
<tr>
|
901
|
+
<td align="left" valign="top"><p class="table">ct_focus</p></td>
|
902
|
+
<td align="left" valign="top"><p class="table">this class is present at the editor node if it is focused</p></td>
|
903
|
+
</tr>
|
904
|
+
<tr>
|
905
|
+
<td align="left" valign="top"><p class="table">ct_selected</p></td>
|
906
|
+
<td align="left" valign="top"><p class="table">this class is present at an element or value if it is selected</p></td>
|
907
|
+
</tr>
|
908
|
+
<tr>
|
909
|
+
<td align="left" valign="top"><p class="table">ct_cursor</p></td>
|
910
|
+
<td align="left" valign="top"><p class="table">cursor on the border of the currently selected element</p></td>
|
911
|
+
</tr>
|
912
|
+
<tr>
|
913
|
+
<td align="left" valign="top"><p class="table">ct_empty</p></td>
|
914
|
+
<td align="left" valign="top"><p class="table">empty value or element placeholder</p></td>
|
915
|
+
</tr>
|
916
|
+
<tr>
|
917
|
+
<td align="left" valign="top"><p class="table">ct_fold_button</p></td>
|
918
|
+
<td align="left" valign="top"><p class="table">marks the fold button</p></td>
|
919
|
+
</tr>
|
920
|
+
<tr>
|
921
|
+
<td align="left" valign="top"><p class="table">ct_fold_open</p></td>
|
922
|
+
<td align="left" valign="top"><p class="table">present at the fold button when the fold is open</p></td>
|
923
|
+
</tr>
|
924
|
+
<tr>
|
925
|
+
<td align="left" valign="top"><p class="table">ct_fold_closed</p></td>
|
926
|
+
<td align="left" valign="top"><p class="table">present at the fold button when the fold is closed</p></td>
|
927
|
+
</tr>
|
928
|
+
<tr>
|
929
|
+
<td align="left" valign="top"><p class="table">ct_fold_empty</p></td>
|
930
|
+
<td align="left" valign="top"><p class="table">present at the fold button when the containing element has no contained elements</p></td>
|
931
|
+
</tr>
|
932
|
+
<tr>
|
933
|
+
<td align="left" valign="top"><p class="table">ct_message_popup</p></td>
|
934
|
+
<td align="left" valign="top"><p class="table">popup window shown when hovering over a model element</p></td>
|
935
|
+
</tr>
|
936
|
+
<tr>
|
937
|
+
<td align="left" valign="top"><p class="table">ct_info_message</p></td>
|
938
|
+
<td align="left" valign="top"><p class="table">info message within the message popup window</p></td>
|
939
|
+
</tr>
|
940
|
+
<tr>
|
941
|
+
<td align="left" valign="top"><p class="table">ct_error_message</p></td>
|
942
|
+
<td align="left" valign="top"><p class="table">error message within the message popup window</p></td>
|
943
|
+
</tr>
|
944
|
+
</tbody>
|
945
|
+
</table>
|
946
|
+
</div>
|
947
|
+
<div class="tableblock">
|
948
|
+
<table rules="none"
|
949
|
+
width="100%"
|
950
|
+
frame="hsides"
|
951
|
+
cellspacing="0" cellpadding="4">
|
952
|
+
<caption class="title">Highlighting Related CSS Classes</caption>
|
953
|
+
<col width="50%" />
|
954
|
+
<col width="50%" />
|
955
|
+
<tbody>
|
956
|
+
<tr>
|
957
|
+
<td align="left" valign="top"><p class="table">ct_identifier_attribute</p></td>
|
958
|
+
<td align="left" valign="top"><p class="table">marks the attribute holding the identifier of an element</p></td>
|
959
|
+
</tr>
|
960
|
+
<tr>
|
961
|
+
<td align="left" valign="top"><p class="table">ct_class_name</p></td>
|
962
|
+
<td align="left" valign="top"><p class="table">marks an element’s class name</p></td>
|
963
|
+
</tr>
|
964
|
+
<tr>
|
965
|
+
<td align="left" valign="top"><p class="table">ct_feature_name</p></td>
|
966
|
+
<td align="left" valign="top"><p class="table">marks the feature name</p></td>
|
967
|
+
</tr>
|
968
|
+
<tr>
|
969
|
+
<td align="left" valign="top"><p class="table">ct_error</p></td>
|
970
|
+
<td align="left" valign="top"><p class="table">marks elements and features for which a constraint check failed</p></td>
|
971
|
+
</tr>
|
972
|
+
<tr>
|
973
|
+
<td align="left" valign="top"><p class="table">ct_error_description</p></td>
|
974
|
+
<td align="left" valign="top"><p class="table">internal. error description to be displayed for a node</p></td>
|
975
|
+
</tr>
|
976
|
+
<tr>
|
977
|
+
<td align="left" valign="top"><p class="table">ct_error_popup</p></td>
|
978
|
+
<td align="left" valign="top"><p class="table">popup window shown when the mouse is over an erroneous element</p></td>
|
979
|
+
</tr>
|
980
|
+
<tr>
|
981
|
+
<td align="left" valign="top"><p class="table">ct_ref_source</p></td>
|
982
|
+
<td align="left" valign="top"><p class="table">marks a reference when it is highlighted</p></td>
|
983
|
+
</tr>
|
984
|
+
<tr>
|
985
|
+
<td align="left" valign="top"><p class="table">ct_ref_target</p></td>
|
986
|
+
<td align="left" valign="top"><p class="table">marks the target element when a reference is highlighted</p></td>
|
987
|
+
</tr>
|
988
|
+
<tr>
|
989
|
+
<td align="left" valign="top"><p class="table">ct_element_icon</p></td>
|
990
|
+
<td align="left" valign="top"><p class="table">marks a node which can take an element’s icon with a "background" style</p></td>
|
991
|
+
</tr>
|
992
|
+
</tbody>
|
993
|
+
</table>
|
994
|
+
</div>
|
995
|
+
<div class="tableblock">
|
996
|
+
<table rules="none"
|
997
|
+
width="100%"
|
998
|
+
frame="hsides"
|
999
|
+
cellspacing="0" cellpadding="4">
|
1000
|
+
<caption class="title">CSS Classes used by the Workbench</caption>
|
1001
|
+
<col width="50%" />
|
1002
|
+
<col width="50%" />
|
1003
|
+
<tbody>
|
1004
|
+
<tr>
|
1005
|
+
<td align="left" valign="top"><p class="table">ct_layout_main</p></td>
|
1006
|
+
<td align="left" valign="top"><p class="table">marks the main editor pane</p></td>
|
1007
|
+
</tr>
|
1008
|
+
<tr>
|
1009
|
+
<td align="left" valign="top"><p class="table">ct_layout_sidebar</p></td>
|
1010
|
+
<td align="left" valign="top"><p class="table">marks the module index view</p></td>
|
1011
|
+
</tr>
|
1012
|
+
<tr>
|
1013
|
+
<td align="left" valign="top"><p class="table">ct_layout_sidebar_drag</p></td>
|
1014
|
+
<td align="left" valign="top"><p class="table">draggable border of the index view</p></td>
|
1015
|
+
</tr>
|
1016
|
+
<tr>
|
1017
|
+
<td align="left" valign="top"><p class="table">ct_layout_toolbar</p></td>
|
1018
|
+
<td align="left" valign="top"><p class="table">toolbar pane</p></td>
|
1019
|
+
</tr>
|
1020
|
+
<tr>
|
1021
|
+
<td align="left" valign="top"><p class="table">ct_toolbar</p></td>
|
1022
|
+
<td align="left" valign="top"><p class="table">the toolbar</p></td>
|
1023
|
+
</tr>
|
1024
|
+
<tr>
|
1025
|
+
<td align="left" valign="top"><p class="table">ct_toolbar_icon</p></td>
|
1026
|
+
<td align="left" valign="top"><p class="table">an icon of a toolbar button</p></td>
|
1027
|
+
</tr>
|
1028
|
+
<tr>
|
1029
|
+
<td align="left" valign="top"><p class="table">ct_tooltop_popup</p></td>
|
1030
|
+
<td align="left" valign="top"><p class="table">tooltip popup</p></td>
|
1031
|
+
</tr>
|
1032
|
+
<tr>
|
1033
|
+
<td align="left" valign="top"><p class="table">ct_<…>_button</p></td>
|
1034
|
+
<td align="left" valign="top"><p class="table">specific toolbar buttons</p></td>
|
1035
|
+
</tr>
|
1036
|
+
<tr>
|
1037
|
+
<td align="left" valign="top"><p class="table">ct_<…>_dialog</p></td>
|
1038
|
+
<td align="left" valign="top"><p class="table">marks nodes serving as dialog windows</p></td>
|
1039
|
+
</tr>
|
1040
|
+
<tr>
|
1041
|
+
<td align="left" valign="top"><p class="table">ct_clipboard_area</p></td>
|
1042
|
+
<td align="left" valign="top"><p class="table">the clipboard area (textarea) in the module editor</p></td>
|
1043
|
+
</tr>
|
1044
|
+
</tbody>
|
1045
|
+
</table>
|
1046
|
+
</div>
|
1047
|
+
</div>
|
1048
|
+
<div id="footer">
|
1049
|
+
<div id="footer-text">
|
1050
|
+
Last updated 2010-06-14 14:05:31 WEDT
|
1051
|
+
</div>
|
1052
|
+
</div>
|
1053
|
+
</body>
|
1054
|
+
</html>
|