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 Jan 2, 2016
2 parents 0f4057d + 1a294ce commit de11f23
Show file tree
Hide file tree
Showing 10 changed files with 157 additions and 35 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ An UML Class explorer for InterSystems Caché.
+ 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 Class methods, properties, parameters, SQL queries, xDatas and more;
+ See any keywords and related information by hovering over everything with pointer;
+ Check which fields are connected by hovering over link;
+ View class methods code with syntax highlighting;
+ View methods code, sql queries and xDatas with syntax highlighting;
+ Zoom in and out;
+ Search on diagram or in class tree;
+ Explore!
Expand Down
16 changes: 15 additions & 1 deletion cache/projectTemplate.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<Description>
Cache Class Explorer vX.X.X/*build.replace:pkg.version*/
Class contains methods that return structured classes/packages data.</Description>
<TimeChanged>63844,1495</TimeChanged>
<TimeChanged>63919,67431.456639</TimeChanged>
<TimeCreated>63653,67019.989197</TimeCreated>

<Method name="getAllNamespacesList">
Expand Down Expand Up @@ -97,6 +97,7 @@ Return structured data about class.</Description>
set oProperties = ##class(%ZEN.proxyObject).%New()
set oQueries = ##class(%ZEN.proxyObject).%New()
set oIndices = ##class(%ZEN.proxyObject).%New()
set oXDatas = ##class(%ZEN.proxyObject).%New()
set oClass.isDataType = classDefinition.ClientDataTypeIsDefined()
set oClass.isOdbcType = classDefinition.OdbcTypeIsDefined()
Expand Down Expand Up @@ -184,6 +185,19 @@ Return structured data about class.</Description>
do oQueries.%DispatchSetProperty(q.Name, oProp)
}
#dim xd as %Dictionary.XDataDefinition
set oClass.xdatas = oXDatas
set props = ##class(%Dictionary.ClassDefinition).%OpenId("%Dictionary.XDataDefinition")
for i=1:1:classDefinition.XDatas.Count() {
set oProp = ##class(%ZEN.proxyObject).%New()
set xd = classDefinition.XDatas.GetAt(i)
for j=1:1:props.Properties.Count() {
set pname = props.Properties.GetAt(j).Name
set:(pname '= "parent") $PROPERTY(oProp, pname) = $PROPERTY(xd, pname)
}
do oXDatas.%DispatchSetProperty(xd.Name, oProp)
}
#dim ind as %Dictionary.IndexDefinition
set oClass.indices = oIndices
set props = ##class(%Dictionary.ClassDefinition).%OpenId("%Dictionary.IndexDefinition")
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": "CacheClassExplorer",
"version": "1.11.0",
"version": "1.12.0",
"description": "Class Explorer for InterSystems Caché",
"directories": {
"test": "test"
Expand Down
8 changes: 7 additions & 1 deletion web/css/classView.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ svg {
/*fill: lightgray;*/
}

.uml-class-attrs-rect, .uml-class-methods-rect, .uml-class-queries-rect {
.uml-class-attrs-rect, .uml-class-methods-rect, .uml-class-queries-rect, .uml-class-xdatas-rect {
fill: white;
}

Expand Down Expand Up @@ -78,6 +78,12 @@ text {
fill: magenta;
}

.uml-class-xdatas-label {
font-family: monospace;
font-weight: 900;
fill: #0ab;
}

.line-clickable {
cursor: pointer;
-webkit-transition: all .2s ease;
Expand Down
5 changes: 5 additions & 0 deletions web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ <h1>
<td><label for="setting.showQueries">Show Queries</label></td>
<td>Display block with class queries</td>
</tr>
<tr>
<td><input id="setting.showXDatas" type="checkbox"/></td>
<td><label for="setting.showXDatas">Show xDatas</label></td>
<td>Display block with class xDatas</td>
</tr>
</tbody>
</table>
<p id="settingsExtraText"></p>
Expand Down
6 changes: 4 additions & 2 deletions web/js/CacheClassExplorer.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ var CacheClassExplorer = function (treeViewContainer, classViewContainer) {
showParameters: id("setting.showParameters"),
showProperties: id("setting.showProperties"),
showMethods: id("setting.showMethods"),
showQueries: id("setting.showQueries")
showQueries: id("setting.showQueries"),
showXDatas: id("setting.showXDatas")
}
};

Expand All @@ -64,7 +65,8 @@ var CacheClassExplorer = function (treeViewContainer, classViewContainer) {
showParameters: settingsValue("showParameters", true),
showProperties: settingsValue("showProperties", true),
showMethods: settingsValue("showMethods", true),
showQueries: settingsValue("showQueries", true)
showQueries: settingsValue("showQueries", true),
showXDatas: settingsValue("showXDatas", true)
};

this.UI = new UI(this);
Expand Down
39 changes: 38 additions & 1 deletion web/js/ClassView.js
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,10 @@ ClassView.prototype.getPropertyHoverText = function (prop, type) {
"Encoded": 1,
// -- queries
"SqlView": 1,
// -- xDatas
"MimeType": function (data) {
return "MimeType = " + data;
},
// -- class
"ClientDataType": function (data, p) {
return !p["isDataType"] ? ""
Expand Down Expand Up @@ -450,6 +454,7 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
classProps = classMetaData["properties"],
classMethods = classMetaData["methods"],
classQueries = classMetaData["queries"],
classXDatas = classMetaData["xdatas"],
keyWordsArray = [name],
self = this;

Expand Down Expand Up @@ -525,6 +530,22 @@ ClassView.prototype.createClassInstance = function (name, classMetaData) {
}
return arr;
})(classQueries),
xdatas: (function (xds) {
var arr = [], n;
for (n in xds) {
keyWordsArray.push(n);
arr.push({
name: n,
text: n + (xds[n]["MimeType"] ? ": " + xds[n]["MimeType"] : ""),
hover: self.getPropertyHoverText(xds[n], "xdata"),
icons: self.getPropertyIcons(xds[n]),
clickHandler: (function (d, className) {
return function () { self.showXData(className, d); }
})(xds[n], name)
});
}
return arr;
})(classXDatas),
classSigns: this.getClassSigns(classMetaData),
classType: classMetaData.ClassType || "registered",
SYMBOL_12_WIDTH: self.SYMBOL_12_WIDTH
Expand Down Expand Up @@ -571,6 +592,22 @@ ClassView.prototype.showQuery = function (className, queryData) {

};

/**
* @param {string} className
* @param {string} xData
*/
ClassView.prototype.showXData = function (className, xData) {

xData = xData || "";

this.showPanel({
header: "##class(" + className + ")." + xData["Name"] + (xData["MimeType"] ? " (" + xData["MimeType"] + ")" : xData["MimeType"]),
comment: xData["Description"],
body: lib.highlightXML(xData["Data"] || "")
});

};

/**
* Show panel filled with given HTML contents.
* @param {string} data.header
Expand Down Expand Up @@ -949,7 +986,7 @@ ClassView.prototype.bindLinkHighlight = function () {
highlighted = !!fields.length;
});

this.paper.on("cell:mouseout", function (e) {
this.paper.on("cell:mouseout", function () {
highlighted = false;
freeFields();
});
Expand Down
55 changes: 49 additions & 6 deletions web/js/Lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,7 @@ Lib.prototype.sqlKeyWords = {
*/
Lib.prototype.highlightCOS = function (code) {
var self = this;
return code.replace(/[<>&]/g, function (r) {
return r === "<" ? "&lt;" : r === ">" ? "&gt;" : "&amp;"
}).replace(/(&[lgtamp]{2,3};)|(\/\/[^\n]*)\n|("[^"]*")|([\$#]{1,3}[a-zA-Z][a-zA-Z0-9]*)|\((%?[a-zA-Z0-9\.]+)\)\.|(%?[a-zA-Z][a-zA-Z0-9]*)\(|([a-zA-Z]+)|(\/\*[^]*?\*\/)|(\^%?[a-zA-Z][a-zA-Z0-9]*)/g, function (part) {
return this.replaceSpecial(code).replace(/(&[lgtamp]{2,3};)|(\/\/[^\n]*)\n|("[^"]*")|([\$#]{1,3}[a-zA-Z][a-zA-Z0-9]*)|\((%?[a-zA-Z0-9\.]+)\)\.|(%?[a-zA-Z][a-zA-Z0-9]*)\(|([a-zA-Z]+)|(\/\*[^]*?\*\/)|(\^%?[a-zA-Z][a-zA-Z0-9]*)/g, function (part) {
var i = -1, c;
[].slice.call(arguments, 1, arguments.length - 2).every(function (e) {
i++;
Expand All @@ -201,15 +199,19 @@ Lib.prototype.highlightCOS = function (code) {
});
};

Lib.prototype.replaceSpecial = function (str) {
return str.replace(/[<>&]/g, function (r) {
return r === "<" ? "&lt;" : r === ">" ? "&gt;" : "&amp;";
});
};

/**
* Highlight SQL code.
* @param {string} code
*/
Lib.prototype.highlightSQL = function (code) {
var self = this;
return code.replace(/[<>&]/g, function (r) {
return r === "<" ? "&lt;" : r === ">" ? "&gt;" : "&amp;"
}).replace(/(&[lgtamp]{2,3};)|([a-zA-Z]+)/gi, function (part, a, kw) {
return this.replaceSpecial(code).replace(/(&[lgtamp]{2,3};)|([a-zA-Z]+)/gi, function (part, a, kw) {
var i = -1, c;
[].slice.call(arguments, 1, arguments.length - 2).every(function (e) {
i++;
Expand All @@ -224,6 +226,47 @@ Lib.prototype.highlightSQL = function (code) {
});
};

/**
* Highlight XML code.
* @param {string} code
*/
Lib.prototype.highlightXML = function (code) {

var replaceSpecial = this.replaceSpecial,
level = 0,
regex = new RegExp("<!\\[CDATA\\[([^]*?)]]" // this line break is done to avoid xData
// injection fail, as CDATA cannot have the closing character sequence inside.
// DO NOT join these three characters in one inline string
// KEEP THIS LINE
+ [].join("")
+ ">|<(\\/?)[\\w](?:.*(?=\\/>)|.*(?=>))(\\/?)>|(<!--[^]*?-->)"
+ "|(<\\?[^]*?\\?>)|(<[^]*?>)", "g");

function stringFill (n) {
return new Array(n + 1).join(" ")
}

return code.replace(regex, function (part, cData, tagS, tagG, comment, special, etc) {
return typeof tagS !== "undefined" ? part.replace(/<\/?([^\s]+)(.*(?=\/>)|.*(?=>))\/?>/ig, function (p, tagName, attrs) {
if (tagS) level--;
var s = stringFill(level) + " &lt;" + tagS + "<span class=\"syntax-keyword\">"
+ tagName + "</span>"
+ attrs.replace(/(\s*[^=]+)=(\s*(?:'[^']*'|"[^"]*"))/g, function (part, a, b) {
return "<span class=\"syntax-names\">" + a
+ "</span>=<span class=\"syntax-string\">" + b + "</span>";
})
+ tagG + "&gt;";
if (!tagS && !tagG) level++;
return s;
}) : comment ? "<span class=\"syntax-comment\">" + replaceSpecial(comment) + "</span>"
: special ? replaceSpecial(special)
: etc ? replaceSpecial(etc)
: "<span class=\"syntax-other\">&lt;![CDATA[</span>"
+ replaceSpecial(cData) + "<span class=\"syntax-other\">]]&gt;</span>";
});

};

Lib.prototype.getSelection = function () {
var html = "";
if (typeof window.getSelection != "undefined") {
Expand Down
1 change: 1 addition & 0 deletions web/js/Logic.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Logic.prototype.process = function (data) {
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;
if (cls.xdatas && !this.umlExplorer.settings.showXDatas) delete cls.xdatas;
}

if (!this.umlExplorer.settings.showDataTypesOnDiagram) {
Expand Down
56 changes: 35 additions & 21 deletions web/jsLib/joint.shapes.uml.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,25 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({

markup: [
'<g class="rotatable">',
'<g class="scalable">',
'<rect class="uml-class-name-rect"/>',
'<rect class="uml-class-params-rect"/>',
'<text class="uml-class-params-label">Parameters</text>',
'<rect class="uml-class-attrs-rect"/>',
'<text class="uml-class-attrs-label">Properties</text>',
'<rect class="uml-class-methods-rect"/>',
'<text class="uml-class-methods-label">Methods</text>',
'<rect class="uml-class-queries-rect"/>',
'<text class="uml-class-queries-label">Queries</text>',
'</g>',
'<text class="uml-class-name-text"/>',
'<text class="uml-class-params-text"/>',
'<text class="uml-class-attrs-text"/>',
'<text class="uml-class-methods-text"/>',
'<text class="uml-class-queries-text"/>',
'<g class="scalable">',
'<rect class="uml-class-name-rect"/>',
'<rect class="uml-class-params-rect"/>',
'<text class="uml-class-params-label">Parameters</text>',
'<rect class="uml-class-attrs-rect"/>',
'<text class="uml-class-attrs-label">Properties</text>',
'<rect class="uml-class-methods-rect"/>',
'<text class="uml-class-methods-label">Methods</text>',
'<rect class="uml-class-queries-rect"/>',
'<text class="uml-class-queries-label">Queries</text>',
'<rect class="uml-class-xdatas-rect"/>',
'<text class="uml-class-xdatas-label">xDatas</text>',
'</g>',
'<text class="uml-class-name-text"/>',
'<text class="uml-class-params-text"/>',
'<text class="uml-class-attrs-text"/>',
'<text class="uml-class-methods-text"/>',
'<text class="uml-class-queries-text"/>',
'<text class="uml-class-xdatas-text"/>',
'</g>'
].join(''),

Expand All @@ -50,6 +53,7 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
'.uml-class-attrs-rect': { 'stroke': 'black', 'stroke-width': 1, 'fill': '#2980b9' },
'.uml-class-methods-rect': { 'stroke': 'black', 'stroke-width': 1, 'fill': '#2980b9' },
'.uml-class-queries-rect': { 'stroke': 'black', 'stroke-width': 1, 'fill': '#2980b9' },
'.uml-class-xdatas-rect': { 'stroke': 'black', 'stroke-width': 1, 'fill': '#2980b9' },

'.uml-class-name-text': {
'ref': '.uml-class-name-rect', 'ref-y': .5, 'ref-x': .5, 'text-anchor': 'middle', 'y-alignment': 'middle', 'font-weight': 'bold',
Expand All @@ -71,6 +75,10 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
'ref': '.uml-class-queries-rect', 'ref-y': 5, 'ref-x': 5,
'fill': 'black', 'font-size': 12
},
'.uml-class-xdatas-text': {
'ref': '.uml-class-xdatas-rect', 'ref-y': 5, 'ref-x': 5,
'fill': 'black', 'font-size': 12
},
'.uml-class-attrs-label': {
ref: '.uml-class-attrs-label', fill: "black", 'font-size': 10,
xPos: -56
Expand All @@ -83,6 +91,9 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
},
'.uml-class-params-label': {
ref: '.uml-class-methods-label', fill: "black", 'font-size': 10
},
'.uml-class-xdatas-label': {
ref: '.uml-class-xdatas-label', fill: "black", 'font-size': 10
}
},

Expand All @@ -91,6 +102,7 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
attributes: [],
methods: [],
queries: [],
xdatas: [],
classSigns: []

}, joint.shapes.basic.Generic.prototype.defaults),
Expand All @@ -100,10 +112,11 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
var o,
rects = [
{ type: 'name', text: this.getClassName() },
{ type: 'params', text: (o = this.get('params')) , o: (o.forEach(function(e){e._BLOCK="parameters"}) && o) },
{ type: 'attrs', text: (o = this.get('attributes')), o: (o.forEach(function(e){e._BLOCK="properties"}) && o) },
{ type: 'methods', text: (o = this.get('methods')) , o: (o.forEach(function(e){e._BLOCK="methods"}) && o) },
{ type: 'queries', text: (o = this.get('queries')) , o: (o.forEach(function(e){e._BLOCK="queries"}) && o) }
{ type: 'params', text: (o = this.get('params')||[]) , o: (o.forEach(function(e){e._BLOCK="parameters"}) && o) },
{ type: 'attrs', text: (o = this.get('attributes')||[]), o: (o.forEach(function(e){e._BLOCK="properties"}) && o) },
{ type: 'methods', text: (o = this.get('methods')||[]) , o: (o.forEach(function(e){e._BLOCK="methods"}) && o) },
{ type: 'queries', text: (o = this.get('queries')||[]) , o: (o.forEach(function(e){e._BLOCK="queries"}) && o) },
{ type: 'xdatas', text: (o = this.get('xdatas')||[]) , o: (o.forEach(function(e){e._BLOCK="xdatas"}) && o) }
],
self = this,
classSigns = this.get('classSigns'),
Expand Down Expand Up @@ -199,7 +212,8 @@ joint.shapes.uml.Class = joint.shapes.basic.Generic.extend({
{ type: 'params', text: this.get('params') },
{ type: 'attrs', text: this.get('attributes') },
{ type: 'methods', text: this.get('methods') },
{ type: 'queries', text: this.get('queries') }
{ type: 'queries', text: this.get('queries') },
{ type: 'xdatas', text: this.get('xdatas') }
];

var offsetY = 0;
Expand Down

0 comments on commit de11f23

Please sign in to comment.