Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
nikitaeverywhere committed Oct 17, 2015
2 parents dce0851 + ee901c1 commit 966bf88
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 83 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ An UML Class explorer for InterSystems Caché.

## Screenshots

![Demo](https://cloud.githubusercontent.com/assets/4989256/9852547/890543f8-5b07-11e5-9dc3-a539e33b2058.png)
![Demo](https://cloud.githubusercontent.com/assets/4989256/10561433/30415858-7531-11e5-97c6-6623d2b6ab30.png)

## Installation

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "CacheUMLExplorer",
"version": "1.4.1",
"version": "1.5.1",
"description": "An UML Class explorer for InterSystems Caché",
"directories": {
"test": "test"
Expand Down
17 changes: 16 additions & 1 deletion web/css/hoverMessage.css
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
.hoverMessage {

box-sizing: border-box;
white-space: pre-line;
background: rgba(255, 255, 255, 0.9);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
border: 1px solid dimgray;
padding: .3em;
overflow: hidden;
line-height: 1em;
max-height: 10em;

}

.line-hoverable {
cursor: pointer;
-webkit-transition: all .5s ease;
-moz-transition: all .5s ease;
-o-transition: all .5s ease;
transition: all .5s ease;
}

.line-hoverable:hover {
fill: red;
}

.hoverContainer {
Expand All @@ -16,5 +30,6 @@
left: 0;
top: 0;
padding: 20px;
cursor: pointer;

}
134 changes: 60 additions & 74 deletions web/js/ClassView.js
Original file line number Diff line number Diff line change
Expand Up @@ -279,37 +279,6 @@ ClassView.prototype.filterInherits = function (data) {
"%DataType": true
};

// inheritance: { "ClassName": { "IHCN": 1, ... }, ... }
// inherit isDataType & classType if not set for inherited classes
//var rec = function (className) {
// if (!(cls = data.classes[className])) return { isDataType: null, classType: null };
// var c, res = { isDataType: cls.isDataType || null, classType: cls.classType || null}, resi, cls;
// if (className === "%DeepSee.ListingTable") console.log("-------", res);
// if (data.inheritance[className]) {
// for (c in data.inheritance[className]) {
// resi = undefined;
// if (data.classes[c]) {
// if (data.classes[c].isDataType) resi = {
// isDataType: data.classes[c].isDataType,
// classType: data.classes[c].classType || null
// }; else if (data.classes[c].classType) {
// res.classType = data.classes[c].classType;
// }
// }
// if (!resi) resi = rec(c);
// if (className === "Aviation.Cubes.Aircraft.Listing") console.log(c, resi);
// if (res.isDataType === null) { res.isDataType = resi.isDataType; }
// if (res.classType === null) { res.classType = resi.classType; }
// }
// }
// if (res.isDataType !== null && !cls.isDataType) { cls.isDataType = res.isDataType; }
// if (res.classType !== null && !cls.classType) { cls.classType = res.classType; }
// return res;
//};
//for (p1 in data.classes) {
// rec(p1);
//}

var f = function (p) {
return filter.hasOwnProperty(p) || (data.classes[p] || {})["isDataType"] ||
lib.obj(((data.classes[p] || {}).super || "").split(",")).hasOwnProperty("%DataType");
Expand Down Expand Up @@ -341,33 +310,6 @@ ClassView.prototype.getClassSigns = function (classMetaData) {

var signs = [], ct;

// todo: preprocess class type before diagram load
//if (classMetaData["classType"] || sup) {
// ct = classMetaData["classType"];
// if (sup.hasOwnProperty("%Library.Persistent") || sup.hasOwnProperty("%Persistent")) {
// ct = "Persistent";
// }
// if (sup.hasOwnProperty("%Library.SerialObject") || sup.hasOwnProperty("%SerialObject")) {
// ct = "Serial";
// }
// if (
// sup.hasOwnProperty("%Library.RegisteredObject")
// || sup.hasOwnProperty("%RegisteredObject")
// ) {
// ct = "Registered";
// }
// if (sup.hasOwnProperty("%Library.DataType") || sup.hasOwnProperty("%DataType")) {
// ct = "Datatype";
// }
// if (ct) {
// CT = ct;
// signs.push({
// icon: lib.image.greenPill,
// text: lib.capitalize(ct),
// textStyle: "fill:rgb(130,0,255)"
// });
// }
//}
if (ct = classMetaData["$classType"]) {
if (ct !== "Serial" && ct !== "Registered" && ct !== "Persistent" && ct !== "DataType") {
signs.push({
Expand Down Expand Up @@ -459,6 +401,7 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
keyWordsArray.push(n);
arr.push({
text: n + (params[n]["Type"] ? ": " + params[n]["Type"] : ""),
hover: params[n]["Description"] || "",
icons: self.getPropertyIcons(params[n])
});
}
Expand All @@ -470,6 +413,7 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
keyWordsArray.push(n);
arr.push({
text: n + (ps[n]["Type"] ? ": " + ps[n]["Type"] : ""),
hover: ps[n]["Description"] || "",
icons: self.getPropertyIcons(ps[n])
});
}
Expand All @@ -487,6 +431,7 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
clickHandler: (function (n) {
return function () { self.showMethodCode(name, n); }
})(n),
hover: met[n]["Description"] || "",
icons: self.getPropertyIcons(met[n])
});
}
Expand All @@ -499,7 +444,10 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
arr.push({
text: n,
icons: self.getPropertyIcons(qrs[n]),
hover: qrs[n]["SqlQuery"]
hover: qrs[n]["SqlQuery"],
clickHandler: (function (q, className) {
return function () { self.showQuery(className, q); }
})(qrs[n], name)
});
}
return arr;
Expand All @@ -519,26 +467,58 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {

ClassView.prototype.showMethodCode = function (className, methodName) {

var self = this,
els = this.cacheUMLExplorer.elements;
var self = this;

this.cacheUMLExplorer.source.getMethod(className, methodName, function (err, data) {
if (err || data.error) {
self.cacheUMLExplorer.UI.displayMessage("Unable to get method \"" + methodName + "\"!");
return;
}
els.methodLabel.textContent = className + ": " + methodName + "("
self.showPanel({
header: className + ": " + methodName + "("
+ (data["arguments"] || "").replace(/,/g, ", ").replace(/:/g, ": ") + ")"
+ (data["returns"] ? ": " + data["returns"] : "");
els.methodDescription.innerHTML = data["description"] || "";
els.methodCode.innerHTML = lib.highlightCOS(data["code"] || "");
els.methodViewBounds.style.height =
els.classView.offsetHeight - els.methodViewBounds.offsetTop + "px";
els.methodCodeView.classList.add("active");
+ (data["returns"] ? ": " + data["returns"] : ""),
comment: data["description"],
body: lib.highlightCOS(data["code"] || "")
});
});

};

ClassView.prototype.showQuery = function (className, queryData) {

queryData = queryData || {};

this.showPanel({
header: "##class(" + className + ")." + queryData["Name"] + "("
+ (queryData["FormalSpec"] || "").replace(/,/g, ", ").replace(/:/g, ": ") + ")",
comment: queryData["Description"],
body: lib.highlightSQL(queryData["SqlQuery"] || "")
});

};

/**
* Show panel filled with given HTML contents.
* @param {string} data.header
* @param {string} [data.comment]
* @param {string} data.body
*/
ClassView.prototype.showPanel = function (data) {

var els = this.cacheUMLExplorer.elements;

data = data || {};

els.methodLabel.textContent = data.header || "";
els.methodDescription.innerHTML = data.comment || "";
els.methodCode.innerHTML = data.body || "";
els.methodViewBounds.style.height =
els.classView.offsetHeight - els.methodViewBounds.offsetTop + "px";
els.methodCodeView.classList.add("active");

};

ClassView.prototype.hideMethodCode = function () {

this.cacheUMLExplorer.elements.methodCodeView.classList.remove("active");
Expand Down Expand Up @@ -870,7 +850,8 @@ ClassView.prototype.init = function () {
this.graph.on("change:position", function (object) {
if (_.contains(self.objects, object))
for (p in self.links) {
self.paper.findViewByModel(self.links[p]).update();
var link = self.paper.findViewByModel(self.links[p]);
if (link) link.update(); // removed links, should be in todo
}
});

Expand Down Expand Up @@ -955,13 +936,18 @@ ClassView.prototype.init = function () {
ClassView.prototype.onRendered = function () {

[].slice.call(document.querySelectorAll(".line-hoverable")).forEach(function (el) {
var hm = new HoverMessage(el.getAttribute("hovertext"));
var hm = new HoverMessage(el.getAttribute("hovertext"), el["clickHandler"] || null),
APPEAR_TIMEOUT = 500, tm = 0;
el.addEventListener("mouseover", function (e) {
hm.attach(e.pageX || e.clientX, e.pageY || e.clientY);
if (tm) clearTimeout(tm);
tm = setTimeout(function () {
clearTimeout(tm);
hm.attach(e.pageX || e.clientX, e.pageY || e.clientY);
}, APPEAR_TIMEOUT);
});
el.addEventListener("mouseout", function () {
clearTimeout(tm);
});
//el.addEventListener("mouseout", function () {
// hm.detach();
//});
});

};
18 changes: 13 additions & 5 deletions web/js/HoverMessage.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
var HoverMessage = function (text) {
var HoverMessage = function (text, clickHandler) {

var self = this;

this.clickHandler = typeof clickHandler === "function" ? clickHandler : function () {};
this.element = document.createElement("div");
this.element.className = "hoverMessage";
this.element.textContent = text;
this.element.innerHTML = text;
this.container = document.createElement("div");
this.container.className = "hoverContainer";
this.container.appendChild(this.element);

this.container.addEventListener("mouseout", function (event) {
var e = event.toElement || event.relatedTarget;
if (e.parentNode == this || e == this) return;
if (e && ((function check (e, t) { // if one of the parents is this object
if (e === t) return true;
if (!e.parentNode) return false;
return check(e.parentNode, t);
})(e, this))) return;
self.detach();
});
this.container.addEventListener("click", function () {
self.clickHandler();
});

};

HoverMessage.prototype.attach = function (screenX, screenY) {

var e = this.container,
w = Math.min(400, window.innerWidth/2);
var e = this.container, w;

document.body.appendChild(e);
e.style.width = (w = Math.min(e.offsetWidth, window.innerWidth/2)) + "px";
e.style.top = (screenY - e.offsetHeight + 15) + "px";
Expand Down
36 changes: 36 additions & 0 deletions web/js/Lib.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion web/jsLib/joint.js
Original file line number Diff line number Diff line change
Expand Up @@ -17230,9 +17230,10 @@ if ( typeof window === "object" && typeof window.document === "object" ) {
}
if (typeof lines[i]["clickHandler"] === "function") {
tspan.node.addEventListener("click", lines[i]["clickHandler"]);
tspan.node["clickHandler"] = lines[i]["clickHandler"];
tspan.addClass('line-clickable');
}
if (typeof lines[i]["hover"] === "string") {
if (lines[i]["hover"] && typeof lines[i]["hover"] === "string") {
tspan.addClass('line-hoverable');
tspan.node.setAttribute("hovertext", lines[i]["hover"]);
}
Expand Down

0 comments on commit 966bf88

Please sign in to comment.