concrete 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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,68 @@
|
|
|
1
|
+
// Concrete Model Editor
|
|
2
|
+
//
|
|
3
|
+
// Copyright (c) 2010 Martin Thiede
|
|
4
|
+
//
|
|
5
|
+
// Concrete is freely distributable under the terms of an MIT-style license.
|
|
6
|
+
|
|
7
|
+
Element.addMethods({
|
|
8
|
+
left: function(e) {
|
|
9
|
+
return e.cumulativeOffset().left;
|
|
10
|
+
},
|
|
11
|
+
right: function(e) {
|
|
12
|
+
return e.cumulativeOffset().left + Element.getWidth(e);
|
|
13
|
+
},
|
|
14
|
+
top: function(e) {
|
|
15
|
+
return e.cumulativeOffset().top;
|
|
16
|
+
},
|
|
17
|
+
bottom: function(e) {
|
|
18
|
+
return e.cumulativeOffset().top + Element.getHeight(e);
|
|
19
|
+
},
|
|
20
|
+
matchesClasses: function(e, classes) {
|
|
21
|
+
for (var i=0; i<classes.length; i++) {
|
|
22
|
+
if (e.hasClassName(classes[i])) return true;
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
},
|
|
26
|
+
// this method is necessary because Prototype's up() doesn't support searching for multiple classes
|
|
27
|
+
// optionally a single class may be specified, in this case this is a speed improvement over up()
|
|
28
|
+
findAncestor: function(e, classes) {
|
|
29
|
+
var parent = e.parentNode;
|
|
30
|
+
if (classes instanceof Array) {
|
|
31
|
+
while (!parent.matchesClasses(classes)) {
|
|
32
|
+
parent = parent.parentNode;
|
|
33
|
+
if (!parent || parent.nodeType != 1) return;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
while (!parent.hasClassName(classes)) {
|
|
38
|
+
parent = parent.parentNode;
|
|
39
|
+
if (!parent || parent.nodeType != 1) return;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return parent;
|
|
43
|
+
},
|
|
44
|
+
findAncestorOrSelf: function(e, classes) {
|
|
45
|
+
if ( e.matchesClasses(classes) )
|
|
46
|
+
return e;
|
|
47
|
+
else
|
|
48
|
+
return e.findAncestor(classes);
|
|
49
|
+
},
|
|
50
|
+
// collects the first elements on each descendant path which match the searchClasses
|
|
51
|
+
// stops searching a path when it hits an element matching the stopClasses
|
|
52
|
+
findFirstDescendants: function(e, searchClasses, stopClasses) {
|
|
53
|
+
return e.childElements().collect(function(c) {
|
|
54
|
+
if (c.matchesClasses(searchClasses)) {
|
|
55
|
+
return c;
|
|
56
|
+
}
|
|
57
|
+
else if (c.matchesClasses(stopClasses)) {
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
return c.findFirstDescendants(searchClasses, stopClasses);
|
|
62
|
+
}
|
|
63
|
+
}, this).flatten();
|
|
64
|
+
},
|
|
65
|
+
allChildren: function(e) {
|
|
66
|
+
return $A(e.getElementsByTagName("*"));
|
|
67
|
+
}
|
|
68
|
+
})
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// Concrete Model Editor
|
|
2
|
+
//
|
|
3
|
+
// Copyright (c) 2010 Martin Thiede
|
|
4
|
+
//
|
|
5
|
+
// Concrete is freely distributable under the terms of an MIT-style license.
|
|
6
|
+
|
|
7
|
+
// Interface ExternalIdentifierProvider
|
|
8
|
+
//
|
|
9
|
+
// getElementInfo: function(ident, options) {}
|
|
10
|
+
// returns the element info if +ident+ is the identifier of an element, false otherwise
|
|
11
|
+
// the element info is an object with properties +type+ and +module+
|
|
12
|
+
// if option +ignoreModule+ is specified, elements from that module will be ignored
|
|
13
|
+
//
|
|
14
|
+
// getIdentifiers: function(types) {}
|
|
15
|
+
// returns the identifiers of all elements of classes given in +types+
|
|
16
|
+
|
|
17
|
+
// assumes an index consisting of modules, each with the following structure:
|
|
18
|
+
// [ { name: <module name>, elements: [
|
|
19
|
+
// { _class: <class name>, name: <element name>, elements: [
|
|
20
|
+
// { _class: <class name>, name: <element name>, ...
|
|
21
|
+
//
|
|
22
|
+
// optionally the property "elements" may hold a single element instead of an Array
|
|
23
|
+
//
|
|
24
|
+
Concrete.IndexBasedExternalIdentifierProvider = Class.create({
|
|
25
|
+
|
|
26
|
+
initialize: function(index, metamodelProvider) {
|
|
27
|
+
this._index = index;
|
|
28
|
+
this._metamodelProvider = metamodelProvider;
|
|
29
|
+
this._separator = "/";
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
getElementInfo: function(ident, options) {
|
|
33
|
+
if (!Object.isString(ident)) return false;
|
|
34
|
+
for (var i=0; i<this._index.size(); i++) {
|
|
35
|
+
var m = this._index[i];
|
|
36
|
+
if (!options || !options.ignoreModule || options.ignoreModule != m.name) {
|
|
37
|
+
var parts = ident.split(this._separator);
|
|
38
|
+
var type = this._getType(m, parts);
|
|
39
|
+
if (type) return { type: type, module: m.name };
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
return false;
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
getIdentifiers: function(type) {
|
|
46
|
+
var typenames = type.allSubTypes().concat(type).collect(function(t){return t.name});
|
|
47
|
+
var result = [];
|
|
48
|
+
this._index.each(function(m) {
|
|
49
|
+
result = result.concat(this._getIdentifiers(m, typenames, ""));
|
|
50
|
+
}, this);
|
|
51
|
+
return result;
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
getAllElementInfo: function() {
|
|
55
|
+
var result = [];
|
|
56
|
+
this._index.each(function(m) {
|
|
57
|
+
result = result.concat(this._getAllElementInfo(m, "", m));
|
|
58
|
+
}, this);
|
|
59
|
+
return result;
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
// private
|
|
63
|
+
|
|
64
|
+
_getType: function(cont, parts) {
|
|
65
|
+
var local = parts.shift();
|
|
66
|
+
while (local == "" && parts.size() > 0) { local = parts.shift() }
|
|
67
|
+
if (local == "") return false;
|
|
68
|
+
var elements = cont.elements
|
|
69
|
+
if (!(elements instanceof Array)) elements = [elements].compact();
|
|
70
|
+
var e = elements.find(function(e) { return e.name == local });
|
|
71
|
+
if (e) {
|
|
72
|
+
if (parts.size() > 0) {
|
|
73
|
+
return this._getType(e, parts);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
return this._metamodelProvider.metaclassesByName[e._class];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
_getIdentifiers: function(cont, typenames, path) {
|
|
85
|
+
var result = [];
|
|
86
|
+
var elements = cont.elements
|
|
87
|
+
if (!(elements instanceof Array)) elements = [elements].compact();
|
|
88
|
+
elements.each(function(e) {
|
|
89
|
+
var epath = path + this._separator + e.name;
|
|
90
|
+
if (typenames.include(e._class)) {
|
|
91
|
+
result.push(epath);
|
|
92
|
+
}
|
|
93
|
+
result = result.concat(this._getIdentifiers(e, typenames, epath));
|
|
94
|
+
}, this);
|
|
95
|
+
return result;
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
_getAllElementInfo: function(cont, path, module) {
|
|
99
|
+
var result = [];
|
|
100
|
+
var elements = cont.elements
|
|
101
|
+
if (!(elements instanceof Array)) elements = [elements].compact();
|
|
102
|
+
elements.each(function(e) {
|
|
103
|
+
var epath = path + this._separator + e.name;
|
|
104
|
+
result.push({identifier: epath, type: e._class, module: module.name});
|
|
105
|
+
result = result.concat(this._getAllElementInfo(e, epath, module));
|
|
106
|
+
}, this);
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
});
|
|
112
|
+
|
data/concrete/helper.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Concrete Model Editor
|
|
2
|
+
//
|
|
3
|
+
// Copyright (c) 2010 Martin Thiede
|
|
4
|
+
//
|
|
5
|
+
// Concrete is freely distributable under the terms of an MIT-style license.
|
|
6
|
+
|
|
7
|
+
Concrete.Helper = {
|
|
8
|
+
|
|
9
|
+
createDOMNode: function(tag, attrs, inner) {
|
|
10
|
+
var node = new Element(tag);
|
|
11
|
+
if (attrs.class) node.className = attrs.class;
|
|
12
|
+
if (attrs.style) node.writeAttribute("style", attrs.style);
|
|
13
|
+
node.innerHTML = inner;
|
|
14
|
+
return node;
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
// simple pretty printing, objects in an array are indented
|
|
18
|
+
prettyPrintJSON: function(json) {
|
|
19
|
+
var lastIndex = 0;
|
|
20
|
+
var result = "";
|
|
21
|
+
var indent = "";
|
|
22
|
+
var objectNestLevel = 0;
|
|
23
|
+
var dedentLevels = [];
|
|
24
|
+
var firstObject = true;
|
|
25
|
+
var firstList = true;
|
|
26
|
+
var writeLine = function(i) {
|
|
27
|
+
result = result + json.slice(lastIndex, i);
|
|
28
|
+
lastIndex = i;
|
|
29
|
+
}
|
|
30
|
+
for (var i=0; i < json.length; i++) {
|
|
31
|
+
if (json[i] == "{" ) {
|
|
32
|
+
writeLine(i);
|
|
33
|
+
if (!firstObject) result = result + "\n" + indent;
|
|
34
|
+
firstObject = false;
|
|
35
|
+
objectNestLevel++;
|
|
36
|
+
}
|
|
37
|
+
else if (json[i] == "}" ) {
|
|
38
|
+
objectNestLevel--;
|
|
39
|
+
if (objectNestLevel == dedentLevels.last()) {
|
|
40
|
+
dedentLevels.pop();
|
|
41
|
+
indent = indent.slice(2);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else if (json[i] == "[") {
|
|
45
|
+
writeLine(i+1);
|
|
46
|
+
if (!firstList) indent = indent + " ";
|
|
47
|
+
firstList = false;
|
|
48
|
+
}
|
|
49
|
+
else if (json[i] == "]") {
|
|
50
|
+
indent = indent.slice(2);
|
|
51
|
+
}
|
|
52
|
+
else if (json[i] == ":" && json[i+2] == "{") {
|
|
53
|
+
writeLine(i+2);
|
|
54
|
+
indent = indent + " ";
|
|
55
|
+
dedentLevels.push(objectNestLevel);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
writeLine(json.length);
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
};
|
|
63
|
+
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// Concrete Model Editor
|
|
2
|
+
//
|
|
3
|
+
// Copyright (c) 2010 Martin Thiede
|
|
4
|
+
//
|
|
5
|
+
// Concrete is freely distributable under the terms of an MIT-style license.
|
|
6
|
+
|
|
7
|
+
Concrete.AbstractIdentifierProvider = Class.create({
|
|
8
|
+
|
|
9
|
+
initialize: function() {
|
|
10
|
+
this._elementByIdentifier = {};
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
// returns the identifier for +element+
|
|
14
|
+
// returns undefined if the element has no identifier
|
|
15
|
+
getIdentifier: function(element) {
|
|
16
|
+
return element._identifier;
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
// returns the element associated with +identifier+
|
|
20
|
+
// returns undefined if there is no element with this identifier
|
|
21
|
+
getElement: function(identifier) {
|
|
22
|
+
return this._elementByIdentifier[identifier];
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
// ModelChangeListener Interface
|
|
26
|
+
|
|
27
|
+
elementAdded: function(element) {
|
|
28
|
+
throw new Error("Abstract, override in subclass");
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
elementChanged: function(element, feature) {
|
|
32
|
+
throw new Error("Abstract, override in subclass");
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
elementRemoved: function(element) {
|
|
36
|
+
throw new Error("Abstract, override in subclass");
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
rootChanged: function(root) {
|
|
40
|
+
throw new Error("Abstract, override in subclass");
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
commitChanges: function() {
|
|
44
|
+
throw new Error("Abstract, override in subclass");
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
// ModelChangeListener End
|
|
48
|
+
|
|
49
|
+
// Private
|
|
50
|
+
|
|
51
|
+
_changeIdentifier: function(element, identifier) {
|
|
52
|
+
var identifierChanged = (identifier != element._identifier);
|
|
53
|
+
if (identifierChanged) {
|
|
54
|
+
var lastWithSameId = this._elementByIdentifier[identifier];
|
|
55
|
+
// old identifier
|
|
56
|
+
if (element._identifier) {
|
|
57
|
+
var ebi = this._elementByIdentifier[element._identifier];
|
|
58
|
+
if (ebi instanceof Array) {
|
|
59
|
+
var idx = ebi.indexOf(element);
|
|
60
|
+
if (idx >= 0) delete ebi[idx];
|
|
61
|
+
ebi = ebi.compact();
|
|
62
|
+
this._elementByIdentifier[element._identifier] = (ebi.size() > 1) ? ebi : ebi.first();
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
delete this._elementByIdentifier[element._identifier];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// new identifier
|
|
69
|
+
if (identifier == undefined) {
|
|
70
|
+
delete element._identifier;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
var ebi = this._elementByIdentifier[identifier];
|
|
74
|
+
if (ebi instanceof Array) {
|
|
75
|
+
ebi.push(element);
|
|
76
|
+
}
|
|
77
|
+
else if (ebi) {
|
|
78
|
+
this._elementByIdentifier[identifier] = [ebi, element];
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
this._elementByIdentifier[identifier] = element;
|
|
82
|
+
}
|
|
83
|
+
element._identifier = identifier;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
Concrete.QualifiedNameBasedIdentifierProvider = Class.create(Concrete.AbstractIdentifierProvider, {
|
|
90
|
+
|
|
91
|
+
// Options:
|
|
92
|
+
// - nameAttribute: name of the attribute which holds an element's (non qualified) name, defaults to "name"
|
|
93
|
+
// - separator: separator between parts (non qualified names) of qualified name, defaults to "/"
|
|
94
|
+
// - leadingSeparator: specifies if qualified names should start with a leading separator, defaults to "true"
|
|
95
|
+
initialize: function($super, options) {
|
|
96
|
+
$super();
|
|
97
|
+
this.options = options || {};
|
|
98
|
+
this.options.nameAttribute = this.options.nameAttribute || "name";
|
|
99
|
+
this.options.separator = this.options.separator || "/";
|
|
100
|
+
if (this.options.leadingSeparator == undefined) this.options.leadingSeparator = true;
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
// ModelChangeListener Interface
|
|
104
|
+
|
|
105
|
+
elementAdded: function(element) {
|
|
106
|
+
this._updateElement(element);
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
elementChanged: function(element, feature) {
|
|
110
|
+
this._updateElement(element);
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
elementRemoved: function(element) {
|
|
114
|
+
this._removeIdentifiers(element);
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
rootChanged: function(root) {
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
commitChanges: function() {
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
// ModelChangeListener End
|
|
124
|
+
|
|
125
|
+
_updateElement: function(element) {
|
|
126
|
+
var parent = element.ancestors().find(function(a) {return a._identifier; });
|
|
127
|
+
var qnamePrefix = (parent && parent._identifier) || "";
|
|
128
|
+
this._updateQNames(element, qnamePrefix);
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
_updateQNames: function(element, qnamePrefix) {
|
|
132
|
+
var nameAttribute = element.features.find(function(f) { return f.mmFeature.name == this.options.nameAttribute; }, this);
|
|
133
|
+
var nameValue = nameAttribute && nameAttribute.slot.childElements().select(function(e) { return !e.hasClassName("ct_empty"); }).first();
|
|
134
|
+
var name = nameValue && nameValue.value;
|
|
135
|
+
if (name) {
|
|
136
|
+
if (qnamePrefix.length > 0 || this.options.leadingSeparator) {
|
|
137
|
+
var qname = qnamePrefix+this.options.separator+name;
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
var qname = name;
|
|
141
|
+
}
|
|
142
|
+
this._changeIdentifier(element, qname);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
var qname = qnamePrefix;
|
|
146
|
+
this._changeIdentifier(element, undefined);
|
|
147
|
+
}
|
|
148
|
+
element.features.each(function(f) {
|
|
149
|
+
if (f.mmFeature.isContainment()) {
|
|
150
|
+
f.slot.childElements().each(function(e) {
|
|
151
|
+
this._updateQNames(e, qname);
|
|
152
|
+
}, this);
|
|
153
|
+
}
|
|
154
|
+
}, this);
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
_removeIdentifiers: function(element) {
|
|
158
|
+
this._changeIdentifier(element, undefined)
|
|
159
|
+
element.features.each(function(f) {
|
|
160
|
+
if (f.mmFeature.isContainment()) {
|
|
161
|
+
f.slot.childElements().each(function(e) {
|
|
162
|
+
this._removeIdentifiers(e);
|
|
163
|
+
}, this);
|
|
164
|
+
}
|
|
165
|
+
}, this);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Concrete Model Editor
|
|
2
|
+
//
|
|
3
|
+
// Copyright (c) 2010 Martin Thiede
|
|
4
|
+
//
|
|
5
|
+
// Concrete is freely distributable under the terms of an MIT-style license.
|
|
6
|
+
|
|
7
|
+
Concrete.InlineEditor = Class.create(Concrete.BasicInlineEditor, {
|
|
8
|
+
|
|
9
|
+
initialize: function(stateChangeFunc) {
|
|
10
|
+
this.stateChangeFunc = stateChangeFunc;
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
edit: function(element, opt) {
|
|
14
|
+
var init = opt.init || ""
|
|
15
|
+
var partial = opt.partial || false
|
|
16
|
+
if (opt.options instanceof Array) {
|
|
17
|
+
this._options = opt.options
|
|
18
|
+
this._regexp = undefined
|
|
19
|
+
}
|
|
20
|
+
else if (opt.options instanceof RegExp) {
|
|
21
|
+
this._options = []
|
|
22
|
+
this._regexp = opt.options
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
this._options = []
|
|
26
|
+
}
|
|
27
|
+
this._successHandler = opt.onSuccess
|
|
28
|
+
this._failureHandler = opt.onFailure
|
|
29
|
+
this.isActive = true
|
|
30
|
+
this.stateChangeFunc(this.isActive);
|
|
31
|
+
this.show(element, init, partial, this._options)
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
finish: function() {
|
|
35
|
+
if ((this._options.size() == 0 || this._options.include(this.getText())) && (this._regexp == undefined || this._regexp.test(this.getText()))) {
|
|
36
|
+
this.isActive = false
|
|
37
|
+
this.stateChangeFunc(this.isActive);
|
|
38
|
+
this.hide()
|
|
39
|
+
if (this._successHandler) this._successHandler(this.getText())
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
this.setError()
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
cancel: function() {
|
|
47
|
+
this.isActive = false
|
|
48
|
+
this.stateChangeFunc(this.isActive);
|
|
49
|
+
this.hide()
|
|
50
|
+
if (this._failureHandler) this._failureHandler()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
|