From 6c935a5e84562b4bb478307f3dc6672289b367b3 Mon Sep 17 00:00:00 2001 From: ZitRo Date: Sun, 18 Oct 2015 17:41:38 +0300 Subject: [PATCH 01/11] important changes: extended hover description for all class elements, minor fixes --- cache/projectTemplate.xml | 16 +++- package.json | 4 +- web/css/extras.css | 8 ++ web/css/hoverMessage.css | 2 +- web/css/interface.css | 1 + web/js/ClassView.js | 151 +++++++++++++++++++++++++++++++++----- web/js/HoverMessage.js | 15 ++-- web/js/Lib.js | 25 ++++++- web/js/Logic.js | 25 +++++++ 9 files changed, 219 insertions(+), 28 deletions(-) diff --git a/cache/projectTemplate.xml b/cache/projectTemplate.xml index e2f38a3..08224e5 100644 --- a/cache/projectTemplate.xml +++ b/cache/projectTemplate.xml @@ -4,7 +4,7 @@ Cache UML Explorer vX.X.X/*build.replace:pkg.version*/ Class contains methods that return structured classes/packages data. -63830,81286.756889 +63843,54972.140109 63653,67019.989197 @@ -94,6 +94,7 @@ Return structured data about class. set package = $LISTTOSTRING($LIST($LISTFROMSTRING(classDefinition.Name, "."), 1, *-1),".") set oProperties = ##class(%ZEN.proxyObject).%New() set oQueries = ##class(%ZEN.proxyObject).%New() + set oIndices = ##class(%ZEN.proxyObject).%New() set oClass.NAMESPACE = $NAMESPACE set oClass.SYSTEM = classDefinition.System @@ -171,6 +172,19 @@ Return structured data about class. do oQueries.%DispatchSetProperty(q.Name, oProp) } + #dim ind as %Dictionary.IndexDefinition + set oClass.indices = oIndices + set props = ##class(%Dictionary.ClassDefinition).%OpenId("%Dictionary.IndexDefinition") + for i=1:1:classDefinition.Indices.Count() { + set oProp = ##class(%ZEN.proxyObject).%New() + set ind = classDefinition.Indices.GetAt(i) + for j=1:1:props.Properties.Count() { + set pname = props.Properties.GetAt(j).Name + set:(pname '= "parent") $PROPERTY(oProp, pname) = $PROPERTY(ind, pname) + } + do oIndices.%DispatchSetProperty(ind.Name, oProp) + } + do ..collectInheritance(oData, oClass.super) quit oClass diff --git a/package.json b/package.json index af589bb..19cc458 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "CacheUMLExplorer", - "version": "1.5.1", + "version": "1.6.1", "description": "An UML Class explorer for InterSystems Caché", "directories": { "test": "test" @@ -9,7 +9,7 @@ "devDependencies": { "autoprefixer-core": "^5.1.11", "express": "^5.0.0-alpha.1", - "gulp": "^3.8.11", + "gulp": "^3.9.0", "gulp-add-src": "^0.2.0", "gulp-clean": "^0.3.1", "gulp-concat": "^2.4.1", diff --git a/web/css/extras.css b/web/css/extras.css index 9b0c61c..e058939 100644 --- a/web/css/extras.css +++ b/web/css/extras.css @@ -311,4 +311,12 @@ .icon.list:hover:after { left: 4px; box-shadow: inset 0 0 0 32px #ffcc1b, 0 -7px 0 0 #ffcc1b, 0 7px 0 0 #ffcc1b; +} + +.underlined { + text-decoration: underline; +} + +.clickable { + cursor: pointer; } \ No newline at end of file diff --git a/web/css/hoverMessage.css b/web/css/hoverMessage.css index 4986292..7fd3a93 100644 --- a/web/css/hoverMessage.css +++ b/web/css/hoverMessage.css @@ -13,6 +13,7 @@ .line-hoverable { cursor: pointer; + font-style: italic; -webkit-transition: all .5s ease; -moz-transition: all .5s ease; -o-transition: all .5s ease; @@ -30,6 +31,5 @@ left: 0; top: 0; padding: 20px; - cursor: pointer; } \ No newline at end of file diff --git a/web/css/interface.css b/web/css/interface.css index 7df65d9..73e6075 100644 --- a/web/css/interface.css +++ b/web/css/interface.css @@ -86,6 +86,7 @@ html, body { .message { font-size: 14pt; background: rgba(245, 245, 245, 0.9); + z-index: 1; -webkit-transition: all .2s ease; -moz-transition: all .2s ease; -o-transition: all .2s ease; diff --git a/web/js/ClassView.js b/web/js/ClassView.js index 5eaf224..a46160d 100644 --- a/web/js/ClassView.js +++ b/web/js/ClassView.js @@ -133,7 +133,7 @@ ClassView.prototype.renderInfoGraphic = function () { abstract: 1 }, "Class method": { - classMethod: 1 + ClassMethod: 1 }, "Client method": { clientMethod: 1 @@ -349,28 +349,143 @@ ClassView.prototype.getClassSigns = function (classMetaData) { /** * Returns array of icons according to method metadata. * - * @param method + * @param property */ -ClassView.prototype.getPropertyIcons = function (method) { +ClassView.prototype.getPropertyIcons = function (property) { var icons = []; - if (typeof method["Private"] !== "undefined") { - icons.push({ src: lib.image[method["Private"] ? "minus" : "plus"] }); + if (typeof property["Private"] !== "undefined") { + icons.push({ src: lib.image[property["Private"] ? "minus" : "plus"] }); + } + if (property["Abstract"]) icons.push({ src: lib.image.crystalBall }); + if (property["ClientMethod"]) icons.push({ src: lib.image.user }); + if (property["Final"]) icons.push({ src: lib.image.blueFlag }); + if (property["NotInheritable"]) icons.push({ src: lib.image.redFlag }); + if (property["SqlProc"]) icons.push({ src: lib.image.table }); + if (property["WebMethod"]) icons.push({ src: lib.image.earth }); + if (property["ZenMethod"]) icons.push({ src: lib.image.zed }); + if (property["ReadOnly"]) icons.push({ src: lib.image.eye }); + if (property["index"]) { + icons.push( + property["index"]["Unique"] ? { src: lib.image.keyRed } + : (property["index"]["PrimaryKey"] || property["index"]["IDKey"]) + ? { src: lib.image.keyGreen } : { src: lib.image.keyYellow } + ); } - 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 prop + * @param {string} type = ["parameter", "property", "method", "query"] + * @returns {string} + */ +ClassView.prototype.getPropertyHoverText = function (prop, type) { + + var ind, i, desc = "", + indexText = { + "IdKey": function () { return "IdKey"; }, + "Type": function (type) { return "Type="+type; }, + "Internal": function () { return "Internal"; }, + "Extent": function () { return "Extent"; }, + "PrimaryKey": function () { return "PrimaryKey"; }, + "Unique": function () { return "Unique"; } + }, + propText = { + "Calculated": 1, + "Final": 1, + "Identity": 1, + "InitialExpression": function (data) { + return (data === "\"\"") + ? "" + : "InitialExpression=" + + lib.highlightCOS(data + "") + }, + "Internal": 1, + "MultiDimensional": 1, + "NoModBit": 1, + "NotInheritable": 1, + "Private": 1, + "ReadOnly": 1, + "Relationship": function (data, p) { + return "Relationship [ Cardinality=" + + p["Cardinality"] + ", Inverse=" + p["Inverse"] + " ]"; + }, + "Required": 1, + "SqlComputed": function (data, p) { + return p["SqlComputeCode"] + ? "SqlComputed [ SqlComputeCode={" + + lib.highlightCOS(p["SqlComputeCode"]) + "} ]" + : ""; + }, + "Transient": 1, + // -- methods + "Abstract": 1, + // "ClassMethod": 1, - they're underlined + "ClientMethod": 1, + "CodeMode": function (data) { + return data === "code" ? "" : "CodeMode=" + + "" + data + ""; + }, + "ForceGenerate": 1, + "NoContext": 1, + "NotForProperty": 1, + "ReturnResultsets": 1, + "SoapAction": function (data) { + return data === "[default]" ? "" + : "SoapAction=" + + "" + data + ""; + }, + "SqlProc": 1, + "WebMethod": 1, + "ZenMethod": 1, + // -- parameters + "Encoded": 1, + // -- queries + "SqlView": 1 + }; + + if (ind = prop["index"]) { + desc += "INDEX " + + ind["Name"] + " " + (function () { + var txt = []; + for (i in ind) { + if (indexText[i] && ind[i]) txt.push(indexText[i](ind[i])); + } + return txt.join(", "); + })() + + "\n"; + } + + var txt = [], val; + for (i in prop) { + if (propText[i] && (prop[i] || i === "InitialExpression")) { + val = propText[i] === 1 + ? "" + i + "" + : propText[i](prop[i], prop); + if (val !== "") txt.push(val); + } + } + if (txt.length) desc += txt.join(", "); + + // Display FormalSpec in methods? + + if (desc && prop["Description"]) desc += "
"; + desc += prop["Description"] || ""; + + if (desc && type) { + desc = "" + lib.capitalize(type) + + " " + (prop["Name"] || "") + ":" + + ("
") + desc; + } + + return desc; + +}; + /** * @param {string} name * @param classMetaData @@ -401,7 +516,7 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) { keyWordsArray.push(n); arr.push({ text: n + (params[n]["Type"] ? ": " + params[n]["Type"] : ""), - hover: params[n]["Description"] || "", + hover: self.getPropertyHoverText(params[n], "parameter"), icons: self.getPropertyIcons(params[n]) }); } @@ -413,7 +528,7 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) { keyWordsArray.push(n); arr.push({ text: n + (ps[n]["Type"] ? ": " + ps[n]["Type"] : ""), - hover: ps[n]["Description"] || "", + hover: self.getPropertyHoverText(ps[n], "property"), icons: self.getPropertyIcons(ps[n]) }); } @@ -427,11 +542,11 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) { text: n + (met[n]["ReturnType"] ? ": " + met[n]["ReturnType"] : ""), styles: (function (t) { return t ? { textDecoration: "underline" } : {} - })(met[n]["classMethod"]), + })(met[n]["ClassMethod"]), clickHandler: (function (n) { return function () { self.showMethodCode(name, n); } })(n), - hover: met[n]["Description"] || "", + hover: self.getPropertyHoverText(met[n], "method"), icons: self.getPropertyIcons(met[n]) }); } @@ -444,7 +559,7 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) { arr.push({ text: n, icons: self.getPropertyIcons(qrs[n]), - hover: qrs[n]["SqlQuery"], + hover: self.getPropertyHoverText(qrs[n], "query"), clickHandler: (function (q, className) { return function () { self.showQuery(className, q); } })(qrs[n], name) diff --git a/web/js/HoverMessage.js b/web/js/HoverMessage.js index b046f5b..ebf9ce5 100644 --- a/web/js/HoverMessage.js +++ b/web/js/HoverMessage.js @@ -2,7 +2,7 @@ var HoverMessage = function (text, clickHandler) { var self = this; - this.clickHandler = typeof clickHandler === "function" ? clickHandler : function () {}; + this.clickHandler = typeof clickHandler === "function" ? clickHandler : null; this.element = document.createElement("div"); this.element.className = "hoverMessage"; this.element.innerHTML = text; @@ -19,9 +19,13 @@ var HoverMessage = function (text, clickHandler) { })(e, this))) return; self.detach(); }); - this.container.addEventListener("click", function () { - self.clickHandler(); - }); + + if (this.clickHandler) { + if (this.container.classList) this.container.classList.add("clickable"); + this.container.addEventListener("click", function () { + if (!lib.getSelection()) self.clickHandler(); + }); + } }; @@ -30,7 +34,8 @@ HoverMessage.prototype.attach = function (screenX, screenY) { var e = this.container, w; document.body.appendChild(e); - e.style.width = (w = Math.min(e.offsetWidth, window.innerWidth/2)) + "px"; + // +1 to width fixes "X.4234" rational part that may appear on SVG + e.style.width = (w = Math.ceil(Math.min(e.offsetWidth, window.innerWidth/2) + 1)) + "px"; e.style.top = (screenY - e.offsetHeight + 15) + "px"; e.style.left = Math.min(window.innerWidth - w - 10, screenX - w/2) + "px"; diff --git a/web/js/Lib.js b/web/js/Lib.js index 7c901ef..cb02715 100644 --- a/web/js/Lib.js +++ b/web/js/Lib.js @@ -193,8 +193,28 @@ Lib.prototype.highlightSQL = function (code) { }); }; +Lib.prototype.getSelection = function () { + var html = ""; + if (typeof window.getSelection != "undefined") { + var sel = window.getSelection(); + if (sel.rangeCount) { + var container = document.createElement("div"); + for (var i = 0, len = sel.rangeCount; i < len; ++i) { + container.appendChild(sel.getRangeAt(i).cloneContents()); + } + html = container.innerHTML; + } + } else if (typeof document.selection != "undefined") { + if (document.selection.type == "Text") { + html = document.selection.createRange().htmlText; + } + } + return html; +}; + /** * Contains graphic base64s for the application. + * 16x16 px */ Lib.prototype.image = { chip: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAK3RFWHRDcmVhdGlvbiBUaW1lAE1pIDE3IERleiAyMDAzIDIyOjM1OjIxICswMTAw2q8EHwAAAAd0SU1FB9MCGRcbLxQhzGIAAAAJcEhZcwAACvAAAArwAUKsNJgAAAAEZ0FNQQAAsY8L/GEFAAACEklEQVR42sWTz6sSURTHj/gjFUVdDAQOhDhgDwRJSXHjSoRCc+XORbt2blpUu/6A1iHu4tFGcCUVvtVDIfwBpk6rRJ/ib1MZdfytM5070KMieC0edGDuDHfu53y/59x7Af53yG74L49GowxFUa9ms9kVz/PpVCr1BefFGxM4HA6j1Wq9YBjmIU3TgDAMh0NxMpn0RqPRh8Vi8bJUKnGKv8HhcPipwWB44XK57isUCkB12Gw2oFQqZXK5nMYEz47H4xtcysl/Bb1e712n0xlF5YTP56MOhwMsl0vYbrdAvsfjMbAsC7FYDERRPKtUKufXDvx+v9VoNF4GAgHaZDLBdDqF9XotgbiY2IdCoQCozFssFgHtW6UmkSESicTtdvu7YDBoUKlUMJ/PJcv7/R5OpxO0220ol8uQSCRAr9efisXiVbVafd7tduuSA5vNFgmFQrJOpyNZJiBRFgQBms2mBK9Wq0OtVuvjm4rH4w8QOxFWSqDT6Q5ESaPRAMdxsNvtJLjRaEA+n4dkMgmoqEin0yzuwtuf8HUJ2LTHZrPZQqyTUKvVEliv10lSEbfsG4KaXC7nQ/vsbweFDFjXe2zQEpvl1Wq1dxCAbDYLaJWUJ8tkMh97vd5rTMrCHyElaLVaAj6fsb7zfr9/D/f6DNV5dPQV5/So/AQFKv98lD0ezyPsw9ztdjODweA71v7pdm/QbcYPCZIkO9gEQq4AAAAASUVORK5CYII=", @@ -213,5 +233,8 @@ Lib.prototype.image = { 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=", - binoculars: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADrElEQVR42m2Sa0zTVxiHfwfaSgthCxTEuZlMdkn2wW26utlEwtQB2rUUicSJ4gRS7cBNXIlmSGCbcYuGbMsYirawoWSJyEAm09VOII6tYKmOS8cYtEBrL7b0Tiv08t9/zZa4ZOfDSc553/Pk5Pe8BI+s3cUljrzc3FSj6T41NjZOLn/bRv6+31tSSvH5m6hJ3e9kfFLnuaW88fi/b8ijgLJy6ZL8QhPL4fSjq7sLkrKSWL29/TK1Z88uWBxeHJO9//DiN3L2/wK2C8XTIoEgs3/gNn4bvYfJidFYXVxQRG3kb0RPZzfC4WWHRjOc9h/Aidr6D9LTMo72DfQl7ywsZI6MaKH+ZRDqX2/H6ufOK6jC4t0ofWsfDPqZaAo3dSHgXxzUaIYKYg3Ha+rChw5K42fn/kRvrwpTf+jAZDJgsVjg9/pwov4kNBo1nlv7DGwOG9gJiejvU+FqdychlYer+C63b1Amq8KaJ7jwBJfQ/FUzrA/siI9jYqD/Jta9vAEejxs/3rgGr9sJl28RPVev04COHFJT++E+p9fbVnmoHHHReDooOzo7rsDpciIaAbTaIWRlb8UDmwVnzzbCarbCanPAYrPjYptCSmSy4/XJKal1ktK3kchmwWRzoUUhh8NqRSgKDA8PIntLDuz0+bz8HDhJHExN6ZH4WAqq35UqyIFSycj42Nj6CEXhYTCIYCCAlasy8NKL67Gw4MDo6F28nv0Gpg163NOqEfAHQOjkCL2tfnK1lVRUvncyLX1VzbHqKlz7QYVbdDgUHazZOB/gcrnapOSku0ajsexNkZhTVCDEqTOfwevxwDCjh9fl+IJUHDl6msfbVF1cJIKitR3jEzpEIhGY5ueWv+/5bsU/E7okEOazdgrz8PGpM/DQZrxuN53H/CekXPLOhChf/MIrG9bRvltgNpsRCYVx32iEUtkb01xSVk5t2ZqLLD4PDQ2N8C76EA2FMDc7rSPSiiOB/Qf2sp99OhNNF1rh93ngcroxO2+AsrcnBpAcrqKyN2dBKMjBp6c/h9vpjFmaM+iDJE8gpj6qrYPda0dzkxwhmhwOLSMajeIn1fUYYP/BCqp4VyFMJgs6Oq8gshxChIrARpshmZnPUw2NX0KlvIlLrS10exQJHDaeWrMWd9Q/xwDbtuVSX7ddwo7tefS39WCtYCF9ZQZYDAbIq/zNEcGO/LiZmUlqaEgNGg0Gkwk2J4HcGVbHADzea5RAVEB1d3XASauNoxXS40ziGXHRvwAVvrukyLa34QAAAABJRU5ErkJggg==" + binoculars: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADrElEQVR42m2Sa0zTVxiHfwfaSgthCxTEuZlMdkn2wW26utlEwtQB2rUUicSJ4gRS7cBNXIlmSGCbcYuGbMsYirawoWSJyEAm09VOII6tYKmOS8cYtEBrL7b0Tiv08t9/zZa4ZOfDSc553/Pk5Pe8BI+s3cUljrzc3FSj6T41NjZOLn/bRv6+31tSSvH5m6hJ3e9kfFLnuaW88fi/b8ijgLJy6ZL8QhPL4fSjq7sLkrKSWL29/TK1Z88uWBxeHJO9//DiN3L2/wK2C8XTIoEgs3/gNn4bvYfJidFYXVxQRG3kb0RPZzfC4WWHRjOc9h/Aidr6D9LTMo72DfQl7ywsZI6MaKH+ZRDqX2/H6ufOK6jC4t0ofWsfDPqZaAo3dSHgXxzUaIYKYg3Ha+rChw5K42fn/kRvrwpTf+jAZDJgsVjg9/pwov4kNBo1nlv7DGwOG9gJiejvU+FqdychlYer+C63b1Amq8KaJ7jwBJfQ/FUzrA/siI9jYqD/Jta9vAEejxs/3rgGr9sJl28RPVev04COHFJT++E+p9fbVnmoHHHReDooOzo7rsDpciIaAbTaIWRlb8UDmwVnzzbCarbCanPAYrPjYptCSmSy4/XJKal1ktK3kchmwWRzoUUhh8NqRSgKDA8PIntLDuz0+bz8HDhJHExN6ZH4WAqq35UqyIFSycj42Nj6CEXhYTCIYCCAlasy8NKL67Gw4MDo6F28nv0Gpg163NOqEfAHQOjkCL2tfnK1lVRUvncyLX1VzbHqKlz7QYVbdDgUHazZOB/gcrnapOSku0ajsexNkZhTVCDEqTOfwevxwDCjh9fl+IJUHDl6msfbVF1cJIKitR3jEzpEIhGY5ueWv+/5bsU/E7okEOazdgrz8PGpM/DQZrxuN53H/CekXPLOhChf/MIrG9bRvltgNpsRCYVx32iEUtkb01xSVk5t2ZqLLD4PDQ2N8C76EA2FMDc7rSPSiiOB/Qf2sp99OhNNF1rh93ngcroxO2+AsrcnBpAcrqKyN2dBKMjBp6c/h9vpjFmaM+iDJE8gpj6qrYPda0dzkxwhmhwOLSMajeIn1fUYYP/BCqp4VyFMJgs6Oq8gshxChIrARpshmZnPUw2NX0KlvIlLrS10exQJHDaeWrMWd9Q/xwDbtuVSX7ddwo7tefS39WCtYCF9ZQZYDAbIq/zNEcGO/LiZmUlqaEgNGg0Gkwk2J4HcGVbHADzea5RAVEB1d3XASauNoxXS40ziGXHRvwAVvrukyLa34QAAAABJRU5ErkJggg==", + keyYellow: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACi0lEQVQ4jX2TS0hUURzGv3POfcwdx8GZVHzMCDOZFpHIiPQgXJg2tTCwSClatLBVCwOX0SZatKl2QUQtCiNqkRENtUjTSoyYsjItNUwTlZkcfIyPO/eec1qohDTjt/w4v4//+f78SUNDAzLJ5lLlnDQFCq1mT9ZyeWJRGx+LuZ6oTNxnVCYBQMkEpyypFeQqD88fl42hwCQYG0Fi0i6LDhfV3+6paFky2RFGZZymg7mQyPXol69e8DVWVwHMYaM7WoLn8Wtw+sK4eLQ/xKh8wAXxpg0wTZEdrik8V1DiBFYkIG30/dyF2mOtSPla4fcu4kBwts606Ym0AYpCdlfvyffC5BsO9m//ivabbZjqvQSvm6OieB4KlaG0HRBCUqrCALluWAw1lTOo9t+ACg2gOrigkICSdgLLEgPRgcQEVPbPtCkMQwOjGiCBvl8eCEEG05coFW9ydoiDCwDrT4gEqARxWOgeLMDHCc8nXRWP//vCsslKaytjkfry94HV3zNweIoBBohVisScga7Pftx7F5xhVJ6hRE5uClgxyd6qstVnTQeH8wwHgSP1DYiP41bnzu8fRotm55Na1tyy1qOr/AolMr5W78bqLHkoUMQ6TtbEXU6dIzePAFLg5ZttePQ2r01VZERhEoZmb94YANi2PJ3v1e6eqrP0bMOG368hPm2Ip71BM9Lv6zN0EaFEIp0o57LF6VTbmw/n6C6HhbJgNqDZ6Boo/HKnc4c/ZdOmTDAAUCGxaGiASlMIVeSDUIKFmBMqlSUuw+aUyD8ZaQAK52I0x60vhMPlbvAxwOK43lE6Ev2RddbQbHsrGAAUSjGsqurrF6/i+2KxZGppyaWNTStuLuiUwtZOdiv9BTLFAAB6Bi65AAAAAElFTkSuQmCC", + keyRed: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACeklEQVQ4jX2TO0zTURTGv3vv/9F/H4Q2LZRHa4o8fASGGuJjMBEluDAQI0Tj4ICTkUQZ3YyJxsHEyRijgwZjdFBjbHQCnDAGMQqioDYgMUBttdACbf/3HheNoK1nPDnfL/m+cw7r7OxEqbKJdMlYd0QWeryrK00pzZiJu9wPdKVuC6IMAGilxHkiI6hrd08K6orOzkHEp5HK2o2j/pr2683NvVkhDgqiBC8mlkTwm+a5i5tqu1oFIKSN4WAYTy5cgrOjHWdfj0cF0R3JmK8oICeVp6O66kTQ5QQUAbaNkYataOs7g3zfKYSWs9iTTB/IcX6oqAWNs+2tlRU+ZNIAA6Bp2D35FgP9p1HzOY59UqElncVQwBstCmCM5XUh/jSEwN7UPFqvXoFOBmCUQXIGArSiFgpSjY8mU7Pg6yCMwzIMCMMAAIx4PVCMvSseoq75Mh8mJUgB/PcIAURgBRvDwQBeecvGTKXu/2NhhYv6tu+LsfaxF5G1hXk4wrUAAMU4Ug4Lg+EQbtXVzQuiY5xobgNglbGdO+y1x90zUwGLMTgmJoBPX3BtW9P7ly3VybRmuH4YxnNTyvOcKAGsO6Qc0f6IJh4eTibcTiXhFwwoKDzzeXHP5+/XQTGNCJZtb9wYANhERytM4+YRVTA90kbIMJAwLfUoUpeLVdeOWKRinKhYXOCSqNep6wM93nLTbRfQ6PEAysZgoOrNjc0NoTzn3aXEAMAVsGwB0At5RCsrwBjDkumEDgq7C7bkRN9KqgFoUqmP5Q5zqWNLUxlm4oCSuByqnx41Xcct+ZfhYgAOTOmaPvR0IbFrMZ3JZw23EWdameT8q/brZf9XPwERTf+roi2jYwAAAABJRU5ErkJggg==", + keyGreen: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACbElEQVQ4jX2TS0iUURzFz31933wz44yOjviYERTTIjCYkLJFkCW2cSGRUrRoYW1cuHAV7aJFm2odUYvCiFpUREOt1FZGWNEblUwTmxwdfI7OzHfvv8UgIc147upy7/n97zlwWVdXF4qJXFLQrAf1ud5cWbqZp6wZNe1/Qsrch6B1AJDFzCZLlqdKPgz2U/ef2BzmxSR0ym0qH6/pKL3d0ocNcRKCkrzgZE1wKuwrLdci3b5WwAgXwdE6XHxxHW3eTqQvf4hB0ANoFioIcDOmpKGz+kKwygsNgoaLmrF96G8fQG92ACa6BhxZOoEMP1UwgpBsf6S1MpTFCvI5JWbbPuHS0CAWa39AHNNgLSugkXCscAeMZYUSoO0tBNJHE4i33kRAWQjCBjQHCLJgBJ0znxPjqVkJ8Y8JDtuxoISV72msDDDsa0GA1DI0tf5NGxgwbF+h/GI5sNEqsHdl72Gbx/9FYGnRuNm+EJ/oeFPvbiUQ9tTmDwyHTDnwDEeh7jUkSNA5cJrbCdhkh9jBreeLPRNh7jD89HzBMmbgubX3e83bmiWxYvn4svWabH0VnJL5grcfmKHjdr14unk66YdXQ1UwMBjQq3KwR+FBpShOkkCOuzMuABiXzjqV1l3vmZy9UeLCG7WQTjom8Kwh48QjY+SYODihkDhp6rO8aqi2t9Q2/hxCTSUwcOEbrv7ov7MniizvKWbOAwzWuAO4KotIrBKMMchVL0hRHfldDU6LRd0ApNFmyim1Vw90Ngd+YRqARvBG4yQb9503juvuZgYAyTgmpFIjMy+Th38vrGe3NvwWm5YBpvk8ZP7L7qa/51LzXlKvOSsAAAAASUVORK5CYII=" }; \ No newline at end of file diff --git a/web/js/Logic.js b/web/js/Logic.js index c5ba36a..f4b8c3d 100644 --- a/web/js/Logic.js +++ b/web/js/Logic.js @@ -49,6 +49,7 @@ Logic.prototype.process = function (data) { } this.fillAssociations(); + this.fillIndices(); delete data.classes["%Persistent"]; delete data.classes["%Library.Persistent"]; @@ -61,6 +62,30 @@ Logic.prototype.process = function (data) { }; +Logic.prototype.fillIndices = function () { + + var className, cls, indexName, j, index, props, propName; + + for (className in this.data.classes) { + cls = this.data.classes[className]; + for (indexName in cls.indices) { + index = cls.indices[indexName]; + props = index["Properties"].split(","); + for (j in props) { + if (cls.properties[propName = props[j].match(/[^\(]+/)[0]]) { + cls.properties[propName].index = index; + } else { + console.warn( + "No property", propName, "defined in", className,"to assign index", + indexName, "to." + ); + } + } + } + } + +}; + Logic.prototype.fillAssociations = function () { var self = this, From 7b78b4685951acee8e03b66b09bd012ef611d168 Mon Sep 17 00:00:00 2001 From: ZitRo Date: Sun, 18 Oct 2015 19:31:49 +0300 Subject: [PATCH 02/11] full description to classes on hover --- package.json | 2 +- web/css/extras.css | 4 +++ web/js/ClassView.js | 87 +++++++++++++++++++++++++++++++++++++-------- web/js/Logic.js | 6 ++-- 4 files changed, 81 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index 19cc458..58de874 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "CacheUMLExplorer", - "version": "1.6.1", + "version": "1.7.0", "description": "An UML Class explorer for InterSystems Caché", "directories": { "test": "test" diff --git a/web/css/extras.css b/web/css/extras.css index e058939..6c866f4 100644 --- a/web/css/extras.css +++ b/web/css/extras.css @@ -319,4 +319,8 @@ .clickable { cursor: pointer; +} + +.nowrap { + white-space: nowrap; } \ No newline at end of file diff --git a/web/js/ClassView.js b/web/js/ClassView.js index a46160d..3a098e6 100644 --- a/web/js/ClassView.js +++ b/web/js/ClassView.js @@ -112,7 +112,7 @@ ClassView.prototype.renderInfoGraphic = function () { basePackageName: "Welcome to Caché UML explorer!", classes: { "Shared object": { - super: "Super object", + Super: "Super object", classType: "Serial", parameters: { "Also inherit Super object": {} @@ -121,7 +121,7 @@ ClassView.prototype.renderInfoGraphic = function () { properties: {} }, "Class name": { - super: "Super object", + Super: "Super object", ABSTRACT: 1, FINAL: 1, HIDDEN: 1, @@ -281,7 +281,7 @@ ClassView.prototype.filterInherits = function (data) { var f = function (p) { return filter.hasOwnProperty(p) || (data.classes[p] || {})["isDataType"] || - lib.obj(((data.classes[p] || {}).super || "").split(",")).hasOwnProperty("%DataType"); + lib.obj(((data.classes[p] || {}).Super || "").split(",")).hasOwnProperty("%DataType"); }; if (this.cacheUMLExplorer.settings.showDataTypesOnDiagram) @@ -302,7 +302,7 @@ ClassView.prototype.filterInherits = function (data) { }; /** - * Returns array of signs to render or empry array. + * Returns array of signs to render or empty array. * * @param classMetaData */ @@ -319,25 +319,25 @@ ClassView.prototype.getClassSigns = function (classMetaData) { }); } } - if (classMetaData["ABSTRACT"]) signs.push({ + if (classMetaData["Abstract"]) signs.push({ icon: lib.image.crystalBall, text: "Abstract", textStyle: "fill:rgb(130,0,255)" }); - if (classMetaData["FINAL"]) signs.push({ + if (classMetaData["Final"]) signs.push({ icon: lib.image.blueFlag, text: "Final", textStyle: "fill:rgb(130,0,255)" }); - if (classMetaData["SYSTEM"]) signs.push({ + if (classMetaData["System"]) signs.push({ icon: lib.image.chip, - text: "System/" + classMetaData["SYSTEM"] + text: "System/" + classMetaData["System"] }); - if (classMetaData["PROCEDUREBLOCK"] === 0) signs.push({ + if (classMetaData["ProcedureBlock"] === 0) signs.push({ icon: lib.image.moleculeCubeCross, text: "NotProcBlock" }); - if (classMetaData["HIDDEN"]) signs.push({ + if (classMetaData["Hidden"]) signs.push({ icon: lib.image.ghost, text: "Hidden" }); @@ -445,9 +445,67 @@ ClassView.prototype.getPropertyHoverText = function (prop, type) { // -- parameters "Encoded": 1, // -- queries - "SqlView": 1 + "SqlView": 1, + // -- class + "ClientDataType": function (data, p) { + return !p["isDataType"] ? "" + : "ClientDataType=" + + "" + data + ""; + }, + "DdlAllowed": 1, + "Deployed": 1, + "Dynamic": 1, + "Inheritance": function (data) { + return data === "left" ? "" + : "Inheritance=" + + "" + data + ""; + }, + "Language": function (data) { + return data === "cache" ? "" + : "Language=" + + "" + data + ""; + }, + "LegacyInstanceContext": 1, + // ModificationLevel ? + "NoExtent": 1, + "OdbcType": function (data, p) { + return !p["isOdbcType"] ? "" + : "OdbcType=" + + "" + data + ""; + }, + "ProcedureBlock": function (data) { + return data ? "" : "Not ProcedureBlock"; + }, + "SoapBindingStyle": function (data, p) { + return !p["isSoapBindingStyle"] ? "" + : "SoapBindingStyle=" + + "" + data + ""; + }, + "SoapBodyUse": function (data, p) { + return !p["isSoapBodyUse"] ? "" + : "SoapBodyUse=" + + "" + data + ""; + }, + "SqlCategory": function (data, p) { + return !p["isSqlCategory"] ? "" + : "SqlCategory=" + + "" + data + ""; + }, + "SqlRowIdPrivate": 1, + "System": function (data) { + return !data ? "" + : "System=" + + "" + data + "" + } }; + if (type === "class" && prop["TimeChanged"] && prop["TimeCreated"]) { + desc += "Changed: " + + "" + prop["TimeChanged"] + ", " + + "Created: " + + "" + prop["TimeCreated"] + "
"; + } + if (ind = prop["index"]) { desc += "INDEX " + ind["Name"] + " " + (function () { @@ -462,7 +520,7 @@ ClassView.prototype.getPropertyHoverText = function (prop, type) { var txt = [], val; for (i in prop) { - if (propText[i] && (prop[i] || i === "InitialExpression")) { + if (propText[i] && (prop[i] || i === "InitialExpression" || i === "ProcedureBlock")) { val = propText[i] === 1 ? "" + i + "" : propText[i](prop[i], prop); @@ -478,7 +536,7 @@ ClassView.prototype.getPropertyHoverText = function (prop, type) { if (desc && type) { desc = "" + lib.capitalize(type) - + " " + (prop["Name"] || "") + ":" + + " " + (prop["Name"] || "") + "" + ("
") + desc; } @@ -504,8 +562,9 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) { name: [{ text: name, clickHandler: function () { - self.openClassDoc(name, classMetaData["NAMESPACE"]); + self.openClassDoc(name, self.cacheUMLExplorer.NAMESPACE); }, + hover: self.getPropertyHoverText(classMetaData, "class"), styles: { cursor: "help" } diff --git a/web/js/Logic.js b/web/js/Logic.js index f4b8c3d..cb39002 100644 --- a/web/js/Logic.js +++ b/web/js/Logic.js @@ -32,7 +32,7 @@ Logic.prototype.process = function (data) { if (!this.data.inheritance) this.data.inheritance = {}; for (clsName in data.classes) { cls = data.classes[clsName]; - if (cls.super) cls.super.split(",").forEach(function (name) { + if (cls.Super) cls.Super.split(",").forEach(function (name) { self.inherits(clsName, name); }); if (cls.parameters && !this.umlExplorer.settings.showParameters) delete cls.parameters; @@ -200,8 +200,8 @@ Logic.prototype.alignClassTypes = function () { // try to get class type from parent if (classObj.$classType) derivedObj.$classType = classObj.$classType; // reassign class type from classType property - if (derivedObj.classType) - derivedObj.$classType = self.getNormalClassType(derivedObj.classType); + if (derivedObj.ClassType) + derivedObj.$classType = self.getNormalClassType(derivedObj.ClassType); } extendDerivedClasses(derivedClassName, derivedObj); }); From 32ae8357b7998bebbf9e1e774cfb7b3ee8901094 Mon Sep 17 00:00:00 2001 From: ZitRo Date: Sun, 18 Oct 2015 19:37:01 +0300 Subject: [PATCH 03/11] show queries option add --- package.json | 2 +- web/index.html | 4 ++++ web/js/CacheUMLExplorer.js | 6 ++++-- web/js/Logic.js | 1 + 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 58de874..95d6598 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "CacheUMLExplorer", - "version": "1.7.0", + "version": "1.7.1", "description": "An UML Class explorer for InterSystems Caché", "directories": { "test": "test" diff --git a/web/index.html b/web/index.html index 9a3389e..8868f72 100644 --- a/web/index.html +++ b/web/index.html @@ -112,6 +112,10 @@

+ + + + diff --git a/web/js/CacheUMLExplorer.js b/web/js/CacheUMLExplorer.js index 5c8d926..2b185b2 100644 --- a/web/js/CacheUMLExplorer.js +++ b/web/js/CacheUMLExplorer.js @@ -41,7 +41,8 @@ var CacheUMLExplorer = function (treeViewContainer, classViewContainer) { showDataTypesOnDiagram: id("setting.showDataTypesOnDiagram"), showParameters: id("setting.showParameters"), showProperties: id("setting.showProperties"), - showMethods: id("setting.showMethods") + showMethods: id("setting.showMethods"), + showQueries: id("setting.showQueries") } }; @@ -55,7 +56,8 @@ var CacheUMLExplorer = function (treeViewContainer, classViewContainer) { showDataTypesOnDiagram: settingsValue("showDataTypesOnDiagram"), showParameters: settingsValue("showParameters", true), showProperties: settingsValue("showProperties", true), - showMethods: settingsValue("showMethods", true) + showMethods: settingsValue("showMethods", true), + showQueries: settingsValue("showQueries", true) }; this.UI = new UI(this); diff --git a/web/js/Logic.js b/web/js/Logic.js index cb39002..628f3c1 100644 --- a/web/js/Logic.js +++ b/web/js/Logic.js @@ -38,6 +38,7 @@ Logic.prototype.process = function (data) { if (cls.parameters && !this.umlExplorer.settings.showParameters) delete cls.parameters; if (cls.properties && !this.umlExplorer.settings.showProperties) delete cls.properties; if (cls.methods && !this.umlExplorer.settings.showMethods) delete cls.methods; + if (cls.queries && !this.umlExplorer.settings.showQueries) delete cls.queries; } this.alignClassTypes(); // call after inheritance scheme done From d6f2e94b034ed76238129c179cbbfaa36ac2f3a6 Mon Sep 17 00:00:00 2001 From: ZitRo Date: Sun, 18 Oct 2015 20:22:18 +0300 Subject: [PATCH 04/11] fixed click when dragging classes, show queries option add --- package.json | 2 +- web/css/settingsView.css | 5 +++++ web/index.html | 13 ++++++++++++- web/js/CacheUMLExplorer.js | 8 +++++++- web/js/ClassView.js | 2 ++ web/jsLib/joint.js | 13 ++++++++++++- 6 files changed, 39 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 95d6598..5b06697 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "CacheUMLExplorer", - "version": "1.7.1", + "version": "1.7.3", "description": "An UML Class explorer for InterSystems Caché", "directories": { "test": "test" diff --git a/web/css/settingsView.css b/web/css/settingsView.css index d864457..7d83406 100644 --- a/web/css/settingsView.css +++ b/web/css/settingsView.css @@ -29,4 +29,9 @@ #settingsView table td { text-align: left; +} + +#settingsView table td:nth-child(3) { + color: #888; + padding-left: 1em; } \ No newline at end of file diff --git a/web/index.html b/web/index.html index 8868f72..f8da60e 100644 --- a/web/index.html +++ b/web/index.html @@ -98,26 +98,37 @@

