diff --git a/web/js/CacheUMLExplorer.js b/web/js/CacheUMLExplorer.js
index 0a101ab..8e10ce7 100644
--- a/web/js/CacheUMLExplorer.js
+++ b/web/js/CacheUMLExplorer.js
@@ -18,6 +18,7 @@ var CacheUMLExplorer = function (treeViewContainer, classViewContainer) {
zoomInButton: id("button.zoomIn"),
zoomOutButton: id("button.zoomOut"),
zoomNormalButton: id("button.zoomNormal"),
+ helpButton: id("button.showHelp"),
infoButton: id("button.showInfo"),
methodCodeView: id("methodCodeView"),
closeMethodCodeView: id("closeMethodCodeView"),
@@ -53,7 +54,11 @@ CacheUMLExplorer.prototype.init = function () {
this.classView.loadClass(hash.substr(7));
} else if (hash.indexOf("package:") === 1) {
this.classView.loadPackage(hash.substr(9));
+ } else {
+ this.classView.renderInfoGraphic();
}
+ } else {
+ this.classView.renderInfoGraphic();
}
this.elements.infoButton.addEventListener("click", function () {
diff --git a/web/js/ClassView.js b/web/js/ClassView.js
index 8227fb5..07d745f 100644
--- a/web/js/ClassView.js
+++ b/web/js/ClassView.js
@@ -73,10 +73,130 @@ ClassView.prototype.openClassDoc = function (className, nameSpace) {
};
+/**
+ * Render help info
+ */
+ClassView.prototype.renderInfoGraphic = function () {
+
+ this.cacheUMLExplorer.classTree.SELECTED_CLASS_NAME =
+ this.cacheUMLExplorer.elements.className.innerHTML =
+ "Welcome to Caché UML explorer!";
+
+ location.hash = "help";
+
+ this.showLoader();
+ this.render({
+ basePackageName: "Welcome to Cach? UML explorer!",
+ classes: {
+ "Shared object": {
+ super: "Super object",
+ parameters: {
+ "Also inherit Super object": {}
+ },
+ methods: {},
+ properties: {}
+ },
+ "Class name": {
+ super: "Super object",
+ ABSTRACT: 1,
+ FINAL: 1,
+ HIDDEN: 1,
+ NAMESPACE: "SAMPLES",
+ PROCEDUREBLOCK: 0,
+ SYSTEM: 4,
+ methods: {
+ "Abstract public method": {
+ abstract: 1
+ },
+ "Class method": {
+ classMethod: 1
+ },
+ "Client method": {
+ clientMethod: 1
+ },
+ "Final method": {
+ final: 1
+ },
+ "Not inheritable method": {
+ notInheritable: 1
+ },
+ "Private method": {
+ private: 1
+ },
+ "Sql procedure": {
+ sqlProc: 1
+ },
+ "Web method": {
+ webMethod: 1
+ },
+ "ZEN method": {
+ zenMethod: 1
+ },
+ "Method": {
+ returns: "%Return type"
+ }
+ },
+ parameters: {
+ "PARAMETER WITHOUT TYPE": {},
+ "PARAMETER": {
+ type: "Type"
+ }
+ },
+ properties: {
+ "Public property name": {
+ private: 0
+ },
+ "Private property name": {
+ private: 1
+ },
+ "Public read-only property": {
+ private: 0,
+ readOnly: 1
+ },
+ "Property": {
+ type: "Type of property"
+ },
+ "Other object": {
+ private: 0,
+ type: "Shared object"
+ },
+ "Another object": {
+ private: 1,
+ type: "Not shared object"
+ }
+ }
+ },
+ "Super object": {
+ methods: {},
+ properties: {},
+ parameters: {}
+ },
+ "HELP": {
+ parameters: {
+ "See the basics here!": {}
+ }
+ }
+ },
+ composition: {},
+ aggregation: {
+ "Class name": {
+ "Shared object": "1..1"
+ }
+ },
+ inheritance: {
+ "Class name": { "Super object": 1 },
+ "Shared object": { "Super object": 1 }
+ },
+ restrictPackage: 1
+ });
+
+ this.removeLoader();
+
+};
+
/**
* Returns array of signs to render or empry array.
*
- * @private
* @param classMetaData
*/
ClassView.prototype.getClassSigns = function (classMetaData) {
@@ -85,11 +205,11 @@ ClassView.prototype.getClassSigns = function (classMetaData) {
if (classMetaData["classType"]) signs.push({
icon: lib.image.greenPill,
- text: classMetaData["classType"],
+ text: lib.capitalize(classMetaData["classType"]),
textStyle: "fill:rgb(130,0,255)"
});
if (classMetaData["ABSTRACT"]) signs.push({
- icon: lib.image.iceCube,
+ icon: lib.image.crystalBall,
text: "Abstract",
textStyle: "fill:rgb(130,0,255)"
});
@@ -115,6 +235,29 @@ ClassView.prototype.getClassSigns = function (classMetaData) {
};
+/**
+ * Returns array of icons according to method metadata.
+ *
+ * @param method
+ */
+ClassView.prototype.getMethodIcons = function (method) {
+
+ var icons = [];
+
+ icons.push({ src: lib.image[method["private"] ? "minus" : "plus"] });
+ if (method["abstract"]) icons.push({ src: lib.image.crystalBall });
+ if (method["clientMethod"]) icons.push({ src: lib.image.user });
+ if (method["final"]) icons.push({ src: lib.image.blueFlag });
+ if (method["notInheritable"]) icons.push({ src: lib.image.redFlag });
+ if (method["sqlProc"]) icons.push({ src: lib.image.table });
+ if (method["webMethod"]) icons.push({ src: lib.image.earth });
+ if (method["zenMethod"]) icons.push({ src: lib.image.zed });
+ if (method["readOnly"]) icons.push({ src: lib.image.eye });
+
+ return icons;
+
+};
+
/**
* @param {string} name
* @param classMetaData
@@ -127,65 +270,53 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
classMethods = classMetaData["methods"],
self = this;
- var insertString = function (array, string, extraString) {
- array.push({ text: string + (extraString ? extraString : "")});
- };
-
var classInstance = new joint.shapes.uml.Class({
- name: name,
+ name: [{
+ text: name,
+ clickHandler: function () {
+ self.openClassDoc(name, classMetaData["NAMESPACE"]);
+ },
+ styles: {
+ cursor: "help"
+ }
+ }],
params: (function (params) {
var arr = [], n;
for (n in params) {
- insertString(arr, n + (params[n]["type"] ? ": " + params[n]["type"] : ""));
+ arr.push({
+ text: n + (params[n]["type"] ? ": " + params[n]["type"] : "")
+ });
}
return arr;
})(classParams),
attributes: (function (ps) {
var arr = [], n;
for (n in ps) {
- insertString(
- arr,
- (ps[n]["private"] ? "- " : "+ ") + n
- + (ps[n]["type"] ? ": " + ps[n]["type"] : "")
- );
+ arr.push({
+ text: n + (ps[n]["type"] ? ": " + ps[n]["type"] : ""),
+ icons: self.getMethodIcons(ps[n])
+ });
}
return arr;
})(classProps),
methods: (function (met) {
var arr = [], n;
for (n in met) {
- insertString(
- arr,
- (met[n]["private"] ? "- " : "+ ") + n
- + (met[n]["returns"] ? ": " + met[n]["returns"] : ""),
- (met[n]["classMethod"] ?
- "\x1b" + JSON.stringify({STYLES:{
- textDecoration: "underline"
- }}) : "")
- );
+ arr.push({
+ text: n + (met[n]["returns"] ? ": " + met[n]["returns"] : ""),
+ styles: (function (t) {
+ return t ? { textDecoration: "underline" } : {}
+ })(met[n]["classMethod"]),
+ clickHandler: (function (n) {
+ return function () { self.showMethodCode(name, n); }
+ })(n),
+ icons: self.getMethodIcons(met[n])
+ });
}
return arr;
})(classMethods),
- directProps: {
- nameClickHandler: function () {
- self.openClassDoc(name, classMetaData["NAMESPACE"]);
- }
- },
classSigns: this.getClassSigns(classMetaData),
- SYMBOL_12_WIDTH: self.SYMBOL_12_WIDTH,
- attrs: {
- ".uml-class-methods-text": {
- lineClickHandlers: (function (ps) {
- var arr = [], p;
- for (p in ps) {
- arr.push((function (p) { return function () {
- self.showMethodCode(name, p)
- }})(p));
- }
- return arr;
- })(classMethods)
- }
- }
+ SYMBOL_12_WIDTH: self.SYMBOL_12_WIDTH
});
this.objects.push(classInstance);
@@ -358,7 +489,7 @@ ClassView.prototype.loadClass = function (className) {
self.showLoader("Unable to get " + self.cacheUMLExplorer.classTree.SELECTED_CLASS_NAME);
console.error.call(console, err);
} else {
- self.cacheUMLExplorer.classView.render(data);
+ self.render(data);
}
});
@@ -380,7 +511,7 @@ ClassView.prototype.loadPackage = function (packageName) {
self.showLoader("Unable to get package " + packageName);
console.error.call(console, err);
} else {
- self.cacheUMLExplorer.classView.render(data);
+ self.render(data);
}
});
@@ -492,6 +623,9 @@ ClassView.prototype.init = function () {
this.cacheUMLExplorer.elements.closeMethodCodeView.addEventListener("click", function () {
self.hideMethodCode();
});
+ this.cacheUMLExplorer.elements.helpButton.addEventListener("click", function () {
+ self.renderInfoGraphic();
+ });
this.SYMBOL_12_WIDTH = (function () {
var e = document.createElementNS("http://www.w3.org/2000/svg", "text"),
diff --git a/web/js/Lib.js b/web/js/Lib.js
index e23a372..6df7342 100644
--- a/web/js/Lib.js
+++ b/web/js/Lib.js
@@ -41,6 +41,14 @@ Lib.prototype.countProperties = function (object) {
};
+/**
+ * Make first letter of string uppercase.
+ * @param {string} string
+ */
+Lib.prototype.capitalize = function (string) {
+ return string[0].toUpperCase() + string.substr(1);
+};
+
/**
* Contains graphic base64s for the application.
*/
@@ -51,5 +59,14 @@ Lib.prototype.image = {
ghost: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAKnRFWHRDcmVhdGlvbiBUaW1lAERvIDYgTXJ6IDIwMDMgMjM6NTk6MTcgKzAxMDCMVVlHAAAAB3RJTUUH0wMGFxkwngXNbAAAAAlwSFlzAAAK8AAACvABQqw0mAAAAARnQU1BAACxjwv8YQUAAAJkSURBVHjapVNNTxNRFL3TTvno9EuqmNZpymihWKhNkBrTLtQ0Gt1IYsqiEohrkiYuYOEPkISlEFmQuGqicclC2RAjLthha2hjMBSaJii0NLRTnDLTmY53pqGpKaKJL3l5d97cc+45790H8J+DOG1zdnbtXqm0P03T5us8L1RTqewnvd7wfG7uceKvjAsLX5+urqZrctOQJFmen//AR6Nvw2eCY7Hs1ZWV7SrHSQ1wPJ5W1xpSzsy8/zk5+cbVjNE0f+zt7T9hGDPp9wdgfT0BiUQWxscjsLj4GqpVgHD4vp5lD5/9kcBi6QhkMt/A5wtALleGjY0kDA/fht3dQ5BlAJOJAJq2PEKjmlMJurp0vTpdGzCMFxMZBBjB4ehTp6JAkpQiVsvEhNzTQjA29rlNFNnzPl8vJtHg9dLg93uAoi7A4OA1qFTqBAaDCeMKfYIjT4Lu7i1be/tlrVJ1auquume3WyESCYHRSAHLAoiiQmAEnuftLQpEUTtgs1kadvJ5Qa1qMFDqWqlICASwWs/B8XGVaVHAsqXQ0JBTjRWpxaIIJNmmgpQpCDKeg4xKL+J/0dtCYLebH5IkCRwHOCWsKKuVBaFOoCjAXgCdjsRcW/A3C6OjLz14aFeUq9JqASVqMbGjcfIEUfev0RBIUsMbsjmCwehAQ4Ek/bhkwkuOxw9gaekjZLM5cLl6YGTkARQKZWyqL5DJbIPb7YZA4Cb09/cRy8vv7iA0pT4mj+eVjqY3XxQKRyGK6tSixy1JktbQUid2cblUKt5yOpkbOztplqKo7wRBbHLc0XQyGcv/05M9a/wC59cUbcvinwEAAAAASUVORK5CYII=",
moleculeCubeCross: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAKnRFWHRDcmVhdGlvbiBUaW1lAE1pIDUgTXJ6IDIwMDMgMjM6MzY6MDEgKzAxMDC/PwNMAAAAB3RJTUUH0wMFFx0vZdSqcwAAAAlwSFlzAAAK8AAACvABQqw0mAAAAARnQU1BAACxjwv8YQUAAALsSURBVHjarVNrSJNhGH2+75vfvuY25/IuKs50UxNBrbwMFbwWqWnQxQwvf0qICBHth4JJZaWE6C+pDAuxKLFBzcRQ0ywrLbw3W1hqbl72remmm5t7c9YEu/zz/Hg5z+Fw4Dy8D8BOAAFgwwIQqQHIbXooFKwksul+DM5v0/nAtXLM8mhjyUaWHz9zrEE59KC88i4TxwJmlvUBY2ODYRJTK/M4kbIcJBQ8WcNs3tT2lqWaHfhJ75/TVeFaKNoMoCMoWuXJs6/kZgBmg+tp2UhzoaIrmVwC7rgCzFI7p2t0jDguUBQQxVFPYKWGNuiWaH7E0GBPWAJS5kyraxPa2I+f5VJ9eNTUBdVg2v6TjmwXWzOhnMUYi6WXo50pUiP7NtUY2NSE3L4YPORqaHgI8GyrV0l1TUt8atoxC190h3so3RahcEAdBCy7BwW7WH25Z/MT8zKzuq0zw0oo7dIMj7Rxt/AFBZT3S3VhBiO4tyWlGb+3SpRW324uh6MBpLLOuJUIhUI4kp4uRgid9jeDvKOiumaprg6PFHuz53A4Y/WxKIpDEoTmrwC34VEvqrQ0boM6TfX1ZRyoulHhqV9jnxK5MK8nJpcczc4OtPiMFJtjZLG3ArDf/wDvdmQZo08E460jJK1WKO0yExiE9KnW7COOllwcl/XwwsLyfHHjZOrSwJ53SsBcX3yIOQQwv7mDaVfYtahZxYBHgnBdzhdEcKFHMmU0XKrViXJzMiyefRSz1p/UP3YIWffP+zoINQCHN+T6zQBPBegGi4s6uhrr4mLjPUA3rYYFQYhMx3Pwma+uEhdOznr7OvKLZ0xgenv7psx1AdadANq2KrwCyMEEdrciEzwYsGIAMBuhs2sevK5cBVuChc4NyMZUo0Nlne3tzb8a/4FmAh9GBXvRSKiD+aWIr0apzghlOaLXfq6IbqxfbwWw/98dbVZwwkHecueTr1Zjyp8EuK+agF6KgfkxmQgbb5E+Ogig3pGr/Rd+Ai1UJxH01MR4AAAAAElFTkSuQmCC",
greenPill: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAK3RFWHRDcmVhdGlvbiBUaW1lAE1pIDE3IFNlcCAyMDAzIDIzOjI5OjEwICswMTAwQo74agAAAAd0SU1FB9MJERUdI/ot6l8AAAAJcEhZcwAACvAAAArwAUKsNJgAAAAEZ0FNQQAAsY8L/GEFAAACa0lEQVR42qWTT0hUQRzHv+/Ne+7uc3dphVSMjYoWsbA/h6g8iNWtKCjqoEmXugoh0aFDHkICLx2ELh0khAjKCIsKPGSY7FL+QYvIlCKSfM99m2/dt7O7789Ms4fCUknoC78fM8x8P/zmNzPAf0r6NejpGW4Nh8m1aLQybhjWhCSFbnR2Hn65IUpX1/P2oaE55vucU8p5Nsv54OBHv7d3/OqGAN3dz97rOucLus/TJue6ISAW5+Mpi9++NXnnSscTdT2vXE7BoBpPmzlYVgk0z6CIg9kFhtfBPqQSNy99PdT34uzEsdi6AF3PTGcyJuycDbfEMW1+wIm3ccwGBrDjgI14k3V00ZxLNifrd64J8H3SPT72iS0t/YCeNtA6eRAtiW2IqVVw86JCSUVzw+56vuykGodrW1YCSDklkw/m9u87J0jekae5fpDIDKJyCAWfig0EnIsl5iFRW6MZeq5NviB9s/oLU78BZY2O3n/V2HAmMZwf2BMN5eA7HMxjKHmOADARHI7noi4UIxmTnqSnvWTxoftZWVmOprkX82Zhu15Bm5woR6DSRSisoBhxEKxUQQgRRQK7gtXknbFwXViGpL+bgstaTSDnvamvjW1VNVkYFWgRBRUBAlmRQSRJhIIRY7642JENrQaU1Ya9GgIjW6rDETUooSJIoKjlEAAi5jLBxPJiOttFq5U1AfcwRU95rd+p/XhTTFWIMKtlsypBJTKYuLssLT36o4mrNMNn/TpuOjY7zhmTPMrgFrl4aD7mLXtWvPvzmAJdHyDEv/AxvllKFbN+vFRgVdT20suF0l3msnYMILOhf/Iv/QS2OyBbr28yxQAAAABJRU5ErkJggg==",
- iceCube: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAK3RFWHRDcmVhdGlvbiBUaW1lAE1pIDE5IEZlYiAyMDAzIDAwOjU2OjEzICswMTAwhV8lEQAAAAd0SU1FB9MCEwAKIKGTp3IAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAEZ0FNQQAAsY8L/GEFAAACoUlEQVR42qWTz08TQRTHvzOz3W63lLbQWixIBRU08QdcTAwxil5M0IPRuwfiP6DGq3f9B4gXPegBLx5M8KAnY6JEQtB4QIOGIhhagVbLtrvbnRnfQqwYj0wyO28y8z7v+97bAXY52B/jflHnN1cwmmlTp3tTOKYYhp+t+7FAonIiLsp5Q5RW6qpc9VQpcLDka/Xkzmhs0Qidn6/qiZEOXE/0hkCOL75kjUDjYlwgE2Xp/ZZIL3vBoPA1phZcJHMMqXU2Tq6DW4DFqjduWIxlOUefLdgBUwAmHdjb6r65Cg+Xm/hck+i2GYpNhbhgA+HZFsBpKuNVRUNoYI/JMUSR10lBv8UxYJNNDnsthqH2CGZ+BogEgFQqaAF8qd2UgCU0A91DmRzmHYVKU2ODQO8dCUnwGtkWZ6BM4PjaDX15+FFSNxlZFbogaA2nRVkE0ARRsGmfpD35ImcyXMpGoQLdaAGSgjlRxhAnPZzoaYPjYIzjsG0gFxXYR1NTfbvMcAUelzw0KGgLUHVlszdmoDvKsY/yXqGiFT1FTVYhHHWp4ChKx1eULnCh0wQ14q8CLbUf5jhdlTiTNuFpjdlfElNrATJU1KKrcZzkHU0IMLo3U6PgSnmtIkakdgiDBO0mSR51EgUqgmRhXRTaKP+iJ0kBwxtqZZ3OI9D1FmDVDZwRkl+mqrsU7VrBwpXstrMkNcNEThoM7TQ3qde9dgR331amW4D5jdqLl5/MU1cLMRzp5PhI0fIRvtW6bIT+xgjw9AcpI1XLJY5Hc8Hk7Dtxe8db0Ozkg9pYLpoYM7k639FeP9TfI5BKM1zusTCzGaDkSizMBY3JD/aNrzf5xH+PaefI3FrqFqo2moqZ5zq7omfzKaNv9bs7+3pNjONeYW63L/if8Rs4lyRrD9xpXAAAAABJRU5ErkJggg=="
+ iceCube: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAK3RFWHRDcmVhdGlvbiBUaW1lAE1pIDE5IEZlYiAyMDAzIDAwOjU2OjEzICswMTAwhV8lEQAAAAd0SU1FB9MCEwAKIKGTp3IAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAEZ0FNQQAAsY8L/GEFAAACoUlEQVR42qWTz08TQRTHvzOz3W63lLbQWixIBRU08QdcTAwxil5M0IPRuwfiP6DGq3f9B4gXPegBLx5M8KAnY6JEQtB4QIOGIhhagVbLtrvbnRnfQqwYj0wyO28y8z7v+97bAXY52B/jflHnN1cwmmlTp3tTOKYYhp+t+7FAonIiLsp5Q5RW6qpc9VQpcLDka/Xkzmhs0Qidn6/qiZEOXE/0hkCOL75kjUDjYlwgE2Xp/ZZIL3vBoPA1phZcJHMMqXU2Tq6DW4DFqjduWIxlOUefLdgBUwAmHdjb6r65Cg+Xm/hck+i2GYpNhbhgA+HZFsBpKuNVRUNoYI/JMUSR10lBv8UxYJNNDnsthqH2CGZ+BogEgFQqaAF8qd2UgCU0A91DmRzmHYVKU2ODQO8dCUnwGtkWZ6BM4PjaDX15+FFSNxlZFbogaA2nRVkE0ARRsGmfpD35ImcyXMpGoQLdaAGSgjlRxhAnPZzoaYPjYIzjsG0gFxXYR1NTfbvMcAUelzw0KGgLUHVlszdmoDvKsY/yXqGiFT1FTVYhHHWp4ChKx1eULnCh0wQ14q8CLbUf5jhdlTiTNuFpjdlfElNrATJU1KKrcZzkHU0IMLo3U6PgSnmtIkakdgiDBO0mSR51EgUqgmRhXRTaKP+iJ0kBwxtqZZ3OI9D1FmDVDZwRkl+mqrsU7VrBwpXstrMkNcNEThoM7TQ3qde9dgR331amW4D5jdqLl5/MU1cLMRzp5PhI0fIRvtW6bIT+xgjw9AcpI1XLJY5Hc8Hk7Dtxe8db0Ozkg9pYLpoYM7k639FeP9TfI5BKM1zusTCzGaDkSizMBY3JD/aNrzf5xH+PaefI3FrqFqo2moqZ5zq7omfzKaNv9bs7+3pNjONeYW63L/if8Rs4lyRrD9xpXAAAAABJRU5ErkJggg==",
+ minus: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABNElEQVR42u2SsUoDQRCG/73EEBMPLCwkhahgI1j6BHYiFvoUFhZB8OmsBMEHCAGxEImEgImBvYu5y+3u+O/tRQtLCy08mJu5ufn+mZs9hR9e6l8ASk7O+tjttDEvvsuJoy37uOCsvzHZqAOD0UzJdVdwegiMXoGVGusiLxuKvBnPWnoKOFpBs0y2WHf7AGUvL3R0tBdjMCRI9VkKTMdAohlngE4IETD2C84Zk3dPOlHzq27SPFhfw/0d8ObBNHQrbAC9N0ur8pkrm+kXnSp9fqzjHROj9wg0V1kgFVxB3lsCWTVBXn2GEYwn74nqbW/K1v4GzHBCVe7AFOVLERvE2FWMfEI+FiuIONzzIoe6aTT6nVa9nWcLTqUIlmdT+mBV7BfqFCwfHGqIuNgpt/QHfqRfF/gAIz+4k570HlcAAAAASUVORK5CYII=",
+ plus: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAABh0lEQVQ4y52SPUtcURCGn3Pu2V3ZpAhaLAQtQiwDVrGSoK1dKlvxP1j6D2wFK6ukCf6DkCJoE6IogWCzoiFgsHDDsnv3494zMykuCYl774KZ7hzeeZh35nWU1MrBorUWZgj1GgAxy7n9PuJ4q+3ua0MZYJBlbLxc52vnDQDd1HN12SyTlgMAUEfNNwBIrFJVDYjqEAVRSMf+4QBUyMVjQJQpE6wcLJYOmOWOYe5QgywXuv0hz3dnJ7ShRoOt188w54laNGgeOL97BxpQPM3HjlerCS9ay6gVtlTg8P0JIRspX24/46ghAgpE9ajWEQNVEPOYwfnNKfwGAN1enyBixOjwDnIFU080MEDEIUCMxVsNogIGikcihJgZ7euk+AWg2NhSa41veoQa/LiJADyq37vUWAnpYMzZx39383PQYWmTP5YAPn24K7/Cxc71RDznt5/ak+Yc444HBHGFJN0bTWgrE5KLYSaIJZhSWZVBEgPRBKWw8mDA3+fS/5lg/+0hvaxbAKZk+ReMaMs7XA7SqAAAAABJRU5ErkJggg==",
+ crystalBall: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAK3RFWHRDcmVhdGlvbiBUaW1lAEZyIDE5IERleiAyMDAzIDIwOjIzOjM3ICswMTAwgTNEtwAAAAd0SU1FB9MCGRcHLoVRoakAAAAJcEhZcwAACvAAAArwAUKsNJgAAAAEZ0FNQQAAsY8L/GEFAAACeUlEQVR42qWTy08TURTGv3m3nSm2lVcLKYkkGIVA3MhSNsQtK6uJG1m4UBJZ+l8YdhhYYKJ148ZHWBlcGYm60EIGfPAoFZBiQYZ2Ou/xzERMGogbTnJzMnfu+d3vPC5wSmNO2nw4Odmpadqdqq4PeUCSBTYlQXiVTqenbo2O1v4LeJrP51ZKpenW9nalv7cXqWQSW9vbWFBV7O/srJ9NJkfujo19PhEwPTU1XDk8nO0fGOA702lIkQgYhoFt2zAMAyvFItRCoZyQ5Uv3xse3ghjuKPjRzAz7s1KZzXZ3t6QSCZB0OK4L23FgWBbqBBF4Hg7DyHvlcurN3NzzII49ApRKpUFelnsYloXj++FyAwh5n1T45C3PAycIYCXp2vVcTgzi+COAUa/3tTU3Q6ebtioVRGIxSJIU5uhRYJCCYZpgCRCJx2We58/Rr+V/gFqt5kVkGTwdEChQEEXQIQSKfAIwf/ddSknb3w8u9BoUkBVMXUc8kwkhUjQKjiAsAQIFLtXBrNdBuaCmaYeqqq411ODBxMTHzfXiokJtC+UTQInHoTQ1hV4idVFFQYy+vy8uPlaXl+2GLgTmJ1oKQmv6ZldvHxcAAlA0JofyQWq4RAr5J/nS23fzN3Y3ivqxCfSz6CtexOqH+7f9+aUl/xOV/gutAq15VfWfjQz7L1i8XgWyxwbJvwwRHdk1dGUzKK7D+foD1V+AGXSoAliUrEGN26UIxcG3wTp6Gov4Hr511dwTLSeDM0nw5xkk0gdAVYPVBpTpBehUQ5M852L3xFF2OxFd85Dz4uKQyHMX4LodjmmLVcuvHujY+G1hoWZj7oqFlx00Y6d9yaH9AfjUFDAtnmCxAAAAAElFTkSuQmCC",
+ user: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACyUlEQVR42nWTa0hTYRjH/+dsZze10i5j81JhLqOijBSVqcSIjKLAvGSB0Lf1QcxSJCFDoRsUZQT5IVJKIx2VlWIfSsxrWSrzEpmXWro5LzHNy25n5/Ruo0Jx5/By4Ln8nuf98z8UVnmURW0lieFrsxUbZLLZBTv/YXSubO6386LpWoJ1ZS21MhBR0v62NGuXJiYsADMOQEAqBqdtKNb1D09NLqkM15N4n4CNeU3qolRVS0q0Am0GG2iaB0XKQ9dLoTdYUFzZlz1+I+meT0Dwhcb7rwvjteMLFFjeBZpk3eNEZA2BiEbJI31re15Mgk/AzsvNt17kq89/NFvhJwAYigZPKliew6ZACa5U9JgbcvYrfAMuNd2uzVef65y0w8HxsDg42Fw82YKDzF+Mmmd6c0dBnG9AiLb+bmlBYvanXxzsDue/tFgkxKLDhYbnPfXDNzVHfQJCtXXyrSq5OUq9DbyN9STdIooDGHzRm9DdNnTY+OD4G58A/9SaCKXC71t6WhSmeAa80wWKKEkREd+/0mPWbDlrrkovWxUQeFp35mDc5ofHkrdjYJrFiMUGxt1MXgFNg5EIMdo3jqHPI9Vj5SknlwGCMnTRB+LDOjNT96KyawZLZLKMob1XgNc3AqEA0gApxgaMGGweuGN6kpHrAQSeepq8Ria6WpiniarutQAcBzEt8DRx1P8VvV8e0nV+GHzXh9mxSY2xKrORitS+rIuN3XKEDZGj3zAPf5G7i1p2RwpeQ7kVFTIi2GcXYWzvbzVUpCVQe3LqepMO7djdOs/AOW8FjZVT/1Joj6BuPWg/Ccx1HROG8hNKskFtl1Il3/dTEghifkAmIYM4z0yKmMkTcx8n6z02B7gFK6xfv5uMj9ODKXlqZRBrc6pEUnEuJWUiIRGFw8WSXcXEAESLJfIH0wIhHOwEWNcwZ3d0k1gLLRMPmHRZP/4A67cYINx3gGMAAAAASUVORK5CYII=",
+ redFlag: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAKnRFWHRDcmVhdGlvbiBUaW1lAERpIDIgU2VwIDIwMDMgMTY6MDk6MzEgKzAxMDAbRI2sAAAAB3RJTUUH0wkCDgsfmwWX7wAAAAlwSFlzAAALEgAACxIB0t1+/AAAAARnQU1BAACxjwv8YQUAAAHnSURBVHjapZK/axRBFMe/s79md0nOhEQtvErwBwhik0JBTCGW1hZXpdFWFCz9G4QUV9gasBBFEJU0R2wMKFhYCBIPlLvb3MU79/b2bn/c7Ph2wy4LZ+AkDx4MM/P9zHvfecAxg+WLer3+iKnq3bj90z71/tmbW60fWx7DKI5gCRW31TOVm4lIFgKB4bDtf7zmyHupTssB1Wr1/o319dOv3m5jde/1hn39/IYSAPK3D1syaPYUuLgCrF3Ap4c7q3AOMp2SA3zf70zGY3T3HfTCBPq5BSxeOYHKSQXaXgeYSiCiDKbw++Ew1xUVeJ7naJoG2+QYC9qO6bJMgKTc6OHaG8UFQCkdOUIImJxjIg0CCLpcVuYKhskgcGcAjLFOEAQwdAMTZiBJSy4/m7LUQ4UbYrYFRVGcFGBSC5HKIQUBNFKplDrDn0GMwRcXy1YfEY4AhGGYAWLJ4X53oQcSSS9Erz2Vn3f6T8mOF9FW6+wSsDsDoMha4IaONl/B5kv/+dWDXw1iCF3FtzvAh38NUgGgH8gq4LoOVlnEu0uXvz5uNOrZoTh6EgsTpZQpQBqGAZOSA0vzjHIBqNVqHlUxMk0TnL6SPPk/QBrkwb5lWRmAYPY8gLKJ6Ha7m81m84Hrui2CPJkHcOz4C2fdx/hnBd3YAAAAAElFTkSuQmCC",
+ table: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADC0lEQVR42p2TS2wbRRyHv5ldr2Nnk9ixHbe0QC2BWoGQONGQFAgPicIBBBQkhBAHHleoQNw4cCwPcUOoQryCUtkkbSJLEVCVtiBRDkUUFQmaCrUQKCJOG7vrR7Pr3eHvdaB3ZrWa3dndb/6/b2bVgem5x7bvKL0WhcoYei1ERR5GD8u15mpryZn6b2wgYamfz5x/V3339Q/GLx3F+Hb8QAnAxD3SXwUo+vh/xxKJiM6p24gBh7c+zfLqGknLkjcd0omXaAdvYozamNEn6dyPH3wvYzW5TxIOtNjz66E+oJx7jp9qNVK2IqEHyVovshrs25hNyREwrHfT5iTr0Qra9AAd9v5ViQHezl23un4dHElRW4cTDXhoDLpRv3xbONUVGM9AIQlBKBFG4KvqiaY6duSYN7lrwq3XG3EFNV/xbV3x8FiEvwFw5JyvaSYyhoJj6HQNuVyG6sIXTXX8yyPexJ3jrtfwGBDAhY7hm1WLx7eErJvYmsSCuT80k3nD5pShFRhGs8NUD34eA8xbzRvQgU8maaG15lJgcVOuJ9AmJV7TjsWyb3G9rOKQROi5HcpmcY4fRC3OL3rjd427l+uXxb7mz7biqFTw1LVdrkT9CpKWYWbZYqoQco1AWuIpl8+wMFttqrnKgnfHPZPu2lodtwfoKBb/tnl+m087VLGDtADeP+/wQLHLFonQlAiF/Ciz5fmmOlwue/c9OOU2LtUZSsBZT1OW2V7ZHnBFbEdSRVI4+85Y7BEvJTeiIXKKYzk++agSA8z04E7CdpvRZIIuFr91NLcX5Utti0DNoMg97dncnDWMDMheFWo2n2e1/B7q4w9mvIm7JcLFNYYdzbm2pnLB5tUbfdYlglGKlDa8cTbBE1tDtqWjOEI+n+OzmVnUgU8rzXt3Tw1elK08IoBfmrD/nM3btwR9B1JIOmF4+bTNC6WQHS7UexE25flw/3QMMPlNBeo9iXEFFodWUuy9rtlfhd6fJ/vgnd9dHhnrUEqHtHzIjI5w6uSPqGeefPbR4ubiHP+jLS0tvf4PKUZIoAyrwMEAAAAASUVORK5CYII=",
+ earth: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADUklEQVR42l1TW2hcVRRd5z7mcedOXtMmmmknpg+VZEIFrfjT0lZqQiemoWXyVxpRKNUKiiD4WUHBHxE/IvVnIuhHDLYiHUhKBEmxUEgKLbEW0kkyebSTmWle87iPmXNOd6a0VA9cOHeffdZae+19GP63XhvJRPv3+o7uCWrfpwq8Fmv1K9nLc9Z52q6Mv9t88/l89nTTl3xoRuu8o2c6zZ5XG3XMbEmoUiBTYQiqQJ0qIewqfpwpjV1btuP/nA0XnwHsHpo3hmPNd49FjLYncBILRYG/1wUadAZbAJ1eib1eQFckvr1dTA/dLnakzreVawBfT+bHvjgU6oYQ4IJhyRJYcoANV0JTUAOI+gQaCditAi8YDBcm18Z/iL3Yw966dP/E5GAkqasqbC5xqyCRLgMGyfbQ5W0XHIq/bW5flnhUAXboQNaqYuDKgxiL/7KQGBnYPVhwBR4Qa5GSc5yhIiSYBAr0f8CgMjU6q5AUijsViRZi+Pyv7DA7+/vKavxIa7NacvB6QAEn1iVL4l8bZJ7EJjEerWeIEECOSCy6XKlyAtDx5Y18ll2YyFj7XtnhS226eCeooHcnQ4kUTG8J3CmJWhkGYwiRebvI0CZNoEqlSIXh3J+PbPbRtYzVvj/kW1x30ElS39/lwQaxBFUFc6UKvlpwoZKsnM1xsEHBh2EdnHMk8hI/3czZrC8xu3roWHvzUq6MAnXg47CKiF9BPQEkcy4SaRemyqgjHFFTxaftHpRdIA0F312dz7I3Lk4ljg90Da5tOMg7EsdDCs616ZgvS3w2U4ZDbdMgYJMXglxNvmlgalPgt1WOGxOzwyz8wcSJw/3RpNkSxPKahfciHsRbPTgzVUKqUEUd1epKCU51bzoC3a0apksKpu+tIXAvHasN0v5PJse6Th7ozhPNNy97cT3HcSllIexntZZVxZMZEFR7lvxgNOKBW3Pj80NHemoALfE/jEC48W7T4Y622EseLOcsXM848NGpS3NQ3f6oEy7TwGkU1TtzaW2r2LH4c2/52WMK9Y+aeoM56u3a06O31INrKoRbqTFzejKc5CO/Dn12cUx17PjKyOnif17j09XU92uv2micQtCMSb8/IEguLKukbFlJpVi+nL0Sv/p8/mODDJQs66BSJwAAAABJRU5ErkJggg==",
+ zed: "data:image/png;base64,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",
+ eye: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAC7UlEQVR42qWTS0iUURTH//eb8ROdZ5o46qRktHBSFCzJlfRCKNqULXoZtOgdZSY9rIULIYLIHliQRBmIUBCREkSlUSBZmjROqTHj6ExOJqYzozPf896uBhLhqg5c7uHA73A4//8h+M8gfxc0z+FiaGotFKmEKbLOJAmQNQNkqZvNxuoT97zrWbSB+rXaTqh2jcOVoCoEXYMuxyFIcbDZOMAf5c1YTGqmCjuRdLx/eqGB6q3JIWBug4FaWDwG6veBBoMgPGdUBwQRMJkhGBJAZAWKokd5ucB00jNCOCwYjEKQGGnGdFcPIq86QFkyaGY+qCUdRjEJiIyBTAzAODMBU2Y2rGl2yCoN6Tp1EjZ2/iRi0as9Nx/wUZMhl5+FVlAG1bYKUDgbnUWK0wrDzyHonz/A3HkZxvHPWOlygoqWKqK69wbeNT5zOjacQeb20+ic4RMzIF/lydQ4Ghtv4FsM2FzXADERcGkM0Te3IbfXoWAZCRLv/R1S6rpLibZluRjmzGBUw2RgFNG3D9Hd14+WR48gxyWUVd9C3q6DWKMFsHm5HSP+ISQ9PSqTKb9Hsue4EueW2T8ex70gw3DvJ7w4UIrIH3IVHrkJ+9b92CIGsNMRw5gtD/G+JzLxNRYFzGVNzjRXMSb4wiueBJGdkoLnx8rxw/N2HjZbUrG6yQNfRMadUhFOsxGh94/heHMhSFjP9lPu1o4reu5uFFUcQk3IhdYvDOlWgh9tzYiHw0jeuA+jmhVltnHczeqFt70BjlAnslc4q4j+eptBIFrA/7IrIxySgdz1uDebB68lH35bITRK4JjqQ2G4C3tENxK+f0SyKGBpdlZImZNxbkS5bVOOyHS3PDllkXwBcOWhQ+A2I7+dRhgSqIYZaoRuWgIiGKOyohVkXBwcWbCy0rLWLkjqNaaqlZRLxSgF4zvhHzcWm/9VyuuMNXMXnkivHZhe9Jik665iSkktZ0o0ynTOzHUwaBTdnK5POzew+DH9a/wCg6d3xpUf4V0AAAAASUVORK5CYII="
};
\ No newline at end of file
diff --git a/web/jsLib/joint.js b/web/jsLib/joint.js
index 41a8aad..b119fe2 100644
--- a/web/jsLib/joint.js
+++ b/web/jsLib/joint.js
@@ -17138,7 +17138,7 @@ if ( typeof window === "object" && typeof window.document === "object" ) {
text: function(content, opt) {
opt = opt || {};
- var lines = content.split('\n');
+ var lines = content/*.split('\n')*/;
var i = 0;
var tspan;
@@ -17162,6 +17162,8 @@ if ( typeof window === "object" && typeof window.document === "object" ) {
this.node.textContent = '';
var textNode = this.node;
+ var image;
+ //console.log(textNode.parentNode);
if (opt.textPath) {
@@ -17201,45 +17203,58 @@ if ( typeof window === "object" && typeof window.document === "object" ) {
textNode = textPath.node;
}
- //if (lines.length === 1) {
- // textNode.textContent = content;
- // return this;
- //}
+ // trash - elements collected outside tspan element, variable "to save algorithm"
+ if (textNode.TRASH instanceof Array) {
+ _.each(textNode.TRASH, function (e) { e.parentNode.removeChild(e); });
+ }
+ textNode.TRASH = [];
for (; i < lines.length; i++) {
- var jj, setup;
+ var jj, setup, iconLeft, xOrigin = this.attr('x') || 0,
+ iconXOrigin = (opt["ref-x"] || 0) + xOrigin;
// Shift all the
but first by one line (`1em`)
- tspan = V('tspan', { dy: (i == 0 ? '0em' : opt.lineHeight || '1em'), x: this.attr('x') || 0 });
+ tspan = V('tspan', {
+ dy: (i == 0 ? '0em' : opt.lineHeight || '1em'),
+ x: xOrigin + (lines[i].icons ? lines[i].icons.length*10 + 2 : 0)
+ });
tspan.addClass('line');
- if (!lines[i]) {
+ if (!lines[i].text) {
tspan.addClass('empty-line');
}
- if (lines[i].indexOf("\x1b") !== -1) {
- jj = lines[i].split("\x1b");
- lines[i] = jj[0];
- setup = JSON.parse(jj[1]);
- if (setup["STYLES"]) {
- for (var j in setup["STYLES"]) {
- tspan.node.style[j] = setup["STYLES"][j];
- }
+ if (lines[i]["styles"]) {
+ for (var j in lines[i]["styles"]) {
+ tspan.node.style[j] = lines[i]["styles"][j];
}
}
- if (opt.clickHandler) {
- tspan.node.onclick = opt.clickHandler;
+ if (typeof lines[i]["clickHandler"] === "function") {
+ tspan.node.addEventListener("click", lines[i]["clickHandler"]);
+ tspan.addClass('line-clickable');
}
- if (opt.lineClickHandlers && opt.lineClickHandlers[i]) {
- tspan.node.addEventListener("click", opt.lineClickHandlers[i]);
- tspan.node.setAttribute("class", tspan.node.getAttribute("class") + " line-clickable");
- }
// Make sure the textContent is never empty. If it is, add an additional
// space (an invisible character) so that following lines are correctly
// relatively positioned. `dy=1em` won't work with empty lines otherwise.
- tspan.node.textContent = lines[i] || ' ';
+ tspan.node.textContent = lines[i].text || ' ';
V(textNode).append(tspan);
+
+ if (lines[i].icons instanceof Array) {
+ iconLeft = iconXOrigin;
+ _.each(lines[i].icons, function (ic) {
+ image = V("image");
+ image.attr("xlink:href", ic.src);
+ image.attr("width", 10);
+ image.attr("height", 10);
+ image.attr("y", textNode.getBoundingClientRect().top + i*(opt["font-size"] || 14) + 2);
+ image.attr("x", iconLeft);
+ iconLeft += 10;
+ V(textNode.parentNode).append(image);
+ textNode.TRASH.push(image.node);
+ });
+ }
+
}
return this;
},
@@ -20952,7 +20967,7 @@ joint.dia.ElementView = joint.dia.CellView.extend({
// to rewrite them, if needed. (i.e display: 'none')
if (!_.isUndefined(attrs.text)) {
$selected.each(function() {
- V(this).text(attrs.text + '', attrs);
+ V(this).text(attrs.text, attrs);
});
specialAttributes.push('lineHeight','textPath');
}
diff --git a/web/jsLib/joint.shapes.uml.js b/web/jsLib/joint.shapes.uml.js
index 51d3b6f..cb07998 100644
--- a/web/jsLib/joint.shapes.uml.js
+++ b/web/jsLib/joint.shapes.uml.js
@@ -88,9 +88,9 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
var o,
rects = [
{ type: 'name', text: this.getClassName() },
- { type: 'params', text: (o = this.get('params')) .map(function (e) { return e.text; }), o: o },
- { type: 'attrs', text: (o = this.get('attributes')).map(function (e) { return e.text; }), o: o },
- { type: 'methods', text: (o = this.get('methods')) .map(function (e) { return e.text; }), o: o }
+ { type: 'params', text: (o = this.get('params')) , o: o },
+ { type: 'attrs', text: (o = this.get('attributes')), o: o },
+ { type: 'methods', text: (o = this.get('methods')) , o: o }
],
self = this,
classSigns = this.get('classSigns'),
@@ -109,8 +109,8 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
this.defaults.size.width = Math.max(this.defaults.MIN_WIDTH, Math.min(w, 250));
_.each(rects, function (rect) {
- (rect.text instanceof Array ? rect.text : [rect.text]).forEach(function (s) {
- var t = s.split("\x1b")[0].length*SYMBOL_12_WIDTH + 8;
+ rect.text.forEach(function (s) {
+ var t = s.text.length*SYMBOL_12_WIDTH + 8 + (s.icons ? s.icons.length*10 + 2 : 0);
if (t > self.defaults.size.width) {
self.defaults.size.width = t;
}
@@ -157,7 +157,8 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
},
getClassName: function () {
- return this.get('name');
+ var n = this.get('name');
+ return n instanceof Array ? n : [{ text: n }];
},
updateRectangles: function () {
@@ -168,9 +169,9 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
var rects = [
{ type: 'name', text: this.getClassName() },
- { type: 'params', text: this.get('params').map(function (e) { return e.text; }) },
- { type: 'attrs', text: this.get('attributes').map(function (e) { return e.text; }) },
- { type: 'methods', text: this.get('methods').map(function (e) { return e.text; }) }
+ { type: 'params', text: this.get('params') },
+ { type: 'attrs', text: this.get('attributes') },
+ { type: 'methods', text: this.get('methods') }
];
var offsetY = 0;
@@ -180,11 +181,10 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
_.each(rects, function(rect) {
- var lines = _.isArray(rect.text) ? rect.text : [rect.text];
-
+ var lines = _.isArray(rect.text) ? rect.text : [{ text: rect.text }];
if (rect.type === "name") {
if (self.HEAD_EMPTY_LINES) lines.unshift("");
- for (var i = 0; i < self.HEAD_EMPTY_LINES; i++) lines.unshift("");
+ for (var i = 0; i < self.HEAD_EMPTY_LINES; i++) lines.unshift({ text: "" });
}
var rectHeight = lines.length * 12 + (lines.length ? 10 : 0),
@@ -192,7 +192,8 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
rectRect = attrs['.uml-class-' + rect.type + '-rect'],
rectLabel = attrs['.uml-class-' + rect.type + '-label'];
- rectText.text = lines.join('\n');
+ rectText.text = lines;
+
if (nameClickHandler) {
if (rect.type === "name") {
rectText.clickHandler = nameClickHandler;