Skip to content

Commit 6c935a5

Browse files
important changes: extended hover description for all class elements, minor fixes
1 parent ee901c1 commit 6c935a5

File tree

9 files changed

+219
-28
lines changed

9 files changed

+219
-28
lines changed

cache/projectTemplate.xml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<Description>
55
Cache UML Explorer vX.X.X/*build.replace:pkg.version*/
66
Class contains methods that return structured classes/packages data.</Description>
7-
<TimeChanged>63830,81286.756889</TimeChanged>
7+
<TimeChanged>63843,54972.140109</TimeChanged>
88
<TimeCreated>63653,67019.989197</TimeCreated>
99

1010
<Method name="getAllNamespacesList">
@@ -94,6 +94,7 @@ Return structured data about class.</Description>
9494
set package = $LISTTOSTRING($LIST($LISTFROMSTRING(classDefinition.Name, "."), 1, *-1),".")
9595
set oProperties = ##class(%ZEN.proxyObject).%New()
9696
set oQueries = ##class(%ZEN.proxyObject).%New()
97+
set oIndices = ##class(%ZEN.proxyObject).%New()
9798
9899
set oClass.NAMESPACE = $NAMESPACE
99100
set oClass.SYSTEM = classDefinition.System
@@ -171,6 +172,19 @@ Return structured data about class.</Description>
171172
do oQueries.%DispatchSetProperty(q.Name, oProp)
172173
}
173174
175+
#dim ind as %Dictionary.IndexDefinition
176+
set oClass.indices = oIndices
177+
set props = ##class(%Dictionary.ClassDefinition).%OpenId("%Dictionary.IndexDefinition")
178+
for i=1:1:classDefinition.Indices.Count() {
179+
set oProp = ##class(%ZEN.proxyObject).%New()
180+
set ind = classDefinition.Indices.GetAt(i)
181+
for j=1:1:props.Properties.Count() {
182+
set pname = props.Properties.GetAt(j).Name
183+
set:(pname '= "parent") $PROPERTY(oProp, pname) = $PROPERTY(ind, pname)
184+
}
185+
do oIndices.%DispatchSetProperty(ind.Name, oProp)
186+
}
187+
174188
do ..collectInheritance(oData, oClass.super)
175189
176190
quit oClass

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "CacheUMLExplorer",
3-
"version": "1.5.1",
3+
"version": "1.6.1",
44
"description": "An UML Class explorer for InterSystems Caché",
55
"directories": {
66
"test": "test"
@@ -9,7 +9,7 @@
99
"devDependencies": {
1010
"autoprefixer-core": "^5.1.11",
1111
"express": "^5.0.0-alpha.1",
12-
"gulp": "^3.8.11",
12+
"gulp": "^3.9.0",
1313
"gulp-add-src": "^0.2.0",
1414
"gulp-clean": "^0.3.1",
1515
"gulp-concat": "^2.4.1",

web/css/extras.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,4 +311,12 @@
311311
.icon.list:hover:after {
312312
left: 4px;
313313
box-shadow: inset 0 0 0 32px #ffcc1b, 0 -7px 0 0 #ffcc1b, 0 7px 0 0 #ffcc1b;
314+
}
315+
316+
.underlined {
317+
text-decoration: underline;
318+
}
319+
320+
.clickable {
321+
cursor: pointer;
314322
}

web/css/hoverMessage.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
.line-hoverable {
1515
cursor: pointer;
16+
font-style: italic;
1617
-webkit-transition: all .5s ease;
1718
-moz-transition: all .5s ease;
1819
-o-transition: all .5s ease;
@@ -30,6 +31,5 @@
3031
left: 0;
3132
top: 0;
3233
padding: 20px;
33-
cursor: pointer;
3434

3535
}

web/css/interface.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ html, body {
8686
.message {
8787
font-size: 14pt;
8888
background: rgba(245, 245, 245, 0.9);
89+
z-index: 1;
8990
-webkit-transition: all .2s ease;
9091
-moz-transition: all .2s ease;
9192
-o-transition: all .2s ease;

web/js/ClassView.js

Lines changed: 133 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ ClassView.prototype.renderInfoGraphic = function () {
133133
abstract: 1
134134
},
135135
"Class method": {
136-
classMethod: 1
136+
ClassMethod: 1
137137
},
138138
"Client method": {
139139
clientMethod: 1
@@ -349,28 +349,143 @@ ClassView.prototype.getClassSigns = function (classMetaData) {
349349
/**
350350
* Returns array of icons according to method metadata.
351351
*
352-
* @param method
352+
* @param property
353353
*/
354-
ClassView.prototype.getPropertyIcons = function (method) {
354+
ClassView.prototype.getPropertyIcons = function (property) {
355355

356356
var icons = [];
357357

358-
if (typeof method["Private"] !== "undefined") {
359-
icons.push({ src: lib.image[method["Private"] ? "minus" : "plus"] });
358+
if (typeof property["Private"] !== "undefined") {
359+
icons.push({ src: lib.image[property["Private"] ? "minus" : "plus"] });
360+
}
361+
if (property["Abstract"]) icons.push({ src: lib.image.crystalBall });
362+
if (property["ClientMethod"]) icons.push({ src: lib.image.user });
363+
if (property["Final"]) icons.push({ src: lib.image.blueFlag });
364+
if (property["NotInheritable"]) icons.push({ src: lib.image.redFlag });
365+
if (property["SqlProc"]) icons.push({ src: lib.image.table });
366+
if (property["WebMethod"]) icons.push({ src: lib.image.earth });
367+
if (property["ZenMethod"]) icons.push({ src: lib.image.zed });
368+
if (property["ReadOnly"]) icons.push({ src: lib.image.eye });
369+
if (property["index"]) {
370+
icons.push(
371+
property["index"]["Unique"] ? { src: lib.image.keyRed }
372+
: (property["index"]["PrimaryKey"] || property["index"]["IDKey"])
373+
? { src: lib.image.keyGreen } : { src: lib.image.keyYellow }
374+
);
360375
}
361-
if (method["Abstract"]) icons.push({ src: lib.image.crystalBall });
362-
if (method["ClientMethod"]) icons.push({ src: lib.image.user });
363-
if (method["Final"]) icons.push({ src: lib.image.blueFlag });
364-
if (method["NotInheritable"]) icons.push({ src: lib.image.redFlag });
365-
if (method["SqlProc"]) icons.push({ src: lib.image.table });
366-
if (method["WebMethod"]) icons.push({ src: lib.image.earth });
367-
if (method["ZenMethod"]) icons.push({ src: lib.image.zed });
368-
if (method["ReadOnly"]) icons.push({ src: lib.image.eye });
369376

370377
return icons;
371378

372379
};
373380

381+
/**
382+
* @param prop
383+
* @param {string} type = ["parameter", "property", "method", "query"]
384+
* @returns {string}
385+
*/
386+
ClassView.prototype.getPropertyHoverText = function (prop, type) {
387+
388+
var ind, i, desc = "",
389+
indexText = {
390+
"IdKey": function () { return "IdKey"; },
391+
"Type": function (type) { return "Type="+type; },
392+
"Internal": function () { return "Internal"; },
393+
"Extent": function () { return "Extent"; },
394+
"PrimaryKey": function () { return "PrimaryKey"; },
395+
"Unique": function () { return "Unique"; }
396+
},
397+
propText = {
398+
"Calculated": 1,
399+
"Final": 1,
400+
"Identity": 1,
401+
"InitialExpression": function (data) {
402+
return (data === "\"\"")
403+
? ""
404+
: "<span class=\"syntax-keyword\">InitialExpression</span>="
405+
+ lib.highlightCOS(data + "")
406+
},
407+
"Internal": 1,
408+
"MultiDimensional": 1,
409+
"NoModBit": 1,
410+
"NotInheritable": 1,
411+
"Private": 1,
412+
"ReadOnly": 1,
413+
"Relationship": function (data, p) {
414+
return "<span class=\"syntax-keyword\">Relationship</span> [ Cardinality="
415+
+ p["Cardinality"] + ", Inverse=" + p["Inverse"] + " ]";
416+
},
417+
"Required": 1,
418+
"SqlComputed": function (data, p) {
419+
return p["SqlComputeCode"]
420+
? "<span class=\"syntax-keyword\">SqlComputed</span> [ SqlComputeCode={"
421+
+ lib.highlightCOS(p["SqlComputeCode"]) + "} ]"
422+
: "";
423+
},
424+
"Transient": 1,
425+
// -- methods
426+
"Abstract": 1,
427+
// "ClassMethod": 1, - they're underlined
428+
"ClientMethod": 1,
429+
"CodeMode": function (data) {
430+
return data === "code" ? "" : "<span class=\"syntax-keyword\">CodeMode</span>="
431+
+ "<span class=\"syntax-string\">" + data + "</span>";
432+
},
433+
"ForceGenerate": 1,
434+
"NoContext": 1,
435+
"NotForProperty": 1,
436+
"ReturnResultsets": 1,
437+
"SoapAction": function (data) {
438+
return data === "[default]" ? ""
439+
: "<span class=\"syntax-keyword\">SoapAction</span>="
440+
+ "<span class=\"syntax-string\">" + data + "</span>";
441+
},
442+
"SqlProc": 1,
443+
"WebMethod": 1,
444+
"ZenMethod": 1,
445+
// -- parameters
446+
"Encoded": 1,
447+
// -- queries
448+
"SqlView": 1
449+
};
450+
451+
if (ind = prop["index"]) {
452+
desc += "<span class=\"syntax-keyword\">INDEX</span> <span class=\"syntax-string\">"
453+
+ ind["Name"] + "</span> " + (function () {
454+
var txt = [];
455+
for (i in ind) {
456+
if (indexText[i] && ind[i]) txt.push(indexText[i](ind[i]));
457+
}
458+
return txt.join(", ");
459+
})()
460+
+ "\n";
461+
}
462+
463+
var txt = [], val;
464+
for (i in prop) {
465+
if (propText[i] && (prop[i] || i === "InitialExpression")) {
466+
val = propText[i] === 1
467+
? "<span class=\"syntax-keyword\">" + i + "</span>"
468+
: propText[i](prop[i], prop);
469+
if (val !== "") txt.push(val);
470+
}
471+
}
472+
if (txt.length) desc += txt.join(", ");
473+
474+
// Display FormalSpec in methods?
475+
476+
if (desc && prop["Description"]) desc += "<hr/>";
477+
desc += prop["Description"] || "";
478+
479+
if (desc && type) {
480+
desc = "<span class=\"underlined\"><span class=\"syntax-keyword\">" + lib.capitalize(type)
481+
+ "</span> <span class=\"syntax-string\">" + (prop["Name"] || "") + "</span></span>:"
482+
+ ("<br/>") + desc;
483+
}
484+
485+
return desc;
486+
487+
};
488+
374489
/**
375490
* @param {string} name
376491
* @param classMetaData
@@ -401,7 +516,7 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
401516
keyWordsArray.push(n);
402517
arr.push({
403518
text: n + (params[n]["Type"] ? ": " + params[n]["Type"] : ""),
404-
hover: params[n]["Description"] || "",
519+
hover: self.getPropertyHoverText(params[n], "parameter"),
405520
icons: self.getPropertyIcons(params[n])
406521
});
407522
}
@@ -413,7 +528,7 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
413528
keyWordsArray.push(n);
414529
arr.push({
415530
text: n + (ps[n]["Type"] ? ": " + ps[n]["Type"] : ""),
416-
hover: ps[n]["Description"] || "",
531+
hover: self.getPropertyHoverText(ps[n], "property"),
417532
icons: self.getPropertyIcons(ps[n])
418533
});
419534
}
@@ -427,11 +542,11 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
427542
text: n + (met[n]["ReturnType"] ? ": " + met[n]["ReturnType"] : ""),
428543
styles: (function (t) {
429544
return t ? { textDecoration: "underline" } : {}
430-
})(met[n]["classMethod"]),
545+
})(met[n]["ClassMethod"]),
431546
clickHandler: (function (n) {
432547
return function () { self.showMethodCode(name, n); }
433548
})(n),
434-
hover: met[n]["Description"] || "",
549+
hover: self.getPropertyHoverText(met[n], "method"),
435550
icons: self.getPropertyIcons(met[n])
436551
});
437552
}
@@ -444,7 +559,7 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
444559
arr.push({
445560
text: n,
446561
icons: self.getPropertyIcons(qrs[n]),
447-
hover: qrs[n]["SqlQuery"],
562+
hover: self.getPropertyHoverText(qrs[n], "query"),
448563
clickHandler: (function (q, className) {
449564
return function () { self.showQuery(className, q); }
450565
})(qrs[n], name)

web/js/HoverMessage.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ var HoverMessage = function (text, clickHandler) {
22

33
var self = this;
44

5-
this.clickHandler = typeof clickHandler === "function" ? clickHandler : function () {};
5+
this.clickHandler = typeof clickHandler === "function" ? clickHandler : null;
66
this.element = document.createElement("div");
77
this.element.className = "hoverMessage";
88
this.element.innerHTML = text;
@@ -19,9 +19,13 @@ var HoverMessage = function (text, clickHandler) {
1919
})(e, this))) return;
2020
self.detach();
2121
});
22-
this.container.addEventListener("click", function () {
23-
self.clickHandler();
24-
});
22+
23+
if (this.clickHandler) {
24+
if (this.container.classList) this.container.classList.add("clickable");
25+
this.container.addEventListener("click", function () {
26+
if (!lib.getSelection()) self.clickHandler();
27+
});
28+
}
2529

2630
};
2731

@@ -30,7 +34,8 @@ HoverMessage.prototype.attach = function (screenX, screenY) {
3034
var e = this.container, w;
3135

3236
document.body.appendChild(e);
33-
e.style.width = (w = Math.min(e.offsetWidth, window.innerWidth/2)) + "px";
37+
// +1 to width fixes "X.4234" rational part that may appear on SVG
38+
e.style.width = (w = Math.ceil(Math.min(e.offsetWidth, window.innerWidth/2) + 1)) + "px";
3439
e.style.top = (screenY - e.offsetHeight + 15) + "px";
3540
e.style.left = Math.min(window.innerWidth - w - 10, screenX - w/2) + "px";
3641

0 commit comments

Comments
 (0)