- + + Show data type classes on diagram + + + + + Visualize class keywords + Display block with class parameters + Display block with class properties + Display block with class methods + Display block with class queries +

diff --git a/web/js/CacheUMLExplorer.js b/web/js/CacheUMLExplorer.js index 2b185b2..c1ba2bc 100644 --- a/web/js/CacheUMLExplorer.js +++ b/web/js/CacheUMLExplorer.js @@ -37,8 +37,10 @@ var CacheUMLExplorer = function (treeViewContainer, classViewContainer) { diagramSearchButton: id("button.diagramSearch"), settingsView: id("settingsView"), closeSettings: id("closeSettings"), + settingsExtraText: id("settingsExtraText"), settings: { showDataTypesOnDiagram: id("setting.showDataTypesOnDiagram"), + showClassIcons: id("setting.showClassIcons"), showParameters: id("setting.showParameters"), showProperties: id("setting.showProperties"), showMethods: id("setting.showMethods"), @@ -54,6 +56,7 @@ var CacheUMLExplorer = function (treeViewContainer, classViewContainer) { // note: this.elements is required to be modified with the same name as settings keys this.settings = { showDataTypesOnDiagram: settingsValue("showDataTypesOnDiagram"), + showClassIcons: settingsValue("showClassIcons", true), showParameters: settingsValue("showParameters", true), showProperties: settingsValue("showProperties", true), showMethods: settingsValue("showMethods", true), @@ -73,12 +76,14 @@ var CacheUMLExplorer = function (treeViewContainer, classViewContainer) { CacheUMLExplorer.prototype.initSettings = function () { - var self = this; + var self = this, + textChanged = "Please, re-render diagram to make changes apply."; for (var st in this.elements.settings) { this.elements.settings[st].checked = this.settings[st]; this.elements.settings[st].addEventListener("change", (function (st) { return function (e) { + self.elements.settingsExtraText.innerHTML = textChanged; localStorage.setItem( st, self.settings[st] = (e.target || e.srcElement).checked @@ -200,6 +205,7 @@ CacheUMLExplorer.prototype.init = function () { self.elements.settingsView.classList.add("active"); }); this.elements.closeSettings.addEventListener("click", function () { + self.elements.settingsExtraText.textContent = ""; self.elements.settingsView.classList.remove("active"); }); diff --git a/web/js/ClassView.js b/web/js/ClassView.js index 3a098e6..4d5e643 100644 --- a/web/js/ClassView.js +++ b/web/js/ClassView.js @@ -310,6 +310,8 @@ ClassView.prototype.getClassSigns = function (classMetaData) { var signs = [], ct; + if (!this.cacheUMLExplorer.settings.showClassIcons) return signs; + if (ct = classMetaData["$classType"]) { if (ct !== "Serial" && ct !== "Registered" && ct !== "Persistent" && ct !== "DataType") { signs.push({ diff --git a/web/jsLib/joint.js b/web/jsLib/joint.js index c7500f7..4533b75 100644 --- a/web/jsLib/joint.js +++ b/web/jsLib/joint.js @@ -17229,7 +17229,18 @@ if ( typeof window === "object" && typeof window.document === "object" ) { } } if (typeof lines[i]["clickHandler"] === "function") { - tspan.node.addEventListener("click", lines[i]["clickHandler"]); + tspan.node.addEventListener("click", (function (el, handler) { + var clickable = true; + el.addEventListener("mousemove", function () { + clickable = false; + }); + el.addEventListener("mousedown", function () { + clickable = true; + }); + return function (e) { + if (clickable) handler(e); + }; + })(tspan.node, lines[i]["clickHandler"])); tspan.node["clickHandler"] = lines[i]["clickHandler"]; tspan.addClass('line-clickable'); } From 20dcb66b0294347deb0a709d0aebb6134e081e95 Mon Sep 17 00:00:00 2001 From: ZitRo Date: Sun, 18 Oct 2015 20:48:42 +0300 Subject: [PATCH 05/11] fixed different strokes on different scale levels --- package.json | 2 +- web/css/classView.css | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 5b06697..62cefe5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "CacheUMLExplorer", - "version": "1.7.3", + "version": "1.7.4", "description": "An UML Class explorer for InterSystems Caché", "directories": { "test": "test" diff --git a/web/css/classView.css b/web/css/classView.css index 24ae0b2..3cedfef 100644 --- a/web/css/classView.css +++ b/web/css/classView.css @@ -107,4 +107,12 @@ text { .element.highlighted { outline: 4px solid rgba(255, 0, 0, 0.6); +} + +.marker-source, .marker-target { + vector-effect: none !important; +} + +.connection { + stroke: black; } \ No newline at end of file From abd0d700507b33d2f8cc053f09ab5c71806fc5ba Mon Sep 17 00:00:00 2001 From: ZitRo Date: Sun, 18 Oct 2015 23:18:51 +0300 Subject: [PATCH 06/11] fixed old and important bug that didn't show packages named same as classes --- cache/projectTemplate.xml | 44 +++++++++++++++++++++++---------------- package.json | 2 +- web/js/ClassTree.js | 9 ++++++-- 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/cache/projectTemplate.xml b/cache/projectTemplate.xml index 08224e5..44a0a19 100644 --- a/cache/projectTemplate.xml +++ b/cache/projectTemplate.xml @@ -4,7 +4,7 @@ Cache UML Explorer vX.X.X/*build.replace:pkg.version*/ Class contains methods that return structured classes/packages data. -63843,54972.140109 +63843,83200.096917 63653,67019.989197 @@ -45,33 +45,34 @@ Returns structured class tree with all classes available in current namespace level) { set level = level + 1 set resp = ##class(%ZEN.proxyObject).%New() - do objects.GetAt(level - 1).%DispatchSetProperty($LISTGET(parts, level - 1), resp) + do objects.GetAt(level - 1).%DispatchSetProperty("/" _ $LISTGET(parts, level - 1), resp) do objects.SetAt(resp, level) } if ($LISTLENGTH(parts) = level) { do resp.%DispatchSetProperty($LISTGET(parts, level), classes.Data("Hidden")) } set lastParts = parts + for i=1:1:$LISTLENGTH(lastParts)-1 { + set $LIST(lastParts, i) = "/"_$LISTGET(lastParts, i) + } } quit objects.GetAt(1) @@ -96,18 +97,25 @@ Return structured data about class. set oQueries = ##class(%ZEN.proxyObject).%New() set oIndices = ##class(%ZEN.proxyObject).%New() - set oClass.NAMESPACE = $NAMESPACE - set oClass.SYSTEM = classDefinition.System - set oClass.PROCEDUREBLOCK = classDefinition.ProcedureBlock - set oClass.ABSTRACT = classDefinition.Abstract - set oClass.FINAL = classDefinition.Final - set oClass.HIDDEN = classDefinition.Hidden - set oClass.classType = classDefinition.ClassType - set oClass.serverOnly = classDefinition.ServerOnly // - set oClass.isDataType = classDefinition.ClientDataTypeIsDefined() + set oClass.isOdbcType = classDefinition.OdbcTypeIsDefined() + set oClass.isSoapBindingStyle = classDefinition.SoapBindingStyleIsDefined() + set oClass.isSoapBodyUse = classDefinition.SoapBodyUseIsDefined() + set oClass.isSqlCategory = classDefinition.SqlCategoryIsDefined() + + set props = ##class(%Dictionary.ClassDefinition).%OpenId("%Dictionary.ClassDefinition") + for j=1:1:props.Properties.Count() { + set pname = props.Properties.GetAt(j).Name + set:((pname '= "parent") + && ('props.Properties.GetAt(j).Private) + && ('$IsObject($PROPERTY(classDefinition, pname)))) $PROPERTY(oClass, pname) = $PROPERTY(classDefinition, pname) + } + if (oClass.TimeChanged) { set oClass.TimeChanged = $zdatetime(oClass.TimeChanged) } + if (oClass.TimeCreated) { set oClass.TimeCreated = $zdatetime(oClass.TimeCreated) } + set oClass.Super = "" // do not quit with super at this moment if (oData.restrictPackage) && ('..inPackage(oData.basePackageName, package)) quit oClass - set oClass.super = ..correctInheritance(oData, classDefinition, package) + set oClass.Super = ..correctInheritance(oData, classDefinition, package) // now expand super names set oClass.properties = oProperties set count = classDefinition.Properties.Count() @@ -185,7 +193,7 @@ Return structured data about class. do oIndices.%DispatchSetProperty(ind.Name, oProp) } - do ..collectInheritance(oData, oClass.super) + do ..collectInheritance(oData, oClass.Super) quit oClass ]]> diff --git a/package.json b/package.json index 62cefe5..caab87e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "CacheUMLExplorer", - "version": "1.7.4", + "version": "1.7.5", "description": "An UML Class explorer for InterSystems Caché", "directories": { "test": "test" diff --git a/web/js/ClassTree.js b/web/js/ClassTree.js index 93d7cfe..b38b99a 100644 --- a/web/js/ClassTree.js +++ b/web/js/ClassTree.js @@ -186,13 +186,18 @@ ClassTree.prototype.updateTree = function (treeObject, doNotChangeRoot) { }; + var getRealName = function (modName) { + modName = modName + ""; + return modName.slice((modName || "")[0] === "/" ? 1 : 0, modName.length); + }; + var build = function (rootElement, object, path, level) { var i, element, rec, arr = []; for (i in object) { - arr.push({ name: i, val: object[i] }); + arr.push({ name: getRealName(i), val: object[i] }); } arr.sort(function (a, b) { @@ -209,7 +214,7 @@ ClassTree.prototype.updateTree = function (treeObject, doNotChangeRoot) { path.join("."), level )) { - build(rec, element.val, path.concat([element.name]), level + 1); + build(rec, element.val, path.concat([getRealName(element.name)]), level + 1); } } From b69c672d0ba67b1feaf588a7f8e227fcd4fb7aaa Mon Sep 17 00:00:00 2001 From: ZitRo Date: Mon, 19 Oct 2015 00:11:55 +0300 Subject: [PATCH 07/11] project rename, settings for standard UML notation --- cache/projectTemplate.xml | 52 +++++------ gulpfile.js | 26 +++--- package.json | 4 +- web/index.html | 13 ++- ...heUMLExplorer.js => CacheClassExplorer.js} | 24 +++-- web/js/ClassTree.js | 18 ++-- web/js/ClassView.js | 90 ++++++++++--------- web/js/Lib.js | 4 +- web/js/Source.js | 2 +- web/js/UI.js | 4 +- web/jsLib/joint.js | 4 +- 11 files changed, 128 insertions(+), 113 deletions(-) rename web/js/{CacheUMLExplorer.js => CacheClassExplorer.js} (88%) diff --git a/cache/projectTemplate.xml b/cache/projectTemplate.xml index 44a0a19..ec24c5e 100644 --- a/cache/projectTemplate.xml +++ b/cache/projectTemplate.xml @@ -1,8 +1,8 @@ - + -Cache UML Explorer vX.X.X/*build.replace:pkg.version*/ +Cache Class Explorer vX.X.X/*build.replace:pkg.version*/ Class contains methods that return structured classes/packages data. 63843,83200.096917 63653,67019.989197 @@ -365,19 +365,19 @@ Returns structured package data - + - - - - + + + + - + -REST interface for UMLExplorer +REST interface for ClassExplorer %CSP.REST 63697,73073.878177 63648,30450.187229 @@ -387,8 +387,8 @@ REST interface for UMLExplorer - - + + @@ -405,7 +405,7 @@ Method returns whole class tree visible in the current namespace. 1 %Status @@ -442,7 +442,7 @@ Return the list of all namespaces 1 %Status @@ -500,7 +500,7 @@ Method returns user application HTML. - + Cache UML Explorer vX.X.X/*build.replace:pkg.version*/ static content generator. Class contains methods that return JS/CSS/HTML data for single page application. @@ -514,7 +514,7 @@ Write the contents of xData tag Const:%String %Status - + %Projection.AbstractProjection 63696,65168.289869 63696,64041.85537 @@ -574,14 +574,14 @@ This method is invoked when a class is compiled. set cspProperties("NameSpace") = ns set cspProperties("Description") = "A WEB application for Cache UML Explorer." set cspProperties("IsNameSpaceDefault") = 1 - set cspProperties("DispatchClass") = "UMLExplorer.Router" - if ('##class(Security.Applications).Exists("/UMLExplorer")) { - w !, "Creating WEB application ""/UMLExplorer""..." - set tSC = ##class(Security.Applications).Create("/UMLExplorer", .cspProperties) + set cspProperties("DispatchClass") = "ClassExplorer.Router" + if ('##class(Security.Applications).Exists("/ClassExplorer")) { + w !, "Creating WEB application ""/ClassExplorer""..." + set tSC = ##class(Security.Applications).Create("/ClassExplorer", .cspProperties) if $$$ISERR(tSC) throw ##class(%Installer.Exception).CreateFromStatus(tSC) - w !, "WEB application ""/UMLExplorer"" created." + w !, "WEB application ""/ClassExplorer"" created." } else { - w !, "WEB application ""/UMLExplorer"" already exists, so it is ready to use." + w !, "WEB application ""/ClassExplorer"" already exists, so it is ready to use." } zn:ns'="%SYS" ns quit $$$OK @@ -597,10 +597,10 @@ This method is invoked when a class is 'uncompiled'. ", " ** @version <%= pkg.version %>", " ** @license <%= pkg.license %>", - " ** @see https://github.com/ZitRos/CacheUMLExplorer", + " ** @see https://github.com/ZitRos/CacheClassExplorer", " **/", "" ].join("\n"); @@ -58,7 +58,7 @@ gulp.task("gatherLibs", ["clean"], function () { "web/jsLib/joint.layout.DirectedGraph.min.js" ])) .pipe(stripComments({ safe: true })) - .pipe(concat("CacheUMLExplorer.js")) + .pipe(concat("CacheClassExplorer.js")) .pipe(replace(/ /g, "\\x0B")) .pipe(replace(/\x1b/g, "\\x1B")) .pipe(gulp.dest("build/web/js/")); @@ -66,9 +66,9 @@ gulp.task("gatherLibs", ["clean"], function () { gulp.task("gatherScripts", ["clean", "gatherLibs"], function () { return gulp.src("web/js/*.js") - .pipe(concat("CacheUMLExplorer.js")) + .pipe(concat("CacheClassExplorer.js")) .pipe(specialReplace()) - .pipe(wrap("CacheUMLExplorer = (function(){<%= contents %> return CacheUMLExplorer;}());")) + .pipe(wrap("CacheClassExplorer = (function(){<%= contents %> return CacheClassExplorer;}());")) .pipe(uglify({ output: { ascii_only: true, @@ -78,15 +78,15 @@ gulp.task("gatherScripts", ["clean", "gatherLibs"], function () { preserveComments: "some" })) .pipe(header(banner, { pkg: pkg })) - .pipe(addsrc.prepend("build/web/js/CacheUMLExplorer.js")) - .pipe(concat("CacheUMLExplorer.js")) + .pipe(addsrc.prepend("build/web/js/CacheClassExplorer.js")) + .pipe(concat("CacheClassExplorer.js")) .pipe(replace(/\x1b/g, "\\x1B")) .pipe(gulp.dest("build/web/js/")); }); gulp.task("gatherCSS", ["clean"], function () { return gulp.src("web/css/*.css") - .pipe(concat("CacheUMLExplorer.css")) + .pipe(concat("CacheClassExplorer.css")) .pipe(postcss([ autoprefixer({ browsers: ["last 3 version"] }) ])) .pipe(minifyCSS({ keepSpecialComments: 0 })) .pipe(gulp.dest("build/web/css/")); @@ -95,8 +95,8 @@ gulp.task("gatherCSS", ["clean"], function () { gulp.task("addHTMLFile", ["clean"], function () { return gulp.src("web/index.html") .pipe(htmlReplace({ - "css": "css/CacheUMLExplorer.css", - "js": "js/CacheUMLExplorer.js" + "css": "css/CacheClassExplorer.css", + "js": "js/CacheClassExplorer.js" })) .pipe(gulp.dest("build/web/")); }); @@ -118,23 +118,23 @@ gulp.task("exportCacheXML", [ .pipe(specialReplace()) .pipe(replace( /\{\{replace:css}}/, - function () { return fs.readFileSync("build/web/css/CacheUMLExplorer.css", "utf-8"); } + function () { return fs.readFileSync("build/web/css/CacheClassExplorer.css", "utf-8"); } )) .pipe(replace( /\{\{replace:js}}/, - function () { return fs.readFileSync("build/web/js/CacheUMLExplorer.js", "utf-8"); } + function () { return fs.readFileSync("build/web/js/CacheClassExplorer.js", "utf-8"); } )) .pipe(replace( /\{\{replace:html}}/, function () { return fs.readFileSync("build/web/index.html", "utf-8"); } )) - .pipe(rename(function (path) { path.basename = "CacheUMLExplorer-v" + pkg["version"]; })) + .pipe(rename(function (path) { path.basename = "CacheClassExplorer-v" + pkg["version"]; })) .pipe(gulp.dest("build/Cache")); }); gulp.task("zipRelease", ["exportCacheXML"], function () { return gulp.src(["build/**/*", "!build/web/**/*"]) - .pipe(zip("CacheUMLExplorer-v" + pkg["version"] + ".zip", { + .pipe(zip("CacheClassExplorer-v" + pkg["version"] + ".zip", { comment: "Cache UML explorer v" + pkg["version"] + " by Nikita Savchenko\n\n" + "+ Cache folder holds XML file to import to InterSystems Cache.\n\n" + "For further information about installation and information, check README.md file." diff --git a/package.json b/package.json index caab87e..ae3b112 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "CacheUMLExplorer", - "version": "1.7.5", + "name": "CacheClassExplorer", + "version": "1.8.1", "description": "An UML Class explorer for InterSystems Caché", "directories": { "test": "test" diff --git a/web/index.html b/web/index.html index f8da60e..aa1a293 100644 --- a/web/index.html +++ b/web/index.html @@ -2,7 +2,7 @@ - Cache UML explorer + Cache Class Explorer @@ -22,7 +22,7 @@ - + @@ -30,7 +30,7 @@ - +
@@ -104,7 +104,12 @@

- Visualize class keywords + Visualize class keywords (turn off for standard UML notation) + + + + + Visualize property keywords (turn off for standard UML notation) diff --git a/web/js/CacheUMLExplorer.js b/web/js/CacheClassExplorer.js similarity index 88% rename from web/js/CacheUMLExplorer.js rename to web/js/CacheClassExplorer.js index c1ba2bc..57d9854 100644 --- a/web/js/CacheUMLExplorer.js +++ b/web/js/CacheClassExplorer.js @@ -1,12 +1,12 @@ /** - * UML class diagram visualization tool for InterSystems products. + * Class diagram visualization tool for InterSystems products. * @author ZitRo * @see http://zitros.tk * @param {HTMLElement} treeViewContainer * @param {HTMLElement} classViewContainer * @constructor */ -var CacheUMLExplorer = function (treeViewContainer, classViewContainer) { +var CacheClassExplorer = function (treeViewContainer, classViewContainer) { var id = function (e) { return document.getElementById(e); }; @@ -41,6 +41,7 @@ var CacheUMLExplorer = function (treeViewContainer, classViewContainer) { settings: { showDataTypesOnDiagram: id("setting.showDataTypesOnDiagram"), showClassIcons: id("setting.showClassIcons"), + showPropertyIcons: id("setting.showPropertyIcons"), showParameters: id("setting.showParameters"), showProperties: id("setting.showProperties"), showMethods: id("setting.showMethods"), @@ -57,6 +58,7 @@ var CacheUMLExplorer = function (treeViewContainer, classViewContainer) { this.settings = { showDataTypesOnDiagram: settingsValue("showDataTypesOnDiagram"), showClassIcons: settingsValue("showClassIcons", true), + showPropertyIcons: settingsValue("showPropertyIcons", true), showParameters: settingsValue("showParameters", true), showProperties: settingsValue("showProperties", true), showMethods: settingsValue("showMethods", true), @@ -74,12 +76,16 @@ var CacheUMLExplorer = function (treeViewContainer, classViewContainer) { }; -CacheUMLExplorer.prototype.initSettings = function () { +CacheClassExplorer.prototype.initSettings = function () { var self = this, textChanged = "Please, re-render diagram to make changes apply."; for (var st in this.elements.settings) { + if (!this.elements.settings[st]) { + console.warn(st, "is Bred Sivoi Cobyly."); + continue; + } this.elements.settings[st].checked = this.settings[st]; this.elements.settings[st].addEventListener("change", (function (st) { return function (e) { @@ -98,7 +104,7 @@ CacheUMLExplorer.prototype.initSettings = function () { * Render namespaces. * @param nsData */ -CacheUMLExplorer.prototype.updateNamespaces = function (nsData) { +CacheClassExplorer.prototype.updateNamespaces = function (nsData) { var ns, e; @@ -118,7 +124,7 @@ CacheUMLExplorer.prototype.updateNamespaces = function (nsData) { /** * @param {string} namespace */ -CacheUMLExplorer.prototype.setNamespace = function (namespace) { +CacheClassExplorer.prototype.setNamespace = function (namespace) { var self = this; @@ -132,7 +138,7 @@ CacheUMLExplorer.prototype.setNamespace = function (namespace) { }; -CacheUMLExplorer.prototype.updateURL = function () { +CacheClassExplorer.prototype.updateURL = function () { var obj = { name: this.classTree.SELECTED_NAME, @@ -145,7 +151,7 @@ CacheUMLExplorer.prototype.updateURL = function () { }; -CacheUMLExplorer.prototype.restoreFromURL = function () { +CacheClassExplorer.prototype.restoreFromURL = function () { var hash = (location.hash || "").substr(1), obj; @@ -165,7 +171,7 @@ CacheUMLExplorer.prototype.restoreFromURL = function () { }; -CacheUMLExplorer.prototype.init = function () { +CacheClassExplorer.prototype.init = function () { var self = this, restored; @@ -184,7 +190,7 @@ CacheUMLExplorer.prototype.init = function () { this.elements.infoButton.addEventListener("click", function () { self.UI.displayMessage( - "Caché UML explorer v" + "Caché Class explorer v" + "[NOT-BUILT]"/*build.replace:"pkg.version"*/ + "
for InterSystems Caché" + "
By Nikita Savchenko" diff --git a/web/js/ClassTree.js b/web/js/ClassTree.js index b38b99a..7544b84 100644 --- a/web/js/ClassTree.js +++ b/web/js/ClassTree.js @@ -1,6 +1,6 @@ /** * Class tree representation. - * @param {CacheUMLExplorer} parent + * @param {CacheClassExplorer} parent * @param {HTMLElement} treeViewContainer * @constructor */ @@ -8,7 +8,7 @@ var ClassTree = function (parent, treeViewContainer) { var self = this; - this.cacheUMLExplorer = parent; + this.cacheClassExplorer = parent; this.container = treeViewContainer; this.loader = null; this.SELECTED_NAME = null; @@ -16,7 +16,7 @@ var ClassTree = function (parent, treeViewContainer) { this.SELECTED_ELEMENT = null; this.treeObject = null; - this.cacheUMLExplorer.elements.classTreeSearch.addEventListener("input", function (e) { + this.cacheClassExplorer.elements.classTreeSearch.addEventListener("input", function (e) { self.searchChanged.call(self, (e.target || e.srcElement).value); }); @@ -30,9 +30,9 @@ var ClassTree = function (parent, treeViewContainer) { ClassTree.prototype.updateSizes = function () { - var dh = this.cacheUMLExplorer.elements.searchBlock.clientHeight, + var dh = this.cacheClassExplorer.elements.searchBlock.clientHeight, h = window.innerHeight - dh, - b = this.cacheUMLExplorer.elements.treeViewContainer; + b = this.cacheClassExplorer.elements.treeViewContainer; b.style.paddingTop = 0; b.style.marginTop = dh + "px"; @@ -44,7 +44,7 @@ ClassTree.prototype.showLoader = function () { if (this.loader) return; - this.cacheUMLExplorer.elements.classTreeSearch.value = ""; + this.cacheClassExplorer.elements.classTreeSearch.value = ""; this.treeObject = null; this.loader = document.createElement("div"); this.loader.className = "spinner"; @@ -56,7 +56,7 @@ ClassTree.prototype.removeLoader = function () { if (!this.loader) return; - this.cacheUMLExplorer.elements.classTreeSearch.value = ""; + this.cacheClassExplorer.elements.classTreeSearch.value = ""; this.loader.parentNode.removeChild(this.loader); this.loader = null; @@ -71,7 +71,7 @@ ClassTree.prototype.classSelected = function (element, className) { if (!element.classList.contains("selected")) { element.classList.add("selected"); - this.cacheUMLExplorer.classView.loadClass(className); + this.cacheClassExplorer.classView.loadClass(className); } }; @@ -85,7 +85,7 @@ ClassTree.prototype.packageSelected = function (element, packageName) { if (!element.classList.contains("selected")) { element.classList.add("selected"); - this.cacheUMLExplorer.classView.loadPackage(packageName); + this.cacheClassExplorer.classView.loadPackage(packageName); } }; diff --git a/web/js/ClassView.js b/web/js/ClassView.js index 4d5e643..27a8e34 100644 --- a/web/js/ClassView.js +++ b/web/js/ClassView.js @@ -5,7 +5,7 @@ var ClassView = function (parent, container) { this.container = container; - this.cacheUMLExplorer = parent; + this.cacheClassExplorer = parent; this.graph = null; this.paper = null; @@ -82,7 +82,7 @@ ClassView.prototype.resetView = function () { this.graph.clear(); this.HIGHLIGHTED_VIEW = null; this.SEARCH_INDEX = 0; - this.cacheUMLExplorer.elements.diagramSearch.value = ""; + this.cacheClassExplorer.elements.diagramSearch.value = ""; }; @@ -101,15 +101,15 @@ ClassView.prototype.openClassDoc = function (className, nameSpace) { */ ClassView.prototype.renderInfoGraphic = function () { - this.cacheUMLExplorer.classTree.SELECTED_NAME = - this.cacheUMLExplorer.elements.className.textContent = - "Welcome to Caché UML explorer!"; + this.cacheClassExplorer.classTree.SELECTED_NAME = + this.cacheClassExplorer.elements.className.textContent = + "Welcome to Caché Class explorer!"; location.hash = "{\"type\":\"help\"}"; this.showLoader(); this.render({ - basePackageName: "Welcome to Caché UML explorer!", + basePackageName: "Welcome to Caché Class explorer!", classes: { "Shared object": { Super: "Super object", @@ -284,7 +284,7 @@ ClassView.prototype.filterInherits = function (data) { lib.obj(((data.classes[p] || {}).Super || "").split(",")).hasOwnProperty("%DataType"); }; - if (this.cacheUMLExplorer.settings.showDataTypesOnDiagram) + if (this.cacheClassExplorer.settings.showDataTypesOnDiagram) return; toFilter.forEach(function (p) { @@ -310,7 +310,7 @@ ClassView.prototype.getClassSigns = function (classMetaData) { var signs = [], ct; - if (!this.cacheUMLExplorer.settings.showClassIcons) return signs; + if (!this.cacheClassExplorer.settings.showClassIcons) return signs; if (ct = classMetaData["$classType"]) { if (ct !== "Serial" && ct !== "Registered" && ct !== "Persistent" && ct !== "DataType") { @@ -357,6 +357,9 @@ ClassView.prototype.getPropertyIcons = function (property) { var icons = []; + if (!this.cacheClassExplorer.settings.showPropertyIcons) + return [{ src: lib.image[(property["Private"] ? "minus" : "plus") + "Simple"] }]; + if (typeof property["Private"] !== "undefined") { icons.push({ src: lib.image[property["Private"] ? "minus" : "plus"] }); } @@ -564,7 +567,7 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) { name: [{ text: name, clickHandler: function () { - self.openClassDoc(name, self.cacheUMLExplorer.NAMESPACE); + self.openClassDoc(name, self.cacheClassExplorer.NAMESPACE); }, hover: self.getPropertyHoverText(classMetaData, "class"), styles: { @@ -645,9 +648,9 @@ ClassView.prototype.showMethodCode = function (className, methodName) { var self = this; - this.cacheUMLExplorer.source.getMethod(className, methodName, function (err, data) { + this.cacheClassExplorer.source.getMethod(className, methodName, function (err, data) { if (err || data.error) { - self.cacheUMLExplorer.UI.displayMessage("Unable to get method \"" + methodName + "\"!"); + self.cacheClassExplorer.UI.displayMessage("Unable to get method \"" + methodName + "\"!"); return; } self.showPanel({ @@ -682,7 +685,7 @@ ClassView.prototype.showQuery = function (className, queryData) { */ ClassView.prototype.showPanel = function (data) { - var els = this.cacheUMLExplorer.elements; + var els = this.cacheClassExplorer.elements; data = data || {}; @@ -697,7 +700,7 @@ ClassView.prototype.showPanel = function (data) { ClassView.prototype.hideMethodCode = function () { - this.cacheUMLExplorer.elements.methodCodeView.classList.remove("active"); + this.cacheClassExplorer.elements.methodCodeView.classList.remove("active"); }; @@ -742,11 +745,11 @@ ClassView.prototype.render = function (data) { cS.parentNode.removeChild(cS); c2.parentNode.removeChild(c2); setTimeout(function () { - self.confirmRender(data); self.cacheUMLExplorer.UI.removeMessage(); + self.confirmRender(data); self.cacheClassExplorer.UI.removeMessage(); }, 25); }); bOff.addEventListener("click", function () { - self.cacheUMLExplorer.UI.removeMessage(); + self.cacheClassExplorer.UI.removeMessage(); }); c.appendChild(c1); @@ -756,7 +759,7 @@ ClassView.prototype.render = function (data) { c2.appendChild(bOff); load.appendChild(lt); load.appendChild(spinner); - this.cacheUMLExplorer.UI.displayMessage(c, false); + this.cacheClassExplorer.UI.displayMessage(c, false); }; @@ -767,7 +770,6 @@ ClassView.prototype.confirmRender = function (data) { uml = joint.shapes.uml, relFrom, relTo, classes = {}, connector; - console.log(data); // todo this.filterInherits(data); // Reset view and zoom again because it may cause visual damage to icons. @@ -865,22 +867,22 @@ ClassView.prototype.loadClass = function (className) { var self = this; - this.cacheUMLExplorer.classTree.SELECTED_NAME = className; - this.cacheUMLExplorer.classTree.SELECTED_TYPE = "class"; + this.cacheClassExplorer.classTree.SELECTED_NAME = className; + this.cacheClassExplorer.classTree.SELECTED_TYPE = "class"; this.showLoader(); - this.cacheUMLExplorer.source.getClassView(className, function (err, data) { + this.cacheClassExplorer.source.getClassView(className, function (err, data) { //console.log(data); self.removeLoader(); if (err) { - self.showLoader("Unable to get " + self.cacheUMLExplorer.classTree.SELECTED_NAME); + self.showLoader("Unable to get " + self.cacheClassExplorer.classTree.SELECTED_NAME); console.error.call(console, err); } else { self.render(data); } }); - this.cacheUMLExplorer.elements.className.textContent = className; - this.cacheUMLExplorer.updateURL(); + this.cacheClassExplorer.elements.className.textContent = className; + this.cacheClassExplorer.updateURL(); }; @@ -888,10 +890,10 @@ ClassView.prototype.loadPackage = function (packageName) { var self = this; - this.cacheUMLExplorer.classTree.SELECTED_NAME = packageName; - this.cacheUMLExplorer.classTree.SELECTED_TYPE = "package"; + this.cacheClassExplorer.classTree.SELECTED_NAME = packageName; + this.cacheClassExplorer.classTree.SELECTED_TYPE = "package"; this.showLoader(); - this.cacheUMLExplorer.source.getPackageView(packageName, function (err, data) { + this.cacheClassExplorer.source.getPackageView(packageName, function (err, data) { //console.log(data); self.removeLoader(); if (err) { @@ -902,8 +904,8 @@ ClassView.prototype.loadPackage = function (packageName) { } }); - this.cacheUMLExplorer.elements.className.textContent = packageName; - this.cacheUMLExplorer.updateURL(); + this.cacheClassExplorer.elements.className.textContent = packageName; + this.cacheClassExplorer.updateURL(); }; @@ -919,8 +921,8 @@ ClassView.prototype.updateSizes = function () { ClassView.prototype.zoom = function (delta) { var scaleOld = this.PAPER_SCALE, scaleDelta; - var sw = this.cacheUMLExplorer.elements.classViewContainer.offsetWidth, - sh = this.cacheUMLExplorer.elements.classViewContainer.offsetHeight, + var sw = this.cacheClassExplorer.elements.classViewContainer.offsetWidth, + sh = this.cacheClassExplorer.elements.classViewContainer.offsetHeight, side = delta > 0 ? 1 : -1, ox = this.paper.options.origin.x, oy = this.paper.options.origin.y; @@ -959,8 +961,8 @@ ClassView.prototype.focusOnInstance = function (jointInstance) { */ ClassView.prototype.focusOnXY = function (x, y) { - var sw = this.cacheUMLExplorer.elements.classViewContainer.offsetWidth, - sh = this.cacheUMLExplorer.elements.classViewContainer.offsetHeight, + var sw = this.cacheClassExplorer.elements.classViewContainer.offsetWidth, + sh = this.cacheClassExplorer.elements.classViewContainer.offsetHeight, scale = this.PAPER_SCALE; this.paper.setOrigin( @@ -1057,38 +1059,38 @@ ClassView.prototype.init = function () { relP.x = e.pageX; relP.y = e.pageY; }; - this.cacheUMLExplorer.elements.classViewContainer.addEventListener("mousemove", moveHandler); - this.cacheUMLExplorer.elements.classViewContainer.addEventListener("touchmove", moveHandler); - this.cacheUMLExplorer.elements.classViewContainer.addEventListener("mousewheel", function (e) { + this.cacheClassExplorer.elements.classViewContainer.addEventListener("mousemove", moveHandler); + this.cacheClassExplorer.elements.classViewContainer.addEventListener("touchmove", moveHandler); + this.cacheClassExplorer.elements.classViewContainer.addEventListener("mousewheel", function (e) { self.zoom(Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)))); }); - this.cacheUMLExplorer.elements.zoomInButton.addEventListener("click", function () { + this.cacheClassExplorer.elements.zoomInButton.addEventListener("click", function () { self.zoom(1); }); - this.cacheUMLExplorer.elements.zoomOutButton.addEventListener("click", function () { + this.cacheClassExplorer.elements.zoomOutButton.addEventListener("click", function () { self.zoom(-1); }); - this.cacheUMLExplorer.elements.zoomNormalButton.addEventListener("click", function () { + this.cacheClassExplorer.elements.zoomNormalButton.addEventListener("click", function () { self.zoom(null); }); - this.cacheUMLExplorer.elements.closeMethodCodeView.addEventListener("click", function () { + this.cacheClassExplorer.elements.closeMethodCodeView.addEventListener("click", function () { self.hideMethodCode(); }); - this.cacheUMLExplorer.elements.helpButton.addEventListener("click", function () { + this.cacheClassExplorer.elements.helpButton.addEventListener("click", function () { self.renderInfoGraphic(); }); - this.cacheUMLExplorer.elements.diagramSearch.addEventListener("input", function (e) { + this.cacheClassExplorer.elements.diagramSearch.addEventListener("input", function (e) { self.searchOnDiagram((e.target || e.srcElement).value); }); - this.cacheUMLExplorer.elements.diagramSearch.addEventListener("keydown", function (e) { + this.cacheClassExplorer.elements.diagramSearch.addEventListener("keydown", function (e) { if (e.keyCode === 13) { self.SEARCH_INDEX++; self.searchOnDiagram((e.target || e.srcElement).value); } }); - this.cacheUMLExplorer.elements.diagramSearchButton.addEventListener("click", function () { + this.cacheClassExplorer.elements.diagramSearchButton.addEventListener("click", function () { self.SEARCH_INDEX++; - self.searchOnDiagram(self.cacheUMLExplorer.elements.diagramSearch.value); + self.searchOnDiagram(self.cacheClassExplorer.elements.diagramSearch.value); }); this.SYMBOL_12_WIDTH = (function () { diff --git a/web/js/Lib.js b/web/js/Lib.js index cb02715..25592d6 100644 --- a/web/js/Lib.js +++ b/web/js/Lib.js @@ -236,5 +236,7 @@ Lib.prototype.image = { binoculars: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADrElEQVR42m2Sa0zTVxiHfwfaSgthCxTEuZlMdkn2wW26utlEwtQB2rUUicSJ4gRS7cBNXIlmSGCbcYuGbMsYirawoWSJyEAm09VOII6tYKmOS8cYtEBrL7b0Tiv08t9/zZa4ZOfDSc553/Pk5Pe8BI+s3cUljrzc3FSj6T41NjZOLn/bRv6+31tSSvH5m6hJ3e9kfFLnuaW88fi/b8ijgLJy6ZL8QhPL4fSjq7sLkrKSWL29/TK1Z88uWBxeHJO9//DiN3L2/wK2C8XTIoEgs3/gNn4bvYfJidFYXVxQRG3kb0RPZzfC4WWHRjOc9h/Aidr6D9LTMo72DfQl7ywsZI6MaKH+ZRDqX2/H6ufOK6jC4t0ofWsfDPqZaAo3dSHgXxzUaIYKYg3Ha+rChw5K42fn/kRvrwpTf+jAZDJgsVjg9/pwov4kNBo1nlv7DGwOG9gJiejvU+FqdychlYer+C63b1Amq8KaJ7jwBJfQ/FUzrA/siI9jYqD/Jta9vAEejxs/3rgGr9sJl28RPVev04COHFJT++E+p9fbVnmoHHHReDooOzo7rsDpciIaAbTaIWRlb8UDmwVnzzbCarbCanPAYrPjYptCSmSy4/XJKal1ktK3kchmwWRzoUUhh8NqRSgKDA8PIntLDuz0+bz8HDhJHExN6ZH4WAqq35UqyIFSycj42Nj6CEXhYTCIYCCAlasy8NKL67Gw4MDo6F28nv0Gpg163NOqEfAHQOjkCL2tfnK1lVRUvncyLX1VzbHqKlz7QYVbdDgUHazZOB/gcrnapOSku0ajsexNkZhTVCDEqTOfwevxwDCjh9fl+IJUHDl6msfbVF1cJIKitR3jEzpEIhGY5ueWv+/5bsU/E7okEOazdgrz8PGpM/DQZrxuN53H/CekXPLOhChf/MIrG9bRvltgNpsRCYVx32iEUtkb01xSVk5t2ZqLLD4PDQ2N8C76EA2FMDc7rSPSiiOB/Qf2sp99OhNNF1rh93ngcroxO2+AsrcnBpAcrqKyN2dBKMjBp6c/h9vpjFmaM+iDJE8gpj6qrYPda0dzkxwhmhwOLSMajeIn1fUYYP/BCqp4VyFMJgs6Oq8gshxChIrARpshmZnPUw2NX0KlvIlLrS10exQJHDaeWrMWd9Q/xwDbtuVSX7ddwo7tefS39WCtYCF9ZQZYDAbIq/zNEcGO/LiZmUlqaEgNGg0Gkwk2J4HcGVbHADzea5RAVEB1d3XASauNoxXS40ziGXHRvwAVvrukyLa34QAAAABJRU5ErkJggg==", keyYellow: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACi0lEQVQ4jX2TS0hUURzGv3POfcwdx8GZVHzMCDOZFpHIiPQgXJg2tTCwSClatLBVCwOX0SZatKl2QUQtCiNqkRENtUjTSoyYsjItNUwTlZkcfIyPO/eec1qohDTjt/w4v4//+f78SUNDAzLJ5lLlnDQFCq1mT9ZyeWJRGx+LuZ6oTNxnVCYBQMkEpyypFeQqD88fl42hwCQYG0Fi0i6LDhfV3+6paFky2RFGZZymg7mQyPXol69e8DVWVwHMYaM7WoLn8Wtw+sK4eLQ/xKh8wAXxpg0wTZEdrik8V1DiBFYkIG30/dyF2mOtSPla4fcu4kBwts606Ym0AYpCdlfvyffC5BsO9m//ivabbZjqvQSvm6OieB4KlaG0HRBCUqrCALluWAw1lTOo9t+ACg2gOrigkICSdgLLEgPRgcQEVPbPtCkMQwOjGiCBvl8eCEEG05coFW9ydoiDCwDrT4gEqARxWOgeLMDHCc8nXRWP//vCsslKaytjkfry94HV3zNweIoBBohVisScga7Pftx7F5xhVJ6hRE5uClgxyd6qstVnTQeH8wwHgSP1DYiP41bnzu8fRotm55Na1tyy1qOr/AolMr5W78bqLHkoUMQ6TtbEXU6dIzePAFLg5ZttePQ2r01VZERhEoZmb94YANi2PJ3v1e6eqrP0bMOG368hPm2Ip71BM9Lv6zN0EaFEIp0o57LF6VTbmw/n6C6HhbJgNqDZ6Boo/HKnc4c/ZdOmTDAAUCGxaGiASlMIVeSDUIKFmBMqlSUuw+aUyD8ZaQAK52I0x60vhMPlbvAxwOK43lE6Ev2RddbQbHsrGAAUSjGsqurrF6/i+2KxZGppyaWNTStuLuiUwtZOdiv9BTLFAAB6Bi65AAAAAElFTkSuQmCC", keyRed: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACeklEQVQ4jX2TO0zTURTGv3vv/9F/H4Q2LZRHa4o8fASGGuJjMBEluDAQI0Tj4ICTkUQZ3YyJxsHEyRijgwZjdFBjbHQCnDAGMQqioDYgMUBttdACbf/3HheNoK1nPDnfL/m+cw7r7OxEqbKJdMlYd0QWeryrK00pzZiJu9wPdKVuC6IMAGilxHkiI6hrd08K6orOzkHEp5HK2o2j/pr2683NvVkhDgqiBC8mlkTwm+a5i5tqu1oFIKSN4WAYTy5cgrOjHWdfj0cF0R3JmK8oICeVp6O66kTQ5QQUAbaNkYataOs7g3zfKYSWs9iTTB/IcX6oqAWNs+2tlRU+ZNIAA6Bp2D35FgP9p1HzOY59UqElncVQwBstCmCM5XUh/jSEwN7UPFqvXoFOBmCUQXIGArSiFgpSjY8mU7Pg6yCMwzIMCMMAAIx4PVCMvSseoq75Mh8mJUgB/PcIAURgBRvDwQBeecvGTKXu/2NhhYv6tu+LsfaxF5G1hXk4wrUAAMU4Ug4Lg+EQbtXVzQuiY5xobgNglbGdO+y1x90zUwGLMTgmJoBPX3BtW9P7ly3VybRmuH4YxnNTyvOcKAGsO6Qc0f6IJh4eTibcTiXhFwwoKDzzeXHP5+/XQTGNCJZtb9wYANhERytM4+YRVTA90kbIMJAwLfUoUpeLVdeOWKRinKhYXOCSqNep6wM93nLTbRfQ6PEAysZgoOrNjc0NoTzn3aXEAMAVsGwB0At5RCsrwBjDkumEDgq7C7bkRN9KqgFoUqmP5Q5zqWNLUxlm4oCSuByqnx41Xcct+ZfhYgAOTOmaPvR0IbFrMZ3JZw23EWdameT8q/brZf9XPwERTf+roi2jYwAAAABJRU5ErkJggg==", - keyGreen: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACbElEQVQ4jX2TS0iUURzFz31933wz44yOjviYERTTIjCYkLJFkCW2cSGRUrRoYW1cuHAV7aJFm2odUYvCiFpUREOt1FZGWNEblUwTmxwdfI7OzHfvv8UgIc147upy7/n97zlwWVdXF4qJXFLQrAf1ud5cWbqZp6wZNe1/Qsrch6B1AJDFzCZLlqdKPgz2U/ef2BzmxSR0ym0qH6/pKL3d0ocNcRKCkrzgZE1wKuwrLdci3b5WwAgXwdE6XHxxHW3eTqQvf4hB0ANoFioIcDOmpKGz+kKwygsNgoaLmrF96G8fQG92ACa6BhxZOoEMP1UwgpBsf6S1MpTFCvI5JWbbPuHS0CAWa39AHNNgLSugkXCscAeMZYUSoO0tBNJHE4i33kRAWQjCBjQHCLJgBJ0znxPjqVkJ8Y8JDtuxoISV72msDDDsa0GA1DI0tf5NGxgwbF+h/GI5sNEqsHdl72Gbx/9FYGnRuNm+EJ/oeFPvbiUQ9tTmDwyHTDnwDEeh7jUkSNA5cJrbCdhkh9jBreeLPRNh7jD89HzBMmbgubX3e83bmiWxYvn4svWabH0VnJL5grcfmKHjdr14unk66YdXQ1UwMBjQq3KwR+FBpShOkkCOuzMuABiXzjqV1l3vmZy9UeLCG7WQTjom8Kwh48QjY+SYODihkDhp6rO8aqi2t9Q2/hxCTSUwcOEbrv7ov7MniizvKWbOAwzWuAO4KotIrBKMMchVL0hRHfldDU6LRd0ApNFmyim1Vw90Ngd+YRqARvBG4yQb9503juvuZgYAyTgmpFIjMy+Th38vrGe3NvwWm5YBpvk8ZP7L7qa/51LzXlKvOSsAAAAASUVORK5CYII=" + keyGreen: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACbElEQVQ4jX2TS0iUURzFz31933wz44yOjviYERTTIjCYkLJFkCW2cSGRUrRoYW1cuHAV7aJFm2odUYvCiFpUREOt1FZGWNEblUwTmxwdfI7OzHfvv8UgIc147upy7/n97zlwWVdXF4qJXFLQrAf1ud5cWbqZp6wZNe1/Qsrch6B1AJDFzCZLlqdKPgz2U/ef2BzmxSR0ym0qH6/pKL3d0ocNcRKCkrzgZE1wKuwrLdci3b5WwAgXwdE6XHxxHW3eTqQvf4hB0ANoFioIcDOmpKGz+kKwygsNgoaLmrF96G8fQG92ACa6BhxZOoEMP1UwgpBsf6S1MpTFCvI5JWbbPuHS0CAWa39AHNNgLSugkXCscAeMZYUSoO0tBNJHE4i33kRAWQjCBjQHCLJgBJ0znxPjqVkJ8Y8JDtuxoISV72msDDDsa0GA1DI0tf5NGxgwbF+h/GI5sNEqsHdl72Gbx/9FYGnRuNm+EJ/oeFPvbiUQ9tTmDwyHTDnwDEeh7jUkSNA5cJrbCdhkh9jBreeLPRNh7jD89HzBMmbgubX3e83bmiWxYvn4svWabH0VnJL5grcfmKHjdr14unk66YdXQ1UwMBjQq3KwR+FBpShOkkCOuzMuABiXzjqV1l3vmZy9UeLCG7WQTjom8Kwh48QjY+SYODihkDhp6rO8aqi2t9Q2/hxCTSUwcOEbrv7ov7MniizvKWbOAwzWuAO4KotIrBKMMchVL0hRHfldDU6LRd0ApNFmyim1Vw90Ngd+YRqARvBG4yQb9503juvuZgYAyTgmpFIjMy+Th38vrGe3NvwWm5YBpvk8ZP7L7qa/51LzXlKvOSsAAAAASUVORK5CYII=", + minusSimple: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAL0lEQVQ4jWP8//8/IwMFgIkSzaMGUMkAFhiDkZHxHyka////z0QVFzCOJqThYAAAIOcKHde8N5QAAAAASUVORK5CYII=", + plusSimple: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAARUlEQVQ4jdWRMQ4AIAjErP9/M+eiiyEyYCTeSjiagiRaIj2zHBYABlgdwR8FrDdGsvZI6ncJ3OGkWte81EusLzhKfEIwANMfFhcD7xBqAAAAAElFTkSuQmCC" }; \ No newline at end of file diff --git a/web/js/Source.js b/web/js/Source.js index fe6083c..1585aef 100644 --- a/web/js/Source.js +++ b/web/js/Source.js @@ -1,7 +1,7 @@ var Source = function (cacheUMLExplorer) { this.URL = window.location.protocol + "//" + window.location.hostname + ":" + - 57776/*build.replace:window.location.port*/ + "/UMLExplorer"; + 57776/*build.replace:window.location.port*/ + "/ClassExplorer"; this.cue = cacheUMLExplorer; diff --git a/web/js/UI.js b/web/js/UI.js index d3d188d..dead2e7 100644 --- a/web/js/UI.js +++ b/web/js/UI.js @@ -1,11 +1,11 @@ /** * User interface functions. - * @param {CacheUMLExplorer} cacheUMLExplorer + * @param {CacheClassExplorer} cacheUMLExplorer * @constructor */ var UI = function (cacheUMLExplorer) { - this.cacheUMLExplorer = cacheUMLExplorer; + this.cacheClassExplorer = cacheUMLExplorer; this.BODY = cacheUMLExplorer.elements.uiBody; /** diff --git a/web/jsLib/joint.js b/web/jsLib/joint.js index 4533b75..4aeaed8 100644 --- a/web/jsLib/joint.js +++ b/web/jsLib/joint.js @@ -17217,7 +17217,7 @@ if ( typeof window === "object" && typeof window.document === "object" ) { // Shift all the but first by one line (`1em`) tspan = V('tspan', { dy: (i == 0 ? '0em' : opt.lineHeight || '1em'), - x: xOrigin + (lines[i].icons ? lines[i].icons.length*10 + 2 : 0) + x: xOrigin + (lines[i].icons ? lines[i].icons.length*10 : 0) }); tspan.addClass('line'); if (!lines[i].text) { @@ -17264,7 +17264,7 @@ if ( typeof window === "object" && typeof window.document === "object" ) { image.attr("width", 10); image.attr("height", 10); image.attr("y", textNode.getBoundingClientRect().top + i*(opt["font-size"] || 14) + 2); - image.attr("x", iconLeft); + image.attr("x", iconLeft - 1); iconLeft += 10; V(textNode.parentNode).append(image); textNode.TRASH.push(image.node); From 8665551b89b69d18a080708995b1e397f37708b7 Mon Sep 17 00:00:00 2001 From: ZitRo Date: Mon, 19 Oct 2015 00:24:28 +0300 Subject: [PATCH 08/11] classes ClassType now renders truthfully and constantly --- cache/projectTemplate.xml | 6 +++++- package.json | 2 +- web/css/hoverMessage.css | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/cache/projectTemplate.xml b/cache/projectTemplate.xml index ec24c5e..efe617d 100644 --- a/cache/projectTemplate.xml +++ b/cache/projectTemplate.xml @@ -4,7 +4,7 @@ Cache Class Explorer vX.X.X/*build.replace:pkg.version*/ Class contains methods that return structured classes/packages data. -63843,83200.096917 +63844,1327.122337 63653,67019.989197 @@ -88,6 +88,7 @@ Return structured data about class. %ZEN.proxyObject } if (oClass.TimeChanged) { set oClass.TimeChanged = $zdatetime(oClass.TimeChanged) } if (oClass.TimeCreated) { set oClass.TimeCreated = $zdatetime(oClass.TimeCreated) } + if ((compiledClassDefinition '= "") && (compiledClassDefinition.ClassType '= "")) { + set oClass.ClassType = compiledClassDefinition.ClassType // set class type from all inherited classes + } set oClass.Super = "" // do not quit with super at this moment if (oData.restrictPackage) && ('..inPackage(oData.basePackageName, package)) quit oClass diff --git a/package.json b/package.json index ae3b112..cb21f72 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "CacheClassExplorer", - "version": "1.8.1", + "version": "1.8.2", "description": "An UML Class explorer for InterSystems Caché", "directories": { "test": "test" diff --git a/web/css/hoverMessage.css b/web/css/hoverMessage.css index 7fd3a93..7c5e047 100644 --- a/web/css/hoverMessage.css +++ b/web/css/hoverMessage.css @@ -30,6 +30,6 @@ box-sizing: border-box; left: 0; top: 0; - padding: 20px; + padding: 15px; } \ No newline at end of file From a9412076db9d677667cb60b7715c8d3f65152414 Mon Sep 17 00:00:00 2001 From: ZitRo Date: Mon, 19 Oct 2015 00:34:34 +0300 Subject: [PATCH 09/11] screenshot update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8bb5ec0..d55ad16 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ An UML Class explorer for InterSystems Caché. ## Screenshots -![Demo](https://cloud.githubusercontent.com/assets/4989256/10561433/30415858-7531-11e5-97c6-6623d2b6ab30.png) +![Demo](https://cloud.githubusercontent.com/assets/4989256/10566777/112646cc-75f9-11e5-95cc-3db82abf1706.png) ## Installation From 573f36ddda562a2d89d86582a6e618ae9c0dae5e Mon Sep 17 00:00:00 2001 From: ZitRo Date: Mon, 19 Oct 2015 00:38:31 +0300 Subject: [PATCH 10/11] readme update --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d55ad16..3991d07 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,10 @@ An UML Class explorer for InterSystems Caché. + Build class diagrams; + Build diagrams for any package or subpackage; + Edit diagrams after build; ++ Switch between strict UML notation and designed view; + Export diagrams as an image; + See Class methods, properties, parameters, SQL queries and more; ++ See any keywords and related information by hovering over everything with pointer; + View class methods code with syntax highlighting; + Zoom in and out; + Search on diagram or in class tree; @@ -18,17 +20,17 @@ An UML Class explorer for InterSystems Caché. ## Installation -To install latest Caché UML Explorer, you just need to import UMLExplorer package. Download the +To install latest Caché Class Explorer, you just need to import ClassExplorer package. Download the archive from [latest releases](https://github.com/intersystems-ru/UMLExplorer/releases), and then import Cache/CacheUMLExplorer-vX.X.X.xml file. ###### Web application -Note that importing UMLExplorer.WebAppInstaller class will also create a /UMLExplorer application. +Note that importing ClassExplorer.WebAppInstaller class will also create a /ClassExplorer application. If you want to create WEB application manually, please, do not import this class. Anyway, importing this class requires %SYS permission. ## Usage -Visit [server domain and port]/UMLExplorer/ (slash at end required) to enter +Visit [server domain and port]/ClassExplorer/ (slash at end required) to enter application. ## Build From 9c656e3c49c4b7fb050fe3d582043f3fdc4c88cb Mon Sep 17 00:00:00 2001 From: ZitRo Date: Mon, 19 Oct 2015 00:38:53 +0300 Subject: [PATCH 11/11] readme update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3991d07..d7f3a4d 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ An UML Class explorer for InterSystems Caché. To install latest Caché Class Explorer, you just need to import ClassExplorer package. Download the archive from [latest releases](https://github.com/intersystems-ru/UMLExplorer/releases), and then import -Cache/CacheUMLExplorer-vX.X.X.xml file. +Cache/CacheClassExplorer-vX.X.X.xml file. ###### Web application Note that importing ClassExplorer.WebAppInstaller class will also create a /ClassExplorer application.